9693c13824652b5ffa51b2dd9770dcddb1e03385
kent
  Thu Feb 5 22:07:15 2015 -0800
Added wildExpandList() function.

diff --git src/lib/wildcmp.c src/lib/wildcmp.c
index 1fa1309..738b00d 100644
--- src/lib/wildcmp.c
+++ src/lib/wildcmp.c
@@ -1,21 +1,22 @@
 /* Wildcard matching. 
  *
  * This file is copyright 2002 Jim Kent, but license is hereby
  * granted for all use - public, private or commercial. */
 
 #include "common.h"
+#include "hash.h"
 
 
 static int subMatch(const char *str, const char *wild, char single, char multi)
 /* Returns number of characters that match between str and wild up
  * to the next wildcard in wild (or up to end of string.). */
 {
 int len = 0;
 
 for(;;)
     {
     if(toupper(*str++) != toupper(*wild++) )
         return(0);
     ++len;
     char c = *wild;
     if (c == 0 || c == single || c == multi)
@@ -102,15 +103,68 @@
     ++wildCard;
     }
 }
 
 boolean wildMatch(const char *wildCard, const char *string)
 /* Match using * and ? wildcards. */
 {
 return globMatch(wildCard, string, '?', '*');
 }
 
 boolean sqlMatchLike(char *wildCard, char *string)
 /* Match using % and _ wildcards. */
 {
 return globMatch(wildCard, string, '_', '%');
 }
+
+static int addMatching(char *pattern, struct slName *itemList, struct slName **retMatchList)
+/* Add all items that match pattern to retMatchList */
+{
+int count = 0;
+struct slName *item;
+for (item = itemList; item != NULL; item = item->next)
+    {
+    char *name = item->name;
+    if (wildMatch(pattern, name))
+         {
+	 slNameAddHead(retMatchList, name);
+	 ++count;
+	 }
+    }
+return count;
+}
+
+struct slName *wildExpandList(struct slName *allList, struct slName *wildList, boolean abortMissing)
+/* Wild list is a list of names, possibly including * and ? wildcard characters.  This 
+ * function returns names taken from allList that match patterns in wildList.  Works much
+ * like wildcard expansion over a file system but expands over allList instead. */
+{
+/* Build hash of allList */
+struct hash *allHash = hashNew(0);
+struct slName *name;
+for (name = allList; name != NULL; name = name->next)
+    hashAdd(allHash, name->name, NULL);
+
+/* Expand any field names with wildcards. */
+struct slName *expandedList = NULL;
+struct slName *field;
+for (field = wildList; field != NULL; field = field->next)
+    {
+    char *name = field->name;
+    if (anyWild(name))
+        {
+	int addCount = addMatching(name, allList, &expandedList);
+	if (addCount == 0 && abortMissing)
+	    errAbort("No match for %s", name);
+	}
+    else
+        {
+	if (abortMissing && !hashLookup(allHash, name))
+	    errAbort("No match for %s", name);
+	slNameAddHead(&expandedList, name);
+	}
+    }
+hashFree(&allHash);
+slReverse(&expandedList);
+return expandedList;
+}
+