00001
00002
00003
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 ;
00218
break;
00219
case yes:
00220
if (cs->user.tri !=
no)
00221 ;
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
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 }