Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
0004  */
0005 
0006 #include <ctype.h>
0007 #include <limits.h>
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <string.h>
0011 #include <time.h>
0012 #include <unistd.h>
0013 #include <getopt.h>
0014 #include <sys/time.h>
0015 #include <errno.h>
0016 
0017 #include "lkc.h"
0018 
0019 static void conf(struct menu *menu);
0020 static void check_conf(struct menu *menu);
0021 
0022 enum input_mode {
0023     oldaskconfig,
0024     syncconfig,
0025     oldconfig,
0026     allnoconfig,
0027     allyesconfig,
0028     allmodconfig,
0029     alldefconfig,
0030     randconfig,
0031     defconfig,
0032     savedefconfig,
0033     listnewconfig,
0034     helpnewconfig,
0035     olddefconfig,
0036     yes2modconfig,
0037     mod2yesconfig,
0038     mod2noconfig,
0039 };
0040 static enum input_mode input_mode = oldaskconfig;
0041 static int input_mode_opt;
0042 static int indent = 1;
0043 static int tty_stdio;
0044 static int sync_kconfig;
0045 static int conf_cnt;
0046 static char line[PATH_MAX];
0047 static struct menu *rootEntry;
0048 
0049 static void print_help(struct menu *menu)
0050 {
0051     struct gstr help = str_new();
0052 
0053     menu_get_ext_help(menu, &help);
0054 
0055     printf("\n%s\n", str_get(&help));
0056     str_free(&help);
0057 }
0058 
0059 static void strip(char *str)
0060 {
0061     char *p = str;
0062     int l;
0063 
0064     while ((isspace(*p)))
0065         p++;
0066     l = strlen(p);
0067     if (p != str)
0068         memmove(str, p, l + 1);
0069     if (!l)
0070         return;
0071     p = str + l - 1;
0072     while ((isspace(*p)))
0073         *p-- = 0;
0074 }
0075 
0076 /* Helper function to facilitate fgets() by Jean Sacren. */
0077 static void xfgets(char *str, int size, FILE *in)
0078 {
0079     if (!fgets(str, size, in))
0080         fprintf(stderr, "\nError in reading or end of file.\n");
0081 
0082     if (!tty_stdio)
0083         printf("%s", str);
0084 }
0085 
0086 static void set_randconfig_seed(void)
0087 {
0088     unsigned int seed;
0089     char *env;
0090     bool seed_set = false;
0091 
0092     env = getenv("KCONFIG_SEED");
0093     if (env && *env) {
0094         char *endp;
0095 
0096         seed = strtol(env, &endp, 0);
0097         if (*endp == '\0')
0098             seed_set = true;
0099     }
0100 
0101     if (!seed_set) {
0102         struct timeval now;
0103 
0104         /*
0105          * Use microseconds derived seed, compensate for systems where it may
0106          * be zero.
0107          */
0108         gettimeofday(&now, NULL);
0109         seed = (now.tv_sec + 1) * (now.tv_usec + 1);
0110     }
0111 
0112     printf("KCONFIG_SEED=0x%X\n", seed);
0113     srand(seed);
0114 }
0115 
0116 static bool randomize_choice_values(struct symbol *csym)
0117 {
0118     struct property *prop;
0119     struct symbol *sym;
0120     struct expr *e;
0121     int cnt, def;
0122 
0123     /*
0124      * If choice is mod then we may have more items selected
0125      * and if no then no-one.
0126      * In both cases stop.
0127      */
0128     if (csym->curr.tri != yes)
0129         return false;
0130 
0131     prop = sym_get_choice_prop(csym);
0132 
0133     /* count entries in choice block */
0134     cnt = 0;
0135     expr_list_for_each_sym(prop->expr, e, sym)
0136         cnt++;
0137 
0138     /*
0139      * find a random value and set it to yes,
0140      * set the rest to no so we have only one set
0141      */
0142     def = rand() % cnt;
0143 
0144     cnt = 0;
0145     expr_list_for_each_sym(prop->expr, e, sym) {
0146         if (def == cnt++) {
0147             sym->def[S_DEF_USER].tri = yes;
0148             csym->def[S_DEF_USER].val = sym;
0149         } else {
0150             sym->def[S_DEF_USER].tri = no;
0151         }
0152         sym->flags |= SYMBOL_DEF_USER;
0153         /* clear VALID to get value calculated */
0154         sym->flags &= ~SYMBOL_VALID;
0155     }
0156     csym->flags |= SYMBOL_DEF_USER;
0157     /* clear VALID to get value calculated */
0158     csym->flags &= ~SYMBOL_VALID;
0159 
0160     return true;
0161 }
0162 
0163 enum conf_def_mode {
0164     def_default,
0165     def_yes,
0166     def_mod,
0167     def_no,
0168     def_random
0169 };
0170 
0171 static bool conf_set_all_new_symbols(enum conf_def_mode mode)
0172 {
0173     struct symbol *sym, *csym;
0174     int i, cnt;
0175     /*
0176      * can't go as the default in switch-case below, otherwise gcc whines
0177      * about -Wmaybe-uninitialized
0178      */
0179     int pby = 50; /* probability of bool     = y */
0180     int pty = 33; /* probability of tristate = y */
0181     int ptm = 33; /* probability of tristate = m */
0182     bool has_changed = false;
0183 
0184     if (mode == def_random) {
0185         int n, p[3];
0186         char *env = getenv("KCONFIG_PROBABILITY");
0187 
0188         n = 0;
0189         while (env && *env) {
0190             char *endp;
0191             int tmp = strtol(env, &endp, 10);
0192 
0193             if (tmp >= 0 && tmp <= 100) {
0194                 p[n++] = tmp;
0195             } else {
0196                 errno = ERANGE;
0197                 perror("KCONFIG_PROBABILITY");
0198                 exit(1);
0199             }
0200             env = (*endp == ':') ? endp + 1 : endp;
0201             if (n >= 3)
0202                 break;
0203         }
0204         switch (n) {
0205         case 1:
0206             pby = p[0];
0207             ptm = pby / 2;
0208             pty = pby - ptm;
0209             break;
0210         case 2:
0211             pty = p[0];
0212             ptm = p[1];
0213             pby = pty + ptm;
0214             break;
0215         case 3:
0216             pby = p[0];
0217             pty = p[1];
0218             ptm = p[2];
0219             break;
0220         }
0221 
0222         if (pty + ptm > 100) {
0223             errno = ERANGE;
0224             perror("KCONFIG_PROBABILITY");
0225             exit(1);
0226         }
0227     }
0228 
0229     for_all_symbols(i, sym) {
0230         if (sym_has_value(sym) || sym->flags & SYMBOL_VALID)
0231             continue;
0232         switch (sym_get_type(sym)) {
0233         case S_BOOLEAN:
0234         case S_TRISTATE:
0235             has_changed = true;
0236             switch (mode) {
0237             case def_yes:
0238                 sym->def[S_DEF_USER].tri = yes;
0239                 break;
0240             case def_mod:
0241                 sym->def[S_DEF_USER].tri = mod;
0242                 break;
0243             case def_no:
0244                 sym->def[S_DEF_USER].tri = no;
0245                 break;
0246             case def_random:
0247                 sym->def[S_DEF_USER].tri = no;
0248                 cnt = rand() % 100;
0249                 if (sym->type == S_TRISTATE) {
0250                     if (cnt < pty)
0251                         sym->def[S_DEF_USER].tri = yes;
0252                     else if (cnt < pty + ptm)
0253                         sym->def[S_DEF_USER].tri = mod;
0254                 } else if (cnt < pby)
0255                     sym->def[S_DEF_USER].tri = yes;
0256                 break;
0257             default:
0258                 continue;
0259             }
0260             if (!(sym_is_choice(sym) && mode == def_random))
0261                 sym->flags |= SYMBOL_DEF_USER;
0262             break;
0263         default:
0264             break;
0265         }
0266 
0267     }
0268 
0269     sym_clear_all_valid();
0270 
0271     /*
0272      * We have different type of choice blocks.
0273      * If curr.tri equals to mod then we can select several
0274      * choice symbols in one block.
0275      * In this case we do nothing.
0276      * If curr.tri equals yes then only one symbol can be
0277      * selected in a choice block and we set it to yes,
0278      * and the rest to no.
0279      */
0280     if (mode != def_random) {
0281         for_all_symbols(i, csym) {
0282             if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
0283                 sym_is_choice_value(csym))
0284                 csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
0285         }
0286     }
0287 
0288     for_all_symbols(i, csym) {
0289         if (sym_has_value(csym) || !sym_is_choice(csym))
0290             continue;
0291 
0292         sym_calc_value(csym);
0293         if (mode == def_random)
0294             has_changed |= randomize_choice_values(csym);
0295         else {
0296             set_all_choice_values(csym);
0297             has_changed = true;
0298         }
0299     }
0300 
0301     return has_changed;
0302 }
0303 
0304 static void conf_rewrite_tristates(tristate old_val, tristate new_val)
0305 {
0306     struct symbol *sym;
0307     int i;
0308 
0309     for_all_symbols(i, sym) {
0310         if (sym_get_type(sym) == S_TRISTATE &&
0311             sym->def[S_DEF_USER].tri == old_val)
0312             sym->def[S_DEF_USER].tri = new_val;
0313     }
0314     sym_clear_all_valid();
0315 }
0316 
0317 static int conf_askvalue(struct symbol *sym, const char *def)
0318 {
0319     if (!sym_has_value(sym))
0320         printf("(NEW) ");
0321 
0322     line[0] = '\n';
0323     line[1] = 0;
0324 
0325     if (!sym_is_changeable(sym)) {
0326         printf("%s\n", def);
0327         line[0] = '\n';
0328         line[1] = 0;
0329         return 0;
0330     }
0331 
0332     switch (input_mode) {
0333     case oldconfig:
0334     case syncconfig:
0335         if (sym_has_value(sym)) {
0336             printf("%s\n", def);
0337             return 0;
0338         }
0339         /* fall through */
0340     default:
0341         fflush(stdout);
0342         xfgets(line, sizeof(line), stdin);
0343         break;
0344     }
0345 
0346     return 1;
0347 }
0348 
0349 static int conf_string(struct menu *menu)
0350 {
0351     struct symbol *sym = menu->sym;
0352     const char *def;
0353 
0354     while (1) {
0355         printf("%*s%s ", indent - 1, "", menu->prompt->text);
0356         printf("(%s) ", sym->name);
0357         def = sym_get_string_value(sym);
0358         if (def)
0359             printf("[%s] ", def);
0360         if (!conf_askvalue(sym, def))
0361             return 0;
0362         switch (line[0]) {
0363         case '\n':
0364             break;
0365         case '?':
0366             /* print help */
0367             if (line[1] == '\n') {
0368                 print_help(menu);
0369                 def = NULL;
0370                 break;
0371             }
0372             /* fall through */
0373         default:
0374             line[strlen(line)-1] = 0;
0375             def = line;
0376         }
0377         if (def && sym_set_string_value(sym, def))
0378             return 0;
0379     }
0380 }
0381 
0382 static int conf_sym(struct menu *menu)
0383 {
0384     struct symbol *sym = menu->sym;
0385     tristate oldval, newval;
0386 
0387     while (1) {
0388         printf("%*s%s ", indent - 1, "", menu->prompt->text);
0389         if (sym->name)
0390             printf("(%s) ", sym->name);
0391         putchar('[');
0392         oldval = sym_get_tristate_value(sym);
0393         switch (oldval) {
0394         case no:
0395             putchar('N');
0396             break;
0397         case mod:
0398             putchar('M');
0399             break;
0400         case yes:
0401             putchar('Y');
0402             break;
0403         }
0404         if (oldval != no && sym_tristate_within_range(sym, no))
0405             printf("/n");
0406         if (oldval != mod && sym_tristate_within_range(sym, mod))
0407             printf("/m");
0408         if (oldval != yes && sym_tristate_within_range(sym, yes))
0409             printf("/y");
0410         printf("/?] ");
0411         if (!conf_askvalue(sym, sym_get_string_value(sym)))
0412             return 0;
0413         strip(line);
0414 
0415         switch (line[0]) {
0416         case 'n':
0417         case 'N':
0418             newval = no;
0419             if (!line[1] || !strcmp(&line[1], "o"))
0420                 break;
0421             continue;
0422         case 'm':
0423         case 'M':
0424             newval = mod;
0425             if (!line[1])
0426                 break;
0427             continue;
0428         case 'y':
0429         case 'Y':
0430             newval = yes;
0431             if (!line[1] || !strcmp(&line[1], "es"))
0432                 break;
0433             continue;
0434         case 0:
0435             newval = oldval;
0436             break;
0437         case '?':
0438             goto help;
0439         default:
0440             continue;
0441         }
0442         if (sym_set_tristate_value(sym, newval))
0443             return 0;
0444 help:
0445         print_help(menu);
0446     }
0447 }
0448 
0449 static int conf_choice(struct menu *menu)
0450 {
0451     struct symbol *sym, *def_sym;
0452     struct menu *child;
0453     bool is_new;
0454 
0455     sym = menu->sym;
0456     is_new = !sym_has_value(sym);
0457     if (sym_is_changeable(sym)) {
0458         conf_sym(menu);
0459         sym_calc_value(sym);
0460         switch (sym_get_tristate_value(sym)) {
0461         case no:
0462             return 1;
0463         case mod:
0464             return 0;
0465         case yes:
0466             break;
0467         }
0468     } else {
0469         switch (sym_get_tristate_value(sym)) {
0470         case no:
0471             return 1;
0472         case mod:
0473             printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
0474             return 0;
0475         case yes:
0476             break;
0477         }
0478     }
0479 
0480     while (1) {
0481         int cnt, def;
0482 
0483         printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
0484         def_sym = sym_get_choice_value(sym);
0485         cnt = def = 0;
0486         line[0] = 0;
0487         for (child = menu->list; child; child = child->next) {
0488             if (!menu_is_visible(child))
0489                 continue;
0490             if (!child->sym) {
0491                 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
0492                 continue;
0493             }
0494             cnt++;
0495             if (child->sym == def_sym) {
0496                 def = cnt;
0497                 printf("%*c", indent, '>');
0498             } else
0499                 printf("%*c", indent, ' ');
0500             printf(" %d. %s", cnt, menu_get_prompt(child));
0501             if (child->sym->name)
0502                 printf(" (%s)", child->sym->name);
0503             if (!sym_has_value(child->sym))
0504                 printf(" (NEW)");
0505             printf("\n");
0506         }
0507         printf("%*schoice", indent - 1, "");
0508         if (cnt == 1) {
0509             printf("[1]: 1\n");
0510             goto conf_childs;
0511         }
0512         printf("[1-%d?]: ", cnt);
0513         switch (input_mode) {
0514         case oldconfig:
0515         case syncconfig:
0516             if (!is_new) {
0517                 cnt = def;
0518                 printf("%d\n", cnt);
0519                 break;
0520             }
0521             /* fall through */
0522         case oldaskconfig:
0523             fflush(stdout);
0524             xfgets(line, sizeof(line), stdin);
0525             strip(line);
0526             if (line[0] == '?') {
0527                 print_help(menu);
0528                 continue;
0529             }
0530             if (!line[0])
0531                 cnt = def;
0532             else if (isdigit(line[0]))
0533                 cnt = atoi(line);
0534             else
0535                 continue;
0536             break;
0537         default:
0538             break;
0539         }
0540 
0541     conf_childs:
0542         for (child = menu->list; child; child = child->next) {
0543             if (!child->sym || !menu_is_visible(child))
0544                 continue;
0545             if (!--cnt)
0546                 break;
0547         }
0548         if (!child)
0549             continue;
0550         if (line[0] && line[strlen(line) - 1] == '?') {
0551             print_help(child);
0552             continue;
0553         }
0554         sym_set_choice_value(sym, child->sym);
0555         for (child = child->list; child; child = child->next) {
0556             indent += 2;
0557             conf(child);
0558             indent -= 2;
0559         }
0560         return 1;
0561     }
0562 }
0563 
0564 static void conf(struct menu *menu)
0565 {
0566     struct symbol *sym;
0567     struct property *prop;
0568     struct menu *child;
0569 
0570     if (!menu_is_visible(menu))
0571         return;
0572 
0573     sym = menu->sym;
0574     prop = menu->prompt;
0575     if (prop) {
0576         const char *prompt;
0577 
0578         switch (prop->type) {
0579         case P_MENU:
0580             /*
0581              * Except in oldaskconfig mode, we show only menus that
0582              * contain new symbols.
0583              */
0584             if (input_mode != oldaskconfig && rootEntry != menu) {
0585                 check_conf(menu);
0586                 return;
0587             }
0588             /* fall through */
0589         case P_COMMENT:
0590             prompt = menu_get_prompt(menu);
0591             if (prompt)
0592                 printf("%*c\n%*c %s\n%*c\n",
0593                     indent, '*',
0594                     indent, '*', prompt,
0595                     indent, '*');
0596         default:
0597             ;
0598         }
0599     }
0600 
0601     if (!sym)
0602         goto conf_childs;
0603 
0604     if (sym_is_choice(sym)) {
0605         conf_choice(menu);
0606         if (sym->curr.tri != mod)
0607             return;
0608         goto conf_childs;
0609     }
0610 
0611     switch (sym->type) {
0612     case S_INT:
0613     case S_HEX:
0614     case S_STRING:
0615         conf_string(menu);
0616         break;
0617     default:
0618         conf_sym(menu);
0619         break;
0620     }
0621 
0622 conf_childs:
0623     if (sym)
0624         indent += 2;
0625     for (child = menu->list; child; child = child->next)
0626         conf(child);
0627     if (sym)
0628         indent -= 2;
0629 }
0630 
0631 static void check_conf(struct menu *menu)
0632 {
0633     struct symbol *sym;
0634     struct menu *child;
0635 
0636     if (!menu_is_visible(menu))
0637         return;
0638 
0639     sym = menu->sym;
0640     if (sym && !sym_has_value(sym) &&
0641         (sym_is_changeable(sym) ||
0642          (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
0643 
0644         switch (input_mode) {
0645         case listnewconfig:
0646             if (sym->name)
0647                 print_symbol_for_listconfig(sym);
0648             break;
0649         case helpnewconfig:
0650             printf("-----\n");
0651             print_help(menu);
0652             printf("-----\n");
0653             break;
0654         default:
0655             if (!conf_cnt++)
0656                 printf("*\n* Restart config...\n*\n");
0657             rootEntry = menu_get_parent_menu(menu);
0658             conf(rootEntry);
0659             break;
0660         }
0661     }
0662 
0663     for (child = menu->list; child; child = child->next)
0664         check_conf(child);
0665 }
0666 
0667 static const struct option long_opts[] = {
0668     {"help",          no_argument,       NULL,            'h'},
0669     {"silent",        no_argument,       NULL,            's'},
0670     {"oldaskconfig",  no_argument,       &input_mode_opt, oldaskconfig},
0671     {"oldconfig",     no_argument,       &input_mode_opt, oldconfig},
0672     {"syncconfig",    no_argument,       &input_mode_opt, syncconfig},
0673     {"defconfig",     required_argument, &input_mode_opt, defconfig},
0674     {"savedefconfig", required_argument, &input_mode_opt, savedefconfig},
0675     {"allnoconfig",   no_argument,       &input_mode_opt, allnoconfig},
0676     {"allyesconfig",  no_argument,       &input_mode_opt, allyesconfig},
0677     {"allmodconfig",  no_argument,       &input_mode_opt, allmodconfig},
0678     {"alldefconfig",  no_argument,       &input_mode_opt, alldefconfig},
0679     {"randconfig",    no_argument,       &input_mode_opt, randconfig},
0680     {"listnewconfig", no_argument,       &input_mode_opt, listnewconfig},
0681     {"helpnewconfig", no_argument,       &input_mode_opt, helpnewconfig},
0682     {"olddefconfig",  no_argument,       &input_mode_opt, olddefconfig},
0683     {"yes2modconfig", no_argument,       &input_mode_opt, yes2modconfig},
0684     {"mod2yesconfig", no_argument,       &input_mode_opt, mod2yesconfig},
0685     {"mod2noconfig",  no_argument,       &input_mode_opt, mod2noconfig},
0686     {NULL, 0, NULL, 0}
0687 };
0688 
0689 static void conf_usage(const char *progname)
0690 {
0691     printf("Usage: %s [options] <kconfig-file>\n", progname);
0692     printf("\n");
0693     printf("Generic options:\n");
0694     printf("  -h, --help              Print this message and exit.\n");
0695     printf("  -s, --silent            Do not print log.\n");
0696     printf("\n");
0697     printf("Mode options:\n");
0698     printf("  --listnewconfig         List new options\n");
0699     printf("  --helpnewconfig         List new options and help text\n");
0700     printf("  --oldaskconfig          Start a new configuration using a line-oriented program\n");
0701     printf("  --oldconfig             Update a configuration using a provided .config as base\n");
0702     printf("  --syncconfig            Similar to oldconfig but generates configuration in\n"
0703            "                          include/{generated/,config/}\n");
0704     printf("  --olddefconfig          Same as oldconfig but sets new symbols to their default value\n");
0705     printf("  --defconfig <file>      New config with default defined in <file>\n");
0706     printf("  --savedefconfig <file>  Save the minimal current configuration to <file>\n");
0707     printf("  --allnoconfig           New config where all options are answered with no\n");
0708     printf("  --allyesconfig          New config where all options are answered with yes\n");
0709     printf("  --allmodconfig          New config where all options are answered with mod\n");
0710     printf("  --alldefconfig          New config with all symbols set to default\n");
0711     printf("  --randconfig            New config with random answer to all options\n");
0712     printf("  --yes2modconfig         Change answers from yes to mod if possible\n");
0713     printf("  --mod2yesconfig         Change answers from mod to yes if possible\n");
0714     printf("  --mod2noconfig          Change answers from mod to no if possible\n");
0715     printf("  (If none of the above is given, --oldaskconfig is the default)\n");
0716 }
0717 
0718 int main(int ac, char **av)
0719 {
0720     const char *progname = av[0];
0721     int opt;
0722     const char *name, *defconfig_file = NULL /* gcc uninit */;
0723     int no_conf_write = 0;
0724 
0725     tty_stdio = isatty(0) && isatty(1);
0726 
0727     while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) {
0728         switch (opt) {
0729         case 'h':
0730             conf_usage(progname);
0731             exit(1);
0732             break;
0733         case 's':
0734             conf_set_message_callback(NULL);
0735             break;
0736         case 0:
0737             input_mode = input_mode_opt;
0738             switch (input_mode) {
0739             case syncconfig:
0740                 /*
0741                  * syncconfig is invoked during the build stage.
0742                  * Suppress distracting
0743                  *   "configuration written to ..."
0744                  */
0745                 conf_set_message_callback(NULL);
0746                 sync_kconfig = 1;
0747                 break;
0748             case defconfig:
0749             case savedefconfig:
0750                 defconfig_file = optarg;
0751                 break;
0752             case randconfig:
0753                 set_randconfig_seed();
0754                 break;
0755             default:
0756                 break;
0757             }
0758         default:
0759             break;
0760         }
0761     }
0762     if (ac == optind) {
0763         fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
0764         conf_usage(progname);
0765         exit(1);
0766     }
0767     conf_parse(av[optind]);
0768     //zconfdump(stdout);
0769 
0770     switch (input_mode) {
0771     case defconfig:
0772         if (conf_read(defconfig_file)) {
0773             fprintf(stderr,
0774                 "***\n"
0775                   "*** Can't find default configuration \"%s\"!\n"
0776                   "***\n",
0777                 defconfig_file);
0778             exit(1);
0779         }
0780         break;
0781     case savedefconfig:
0782     case syncconfig:
0783     case oldaskconfig:
0784     case oldconfig:
0785     case listnewconfig:
0786     case helpnewconfig:
0787     case olddefconfig:
0788     case yes2modconfig:
0789     case mod2yesconfig:
0790     case mod2noconfig:
0791         conf_read(NULL);
0792         break;
0793     case allnoconfig:
0794     case allyesconfig:
0795     case allmodconfig:
0796     case alldefconfig:
0797     case randconfig:
0798         name = getenv("KCONFIG_ALLCONFIG");
0799         if (!name)
0800             break;
0801         if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
0802             if (conf_read_simple(name, S_DEF_USER)) {
0803                 fprintf(stderr,
0804                     "*** Can't read seed configuration \"%s\"!\n",
0805                     name);
0806                 exit(1);
0807             }
0808             break;
0809         }
0810         switch (input_mode) {
0811         case allnoconfig:   name = "allno.config"; break;
0812         case allyesconfig:  name = "allyes.config"; break;
0813         case allmodconfig:  name = "allmod.config"; break;
0814         case alldefconfig:  name = "alldef.config"; break;
0815         case randconfig:    name = "allrandom.config"; break;
0816         default: break;
0817         }
0818         if (conf_read_simple(name, S_DEF_USER) &&
0819             conf_read_simple("all.config", S_DEF_USER)) {
0820             fprintf(stderr,
0821                 "*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
0822                 name);
0823             exit(1);
0824         }
0825         break;
0826     default:
0827         break;
0828     }
0829 
0830     if (sync_kconfig) {
0831         name = getenv("KCONFIG_NOSILENTUPDATE");
0832         if (name && *name) {
0833             if (conf_get_changed()) {
0834                 fprintf(stderr,
0835                     "\n*** The configuration requires explicit update.\n\n");
0836                 return 1;
0837             }
0838             no_conf_write = 1;
0839         }
0840     }
0841 
0842     switch (input_mode) {
0843     case allnoconfig:
0844         conf_set_all_new_symbols(def_no);
0845         break;
0846     case allyesconfig:
0847         conf_set_all_new_symbols(def_yes);
0848         break;
0849     case allmodconfig:
0850         conf_set_all_new_symbols(def_mod);
0851         break;
0852     case alldefconfig:
0853         conf_set_all_new_symbols(def_default);
0854         break;
0855     case randconfig:
0856         /* Really nothing to do in this loop */
0857         while (conf_set_all_new_symbols(def_random)) ;
0858         break;
0859     case defconfig:
0860         conf_set_all_new_symbols(def_default);
0861         break;
0862     case savedefconfig:
0863         break;
0864     case yes2modconfig:
0865         conf_rewrite_tristates(yes, mod);
0866         break;
0867     case mod2yesconfig:
0868         conf_rewrite_tristates(mod, yes);
0869         break;
0870     case mod2noconfig:
0871         conf_rewrite_tristates(mod, no);
0872         break;
0873     case oldaskconfig:
0874         rootEntry = &rootmenu;
0875         conf(&rootmenu);
0876         input_mode = oldconfig;
0877         /* fall through */
0878     case oldconfig:
0879     case listnewconfig:
0880     case helpnewconfig:
0881     case syncconfig:
0882         /* Update until a loop caused no more changes */
0883         do {
0884             conf_cnt = 0;
0885             check_conf(&rootmenu);
0886         } while (conf_cnt);
0887         break;
0888     case olddefconfig:
0889     default:
0890         break;
0891     }
0892 
0893     if (input_mode == savedefconfig) {
0894         if (conf_write_defconfig(defconfig_file)) {
0895             fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
0896                 defconfig_file);
0897             return 1;
0898         }
0899     } else if (input_mode != listnewconfig && input_mode != helpnewconfig) {
0900         if (!no_conf_write && conf_write(NULL)) {
0901             fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
0902             exit(1);
0903         }
0904 
0905         /*
0906          * Create auto.conf if it does not exist.
0907          * This prevents GNU Make 4.1 or older from emitting
0908          * "include/config/auto.conf: No such file or directory"
0909          * in the top-level Makefile
0910          *
0911          * syncconfig always creates or updates auto.conf because it is
0912          * used during the build.
0913          */
0914         if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
0915             fprintf(stderr,
0916                 "\n*** Error during sync of the configuration.\n\n");
0917             return 1;
0918         }
0919     }
0920     return 0;
0921 }