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

Archive Download this file

Revision: 2476