06d7be056190c14b85e71bc12523f18ea6815b5e
markd
  Mon Dec 7 00:50:29 2020 -0800
BLAT mmap index support merge with master

diff --git src/hg/hgc/mafClick.c src/hg/hgc/mafClick.c
index 6e93d79..a3d930e 100644
--- src/hg/hgc/mafClick.c
+++ src/hg/hgc/mafClick.c
@@ -533,30 +533,49 @@
         {
         char *fileName = trackDbSetting(tdb, "bigDataUrl");
         struct bbiFile *bbi = bigBedFileOpen(fileName);
         mafList = bigMafLoadInRegion(bbi, seqName, winStart, winEnd);
         }
     else
         mafList = mafOrAxtLoadInRegion2(conn,conn2, tdb, seqName, winStart, winEnd,
                                         axtOtherDb, fileName);
     safef(dbChrom, sizeof(dbChrom), "%s.%s", hubConnectSkipHubPrefix(database), seqName);
 
     safef(option, sizeof(option), "%s.speciesOrder", tdb->track);
     speciesOrder = cartUsualString(cart, option, NULL);
     if (speciesOrder == NULL)
 	speciesOrder = trackDbSetting(tdb, "speciesOrder");
 
+    int speciesCt = 0;
+    char *species[2048];
+    struct mafComp **newOrder;
+    if (speciesOrder)
+        {
+        // chop up speciesOrder string and store it away, checking for errors along the way
+        speciesCt = chopLine(cloneString(speciesOrder), species);
+        newOrder = needMem((speciesCt + 1) * sizeof (struct mafComp *));
+
+        int ii;
+        struct hash *nameHash = newHash(5);
+        for(ii=0; ii < speciesCt; ii++)
+            {
+            if (hashLookup(nameHash, species[ii]))
+                errAbort("speciesOrder contains %s more than once.", species[ii]);
+            hashStore(nameHash, species[ii]);
+            }
+        }
+
     for (maf = mafList; maf != NULL; maf = maf->next)
         {
         int mcCount = 0;
         struct mafComp *mc;
         struct mafAli *subset;
         struct mafComp *nextMc;
 
         /* remove empty components and configured off components
          * from MAF, and ignore
          * the entire MAF if all components are empty
          * (solely for gap annotation) */
 
         if (!useTarg)
             {
             for (mc = maf->components->next; mc != NULL; mc = nextMc)
@@ -572,46 +591,46 @@
 		if (!cartUsualBoolean(cart, option, TRUE))
 		    {
 		    if (speciesOffHash == NULL)
 			speciesOffHash = newHash(4);
 		    hashStoreName(speciesOffHash, organism);
 		    }
 		if (!cartUsualBoolean(cart, option, TRUE))
 		    slRemoveEl(&maf->components, mc);
 		else
 		    mcCount++;
 		}
 	    }
         if (mcCount == 0)
             continue;
 
-	if (speciesOrder)
+	if (speciesCt)
 	    {
-	    int speciesCt;
-	    char *species[2048];
-	    struct mafComp **newOrder, *mcThis;
+	    struct mafComp *mcThis;
 	    int i;
 
 	    mcCount = 0;
 	    speciesCt = chopLine(cloneString(speciesOrder), species);
 	    newOrder = needMem((speciesCt + 1) * sizeof (struct mafComp *));
 	    newOrder[mcCount++] = maf->components;
 
 	    for (i = 0; i < speciesCt; i++)
 		{
 		if ((mcThis = mafMayFindCompSpecies(maf, species[i], '.')) == NULL)
 		    continue;
+                if (mcThis == maf->components)
+                    errAbort("Reference species (%s) shouldn't be in speciesOrder in trackDb", species[i]);
 		newOrder[mcCount++] = mcThis;
 		}
 
 	    maf->components = NULL;
 	    for (i = 0; i < mcCount; i++)
 		{
 		newOrder[i]->next = 0;
 		slAddHead(&maf->components, newOrder[i]);
 		}
 
 	    slReverse(&maf->components);
 	    }
 	subset = mafSubsetE(maf, dbChrom, winStart, winEnd, TRUE);
 	if (subset != NULL)
 	    {