X-Git-Url: https://jxself.org/git/?p=carl9170fw.git;a=blobdiff_plain;f=config%2Fsymbol.c;h=c9123ed2b791ad2de18450485f11ed15984cf448;hp=387d554838828de87d82b829ae0dfd9b464feaa2;hb=2f1132cbcec40e431991cda7ff3744455b46c3df;hpb=3c443264cbef7b1e1fe08cc51cb7ad6d5752e7ae diff --git a/config/symbol.c b/config/symbol.c index 387d554..c9123ed 100644 --- a/config/symbol.c +++ b/config/symbol.c @@ -77,7 +77,7 @@ const char *sym_type_name(enum symbol_type type) { switch (type) { case S_BOOLEAN: - return "boolean"; + return "bool"; case S_TRISTATE: return "tristate"; case S_INT: @@ -112,7 +112,7 @@ struct property *sym_get_env_prop(struct symbol *sym) return NULL; } -struct property *sym_get_default_prop(struct symbol *sym) +static struct property *sym_get_default_prop(struct symbol *sym) { struct property *prop; @@ -136,7 +136,7 @@ static struct property *sym_get_range_prop(struct symbol *sym) return NULL; } -static int sym_get_range_val(struct symbol *sym, int base) +static long long sym_get_range_val(struct symbol *sym, int base) { sym_calc_value(sym); switch (sym->type) { @@ -149,13 +149,14 @@ static int sym_get_range_val(struct symbol *sym, int base) default: break; } - return strtol(sym->curr.val, NULL, base); + return strtoll(sym->curr.val, NULL, base); } static void sym_validate_range(struct symbol *sym) { struct property *prop; - int base, val, val2; + int base; + long long val, val2; char str[64]; switch (sym->type) { @@ -171,7 +172,7 @@ static void sym_validate_range(struct symbol *sym) prop = sym_get_range_prop(sym); if (!prop) return; - val = strtol(sym->curr.val, NULL, base); + val = strtoll(sym->curr.val, NULL, base); val2 = sym_get_range_val(prop->expr->left.sym, base); if (val >= val2) { val2 = sym_get_range_val(prop->expr->right.sym, base); @@ -179,21 +180,55 @@ static void sym_validate_range(struct symbol *sym) return; } if (sym->type == S_INT) - sprintf(str, "%d", val2); + sprintf(str, "%lld", val2); else - sprintf(str, "0x%x", val2); + sprintf(str, "0x%llx", val2); sym->curr.val = strdup(str); } +static void sym_set_changed(struct symbol *sym) +{ + struct property *prop; + + sym->flags |= SYMBOL_CHANGED; + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu) + prop->menu->flags |= MENU_CHANGED; + } +} + +static void sym_set_all_changed(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym_set_changed(sym); +} + static void sym_calc_visibility(struct symbol *sym) { struct property *prop; + struct symbol *choice_sym = NULL; tristate tri; /* any prompt visible? */ tri = no; + + if (sym_is_choice_value(sym)) + choice_sym = prop_get_symbol(sym_get_choice_prop(sym)); + for_all_prompts(sym, prop) { prop->visible.tri = expr_calc_value(prop->visible.expr); + /* + * Tristate choice_values with visibility 'mod' are + * not visible if the corresponding choice's value is + * 'yes'. + */ + if (choice_sym && sym->type == S_TRISTATE && + prop->visible.tri == mod && choice_sym->curr.tri == yes) + prop->visible.tri = no; + tri = EXPR_OR(tri, prop->visible.tri); } if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) @@ -223,6 +258,15 @@ static void sym_calc_visibility(struct symbol *sym) sym->rev_dep.tri = tri; sym_set_changed(sym); } + tri = no; + if (sym->implied.expr && sym->dir_dep.tri != no) + tri = expr_calc_value(sym->implied.expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (sym->implied.tri != tri) { + sym->implied.tri = tri; + sym_set_changed(sym); + } } /* @@ -362,6 +406,10 @@ void sym_calc_value(struct symbol *sym) newval.tri = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); } + if (sym->implied.tri != no) { + sym->flags |= SYMBOL_WRITE; + newval.tri = EXPR_OR(newval.tri, sym->implied.tri); + } } calc_newval: if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { @@ -378,7 +426,8 @@ void sym_calc_value(struct symbol *sym) } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } - if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) + if (newval.tri == mod && + (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes)) newval.tri = yes; break; case S_STRING: @@ -446,28 +495,7 @@ void sym_clear_all_valid(void) for_all_symbols(i, sym) sym->flags &= ~SYMBOL_VALID; sym_add_change_count(1); - if (modules_sym) - sym_calc_value(modules_sym); -} - -void sym_set_changed(struct symbol *sym) -{ - struct property *prop; - - sym->flags |= SYMBOL_CHANGED; - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu) - prop->menu->flags |= MENU_CHANGED; - } -} - -void sym_set_all_changed(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym_set_changed(sym); + sym_calc_value(modules_sym); } bool sym_tristate_within_range(struct symbol *sym, tristate val) @@ -484,6 +512,8 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) return false; if (sym->visible <= sym->rev_dep.tri) return false; + if (sym->implied.tri == yes && val == mod) + return false; if (sym_is_choice_value(sym) && sym->visible == yes) return val == yes; return val >= sym->rev_dep.tri && val <= sym->visible; @@ -594,7 +624,7 @@ bool sym_string_valid(struct symbol *sym, const char *str) bool sym_string_within_range(struct symbol *sym, const char *str) { struct property *prop; - int val; + long long val; switch (sym->type) { case S_STRING: @@ -605,7 +635,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str) prop = sym_get_range_prop(sym); if (!prop) return true; - val = strtol(str, NULL, 10); + val = strtoll(str, NULL, 10); return val >= sym_get_range_val(prop->expr->left.sym, 10) && val <= sym_get_range_val(prop->expr->right.sym, 10); case S_HEX: @@ -614,7 +644,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str) prop = sym_get_range_prop(sym); if (!prop) return true; - val = strtol(str, NULL, 16); + val = strtoll(str, NULL, 16); return val >= sym_get_range_val(prop->expr->left.sym, 16) && val <= sym_get_range_val(prop->expr->right.sym, 16); case S_BOOLEAN: @@ -736,6 +766,10 @@ const char *sym_get_string_default(struct symbol *sym) if (sym->type == S_BOOLEAN && val == mod) val = yes; + /* adjust the default value if this symbol is implied by another */ + if (val < sym->implied.tri) + val = sym->implied.tri; + switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: @@ -873,6 +907,10 @@ const char *sym_expand_string_value(const char *in) char *res; size_t reslen; + /* + * Note: 'in' might come from a token that's about to be + * freed, so make sure to always allocate a new string + */ reslen = strlen(in) + 1; res = xmalloc(reslen); res[0] = '\0'; @@ -963,11 +1001,11 @@ struct sym_match { * - first, symbols that match exactly * - then, alphabetical sort */ -static int sym_rel_comp( const void *sym1, const void *sym2 ) +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; - int l1, l2; + const struct sym_match *s1 = sym1; + const struct sym_match *s2 = sym2; + int exact1, exact2; /* Exact match: * - if matched length on symbol s1 is the length of that symbol, @@ -978,11 +1016,11 @@ static int sym_rel_comp( const void *sym1, const void *sym2 ) * exactly; if this is the case, we can't decide which comes first, * and we fallback to sorting alphabetically. */ - l1 = s1->eo - s1->so; - l2 = s2->eo - s2->so; - if (l1 == strlen(s1->sym->name) && l2 != strlen(s2->sym->name)) + exact1 = (s1->eo - s1->so) == strlen(s1->sym->name); + exact2 = (s2->eo - s2->so) == strlen(s2->sym->name); + if (exact1 && !exact2) return -1; - if (l1 != strlen(s1->sym->name) && l2 == strlen(s2->sym->name)) + if (!exact1 && exact2) return 1; /* As a fallback, sort symbols alphabetically */ @@ -992,7 +1030,7 @@ static int sym_rel_comp( const void *sym1, const void *sym2 ) struct symbol **sym_re_search(const char *pattern) { struct symbol *sym, **sym_arr = NULL; - struct sym_match **sym_match_arr = NULL; + struct sym_match *sym_match_arr = NULL; int i, cnt, size; regex_t re; regmatch_t match[1]; @@ -1005,47 +1043,38 @@ struct symbol **sym_re_search(const char *pattern) 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, 1, match, 0)) continue; - if (cnt + 1 >= size) { + if (cnt >= size) { void *tmp; size += 16; - tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *)); - if (!tmp) { + 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); - 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 + /* As regexec returned 0, we know we have a match, so * we can use match[0].rm_[se]o without further checks */ - tmp_sym_match->so = match[0].rm_so; - tmp_sym_match->eo = match[0].rm_eo; - sym_match_arr[cnt++] = tmp_sym_match; + sym_match_arr[cnt].so = match[0].rm_so; + sym_match_arr[cnt].eo = match[0].rm_eo; + sym_match_arr[cnt++].sym = sym; } if (sym_match_arr) { - qsort(sym_match_arr, cnt, sizeof(struct sym_match*), sym_rel_comp); - sym_arr = malloc((cnt+1) * sizeof(struct symbol)); + 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[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); - } + /* sym_match_arr can be NULL if no match, but free(NULL) is OK */ + free(sym_match_arr); regfree(&re); return sym_arr; @@ -1055,7 +1084,7 @@ sym_re_search_free: * When we check for recursive dependencies we use a stack to save * current state so we can print out relevant info to user. * The entries are located on the call stack so no need to free memory. - * Note inser() remove() must always match to properly clear the stack. + * Note insert() remove() must always match to properly clear the stack. */ static struct dep_stack { struct dep_stack *prev, *next; @@ -1125,6 +1154,7 @@ static void sym_check_print_recursive(struct symbol *last_sym) if (stack->sym == last_sym) fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", prop->file->name, prop->lineno); + if (stack->expr) { fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", prop->file->name, prop->lineno, @@ -1154,6 +1184,11 @@ static void sym_check_print_recursive(struct symbol *last_sym) } } + fprintf(stderr, + "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n" + "subsection \"Kconfig recursive dependency limitations\"\n" + "\n"); + if (check_top == &cv_stack) dep_stack_remove(); } @@ -1174,6 +1209,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e) case E_NOT: return sym_check_expr_deps(e->left.expr); case E_EQUAL: + case E_GEQ: + case E_GTH: + case E_LEQ: + case E_LTH: case E_UNEQUAL: sym = sym_check_deps(e->left.sym); if (sym) @@ -1341,6 +1380,8 @@ const char *prop_get_type_name(enum prop_type type) return "choice"; case P_SELECT: return "select"; + case P_IMPLY: + return "imply"; case P_RANGE: return "range"; case P_SYMBOL: