4a030195664cbdd1d3c1a4b81b1ed41dbf6d9bc5
angie
  Fri Feb 15 14:02:58 2019 -0800
Prevent hgFind lib (specifically genomePos -> hgPositionsHtml) from opening a web page; instead, pass up results and warning messages to the calling CGI so it can open the page its own way.  refs #22945
hgTracks, hgTables and hgVai used to call findGenomePos{,Web} to resolve positions; hgTables and hgVai had to detect after the fact whether an HTML page had been started (with warnings and/or multiple results).
In fact, hgPositionsHtml called webEnd which could cause conflicts with what the CGI was doing afterwards.
Now, instead of findGenomePos{,Web} there is hgFindSearch which returns hgp and also warning messages, if any, via a dyString parameter.
The calling CGI decides how to open the page if necessary (for hgTracks, it's already open) and displays warnings/multiple results -- or just proceeds as usual with the single position result.

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index a270717..8379cc1 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -19,30 +19,31 @@
 #include "jsHelper.h"
 #include "trashDir.h"
 #ifndef GBROWSE
 #include "customFactory.h"
 #include "googleAnalytics.h"
 #include "wikiLink.h"
 #endif /* GBROWSE */
 #include "hgMaf.h"
 #include "hui.h"
 #include "geoMirror.h"
 #include "hubConnect.h"
 #include "trackHub.h"
 #include "cgiApoptosis.h"
 #include "customComposite.h"
 #include "regexHelper.h"
+#include "windowsToAscii.h"
 
 static char *sessionVar = "hgsid";	/* Name of cgi variable session is stored in. */
 static char *positionCgiName = "position";
 
 DbConnector cartDefaultConnector = hConnectCart;
 DbDisconnect cartDefaultDisconnector = hDisconnectCart;
 
 static void hashUpdateDynamicVal(struct hash *hash, char *name, void *val)
 /* Val is a dynamically allocated (freeMem-able) entity to put
  * in hash.  Override existing hash item with that name if any.
  * Otherwise make new hash item. */
 {
 struct hashEl *hel = hashLookup(hash, name);
 if (hel == NULL)
     hashAdd(hash, name, val);
@@ -2372,59 +2373,76 @@
 cartErrorCatcher(doMiddle, cart);
 popWarnHandler();
 }
 
 static boolean inWeb = FALSE;
 static boolean didCartHtmlStart = FALSE;
 
 void cartHtmlStart(char *title)
 /* Write HTML header and put in normal error handler. */
 {
 pushWarnHandler(htmlVaWarn);
 htmStart(stdout, title);
 didCartHtmlStart = TRUE;
 }
 
+static void cartVaWebStartMaybeHeader(struct cart *cart, char *db, boolean withHttpHeader,
+                                      char *format, va_list args)
+/* Print out optional Content-Type and pretty wrapper around things when working from cart. */
+{
+pushWarnHandler(htmlVaWarn);
+webStartWrapper(cart, trackHubSkipHubName(db), format, args, withHttpHeader, FALSE);
+inWeb = TRUE;
+jsIncludeFile("jquery.js", NULL);
+jsIncludeFile("utils.js", NULL);
+jsIncludeFile("ajax.js", NULL);
+}
+
 void cartVaWebStart(struct cart *cart, char *db, char *format, va_list args)
 /* Print out pretty wrapper around things when working
  * from cart. */
 {
-pushWarnHandler(htmlVaWarn);
-webStartWrapper(cart, trackHubSkipHubName(db), format, args, FALSE, FALSE);
-inWeb = TRUE;
+cartVaWebStartMaybeHeader(cart, db, FALSE, format, args);
 }
 
 void cartWebStart(struct cart *cart, char *db, char *format, ...)
 /* Print out pretty wrapper around things when working
  * from cart. */
 {
 va_list args;
 va_start(args, format);
 cartVaWebStart(cart, db, format, args);
 va_end(args);
-jsIncludeFile("jquery.js", NULL);
-jsIncludeFile("utils.js", NULL);
-jsIncludeFile("ajax.js", NULL);
 // WTF - variable outside of a form on almost every page we make below?
 // Tim put this in.  Talking with him it sounds like some pages might actually
 // depend on it.  Not removing it until we have a chance to test.  Best fix
 // might be to add it to cartSaveSession, though this would then no longer be
 // well named, and not all things have 'db.'  Arrr.  Probably best to remove
 // and test a bunch.
 cgiMakeHiddenVar("db", db);  
 }
 
+void cartWebStartHeader(struct cart *cart, char *db, char *format, ...)
+/* Print out Content-type header and then pretty wrapper around things when working
+ * from cart. */
+{
+va_list args;
+va_start(args, format);
+cartVaWebStartMaybeHeader(cart, db, TRUE, format, args);
+va_end(args);
+}
+
 void cartWebEnd()
 /* Write out HTML footer and get rid or error handler. */
 {
 webEnd();
 popWarnHandler();
 inWeb = FALSE;
 }
 
 void cartFooter(void)
 /* Write out HTML footer, possibly with googleAnalytics too */
 {
 #ifndef GBROWSE
 googleAnalytics();	/* can't do this in htmlEnd	*/
 #endif /* GBROWSE */
 htmlEnd();		/* because it is in a higher library */
@@ -3595,31 +3613,31 @@
 	    position = cloneString(cartUsualString(lastDbPosCart, "position", NULL));
 	    }
 	else
 	    {
 	    position = dbLocalPosContent;  // old style value
 	    }
 	}
     else
 	{
 	position = defaultPosition; // no value was set
 	}
     }
     
 if (position == NULL)
     {
-    position = cloneString(cartUsualString(cart, "position", NULL));
+    position = windowsToAscii(cloneString(cartUsualString(cart, "position", NULL)));
     }
 
 /* default if not set at all, as would happen if it came from a URL with no
  * position. Otherwise tell them to go back to the gateway. Also recognize
  * "default" as specifying the default position. */
 if (((position == NULL) || sameString(position, "default"))
     && (defaultPosition != NULL))
     position = cloneString(defaultPosition);
 
 if (!gotCart)
     {
     cartSetBoolean(lastDbPosCart, "virtMode", FALSE);
     cartSetString(lastDbPosCart, "virtModeType", "default");
     cartSetString(lastDbPosCart, "lastVirtModeType", "default");
     cartSetString(lastDbPosCart, "position", position);