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 Tue Feb 2 17:46:04 2010 for RTAI API by  doxygen 1.4.7