Преглед изворни кода

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

Dave Gamble пре 14 година
родитељ
комит
6a58ba5285
3 измењених фајлова са 24 додато и 12 уклоњено
  1. 13 8
      cJSON.c
  2. 3 0
      cJSON.h
  3. 8 4
      test.c

+ 13 - 8
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 - 0
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();

+ 8 - 4
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. */