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