annotate val.c @ 342:d9ecc4ea68e1

val: introduce VT_NULL The not-a-value value. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 10 Aug 2017 10:23:09 +0300
parents 482885766614
children c85a698f3672
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 /*
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
2 * Copyright (c) 2014-2017 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>
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
28 #include <ctype.h>
58
260a210c9e84 val: include inttypes.h for PRIu64
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
29 #include <inttypes.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
30
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
31 #include <jeffpc/val.h>
19
017a4abcfe3d init: add a single initialize-the-library function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 9
diff changeset
32 #include <jeffpc/jeffpc.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
33 #include <jeffpc/error.h>
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
34 #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
35 #include <jeffpc/mem.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
36
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
37 #define INIT_STATIC_VAL(t, memb, val) \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
38 { \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
39 .type = (t), \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
40 .static_alloc = true, \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
41 .memb = (val), \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
42 }
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 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
45 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
46 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
47 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
48 [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
49 [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
50 [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
51 [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
52 [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
53 [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
54 [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
55 [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
56 [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
57 [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
58 };
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
59
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
60 static struct mem_cache *val_cache;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
61
174
532cbad2de95 init: mark val and str subsystem init functions as constructors
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 161
diff changeset
62 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
63 {
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
64 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
65 ASSERT(!IS_ERR(val_cache));
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
66 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
67
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
68 static 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
69 {
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
70 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
71
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
72 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
73 if (!val)
161
67b08ecf5c1e val: internal val allocation function should return errnos
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 160
diff changeset
74 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
75
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
76 val->type = type;
156
9e156cc8bdb8 val: add support for static vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 153
diff changeset
77 val->static_alloc = false;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
78
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
79 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
80
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 return val;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
82 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
83
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
84 void val_free(struct val *val)
8
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 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
87 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
88
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
89 switch (val->type) {
342
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
90 case VT_NULL:
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
91 case VT_INT:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
92 case VT_BOOL:
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
93 case VT_CHAR:
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
94 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
95 case VT_STR:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
96 case VT_SYM:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
97 str_putref(val->str);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
98 break;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
99 case VT_CONS:
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
100 val_putref(val->cons.head);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
101 val_putref(val->cons.tail);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
102 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
103 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
104
160
11d55479b0e1 val: use the libjeffpc slab allocator API instead of libumem
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 158
diff changeset
105 mem_cache_free(val_cache, val);
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
106 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
107
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
108 #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
109 struct val *val_alloc_##fxn(ctype v) \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
110 { \
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
111 struct val *val; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
112 \
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
113 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
114 if (IS_ERR(val)) { \
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
115 putref(v); \
161
67b08ecf5c1e val: internal val allocation function should return errnos
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 160
diff changeset
116 return val; \
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
117 } \
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
118 \
153
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
119 val->_set_##valelem = v; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
120 \
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
121 return val; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
122 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
123
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
124 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
125 DEF_VAL_SET(str, VT_STR, str, struct str *, str_putref)
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
126 DEF_VAL_SET(sym, VT_SYM, str, struct str *, str_putref)
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
127 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
128
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
129 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
130 {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
131 if (i < ARRAY_LEN(val_ints)) {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
132 /*
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
133 * 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
134 * 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
135 * 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
136 * 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
137 * as static.
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
138 */
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
139 return (struct val *) &val_ints[i];
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
140 }
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
141
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
142 return val_alloc_int_heap(i);
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
143 }
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
144
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
145 struct val *val_alloc_bool(bool b)
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
146 {
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
147 const struct val *ret;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
148
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
149 ret = b ? &val_true : &val_false;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
150
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
151 /*
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
152 * 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
153 * 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
154 * 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
155 * 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
156 * as static.
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
157 */
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
158 return (struct val *) ret;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
159 }
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
160
342
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
161 struct val *val_alloc_null(void)
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
162 {
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
163 /*
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
164 * 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
165 * 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
166 * 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
167 * 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
168 * as static.
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
169 */
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
170 return (struct val *) &val_null;
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
171 }
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
172
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
173 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
174 {
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
175 struct val *val;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
176
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
177 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
178 if (IS_ERR(val)) {
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
179 val_putref(head);
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
180 val_putref(tail);
161
67b08ecf5c1e val: internal val allocation function should return errnos
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 160
diff changeset
181 return val;
242
aa5db4b6b24f val: free references passed to val_alloc_* on error
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 174
diff changeset
182 }
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
183
153
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
184 val->_set_cons.head = head;
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
185 val->_set_cons.tail = tail;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
186
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
187 return val;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
188 }
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
189
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
190 void val_dump_file(FILE *out, struct val *val, int indent)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
191 {
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
192 if (!val)
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
193 return;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
194
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
195 switch (val->type) {
342
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
196 case VT_NULL:
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
197 fprintf(out, "%*snull\n", indent, "");
d9ecc4ea68e1 val: introduce VT_NULL
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 243
diff changeset
198 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
199 case VT_STR:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
200 case VT_SYM:
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
201 fprintf(out, "%*s'%s'\n", indent, "", str_cstr(val->str));
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
202 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
203 case VT_INT:
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
204 fprintf(out, "%*s%"PRIu64"\n", indent, "", val->i);
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
205 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
206 case VT_BOOL:
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
207 fprintf(out, "%*s%s\n", indent, "",
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
208 val->b ? "true" : "false");
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
209 break;
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
210 case VT_CHAR:
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
211 if (isprint(val->i))
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
212 fprintf(out, "%*s\\u%04"PRIX64": '%c'\n",
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
213 indent, "", val->i, (char) val->i);
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
214 else
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
215 fprintf(out, "%*s\\u%04"PRIX64"\n", indent,
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
216 "", val->i);
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
217 break;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
218 case VT_CONS:
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
219 fprintf(out, "%*scons head:\n", indent, "");
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
220 val_dump(val->cons.head, indent + 2);
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
221 fprintf(out, "%*scons tail:\n", indent, "");
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
222 val_dump(val->cons.tail, indent + 2);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
223 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
224 default:
243
482885766614 val: add val_dump_file
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 242
diff changeset
225 fprintf(out, "Unknown type %d\n", val->type);
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
226 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
227 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
228 }