16fdc50e4e49b031f566911bf0371d4942282d75 larrym Fri Apr 27 16:22:37 2012 -0700 use a union in jsonElement to simplify code and eliminate typecasts (per suggestion of angie and tim); rename jsonHash to jsonObject; fix some obsolete comments diff --git src/hg/lib/jsHelper.c src/hg/lib/jsHelper.c index 14e87af..bd2a2e3 100644 --- src/hg/lib/jsHelper.c +++ src/hg/lib/jsHelper.c @@ -1,45 +1,45 @@ -/* javascript - some little helper routines to manage our javascript. - * We don't do much javascript - just occassionally use it so that - * when they select something from a pull-down, it will go hit the server to - * figure out how to reload other control options based on the choice. - * (For instance if they change the group, which items in the track - * drop-down need to change). - * - * We accomplish this by maintaining two forms - a mainForm and a - * hiddenForm. The hiddenForm maintains echo's of all the variables - * in the main form, which get updated onChange of controls that need - * to 'ripple' to other controls. The onChange also submits the - * control. */ +// jsHelper.c - helper routines for interface between CGIs and client-side javascript #include "common.h" #include #include "dystring.h" #include "cheapcgi.h" #include "cart.h" #include "hPrint.h" #include "hash.h" #include "jsHelper.h" #include "web.h" #include "hui.h" #include "hgConfig.h" #include "portable.h" - static boolean jsInited = FALSE; -struct jsonHashElement *jsonGlobalsHash = NULL; +struct jsonElement *jsonGlobalsHash = NULL; + +/* mainForm/hiddenForm code supports the following: when the user selects + * something from a pull-down, it will go hit the server to + * figure out how to reload other control options based on the choice. + * (For instance if they change the group, which items in the track + * drop-down need to change). + * + * We accomplish this by maintaining two forms - a mainForm and a + * hiddenForm. The hiddenForm maintains echo's of all the variables + * in the main form, which get updated onChange of controls that need + * to 'ripple' to other controls. The onChange also submits the + * control. */ void jsInit() /* If this is the first call, set window.onload to the operations * performed upon loading a page and print supporting javascript. * Currently this just sets the page vertical position if specified on * CGI, and also calls jsWriteFunctions. * Subsequent calls do nothing, so this can be called many times. */ { if (! jsInited) { puts( "\n" "\n"); } } void jsonErrPrintf(struct dyString *ds, char *format, ...) // Printf a json error to a dyString for communicating with ajax code; format is: // {"error": error message here} { va_list args; va_start(args, format); dyStringPrintf(ds, "{\"error\": \""); struct dyString *buf = newDyString(1000); dyStringVaPrintf(buf, format, args); dyStringAppend(ds, javaScriptLiteralEncode(dyStringCannibalize(&buf))); @@ -829,102 +779,102 @@ // parse out a name : val pair skipLeadingSpacesWithPos(str, posPtr); char *name = getString(str, posPtr); skipLeadingSpacesWithPos(str, posPtr); getSpecificChar(':', str, posPtr); skipLeadingSpacesWithPos(str, posPtr); hashAdd(h, name, jsonParseExpression(str, posPtr)); skipLeadingSpacesWithPos(str, posPtr); if(str[*posPtr] == ',') (*posPtr)++; else break; } skipLeadingSpacesWithPos(str, posPtr); getSpecificChar('}', str, posPtr); -return (struct jsonElement *) newJsonHash(h); +return newJsonObject(h); } static struct jsonElement *jsonParseList(char *str, int *posPtr) { struct slRef *list = NULL; getSpecificChar('[', str, posPtr); while(str[*posPtr] != ']') { struct slRef *e; AllocVar(e); skipLeadingSpacesWithPos(str, posPtr); e->val = jsonParseExpression(str, posPtr); slAddHead(&list, e); skipLeadingSpacesWithPos(str, posPtr); if(str[*posPtr] == ',') (*posPtr)++; else break; } skipLeadingSpacesWithPos(str, posPtr); getSpecificChar(']', str, posPtr); slReverse(&list); -return (struct jsonElement *) newJsonList(list); +return newJsonList(list); } static struct jsonElement *jsonParseString(char *str, int *posPtr) { -return (struct jsonElement *) newJsonString(getString(str, posPtr)); +return newJsonString(getString(str, posPtr)); } static struct jsonElement *jsonParseBoolean(char *str, int *posPtr) { -struct jsonBooleanElement *ele = NULL; +struct jsonElement *ele = NULL; int i; for(i = 0; str[*posPtr + i] && isalpha(str[*posPtr + i]); i++); ; char *val = cloneStringZ(str + *posPtr, i); if(sameString(val, "true")) ele = newJsonBoolean(TRUE); else if(sameString(val, "false")) ele = newJsonBoolean(FALSE); else errAbort("Invalid boolean value '%s'; pos: %d", val, *posPtr); *posPtr += i; freez(&val); -return (struct jsonElement *) ele; +return ele; } static struct jsonElement *jsonParseNumber(char *str, int *posPtr) { int i; boolean integral = TRUE; struct jsonElement *retVal = NULL; for(i = 0;; i++) { char c = str[*posPtr + i]; if(c == 'e' || c == 'E' || c == '.') integral = FALSE; else if(!c || (!isdigit(c) && c != '-')) break; } char *val = cloneStringZ(str + *posPtr, i); *posPtr += i; if(integral) - retVal = (struct jsonElement *) newJsonNumber(sqlLongLong(val)); + retVal = newJsonNumber(sqlLongLong(val)); else { double d; if(sscanf(val, "%lf", &d)) - retVal = (struct jsonElement *) newJsonDouble(d); + retVal = newJsonDouble(d); else errAbort("Invalid JSON Double: %s", val); } freez(&val); return retVal; } 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);