--- linux-2.6.23-rc4/scripts/kconfig/qconf.cc.orig 2007-09-01 21:15:39.017466409 +0300 +++ linux-2.6.23-rc4/scripts/kconfig/qconf.cc 2007-09-01 22:54:14.099825858 +0300 @@ -1245,6 +1245,12 @@ } } +static int search_filter(struct symbol *sym, void *context) +{ + FindQuery *query = (FindQuery *)context; + return query->sym_matches(sym); +} + void ConfigSearchWindow::search(void) { struct symbol **p; @@ -1255,7 +1261,9 @@ list->list->clear(); info->clear(); - result = sym_re_search(editField->text().latin1()); + FindQuery query(editField->text(), REGEX); + + result = sym_generic_search(search_filter, (void *)&query); if (!result) return; for (p = result; *p; p++) { @@ -1265,6 +1273,57 @@ } } +FindQuery::FindQuery(QString q, SEARCH_TYPE t, bool a_case) : + query(q), search_type(t), case_sensitive(a_case) +{ + compiled_regex = NULL; + if (search_type == REGEX) + { + compiled_regex = new QRegExp(query, case_sensitive); + } +} + +FindQuery::~FindQuery() +{ + if (compiled_regex) + { + delete compiled_regex; + compiled_regex = NULL; + } +} + +bool FindQuery::string_matches(const char *string) +{ + QString qs(string); + + if (search_type == SUBSTRING) + { + return qs.contains(query, case_sensitive); + } + else if (search_type == REGEX) + { + return (compiled_regex->search(qs) >= 0); + } + else + { + return false; + } +} + +bool FindQuery::sym_matches(struct symbol *sym) +{ + if (!sym) + { + return false; + } + + return (string_matches(sym->name) || + (sym->prop && + sym->prop->menu && + string_matches(sym->prop->menu->help) + )); +} + /* * Construct the complete config widget */ --- linux-2.6.23-rc4/scripts/kconfig/qconf.h.orig 2007-09-01 21:15:33.537030610 +0300 +++ linux-2.6.23-rc4/scripts/kconfig/qconf.h 2007-09-01 21:51:07.786743297 +0300 @@ -332,3 +332,21 @@ QSplitter* split1; QSplitter* split2; }; + +enum SEARCH_TYPE { SUBSTRING, KEYWORDS, REGEX }; +class FindQuery +{ + public: + bool case_sensitive; + SEARCH_TYPE search_type; + QString query; + QRegExp * compiled_regex; + + public: + FindQuery() : query("") { case_sensitive = false; search_type = SUBSTRING; } + FindQuery(QString q, SEARCH_TYPE t, bool a_case = false); + ~FindQuery(); + bool string_matches(const char *); + bool sym_matches(struct symbol *sym); +}; + --- linux-2.6.23-rc4/scripts/kconfig/lkc.h.orig 2007-09-01 19:56:36.528350007 +0300 +++ linux-2.6.23-rc4/scripts/kconfig/lkc.h 2007-09-01 19:57:57.758809341 +0300 @@ -111,6 +111,9 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct symbol *prop_get_symbol(struct property *prop); +typedef int (*sym_search_filter_t)(struct symbol *sym, void *context); +struct symbol **sym_generic_search(sym_search_filter_t filter, void *context); + static inline tristate sym_get_tristate_value(struct symbol *sym) { return sym->curr.tri; --- linux-2.6.23-rc4/scripts/kconfig/symbol.c.orig 2007-09-01 21:24:07.885930947 +0300 +++ linux-2.6.23-rc4/scripts/kconfig/symbol.c 2007-09-01 20:41:58.420791258 +0300 @@ -717,23 +717,39 @@ return symbol; } +static int re_search_filter(struct symbol *sym, void *re_void) +{ + return (regexec((regex_t*)re_void, sym->name, 0, NULL, 0) == 0); +} + struct symbol **sym_re_search(const char *pattern) { - struct symbol *sym, **sym_arr = NULL; - int i, cnt, size; regex_t re; + struct symbol **results; - cnt = size = 0; - /* Skip if empty */ if (strlen(pattern) == 0) return NULL; if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) return NULL; + results = sym_generic_search(re_search_filter, (void *)&re); + + regfree(&re); + + return results; +} + +struct symbol **sym_generic_search(sym_search_filter_t filter, void *context) +{ + struct symbol *sym, **sym_arr = NULL; + int i, cnt, size; + + cnt = size = 0; + for_all_symbols(i, sym) { if (sym->flags & SYMBOL_CONST || !sym->name) continue; - if (regexec(&re, sym->name, 0, NULL, 0)) + if (!filter(sym, context)) continue; if (cnt + 1 >= size) { void *tmp = sym_arr; @@ -748,7 +764,6 @@ } if (sym_arr) sym_arr[cnt] = NULL; - regfree(&re); return sym_arr; }