Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2808