]> git.sesse.net Git - mlt/blob - src/modules/rotoscoping/cJSON.c
Move burningtv into plusgpl module.
[mlt] / src / modules / rotoscoping / cJSON.c
1 /*
2   Copyright (c) 2009 Dave Gamble
3
4   Permission is hereby granted, free of charge, to any person obtaining a copy
5   of this software and associated documentation files (the "Software"), to deal
6   in the Software without restriction, including without limitation the rights
7   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   copies of the Software, and to permit persons to whom the Software is
9   furnished to do so, subject to the following conditions:
10
11   The above copyright notice and this permission notice shall be included in
12   all copies or substantial portions of the Software.
13
14   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   THE SOFTWARE.
21 */
22
23 // cJSON
24 // JSON parser in C.
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <math.h>
29 #include <stdlib.h>
30 #include <float.h>
31 #include <limits.h>
32 #include <ctype.h>
33 #include "cJSON.h"
34
35 static int cJSON_strcasecmp(const char *s1,const char *s2)
36 {
37         if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
38         for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0)    return 0;
39         return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
40 }
41
42 static void *(*cJSON_malloc)(size_t sz) = malloc;
43 static void (*cJSON_free)(void *ptr) = free;
44
45 static char* cJSON_strdup(const char* str)
46 {
47       size_t len;
48       char* copy;
49
50       len = strlen(str) + 1;
51       if (!(copy = (char*)cJSON_malloc(len))) return 0;
52       memcpy(copy,str,len);
53       return copy;
54 }
55
56 void cJSON_InitHooks(cJSON_Hooks* hooks)
57 {
58     if (!hooks) { /* Reset hooks */
59         cJSON_malloc = malloc;
60         cJSON_free = free;
61         return;
62     }
63
64         cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
65         cJSON_free       = (hooks->free_fn)?hooks->free_fn:free;
66 }
67
68 // Internal constructor.
69 static cJSON *cJSON_New_Item()
70 {
71         cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
72         if (node) memset(node,0,sizeof(cJSON));
73         return node;
74 }
75
76 // Delete a cJSON structure.
77 void cJSON_Delete(cJSON *c)
78 {
79         cJSON *next;
80         while (c)
81         {
82                 next=c->next;
83                 if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
84                 if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
85                 if (c->string) cJSON_free(c->string);
86                 cJSON_free(c);
87                 c=next;
88         }
89 }
90
91 // Parse the input text to generate a number, and populate the result into item.
92 static const char *parse_number(cJSON *item,const char *num)
93 {
94         double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
95
96         // Could use sscanf for this?
97         if (*num=='-') sign=-1,num++;   // Has sign?
98         if (*num=='0') num++;                   // is zero
99         if (*num>='1' && *num<='9')     do      n=(n*10.0)+(*num++ -'0');       while (*num>='0' && *num<='9'); // Number?
100         if (*num=='.') {num++;          do      n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}      // Fractional part?
101         if (*num=='e' || *num=='E')             // Exponent?
102         {       num++;if (*num=='+') num++;     else if (*num=='-') signsubscale=-1,num++;              // With sign?
103                 while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');   // Number?
104         }
105
106         n=sign*n*pow(10.0,(scale+subscale*signsubscale));       // number = +/- number.fraction * 10^+/- exponent
107         
108         item->valuedouble=n;
109         item->valueint=(int)n;
110         item->type=cJSON_Number;
111         return num;
112 }
113
114 // Render the number nicely from the given item into a string.
115 static char *print_number(cJSON *item)
116 {
117         char *str;
118         double d=item->valuedouble;
119         if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
120         {
121                 str=(char*)cJSON_malloc(21);    // 2^64+1 can be represented in 21 chars.
122                 if (str) sprintf(str,"%d",item->valueint);
123         }
124         else
125         {
126                 str=(char*)cJSON_malloc(64);    // This is a nice tradeoff.
127                 if (str)
128                 {
129                         if (fabs(floor(d)-d)<=DBL_EPSILON)                      sprintf(str,"%.0f",d);
130                         else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)       sprintf(str,"%e",d);
131                         else                                                                            sprintf(str,"%f",d);
132                 }
133         }
134         return str;
135 }
136
137 // Parse the input text into an unescaped cstring, and populate item.
138 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
139 static const char *parse_string(cJSON *item,const char *str)
140 {
141         const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
142         if (*str!='\"') return 0;       // not a string!
143         
144         while (*ptr!='\"' && (unsigned char)*ptr>31 && ++len) if (*ptr++ == '\\') ptr++;        // Skip escaped quotes.
145         
146         out=(char*)cJSON_malloc(len+1); // This is how long we need for the string, roughly.
147         if (!out) return 0;
148         
149         ptr=str+1;ptr2=out;
150         while (*ptr!='\"' && (unsigned char)*ptr>31)
151         {
152                 if (*ptr!='\\') *ptr2++=*ptr++;
153                 else
154                 {
155                         ptr++;
156                         switch (*ptr)
157                         {
158                                 case 'b': *ptr2++='\b'; break;
159                                 case 'f': *ptr2++='\f'; break;
160                                 case 'n': *ptr2++='\n'; break;
161                                 case 'r': *ptr2++='\r'; break;
162                                 case 't': *ptr2++='\t'; break;
163                                 case 'u':        // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
164                                         sscanf(ptr+1,"%4x",&uc);        // get the unicode char.
165                                         len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
166                                         
167                                         switch (len) {
168                                                 case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
169                                                 case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
170                                                 case 1: *--ptr2 =(uc | firstByteMark[len]);
171                                         }
172                                         ptr2+=len;ptr+=4;
173                                         break;
174                                 default:  *ptr2++=*ptr; break;
175                         }
176                         ptr++;
177                 }
178         }
179         *ptr2=0;
180         if (*ptr=='\"') ptr++;
181         item->valuestring=out;
182         item->type=cJSON_String;
183         return ptr;
184 }
185
186 // Render the cstring provided to an escaped version that can be printed.
187 static char *print_string_ptr(const char *str)
188 {
189         const char *ptr;char *ptr2,*out;int len=0;
190         
191         if (!str) return cJSON_strdup("");
192         ptr=str;while (*ptr && ++len) {if ((unsigned char)*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
193         
194         out=(char*)cJSON_malloc(len+3);
195         if (!out) return 0;
196
197         ptr2=out;ptr=str;
198         *ptr2++='\"';
199         while (*ptr)
200         {
201                 if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
202                 else
203                 {
204                         *ptr2++='\\';
205                         switch (*ptr++)
206                         {
207                                 case '\\':      *ptr2++='\\';   break;
208                                 case '\"':      *ptr2++='\"';   break;
209                                 case '\b':      *ptr2++='b';    break;
210                                 case '\f':      *ptr2++='f';    break;
211                                 case '\n':      *ptr2++='n';    break;
212                                 case '\r':      *ptr2++='r';    break;
213                                 case '\t':      *ptr2++='t';    break;
214                                 default: ptr2--;        break;  // eviscerate with prejudice.
215                         }
216                 }
217         }
218         *ptr2++='\"';*ptr2++=0;
219         return out;
220 }
221 // Invote print_string_ptr (which is useful) on an item.
222 static char *print_string(cJSON *item)  {return print_string_ptr(item->valuestring);}
223
224 // Predeclare these prototypes.
225 static const char *parse_value(cJSON *item,const char *value);
226 static char *print_value(cJSON *item,int depth,int fmt);
227 static const char *parse_array(cJSON *item,const char *value);
228 static char *print_array(cJSON *item,int depth,int fmt);
229 static const char *parse_object(cJSON *item,const char *value);
230 static char *print_object(cJSON *item,int depth,int fmt);
231
232 // Utility to jump whitespace and cr/lf
233 static const char *skip(const char *in) {while (in && (unsigned char)*in<=32) in++; return in;}
234
235 // Parse an object - create a new root, and populate.
236 cJSON *cJSON_Parse(const char *value)
237 {
238         cJSON *c=cJSON_New_Item();
239         if (!c) return 0;       /* memory fail */
240
241         if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
242         return c;
243 }
244
245 // Render a cJSON item/entity/structure to text.
246 char *cJSON_Print(cJSON *item)                          {return print_value(item,0,1);}
247 char *cJSON_PrintUnformatted(cJSON *item)       {return print_value(item,0,0);}
248
249 // Parser core - when encountering text, process appropriately.
250 static const char *parse_value(cJSON *item,const char *value)
251 {
252         if (!value)                                             return 0;       // Fail on null.
253         if (!strncmp(value,"null",4))   { item->type=cJSON_NULL;  return value+4; }
254         if (!strncmp(value,"false",5))  { item->type=cJSON_False; return value+5; }
255         if (!strncmp(value,"true",4))   { item->type=cJSON_True; item->valueint=1;      return value+4; }
256         if (*value=='\"')                               { return parse_string(item,value); }
257         if (*value=='-' || (*value>='0' && *value<='9'))        { return parse_number(item,value); }
258         if (*value=='[')                                { return parse_array(item,value); }
259         if (*value=='{')                                { return parse_object(item,value); }
260
261         return 0;       // failure.
262 }
263
264 // Render a value to text.
265 static char *print_value(cJSON *item,int depth,int fmt)
266 {
267         char *out=0;
268         if (!item) return 0;
269         switch ((item->type)&255)
270         {
271                 case cJSON_NULL:        out=cJSON_strdup("null");       break;
272                 case cJSON_False:       out=cJSON_strdup("false");break;
273                 case cJSON_True:        out=cJSON_strdup("true"); break;
274                 case cJSON_Number:      out=print_number(item);break;
275                 case cJSON_String:      out=print_string(item);break;
276                 case cJSON_Array:       out=print_array(item,depth,fmt);break;
277                 case cJSON_Object:      out=print_object(item,depth,fmt);break;
278         }
279         return out;
280 }
281
282 // Build an array from input text.
283 static const char *parse_array(cJSON *item,const char *value)
284 {
285         cJSON *child;
286         if (*value!='[')        return 0;       // not an array!
287
288         item->type=cJSON_Array;
289         value=skip(value+1);
290         if (*value==']') return value+1;        // empty array.
291
292         item->child=child=cJSON_New_Item();
293         if (!item->child) return 0;              // memory fail
294         value=skip(parse_value(child,skip(value)));     // skip any spacing, get the value.
295         if (!value) return 0;
296
297         while (*value==',')
298         {
299                 cJSON *new_item;
300                 if (!(new_item=cJSON_New_Item())) return 0;     // memory fail
301                 child->next=new_item;new_item->prev=child;child=new_item;
302                 value=skip(parse_value(child,skip(value+1)));
303                 if (!value) return 0;   // memory fail
304         }
305
306         if (*value==']') return value+1;        // end of array
307         return 0;       // malformed.
308 }
309
310 // Render an array to text
311 static char *print_array(cJSON *item,int depth,int fmt)
312 {
313         char **entries;
314         char *out=0,*ptr,*ret;int len=5;
315         cJSON *child=item->child;
316         int numentries=0,i=0,fail=0;
317         
318         // How many entries in the array?
319         while (child) numentries++,child=child->next;
320         // Allocate an array to hold the values for each
321         entries=(char**)cJSON_malloc(numentries*sizeof(char*));
322         if (!entries) return 0;
323         memset(entries,0,numentries*sizeof(char*));
324         // Retrieve all the results:
325         child=item->child;
326         while (child && !fail)
327         {
328                 ret=print_value(child,depth+1,fmt);
329                 entries[i++]=ret;
330                 if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
331                 child=child->next;
332         }
333         
334         // If we didn't fail, try to malloc the output string
335         if (!fail) out=cJSON_malloc(len);
336         // If that fails, we fail.
337         if (!out) fail=1;
338
339         // Handle failure.
340         if (fail)
341         {
342                 for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
343                 cJSON_free(entries);
344                 return 0;
345         }
346         
347         // Compose the output array.
348         *out='[';
349         ptr=out+1;*ptr=0;
350         for (i=0;i<numentries;i++)
351         {
352                 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
353                 if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
354                 cJSON_free(entries[i]);
355         }
356         cJSON_free(entries);
357         *ptr++=']';*ptr++=0;
358         return out;     
359 }
360
361 // Build an object from the text.
362 static const char *parse_object(cJSON *item,const char *value)
363 {
364         cJSON *child;
365         if (*value!='{')        return 0;       // not an object!
366         
367         item->type=cJSON_Object;
368         value=skip(value+1);
369         if (*value=='}') return value+1;        // empty array.
370         
371         item->child=child=cJSON_New_Item();
372         if (!item->child) return 0;
373         value=skip(parse_string(child,skip(value)));
374         if (!value) return 0;
375         child->string=child->valuestring;child->valuestring=0;
376         if (*value!=':') return 0;      // fail!
377         value=skip(parse_value(child,skip(value+1)));   // skip any spacing, get the value.
378         if (!value) return 0;
379         
380         while (*value==',')
381         {
382                 cJSON *new_item;
383                 if (!(new_item=cJSON_New_Item()))       return 0; // memory fail
384                 child->next=new_item;new_item->prev=child;child=new_item;
385                 value=skip(parse_string(child,skip(value+1)));
386                 if (!value) return 0;
387                 child->string=child->valuestring;child->valuestring=0;
388                 if (*value!=':') return 0;      // fail!
389                 value=skip(parse_value(child,skip(value+1)));   // skip any spacing, get the value.             
390                 if (!value) return 0;
391         }
392         
393         if (*value=='}') return value+1;        // end of array
394         return 0;       // malformed.   
395 }
396
397 // Render an object to text.
398 static char *print_object(cJSON *item,int depth,int fmt)
399 {
400         char **entries=0,**names=0;
401         char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
402         cJSON *child=item->child;
403         int numentries=0,fail=0;
404         // Count the number of entries.
405         while (child) numentries++,child=child->next;
406         // Allocate space for the names and the objects
407         entries=(char**)cJSON_malloc(numentries*sizeof(char*));
408         if (!entries) return 0;
409         names=(char**)cJSON_malloc(numentries*sizeof(char*));
410         if (!names) {cJSON_free(entries);return 0;}
411         memset(entries,0,sizeof(char*)*numentries);
412         memset(names,0,sizeof(char*)*numentries);
413
414         // Collect all the results into our arrays:
415         child=item->child;depth++;if (fmt) len+=depth;
416         while (child)
417         {
418                 names[i]=str=print_string_ptr(child->string);
419                 entries[i++]=ret=print_value(child,depth,fmt);
420                 if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
421                 child=child->next;
422         }
423         
424         // Try to allocate the output string
425         if (!fail) out=(char*)cJSON_malloc(len);
426         if (!out) fail=1;
427
428         // Handle failure
429         if (fail)
430         {
431                 for (i=0;i<numentries;i++) {if (names[i]) free(names[i]);if (entries[i]) free(entries[i]);}
432                 free(names);free(entries);
433                 return 0;
434         }
435         
436         // Compose the output:
437         *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
438         for (i=0;i<numentries;i++)
439         {
440                 if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
441                 strcpy(ptr,names[i]);ptr+=strlen(names[i]);
442                 *ptr++=':';if (fmt) *ptr++='\t';
443                 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
444                 if (i!=numentries-1) *ptr++=',';
445                 if (fmt) *ptr++='\n';*ptr=0;
446                 cJSON_free(names[i]);cJSON_free(entries[i]);
447         }
448         
449         cJSON_free(names);cJSON_free(entries);
450         if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
451         *ptr++='}';*ptr++=0;
452         return out;     
453 }
454
455 // Get Array size/item / object item.
456 int    cJSON_GetArraySize(cJSON *array)                                                 {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
457 cJSON *cJSON_GetArrayItem(cJSON *array,int item)                                {cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
458 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)    {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
459
460 // Utility for array list handling.
461 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
462 // Utility for handling references.
463 static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
464
465 // Add item to array/object.
466 void   cJSON_AddItemToArray(cJSON *array, cJSON *item)                                          {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
467 void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)      {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
468 void    cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)                                                {cJSON_AddItemToArray(array,create_reference(item));}
469 void    cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)    {cJSON_AddItemToObject(object,string,create_reference(item));}
470
471 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)                        {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
472         if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
473 void   cJSON_DeleteItemFromArray(cJSON *array,int which)                        {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
474 cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
475 void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
476
477 // Replace array/object items with new ones.
478 void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)          {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
479         newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
480         if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
481 void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
482
483 // Create basic types:
484 cJSON *cJSON_CreateNull()                                               {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
485 cJSON *cJSON_CreateTrue()                                               {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
486 cJSON *cJSON_CreateFalse()                                              {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
487 cJSON *cJSON_CreateBool(int b)                                  {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
488 cJSON *cJSON_CreateNumber(double num)                   {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
489 cJSON *cJSON_CreateString(const char *string)   {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
490 cJSON *cJSON_CreateArray()                                              {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
491 cJSON *cJSON_CreateObject()                                             {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
492
493 // Create Arrays:
494 cJSON *cJSON_CreateIntArray(int *numbers,int count)                             {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
495 cJSON *cJSON_CreateFloatArray(float *numbers,int count)                 {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
496 cJSON *cJSON_CreateDoubleArray(double *numbers,int count)               {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
497 cJSON *cJSON_CreateStringArray(const char **strings,int count)  {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}