From: "Yann E. MORIN" <[email protected]>
When searching for symbols, return the symbols sorted by relevance.
Relevance is the ratio of the length of the matched string and the
length of the symbol name. Symbols of equal relevance are sorted
alphabetically.
Reported-by: Jean Delvare <[email protected]>
Signed-off-by: "Yann E. MORIN" <[email protected]>
Cc: Jean Delvare <[email protected]>
Cc: Michal Marek <[email protected]>
Cc: Roland Eggner <[email protected]>
Cc: Wang YanQing <[email protected]>
---
scripts/kconfig/symbol.c | 66 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 9 deletions(-)
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index ecc5aa5..baba030 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -943,38 +943,86 @@ const char *sym_escape_string_value(const char *in)
return res;
}
+struct sym_match {
+ struct symbol *sym;
+ int rel;
+};
+
+/* Compare matched symbols as thus:
+ * - highest relevance first
+ * - equal relevance sorted alphabetically
+ */
+static int sym_rel_comp( const void *sym1, const void *sym2 )
+{
+ struct sym_match **s1 = (struct sym_match **)sym1;
+ struct sym_match **s2 = (struct sym_match **)sym2;
+
+ if ( (*s1)->rel > (*s2)->rel )
+ return -1;
+ else if ( (*s1)->rel < (*s2)->rel )
+ return 1;
+ else
+ return strcmp( (*s1)->sym->name, (*s2)->sym->name );
+}
+
struct symbol **sym_re_search(const char *pattern)
{
struct symbol *sym, **sym_arr = NULL;
+ struct sym_match **sym_match_arr = NULL;
int i, cnt, size;
regex_t re;
+ regmatch_t match[1];
cnt = size = 0;
/* Skip if empty */
if (strlen(pattern) == 0)
return NULL;
- if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+ if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
return NULL;
for_all_symbols(i, sym) {
+ struct sym_match *tmp_sym_match;
if (sym->flags & SYMBOL_CONST || !sym->name)
continue;
- if (regexec(&re, sym->name, 0, NULL, 0))
+ if (regexec(&re, sym->name, 1, match, 0))
continue;
if (cnt + 1 >= size) {
- void *tmp = sym_arr;
+ void *tmp;
size += 16;
- sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
- if (!sym_arr) {
- free(tmp);
- return NULL;
+ tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *));
+ if (!tmp) {
+ goto sym_re_search_free;
}
+ sym_match_arr = tmp;
}
sym_calc_value(sym);
- sym_arr[cnt++] = sym;
+ tmp_sym_match = (struct sym_match*)malloc(sizeof(struct sym_match));
+ if (!tmp_sym_match)
+ goto sym_re_search_free;
+ tmp_sym_match->sym = sym;
+ /* As regexec return 0, we know we have a match, so
+ * we can use match[0].rm_[se]o without further checks
+ */
+ tmp_sym_match->rel = (100*(match[0].rm_eo-match[0].rm_so))
+ /strlen(sym->name);
+ sym_match_arr[cnt++] = tmp_sym_match;
}
- if (sym_arr)
+
+ if( sym_match_arr ) {
+ qsort( sym_match_arr, cnt, sizeof(struct sym_match*), sym_rel_comp );
+ sym_arr = malloc( (cnt+1) * sizeof(struct symbol) );
+ if (!sym_arr)
+ goto sym_re_search_free;
+ for ( i=0; i<cnt; i++ )
+ sym_arr[i] = sym_match_arr[i]->sym;
sym_arr[cnt] = NULL;
+ }
+sym_re_search_free:
+ if (sym_match_arr) {
+ for ( i=0; i<cnt; i++ )
+ free( sym_match_arr[i] );
+ free( sym_match_arr );
+ }
regfree(&re);
return sym_arr;
--
1.8.1.2
Jean, All,
On Mon, May 06, 2013 at 08:20:47PM +0200, Yann E. MORIN wrote:
> When searching for symbols, return the symbols sorted by relevance.
Woops... Worng version of the patch. Forget it...
Sorry...
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'