summaryrefslogtreecommitdiff
path: root/xs.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs.h')
-rw-r--r--xs.h254
1 files changed, 151 insertions, 103 deletions
diff --git a/xs.h b/xs.h
index d2de44a..972665c 100644
--- a/xs.h
+++ b/xs.h
@@ -21,8 +21,8 @@ typedef enum {
21 XSTYPE_FALSE = 0x15, /* Boolean */ 21 XSTYPE_FALSE = 0x15, /* Boolean */
22 XSTYPE_LIST = 0x1d, /* Sequence of LITEMs up to EOM (with size) */ 22 XSTYPE_LIST = 0x1d, /* Sequence of LITEMs up to EOM (with size) */
23 XSTYPE_LITEM = 0x1f, /* Element of a list (any type) */ 23 XSTYPE_LITEM = 0x1f, /* Element of a list (any type) */
24 XSTYPE_DICT = 0x1c, /* Sequence of DITEMs up to EOM (with size) */ 24 XSTYPE_DICT = 0x1c, /* Sequence of KEYVALs up to EOM (with size) */
25 XSTYPE_DITEM = 0x1e, /* Element of a dict (STRING key + any type) */ 25 XSTYPE_KEYVAL = 0x1e, /* key + value (STRING key + any type) */
26 XSTYPE_EOM = 0x19, /* End of Multiple (LIST or DICT) */ 26 XSTYPE_EOM = 0x19, /* End of Multiple (LIST or DICT) */
27 XSTYPE_DATA = 0x10 /* A block of anonymous data */ 27 XSTYPE_DATA = 0x10 /* A block of anonymous data */
28} xstype; 28} xstype;
@@ -32,6 +32,7 @@ typedef enum {
32typedef char xs_val; 32typedef char xs_val;
33typedef char xs_str; 33typedef char xs_str;
34typedef char xs_list; 34typedef char xs_list;
35typedef char xs_keyval;
35typedef char xs_dict; 36typedef char xs_dict;
36typedef char xs_number; 37typedef char xs_number;
37typedef char xs_data; 38typedef char xs_data;
@@ -45,6 +46,10 @@ typedef char xs_data;
45/* not really all, just very much */ 46/* not really all, just very much */
46#define XS_ALL 0xfffffff 47#define XS_ALL 0xfffffff
47 48
49#ifndef xs_countof
50#define xs_countof(a) (sizeof((a)) / sizeof((*a)))
51#endif
52
48void *xs_free(void *ptr); 53void *xs_free(void *ptr);
49void *_xs_realloc(void *ptr, size_t size, const char *file, int line, const char *func); 54void *_xs_realloc(void *ptr, size_t size, const char *file, int line, const char *func);
50#define xs_realloc(ptr, size) _xs_realloc(ptr, size, __FILE__, __LINE__, __FUNCTION__) 55#define xs_realloc(ptr, size) _xs_realloc(ptr, size, __FILE__, __LINE__, __FUNCTION__)
@@ -89,9 +94,10 @@ xs_list *xs_list_new(void);
89xs_list *xs_list_append_m(xs_list *list, const char *mem, int dsz); 94xs_list *xs_list_append_m(xs_list *list, const char *mem, int dsz);
90xs_list *_xs_list_append(xs_list *list, const xs_val *vals[]); 95xs_list *_xs_list_append(xs_list *list, const xs_val *vals[]);
91#define xs_list_append(list, ...) _xs_list_append(list, (const xs_val *[]){ __VA_ARGS__, NULL }) 96#define xs_list_append(list, ...) _xs_list_append(list, (const xs_val *[]){ __VA_ARGS__, NULL })
92int xs_list_iter(xs_list **list, xs_val **value); 97int xs_list_iter(xs_list **list, const xs_val **value);
98int xs_list_next(const xs_list *list, const xs_val **value, int *ctxt);
93int xs_list_len(const xs_list *list); 99int xs_list_len(const xs_list *list);
94xs_val *xs_list_get(const xs_list *list, int num); 100const xs_val *xs_list_get(const xs_list *list, int num);
95xs_list *xs_list_del(xs_list *list, int num); 101xs_list *xs_list_del(xs_list *list, int num);
96xs_list *xs_list_insert(xs_list *list, int num, const xs_val *data); 102xs_list *xs_list_insert(xs_list *list, int num, const xs_val *data);
97xs_list *xs_list_set(xs_list *list, int num, const xs_val *data); 103xs_list *xs_list_set(xs_list *list, int num, const xs_val *data);
@@ -104,17 +110,20 @@ xs_list *xs_split_n(const char *str, const char *sep, int times);
104#define xs_split(str, sep) xs_split_n(str, sep, XS_ALL) 110#define xs_split(str, sep) xs_split_n(str, sep, XS_ALL)
105xs_list *xs_list_cat(xs_list *l1, const xs_list *l2); 111xs_list *xs_list_cat(xs_list *l1, const xs_list *l2);
106 112
113int xs_keyval_size(const xs_str *key, const xs_val *value);
114xs_str *xs_keyval_key(const xs_keyval *keyval);
115xs_val *xs_keyval_value(const xs_keyval *keyval);
116xs_keyval *xs_keyval_make(xs_keyval *keyval, const xs_str *key, const xs_val *value);
117
107xs_dict *xs_dict_new(void); 118xs_dict *xs_dict_new(void);
108xs_dict *xs_dict_append_m(xs_dict *dict, const xs_str *key, const xs_val *mem, int dsz); 119xs_dict *xs_dict_append(xs_dict *dict, const xs_str *key, const xs_val *value);
109#define xs_dict_append(dict, key, data) xs_dict_append_m(dict, key, data, xs_size(data)) 120xs_dict *xs_dict_prepend(xs_dict *dict, const xs_str *key, const xs_val *value);
110xs_dict *xs_dict_prepend_m(xs_dict *dict, const xs_str *key, const xs_val *mem, int dsz); 121int xs_dict_next(const xs_dict *dict, const xs_str **key, const xs_val **value, int *ctxt);
111#define xs_dict_prepend(dict, key, data) xs_dict_prepend_m(dict, key, data, xs_size(data)) 122const xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def);
112int xs_dict_iter(xs_dict **dict, xs_str **key, xs_val **value);
113int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt);
114xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def);
115#define xs_dict_get(dict, key) xs_dict_get_def(dict, key, NULL) 123#define xs_dict_get(dict, key) xs_dict_get_def(dict, key, NULL)
116xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key); 124xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key);
117xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *data); 125xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *data);
126xs_dict *xs_dict_gc(xs_dict *dict);
118 127
119xs_val *xs_val_new(xstype t); 128xs_val *xs_val_new(xstype t);
120xs_number *xs_number_new(double f); 129xs_number *xs_number_new(double f);
@@ -242,7 +251,7 @@ xstype xs_type(const xs_val *data)
242 case XSTYPE_LIST: 251 case XSTYPE_LIST:
243 case XSTYPE_LITEM: 252 case XSTYPE_LITEM:
244 case XSTYPE_DICT: 253 case XSTYPE_DICT:
245 case XSTYPE_DITEM: 254 case XSTYPE_KEYVAL:
246 case XSTYPE_NUMBER: 255 case XSTYPE_NUMBER:
247 case XSTYPE_EOM: 256 case XSTYPE_EOM:
248 case XSTYPE_DATA: 257 case XSTYPE_DATA:
@@ -260,7 +269,7 @@ xstype xs_type(const xs_val *data)
260void _xs_put_size(xs_val *ptr, int i) 269void _xs_put_size(xs_val *ptr, int i)
261/* must match _XS_TYPE_SIZE */ 270/* must match _XS_TYPE_SIZE */
262{ 271{
263 memcpy(ptr, &i, sizeof(i)); 272 memcpy(ptr + 1, &i, sizeof(i));
264} 273}
265 274
266 275
@@ -294,7 +303,7 @@ int xs_size(const xs_val *data)
294 303
295 break; 304 break;
296 305
297 case XSTYPE_DITEM: 306 case XSTYPE_KEYVAL:
298 /* calculate the size of the key and the value */ 307 /* calculate the size of the key and the value */
299 p = data + 1; 308 p = data + 1;
300 p += xs_size(p); 309 p += xs_size(p);
@@ -378,7 +387,7 @@ xs_val *xs_expand(xs_val *data, int offset, int size)
378 if (xs_type(data) == XSTYPE_LIST || 387 if (xs_type(data) == XSTYPE_LIST ||
379 xs_type(data) == XSTYPE_DICT || 388 xs_type(data) == XSTYPE_DICT ||
380 xs_type(data) == XSTYPE_DATA) 389 xs_type(data) == XSTYPE_DATA)
381 _xs_put_size(data + 1, sz); 390 _xs_put_size(data, sz);
382 391
383 return data; 392 return data;
384} 393}
@@ -403,7 +412,7 @@ xs_val *xs_collapse(xs_val *data, int offset, int size)
403 if (xs_type(data) == XSTYPE_LIST || 412 if (xs_type(data) == XSTYPE_LIST ||
404 xs_type(data) == XSTYPE_DICT || 413 xs_type(data) == XSTYPE_DICT ||
405 xs_type(data) == XSTYPE_DATA) 414 xs_type(data) == XSTYPE_DATA)
406 _xs_put_size(data + 1, sz); 415 _xs_put_size(data, sz);
407 416
408 return xs_realloc(data, _xs_blk_size(sz)); 417 return xs_realloc(data, _xs_blk_size(sz));
409} 418}
@@ -664,10 +673,10 @@ xs_list *xs_list_new(void)
664{ 673{
665 int sz = 1 + _XS_TYPE_SIZE + 1; 674 int sz = 1 + _XS_TYPE_SIZE + 1;
666 xs_list *l = xs_realloc(NULL, sz); 675 xs_list *l = xs_realloc(NULL, sz);
667 memset(l, '\0', sz); 676 memset(l, XSTYPE_EOM, sz);
668 677
669 l[0] = XSTYPE_LIST; 678 l[0] = XSTYPE_LIST;
670 _xs_put_size(&l[1], sz); 679 _xs_put_size(l, sz);
671 680
672 return l; 681 return l;
673} 682}
@@ -717,7 +726,7 @@ xs_list *_xs_list_append(xs_list *list, const xs_val *vals[])
717} 726}
718 727
719 728
720int xs_list_iter(xs_list **list, xs_val **value) 729int xs_list_iter(xs_list **list, const xs_val **value)
721/* iterates a list value */ 730/* iterates a list value */
722{ 731{
723 int goon = 1; 732 int goon = 1;
@@ -748,23 +757,58 @@ int xs_list_iter(xs_list **list, xs_val **value)
748} 757}
749 758
750 759
760int xs_list_next(const xs_list *list, const xs_val **value, int *ctxt)
761/* iterates a list, with context */
762{
763 if (xs_type(list) != XSTYPE_LIST)
764 return 0;
765
766 int goon = 1;
767
768 const char *p = list;
769
770 /* skip the start of the list */
771 if (*ctxt == 0)
772 *ctxt = 1 + _XS_TYPE_SIZE;
773
774 p += *ctxt;
775
776 /* an element? */
777 if (xs_type(p) == XSTYPE_LITEM) {
778 p++;
779
780 *value = p;
781
782 p += xs_size(*value);
783 }
784 else {
785 /* end of list */
786 goon = 0;
787 }
788
789 /* update the context */
790 *ctxt = p - list;
791
792 return goon;
793}
794
795
751int xs_list_len(const xs_list *list) 796int xs_list_len(const xs_list *list)
752/* returns the number of elements in the list */ 797/* returns the number of elements in the list */
753{ 798{
754 XS_ASSERT_TYPE_NULL(list, XSTYPE_LIST); 799 XS_ASSERT_TYPE_NULL(list, XSTYPE_LIST);
755 800
756 int c = 0; 801 int c = 0, ct = 0;
757 xs_list *p = (xs_list *)list; 802 const xs_val *v;
758 xs_val *v;
759 803
760 while (xs_list_iter(&p, &v)) 804 while (xs_list_next(list, &v, &ct))
761 c++; 805 c++;
762 806
763 return c; 807 return c;
764} 808}
765 809
766 810
767xs_val *xs_list_get(const xs_list *list, int num) 811const xs_val *xs_list_get(const xs_list *list, int num)
768/* returns the element #num */ 812/* returns the element #num */
769{ 813{
770 XS_ASSERT_TYPE(list, XSTYPE_LIST); 814 XS_ASSERT_TYPE(list, XSTYPE_LIST);
@@ -772,11 +816,10 @@ xs_val *xs_list_get(const xs_list *list, int num)
772 if (num < 0) 816 if (num < 0)
773 num = xs_list_len(list) + num; 817 num = xs_list_len(list) + num;
774 818
775 int c = 0; 819 int c = 0, ct = 0;
776 xs_list *p = (xs_list *)list; 820 const xs_val *v;
777 xs_val *v;
778 821
779 while (xs_list_iter(&p, &v)) { 822 while (xs_list_next(list, &v, &ct)) {
780 if (c == num) 823 if (c == num)
781 return v; 824 return v;
782 825
@@ -792,7 +835,7 @@ xs_list *xs_list_del(xs_list *list, int num)
792{ 835{
793 XS_ASSERT_TYPE(list, XSTYPE_LIST); 836 XS_ASSERT_TYPE(list, XSTYPE_LIST);
794 837
795 xs_val *v; 838 const xs_val *v;
796 839
797 if ((v = xs_list_get(list, num)) != NULL) 840 if ((v = xs_list_get(list, num)) != NULL)
798 list = xs_collapse(list, v - 1 - list, xs_size(v - 1)); 841 list = xs_collapse(list, v - 1 - list, xs_size(v - 1));
@@ -806,7 +849,7 @@ xs_list *xs_list_insert(xs_list *list, int num, const xs_val *data)
806{ 849{
807 XS_ASSERT_TYPE(list, XSTYPE_LIST); 850 XS_ASSERT_TYPE(list, XSTYPE_LIST);
808 851
809 xs_val *v; 852 const xs_val *v;
810 int offset; 853 int offset;
811 854
812 if ((v = xs_list_get(list, num)) != NULL) 855 if ((v = xs_list_get(list, num)) != NULL)
@@ -835,16 +878,16 @@ xs_list *xs_list_dequeue(xs_list *list, xs_val **data, int last)
835{ 878{
836 XS_ASSERT_TYPE(list, XSTYPE_LIST); 879 XS_ASSERT_TYPE(list, XSTYPE_LIST);
837 880
838 xs_list *p = list; 881 int ct = 0;
839 xs_val *v = NULL; 882 const xs_val *v = NULL;
840 883
841 if (!last) { 884 if (!last) {
842 /* get the first */ 885 /* get the first */
843 xs_list_iter(&p, &v); 886 xs_list_next(list, &v, &ct);
844 } 887 }
845 else { 888 else {
846 /* iterate to the end */ 889 /* iterate to the end */
847 while (xs_list_iter(&p, &v)); 890 while (xs_list_next(list, &v, &ct));
848 } 891 }
849 892
850 if (v != NULL) { 893 if (v != NULL) {
@@ -864,11 +907,11 @@ int xs_list_in(const xs_list *list, const xs_val *val)
864 XS_ASSERT_TYPE_NULL(list, XSTYPE_LIST); 907 XS_ASSERT_TYPE_NULL(list, XSTYPE_LIST);
865 908
866 int n = 0; 909 int n = 0;
867 xs_list *p = (xs_list *)list; 910 int ct = 0;
868 xs_val *v; 911 const xs_val *v;
869 int sz = xs_size(val); 912 int sz = xs_size(val);
870 913
871 while (xs_list_iter(&p, &v)) { 914 while (xs_list_next(list, &v, &ct)) {
872 if (sz == xs_size(v) && memcmp(val, v, sz) == 0) 915 if (sz == xs_size(v) && memcmp(val, v, sz) == 0)
873 return n; 916 return n;
874 917
@@ -885,13 +928,13 @@ xs_str *xs_join(const xs_list *list, const char *sep)
885 XS_ASSERT_TYPE(list, XSTYPE_LIST); 928 XS_ASSERT_TYPE(list, XSTYPE_LIST);
886 929
887 xs_str *s = NULL; 930 xs_str *s = NULL;
888 xs_list *p = (xs_list *)list; 931 const xs_val *v;
889 xs_val *v;
890 int c = 0; 932 int c = 0;
933 int ct = 0;
891 int offset = 0; 934 int offset = 0;
892 int ssz = strlen(sep); 935 int ssz = strlen(sep);
893 936
894 while (xs_list_iter(&p, &v)) { 937 while (xs_list_next(list, &v, &ct)) {
895 /* refuse to join non-string values */ 938 /* refuse to join non-string values */
896 if (xs_type(v) == XSTYPE_STRING) { 939 if (xs_type(v) == XSTYPE_STRING) {
897 int sz; 940 int sz;
@@ -961,6 +1004,40 @@ xs_list *xs_list_cat(xs_list *l1, const xs_list *l2)
961} 1004}
962 1005
963 1006
1007/** keyvals **/
1008
1009int xs_keyval_size(const xs_str *key, const xs_val *value)
1010/* returns the needed size for a keyval */
1011{
1012 return 1 + xs_size(key) + xs_size(value);
1013}
1014
1015
1016xs_str *xs_keyval_key(const xs_keyval *keyval)
1017/* returns a pointer to the key of the keyval */
1018{
1019 return (xs_str *)&keyval[1];
1020}
1021
1022
1023xs_val *xs_keyval_value(const xs_keyval *keyval)
1024/* returns a pointer to the value of the keyval */
1025{
1026 return (xs_val *)&keyval[1 + xs_size(xs_keyval_key(keyval))];
1027}
1028
1029
1030xs_keyval *xs_keyval_make(xs_keyval *keyval, const xs_str *key, const xs_val *value)
1031/* builds a keyval into mem (should have enough size) */
1032{
1033 keyval[0] = XSTYPE_KEYVAL;
1034 memcpy(xs_keyval_key(keyval), key, xs_size(key));
1035 memcpy(xs_keyval_value(keyval), value, xs_size(value));
1036
1037 return keyval;
1038}
1039
1040
964/** dicts **/ 1041/** dicts **/
965 1042
966xs_dict *xs_dict_new(void) 1043xs_dict *xs_dict_new(void)
@@ -968,87 +1045,47 @@ xs_dict *xs_dict_new(void)
968{ 1045{
969 int sz = 1 + _XS_TYPE_SIZE + 1; 1046 int sz = 1 + _XS_TYPE_SIZE + 1;
970 xs_dict *d = xs_realloc(NULL, sz); 1047 xs_dict *d = xs_realloc(NULL, sz);
971 memset(d, '\0', sz); 1048 memset(d, XSTYPE_EOM, sz);
972 1049
973 d[0] = XSTYPE_DICT; 1050 d[0] = XSTYPE_DICT;
974 _xs_put_size(&d[1], sz); 1051 _xs_put_size(d, sz);
975 1052
976 return d; 1053 return d;
977} 1054}
978 1055
979 1056
980xs_dict *_xs_dict_write_ditem(xs_dict *dict, int offset, const xs_str *key, 1057xs_dict *_xs_dict_write_keyval(xs_dict *dict, int offset, const xs_str *key, const xs_val *value)
981 const xs_val *data, int dsz) 1058/* adds a new keyval to the dict */
982/* inserts a memory block into the dict */
983{ 1059{
984 XS_ASSERT_TYPE(dict, XSTYPE_DICT); 1060 XS_ASSERT_TYPE(dict, XSTYPE_DICT);
985 XS_ASSERT_TYPE(key, XSTYPE_STRING); 1061 XS_ASSERT_TYPE(key, XSTYPE_STRING);
986 1062
987 if (data == NULL) { 1063 if (value == NULL)
988 data = xs_stock(XSTYPE_NULL); 1064 value = xs_stock(XSTYPE_NULL);
989 dsz = xs_size(data);
990 }
991
992 int ksz = xs_size(key);
993 1065
994 dict = xs_expand(dict, offset, 1 + ksz + dsz); 1066 dict = xs_expand(dict, offset, xs_keyval_size(key, value));
995 1067
996 dict[offset] = XSTYPE_DITEM; 1068 xs_keyval_make(&dict[offset], key, value);
997 memcpy(&dict[offset + 1], key, ksz);
998 memcpy(&dict[offset + 1 + ksz], data, dsz);
999 1069
1000 return dict; 1070 return dict;
1001} 1071}
1002 1072
1003 1073
1004xs_dict *xs_dict_append_m(xs_dict *dict, const xs_str *key, const xs_val *mem, int dsz) 1074xs_dict *xs_dict_append(xs_dict *dict, const xs_str *key, const xs_val *value)
1005/* appends a memory block to the dict */ 1075/* appends a memory block to the dict */
1006{ 1076{
1007 return _xs_dict_write_ditem(dict, xs_size(dict) - 1, key, mem, dsz); 1077 return _xs_dict_write_keyval(dict, xs_size(dict) - 1, key, value);
1008} 1078}
1009 1079
1010 1080
1011xs_dict *xs_dict_prepend_m(xs_dict *dict, const xs_str *key, const xs_val *mem, int dsz) 1081xs_dict *xs_dict_prepend(xs_dict *dict, const xs_str *key, const xs_val *value)
1012/* prepends a memory block to the dict */ 1082/* prepends a memory block to the dict */
1013{ 1083{
1014 return _xs_dict_write_ditem(dict, 4, key, mem, dsz); 1084 return _xs_dict_write_keyval(dict, 1 + _XS_TYPE_SIZE, key, value);
1015}
1016
1017
1018int xs_dict_iter(xs_dict **dict, xs_str **key, xs_val **value)
1019/* iterates a dict value */
1020{
1021 int goon = 1;
1022
1023 xs_val *p = *dict;
1024
1025 /* skip the start of the list */
1026 if (xs_type(p) == XSTYPE_DICT)
1027 p += 1 + _XS_TYPE_SIZE;
1028
1029 /* an element? */
1030 if (xs_type(p) == XSTYPE_DITEM) {
1031 p++;
1032
1033 *key = p;
1034 p += xs_size(*key);
1035
1036 *value = p;
1037 p += xs_size(*value);
1038 }
1039 else {
1040 /* end of list */
1041 goon = 0;
1042 }
1043
1044 /* store back the pointer */
1045 *dict = p;
1046
1047 return goon;
1048} 1085}
1049 1086
1050 1087
1051int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt) 1088int xs_dict_next(const xs_dict *dict, const xs_str **key, const xs_val **value, int *ctxt)
1052/* iterates a dict, with context */ 1089/* iterates a dict, with context */
1053{ 1090{
1054 if (xs_type(dict) != XSTYPE_DICT) 1091 if (xs_type(dict) != XSTYPE_DICT)
@@ -1065,7 +1102,7 @@ int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt)
1065 p += *ctxt; 1102 p += *ctxt;
1066 1103
1067 /* an element? */ 1104 /* an element? */
1068 if (xs_type(p) == XSTYPE_DITEM) { 1105 if (xs_type(p) == XSTYPE_KEYVAL) {
1069 p++; 1106 p++;
1070 1107
1071 *key = p; 1108 *key = p;
@@ -1086,14 +1123,14 @@ int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt)
1086} 1123}
1087 1124
1088 1125
1089xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def) 1126const xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def)
1090/* returns the value directed by key, or the default value */ 1127/* returns the value directed by key, or the default value */
1091{ 1128{
1092 XS_ASSERT_TYPE(dict, XSTYPE_DICT); 1129 XS_ASSERT_TYPE(dict, XSTYPE_DICT);
1093 XS_ASSERT_TYPE(key, XSTYPE_STRING); 1130 XS_ASSERT_TYPE(key, XSTYPE_STRING);
1094 1131
1095 xs_str *k; 1132 const xs_str *k;
1096 xs_val *v; 1133 const xs_val *v;
1097 int c = 0; 1134 int c = 0;
1098 1135
1099 while (xs_dict_next(dict, &k, &v, &c)) { 1136 while (xs_dict_next(dict, &k, &v, &c)) {
@@ -1111,14 +1148,14 @@ xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key)
1111 XS_ASSERT_TYPE(dict, XSTYPE_DICT); 1148 XS_ASSERT_TYPE(dict, XSTYPE_DICT);
1112 XS_ASSERT_TYPE(key, XSTYPE_STRING); 1149 XS_ASSERT_TYPE(key, XSTYPE_STRING);
1113 1150
1114 xs_str *k; 1151 const xs_str *k;
1115 xs_val *v; 1152 const xs_val *v;
1116 int c = 0; 1153 int c = 0;
1117 1154
1118 while (xs_dict_next(dict, &k, &v, &c)) { 1155 while (xs_dict_next(dict, &k, &v, &c)) {
1119 if (strcmp(k, key) == 0) { 1156 if (strcmp(k, key) == 0) {
1120 /* the address of the item is just behind the key */ 1157 /* the address of the item is just behind the key */
1121 char *i = k - 1; 1158 char *i = (char *)k - 1;
1122 1159
1123 dict = xs_collapse(dict, i - dict, xs_size(i)); 1160 dict = xs_collapse(dict, i - dict, xs_size(i));
1124 break; 1161 break;
@@ -1145,6 +1182,14 @@ xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *data)
1145} 1182}
1146 1183
1147 1184
1185xs_dict *xs_dict_gc(xs_dict *dict)
1186/* collects garbage (leaked values) inside a dict */
1187{
1188 /* this kind of dicts does not get garbage */
1189 return dict;
1190}
1191
1192
1148/** other values **/ 1193/** other values **/
1149 1194
1150xs_val *xs_val_new(xstype t) 1195xs_val *xs_val_new(xstype t)
@@ -1195,8 +1240,11 @@ double xs_number_get(const xs_number *v)
1195{ 1240{
1196 double f = 0.0; 1241 double f = 0.0;
1197 1242
1198 if (v != NULL && v[0] == XSTYPE_NUMBER) 1243 if (xs_type(v) == XSTYPE_NUMBER)
1199 f = atof(&v[1]); 1244 f = atof(&v[1]);
1245 else
1246 if (xs_type(v) == XSTYPE_STRING)
1247 f = atof(v);
1200 1248
1201 return f; 1249 return f;
1202} 1250}
@@ -1207,7 +1255,7 @@ const char *xs_number_str(const xs_number *v)
1207{ 1255{
1208 const char *p = NULL; 1256 const char *p = NULL;
1209 1257
1210 if (v != NULL && v[0] == XSTYPE_NUMBER) 1258 if (xs_type(v) == XSTYPE_NUMBER)
1211 p = &v[1]; 1259 p = &v[1];
1212 1260
1213 return p; 1261 return p;
@@ -1227,7 +1275,7 @@ xs_data *xs_data_new(const void *data, int size)
1227 v = xs_realloc(NULL, _xs_blk_size(total_size)); 1275 v = xs_realloc(NULL, _xs_blk_size(total_size));
1228 v[0] = XSTYPE_DATA; 1276 v[0] = XSTYPE_DATA;
1229 1277
1230 _xs_put_size(v + 1, total_size); 1278 _xs_put_size(v, total_size);
1231 1279
1232 memcpy(&v[1 + _XS_TYPE_SIZE], data, size); 1280 memcpy(&v[1 + _XS_TYPE_SIZE], data, size);
1233 1281