467c156e4959074434f3889c77cb698a155fa21a
angie
  Fri Jan 21 10:47:53 2011 -0800
Fixing gross abuse of hTrackDb (via hTrackDbForTrack) found by Larryand Hiram during work on Bug #1114: snp125OfferGeneTracksForFunction
was modifying the returned results, which broke when caching was
introduced to hTrackDb.  Since hgTrackUi already has trackHash, just
look up tdbs there and do a shallow copy so that altering the next
pointer with slAddHead and slSort doesn't destroy the cached version.

diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c
index 12cb49a..d6d9865 100644
--- src/hg/hgTrackUi/hgTrackUi.c
+++ src/hg/hgTrackUi/hgTrackUi.c
@@ -134,41 +134,46 @@
 	cartUsualString(cart, snpMapSourceStrings[snpMapSource], snpMapSourceDefault[snpMapSource]);
     snpFilterButtons(snpMapSourceStrings[snpMapSource], snpMapSourceCart[snpMapSource]);
     printf(" - <B>%s</B><BR>\n", snpMapSourceLabels[snpMapSource]);
     }
 printf("<BR><B>Variant Types:</B><BR>\n");
 for (snpMapType=0; snpMapType<snpMapTypeCartSize; snpMapType++)
     {
     snpMapTypeCart[snpMapType] =
 	cartUsualString(cart, snpMapTypeStrings[snpMapType], snpMapTypeDefault[snpMapType]);
     snpMapTypeFilterButtons(snpMapTypeStrings[snpMapType], snpMapTypeCart[snpMapType]);
     printf(" - <B>%s</B><BR>\n", snpMapTypeLabels[snpMapType]);
     }
 }
 
 void snp125OfferGeneTracksForFunction(struct trackDb *tdb)
+/* Get a list of genePred tracks and make checkboxes to enable hgc's functional
+ * annotations. */
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct slName *genePredTables = hTrackTablesOfType(conn, "genePred%%"), *gt;
 if (genePredTables != NULL)
     {
     struct trackDb *geneTdbList = NULL, *gTdb;
     for (gt = genePredTables;  gt != NULL;  gt = gt->next)
 	{
-	gTdb = hTrackDbForTrack(database, gt->name);
+	gTdb = hashFindVal(trackHash, gt->name);
 	if (gTdb && sameString(gTdb->grp, "genes"))
 	    {
+	    // We are going to overwrite gTdb's next pointer and possibly its priority,
+	    // so make a shallow copy:
+	    gTdb = CloneVar(gTdb);
 	    if (gTdb->parent)
 		gTdb->priority = (gTdb->parent->priority + gTdb->priority/1000);
 	    slAddHead(&geneTdbList, gTdb);
 	    }
 	}
     slSort(&geneTdbList, trackDbCmp);
     jsBeginCollapsibleSection(cart, tdb->track, "geneTracks",
 			      "Use Gene Tracks for Functional Annotation", FALSE);
     printf("<BR><B>On details page, show function and coding differences relative to: </B> ");
     char cartVar[256];
     safef(cartVar, sizeof(cartVar), "%s_geneTrack", tdb->track);
     jsMakeCheckboxGroupSetClearButton(cartVar, TRUE);
     jsMakeCheckboxGroupSetClearButton(cartVar, FALSE);
     struct slName *selectedGeneTracks = cartOptionalSlNameList(cart, cartVar);
     if (!cartListVarExists(cart, cartVar))