Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/config/confdata.c

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

Archive Download this file

Revision: 2411