Commits

Anonymous committed 2aceb6d

r4927@telaviv1: shlomi | 2008-04-23 21:09:18 +0300
Added the "make xconfig" kernel patch.

  • Participants
  • Parent commits d094471

Comments (0)

Files changed (3)

File lib/Shlomif/Homepage/SectionMenu/Sects/Software.pm

                     'title' => "Park - a Dialect of the Lisp Programming Language inspired by Arc",
                 },
                 {
+                    'text' => "Kernel Configuration Search Enhancement",
+                    'url' => "open-source/projects/linux-kernel/xconfig-search/",
+                    'title' => "Patch to Enhance the Configuration Searching of the Linux Kernel",
+                },
+                {
                     'text' => "Bits and Bobs",
                     'url' => "open-source/bits.html",
                     'title' => "Small Open Source Programs",

File t2/open-source/projects/linux-kernel/xconfig-search/index.html.wml

+#include '../template.wml'
+
+<latemp_subject "Linux Kernel Patch: &quot;make xconfig&quot; Search Enhancement" />
+
+<h2 id="intro">Introduction</h2>
+
+<p>
+This is a patch to <a href="http://www.kernel.org/">the Linux kernel</a>
+that enhances the search dialog of "make xconfig". According to the input
+of the kernel developers, it was done in a modular way by enhancing the
+kernel C configuration API.
+</p>
+
+<h2 id="download">Download</h2>
+
+<ul>
+<li>
+<a href="xconfig-search-patch-take3-11.diff"><b>take3-11 - Latest Version</b></a> -
+applies and compiles cleanly on linux-2.6.25-rc6, some earlier kernels and
+probably later ones up to and including 2.6.25.
+</li>
+</ul>
+
+<h2 id="licence">Licence</h2>
+
+<p>
+I hereby disclaim any explicit or implicit claims to copyrights of the
+GPLed code that I modified. I added some new files and they are under
+the X11 Licence.
+</p>
+

File t2/open-source/projects/linux-kernel/xconfig-search/xconfig-search-patch-take3-11.diff

+--- 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 <string.h>
++#include <stdlib.h>
++#include <ctype.h>
++
++#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;i<ret->num_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 <qfiledialog.h>
+ #include <qdragobject.h>
+ #include <qregexp.h>
++#include <qradiobutton.h>
+ 
+ #include <stdlib.h>
+ 
+@@ -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 <qlistview.h>
++#include <qvbuttongroup.h>
++#include <qcheckbox.h>
+ #if QT_VERSION >= 300
+ #include <qsettings.h>
+ #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 <regex.h>
+ #include <sys/utsname.h>
+ 
++#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 <ctype.h>
+ #include <stdarg.h>
+ #include <stdio.h>