ba4333b84dc63534d59b306fea2031d7e8d08fbf
angie
  Thu Jan 14 12:24:50 2016 -0800
Added the capability to substitute $hgsid from the cart in a help file
included by webIncludeHelpFileSubst, for internal links.
Improved the description of hgVai Transcript Status options.
refs #16502

diff --git src/hg/lib/hVarSubst.c src/hg/lib/hVarSubst.c
index 458d1f0..1893e30 100644
--- src/hg/lib/hVarSubst.c
+++ src/hg/lib/hVarSubst.c
@@ -159,42 +159,43 @@
 * (e.g. D. yakuba). */
 {
 return (name != NULL && strlen(name) > 4 &&
 	isalpha(name[0]) &&
 	name[1] == '.' && name[2] == ' ' &&
 	isalpha(name[3]));
 }
 
 static boolean isDatabaseVar(char *varBase)
 /* Is this a variable that can be resolved only from the database name?
  * Specify the base name, excluding the o_ prefix. */
 {
 return (strcasecmp(varBase, "organism") == 0)
     || (strcasecmp(varBase, "date") == 0)
     || (strcasecmp(varBase, "linkToGatewayPage") == 0)
-    || (strcasecmp(varBase, "db") == 0);
+    || (strcasecmp(varBase, "db") == 0)
+    || (strcasecmp(varBase, "hgsid") == 0);
 }
 
 static char *valOrDb(char *val, char *database)
 /* return val if not-null, or a clone of database if it is null */
 {
 if (val == NULL)
     val = cloneString(database);
 return val;
 }
 
-static void substDatabaseVar(char *database, char *varBase,
+static void substDatabaseVar(char *database, struct cart *cart, char *varBase,
                              struct dyString *dest)
 /* substitute a variable resolved from the database name.
  * Specify the base name, excluding the o_ prefix. If database
  * can be looked up, just substitute the database name. */
 {
 if (sameString(varBase, "Organism"))
     {
     char *org = valOrDb(hOrganism(database), database);
     dyStringAppend(dest, org);
     freeMem(org);
     }
 else if (sameString(varBase, "ORGANISM"))
     {
     char *org = hOrganism(database);
     if (org != NULL)
@@ -210,106 +211,131 @@
     if ((org != NULL) && !isAbbrevScientificName(org))
             tolowers(org);
     else
             org = valOrDb(org, database);
     dyStringAppend(dest, org);
     freeMem(org);
     }
 else if (sameString(varBase, "date"))
     {
     char *date = valOrDb(hFreezeDateOpt(database), database);
     dyStringAppend(dest, date);
     freeMem(date);
     }
 else if (sameString(varBase, "db"))
     dyStringAppend(dest, database);
+else if (sameString(varBase, "hgsid") && cart != NULL)
+    dyStringAppend(dest, cartSessionId(cart));
 }
 
 static void substTrackDbVar(char *desc, struct trackDb *tdb, char *database,
                             char *varName, struct dyString *dest)
 /* substitute a variable value obtained from trackDb */
 {
 if (sameString(varName, "matrix"))
     substMatrixHtml(tdb, dest);
 else if (sameString(varName, "chainLinearGap"))
     substLinearGap(tdb, dest);
 else if (sameString(varName, "downloadsServer"))
     dyStringAppend(dest, hDownloadsServer());
 else
     dyStringAppend(dest, lookupTrackDbSubVar(desc, tdb, varName, varName));
 }
 
-static void substVar(char *desc, struct trackDb *tdb, char *database,
+static void substVar(char *desc, struct cart *cart, struct trackDb *tdb, char *database,
                      char *varName, struct dyString *dest)
 /* look up varName and insert value in output string.  Error if variable
  * can't be found */
 {
 if (isDatabaseVar(varName))
-    substDatabaseVar(database, varName, dest);
+    substDatabaseVar(database, cart, varName, dest);
 else if (tdb == NULL)
     errAbort("invalid variable \"%s\" to substitute in %s",
              varName, desc);
 else if (startsWith("o_", varName) && isDatabaseVar(varName+2))
-    substDatabaseVar(lookupOtherDb(desc, tdb, varName), varName+2, dest);
+    substDatabaseVar(lookupOtherDb(desc, tdb, varName), cart, varName+2, dest);
 else
     substTrackDbVar(desc, tdb, database, varName, dest);
 }
 
-char *hVarSubst(char *desc, struct trackDb *tdb, char *database, char *src)
+static char *hVarSubstExt(char *desc, struct cart *cart, struct trackDb *tdb, char *database,
+                          char *src)
 /* Parse a string and substitute variable references.  Return NULL if
  * no variable references were found.  Error on missing variables (except
  * $matrix).  desc is a brief description to print on an error to help with
  * debugging. tdb maybe NULL to only do substitutions based on database
- * and organism. See trackDb/README for more information.*/
+ * and organism.  cart may be NULL. See trackDb/README for more information.*/
 {
 struct dyString *dest = NULL;
 char *start = src;  // start of current static string in src
 char *next = src;   // cursor
 char varName[65];
 
 while ((next = strchr(next, '$')) != NULL)
     {
     if (dest == NULL)
         dest = dyStringNew(strlen(src));
     dyStringAppendN(dest, start, next-start);
     if (*(next+1) == '$')
         {
         // $$ is a literal $
         dyStringAppendC(dest, '$');
         start = next = next + 2;
         }
     else
         {
         // variable reference
         start = next = parseVarName(desc, next, varName, sizeof(varName));
-        substVar(desc, tdb, database, varName, dest);
+        substVar(desc, cart, tdb, database, varName, dest);
         }
     }
 if (dest != NULL)
     {
     dyStringAppend(dest, start);
     return dyStringCannibalize(&dest);
     }
 else
     return NULL; // no substitutions
 }
 
+char *hVarSubst(char *desc, struct trackDb *tdb, char *database, char *src)
+/* Parse a string and substitute variable references.  Return NULL if
+ * no variable references were found.  Error on missing variables (except
+ * $matrix).  desc is a brief description to print on error to help with
+ * debugging. tdb maybe NULL to only do substitutions based on database
+ * and organism. See trackDb/README for more information.*/
+{
+return hVarSubstExt(desc, NULL, tdb, database, src);
+}
+
 void hVarSubstInVar(char *desc, struct trackDb *tdb, char *database, char **varPtr)
 /* hVarSubst on a dynamically allocated string, replacing string in substitutions
  * occur, freeing the old memory if necessary.  See hVarSubst for details.
  */
 {
-char *dest = hVarSubst(desc, tdb, database, *varPtr);
+char *dest = hVarSubstExt(desc, NULL, tdb, database, *varPtr);
 if (dest != NULL)
     {
     freez(varPtr);
     *varPtr = dest;
     }
 }
 
 void hVarSubstTrackDb(struct trackDb *tdb, char *database)
 /* Substitute variables in trackDb shortLabel, longLabel, and html fields. */
 {
 hVarSubstInVar(tdb->track, tdb, database, &tdb->shortLabel);
 hVarSubstInVar(tdb->track, tdb, database, &tdb->longLabel);
 hVarSubstInVar(tdb->track, tdb, database, &tdb->html);
 }
+
+void hVarSubstWithCart(char *desc, struct cart *cart, struct trackDb *tdb, char *database,
+                       char **varPtr)
+/* Like hVarSubstInVar, but if cart is non-NULL, $hgsid will be substituted. */
+{
+char *dest = hVarSubstExt(desc, cart, tdb, database, *varPtr);
+if (dest != NULL)
+    {
+    freez(varPtr);
+    *varPtr = dest;
+    }
+}