0cb4c703bd9ff662207617fa0980092ac670aece
braney
  Tue Sep 4 16:52:03 2018 -0700
add wildcard filtering and fix-up single selection in filterValue settings refs #20227

diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c
index 2f97d8d..021a26d 100644
--- src/hg/hgTracks/bigBedTrack.c
+++ src/hg/hgTracks/bigBedTrack.c
@@ -125,34 +125,47 @@
             ret->value1 = min;
             ret->value2 = max;
             }
         }
     }
 return ret;
 }
 
 struct bigBedFilter *bigBedMakeFilterText(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb, char *filterName, char *field)
 /* Add a bigBed filter using a trackDb filterText statement. */
 {
 struct bigBedFilter *filter;
 char *setting = trackDbSettingClosestToHome(tdb, filterName);
 char *value = cartUsualStringClosestToHome(cart, tdb, FALSE, filterName, setting);
 
+char filterType[4096];
+safef(filterType, sizeof filterType, "%s%s", field, FILTER_TYPE_NAME);
+char *typeValue = cartOrTdbString(cart, tdb, filterType, FILTERTEXT_WILDCARD);
+
 AllocVar(filter);
 filter->fieldNum =  bbExtraFieldIndex(bbi, field) + 3;
+
+if (sameString(typeValue, FILTERTEXT_REGEXP) )
+    {
     filter->comparisonType = COMPARE_REGEXP;
     regcomp(&filter->regEx, value, REG_NOSUB);
+    }
+else
+    {
+    filter->comparisonType = COMPARE_WILDCARD;
+    filter->wildCardString = cloneString(value);
+    }
 
 return filter;
 }
 
 struct bigBedFilter *bigBedMakeFilterBy(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb, char *field, struct slName *choices)
 /* Add a bigBed filter using a trackDb filterBy statement. */
 {
 struct bigBedFilter *filter;
 char filterType[4096];
 safef(filterType, sizeof filterType, "%s%s", field, FILTER_TYPE_NAME);
 char *setting = cartOrTdbString(cart, tdb, filterType, NULL);
 
 AllocVar(filter);
 filter->fieldNum =  bbExtraFieldIndex(bbi, field) + 3;
 if (setting && (sameString(setting, FILTERBY_SINGLE_LIST) || sameString(setting, FILTERBY_MULTIPLE_LIST_OR)))
@@ -207,30 +220,34 @@
 
 return filters;
 }
 
 
 boolean bigBedFilterInterval(char **bedRow, struct bigBedFilter *filters)
 /* Go through a row and filter based on filters.  Return TRUE if all filters are passed. */
 {
 struct bigBedFilter *filter;
 for(filter = filters; filter; filter = filter->next)
     {
     double val = atof(bedRow[filter->fieldNum]);
 
     switch(filter->comparisonType)
         {
+        case COMPARE_WILDCARD:
+            if ( !wildMatch(filter->wildCardString, bedRow[filter->fieldNum]))
+                return FALSE;
+            break;
         case COMPARE_REGEXP:
             if (regexec(&filter->regEx,bedRow[filter->fieldNum], 0, NULL,0 ) != 0)
                 return FALSE;
             break;
         case COMPARE_HASH_LIST_AND:
         case COMPARE_HASH_LIST_OR:
             {
             struct slName *values = commaSepToSlNames(bedRow[filter->fieldNum]);
             unsigned found = 0;
             for(; values; values = values->next)
                 {
                 if (hashLookup(filter->valueHash, values->name))
                     {
                     found++;
                     if (filter->comparisonType == COMPARE_HASH_LIST_OR)