base/config/kconfig/confdata.c

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 00003 * Released under the terms of the GNU GPL v2.0. 00004 */ 00005 00006 #include <sys/stat.h> 00007 #include <ctype.h> 00008 #include <stdio.h> 00009 #include <stdlib.h> 00010 #include <string.h> 00011 #include <unistd.h> 00012 00013 #define LKC_DIRECT_LINK 00014 #include "lkc.h" 00015 00016 const char conf_def_filename[] = "../../../.rtai_config"; 00017 00018 const char conf_defname[] = "base/arch/$ARCH/defconfig"; 00019 00020 const char *conf_confnames[] = { 00021 "../../../.rtai_config", 00022 "/lib/modules/$UNAME_RELEASE/.rtai_config", 00023 "/etc/rtai-config", 00024 conf_defname, 00025 NULL 00026 }; 00027 00028 static char *conf_expand_value(const char *in) 00029 { 00030 struct symbol *sym; 00031 const char *src; 00032 static char res_value[SYMBOL_MAXLENGTH]; 00033 char *dst, name[SYMBOL_MAXLENGTH]; 00034 00035 res_value[0] = 0; 00036 dst = name; 00037 while ((src = strchr(in, '$'))) { 00038 strncat(res_value, in, src - in); 00039 src++; 00040 dst = name; 00041 while (isalnum(*src) || *src == '_') 00042 *dst++ = *src++; 00043 *dst = 0; 00044 sym = sym_lookup(name, 0); 00045 sym_calc_value(sym); 00046 strcat(res_value, sym_get_string_value(sym)); 00047 in = src; 00048 } 00049 strcat(res_value, in); 00050 00051 return res_value; 00052 } 00053 00054 char *conf_get_default_confname(void) 00055 { 00056 struct stat buf; 00057 static char fullname[PATH_MAX+1]; 00058 char *env, *name; 00059 00060 name = conf_expand_value(conf_defname); 00061 env = getenv(SRCTREE); 00062 if (env) { 00063 sprintf(fullname, "%s/%s", env, name); 00064 if (!stat(fullname, &buf)) 00065 return fullname; 00066 } 00067 return name; 00068 } 00069 00070 int conf_read(const char *name) 00071 { 00072 FILE *in = NULL; 00073 char line[1024]; 00074 char *p, *p2; 00075 int lineno = 0; 00076 struct symbol *sym; 00077 struct property *prop; 00078 struct expr *e; 00079 int i; 00080 00081 if (name) { 00082 in = zconf_fopen(name); 00083 } else { 00084 const char **names = conf_confnames; 00085 while ((name = *names++)) { 00086 name = conf_expand_value(name); 00087 in = zconf_fopen(name); 00088 if (in) { 00089 printf("#\n" 00090 "# using defaults found in %s\n" 00091 "#\n", name); 00092 break; 00093 } 00094 } 00095 } 00096 00097 if (!in) 00098 return 1; 00099 00100 for_all_symbols(i, sym) { 00101 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; 00102 sym->flags &= ~SYMBOL_VALID; 00103 switch (sym->type) { 00104 case S_INT: 00105 case S_HEX: 00106 case S_STRING: 00107 if (sym->user.val) 00108 free(sym->user.val); 00109 default: 00110 sym->user.val = NULL; 00111 sym->user.tri = no; 00112 } 00113 } 00114 00115 while (fgets(line, sizeof(line), in)) { 00116 lineno++; 00117 sym = NULL; 00118 switch (line[0]) { 00119 case '#': 00120 if (memcmp(line + 2, "CONFIG_", 7)) 00121 continue; 00122 p = strchr(line + 9, ' '); 00123 if (!p) 00124 continue; 00125 *p++ = 0; 00126 if (strncmp(p, "is not set", 10)) 00127 continue; 00128 sym = sym_find(line + 9); 00129 if (!sym) { 00130 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9); 00131 break; 00132 } 00133 switch (sym->type) { 00134 case S_BOOLEAN: 00135 case S_TRISTATE: 00136 sym->user.tri = no; 00137 sym->flags &= ~SYMBOL_NEW; 00138 break; 00139 default: 00140 ; 00141 } 00142 break; 00143 case 'C': 00144 if (memcmp(line, "CONFIG_", 7)) 00145 continue; 00146 p = strchr(line + 7, '='); 00147 if (!p) 00148 continue; 00149 *p++ = 0; 00150 p2 = strchr(p, '\n'); 00151 if (p2) 00152 *p2 = 0; 00153 sym = sym_find(line + 7); 00154 if (!sym) { 00155 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); 00156 break; 00157 } 00158 switch (sym->type) { 00159 case S_TRISTATE: 00160 if (p[0] == 'm') { 00161 sym->user.tri = mod; 00162 sym->flags &= ~SYMBOL_NEW; 00163 break; 00164 } 00165 case S_BOOLEAN: 00166 if (p[0] == 'y') { 00167 sym->user.tri = yes; 00168 sym->flags &= ~SYMBOL_NEW; 00169 break; 00170 } 00171 if (p[0] == 'n') { 00172 sym->user.tri = no; 00173 sym->flags &= ~SYMBOL_NEW; 00174 break; 00175 } 00176 break; 00177 case S_STRING: 00178 if (*p++ != '"') 00179 break; 00180 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 00181 if (*p2 == '"') { 00182 *p2 = 0; 00183 break; 00184 } 00185 memmove(p2, p2 + 1, strlen(p2)); 00186 } 00187 if (!p2) { 00188 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); 00189 exit(1); 00190 } 00191 case S_INT: 00192 case S_HEX: 00193 if (sym_string_valid(sym, p)) { 00194 sym->user.val = strdup(p); 00195 sym->flags &= ~SYMBOL_NEW; 00196 } else { 00197 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); 00198 exit(1); 00199 } 00200 break; 00201 default: 00202 ; 00203 } 00204 break; 00205 case '\n': 00206 break; 00207 default: 00208 continue; 00209 } 00210 if (sym && sym_is_choice_value(sym)) { 00211 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 00212 switch (sym->user.tri) { 00213 case no: 00214 break; 00215 case mod: 00216 if (cs->user.tri == yes) 00217 /* warn? */; 00218 break; 00219 case yes: 00220 if (cs->user.tri != no) 00221 /* warn? */; 00222 cs->user.val = sym; 00223 break; 00224 } 00225 cs->user.tri = E_OR(cs->user.tri, sym->user.tri); 00226 cs->flags &= ~SYMBOL_NEW; 00227 } 00228 } 00229 fclose(in); 00230 00231 for_all_symbols(i, sym) { 00232 sym_calc_value(sym); 00233 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 00234 if (sym->visible == no) 00235 sym->flags |= SYMBOL_NEW; 00236 switch (sym->type) { 00237 case S_STRING: 00238 case S_INT: 00239 case S_HEX: 00240 if (!sym_string_within_range(sym, sym->user.val)) 00241 sym->flags |= SYMBOL_NEW; 00242 default: 00243 break; 00244 } 00245 } 00246 if (!sym_is_choice(sym)) 00247 continue; 00248 prop = sym_get_choice_prop(sym); 00249 for (e = prop->expr; e; e = e->left.expr) 00250 if (e->right.sym->visible != no) 00251 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 00252 } 00253 00254 sym_change_count = 1; 00255 00256 return 0; 00257 } 00258 00259 int conf_write(const char *name) 00260 { 00261 FILE *out; 00262 struct symbol *sym; 00263 struct menu *menu; 00264 const char *basename; 00265 char dirname[128], tmpname[128], newname[128]; 00266 int type, l; 00267 const char *str; 00268 00269 dirname[0] = 0; 00270 if (name && name[0]) { 00271 char *slash = strrchr(name, '/'); 00272 if (slash) { 00273 int size = slash - name + 1; 00274 memcpy(dirname, name, size); 00275 dirname[size] = 0; 00276 if (slash[1]) 00277 basename = slash + 1; 00278 else 00279 basename = conf_def_filename; 00280 } else 00281 basename = name; 00282 } else 00283 basename = conf_def_filename; 00284 00285 sprintf(newname, "%s.tmpconfig.%d", dirname, getpid()); 00286 out = fopen(newname, "w"); 00287 if (!out) 00288 return 1; 00289 fprintf(out, "#\n" 00290 "# Automatically generated make config: don't edit\n" 00291 "#\n"); 00292 if (!sym_change_count) 00293 sym_clear_all_valid(); 00294 00295 menu = rootmenu.list; 00296 while (menu) { 00297 sym = menu->sym; 00298 if (!sym) { 00299 if (!menu_is_visible(menu)) 00300 goto next; 00301 str = menu_get_prompt(menu); 00302 fprintf(out, "\n" 00303 "#\n" 00304 "# %s\n" 00305 "#\n", str); 00306 } else if (!(sym->flags & SYMBOL_CHOICE)) { 00307 sym_calc_value(sym); 00308 if (!(sym->flags & SYMBOL_WRITE)) 00309 goto next; 00310 sym->flags &= ~SYMBOL_WRITE; 00311 type = sym->type; 00312 if (type == S_TRISTATE) { 00313 sym_calc_value(modules_sym); 00314 if (modules_sym->curr.tri == no) 00315 type = S_BOOLEAN; 00316 } 00317 switch (type) { 00318 case S_BOOLEAN: 00319 case S_TRISTATE: 00320 switch (sym_get_tristate_value(sym)) { 00321 case no: 00322 fprintf(out, "# CONFIG_%s is not set\n", sym->name); 00323 break; 00324 case mod: 00325 fprintf(out, "CONFIG_%s=m\n", sym->name); 00326 break; 00327 case yes: 00328 fprintf(out, "CONFIG_%s=y\n", sym->name); 00329 break; 00330 } 00331 break; 00332 case S_STRING: 00333 // fix me 00334 str = sym_get_string_value(sym); 00335 fprintf(out, "CONFIG_%s=\"", sym->name); 00336 do { 00337 l = strcspn(str, "\"\\"); 00338 if (l) { 00339 fwrite(str, l, 1, out); 00340 } 00341 str += l; 00342 while (*str == '\\' || *str == '"') { 00343 fprintf(out, "\\%c", *str); 00344 str++; 00345 } 00346 } while (*str); 00347 fputs("\"\n", out); 00348 break; 00349 case S_HEX: 00350 str = sym_get_string_value(sym); 00351 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 00352 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 00353 break; 00354 } 00355 case S_INT: 00356 str = sym_get_string_value(sym); 00357 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 00358 break; 00359 } 00360 } 00361 00362 next: 00363 if (menu->list) { 00364 menu = menu->list; 00365 continue; 00366 } 00367 if (menu->next) 00368 menu = menu->next; 00369 else while ((menu = menu->parent)) { 00370 if (menu->next) { 00371 menu = menu->next; 00372 break; 00373 } 00374 } 00375 } 00376 fclose(out); 00377 00378 if (!name || basename != conf_def_filename) { 00379 if (!name) 00380 name = conf_def_filename; 00381 sprintf(tmpname, "%s.old", name); 00382 rename(name, tmpname); 00383 } 00384 sprintf(tmpname, "%s%s", dirname, basename); 00385 if (rename(newname, tmpname)) 00386 return 1; 00387 00388 sym_change_count = 0; 00389 00390 return 0; 00391 }

Generated on Thu Nov 20 11:49:47 2008 for RTAI API by doxygen 1.3.8