summaryrefslogtreecommitdiff
path: root/xs.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs.h')
-rw-r--r--xs.h26
1 files changed, 18 insertions, 8 deletions
diff --git a/xs.h b/xs.h
index 39b3b64..05d84f5 100644
--- a/xs.h
+++ b/xs.h
@@ -1,4 +1,4 @@
1/* copyright (c) 2022 - 2024 grunfink et al. / MIT license */ 1/* copyright (c) 2022 - 2025 grunfink et al. / MIT license */
2 2
3#ifndef _XS_H 3#ifndef _XS_H
4 4
@@ -157,6 +157,9 @@ unsigned int xs_hash_func(const char *data, int size);
157#define xs_is_true(v) (xs_type((v)) == XSTYPE_TRUE) 157#define xs_is_true(v) (xs_type((v)) == XSTYPE_TRUE)
158#define xs_is_false(v) (xs_type((v)) == XSTYPE_FALSE) 158#define xs_is_false(v) (xs_type((v)) == XSTYPE_FALSE)
159#define xs_not(v) xs_stock(xs_is_true((v)) ? XSTYPE_FALSE : XSTYPE_TRUE) 159#define xs_not(v) xs_stock(xs_is_true((v)) ? XSTYPE_FALSE : XSTYPE_TRUE)
160#define xs_is_string(v) (xs_type((v)) == XSTYPE_STRING)
161#define xs_is_list(v) (xs_type((v)) == XSTYPE_LIST)
162#define xs_is_dict(v) (xs_type((v)) == XSTYPE_DICT)
160 163
161#define xs_list_foreach(l, v) for (int ct_##__LINE__ = 0; xs_list_next(l, &v, &ct_##__LINE__); ) 164#define xs_list_foreach(l, v) for (int ct_##__LINE__ = 0; xs_list_next(l, &v, &ct_##__LINE__); )
162#define xs_dict_foreach(l, k, v) for (int ct_##__LINE__ = 0; xs_dict_next(l, &k, &v, &ct_##__LINE__); ) 165#define xs_dict_foreach(l, k, v) for (int ct_##__LINE__ = 0; xs_dict_next(l, &k, &v, &ct_##__LINE__); )
@@ -623,15 +626,14 @@ int xs_between(const char *prefix, const char *str, const char *suffix)
623xs_str *xs_crop_i(xs_str *str, int start, int end) 626xs_str *xs_crop_i(xs_str *str, int start, int end)
624/* crops the string to be only from start to end */ 627/* crops the string to be only from start to end */
625{ 628{
626 XS_ASSERT_TYPE(str, XSTYPE_STRING);
627
628 int sz = strlen(str); 629 int sz = strlen(str);
629 630
630 if (end <= 0) 631 if (end <= 0)
631 end = sz + end; 632 end = sz + end;
632 633
633 /* crop from the top */ 634 /* crop from the top */
634 str[end] = '\0'; 635 if (end > 0 && end < sz)
636 str[end] = '\0';
635 637
636 /* crop from the bottom */ 638 /* crop from the bottom */
637 str = xs_collapse(str, 0, start); 639 str = xs_collapse(str, 0, start);
@@ -1061,14 +1063,15 @@ xs_keyval *xs_keyval_make(xs_keyval *keyval, const xs_str *key, const xs_val *va
1061 1063
1062typedef struct { 1064typedef struct {
1063 int value_offset; /* offset to value (from dict start) */ 1065 int value_offset; /* offset to value (from dict start) */
1064 int next; /* next node in sequential search */ 1066 int next; /* next node in sequential scanning */
1065 int child[4]; /* child nodes in hashed search */ 1067 int child[4]; /* child nodes in hashed search */
1066 char key[]; /* C string key */ 1068 char key[]; /* C string key */
1067} ditem_hdr; 1069} ditem_hdr;
1068 1070
1069typedef struct { 1071typedef struct {
1070 int size; /* size of full dict (_XS_TYPE_SIZE) */ 1072 int size; /* size of full dict (_XS_TYPE_SIZE) */
1071 int first; /* first node for sequential search */ 1073 int first; /* first node for sequential scanning */
1074 int last; /* last node for sequential scanning */
1072 int root; /* root node for hashed search */ 1075 int root; /* root node for hashed search */
1073 /* a bunch of ditem_hdr and value follows */ 1076 /* a bunch of ditem_hdr and value follows */
1074} dict_hdr; 1077} dict_hdr;
@@ -1153,8 +1156,15 @@ xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *value)
1153 memcpy(dict + di->value_offset, value, vsz); 1156 memcpy(dict + di->value_offset, value, vsz);
1154 1157
1155 /* chain to the sequential list */ 1158 /* chain to the sequential list */
1156 di->next = dh->first; 1159 if (dh->first == 0)
1157 dh->first = end; 1160 dh->first = end;
1161 else {
1162 /* chain this new element to the last one */
1163 ditem_hdr *dil = (ditem_hdr *)(dict + dh->last);
1164 dil->next = end;
1165 }
1166
1167 dh->last = end;
1158 } 1168 }
1159 else { 1169 else {
1160 /* ditem already exists */ 1170 /* ditem already exists */