From d37056f1ef380a5649e192436e84a15d1520c5e0 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 3 Jan 2022 23:04:52 +0100 Subject: "gcc/clang -O2 -Wall -std=c99 -pedantic" compiles examples with no warnings. More cleanups. --- examples/complex.c | 2 +- examples/csset_erase.c | 3 +- examples/list.c | 2 +- examples/phonebook.c | 7 +--- examples/replace.c | 1 - examples/runall.sh | 2 +- include/stc/cbits.h | 2 +- include/stc/ccommon.h | 15 +++++-- include/stc/clist.h | 2 +- include/stc/crandom.h | 2 +- include/stc/csmap.h | 108 ++++++++++++++++++++++++++----------------------- include/stc/cstr.h | 17 ++------ include/stc/csview.h | 24 +++++++---- include/stc/cvec.h | 28 ++++++------- 14 files changed, 112 insertions(+), 103 deletions(-) diff --git a/examples/complex.c b/examples/complex.c index 747cec07..b0cd7a01 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -30,7 +30,7 @@ void check_drop(float* v) {printf("destroy %g\n", *v);} int main() { int xdim = 4, ydim = 6; - int x = 1, y = 3, tableKey = 42; + int x = 1, tableKey = 42; const char* strKey = "first"; c_auto (MapMap, mmap) diff --git a/examples/csset_erase.c b/examples/csset_erase.c index 485e78de..fe9977a9 100644 --- a/examples/csset_erase.c +++ b/examples/csset_erase.c @@ -19,7 +19,8 @@ int main() it = csset_int_lower_bound(&set, val); c_foreach (k, csset_int, it, csset_int_end(&set)) - printf(" %d", *k.ref); puts(""); + printf(" %d", *k.ref); + puts(""); printf("Erase values >= %d:\n", val); while (it.ref != csset_int_end(&set).ref) diff --git a/examples/list.c b/examples/list.c index 4d177b3b..cbf282a5 100644 --- a/examples/list.c +++ b/examples/list.c @@ -40,7 +40,7 @@ int main() { c_foreach (i, clist_fx, list) printf(" %g", *i.ref); puts(""); - int removed = clist_fx_remove(&list, 30); + clist_fx_remove(&list, 30); clist_fx_insert(&list, clist_fx_begin(&list), 5); // same as push_front() clist_fx_push_back(&list, 500); clist_fx_push_front(&list, 1964); diff --git a/examples/phonebook.c b/examples/phonebook.c index eeb1d3b8..fff84bec 100644 --- a/examples/phonebook.c +++ b/examples/phonebook.c @@ -39,8 +39,6 @@ void print_phone_book(cmap_str phone_book) int main(int argc, char **argv) { - c_static_assert(sizeof argc == 4); - c_auto (cset_str, names) { c_apply(v, cset_str_emplace(&names, v), const char*, {"Hello", "Cool", "True"}); @@ -48,7 +46,6 @@ int main(int argc, char **argv) puts(""); } - bool erased; c_auto (cmap_str, phone_book) { c_apply(v, cmap_str_emplace(&phone_book, c_pair(v)), cmap_str_raw, { {"Lilia Friedman", "(892) 670-4739"}, @@ -69,8 +66,8 @@ int main(int argc, char **argv) if (cmap_str_contains(&phone_book, "Tariq Beltran")) printf("\nTariq Beltran is in phone book\n"); - erased = cmap_str_erase(&phone_book, "Tariq Beltran"); - erased = cmap_str_erase(&phone_book, "Elliott Mooney"); + cmap_str_erase(&phone_book, "Tariq Beltran"); + cmap_str_erase(&phone_book, "Elliott Mooney"); printf("\nPhone book after erasing Tariq and Elliott:\n"); print_phone_book(phone_book); diff --git a/examples/replace.c b/examples/replace.c index 0349d9f4..bc28cb2a 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -6,7 +6,6 @@ int main () const char *base = "this is a test string."; const char *s2 = "n example"; const char *s3 = "sample phrase"; - const char *s4 = "useful."; // replace signatures used in the same order as described above: diff --git a/examples/runall.sh b/examples/runall.sh index e95068ff..3c6e3ec9 100644 --- a/examples/runall.sh +++ b/examples/runall.sh @@ -1,5 +1,5 @@ #!/bin/bash -cc='gcc -std=c99 -pedantic' +cc='clang -O2 -Wall -std=c99 -pedantic' #cc='clang' #cc='clang -c -DSTC_HEADER' #cc='cl -nologo' diff --git a/include/stc/cbits.h b/include/stc/cbits.h index f99867e9..18d8e70c 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -241,4 +241,4 @@ STC_DEF bool cbits_disjoint(cbits s, cbits other) { _cbits_SETOP(&, 0); } #endif #endif -#undef i_opt \ No newline at end of file +#undef i_opt diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 1c351c05..cba1fc70 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #if defined(_MSC_VER) @@ -127,15 +128,21 @@ STC_INLINE uint64_t c_default_hash(const void* key, size_t len) { while (--len) h = (h << 10) - h + *x++; return _c_ROTL(h, 26) ^ h; } -#define c_hash32(data, len_is_4) \ - ((*(const uint32_t*)data * 0xc6a4a7935bd1e99d) >> 15) -#define c_hash64(data, len_is_8) \ - (*(const uint64_t *)data * 0xc6a4a7935bd1e99d) +STC_INLINE uint64_t c_hash32(const void* key, size_t len) { + uint32_t x; memcpy(&x, key, 4); + return x*0xc6a4a7935bd1e99d >> 15; +} +STC_INLINE uint64_t c_hash64(const void* key, size_t len) { + uint64_t x; memcpy(&x, key, 8); + return x*0xc6a4a7935bd1e99d; +} #define c_foreach(...) c_MACRO_OVERLOAD(c_foreach, __VA_ARGS__) + #define c_foreach_3(it, C, cnt) \ for (C##_iter it = C##_begin(&cnt), it##_end_ = C##_end(&cnt) \ ; it.ref != it##_end_.ref; C##_next(&it)) + #define c_foreach_4(it, C, start, finish) \ for (C##_iter it = start, it##_end_ = finish \ ; it.ref != it##_end_.ref; C##_next(&it)) diff --git a/include/stc/clist.h b/include/stc/clist.h index d53c35c8..442e5a30 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -100,10 +100,10 @@ STC_API _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx STC_API size_t _cx_memb(_remove)(_cx_self* self, i_valraw val); STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val); STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y); +STC_API void _cx_memb(_sort)(_cx_self* self); #endif STC_API _cx_iter _cx_memb(_splice)(_cx_self* self, _cx_iter it, _cx_self* other); STC_API _cx_self _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_iter it2); -STC_API void _cx_memb(_sort)(_cx_self* self); STC_API _cx_node* _cx_memb(_erase_after_)(_cx_self* self, _cx_node* node); #if !c_option(c_no_clone) diff --git a/include/stc/crandom.h b/include/stc/crandom.h index 887e5f51..5e4c4ad3 100644 --- a/include/stc/crandom.h +++ b/include/stc/crandom.h @@ -220,4 +220,4 @@ STC_DEF double stc64_normalf(stc64_t* rng, stc64_normalf_t* dist) { } #endif #endif -#undef i_opt \ No newline at end of file +#undef i_opt diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 1a2134ad..316fd0db 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -57,6 +57,7 @@ int main(void) { struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; #define _csmap_rep(self) c_container_of((self)->nodes, struct csmap_rep, nodes) +static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0}; #endif // CSMAP_H_INCLUDED #ifndef _i_prefix @@ -93,10 +94,15 @@ typedef _i_SET_ONLY( i_keyraw ) _i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } ) _cx_raw; -STC_API _cx_self _cx_memb(_init)(void); #if !c_option(c_no_clone) STC_API _cx_self _cx_memb(_clone)(_cx_self tree); +STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); +STC_API _cx_value _cx_memb(_value_clone)(_cx_value _val); +#endif +#if !defined _i_no_raw +STC_API _cx_result _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)); #endif +STC_API _cx_result _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)); STC_API void _cx_memb(_drop)(_cx_self* self); STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap); STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out); @@ -112,7 +118,7 @@ STC_API void _cx_memb(_next)(_cx_iter* it); STC_INLINE bool _cx_memb(_empty)(_cx_self tree) { return _csmap_rep(&tree)->size == 0; } STC_INLINE size_t _cx_memb(_size)(_cx_self tree) { return _csmap_rep(&tree)->size; } STC_INLINE size_t _cx_memb(_capacity)(_cx_self tree) { return _csmap_rep(&tree)->cap; } -STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } + STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); } STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; } @@ -121,6 +127,12 @@ STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, i_keyraw rkey) STC_INLINE _cx_value* _cx_memb(_get_mut)(_cx_self* self, i_keyraw rkey) { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } +STC_INLINE _cx_self +_cx_memb(_init)(void) { + _cx_self tree = {(_cx_node *)_csmap_sentinel.nodes}; + return tree; +} + STC_INLINE _cx_self _cx_memb(_with_capacity)(const size_t cap) { _cx_self tree = _cx_memb(_init)(); @@ -128,6 +140,10 @@ _cx_memb(_with_capacity)(const size_t cap) { return tree; } +STC_INLINE void +_cx_memb(_clear)(_cx_self* self) + { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } + STC_INLINE _cx_raw _cx_memb(_value_toraw)(_cx_value* val) { return _i_SET_ONLY( i_keyto(val) ) @@ -168,40 +184,6 @@ _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) { return it; } -#if !c_option(c_no_clone) -STC_INLINE void -_cx_memb(_copy)(_cx_self *self, _cx_self other) { - if (self->nodes == other.nodes) return; - _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); -} - -STC_INLINE _cx_value -_cx_memb(_value_clone)(_cx_value _val) { - *_i_keyref(&_val) = i_keyfrom(i_keyto(_i_keyref(&_val))); - _i_MAP_ONLY( _val.second = i_valfrom(i_valto(&_val.second)); ) - return _val; -} -#if !defined _i_no_raw -STC_INLINE _cx_result -_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, rkey); - if (res.inserted) { - *_i_keyref(res.ref) = i_keyfrom(rkey); - _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) - } - return res; -} -#endif -#endif // !c_no_clone - -STC_INLINE _cx_result -_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); - if (res.inserted) { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} - else { i_keydrop(&key); _i_MAP_ONLY( i_valdrop(&mapped); )} - return res; -} - STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { _cx_iter it; it._d = self->nodes, it._top = 0; @@ -225,16 +207,6 @@ _cx_memb(_advance)(_cx_iter it, size_t n) { /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(_i_implement) -#ifndef CSMAP_H_INCLUDED -static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0}; -#endif // CSMAP_H_INCLUDED - -STC_DEF _cx_self -_cx_memb(_init)(void) { - _cx_self tree = {(_cx_node *) _csmap_sentinel.nodes}; - return tree; -} - STC_DEF _cx_value* _cx_memb(_front)(const _cx_self* self) { _cx_node *d = self->nodes; @@ -255,8 +227,9 @@ STC_DEF bool _cx_memb(_reserve)(_cx_self* self, const size_t cap) { struct csmap_rep* rep = _csmap_rep(self), *oldrep; if (cap >= rep->size) { - oldrep = rep->cap ? rep : NULL; - rep = (struct csmap_rep*) c_realloc(oldrep, + // second test is bogus, but supresses gcc warning: + oldrep = rep->cap && rep != &_csmap_sentinel ? rep : NULL; + rep = (struct csmap_rep*) c_realloc(oldrep, sizeof(struct csmap_rep) + (cap + 1)*sizeof(_cx_node)); if (!rep) return false; if (oldrep == NULL) @@ -282,6 +255,14 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { return (_cx_size) tn; } +STC_DEF _cx_result +_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { + _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); + if (res.inserted) { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} + else { i_keydrop(&key); _i_MAP_ONLY( i_valdrop(&mapped); )} + return res; +} + #if !defined _i_isset STC_DEF _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { @@ -290,6 +271,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { else { i_keydrop(&key); i_valdrop(&res.ref->second); } res.ref->second = mapped; return res; } + #if !c_option(c_no_clone) && !defined _i_no_raw STC_DEF _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { @@ -474,6 +456,19 @@ _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { } #if !c_option(c_no_clone) +STC_DEF void +_cx_memb(_copy)(_cx_self *self, _cx_self other) { + if (self->nodes == other.nodes) return; + _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); +} + +STC_DEF _cx_value +_cx_memb(_value_clone)(_cx_value _val) { + *_i_keyref(&_val) = i_keyfrom(i_keyto(_i_keyref(&_val))); + _i_MAP_ONLY( _val.second = i_valfrom(i_valto(&_val.second)); ) + return _val; +} + STC_DEF _cx_size _cx_memb(_clone_r_)(_cx_self* self, _cx_node* src, _cx_size sn) { if (sn == 0) return 0; @@ -492,6 +487,18 @@ _cx_memb(_clone)(_cx_self tree) { _csmap_rep(&clone)->size = _csmap_rep(&tree)->size; return clone; } + +#if !defined _i_no_raw +STC_DEF _cx_result +_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { + _cx_result res = _cx_memb(_insert_entry_)(self, rkey); + if (res.inserted) { + *_i_keyref(res.ref) = i_keyfrom(rkey); + _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) + } + return res; +} +#endif #endif // !c_no_clone STC_DEF void @@ -506,9 +513,10 @@ _cx_memb(_drop_r_)(_cx_node* d, _cx_size tn) { STC_DEF void _cx_memb(_drop)(_cx_self* self) { struct csmap_rep* rep = _csmap_rep(self); - if (rep->cap) { + // second test is bogus, but supresses gcc warning: + if (rep->cap && rep != &_csmap_sentinel) { _cx_memb(_drop_r_)(self->nodes, (_cx_size) rep->root); - c_free(rep); + c_free(rep); // correct, but may give warning } } diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 8881e43b..594d3236 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -38,12 +38,9 @@ typedef char cstr_value; typedef struct { size_t size, cap; char str[]; } _cstr_rep_t; #define _cstr_rep(self) c_container_of((self)->str, _cstr_rep_t, str) -#if defined(_i_static) - static struct { size_t size, cap; char str[1]; } _cstr_nullrep = {0, 0, {0}}; - static const cstr cstr_null = {_cstr_nullrep.str}; -#else - extern const cstr cstr_null; -#endif +static struct { size_t size, cap; char str[1]; } _cstr_nullrep = {0, 0, {0}}; +static const cstr cstr_null = {_cstr_nullrep.str}; + /* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ #define _cstr_opt_mem(cap) ((((offsetof(_cstr_rep_t, str) + (cap) + 8)>>4)<<4) + 8) /* optimal string capacity: 7, 23, 39, ... */ @@ -177,11 +174,6 @@ cstr_ends_with(cstr s, const char* sub) { /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(_i_implement) -#if !defined(_i_static) - static struct { size_t size, cap; char str[1]; } _cstr_nullrep = {0, 0, {0}}; - const cstr cstr_null = {_cstr_nullrep.str}; -#endif - STC_DEF size_t cstr_reserve(cstr* self, const size_t cap) { _cstr_rep_t* rep = _cstr_rep(self); @@ -387,7 +379,6 @@ c_strnstrn(const char *s, const char *needle, size_t slen, const size_t nlen) { } while (slen--); return NULL; } - #endif #endif -#undef i_opt \ No newline at end of file +#undef i_opt diff --git a/include/stc/csview.h b/include/stc/csview.h index e1f82272..c1f4c9ac 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -126,16 +126,26 @@ STC_INLINE int csview_cmp(const csview* x, const csview* y) { STC_DEF csview csview_substr(csview sv, intptr_t pos, size_t n) { - if (pos < 0) { pos += sv.size; if (pos < 0) pos = 0; } - if (pos > sv.size) pos = sv.size; if (pos + n > sv.size) n = sv.size - pos; - sv.str += pos, sv.size = n; return sv; + if (pos < 0) { + pos += sv.size; + if (pos < 0) pos = 0; + } + if (pos > sv.size) pos = sv.size; + if (pos + n > sv.size) n = sv.size - pos; + sv.str += pos, sv.size = n; + return sv; } STC_DEF csview csview_slice(csview sv, intptr_t p1, intptr_t p2) { - if (p1 < 0) { p1 += sv.size; if (p1 < 0) p1 = 0; } - if (p2 < 0) p2 += sv.size; if (p2 > sv.size) p2 = sv.size; - sv.str += p1, sv.size = p2 > p1 ? p2 - p1 : 0; return sv; + if (p1 < 0) { + p1 += sv.size; + if (p1 < 0) p1 = 0; + } + if (p2 < 0) p2 += sv.size; + if (p2 > sv.size) p2 = sv.size; + sv.str += p1, sv.size = p2 > p1 ? p2 - p1 : 0; + return sv; } STC_DEF csview @@ -149,4 +159,4 @@ csview_token(csview sv, csview sep, size_t* start) { #endif #endif -#undef i_opt \ No newline at end of file +#undef i_opt diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 8e630926..6a8c0d20 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -66,6 +66,7 @@ int main() { struct cvec_rep { size_t size, cap; void* data[]; }; #define cvec_rep_(self) c_container_of((self)->data, struct cvec_rep, data) +static struct cvec_rep _cvec_sentinel = {0, 0}; #endif // CVEC_H_INCLUDED #ifndef _i_prefix @@ -78,7 +79,6 @@ struct cvec_rep { size_t size, cap; void* data[]; }; #endif typedef i_valraw _cx_raw; -STC_API _cx_self _cx_memb(_init)(void); STC_API void _cx_memb(_drop)(_cx_self* self); STC_API void _cx_memb(_clear)(_cx_self* self); STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap); @@ -100,11 +100,11 @@ STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val) { return i_valfrom(i_valto(&val)); } STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); } -STC_INLINE void -_cx_memb(_copy)(_cx_self *self, _cx_self other) { - if (self->data == other.data) return; - _cx_memb(_drop)(self); *self = _cx_memb(_clone)(other); -} +STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { + if (self->data == other.data) return; + _cx_memb(_drop)(self); + *self = _cx_memb(_clone)(other); + } #if !defined _i_no_raw STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2); @@ -149,6 +149,12 @@ STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs) { it.ref += offs; return it; } STC_INLINE size_t _cx_memb(_index)(_cx_self cx, _cx_iter it) { return it.ref - cx.data; } +STC_INLINE _cx_self +_cx_memb(_init)(void) { + _cx_self cx = {(_cx_value *) _cvec_sentinel.data}; + return cx; +} + STC_INLINE _cx_self _cx_memb(_with_size)(const size_t size, i_val null) { _cx_self cx = _cx_memb(_init)(); @@ -235,16 +241,6 @@ _cx_memb(_sort)(_cx_self* self) { /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(_i_implement) -#ifndef CVEC_H_INCLUDED -static struct cvec_rep _cvec_sentinel = {0, 0}; -#endif - -STC_DEF _cx_self -_cx_memb(_init)(void) { - _cx_self cx = {(_cx_value *) _cvec_sentinel.data}; - return cx; -} - STC_DEF void _cx_memb(_clear)(_cx_self* self) { struct cvec_rep* rep = cvec_rep_(self); -- cgit v1.2.3