commit 4105e73
default
·
2023-09-13 16:19:19 +0000 UTC
parent 53a906b
Backport from xs.
4 files changed,
+71,
-36
M
xs.h
+39,
-18
1@@ -59,6 +59,7 @@ xs_val *xs_insert_m(xs_val *data, int offset, const char *mem, int size);
2 #define xs_append_m(data, mem, size) xs_insert_m(data, xs_size(data) - 1, mem, size)
3
4 xs_str *xs_str_new(const char *str);
5+xs_str *xs_str_new_sz(const char *mem, int sz);
6 xs_str *xs_str_wrap_i(const char *prefix, xs_str *str, const char *suffix);
7 #define xs_str_prepend_i(str, prefix) xs_str_wrap_i(prefix, str, NULL)
8 #define xs_str_cat(str, suffix) xs_str_wrap_i(NULL, str, suffix)
9@@ -72,6 +73,8 @@ int xs_starts_and_ends(const char *prefix, const char *str, const char *suffix);
10 #define xs_startswith(str, prefix) xs_starts_and_ends(prefix, str, NULL)
11 #define xs_endswith(str, suffix) xs_starts_and_ends(NULL, str, suffix)
12 xs_str *xs_crop_i(xs_str *str, int start, int end);
13+xs_str *xs_lstrip_chars_i(xs_str *str, const char *chars);
14+xs_str *xs_rstrip_chars_i(xs_str *str, const char *chars);
15 xs_str *xs_strip_chars_i(xs_str *str, const char *chars);
16 #define xs_strip_i(str) xs_strip_chars_i(str, " \r\n\t\v\f")
17 xs_str *xs_tolower_i(xs_str *str);
18@@ -424,6 +427,17 @@ xs_str *xs_str_new(const char *str)
19 }
20
21
22+xs_str *xs_str_new_sz(const char *mem, int sz)
23+/* creates a new string from a memory block, adding an asciiz */
24+{
25+ xs_str *s = xs_realloc(NULL, _xs_blk_size(sz + 1));
26+ memcpy(s, mem, sz);
27+ s[sz] = '\0';
28+
29+ return s;
30+}
31+
32+
33 xs_str *xs_str_wrap_i(const char *prefix, xs_str *str, const char *suffix)
34 /* wraps str with prefix and suffix */
35 {
36@@ -546,26 +560,36 @@ xs_str *xs_crop_i(xs_str *str, int start, int end)
37 }
38
39
40-xs_str *xs_strip_chars_i(xs_str *str, const char *chars)
41-/* strips the string of chars from the start and the end */
42+xs_str *xs_lstrip_chars_i(xs_str *str, const char *chars)
43+/* strips all chars from the start of str */
44 {
45- XS_ASSERT_TYPE(str, XSTYPE_STRING);
46+ int n;
47
48+ for (n = 0; str[n] && strchr(chars, str[n]); n++);
49+
50+ if (n)
51+ str = xs_collapse(str, 0, n);
52+
53+ return str;
54+}
55+
56+
57+xs_str *xs_rstrip_chars_i(xs_str *str, const char *chars)
58+/* strips all chars from the end of str */
59+{
60 int n;
61
62- /* strip first from the end */
63 for (n = strlen(str); n > 0 && strchr(chars, str[n - 1]); n--);
64 str[n] = '\0';
65
66- if (str[0]) {
67- /* now strip from the beginning */
68- for (n = 0; str[n] && strchr(chars, str[n]); n++);
69+ return str;
70+}
71
72- if (n)
73- str = xs_collapse(str, 0, n);
74- }
75
76- return str;
77+xs_str *xs_strip_chars_i(xs_str *str, const char *chars)
78+/* strips the string of chars from the start and the end */
79+{
80+ return xs_lstrip_chars_i(xs_rstrip_chars_i(str, chars), chars);
81 }
82
83
84@@ -859,11 +883,9 @@ xs_list *xs_split_n(const char *str, const char *sep, int times)
85 list = xs_list_new();
86
87 while (times > 0 && (ss = strstr(str, sep)) != NULL) {
88- /* add the first part (without the asciiz) */
89- list = xs_list_append_m(list, str, ss - str);
90-
91- /* add the asciiz */
92- list = xs_insert_m(list, xs_size(list) - 1, "", 1);
93+ /* create a new string with this slice and add it to the list */
94+ xs *s = xs_str_new_sz(str, ss - str);
95+ list = xs_list_append(list, s);
96
97 /* skip past the separator */
98 str = ss + sz;
99@@ -1131,8 +1153,7 @@ int xs_data_size(const xs_data *value)
100 void xs_data_get(const xs_data *value, void *data)
101 /* copies the raw data stored inside value into data */
102 {
103- int size = _xs_get_24b(value + 1) - 4;
104- memcpy(data, &value[4], size);
105+ memcpy(data, &value[4], xs_data_size(value));
106 }
107
108
+4,
-4
1@@ -33,12 +33,12 @@ xs_list *xs_regex_split_n(const char *str, const char *rx, int count)
2
3 while (count > 0 && !regexec(&re, (p = str + offset), 1, &rm, offset > 0 ? REG_NOTBOL : 0)) {
4 /* add first the leading part of the string */
5- list = xs_list_append_m(list, p, rm.rm_so);
6- list = xs_insert_m(list, xs_size(list) - 1, "", 1);
7+ xs *s1 = xs_str_new_sz(p, rm.rm_so);
8+ list = xs_list_append(list, s1);
9
10 /* add now the matched text as the separator */
11- list = xs_list_append_m(list, p + rm.rm_so, rm.rm_eo - rm.rm_so);
12- list = xs_insert_m(list, xs_size(list) - 1, "", 1);
13+ xs *s2 = xs_str_new_sz(p + rm.rm_so, rm.rm_eo - rm.rm_so);
14+ list = xs_list_append(list, s2);
15
16 /* move forward */
17 offset += rm.rm_eo;
+27,
-13
1@@ -16,6 +16,7 @@
2 unsigned int xs_unicode_to_lower(unsigned int cpoint);
3 int xs_unicode_nfd(unsigned int cpoint, unsigned int *base, unsigned int *diac);
4 int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint);
5+ int xs_unicode_is_alpha(unsigned int cpoint);
6
7 #ifdef XS_IMPLEMENTATION
8
9@@ -101,6 +102,15 @@ unsigned int xs_utf8_dec(char **str)
10 }
11
12
13+static int int_range_cmp(const void *p1, const void *p2)
14+{
15+ const unsigned int *a = p1;
16+ const unsigned int *b = p2;
17+
18+ return *a < b[0] ? -1 : *a > b[1] ? 1 : 0;
19+}
20+
21+
22 /* intentionally dead simple */
23
24 static unsigned int xs_unicode_width_table[] = {
25@@ -119,20 +129,12 @@ static unsigned int xs_unicode_width_table[] = {
26 int xs_unicode_width(unsigned int cpoint)
27 /* returns the width in columns of a Unicode codepoint (somewhat simplified) */
28 {
29- unsigned int *p = xs_unicode_width_table;
30- unsigned int *e = p + sizeof(xs_unicode_width_table) / sizeof(unsigned int);
31-
32- while (p < e) {
33- if (cpoint < p[0])
34- return 1;
35-
36- if (cpoint >= p[0] && cpoint <= p[1])
37- return p[2];
38-
39- p += 3;
40- }
41+ unsigned int *r = bsearch(&cpoint, xs_unicode_width_table,
42+ sizeof(xs_unicode_width_table) / (sizeof(unsigned int) * 3),
43+ sizeof(unsigned int) * 3,
44+ int_range_cmp);
45
46- return 0;
47+ return r ? r[2] : 1;
48 }
49
50
51@@ -232,6 +234,18 @@ int xs_unicode_nfc(unsigned int base, unsigned int diac, unsigned int *cpoint)
52 }
53
54
55+int xs_unicode_is_alpha(unsigned int cpoint)
56+/* checks if a codepoint is an alpha (i.e. a letter) */
57+{
58+ unsigned int *r = bsearch(&cpoint, xs_unicode_alpha_table,
59+ sizeof(xs_unicode_alpha_table) / (sizeof(unsigned int) * 2),
60+ sizeof(unsigned int) * 2,
61+ int_range_cmp);
62+
63+ return !!r;
64+}
65+
66+
67 #endif /* _XS_UNICODE_TBL_H */
68
69 #endif /* XS_IMPLEMENTATION */
+1,
-1
1@@ -1 +1 @@
2-/* fdd04f1862e0d8bdebb7b438798914643895d43f */
3+/* 5bf06243b37eec60e48e53d87d4d147d01ad9924 */