From 6a58ba528584781c2386894ccec8205f8f242499 Mon Sep 17 00:00:00 2001 From: Dave Gamble Date: Wed, 2 Mar 2011 21:22:57 +0000 Subject: [PATCH] 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 --- cJSON.c | 21 +++++++++++++-------- cJSON.h | 3 +++ test.c | 12 ++++++++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/cJSON.c b/cJSON.c index ec728ca..461b332 100644 --- a/cJSON.c +++ b/cJSON.c @@ -32,6 +32,10 @@ #include #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. */ diff --git a/cJSON.h b/cJSON.h index 2da0f44..b7a6cd3 100644 --- a/cJSON.h +++ b/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(); diff --git a/test.c b/test.c index a435e9a..2cab632 100644 --- a/test.c +++ b/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. */