104810c1ffc3b9350af01e2f97f8e58328b9434d tdreszer Mon Mar 28 12:33:39 2011 -0700 Addressed a bug in description searches and slightly streamlined. diff --git src/hg/hgFileSearch/hgFileSearch.c src/hg/hgFileSearch/hgFileSearch.c index 8dd6b68..f24d423 100644 --- src/hg/hgFileSearch/hgFileSearch.c +++ src/hg/hgFileSearch/hgFileSearch.c @@ -31,60 +31,95 @@ #define TRACK_SEARCH_ON_DESCR "tsDescr" #define TRACK_SEARCH_SORT "tsSort" #define SUPPORT_COMPOSITE_SEARCH #ifdef SUPPORT_COMPOSITE_SEARCH //#define USE_TABS #endif///def SUPPORT_COMPOSITE_SEARCH #ifdef SUPPORT_COMPOSITE_SEARCH // make a matchString function to support "contains", "is" etc. and wildcards in contains // ((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) || #define MATCH_ON_EACH_WORD #ifdef MATCH_ON_EACH_WORD +#define MATCH_ON_WILDS +static boolean matchToken(char *string, char *token) +{ +if (string == NULL) + return (token == NULL); +if (token == NULL) + return TRUE; + +if (!strchr(token,'*') && !strchr(token,'?')) + return (strcasestr(string,token) != NULL); + +#ifdef MATCH_ON_WILDS +char wordWild[1024]; +safef(wordWild,sizeof wordWild,"*%s*",token); +return wildMatch(wordWild, string); + +// do this with regex ? Would require all sorts of careful parsing for ()., etc. +//safef(wordWild,sizeof wordWild,"^*%s*$",token); +//regex_t regEx; +//int err = regcomp(®Ex, token, REG_NOSUB | REG_ICASE); +//if(err != 0) // Compile the regular expression so that it can be used. Use: REG_EXTENDED ? +// { +// char buffer[128]; +// regerror(err, ®Ex, buffer, sizeof buffer); +// warn("ERROR: Invalid regular expression: [%s] %s\n",token,buffer); +// regfree(®Ex); +// return FALSE; +// } +//err = regexec(®Ex, mdbVar->val, 0, NULL, 0); +//regfree(®Ex); +//return (err == 0); + +#endif//def MATCH_ON_WILDS +} + static boolean doesNameMatch(struct trackDb *tdb, struct slName *wordList) // We parse str and look for every word at the start of any word in track description (i.e. google style). { if (tdb->html == NULL) return (wordList != NULL); struct slName *word = wordList; for(; word != NULL; word = word->next) { - char wordWild[256]; - safef(wordWild,sizeof wordWild,"*%s*",word->name); - if (!wildMatch(wordWild, tdb->shortLabel) - && !wildMatch(wordWild, tdb->longLabel)) + if (!matchToken(tdb->shortLabel,word->name) + && !matchToken(tdb->longLabel, word->name)) return FALSE; } return TRUE; } static boolean doesDescriptionMatch(struct trackDb *tdb, struct slName *wordList) // We parse str and look for every word at the start of any word in track description (i.e. google style). { +//static boolean tryitOneCycle=TRUE; if (tdb->html == NULL) return (wordList != NULL); +if (strchr(tdb->html,'\n')) + strSwapChar(tdb->html,'\n',' '); // DANGER: don't own memory. However, this CGI will use html for no other purpose + struct slName *word = wordList; for(; word != NULL; word = word->next) { - char wordWild[256]; - safef(wordWild,sizeof wordWild,"*%s*",word->name); - if (!wildMatch(wordWild, tdb->html)) + if (!matchToken(tdb->html,word->name)) return FALSE; } return TRUE; } #endif///def MATCH_ON_EACH_WORD static struct trackDb *tdbFilterBy(struct trackDb **pTdbList, char *name, char *description, char *group) // returns tdbs that match supplied criterion, leaving unmatched in list passed in { #ifdef MATCH_ON_EACH_WORD // Set the word lists up once struct slName *nameList = NULL; if (name) nameList = slNameListOfUniqueWords(cloneString(name),TRUE); // TRUE means respect quotes struct slName *descList = NULL; @@ -116,31 +151,30 @@ else if (name && !doesNameMatch(tdb, nameList)) slAddHead(&tdbRejects,tdb); else if (description && !doesDescriptionMatch(tdb, descList)) slAddHead(&tdbRejects,tdb); #else///ifndef MATCH_ON_EACH_WORD else if (name && (!wildMatch(nameWild,tdb->shortLabel) && !wildMatch(nameWild,tdb->longLabel))) slAddHead(&tdbRejects,tdb); else if (description && (tdb->html == NULL || !wildMatch(descWild,tdb->html))) slAddHead(&tdbRejects,tdb); #endif///ndef MATCH_ON_EACH_WORD else slAddHead(&tdbMatched,tdb); } //slReverse(&tdbRejects); // Needed? //slReverse(&tdbMatched); // Needed? - *pTdbList = tdbRejects; //warn("matched %d tracks",slCount(tdbMatched)); return tdbMatched; } static boolean mdbSelectsAddFoundComposites(struct slPair **pMdbSelects,struct trackDb *tdbsFound) // Adds a composite mdbSelect (if found in tdbsFound) to the head of the pairs list. // If tdbsFound is NULL, then add dummy composite search criteria { // create comma separated list of composites struct dyString *dyComposites = dyStringNew(256); struct trackDb *tdb = tdbsFound; for(;tdb != NULL; tdb = tdb->next) {