Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6:
  kconfig: Fix warning: ignoring return value of 'fgets'
  kconfig: Fix warning: ignoring return value of 'fwrite'
  nconfig: Fix segfault when menu is empty
  kconfig: fix tristate choice with minimal config
  kconfig: fix savedefconfig for tristate choices
This commit is contained in:
Linus Torvalds 2010-08-13 17:56:27 -07:00
commit 090b710e8a
5 changed files with 97 additions and 43 deletions

View File

@ -108,7 +108,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
check_stdin(); check_stdin();
case oldaskconfig: case oldaskconfig:
fflush(stdout); fflush(stdout);
fgets(line, 128, stdin); xfgets(line, 128, stdin);
return 1; return 1;
default: default:
break; break;
@ -306,7 +306,7 @@ static int conf_choice(struct menu *menu)
check_stdin(); check_stdin();
case oldaskconfig: case oldaskconfig:
fflush(stdout); fflush(stdout);
fgets(line, 128, stdin); xfgets(line, 128, stdin);
strip(line); strip(line);
if (line[0] == '?') { if (line[0] == '?') {
print_help(menu); print_help(menu);
@ -644,3 +644,14 @@ int main(int ac, char **av)
} }
return 0; return 0;
} }
/*
* Helper function to facilitate fgets() by Jean Sacren.
*/
void xfgets(str, size, in)
char *str;
int size;
FILE *in;
{
if (fgets(str, size, in) == NULL)
fprintf(stderr, "\nError in reading or end of file.\n");
}

View File

@ -412,7 +412,7 @@ static void conf_write_string(bool headerfile, const char *name,
while (1) { while (1) {
l = strcspn(str, "\"\\"); l = strcspn(str, "\"\\");
if (l) { if (l) {
fwrite(str, l, 1, out); xfwrite(str, l, 1, out);
str += l; str += l;
} }
if (!*str) if (!*str)
@ -497,7 +497,7 @@ int conf_write_defconfig(const char *filename)
/* /*
* If symbol is a choice value and equals to the * If symbol is a choice value and equals to the
* default for a choice - skip. * default for a choice - skip.
* But only if value equal to "y". * But only if value is bool and equal to "y" .
*/ */
if (sym_is_choice_value(sym)) { if (sym_is_choice_value(sym)) {
struct symbol *cs; struct symbol *cs;
@ -506,9 +506,8 @@ int conf_write_defconfig(const char *filename)
cs = prop_get_symbol(sym_get_choice_prop(sym)); cs = prop_get_symbol(sym_get_choice_prop(sym));
ds = sym_choice_default(cs); ds = sym_choice_default(cs);
if (sym == ds) { if (sym == ds) {
if ((sym->type == S_BOOLEAN || if ((sym->type == S_BOOLEAN) &&
sym->type == S_TRISTATE) && sym_get_tristate_value(sym) == yes)
sym_get_tristate_value(sym) == yes)
goto next_menu; goto next_menu;
} }
} }
@ -919,13 +918,73 @@ void conf_set_changed_callback(void (*fn)(void))
conf_changed_callback = fn; conf_changed_callback = fn;
} }
static void randomize_choice_values(struct symbol *csym)
{
struct property *prop;
struct symbol *sym;
struct expr *e;
int cnt, def;
/*
* If choice is mod then we may have more items slected
* and if no then no-one.
* In both cases stop.
*/
if (csym->curr.tri != yes)
return;
prop = sym_get_choice_prop(csym);
/* count entries in choice block */
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym)
cnt++;
/*
* find a random value and set it to yes,
* set the rest to no so we have only one set
*/
def = (rand() % cnt);
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym) {
if (def == cnt++) {
sym->def[S_DEF_USER].tri = yes;
csym->def[S_DEF_USER].val = sym;
}
else {
sym->def[S_DEF_USER].tri = no;
}
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID);
}
static void set_all_choice_values(struct symbol *csym)
{
struct property *prop;
struct symbol *sym;
struct expr *e;
prop = sym_get_choice_prop(csym);
/*
* Set all non-assinged choice values to no
*/
expr_list_for_each_sym(prop->expr, e, sym) {
if (!sym_has_value(sym))
sym->def[S_DEF_USER].tri = no;
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID);
}
void conf_set_all_new_symbols(enum conf_def_mode mode) void conf_set_all_new_symbols(enum conf_def_mode mode)
{ {
struct symbol *sym, *csym; struct symbol *sym, *csym;
struct property *prop; int i, cnt;
struct expr *e;
int i, cnt, def;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
if (sym_has_value(sym)) if (sym_has_value(sym))
@ -961,8 +1020,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
sym_clear_all_valid(); sym_clear_all_valid();
if (mode != def_random)
return;
/* /*
* We have different type of choice blocks. * We have different type of choice blocks.
* If curr.tri equal to mod then we can select several * If curr.tri equal to mod then we can select several
@ -977,35 +1034,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
continue; continue;
sym_calc_value(csym); sym_calc_value(csym);
if (mode == def_random)
if (csym->curr.tri != yes) randomize_choice_values(csym);
continue; else
set_all_choice_values(csym);
prop = sym_get_choice_prop(csym);
/* count entries in choice block */
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym)
cnt++;
/*
* find a random value and set it to yes,
* set the rest to no so we have only one set
*/
def = (rand() % cnt);
cnt = 0;
expr_list_for_each_sym(prop->expr, e, sym) {
if (def == cnt++) {
sym->def[S_DEF_USER].tri = yes;
csym->def[S_DEF_USER].val = sym;
}
else {
sym->def[S_DEF_USER].tri = no;
}
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID);
} }
} }

View File

@ -1087,7 +1087,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
{ {
fwrite(str, strlen(str), 1, data); xfwrite(str, strlen(str), 1, data);
} }
void expr_fprint(struct expr *e, FILE *out) void expr_fprint(struct expr *e, FILE *out)

View File

@ -72,6 +72,9 @@ void zconf_nextfile(const char *name);
int zconf_lineno(void); int zconf_lineno(void);
char *zconf_curname(void); char *zconf_curname(void);
/* conf.c */
void xfgets(char *str, int size, FILE *in);
/* confdata.c */ /* confdata.c */
const char *conf_get_configname(void); const char *conf_get_configname(void);
const char *conf_get_autoconfig_name(void); const char *conf_get_autoconfig_name(void);
@ -80,6 +83,13 @@ void sym_set_change_count(int count);
void sym_add_change_count(int count); void sym_add_change_count(int count);
void conf_set_all_new_symbols(enum conf_def_mode mode); void conf_set_all_new_symbols(enum conf_def_mode mode);
/* confdata.c and expr.c */
static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
{
if (fwrite(str, len, count, out) < count)
fprintf(stderr, "\nError in writing or end of file.\n");
}
/* kconfig_load.c */ /* kconfig_load.c */
void kconfig_load(void); void kconfig_load(void);

View File

@ -676,6 +676,8 @@ static void *item_data(void)
struct mitem *mcur; struct mitem *mcur;
cur = current_item(curses_menu); cur = current_item(curses_menu);
if (!cur)
return NULL;
mcur = (struct mitem *) item_userptr(cur); mcur = (struct mitem *) item_userptr(cur);
return mcur->usrptr; return mcur->usrptr;