From 5dad12ce1a2dcd6bd9805c2f7eeb96f9dbe8aa48 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 29 Jul 2020 16:02:04 +0200 Subject: Renamed crandom.h to crand.h + Changed API. Renamed coptget.h to copt.h. --- examples/advanced.c | 4 +- examples/benchmark.c | 8 +-- examples/bits.c | 4 +- examples/demos.c | 6 +- examples/geek2.c | 2 +- examples/geek3.c | 2 +- examples/geek4.c | 4 +- examples/heap.c | 10 +-- examples/inits.c | 2 +- examples/list.c | 6 +- examples/prime.c | 2 +- examples/priority.c | 6 +- examples/rngbirthday.c | 11 ++-- examples/rngtest.c | 16 +++-- stc/cbitset.h | 64 +++++++++--------- stc/clist.h | 8 +-- stc/cmap.h | 2 +- stc/copt.h | 173 +++++++++++++++++++++++++++++++++++++++++++++++++ stc/coptget.h | 173 ------------------------------------------------- stc/crand.h | 138 +++++++++++++++++++++++++++++++++++++++ stc/crandom.h | 108 ------------------------------ stc/cstr.h | 130 ++++++++++++++++++------------------- stc/cvec.h | 2 +- stc/cvecpq.h | 6 +- 24 files changed, 460 insertions(+), 427 deletions(-) create mode 100644 stc/copt.h delete mode 100644 stc/coptget.h create mode 100644 stc/crand.h delete mode 100644 stc/crandom.h diff --git a/examples/advanced.c b/examples/advanced.c index bba534ca..68732544 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -34,8 +34,8 @@ int vikingvw_equals(const VikingVw* x, const VikingVw* y) { // Viking data struct ----------------------- typedef struct Viking { - cstr name; - cstr country; + cstr_t name; + cstr_t country; } Viking; diff --git a/examples/benchmark.c b/examples/benchmark.c index 568ba880..ea6c1794 100644 --- a/examples/benchmark.c +++ b/examples/benchmark.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include "others/khash.h" @@ -21,9 +21,9 @@ KHASH_MAP_INIT_INT64(ii, uint64_t) size_t seed; static const float max_load_factor = 0.77f; -crandom64_t rng; -#define SEED(s) rng = crandom64_uniform_engine(seed) -#define RAND(N) (crandom64_uniform_int(&rng) & ((1 << N) - 1)) +crand_eng64_t rng; +#define SEED(s) rng = crand_eng64(seed) +#define RAND(N) (crand_gen_i64(&rng) & ((1 << N) - 1)) #define CMAP_SETUP(tag, Key, Value) cmap_##tag map = cmap_init \ diff --git a/examples/bits.c b/examples/bits.c index fd074232..bf9125de 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -2,7 +2,7 @@ #include int main() { - cbitset set = cbitset_make(23, true); + cbitset_t set = cbitset_make(23, true); printf("count %zu, %zu\n", cbitset_count(set), set.size); cbitset_reset(&set, 9); cbitset_resize(&set, 43, false); @@ -21,7 +21,7 @@ int main() { printf("%d", cbitset_test(set, i)); puts(""); - cbitset s2 = cbitset_from(set); + cbitset_t s2 = cbitset_from(set); cbitset_flip_all(&s2); cbitset_set(&s2, 16); cbitset_set(&s2, 17); diff --git a/examples/demos.c b/examples/demos.c index 845f0cf0..3c7ac5f4 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -8,7 +8,7 @@ void stringdemo1() { printf("\nSTRINGDEMO1\n"); - cstr cs = cstr_make("one-nine-three-seven-five"); + cstr_t cs = cstr_make("one-nine-three-seven-five"); printf("%s.\n", cs.str); cstr_insert(&cs, 3, "-two"); @@ -54,7 +54,7 @@ void vectordemo1() -declare_cvec(cs, cstr, cstr_destroy, cstr_compare); // supply inline destructor of values +declare_cvec(cs, cstr_t, cstr_destroy, cstr_compare); // supply inline destructor of values void vectordemo2() { @@ -150,7 +150,7 @@ void mapdemo2() } -declare_cmap_str(ss, cstr, cstr_destroy); +declare_cmap_str(ss, cstr_t, cstr_destroy); void mapdemo3() { diff --git a/examples/geek2.c b/examples/geek2.c index c3a9ddfc..988f1f98 100644 --- a/examples/geek2.c +++ b/examples/geek2.c @@ -3,7 +3,7 @@ #include #include -declare_cmap_str(ss, cstr, cstr_destroy); +declare_cmap_str(ss, cstr_t, cstr_destroy); declare_cset_str(); int main() diff --git a/examples/geek3.c b/examples/geek3.c index 4c53a026..b8de97c8 100644 --- a/examples/geek3.c +++ b/examples/geek3.c @@ -4,7 +4,7 @@ #include declare_cmap_str(si, int); -declare_cmap_str(ss, cstr, cstr_destroy); +declare_cmap_str(ss, cstr_t, cstr_destroy); int main () { diff --git a/examples/geek4.c b/examples/geek4.c index dcf7edbf..c541e805 100644 --- a/examples/geek4.c +++ b/examples/geek4.c @@ -59,7 +59,7 @@ int commonWords(cvec_str S) // Extract all words of first string and store it in ans while (i < cstr_size(S.data[0])) { // To store separate words - cstr word = cstr_init; + cstr_t word = cstr_init; cmapentry_sb tmp = {cstr_init, false}; while (i < cstr_size(S.data[0]) && S.data[0].str[i] != ' ') { @@ -89,7 +89,7 @@ int commonWords(cvec_str S) i = 0; while (i < cstr_size(S.data[j])) { - cstr word = cstr_init; + cstr_t word = cstr_init; while (i < cstr_size(S.data[j]) && S.data[j].str[i] != ' ') { cstr_push_back(&word, S.data[j].str[i]); i++; diff --git a/examples/heap.c b/examples/heap.c index 857ff1fb..55aac409 100644 --- a/examples/heap.c +++ b/examples/heap.c @@ -1,7 +1,7 @@ #include #include #include "stc/cvecpq.h" -#include "stc/crandom.h" +#include "stc/crand.h" declare_cvec(f, float); declare_cvec_priority_queue(f, >); @@ -9,12 +9,12 @@ declare_cvec_priority_queue(f, >); int main() { uint32_t seed = time(NULL); - crandom32_t pcg = crandom32_uniform_engine(seed); + crand_eng32_t pcg = crand_eng32(seed); int N = 30000000, M = 100; cvec_f vec = cvec_init; clock_t start = clock(); for (int i=0; i #include -declare_cmap(id, int, cstr, cstr_destroy); // Map of int -> cstr +declare_cmap(id, int, cstr_t, cstr_destroy); // Map of int -> cstr_t declare_cmap_str(cnt, int); typedef struct {int x, y;} ipair_t; diff --git a/examples/list.c b/examples/list.c index 352965b2..2689d187 100644 --- a/examples/list.c +++ b/examples/list.c @@ -1,15 +1,15 @@ #include #include #include -#include +#include declare_clist(ix, uint64_t); int main() { clist_ix list = clist_init; - crandom32_t pcg = crandom32_uniform_engine(time(NULL)); + crand_eng32_t pcg = crand_eng32(time(NULL)); int n; for (int i=0; i<10000000; ++i) // ten million - clist_ix_push_back(&list, crandom32_uniform_int(&pcg)); + clist_ix_push_back(&list, crand_gen_i32(&pcg)); n = 100; c_foreach (i, clist_ix, list) if (n--) printf("%8d: %10zu\n", 100 - n, i.item->value); else break; diff --git a/examples/prime.c b/examples/prime.c index 463203d2..611690ac 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -10,7 +10,7 @@ static inline void sieveOfEratosthenes(size_t n) { - cbitset prime = cbitset_make(n + 1, true); + cbitset_t prime = cbitset_make(n + 1, true); printf("computing prime numbers up to %zu\n", n); cbitset_reset(&prime, 0); cbitset_reset(&prime, 1); diff --git a/examples/priority.c b/examples/priority.c index 1aee8f58..cf1c386c 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -3,18 +3,18 @@ #include #include #include -#include +#include declare_cvec(i, uint32_t); declare_cvec_priority_queue(i, >); // min-heap (increasing values) int main() { - crandom32_t pcg = crandom32_uniform_engine(time(NULL)); + crand_eng32_t pcg = crand_eng32(time(NULL)); cvec_i heap = cvec_init; // Push ten million random numbers to queue for (int i=0; i<10000000; ++i) - cvecpq_i_push(&heap, crandom32_uniform_int(&pcg)); + cvecpq_i_push(&heap, crand_gen_i32(&pcg)); // Extract the hundred smallest. for (int i=0; i<100; ++i) { diff --git a/examples/rngbirthday.c b/examples/rngbirthday.c index 69d510e6..43718fe8 100644 --- a/examples/rngbirthday.c +++ b/examples/rngbirthday.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -15,12 +15,12 @@ const static uint64_t mask = (1ull << 52) - 1; void repeats(void) { - crandom64_t rng = crandom64_uniform_engine(seed); + crand_eng64_t rng = crand_eng64(seed); cmap_ic m = cmap_init; cmap_ic_reserve(&m, N); clock_t now = clock(); for (size_t i = 0; i < N; ++i) { - uint64_t k = crandom64_uniform_int(&rng) & mask; + uint64_t k = crand_gen_i64(&rng) & mask; int v = ++cmap_ic_insert(&m, k, 0)->value; if (v > 1) printf("%zu: %x - %d\n", i, k, v); } @@ -34,12 +34,13 @@ declare_cvec(x, uint64_t); void distribution(void) { - crandom32_t rng = crandom32_uniform_engine(seed); // time(NULL), time(NULL)); + crand_eng32_t rng = crand_eng32(seed); // time(NULL), time(NULL)); const size_t N = 1ull << 28, M = 1ull << 9; // 1ull << 10; cmap_x map = cmap_x_make(M); clock_t now = clock(); + crand_i32_uniform_t dist = crand_i32_uniform(0, M); for (size_t i = 0; i < N; ++i) { - ++cmap_x_insert(&map, crandom32_uniform_int_bounded(&rng, M), 0)->value; + ++cmap_x_insert(&map, crand_gen_i32_uniform(&rng, dist), 0)->value; } float diff = (float) (clock() - now) / CLOCKS_PER_SEC; diff --git a/examples/rngtest.c b/examples/rngtest.c index 296cdc3a..d33daa3b 100644 --- a/examples/rngtest.c +++ b/examples/rngtest.c @@ -1,6 +1,6 @@ #include #include -#include +#include #ifdef __cplusplus #include #endif @@ -14,26 +14,28 @@ int main(void) uint64_t v; printf("start\n"); - crandom32_t pcg = crandom32_uniform_engine(time(NULL)); + crand_eng32_t pcg = crand_eng32(time(NULL)); before = clock(); \ v = 0; for (size_t i=0; i> 6) * 8), size}; +STC_INLINE cbitset_t cbitset_make(size_t size, bool value) { + cbitset_t set = {(uint64_t *) malloc(((size + 63) >> 6) * 8), size}; cbitset_set_all(&set, value); return set; } -STC_INLINE cbitset cbitset_from(cbitset other) { +STC_INLINE cbitset_t cbitset_from(cbitset_t other) { size_t n = (other.size + 63) >> 6; - cbitset set = {(uint64_t *) memcpy(malloc(n * 8), other._arr, n * 8), other.size}; + cbitset_t set = {(uint64_t *) memcpy(malloc(n * 8), other._arr, n * 8), other.size}; return set; } -STC_INLINE void cbitset_destroy(cbitset* self) { +STC_INLINE void cbitset_destroy(cbitset_t* self) { free(self->_arr); } -STC_INLINE size_t cbitset_size(cbitset set) {return set.size;} +STC_INLINE size_t cbitset_size(cbitset_t set) {return set.size;} -STC_INLINE void cbitset_set(cbitset *self, size_t i) { +STC_INLINE void cbitset_set(cbitset_t *self, size_t i) { self->_arr[i >> 6] |= 1ull << (i & 63); } -STC_INLINE void cbitset_reset(cbitset *self, size_t i) { +STC_INLINE void cbitset_reset(cbitset_t *self, size_t i) { self->_arr[i >> 6] &= ~(1ull << (i & 63)); } -STC_INLINE void cbitset_set_to(cbitset *self, size_t i, bool value) { +STC_INLINE void cbitset_set_to(cbitset_t *self, size_t i, bool value) { value ? cbitset_set(self, i) : cbitset_reset(self, i); } -STC_INLINE void cbitset_flip(cbitset *self, size_t i) { +STC_INLINE void cbitset_flip(cbitset_t *self, size_t i) { self->_arr[i >> 6] ^= 1ull << (i & 63); } -STC_INLINE bool cbitset_test(cbitset set, size_t i) { +STC_INLINE bool cbitset_test(cbitset_t set, size_t i) { return (set._arr[i >> 6] & (1ull << (i & 63))) != 0; } -STC_INLINE void cbitset_set_all(cbitset *self, bool value) { +STC_INLINE void cbitset_set_all(cbitset_t *self, bool value) { memset(self->_arr, value ? 0xff : 0x0, ((self->size + 63) >> 6) * 8); } -STC_INLINE void cbitset_set_all_64(cbitset *self, uint64_t pattern) { +STC_INLINE void cbitset_set_all_64(cbitset_t *self, uint64_t pattern) { size_t n = (self->size + 63) >> 6; for (size_t i=0; i_arr[i] = pattern; } -STC_INLINE void cbitset_flip_all(cbitset *self) { +STC_INLINE void cbitset_flip_all(cbitset_t *self) { size_t n = (self->size + 63) >> 6; for (size_t i=0; i_arr[i] ^= ~0ull; } /* Intersection */ -STC_INLINE void cbitset_set_and(cbitset *self, cbitset other) { +STC_INLINE void cbitset_set_and(cbitset_t *self, cbitset_t other) { assert(self->size == other.size); size_t n = (self->size + 63) >> 6; for (size_t i=0; i_arr[i] &= other._arr[i]; } /* Union */ -STC_INLINE void cbitset_set_or(cbitset *self, cbitset other) { +STC_INLINE void cbitset_set_or(cbitset_t *self, cbitset_t other) { assert(self->size == other.size); size_t n = (self->size + 63) >> 6; for (size_t i=0; i_arr[i] |= other._arr[i]; } /* Exclusive disjunction */ -STC_INLINE void cbitset_set_xor(cbitset *self, cbitset other) { +STC_INLINE void cbitset_set_xor(cbitset_t *self, cbitset_t other) { assert(self->size == other.size); size_t n = (self->size + 63) >> 6; for (size_t i=0; i_arr[i] ^= other._arr[i]; } -STC_INLINE cbitset cbitset_and(cbitset s1, cbitset s2) { - cbitset set = cbitset_from(s1); +STC_INLINE cbitset_t cbitset_and(cbitset_t s1, cbitset_t s2) { + cbitset_t set = cbitset_from(s1); cbitset_set_and(&set, s2); return set; } -STC_INLINE cbitset cbitset_or(cbitset s1, cbitset s2) { - cbitset set = cbitset_from(s1); +STC_INLINE cbitset_t cbitset_or(cbitset_t s1, cbitset_t s2) { + cbitset_t set = cbitset_from(s1); cbitset_set_or(&set, s2); return set; } -STC_INLINE cbitset cbitset_xor(cbitset s1, cbitset s2) { - cbitset set = cbitset_from(s1); +STC_INLINE cbitset_t cbitset_xor(cbitset_t s1, cbitset_t s2) { + cbitset_t set = cbitset_from(s1); cbitset_set_xor(&set, s2); return set; } -STC_INLINE cbitset cbitset_not(cbitset s1) { - cbitset set = cbitset_from(s1); +STC_INLINE cbitset_t cbitset_not(cbitset_t s1) { + cbitset_t set = cbitset_from(s1); cbitset_flip_all(&set); return set; } #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -STC_API void cbitset_resize(cbitset* self, size_t size, bool value) { +STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value) { size_t new_n = (size + 63) >> 6, osize = self->size, old_n = (osize + 63) >> 6; self->_arr = (uint64_t *) realloc(self->_arr, new_n * 8); self->size = size; @@ -158,7 +158,7 @@ STC_API void cbitset_resize(cbitset* self, size_t size, bool value) { } } -STC_API size_t cbitset_count(cbitset set) { +STC_API size_t cbitset_count(cbitset_t set) { size_t count = 0, n = (set.size + 63) >> 6; if (set.size > 0) { --n; for (size_t i=0; i #include - #include + #include declare_clist(ix, int64_t); int main() { clist_ix list = clist_init; - crandom32_t pcg = crandom32_uniform_engine(12345); + crand_eng32_t pcg = crand_eng32(12345); int n; for (int i=0; i<1000000; ++i) // one million - clist_ix_push_back(&list, crandom32_uniform_int(&pcg)); + clist_ix_push_back(&list, crand_gen_i32(&pcg)); n = 0; c_foreach (i, clist_ix, list) if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.item->value); @@ -65,7 +65,7 @@ #define declare_clist_4(tag, Value, valueDestroy, valueCompare) \ declare_clist_6(tag, Value, valueDestroy, Value, valueCompare, c_defaultGetRaw) #define declare_clist_str() \ - declare_clist_6(str, cstr, cstr_destroy, const char*, cstr_compareRaw, cstr_getRaw) + declare_clist_6(str, cstr_t, cstr_destroy, const char*, cstr_compareRaw, cstr_getRaw) #define declare_clist_types(tag, Value) \ typedef struct clistnode_##tag { \ diff --git a/stc/cmap.h b/stc/cmap.h index 017864cd..7a58506e 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -115,7 +115,7 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; declare_CHASH_STR(tag, cmap, Value, ValueDestroy) #define declare_CHASH_STR(tag, ctype, Value, valueDestroy) \ - declare_CHASH(tag, ctype, cstr, Value, valueDestroy, cstr_equalsRaw, cstr_hashRaw, \ + declare_CHASH(tag, ctype, cstr_t, Value, valueDestroy, cstr_equalsRaw, cstr_hashRaw, \ cstr_destroy, const char*, cstr_getRaw, cstr_make) #define OPT_1_cset(x) diff --git a/stc/copt.h b/stc/copt.h new file mode 100644 index 00000000..49c895e0 --- /dev/null +++ b/stc/copt.h @@ -0,0 +1,173 @@ +/* MIT License + * + * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef COPT__H__ +#define COPT__H__ + +/* Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c + Fixed major bugs with option arguments (both long and short). + Added arg->faulty output field, and has a more consistent API. + + copt_get() is similar to GNU's getopt_long(). Each call parses one option and + returns the option name. opt->arg points to the option argument if present. + The function returns -1 when all command-line arguments are parsed. In this case, + opt->ind is the index of the first non-option argument. +Example: + int main(int argc, char *argv[]) + { + copt_long_t longopts[] = { + {"foo", copt_no_argument, 'f'}, + {"bar", copt_required_argument, 'b'}, + {"opt", copt_optional_argument, 'o'}, + {NULL} + }; + const char* optstr = "xy:z::123"; + printf("program -x -y ARG -z [ARG] -1 -2 -3 --foo --bar ARG --opt [ARG] [ARGUMENTS]\n"); + int c; + copt_t opt = copt_init; + while ((c = copt_get(&opt, argc, argv, optstr, longopts)) != -1) { + switch (c) { + case '?': printf("error: unknown option: %s\n", opt.faulty); break; + case ':': printf("error: missing argument for %s\n", opt.faulty); break; + default: printf("option: %c [%s]\n", c, opt.arg ? opt.arg : ""); break; + } + } + printf("\nNon-option arguments:"); + for (int i = opt.ind; i < argc; ++i) + printf(" %s", argv[i]); + putchar('\n'); + return 0; + } +*/ + +#include +#include + +enum { + copt_no_argument = 0, + copt_required_argument = 1, + copt_optional_argument = 2 +}; +typedef struct { + int ind; /* equivalent to optind */ + int opt; /* equivalent to optopt */ + char *arg; /* equivalent to optarg */ + char *faulty; /* points to the faulty option */ + int longindex; /* idx of long option; or -1 if short */ + int _i, _pos, _nargs; + char _faulty[4]; +} copt_t; + +typedef struct { + char *name; + int has_arg; + int val; +} copt_long_t; + +static const copt_t copt_init = {1, 0, NULL, NULL, -1, 1, 0, 0, {'-', '?', '\0'}}; + +static void _copt_permute(char *argv[], int j, int n) { /* move argv[j] over n elements to the left */ + int k; + char *p = argv[j]; + for (k = 0; k < n; ++k) + argv[j - k] = argv[j - k - 1]; + argv[j - k] = p; +} + +/* @param opt output; must be initialized to copt_init on first call + * @return ASCII val for a short option; longopt.val for a long option; + * -1 if argv[] is fully processed; '?' for an unknown option or + * an ambiguous long option; ':' if an option argument is missing + */ +static int copt_get(copt_t *opt, int argc, char *argv[], + const char *shortopts, const copt_long_t *longopts) { + int optc = -1, i0, j, posixly_correct = (shortopts[0] == '+'); + if (!posixly_correct) { + while (opt->_i < argc && (argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0')) + ++opt->_i, ++opt->_nargs; + } + opt->arg = 0, opt->longindex = -1, i0 = opt->_i; + if (opt->_i >= argc || argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0') { + opt->ind = opt->_i - opt->_nargs; + return -1; + } + if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { /* "--" or a long option */ + if (argv[opt->_i][2] == '\0') { /* a bare "--" */ + _copt_permute(argv, opt->_i, opt->_nargs); + ++opt->_i, opt->ind = opt->_i - opt->_nargs; + return -1; + } + opt->opt = 0, optc = '?', opt->_pos = -1; + if (longopts) { /* parse long options */ + int k, n_exact = 0, n_partial = 0; + const copt_long_t *o = 0, *o_exact = 0, *o_partial = 0; + for (j = 2; argv[opt->_i][j] != '\0' && argv[opt->_i][j] != '='; ++j) {} /* find the end of the option name */ + for (k = 0; longopts[k].name != 0; ++k) + if (strncmp(&argv[opt->_i][2], longopts[k].name, j - 2) == 0) { + if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k]; + else ++n_partial, o_partial = &longopts[k]; + } + opt->faulty = argv[opt->_i]; + if (n_exact > 1 || (n_exact == 0 && n_partial > 1)) return '?'; + o = n_exact == 1? o_exact : n_partial == 1? o_partial : 0; + if (o) { + opt->opt = optc = o->val, opt->longindex = o - longopts; + if (o->has_arg != copt_no_argument) { + if (argv[opt->_i][j] == '=') + opt->arg = &argv[opt->_i][j + 1]; + else if (argv[opt->_i][j] == '\0' && opt->_i < argc - 1 && (o->has_arg == copt_required_argument || + argv[opt->_i + 1][0] != '-')) + opt->arg = argv[++opt->_i]; + else if (o->has_arg == copt_required_argument) + optc = ':'; /* missing option argument */ + } + } + } + } else { /* a short option */ + const char *p; + if (opt->_pos == 0) opt->_pos = 1; + optc = opt->opt = argv[opt->_i][opt->_pos++]; + opt->_faulty[1] = optc, opt->faulty = opt->_faulty; + p = strchr((char *) shortopts, optc); + if (p == 0) { + optc = '?'; /* unknown option */ + } else if (p[1] == ':') { + if (argv[opt->_i][opt->_pos] != '\0') + opt->arg = &argv[opt->_i][opt->_pos]; + else if (opt->_i < argc - 1 && (p[2] != ':' || argv[opt->_i + 1][0] != '-')) + opt->arg = argv[++opt->_i]; + else if (p[2] != ':') + optc = ':'; + opt->_pos = -1; + } + } + if (opt->_pos < 0 || argv[opt->_i][opt->_pos] == 0) { + ++opt->_i, opt->_pos = 0; + if (opt->_nargs > 0) /* permute */ + for (j = i0; j < opt->_i; ++j) + _copt_permute(argv, j, opt->_nargs); + } + opt->ind = opt->_i - opt->_nargs; + return optc; +} + +#endif diff --git a/stc/coptget.h b/stc/coptget.h deleted file mode 100644 index 49c895e0..00000000 --- a/stc/coptget.h +++ /dev/null @@ -1,173 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef COPT__H__ -#define COPT__H__ - -/* Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c - Fixed major bugs with option arguments (both long and short). - Added arg->faulty output field, and has a more consistent API. - - copt_get() is similar to GNU's getopt_long(). Each call parses one option and - returns the option name. opt->arg points to the option argument if present. - The function returns -1 when all command-line arguments are parsed. In this case, - opt->ind is the index of the first non-option argument. -Example: - int main(int argc, char *argv[]) - { - copt_long_t longopts[] = { - {"foo", copt_no_argument, 'f'}, - {"bar", copt_required_argument, 'b'}, - {"opt", copt_optional_argument, 'o'}, - {NULL} - }; - const char* optstr = "xy:z::123"; - printf("program -x -y ARG -z [ARG] -1 -2 -3 --foo --bar ARG --opt [ARG] [ARGUMENTS]\n"); - int c; - copt_t opt = copt_init; - while ((c = copt_get(&opt, argc, argv, optstr, longopts)) != -1) { - switch (c) { - case '?': printf("error: unknown option: %s\n", opt.faulty); break; - case ':': printf("error: missing argument for %s\n", opt.faulty); break; - default: printf("option: %c [%s]\n", c, opt.arg ? opt.arg : ""); break; - } - } - printf("\nNon-option arguments:"); - for (int i = opt.ind; i < argc; ++i) - printf(" %s", argv[i]); - putchar('\n'); - return 0; - } -*/ - -#include -#include - -enum { - copt_no_argument = 0, - copt_required_argument = 1, - copt_optional_argument = 2 -}; -typedef struct { - int ind; /* equivalent to optind */ - int opt; /* equivalent to optopt */ - char *arg; /* equivalent to optarg */ - char *faulty; /* points to the faulty option */ - int longindex; /* idx of long option; or -1 if short */ - int _i, _pos, _nargs; - char _faulty[4]; -} copt_t; - -typedef struct { - char *name; - int has_arg; - int val; -} copt_long_t; - -static const copt_t copt_init = {1, 0, NULL, NULL, -1, 1, 0, 0, {'-', '?', '\0'}}; - -static void _copt_permute(char *argv[], int j, int n) { /* move argv[j] over n elements to the left */ - int k; - char *p = argv[j]; - for (k = 0; k < n; ++k) - argv[j - k] = argv[j - k - 1]; - argv[j - k] = p; -} - -/* @param opt output; must be initialized to copt_init on first call - * @return ASCII val for a short option; longopt.val for a long option; - * -1 if argv[] is fully processed; '?' for an unknown option or - * an ambiguous long option; ':' if an option argument is missing - */ -static int copt_get(copt_t *opt, int argc, char *argv[], - const char *shortopts, const copt_long_t *longopts) { - int optc = -1, i0, j, posixly_correct = (shortopts[0] == '+'); - if (!posixly_correct) { - while (opt->_i < argc && (argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0')) - ++opt->_i, ++opt->_nargs; - } - opt->arg = 0, opt->longindex = -1, i0 = opt->_i; - if (opt->_i >= argc || argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0') { - opt->ind = opt->_i - opt->_nargs; - return -1; - } - if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { /* "--" or a long option */ - if (argv[opt->_i][2] == '\0') { /* a bare "--" */ - _copt_permute(argv, opt->_i, opt->_nargs); - ++opt->_i, opt->ind = opt->_i - opt->_nargs; - return -1; - } - opt->opt = 0, optc = '?', opt->_pos = -1; - if (longopts) { /* parse long options */ - int k, n_exact = 0, n_partial = 0; - const copt_long_t *o = 0, *o_exact = 0, *o_partial = 0; - for (j = 2; argv[opt->_i][j] != '\0' && argv[opt->_i][j] != '='; ++j) {} /* find the end of the option name */ - for (k = 0; longopts[k].name != 0; ++k) - if (strncmp(&argv[opt->_i][2], longopts[k].name, j - 2) == 0) { - if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k]; - else ++n_partial, o_partial = &longopts[k]; - } - opt->faulty = argv[opt->_i]; - if (n_exact > 1 || (n_exact == 0 && n_partial > 1)) return '?'; - o = n_exact == 1? o_exact : n_partial == 1? o_partial : 0; - if (o) { - opt->opt = optc = o->val, opt->longindex = o - longopts; - if (o->has_arg != copt_no_argument) { - if (argv[opt->_i][j] == '=') - opt->arg = &argv[opt->_i][j + 1]; - else if (argv[opt->_i][j] == '\0' && opt->_i < argc - 1 && (o->has_arg == copt_required_argument || - argv[opt->_i + 1][0] != '-')) - opt->arg = argv[++opt->_i]; - else if (o->has_arg == copt_required_argument) - optc = ':'; /* missing option argument */ - } - } - } - } else { /* a short option */ - const char *p; - if (opt->_pos == 0) opt->_pos = 1; - optc = opt->opt = argv[opt->_i][opt->_pos++]; - opt->_faulty[1] = optc, opt->faulty = opt->_faulty; - p = strchr((char *) shortopts, optc); - if (p == 0) { - optc = '?'; /* unknown option */ - } else if (p[1] == ':') { - if (argv[opt->_i][opt->_pos] != '\0') - opt->arg = &argv[opt->_i][opt->_pos]; - else if (opt->_i < argc - 1 && (p[2] != ':' || argv[opt->_i + 1][0] != '-')) - opt->arg = argv[++opt->_i]; - else if (p[2] != ':') - optc = ':'; - opt->_pos = -1; - } - } - if (opt->_pos < 0 || argv[opt->_i][opt->_pos] == 0) { - ++opt->_i, opt->_pos = 0; - if (opt->_nargs > 0) /* permute */ - for (j = i0; j < opt->_i; ++j) - _copt_permute(argv, j, opt->_nargs); - } - opt->ind = opt->_i - opt->_nargs; - return optc; -} - -#endif diff --git a/stc/crand.h b/stc/crand.h new file mode 100644 index 00000000..7c3c9b44 --- /dev/null +++ b/stc/crand.h @@ -0,0 +1,138 @@ +/* MIT License + * + * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CRAND__H__ +#define CRAND__H__ + +#include "cdefs.h" +#include +/* + crand_eng32_t eng = crand_eng32(seed); + crand_f32_uniform_t fdist = crand_f32_uniform(1.0f, 6.0f); + crand_i32_uniform_t idist = crand_i32_uniform(1, 6); + + uint32_t i = crand_gen_i32(&eng); + int j = crand_gen_i32_uniform(&eng, idist); + float r = crand_gen_f32_uniform(&eng, fdist); +*/ + +typedef struct {uint64_t state, inc;} crand_eng32_t; +typedef struct {int32_t min; uint32_t range;} crand_i32_uniform_t; +typedef struct {float min, range;} crand_f32_uniform_t; + +/* 32 bit random number generator engine */ +STC_API crand_eng32_t crand_eng32_with_id(uint64_t seed, uint64_t seq); + +STC_INLINE crand_eng32_t crand_eng32(uint64_t seed) { + return crand_eng32_with_id(seed, 0); +} + +/* int random number generator, range [0, 2^32) */ +STC_API uint32_t crand_gen_i32(crand_eng32_t* rng); + +STC_INLINE float crand_gen_f32(crand_eng32_t* rng) { + union {uint32_t i; float f;} u = {0x3F800000u | (crand_gen_i32(rng) >> 9)}; + return u.f - 1.0f; +} + +/* int random number generator in range [low, high] */ +STC_INLINE crand_i32_uniform_t crand_i32_uniform(int32_t low, int32_t high) { + crand_i32_uniform_t dist = {low, high - low}; return dist; +} +STC_INLINE uint32_t crand_gen_i32_uniform(crand_eng32_t* rng, crand_i32_uniform_t dist) { + return dist.min + (int32_t) (((uint64_t) crand_gen_i32(rng) * dist.range) >> 32); +} + +/* float random number in range [low, high). Note: 23 bit resolution. */ +STC_INLINE crand_f32_uniform_t crand_f32_uniform(float low, float high) { + crand_f32_uniform_t dist = {low, high - low}; return dist; +} +STC_INLINE float crand_gen_f32_uniform(crand_eng32_t* rng, crand_f32_uniform_t dist) { + return dist.min + crand_gen_f32(rng) * dist.range; +} + + +typedef struct {uint64_t state[4];} crand_eng64_t; +typedef struct {double min, range;} crand_f64_uniform_t; + +/* 64 bit random number generator engine */ +STC_API crand_eng64_t crand_eng64(const uint64_t seed); + +/* int random number generator, range [0, 2^64) */ +STC_API uint64_t crand_gen_i64(crand_eng64_t* rng); + +STC_INLINE double crand_gen_f64(crand_eng64_t* rng) { + union {uint64_t i; double f;} u = {0x3FF0000000000000ull | (crand_gen_i64(rng) >> 12)}; + return u.f - 1.0; +} + +/* double random number in range [low, high). 52 bit resolution. */ +STC_INLINE crand_f64_uniform_t crand_f64_uniform(float low, float high) { + crand_f64_uniform_t dist = {low, high - low}; return dist; +} +STC_INLINE double crand_gen_f64_uniform(crand_eng64_t* rng, crand_f64_uniform_t dist) { + return dist.min + crand_gen_f64(rng) * dist.range; +} + + +#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) + +/* PCG32 random number generator: https://www.pcg-random.org/index.html */ + +STC_API crand_eng32_t crand_eng32_with_id(uint64_t seed, uint64_t seq) { + crand_eng32_t rng = {0u, (seq << 1u) | 1u}; /* inc must be odd */ + crand_gen_i32(&rng); + rng.state += seed; + crand_gen_i32(&rng); + return rng; +} + +STC_API uint32_t crand_gen_i32(crand_eng32_t* rng) { + uint64_t old = rng->state; + rng->state = old * 6364136223846793005ull + rng->inc; + uint32_t xos = ((old >> 18u) ^ old) >> 27u; + uint32_t rot = old >> 59u; + return (xos >> rot) | (xos << ((-rot) & 31)); +} + +/* SFC64 random number generator: http://pracrand.sourceforge.net */ + +STC_API crand_eng64_t crand_eng64(const uint64_t seed) { + crand_eng64_t state = {{seed, seed, seed, 1}}; + for (int i = 0; i < 12; ++i) crand_gen_i64(&state); + return state; +} + +STC_API uint64_t crand_gen_i64(crand_eng64_t* rng) { + enum {LR=24, RS=11, LS=3}; + uint64_t *s = rng->state; + const uint64_t result = s[0] + s[1] + s[3]++; + s[0] = s[1] ^ (s[1] >> RS); + s[1] = s[2] + (s[2] << LS); + s[2] = (s[2] << LR) | (s[2] >> (64 - LR)); + return result; +} + +#endif + +#endif diff --git a/stc/crandom.h b/stc/crandom.h deleted file mode 100644 index f37f89dc..00000000 --- a/stc/crandom.h +++ /dev/null @@ -1,108 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef CRANDOM__H__ -#define CRANDOM__H__ - -#include "cdefs.h" -#include - -typedef struct {uint64_t state, inc;} crandom32_t; - -/* 32 bit random number generator engine */ -STC_API crandom32_t crandom32_uniform_engine2(uint64_t seed, uint64_t seq); - -STC_INLINE crandom32_t crandom32_uniform_engine(uint64_t seed) { - return crandom32_uniform_engine2(seed, 0); -} -/* int random number generator, range [0, 2^32) */ -STC_API uint32_t crandom32_uniform_int(crandom32_t* rng); - -/* float random number in range [0.0f, 1.0f). Note: 23 bit resolution. */ -STC_INLINE float crandom32_uniform_real(crandom32_t* rng) { - union {uint32_t i; float f;} u = {0x3F800000u | (crandom32_uniform_int(rng) >> 9)}; - return u.f - 1.0f; -} - -/* int random number generator in range [0, bound) */ -STC_INLINE uint32_t crandom32_uniform_int_bounded(crandom32_t* rng, uint32_t bound) { - return (uint32_t) (((uint64_t) crandom32_uniform_int(rng) * bound) >> 32); -} - - -typedef struct {uint64_t state[4];} crandom64_t; - -/* 64 bit random number generator engine */ -STC_API crandom64_t crandom64_uniform_engine(const uint64_t seed); - -/* int random number generator, range [0, 2^64) */ -STC_API uint64_t crandom64_uniform_int(crandom64_t* rng); - -/* float64 random number in range [0.0, 1.0), 52 bit resolution */ -STC_INLINE double crandom64_uniform_real(crandom64_t* rng) { - union {uint64_t i; double f;} u = {0x3FF0000000000000ull | (crandom64_uniform_int(rng) >> 12)}; - return u.f - 1.0; -} - - -#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) - -/* PCG32 random number generator: https://www.pcg-random.org/index.html */ - -STC_API crandom32_t crandom32_uniform_engine2(uint64_t seed, uint64_t seq) { - crandom32_t rng = {0u, (seq << 1u) | 1u}; /* inc must be odd */ - crandom32_uniform_int(&rng); - rng.state += seed; - crandom32_uniform_int(&rng); - return rng; -} - -STC_API uint32_t crandom32_uniform_int(crandom32_t* rng) { - uint64_t old = rng->state; - rng->state = old * 6364136223846793005ull + rng->inc; - uint32_t xos = ((old >> 18u) ^ old) >> 27u; - uint32_t rot = old >> 59u; - return (xos >> rot) | (xos << ((-rot) & 31)); -} - -/* SFC64 random number generator: http://pracrand.sourceforge.net */ - -STC_API crandom64_t crandom64_uniform_engine(const uint64_t seed) { - crandom64_t state = {{seed, seed, seed, 1}}; - for (int i = 0; i < 12; ++i) crandom64_uniform_int(&state); - return state; -} - -STC_API uint64_t crandom64_uniform_int(crandom64_t* rng) { - enum {LR=24, RS=11, LS=3}; - uint64_t *s = rng->state; - const uint64_t result = s[0] + s[1] + s[3]++; - s[0] = s[1] ^ (s[1] >> RS); - s[1] = s[2] + (s[2] << LS); - s[2] = (s[2] << LR) | (s[2] >> (64 - LR)); - return result; -} - -#endif - -#endif diff --git a/stc/cstr.h b/stc/cstr.h index 3d2584e2..35049094 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -31,154 +31,154 @@ #include "cdefs.h" -typedef struct cstr { +typedef struct cstr_t { char* str; -} cstr; +} cstr_t; #define _cstr_rep(self) (((size_t *) (self)->str) - 2) #define _cstr_size(s) ((size_t *) (s).str)[-2] #define _cstr_mem(cap) (sizeof(size_t) * (3 + (cap)/sizeof(size_t))) static size_t _cstr_nullrep[] = {0, 0, 0}; -static cstr cstr_init = {(char* ) &_cstr_nullrep[2]}; +static cstr_t cstr_init = {(char* ) &_cstr_nullrep[2]}; #define cstr_size(s) ((const size_t *) (s).str)[-2] #define cstr_capacity(s) ((const size_t *) (s).str)[-1] #define cstr_npos ((size_t) (-1)) -STC_API cstr +STC_API cstr_t cstr_make_n(const char* str, size_t len); -STC_API cstr +STC_API cstr_t cstr_from(const char* fmt, ...); STC_API void -cstr_reserve(cstr* self, size_t cap); +cstr_reserve(cstr_t* self, size_t cap); STC_API void -cstr_resize(cstr* self, size_t len, char fill); -STC_API cstr +cstr_resize(cstr_t* self, size_t len, char fill); +STC_API cstr_t cstr_make_reserved(size_t cap); -STC_API cstr* -cstr_assign_n(cstr* self, const char* str, size_t len); -STC_API cstr* -cstr_append_n(cstr* self, const char* str, size_t len); +STC_API cstr_t* +cstr_assign_n(cstr_t* self, const char* str, size_t len); +STC_API cstr_t* +cstr_append_n(cstr_t* self, const char* str, size_t len); STC_API void -cstr_insert_n(cstr* self, size_t pos, const char* str, size_t n); +cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n); STC_API size_t -cstr_replace_n(cstr* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2); +cstr_replace_n(cstr_t* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2); STC_API void -cstr_erase(cstr* self, size_t pos, size_t n); +cstr_erase(cstr_t* self, size_t pos, size_t n); STC_API char* -cstr_strnstr(cstr s, size_t pos, const char* needle, size_t n); +cstr_strnstr(cstr_t s, size_t pos, const char* needle, size_t n); STC_INLINE void -cstr_destroy(cstr* self) { +cstr_destroy(cstr_t* self) { if (cstr_capacity(*self)) { free(_cstr_rep(self)); } } -STC_INLINE cstr +STC_INLINE cstr_t cstr_make_filled(size_t len, char fill) { - cstr s = cstr_init; + cstr_t s = cstr_init; if (len) cstr_resize(&s, len, fill); return s; } -STC_INLINE cstr +STC_INLINE cstr_t cstr_make(const char* str) { return cstr_make_n(str, strlen(str)); } -STC_INLINE cstr -cstr_make_copy(cstr s) { +STC_INLINE cstr_t +cstr_make_copy(cstr_t s) { return cstr_make_n(s.str, cstr_size(s)); } STC_INLINE void -cstr_clear(cstr* self) { +cstr_clear(cstr_t* self) { cstr_destroy(self); *self = cstr_init; } -STC_INLINE cstr* -cstr_assign(cstr* self, const char* str) { +STC_INLINE cstr_t* +cstr_assign(cstr_t* self, const char* str) { return cstr_assign_n(self, str, strlen(str)); } -STC_INLINE cstr* -cstr_copy(cstr* self, cstr s) { +STC_INLINE cstr_t* +cstr_copy(cstr_t* self, cstr_t s) { return cstr_assign_n(self, s.str, cstr_size(s)); } -STC_INLINE cstr* -cstr_take(cstr* self, cstr s) { +STC_INLINE cstr_t* +cstr_take(cstr_t* self, cstr_t s) { if (self->str != s.str && cstr_capacity(*self)) free(_cstr_rep(self)); self->str = s.str; return self; } -STC_INLINE cstr -cstr_move(cstr* self) { - cstr tmp = *self; +STC_INLINE cstr_t +cstr_move(cstr_t* self) { + cstr_t tmp = *self; *self = cstr_init; return tmp; } -STC_INLINE cstr* -cstr_append(cstr* self, const char* str) { +STC_INLINE cstr_t* +cstr_append(cstr_t* self, const char* str) { return cstr_append_n(self, str, strlen(str)); } -STC_INLINE cstr* -cstr_appendS(cstr* self, cstr s) { +STC_INLINE cstr_t* +cstr_appendS(cstr_t* self, cstr_t s) { return cstr_append_n(self, s.str, cstr_size(s)); } -STC_INLINE cstr* -cstr_push_back(cstr* self, char value) { +STC_INLINE cstr_t* +cstr_push_back(cstr_t* self, char value) { return cstr_append_n(self, &value, 1); } STC_INLINE void -cstr_pop_back(cstr* self) { +cstr_pop_back(cstr_t* self) { --_cstr_size(*self); } STC_INLINE char -cstr_back(cstr s) { +cstr_back(cstr_t s) { return s.str[cstr_size(s) - 1]; } STC_INLINE void -cstr_insert(cstr* self, size_t pos, const char* str) { +cstr_insert(cstr_t* self, size_t pos, const char* str) { cstr_insert_n(self, pos, str, strlen(str)); } STC_INLINE size_t -cstr_replace(cstr* self, size_t pos, const char* str1, const char* str2) { +cstr_replace(cstr_t* self, size_t pos, const char* str1, const char* str2) { return cstr_replace_n(self, pos, str1, strlen(str1), str2, strlen(str2)); } /* readonly */ STC_INLINE bool -cstr_empty(cstr s) { +cstr_empty(cstr_t s) { return cstr_size(s) == 0; } STC_INLINE bool -cstr_equals(cstr s1, const char* str) { +cstr_equals(cstr_t s1, const char* str) { return strcmp(s1.str, str) == 0; } STC_INLINE bool -cstr_equalsS(cstr s1, cstr s2) { +cstr_equalsS(cstr_t s1, cstr_t s2) { return strcmp(s1.str, s2.str) == 0; } STC_INLINE int cstr_compare(const void* s1, const void* s2) { - return strcmp(((const cstr*)s1)->str, ((const cstr*)s2)->str); + return strcmp(((const cstr_t*)s1)->str, ((const cstr_t*)s2)->str); } STC_INLINE size_t -cstr_findN(cstr s, size_t pos, const char* needle, size_t n) { +cstr_findN(cstr_t s, size_t pos, const char* needle, size_t n) { char* res = cstr_strnstr(s, pos, needle, n); return res ? res - s.str : cstr_npos; } STC_INLINE size_t -cstr_find(cstr s, size_t pos, const char* needle) { +cstr_find(cstr_t s, size_t pos, const char* needle) { char* res = strstr(s.str + pos, needle); return res ? res - s.str : cstr_npos; } @@ -200,7 +200,7 @@ STC_INLINE uint32_t cstr_hashRaw(const char* const* sPtr, size_t ignored) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) STC_API void -cstr_reserve(cstr* self, size_t cap) { +cstr_reserve(cstr_t* self, size_t cap) { size_t len = cstr_size(*self), oldcap = cstr_capacity(*self); if (cap > oldcap) { size_t* rep = (size_t *) realloc(oldcap ? _cstr_rep(self) : NULL, _cstr_mem(cap)); @@ -211,35 +211,35 @@ cstr_reserve(cstr* self, size_t cap) { } STC_API void -cstr_resize(cstr* self, size_t len, char fill) { +cstr_resize(cstr_t* self, size_t len, char fill) { size_t n = cstr_size(*self); cstr_reserve(self, len); if (len > n) memset(self->str + n, fill, len - n); self->str[_cstr_size(*self) = len] = '\0'; } -STC_API cstr +STC_API cstr_t cstr_make_reserved(size_t cap) { if (cap == 0) return cstr_init; size_t *rep = (size_t *) malloc(_cstr_mem(cap)); - cstr s = {(char *) (rep + 2)}; + cstr_t s = {(char *) (rep + 2)}; rep[0] = 0, rep[1] = cap, s.str[0] = '\0'; return s; } -STC_API cstr +STC_API cstr_t cstr_make_n(const char* str, size_t len) { if (len == 0) return cstr_init; size_t *rep = (size_t *) malloc(_cstr_mem(len)); - cstr s = {(char *) (rep + 2)}; + cstr_t s = {(char *) (rep + 2)}; memcpy(s.str, str, len); s.str[rep[0] = rep[1] = len] = '\0'; return s; } -STC_API cstr +STC_API cstr_t cstr_from(const char* fmt, ...) { - cstr tmp = cstr_init; + cstr_t tmp = cstr_init; va_list args; va_start(args, fmt); int len = vsnprintf(NULL, (size_t)0, fmt, args); @@ -252,8 +252,8 @@ cstr_from(const char* fmt, ...) { return tmp; } -STC_API cstr* -cstr_assign_n(cstr* self, const char* str, size_t len) { +STC_API cstr_t* +cstr_assign_n(cstr_t* self, const char* str, size_t len) { if (len || cstr_capacity(*self)) { cstr_reserve(self, len); memmove(self->str, str, len); @@ -262,8 +262,8 @@ cstr_assign_n(cstr* self, const char* str, size_t len) { return self; } -STC_API cstr* -cstr_append_n(cstr* self, const char* str, size_t len) { +STC_API cstr_t* +cstr_append_n(cstr_t* self, const char* str, size_t len) { if (len) { size_t oldlen = cstr_size(*self), newlen = oldlen + len; if (newlen > cstr_capacity(*self)) @@ -274,7 +274,7 @@ cstr_append_n(cstr* self, const char* str, size_t len) { return self; } -STC_INLINE void _cstr_internalMove(cstr* self, size_t pos1, size_t pos2) { +STC_INLINE void _cstr_internalMove(cstr_t* self, size_t pos1, size_t pos2) { if (pos1 == pos2) return; size_t len = cstr_size(*self), newlen = len + pos2 - pos1; @@ -285,7 +285,7 @@ STC_INLINE void _cstr_internalMove(cstr* self, size_t pos1, size_t pos2) { } STC_API void -cstr_insert_n(cstr* self, size_t pos, const char* str, size_t n) { +cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n) { char* xstr = (char *) memcpy(n > c_max_alloca ? malloc(n) : alloca(n), str, n); _cstr_internalMove(self, pos, pos + n); memcpy(&self->str[pos], xstr, n); @@ -293,7 +293,7 @@ cstr_insert_n(cstr* self, size_t pos, const char* str, size_t n) { } STC_API size_t -cstr_replace_n(cstr* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2) { +cstr_replace_n(cstr_t* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2) { size_t pos2 = cstr_findN(*self, pos, str1, n1); if (pos2 == cstr_npos) return cstr_npos; char* xstr2 = (char *) memcpy(n2 > c_max_alloca ? malloc(n2) : alloca(n2), str2, n2); @@ -304,7 +304,7 @@ cstr_replace_n(cstr* self, size_t pos, const char* str1, size_t n1, const char* } STC_API void -cstr_erase(cstr* self, size_t pos, size_t n) { +cstr_erase(cstr_t* self, size_t pos, size_t n) { size_t len = cstr_size(*self); if (len) { memmove(&self->str[pos], &self->str[pos + n], len - (pos + n)); @@ -313,7 +313,7 @@ cstr_erase(cstr* self, size_t pos, size_t n) { } STC_API char* -cstr_strnstr(cstr s, size_t pos, const char* needle, size_t n) { +cstr_strnstr(cstr_t s, size_t pos, const char* needle, size_t n) { char *x = s.str + pos, /* haystack */ *z = s.str + cstr_size(s) - n + 1; if (x >= z) diff --git a/stc/cvec.h b/stc/cvec.h index ad8751e8..d76c001b 100644 --- a/stc/cvec.h +++ b/stc/cvec.h @@ -42,7 +42,7 @@ #define declare_cvec_4(tag, Value, valueDestroy, valueCompare) \ declare_cvec_6(tag, Value, valueDestroy, valueCompare, Value, c_defaultGetRaw) #define declare_cvec_str() \ - declare_cvec_6(str, cstr, cstr_destroy, cstr_compareRaw, const char*, cstr_getRaw) + declare_cvec_6(str, cstr_t, cstr_destroy, cstr_compareRaw, const char*, cstr_getRaw) #define declare_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \ diff --git a/stc/cvecpq.h b/stc/cvecpq.h index a8806927..ba81f51b 100644 --- a/stc/cvecpq.h +++ b/stc/cvecpq.h @@ -24,15 +24,15 @@ /* Priority Queue using CVec as heap. #include - #include + #include declare_cvec(i, int); declare_cvec_priority_queue(i, >); // min-heap (increasing values) int main() { - crandom32_t pcg = crandom32_uniform_engine(1234); + crand_eng32_t pcg = crand_eng32(1234); cvec_i heap = cvec_init; // Push one million random numbers onto the queue. for (int i=0; i<1000000; ++i) - cvecpq_i_push(&heap, crandom32_uniform_int(&pcg)); + cvecpq_i_push(&heap, crand_gen_i32(&pcg)); // Extract the 100 smallest. for (int i=0; i<100; ++i) { printf("%d ", cvecpq_i_top(&heap)); -- cgit v1.2.3