annotate val.c @ 851:f9a9816e0142

sexpr: use %define api.pure instead of %pure-parser %pure-parser got deprecated a number of years ago. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Wed, 05 Jan 2022 23:02:19 -0500
parents 93d6c996250f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
1 /*
825
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
2 * Copyright (c) 2014-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
3 *
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
5 * of this software and associated documentation files (the "Software"), to deal
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
6 * in the Software without restriction, including without limitation the rights
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
8 * copies of the Software, and to permit persons to whom the Software is
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
9 * furnished to do so, subject to the following conditions:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
10 *
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
11 * The above copyright notice and this permission notice shall be included in
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
12 * all copies or substantial portions of the Software.
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
13 *
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
20 * SOFTWARE.
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
21 */
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
22
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
23 #include <string.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
24 #include <errno.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
25 #include <stddef.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
26 #include <stdio.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
27 #include <stdbool.h>
58
260a210c9e84 val: include inttypes.h for PRIu64
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
28 #include <inttypes.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
29
464
b1e4c7607050 val: introduce VT_NVL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 463
diff changeset
30 #include <jeffpc/val.h>
19
017a4abcfe3d init: add a single initialize-the-library function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 9
diff changeset
31 #include <jeffpc/jeffpc.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
32 #include <jeffpc/error.h>
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
33 #include <jeffpc/types.h>
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
34 #include <jeffpc/mem.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
35
349
21f04e72ca8a val: expose __val_alloc to other parts of libjeffpc
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 347
diff changeset
36 #include "val_impl.h"
21f04e72ca8a val: expose __val_alloc to other parts of libjeffpc
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 347
diff changeset
37
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
38 #define INIT_STATIC_VAL(t, memb, val) \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
39 { \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
40 .type = (t), \
347
c85a698f3672 val: rename static_alloc struct val member to static_struct
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 342
diff changeset
41 .static_struct = true, \
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
42 .memb = (val), \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
43 }
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
44
350
cc22716beb4a val: preallocate () VT_CONS
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 349
diff changeset
45 static const struct val val_cons_empty = INIT_STATIC_VAL(VT_CONS, i, 0);
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
46 static const struct val val_true = INIT_STATIC_VAL(VT_BOOL, b, true);
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
47 static const struct val val_false = INIT_STATIC_VAL(VT_BOOL, b, false);
342
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
48 static const struct val val_null = INIT_STATIC_VAL(VT_NULL, i, 0);
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
49 static const struct val val_ints[10] = {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
50 [0] = INIT_STATIC_VAL(VT_INT, i, 0),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
51 [1] = INIT_STATIC_VAL(VT_INT, i, 1),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
52 [2] = INIT_STATIC_VAL(VT_INT, i, 2),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
53 [3] = INIT_STATIC_VAL(VT_INT, i, 3),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
54 [4] = INIT_STATIC_VAL(VT_INT, i, 4),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
55 [5] = INIT_STATIC_VAL(VT_INT, i, 5),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
56 [6] = INIT_STATIC_VAL(VT_INT, i, 6),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
57 [7] = INIT_STATIC_VAL(VT_INT, i, 7),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
58 [8] = INIT_STATIC_VAL(VT_INT, i, 8),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
59 [9] = INIT_STATIC_VAL(VT_INT, i, 9),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
60 };
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
61
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
62 static struct mem_cache *val_cache;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
63
174
532cbad2de95 init: mark val and str subsystem init functions as constructors
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 161
diff changeset
64 static void __attribute__((constructor)) init_val_subsys(void)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
65 {
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
66 val_cache = mem_cache_create("val-cache", sizeof(struct val), 0);
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
67 ASSERT(!IS_ERR(val_cache));
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
68 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
69
349
21f04e72ca8a val: expose __val_alloc to other parts of libjeffpc
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 347
diff changeset
70 struct val *__val_alloc(enum val_type type)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
71 {
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
72 struct val *val;
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
73
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
74 val = mem_cache_alloc(val_cache);
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
75 if (!val)
161
67b08ecf5c1e val: internal val allocation function should return errnos
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 160
diff changeset
76 return ERR_PTR(-ENOMEM);
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
77
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
78 val->type = type;
347
c85a698f3672 val: rename static_alloc struct val member to static_struct
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 342
diff changeset
79 val->static_struct = false;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
80
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
81 refcnt_init(&val->refcnt, 1);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
82
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
83 return val;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
84 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
85
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
86 void val_free(struct val *val)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
87 {
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
88 ASSERT(val);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
89 ASSERT3U(refcnt_read(&val->refcnt), ==, 0);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
90
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
91 switch (val->type) {
342
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
92 case VT_NULL:
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
93 case VT_INT:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
94 case VT_BOOL:
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
95 case VT_CHAR:
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
96 break;
365
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
97 case VT_BLOB:
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
98 if (!val->static_alloc)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
99 free(val->_set_blob.ptr);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
100 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
101 case VT_STR:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
102 case VT_SYM:
359
7544e9990bc1 str: implement struct str in terms of struct val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 350
diff changeset
103 if (!val->static_alloc)
7544e9990bc1 str: implement struct str in terms of struct val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 350
diff changeset
104 free((char *) val->_set_str_ptr);
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
105 break;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
106 case VT_CONS:
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
107 val_putref(val->cons.head);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
108 val_putref(val->cons.tail);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
109 break;
463
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
110 case VT_ARRAY: {
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
111 size_t i;
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
112
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
113 for (i = 0; i < val->array.nelem; i++)
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
114 val_putref(val->_set_array.vals[i]);
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
115
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
116 if (!val->static_alloc)
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
117 free(val->_set_array.vals);
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
118 break;
8f455913bfd0 val: introduce VT_ARRAY
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 375
diff changeset
119 }
464
b1e4c7607050 val: introduce VT_NVL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 463
diff changeset
120 case VT_NVL:
b1e4c7607050 val: introduce VT_NVL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 463
diff changeset
121 __val_free_nvl(val);
b1e4c7607050 val: introduce VT_NVL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 463
diff changeset
122 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
123 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
124
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
125 mem_cache_free(val_cache, val);
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
126 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
127
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
128 #define DEF_VAL_SET(fxn, vttype, valelem, ctype, putref) \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
129 struct val *val_alloc_##fxn(ctype v) \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
130 { \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
131 struct val *val; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
132 \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
133 val = __val_alloc(vttype); \
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
134 if (IS_ERR(val)) { \
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
135 putref(v); \
161
67b08ecf5c1e val: internal val allocation function should return errnos
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 160
diff changeset
136 return val; \
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
137 } \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
138 \
153
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
139 val->_set_##valelem = v; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
140 \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
141 return val; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
142 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
143
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
144 static DEF_VAL_SET(int_heap, VT_INT, i, uint64_t, (void))
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
145 DEF_VAL_SET(char, VT_CHAR, i, uint64_t, (void))
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
146
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
147 struct val *val_alloc_int(uint64_t i)
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
148 {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
149 if (i < ARRAY_LEN(val_ints)) {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
150 /*
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
151 * Cast away the const - we define the static as const to get it
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
152 * into .rodata, but we have to drop the const since everything
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
153 * expects struct val to be writable (because refcounts modify it).
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
154 * In this case, we won't get any modifications because we're marked
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
155 * as static.
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
156 */
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
157 return (struct val *) &val_ints[i];
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
158 }
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
159
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
160 return val_alloc_int_heap(i);
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
161 }
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
162
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
163 struct val *val_alloc_bool(bool b)
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
164 {
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
165 const struct val *ret;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
166
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
167 ret = b ? &val_true : &val_false;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
168
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
169 /*
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
170 * Cast away the const - we define the static as const to get it
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
171 * into .rodata, but we have to drop the const since everything
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
172 * expects struct val to be writable (because refcounts modify it).
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
173 * In this case, we won't get any modifications because we're marked
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
174 * as static.
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
175 */
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
176 return (struct val *) ret;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
177 }
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
178
342
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
179 struct val *val_alloc_null(void)
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
180 {
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
181 /*
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
182 * Cast away the const - we define the static as const to get it
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
183 * into .rodata, but we have to drop the const since everything
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
184 * expects struct val to be writable (because refcounts modify it).
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
185 * In this case, we won't get any modifications because we're marked
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
186 * as static.
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
187 */
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
188 return (struct val *) &val_null;
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
189 }
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
190
365
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
191 static struct val *__val_alloc_blob(void *ptr, size_t size, bool heap)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
192 {
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
193 struct val *val;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
194
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
195 val = __val_alloc(VT_BLOB);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
196 if (IS_ERR(val)) {
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
197 if (heap)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
198 free(ptr);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
199
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
200 return val;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
201 }
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
202
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
203 val->_set_blob.ptr = ptr;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
204 val->_set_blob.size = size;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
205 val->static_alloc = !heap;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
206
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
207 return val;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
208 }
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
209
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
210 struct val *val_alloc_blob(void *ptr, size_t size)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
211 {
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
212 return __val_alloc_blob(ptr, size, true);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
213 }
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
214
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
215 struct val *val_alloc_blob_dup(const void *ptr, size_t size)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
216 {
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
217 void *tmp;
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
218
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
219 tmp = malloc(size);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
220 if (!tmp)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
221 return ERR_PTR(-ENOMEM);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
222
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
223 memcpy(tmp, ptr, size);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
224
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
225 return __val_alloc_blob(tmp, size, true);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
226 }
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
227
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
228 struct val *val_alloc_blob_static(const void *ptr, size_t size)
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
229 {
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
230 return __val_alloc_blob((void *) ptr, size, false);
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
231 }
141cc4a78ad5 val: introduce VT_BLOB
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 359
diff changeset
232
366
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
233 struct val *val_empty_cons(void)
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
234 {
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
235 /*
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
236 * Cast away the const - we define the static as const to get it
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
237 * into .rodata, but we have to drop the const since everything
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
238 * expects struct val to be writable (because refcounts modify it).
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
239 * In this case, we won't get any modifications because we're marked
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
240 * as static.
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
241 */
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
242 return (struct val *) &val_cons_empty;
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
243 }
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
244
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
245 struct val *val_alloc_cons(struct val *head, struct val *tail)
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
246 {
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
247 struct val *val;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
248
375
98de274eb895 Backed out changeset fbec0c9877f2
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 370
diff changeset
249 if (!head && !tail)
366
42c208c50fc1 val: add an easy way to allocate an empty cons cell
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 365
diff changeset
250 return val_empty_cons();
350
cc22716beb4a val: preallocate () VT_CONS
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 349
diff changeset
251
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
252 val = __val_alloc(VT_CONS);
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
253 if (IS_ERR(val)) {
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
254 val_putref(head);
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
255 val_putref(tail);
161
67b08ecf5c1e val: internal val allocation function should return errnos
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 160
diff changeset
256 return val;
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
257 }
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
258
153
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
259 val->_set_cons.head = head;
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
260 val->_set_cons.tail = tail;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
261
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
262 return val;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
263 }
825
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
264
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
265 int val_cmp(const struct val *a, const struct val *b)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
266 {
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
267 if (a == b)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
268 return 0;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
269
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
270 if (a->type != b->type)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
271 return (a->type < b->type) ? -1 : +1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
272
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
273 switch (a->type) {
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
274 case VT_STR:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
275 case VT_SYM:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
276 return strcmp(val_cstr(a), val_cstr(b));
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
277 case VT_INT:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
278 case VT_CHAR:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
279 if (a->i < b->i)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
280 return -1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
281 if (a->i > b->i)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
282 return +1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
283 return 0;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
284 case VT_BOOL:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
285 if (!a->b && b->b)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
286 return -1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
287 if (a->b && !b->b)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
288 return +1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
289 return 0;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
290 case VT_NULL:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
291 return 0;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
292 case VT_BLOB: {
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
293 int ret;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
294
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
295 ret = memcmp(a->blob.ptr, b->blob.ptr,
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
296 MIN(a->blob.size, b->blob.size));
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
297 if (ret)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
298 return ret;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
299
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
300 if (a->blob.size < b->blob.size)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
301 return -1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
302 if (a->blob.size > b->blob.size)
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
303 return +1;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
304 return 0;
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
305 }
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
306 case VT_CONS:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
307 case VT_ARRAY:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
308 case VT_NVL:
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
309 panic("not yet implemented");
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
310 }
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
311
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
312 panic("unknown val type %d (%s)", a->type, val_typename(a->type));
93d6c996250f val: add val_cmp
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 470
diff changeset
313 }