2fd1f00f1dd2d4dadcc3c350165e2c0faee69c9b
angie
  Wed Jan 5 09:22:23 2011 -0800
Keep the multShadow vars in the cart so that we can distinguish alist that has been set to empty from a list that has never been
set.  cartListVarExists is the external interface.

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index 834f0de..9b2c375 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -364,37 +364,35 @@
 	{
 	/* This shadow variable enables us to detect when all inputs in
 	 * the multi-select box have been deselected. */
 	char *multVar = cv->name + multSize;
 	if (! cgiVarExists(multVar))
 	    {
 	    storeInOldVars(cart, oldVars, multVar);
 	    cartRemove(cart, multVar);
 	    }
 	}
     }
 
 /* Handle non-boolean vars. */
 for (cv = cgiVarList(); cv != NULL; cv = cv->next)
     {
-    if (! (startsWith(booShadow, cv->name) || hashLookup(booHash, cv->name) ||
-	   startsWith(multShadow, cv->name)) )
-
+    if (! (startsWith(booShadow, cv->name) || hashLookup(booHash, cv->name)))
 	{
 	storeInOldVars(cart, oldVars, cv->name);
 	cartRemove(cart, cv->name);
-        if (differentString(cv->val, CART_VAR_EMPTY))  // NOTE: CART_VAR_EMPTY logic not implemented for boolShad or multiShad
+        if (differentString(cv->val, CART_VAR_EMPTY))  // NOTE: CART_VAR_EMPTY logic not implemented for boolShad
             hashAdd(cgiHash, cv->name, cv->val);
 	}
     }
 
 /* Add new settings to cart (old values of these variables have been
  * removed above). */
 struct hashEl *hel = hashElListHash(cgiHash);
 while (hel != NULL)
     {
     cartAddString(cart, hel->name, hel->val);
     hel = hel->next;
     }
 hashFree(&cgiHash);
 hashFree(&booHash);
 }
@@ -878,30 +876,46 @@
 struct slPair *cartVars = cartVarsWithPrefix(cart,prefix);
 while(cartVars != NULL)
     {
     struct slPair *cartVar = slPopHead(&cartVars);
     cartRemove(cart, cartVar->name);
     freeMem(cartVar);
     }
 }
 
 boolean cartVarExists(struct cart *cart, char *var)
 /* Return TRUE if variable is in cart. */
 {
 return hashFindVal(cart->hash, var) != NULL;
 }
 
+boolean cartListVarExists(struct cart *cart, char *var)
+/* Return TRUE if a list variable is in cart (list may still be empty). */
+{
+static int bufSize = 0;
+static char *buf = NULL;
+char *multShadow = cgiMultListShadowPrefix();
+int len = strlen(multShadow) + strlen(var) + 1;
+if (bufSize < len)
+    {
+    buf = needMoreMem(buf, 0, len*2);
+    bufSize = len*2;
+    }
+safef(buf, bufSize, "%s%s", multShadow, var);
+return cartVarExists(cart, buf);
+}
+
 char *cartString(struct cart *cart, char *var)
 /* Return string valued cart variable. */
 {
 return hashMustFindVal(cart->hash, var);
 }
 
 char *cartOptionalString(struct cart *cart, char *var)
 /* Return string valued cart variable or NULL if it doesn't exist. */
 {
 return hashFindVal(cart->hash, var);
 }
 
 char *cartNonemptyString(struct cart *cart, char *name)
 /* Return string value associated with name.  Return NULL
  * if value doesn't exist or if it is pure white space. */