Simplify things by storing integer values only as int64_t's internally, and
 omit the range check during parsing since we already have the checks when
 accessing the value. There is no longer a json_type_int64, only json_type_int.
Fix some problems with parsing 0 and -0 values, and add a couple of tests.
Fix some minor compile issues on HPUX environments.


git-svn-id: http://svn.metaparadigm.com/svn/json-c/trunk@60 327403b1-1117-474d-bef2-5cb71233fd97
diff --git a/json_object.c b/json_object.c
index c2b6fe2..2b6dad4 100644
--- a/json_object.c
+++ b/json_object.c
@@ -43,7 +43,6 @@
   "object",
   "array",
   "string",
-  "int64",
 };
 #endif /* REFCOUNT_DEBUG */
 
@@ -306,8 +305,6 @@
   case json_type_boolean:
     return jso->o.c_boolean;
   case json_type_int:
-    return (jso->o.c_int != 0);
-  case json_type_int64:
     return (jso->o.c_int64 != 0);
   case json_type_double:
     return (jso->o.c_double != 0);
@@ -324,10 +321,6 @@
 static int json_object_int_to_json_string(struct json_object* jso,
 					  struct printbuf *pb)
 {
-  return sprintbuf(pb, "%d", jso->o.c_int);
-}
-
-static int json_object_int64_to_json_string(struct json_object* jso, struct printbuf *pb) {
   return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
 }
 
@@ -336,7 +329,7 @@
   struct json_object *jso = json_object_new(json_type_int);
   if(!jso) return NULL;
   jso->_to_json_string = &json_object_int_to_json_string;
-  jso->o.c_int = i;
+  jso->o.c_int64 = i;
   return jso;
 }
 
@@ -355,13 +348,11 @@
 	 */
 	if (json_parse_int64(jso->o.c_string, &cint64) != 0)
 		return 0; /* whoops, it didn't work. */
