Blame


1 18824b58 2008-08-03 rsc #include "a.h"
2 18824b58 2008-08-03 rsc
3 18824b58 2008-08-03 rsc static Json *parsevalue(char**);
4 18824b58 2008-08-03 rsc
5 18824b58 2008-08-03 rsc static char*
6 18824b58 2008-08-03 rsc wskip(char *p)
7 18824b58 2008-08-03 rsc {
8 18824b58 2008-08-03 rsc while(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\v')
9 18824b58 2008-08-03 rsc p++;
10 18824b58 2008-08-03 rsc return p;
11 18824b58 2008-08-03 rsc }
12 18824b58 2008-08-03 rsc
13 18824b58 2008-08-03 rsc static int
14 18824b58 2008-08-03 rsc ishex(int c)
15 18824b58 2008-08-03 rsc {
16 18824b58 2008-08-03 rsc return '0' <= c && c <= '9' ||
17 18824b58 2008-08-03 rsc 'a' <= c && c <= 'f' ||
18 18824b58 2008-08-03 rsc 'A' <= c && c <= 'F';
19 18824b58 2008-08-03 rsc }
20 18824b58 2008-08-03 rsc
21 18824b58 2008-08-03 rsc static Json*
22 18824b58 2008-08-03 rsc newjval(int type)
23 18824b58 2008-08-03 rsc {
24 18824b58 2008-08-03 rsc Json *v;
25 18824b58 2008-08-03 rsc
26 18824b58 2008-08-03 rsc v = emalloc(sizeof *v);
27 18824b58 2008-08-03 rsc v->ref = 1;
28 18824b58 2008-08-03 rsc v->type = type;
29 18824b58 2008-08-03 rsc return v;
30 18824b58 2008-08-03 rsc }
31 18824b58 2008-08-03 rsc
32 18824b58 2008-08-03 rsc static Json*
33 18824b58 2008-08-03 rsc badjval(char **pp, char *fmt, ...)
34 18824b58 2008-08-03 rsc {
35 18824b58 2008-08-03 rsc char buf[ERRMAX];
36 18824b58 2008-08-03 rsc va_list arg;
37 18824b58 2008-08-03 rsc
38 18824b58 2008-08-03 rsc if(fmt){
39 18824b58 2008-08-03 rsc va_start(arg, fmt);
40 18824b58 2008-08-03 rsc vsnprint(buf, sizeof buf, fmt, arg);
41 18824b58 2008-08-03 rsc va_end(arg);
42 18824b58 2008-08-03 rsc errstr(buf, sizeof buf);
43 18824b58 2008-08-03 rsc }
44 18824b58 2008-08-03 rsc *pp = nil;
45 18824b58 2008-08-03 rsc return nil;
46 18824b58 2008-08-03 rsc }
47 18824b58 2008-08-03 rsc
48 18824b58 2008-08-03 rsc static char*
49 18824b58 2008-08-03 rsc _parsestring(char **pp, int *len)
50 18824b58 2008-08-03 rsc {
51 18824b58 2008-08-03 rsc char *p, *q, *w, *s, *r;
52 18824b58 2008-08-03 rsc char buf[5];
53 18824b58 2008-08-03 rsc Rune rune;
54 18824b58 2008-08-03 rsc
55 18824b58 2008-08-03 rsc p = wskip(*pp);
56 18824b58 2008-08-03 rsc if(*p != '"'){
57 18824b58 2008-08-03 rsc badjval(pp, "missing opening quote for string");
58 18824b58 2008-08-03 rsc return nil;
59 18824b58 2008-08-03 rsc }
60 18824b58 2008-08-03 rsc for(q=p+1; *q && *q != '\"'; q++){
61 18824b58 2008-08-03 rsc if(*q == '\\' && *(q+1) != 0)
62 18824b58 2008-08-03 rsc q++;
63 18824b58 2008-08-03 rsc if((*q & 0xFF) < 0x20){ // no control chars
64 18824b58 2008-08-03 rsc badjval(pp, "control char in string");
65 18824b58 2008-08-03 rsc return nil;
66 18824b58 2008-08-03 rsc }
67 18824b58 2008-08-03 rsc }
68 18824b58 2008-08-03 rsc if(*q == 0){
69 18824b58 2008-08-03 rsc badjval(pp, "no closing quote in string");
70 18824b58 2008-08-03 rsc return nil;
71 18824b58 2008-08-03 rsc }
72 18824b58 2008-08-03 rsc s = emalloc(q - p);
73 18824b58 2008-08-03 rsc w = s;
74 18824b58 2008-08-03 rsc for(r=p+1; r<q; ){
75 18824b58 2008-08-03 rsc if(*r != '\\'){
76 18824b58 2008-08-03 rsc *w++ = *r++;
77 18824b58 2008-08-03 rsc continue;
78 18824b58 2008-08-03 rsc }
79 18824b58 2008-08-03 rsc r++;
80 18824b58 2008-08-03 rsc switch(*r){
81 18824b58 2008-08-03 rsc default:
82 18824b58 2008-08-03 rsc free(s);
83 18824b58 2008-08-03 rsc badjval(pp, "bad escape \\%c in string", *r&0xFF);
84 18824b58 2008-08-03 rsc return nil;
85 18824b58 2008-08-03 rsc case '\\':
86 18824b58 2008-08-03 rsc case '\"':
87 18824b58 2008-08-03 rsc case '/':
88 18824b58 2008-08-03 rsc *w++ = *r++;
89 18824b58 2008-08-03 rsc break;
90 18824b58 2008-08-03 rsc case 'b':
91 18824b58 2008-08-03 rsc *w++ = '\b';
92 18824b58 2008-08-03 rsc r++;
93 18824b58 2008-08-03 rsc break;
94 18824b58 2008-08-03 rsc case 'f':
95 18824b58 2008-08-03 rsc *w++ = '\f';
96 18824b58 2008-08-03 rsc r++;
97 18824b58 2008-08-03 rsc break;
98 18824b58 2008-08-03 rsc case 'n':
99 18824b58 2008-08-03 rsc *w++ = '\n';
100 18824b58 2008-08-03 rsc r++;
101 18824b58 2008-08-03 rsc break;
102 18824b58 2008-08-03 rsc case 'r':
103 18824b58 2008-08-03 rsc *w++ = '\r';
104 18824b58 2008-08-03 rsc r++;
105 18824b58 2008-08-03 rsc break;
106 18824b58 2008-08-03 rsc case 't':
107 18824b58 2008-08-03 rsc *w++ = '\t';
108 18824b58 2008-08-03 rsc r++;
109 18824b58 2008-08-03 rsc break;
110 18824b58 2008-08-03 rsc case 'u':
111 18824b58 2008-08-03 rsc r++;
112 18824b58 2008-08-03 rsc if(!ishex(r[0]) || !ishex(r[1]) || !ishex(r[2]) || !ishex(r[3])){
113 18824b58 2008-08-03 rsc free(s);
114 18824b58 2008-08-03 rsc badjval(pp, "bad hex \\u%.4s", r);
115 18824b58 2008-08-03 rsc return nil;
116 18824b58 2008-08-03 rsc }
117 18824b58 2008-08-03 rsc memmove(buf, r, 4);
118 18824b58 2008-08-03 rsc buf[4] = 0;
119 18824b58 2008-08-03 rsc rune = strtol(buf, 0, 16);
120 18824b58 2008-08-03 rsc if(rune == 0){
121 18824b58 2008-08-03 rsc free(s);
122 18824b58 2008-08-03 rsc badjval(pp, "\\u0000 in string");
123 18824b58 2008-08-03 rsc return nil;
124 18824b58 2008-08-03 rsc }
125 18824b58 2008-08-03 rsc r += 4;
126 18824b58 2008-08-03 rsc w += runetochar(w, &rune);
127 18824b58 2008-08-03 rsc break;
128 18824b58 2008-08-03 rsc }
129 18824b58 2008-08-03 rsc }
130 18824b58 2008-08-03 rsc *w = 0;
131 18824b58 2008-08-03 rsc if(len)
132 18824b58 2008-08-03 rsc *len = w - s;
133 18824b58 2008-08-03 rsc *pp = q+1;
134 18824b58 2008-08-03 rsc return s;
135 18824b58 2008-08-03 rsc }
136 18824b58 2008-08-03 rsc
137 18824b58 2008-08-03 rsc static Json*
138 18824b58 2008-08-03 rsc parsenumber(char **pp)
139 18824b58 2008-08-03 rsc {
140 18824b58 2008-08-03 rsc char *p, *q;
141 18824b58 2008-08-03 rsc char *t;
142 18824b58 2008-08-03 rsc double d;
143 18824b58 2008-08-03 rsc Json *v;
144 18824b58 2008-08-03 rsc
145 18824b58 2008-08-03 rsc /* -?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))?([Ee][-+]?[0-9]+) */
146 18824b58 2008-08-03 rsc p = wskip(*pp);
147 18824b58 2008-08-03 rsc q = p;
148 18824b58 2008-08-03 rsc if(*q == '-')
149 18824b58 2008-08-03 rsc q++;
150 18824b58 2008-08-03 rsc if(*q == '0')
151 18824b58 2008-08-03 rsc q++;
152 18824b58 2008-08-03 rsc else{
153 18824b58 2008-08-03 rsc if(*q < '1' || *q > '9')
154 18824b58 2008-08-03 rsc return badjval(pp, "invalid number");
155 18824b58 2008-08-03 rsc while('0' <= *q && *q <= '9')
156 18824b58 2008-08-03 rsc q++;
157 18824b58 2008-08-03 rsc }
158 18824b58 2008-08-03 rsc if(*q == '.'){
159 18824b58 2008-08-03 rsc q++;
160 18824b58 2008-08-03 rsc if(*q < '0' || *q > '9')
161 18824b58 2008-08-03 rsc return badjval(pp, "invalid number");
162 18824b58 2008-08-03 rsc while('0' <= *q && *q <= '9')
163 18824b58 2008-08-03 rsc q++;
164 18824b58 2008-08-03 rsc }
165 18824b58 2008-08-03 rsc if(*q == 'e' || *q == 'E'){
166 18824b58 2008-08-03 rsc q++;
167 18824b58 2008-08-03 rsc if(*q == '-' || *q == '+')
168 18824b58 2008-08-03 rsc q++;
169 18824b58 2008-08-03 rsc if(*q < '0' || *q > '9')
170 18824b58 2008-08-03 rsc return badjval(pp, "invalid number");
171 18824b58 2008-08-03 rsc while('0' <= *q && *q <= '9')
172 18824b58 2008-08-03 rsc q++;
173 18824b58 2008-08-03 rsc }
174 18824b58 2008-08-03 rsc
175 18824b58 2008-08-03 rsc t = emalloc(q-p+1);
176 18824b58 2008-08-03 rsc memmove(t, p, q-p);
177 18824b58 2008-08-03 rsc t[q-p] = 0;
178 18824b58 2008-08-03 rsc errno = 0;
179 18824b58 2008-08-03 rsc d = strtod(t, nil);
180 18824b58 2008-08-03 rsc if(errno != 0){
181 18824b58 2008-08-03 rsc free(t);
182 18824b58 2008-08-03 rsc return badjval(pp, nil);
183 18824b58 2008-08-03 rsc }
184 18824b58 2008-08-03 rsc free(t);
185 18824b58 2008-08-03 rsc v = newjval(Jnumber);
186 18824b58 2008-08-03 rsc v->number = d;
187 18824b58 2008-08-03 rsc *pp = q;
188 18824b58 2008-08-03 rsc return v;
189 18824b58 2008-08-03 rsc }
190 18824b58 2008-08-03 rsc
191 18824b58 2008-08-03 rsc static Json*
192 18824b58 2008-08-03 rsc parsestring(char **pp)
193 18824b58 2008-08-03 rsc {
194 18824b58 2008-08-03 rsc char *s;
195 18824b58 2008-08-03 rsc Json *v;
196 18824b58 2008-08-03 rsc int len;
197 18824b58 2008-08-03 rsc
198 18824b58 2008-08-03 rsc s = _parsestring(pp, &len);
199 18824b58 2008-08-03 rsc if(s == nil)
200 18824b58 2008-08-03 rsc return nil;
201 18824b58 2008-08-03 rsc v = newjval(Jstring);
202 18824b58 2008-08-03 rsc v->string = s;
203 18824b58 2008-08-03 rsc v->len = len;
204 18824b58 2008-08-03 rsc return v;
205 18824b58 2008-08-03 rsc }
206 18824b58 2008-08-03 rsc
207 18824b58 2008-08-03 rsc static Json*
208 18824b58 2008-08-03 rsc parsename(char **pp)
209 18824b58 2008-08-03 rsc {
210 18824b58 2008-08-03 rsc if(strncmp(*pp, "true", 4) == 0){
211 18824b58 2008-08-03 rsc *pp += 4;
212 18824b58 2008-08-03 rsc return newjval(Jtrue);
213 18824b58 2008-08-03 rsc }
214 18824b58 2008-08-03 rsc if(strncmp(*pp, "false", 5) == 0){
215 18824b58 2008-08-03 rsc *pp += 5;
216 18824b58 2008-08-03 rsc return newjval(Jfalse);
217 18824b58 2008-08-03 rsc }
218 18824b58 2008-08-03 rsc if(strncmp(*pp, "null", 4) == 0){
219 18824b58 2008-08-03 rsc *pp += 4;
220 18824b58 2008-08-03 rsc return newjval(Jtrue);
221 18824b58 2008-08-03 rsc }
222 18824b58 2008-08-03 rsc return badjval(pp, "invalid name");
223 18824b58 2008-08-03 rsc }
224 18824b58 2008-08-03 rsc
225 18824b58 2008-08-03 rsc static Json*
226 18824b58 2008-08-03 rsc parsearray(char **pp)
227 18824b58 2008-08-03 rsc {
228 18824b58 2008-08-03 rsc char *p;
229 18824b58 2008-08-03 rsc Json *v;
230 18824b58 2008-08-03 rsc
231 18824b58 2008-08-03 rsc p = *pp;
232 18824b58 2008-08-03 rsc if(*p++ != '[')
233 18824b58 2008-08-03 rsc return badjval(pp, "missing bracket for array");
234 18824b58 2008-08-03 rsc v = newjval(Jarray);
235 18824b58 2008-08-03 rsc p = wskip(p);
236 18824b58 2008-08-03 rsc if(*p != ']'){
237 18824b58 2008-08-03 rsc for(;;){
238 18824b58 2008-08-03 rsc if(v->len%32 == 0)
239 18824b58 2008-08-03 rsc v->value = erealloc(v->value, (v->len+32)*sizeof v->value[0]);
240 18824b58 2008-08-03 rsc if((v->value[v->len++] = parsevalue(&p)) == nil){
241 18824b58 2008-08-03 rsc jclose(v);
242 18824b58 2008-08-03 rsc return badjval(pp, nil);
243 18824b58 2008-08-03 rsc }
244 18824b58 2008-08-03 rsc p = wskip(p);
245 18824b58 2008-08-03 rsc if(*p == ']')
246 18824b58 2008-08-03 rsc break;
247 18824b58 2008-08-03 rsc if(*p++ != ','){
248 18824b58 2008-08-03 rsc jclose(v);
249 18824b58 2008-08-03 rsc return badjval(pp, "missing comma in array");
250 18824b58 2008-08-03 rsc }
251 18824b58 2008-08-03 rsc }
252 18824b58 2008-08-03 rsc }
253 18824b58 2008-08-03 rsc p++;
254 18824b58 2008-08-03 rsc *pp = p;
255 18824b58 2008-08-03 rsc return v;
256 18824b58 2008-08-03 rsc }
257 18824b58 2008-08-03 rsc
258 18824b58 2008-08-03 rsc static Json*
259 18824b58 2008-08-03 rsc parseobject(char **pp)
260 18824b58 2008-08-03 rsc {
261 18824b58 2008-08-03 rsc char *p;
262 18824b58 2008-08-03 rsc Json *v;
263 18824b58 2008-08-03 rsc
264 18824b58 2008-08-03 rsc p = *pp;
265 18824b58 2008-08-03 rsc if(*p++ != '{')
266 18824b58 2008-08-03 rsc return badjval(pp, "missing brace for object");
267 18824b58 2008-08-03 rsc v = newjval(Jobject);
268 18824b58 2008-08-03 rsc p = wskip(p);
269 18824b58 2008-08-03 rsc if(*p != '}'){
270 18824b58 2008-08-03 rsc for(;;){
271 18824b58 2008-08-03 rsc if(v->len%32 == 0){
272 18824b58 2008-08-03 rsc v->name = erealloc(v->name, (v->len+32)*sizeof v->name[0]);
273 18824b58 2008-08-03 rsc v->value = erealloc(v->value, (v->len+32)*sizeof v->value[0]);
274 18824b58 2008-08-03 rsc }
275 18824b58 2008-08-03 rsc if((v->name[v->len++] = _parsestring(&p, nil)) == nil){
276 18824b58 2008-08-03 rsc jclose(v);
277 18824b58 2008-08-03 rsc return badjval(pp, nil);
278 18824b58 2008-08-03 rsc }
279 18824b58 2008-08-03 rsc p = wskip(p);
280 18824b58 2008-08-03 rsc if(*p++ != ':'){
281 18824b58 2008-08-03 rsc jclose(v);
282 18824b58 2008-08-03 rsc return badjval(pp, "missing colon in object");
283 18824b58 2008-08-03 rsc }
284 18824b58 2008-08-03 rsc if((v->value[v->len-1] = parsevalue(&p)) == nil){
285 18824b58 2008-08-03 rsc jclose(v);
286 18824b58 2008-08-03 rsc return badjval(pp, nil);
287 18824b58 2008-08-03 rsc }
288 18824b58 2008-08-03 rsc p = wskip(p);
289 18824b58 2008-08-03 rsc if(*p == '}')
290 18824b58 2008-08-03 rsc break;
291 18824b58 2008-08-03 rsc if(*p++ != ','){
292 18824b58 2008-08-03 rsc jclose(v);
293 18824b58 2008-08-03 rsc return badjval(pp, "missing comma in object");
294 18824b58 2008-08-03 rsc }
295 18824b58 2008-08-03 rsc }
296 18824b58 2008-08-03 rsc }
297 18824b58 2008-08-03 rsc p++;
298 18824b58 2008-08-03 rsc *pp = p;
299 18824b58 2008-08-03 rsc return v;
300 18824b58 2008-08-03 rsc }
301 18824b58 2008-08-03 rsc
302 18824b58 2008-08-03 rsc static Json*
303 18824b58 2008-08-03 rsc parsevalue(char **pp)
304 18824b58 2008-08-03 rsc {
305 18824b58 2008-08-03 rsc *pp = wskip(*pp);
306 18824b58 2008-08-03 rsc switch(**pp){
307 18824b58 2008-08-03 rsc case '0':
308 18824b58 2008-08-03 rsc case '1':
309 18824b58 2008-08-03 rsc case '2':
310 18824b58 2008-08-03 rsc case '3':
311 18824b58 2008-08-03 rsc case '4':
312 18824b58 2008-08-03 rsc case '5':
313 18824b58 2008-08-03 rsc case '6':
314 18824b58 2008-08-03 rsc case '7':
315 18824b58 2008-08-03 rsc case '8':
316 18824b58 2008-08-03 rsc case '9':
317 18824b58 2008-08-03 rsc case '-':
318 18824b58 2008-08-03 rsc return parsenumber(pp);
319 18824b58 2008-08-03 rsc case 't':
320 18824b58 2008-08-03 rsc case 'f':
321 18824b58 2008-08-03 rsc case 'n':
322 18824b58 2008-08-03 rsc return parsename(pp);
323 18824b58 2008-08-03 rsc case '\"':
324 18824b58 2008-08-03 rsc return parsestring(pp);
325 18824b58 2008-08-03 rsc case '[':
326 18824b58 2008-08-03 rsc return parsearray(pp);
327 18824b58 2008-08-03 rsc case '{':
328 18824b58 2008-08-03 rsc return parseobject(pp);
329 18824b58 2008-08-03 rsc default:
330 18824b58 2008-08-03 rsc return badjval(pp, "unexpected char <%02x>", **pp & 0xFF);
331 18824b58 2008-08-03 rsc }
332 18824b58 2008-08-03 rsc }
333 18824b58 2008-08-03 rsc
334 18824b58 2008-08-03 rsc Json*
335 18824b58 2008-08-03 rsc parsejson(char *text)
336 18824b58 2008-08-03 rsc {
337 18824b58 2008-08-03 rsc Json *v;
338 18824b58 2008-08-03 rsc
339 18824b58 2008-08-03 rsc v = parsevalue(&text);
340 18824b58 2008-08-03 rsc if(v && text && *wskip(text) != 0){
341 18824b58 2008-08-03 rsc jclose(v);
342 18824b58 2008-08-03 rsc werrstr("extra data in json");
343 18824b58 2008-08-03 rsc return nil;
344 18824b58 2008-08-03 rsc }
345 18824b58 2008-08-03 rsc return v;
346 18824b58 2008-08-03 rsc }
347 18824b58 2008-08-03 rsc
348 18824b58 2008-08-03 rsc void
349 18824b58 2008-08-03 rsc _printjval(Fmt *fmt, Json *v, int n)
350 18824b58 2008-08-03 rsc {
351 18824b58 2008-08-03 rsc int i;
352 18824b58 2008-08-03 rsc
353 18824b58 2008-08-03 rsc if(v == nil){
354 18824b58 2008-08-03 rsc fmtprint(fmt, "nil");
355 18824b58 2008-08-03 rsc return;
356 18824b58 2008-08-03 rsc }
357 18824b58 2008-08-03 rsc switch(v->type){
358 18824b58 2008-08-03 rsc case Jstring:
359 18824b58 2008-08-03 rsc fmtprint(fmt, "\"%s\"", v->string);
360 18824b58 2008-08-03 rsc break;
361 18824b58 2008-08-03 rsc case Jnumber:
362 18824b58 2008-08-03 rsc if(floor(v->number) == v->number)
363 18824b58 2008-08-03 rsc fmtprint(fmt, "%.0f", v->number);
364 18824b58 2008-08-03 rsc else
365 18824b58 2008-08-03 rsc fmtprint(fmt, "%g", v->number);
366 18824b58 2008-08-03 rsc break;
367 18824b58 2008-08-03 rsc case Jobject:
368 18824b58 2008-08-03 rsc fmtprint(fmt, "{");
369 18824b58 2008-08-03 rsc if(n >= 0)
370 18824b58 2008-08-03 rsc n++;
371 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
372 18824b58 2008-08-03 rsc if(n > 0)
373 18824b58 2008-08-03 rsc fmtprint(fmt, "\n%*s", n*4, "");
374 18824b58 2008-08-03 rsc fmtprint(fmt, "\"%s\" : ", v->name[i]);
375 18824b58 2008-08-03 rsc _printjval(fmt, v->value[i], n);
376 18824b58 2008-08-03 rsc fmtprint(fmt, ",");
377 18824b58 2008-08-03 rsc }
378 18824b58 2008-08-03 rsc if(n > 0){
379 18824b58 2008-08-03 rsc n--;
380 18824b58 2008-08-03 rsc if(v->len > 0)
381 18824b58 2008-08-03 rsc fmtprint(fmt, "\n%*s", n*4);
382 18824b58 2008-08-03 rsc }
383 18824b58 2008-08-03 rsc fmtprint(fmt, "}");
384 18824b58 2008-08-03 rsc break;
385 18824b58 2008-08-03 rsc case Jarray:
386 18824b58 2008-08-03 rsc fmtprint(fmt, "[");
387 18824b58 2008-08-03 rsc if(n >= 0)
388 18824b58 2008-08-03 rsc n++;
389 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
390 18824b58 2008-08-03 rsc if(n > 0)
391 18824b58 2008-08-03 rsc fmtprint(fmt, "\n%*s", n*4, "");
392 18824b58 2008-08-03 rsc _printjval(fmt, v->value[i], n);
393 18824b58 2008-08-03 rsc fmtprint(fmt, ",");
394 18824b58 2008-08-03 rsc }
395 18824b58 2008-08-03 rsc if(n > 0){
396 18824b58 2008-08-03 rsc n--;
397 18824b58 2008-08-03 rsc if(v->len > 0)
398 18824b58 2008-08-03 rsc fmtprint(fmt, "\n%*s", n*4);
399 18824b58 2008-08-03 rsc }
400 18824b58 2008-08-03 rsc fmtprint(fmt, "]");
401 18824b58 2008-08-03 rsc break;
402 18824b58 2008-08-03 rsc case Jtrue:
403 18824b58 2008-08-03 rsc fmtprint(fmt, "true");
404 18824b58 2008-08-03 rsc break;
405 18824b58 2008-08-03 rsc case Jfalse:
406 18824b58 2008-08-03 rsc fmtprint(fmt, "false");
407 18824b58 2008-08-03 rsc break;
408 18824b58 2008-08-03 rsc case Jnull:
409 18824b58 2008-08-03 rsc fmtprint(fmt, "null");
410 18824b58 2008-08-03 rsc break;
411 18824b58 2008-08-03 rsc }
412 18824b58 2008-08-03 rsc }
413 18824b58 2008-08-03 rsc
414 18824b58 2008-08-03 rsc /*
415 18824b58 2008-08-03 rsc void
416 18824b58 2008-08-03 rsc printjval(Json *v)
417 18824b58 2008-08-03 rsc {
418 18824b58 2008-08-03 rsc Fmt fmt;
419 18824b58 2008-08-03 rsc char buf[256];
420 18824b58 2008-08-03 rsc
421 18824b58 2008-08-03 rsc fmtfdinit(&fmt, 1, buf, sizeof buf);
422 18824b58 2008-08-03 rsc _printjval(&fmt, v, 0);
423 18824b58 2008-08-03 rsc fmtprint(&fmt, "\n");
424 18824b58 2008-08-03 rsc fmtfdflush(&fmt);
425 18824b58 2008-08-03 rsc }
426 18824b58 2008-08-03 rsc */
427 18824b58 2008-08-03 rsc
428 18824b58 2008-08-03 rsc int
429 18824b58 2008-08-03 rsc jsonfmt(Fmt *fmt)
430 18824b58 2008-08-03 rsc {
431 18824b58 2008-08-03 rsc Json *v;
432 18824b58 2008-08-03 rsc
433 18824b58 2008-08-03 rsc v = va_arg(fmt->args, Json*);
434 18824b58 2008-08-03 rsc if(fmt->flags&FmtSharp)
435 18824b58 2008-08-03 rsc _printjval(fmt, v, 0);
436 18824b58 2008-08-03 rsc else
437 18824b58 2008-08-03 rsc _printjval(fmt, v, -1);
438 18824b58 2008-08-03 rsc return 0;
439 18824b58 2008-08-03 rsc }
440 18824b58 2008-08-03 rsc
441 18824b58 2008-08-03 rsc Json*
442 18824b58 2008-08-03 rsc jincref(Json *v)
443 18824b58 2008-08-03 rsc {
444 18824b58 2008-08-03 rsc if(v == nil)
445 18824b58 2008-08-03 rsc return nil;
446 18824b58 2008-08-03 rsc ++v->ref;
447 18824b58 2008-08-03 rsc return v;
448 18824b58 2008-08-03 rsc }
449 18824b58 2008-08-03 rsc
450 18824b58 2008-08-03 rsc void
451 18824b58 2008-08-03 rsc jclose(Json *v)
452 18824b58 2008-08-03 rsc {
453 18824b58 2008-08-03 rsc int i;
454 18824b58 2008-08-03 rsc
455 18824b58 2008-08-03 rsc if(v == nil)
456 18824b58 2008-08-03 rsc return;
457 18824b58 2008-08-03 rsc if(--v->ref > 0)
458 18824b58 2008-08-03 rsc return;
459 18824b58 2008-08-03 rsc if(v->ref < 0)
460 18824b58 2008-08-03 rsc sysfatal("jclose: ref %d", v->ref);
461 18824b58 2008-08-03 rsc
462 18824b58 2008-08-03 rsc switch(v->type){
463 18824b58 2008-08-03 rsc case Jstring:
464 18824b58 2008-08-03 rsc free(v->string);
465 18824b58 2008-08-03 rsc break;
466 18824b58 2008-08-03 rsc case Jarray:
467 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++)
468 18824b58 2008-08-03 rsc jclose(v->value[i]);
469 18824b58 2008-08-03 rsc free(v->value);
470 18824b58 2008-08-03 rsc break;
471 18824b58 2008-08-03 rsc case Jobject:
472 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
473 18824b58 2008-08-03 rsc free(v->name[i]);
474 18824b58 2008-08-03 rsc jclose(v->value[i]);
475 18824b58 2008-08-03 rsc }
476 18824b58 2008-08-03 rsc free(v->value);
477 18824b58 2008-08-03 rsc free(v->name);
478 18824b58 2008-08-03 rsc break;
479 18824b58 2008-08-03 rsc }
480 18824b58 2008-08-03 rsc free(v);
481 18824b58 2008-08-03 rsc }
482 18824b58 2008-08-03 rsc
483 18824b58 2008-08-03 rsc Json*
484 18824b58 2008-08-03 rsc jlookup(Json *v, char *name)
485 18824b58 2008-08-03 rsc {
486 18824b58 2008-08-03 rsc int i;
487 18824b58 2008-08-03 rsc
488 18824b58 2008-08-03 rsc if(v->type != Jobject)
489 18824b58 2008-08-03 rsc return nil;
490 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++)
491 18824b58 2008-08-03 rsc if(strcmp(v->name[i], name) == 0)
492 18824b58 2008-08-03 rsc return v->value[i];
493 18824b58 2008-08-03 rsc return nil;
494 18824b58 2008-08-03 rsc }
495 18824b58 2008-08-03 rsc
496 18824b58 2008-08-03 rsc Json*
497 18824b58 2008-08-03 rsc jwalk(Json *v, char *path)
498 18824b58 2008-08-03 rsc {
499 18824b58 2008-08-03 rsc char elem[128], *p, *next;
500 18824b58 2008-08-03 rsc int n;
501 18824b58 2008-08-03 rsc
502 18824b58 2008-08-03 rsc for(p=path; *p && v; p=next){
503 18824b58 2008-08-03 rsc next = strchr(p, '/');
504 18824b58 2008-08-03 rsc if(next == nil)
505 18824b58 2008-08-03 rsc next = p+strlen(p);
506 18824b58 2008-08-03 rsc if(next-p >= sizeof elem)
507 18824b58 2008-08-03 rsc sysfatal("jwalk path elem too long - %s", path);
508 18824b58 2008-08-03 rsc memmove(elem, p, next-p);
509 18824b58 2008-08-03 rsc elem[next-p] = 0;
510 18824b58 2008-08-03 rsc if(*next == '/')
511 18824b58 2008-08-03 rsc next++;
512 18824b58 2008-08-03 rsc if(v->type == Jarray && *elem && (n=strtol(elem, &p, 10)) >= 0 && *p == 0){
513 18824b58 2008-08-03 rsc if(n >= v->len)
514 18824b58 2008-08-03 rsc return nil;
515 18824b58 2008-08-03 rsc v = v->value[n];
516 18824b58 2008-08-03 rsc }else
517 18824b58 2008-08-03 rsc v = jlookup(v, elem);
518 18824b58 2008-08-03 rsc }
519 18824b58 2008-08-03 rsc return v;
520 18824b58 2008-08-03 rsc }
521 18824b58 2008-08-03 rsc
522 18824b58 2008-08-03 rsc char*
523 18824b58 2008-08-03 rsc jstring(Json *jv)
524 18824b58 2008-08-03 rsc {
525 18824b58 2008-08-03 rsc if(jv == nil || jv->type != Jstring)
526 18824b58 2008-08-03 rsc return nil;
527 18824b58 2008-08-03 rsc return jv->string;
528 18824b58 2008-08-03 rsc }
529 18824b58 2008-08-03 rsc
530 18824b58 2008-08-03 rsc vlong
531 18824b58 2008-08-03 rsc jint(Json *jv)
532 18824b58 2008-08-03 rsc {
533 18824b58 2008-08-03 rsc if(jv == nil || jv->type != Jnumber)
534 18824b58 2008-08-03 rsc return -1;
535 18824b58 2008-08-03 rsc return jv->number;
536 18824b58 2008-08-03 rsc }
537 18824b58 2008-08-03 rsc
538 18824b58 2008-08-03 rsc double
539 18824b58 2008-08-03 rsc jnumber(Json *jv)
540 18824b58 2008-08-03 rsc {
541 18824b58 2008-08-03 rsc if(jv == nil || jv->type != Jnumber)
542 18824b58 2008-08-03 rsc return 0;
543 18824b58 2008-08-03 rsc return jv->number;
544 18824b58 2008-08-03 rsc }
545 18824b58 2008-08-03 rsc
546 18824b58 2008-08-03 rsc int
547 18824b58 2008-08-03 rsc jstrcmp(Json *jv, char *s)
548 18824b58 2008-08-03 rsc {
549 18824b58 2008-08-03 rsc char *t;
550 18824b58 2008-08-03 rsc
551 18824b58 2008-08-03 rsc t = jstring(jv);
552 18824b58 2008-08-03 rsc if(t == nil)
553 18824b58 2008-08-03 rsc return -2;
554 18824b58 2008-08-03 rsc return strcmp(t, s);
555 18824b58 2008-08-03 rsc }