4223
|
1 #include "config.h"
|
|
2 #include "IO.h"
|
|
3 #include "Str.h"
|
|
4 #include "val.h"
|
|
5 #include "xmalloc.h"
|
|
6
|
|
7 #include <stdlib.h>
|
|
8 #include <assert.h>
|
|
9
|
|
10 void v_init(struct val *v) {
|
|
11 v->ko = ko_new();
|
|
12 v->type = V_UNDEF;
|
|
13 }
|
|
14
|
|
15 void v_end(struct val *v) {
|
|
16 assert(v != NULL);
|
|
17 V_xxx_OFF(v);
|
|
18 ko_delete(v->ko);
|
|
19 v->type = V_UNDEF;
|
|
20 }
|
|
21
|
|
22 int v_cmp_ls(struct val *v, struct val *b) {
|
|
23 if (V_LIST_P(v) && V_LIST_P(b)) {
|
|
24 return li_cmp(v->magic.list, b->magic.list);
|
|
25 }
|
|
26 V_STR(v);
|
|
27 V_STR(b);
|
|
28 return ko_cmp(v->ko, b->ko);
|
|
29 }
|
|
30
|
|
31 void v_ok_str(struct val *v) {
|
|
32 if (V_STR_P(v)) {
|
|
33 return;
|
|
34 }
|
|
35
|
|
36 if (V_EXT_P(v)) {
|
|
37 ko_cpy_s(v->ko, io_name(v->magic.ext, NULL));
|
|
38 } else if (V_LIST_P(v)) {
|
|
39 size_t i;
|
|
40 struct list *li = v->magic.list;
|
|
41 struct val *cur;
|
|
42
|
|
43 ko_zero(v->ko);
|
|
44 for (i = 0; i < li_length(li); ++i) {
|
|
45 cur = li_at(li, i);
|
|
46 V_STR(cur);
|
|
47 ko_cat(v->ko, cur->ko);
|
|
48 }
|
|
49 } else if (V_NUM_P(v)) {
|
|
50 ko_num(v->ko, v->num);
|
|
51 } else if (V_SUB_P(v)) {
|
|
52 v_ok_num(v);
|
|
53 ko_num(v->ko, v->num);
|
|
54 } else {
|
|
55 ko_zero(v->ko);
|
|
56 }
|
|
57 v->type |= V_STR_K;
|
|
58 }
|
|
59
|
|
60 void v_ok_num(struct val *v) {
|
|
61 if (V_NUM_P(v)) {
|
|
62 return;
|
|
63 }
|
|
64
|
|
65 if (V_EXT_P(v)) {
|
|
66 v->num = __LINE__;
|
|
67 } else if (V_SUB_P(v)) {
|
|
68 v->num = sub_id(v->magic.sub);
|
|
69 } else if (V_LIST_P(v)) {
|
|
70 size_t i;
|
|
71
|
|
72 v->num = 0.0;
|
|
73 for (i = 0; i < li_length(v->magic.list); ++i) {
|
|
74 V_NUM(li_at(v->magic.list, i));
|
|
75 v->num += li_at(v->magic.list, i)->num;
|
|
76 }
|
|
77 } else if (V_STR_P(v)) {
|
|
78 v->num = strtod(ko_szp(v->ko), NULL);
|
|
79 } else {
|
|
80 v->num = 0.0;
|
|
81 }
|
|
82 v->type |= V_NUM_K;
|
|
83 }
|
|
84
|
|
85 int v_true(const struct val *v) {
|
|
86 if (V_EXT_P(v) || V_SUB_P(v)) {
|
|
87 return 1;
|
|
88 }
|
|
89 if (V_LIST_P(v)) {
|
|
90 return li_length(v->magic.list) != 0;
|
|
91 }
|
|
92 if (V_STR_P(v)) {
|
|
93 return ko_length(v->ko) != 0 && (ko_length(v->ko) > 1u || ko_at(v->ko, 0) != '0');
|
|
94 }
|
|
95 if (V_NUM_P(v)) {
|
|
96 return v->num != 0.0;
|
|
97 }
|
|
98 return 0;
|
|
99 }
|
|
100
|
|
101 void v_iniset(struct val *dst, const struct val *src) {
|
|
102 v_init(dst);
|
|
103 v_set(dst, src);
|
|
104 }
|
|
105
|
|
106 void v_set(struct val *dst, const struct val *src) {
|
|
107 assert(src != NULL);
|
|
108
|
|
109 V_xxx_OFF(dst);
|
|
110 dst->type = V_UNDEF;
|
|
111
|
|
112 if (V_SUB_P(src)) {
|
|
113 dst->magic.sub = sub_incr(src->magic.sub);
|
|
114 dst->type |= V_SUB_K;
|
|
115 } else if (V_EXT_P(src)) {
|
|
116 dst->magic.ext = io_incr(src->magic.ext);
|
|
117 dst->type |= V_EXT_K;
|
|
118 } else if (V_LIST_P(src)) {
|
|
119 dst->magic.list = li_dup(src->magic.list);
|
|
120 dst->type |= V_LIST_K;
|
|
121 }
|
|
122
|
|
123 if (V_STR_P(src)) {
|
|
124 ko_cpy(dst->ko, src->ko);
|
|
125 dst->type |= V_STR_K;
|
|
126 }
|
|
127 if (V_NUM_P(src)) {
|
|
128 dst->num = src->num;
|
|
129 dst->type |= V_NUM_K;
|
|
130 }
|
|
131 }
|
|
132
|
|
133 void v_set_n(struct val *v, double d) {
|
|
134 V_xxx_OFF(v);
|
|
135 v->num = d;
|
|
136 v->type = V_NUM_K;
|
|
137 }
|
|
138
|
|
139 void v_set_s(struct val *v, const String *s) {
|
|
140 V_xxx_OFF(v);
|
|
141 ko_cpy_m(v->ko, St_ptr(s), St_len(s));
|
|
142 v->type = V_STR_K;
|
|
143 }
|
|
144
|
|
145 void v_set_m(struct val *v, const void *p, size_t n) {
|
|
146 V_xxx_OFF(v);
|
|
147 ko_cpy_m(v->ko, p, n);
|
|
148 v->type = V_STR_K;
|
|
149 }
|
|
150
|
|
151 void v_set_io(struct val *v, IO *io) {
|
|
152 V_xxx_OFF(v);
|
|
153 v->magic.ext = io_incr(io);
|
|
154 v->type = V_EXT_K;
|
|
155 }
|
|
156
|
|
157 void v_set_sub(struct val *v, struct sub *s) {
|
|
158 V_xxx_OFF(v);
|
|
159 v->magic.sub = sub_incr(s);
|
|
160 v->type = V_SUB_K;
|
|
161 }
|
|
162
|
|
163 void v_set_undef(struct val *v) {
|
|
164 V_xxx_OFF(v);
|
|
165 v->type = V_UNDEF;
|
|
166 }
|
|
167
|
|
168 void v_cat(struct val *dst, struct val *src) {
|
|
169 if (V_LIST_P(dst) && V_LIST_P(src)) {
|
|
170 li_append(dst->magic.list, src->magic.list);
|
|
171 return;
|
|
172 }
|
|
173
|
|
174 V_STR(src);
|
|
175 V_STR(dst);
|
|
176 V_xxx_OFF(dst);
|
|
177 ko_cat(dst->ko, src->ko);
|
|
178 dst->type = V_STR_K;
|
|
179 }
|
|
180
|
|
181 void v_cat_m(struct val *v, const void *p, size_t n) {
|
|
182 V_STR(v);
|
|
183 V_xxx_OFF(v);
|
|
184 ko_cat_m(v->ko, p, n);
|
|
185 v->type = V_STR_K;
|
|
186 }
|
|
187
|
|
188 void v_cat_s(struct val *v, const String *s) {
|
|
189 v_cat_m(v, St_ptr(s), St_len(s));
|
|
190 }
|
|
191
|
|
192 void v_cat_c(struct val *v, char c) {
|
|
193 v_cat_m(v, &c, 1);
|
|
194 }
|
|
195
|
|
196 struct val *v_undef(void) {
|
|
197 struct val *v;
|
|
198 v = xmalloc(1, sizeof *v);
|
|
199 v_init(v);
|
|
200 return v;
|
|
201 }
|
|
202
|
|
203 void v_delete(struct val *v) {
|
|
204 v_end(v);
|
|
205 xfree(v);
|
|
206 }
|
|
207
|
|
208 const char *v_sptr(struct val *v, size_t *l) {
|
|
209 V_STR(v);
|
|
210 if (l) {
|
|
211 *l = ko_length(v->ko);
|
|
212 }
|
|
213 return ko_ptr(v->ko);
|
|
214 }
|
|
215
|
|
216 struct kork *v_kork(struct val *v) {
|
|
217 V_STR(v);
|
|
218 return v->ko;
|
|
219 }
|