--- linux-2.6.24-rc1/scripts/kconfig/keywords_search.c.orig 2007-10-25 19:09:35.044535732 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/keywords_search.c 2007-10-26 18:22:43.967264575 +0200 @@ -0,0 +1,216 @@ +/* + * Keywords' Search Micro-Library. + * + * Copyrighted by Shlomi Fish, 2007. + * + * Licensed under the MIT/X11 License: + * + * http://www.opensource.org/licenses/mit-license.php + * + * */ +#include "keywords_search.h" +#include +#include +#include + +#define is_word_char(c) (isalpha(c) || isdigit(c)) + +static int add_word(keywords_search_handle_t *h, const char **p) +{ + const char *start; + keywords_search_keyword_t *word; + + start = *p; + while (is_word_char(**p)) + { + (*p)++; + } + if (h->num_words == h->max_num_words) + { + void *new_ptr; + h->max_num_words += 16; + new_ptr = realloc(h->words, + sizeof(h->words[0]) * h->max_num_words + ); + if (new_ptr == NULL) + { + return 0; + } + h->words = new_ptr; + } + word = &(h->words[h->num_words++]); + word->found = 0; + word->word = + malloc(sizeof(word->word[0]) * + (word->word_len = (*p)-start)+1 + ); + if (! word->word) + { + return 0; + } + memcpy(word->word, start, word->word_len); + word->word[word->word_len] = '\0'; + + return 1; +} + +keywords_search_handle_t *keywords_search_compile(const char *pattern) +{ + int i; + keywords_search_handle_t *ret = NULL; + const char *char_ptr; + + ret = malloc(sizeof(*ret)); + if (!ret) + { + return NULL; + } + + ret->num_words = 0; + ret->max_num_words = 0; + ret->num_found_words = 0; + ret->words = NULL; + + char_ptr = pattern; + + while (*char_ptr) + { + if (is_word_char(*char_ptr)) + { + if (!add_word(ret, &char_ptr)) + { + goto cleanup_words; + } + } + else + { + char_ptr++; + } + } + + return ret; + +cleanup_words: + for(i=0;inum_words;i++) + { + free(ret->words[i].word); + ret->words[i].word = NULL; + } + free(ret->words); + ret->words = NULL; + + free(ret); + ret = NULL; + + return NULL; +} + +static int +cmp_word(keywords_search_handle_t* handle, keywords_search_keyword_t *word, const char *start, const int len) +{ + if (word->found || (word->word_len != len)) + { + return 0; + } + + if (handle->case_sensitivity) + { + return !strncmp(word->word, start, len); + } + else + { + return !strncasecmp(word->word, start, len); + } +} + +static int +find_word(keywords_search_handle_t* handle, const char *start, const int len) +{ + int i; + keywords_search_keyword_t *word; + + word = handle->words; + for(i = 0; i < handle->num_words; i++, word++) + { + if (cmp_word(handle, word, start, len)) + { + word->found = 1; + if (++handle->num_found_words == handle->num_words) + { + return 1; + } + } + } + return 0; +} + +int keywords_search_matches(keywords_search_handle_t *handle, const char *string, int case_sensitivity) +{ + const char *char_ptr, *start; + + char_ptr = string; + + handle->case_sensitivity = case_sensitivity; + + if (handle->num_found_words == handle->num_words) + { + return 1; + } + + /* Handle the NULL string gracefully. */ + if (! string) + { + return 0; + } + + while(*char_ptr) + { + if (is_word_char(*char_ptr)) + { + int len; + + start = char_ptr; + while (is_word_char(*char_ptr)) + { + char_ptr++; + } + + len = char_ptr - start; + + if (find_word(handle, start, len)) + { + return 1; + } + } + else + { + char_ptr++; + } + } + + return 0; +} + +void keywords_search_reset(keywords_search_handle_t *handle) +{ + int i; + + /* Reset the state of the handle to no words found. */ + handle->num_found_words = 0; + for(i=0 ; i < handle->num_words ; i++) + { + handle->words[i].found = 0; + } +} + +void keywords_search_free(keywords_search_handle_t *handle) +{ + int i; + + for(i=0 ; i < handle->num_words ; i++) + { + free(handle->words[i].word); + } + free(handle->words); + free(handle); +} --- linux-2.6.24-rc1/scripts/kconfig/keywords_search.h.orig 2007-10-25 19:09:38.380802836 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/keywords_search.h 2007-10-26 18:22:43.967264575 +0200 @@ -0,0 +1,41 @@ +/* + * Keywords' Search Micro-Library. + * + * Copyrighted by Shlomi Fish, 2007. + * + * Licensed under the MIT/X11 License: + * + * http://www.opensource.org/licenses/mit-license.php + * + * */ +#ifndef KEYWORDS_SEARCH_H +#define KEYWORDS_SEARCH_H + +struct keywords_search_keyword_struct +{ + int found; + char *word; + int word_len; +}; + +typedef struct keywords_search_keyword_struct keywords_search_keyword_t; + +struct keywords_search_handle_struct +{ + int num_words; + int max_num_words; + int num_found_words; + keywords_search_keyword_t *words; + /* The case sensitivity flag - valid only for a search session. */ + int case_sensitivity; +}; + +typedef struct keywords_search_handle_struct keywords_search_handle_t; + +keywords_search_handle_t *keywords_search_compile(const char *pattern); +int keywords_search_matches(keywords_search_handle_t* handle, const char *string, int case_sensitivity); +void keywords_search_reset(keywords_search_handle_t *handle); +void keywords_search_free(keywords_search_handle_t *handle); + +#endif /* KEYWORDS_SEARCH_H */ + --- linux-2.6.24-rc1/scripts/kconfig/lkc.h.orig 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/lkc.h 2007-10-25 20:36:26.378540205 +0200 @@ -111,6 +111,21 @@ 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); +struct symbol **sym_pattern_search(const char *pattern, unsigned int flags); + +enum SYM_PATTERN_SEARCH_FLAGS +{ + SYM_PATTERN_SEARCH_REGEX = 0x0, + SYM_PATTERN_SEARCH_SUBSTRING = 0x1, + SYM_PATTERN_SEARCH_KEYWORDS_AND = 0x2, + SYM_PATTERN_SEARCH_TYPE_MASK = 0xF, + SYM_PATTERN_CASE_SENSITIVE = 0x10, + SYM_PATTERN_CASE_INSENSITIVE = 0x00, + SYM_PATTERN_CASE_MASK = 0x10, +}; + static inline tristate sym_get_tristate_value(struct symbol *sym) { return sym->curr.tri; --- linux-2.6.24-rc1/scripts/kconfig/Makefile.orig 2007-10-25 19:21:13.568914344 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/Makefile 2007-10-25 21:47:20.833984328 +0200 @@ -112,9 +112,9 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o -conf-objs := conf.o zconf.tab.o -mconf-objs := mconf.o zconf.tab.o $(lxdialog) -kxgettext-objs := kxgettext.o zconf.tab.o +conf-objs := conf.o zconf.tab.o keywords_search.o +mconf-objs := mconf.o zconf.tab.o keywords_search.o $(lxdialog) +kxgettext-objs := kxgettext.o zconf.tab.o keywords_search.o hostprogs-y := conf qconf gconf kxgettext @@ -132,11 +132,11 @@ ifeq ($(qconf-target),1) qconf-cxxobjs := qconf.o -qconf-objs := kconfig_load.o zconf.tab.o +qconf-objs := kconfig_load.o zconf.tab.o keywords_search.o endif ifeq ($(gconf-target),1) -gconf-objs := gconf.o kconfig_load.o zconf.tab.o +gconf-objs := gconf.o kconfig_load.o zconf.tab.o keywords_search.o endif clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ @@ -251,7 +251,7 @@ # The following requires flex/bison/gperf # By default we use the _shipped versions, uncomment the following line if # you are modifying the flex/bison src. -# LKC_GENPARSER := 1 +LKC_GENPARSER := 1 ifdef LKC_GENPARSER --- linux-2.6.24-rc1/scripts/kconfig/qconf.cc.orig 2007-10-24 16:39:34.585996016 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/qconf.cc 2007-10-26 19:01:27.417819050 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -1199,6 +1200,36 @@ layout2->addWidget(searchButton); layout1->addLayout(layout2); + // Initialize the "Search Type" button group. + searchType = new QVButtonGroup("Search Type", this, "searchType"); + + searchType->insert(new QRadioButton("Substring Match", searchType), + SYM_PATTERN_SEARCH_SUBSTRING + ); + + searchType->insert(new QRadioButton("Keywords", searchType), + SYM_PATTERN_SEARCH_KEYWORDS_AND + ); + + searchType->insert(new QRadioButton("Regular Expression", searchType), + SYM_PATTERN_SEARCH_REGEX + ); + + searchType->setButton(SYM_PATTERN_SEARCH_SUBSTRING); + layout1->addWidget(searchType); + + // Initialize the "Options" button group. + options = new QVButtonGroup("Options", this, "Options"); + + caseSensitivity = new QCheckBox( + "Case sensitive", options, "Case sensitive" + ); + + caseSensitivity->setChecked(FALSE); + + layout1->addWidget(options); + + // Initialize the ConfigView and ConfigInfoView split = new QSplitter(this); split->setOrientation(QSplitter::Vertical); list = new ConfigView(split, name); @@ -1245,6 +1276,17 @@ } } +unsigned int ConfigSearchWindow::getSearchFlags() +{ + return (searchType->selectedId() + | + (caseSensitivity->isChecked() + ? SYM_PATTERN_CASE_SENSITIVE + : SYM_PATTERN_CASE_INSENSITIVE + ) + ); +} + void ConfigSearchWindow::search(void) { struct symbol **p; @@ -1255,7 +1297,7 @@ list->list->clear(); info->clear(); - result = sym_re_search(editField->text().latin1()); + result = sym_pattern_search(editField->text(), getSearchFlags()); if (!result) return; for (p = result; *p; p++) { --- linux-2.6.24-rc1/scripts/kconfig/qconf.h.orig 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/qconf.h 2007-10-26 18:47:21.816359482 +0200 @@ -4,6 +4,8 @@ */ #include +#include +#include #if QT_VERSION >= 300 #include #else @@ -275,6 +277,7 @@ bool _showDebug; }; +enum SEARCH_TYPE { SUBSTRING, KEYWORDS, REGEX }; class ConfigSearchWindow : public QDialog { Q_OBJECT typedef class QDialog Parent; @@ -288,11 +291,15 @@ protected: QLineEdit* editField; QPushButton* searchButton; + QVButtonGroup *searchType, *options; + QCheckBox *caseSensitivity; QSplitter* split; ConfigView* list; ConfigInfoView* info; struct symbol **result; + + unsigned int getSearchFlags(); }; class ConfigMainWindow : public QMainWindow { @@ -332,3 +339,4 @@ QSplitter* split1; QSplitter* split2; }; + --- linux-2.6.24-rc1/scripts/kconfig/symbol.c.orig 2007-10-09 22:31:38.000000000 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/symbol.c 2007-10-26 14:04:08.035157563 +0200 @@ -9,6 +9,8 @@ #include #include +#include "keywords_search.h" + #define LKC_DIRECT_LINK #include "lkc.h" @@ -717,23 +719,183 @@ 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); +} + + +/* The old function that only searches through sym->name. */ 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 substring_search_context_struct +{ + const char * substring; + char *(*find_func)(const char *,const char *); +}; + +typedef struct substring_search_context_struct substring_search_context_t; + +#define MATCH_SYMBOL() \ + (MATCH(sym->name) || \ + (sym->prop && \ + ((sym->prop->text && MATCH(sym->prop->text)) || \ + (sym->prop->menu && sym->prop->menu->help && \ + MATCH(sym->prop->menu->help))) \ + )); + +static int substring_filter(struct symbol *sym, void *context_void) +{ + substring_search_context_t *context; + context = (substring_search_context_t *)context_void; + +#define MATCH(string) \ + (context->find_func((string), context->substring)) + + return MATCH_SYMBOL(); +#undef MATCH +} + +static struct symbol **substring_search(const char *substring, int case_sense) +{ + substring_search_context_t context; + + context.substring = substring; + context.find_func = case_sense ? strstr : strcasestr; + + return sym_generic_search(substring_filter, (void *)&context); +} + +struct keywords_search_context_struct +{ + keywords_search_handle_t * h; + int case_sense; +}; + +typedef struct keywords_search_context_struct keywords_search_context_t; + +static int keywords_filter(struct symbol *sym, void *context_void) +{ + keywords_search_context_t *context; + context = (keywords_search_context_t *)context_void; + + keywords_search_reset(context->h); + +#define MATCH(string) \ + (keywords_search_matches(context->h, string, context->case_sense)) + + return MATCH_SYMBOL(); +#undef MATCH +} + +static struct symbol **keywords_search(const char *query, int case_sense) +{ + struct symbol **results; + keywords_search_context_t context; + + context.h = keywords_search_compile(query); + if (! context.h) + { + return NULL; + } + context.case_sense = case_sense; + + results = sym_generic_search(keywords_filter, (void *)&context); + keywords_search_free (context.h); + + return results; +} + + +static int re_search2_filter(struct symbol *sym, void *re_void) +{ + regex_t *re = (regex_t*)re_void; + +#define MATCH(string) \ + (regexec(re, (string), 0, NULL, 0) == 0) + + return MATCH_SYMBOL(); +#undef MATCH +} + +static struct symbol **sym_re_search2(const char *pattern, int case_sense) +{ + regex_t re; + struct symbol **results; + int rc_flags; + + rc_flags = case_sense ? 0 : REG_ICASE; + + if (strlen(pattern) == 0) + return NULL; + if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|rc_flags)) + return NULL; + + results = sym_generic_search(re_search2_filter, (void *)&re); + + regfree(&re); + + return results; +} + + +#undef MATCH_SYMBOL + +#define is_case_sensitive(flags) \ + (((flags) & SYM_PATTERN_CASE_MASK) == SYM_PATTERN_CASE_SENSITIVE) + +struct symbol **sym_pattern_search(const char *pattern, unsigned int flags) +{ + unsigned int type; + int case_sense; + + type = (flags & SYM_PATTERN_SEARCH_TYPE_MASK); + case_sense = is_case_sensitive(flags); + + if (type == SYM_PATTERN_SEARCH_REGEX) + { + return sym_re_search2(pattern, case_sense); + } + else if (type == SYM_PATTERN_SEARCH_SUBSTRING) + { + return substring_search(pattern, case_sense); + } + else if (type == SYM_PATTERN_SEARCH_KEYWORDS_AND) + { + return keywords_search(pattern, case_sense); + } + else + { + return NULL; + } +} + +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 +910,6 @@ } if (sym_arr) sym_arr[cnt] = NULL; - regfree(&re); return sym_arr; } --- linux-2.6.24-rc1/scripts/kconfig/zconf.y.orig 2007-10-25 21:41:10.476153230 +0200 +++ linux-2.6.24-rc1/scripts/kconfig/zconf.y 2007-10-25 21:51:26.117733005 +0200 @@ -4,6 +4,7 @@ * Released under the terms of the GNU GPL v2.0. */ +#define _GNU_SOURCE #include #include #include