linux-bk/scripts/kconfig/confdata.c
<<
>>
Prefs
   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 <stdio.h>
   9#include <stdlib.h>
  10#include <string.h>
  11#include <time.h>
  12#include <unistd.h>
  13
  14#define LKC_DIRECT_LINK
  15#include "lkc.h"
  16
  17const char conf_def_filename[] = ".config";
  18
  19const char conf_defname[] = "arch/$ARCH/defconfig";
  20
  21const char *conf_confnames[] = {
  22        ".config",
  23        "/lib/modules/$UNAME_RELEASE/.config",
  24        "/etc/kernel-config",
  25        "/boot/config-$UNAME_RELEASE",
  26        conf_defname,
  27        NULL,
  28};
  29
  30static char *conf_expand_value(const signed char *in)
  31{
  32        struct symbol *sym;
  33        const signed char *src;
  34        static char res_value[SYMBOL_MAXLENGTH];
  35        char *dst, name[SYMBOL_MAXLENGTH];
  36
  37        res_value[0] = 0;
  38        dst = name;
  39        while ((src = strchr(in, '$'))) {
  40                strncat(res_value, in, src - in);
  41                src++;
  42                dst = name;
  43                while (isalnum(*src) || *src == '_')
  44                        *dst++ = *src++;
  45                *dst = 0;
  46                sym = sym_lookup(name, 0);
  47                sym_calc_value(sym);
  48                strcat(res_value, sym_get_string_value(sym));
  49                in = src;
  50        }
  51        strcat(res_value, in);
  52
  53        return res_value;
  54}
  55
  56char *conf_get_default_confname(void)
  57{
  58        struct stat buf;
  59        static char fullname[PATH_MAX+1];
  60        char *env, *name;
  61
  62        name = conf_expand_value(conf_defname);
  63        env = getenv(SRCTREE);
  64        if (env) {
  65                sprintf(fullname, "%s/%s", env, name);
  66                if (!stat(fullname, &buf))
  67                        return fullname;
  68        }
  69        return name;
  70}
  71
  72int conf_read(const char *name)
  73{
  74        FILE *in = NULL;
  75        char line[1024];
  76        char *p, *p2;
  77        int lineno = 0;
  78        struct symbol *sym;
  79        struct property *prop;
  80        struct expr *e;
  81        int i;
  82
  83        if (name) {
  84                in = zconf_fopen(name);
  85        } else {
  86                const char **names = conf_confnames;
  87                while ((name = *names++)) {
  88                        name = conf_expand_value(name);
  89                        in = zconf_fopen(name);
  90                        if (in) {
  91                                printf("#\n"
  92                                       "# using defaults found in %s\n"
  93                                       "#\n", name);
  94                                break;
  95                        }
  96                }
  97        }
  98
  99        if (!in)
 100                return 1;
 101
 102        for_all_symbols(i, sym) {
 103                sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
 104                sym->flags &= ~SYMBOL_VALID;
 105                switch (sym->type) {
 106                case S_INT:
 107                case S_HEX:
 108                case S_STRING:
 109                        if (sym->user.val)
 110                                free(sym->user.val);
 111                default:
 112                        sym->user.val = NULL;
 113                        sym->user.tri = no;
 114                }
 115        }
 116
 117        while (fgets(line, sizeof(line), in)) {
 118                lineno++;
 119                sym = NULL;
 120                switch (line[0]) {
 121                case '#':
 122                        if (memcmp(line + 2, "CONFIG_", 7))
 123                                continue;
 124                        p = strchr(line + 9, ' ');
 125                        if (!p)
 126                                continue;
 127                        *p++ = 0;
 128                        if (strncmp(p, "is not set", 10))
 129                                continue;
 130                        sym = sym_find(line + 9);
 131                        if (!sym) {
 132                                fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
 133                                break;
 134                        }
 135                        switch (sym->type) {
 136                        case S_BOOLEAN:
 137                        case S_TRISTATE:
 138                                sym->user.tri = no;
 139                                sym->flags &= ~SYMBOL_NEW;
 140                                break;
 141                        default:
 142                                ;
 143                        }
 144                        break;
 145                case 'C':
 146                        if (memcmp(line, "CONFIG_", 7))
 147                                continue;
 148                        p = strchr(line + 7, '=');
 149                        if (!p)
 150                                continue;
 151                        *p++ = 0;
 152                        p2 = strchr(p, '\n');
 153                        if (p2)
 154                                *p2 = 0;
 155                        sym = sym_find(line + 7);
 156                        if (!sym) {
 157                                fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
 158                                break;
 159                        }
 160                        switch (sym->type) {
 161                        case S_TRISTATE:
 162                                if (p[0] == 'm') {
 163                                        sym->user.tri = mod;
 164                                        sym->flags &= ~SYMBOL_NEW;
 165                                        break;
 166                                }
 167                        case S_BOOLEAN:
 168                                if (p[0] == 'y') {
 169                                        sym->user.tri = yes;
 170                                        sym->flags &= ~SYMBOL_NEW;
 171                                        break;
 172                                }
 173                                if (p[0] == 'n') {
 174                                        sym->user.tri = no;
 175                                        sym->flags &= ~SYMBOL_NEW;
 176                                        break;
 177                                }
 178                                break;
 179                        case S_STRING:
 180                                if (*p++ != '"')
 181                                        break;
 182                                for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
 183                                        if (*p2 == '"') {
 184                                                *p2 = 0;
 185                                                break;
 186                                        }
 187                                        memmove(p2, p2 + 1, strlen(p2));
 188                                }
 189                                if (!p2) {
 190                                        fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
 191                                        exit(1);
 192                                }
 193                        case S_INT:
 194                        case S_HEX:
 195                                if (sym_string_valid(sym, p)) {
 196                                        sym->user.val = strdup(p);
 197                                        sym->flags &= ~SYMBOL_NEW;
 198                                } else {
 199                                        fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
 200                                        exit(1);
 201                                }
 202                                break;
 203                        default:
 204                                ;
 205                        }
 206                        break;
 207                case '\n':
 208                        break;
 209                default:
 210                        continue;
 211                }
 212                if (sym && sym_is_choice_value(sym)) {
 213                        struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
 214                        switch (sym->user.tri) {
 215                        case no:
 216                                break;
 217                        case mod:
 218                                if (cs->user.tri == yes)
 219                                        /* warn? */;
 220                                break;
 221                        case yes:
 222                                if (cs->user.tri != no)
 223                                        /* warn? */;
 224                                cs->user.val = sym;
 225                                break;
 226                        }
 227                        cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
 228                        cs->flags &= ~SYMBOL_NEW;
 229                }
 230        }
 231        fclose(in);
 232
 233        if (modules_sym)
 234                sym_calc_value(modules_sym);
 235        for_all_symbols(i, sym) {
 236                sym_calc_value(sym);
 237                if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
 238                        if (sym->visible == no)
 239                                sym->flags |= SYMBOL_NEW;
 240                        switch (sym->type) {
 241                        case S_STRING:
 242                        case S_INT:
 243                        case S_HEX:
 244                                if (!sym_string_within_range(sym, sym->user.val))
 245                                        sym->flags |= SYMBOL_NEW;
 246                        default:
 247                                break;
 248                        }
 249                }
 250                if (!sym_is_choice(sym))
 251                        continue;
 252                prop = sym_get_choice_prop(sym);
 253                for (e = prop->expr; e; e = e->left.expr)
 254                        if (e->right.sym->visible != no)
 255                                sym->flags |= e->right.sym->flags & SYMBOL_NEW;
 256        }
 257
 258        sym_change_count = 1;
 259
 260        return 0;
 261}
 262
 263int conf_write(const char *name)
 264{
 265        FILE *out, *out_h;
 266        struct symbol *sym;
 267        struct menu *menu;
 268        const char *basename;
 269        char dirname[128], tmpname[128], newname[128];
 270        int type, l;
 271        const char *str;
 272        time_t now;
 273        int use_timestamp = 1;
 274        char *env;
 275
 276        dirname[0] = 0;
 277        if (name && name[0]) {
 278                struct stat st;
 279                char *slash;
 280
 281                if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
 282                        strcpy(dirname, name);
 283                        strcat(dirname, "/");
 284                        basename = conf_def_filename;
 285                } else if ((slash = strrchr(name, '/'))) {
 286                        int size = slash - name + 1;
 287                        memcpy(dirname, name, size);
 288                        dirname[size] = 0;
 289                        if (slash[1])
 290                                basename = slash + 1;
 291                        else
 292                                basename = conf_def_filename;
 293                } else
 294                        basename = name;
 295        } else
 296                basename = conf_def_filename;
 297
 298        sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
 299        out = fopen(newname, "w");
 300        if (!out)
 301                return 1;
 302        out_h = NULL;
 303        if (!name) {
 304                out_h = fopen(".tmpconfig.h", "w");
 305                if (!out_h)
 306                        return 1;
 307        }
 308        sym = sym_lookup("KERNELRELEASE", 0);
 309        sym_calc_value(sym);
 310        time(&now);
 311        env = getenv("KCONFIG_NOTIMESTAMP");
 312        if (env && *env)
 313                use_timestamp = 0;
 314
 315        fprintf(out, "#\n"
 316                     "# Automatically generated make config: don't edit\n"
 317                     "# Linux kernel version: %s\n"
 318                     "%s%s"
 319                     "#\n",
 320                     sym_get_string_value(sym),
 321                     use_timestamp ? "# " : "",
 322                     use_timestamp ? ctime(&now) : "");
 323        if (out_h)
 324                fprintf(out_h, "/*\n"
 325                               " * Automatically generated C config: don't edit\n"
 326                               " * Linux kernel version: %s\n"
 327                               "%s%s"
 328                               " */\n"
 329                               "#define AUTOCONF_INCLUDED\n",
 330                               sym_get_string_value(sym),
 331                               use_timestamp ? " * " : "",
 332                               use_timestamp ? ctime(&now) : "");
 333
 334        if (!sym_change_count)
 335                sym_clear_all_valid();
 336
 337        menu = rootmenu.list;
 338        while (menu) {
 339                sym = menu->sym;
 340                if (!sym) {
 341                        if (!menu_is_visible(menu))
 342                                goto next;
 343                        str = menu_get_prompt(menu);
 344                        fprintf(out, "\n"
 345                                     "#\n"
 346                                     "# %s\n"
 347                                     "#\n", str);
 348                        if (out_h)
 349                                fprintf(out_h, "\n"
 350                                               "/*\n"
 351                                               " * %s\n"
 352                                               " */\n", str);
 353                } else if (!(sym->flags & SYMBOL_CHOICE)) {
 354                        sym_calc_value(sym);
 355                        if (!(sym->flags & SYMBOL_WRITE))
 356                                goto next;
 357                        sym->flags &= ~SYMBOL_WRITE;
 358                        type = sym->type;
 359                        if (type == S_TRISTATE) {
 360                                sym_calc_value(modules_sym);
 361                                if (modules_sym->curr.tri == no)
 362                                        type = S_BOOLEAN;
 363                        }
 364                        switch (type) {
 365                        case S_BOOLEAN:
 366                        case S_TRISTATE:
 367                                switch (sym_get_tristate_value(sym)) {
 368                                case no:
 369                                        fprintf(out, "# CONFIG_%s is not set\n", sym->name);
 370                                        if (out_h)
 371                                                fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
 372                                        break;
 373                                case mod:
 374                                        fprintf(out, "CONFIG_%s=m\n", sym->name);
 375                                        if (out_h)
 376                                                fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
 377                                        break;
 378                                case yes:
 379                                        fprintf(out, "CONFIG_%s=y\n", sym->name);
 380                                        if (out_h)
 381                                                fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
 382                                        break;
 383                                }
 384                                break;
 385                        case S_STRING:
 386                                // fix me
 387                                str = sym_get_string_value(sym);
 388                                fprintf(out, "CONFIG_%s=\"", sym->name);
 389                                if (out_h)
 390                                        fprintf(out_h, "#define CONFIG_%s \"", sym->name);
 391                                do {
 392                                        l = strcspn(str, "\"\\");
 393                                        if (l) {
 394                                                fwrite(str, l, 1, out);
 395                                                if (out_h)
 396                                                        fwrite(str, l, 1, out_h);
 397                                        }
 398                                        str += l;
 399                                        while (*str == '\\' || *str == '"') {
 400                                                fprintf(out, "\\%c", *str);
 401                                                if (out_h)
 402                                                        fprintf(out_h, "\\%c", *str);
 403                                                str++;
 404                                        }
 405                                } while (*str);
 406                                fputs("\"\n", out);
 407                                if (out_h)
 408                                        fputs("\"\n", out_h);
 409                                break;
 410                        case S_HEX:
 411                                str = sym_get_string_value(sym);
 412                                if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
 413                                        fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
 414                                        if (out_h)
 415                                                fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
 416                                        break;
 417                                }
 418                        case S_INT:
 419                                str = sym_get_string_value(sym);
 420                                fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
 421                                if (out_h)
 422                                        fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
 423                                break;
 424                        }
 425                }
 426
 427        next:
 428                if (menu->list) {
 429                        menu = menu->list;
 430                        continue;
 431                }
 432                if (menu->next)
 433                        menu = menu->next;
 434                else while ((menu = menu->parent)) {
 435                        if (menu->next) {
 436                                menu = menu->next;
 437                                break;
 438                        }
 439                }
 440        }
 441        fclose(out);
 442        if (out_h) {
 443                fclose(out_h);
 444                rename(".tmpconfig.h", "include/linux/autoconf.h");
 445                file_write_dep(NULL);
 446        }
 447        if (!name || basename != conf_def_filename) {
 448                if (!name)
 449                        name = conf_def_filename;
 450                sprintf(tmpname, "%s.old", name);
 451                rename(name, tmpname);
 452        }
 453        sprintf(tmpname, "%s%s", dirname, basename);
 454        if (rename(newname, tmpname))
 455                return 1;
 456
 457        sym_change_count = 0;
 458
 459        return 0;
 460}
 461
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.