[PATCH 2.6.23-rc4] qconf ("make xconfig") Search Dialog Enhancement (rev8)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all!

[ I'm not subscribed to this list so please CC me on your replies. ]

This patch adds an option to use either substring match, regular expression 
match, or keywords search in the "make xconfig" Edit->Find dialog.

It also allows searching on the "help" field of the menus as well as 
the "name" of the symbol.

This change involved adding the sym_generic_search function to the LKC, and 
implementing sym_re_search using it.

Regards,

	Shlomi Fish

--- 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-08 11:29:31.357869409 
+0300
@@ -1199,6 +1199,23 @@
 	layout2->addWidget(searchButton);
 	layout1->addLayout(layout2);
 
+	// Initialize the "Search Type" button group.
+	searchType = new QVButtonGroup("Search Type", this, "searchType");
+
+	substringSearch = new QRadioButton(
+		"Substring Match", searchType, "Substring Match"
+		);
+
+	keywordsSearch = new QRadioButton("Keywords", searchType, "Keywords");
+
+	regexSearch = new QRadioButton(
+		"Regular Expression", searchType, "Regular Expression"
+		);
+
+	substringSearch->setChecked(TRUE);
+	layout1->addWidget(searchType);
+
+	// Initialize the ConfigView and ConfigInfoView
 	split = new QSplitter(this);
 	split->setOrientation(QSplitter::Vertical);
 	list = new ConfigView(split, name);
@@ -1245,6 +1262,20 @@
 	}
 }
 
+SEARCH_TYPE ConfigSearchWindow::getSearchType()
+{
+	return	substringSearch->isChecked() ? SUBSTRING :
+		regexSearch->isChecked() ? REGEX :
+		KEYWORDS;
+}
+
+
+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 +1286,9 @@
 	list->list->clear();
 	info->clear();
 
-	result = sym_re_search(editField->text().latin1());
+	FindQuery query(editField->text(), getSearchType());
+
+	result = sym_generic_search(search_filter, (void *)&query);
 	if (!result)
 		return;
 	for (p = result; *p; p++) {
@@ -1265,6 +1298,114 @@
 	}
 }
 
+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);
+	}
+	else if (search_type == KEYWORDS)
+	{
+		compile_keywords();
+	}
+}
+
+void FindQuery::compile_keywords()
+{
+	QRegExp split_words("\\s+");
+	QStringList bare_words = QStringList::split(split_words, query);
+
+	QStringList::iterator it;
+	for ( it = bare_words.begin(); it != bare_words.end(); ++it )
+	{
+		QString escaped = QRegExp::escape(*it);
+		
+		keywords.append(QRegExp(QString("\\b") + escaped + "\\b"));
+	}
+}
+
+FindQuery::~FindQuery()
+{
+	if (compiled_regex)
+	{
+		delete compiled_regex;
+		compiled_regex = NULL;
+	}
+}
+
+bool FindQuery::string_matches_regex(QRegExp & re, const char *string)
+{
+	QString qs(string);
+
+	return (re.search(qs) >= 0);
+}
+
+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 string_matches_regex(*compiled_regex, string);
+	}
+	else
+	{
+		return false;
+	}
+}
+
+bool FindQuery::sym_matches(struct symbol *sym)
+{
+	if (!sym)
+	{
+		return false;
+	}
+
+	if (search_type == KEYWORDS)
+	{
+		return sym_matches_keywords(sym);
+	}
+	else
+	{
+		return sym_matches_atom(sym);
+	}
+
+}
+
+bool FindQuery::sym_matches_atom(struct symbol *sym)
+{
+	return (string_matches(sym->name) ||
+		(sym->prop &&
+		 sym->prop->menu &&
+		 string_matches(sym->prop->menu->help)
+		));
+}
+
+bool FindQuery::sym_matches_keywords(struct symbol *sym)
+{
+	QValueList<QRegExp>::iterator it;
+
+	for ( it = keywords.begin(); it != keywords.end(); ++it )
+	{
+		if (!(string_matches_regex(*it, sym->name)
+				||
+			(sym->prop &&
+			 sym->prop->menu &&
+			 string_matches_regex(*it, sym->prop->menu->help))))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
 /*
  * 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-08 11:12:18.015699416 
+0300
@@ -4,6 +4,8 @@
  */
 
 #include <qlistview.h>
+#include <qradiobutton.h>
+#include <qvbuttongroup.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;
+	QRadioButton *substringSearch, *keywordsSearch, *regexSearch;
 	QSplitter* split;
 	ConfigView* list;
 	ConfigInfoView* info;
 
 	struct symbol **result;
+
+	SEARCH_TYPE getSearchType();
 };
 
 class ConfigMainWindow : public QMainWindow {
@@ -332,3 +339,25 @@
 	QSplitter* split1;
 	QSplitter* split2;
 };
+
+class FindQuery
+{
+	public:
+	bool case_sensitive;
+	SEARCH_TYPE search_type;
+	QString query;
+	QRegExp * compiled_regex;
+	QValueList<QRegExp> keywords;
+
+	public:
+	FindQuery() : query("") { case_sensitive = false; search_type = SUBSTRING; }
+	FindQuery(QString q, SEARCH_TYPE t, bool a_case = false);
+	~FindQuery();
+	void compile_keywords();
+	bool string_matches(const char *);
+	bool string_matches_regex(QRegExp & re, const char *string);
+	bool sym_matches(struct symbol *sym);
+	bool sym_matches_keywords(struct symbol *sym);
+	bool sym_matches_atom(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;
 }


---------------------------------------------------------------------
Shlomi Fish      [email protected]
Homepage:        http://www.shlomifish.org/

If it's not in my E-mail it doesn't happen. And if my E-mail is saying
one thing, and everything else says something else - E-mail will conquer.
    -- An Israeli Linuxer
-- 

---------------------------------------------------------------------
Shlomi Fish      [email protected]
Homepage:        http://www.shlomifish.org/

If it's not in my E-mail it doesn't happen. And if my E-mail is saying
one thing, and everything else says something else - E-mail will conquer.
    -- An Israeli Linuxer
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux