commit 75cc7ae

grunfink  ·  2025-08-23 18:41:16 +0000 UTC
parent fee442d
Added some more helping functions.
4 files changed,  +91, -19
M xs.h
M xs.h
+60, -17
  1@@ -134,7 +134,9 @@ xs_dict *xs_dict_set_path_sep(xs_dict *dict, const char *path, const xs_val *val
  2 
  3 xs_val *xs_val_new(xstype t);
  4 xs_number *xs_number_new(double f);
  5+xs_number *xs_number_new_l(long l);
  6 double xs_number_get(const xs_number *v);
  7+long xs_number_get_l(const xs_number *v);
  8 const char *xs_number_str(const xs_number *v);
  9 
 10 xs_data *xs_data_new(const void *data, int size);
 11@@ -163,6 +165,7 @@ uint64_t xs_hash64_func(const char *data, int size);
 12 #define xs_is_string(v) (xs_type((v)) == XSTYPE_STRING)
 13 #define xs_is_list(v) (xs_type((v)) == XSTYPE_LIST)
 14 #define xs_is_dict(v) (xs_type((v)) == XSTYPE_DICT)
 15+#define xs_is_number(v) (xs_type((v)) == XSTYPE_NUMBER)
 16 
 17 #define xs_list_foreach(l, v) for (int ct_##__LINE__ = 0; xs_list_next(l, &v, &ct_##__LINE__); )
 18 #define xs_dict_foreach(l, k, v) for (int ct_##__LINE__ = 0; xs_dict_next(l, &k, &v, &ct_##__LINE__); )
 19@@ -362,9 +365,22 @@ int xs_is_null(const xs_val *data)
 20 int xs_cmp(const xs_val *v1, const xs_val *v2)
 21 /* compares two values */
 22 {
 23-    if (xs_type(v1) == XSTYPE_STRING && xs_type(v2) == XSTYPE_STRING)
 24+    xstype t1 = xs_type(v1);
 25+    xstype t2 = xs_type(v2);
 26+
 27+    if (t1 == XSTYPE_NULL || t2 == XSTYPE_NULL)
 28+        return 0;
 29+
 30+    if (t1 == XSTYPE_STRING && t2 == XSTYPE_STRING)
 31         return strcmp(v1, v2);
 32 
 33+    if (t1 == XSTYPE_NUMBER && t2 == XSTYPE_NUMBER) {
 34+        double d1 = xs_number_get(v1);
 35+        double d2 = xs_number_get(v2);
 36+
 37+        return d1 == d2 ? 0 : d1 < d2 ? -1 : 1;
 38+    }
 39+
 40     int s1 = xs_size(v1);
 41     int s2 = xs_size(v2);
 42     int d = s1 - s2;
 43@@ -975,6 +991,9 @@ xs_str *xs_join(const xs_list *list, const char *sep)
 44 
 45     xs_list_foreach(list, v) {
 46         /* refuse to join non-string values */
 47+        if (xs_type(v) == XSTYPE_NUMBER)
 48+            v = xs_number_str(v);
 49+
 50         if (xs_type(v) == XSTYPE_STRING) {
 51             int sz;
 52 
 53@@ -1396,10 +1415,20 @@ xs_val *xs_val_new(xstype t)
 54 
 55 /** numbers */
 56 
 57+xs_number *_xs_number_new(const char *str)
 58+{
 59+    xs_number *v = xs_realloc(NULL, 1 + xs_size(str));
 60+
 61+    v[0] = XSTYPE_NUMBER;
 62+    memcpy(&v[1], str, xs_size(str));
 63+
 64+    return v;
 65+}
 66+
 67+
 68 xs_number *xs_number_new(double f)
 69-/* adds a new number value */
 70+/* creates a new number value from a double */
 71 {
 72-    xs_number *v;
 73     char tmp[64];
 74 
 75     snprintf(tmp, sizeof(tmp), "%.15lf", f);
 76@@ -1416,40 +1445,54 @@ xs_number *xs_number_new(double f)
 77         *ptr = '\0';
 78     }
 79 
 80-    /* alloc for the marker and the full string */
 81-    v = xs_realloc(NULL, _xs_blk_size(1 + xs_size(tmp)));
 82+    return _xs_number_new(tmp);
 83+}
 84 
 85-    v[0] = XSTYPE_NUMBER;
 86-    memcpy(&v[1], tmp, xs_size(tmp));
 87 
 88-    return v;
 89+xs_number *xs_number_new_l(long l)
 90+/* creates a new number value from a long */
 91+{
 92+    char tmp[64];
 93+
 94+    snprintf(tmp, sizeof(tmp), "%ld", l);
 95+
 96+    return _xs_number_new(tmp);
 97 }
 98 
 99 
100 double xs_number_get(const xs_number *v)
101 /* gets the number as a double */
102 {
103-    double f = 0.0;
104+    if (xs_type(v) == XSTYPE_NUMBER)
105+        v++;
106+
107+    if (xs_type(v) == XSTYPE_STRING)
108+        return atof(v);
109 
110+    return 0.0;
111+}
112+
113+
114+long xs_number_get_l(const xs_number *v)
115+/* gets the number as a long */
116+{
117     if (xs_type(v) == XSTYPE_NUMBER)
118-        f = atof(&v[1]);
119-    else
120+        v++;
121+
122     if (xs_type(v) == XSTYPE_STRING)
123-        f = atof(v);
124+        return atol(v);
125 
126-    return f;
127+    return 0;
128 }
129 
130 
131 const char *xs_number_str(const xs_number *v)
132 /* gets the number as a string */
133 {
134-    const char *p = NULL;
135-
136     if (xs_type(v) == XSTYPE_NUMBER)
137-        p = &v[1];
138+        return v + 1;
139 
140-    return p;
141+    return NULL;
142 }
143 
144 
+26, -1
 1@@ -14,6 +14,7 @@ typedef struct _xs_set {
 2 void xs_set_init(xs_set *s);
 3 xs_list *xs_set_result(xs_set *s);
 4 void xs_set_free(xs_set *s);
 5+int xs_set_in(const xs_set *s, const xs_val *data);
 6 int xs_set_add(xs_set *s, const xs_val *data);
 7 
 8 
 9@@ -60,7 +61,7 @@ static int _store_hash(xs_set *s, const char *data, int value)
10 
11     while (s->hash[(i = hash % s->elems)]) {
12         /* get the pointer to the stored data */
13-        char *p = &s->list[s->hash[i]];
14+        const char *p = &s->list[s->hash[i]];
15 
16         /* already here? */
17         if (memcmp(p, data, sz) == 0)
18@@ -79,6 +80,30 @@ static int _store_hash(xs_set *s, const char *data, int value)
19 }
20 
21 
22+int xs_set_in(const xs_set *s, const xs_val *data)
23+/* returns 1 if the data is already in the set */
24+{
25+    unsigned int hash, i;
26+    int sz = xs_size(data);
27+
28+    hash = xs_hash_func(data, sz);
29+
30+    while (s->hash[(i = hash % s->elems)]) {
31+        /* get the pointer to the stored data */
32+        const char *p = &s->list[s->hash[i]];
33+
34+        /* already here? */
35+        if (memcmp(p, data, sz) == 0)
36+            return 1;
37+
38+        /* try next value */
39+        hash++;
40+    }
41+
42+    return 0;
43+}
44+
45+
46 int xs_set_add(xs_set *s, const xs_val *data)
47 /* adds the data to the set */
48 /* returns: 1 if added, 0 if already there */
+4, -0
 1@@ -79,6 +79,10 @@ unsigned int xs_utf8_dec(const char **str)
 2 /* decodes an utf-8 char inside str and updates the pointer */
 3 {
 4     const char *p = *str;
 5+
 6+    if (!xs_is_string(p))
 7+        return 0;
 8+
 9     unsigned int cpoint = 0;
10     unsigned char c = *p++;
11     int cb = 0;
+1, -1
1@@ -1 +1 @@
2-/* 401d229ffbec89b4a5cf97793926b7afb84a4f26 2025-07-08T15:44:54+02:00 */
3+/* ad90abcefd455c0ba0faf155dc2976490dbde0b0 2025-08-23T20:36:11+02:00 */