From 75cc7ae7a3799a27a5647a2c7d912e6a6e2fbb5b Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 23 Aug 2025 20:41:16 +0200 Subject: Added some more helping functions. --- xs.h | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 17 deletions(-) (limited to 'xs.h') diff --git a/xs.h b/xs.h index 54b913e..5f2e6aa 100644 --- a/xs.h +++ b/xs.h @@ -134,7 +134,9 @@ xs_dict *xs_dict_set_path_sep(xs_dict *dict, const char *path, const xs_val *val xs_val *xs_val_new(xstype t); xs_number *xs_number_new(double f); +xs_number *xs_number_new_l(long l); double xs_number_get(const xs_number *v); +long xs_number_get_l(const xs_number *v); const char *xs_number_str(const xs_number *v); xs_data *xs_data_new(const void *data, int size); @@ -163,6 +165,7 @@ uint64_t xs_hash64_func(const char *data, int size); #define xs_is_string(v) (xs_type((v)) == XSTYPE_STRING) #define xs_is_list(v) (xs_type((v)) == XSTYPE_LIST) #define xs_is_dict(v) (xs_type((v)) == XSTYPE_DICT) +#define xs_is_number(v) (xs_type((v)) == XSTYPE_NUMBER) #define xs_list_foreach(l, v) for (int ct_##__LINE__ = 0; xs_list_next(l, &v, &ct_##__LINE__); ) #define xs_dict_foreach(l, k, v) for (int ct_##__LINE__ = 0; xs_dict_next(l, &k, &v, &ct_##__LINE__); ) @@ -362,9 +365,22 @@ int xs_is_null(const xs_val *data) int xs_cmp(const xs_val *v1, const xs_val *v2) /* compares two values */ { - if (xs_type(v1) == XSTYPE_STRING && xs_type(v2) == XSTYPE_STRING) + xstype t1 = xs_type(v1); + xstype t2 = xs_type(v2); + + if (t1 == XSTYPE_NULL || t2 == XSTYPE_NULL) + return 0; + + if (t1 == XSTYPE_STRING && t2 == XSTYPE_STRING) return strcmp(v1, v2); + if (t1 == XSTYPE_NUMBER && t2 == XSTYPE_NUMBER) { + double d1 = xs_number_get(v1); + double d2 = xs_number_get(v2); + + return d1 == d2 ? 0 : d1 < d2 ? -1 : 1; + } + int s1 = xs_size(v1); int s2 = xs_size(v2); int d = s1 - s2; @@ -975,6 +991,9 @@ xs_str *xs_join(const xs_list *list, const char *sep) xs_list_foreach(list, v) { /* refuse to join non-string values */ + if (xs_type(v) == XSTYPE_NUMBER) + v = xs_number_str(v); + if (xs_type(v) == XSTYPE_STRING) { int sz; @@ -1396,10 +1415,20 @@ xs_val *xs_val_new(xstype t) /** numbers */ +xs_number *_xs_number_new(const char *str) +{ + xs_number *v = xs_realloc(NULL, 1 + xs_size(str)); + + v[0] = XSTYPE_NUMBER; + memcpy(&v[1], str, xs_size(str)); + + return v; +} + + xs_number *xs_number_new(double f) -/* adds a new number value */ +/* creates a new number value from a double */ { - xs_number *v; char tmp[64]; snprintf(tmp, sizeof(tmp), "%.15lf", f); @@ -1416,40 +1445,54 @@ xs_number *xs_number_new(double f) *ptr = '\0'; } - /* alloc for the marker and the full string */ - v = xs_realloc(NULL, _xs_blk_size(1 + xs_size(tmp))); + return _xs_number_new(tmp); +} - v[0] = XSTYPE_NUMBER; - memcpy(&v[1], tmp, xs_size(tmp)); - return v; +xs_number *xs_number_new_l(long l) +/* creates a new number value from a long */ +{ + char tmp[64]; + + snprintf(tmp, sizeof(tmp), "%ld", l); + + return _xs_number_new(tmp); } double xs_number_get(const xs_number *v) /* gets the number as a double */ { - double f = 0.0; + if (xs_type(v) == XSTYPE_NUMBER) + v++; + + if (xs_type(v) == XSTYPE_STRING) + return atof(v); + return 0.0; +} + + +long xs_number_get_l(const xs_number *v) +/* gets the number as a long */ +{ if (xs_type(v) == XSTYPE_NUMBER) - f = atof(&v[1]); - else + v++; + if (xs_type(v) == XSTYPE_STRING) - f = atof(v); + return atol(v); - return f; + return 0; } const char *xs_number_str(const xs_number *v) /* gets the number as a string */ { - const char *p = NULL; - if (xs_type(v) == XSTYPE_NUMBER) - p = &v[1]; + return v + 1; - return p; + return NULL; } -- cgit