Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/config/confdata.c

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

Archive Download this file

Revision: 1808