|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.