~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/kconfig/confdata.c

Version: ~ [ linux-5.14-rc3 ] ~ [ linux-5.13.5 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.53 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.135 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.198 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.240 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.276 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.276 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  4  */
  5 
  6 #include <sys/mman.h>
  7 #include <sys/stat.h>
  8 #include <sys/types.h>
  9 #include <ctype.h>
 10 #include <errno.h>
 11 #include <fcntl.h>
 12 #include <limits.h>
 13 #include <stdarg.h>
 14 #include <stdio.h>
 15 #include <stdlib.h>
 16 #include <string.h>
 17 #include <time.h>
 18 #include <unistd.h>
 19 
 20 #include "lkc.h"
 21 
 22 /* return true if 'path' exists, false otherwise */
 23 static bool is_present(const char *path)
 24 {
 25         struct stat st;
 26 
 27         return !stat(path, &st);
 28 }
 29 
 30 /* return true if 'path' exists and it is a directory, false otherwise */
 31 static bool is_dir(const char *path)
 32 {
 33         struct stat st;
 34 
 35         if (stat(path, &st))
 36                 return false;
 37 
 38         return S_ISDIR(st.st_mode);
 39 }
 40 
 41 /* return true if the given two files are the same, false otherwise */
 42 static bool is_same(const char *file1, const char *file2)
 43 {
 44         int fd1, fd2;
 45         struct stat st1, st2;
 46         void *map1, *map2;
 47         bool ret = false;
 48 
 49         fd1 = open(file1, O_RDONLY);
 50         if (fd1 < 0)
 51                 return ret;
 52 
 53         fd2 = open(file2, O_RDONLY);
 54         if (fd2 < 0)
 55                 goto close1;
 56 
 57         ret = fstat(fd1, &st1);
 58         if (ret)
 59                 goto close2;
 60         ret = fstat(fd2, &st2);
 61         if (ret)
 62                 goto close2;
 63 
 64         if (st1.st_size != st2.st_size)
 65                 goto close2;
 66 
 67         map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
 68         if (map1 == MAP_FAILED)
 69                 goto close2;
 70 
 71         map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
 72         if (map2 == MAP_FAILED)
 73                 goto close2;
 74 
 75         if (bcmp(map1, map2, st1.st_size))
 76                 goto close2;
 77 
 78         ret = true;
 79 close2:
 80         close(fd2);
 81 close1:
 82         close(fd1);
 83 
 84         return ret;
 85 }
 86 
 87 /*
 88  * Create the parent directory of the given path.
 89  *
 90  * For example, if 'include/config/auto.conf' is given, create 'include/config'.
 91  */
 92 static int make_parent_dir(const char *path)
 93 {
 94         char tmp[PATH_MAX + 1];
 95         char *p;
 96 
 97         strncpy(tmp, path, sizeof(tmp));
 98         tmp[sizeof(tmp) - 1] = 0;
 99 
100         /* Remove the base name. Just return if nothing is left */
101         p = strrchr(tmp, '/');
102         if (!p)
103                 return 0;
104         *(p + 1) = 0;
105 
106         /* Just in case it is an absolute path */
107         p = tmp;
108         while (*p == '/')
109                 p++;
110 
111         while ((p = strchr(p, '/'))) {
112                 *p = 0;
113 
114                 /* skip if the directory exists */
115                 if (!is_dir(tmp) && mkdir(tmp, 0755))
116                         return -1;
117 
118                 *p = '/';
119                 while (*p == '/')
120                         p++;
121         }
122 
123         return 0;
124 }
125 
126 static char depfile_path[PATH_MAX];
127 static size_t depfile_prefix_len;
128 
129 /* touch depfile for symbol 'name' */
130 static int conf_touch_dep(const char *name)
131 {
132         int fd, ret;
133         char *d;
134 
135         /* check overflow: prefix + name + '\0' must fit in buffer. */
136         if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
137                 return -1;
138 
139         d = depfile_path + depfile_prefix_len;
140         strcpy(d, name);
141 
142         /* Assume directory path already exists. */
143         fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
144         if (fd == -1) {
145                 if (errno != ENOENT)
146                         return -1;
147 
148                 ret = make_parent_dir(depfile_path);
149                 if (ret)
150                         return ret;
151 
152                 /* Try it again. */
153                 fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
154                 if (fd == -1)
155                         return -1;
156         }
157         close(fd);
158 
159         return 0;
160 }
161 
162 struct conf_printer {
163         void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
164         void (*print_comment)(FILE *, const char *, void *);
165 };
166 
167 static void conf_warning(const char *fmt, ...)
168         __attribute__ ((format (printf, 1, 2)));
169 
170 static void conf_message(const char *fmt, ...)
171         __attribute__ ((format (printf, 1, 2)));
172 
173 static const char *conf_filename;
174 static int conf_lineno, conf_warnings;
175 
176 static void conf_warning(const char *fmt, ...)
177 {
178         va_list ap;
179         va_start(ap, fmt);
180         fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
181         vfprintf(stderr, fmt, ap);
182         fprintf(stderr, "\n");
183         va_end(ap);
184         conf_warnings++;
185 }
186 
187 static void conf_default_message_callback(const char *s)
188 {
189         printf("#\n# ");
190         printf("%s", s);
191         printf("\n#\n");
192 }
193 
194 static void (*conf_message_callback)(const char *s) =
195         conf_default_message_callback;
196 void conf_set_message_callback(void (*fn)(const char *s))
197 {
198         conf_message_callback = fn;
199 }
200 
201 static void conf_message(const char *fmt, ...)
202 {
203         va_list ap;
204         char buf[4096];
205 
206         if (!conf_message_callback)
207                 return;
208 
209         va_start(ap, fmt);
210 
211         vsnprintf(buf, sizeof(buf), fmt, ap);
212         conf_message_callback(buf);
213         va_end(ap);
214 }
215 
216 const char *conf_get_configname(void)
217 {
218         char *name = getenv("KCONFIG_CONFIG");
219 
220         return name ? name : ".config";
221 }
222 
223 static const char *conf_get_autoconfig_name(void)
224 {
225         char *name = getenv("KCONFIG_AUTOCONFIG");
226 
227         return name ? name : "include/config/auto.conf";
228 }
229 
230 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
231 {
232         char *p2;
233 
234         switch (sym->type) {
235         case S_TRISTATE:
236                 if (p[0] == 'm') {
237                         sym->def[def].tri = mod;
238                         sym->flags |= def_flags;
239                         break;
240                 }
241                 /* fall through */
242         case S_BOOLEAN:
243                 if (p[0] == 'y') {
244                         sym->def[def].tri = yes;
245                         sym->flags |= def_flags;
246                         break;
247                 }
248                 if (p[0] == 'n') {
249                         sym->def[def].tri = no;
250                         sym->flags |= def_flags;
251                         break;
252                 }
253                 if (def != S_DEF_AUTO)
254                         conf_warning("symbol value '%s' invalid for %s",
255                                      p, sym->name);
256                 return 1;
257         case S_STRING:
258                 if (*p++ != '"')
259                         break;
260                 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
261                         if (*p2 == '"') {
262                                 *p2 = 0;
263                                 break;
264                         }
265                         memmove(p2, p2 + 1, strlen(p2));
266                 }
267                 if (!p2) {
268                         if (def != S_DEF_AUTO)
269                                 conf_warning("invalid string found");
270                         return 1;
271                 }
272                 /* fall through */
273         case S_INT:
274         case S_HEX:
275                 if (sym_string_valid(sym, p)) {
276                         sym->def[def].val = xstrdup(p);
277                         sym->flags |= def_flags;
278                 } else {
279                         if (def != S_DEF_AUTO)
280                                 conf_warning("symbol value '%s' invalid for %s",
281                                              p, sym->name);
282                         return 1;
283                 }
284                 break;
285         default:
286                 ;
287         }
288         return 0;
289 }
290 
291 #define LINE_GROWTH 16
292 static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
293 {
294         char *nline;
295         size_t new_size = slen + 1;
296         if (new_size > *n) {
297                 new_size += LINE_GROWTH - 1;
298                 new_size *= 2;
299                 nline = xrealloc(*lineptr, new_size);
300                 if (!nline)
301                         return -1;
302 
303                 *lineptr = nline;
304                 *n = new_size;
305         }
306 
307         (*lineptr)[slen] = c;
308 
309         return 0;
310 }
311 
312 static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
313 {
314         char *line = *lineptr;
315         size_t slen = 0;
316 
317         for (;;) {
318                 int c = getc(stream);
319 
320                 switch (c) {
321                 case '\n':
322                         if (add_byte(c, &line, slen, n) < 0)
323                                 goto e_out;
324                         slen++;
325                         /* fall through */
326                 case EOF:
327                         if (add_byte('\0', &line, slen, n) < 0)
328                                 goto e_out;
329                         *lineptr = line;
330                         if (slen == 0)
331                                 return -1;
332                         return slen;
333                 default:
334                         if (add_byte(c, &line, slen, n) < 0)
335                                 goto e_out;
336                         slen++;
337                 }
338         }
339 
340 e_out:
341         line[slen-1] = '\0';
342         *lineptr = line;
343         return -1;
344 }
345 
346 int conf_read_simple(const char *name, int def)
347 {
348         FILE *in = NULL;
349         char   *line = NULL;
350         size_t  line_asize = 0;
351         char *p, *p2;
352         struct symbol *sym;
353         int i, def_flags;
354 
355         if (name) {
356                 in = zconf_fopen(name);
357         } else {
358                 char *env;
359 
360                 name = conf_get_configname();
361                 in = zconf_fopen(name);
362                 if (in)
363                         goto load;
364                 conf_set_changed(true);
365 
366                 env = getenv("KCONFIG_DEFCONFIG_LIST");
367                 if (!env)
368                         return 1;
369 
370                 while (1) {
371                         bool is_last;
372 
373                         while (isspace(*env))
374                                 env++;
375 
376                         if (!*env)
377                                 break;
378 
379                         p = env;
380                         while (*p && !isspace(*p))
381                                 p++;
382 
383                         is_last = (*p == '\0');
384 
385                         *p = '\0';
386 
387                         in = zconf_fopen(env);
388                         if (in) {
389                                 conf_message("using defaults found in %s",
390                                              env);
391                                 goto load;
392                         }
393 
394                         if (is_last)
395                                 break;
396 
397                         env = p + 1;
398                 }
399         }
400         if (!in)
401                 return 1;
402 
403 load:
404         conf_filename = name;
405         conf_lineno = 0;
406         conf_warnings = 0;
407 
408         def_flags = SYMBOL_DEF << def;
409         for_all_symbols(i, sym) {
410                 sym->flags |= SYMBOL_CHANGED;
411                 sym->flags &= ~(def_flags|SYMBOL_VALID);
412                 if (sym_is_choice(sym))
413                         sym->flags |= def_flags;
414                 switch (sym->type) {
415                 case S_INT:
416                 case S_HEX:
417                 case S_STRING:
418                         if (sym->def[def].val)
419                                 free(sym->def[def].val);
420                         /* fall through */
421                 default:
422                         sym->def[def].val = NULL;
423                         sym->def[def].tri = no;
424                 }
425         }
426 
427         while (compat_getline(&line, &line_asize, in) != -1) {
428                 conf_lineno++;
429                 sym = NULL;
430                 if (line[0] == '#') {
431                         if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
432                                 continue;
433                         p = strchr(line + 2 + strlen(CONFIG_), ' ');
434                         if (!p)
435                                 continue;
436                         *p++ = 0;
437                         if (strncmp(p, "is not set", 10))
438                                 continue;
439                         if (def == S_DEF_USER) {
440                                 sym = sym_find(line + 2 + strlen(CONFIG_));
441                                 if (!sym) {
442                                         conf_set_changed(true);
443                                         continue;
444                                 }
445                         } else {
446                                 sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
447                                 if (sym->type == S_UNKNOWN)
448                                         sym->type = S_BOOLEAN;
449                         }
450                         if (sym->flags & def_flags) {
451                                 conf_warning("override: reassigning to symbol %s", sym->name);
452                         }
453                         switch (sym->type) {
454                         case S_BOOLEAN:
455                         case S_TRISTATE:
456                                 sym->def[def].tri = no;
457                                 sym->flags |= def_flags;
458                                 break;
459                         default:
460                                 ;
461                         }
462                 } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
463                         p = strchr(line + strlen(CONFIG_), '=');
464                         if (!p)
465                                 continue;
466                         *p++ = 0;
467                         p2 = strchr(p, '\n');
468                         if (p2) {
469                                 *p2-- = 0;
470                                 if (*p2 == '\r')
471                                         *p2 = 0;
472                         }
473 
474                         sym = sym_find(line + strlen(CONFIG_));
475                         if (!sym) {
476                                 if (def == S_DEF_AUTO)
477                                         /*
478                                          * Reading from include/config/auto.conf
479                                          * If CONFIG_FOO previously existed in
480                                          * auto.conf but it is missing now,
481                                          * include/config/FOO must be touched.
482                                          */
483                                         conf_touch_dep(line + strlen(CONFIG_));
484                                 else
485                                         conf_set_changed(true);
486                                 continue;
487                         }
488 
489                         if (sym->flags & def_flags) {
490                                 conf_warning("override: reassigning to symbol %s", sym->name);
491                         }
492                         if (conf_set_sym_val(sym, def, def_flags, p))
493                                 continue;
494                 } else {
495                         if (line[0] != '\r' && line[0] != '\n')
496                                 conf_warning("unexpected data: %.*s",
497                                              (int)strcspn(line, "\r\n"), line);
498 
499                         continue;
500                 }
501 
502                 if (sym && sym_is_choice_value(sym)) {
503                         struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
504                         switch (sym->def[def].tri) {
505                         case no:
506                                 break;
507                         case mod:
508                                 if (cs->def[def].tri == yes) {
509                                         conf_warning("%s creates inconsistent choice state", sym->name);
510                                         cs->flags &= ~def_flags;
511                                 }
512                                 break;
513                         case yes:
514                                 if (cs->def[def].tri != no)
515                                         conf_warning("override: %s changes choice state", sym->name);
516                                 cs->def[def].val = sym;
517                                 break;
518                         }
519                         cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
520                 }
521         }
522         free(line);
523         fclose(in);
524         return 0;
525 }
526 
527 int conf_read(const char *name)
528 {
529         struct symbol *sym;
530         int conf_unsaved = 0;
531         int i;
532 
533         conf_set_changed(false);
534 
535         if (conf_read_simple(name, S_DEF_USER)) {
536                 sym_calc_value(modules_sym);
537                 return 1;
538         }
539 
540         sym_calc_value(modules_sym);
541 
542         for_all_symbols(i, sym) {
543                 sym_calc_value(sym);
544                 if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
545                         continue;
546                 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
547                         /* check that calculated value agrees with saved value */
548                         switch (sym->type) {
549                         case S_BOOLEAN:
550                         case S_TRISTATE:
551                                 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
552                                         continue;
553                                 break;
554                         default:
555                                 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
556                                         continue;
557                                 break;
558                         }
559                 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
560                         /* no previous value and not saved */
561                         continue;
562                 conf_unsaved++;
563                 /* maybe print value in verbose mode... */
564         }
565 
566         for_all_symbols(i, sym) {
567                 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
568                         /* Reset values of generates values, so they'll appear
569                          * as new, if they should become visible, but that
570                          * doesn't quite work if the Kconfig and the saved
571                          * configuration disagree.
572                          */
573                         if (sym->visible == no && !conf_unsaved)
574                                 sym->flags &= ~SYMBOL_DEF_USER;
575                         switch (sym->type) {
576                         case S_STRING:
577                         case S_INT:
578                         case S_HEX:
579                                 /* Reset a string value if it's out of range */
580                                 if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
581                                         break;
582                                 sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
583                                 conf_unsaved++;
584                                 break;
585                         default:
586                                 break;
587                         }
588                 }
589         }
590 
591         if (conf_warnings || conf_unsaved)
592                 conf_set_changed(true);
593 
594         return 0;
595 }
596 
597 /*
598  * Kconfig configuration printer
599  *
600  * This printer is used when generating the resulting configuration after
601  * kconfig invocation and `defconfig' files. Unset symbol might be omitted by
602  * passing a non-NULL argument to the printer.
603  *
604  */
605 static void
606 kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
607 {
608 
609         switch (sym->type) {
610         case S_BOOLEAN:
611         case S_TRISTATE:
612                 if (*value == 'n') {
613                         bool skip_unset = (arg != NULL);
614 
615                         if (!skip_unset)
616                                 fprintf(fp, "# %s%s is not set\n",
617                                     CONFIG_, sym->name);
618                         return;
619                 }
620                 break;
621         default:
622                 break;
623         }
624 
625         fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
626 }
627 
628 static void
629 kconfig_print_comment(FILE *fp, const char *value, void *arg)
630 {
631         const char *p = value;
632         size_t l;
633 
634         for (;;) {
635                 l = strcspn(p, "\n");
636                 fprintf(fp, "#");
637                 if (l) {
638                         fprintf(fp, " ");
639                         xfwrite(p, l, 1, fp);
640                         p += l;
641                 }
642                 fprintf(fp, "\n");
643                 if (*p++ == '\0')
644                         break;
645         }
646 }
647 
648 static struct conf_printer kconfig_printer_cb =
649 {
650         .print_symbol = kconfig_print_symbol,
651         .print_comment = kconfig_print_comment,
652 };
653 
654 /*
655  * Header printer
656  *
657  * This printer is used when generating the `include/generated/autoconf.h' file.
658  */
659 static void
660 header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
661 {
662 
663         switch (sym->type) {
664         case S_BOOLEAN:
665         case S_TRISTATE: {
666                 const char *suffix = "";
667 
668                 switch (*value) {
669                 case 'n':
670                         break;
671                 case 'm':
672                         suffix = "_MODULE";
673                         /* fall through */
674                 default:
675                         fprintf(fp, "#define %s%s%s 1\n",
676                             CONFIG_, sym->name, suffix);
677                 }
678                 break;
679         }
680         case S_HEX: {
681                 const char *prefix = "";
682 
683                 if (value[0] != '' || (value[1] != 'x' && value[1] != 'X'))
684                         prefix = "0x";
685                 fprintf(fp, "#define %s%s %s%s\n",
686                     CONFIG_, sym->name, prefix, value);
687                 break;
688         }
689         case S_STRING:
690         case S_INT:
691                 fprintf(fp, "#define %s%s %s\n",
692                     CONFIG_, sym->name, value);
693                 break;
694         default:
695                 break;
696         }
697 
698 }
699 
700 static void
701 header_print_comment(FILE *fp, const char *value, void *arg)
702 {
703         const char *p = value;
704         size_t l;
705 
706         fprintf(fp, "/*\n");
707         for (;;) {
708                 l = strcspn(p, "\n");
709                 fprintf(fp, " *");
710                 if (l) {
711                         fprintf(fp, " ");
712                         xfwrite(p, l, 1, fp);
713                         p += l;
714                 }
715                 fprintf(fp, "\n");
716                 if (*p++ == '\0')
717                         break;
718         }
719         fprintf(fp, " */\n");
720 }
721 
722 static struct conf_printer header_printer_cb =
723 {
724         .print_symbol = header_print_symbol,
725         .print_comment = header_print_comment,
726 };
727 
728 static void conf_write_symbol(FILE *fp, struct symbol *sym,
729                               struct conf_printer *printer, void *printer_arg)
730 {
731         const char *str;
732 
733         switch (sym->type) {
734         case S_UNKNOWN:
735                 break;
736         case S_STRING:
737                 str = sym_get_string_value(sym);
738                 str = sym_escape_string_value(str);
739                 printer->print_symbol(fp, sym, str, printer_arg);
740                 free((void *)str);
741                 break;
742         default:
743                 str = sym_get_string_value(sym);
744                 printer->print_symbol(fp, sym, str, printer_arg);
745         }
746 }
747 
748 static void
749 conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
750 {
751         char buf[256];
752 
753         snprintf(buf, sizeof(buf),
754             "\n"
755             "Automatically generated file; DO NOT EDIT.\n"
756             "%s\n",
757             rootmenu.prompt->text);
758 
759         printer->print_comment(fp, buf, printer_arg);
760 }
761 
762 /*
763  * Write out a minimal config.
764  * All values that has default values are skipped as this is redundant.
765  */
766 int conf_write_defconfig(const char *filename)
767 {
768         struct symbol *sym;
769         struct menu *menu;
770         FILE *out;
771 
772         out = fopen(filename, "w");
773         if (!out)
774                 return 1;
775 
776         sym_clear_all_valid();
777 
778         /* Traverse all menus to find all relevant symbols */
779         menu = rootmenu.list;
780 
781         while (menu != NULL)
782         {
783                 sym = menu->sym;
784                 if (sym == NULL) {
785                         if (!menu_is_visible(menu))
786                                 goto next_menu;
787                 } else if (!sym_is_choice(sym)) {
788                         sym_calc_value(sym);
789                         if (!(sym->flags & SYMBOL_WRITE))
790                                 goto next_menu;
791                         sym->flags &= ~SYMBOL_WRITE;
792                         /* If we cannot change the symbol - skip */
793                         if (!sym_is_changeable(sym))
794                                 goto next_menu;
795                         /* If symbol equals to default value - skip */
796                         if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
797                                 goto next_menu;
798 
799                         /*
800                          * If symbol is a choice value and equals to the
801                          * default for a choice - skip.
802                          * But only if value is bool and equal to "y" and
803                          * choice is not "optional".
804                          * (If choice is "optional" then all values can be "n")
805                          */
806                         if (sym_is_choice_value(sym)) {
807                                 struct symbol *cs;
808                                 struct symbol *ds;
809 
810                                 cs = prop_get_symbol(sym_get_choice_prop(sym));
811                                 ds = sym_choice_default(cs);
812                                 if (!sym_is_optional(cs) && sym == ds) {
813                                         if ((sym->type == S_BOOLEAN) &&
814                                             sym_get_tristate_value(sym) == yes)
815                                                 goto next_menu;
816                                 }
817                         }
818                         conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
819                 }
820 next_menu:
821                 if (menu->list != NULL) {
822                         menu = menu->list;
823                 }
824                 else if (menu->next != NULL) {
825                         menu = menu->next;
826                 } else {
827                         while ((menu = menu->parent)) {
828                                 if (menu->next != NULL) {
829                                         menu = menu->next;
830                                         break;
831                                 }
832                         }
833                 }
834         }
835         fclose(out);
836         return 0;
837 }
838 
839 int conf_write(const char *name)
840 {
841         FILE *out;
842         struct symbol *sym;
843         struct menu *menu;
844         const char *str;
845         char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
846         char *env;
847         int i;
848         bool need_newline = false;
849 
850         if (!name)
851                 name = conf_get_configname();
852 
853         if (!*name) {
854                 fprintf(stderr, "config name is empty\n");
855                 return -1;
856         }
857 
858         if (is_dir(name)) {
859                 fprintf(stderr, "%s: Is a directory\n", name);
860                 return -1;
861         }
862 
863         if (make_parent_dir(name))
864                 return -1;
865 
866         env = getenv("KCONFIG_OVERWRITECONFIG");
867         if (env && *env) {
868                 *tmpname = 0;
869                 out = fopen(name, "w");
870         } else {
871                 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
872                          name, (int)getpid());
873                 out = fopen(tmpname, "w");
874         }
875         if (!out)
876                 return 1;
877 
878         conf_write_heading(out, &kconfig_printer_cb, NULL);
879 
880         if (!conf_get_changed())
881                 sym_clear_all_valid();
882 
883         menu = rootmenu.list;
884         while (menu) {
885                 sym = menu->sym;
886                 if (!sym) {
887                         if (!menu_is_visible(menu))
888                                 goto next;
889                         str = menu_get_prompt(menu);
890                         fprintf(out, "\n"
891                                      "#\n"
892                                      "# %s\n"
893                                      "#\n", str);
894                         need_newline = false;
895                 } else if (!(sym->flags & SYMBOL_CHOICE) &&
896                            !(sym->flags & SYMBOL_WRITTEN)) {
897                         sym_calc_value(sym);
898                         if (!(sym->flags & SYMBOL_WRITE))
899                                 goto next;
900                         if (need_newline) {
901                                 fprintf(out, "\n");
902                                 need_newline = false;
903                         }
904                         sym->flags |= SYMBOL_WRITTEN;
905                         conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
906                 }
907 
908 next:
909                 if (menu->list) {
910                         menu = menu->list;
911                         continue;
912                 }
913                 if (menu->next)
914                         menu = menu->next;
915                 else while ((menu = menu->parent)) {
916                         if (!menu->sym && menu_is_visible(menu) &&
917                             menu != &rootmenu) {
918                                 str = menu_get_prompt(menu);
919                                 fprintf(out, "# end of %s\n", str);
920                                 need_newline = true;
921                         }
922                         if (menu->next) {
923                                 menu = menu->next;
924                                 break;
925                         }
926                 }
927         }
928         fclose(out);
929 
930         for_all_symbols(i, sym)
931                 sym->flags &= ~SYMBOL_WRITTEN;
932 
933         if (*tmpname) {
934                 if (is_same(name, tmpname)) {
935                         conf_message("No change to %s", name);
936                         unlink(tmpname);
937                         conf_set_changed(false);
938                         return 0;
939                 }
940 
941                 snprintf(oldname, sizeof(oldname), "%s.old", name);
942                 rename(name, oldname);
943                 if (rename(tmpname, name))
944                         return 1;
945         }
946 
947         conf_message("configuration written to %s", name);
948 
949         conf_set_changed(false);
950 
951         return 0;
952 }
953 
954 /* write a dependency file as used by kbuild to track dependencies */
955 static int conf_write_dep(const char *name)
956 {
957         struct file *file;
958         FILE *out;
959 
960         out = fopen("..config.tmp", "w");
961         if (!out)
962                 return 1;
963         fprintf(out, "deps_config := \\\n");
964         for (file = file_list; file; file = file->next) {
965                 if (file->next)
966                         fprintf(out, "\t%s \\\n", file->name);
967                 else
968                         fprintf(out, "\t%s\n", file->name);
969         }
970         fprintf(out, "\n%s: \\\n"
971                      "\t$(deps_config)\n\n", conf_get_autoconfig_name());
972 
973         env_write_dep(out, conf_get_autoconfig_name());
974 
975         fprintf(out, "\n$(deps_config): ;\n");
976         fclose(out);
977 
978         if (make_parent_dir(name))
979                 return 1;
980         rename("..config.tmp", name);
981         return 0;
982 }
983 
984 static int conf_touch_deps(void)
985 {
986         const char *name;
987         struct symbol *sym;
988         int res, i;
989 
990         strcpy(depfile_path, "include/config/");
991         depfile_prefix_len = strlen(depfile_path);
992 
993         name = conf_get_autoconfig_name();
994         conf_read_simple(name, S_DEF_AUTO);
995         sym_calc_value(modules_sym);
996 
997         for_all_symbols(i, sym) {
998                 sym_calc_value(sym);
999                 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
1000                         continue;
1001                 if (sym->flags & SYMBOL_WRITE) {
1002                         if (sym->flags & SYMBOL_DEF_AUTO) {
1003                                 /*
1004                                  * symbol has old and new value,
1005                                  * so compare them...
1006                                  */
1007                                 switch (sym->type) {
1008                                 case S_BOOLEAN:
1009                                 case S_TRISTATE:
1010                                         if (sym_get_tristate_value(sym) ==
1011                                             sym->def[S_DEF_AUTO].tri)
1012                                                 continue;
1013                                         break;
1014                                 case S_STRING:
1015                                 case S_HEX:
1016                                 case S_INT:
1017                                         if (!strcmp(sym_get_string_value(sym),
1018                                                     sym->def[S_DEF_AUTO].val))
1019                                                 continue;
1020                                         break;
1021                                 default:
1022                                         break;
1023                                 }
1024                         } else {
1025                                 /*
1026                                  * If there is no old value, only 'no' (unset)
1027                                  * is allowed as new value.
1028                                  */
1029                                 switch (sym->type) {
1030                                 case S_BOOLEAN:
1031                                 case S_TRISTATE:
1032                                         if (sym_get_tristate_value(sym) == no)
1033                                                 continue;
1034                                         break;
1035                                 default:
1036                                         break;
1037                                 }
1038                         }
1039                 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
1040                         /* There is neither an old nor a new value. */
1041                         continue;
1042                 /* else
1043                  *      There is an old value, but no new value ('no' (unset)
1044                  *      isn't saved in auto.conf, so the old value is always
1045                  *      different from 'no').
1046                  */
1047 
1048                 res = conf_touch_dep(sym->name);
1049                 if (res)
1050                         return res;
1051         }
1052 
1053         return 0;
1054 }
1055 
1056 int conf_write_autoconf(int overwrite)
1057 {
1058         struct symbol *sym;
1059         const char *name;
1060         const char *autoconf_name = conf_get_autoconfig_name();
1061         FILE *out, *out_h;
1062         int i;
1063 
1064         if (!overwrite && is_present(autoconf_name))
1065                 return 0;
1066 
1067         conf_write_dep("include/config/auto.conf.cmd");
1068 
1069         if (conf_touch_deps())
1070                 return 1;
1071 
1072         out = fopen(".tmpconfig", "w");
1073         if (!out)
1074                 return 1;
1075 
1076         out_h = fopen(".tmpconfig.h", "w");
1077         if (!out_h) {
1078                 fclose(out);
1079                 return 1;
1080         }
1081 
1082         conf_write_heading(out, &kconfig_printer_cb, NULL);
1083         conf_write_heading(out_h, &header_printer_cb, NULL);
1084 
1085         for_all_symbols(i, sym) {
1086                 sym_calc_value(sym);
1087                 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
1088                         continue;
1089 
1090                 /* write symbols to auto.conf and autoconf.h */
1091                 conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
1092                 conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
1093         }
1094         fclose(out);
1095         fclose(out_h);
1096 
1097         name = getenv("KCONFIG_AUTOHEADER");
1098         if (!name)
1099                 name = "include/generated/autoconf.h";
1100         if (make_parent_dir(name))
1101                 return 1;
1102         if (rename(".tmpconfig.h", name))
1103                 return 1;
1104 
1105         if (make_parent_dir(autoconf_name))
1106                 return 1;
1107         /*
1108          * This must be the last step, kbuild has a dependency on auto.conf
1109          * and this marks the successful completion of the previous steps.
1110          */
1111         if (rename(".tmpconfig", autoconf_name))
1112                 return 1;
1113 
1114         return 0;
1115 }
1116 
1117 static bool conf_changed;
1118 static void (*conf_changed_callback)(void);
1119 
1120 void conf_set_changed(bool val)
1121 {
1122         if (conf_changed_callback && conf_changed != val)
1123                 conf_changed_callback();
1124 
1125         conf_changed = val;
1126 }
1127 
1128 bool conf_get_changed(void)
1129 {
1130         return conf_changed;
1131 }
1132 
1133 void conf_set_changed_callback(void (*fn)(void))
1134 {
1135         conf_changed_callback = fn;
1136 }
1137 
1138 void set_all_choice_values(struct symbol *csym)
1139 {
1140         struct property *prop;
1141         struct symbol *sym;
1142         struct expr *e;
1143 
1144         prop = sym_get_choice_prop(csym);
1145 
1146         /*
1147          * Set all non-assinged choice values to no
1148          */
1149         expr_list_for_each_sym(prop->expr, e, sym) {
1150                 if (!sym_has_value(sym))
1151                         sym->def[S_DEF_USER].tri = no;
1152         }
1153         csym->flags |= SYMBOL_DEF_USER;
1154         /* clear VALID to get value calculated */
1155         csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
1156 }
1157 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp