1bb62b14d1241d1bebf9f0665c2eb7e0a2334ca5
braney
  Thu Oct 11 13:01:58 2012 -0700
this resolves the '+' in track names problem (#9254) by modifying all hub track names by changing all characters that aren't alphanumeric or dash or underbar into underbars.  I also added code to check for track name overlaps, and confirmed that none of the hubs in hgcentral.hubStatus would end up with duplicated track names because of this munging.  I also changed the udcTimeout in hubCheck to be 1 second.
diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c
index 71743eb..ff0584b 100644
--- src/hg/lib/trackHub.c
+++ src/hg/lib/trackHub.c
@@ -436,40 +436,100 @@
 	    errAbort("unrecognized type %s in genome %s track %s", type, genome->name, tdb->track);
 	freez(&bigDataUrl);
 	}
     errCatchEnd(errCatch);
     if (errCatch->gotError)
 	{
 	retVal = 1;
 	dyStringPrintf(errors, "%s", errCatch->message->string);
 	}
     errCatchFree(&errCatch);
     }
 
 return retVal;
 }
 
+static void fixName(char *name)
+/* change all characters other than alphanumeric, dash, and underbar
+ * to underbar */
+{
+if (name == NULL)
+    return;
+
+char *in = name;
+char c;
+
+for(; (c = *in) != 0; in++)
+    {
+    if (c == ' ')
+	break;
+
+    if (!(isalnum(c) || c == '-' || c == '_'))
+	*in = '_';
+    }
+}
+
+static void polishOneTrack( struct trackHub *hub, struct trackDb *bt,
+    struct hash *hash)
+/* get rid of special characters in track name, squirrel away a copy
+ * of the original name for html retrieval, make sure there aren't 
+ * two tracks with the same name */
+{
+char *htmlName = trackDbSetting(bt, "html");
+
+/* if the user didn't specify an html variable, set it to be the original
+ * track name */
+if (htmlName == NULL)
+    trackDbAddSetting(bt, "html", bt->track);
+
+fixName(bt->track);
+
+if (hashLookup(hash, bt->track) != NULL)
+    errAbort("more than one track called %s in hub %s\n", bt->track, hub->url);
+hashStore(hash, bt->track);
+}
+
+void trackHubPolishTrackNames(struct trackHub *hub, struct trackDb *tdbList)
+/* remove all the special characters from trackHub track names */
+{
+struct trackDb *next, *tdb;
+struct hash *nameHash = hashNew(5);
+
+for (tdb = tdbList; tdb != NULL; tdb = next)
+    {
+    next = tdb->next;
+    polishOneTrack(hub, tdb, nameHash);
+    if (tdb->subtracks != NULL)
+	{
+	trackHubPolishTrackNames(hub, tdb->subtracks);
+	}
+    }
+}
+
 static int hubCheckGenome(struct trackHub *hub, struct trackHubGenome *genome,
     struct dyString *errors, boolean checkTracks)
 /* Check out genome within hub. */
 {
 struct errCatch *errCatch = errCatchNew();
 struct trackDb *tdbList = NULL;
 int retVal = 0;
 
 if (errCatchStart(errCatch))
+    {
     tdbList = trackHubTracksForGenome(hub, genome);
+    trackHubPolishTrackNames(hub, tdbList);
+    }
 errCatchEnd(errCatch);
 
 if (errCatch->gotError)
     {
     retVal = 1;
     dyStringPrintf(errors, "%s", errCatch->message->string);
     }
 errCatchFree(&errCatch);
 
 if (!checkTracks)
     return retVal;
 
 struct trackDb *tdb;
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     retVal |= hubCheckTrack(hub, genome, tdb, errors);