Mercurial > libjeffpc
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 |
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 } |