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);