mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Include some analysis so that you can debug a failed parse.
You really oughtn't go too far with this, because it's only loose information; as I've said before, cJSON +isn't+ a validating parser. But this might give you enough info to save yourself on some rare occasion ;) git-svn-id: http://svn.code.sf.net/p/cjson/code@38 e3330c51-1366-4df0-8b21-3ccf24e3d50e
This commit is contained in:
parent
b5d57642c2
commit
6a58ba5285
21
cJSON.c
21
cJSON.c
@ -32,6 +32,10 @@
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr() {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
@ -139,7 +143,7 @@ static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
|
||||
if (*str!='\"') return 0; /* not a string! */
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
@ -235,6 +239,7 @@ static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_Parse(const char *value)
|
||||
{
|
||||
ep=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
@ -258,7 +263,7 @@ static const char *parse_value(cJSON *item,const char *value)
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
return 0; /* failure. */
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
@ -283,7 +288,7 @@ static char *print_value(cJSON *item,int depth,int fmt)
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') return 0; /* not an array! */
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
@ -304,7 +309,7 @@ static const char *parse_array(cJSON *item,const char *value)
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
return 0; /* malformed. */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
@ -362,7 +367,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') return 0; /* not an object! */
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
@ -373,7 +378,7 @@ static const char *parse_object(cJSON *item,const char *value)
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') return 0; /* fail! */
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
@ -385,13 +390,13 @@ static const char *parse_object(cJSON *item,const char *value)
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') return 0; /* fail! */
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
return 0; /* malformed. */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
|
3
cJSON.h
3
cJSON.h
@ -77,6 +77,9 @@ extern int cJSON_GetArraySize(cJSON *array);
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr();
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull();
|
||||
|
12
test.c
12
test.c
@ -30,10 +30,14 @@ void doit(char *text)
|
||||
char *out;cJSON *json;
|
||||
|
||||
json=cJSON_Parse(text);
|
||||
out=cJSON_Print(json);
|
||||
cJSON_Delete(json);
|
||||
printf("%s\n",out);
|
||||
free(out);
|
||||
if (!json) {printf("Error before: [%s]\n",cJSON_GetErrorPtr());}
|
||||
else
|
||||
{
|
||||
out=cJSON_Print(json);
|
||||
cJSON_Delete(json);
|
||||
printf("%s\n",out);
|
||||
free(out);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a file, parse, render back, etc. */
|
||||
|
Loading…
Reference in New Issue
Block a user