efba7e00a3e2c79d5714f693eda1a81f23eb479b
angie
  Fri Aug 3 09:11:21 2012 -0700
Code Review #8673 - thanks Tim!
diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c
index 289fd70..0470829 100644
--- src/hg/hgTrackUi/hgTrackUi.c
+++ src/hg/hgTrackUi/hgTrackUi.c
@@ -218,71 +218,72 @@
 safef(cartVar, sizeof(cartVar), "%s.include_%s", track, attributeVar);
 jsMakeCheckboxGroupSetClearButton(cartVar, TRUE);
 puts(" ");
 jsMakeCheckboxGroupSetClearButton(cartVar, FALSE);
 printf("</TD></TR>\n<TR><TD>\n");
 boolean foundInCart = FALSE;
 struct slName *selectedAttributes = snp125FilterFromCart(cart, track, attributeVar, &foundInCart);
 // Include all by default:
 if (! foundInCart)
     selectedAttributes = slNameListFromStringArray(values, menuSize);
 cgiMakeCheckboxGroupWithVals(cartVar, labels, values, menuSize, selectedAttributes,
 			     SNP125_FILTER_COLUMNS);
 printf("</TD></TR>\n");
 }
 
-static char *getSetFieldValStr(struct sqlFieldInfo *fi, char *table)
-/* Destructively prepare fi->type for chopCommas, making sure it looks like a set() def. */
+static char *commaSepFromSqlSetTypeDecl(struct sqlFieldInfo *fi, char *table)
+/* Destructively prepare fi->type for chopCommas: strip initial "set(" and final ")",
+ * informatively errAborting if not found, and strip the single-quote characters
+ * that mysql puts around each field. */
 {
 if (!startsWith("set(", fi->type))
     errAbort("Expected %s.%s's type to begin with 'set(' but got '%s'",
 	     table, fi->field, fi->type);
 char *vals = fi->type + strlen("set(");
 char *rightParen = strrchr(vals, ')');
 if (rightParen == NULL || rightParen[1] != '\0')
     errAbort("Expected %s.%s's type to end with ')' but got '%s'",
 	     table, fi->field, fi->type);
 else
     *rightParen = '\0';
 stripChar(vals, '\'');
 return vals;
 }
 
 static void snp137PrintFunctionFilterControls(struct trackDb *tdb)
 /* As of snp137, show func filter choices based on sql field set
  * values and Sequence Ontology (SO) terms so we won't have to
  * hardcode menus as new functional categories are added. */
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlFieldInfo *fi, *fiList = sqlFieldInfoGet(conn, tdb->table);
 hFreeConn(&conn);
 for (fi = fiList;  fi != NULL;  fi = fi->next)
     {
     if (sameString(fi->field, "func"))
 	{
-	char *vals = getSetFieldValStr(fi, tdb->table);
-	char *values[128];
+	char *vals = commaSepFromSqlSetTypeDecl(fi, tdb->table);
+	char *values[128]; // 22 values as of snp137
 	int valCount = chopCommas(vals, values);
 	char *labels[valCount];
 	int i;
 	for (i = 0;  i < valCount;  i++)
 	    {
-	    char *val = values[i];
-	    if (sameString(val, "unknown"))
+	    if (sameString(values[i], "unknown"))
 		labels[i] = "Unknown";
 	    else
-		labels[i] = snpMisoLinkFromFunc(val);
+		labels[i] = snpMisoLinkFromFunc(values[i]);
 	    }
 	snp125PrintFilterControls(tdb->track, "Function", "func", labels, values, valCount);
 	return;;
 	}
     }
 errAbort("Didn't find definition of func field in %s", tdb->table);
 }
 
 static void snp125PrintFilterControlSection(struct trackDb *tdb, int version)
 /* Print a collapsible section of filtering controls on SNP properties, first numeric
  * and then enum/set. */
 {
 char cartVar[512];
 printf("<TR><TD colspan=2><A name=\"filterControls\"></TD></TR>\n");
 jsBeginCollapsibleSection(cart, tdb->track, "filterByAttribute", "Filtering Options", FALSE);