diff options
Diffstat (limited to 'scripts/kconfig/confdata.c')
-rw-r--r-- | scripts/kconfig/confdata.c | 157 |
1 files changed, 97 insertions, 60 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 08ba146a83c5..501fdcc5e999 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | 3 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <sys/mman.h> | ||
6 | #include <sys/stat.h> | 7 | #include <sys/stat.h> |
7 | #include <ctype.h> | 8 | #include <ctype.h> |
8 | #include <errno.h> | 9 | #include <errno.h> |
@@ -36,6 +37,52 @@ static bool is_dir(const char *path) | |||
36 | return S_ISDIR(st.st_mode); | 37 | return S_ISDIR(st.st_mode); |
37 | } | 38 | } |
38 | 39 | ||
40 | /* return true if the given two files are the same, false otherwise */ | ||
41 | static bool is_same(const char *file1, const char *file2) | ||
42 | { | ||
43 | int fd1, fd2; | ||
44 | struct stat st1, st2; | ||
45 | void *map1, *map2; | ||
46 | bool ret = false; | ||
47 | |||
48 | fd1 = open(file1, O_RDONLY); | ||
49 | if (fd1 < 0) | ||
50 | return ret; | ||
51 | |||
52 | fd2 = open(file2, O_RDONLY); | ||
53 | if (fd2 < 0) | ||
54 | goto close1; | ||
55 | |||
56 | ret = fstat(fd1, &st1); | ||
57 | if (ret) | ||
58 | goto close2; | ||
59 | ret = fstat(fd2, &st2); | ||
60 | if (ret) | ||
61 | goto close2; | ||
62 | |||
63 | if (st1.st_size != st2.st_size) | ||
64 | goto close2; | ||
65 | |||
66 | map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); | ||
67 | if (map1 == MAP_FAILED) | ||
68 | goto close2; | ||
69 | |||
70 | map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); | ||
71 | if (map2 == MAP_FAILED) | ||
72 | goto close2; | ||
73 | |||
74 | if (bcmp(map1, map2, st1.st_size)) | ||
75 | goto close2; | ||
76 | |||
77 | ret = true; | ||
78 | close2: | ||
79 | close(fd2); | ||
80 | close1: | ||
81 | close(fd1); | ||
82 | |||
83 | return ret; | ||
84 | } | ||
85 | |||
39 | /* | 86 | /* |
40 | * Create the parent directory of the given path. | 87 | * Create the parent directory of the given path. |
41 | * | 88 | * |
@@ -130,8 +177,6 @@ static void conf_message(const char *fmt, ...) | |||
130 | static const char *conf_filename; | 177 | static const char *conf_filename; |
131 | static int conf_lineno, conf_warnings; | 178 | static int conf_lineno, conf_warnings; |
132 | 179 | ||
133 | const char conf_defname[] = "arch/$(ARCH)/defconfig"; | ||
134 | |||
135 | static void conf_warning(const char *fmt, ...) | 180 | static void conf_warning(const char *fmt, ...) |
136 | { | 181 | { |
137 | va_list ap; | 182 | va_list ap; |
@@ -179,28 +224,13 @@ const char *conf_get_configname(void) | |||
179 | return name ? name : ".config"; | 224 | return name ? name : ".config"; |
180 | } | 225 | } |
181 | 226 | ||
182 | const char *conf_get_autoconfig_name(void) | 227 | static const char *conf_get_autoconfig_name(void) |
183 | { | 228 | { |
184 | char *name = getenv("KCONFIG_AUTOCONFIG"); | 229 | char *name = getenv("KCONFIG_AUTOCONFIG"); |
185 | 230 | ||
186 | return name ? name : "include/config/auto.conf"; | 231 | return name ? name : "include/config/auto.conf"; |
187 | } | 232 | } |
188 | 233 | ||
189 | char *conf_get_default_confname(void) | ||
190 | { | ||
191 | static char fullname[PATH_MAX+1]; | ||
192 | char *env, *name; | ||
193 | |||
194 | name = expand_string(conf_defname); | ||
195 | env = getenv(SRCTREE); | ||
196 | if (env) { | ||
197 | sprintf(fullname, "%s/%s", env, name); | ||
198 | if (is_present(fullname)) | ||
199 | return fullname; | ||
200 | } | ||
201 | return name; | ||
202 | } | ||
203 | |||
204 | static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | 234 | static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) |
205 | { | 235 | { |
206 | char *p2; | 236 | char *p2; |
@@ -504,11 +534,9 @@ int conf_read(const char *name) | |||
504 | switch (sym->type) { | 534 | switch (sym->type) { |
505 | case S_BOOLEAN: | 535 | case S_BOOLEAN: |
506 | case S_TRISTATE: | 536 | case S_TRISTATE: |
507 | if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) | 537 | if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) |
508 | break; | ||
509 | if (!sym_is_choice(sym)) | ||
510 | continue; | 538 | continue; |
511 | /* fall through */ | 539 | break; |
512 | default: | 540 | default: |
513 | if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) | 541 | if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) |
514 | continue; | 542 | continue; |
@@ -766,7 +794,7 @@ int conf_write_defconfig(const char *filename) | |||
766 | goto next_menu; | 794 | goto next_menu; |
767 | sym->flags &= ~SYMBOL_WRITE; | 795 | sym->flags &= ~SYMBOL_WRITE; |
768 | /* If we cannot change the symbol - skip */ | 796 | /* If we cannot change the symbol - skip */ |
769 | if (!sym_is_changable(sym)) | 797 | if (!sym_is_changeable(sym)) |
770 | goto next_menu; | 798 | goto next_menu; |
771 | /* If symbol equals to default value - skip */ | 799 | /* If symbol equals to default value - skip */ |
772 | if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) | 800 | if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) |
@@ -817,40 +845,35 @@ int conf_write(const char *name) | |||
817 | FILE *out; | 845 | FILE *out; |
818 | struct symbol *sym; | 846 | struct symbol *sym; |
819 | struct menu *menu; | 847 | struct menu *menu; |
820 | const char *basename; | ||
821 | const char *str; | 848 | const char *str; |
822 | char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; | 849 | char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; |
823 | char *env; | 850 | char *env; |
851 | bool need_newline = false; | ||
852 | |||
853 | if (!name) | ||
854 | name = conf_get_configname(); | ||
855 | |||
856 | if (!*name) { | ||
857 | fprintf(stderr, "config name is empty\n"); | ||
858 | return -1; | ||
859 | } | ||
860 | |||
861 | if (is_dir(name)) { | ||
862 | fprintf(stderr, "%s: Is a directory\n", name); | ||
863 | return -1; | ||
864 | } | ||
865 | |||
866 | if (make_parent_dir(name)) | ||
867 | return -1; | ||
824 | 868 | ||
825 | dirname[0] = 0; | ||
826 | if (name && name[0]) { | ||
827 | char *slash; | ||
828 | |||
829 | if (is_dir(name)) { | ||
830 | strcpy(dirname, name); | ||
831 | strcat(dirname, "/"); | ||
832 | basename = conf_get_configname(); | ||
833 | } else if ((slash = strrchr(name, '/'))) { | ||
834 | int size = slash - name + 1; | ||
835 | memcpy(dirname, name, size); | ||
836 | dirname[size] = 0; | ||
837 | if (slash[1]) | ||
838 | basename = slash + 1; | ||
839 | else | ||
840 | basename = conf_get_configname(); | ||
841 | } else | ||
842 | basename = name; | ||
843 | } else | ||
844 | basename = conf_get_configname(); | ||
845 | |||
846 | sprintf(newname, "%s%s", dirname, basename); | ||
847 | env = getenv("KCONFIG_OVERWRITECONFIG"); | 869 | env = getenv("KCONFIG_OVERWRITECONFIG"); |
848 | if (!env || !*env) { | 870 | if (env && *env) { |
849 | sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); | ||
850 | out = fopen(tmpname, "w"); | ||
851 | } else { | ||
852 | *tmpname = 0; | 871 | *tmpname = 0; |
853 | out = fopen(newname, "w"); | 872 | out = fopen(name, "w"); |
873 | } else { | ||
874 | snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", | ||
875 | name, (int)getpid()); | ||
876 | out = fopen(tmpname, "w"); | ||
854 | } | 877 | } |
855 | if (!out) | 878 | if (!out) |
856 | return 1; | 879 | return 1; |
@@ -871,12 +894,16 @@ int conf_write(const char *name) | |||
871 | "#\n" | 894 | "#\n" |
872 | "# %s\n" | 895 | "# %s\n" |
873 | "#\n", str); | 896 | "#\n", str); |
897 | need_newline = false; | ||
874 | } else if (!(sym->flags & SYMBOL_CHOICE)) { | 898 | } else if (!(sym->flags & SYMBOL_CHOICE)) { |
875 | sym_calc_value(sym); | 899 | sym_calc_value(sym); |
876 | if (!(sym->flags & SYMBOL_WRITE)) | 900 | if (!(sym->flags & SYMBOL_WRITE)) |
877 | goto next; | 901 | goto next; |
902 | if (need_newline) { | ||
903 | fprintf(out, "\n"); | ||
904 | need_newline = false; | ||
905 | } | ||
878 | sym->flags &= ~SYMBOL_WRITE; | 906 | sym->flags &= ~SYMBOL_WRITE; |
879 | |||
880 | conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); | 907 | conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); |
881 | } | 908 | } |
882 | 909 | ||
@@ -888,6 +915,12 @@ next: | |||
888 | if (menu->next) | 915 | if (menu->next) |
889 | menu = menu->next; | 916 | menu = menu->next; |
890 | else while ((menu = menu->parent)) { | 917 | else while ((menu = menu->parent)) { |
918 | if (!menu->sym && menu_is_visible(menu) && | ||
919 | menu != &rootmenu) { | ||
920 | str = menu_get_prompt(menu); | ||
921 | fprintf(out, "# end of %s\n", str); | ||
922 | need_newline = true; | ||
923 | } | ||
891 | if (menu->next) { | 924 | if (menu->next) { |
892 | menu = menu->next; | 925 | menu = menu->next; |
893 | break; | 926 | break; |
@@ -897,14 +930,20 @@ next: | |||
897 | fclose(out); | 930 | fclose(out); |
898 | 931 | ||
899 | if (*tmpname) { | 932 | if (*tmpname) { |
900 | strcat(dirname, basename); | 933 | if (is_same(name, tmpname)) { |
901 | strcat(dirname, ".old"); | 934 | conf_message("No change to %s", name); |
902 | rename(newname, dirname); | 935 | unlink(tmpname); |
903 | if (rename(tmpname, newname)) | 936 | sym_set_change_count(0); |
937 | return 0; | ||
938 | } | ||
939 | |||
940 | snprintf(oldname, sizeof(oldname), "%s.old", name); | ||
941 | rename(name, oldname); | ||
942 | if (rename(tmpname, name)) | ||
904 | return 1; | 943 | return 1; |
905 | } | 944 | } |
906 | 945 | ||
907 | conf_message("configuration written to %s", newname); | 946 | conf_message("configuration written to %s", name); |
908 | 947 | ||
909 | sym_set_change_count(0); | 948 | sym_set_change_count(0); |
910 | 949 | ||
@@ -917,8 +956,6 @@ static int conf_write_dep(const char *name) | |||
917 | struct file *file; | 956 | struct file *file; |
918 | FILE *out; | 957 | FILE *out; |
919 | 958 | ||
920 | if (!name) | ||
921 | name = ".kconfig.d"; | ||
922 | out = fopen("..config.tmp", "w"); | 959 | out = fopen("..config.tmp", "w"); |
923 | if (!out) | 960 | if (!out) |
924 | return 1; | 961 | return 1; |