Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2531