Adding upstream version 6.02~pre8+dfsg.
[syslinux-debian/hramrach.git] / com32 / gpllib / zzjson / zzjson_create.c
blob7e6bd5bd003dffef134de3e8717c2acfaf0c8023
1 /* JSON Create ZZJSON structures
2 * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
3 * License: GNU Lesser General Public License version 2.1
4 */
6 #include "zzjson.h"
7 #include <stdlib.h>
8 #include <string.h>
9 #include <stdarg.h>
11 #ifdef CONFIG_NO_ERROR_MESSAGES
12 #define ERROR(x...)
13 #else
14 #define ERROR(x...) config->error(config->ehandle, ##x)
15 #endif
16 #define MEMERROR() ERROR("out of memory")
18 static ZZJSON *zzjson_create_templ(ZZJSON_CONFIG *config, ZZJSON_TYPE type) {
19 ZZJSON *zzjson = config->calloc(1, sizeof(ZZJSON));
20 if (!zzjson) MEMERROR();
21 else zzjson->type = type;
22 return zzjson;
25 ZZJSON *zzjson_create_true(ZZJSON_CONFIG *config) {
26 return zzjson_create_templ(config, ZZJSON_TRUE);
29 ZZJSON *zzjson_create_false(ZZJSON_CONFIG *config) {
30 return zzjson_create_templ(config, ZZJSON_FALSE);
33 ZZJSON *zzjson_create_null(ZZJSON_CONFIG *config) {
34 return zzjson_create_templ(config, ZZJSON_NULL);
37 ZZJSON *zzjson_create_number_d(ZZJSON_CONFIG *config, double d) {
38 ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_DOUBLE);
39 if (zzjson)
40 zzjson->value.number.val.dval = d;
41 return zzjson;
44 ZZJSON *zzjson_create_number_i(ZZJSON_CONFIG *config, long long i) {
45 ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_NEGINT);
46 if (zzjson) {
47 zzjson->type = i<0LL ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
48 zzjson->value.number.val.ival = llabs(i);
50 return zzjson;
53 /* sdup mimics strdup, but avoids having another function pointer in config */
54 static char *sdup(ZZJSON_CONFIG *config, char *s) {
55 size_t slen = strlen(s)+1;
56 char *scopy = config->malloc(slen);
58 if (!scopy) MEMERROR();
59 else memcpy(scopy, s, slen);
60 return scopy;
63 ZZJSON *zzjson_create_string(ZZJSON_CONFIG *config, char *s) {
64 ZZJSON *zzjson = NULL;
65 char *scopy;
67 if (!(scopy = sdup(config,s))) return zzjson;
69 if ((zzjson = zzjson_create_templ(config, ZZJSON_STRING)))
70 zzjson->value.string.string = scopy;
71 else
72 config->free(scopy);
74 return zzjson;
77 ZZJSON *zzjson_create_array(ZZJSON_CONFIG *config, ...) {
78 ZZJSON *zzjson, *retval, *val;
79 va_list ap;
81 if (!(zzjson = zzjson_create_templ(config, ZZJSON_ARRAY))) return zzjson;
82 retval = zzjson;
84 va_start(ap, config);
85 val = va_arg(ap, ZZJSON *);
86 while (val) {
87 zzjson->value.array.val = val;
88 val = va_arg(ap, ZZJSON *);
90 if (val) {
91 ZZJSON *next = zzjson_create_templ(config, ZZJSON_ARRAY);
92 if (!next) {
93 while (retval) {
94 next = retval->next;
95 config->free(retval);
96 retval = next;
98 break;
100 zzjson->next = next;
101 zzjson = next;
104 va_end(ap);
105 return retval;
108 ZZJSON *zzjson_create_object(ZZJSON_CONFIG *config, ...) {
109 ZZJSON *zzjson, *retval, *val;
110 char *label, *labelcopy;
111 va_list ap;
113 if (!(zzjson = zzjson_create_templ(config, ZZJSON_OBJECT))) return zzjson;
114 retval = zzjson;
116 va_start(ap, config);
117 label = va_arg(ap, char *);
118 while (label) {
119 val = va_arg(ap, ZZJSON *);
120 labelcopy = sdup(config, label);
122 if (!labelcopy) {
123 zzjson_free(config, retval);
124 retval = NULL;
125 break;
128 zzjson->value.object.label = labelcopy;
129 zzjson->value.object.val = val;
131 label = va_arg(ap, char *);
133 if (label) {
134 ZZJSON *next = zzjson_create_templ(config, ZZJSON_OBJECT);
135 if (!next) {
136 while (retval) {
137 next = retval->next;
138 config->free(retval->value.object.label);
139 config->free(retval);
140 retval = next;
142 break;
144 zzjson->next = next;
145 zzjson = next;
148 va_end(ap);
149 return retval;
152 ZZJSON *zzjson_array_prepend(ZZJSON_CONFIG *config, ZZJSON *array,
153 ZZJSON *val) {
154 ZZJSON *zzjson;
156 if (!array->value.array.val) { /* empty array */
157 array->value.array.val = val;
158 return array;
161 zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
162 if (zzjson) {
163 zzjson->value.array.val = val;
164 zzjson->next = array;
166 return zzjson;
169 ZZJSON *zzjson_array_append(ZZJSON_CONFIG *config, ZZJSON *array,
170 ZZJSON *val) {
171 ZZJSON *retval = array, *zzjson;
173 if (!array->value.array.val) { /* empty array */
174 array->value.array.val = val;
175 return array;
178 zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
179 if (!zzjson) return NULL;
181 while (array->next) array = array->next;
183 zzjson->value.array.val = val;
184 array->next = zzjson;
186 return retval;
189 ZZJSON *zzjson_object_prepend(ZZJSON_CONFIG *config, ZZJSON *object,
190 char *label, ZZJSON *val) {
191 ZZJSON *zzjson = NULL;
192 char *labelcopy = sdup(config, label);
194 if (!labelcopy) return zzjson;
196 if (!object->value.object.label) { /* empty object */
197 object->value.object.label = labelcopy;
198 object->value.object.val = val;
199 return object;
202 zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
203 if (zzjson) {
204 zzjson->value.object.label = labelcopy;
205 zzjson->value.object.val = val;
206 zzjson->next = object;
207 } else {
208 config->free(labelcopy);
210 return zzjson;
213 ZZJSON *zzjson_object_append(ZZJSON_CONFIG *config, ZZJSON *object,
214 char *label, ZZJSON *val) {
215 ZZJSON *retval = object, *zzjson = NULL;
216 char *labelcopy = sdup(config, label);
218 if (!labelcopy) return zzjson;
220 if (!object->value.object.label) { /* empty object */
221 object->value.object.label = labelcopy;
222 object->value.object.val = val;
223 return object;
226 zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
227 if (!zzjson) {
228 config->free(labelcopy);
229 return NULL;
232 while (object->next) object = object->next;
234 zzjson->value.object.label = labelcopy;
235 zzjson->value.object.val = val;
236 object->next = zzjson;
238 return retval;