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