Annotation of qemu/roms/seabios/tools/kconfig/confdata.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2002 Roman Zippel <[email protected]>
        !             3:  * Released under the terms of the GNU GPL v2.0.
        !             4:  */
        !             5: 
        !             6: #include <sys/stat.h>
        !             7: #include <ctype.h>
        !             8: #include <errno.h>
        !             9: #include <fcntl.h>
        !            10: #include <stdio.h>
        !            11: #include <stdlib.h>
        !            12: #include <string.h>
        !            13: #include <time.h>
        !            14: #include <unistd.h>
        !            15: 
        !            16: #define LKC_DIRECT_LINK
        !            17: #include "lkc.h"
        !            18: 
        !            19: static void conf_warning(const char *fmt, ...)
        !            20:        __attribute__ ((format (printf, 1, 2)));
        !            21: 
        !            22: static void conf_message(const char *fmt, ...)
        !            23:        __attribute__ ((format (printf, 1, 2)));
        !            24: 
        !            25: static const char *conf_filename;
        !            26: static int conf_lineno, conf_warnings, conf_unsaved;
        !            27: 
        !            28: const char conf_defname[] = "arch/$ARCH/defconfig";
        !            29: 
        !            30: static void conf_warning(const char *fmt, ...)
        !            31: {
        !            32:        va_list ap;
        !            33:        va_start(ap, fmt);
        !            34:        fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
        !            35:        vfprintf(stderr, fmt, ap);
        !            36:        fprintf(stderr, "\n");
        !            37:        va_end(ap);
        !            38:        conf_warnings++;
        !            39: }
        !            40: 
        !            41: static void conf_default_message_callback(const char *fmt, va_list ap)
        !            42: {
        !            43:        printf("#\n# ");
        !            44:        vprintf(fmt, ap);
        !            45:        printf("\n#\n");
        !            46: }
        !            47: 
        !            48: static void (*conf_message_callback) (const char *fmt, va_list ap) =
        !            49:        conf_default_message_callback;
        !            50: void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
        !            51: {
        !            52:        conf_message_callback = fn;
        !            53: }
        !            54: 
        !            55: static void conf_message(const char *fmt, ...)
        !            56: {
        !            57:        va_list ap;
        !            58: 
        !            59:        va_start(ap, fmt);
        !            60:        if (conf_message_callback)
        !            61:                conf_message_callback(fmt, ap);
        !            62: }
        !            63: 
        !            64: const char *conf_get_configname(void)
        !            65: {
        !            66:        char *name = getenv("KCONFIG_CONFIG");
        !            67: 
        !            68:        return name ? name : ".config";
        !            69: }
        !            70: 
        !            71: const char *conf_get_autoconfig_name(void)
        !            72: {
        !            73:        char *name = getenv("KCONFIG_AUTOCONFIG");
        !            74: 
        !            75:        return name ? name : "include/config/auto.conf";
        !            76: }
        !            77: 
        !            78: static char *conf_expand_value(const char *in)
        !            79: {
        !            80:        struct symbol *sym;
        !            81:        const char *src;
        !            82:        static char res_value[SYMBOL_MAXLENGTH];
        !            83:        char *dst, name[SYMBOL_MAXLENGTH];
        !            84: 
        !            85:        res_value[0] = 0;
        !            86:        dst = name;
        !            87:        while ((src = strchr(in, '$'))) {
        !            88:                strncat(res_value, in, src - in);
        !            89:                src++;
        !            90:                dst = name;
        !            91:                while (isalnum(*src) || *src == '_')
        !            92:                        *dst++ = *src++;
        !            93:                *dst = 0;
        !            94:                sym = sym_lookup(name, 0);
        !            95:                sym_calc_value(sym);
        !            96:                strcat(res_value, sym_get_string_value(sym));
        !            97:                in = src;
        !            98:        }
        !            99:        strcat(res_value, in);
        !           100: 
        !           101:        return res_value;
        !           102: }
        !           103: 
        !           104: char *conf_get_default_confname(void)
        !           105: {
        !           106:        struct stat buf;
        !           107:        static char fullname[PATH_MAX+1];
        !           108:        char *env, *name;
        !           109: 
        !           110:        name = conf_expand_value(conf_defname);
        !           111:        env = getenv(SRCTREE);
        !           112:        if (env) {
        !           113:                sprintf(fullname, "%s/%s", env, name);
        !           114:                if (!stat(fullname, &buf))
        !           115:                        return fullname;
        !           116:        }
        !           117:        return name;
        !           118: }
        !           119: 
        !           120: static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
        !           121: {
        !           122:        char *p2;
        !           123: 
        !           124:        switch (sym->type) {
        !           125:        case S_TRISTATE:
        !           126:                if (p[0] == 'm') {
        !           127:                        sym->def[def].tri = mod;
        !           128:                        sym->flags |= def_flags;
        !           129:                        break;
        !           130:                }
        !           131:        case S_BOOLEAN:
        !           132:                if (p[0] == 'y') {
        !           133:                        sym->def[def].tri = yes;
        !           134:                        sym->flags |= def_flags;
        !           135:                        break;
        !           136:                }
        !           137:                if (p[0] == 'n') {
        !           138:                        sym->def[def].tri = no;
        !           139:                        sym->flags |= def_flags;
        !           140:                        break;
        !           141:                }
        !           142:                conf_warning("symbol value '%s' invalid for %s", p, sym->name);
        !           143:                break;
        !           144:        case S_OTHER:
        !           145:                if (*p != '"') {
        !           146:                        for (p2 = p; *p2 && !isspace(*p2); p2++)
        !           147:                                ;
        !           148:                        sym->type = S_STRING;
        !           149:                        goto done;
        !           150:                }
        !           151:        case S_STRING:
        !           152:                if (*p++ != '"')
        !           153:                        break;
        !           154:                for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
        !           155:                        if (*p2 == '"') {
        !           156:                                *p2 = 0;
        !           157:                                break;
        !           158:                        }
        !           159:                        memmove(p2, p2 + 1, strlen(p2));
        !           160:                }
        !           161:                if (!p2) {
        !           162:                        conf_warning("invalid string found");
        !           163:                        return 1;
        !           164:                }
        !           165:        case S_INT:
        !           166:        case S_HEX:
        !           167:        done:
        !           168:                if (sym_string_valid(sym, p)) {
        !           169:                        sym->def[def].val = strdup(p);
        !           170:                        sym->flags |= def_flags;
        !           171:                } else {
        !           172:                        conf_warning("symbol value '%s' invalid for %s", p, sym->name);
        !           173:                        return 1;
        !           174:                }
        !           175:                break;
        !           176:        default:
        !           177:                ;
        !           178:        }
        !           179:        return 0;
        !           180: }
        !           181: 
        !           182: int conf_read_simple(const char *name, int def)
        !           183: {
        !           184:        FILE *in = NULL;
        !           185:        char line[1024];
        !           186:        char *p, *p2;
        !           187:        struct symbol *sym;
        !           188:        int i, def_flags;
        !           189: 
        !           190:        if (name) {
        !           191:                in = zconf_fopen(name);
        !           192:        } else {
        !           193:                struct property *prop;
        !           194: 
        !           195:                name = conf_get_configname();
        !           196:                in = zconf_fopen(name);
        !           197:                if (in)
        !           198:                        goto load;
        !           199:                sym_add_change_count(1);
        !           200:                if (!sym_defconfig_list) {
        !           201:                        if (modules_sym)
        !           202:                                sym_calc_value(modules_sym);
        !           203:                        return 1;
        !           204:                }
        !           205: 
        !           206:                for_all_defaults(sym_defconfig_list, prop) {
        !           207:                        if (expr_calc_value(prop->visible.expr) == no ||
        !           208:                            prop->expr->type != E_SYMBOL)
        !           209:                                continue;
        !           210:                        name = conf_expand_value(prop->expr->left.sym->name);
        !           211:                        in = zconf_fopen(name);
        !           212:                        if (in) {
        !           213:                                conf_message(_("using defaults found in %s"),
        !           214:                                         name);
        !           215:                                goto load;
        !           216:                        }
        !           217:                }
        !           218:        }
        !           219:        if (!in)
        !           220:                return 1;
        !           221: 
        !           222: load:
        !           223:        conf_filename = name;
        !           224:        conf_lineno = 0;
        !           225:        conf_warnings = 0;
        !           226:        conf_unsaved = 0;
        !           227: 
        !           228:        def_flags = SYMBOL_DEF << def;
        !           229:        for_all_symbols(i, sym) {
        !           230:                sym->flags |= SYMBOL_CHANGED;
        !           231:                sym->flags &= ~(def_flags|SYMBOL_VALID);
        !           232:                if (sym_is_choice(sym))
        !           233:                        sym->flags |= def_flags;
        !           234:                switch (sym->type) {
        !           235:                case S_INT:
        !           236:                case S_HEX:
        !           237:                case S_STRING:
        !           238:                        if (sym->def[def].val)
        !           239:                                free(sym->def[def].val);
        !           240:                default:
        !           241:                        sym->def[def].val = NULL;
        !           242:                        sym->def[def].tri = no;
        !           243:                }
        !           244:        }
        !           245: 
        !           246:        while (fgets(line, sizeof(line), in)) {
        !           247:                conf_lineno++;
        !           248:                sym = NULL;
        !           249:                if (line[0] == '#') {
        !           250:                        if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
        !           251:                                continue;
        !           252:                        p = strchr(line + 2 + strlen(CONFIG_), ' ');
        !           253:                        if (!p)
        !           254:                                continue;
        !           255:                        *p++ = 0;
        !           256:                        if (strncmp(p, "is not set", 10))
        !           257:                                continue;
        !           258:                        if (def == S_DEF_USER) {
        !           259:                                sym = sym_find(line + 2 + strlen(CONFIG_));
        !           260:                                if (!sym) {
        !           261:                                        sym_add_change_count(1);
        !           262:                                        goto setsym;
        !           263:                                }
        !           264:                        } else {
        !           265:                                sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
        !           266:                                if (sym->type == S_UNKNOWN)
        !           267:                                        sym->type = S_BOOLEAN;
        !           268:                        }
        !           269:                        if (sym->flags & def_flags) {
        !           270:                                conf_warning("override: reassigning to symbol %s", sym->name);
        !           271:                        }
        !           272:                        switch (sym->type) {
        !           273:                        case S_BOOLEAN:
        !           274:                        case S_TRISTATE:
        !           275:                                sym->def[def].tri = no;
        !           276:                                sym->flags |= def_flags;
        !           277:                                break;
        !           278:                        default:
        !           279:                                ;
        !           280:                        }
        !           281:                } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
        !           282:                        p = strchr(line + strlen(CONFIG_), '=');
        !           283:                        if (!p)
        !           284:                                continue;
        !           285:                        *p++ = 0;
        !           286:                        p2 = strchr(p, '\n');
        !           287:                        if (p2) {
        !           288:                                *p2-- = 0;
        !           289:                                if (*p2 == '\r')
        !           290:                                        *p2 = 0;
        !           291:                        }
        !           292:                        if (def == S_DEF_USER) {
        !           293:                                sym = sym_find(line + strlen(CONFIG_));
        !           294:                                if (!sym) {
        !           295:                                        sym_add_change_count(1);
        !           296:                                        goto setsym;
        !           297:                                }
        !           298:                        } else {
        !           299:                                sym = sym_lookup(line + strlen(CONFIG_), 0);
        !           300:                                if (sym->type == S_UNKNOWN)
        !           301:                                        sym->type = S_OTHER;
        !           302:                        }
        !           303:                        if (sym->flags & def_flags) {
        !           304:                                conf_warning("override: reassigning to symbol %s", sym->name);
        !           305:                        }
        !           306:                        if (conf_set_sym_val(sym, def, def_flags, p))
        !           307:                                continue;
        !           308:                } else {
        !           309:                        if (line[0] != '\r' && line[0] != '\n')
        !           310:                                conf_warning("unexpected data");
        !           311:                        continue;
        !           312:                }
        !           313: setsym:
        !           314:                if (sym && sym_is_choice_value(sym)) {
        !           315:                        struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
        !           316:                        switch (sym->def[def].tri) {
        !           317:                        case no:
        !           318:                                break;
        !           319:                        case mod:
        !           320:                                if (cs->def[def].tri == yes) {
        !           321:                                        conf_warning("%s creates inconsistent choice state", sym->name);
        !           322:                                        cs->flags &= ~def_flags;
        !           323:                                }
        !           324:                                break;
        !           325:                        case yes:
        !           326:                                if (cs->def[def].tri != no)
        !           327:                                        conf_warning("override: %s changes choice state", sym->name);
        !           328:                                cs->def[def].val = sym;
        !           329:                                break;
        !           330:                        }
        !           331:                        cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
        !           332:                }
        !           333:        }
        !           334:        fclose(in);
        !           335: 
        !           336:        if (modules_sym)
        !           337:                sym_calc_value(modules_sym);
        !           338:        return 0;
        !           339: }
        !           340: 
        !           341: int conf_read(const char *name)
        !           342: {
        !           343:        struct symbol *sym, *choice_sym;
        !           344:        struct property *prop;
        !           345:        struct expr *e;
        !           346:        int i, flags;
        !           347: 
        !           348:        sym_set_change_count(0);
        !           349: 
        !           350:        if (conf_read_simple(name, S_DEF_USER))
        !           351:                return 1;
        !           352: 
        !           353:        for_all_symbols(i, sym) {
        !           354:                sym_calc_value(sym);
        !           355:                if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
        !           356:                        goto sym_ok;
        !           357:                if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
        !           358:                        /* check that calculated value agrees with saved value */
        !           359:                        switch (sym->type) {
        !           360:                        case S_BOOLEAN:
        !           361:                        case S_TRISTATE:
        !           362:                                if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
        !           363:                                        break;
        !           364:                                if (!sym_is_choice(sym))
        !           365:                                        goto sym_ok;
        !           366:                        default:
        !           367:                                if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
        !           368:                                        goto sym_ok;
        !           369:                                break;
        !           370:                        }
        !           371:                } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
        !           372:                        /* no previous value and not saved */
        !           373:                        goto sym_ok;
        !           374:                conf_unsaved++;
        !           375:                /* maybe print value in verbose mode... */
        !           376:        sym_ok:
        !           377:                if (!sym_is_choice(sym))
        !           378:                        continue;
        !           379:                /* The choice symbol only has a set value (and thus is not new)
        !           380:                 * if all its visible childs have values.
        !           381:                 */
        !           382:                prop = sym_get_choice_prop(sym);
        !           383:                flags = sym->flags;
        !           384:                expr_list_for_each_sym(prop->expr, e, choice_sym)
        !           385:                        if (choice_sym->visible != no)
        !           386:                                flags &= choice_sym->flags;
        !           387:                sym->flags &= flags | ~SYMBOL_DEF_USER;
        !           388:        }
        !           389: 
        !           390:        for_all_symbols(i, sym) {
        !           391:                if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
        !           392:                        /* Reset values of generates values, so they'll appear
        !           393:                         * as new, if they should become visible, but that
        !           394:                         * doesn't quite work if the Kconfig and the saved
        !           395:                         * configuration disagree.
        !           396:                         */
        !           397:                        if (sym->visible == no && !conf_unsaved)
        !           398:                                sym->flags &= ~SYMBOL_DEF_USER;
        !           399:                        switch (sym->type) {
        !           400:                        case S_STRING:
        !           401:                        case S_INT:
        !           402:                        case S_HEX:
        !           403:                                /* Reset a string value if it's out of range */
        !           404:                                if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
        !           405:                                        break;
        !           406:                                sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
        !           407:                                conf_unsaved++;
        !           408:                                break;
        !           409:                        default:
        !           410:                                break;
        !           411:                        }
        !           412:                }
        !           413:        }
        !           414: 
        !           415:        sym_add_change_count(conf_warnings || conf_unsaved);
        !           416: 
        !           417:        return 0;
        !           418: }
        !           419: 
        !           420: /* Write a S_STRING */
        !           421: static void conf_write_string(bool headerfile, const char *name,
        !           422:                               const char *str, FILE *out)
        !           423: {
        !           424:        int l;
        !           425:        if (headerfile)
        !           426:                fprintf(out, "#define %s%s \"", CONFIG_, name);
        !           427:        else
        !           428:                fprintf(out, "%s%s=\"", CONFIG_, name);
        !           429: 
        !           430:        while (1) {
        !           431:                l = strcspn(str, "\"\\");
        !           432:                if (l) {
        !           433:                        xfwrite(str, l, 1, out);
        !           434:                        str += l;
        !           435:                }
        !           436:                if (!*str)
        !           437:                        break;
        !           438:                fprintf(out, "\\%c", *str++);
        !           439:        }
        !           440:        fputs("\"\n", out);
        !           441: }
        !           442: 
        !           443: static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
        !           444: {
        !           445:        const char *str;
        !           446: 
        !           447:        switch (sym->type) {
        !           448:        case S_BOOLEAN:
        !           449:        case S_TRISTATE:
        !           450:                switch (sym_get_tristate_value(sym)) {
        !           451:                case no:
        !           452:                        if (write_no)
        !           453:                                fprintf(out, "# %s%s is not set\n",
        !           454:                                    CONFIG_, sym->name);
        !           455:                        break;
        !           456:                case mod:
        !           457:                        fprintf(out, "%s%s=m\n", CONFIG_, sym->name);
        !           458:                        break;
        !           459:                case yes:
        !           460:                        fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
        !           461:                        break;
        !           462:                }
        !           463:                break;
        !           464:        case S_STRING:
        !           465:                conf_write_string(false, sym->name, sym_get_string_value(sym), out);
        !           466:                break;
        !           467:        case S_HEX:
        !           468:        case S_INT:
        !           469:                str = sym_get_string_value(sym);
        !           470:                fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str);
        !           471:                break;
        !           472:        case S_OTHER:
        !           473:        case S_UNKNOWN:
        !           474:                break;
        !           475:        }
        !           476: }
        !           477: 
        !           478: /*
        !           479:  * Write out a minimal config.
        !           480:  * All values that has default values are skipped as this is redundant.
        !           481:  */
        !           482: int conf_write_defconfig(const char *filename)
        !           483: {
        !           484:        struct symbol *sym;
        !           485:        struct menu *menu;
        !           486:        FILE *out;
        !           487: 
        !           488:        out = fopen(filename, "w");
        !           489:        if (!out)
        !           490:                return 1;
        !           491: 
        !           492:        sym_clear_all_valid();
        !           493: 
        !           494:        /* Traverse all menus to find all relevant symbols */
        !           495:        menu = rootmenu.list;
        !           496: 
        !           497:        while (menu != NULL)
        !           498:        {
        !           499:                sym = menu->sym;
        !           500:                if (sym == NULL) {
        !           501:                        if (!menu_is_visible(menu))
        !           502:                                goto next_menu;
        !           503:                } else if (!sym_is_choice(sym)) {
        !           504:                        sym_calc_value(sym);
        !           505:                        if (!(sym->flags & SYMBOL_WRITE))
        !           506:                                goto next_menu;
        !           507:                        sym->flags &= ~SYMBOL_WRITE;
        !           508:                        /* If we cannot change the symbol - skip */
        !           509:                        if (!sym_is_changable(sym))
        !           510:                                goto next_menu;
        !           511:                        /* If symbol equals to default value - skip */
        !           512:                        if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
        !           513:                                goto next_menu;
        !           514: 
        !           515:                        /*
        !           516:                         * If symbol is a choice value and equals to the
        !           517:                         * default for a choice - skip.
        !           518:                         * But only if value is bool and equal to "y" and
        !           519:                         * choice is not "optional".
        !           520:                         * (If choice is "optional" then all values can be "n")
        !           521:                         */
        !           522:                        if (sym_is_choice_value(sym)) {
        !           523:                                struct symbol *cs;
        !           524:                                struct symbol *ds;
        !           525: 
        !           526:                                cs = prop_get_symbol(sym_get_choice_prop(sym));
        !           527:                                ds = sym_choice_default(cs);
        !           528:                                if (!sym_is_optional(cs) && sym == ds) {
        !           529:                                        if ((sym->type == S_BOOLEAN) &&
        !           530:                                            sym_get_tristate_value(sym) == yes)
        !           531:                                                goto next_menu;
        !           532:                                }
        !           533:                        }
        !           534:                        conf_write_symbol(sym, out, true);
        !           535:                }
        !           536: next_menu:
        !           537:                if (menu->list != NULL) {
        !           538:                        menu = menu->list;
        !           539:                }
        !           540:                else if (menu->next != NULL) {
        !           541:                        menu = menu->next;
        !           542:                } else {
        !           543:                        while ((menu = menu->parent)) {
        !           544:                                if (menu->next != NULL) {
        !           545:                                        menu = menu->next;
        !           546:                                        break;
        !           547:                                }
        !           548:                        }
        !           549:                }
        !           550:        }
        !           551:        fclose(out);
        !           552:        return 0;
        !           553: }
        !           554: 
        !           555: int conf_write(const char *name)
        !           556: {
        !           557:        FILE *out;
        !           558:        struct symbol *sym;
        !           559:        struct menu *menu;
        !           560:        const char *basename;
        !           561:        const char *str;
        !           562:        char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
        !           563:        time_t now;
        !           564:        int use_timestamp = 1;
        !           565:        char *env;
        !           566: 
        !           567:        dirname[0] = 0;
        !           568:        if (name && name[0]) {
        !           569:                struct stat st;
        !           570:                char *slash;
        !           571: 
        !           572:                if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
        !           573:                        strcpy(dirname, name);
        !           574:                        strcat(dirname, "/");
        !           575:                        basename = conf_get_configname();
        !           576:                } else if ((slash = strrchr(name, '/'))) {
        !           577:                        int size = slash - name + 1;
        !           578:                        memcpy(dirname, name, size);
        !           579:                        dirname[size] = 0;
        !           580:                        if (slash[1])
        !           581:                                basename = slash + 1;
        !           582:                        else
        !           583:                                basename = conf_get_configname();
        !           584:                } else
        !           585:                        basename = name;
        !           586:        } else
        !           587:                basename = conf_get_configname();
        !           588: 
        !           589:        sprintf(newname, "%s%s", dirname, basename);
        !           590:        env = getenv("KCONFIG_OVERWRITECONFIG");
        !           591:        if (!env || !*env) {
        !           592:                sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
        !           593:                out = fopen(tmpname, "w");
        !           594:        } else {
        !           595:                *tmpname = 0;
        !           596:                out = fopen(newname, "w");
        !           597:        }
        !           598:        if (!out)
        !           599:                return 1;
        !           600: 
        !           601:        time(&now);
        !           602:        env = getenv("KCONFIG_NOTIMESTAMP");
        !           603:        if (env && *env)
        !           604:                use_timestamp = 0;
        !           605: 
        !           606:        fprintf(out, _("#\n"
        !           607:                       "# Automatically generated make config: don't edit\n"
        !           608:                       "# %s\n"
        !           609:                       "%s%s"
        !           610:                       "#\n"),
        !           611:                     rootmenu.prompt->text,
        !           612:                     use_timestamp ? "# " : "",
        !           613:                     use_timestamp ? ctime(&now) : "");
        !           614: 
        !           615:        if (!conf_get_changed())
        !           616:                sym_clear_all_valid();
        !           617: 
        !           618:        menu = rootmenu.list;
        !           619:        while (menu) {
        !           620:                sym = menu->sym;
        !           621:                if (!sym) {
        !           622:                        if (!menu_is_visible(menu))
        !           623:                                goto next;
        !           624:                        str = menu_get_prompt(menu);
        !           625:                        fprintf(out, "\n"
        !           626:                                     "#\n"
        !           627:                                     "# %s\n"
        !           628:                                     "#\n", str);
        !           629:                } else if (!(sym->flags & SYMBOL_CHOICE)) {
        !           630:                        sym_calc_value(sym);
        !           631:                        if (!(sym->flags & SYMBOL_WRITE))
        !           632:                                goto next;
        !           633:                        sym->flags &= ~SYMBOL_WRITE;
        !           634:                        /* Write config symbol to file */
        !           635:                        conf_write_symbol(sym, out, true);
        !           636:                }
        !           637: 
        !           638: next:
        !           639:                if (menu->list) {
        !           640:                        menu = menu->list;
        !           641:                        continue;
        !           642:                }
        !           643:                if (menu->next)
        !           644:                        menu = menu->next;
        !           645:                else while ((menu = menu->parent)) {
        !           646:                        if (menu->next) {
        !           647:                                menu = menu->next;
        !           648:                                break;
        !           649:                        }
        !           650:                }
        !           651:        }
        !           652:        fclose(out);
        !           653: 
        !           654:        if (*tmpname) {
        !           655:                strcat(dirname, basename);
        !           656:                strcat(dirname, ".old");
        !           657:                rename(newname, dirname);
        !           658:                if (rename(tmpname, newname))
        !           659:                        return 1;
        !           660:        }
        !           661: 
        !           662:        conf_message(_("configuration written to %s"), newname);
        !           663: 
        !           664:        sym_set_change_count(0);
        !           665: 
        !           666:        return 0;
        !           667: }
        !           668: 
        !           669: static int conf_split_config(void)
        !           670: {
        !           671:        const char *name;
        !           672:        char path[PATH_MAX+1];
        !           673:        char *s, *d, c;
        !           674:        struct symbol *sym;
        !           675:        struct stat sb;
        !           676:        int res, i, fd;
        !           677: 
        !           678:        name = conf_get_autoconfig_name();
        !           679:        conf_read_simple(name, S_DEF_AUTO);
        !           680: 
        !           681:        if (chdir("include/config"))
        !           682:                return 1;
        !           683: 
        !           684:        res = 0;
        !           685:        for_all_symbols(i, sym) {
        !           686:                sym_calc_value(sym);
        !           687:                if ((sym->flags & SYMBOL_AUTO) || !sym->name)
        !           688:                        continue;
        !           689:                if (sym->flags & SYMBOL_WRITE) {
        !           690:                        if (sym->flags & SYMBOL_DEF_AUTO) {
        !           691:                                /*
        !           692:                                 * symbol has old and new value,
        !           693:                                 * so compare them...
        !           694:                                 */
        !           695:                                switch (sym->type) {
        !           696:                                case S_BOOLEAN:
        !           697:                                case S_TRISTATE:
        !           698:                                        if (sym_get_tristate_value(sym) ==
        !           699:                                            sym->def[S_DEF_AUTO].tri)
        !           700:                                                continue;
        !           701:                                        break;
        !           702:                                case S_STRING:
        !           703:                                case S_HEX:
        !           704:                                case S_INT:
        !           705:                                        if (!strcmp(sym_get_string_value(sym),
        !           706:                                                    sym->def[S_DEF_AUTO].val))
        !           707:                                                continue;
        !           708:                                        break;
        !           709:                                default:
        !           710:                                        break;
        !           711:                                }
        !           712:                        } else {
        !           713:                                /*
        !           714:                                 * If there is no old value, only 'no' (unset)
        !           715:                                 * is allowed as new value.
        !           716:                                 */
        !           717:                                switch (sym->type) {
        !           718:                                case S_BOOLEAN:
        !           719:                                case S_TRISTATE:
        !           720:                                        if (sym_get_tristate_value(sym) == no)
        !           721:                                                continue;
        !           722:                                        break;
        !           723:                                default:
        !           724:                                        break;
        !           725:                                }
        !           726:                        }
        !           727:                } else if (!(sym->flags & SYMBOL_DEF_AUTO))
        !           728:                        /* There is neither an old nor a new value. */
        !           729:                        continue;
        !           730:                /* else
        !           731:                 *      There is an old value, but no new value ('no' (unset)
        !           732:                 *      isn't saved in auto.conf, so the old value is always
        !           733:                 *      different from 'no').
        !           734:                 */
        !           735: 
        !           736:                /* Replace all '_' and append ".h" */
        !           737:                s = sym->name;
        !           738:                d = path;
        !           739:                while ((c = *s++)) {
        !           740:                        c = tolower(c);
        !           741:                        *d++ = (c == '_') ? '/' : c;
        !           742:                }
        !           743:                strcpy(d, ".h");
        !           744: 
        !           745:                /* Assume directory path already exists. */
        !           746:                fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
        !           747:                if (fd == -1) {
        !           748:                        if (errno != ENOENT) {
        !           749:                                res = 1;
        !           750:                                break;
        !           751:                        }
        !           752:                        /*
        !           753:                         * Create directory components,
        !           754:                         * unless they exist already.
        !           755:                         */
        !           756:                        d = path;
        !           757:                        while ((d = strchr(d, '/'))) {
        !           758:                                *d = 0;
        !           759:                                if (stat(path, &sb) && mkdir(path, 0755)) {
        !           760:                                        res = 1;
        !           761:                                        goto out;
        !           762:                                }
        !           763:                                *d++ = '/';
        !           764:                        }
        !           765:                        /* Try it again. */
        !           766:                        fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
        !           767:                        if (fd == -1) {
        !           768:                                res = 1;
        !           769:                                break;
        !           770:                        }
        !           771:                }
        !           772:                close(fd);
        !           773:        }
        !           774: out:
        !           775:        if (chdir("../.."))
        !           776:                return 1;
        !           777: 
        !           778:        return res;
        !           779: }
        !           780: 
        !           781: int conf_write_autoconf(void)
        !           782: {
        !           783:        struct symbol *sym;
        !           784:        const char *str;
        !           785:        const char *name;
        !           786:        FILE *out, *tristate, *out_h;
        !           787:        time_t now;
        !           788:        int i;
        !           789: 
        !           790:        sym_clear_all_valid();
        !           791: 
        !           792:        file_write_dep("include/config/auto.conf.cmd");
        !           793: 
        !           794:        if (conf_split_config())
        !           795:                return 1;
        !           796: 
        !           797:        out = fopen(".tmpconfig", "w");
        !           798:        if (!out)
        !           799:                return 1;
        !           800: 
        !           801:        tristate = fopen(".tmpconfig_tristate", "w");
        !           802:        if (!tristate) {
        !           803:                fclose(out);
        !           804:                return 1;
        !           805:        }
        !           806: 
        !           807:        out_h = fopen(".tmpconfig.h", "w");
        !           808:        if (!out_h) {
        !           809:                fclose(out);
        !           810:                fclose(tristate);
        !           811:                return 1;
        !           812:        }
        !           813: 
        !           814:        time(&now);
        !           815:        fprintf(out, "#\n"
        !           816:                     "# Automatically generated make config: don't edit\n"
        !           817:                     "# %s\n"
        !           818:                     "# %s"
        !           819:                     "#\n",
        !           820:                     rootmenu.prompt->text, ctime(&now));
        !           821:        fprintf(tristate, "#\n"
        !           822:                          "# Automatically generated - do not edit\n"
        !           823:                          "\n");
        !           824:        fprintf(out_h, "/*\n"
        !           825:                       " * Automatically generated C config: don't edit\n"
        !           826:                       " * %s\n"
        !           827:                       " * %s"
        !           828:                       " */\n",
        !           829:                       rootmenu.prompt->text, ctime(&now));
        !           830: 
        !           831:        for_all_symbols(i, sym) {
        !           832:                sym_calc_value(sym);
        !           833:                if (!sym->name)
        !           834:                        continue;
        !           835:                if (!(sym->flags & SYMBOL_WRITE)) {
        !           836:                        if (sym->type == S_BOOLEAN || sym->type == S_HEX
        !           837:                            || sym->type == S_INT)
        !           838:                                fprintf(out_h, "#define %s%s 0\n",
        !           839:                                        CONFIG_, sym->name);
        !           840:                        continue;
        !           841:                }
        !           842: 
        !           843:                /* write symbol to config file */
        !           844:                conf_write_symbol(sym, out, false);
        !           845: 
        !           846:                /* update autoconf and tristate files */
        !           847:                switch (sym->type) {
        !           848:                case S_BOOLEAN:
        !           849:                case S_TRISTATE:
        !           850:                        switch (sym_get_tristate_value(sym)) {
        !           851:                        case no:
        !           852:                                fprintf(out_h, "#define %s%s 0\n",
        !           853:                                    CONFIG_, sym->name);
        !           854:                                break;
        !           855:                        case mod:
        !           856:                                fprintf(tristate, "%s%s=M\n",
        !           857:                                    CONFIG_, sym->name);
        !           858:                                fprintf(out_h, "#define %s%s_MODULE 1\n",
        !           859:                                    CONFIG_, sym->name);
        !           860:                                break;
        !           861:                        case yes:
        !           862:                                if (sym->type == S_TRISTATE)
        !           863:                                        fprintf(tristate,"%s%s=Y\n",
        !           864:                                            CONFIG_, sym->name);
        !           865:                                fprintf(out_h, "#define %s%s 1\n",
        !           866:                                    CONFIG_, sym->name);
        !           867:                                break;
        !           868:                        }
        !           869:                        break;
        !           870:                case S_STRING:
        !           871:                        conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
        !           872:                        break;
        !           873:                case S_HEX:
        !           874:                        str = sym_get_string_value(sym);
        !           875:                        if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
        !           876:                                fprintf(out_h, "#define %s%s 0x%s\n",
        !           877:                                    CONFIG_, sym->name, str);
        !           878:                                break;
        !           879:                        }
        !           880:                case S_INT:
        !           881:                        str = sym_get_string_value(sym);
        !           882:                        fprintf(out_h, "#define %s%s %s\n",
        !           883:                            CONFIG_, sym->name, str);
        !           884:                        break;
        !           885:                default:
        !           886:                        break;
        !           887:                }
        !           888:        }
        !           889:        fclose(out);
        !           890:        fclose(tristate);
        !           891:        fclose(out_h);
        !           892: 
        !           893:        name = getenv("KCONFIG_AUTOHEADER");
        !           894:        if (!name)
        !           895:                name = "include/generated/autoconf.h";
        !           896:        if (rename(".tmpconfig.h", name))
        !           897:                return 1;
        !           898:        name = getenv("KCONFIG_TRISTATE");
        !           899:        if (!name)
        !           900:                name = "include/config/tristate.conf";
        !           901:        if (rename(".tmpconfig_tristate", name))
        !           902:                return 1;
        !           903:        name = conf_get_autoconfig_name();
        !           904:        /*
        !           905:         * This must be the last step, kbuild has a dependency on auto.conf
        !           906:         * and this marks the successful completion of the previous steps.
        !           907:         */
        !           908:        if (rename(".tmpconfig", name))
        !           909:                return 1;
        !           910: 
        !           911:        return 0;
        !           912: }
        !           913: 
        !           914: static int sym_change_count;
        !           915: static void (*conf_changed_callback)(void);
        !           916: 
        !           917: void sym_set_change_count(int count)
        !           918: {
        !           919:        int _sym_change_count = sym_change_count;
        !           920:        sym_change_count = count;
        !           921:        if (conf_changed_callback &&
        !           922:            (bool)_sym_change_count != (bool)count)
        !           923:                conf_changed_callback();
        !           924: }
        !           925: 
        !           926: void sym_add_change_count(int count)
        !           927: {
        !           928:        sym_set_change_count(count + sym_change_count);
        !           929: }
        !           930: 
        !           931: bool conf_get_changed(void)
        !           932: {
        !           933:        return sym_change_count;
        !           934: }
        !           935: 
        !           936: void conf_set_changed_callback(void (*fn)(void))
        !           937: {
        !           938:        conf_changed_callback = fn;
        !           939: }
        !           940: 
        !           941: static void randomize_choice_values(struct symbol *csym)
        !           942: {
        !           943:        struct property *prop;
        !           944:        struct symbol *sym;
        !           945:        struct expr *e;
        !           946:        int cnt, def;
        !           947: 
        !           948:        /*
        !           949:         * If choice is mod then we may have more items selected
        !           950:         * and if no then no-one.
        !           951:         * In both cases stop.
        !           952:         */
        !           953:        if (csym->curr.tri != yes)
        !           954:                return;
        !           955: 
        !           956:        prop = sym_get_choice_prop(csym);
        !           957: 
        !           958:        /* count entries in choice block */
        !           959:        cnt = 0;
        !           960:        expr_list_for_each_sym(prop->expr, e, sym)
        !           961:                cnt++;
        !           962: 
        !           963:        /*
        !           964:         * find a random value and set it to yes,
        !           965:         * set the rest to no so we have only one set
        !           966:         */
        !           967:        def = (rand() % cnt);
        !           968: 
        !           969:        cnt = 0;
        !           970:        expr_list_for_each_sym(prop->expr, e, sym) {
        !           971:                if (def == cnt++) {
        !           972:                        sym->def[S_DEF_USER].tri = yes;
        !           973:                        csym->def[S_DEF_USER].val = sym;
        !           974:                }
        !           975:                else {
        !           976:                        sym->def[S_DEF_USER].tri = no;
        !           977:                }
        !           978:        }
        !           979:        csym->flags |= SYMBOL_DEF_USER;
        !           980:        /* clear VALID to get value calculated */
        !           981:        csym->flags &= ~(SYMBOL_VALID);
        !           982: }
        !           983: 
        !           984: static void set_all_choice_values(struct symbol *csym)
        !           985: {
        !           986:        struct property *prop;
        !           987:        struct symbol *sym;
        !           988:        struct expr *e;
        !           989: 
        !           990:        prop = sym_get_choice_prop(csym);
        !           991: 
        !           992:        /*
        !           993:         * Set all non-assinged choice values to no
        !           994:         */
        !           995:        expr_list_for_each_sym(prop->expr, e, sym) {
        !           996:                if (!sym_has_value(sym))
        !           997:                        sym->def[S_DEF_USER].tri = no;
        !           998:        }
        !           999:        csym->flags |= SYMBOL_DEF_USER;
        !          1000:        /* clear VALID to get value calculated */
        !          1001:        csym->flags &= ~(SYMBOL_VALID);
        !          1002: }
        !          1003: 
        !          1004: void conf_set_all_new_symbols(enum conf_def_mode mode)
        !          1005: {
        !          1006:        struct symbol *sym, *csym;
        !          1007:        int i, cnt;
        !          1008: 
        !          1009:        for_all_symbols(i, sym) {
        !          1010:                if (sym_has_value(sym))
        !          1011:                        continue;
        !          1012:                switch (sym_get_type(sym)) {
        !          1013:                case S_BOOLEAN:
        !          1014:                case S_TRISTATE:
        !          1015:                        switch (mode) {
        !          1016:                        case def_yes:
        !          1017:                                sym->def[S_DEF_USER].tri = yes;
        !          1018:                                break;
        !          1019:                        case def_mod:
        !          1020:                                sym->def[S_DEF_USER].tri = mod;
        !          1021:                                break;
        !          1022:                        case def_no:
        !          1023:                                sym->def[S_DEF_USER].tri = no;
        !          1024:                                break;
        !          1025:                        case def_random:
        !          1026:                                cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
        !          1027:                                sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
        !          1028:                                break;
        !          1029:                        default:
        !          1030:                                continue;
        !          1031:                        }
        !          1032:                        if (!(sym_is_choice(sym) && mode == def_random))
        !          1033:                                sym->flags |= SYMBOL_DEF_USER;
        !          1034:                        break;
        !          1035:                default:
        !          1036:                        break;
        !          1037:                }
        !          1038: 
        !          1039:        }
        !          1040: 
        !          1041:        sym_clear_all_valid();
        !          1042: 
        !          1043:        /*
        !          1044:         * We have different type of choice blocks.
        !          1045:         * If curr.tri equals to mod then we can select several
        !          1046:         * choice symbols in one block.
        !          1047:         * In this case we do nothing.
        !          1048:         * If curr.tri equals yes then only one symbol can be
        !          1049:         * selected in a choice block and we set it to yes,
        !          1050:         * and the rest to no.
        !          1051:         */
        !          1052:        for_all_symbols(i, csym) {
        !          1053:                if (sym_has_value(csym) || !sym_is_choice(csym))
        !          1054:                        continue;
        !          1055: 
        !          1056:                sym_calc_value(csym);
        !          1057:                if (mode == def_random)
        !          1058:                        randomize_choice_values(csym);
        !          1059:                else
        !          1060:                        set_all_choice_values(csym);
        !          1061:        }
        !          1062: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.