6b1d561438309ce780bfd6141f76919d3eb2cd0d
larrym
  Mon Apr 23 12:02:04 2012 -0700
support scientific notation in jsonParseNumber
diff --git src/hg/lib/jsHelper.c src/hg/lib/jsHelper.c
index 32b0d9b..a478a9c 100644
--- src/hg/lib/jsHelper.c
+++ src/hg/lib/jsHelper.c
@@ -762,31 +762,31 @@
 static char *getString(char *str, int *posPtr)
 {
 // read a double-quote delimited string; we handle backslash escaping.
 // returns allocated string.
 boolean escapeMode = FALSE;
 int i;
 struct dyString *ds = dyStringNew(1024);
 getSpecificChar('"', str, posPtr);
 for(i = 0;; i++)
     {
     char c = str[*posPtr + i];
     if(!c)
         errAbort("Premature end of string (missing trailing double-quote); string position '%d'", *posPtr);
     else if(escapeMode)
         {
-        // We support escape sequences listed in https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON
+        // We support escape sequences listed in http://www.json.org,
         // except for Unicode which we cannot support in C-strings
         switch(c)
             {
             case 'b':
                 c = '\b';
                 break;
             case 'f':
                 c = '\f';
                 break;
             case 'n':
                 c = '\n';
                 break;
             case 'r':
                 c = '\r';
                 break;
@@ -880,42 +880,52 @@
     ;
 char *val = cloneStringZ(str + *posPtr, i);
 if(sameWord(val, "true"))
     ele = newJsonBoolean(TRUE);
 else if(sameWord(val, "false"))
     ele =  newJsonBoolean(FALSE);
 else
     errAbort("Invalid boolean value '%s'; pos: %d", val, *posPtr);
 *posPtr += i;
 return (struct jsonElement *) ele;
 }
 
 static struct jsonElement *jsonParseNumber(char *str, int *posPtr)
 {
 int i;
+boolean integral = TRUE;
 for(i = 0;; i++)
     {
     char c = str[*posPtr + i];
-    if(!(c && (isdigit(c) || c == '.' || c == '-' || c == '+')))
+    if(c == 'e' || c == 'E' || c == '.')
+        integral = FALSE;
+    else if(!c || (!isdigit(c) && c != '-'))
         break;
     }
 char *val = cloneStringZ(str + *posPtr, i);
 *posPtr += i;
-if(strchr(val, '.') == NULL)
+if(integral)
     return (struct jsonElement *) newJsonNumber(sqlLongLong(val));
 else
-    return (struct jsonElement *) newJsonDouble(sqlDouble(val));
+    {
+    double d;
+    if(sscanf(val, "%lf", &d))
+        return (struct jsonElement *) newJsonDouble(d);
+    else
+        errAbort("Invalid JSON Double: %s; pos: %d", val, *posPtr + i);
+    }
+return NULL;
 }
 
 static struct jsonElement *jsonParseExpression(char *str, int *posPtr)
 {
 skipLeadingSpacesWithPos(str, posPtr);
 char c = str[*posPtr];
 if(c == '{')
     return jsonParseObject(str, posPtr);
 else if (c == '[')
     return jsonParseList(str, posPtr);
 else if (c == '"')
     return jsonParseString(str, posPtr);
 else if (isdigit(c) || c == '-')
     return jsonParseNumber(str, posPtr);
 else