OSDN Git Service

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