c43dda79c4fcf4f38056b440334018d34c419fbe tdreszer Thu Mar 24 17:13:22 2011 -0700 Now both name and description searches match each word, accept wildcards and respect quotes diff --git src/hg/hgFileSearch/hgFileSearch.c src/hg/hgFileSearch/hgFileSearch.c index 3850764..7c8038b 100644 --- src/hg/hgFileSearch/hgFileSearch.c +++ src/hg/hgFileSearch/hgFileSearch.c @@ -29,86 +29,112 @@ #define TRACK_SEARCH_ON_NAME "tsName" #define TRACK_SEARCH_ON_GROUP "tsGroup" #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 DESCRIPTION_MATCH_ON_EACH_WORD -#ifdef DESCRIPTION_MATCH_ON_EACH_WORD -static boolean isDescriptionMatch(struct trackDb *tdb, struct slName *wordList) +#define MATCH_ON_EACH_WORD +#ifdef MATCH_ON_EACH_WORD +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)) + 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). { 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->html)) return FALSE; } return TRUE; } -#endif///def DESCRIPTION_MATCH_ON_EACH_WORD +#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 DESCRIPTION_MATCH_ON_EACH_WORD -// Set the word list up once -struct slName *wordList = NULL; +#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; if (description) - wordList = slNameListOfUniqueWords(cloneString(description),TRUE); // TRUE means respect quotes -#endif///def DESCRIPTION_MATCH_ON_EACH_WORD + descList = slNameListOfUniqueWords(cloneString(description),TRUE); +#endif///def MATCH_ON_EACH_WORD struct trackDb *tdbList = *pTdbList; struct trackDb *tdbRejects = NULL; struct trackDb *tdbMatched = NULL; +#ifndef MATCH_ON_EACH_WORD char nameWild[256]; if (name) safef(nameWild,sizeof nameWild,"*%s*",name); -#ifndef DESCRIPTION_MATCH_ON_EACH_WORD char descWild[512]; if (description) safef(descWild,sizeof descWild,"*%s*",description); -#endif///ndef DESCRIPTION_MATCH_ON_EACH_WORD +#endif///ndef MATCH_ON_EACH_WORD while (tdbList != NULL) { struct trackDb *tdb = slPopHead(&tdbList); - if (name && (!wildMatch(nameWild,tdb->shortLabel) && !wildMatch(nameWild,tdb->longLabel))) + if (!tdbIsComposite(tdb)) slAddHead(&tdbRejects,tdb); else if (group && differentString(tdb->grp,group)) slAddHead(&tdbRejects,tdb); -#ifdef DESCRIPTION_MATCH_ON_EACH_WORD - else if (description && !isDescriptionMatch(tdb, wordList)) -#else///ifndef DESCRIPTION_MATCH_ON_EACH_WORD +#ifdef MATCH_ON_EACH_WORD + 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))) -#endif///ndef DESCRIPTION_MATCH_ON_EACH_WORD 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 @@ -223,34 +249,34 @@ { selectedTab = simpleTab; descSearch = cartOptionalString(cart, TRACK_SEARCH_SIMPLE); freez(&nameSearch); } else if(sameString(currentTab, "filesTab")) { selectedTab = filesTab; descSearch = cartOptionalString(cart, TRACK_SEARCH_ON_DESCR); } #else///ifndef USE_TABS enum searchTab selectedTab = filesTab; descSearch = cartOptionalString(cart, TRACK_SEARCH_ON_DESCR); #endif///ndef USE_TABS -#ifndef DESCRIPTION_MATCH_ON_EACH_WORD +#ifndef MATCH_ON_EACH_WORD if(descSearch) stripChar(descSearch, '"'); -#endif///ndef DESCRIPTION_MATCH_ON_EACH_WORD +#endif///ndef MATCH_ON_EACH_WORD #ifdef USE_TABS struct trix *trix; char trixFile[HDB_MAX_PATH_STRING]; getSearchTrixFile(db, trixFile, sizeof(trixFile)); trix = trixOpen(trixFile); #endif///def USE_TABS #endif///def SUPPORT_COMPOSITE_SEARCH printf("<div style='max-width:1080px;'>"); // FIXME: Do we need a form at all? //printf("<form action='%s' name='%s' id='%s' method='get'>\n\n", hgTracksName(),FILE_SEARCH_FORM,FILE_SEARCH_FORM); printf("<form action='../cgi-bin/hgFileSearch' name='%s' id='%s' method='get'>\n\n", FILE_SEARCH_FORM,FILE_SEARCH_FORM); cartSaveSession(cart); // Creates hidden var of hgsid to avoid bad voodoo //safef(buf, sizeof(buf), "%lu", clock1());