1*cf5a6c84SAndroid Build Coastguard Worker /*
2*cf5a6c84SAndroid Build Coastguard Worker * Copyright (C) 2002 Roman Zippel <[email protected]>
3*cf5a6c84SAndroid Build Coastguard Worker * Released under the terms of the GNU GPL v2.0.
4*cf5a6c84SAndroid Build Coastguard Worker */
5*cf5a6c84SAndroid Build Coastguard Worker
6*cf5a6c84SAndroid Build Coastguard Worker #include <sys/stat.h>
7*cf5a6c84SAndroid Build Coastguard Worker #include <ctype.h>
8*cf5a6c84SAndroid Build Coastguard Worker #include <errno.h>
9*cf5a6c84SAndroid Build Coastguard Worker #include <fcntl.h>
10*cf5a6c84SAndroid Build Coastguard Worker #include <limits.h>
11*cf5a6c84SAndroid Build Coastguard Worker #include <stdio.h>
12*cf5a6c84SAndroid Build Coastguard Worker #include <stdlib.h>
13*cf5a6c84SAndroid Build Coastguard Worker #include <string.h>
14*cf5a6c84SAndroid Build Coastguard Worker #include <time.h>
15*cf5a6c84SAndroid Build Coastguard Worker #include <unistd.h>
16*cf5a6c84SAndroid Build Coastguard Worker
17*cf5a6c84SAndroid Build Coastguard Worker #define LKC_DIRECT_LINK
18*cf5a6c84SAndroid Build Coastguard Worker #include "lkc.h"
19*cf5a6c84SAndroid Build Coastguard Worker
20*cf5a6c84SAndroid Build Coastguard Worker static void conf_warning(const char *fmt, ...)
21*cf5a6c84SAndroid Build Coastguard Worker __attribute__ ((format (printf, 1, 2)));
22*cf5a6c84SAndroid Build Coastguard Worker
23*cf5a6c84SAndroid Build Coastguard Worker static const char *conf_filename;
24*cf5a6c84SAndroid Build Coastguard Worker static int conf_lineno, conf_warnings, conf_unsaved;
25*cf5a6c84SAndroid Build Coastguard Worker
26*cf5a6c84SAndroid Build Coastguard Worker #ifndef conf_defname
27*cf5a6c84SAndroid Build Coastguard Worker const char conf_defname[] = "arch/$ARCH/defconfig";
28*cf5a6c84SAndroid Build Coastguard Worker #endif
29*cf5a6c84SAndroid Build Coastguard Worker
30*cf5a6c84SAndroid Build Coastguard Worker #ifndef CONFIG_PREFIX
31*cf5a6c84SAndroid Build Coastguard Worker #define CONFIG_PREFIX "CONFIG_"
32*cf5a6c84SAndroid Build Coastguard Worker #endif
33*cf5a6c84SAndroid Build Coastguard Worker
conf_warning(const char * fmt,...)34*cf5a6c84SAndroid Build Coastguard Worker static void conf_warning(const char *fmt, ...)
35*cf5a6c84SAndroid Build Coastguard Worker {
36*cf5a6c84SAndroid Build Coastguard Worker va_list ap;
37*cf5a6c84SAndroid Build Coastguard Worker va_start(ap, fmt);
38*cf5a6c84SAndroid Build Coastguard Worker fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
39*cf5a6c84SAndroid Build Coastguard Worker vfprintf(stderr, fmt, ap);
40*cf5a6c84SAndroid Build Coastguard Worker fprintf(stderr, "\n");
41*cf5a6c84SAndroid Build Coastguard Worker va_end(ap);
42*cf5a6c84SAndroid Build Coastguard Worker conf_warnings++;
43*cf5a6c84SAndroid Build Coastguard Worker }
44*cf5a6c84SAndroid Build Coastguard Worker
conf_get_configname(void)45*cf5a6c84SAndroid Build Coastguard Worker const char *conf_get_configname(void)
46*cf5a6c84SAndroid Build Coastguard Worker {
47*cf5a6c84SAndroid Build Coastguard Worker char *name = getenv("KCONFIG_CONFIG");
48*cf5a6c84SAndroid Build Coastguard Worker
49*cf5a6c84SAndroid Build Coastguard Worker return name ? name : ".config";
50*cf5a6c84SAndroid Build Coastguard Worker }
51*cf5a6c84SAndroid Build Coastguard Worker
conf_expand_value(const char * in)52*cf5a6c84SAndroid Build Coastguard Worker static char *conf_expand_value(const char *in)
53*cf5a6c84SAndroid Build Coastguard Worker {
54*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
55*cf5a6c84SAndroid Build Coastguard Worker const char *src;
56*cf5a6c84SAndroid Build Coastguard Worker static char res_value[SYMBOL_MAXLENGTH];
57*cf5a6c84SAndroid Build Coastguard Worker char *dst, name[SYMBOL_MAXLENGTH];
58*cf5a6c84SAndroid Build Coastguard Worker
59*cf5a6c84SAndroid Build Coastguard Worker res_value[0] = 0;
60*cf5a6c84SAndroid Build Coastguard Worker dst = name;
61*cf5a6c84SAndroid Build Coastguard Worker while ((src = strchr(in, '$'))) {
62*cf5a6c84SAndroid Build Coastguard Worker strncat(res_value, in, src - in);
63*cf5a6c84SAndroid Build Coastguard Worker src++;
64*cf5a6c84SAndroid Build Coastguard Worker dst = name;
65*cf5a6c84SAndroid Build Coastguard Worker while (isalnum(*src) || *src == '_')
66*cf5a6c84SAndroid Build Coastguard Worker *dst++ = *src++;
67*cf5a6c84SAndroid Build Coastguard Worker *dst = 0;
68*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup(name, 0);
69*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
70*cf5a6c84SAndroid Build Coastguard Worker strcat(res_value, sym_get_string_value(sym));
71*cf5a6c84SAndroid Build Coastguard Worker in = src;
72*cf5a6c84SAndroid Build Coastguard Worker }
73*cf5a6c84SAndroid Build Coastguard Worker strcat(res_value, in);
74*cf5a6c84SAndroid Build Coastguard Worker
75*cf5a6c84SAndroid Build Coastguard Worker return res_value;
76*cf5a6c84SAndroid Build Coastguard Worker }
77*cf5a6c84SAndroid Build Coastguard Worker
conf_get_default_confname(void)78*cf5a6c84SAndroid Build Coastguard Worker char *conf_get_default_confname(void)
79*cf5a6c84SAndroid Build Coastguard Worker {
80*cf5a6c84SAndroid Build Coastguard Worker struct stat buf;
81*cf5a6c84SAndroid Build Coastguard Worker static char fullname[PATH_MAX+1];
82*cf5a6c84SAndroid Build Coastguard Worker char *env, *name;
83*cf5a6c84SAndroid Build Coastguard Worker
84*cf5a6c84SAndroid Build Coastguard Worker name = conf_expand_value(conf_defname);
85*cf5a6c84SAndroid Build Coastguard Worker env = getenv(SRCTREE);
86*cf5a6c84SAndroid Build Coastguard Worker if (env) {
87*cf5a6c84SAndroid Build Coastguard Worker sprintf(fullname, "%s/%s", env, name);
88*cf5a6c84SAndroid Build Coastguard Worker if (!stat(fullname, &buf))
89*cf5a6c84SAndroid Build Coastguard Worker return fullname;
90*cf5a6c84SAndroid Build Coastguard Worker }
91*cf5a6c84SAndroid Build Coastguard Worker return name;
92*cf5a6c84SAndroid Build Coastguard Worker }
93*cf5a6c84SAndroid Build Coastguard Worker
conf_read_simple(const char * name,int def)94*cf5a6c84SAndroid Build Coastguard Worker int conf_read_simple(const char *name, int def)
95*cf5a6c84SAndroid Build Coastguard Worker {
96*cf5a6c84SAndroid Build Coastguard Worker FILE *in = NULL;
97*cf5a6c84SAndroid Build Coastguard Worker char line[1024];
98*cf5a6c84SAndroid Build Coastguard Worker char *p, *p2;
99*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
100*cf5a6c84SAndroid Build Coastguard Worker int i, def_flags;
101*cf5a6c84SAndroid Build Coastguard Worker
102*cf5a6c84SAndroid Build Coastguard Worker if (name) {
103*cf5a6c84SAndroid Build Coastguard Worker in = zconf_fopen(name);
104*cf5a6c84SAndroid Build Coastguard Worker } else {
105*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
106*cf5a6c84SAndroid Build Coastguard Worker
107*cf5a6c84SAndroid Build Coastguard Worker name = conf_get_configname();
108*cf5a6c84SAndroid Build Coastguard Worker in = zconf_fopen(name);
109*cf5a6c84SAndroid Build Coastguard Worker if (in)
110*cf5a6c84SAndroid Build Coastguard Worker goto load;
111*cf5a6c84SAndroid Build Coastguard Worker sym_change_count++;
112*cf5a6c84SAndroid Build Coastguard Worker if (!sym_defconfig_list)
113*cf5a6c84SAndroid Build Coastguard Worker return 1;
114*cf5a6c84SAndroid Build Coastguard Worker
115*cf5a6c84SAndroid Build Coastguard Worker for_all_defaults(sym_defconfig_list, prop) {
116*cf5a6c84SAndroid Build Coastguard Worker if (expr_calc_value(prop->visible.expr) == no ||
117*cf5a6c84SAndroid Build Coastguard Worker prop->expr->type != E_SYMBOL)
118*cf5a6c84SAndroid Build Coastguard Worker continue;
119*cf5a6c84SAndroid Build Coastguard Worker name = conf_expand_value(prop->expr->left.sym->name);
120*cf5a6c84SAndroid Build Coastguard Worker in = zconf_fopen(name);
121*cf5a6c84SAndroid Build Coastguard Worker if (in) {
122*cf5a6c84SAndroid Build Coastguard Worker printf(_("#\n"
123*cf5a6c84SAndroid Build Coastguard Worker "# using defaults found in %s\n"
124*cf5a6c84SAndroid Build Coastguard Worker "#\n"), name);
125*cf5a6c84SAndroid Build Coastguard Worker goto load;
126*cf5a6c84SAndroid Build Coastguard Worker }
127*cf5a6c84SAndroid Build Coastguard Worker }
128*cf5a6c84SAndroid Build Coastguard Worker }
129*cf5a6c84SAndroid Build Coastguard Worker if (!in)
130*cf5a6c84SAndroid Build Coastguard Worker return 1;
131*cf5a6c84SAndroid Build Coastguard Worker
132*cf5a6c84SAndroid Build Coastguard Worker load:
133*cf5a6c84SAndroid Build Coastguard Worker conf_filename = name;
134*cf5a6c84SAndroid Build Coastguard Worker conf_lineno = 0;
135*cf5a6c84SAndroid Build Coastguard Worker conf_warnings = 0;
136*cf5a6c84SAndroid Build Coastguard Worker conf_unsaved = 0;
137*cf5a6c84SAndroid Build Coastguard Worker
138*cf5a6c84SAndroid Build Coastguard Worker def_flags = SYMBOL_DEF << def;
139*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym) {
140*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= SYMBOL_CHANGED;
141*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~(def_flags|SYMBOL_VALID);
142*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice(sym))
143*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= def_flags;
144*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
145*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
146*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
147*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
148*cf5a6c84SAndroid Build Coastguard Worker if (sym->def[def].val)
149*cf5a6c84SAndroid Build Coastguard Worker free(sym->def[def].val);
150*cf5a6c84SAndroid Build Coastguard Worker default:
151*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].val = NULL;
152*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].tri = no;
153*cf5a6c84SAndroid Build Coastguard Worker }
154*cf5a6c84SAndroid Build Coastguard Worker }
155*cf5a6c84SAndroid Build Coastguard Worker
156*cf5a6c84SAndroid Build Coastguard Worker while (fgets(line, sizeof(line), in)) {
157*cf5a6c84SAndroid Build Coastguard Worker conf_lineno++;
158*cf5a6c84SAndroid Build Coastguard Worker sym = NULL;
159*cf5a6c84SAndroid Build Coastguard Worker switch (line[0]) {
160*cf5a6c84SAndroid Build Coastguard Worker case '#':
161*cf5a6c84SAndroid Build Coastguard Worker if (line[1]!=' ' || memcmp(line + 2, CONFIG_PREFIX,
162*cf5a6c84SAndroid Build Coastguard Worker strlen(CONFIG_PREFIX))) {
163*cf5a6c84SAndroid Build Coastguard Worker continue;
164*cf5a6c84SAndroid Build Coastguard Worker }
165*cf5a6c84SAndroid Build Coastguard Worker p = strchr(line + 2 + strlen(CONFIG_PREFIX), ' ');
166*cf5a6c84SAndroid Build Coastguard Worker if (!p)
167*cf5a6c84SAndroid Build Coastguard Worker continue;
168*cf5a6c84SAndroid Build Coastguard Worker *p++ = 0;
169*cf5a6c84SAndroid Build Coastguard Worker if (strncmp(p, "is not set", 10))
170*cf5a6c84SAndroid Build Coastguard Worker continue;
171*cf5a6c84SAndroid Build Coastguard Worker if (def == S_DEF_USER) {
172*cf5a6c84SAndroid Build Coastguard Worker sym = sym_find(line + 2 + strlen(CONFIG_PREFIX));
173*cf5a6c84SAndroid Build Coastguard Worker if (!sym) {
174*cf5a6c84SAndroid Build Coastguard Worker conf_warning("trying to assign nonexistent symbol %s", line + 2 + strlen(CONFIG_PREFIX));
175*cf5a6c84SAndroid Build Coastguard Worker break;
176*cf5a6c84SAndroid Build Coastguard Worker }
177*cf5a6c84SAndroid Build Coastguard Worker } else {
178*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup(line + 9, 0);
179*cf5a6c84SAndroid Build Coastguard Worker if (sym->type == S_UNKNOWN)
180*cf5a6c84SAndroid Build Coastguard Worker sym->type = S_BOOLEAN;
181*cf5a6c84SAndroid Build Coastguard Worker }
182*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & def_flags) {
183*cf5a6c84SAndroid Build Coastguard Worker conf_warning("trying to reassign symbol %s", sym->name);
184*cf5a6c84SAndroid Build Coastguard Worker break;
185*cf5a6c84SAndroid Build Coastguard Worker }
186*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
187*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
188*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
189*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].tri = no;
190*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= def_flags;
191*cf5a6c84SAndroid Build Coastguard Worker break;
192*cf5a6c84SAndroid Build Coastguard Worker default:
193*cf5a6c84SAndroid Build Coastguard Worker ;
194*cf5a6c84SAndroid Build Coastguard Worker }
195*cf5a6c84SAndroid Build Coastguard Worker break;
196*cf5a6c84SAndroid Build Coastguard Worker case 'A' ... 'Z':
197*cf5a6c84SAndroid Build Coastguard Worker if (memcmp(line, CONFIG_PREFIX, strlen(CONFIG_PREFIX))) {
198*cf5a6c84SAndroid Build Coastguard Worker conf_warning("unexpected data");
199*cf5a6c84SAndroid Build Coastguard Worker continue;
200*cf5a6c84SAndroid Build Coastguard Worker }
201*cf5a6c84SAndroid Build Coastguard Worker p = strchr(line + strlen(CONFIG_PREFIX), '=');
202*cf5a6c84SAndroid Build Coastguard Worker if (!p)
203*cf5a6c84SAndroid Build Coastguard Worker continue;
204*cf5a6c84SAndroid Build Coastguard Worker *p++ = 0;
205*cf5a6c84SAndroid Build Coastguard Worker p2 = strchr(p, '\n');
206*cf5a6c84SAndroid Build Coastguard Worker if (p2) {
207*cf5a6c84SAndroid Build Coastguard Worker *p2-- = 0;
208*cf5a6c84SAndroid Build Coastguard Worker if (*p2 == '\r')
209*cf5a6c84SAndroid Build Coastguard Worker *p2 = 0;
210*cf5a6c84SAndroid Build Coastguard Worker }
211*cf5a6c84SAndroid Build Coastguard Worker if (def == S_DEF_USER) {
212*cf5a6c84SAndroid Build Coastguard Worker sym = sym_find(line + strlen(CONFIG_PREFIX));
213*cf5a6c84SAndroid Build Coastguard Worker if (!sym) {
214*cf5a6c84SAndroid Build Coastguard Worker conf_warning("trying to assign nonexistent symbol %s", line + 7);
215*cf5a6c84SAndroid Build Coastguard Worker break;
216*cf5a6c84SAndroid Build Coastguard Worker }
217*cf5a6c84SAndroid Build Coastguard Worker } else {
218*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup(line + strlen(CONFIG_PREFIX), 0);
219*cf5a6c84SAndroid Build Coastguard Worker if (sym->type == S_UNKNOWN)
220*cf5a6c84SAndroid Build Coastguard Worker sym->type = S_OTHER;
221*cf5a6c84SAndroid Build Coastguard Worker }
222*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & def_flags) {
223*cf5a6c84SAndroid Build Coastguard Worker conf_warning("trying to reassign symbol %s", sym->name);
224*cf5a6c84SAndroid Build Coastguard Worker break;
225*cf5a6c84SAndroid Build Coastguard Worker }
226*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
227*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
228*cf5a6c84SAndroid Build Coastguard Worker if (p[0] == 'm') {
229*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].tri = mod;
230*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= def_flags;
231*cf5a6c84SAndroid Build Coastguard Worker break;
232*cf5a6c84SAndroid Build Coastguard Worker }
233*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
234*cf5a6c84SAndroid Build Coastguard Worker if (p[0] == 'y') {
235*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].tri = yes;
236*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= def_flags;
237*cf5a6c84SAndroid Build Coastguard Worker break;
238*cf5a6c84SAndroid Build Coastguard Worker }
239*cf5a6c84SAndroid Build Coastguard Worker if (p[0] == 'n') {
240*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].tri = no;
241*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= def_flags;
242*cf5a6c84SAndroid Build Coastguard Worker break;
243*cf5a6c84SAndroid Build Coastguard Worker }
244*cf5a6c84SAndroid Build Coastguard Worker conf_warning("symbol value '%s' invalid for %s", p, sym->name);
245*cf5a6c84SAndroid Build Coastguard Worker break;
246*cf5a6c84SAndroid Build Coastguard Worker case S_OTHER:
247*cf5a6c84SAndroid Build Coastguard Worker if (*p != '"') {
248*cf5a6c84SAndroid Build Coastguard Worker for (p2 = p; *p2 && !isspace(*p2); p2++)
249*cf5a6c84SAndroid Build Coastguard Worker ;
250*cf5a6c84SAndroid Build Coastguard Worker sym->type = S_STRING;
251*cf5a6c84SAndroid Build Coastguard Worker goto done;
252*cf5a6c84SAndroid Build Coastguard Worker }
253*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
254*cf5a6c84SAndroid Build Coastguard Worker if (*p++ != '"')
255*cf5a6c84SAndroid Build Coastguard Worker break;
256*cf5a6c84SAndroid Build Coastguard Worker for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
257*cf5a6c84SAndroid Build Coastguard Worker if (*p2 == '"') {
258*cf5a6c84SAndroid Build Coastguard Worker *p2 = 0;
259*cf5a6c84SAndroid Build Coastguard Worker break;
260*cf5a6c84SAndroid Build Coastguard Worker }
261*cf5a6c84SAndroid Build Coastguard Worker memmove(p2, p2 + 1, strlen(p2));
262*cf5a6c84SAndroid Build Coastguard Worker }
263*cf5a6c84SAndroid Build Coastguard Worker if (!p2) {
264*cf5a6c84SAndroid Build Coastguard Worker conf_warning("invalid string found");
265*cf5a6c84SAndroid Build Coastguard Worker continue;
266*cf5a6c84SAndroid Build Coastguard Worker }
267*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
268*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
269*cf5a6c84SAndroid Build Coastguard Worker done:
270*cf5a6c84SAndroid Build Coastguard Worker if (sym_string_valid(sym, p)) {
271*cf5a6c84SAndroid Build Coastguard Worker sym->def[def].val = strdup(p);
272*cf5a6c84SAndroid Build Coastguard Worker sym->flags |= def_flags;
273*cf5a6c84SAndroid Build Coastguard Worker } else {
274*cf5a6c84SAndroid Build Coastguard Worker conf_warning("symbol value '%s' invalid for %s", p, sym->name);
275*cf5a6c84SAndroid Build Coastguard Worker continue;
276*cf5a6c84SAndroid Build Coastguard Worker }
277*cf5a6c84SAndroid Build Coastguard Worker break;
278*cf5a6c84SAndroid Build Coastguard Worker default:
279*cf5a6c84SAndroid Build Coastguard Worker ;
280*cf5a6c84SAndroid Build Coastguard Worker }
281*cf5a6c84SAndroid Build Coastguard Worker break;
282*cf5a6c84SAndroid Build Coastguard Worker case '\r':
283*cf5a6c84SAndroid Build Coastguard Worker case '\n':
284*cf5a6c84SAndroid Build Coastguard Worker break;
285*cf5a6c84SAndroid Build Coastguard Worker default:
286*cf5a6c84SAndroid Build Coastguard Worker conf_warning("unexpected data");
287*cf5a6c84SAndroid Build Coastguard Worker continue;
288*cf5a6c84SAndroid Build Coastguard Worker }
289*cf5a6c84SAndroid Build Coastguard Worker if (sym && sym_is_choice_value(sym)) {
290*cf5a6c84SAndroid Build Coastguard Worker struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
291*cf5a6c84SAndroid Build Coastguard Worker switch (sym->def[def].tri) {
292*cf5a6c84SAndroid Build Coastguard Worker case no:
293*cf5a6c84SAndroid Build Coastguard Worker break;
294*cf5a6c84SAndroid Build Coastguard Worker case mod:
295*cf5a6c84SAndroid Build Coastguard Worker if (cs->def[def].tri == yes) {
296*cf5a6c84SAndroid Build Coastguard Worker conf_warning("%s creates inconsistent choice state", sym->name);
297*cf5a6c84SAndroid Build Coastguard Worker cs->flags &= ~def_flags;
298*cf5a6c84SAndroid Build Coastguard Worker }
299*cf5a6c84SAndroid Build Coastguard Worker break;
300*cf5a6c84SAndroid Build Coastguard Worker case yes:
301*cf5a6c84SAndroid Build Coastguard Worker if (cs->def[def].tri != no) {
302*cf5a6c84SAndroid Build Coastguard Worker conf_warning("%s creates inconsistent choice state", sym->name);
303*cf5a6c84SAndroid Build Coastguard Worker cs->flags &= ~def_flags;
304*cf5a6c84SAndroid Build Coastguard Worker } else
305*cf5a6c84SAndroid Build Coastguard Worker cs->def[def].val = sym;
306*cf5a6c84SAndroid Build Coastguard Worker break;
307*cf5a6c84SAndroid Build Coastguard Worker }
308*cf5a6c84SAndroid Build Coastguard Worker cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
309*cf5a6c84SAndroid Build Coastguard Worker }
310*cf5a6c84SAndroid Build Coastguard Worker }
311*cf5a6c84SAndroid Build Coastguard Worker fclose(in);
312*cf5a6c84SAndroid Build Coastguard Worker
313*cf5a6c84SAndroid Build Coastguard Worker if (modules_sym)
314*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(modules_sym);
315*cf5a6c84SAndroid Build Coastguard Worker return 0;
316*cf5a6c84SAndroid Build Coastguard Worker }
317*cf5a6c84SAndroid Build Coastguard Worker
conf_read(const char * name)318*cf5a6c84SAndroid Build Coastguard Worker int conf_read(const char *name)
319*cf5a6c84SAndroid Build Coastguard Worker {
320*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
321*cf5a6c84SAndroid Build Coastguard Worker struct property *prop;
322*cf5a6c84SAndroid Build Coastguard Worker struct expr *e;
323*cf5a6c84SAndroid Build Coastguard Worker int i, flags;
324*cf5a6c84SAndroid Build Coastguard Worker
325*cf5a6c84SAndroid Build Coastguard Worker sym_change_count = 0;
326*cf5a6c84SAndroid Build Coastguard Worker
327*cf5a6c84SAndroid Build Coastguard Worker if (conf_read_simple(name, S_DEF_USER))
328*cf5a6c84SAndroid Build Coastguard Worker return 1;
329*cf5a6c84SAndroid Build Coastguard Worker
330*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym) {
331*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
332*cf5a6c84SAndroid Build Coastguard Worker if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
333*cf5a6c84SAndroid Build Coastguard Worker goto sym_ok;
334*cf5a6c84SAndroid Build Coastguard Worker if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
335*cf5a6c84SAndroid Build Coastguard Worker /* check that calculated value agrees with saved value */
336*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
337*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
338*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
339*cf5a6c84SAndroid Build Coastguard Worker if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
340*cf5a6c84SAndroid Build Coastguard Worker break;
341*cf5a6c84SAndroid Build Coastguard Worker if (!sym_is_choice(sym))
342*cf5a6c84SAndroid Build Coastguard Worker goto sym_ok;
343*cf5a6c84SAndroid Build Coastguard Worker default:
344*cf5a6c84SAndroid Build Coastguard Worker if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
345*cf5a6c84SAndroid Build Coastguard Worker goto sym_ok;
346*cf5a6c84SAndroid Build Coastguard Worker break;
347*cf5a6c84SAndroid Build Coastguard Worker }
348*cf5a6c84SAndroid Build Coastguard Worker } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
349*cf5a6c84SAndroid Build Coastguard Worker /* no previous value and not saved */
350*cf5a6c84SAndroid Build Coastguard Worker goto sym_ok;
351*cf5a6c84SAndroid Build Coastguard Worker conf_unsaved++;
352*cf5a6c84SAndroid Build Coastguard Worker /* maybe print value in verbose mode... */
353*cf5a6c84SAndroid Build Coastguard Worker sym_ok:
354*cf5a6c84SAndroid Build Coastguard Worker if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
355*cf5a6c84SAndroid Build Coastguard Worker if (sym->visible == no)
356*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~SYMBOL_DEF_USER;
357*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
358*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
359*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
360*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
361*cf5a6c84SAndroid Build Coastguard Worker if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
362*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
363*cf5a6c84SAndroid Build Coastguard Worker default:
364*cf5a6c84SAndroid Build Coastguard Worker break;
365*cf5a6c84SAndroid Build Coastguard Worker }
366*cf5a6c84SAndroid Build Coastguard Worker }
367*cf5a6c84SAndroid Build Coastguard Worker if (!sym_is_choice(sym))
368*cf5a6c84SAndroid Build Coastguard Worker continue;
369*cf5a6c84SAndroid Build Coastguard Worker prop = sym_get_choice_prop(sym);
370*cf5a6c84SAndroid Build Coastguard Worker flags = sym->flags;
371*cf5a6c84SAndroid Build Coastguard Worker for (e = prop->expr; e; e = e->left.expr)
372*cf5a6c84SAndroid Build Coastguard Worker if (e->right.sym->visible != no)
373*cf5a6c84SAndroid Build Coastguard Worker flags &= e->right.sym->flags;
374*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= flags | ~SYMBOL_DEF_USER;
375*cf5a6c84SAndroid Build Coastguard Worker }
376*cf5a6c84SAndroid Build Coastguard Worker
377*cf5a6c84SAndroid Build Coastguard Worker sym_change_count += conf_warnings || conf_unsaved;
378*cf5a6c84SAndroid Build Coastguard Worker
379*cf5a6c84SAndroid Build Coastguard Worker return 0;
380*cf5a6c84SAndroid Build Coastguard Worker }
381*cf5a6c84SAndroid Build Coastguard Worker
next_menu(struct menu * menu)382*cf5a6c84SAndroid Build Coastguard Worker struct menu *next_menu(struct menu *menu)
383*cf5a6c84SAndroid Build Coastguard Worker {
384*cf5a6c84SAndroid Build Coastguard Worker if (menu->list) return menu->list;
385*cf5a6c84SAndroid Build Coastguard Worker do {
386*cf5a6c84SAndroid Build Coastguard Worker if (menu->next) {
387*cf5a6c84SAndroid Build Coastguard Worker menu = menu->next;
388*cf5a6c84SAndroid Build Coastguard Worker break;
389*cf5a6c84SAndroid Build Coastguard Worker }
390*cf5a6c84SAndroid Build Coastguard Worker } while ((menu = menu->parent));
391*cf5a6c84SAndroid Build Coastguard Worker
392*cf5a6c84SAndroid Build Coastguard Worker return menu;
393*cf5a6c84SAndroid Build Coastguard Worker }
394*cf5a6c84SAndroid Build Coastguard Worker
395*cf5a6c84SAndroid Build Coastguard Worker #define SYMBOL_FORCEWRITE (1<<31)
396*cf5a6c84SAndroid Build Coastguard Worker
conf_write(const char * name)397*cf5a6c84SAndroid Build Coastguard Worker int conf_write(const char *name)
398*cf5a6c84SAndroid Build Coastguard Worker {
399*cf5a6c84SAndroid Build Coastguard Worker FILE *out;
400*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
401*cf5a6c84SAndroid Build Coastguard Worker struct menu *menu;
402*cf5a6c84SAndroid Build Coastguard Worker const char *basename;
403*cf5a6c84SAndroid Build Coastguard Worker char dirname[128], tmpname[128], newname[128];
404*cf5a6c84SAndroid Build Coastguard Worker int type, l, writetype;
405*cf5a6c84SAndroid Build Coastguard Worker const char *str;
406*cf5a6c84SAndroid Build Coastguard Worker time_t now;
407*cf5a6c84SAndroid Build Coastguard Worker int use_timestamp = 1;
408*cf5a6c84SAndroid Build Coastguard Worker char *env;
409*cf5a6c84SAndroid Build Coastguard Worker
410*cf5a6c84SAndroid Build Coastguard Worker dirname[0] = 0;
411*cf5a6c84SAndroid Build Coastguard Worker if (name && name[0]) {
412*cf5a6c84SAndroid Build Coastguard Worker struct stat st;
413*cf5a6c84SAndroid Build Coastguard Worker char *slash;
414*cf5a6c84SAndroid Build Coastguard Worker
415*cf5a6c84SAndroid Build Coastguard Worker if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
416*cf5a6c84SAndroid Build Coastguard Worker strcpy(dirname, name);
417*cf5a6c84SAndroid Build Coastguard Worker strcat(dirname, "/");
418*cf5a6c84SAndroid Build Coastguard Worker basename = conf_get_configname();
419*cf5a6c84SAndroid Build Coastguard Worker } else if ((slash = strrchr(name, '/'))) {
420*cf5a6c84SAndroid Build Coastguard Worker int size = slash - name + 1;
421*cf5a6c84SAndroid Build Coastguard Worker memcpy(dirname, name, size);
422*cf5a6c84SAndroid Build Coastguard Worker dirname[size] = 0;
423*cf5a6c84SAndroid Build Coastguard Worker if (slash[1])
424*cf5a6c84SAndroid Build Coastguard Worker basename = slash + 1;
425*cf5a6c84SAndroid Build Coastguard Worker else
426*cf5a6c84SAndroid Build Coastguard Worker basename = conf_get_configname();
427*cf5a6c84SAndroid Build Coastguard Worker } else
428*cf5a6c84SAndroid Build Coastguard Worker basename = name;
429*cf5a6c84SAndroid Build Coastguard Worker } else
430*cf5a6c84SAndroid Build Coastguard Worker basename = conf_get_configname();
431*cf5a6c84SAndroid Build Coastguard Worker
432*cf5a6c84SAndroid Build Coastguard Worker sprintf(newname, "%s%s", dirname, basename);
433*cf5a6c84SAndroid Build Coastguard Worker env = getenv("KCONFIG_OVERWRITECONFIG");
434*cf5a6c84SAndroid Build Coastguard Worker if (!env || !*env) {
435*cf5a6c84SAndroid Build Coastguard Worker sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
436*cf5a6c84SAndroid Build Coastguard Worker out = fopen(tmpname, "w");
437*cf5a6c84SAndroid Build Coastguard Worker } else {
438*cf5a6c84SAndroid Build Coastguard Worker *tmpname = 0;
439*cf5a6c84SAndroid Build Coastguard Worker out = fopen(newname, "w");
440*cf5a6c84SAndroid Build Coastguard Worker }
441*cf5a6c84SAndroid Build Coastguard Worker if (!out)
442*cf5a6c84SAndroid Build Coastguard Worker return 1;
443*cf5a6c84SAndroid Build Coastguard Worker
444*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup("KCONFIG_VERSION", 0);
445*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
446*cf5a6c84SAndroid Build Coastguard Worker time(&now);
447*cf5a6c84SAndroid Build Coastguard Worker env = getenv("KCONFIG_NOTIMESTAMP");
448*cf5a6c84SAndroid Build Coastguard Worker if (env && *env)
449*cf5a6c84SAndroid Build Coastguard Worker use_timestamp = 0;
450*cf5a6c84SAndroid Build Coastguard Worker
451*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, _("#\n"
452*cf5a6c84SAndroid Build Coastguard Worker "# Automatically generated make config: don't edit\n"
453*cf5a6c84SAndroid Build Coastguard Worker "# "PROJECT_NAME" version: %s\n"
454*cf5a6c84SAndroid Build Coastguard Worker "%s%s"
455*cf5a6c84SAndroid Build Coastguard Worker "#\n"),
456*cf5a6c84SAndroid Build Coastguard Worker sym_get_string_value(sym),
457*cf5a6c84SAndroid Build Coastguard Worker use_timestamp ? "# " : "",
458*cf5a6c84SAndroid Build Coastguard Worker use_timestamp ? ctime(&now) : "");
459*cf5a6c84SAndroid Build Coastguard Worker
460*cf5a6c84SAndroid Build Coastguard Worker if (!sym_change_count)
461*cf5a6c84SAndroid Build Coastguard Worker sym_clear_all_valid();
462*cf5a6c84SAndroid Build Coastguard Worker
463*cf5a6c84SAndroid Build Coastguard Worker // Write out all symbols (even in closed sub-menus).
464*cf5a6c84SAndroid Build Coastguard Worker if (1) {
465*cf5a6c84SAndroid Build Coastguard Worker for (menu = rootmenu.list; menu; menu = next_menu(menu))
466*cf5a6c84SAndroid Build Coastguard Worker if (menu->sym) menu->sym->flags |= SYMBOL_FORCEWRITE;
467*cf5a6c84SAndroid Build Coastguard Worker writetype = SYMBOL_FORCEWRITE;
468*cf5a6c84SAndroid Build Coastguard Worker
469*cf5a6c84SAndroid Build Coastguard Worker // Don't write out symbols in closed menus.
470*cf5a6c84SAndroid Build Coastguard Worker
471*cf5a6c84SAndroid Build Coastguard Worker } else writetype = SYMBOL_WRITE;
472*cf5a6c84SAndroid Build Coastguard Worker
473*cf5a6c84SAndroid Build Coastguard Worker
474*cf5a6c84SAndroid Build Coastguard Worker menu = rootmenu.list;
475*cf5a6c84SAndroid Build Coastguard Worker while (menu) {
476*cf5a6c84SAndroid Build Coastguard Worker sym = menu->sym;
477*cf5a6c84SAndroid Build Coastguard Worker if (!sym) {
478*cf5a6c84SAndroid Build Coastguard Worker if (!menu_is_visible(menu))
479*cf5a6c84SAndroid Build Coastguard Worker goto next;
480*cf5a6c84SAndroid Build Coastguard Worker str = menu_get_prompt(menu);
481*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, "\n"
482*cf5a6c84SAndroid Build Coastguard Worker "#\n"
483*cf5a6c84SAndroid Build Coastguard Worker "# %s\n"
484*cf5a6c84SAndroid Build Coastguard Worker "#\n", str);
485*cf5a6c84SAndroid Build Coastguard Worker } else if (!(sym->flags & SYMBOL_CHOICE)) {
486*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
487*cf5a6c84SAndroid Build Coastguard Worker if (!(sym->flags & writetype))
488*cf5a6c84SAndroid Build Coastguard Worker goto next;
489*cf5a6c84SAndroid Build Coastguard Worker sym->flags &= ~writetype;
490*cf5a6c84SAndroid Build Coastguard Worker type = sym->type;
491*cf5a6c84SAndroid Build Coastguard Worker if (type == S_TRISTATE) {
492*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(modules_sym);
493*cf5a6c84SAndroid Build Coastguard Worker if (modules_sym->curr.tri == no)
494*cf5a6c84SAndroid Build Coastguard Worker type = S_BOOLEAN;
495*cf5a6c84SAndroid Build Coastguard Worker }
496*cf5a6c84SAndroid Build Coastguard Worker switch (type) {
497*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
498*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
499*cf5a6c84SAndroid Build Coastguard Worker switch (sym_get_tristate_value(sym)) {
500*cf5a6c84SAndroid Build Coastguard Worker case no:
501*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, "# "CONFIG_PREFIX"%s is not set\n", sym->name);
502*cf5a6c84SAndroid Build Coastguard Worker break;
503*cf5a6c84SAndroid Build Coastguard Worker case mod:
504*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=m\n", sym->name);
505*cf5a6c84SAndroid Build Coastguard Worker break;
506*cf5a6c84SAndroid Build Coastguard Worker case yes:
507*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=y\n", sym->name);
508*cf5a6c84SAndroid Build Coastguard Worker break;
509*cf5a6c84SAndroid Build Coastguard Worker }
510*cf5a6c84SAndroid Build Coastguard Worker break;
511*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
512*cf5a6c84SAndroid Build Coastguard Worker str = sym_get_string_value(sym);
513*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=\"", sym->name);
514*cf5a6c84SAndroid Build Coastguard Worker while (1) {
515*cf5a6c84SAndroid Build Coastguard Worker l = strcspn(str, "\"\\");
516*cf5a6c84SAndroid Build Coastguard Worker if (l) {
517*cf5a6c84SAndroid Build Coastguard Worker fwrite(str, l, 1, out);
518*cf5a6c84SAndroid Build Coastguard Worker str += l;
519*cf5a6c84SAndroid Build Coastguard Worker }
520*cf5a6c84SAndroid Build Coastguard Worker if (!*str)
521*cf5a6c84SAndroid Build Coastguard Worker break;
522*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, "\\%c", *str++);
523*cf5a6c84SAndroid Build Coastguard Worker }
524*cf5a6c84SAndroid Build Coastguard Worker fputs("\"\n", out);
525*cf5a6c84SAndroid Build Coastguard Worker break;
526*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
527*cf5a6c84SAndroid Build Coastguard Worker str = sym_get_string_value(sym);
528*cf5a6c84SAndroid Build Coastguard Worker if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
529*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, *str ? str : "0");
530*cf5a6c84SAndroid Build Coastguard Worker break;
531*cf5a6c84SAndroid Build Coastguard Worker }
532*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
533*cf5a6c84SAndroid Build Coastguard Worker str = sym_get_string_value(sym);
534*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, *str ? str : "0");
535*cf5a6c84SAndroid Build Coastguard Worker break;
536*cf5a6c84SAndroid Build Coastguard Worker }
537*cf5a6c84SAndroid Build Coastguard Worker }
538*cf5a6c84SAndroid Build Coastguard Worker
539*cf5a6c84SAndroid Build Coastguard Worker next:
540*cf5a6c84SAndroid Build Coastguard Worker if (writetype == SYMBOL_WRITE) {
541*cf5a6c84SAndroid Build Coastguard Worker if (menu->list) {
542*cf5a6c84SAndroid Build Coastguard Worker menu = menu->list;
543*cf5a6c84SAndroid Build Coastguard Worker continue;
544*cf5a6c84SAndroid Build Coastguard Worker }
545*cf5a6c84SAndroid Build Coastguard Worker if (menu->next)
546*cf5a6c84SAndroid Build Coastguard Worker menu = menu->next;
547*cf5a6c84SAndroid Build Coastguard Worker else while ((menu = menu->parent)) {
548*cf5a6c84SAndroid Build Coastguard Worker if (menu->next) {
549*cf5a6c84SAndroid Build Coastguard Worker menu = menu->next;
550*cf5a6c84SAndroid Build Coastguard Worker break;
551*cf5a6c84SAndroid Build Coastguard Worker }
552*cf5a6c84SAndroid Build Coastguard Worker }
553*cf5a6c84SAndroid Build Coastguard Worker } else
554*cf5a6c84SAndroid Build Coastguard Worker menu = next_menu(menu);
555*cf5a6c84SAndroid Build Coastguard Worker }
556*cf5a6c84SAndroid Build Coastguard Worker fclose(out);
557*cf5a6c84SAndroid Build Coastguard Worker
558*cf5a6c84SAndroid Build Coastguard Worker if (*tmpname) {
559*cf5a6c84SAndroid Build Coastguard Worker strcat(dirname, basename);
560*cf5a6c84SAndroid Build Coastguard Worker strcat(dirname, ".old");
561*cf5a6c84SAndroid Build Coastguard Worker rename(newname, dirname);
562*cf5a6c84SAndroid Build Coastguard Worker if (rename(tmpname, newname))
563*cf5a6c84SAndroid Build Coastguard Worker return 1;
564*cf5a6c84SAndroid Build Coastguard Worker }
565*cf5a6c84SAndroid Build Coastguard Worker
566*cf5a6c84SAndroid Build Coastguard Worker printf(_("#\n"
567*cf5a6c84SAndroid Build Coastguard Worker "# configuration written to %s\n"
568*cf5a6c84SAndroid Build Coastguard Worker "#\n"), newname);
569*cf5a6c84SAndroid Build Coastguard Worker
570*cf5a6c84SAndroid Build Coastguard Worker sym_change_count = 0;
571*cf5a6c84SAndroid Build Coastguard Worker
572*cf5a6c84SAndroid Build Coastguard Worker return 0;
573*cf5a6c84SAndroid Build Coastguard Worker }
574*cf5a6c84SAndroid Build Coastguard Worker
conf_split_config(void)575*cf5a6c84SAndroid Build Coastguard Worker int conf_split_config(void)
576*cf5a6c84SAndroid Build Coastguard Worker {
577*cf5a6c84SAndroid Build Coastguard Worker char *name, path[128];
578*cf5a6c84SAndroid Build Coastguard Worker char *s, *d, c;
579*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
580*cf5a6c84SAndroid Build Coastguard Worker struct stat sb;
581*cf5a6c84SAndroid Build Coastguard Worker int res, i, fd;
582*cf5a6c84SAndroid Build Coastguard Worker
583*cf5a6c84SAndroid Build Coastguard Worker name = getenv("KCONFIG_AUTOCONFIG");
584*cf5a6c84SAndroid Build Coastguard Worker if (!name)
585*cf5a6c84SAndroid Build Coastguard Worker name = "include/config/auto.conf";
586*cf5a6c84SAndroid Build Coastguard Worker conf_read_simple(name, S_DEF_AUTO);
587*cf5a6c84SAndroid Build Coastguard Worker
588*cf5a6c84SAndroid Build Coastguard Worker if (chdir("include/config"))
589*cf5a6c84SAndroid Build Coastguard Worker return 1;
590*cf5a6c84SAndroid Build Coastguard Worker
591*cf5a6c84SAndroid Build Coastguard Worker res = 0;
592*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym) {
593*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
594*cf5a6c84SAndroid Build Coastguard Worker if ((sym->flags & SYMBOL_AUTO) || !sym->name)
595*cf5a6c84SAndroid Build Coastguard Worker continue;
596*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & SYMBOL_WRITE) {
597*cf5a6c84SAndroid Build Coastguard Worker if (sym->flags & SYMBOL_DEF_AUTO) {
598*cf5a6c84SAndroid Build Coastguard Worker /*
599*cf5a6c84SAndroid Build Coastguard Worker * symbol has old and new value,
600*cf5a6c84SAndroid Build Coastguard Worker * so compare them...
601*cf5a6c84SAndroid Build Coastguard Worker */
602*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
603*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
604*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
605*cf5a6c84SAndroid Build Coastguard Worker if (sym_get_tristate_value(sym) ==
606*cf5a6c84SAndroid Build Coastguard Worker sym->def[S_DEF_AUTO].tri)
607*cf5a6c84SAndroid Build Coastguard Worker continue;
608*cf5a6c84SAndroid Build Coastguard Worker break;
609*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
610*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
611*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
612*cf5a6c84SAndroid Build Coastguard Worker if (!strcmp(sym_get_string_value(sym),
613*cf5a6c84SAndroid Build Coastguard Worker sym->def[S_DEF_AUTO].val))
614*cf5a6c84SAndroid Build Coastguard Worker continue;
615*cf5a6c84SAndroid Build Coastguard Worker break;
616*cf5a6c84SAndroid Build Coastguard Worker default:
617*cf5a6c84SAndroid Build Coastguard Worker break;
618*cf5a6c84SAndroid Build Coastguard Worker }
619*cf5a6c84SAndroid Build Coastguard Worker } else {
620*cf5a6c84SAndroid Build Coastguard Worker /*
621*cf5a6c84SAndroid Build Coastguard Worker * If there is no old value, only 'no' (unset)
622*cf5a6c84SAndroid Build Coastguard Worker * is allowed as new value.
623*cf5a6c84SAndroid Build Coastguard Worker */
624*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
625*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
626*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
627*cf5a6c84SAndroid Build Coastguard Worker if (sym_get_tristate_value(sym) == no)
628*cf5a6c84SAndroid Build Coastguard Worker continue;
629*cf5a6c84SAndroid Build Coastguard Worker break;
630*cf5a6c84SAndroid Build Coastguard Worker default:
631*cf5a6c84SAndroid Build Coastguard Worker break;
632*cf5a6c84SAndroid Build Coastguard Worker }
633*cf5a6c84SAndroid Build Coastguard Worker }
634*cf5a6c84SAndroid Build Coastguard Worker } else if (!(sym->flags & SYMBOL_DEF_AUTO))
635*cf5a6c84SAndroid Build Coastguard Worker /* There is neither an old nor a new value. */
636*cf5a6c84SAndroid Build Coastguard Worker continue;
637*cf5a6c84SAndroid Build Coastguard Worker /* else
638*cf5a6c84SAndroid Build Coastguard Worker * There is an old value, but no new value ('no' (unset)
639*cf5a6c84SAndroid Build Coastguard Worker * isn't saved in auto.conf, so the old value is always
640*cf5a6c84SAndroid Build Coastguard Worker * different from 'no').
641*cf5a6c84SAndroid Build Coastguard Worker */
642*cf5a6c84SAndroid Build Coastguard Worker
643*cf5a6c84SAndroid Build Coastguard Worker /* Replace all '_' and append ".h" */
644*cf5a6c84SAndroid Build Coastguard Worker s = sym->name;
645*cf5a6c84SAndroid Build Coastguard Worker d = path;
646*cf5a6c84SAndroid Build Coastguard Worker while ((c = *s++)) {
647*cf5a6c84SAndroid Build Coastguard Worker c = tolower(c);
648*cf5a6c84SAndroid Build Coastguard Worker *d++ = (c == '_') ? '/' : c;
649*cf5a6c84SAndroid Build Coastguard Worker }
650*cf5a6c84SAndroid Build Coastguard Worker strcpy(d, ".h");
651*cf5a6c84SAndroid Build Coastguard Worker
652*cf5a6c84SAndroid Build Coastguard Worker /* Assume directory path already exists. */
653*cf5a6c84SAndroid Build Coastguard Worker fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
654*cf5a6c84SAndroid Build Coastguard Worker if (fd == -1) {
655*cf5a6c84SAndroid Build Coastguard Worker if (errno != ENOENT) {
656*cf5a6c84SAndroid Build Coastguard Worker res = 1;
657*cf5a6c84SAndroid Build Coastguard Worker break;
658*cf5a6c84SAndroid Build Coastguard Worker }
659*cf5a6c84SAndroid Build Coastguard Worker /*
660*cf5a6c84SAndroid Build Coastguard Worker * Create directory components,
661*cf5a6c84SAndroid Build Coastguard Worker * unless they exist already.
662*cf5a6c84SAndroid Build Coastguard Worker */
663*cf5a6c84SAndroid Build Coastguard Worker d = path;
664*cf5a6c84SAndroid Build Coastguard Worker while ((d = strchr(d, '/'))) {
665*cf5a6c84SAndroid Build Coastguard Worker *d = 0;
666*cf5a6c84SAndroid Build Coastguard Worker if (stat(path, &sb) && mkdir(path, 0755)) {
667*cf5a6c84SAndroid Build Coastguard Worker res = 1;
668*cf5a6c84SAndroid Build Coastguard Worker goto out;
669*cf5a6c84SAndroid Build Coastguard Worker }
670*cf5a6c84SAndroid Build Coastguard Worker *d++ = '/';
671*cf5a6c84SAndroid Build Coastguard Worker }
672*cf5a6c84SAndroid Build Coastguard Worker /* Try it again. */
673*cf5a6c84SAndroid Build Coastguard Worker fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
674*cf5a6c84SAndroid Build Coastguard Worker if (fd == -1) {
675*cf5a6c84SAndroid Build Coastguard Worker res = 1;
676*cf5a6c84SAndroid Build Coastguard Worker break;
677*cf5a6c84SAndroid Build Coastguard Worker }
678*cf5a6c84SAndroid Build Coastguard Worker }
679*cf5a6c84SAndroid Build Coastguard Worker close(fd);
680*cf5a6c84SAndroid Build Coastguard Worker }
681*cf5a6c84SAndroid Build Coastguard Worker out:
682*cf5a6c84SAndroid Build Coastguard Worker if (chdir("../.."))
683*cf5a6c84SAndroid Build Coastguard Worker return 1;
684*cf5a6c84SAndroid Build Coastguard Worker
685*cf5a6c84SAndroid Build Coastguard Worker return res;
686*cf5a6c84SAndroid Build Coastguard Worker }
687*cf5a6c84SAndroid Build Coastguard Worker
conf_write_autoconf(void)688*cf5a6c84SAndroid Build Coastguard Worker int conf_write_autoconf(void)
689*cf5a6c84SAndroid Build Coastguard Worker {
690*cf5a6c84SAndroid Build Coastguard Worker struct symbol *sym;
691*cf5a6c84SAndroid Build Coastguard Worker const char *str;
692*cf5a6c84SAndroid Build Coastguard Worker char *name;
693*cf5a6c84SAndroid Build Coastguard Worker FILE *out, *out_h;
694*cf5a6c84SAndroid Build Coastguard Worker time_t now;
695*cf5a6c84SAndroid Build Coastguard Worker int i, l;
696*cf5a6c84SAndroid Build Coastguard Worker
697*cf5a6c84SAndroid Build Coastguard Worker sym_clear_all_valid();
698*cf5a6c84SAndroid Build Coastguard Worker
699*cf5a6c84SAndroid Build Coastguard Worker file_write_dep("include/config/auto.conf.cmd");
700*cf5a6c84SAndroid Build Coastguard Worker
701*cf5a6c84SAndroid Build Coastguard Worker if (conf_split_config())
702*cf5a6c84SAndroid Build Coastguard Worker return 1;
703*cf5a6c84SAndroid Build Coastguard Worker
704*cf5a6c84SAndroid Build Coastguard Worker out = fopen(".tmpconfig", "w");
705*cf5a6c84SAndroid Build Coastguard Worker if (!out)
706*cf5a6c84SAndroid Build Coastguard Worker return 1;
707*cf5a6c84SAndroid Build Coastguard Worker
708*cf5a6c84SAndroid Build Coastguard Worker out_h = fopen(".tmpconfig.h", "w");
709*cf5a6c84SAndroid Build Coastguard Worker if (!out_h) {
710*cf5a6c84SAndroid Build Coastguard Worker fclose(out);
711*cf5a6c84SAndroid Build Coastguard Worker return 1;
712*cf5a6c84SAndroid Build Coastguard Worker }
713*cf5a6c84SAndroid Build Coastguard Worker
714*cf5a6c84SAndroid Build Coastguard Worker sym = sym_lookup("KCONFIG_VERSION", 0);
715*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
716*cf5a6c84SAndroid Build Coastguard Worker time(&now);
717*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, "#\n"
718*cf5a6c84SAndroid Build Coastguard Worker "# Automatically generated make config: don't edit\n"
719*cf5a6c84SAndroid Build Coastguard Worker "# "PROJECT_NAME" version: %s\n"
720*cf5a6c84SAndroid Build Coastguard Worker "# %s"
721*cf5a6c84SAndroid Build Coastguard Worker "#\n",
722*cf5a6c84SAndroid Build Coastguard Worker sym_get_string_value(sym), ctime(&now));
723*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "/*\n"
724*cf5a6c84SAndroid Build Coastguard Worker " * Automatically generated C config: don't edit\n"
725*cf5a6c84SAndroid Build Coastguard Worker " * "PROJECT_NAME" version: %s\n"
726*cf5a6c84SAndroid Build Coastguard Worker " * %s"
727*cf5a6c84SAndroid Build Coastguard Worker " */\n"
728*cf5a6c84SAndroid Build Coastguard Worker // "#define AUTOCONF_INCLUDED\n"
729*cf5a6c84SAndroid Build Coastguard Worker , sym_get_string_value(sym), ctime(&now));
730*cf5a6c84SAndroid Build Coastguard Worker
731*cf5a6c84SAndroid Build Coastguard Worker for_all_symbols(i, sym) {
732*cf5a6c84SAndroid Build Coastguard Worker sym_calc_value(sym);
733*cf5a6c84SAndroid Build Coastguard Worker if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
734*cf5a6c84SAndroid Build Coastguard Worker continue;
735*cf5a6c84SAndroid Build Coastguard Worker switch (sym->type) {
736*cf5a6c84SAndroid Build Coastguard Worker case S_BOOLEAN:
737*cf5a6c84SAndroid Build Coastguard Worker case S_TRISTATE:
738*cf5a6c84SAndroid Build Coastguard Worker switch (sym_get_tristate_value(sym)) {
739*cf5a6c84SAndroid Build Coastguard Worker case no:
740*cf5a6c84SAndroid Build Coastguard Worker break;
741*cf5a6c84SAndroid Build Coastguard Worker case mod:
742*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=m\n", sym->name);
743*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
744*cf5a6c84SAndroid Build Coastguard Worker break;
745*cf5a6c84SAndroid Build Coastguard Worker case yes:
746*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=y\n", sym->name);
747*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "#define "CONFIG_PREFIX"%s 1\n", sym->name);
748*cf5a6c84SAndroid Build Coastguard Worker break;
749*cf5a6c84SAndroid Build Coastguard Worker }
750*cf5a6c84SAndroid Build Coastguard Worker break;
751*cf5a6c84SAndroid Build Coastguard Worker case S_STRING:
752*cf5a6c84SAndroid Build Coastguard Worker str = sym_get_string_value(sym);
753*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=\"", sym->name);
754*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "#define "CONFIG_PREFIX"%s \"", sym->name);
755*cf5a6c84SAndroid Build Coastguard Worker while (1) {
756*cf5a6c84SAndroid Build Coastguard Worker l = strcspn(str, "\"\\");
757*cf5a6c84SAndroid Build Coastguard Worker if (l) {
758*cf5a6c84SAndroid Build Coastguard Worker fwrite(str, l, 1, out);
759*cf5a6c84SAndroid Build Coastguard Worker fwrite(str, l, 1, out_h);
760*cf5a6c84SAndroid Build Coastguard Worker str += l;
761*cf5a6c84SAndroid Build Coastguard Worker }
762*cf5a6c84SAndroid Build Coastguard Worker if (!*str)
763*cf5a6c84SAndroid Build Coastguard Worker break;
764*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, "\\%c", *str);
765*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "\\%c", *str);
766*cf5a6c84SAndroid Build Coastguard Worker str++;
767*cf5a6c84SAndroid Build Coastguard Worker }
768*cf5a6c84SAndroid Build Coastguard Worker fputs("\"\n", out);
769*cf5a6c84SAndroid Build Coastguard Worker fputs("\"\n", out_h);
770*cf5a6c84SAndroid Build Coastguard Worker break;
771*cf5a6c84SAndroid Build Coastguard Worker case S_HEX:
772*cf5a6c84SAndroid Build Coastguard Worker str = sym_get_string_value(sym);
773*cf5a6c84SAndroid Build Coastguard Worker if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
774*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, str);
775*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "#define "CONFIG_PREFIX"%s 0x%s\n", sym->name, str);
776*cf5a6c84SAndroid Build Coastguard Worker break;
777*cf5a6c84SAndroid Build Coastguard Worker }
778*cf5a6c84SAndroid Build Coastguard Worker case S_INT:
779*cf5a6c84SAndroid Build Coastguard Worker str = sym_get_string_value(sym);
780*cf5a6c84SAndroid Build Coastguard Worker fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, str);
781*cf5a6c84SAndroid Build Coastguard Worker fprintf(out_h, "#define "CONFIG_PREFIX"%s %s\n", sym->name, str);
782*cf5a6c84SAndroid Build Coastguard Worker break;
783*cf5a6c84SAndroid Build Coastguard Worker default:
784*cf5a6c84SAndroid Build Coastguard Worker break;
785*cf5a6c84SAndroid Build Coastguard Worker }
786*cf5a6c84SAndroid Build Coastguard Worker }
787*cf5a6c84SAndroid Build Coastguard Worker fclose(out);
788*cf5a6c84SAndroid Build Coastguard Worker fclose(out_h);
789*cf5a6c84SAndroid Build Coastguard Worker
790*cf5a6c84SAndroid Build Coastguard Worker name = getenv("KCONFIG_AUTOHEADER");
791*cf5a6c84SAndroid Build Coastguard Worker if (!name)
792*cf5a6c84SAndroid Build Coastguard Worker name = "include/linux/autoconf.h";
793*cf5a6c84SAndroid Build Coastguard Worker if (rename(".tmpconfig.h", name))
794*cf5a6c84SAndroid Build Coastguard Worker return 1;
795*cf5a6c84SAndroid Build Coastguard Worker name = getenv("KCONFIG_AUTOCONFIG");
796*cf5a6c84SAndroid Build Coastguard Worker if (!name)
797*cf5a6c84SAndroid Build Coastguard Worker name = "include/config/auto.conf";
798*cf5a6c84SAndroid Build Coastguard Worker /*
799*cf5a6c84SAndroid Build Coastguard Worker * This must be the last step, kbuild has a dependency on auto.conf
800*cf5a6c84SAndroid Build Coastguard Worker * and this marks the successful completion of the previous steps.
801*cf5a6c84SAndroid Build Coastguard Worker */
802*cf5a6c84SAndroid Build Coastguard Worker if (rename(".tmpconfig", name))
803*cf5a6c84SAndroid Build Coastguard Worker return 1;
804*cf5a6c84SAndroid Build Coastguard Worker
805*cf5a6c84SAndroid Build Coastguard Worker return 0;
806*cf5a6c84SAndroid Build Coastguard Worker }
807