diff options
| -rw-r--r-- | examples/arc_containers.c | 1 | ||||
| -rw-r--r-- | examples/books.c | 1 | ||||
| -rw-r--r-- | examples/hashmap.c | 1 | ||||
| -rw-r--r-- | examples/mapmap.c | 1 | ||||
| -rw-r--r-- | examples/mmap.c | 1 | ||||
| -rw-r--r-- | examples/rawptr_elements.c | 1 | ||||
| -rw-r--r-- | examples/regex1.c | 1 | ||||
| -rw-r--r-- | examples/regex2.c | 1 | ||||
| -rw-r--r-- | examples/regex_match.c | 3 | ||||
| -rw-r--r-- | examples/splitstr.c | 1 | ||||
| -rw-r--r-- | examples/unordered_set.c | 1 | ||||
| -rw-r--r-- | src/casefold.c (renamed from src/cregex_utf8.c) | 75 |
12 files changed, 80 insertions, 8 deletions
diff --git a/examples/arc_containers.c b/examples/arc_containers.c index f9c14123..0ee2cbeb 100644 --- a/examples/arc_containers.c +++ b/examples/arc_containers.c @@ -1,5 +1,6 @@ // Create a stack and a list of shared pointers to maps,
// and demonstrate sharing and cloning of maps.
+#include <stc/cstr.h>
#define i_type Map
#define i_key_str // strings
#define i_val int
diff --git a/examples/books.c b/examples/books.c index b891388d..eb644ba7 100644 --- a/examples/books.c +++ b/examples/books.c @@ -1,5 +1,6 @@ // https://doc.rust-lang.org/std/collections/struct.HashMap.html
+#include <stc/cstr.h>
#define i_key_str
#define i_val_str
#include <stc/cmap.h>
diff --git a/examples/hashmap.c b/examples/hashmap.c index f39a3904..9ff019e6 100644 --- a/examples/hashmap.c +++ b/examples/hashmap.c @@ -1,5 +1,6 @@ // https://doc.rust-lang.org/rust-by-example/std/hash.html
+#include <stc/cstr.h>
#define i_key_str
#define i_val_str
#include <stdio.h>
diff --git a/examples/mapmap.c b/examples/mapmap.c index 51a5ce59..ccf09314 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -1,5 +1,6 @@ // unordered_map<string, unordered_map<string, string>>:
+#include <stc/cstr.h>
#define i_type People
#define i_key_str
#define i_val_str
diff --git a/examples/mmap.c b/examples/mmap.c index f8e56dc3..16b5d2df 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -2,6 +2,7 @@ // https://en.cppreference.com/w/cpp/container/multimap/insert
// Multimap entries
+#include <stc/cstr.h>
#define i_val_str
#include <stc/clist.h>
diff --git a/examples/rawptr_elements.c b/examples/rawptr_elements.c index f31f9abd..c438727b 100644 --- a/examples/rawptr_elements.c +++ b/examples/rawptr_elements.c @@ -13,6 +13,7 @@ struct { double x, y; } typedef Point; #define i_tag pnt
#include <stc/cset.h>
+#include <stc/cstr.h>
// Map of int64 pointers: Define i_valraw as int64_t for easy emplace calls!
typedef int64_t inttype;
#define i_key_str
diff --git a/examples/regex1.c b/examples/regex1.c index 23a28f08..48dfe515 100644 --- a/examples/regex1.c +++ b/examples/regex1.c @@ -30,3 +30,4 @@ int main(int argc, char* argv[]) } #include "../src/cregex.c" +#include "../src/casefold.c" diff --git a/examples/regex2.c b/examples/regex2.c index 750638c4..60fd707a 100644 --- a/examples/regex2.c +++ b/examples/regex2.c @@ -33,3 +33,4 @@ int main() } #include "../src/cregex.c" +#include "../src/casefold.c" diff --git a/examples/regex_match.c b/examples/regex_match.c index 3747b319..5d2ff215 100644 --- a/examples/regex_match.c +++ b/examples/regex_match.c @@ -1,4 +1,6 @@ #include <stdio.h> +#define i_implement +#include <stc/cstr.h> #include <stc/cregex.h> #include <stc/crandom.h> #include <stc/csview.h> @@ -33,3 +35,4 @@ int main() } #include "../src/cregex.c" +#include "../src/casefold.c" diff --git a/examples/splitstr.c b/examples/splitstr.c index d0aefa85..390a6c6f 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -1,3 +1,4 @@ +#include <stc/cstr.h>
#define i_val_str
#include <stc/cvec.h>
#include <stc/csview.h>
diff --git a/examples/unordered_set.c b/examples/unordered_set.c index 2decb88c..11ffea80 100644 --- a/examples/unordered_set.c +++ b/examples/unordered_set.c @@ -1,5 +1,6 @@ // https://iq.opengenus.org/containers-cpp-stl/
// C program to demonstrate various function of stc cset
+#include <stc/cstr.h>
#define i_key_str
#include <stc/cset.h>
diff --git a/src/cregex_utf8.c b/src/casefold.c index 69be6315..1b0a9463 100644 --- a/src/cregex_utf8.c +++ b/src/casefold.c @@ -1,8 +1,6 @@ -#include <stdint.h> -#include <stdio.h> #include <ctype.h> -#include <stc/utf8.h> -#include <stdbool.h> +#define i_header +#include <stc/cstr.h> static struct CaseFold { uint16_t c0, c1, m1; } casefold[] = { {65, 90, 122}, {181, 181, 956}, {192, 214, 246}, {216, 222, 254}, @@ -127,6 +125,52 @@ bool utf8_isalpha(uint32_t c) { return utf8_islower(c) || utf8_isupper(c); } +static struct fnfold { + int (*conv_asc)(int); + uint32_t (*conv_u8)(uint32_t); +} +fn_tolower = {tolower, utf8_tolower}, +fn_toupper = {toupper, utf8_toupper}; + + +static cstr cstr_casefold(const cstr* self, struct fnfold fold) { + csview sv = cstr_sv(self); + cstr out = cstr_null; + char *buf = cstr_reserve(&out, sv.size*3/2); + uint32_t cp; size_t sz = 0; + utf8_decode_t d = {UTF8_OK}; + + for (; *sv.str; sv.str += d.size) { + utf8_peek(sv.str, &d); + switch (d.size) { + case 1: + buf[sz++] = (char)fold.conv_asc(*sv.str); + break; + default: + cp = fold.conv_u8(d.codep); + sz += utf8_encode(buf + sz, cp); + } + } + _cstr_set_size(&out, sz); + cstr_shrink_to_fit(&out); + return out; +} + +cstr cstr_tolower(const cstr* self) { + return cstr_casefold(self, fn_tolower); +} + +cstr cstr_toupper(const cstr* self) { + return cstr_casefold(self, fn_toupper); +} + +void cstr_lowercase(cstr* self) { + cstr_take(self, cstr_casefold(self, fn_tolower)); +} + +void cstr_uppercase(cstr* self) { + cstr_take(self, cstr_casefold(self, fn_toupper)); +} #ifdef TEST int main() @@ -134,14 +178,29 @@ int main() for (size_t i=0; i < sizeof cfold_low/sizeof *cfold_low; ++i) { char x[3][5]={0}; + unsigned s0, s1, s2; uint32_t a = casefold[i].c0; uint32_t b = utf8_tolower(a); uint32_t c = utf8_toupper(b); - utf8_encode(x[0], a); - utf8_encode(x[1], b); - utf8_encode(x[2], c); - printf("%s %s %s - %u %u %u\n", x[0], x[1], x[2], a, b, c); + s0 = utf8_encode(x[0], a); + s1 = utf8_encode(x[1], b); + s2 = utf8_encode(x[2], c); + printf("%s %s %s - %u %u %u (%u %u %u)\n", x[0], x[1], x[2], a, b, c, s0, s1, s2); + } + c_auto (cstr, t1) + { + t1 = cstr_new("Die preußischen Köstlichkeiten."); + + cstr_buf b = cstr_buffer(&t1); + printf("%s, %llu %llu\n", b.data, b.size, b.cap); + cstr_lowercase(&t1); + b = cstr_buffer(&t1); + printf("%s, %llu %llu\n", b.data, b.size, b.cap); + + cstr_uppercase(&t1); + b = cstr_buffer(&t1); + printf("%s, %llu %llu\n", b.data, b.size, b.cap); } } #endif |
