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; +} +