-	o_type = json_type_int64;
+	o_type = json_type_int;
   }
 
   switch(jso->o_type) {
   case json_type_int:
-    return jso->o.c_int;
-  case json_type_int64:
 	/* Make sure we return the correct values for out of range numbers. */
 	if (cint64 <= INT32_MIN)
 		return INT32_MIN;
@@ -380,9 +371,9 @@
 
 struct json_object* json_object_new_int64(int64_t i)
 {
-  struct json_object *jso = json_object_new(json_type_int64);
+  struct json_object *jso = json_object_new(json_type_int);
   if(!jso) return NULL;
-  jso->_to_json_string = &json_object_int64_to_json_string;
+  jso->_to_json_string = &json_object_int_to_json_string;
   jso->o.c_int64 = i;
   return jso;
 }
@@ -394,8 +385,6 @@
   if(!jso) return 0;
   switch(jso->o_type) {
   case json_type_int:
-    return (int64_t)jso->o.c_int;
-  case json_type_int64:
     return jso->o.c_int64;
   case json_type_double:
     return (int64_t)jso->o.c_double;
@@ -435,8 +424,6 @@
   case json_type_double:
     return jso->o.c_double;
   case json_type_int:
-    return jso->o.c_int;
-  case json_type_int64:
     return jso->o.c_int64;
   case json_type_boolean:
     return jso->o.c_boolean;
diff --git a/json_object.h b/json_object.h
index cea4c81..9a44c6e 100644
--- a/json_object.h
+++ b/json_object.h
@@ -47,7 +47,6 @@
   json_type_object,
   json_type_array,
   json_type_string,
-  json_type_int64
 } json_type;
 
 /* reference counting functions */
@@ -75,7 +74,6 @@
      json_type_object,
      json_type_array,
      json_type_string,
-     json_type_int64,
  */
 extern int json_object_is_type(struct json_object *obj, enum json_type type);
 
@@ -89,7 +87,6 @@
      json_type_object,
      json_type_array,
      json_type_string,
-     json_type_int64,
  */
 extern enum json_type json_object_get_type(struct json_object *obj);
 
@@ -252,15 +249,17 @@
 /* int type methods */
 
 /** Create a new empty json_object of type json_type_int
+ * Note that values are stored as 64-bit values internally.
+ * To ensure the full range is maintained, use json_object_new_int64 instead.
  * @param i the integer
  * @returns a json_object of type json_type_int
  */
 extern struct json_object* json_object_new_int(int32_t i);
 
 
-/** Create a new empty json_object of type json_type_int64
+/** Create a new empty json_object of type json_type_int
  * @param i the integer
- * @returns a json_object of type json_type_int64
+ * @returns a json_object of type json_type_int
  */
 extern struct json_object* json_object_new_int64(int64_t i);
 
@@ -271,6 +270,10 @@
  * double objects will return their integer conversion. Strings will be
  * parsed as an integer. If no conversion exists then 0 is returned.
  *
+ * Note that integers are stored internally as 64-bit values.
+ * If the value of too big or too small to fit into 32-bit, INT32_MAX or
+ * INT32_MIN are returned, respectively.
+ *
  * @param obj the json_object instance
  * @returns an int
  */
diff --git a/json_object_private.h b/json_object_private.h
index a0f9845..04f510a 100644
--- a/json_object_private.h
+++ b/json_object_private.h
@@ -30,7 +30,6 @@
   union data {
     boolean c_boolean;
     double c_double;
-    int32_t c_int;
     int64_t c_int64;
     struct lh_table *c_object;
     struct array_list *c_array;
diff --git a/json_tokener.c b/json_tokener.c
index dbaacaa..da414e7 100644
--- a/json_tokener.c
+++ b/json_tokener.c
@@ -204,7 +204,7 @@
 
     case json_tokener_state_eatws:
       /* Advance until we change state */
-      while (isspace(c)) {
+      while (isspace((int)c)) {
 	if ((!ADVANCE_CHAR(str, tok)) || (!POP_CHAR(c, tok)))
 	  goto out;
       }
@@ -547,17 +547,7 @@
 	int64_t num64;
 	double  numd;
 	if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
-		// Decode the type based on the value range to keep compatibilty
-		//  with code that checks the type of objects. i.e. this:
-		//   json_object_get_type(o) == json_type_int
-		//  will continue to work.
-		// The other option would be to eliminate any distinction between
-		//  int and int64 types, but that would change the ABI of
-		//  json_object_get_int().
-		if (num64 < INT32_MAX && num64 > INT32_MIN)
-			current = json_object_new_int(num64);
-		else
-			current = json_object_new_int64(num64);
+		current = json_object_new_int64(num64);
 	} else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
           current = json_object_new_double(numd);
         } else {
diff --git a/json_util.c b/json_util.c
index 0dcd6d5..9eca953 100644
--- a/json_util.c
+++ b/json_util.c
@@ -10,6 +10,7 @@
  */
 
 #include "config.h"
+#undef realloc
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -131,7 +132,7 @@
 	int64_t num64;
 	if (sscanf(buf, "%" SCNd64, &num64) != 1)
 	{
-		printf("Failed to parse, sscanf != 1\n");
+		MC_DEBUG("Failed to parse, sscanf != 1\n");
 		return 1;
 	}
 	const char *buf_skip_space = buf;
@@ -144,9 +145,11 @@
 		buf_skip_space++;
 		orig_has_neg = 1;
 	}
-	// Skip leading zeros
-	while (*buf_skip_space == '0' && *buf_skip_space)
+	// Skip leading zeros, but keep at least one digit
+	while (buf_skip_space[0] == '0' && buf_skip_space[1] != '\0')
 		buf_skip_space++;
+	if (buf_skip_space[0] == '0' && buf_skip_space[1] == '\0')
+		orig_has_neg = 0; // "-0" is the same as just plain "0"
 	
 	if (errno != ERANGE)
 	{
@@ -171,7 +174,7 @@
 		if (orig_has_neg != recheck_has_neg ||
 		    strncmp(buf_skip_space, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
 			(strlen(buf_skip_space) != buf_cmp_len &&
-			 isdigit(buf_skip_space[buf_cmp_len])
+			 isdigit((int)buf_skip_space[buf_cmp_len])
 		    )
 		   )
 		{
@@ -188,3 +191,14 @@
 	*retval = num64;
 	return 0;
 }
+
+#if HAVE_REALLOC == 0
+void* rpl_realloc(void* p, size_t n)
+{
+	if (n == 0)
+		n = 1;
+	if (p == 0)
+		return malloc(n);
+	return realloc(p, n);
+}
+#endif
diff --git a/printbuf.c b/printbuf.c
index 97366c3..6ed1e94 100644
--- a/printbuf.c
+++ b/printbuf.c
@@ -123,7 +123,7 @@
      would have been written - this code handles both cases. */
   if(size == -1 || size > 127) {
     va_start(ap, msg);
-    if((size = vasprintf(&t, msg, ap)) == -1) { va_end(ap); return -1; }
+    if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
     va_end(ap);
     printbuf_memappend(p, t, size);
     free(t);
diff --git a/test_parse_int64.c b/test_parse_int64.c
index 42d4575..0893356 100644
--- a/test_parse_int64.c
+++ b/test_parse_int64.c
@@ -29,6 +29,12 @@
 
 	checkit("x");
 
+	checkit("0");
+	checkit("-0");
+
+	checkit("00000000");
+	checkit("-00000000");
+
 	checkit("1");
 
 	strcpy(buf, "2147483647"); // aka INT32_MAX
diff --git a/test_parse_int64.expected b/test_parse_int64.expected
index 2d01ca7..23a9803 100644
--- a/test_parse_int64.expected
+++ b/test_parse_int64.expected
@@ -1,5 +1,8 @@
-Failed to parse, sscanf != 1
 buf=x parseit=1, value=-666 
+buf=0 parseit=0, value=0 
+buf=-0 parseit=0, value=0 
+buf=00000000 parseit=0, value=0 
+buf=-00000000 parseit=0, value=0 
 buf=1 parseit=0, value=1 
 buf=2147483647 parseit=0, value=2147483647 
 buf=-1 parseit=0, value=-1