diff options
| author | 2023-09-13 18:19:19 +0200 | |
|---|---|---|
| committer | 2023-09-13 18:19:19 +0200 | |
| commit | 4105e737e6ec9b9d8aca508ac5bedb69947b202d (patch) | |
| tree | f90686ed12ef4ea2b50e65ddeee42bf3650144eb | |
| parent | Updated RELEASE_NOTES. (diff) | |
| download | penes-snac2-4105e737e6ec9b9d8aca508ac5bedb69947b202d.tar.gz penes-snac2-4105e737e6ec9b9d8aca508ac5bedb69947b202d.tar.xz penes-snac2-4105e737e6ec9b9d8aca508ac5bedb69947b202d.zip | |
Backport from xs.
| -rw-r--r-- | xs.h | 57 | ||||
| -rw-r--r-- | xs_regex.h | 8 | ||||
| -rw-r--r-- | xs_unicode.h | 40 | ||||
| -rw-r--r-- | xs_version.h | 2 |
4 files changed, 71 insertions, 36 deletions
| @@ -59,6 +59,7 @@ xs_val *xs_insert_m(xs_val *data, int offset, const char *mem, int size); | |||
| 59 | #define xs_append_m(data, mem, size) xs_insert_m(data, xs_size(data) - 1, mem, size) | 59 | #define xs_append_m(data, mem, size) xs_insert_m(data, xs_size(data) - 1, mem, size) |
| 60 | 60 | ||
| 61 | xs_str *xs_str_new(const char *str); | 61 | xs_str *xs_str_new(const char *str); |
| 62 | xs_str *xs_str_new_sz(const char *mem, int sz); | ||
| 62 | xs_str *xs_str_wrap_i(const char *prefix, xs_str *str, const char *suffix); | 63 | xs_str *xs_str_wrap_i(const char *prefix, xs_str *str, const char *suffix); |
| 63 | #define xs_str_prepend_i(str, prefix) xs_str_wrap_i(prefix, str, NULL) | 64 | #define xs_str_prepend_i(str, prefix) xs_str_wrap_i(prefix, str, NULL) |
| 64 | #define xs_str_cat(str, suffix) xs_str_wrap_i(NULL, str, suffix) | 65 | #define xs_str_cat(str, suffix) xs_str_wrap_i(NULL, str, suffix) |
| @@ -72,6 +73,8 @@ int xs_starts_and_ends(const char *prefix, const char *str, const char *suffix); | |||
| 72 | #define xs_startswith(str, prefix) xs_starts_and_ends(prefix, str, NULL) | 73 | #define xs_startswith(str, prefix) xs_starts_and_ends(prefix, str, NULL) |
| 73 | #define xs_endswith(str, suffix) xs_starts_and_ends(NULL, str, suffix) | 74 | #define xs_endswith(str, suffix) xs_starts_and_ends(NULL, str, suffix) |
| 74 | xs_str *xs_crop_i(xs_str *str, int start, int end); | 75 | xs_str *xs_crop_i(xs_str *str, int start, int end); |
| 76 | xs_str *xs_lstrip_chars_i(xs_str *str, const char *chars); | ||
| 77 | xs_str *xs_rstrip_chars_i(xs_str *str, const char *chars); | ||
| 75 | xs_str *xs_strip_chars_i(xs_str *str, const char *chars); | 78 | xs_str *xs_strip_chars_i(xs_str *str, const char *chars); |
| 76 | #define xs_strip_i(str) xs_strip_chars_i(str, " \r\n\t\v\f") | 79 | #define xs_strip_i(str) xs_strip_chars_i(str, " \r\n\t\v\f") |
| 77 | xs_str *xs_tolower_i(xs_str *str); | 80 | xs_str *xs_tolower_i(xs_str *str); |
| @@ -424,6 +427,17 @@ xs_str *xs_str_new(const char *str) | |||
| 424 | } | 427 | } |
| 425 | 428 | ||
| 426 | 429 | ||
| 430 | xs_str *xs_str_new_sz(const char *mem, int sz) | ||
| 431 | /* creates a new string from a memory block, adding an asciiz */ | ||
| 432 | { | ||
| 433 | xs_str *s = xs_realloc(NULL, _xs_blk_size(sz + 1)); | ||
| 434 | memcpy(s, mem, sz); | ||
| 435 | s[sz] = '\0'; | ||
| 436 | |||
| 437 | return s; | ||
| 438 | } | ||
| 439 | |||
| 440 | |||
| 427 | xs_str *xs_str_wrap_i(const char *prefix, xs_str *str, const char *suffix) | 441 | xs_str *xs_str_wrap_i(const char *prefix, xs_str *str, const char *suffix) |
| 428 | /* wraps str with prefix and suffix */ | 442 | /* wraps str with prefix and suffix */ |
| 429 | { | 443 | { |
| @@ -546,26 +560,36 @@ xs_str *xs_crop_i(xs_str *str, int start, int end) | |||
| 546 | } | 560 | } |
| 547 | 561 | ||
| 548 | 562 | ||
| 549 | xs_str *xs_strip_chars_i(xs_str *str, const char *chars) | 563 | xs_str *xs_lstrip_chars_i(xs_str *str, const char *chars) |
| 550 | /* strips the string of chars from the start and the end */ | 564 | /* strips all chars from the start of str */ |
| 551 | { | 565 | { |
| 552 | XS_ASSERT_TYPE(str, XSTYPE_STRING); | 566 | int n; |
| 553 | 567 | ||
| 568 | for (n = 0; str[n] && strchr(chars, str[n]); n++); | ||
| 569 | |||
| 570 | if (n) | ||
| 571 | str = xs_collapse(str, 0, n); | ||
| 572 | |||
| 573 | return str; | ||
| 574 | } | ||
| 575 | |||
| 576 | |||
| 577 | xs_str *xs_rstrip_chars_i(xs_str *str, const char *chars) | ||
| 578 | /* strips all chars from the end of str */ | ||
| 579 | { | ||
| 554 | int n; | 580 | int n; |
| 555 | 581 | ||
| 556 | /* strip first from the end */ | ||
| 557 | for (n = strlen(str); n > 0 && strchr(chars, str[n - 1]); n--); | 582 | for (n = strlen(str); n > 0 && strchr(chars, str[n - 1]); n--); |
| 558 | str[n] = '\0'; | 583 | str[n] = '\0'; |
| 559 | 584 | ||
| 560 | if (str[0]) { | 585 | return str; |
| 561 | /* now strip from the beginning */ | 586 | } |
| 562 | for (n = 0; str[n] && strchr(chars, str[n]); n++); | ||
| 563 | 587 | ||
| 564 | if (n) | ||
| 565 | str = xs_collapse(str, 0, n); | ||
| 566 | } | ||
| 567 | 588 | ||
| 568 | return str; | 589 | xs_str *xs_strip_chars_i(xs_str *str, const char *chars) |
| 590 | /* strips the string of chars from the start and the end */ | ||
| 591 | { | ||
| 592 | return xs_lstrip_chars_i(xs_rstrip_chars_i(str, chars), chars); | ||
| 569 | } | 593 | } |
| 570 | 594 | ||
| 571 | 595 | ||
| @@ -859,11 +883,9 @@ xs_list *xs_split_n(const char *str, const char *sep, int times) | |||
| 859 | list = xs_list_new(); | 883 | list = xs_list_new(); |
| 860 | 884 | ||
| 861 | while (times > 0 && (ss = strstr(str, sep)) != NULL) { | 885 | while (times > 0 && (ss = strstr(str, sep)) != NULL) { |
| 862 | /* add the first part (without the asciiz) */ | 886 | /* create a new string with this slice and add it to the list */ |
| 863 | list = xs_list_append_m(list, str, ss - str); | 887 | xs *s = xs_str_new_sz(str, ss - str); |
| 864 | 888 | list = xs_list_append(list, s); | |
| 865 | /* add the asciiz */ | ||
| 866 | list = xs_insert_m(list, xs_size(list) - 1, "", 1); | ||
| 867 | 889 | ||
| 868 | /* skip past the separator */ | 890 | /* skip past the separator */ |
| 869 | str = ss + sz; | 891 | str = ss + sz; |
| @@ -1131,8 +1153,7 @@ int xs_data_size(const xs_data *value) | |||
| 1131 | void xs_data_get(const xs_data *value, void *data) | 1153 | void xs_data_get(const xs_data *value, void *data) |
| 1132 | /* copies the raw data stored inside value into data */ | 1154 | /* copies the raw data stored inside value into data */ |
| 1133 | { | 1155 | { |
| 1134 | int size = _xs_get_24b(value + 1) - 4; | 1156 | memcpy(data, &value[4], xs_data_size(value)); |
| 1135 | memcpy(data, &value[4], size); | ||
| 1136 | } | 1157 | } |
| 1137 | 1158 | ||
| 1138 | 1159 | ||
| @@ -33,12 +33,12 @@ xs_list *xs_regex_split_n(const char *str, const char *rx, int count) | |||
| 33 | 33 | ||
| 34 | while (count > 0 && !regexec(&re, (p = str + offset), 1, &rm, offset > 0 ? REG_NOTBOL : 0)) { | 34 | while (count > 0 && !regexec(&re, (p = str + offset), 1, &rm, offset > 0 ? REG_NOTBOL : 0)) { |
| 35 | /* add first the leading part of the string */ | 35 | /* add first the leading part of the string */ |
| 36 | list = xs_list_append_m(list, p, rm.rm_so); | 36 | xs *s1 = xs_str_new_sz(p, rm.rm_so); |
| 37 | list = xs_insert_m(list, xs_size(list) - 1, "", 1); | 37 | list = xs_list_append(list, s1); |
| 38 | 38 | ||
| 39 | /* add now the matched text as the separator */ | 39 | /* add now the matched text as the separator */ |
| 40 | list = xs_list_append_m(list, p + rm.rm_so, rm.rm_eo - rm.rm_so); | 40 | xs *s2 = xs_str_new_sz(p + rm.rm_so, rm.rm_eo - rm.rm_so); |
| 41 | list = xs_insert_m(list, xs_size(list) - 1, "", 1); | 41 | list = xs_list_append(list, s2); |
| 42 | 42 | ||
| 43 | /* move forward */ | 43 | /* move forward */ |
| 44 | offset += rm.rm_eo; | 44 | offset += rm.rm_eo; |
diff --git a/xs_unicode.h b/xs_unicode.h index 35cd9f7..c7d6190 100644 --- a/xs_unicode.h +++ b/xs_unicode.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | unsigned int xs_unicode_to_lower(unsigned int cpoint); | 16 | unsigned int xs_unicode_to_lower(unsigned int cpoint); |
| 17 | int xs_unicode_nfd(unsigned int cpoint, unsigned int *base, unsigned int *diac); | 17 | int xs_unicode_nfd(unsigned int cpoint, unsigned int *base, unsigned int *diac); |
| 18 | int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint); | 18 | int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint); |
| 19 | int xs_unicode_is_alpha(unsigned int cpoint); | ||
| 19 | 20 | ||
| 20 | #ifdef XS_IMPLEMENTATION | 21 | #ifdef XS_IMPLEMENTATION |
| 21 | 22 | ||
| @@ -101,6 +102,15 @@ unsigned int xs_utf8_dec(char **str) | |||
| 101 | } | 102 | } |
| 102 | 103 | ||
| 103 | 104 | ||
| 105 | static int int_range_cmp(const void *p1, const void *p2) | ||
| 106 | { | ||
| 107 | const unsigned int *a = p1; | ||
| 108 | const unsigned int *b = p2; | ||
| 109 | |||
| 110 | return *a < b[0] ? -1 : *a > b[1] ? 1 : 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 104 | /* intentionally dead simple */ | 114 | /* intentionally dead simple */ |
| 105 | 115 | ||
| 106 | static unsigned int xs_unicode_width_table[] = { | 116 | static unsigned int xs_unicode_width_table[] = { |
| @@ -119,20 +129,12 @@ static unsigned int xs_unicode_width_table[] = { | |||
| 119 | int xs_unicode_width(unsigned int cpoint) | 129 | int xs_unicode_width(unsigned int cpoint) |
| 120 | /* returns the width in columns of a Unicode codepoint (somewhat simplified) */ | 130 | /* returns the width in columns of a Unicode codepoint (somewhat simplified) */ |
| 121 | { | 131 | { |
| 122 | unsigned int *p = xs_unicode_width_table; | 132 | unsigned int *r = bsearch(&cpoint, xs_unicode_width_table, |
| 123 | unsigned int *e = p + sizeof(xs_unicode_width_table) / sizeof(unsigned int); | 133 | sizeof(xs_unicode_width_table) / (sizeof(unsigned int) * 3), |
| 124 | 134 | sizeof(unsigned int) * 3, | |
| 125 | while (p < e) { | 135 | int_range_cmp); |
| 126 | if (cpoint < p[0]) | ||
| 127 | return 1; | ||
| 128 | |||
| 129 | if (cpoint >= p[0] && cpoint <= p[1]) | ||
| 130 | return p[2]; | ||
| 131 | |||
| 132 | p += 3; | ||
| 133 | } | ||
| 134 | 136 | ||
| 135 | return 0; | 137 | return r ? r[2] : 1; |
| 136 | } | 138 | } |
| 137 | 139 | ||
| 138 | 140 | ||
| @@ -232,6 +234,18 @@ int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint) | |||
| 232 | } | 234 | } |
| 233 | 235 | ||
| 234 | 236 | ||
| 237 | int xs_unicode_is_alpha(unsigned int cpoint) | ||
| 238 | /* checks if a codepoint is an alpha (i.e. a letter) */ | ||
| 239 | { | ||
| 240 | unsigned int *r = bsearch(&cpoint, xs_unicode_alpha_table, | ||
| 241 | sizeof(xs_unicode_alpha_table) / (sizeof(unsigned int) * 2), | ||
| 242 | sizeof(unsigned int) * 2, | ||
| 243 | int_range_cmp); | ||
| 244 | |||
| 245 | return !!r; | ||
| 246 | } | ||
| 247 | |||
| 248 | |||
| 235 | #endif /* _XS_UNICODE_TBL_H */ | 249 | #endif /* _XS_UNICODE_TBL_H */ |
| 236 | 250 | ||
| 237 | #endif /* XS_IMPLEMENTATION */ | 251 | #endif /* XS_IMPLEMENTATION */ |
diff --git a/xs_version.h b/xs_version.h index 800a008..a05f5bb 100644 --- a/xs_version.h +++ b/xs_version.h | |||
| @@ -1 +1 @@ | |||
| /* fdd04f1862e0d8bdebb7b438798914643895d43f */ | /* 5bf06243b37eec60e48e53d87d4d147d01ad9924 */ | ||