summaryrefslogtreecommitdiff
path: root/extra/config
diff options
context:
space:
mode:
Diffstat (limited to 'extra/config')
-rw-r--r--extra/config/Makefile83
-rwxr-xr-xextra/config/confbin0 -> 163714 bytes
-rw-r--r--extra/config/conf.c565
-rw-r--r--extra/config/confdata.c370
-rw-r--r--extra/config/expr.c1054
-rw-r--r--extra/config/expr.h242
-rw-r--r--extra/config/lex.zconf.c3270
-rw-r--r--extra/config/lex.zconf.c_shipped3270
-rw-r--r--extra/config/lkc.h106
-rw-r--r--extra/config/lkc_defs.h38
-rw-r--r--extra/config/lkc_proto.h38
-rw-r--r--extra/config/lxdialog/BIG.FAT.WARNING4
-rw-r--r--extra/config/lxdialog/Makefile51
-rw-r--r--extra/config/lxdialog/checklist.c369
-rw-r--r--extra/config/lxdialog/colors.h161
-rw-r--r--extra/config/lxdialog/dialog.h184
-rw-r--r--extra/config/lxdialog/inputbox.c240
-rwxr-xr-xextra/config/lxdialog/lxdialogbin0 -> 34594 bytes
-rw-r--r--extra/config/lxdialog/lxdialog.c226
-rw-r--r--extra/config/lxdialog/menubox.c443
-rw-r--r--extra/config/lxdialog/msgbox.c85
-rw-r--r--extra/config/lxdialog/textbox.c556
-rw-r--r--extra/config/lxdialog/util.c359
-rw-r--r--extra/config/lxdialog/yesno.c118
-rwxr-xr-xextra/config/mconfbin0 -> 178758 bytes
-rw-r--r--extra/config/mconf.c711
-rw-r--r--extra/config/menu.c309
-rw-r--r--extra/config/symbol.c618
-rw-r--r--extra/config/zconf.l323
-rw-r--r--extra/config/zconf.tab.c1866
-rw-r--r--extra/config/zconf.tab.c_shipped1866
-rw-r--r--extra/config/zconf.tab.h53
-rw-r--r--extra/config/zconf.tab.h_shipped53
-rw-r--r--extra/config/zconf.y651
34 files changed, 18282 insertions, 0 deletions
diff --git a/extra/config/Makefile b/extra/config/Makefile
new file mode 100644
index 000000000..5b283a297
--- /dev/null
+++ b/extra/config/Makefile
@@ -0,0 +1,83 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2002 Erik Andersen <andersen@codepoet.org>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+TOPDIR=../../
+include $(TOPDIR)Rules.mak
+
+
+all: conf mconf
+
+NATIVE_CFLAGS=-Wall -g -O0
+
+
+CONF_SRC =conf.c zconf.tab.c
+MCONF_SRC =mconf.c zconf.tab.c
+CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC))
+MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC))
+
+conf: $(CONF_OBJS)
+ $(NATIVE_CC) $(NATIVE_CFLAGS) $(NATIVE_LDFLAGS) $^ -o $@
+
+mconf: $(MCONF_OBJS)
+ $(NATIVE_CC) $(NATIVE_CFLAGS) $(NATIVE_LDFLAGS) $^ -o $@
+
+lkc_deps:=lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h
+
+conf.o: conf.c $(lkc_deps)
+
+mconf.o: mconf.c $(lkc_deps)
+
+zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps)
+
+lex.zconf.o: lex.zconf.c $(lkc_deps)
+
+%.o : %.c
+ $(NATIVE_CC) $(NATIVE_CFLAGS) -I. -c $< -o $@
+
+lkc_defs.h: lkc_proto.h
+ sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
+
+###
+# The following requires flex/bison
+# By default we use the _shipped versions, uncomment the
+# following line if you are modifying the flex/bison src.
+# LKC_GENPARSER := 1
+
+#ifdef LKC_GENPARSER
+#
+#%.tab.c %.tab.h: %.y
+# bison -t -d -v -b $* -p $(notdir $*) $<
+#
+#lex.%.c: %.l
+# flex -P$(notdir $*) -o$@ $<
+#else
+
+lex.zconf.c: lex.zconf.c_shipped
+ cp lex.zconf.c_shipped lex.zconf.c
+
+zconf.tab.c: zconf.tab.c_shipped
+ cp zconf.tab.c_shipped zconf.tab.c
+
+zconf.tab.h: zconf.tab.h_shipped
+ cp zconf.tab.h_shipped zconf.tab.h
+#endif
+
+clean:
+ rm -f *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) \
+ conf mconf zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h
+
diff --git a/extra/config/conf b/extra/config/conf
new file mode 100755
index 000000000..ed1a65310
--- /dev/null
+++ b/extra/config/conf
Binary files differ
diff --git a/extra/config/conf.c b/extra/config/conf.c
new file mode 100644
index 000000000..bf82f6664
--- /dev/null
+++ b/extra/config/conf.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static void conf(struct menu *menu);
+static void check_conf(struct menu *menu);
+
+enum {
+ ask_all,
+ ask_new,
+ ask_silent,
+ set_default,
+ set_yes,
+ set_mod,
+ set_no,
+ set_random
+} input_mode = ask_all;
+
+static int indent = 1;
+static int valid_stdin = 1;
+static int conf_cnt;
+static char line[128];
+static struct menu *rootEntry;
+
+static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
+
+#if 0
+static void printc(int ch)
+{
+ static int sep = 0;
+
+ if (!sep) {
+ putchar('[');
+ sep = 1;
+ } else if (ch)
+ putchar('/');
+ if (!ch) {
+ putchar(']');
+ putchar(' ');
+ sep = 0;
+ } else
+ putchar(ch);
+}
+#endif
+
+static void printo(const char *o)
+{
+ static int sep = 0;
+
+ if (!sep) {
+ putchar('(');
+ sep = 1;
+ } else if (o) {
+ putchar(',');
+ putchar(' ');
+ }
+ if (!o) {
+ putchar(')');
+ putchar(' ');
+ sep = 0;
+ } else
+ printf("%s", o);
+}
+
+static void strip(char *str)
+{
+ char *p = str;
+ int l;
+
+ while ((isspace(*p)))
+ p++;
+ l = strlen(p);
+ if (p != str)
+ memmove(str, p, l + 1);
+ if (!l)
+ return;
+ p = str + l - 1;
+ while ((isspace(*p)))
+ *p-- = 0;
+}
+
+static void conf_askvalue(struct symbol *sym, const char *def)
+{
+ enum symbol_type type = sym_get_type(sym);
+ tristate val;
+
+ if (!sym_has_value(sym))
+ printf("(NEW) ");
+
+ line[0] = '\n';
+ line[1] = 0;
+
+ switch (input_mode) {
+ case ask_new:
+ case ask_silent:
+ if (sym_has_value(sym)) {
+ printf("%s\n", def);
+ return;
+ }
+ if (!valid_stdin && input_mode == ask_silent) {
+ printf("aborted!\n\n");
+ printf("Console input/output is redirected. ");
+ printf("Run 'make oldconfig' to update configuration.\n\n");
+ exit(1);
+ }
+ case ask_all:
+ fgets(line, 128, stdin);
+ return;
+ case set_default:
+ printf("%s\n", def);
+ return;
+ default:
+ break;
+ }
+
+ switch (type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ printf("%s\n", def);
+ return;
+ default:
+ ;
+ }
+ switch (input_mode) {
+ case set_yes:
+ if (sym_tristate_within_range(sym, yes)) {
+ line[0] = 'y';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ case set_mod:
+ if (type == S_TRISTATE) {
+ if (sym_tristate_within_range(sym, mod)) {
+ line[0] = 'm';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ } else {
+ if (sym_tristate_within_range(sym, yes)) {
+ line[0] = 'y';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ }
+ case set_no:
+ if (sym_tristate_within_range(sym, no)) {
+ line[0] = 'n';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ case set_random:
+ do {
+ val = (tristate)(random() % 3);
+ } while (!sym_tristate_within_range(sym, val));
+ switch (val) {
+ case no: line[0] = 'n'; break;
+ case mod: line[0] = 'm'; break;
+ case yes: line[0] = 'y'; break;
+ }
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ default:
+ break;
+ }
+ printf("%s", line);
+}
+
+int conf_string(struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ const char *def, *help;
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ printf("(%s) ", sym->name);
+ def = sym_get_string_value(sym);
+ if (sym_get_string_value(sym))
+ printf("[%s] ", def);
+ conf_askvalue(sym, def);
+ switch (line[0]) {
+ case '\n':
+ break;
+ case '?':
+ /* print help */
+ if (line[1] == 0) {
+ help = nohelp_text;
+ if (menu->sym->help)
+ help = menu->sym->help;
+ printf("\n%s\n", menu->sym->help);
+ def = NULL;
+ break;
+ }
+ default:
+ line[strlen(line)-1] = 0;
+ def = line;
+ }
+ if (def && sym_set_string_value(sym, def))
+ return 0;
+ }
+}
+
+static int conf_sym(struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ int type;
+ tristate oldval, newval;
+ const char *help;
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ if (sym->name)
+ printf("(%s) ", sym->name);
+ type = sym_get_type(sym);
+ putchar('[');
+ oldval = sym_get_tristate_value(sym);
+ switch (oldval) {
+ case no:
+ putchar('N');
+ break;
+ case mod:
+ putchar('M');
+ break;
+ case yes:
+ putchar('Y');
+ break;
+ }
+ if (oldval != no && sym_tristate_within_range(sym, no))
+ printf("/n");
+ if (oldval != mod && sym_tristate_within_range(sym, mod))
+ printf("/m");
+ if (oldval != yes && sym_tristate_within_range(sym, yes))
+ printf("/y");
+ if (sym->help)
+ printf("/?");
+ printf("] ");
+ conf_askvalue(sym, sym_get_string_value(sym));
+ strip(line);
+
+ switch (line[0]) {
+ case 'n':
+ case 'N':
+ newval = no;
+ if (!line[1] || !strcmp(&line[1], "o"))
+ break;
+ continue;
+ case 'm':
+ case 'M':
+ newval = mod;
+ if (!line[1])
+ break;
+ continue;
+ case 'y':
+ case 'Y':
+ newval = yes;
+ if (!line[1] || !strcmp(&line[1], "es"))
+ break;
+ continue;
+ case 0:
+ newval = oldval;
+ break;
+ case '?':
+ goto help;
+ default:
+ continue;
+ }
+ if (sym_set_tristate_value(sym, newval))
+ return 0;
+help:
+ help = nohelp_text;
+ if (sym->help)
+ help = sym->help;
+ printf("\n%s\n", help);
+ }
+}
+
+static int conf_choice(struct menu *menu)
+{
+ struct symbol *sym, *def_sym;
+ struct menu *cmenu, *def_menu;
+ const char *help;
+ int type, len;
+ bool is_new;
+
+ sym = menu->sym;
+ type = sym_get_type(sym);
+ is_new = !sym_has_value(sym);
+ if (sym_is_changable(sym)) {
+ conf_sym(menu);
+ sym_calc_value(sym);
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ return 1;
+ case mod:
+ return 0;
+ case yes:
+ break;
+ }
+ } else {
+ sym->def = sym->curr;
+ if (S_TRI(sym->curr) == mod) {
+ printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ return 0;
+ }
+ }
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu_get_prompt(menu));
+ def_sym = sym_get_choice_value(sym);
+ def_menu = NULL;
+ for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
+ if (!menu_is_visible(cmenu))
+ continue;
+ printo(menu_get_prompt(cmenu));
+ if (cmenu->sym == def_sym)
+ def_menu = cmenu;
+ }
+ printo(NULL);
+ if (def_menu)
+ printf("[%s] ", menu_get_prompt(def_menu));
+ else {
+ printf("\n");
+ return 1;
+ }
+ switch (input_mode) {
+ case ask_new:
+ case ask_silent:
+ case ask_all:
+ conf_askvalue(sym, menu_get_prompt(def_menu));
+ strip(line);
+ break;
+ default:
+ line[0] = 0;
+ printf("\n");
+ }
+ if (line[0] == '?' && !line[1]) {
+ help = nohelp_text;
+ if (menu->sym->help)
+ help = menu->sym->help;
+ printf("\n%s\n", help);
+ continue;
+ }
+ if (line[0]) {
+ len = strlen(line) - 1;
+ line[len] = 0;
+
+ def_menu = NULL;
+ for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
+ if (!cmenu->sym || !menu_is_visible(cmenu))
+ continue;
+ if (!strncmp(line, menu_get_prompt(cmenu), len)) {
+ def_menu = cmenu;
+ break;
+ }
+ }
+ }
+ if (def_menu) {
+ sym_set_choice_value(sym, def_menu->sym);
+ if (def_menu->list) {
+ indent += 2;
+ conf(def_menu->list);
+ indent -= 2;
+ }
+ return 1;
+ }
+ }
+}
+
+static void conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ if (prop) {
+ const char *prompt;
+
+ switch (prop->type) {
+ case P_MENU:
+ if (input_mode == ask_silent && rootEntry != menu) {
+ check_conf(menu);
+ return;
+ }
+ case P_COMMENT:
+ prompt = menu_get_prompt(menu);
+ if (prompt)
+ printf("%*c\n%*c %s\n%*c\n",
+ indent, '*',
+ indent, '*', prompt,
+ indent, '*');
+ default:
+ ;
+ }
+ }
+
+ if (!sym)
+ goto conf_childs;
+
+ if (sym_is_choice(sym)) {
+ conf_choice(menu);
+ if (S_TRI(sym->curr) != mod)
+ return;
+ goto conf_childs;
+ }
+
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ conf_string(menu);
+ break;
+ default:
+ conf_sym(menu);
+ break;
+ }
+
+conf_childs:
+ if (sym)
+ indent += 2;
+ for (child = menu->list; child; child = child->next)
+ conf(child);
+ if (sym)
+ indent -= 2;
+}
+
+static void check_conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct menu *child;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ if (!sym)
+ goto conf_childs;
+
+ if (sym_is_choice(sym)) {
+ if (!sym_has_value(sym)) {
+ if (!conf_cnt++)
+ printf("*\n* Restart config...\n*\n");
+ rootEntry = menu_get_parent_menu(menu);
+ conf(rootEntry);
+ }
+ if (sym_get_tristate_value(sym) != mod)
+ return;
+ goto conf_childs;
+ }
+
+ if (!sym_has_value(sym)) {
+ if (!conf_cnt++)
+ printf("*\n* Restart config...\n*\n");
+ rootEntry = menu_get_parent_menu(menu);
+ conf(rootEntry);
+ }
+
+conf_childs:
+ for (child = menu->list; child; child = child->next)
+ check_conf(child);
+}
+
+int main(int ac, char **av)
+{
+ const char *name;
+ struct stat tmpstat;
+
+ if (ac > 1 && av[1][0] == '-') {
+ switch (av[1][1]) {
+ case 'o':
+ input_mode = ask_new;
+ break;
+ case 's':
+ input_mode = ask_silent;
+ valid_stdin = isatty(0) && isatty(1) && isatty(2);
+ break;
+ case 'd':
+ input_mode = set_default;
+ break;
+ case 'n':
+ input_mode = set_no;
+ break;
+ case 'm':
+ input_mode = set_mod;
+ break;
+ case 'y':
+ input_mode = set_yes;
+ break;
+ case 'r':
+ input_mode = set_random;
+ srandom(time(NULL));
+ break;
+ case 'h':
+ case '?':
+ printf("%s [-o|-s] config\n", av[0]);
+ exit(0);
+ }
+ name = av[2];
+ } else
+ name = av[1];
+ conf_parse(name);
+ //zconfdump(stdout);
+ switch (input_mode) {
+ case set_default:
+ name = conf_get_default_confname();
+ if (conf_read(name)) {
+ printf("***\n"
+ "*** Can't find default configuration \"%s\"!\n"
+ "***\n", name);
+ exit(1);
+ }
+ break;
+ case ask_silent:
+ if (stat(".config", &tmpstat)) {
+ printf("***\n"
+ "*** You have not yet configured uClibc!\n"
+ "***\n"
+ "*** Please run some configurator (e.g. \"make oldconfig\"\n"
+ "*** or \"make menuconfig\").\n"
+ "***\n");
+ exit(1);
+ }
+ case ask_all:
+ case ask_new:
+ conf_read(NULL);
+ break;
+ default:
+ break;
+ }
+
+ if (input_mode != ask_silent) {
+ rootEntry = &rootmenu;
+ conf(&rootmenu);
+ if (input_mode == ask_all) {
+ input_mode = ask_silent;
+ valid_stdin = 1;
+ }
+ }
+ do {
+ conf_cnt = 0;
+ check_conf(&rootmenu);
+ } while (conf_cnt);
+ conf_write(NULL);
+ return 0;
+}
diff --git a/extra/config/confdata.c b/extra/config/confdata.c
new file mode 100644
index 000000000..00e87486a
--- /dev/null
+++ b/extra/config/confdata.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+const char conf_def_filename[] = ".config";
+char conf_filename[PATH_MAX+1];
+
+const char conf_defname[] = "extra/Configs/Config.$TARGET_ARCH.default";
+
+const char *conf_confnames[] = {
+ ".config",
+ conf_defname,
+ NULL,
+};
+
+static char *conf_expand_value(const char *in)
+{
+ struct symbol *sym;
+ const char *src;
+ static char res_value[SYMBOL_MAXLENGTH];
+ char *dst, name[SYMBOL_MAXLENGTH];
+
+ res_value[0] = 0;
+ dst = name;
+ while ((src = strchr(in, '$'))) {
+ strncat(res_value, in, src - in);
+ src++;
+ dst = name;
+ while (isalnum(*src) || *src == '_')
+ *dst++ = *src++;
+ *dst = 0;
+ sym = sym_lookup(name, 0);
+ sym_calc_value(sym);
+ strcat(res_value, sym_get_string_value(sym));
+ in = src;
+ }
+ strcat(res_value, in);
+
+ return res_value;
+}
+
+char *conf_get_default_confname(void)
+{
+ return conf_expand_value(conf_defname);
+}
+
+int conf_read(const char *name)
+{
+ FILE *in = NULL;
+ char line[128];
+ char *p, *p2;
+ int lineno = 0;
+ struct symbol *sym;
+ struct property *prop;
+ struct expr *e;
+ int i;
+
+ if (name) {
+ in = fopen(name, "r");
+ if (in)
+ strcpy(conf_filename, name);
+ } else {
+ const char **names = conf_confnames;
+ while ((name = *names++)) {
+ name = conf_expand_value(name);
+ in = fopen(name, "r");
+ if (in) {
+ printf("#\n"
+ "# using defaults found in %s\n"
+ "#\n", name);
+ break;
+ }
+ }
+ }
+
+ if (!in)
+ return 1;
+
+ for_all_symbols(i, sym) {
+ sym->flags |= SYMBOL_NEW;
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ if (S_VAL(sym->def)) {
+ free(S_VAL(sym->def));
+ S_VAL(sym->def) = NULL;
+ }
+ default:
+ ;
+ }
+ }
+
+ while (fgets(line, 128, in)) {
+ lineno++;
+ switch (line[0]) {
+ case '\n':
+ break;
+ case ' ':
+ break;
+ case '#':
+ p = strchr(line, ' ');
+ if (!p)
+ continue;
+ *p++ = 0;
+ p = strchr(p, ' ');
+ if (!p)
+ continue;
+ *p++ = 0;
+ if (strncmp(p, "is not set", 10))
+ continue;
+ sym = sym_lookup(line+2, 0);
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ sym->def = symbol_no.curr;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ default:
+ ;
+ }
+ break;
+ case 'A' ... 'Z':
+ p = strchr(line, '=');
+ if (!p)
+ continue;
+ *p++ = 0;
+ p2 = strchr(p, '\n');
+ if (p2)
+ *p2 = 0;
+ sym = sym_find(line);
+ if (!sym) {
+ fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line);
+ break;
+ }
+ switch (sym->type) {
+ case S_BOOLEAN:
+ sym->def = symbol_yes.curr;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ case S_TRISTATE:
+ if (p[0] == 'm')
+ sym->def = symbol_mod.curr;
+ else
+ sym->def = symbol_yes.curr;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ case S_STRING:
+ if (*p++ != '"')
+ break;
+ for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+ if (*p2 == '"') {
+ *p2 = 0;
+ break;
+ }
+ memmove(p2, p2 + 1, strlen(p2));
+ }
+ case S_INT:
+ case S_HEX:
+ if (sym_string_valid(sym, p)) {
+ S_VAL(sym->def) = strdup(p);
+ sym->flags &= ~SYMBOL_NEW;
+ } else
+ fprintf(stderr, "%s:%d:symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
+ break;
+ default:
+ ;
+ }
+ if (sym_is_choice_value(sym)) {
+ prop = sym_get_choice_prop(sym);
+ switch (S_TRI(sym->def)) {
+ case mod:
+ if (S_TRI(prop->def->def) == yes)
+ /* warn? */;
+ break;
+ case yes:
+ if (S_TRI(prop->def->def) != no)
+ /* warn? */;
+ S_VAL(prop->def->def) = sym;
+ break;
+ case no:
+ break;
+ }
+ S_TRI(prop->def->def) = S_TRI(sym->def);
+ }
+ break;
+ default:
+ continue;
+ }
+ }
+ fclose(in);
+
+ for_all_symbols(i, sym) {
+ if (!sym_is_choice(sym))
+ continue;
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->dep; e; e = e->left.expr)
+ sym->flags |= e->right.sym->flags & SYMBOL_NEW;
+ sym->flags &= ~SYMBOL_NEW;
+ }
+
+ sym_change_count = 1;
+
+ return 0;
+}
+
+int conf_write(const char *name)
+{
+ FILE *out, *out_h;
+ struct symbol *sym;
+ struct menu *menu;
+ char oldname[128];
+ int type, l;
+ const char *str;
+
+ out = fopen(".tmpconfig", "w");
+ if (!out)
+ return 1;
+ out_h = fopen(".tmpconfig.h", "w");
+ if (!out_h)
+ return 1;
+ fprintf(out, "#\n"
+ "# Automatically generated make config: don't edit\n"
+ "#\n");
+ fprintf(out_h, "/*\n"
+ " * Automatically generated C config: don't edit\n"
+ " */\n"
+ "#if !defined __FEATURES_H && !defined __need_uClibc_config_h\n"
+ "#error Never include <bits/uClibc_config.h> directly; use <features.h> instead.\n"
+ "#endif\n"
+ "#define AUTOCONF_INCLUDED\n\n"
+ "/*\n"
+ " * Version Number\n"
+ " */\n"
+ "#define __UCLIBC_MAJOR__ %s\n"
+ "#define __UCLIBC_MINOR__ %s\n"
+ "#define __UCLIBC_SUBLEVEL__ %s\n",
+ getenv("MAJOR_VERSION"),
+ getenv("MINOR_VERSION"),
+ getenv("SUBLEVEL")
+ );
+
+ if (!sym_change_count)
+ sym_clear_all_valid();
+
+ menu = rootmenu.list;
+ while (menu) {
+ sym = menu->sym;
+ if (!sym) {
+ if (!menu_is_visible(menu))
+ goto next;
+ str = menu_get_prompt(menu);
+ fprintf(out, "\n"
+ "#\n"
+ "# %s\n"
+ "#\n", str);
+ fprintf(out_h, "\n"
+ "/*\n"
+ " * %s\n"
+ " */\n", str);
+ } else if (!(sym->flags & SYMBOL_CHOICE)) {
+ sym_calc_value(sym);
+ if (!(sym->flags & SYMBOL_WRITE))
+ goto next;
+ sym->flags &= ~SYMBOL_WRITE;
+ type = sym->type;
+ if (type == S_TRISTATE) {
+ sym_calc_value(modules_sym);
+ if (S_TRI(modules_sym->curr) == no)
+ type = S_BOOLEAN;
+ }
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ fprintf(out, "# %s is not set\n", sym->name);
+ fprintf(out_h, "#undef __%s__\n", sym->name);
+ break;
+ case mod:
+ fprintf(out, "%s=m\n", sym->name);
+ fprintf(out_h, "#define __%s__MODULE 1\n", sym->name);
+ break;
+ case yes:
+ fprintf(out, "%s=y\n", sym->name);
+ fprintf(out_h, "#define __%s__ 1\n", sym->name);
+ break;
+ }
+ break;
+ case S_STRING:
+ // fix me
+ str = sym_get_string_value(sym);
+ fprintf(out, "%s=\"", sym->name);
+ fprintf(out_h, "#define __%s__ \"", sym->name);
+ do {
+ l = strcspn(str, "\"\\");
+ if (l) {
+ fwrite(str, l, 1, out);
+ fwrite(str, l, 1, out_h);
+ }
+ str += l;
+ while (*str == '\\' || *str == '"') {
+ fprintf(out, "\\%c", *str);
+ fprintf(out_h, "\\%c", *str);
+ str++;
+ }
+ } while (*str);
+ fputs("\"\n", out);
+ fputs("\"\n", out_h);
+ break;
+ case S_HEX:
+ str = sym_get_string_value(sym);
+ if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
+ fprintf(out, "%s=%s\n", sym->name, str);
+ fprintf(out_h, "#define __%s__ 0x%s\n", sym->name, str);
+ break;
+ }
+ case S_INT:
+ str = sym_get_string_value(sym);
+ fprintf(out, "%s=%s\n", sym->name, str);
+ fprintf(out_h, "#define __%s__ %s\n", sym->name, str);
+ break;
+ }
+ }
+
+ next:
+ if (menu->list) {
+ menu = menu->list;
+ continue;
+ }
+ if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+ fclose(out);
+ fclose(out_h);
+
+ if (!name) {
+ rename(".tmpconfig.h", "include/bits/uClibc_config.h");
+ name = conf_def_filename;
+ file_write_dep(NULL);
+ } else
+ unlink(".tmpconfig.h");
+
+ sprintf(oldname, "%s.old", name);
+ rename(name, oldname);
+ if (rename(".tmpconfig", name))
+ return 1;
+ strcpy(conf_filename, name);
+
+ sym_change_count = 0;
+
+ return 0;
+}
diff --git a/extra/config/expr.c b/extra/config/expr.c
new file mode 100644
index 000000000..d1af2a581
--- /dev/null
+++ b/extra/config/expr.c
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h