aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig')
-rw-r--r--scripts/kconfig/symbol.c78
1 files changed, 69 insertions, 9 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index ab8f4c835933..387d55483882 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -954,38 +954,98 @@ const char *sym_escape_string_value(const char *in)
954 return res; 954 return res;
955} 955}
956 956
957struct sym_match {
958 struct symbol *sym;
959 off_t so, eo;
960};
961
962/* Compare matched symbols as thus:
963 * - first, symbols that match exactly
964 * - then, alphabetical sort
965 */
966static int sym_rel_comp( const void *sym1, const void *sym2 )
967{
968 struct sym_match *s1 = *(struct sym_match **)sym1;
969 struct sym_match *s2 = *(struct sym_match **)sym2;
970 int l1, l2;
971
972 /* Exact match:
973 * - if matched length on symbol s1 is the length of that symbol,
974 * then this symbol should come first;
975 * - if matched length on symbol s2 is the length of that symbol,
976 * then this symbol should come first.
977 * Note: since the search can be a regexp, both symbols may match
978 * exactly; if this is the case, we can't decide which comes first,
979 * and we fallback to sorting alphabetically.
980 */
981 l1 = s1->eo - s1->so;
982 l2 = s2->eo - s2->so;
983 if (l1 == strlen(s1->sym->name) && l2 != strlen(s2->sym->name))
984 return -1;
985 if (l1 != strlen(s1->sym->name) && l2 == strlen(s2->sym->name))
986 return 1;
987
988 /* As a fallback, sort symbols alphabetically */
989 return strcmp(s1->sym->name, s2->sym->name);
990}
991
957struct symbol **sym_re_search(const char *pattern) 992struct symbol **sym_re_search(const char *pattern)
958{ 993{
959 struct symbol *sym, **sym_arr = NULL; 994 struct symbol *sym, **sym_arr = NULL;
995 struct sym_match **sym_match_arr = NULL;
960 int i, cnt, size; 996 int i, cnt, size;
961 regex_t re; 997 regex_t re;
998 regmatch_t match[1];
962 999
963 cnt = size = 0; 1000 cnt = size = 0;
964 /* Skip if empty */ 1001 /* Skip if empty */
965 if (strlen(pattern) == 0) 1002 if (strlen(pattern) == 0)
966 return NULL; 1003 return NULL;
967 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) 1004 if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
968 return NULL; 1005 return NULL;
969 1006
970 for_all_symbols(i, sym) { 1007 for_all_symbols(i, sym) {
1008 struct sym_match *tmp_sym_match;
971 if (sym->flags & SYMBOL_CONST || !sym->name) 1009 if (sym->flags & SYMBOL_CONST || !sym->name)
972 continue; 1010 continue;
973 if (regexec(&re, sym->name, 0, NULL, 0)) 1011 if (regexec(&re, sym->name, 1, match, 0))
974 continue; 1012 continue;
975 if (cnt + 1 >= size) { 1013 if (cnt + 1 >= size) {
976 void *tmp = sym_arr; 1014 void *tmp;
977 size += 16; 1015 size += 16;
978 sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); 1016 tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *));
979 if (!sym_arr) { 1017 if (!tmp) {
980 free(tmp); 1018 goto sym_re_search_free;
981 return NULL;
982 } 1019 }
1020 sym_match_arr = tmp;
983 } 1021 }
984 sym_calc_value(sym); 1022 sym_calc_value(sym);
985 sym_arr[cnt++] = sym; 1023 tmp_sym_match = (struct sym_match*)malloc(sizeof(struct sym_match));
1024 if (!tmp_sym_match)
1025 goto sym_re_search_free;
1026 tmp_sym_match->sym = sym;
1027 /* As regexec return 0, we know we have a match, so
1028 * we can use match[0].rm_[se]o without further checks
1029 */
1030 tmp_sym_match->so = match[0].rm_so;
1031 tmp_sym_match->eo = match[0].rm_eo;
1032 sym_match_arr[cnt++] = tmp_sym_match;
986 } 1033 }
987 if (sym_arr) 1034 if (sym_match_arr) {
1035 qsort(sym_match_arr, cnt, sizeof(struct sym_match*), sym_rel_comp);
1036 sym_arr = malloc((cnt+1) * sizeof(struct symbol));
1037 if (!sym_arr)
1038 goto sym_re_search_free;
1039 for (i = 0; i < cnt; i++)
1040 sym_arr[i] = sym_match_arr[i]->sym;
988 sym_arr[cnt] = NULL; 1041 sym_arr[cnt] = NULL;
1042 }
1043sym_re_search_free:
1044 if (sym_match_arr) {
1045 for (i = 0; i < cnt; i++)
1046 free(sym_match_arr[i]);
1047 free(sym_match_arr);
1048 }
989 regfree(&re); 1049 regfree(&re);
990 1050
991 return sym_arr; 1051 return sym_arr;