0d6d33d299f335d125044e48eac0c995dc62eac6
chinhli
  Wed Oct 2 15:15:37 2013 -0700
Use slNameAddHead() instead of slNameAddTail() in jsonFindNameRecurse(). Added jsonFindNameUniq() to filter out duplicate name.
diff --git src/hg/lib/jsHelper.c src/hg/lib/jsHelper.c
index 0ac6f91..c72160e 100644
--- src/hg/lib/jsHelper.c
+++ src/hg/lib/jsHelper.c
@@ -984,76 +984,87 @@
         case '/':
         case '\b':
         case '\f':
         case '\n':
         case '\r':
         case '\t':
             *out++ = '\\';
             break;
         }
     *out++ = c;
     }
 *out++ = 0;
 return outString;
 }
 
-void jsonFindNameRecurse(struct jsonElement *ele, char *jName, struct slName *sn)
+void jsonFindNameRecurse(struct jsonElement *ele, char *jName, struct slName **pList)
 // Search the JSON tree recursively to find all the values associated to
-// the name. Value found are added to the tail of the  slName list 
+// the name, and add them to head of the list.  
 {
 switch (ele->type)
     {
     case jsonObject:
         {
         if(hashNumEntries(ele->val.jeHash))
             {
             struct hashEl *el, *list = hashElListHash(ele->val.jeHash);
             slSort(&list, hashElCmp);
             for (el = list; el != NULL; el = el->next)
                 {
                 struct jsonElement *val = el->val;
                 if sameString(el->name, jName)
-                    slNameAddTail(&sn, jsonStringEscape(val->val.jeString));
-                jsonFindNameRecurse(val, jName, sn);
+                    slNameAddHead(pList, jsonStringEscape(val->val.jeString));
+                jsonFindNameRecurse(val, jName, pList);
                 }
             hashElFreeList(&list);
             }
         break;
         }
     case jsonList:
         {
         struct slRef *el;
         if(ele->val.jeList)
             {
             for (el = ele->val.jeList; el != NULL; el = el->next)
                 {
                 struct jsonElement *val = el->val;
-                jsonFindNameRecurse(val, jName, sn);
+                jsonFindNameRecurse(val, jName, pList);
                 }
             }
         break;
         }
     case jsonString:
     case jsonBoolean:
     case jsonNumber:
     case jsonDouble:
         {
         break;
         }
     default:
         {
         errAbort("jsonFindNameRecurse; invalid type: %d", ele->type);
         break;
         }
     }
 }
 
 struct slName *jsonFindName(struct jsonElement *json, char *jName)
 // Search the JSON tree to find all the values associated to the name
-// and  put them into a slName list. The first element of the list is the
-// name itself and values are added to the tail of the list.  
+// and add them to head of the list.  
 {
-struct slName *sn = slNameNew(jName);
-jsonFindNameRecurse(json, jName, sn);
-return sn;
+struct slName *list = NULL;
+jsonFindNameRecurse(json, jName, &list);
+slReverse(&list);
+return list;
+}
+
+struct slName *jsonFindNameUniq(struct jsonElement *json, char *jName)
+// Search the JSON tree to find all the unique values associated to the name
+// and add them to head of the list. 
+{
+struct slName *list = NULL;
+jsonFindNameRecurse(json, jName, &list);
+slUniqify(&list, slNameCmp, slNameFree);
+slReverse(&list);
+return list;
 }