c0b183c96763a6ebf2c050e82859373309a2befe
angie
  Fri Oct 31 17:19:56 2014 -0700
When lookupPosition() returns false (multiple search results), thesubsequent call to doMainPage(conn, TRUE) was causing a popWarnHandler
underflow errAbort because doMainPage ends with an htmlClose (which
btw invokes popWarnHandler three times: one directly, once in
cartWebEnd and once in webEnd).  The symptom was that changes made to
the main page form before looking up a term that returned multiple
results were lost because the underflow errAbort prevented the cart
from being saved.  The solution is to not use doMainPage(conn, TRUE)
but instead to call mainPageAfterOpen enclosed by push and pop of
web warn/error handlers.

Since doMainPage(conn, TRUE) caused trouble that can be avoided by
calling mainPageAfterOpen, I removed the option.

I also removed dead code doLookupPosition; dispatch is called only
when lookupPosition() has already returned a single match, so the
work is already done and it will default to the main page anyway.

refs #12557

diff --git src/hg/hgTables/hgTables.c src/hg/hgTables/hgTables.c
index d71d50c..43f4451 100644
--- src/hg/hgTables/hgTables.c
+++ src/hg/hgTables/hgTables.c
@@ -440,34 +440,30 @@
 }
 
 boolean lookupPosition()
 /* Look up position (aka range) if need be.  Return FALSE if it puts
  * up multiple positions. */
 {
 char *range = cartUsualString(cart, hgtaRange, "");
 boolean isSingle = TRUE;
 range = trimSpaces(range);
 if (range[0] != 0)
     {
     struct region r;
     isSingle = searchPosition(range, &r);
     if (!isSingle)
 	{
-	// We will call doMainPage after this, so push web start handlers;
-	// hgFind code pops the handlers that it pushes, but after doMainPage
-	// we'll close the page and pop again, so we need to push here.
-	webPushErrHandlersCartDb(cart, database);
 	// In case user manually edits the browser location as described in #13009,
 	// revert the position.  If they instead choose from the list as we expect,
 	// that will set the position to their choice.
 	char *lastPosition = cartUsualString(cart, "lastPosition", hDefaultPos(database));
 	cartSetString(cart, "position", lastPosition);
 	}
     }
 else
     {
     cartSetString(cart, hgtaRange, hDefaultPos(database));
     }
 return isSingle;
 }
 
 struct region *getRegions()
@@ -1598,37 +1594,30 @@
 	    {
 	    char *tmp = htmlEncode(name);
 	    hPrintf("%s at %s", tmp, posBuf);
 	    freeMem(tmp);
 	    }
 	hPrintf("</A><BR>\n");
 	++count;
 	}
     lmCleanup(&lm);
     }
 if (count == 0)
     hPrintf(NO_RESULTS);
 htmlClose();
 }
 
-void doLookupPosition(struct sqlConnection *conn)
-/* Handle lookup button press.   The work has actually
- * already been done, so just call main page. */
-{
-doMainPage(conn, FALSE);
-}
-
 /* Remove any meta data variables from the cart. (Copied from above!) */
 void removeMetaData()
 {
 cartRemove(cart, "hgta_metaStatus");
 cartRemove(cart, "hgta_metaVersion");
 cartRemove(cart, "hgta_metaDatabases");
 cartRemove(cart, "hgta_metaTables");
 }
 
 void doMetaData(struct sqlConnection *conn)
 /* Get meta data for a database. */
 {
 puts("Content-Type:text/plain\n");
 char *query = "";
 if (cartVarExists(cart, hgtaMetaStatus))
@@ -1820,31 +1809,31 @@
 	    if (cartVarExists(cart, hgtaDoValueHistogram))
     		{
 		doValueHistogram(cartString(cart, hgtaDoValueHistogram));
 	    	}
 	    else
 	    	{
 	    	errAbort("Sorry, currently only the \"View Table Schema\" function of the Table Browser is available on this server.");
 	    	}
 	    }
 	}
 
     }
 else if (cartVarExists(cart, hgtaDoTest))
     doTest();
 else if (cartVarExists(cart, hgtaDoMainPage))
