1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/kconfig/confdata.c Sun Mar 04 20:09:22 2007 +0000
1.3 @@ -0,0 +1,800 @@
1.4 +/*
1.5 + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
1.6 + * Released under the terms of the GNU GPL v2.0.
1.7 + */
1.8 +
1.9 +#include <sys/stat.h>
1.10 +#include <ctype.h>
1.11 +#include <errno.h>
1.12 +#include <fcntl.h>
1.13 +#include <limits.h>
1.14 +#include <stdio.h>
1.15 +#include <stdlib.h>
1.16 +#include <string.h>
1.17 +#include <time.h>
1.18 +#include <unistd.h>
1.19 +
1.20 +#define LKC_DIRECT_LINK
1.21 +#include "lkc.h"
1.22 +
1.23 +static void conf_warning(const char *fmt, ...)
1.24 + __attribute__ ((format (printf, 1, 2)));
1.25 +
1.26 +static const char *conf_filename;
1.27 +static int conf_lineno, conf_warnings, conf_unsaved;
1.28 +
1.29 +#ifndef conf_defname
1.30 +const char conf_defname[] = "arch/$ARCH/defconfig";
1.31 +#endif
1.32 +
1.33 +static void conf_warning(const char *fmt, ...)
1.34 +{
1.35 + va_list ap;
1.36 + va_start(ap, fmt);
1.37 + fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
1.38 + vfprintf(stderr, fmt, ap);
1.39 + fprintf(stderr, "\n");
1.40 + va_end(ap);
1.41 + conf_warnings++;
1.42 +}
1.43 +
1.44 +const char *conf_get_configname(void)
1.45 +{
1.46 + char *name = getenv("KCONFIG_CONFIG");
1.47 +
1.48 + return name ? name : ".config";
1.49 +}
1.50 +
1.51 +static char *conf_expand_value(const char *in)
1.52 +{
1.53 + struct symbol *sym;
1.54 + const char *src;
1.55 + static char res_value[SYMBOL_MAXLENGTH];
1.56 + char *dst, name[SYMBOL_MAXLENGTH];
1.57 +
1.58 + res_value[0] = 0;
1.59 + dst = name;
1.60 + while ((src = strchr(in, '$'))) {
1.61 + strncat(res_value, in, src - in);
1.62 + src++;
1.63 + dst = name;
1.64 + while (isalnum(*src) || *src == '_')
1.65 + *dst++ = *src++;
1.66 + *dst = 0;
1.67 + sym = sym_lookup(name, 0);
1.68 + sym_calc_value(sym);
1.69 + strcat(res_value, sym_get_string_value(sym));
1.70 + in = src;
1.71 + }
1.72 + strcat(res_value, in);
1.73 +
1.74 + return res_value;
1.75 +}
1.76 +
1.77 +char *conf_get_default_confname(void)
1.78 +{
1.79 + struct stat buf;
1.80 + static char fullname[PATH_MAX+1];
1.81 + char *env, *name;
1.82 +
1.83 + name = conf_expand_value(conf_defname);
1.84 + env = getenv(SRCTREE);
1.85 + if (env) {
1.86 + sprintf(fullname, "%s/%s", env, name);
1.87 + if (!stat(fullname, &buf))
1.88 + return fullname;
1.89 + }
1.90 + return name;
1.91 +}
1.92 +
1.93 +int conf_read_simple(const char *name, int def)
1.94 +{
1.95 + FILE *in = NULL;
1.96 + char line[1024];
1.97 + char *p, *p2;
1.98 + struct symbol *sym;
1.99 + int i, def_flags;
1.100 +
1.101 + if (name) {
1.102 + in = zconf_fopen(name);
1.103 + } else {
1.104 + struct property *prop;
1.105 +
1.106 + name = conf_get_configname();
1.107 + in = zconf_fopen(name);
1.108 + if (in)
1.109 + goto load;
1.110 + sym_change_count++;
1.111 + if (!sym_defconfig_list)
1.112 + return 1;
1.113 +
1.114 + for_all_defaults(sym_defconfig_list, prop) {
1.115 + if (expr_calc_value(prop->visible.expr) == no ||
1.116 + prop->expr->type != E_SYMBOL)
1.117 + continue;
1.118 + name = conf_expand_value(prop->expr->left.sym->name);
1.119 + in = zconf_fopen(name);
1.120 + if (in) {
1.121 + printf(_("#\n"
1.122 + "# using defaults found in %s\n"
1.123 + "#\n"), name);
1.124 + goto load;
1.125 + }
1.126 + }
1.127 + }
1.128 + if (!in)
1.129 + return 1;
1.130 +
1.131 +load:
1.132 + conf_filename = name;
1.133 + conf_lineno = 0;
1.134 + conf_warnings = 0;
1.135 + conf_unsaved = 0;
1.136 +
1.137 + def_flags = SYMBOL_DEF << def;
1.138 + for_all_symbols(i, sym) {
1.139 + sym->flags |= SYMBOL_CHANGED;
1.140 + sym->flags &= ~(def_flags|SYMBOL_VALID);
1.141 + if (sym_is_choice(sym))
1.142 + sym->flags |= def_flags;
1.143 + switch (sym->type) {
1.144 + case S_INT:
1.145 + case S_HEX:
1.146 + case S_STRING:
1.147 + if (sym->def[def].val)
1.148 + free(sym->def[def].val);
1.149 + default:
1.150 + sym->def[def].val = NULL;
1.151 + sym->def[def].tri = no;
1.152 + }
1.153 + }
1.154 +
1.155 + while (fgets(line, sizeof(line), in)) {
1.156 + conf_lineno++;
1.157 + sym = NULL;
1.158 + switch (line[0]) {
1.159 + case '#':
1.160 + if (memcmp(line + 2, "CT_", 3))
1.161 + continue;
1.162 + p = strchr(line + 5, ' ');
1.163 + if (!p)
1.164 + continue;
1.165 + *p++ = 0;
1.166 + if (strncmp(p, "is not set", 10))
1.167 + continue;
1.168 + if (def == S_DEF_USER) {
1.169 + sym = sym_find(line + 5);
1.170 + if (!sym) {
1.171 + conf_warning("trying to assign nonexistent symbol %s", line + 5);
1.172 + break;
1.173 + }
1.174 + } else {
1.175 + sym = sym_lookup(line + 5, 0);
1.176 + if (sym->type == S_UNKNOWN)
1.177 + sym->type = S_BOOLEAN;
1.178 + }
1.179 + if (sym->flags & def_flags) {
1.180 + conf_warning("trying to reassign symbol %s", sym->name);
1.181 + break;
1.182 + }
1.183 + switch (sym->type) {
1.184 + case S_BOOLEAN:
1.185 + case S_TRISTATE:
1.186 + sym->def[def].tri = no;
1.187 + sym->flags |= def_flags;
1.188 + break;
1.189 + default:
1.190 + ;
1.191 + }
1.192 + break;
1.193 + case 'C':
1.194 + if (memcmp(line, "CT_", 3)) {
1.195 + conf_warning("unexpected data");
1.196 + continue;
1.197 + }
1.198 + p = strchr(line + 3, '=');
1.199 + if (!p)
1.200 + continue;
1.201 + *p++ = 0;
1.202 + p2 = strchr(p, '\n');
1.203 + if (p2) {
1.204 + *p2-- = 0;
1.205 + if (*p2 == '\r')
1.206 + *p2 = 0;
1.207 + }
1.208 + if (def == S_DEF_USER) {
1.209 + sym = sym_find(line + 3);
1.210 + if (!sym) {
1.211 + conf_warning("trying to assign nonexistent symbol %s", line + 3);
1.212 + break;
1.213 + }
1.214 + } else {
1.215 + sym = sym_lookup(line + 3, 0);
1.216 + if (sym->type == S_UNKNOWN)
1.217 + sym->type = S_OTHER;
1.218 + }
1.219 + if (sym->flags & def_flags) {
1.220 + conf_warning("trying to reassign symbol %s", sym->name);
1.221 + break;
1.222 + }
1.223 + switch (sym->type) {
1.224 + case S_TRISTATE:
1.225 + if (p[0] == 'm') {
1.226 + sym->def[def].tri = mod;
1.227 + sym->flags |= def_flags;
1.228 + break;
1.229 + }
1.230 + case S_BOOLEAN:
1.231 + if (p[0] == 'y') {
1.232 + sym->def[def].tri = yes;
1.233 + sym->flags |= def_flags;
1.234 + break;
1.235 + }
1.236 + if (p[0] == 'n') {
1.237 + sym->def[def].tri = no;
1.238 + sym->flags |= def_flags;
1.239 + break;
1.240 + }
1.241 + conf_warning("symbol value '%s' invalid for %s", p, sym->name);
1.242 + break;
1.243 + case S_OTHER:
1.244 + if (*p != '"') {
1.245 + for (p2 = p; *p2 && !isspace(*p2); p2++)
1.246 + ;
1.247 + sym->type = S_STRING;
1.248 + goto done;
1.249 + }
1.250 + case S_STRING:
1.251 + if (*p++ != '"')
1.252 + break;
1.253 + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
1.254 + if (*p2 == '"') {
1.255 + *p2 = 0;
1.256 + break;
1.257 + }
1.258 + memmove(p2, p2 + 1, strlen(p2));
1.259 + }
1.260 + if (!p2) {
1.261 + conf_warning("invalid string found");
1.262 + continue;
1.263 + }
1.264 + case S_INT:
1.265 + case S_HEX:
1.266 + done:
1.267 + if (sym_string_valid(sym, p)) {
1.268 + sym->def[def].val = strdup(p);
1.269 + sym->flags |= def_flags;
1.270 + } else {
1.271 + conf_warning("symbol value '%s' invalid for %s", p, sym->name);
1.272 + continue;
1.273 + }
1.274 + break;
1.275 + default:
1.276 + ;
1.277 + }
1.278 + break;
1.279 + case '\r':
1.280 + case '\n':
1.281 + break;
1.282 + default:
1.283 + conf_warning("unexpected data");
1.284 + continue;
1.285 + }
1.286 + if (sym && sym_is_choice_value(sym)) {
1.287 + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
1.288 + switch (sym->def[def].tri) {
1.289 + case no:
1.290 + break;
1.291 + case mod:
1.292 + if (cs->def[def].tri == yes) {
1.293 + conf_warning("%s creates inconsistent choice state", sym->name);
1.294 + cs->flags &= ~def_flags;
1.295 + }
1.296 + break;
1.297 + case yes:
1.298 + if (cs->def[def].tri != no) {
1.299 + conf_warning("%s creates inconsistent choice state", sym->name);
1.300 + cs->flags &= ~def_flags;
1.301 + } else
1.302 + cs->def[def].val = sym;
1.303 + break;
1.304 + }
1.305 + cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
1.306 + }
1.307 + }
1.308 + fclose(in);
1.309 +
1.310 + if (modules_sym)
1.311 + sym_calc_value(modules_sym);
1.312 + return 0;
1.313 +}
1.314 +
1.315 +int conf_read(const char *name)
1.316 +{
1.317 + struct symbol *sym;
1.318 + struct property *prop;
1.319 + struct expr *e;
1.320 + int i, flags;
1.321 +
1.322 + sym_change_count = 0;
1.323 +
1.324 + if (conf_read_simple(name, S_DEF_USER))
1.325 + return 1;
1.326 +
1.327 + for_all_symbols(i, sym) {
1.328 + sym_calc_value(sym);
1.329 + if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
1.330 + goto sym_ok;
1.331 + if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
1.332 + /* check that calculated value agrees with saved value */
1.333 + switch (sym->type) {
1.334 + case S_BOOLEAN:
1.335 + case S_TRISTATE:
1.336 + if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
1.337 + break;
1.338 + if (!sym_is_choice(sym))
1.339 + goto sym_ok;
1.340 + default:
1.341 + if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
1.342 + goto sym_ok;
1.343 + break;
1.344 + }
1.345 + } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
1.346 + /* no previous value and not saved */
1.347 + goto sym_ok;
1.348 + conf_unsaved++;
1.349 + /* maybe print value in verbose mode... */
1.350 + sym_ok:
1.351 + if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
1.352 + if (sym->visible == no)
1.353 + sym->flags &= ~SYMBOL_DEF_USER;
1.354 + switch (sym->type) {
1.355 + case S_STRING:
1.356 + case S_INT:
1.357 + case S_HEX:
1.358 + if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
1.359 + sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
1.360 + default:
1.361 + break;
1.362 + }
1.363 + }
1.364 + if (!sym_is_choice(sym))
1.365 + continue;
1.366 + prop = sym_get_choice_prop(sym);
1.367 + flags = sym->flags;
1.368 + for (e = prop->expr; e; e = e->left.expr)
1.369 + if (e->right.sym->visible != no)
1.370 + flags &= e->right.sym->flags;
1.371 + sym->flags &= flags | ~SYMBOL_DEF_USER;
1.372 + }
1.373 +
1.374 + sym_change_count += conf_warnings || conf_unsaved;
1.375 +
1.376 + return 0;
1.377 +}
1.378 +
1.379 +struct menu *next_menu(struct menu *menu)
1.380 +{
1.381 + if (menu->list) return menu->list;
1.382 + do {
1.383 + if (menu->next) {
1.384 + menu = menu->next;
1.385 + break;
1.386 + }
1.387 + } while ((menu = menu->parent));
1.388 +
1.389 + return menu;
1.390 +}
1.391 +
1.392 +#define SYMBOL_FORCEWRITE (1<<31)
1.393 +
1.394 +int conf_write(const char *name)
1.395 +{
1.396 + FILE *out;
1.397 + struct symbol *sym;
1.398 + struct menu *menu;
1.399 + const char *basename;
1.400 + char dirname[128], tmpname[128], newname[128];
1.401 + int type, l, writetype;
1.402 + const char *str;
1.403 + time_t now;
1.404 + int use_timestamp = 1;
1.405 + char *env;
1.406 +
1.407 + dirname[0] = 0;
1.408 + if (name && name[0]) {
1.409 + struct stat st;
1.410 + char *slash;
1.411 +
1.412 + if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
1.413 + strcpy(dirname, name);
1.414 + strcat(dirname, "/");
1.415 + basename = conf_get_configname();
1.416 + } else if ((slash = strrchr(name, '/'))) {
1.417 + int size = slash - name + 1;
1.418 + memcpy(dirname, name, size);
1.419 + dirname[size] = 0;
1.420 + if (slash[1])
1.421 + basename = slash + 1;
1.422 + else
1.423 + basename = conf_get_configname();
1.424 + } else
1.425 + basename = name;
1.426 + } else
1.427 + basename = conf_get_configname();
1.428 +
1.429 + sprintf(newname, "%s%s", dirname, basename);
1.430 + env = getenv("KCONFIG_OVERWRITECONFIG");
1.431 + if (!env || !*env) {
1.432 + sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
1.433 + out = fopen(tmpname, "w");
1.434 + } else {
1.435 + *tmpname = 0;
1.436 + out = fopen(newname, "w");
1.437 + }
1.438 + if (!out)
1.439 + return 1;
1.440 +
1.441 + sym = sym_lookup("PROJECTVERSION", 0);
1.442 + sym_calc_value(sym);
1.443 + time(&now);
1.444 + env = getenv("KCONFIG_NOTIMESTAMP");
1.445 + if (env && *env)
1.446 + use_timestamp = 0;
1.447 +
1.448 + fprintf(out, _("#\n"
1.449 + "# Automatically generated make config: don't edit\n"
1.450 + "# "PROJECT_NAME" version: %s\n"
1.451 + "%s%s"
1.452 + "#\n"),
1.453 + sym_get_string_value(sym),
1.454 + use_timestamp ? "# " : "",
1.455 + use_timestamp ? ctime(&now) : "");
1.456 +
1.457 + if (!sym_change_count)
1.458 + sym_clear_all_valid();
1.459 +
1.460 + // Write out all symbols (even in closed sub-menus).
1.461 + if (1) {
1.462 + for (menu = rootmenu.list; menu; menu = next_menu(menu))
1.463 + if (menu->sym) menu->sym->flags |= SYMBOL_FORCEWRITE;
1.464 + writetype = SYMBOL_FORCEWRITE;
1.465 +
1.466 + // Don't write out symbols in closed menus.
1.467 +
1.468 + } else writetype = SYMBOL_WRITE;
1.469 +
1.470 +
1.471 + menu = rootmenu.list;
1.472 + while (menu) {
1.473 + sym = menu->sym;
1.474 + if (!sym) {
1.475 + if (!menu_is_visible(menu))
1.476 + goto next;
1.477 + str = menu_get_prompt(menu);
1.478 + fprintf(out, "\n"
1.479 + "#\n"
1.480 + "# %s\n"
1.481 + "#\n", str);
1.482 + } else if (!(sym->flags & SYMBOL_CHOICE)) {
1.483 + sym_calc_value(sym);
1.484 + if (!(sym->flags & writetype))
1.485 + goto next;
1.486 + sym->flags &= ~writetype;
1.487 + type = sym->type;
1.488 + if (type == S_TRISTATE) {
1.489 + sym_calc_value(modules_sym);
1.490 + if (modules_sym->curr.tri == no)
1.491 + type = S_BOOLEAN;
1.492 + }
1.493 + switch (type) {
1.494 + case S_BOOLEAN:
1.495 + case S_TRISTATE:
1.496 + switch (sym_get_tristate_value(sym)) {
1.497 + case no:
1.498 + fprintf(out, "# CT_%s is not set\n", sym->name);
1.499 + break;
1.500 + case mod:
1.501 + fprintf(out, "CT_%s=m\n", sym->name);
1.502 + break;
1.503 + case yes:
1.504 + fprintf(out, "CT_%s=y\n", sym->name);
1.505 + break;
1.506 + }
1.507 + break;
1.508 + case S_STRING:
1.509 + str = sym_get_string_value(sym);
1.510 + fprintf(out, "CT_%s=\"", sym->name);
1.511 + while (1) {
1.512 + l = strcspn(str, "\"\\");
1.513 + if (l) {
1.514 + fwrite(str, l, 1, out);
1.515 + str += l;
1.516 + }
1.517 + if (!*str)
1.518 + break;
1.519 + fprintf(out, "\\%c", *str++);
1.520 + }
1.521 + fputs("\"\n", out);
1.522 + break;
1.523 + case S_HEX:
1.524 + str = sym_get_string_value(sym);
1.525 + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
1.526 + fprintf(out, "CT_%s=%s\n", sym->name, *str ? str : "0");
1.527 + break;
1.528 + }
1.529 + case S_INT:
1.530 + str = sym_get_string_value(sym);
1.531 + fprintf(out, "CT_%s=%s\n", sym->name, *str ? str : "0");
1.532 + break;
1.533 + }
1.534 + }
1.535 +
1.536 + next:
1.537 + if (writetype == SYMBOL_WRITE) {
1.538 + if (menu->list) {
1.539 + menu = menu->list;
1.540 + continue;
1.541 + }
1.542 + if (menu->next)
1.543 + menu = menu->next;
1.544 + else while ((menu = menu->parent)) {
1.545 + if (menu->next) {
1.546 + menu = menu->next;
1.547 + break;
1.548 + }
1.549 + }
1.550 + } else
1.551 + menu = next_menu(menu);
1.552 + }
1.553 + fclose(out);
1.554 +
1.555 + if (*tmpname) {
1.556 + strcat(dirname, basename);
1.557 + strcat(dirname, ".old");
1.558 + rename(newname, dirname);
1.559 + if (rename(tmpname, newname))
1.560 + return 1;
1.561 + }
1.562 +
1.563 + printf(_("#\n"
1.564 + "# configuration written to %s\n"
1.565 + "#\n"), newname);
1.566 +
1.567 + sym_change_count = 0;
1.568 +
1.569 + return 0;
1.570 +}
1.571 +
1.572 +int conf_split_config(void)
1.573 +{
1.574 + char *name, path[128];
1.575 + char *s, *d, c;
1.576 + struct symbol *sym;
1.577 + struct stat sb;
1.578 + int res, i, fd;
1.579 +
1.580 + name = getenv("KCONFIG_AUTOCONFIG");
1.581 + if (!name)
1.582 + name = "include/config/auto.conf";
1.583 + conf_read_simple(name, S_DEF_AUTO);
1.584 +
1.585 + if (chdir("include/config"))
1.586 + return 1;
1.587 +
1.588 + res = 0;
1.589 + for_all_symbols(i, sym) {
1.590 + sym_calc_value(sym);
1.591 + if ((sym->flags & SYMBOL_AUTO) || !sym->name)
1.592 + continue;
1.593 + if (sym->flags & SYMBOL_WRITE) {
1.594 + if (sym->flags & SYMBOL_DEF_AUTO) {
1.595 + /*
1.596 + * symbol has old and new value,
1.597 + * so compare them...
1.598 + */
1.599 + switch (sym->type) {
1.600 + case S_BOOLEAN:
1.601 + case S_TRISTATE:
1.602 + if (sym_get_tristate_value(sym) ==
1.603 + sym->def[S_DEF_AUTO].tri)
1.604 + continue;
1.605 + break;
1.606 + case S_STRING:
1.607 + case S_HEX:
1.608 + case S_INT:
1.609 + if (!strcmp(sym_get_string_value(sym),
1.610 + sym->def[S_DEF_AUTO].val))
1.611 + continue;
1.612 + break;
1.613 + default:
1.614 + break;
1.615 + }
1.616 + } else {
1.617 + /*
1.618 + * If there is no old value, only 'no' (unset)
1.619 + * is allowed as new value.
1.620 + */
1.621 + switch (sym->type) {
1.622 + case S_BOOLEAN:
1.623 + case S_TRISTATE:
1.624 + if (sym_get_tristate_value(sym) == no)
1.625 + continue;
1.626 + break;
1.627 + default:
1.628 + break;
1.629 + }
1.630 + }
1.631 + } else if (!(sym->flags & SYMBOL_DEF_AUTO))
1.632 + /* There is neither an old nor a new value. */
1.633 + continue;
1.634 + /* else
1.635 + * There is an old value, but no new value ('no' (unset)
1.636 + * isn't saved in auto.conf, so the old value is always
1.637 + * different from 'no').
1.638 + */
1.639 +
1.640 + /* Replace all '_' and append ".h" */
1.641 + s = sym->name;
1.642 + d = path;
1.643 + while ((c = *s++)) {
1.644 + c = tolower(c);
1.645 + *d++ = (c == '_') ? '/' : c;
1.646 + }
1.647 + strcpy(d, ".h");
1.648 +
1.649 + /* Assume directory path already exists. */
1.650 + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1.651 + if (fd == -1) {
1.652 + if (errno != ENOENT) {
1.653 + res = 1;
1.654 + break;
1.655 + }
1.656 + /*
1.657 + * Create directory components,
1.658 + * unless they exist already.
1.659 + */
1.660 + d = path;
1.661 + while ((d = strchr(d, '/'))) {
1.662 + *d = 0;
1.663 + if (stat(path, &sb) && mkdir(path, 0755)) {
1.664 + res = 1;
1.665 + goto out;
1.666 + }
1.667 + *d++ = '/';
1.668 + }
1.669 + /* Try it again. */
1.670 + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1.671 + if (fd == -1) {
1.672 + res = 1;
1.673 + break;
1.674 + }
1.675 + }
1.676 + close(fd);
1.677 + }
1.678 +out:
1.679 + if (chdir("../.."))
1.680 + return 1;
1.681 +
1.682 + return res;
1.683 +}
1.684 +
1.685 +int conf_write_autoconf(void)
1.686 +{
1.687 + struct symbol *sym;
1.688 + const char *str;
1.689 + char *name;
1.690 + FILE *out, *out_h;
1.691 + time_t now;
1.692 + int i, l;
1.693 +
1.694 + sym_clear_all_valid();
1.695 +
1.696 + file_write_dep("include/config/auto.conf.cmd");
1.697 +
1.698 + if (conf_split_config())
1.699 + return 1;
1.700 +
1.701 + out = fopen(".tmpconfig", "w");
1.702 + if (!out)
1.703 + return 1;
1.704 +
1.705 + out_h = fopen(".tmpconfig.h", "w");
1.706 + if (!out_h) {
1.707 + fclose(out);
1.708 + return 1;
1.709 + }
1.710 +
1.711 + sym = sym_lookup("PROJECTVERSION", 0);
1.712 + sym_calc_value(sym);
1.713 + time(&now);
1.714 + fprintf(out, "#\n"
1.715 + "# Automatically generated make config: don't edit\n"
1.716 + "# "PROJECT_NAME" version: %s\n"
1.717 + "# %s"
1.718 + "#\n",
1.719 + sym_get_string_value(sym), ctime(&now));
1.720 + fprintf(out_h, "/*\n"
1.721 + " * Automatically generated C config: don't edit\n"
1.722 + " * "PROJECT_NAME" version: %s\n"
1.723 + " * %s"
1.724 + " */\n"
1.725 + "#define AUTOCONF_INCLUDED\n",
1.726 + sym_get_string_value(sym), ctime(&now));
1.727 +
1.728 + for_all_symbols(i, sym) {
1.729 + sym_calc_value(sym);
1.730 + if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
1.731 + continue;
1.732 + switch (sym->type) {
1.733 + case S_BOOLEAN:
1.734 + case S_TRISTATE:
1.735 + switch (sym_get_tristate_value(sym)) {
1.736 + case no:
1.737 + break;
1.738 + case mod:
1.739 + fprintf(out, "CT_%s=m\n", sym->name);
1.740 + fprintf(out_h, "#define CT_%s_MODULE 1\n", sym->name);
1.741 + break;
1.742 + case yes:
1.743 + fprintf(out, "CT_%s=y\n", sym->name);
1.744 + fprintf(out_h, "#define CT_%s 1\n", sym->name);
1.745 + break;
1.746 + }
1.747 + break;
1.748 + case S_STRING:
1.749 + str = sym_get_string_value(sym);
1.750 + fprintf(out, "CT_%s=\"", sym->name);
1.751 + fprintf(out_h, "#define CT_%s \"", sym->name);
1.752 + while (1) {
1.753 + l = strcspn(str, "\"\\");
1.754 + if (l) {
1.755 + fwrite(str, l, 1, out);
1.756 + fwrite(str, l, 1, out_h);
1.757 + str += l;
1.758 + }
1.759 + if (!*str)
1.760 + break;
1.761 + fprintf(out, "\\%c", *str);
1.762 + fprintf(out_h, "\\%c", *str);
1.763 + str++;
1.764 + }
1.765 + fputs("\"\n", out);
1.766 + fputs("\"\n", out_h);
1.767 + break;
1.768 + case S_HEX:
1.769 + str = sym_get_string_value(sym);
1.770 + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
1.771 + fprintf(out, "CT_%s=%s\n", sym->name, str);
1.772 + fprintf(out_h, "#define CT_%s 0x%s\n", sym->name, str);
1.773 + break;
1.774 + }
1.775 + case S_INT:
1.776 + str = sym_get_string_value(sym);
1.777 + fprintf(out, "CT_%s=%s\n", sym->name, str);
1.778 + fprintf(out_h, "#define CT_%s %s\n", sym->name, str);
1.779 + break;
1.780 + default:
1.781 + break;
1.782 + }
1.783 + }
1.784 + fclose(out);
1.785 + fclose(out_h);
1.786 +
1.787 + name = getenv("KCONFIG_AUTOHEADER");
1.788 + if (!name)
1.789 + name = "include/linux/autoconf.h";
1.790 + if (rename(".tmpconfig.h", name))
1.791 + return 1;
1.792 + name = getenv("KCONFIG_AUTOCONFIG");
1.793 + if (!name)
1.794 + name = "include/config/auto.conf";
1.795 + /*
1.796 + * This must be the last step, kbuild has a dependency on auto.conf
1.797 + * and this marks the successful completion of the previous steps.
1.798 + */
1.799 + if (rename(".tmpconfig", name))
1.800 + return 1;
1.801 +
1.802 + return 0;
1.803 +}