-    doMainPage(conn, FALSE);
+    doMainPage(conn);
 else if (cartVarExists(cart, hgtaDoSchema))
     doSchema(conn);
 else if (cartVarExists(cart, hgtaDoTopSubmit))
     doTopSubmit(conn);
 else if (cartVarExists(cart, hgtaDoSummaryStats))
     doSummaryStats(conn);
 else if (cartVarExists(cart, hgtaDoIntersectPage))
     doIntersectPage(conn);
 else if (cartVarExists(cart, hgtaDoPalOut))
     doGenePredPal(conn);
 else if (cartVarExists(cart, hgtaDoPal))
     doOutPalOptions( conn);
 else if (cartVarExists(cart, hgtaDoClearIntersect))
     doClearIntersect(conn);
 else if (cartVarExists(cart, hgtaDoIntersectMore))
@@ -1915,49 +1904,47 @@
 else if (cartVarExists(cart, hgtaDoGetCustomTrackFile))
     doGetCustomTrackFile(conn);
 else if (cartVarExists(cart, hgtaDoRemoveCustomTrack))
     doRemoveCustomTrack(conn);
 else if (cartVarExists(cart, hgtaDoClearSubtrackMerge))
     doClearSubtrackMerge(conn);
 /* Hack but I don't know what else to do now: hCompositeUi makes a hidden
  * var for hgtaDoSubtrackMergePage, so that javascript can submit and it will
  * look like that button was pressed.  However when the real submit button is
  * pressed, it will look like both were pressed... so check the real submit
  * button first (and check doMainPage before this too, for "cancel"!): */
 else if (cartVarExists(cart, hgtaDoSubtrackMergeSubmit))
     doSubtrackMergeSubmit(conn);
 else if (cartVarExists(cart, hgtaDoSubtrackMergePage))
     doSubtrackMergePage(conn);
-else if (cartVarExists(cart, hgtaDoLookupPosition))
-    doLookupPosition(conn);
 else if (cartVarExists(cart, hgtaDoSetUserRegions))
     doSetUserRegions(conn);
 else if (cartVarExists(cart, hgtaDoSubmitUserRegions))
     doSubmitUserRegions(conn);
 else if (cartVarExists(cart, hgtaDoClearSetUserRegionsText))
     doClearSetUserRegionsText(conn);
 else if (cartVarExists(cart, hgtaDoClearUserRegions))
     doClearUserRegions(conn);
 else if (cartVarExists(cart, hgtaDoMetaData))
     doMetaData(conn);
 else if (cartVarExists(cart, hgtaDoGsLogin))
     {
     doGsLogin(conn);
     dispatch();
     }
 else	/* Default - put up initial page. */
-    doMainPage(conn, FALSE);
+    doMainPage(conn);
 cartRemovePrefix(cart, hgtaDo);
 hFreeConn(&conn);
 }
 
 char *excludeVars[] = {"Submit", "submit", NULL};
 
 static void rAddTablesToHash(struct trackDb *tdbList, struct hash *hash)
 /* Add tracks in list to hash, keyed by tdb->table*/
 {
 struct trackDb *tdb;
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     {
     hashAdd(hash, tdb->table, tdb);
     if (tdb->subtracks)
         rAddTablesToHash(tdb->subtracks, hash);
@@ -2051,32 +2038,34 @@
 
 /* Init track and group lists and figure out what page to put up. */
 initGroupsTracksTables();
 if (lookupPosition())
     {
     if (cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE))
 	doGetGreatOutput(dispatch);
     else
 	dispatch();
     }
 else
     {
     struct sqlConnection *conn = NULL;
     if (!trackHubDatabase(database))
 	conn = curTrack ? hAllocConnTrack(database, curTrack) : hAllocConn(database);
-    doMainPage(conn, TRUE);
+    webPushErrHandlersCartDb(cart, database);
+    mainPageAfterOpen(conn);
     hFreeConn(&conn);
+    webPopErrHandlers();
     }
 
 textOutClose(&compressPipeline, &saveStdout);
 
 if (doGenomeSpace())
     {
     if (gsTemp)
 	{
 	cartSetString(cart, "gsTemp", gsTemp);
 	char *workUrl = NULL;
 	startBackgroundWork("./hgTables backgroundExec=gsSendToDM", &workUrl);
 
 	htmlOpen("Uploading Output to GenomeSpace");
 
 	puts("<script type=\"text/JavaScript\">");