Commit ae10cf68 authored by Roman Zippel's avatar Roman Zippel Committed by Linus Torvalds

[PATCH] new kernel configuration 2/7

This adds the new kernel config core (library + the three front ends).
parent 5d31b48c
#################
#
# Shared Makefile for the various lkc executables:
# conf: Used for defconfig, oldconfig and related targets
# mconf: Used for the mconfig target.
# Utilizes the lxdialog package
# qconf: Used for the xconfig target
# Based on QT which needs to be installed to compile it
#
# object files used by all lkc flavours
libkconfig-objs := zconf.tab.o
host-progs := conf mconf qconf
conf-objs := conf.o libkconfig.so
mconf-objs := mconf.o libkconfig.so
qconf-objs := kconfig_load.o
qconf-cxxobjs := qconf.o
clean-files := libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \
zconf.tab.c zconf.tab.h lex.zconf.c
include $(TOPDIR)/Rules.make
# generated files seem to need this to find local include files
HOSTCFLAGS_lex.zconf.o := -I$(src)
HOSTCFLAGS_zconf.tab.o := -I$(src)
HOSTLOADLIBES_qconf = -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -l$(QTLIB) -ldl
HOSTCXXFLAGS_qconf.o = -I$(QTDIR)/include
$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o: $(obj)/zconf.tab.h
$(obj)/qconf.o: $(obj)/.tmp_qtcheck
-include $(obj)/.tmp_qtcheck
# QT needs some extra effort...
$(obj)/.tmp_qtcheck:
@set -e; for d in $$QTDIR /usr/share/qt /usr/lib/qt3; do \
if [ -x $$d/bin/moc ]; then DIR=$$d; break; fi; \
done; \
if [ -z "$$DIR" ]; then \
echo "*"; \
echo "* Unable to find the QT installation. Please make sure that the"; \
echo "* QT development package is correctly installed and the QTDIR"; \
echo "* environment variable is set to the correct location."; \
echo "*"; \
false; \
fi; \
LIB=qt; \
if [ -f $$DIR/lib/libqt-mt.so ]; then LIB=qt-mt; fi; \
echo "QTDIR=$$DIR" > $@; echo "QTLIB=$$LIB" >> $@
$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
$(obj)/%.moc: $(src)/%.h
$(QTDIR)/bin/moc -i $< -o $@
$(obj)/lkc_defs.h: $(src)/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
$(obj)/zconf.tab.c: $(obj)/zconf.y
$(obj)/zconf.tab.h: $(obj)/zconf.tab.c
%.tab.c: %.y
bison -t -d -v -b $* -p $(notdir $*) $<
lex.%.c: %.l
flex -P$(notdir $*) -o$@ $<
endif
/*
* 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 your kernel!\n"
"***\n"
"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
"*** \"make menuconfig\" or \"make xconfig\").\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;
}
/*
* 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[] = "arch/$ARCH/defconfig";
const char *conf_confnames[] = {
".config",
"/lib/modules/$UNAME_RELEASE/.config",
"/etc/kernel-config",
"/boot/config-$UNAME_RELEASE",
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 '#':
if (memcmp(line + 2, "CONFIG_", 7))
continue;
p = strchr(line + 9, ' ');
if (!p)
continue;
*p++ = 0;
if (strncmp(p, "is not set", 10))
continue;
//printf("%s -> n\n", line + 9);
sym = sym_lookup(line + 9, 0);
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
sym->def = symbol_no.curr;
sym->flags &= ~SYMBOL_NEW;
break;
default:
;
}
break;
case 'C':
if (memcmp(line, "CONFIG_", 7))
continue;
p = strchr(line + 7, '=');
if (!p)
continue;
*p++ = 0;
p2 = strchr(p, '\n');
if (p2)
*p2 = 0;
//printf("%s -> %s\n", line + 7, p);
sym = sym_find(line + 7);
if (!sym) {
fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
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;
case '\n':
break;
default:
continue;
}
}
fclose(in);
for_all_symbols(i, sym) {
if (!sym_is_choice(sym))
continue;
prop = sym_get_choice_prop(sym);
sym->flags &= ~SYMBOL_NEW;
for (e = prop->dep; e; e = e->left.expr)
sym->flags |= e->right.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"
"#define AUTOCONF_INCLUDED\n");
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, "# CONFIG_%s is not set\n", sym->name);
fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
break;
case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name);
fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
break;
case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name);
fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
break;
}
break;
case S_STRING:
// fix me
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=\"", sym->name);
fprintf(out_h, "#define CONFIG_%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, "CONFIG_%s=%s\n", sym->name, str);
fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
fprintf(out_h, "#define CONFIG_%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/linux/autoconf.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;
}
/*
* 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"
struct expr *expr_alloc_symbol(struct symbol *sym)
{
struct expr *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
e->type = E_SYMBOL;
e->left.sym = sym;
return e;
}
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
{
struct expr *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
e->type = type;
e->left.expr = ce;
return e;
}
struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
{
struct expr *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
e->type = type;
e->left.expr = e1;
e->right.expr = e2;
return e;
}
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
{
struct expr *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
e->type = type;
e->left.sym = s1;
e->right.sym = s2;
return e;
}
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
{
if (!e1)
return e2;
return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
}
struct expr *expr_copy(struct expr *org)
{
struct expr *e;
if (!org)
return NULL;
e = malloc(sizeof(*org));
memcpy(e, org, sizeof(*org));
switch (org->type) {
case E_SYMBOL:
e->left = org->left;
break;
case E_NOT:
e->left.expr = expr_copy(org->left.expr);
break;
case E_EQUAL:
case E_UNEQUAL:
e->left.sym = org->left.sym;
e->right.sym = org->right.sym;
break;
case E_AND:
case E_OR:
case E_CHOICE:
e->left.expr = expr_copy(org->left.expr);
e->right.expr = expr_copy(org->right.expr);
break;
default:
printf("can't copy type %d\n", e->type);
free(e);
e = NULL;
break;
}
return e;
}
void expr_free(struct expr *e)
{
if (!e)
return;
switch (e->type) {
case E_SYMBOL:
break;
case E_NOT:
expr_free(e->left.expr);
return;
case E_EQUAL:
case E_UNEQUAL:
break;
case E_OR:
case E_AND:
expr_free(e->left.expr);
expr_free(e->right.expr);
break;
default:
printf("how to free type %d?\n", e->type);
break;
}
free(e);
}
static int trans_count;
#define e1 (*ep1)
#define e2 (*ep2)
static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
{
if (e1->type == type) {
__expr_eliminate_eq(type, &e1->left.expr, &e2);
__expr_eliminate_eq(type, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
__expr_eliminate_eq(type, &e1, &e2->left.expr);
__expr_eliminate_eq(type, &e1, &e2->right.expr);
return;
}
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
return;
if (!expr_eq(e1, e2))
return;
trans_count++;
expr_free(e1); expr_free(e2);
switch (type) {
case E_OR:
e1 = expr_alloc_symbol(&symbol_no);
e2 = expr_alloc_symbol(&symbol_no);
break;
case E_AND:
e1 = expr_alloc_symbol(&symbol_yes);
e2 = expr_alloc_symbol(&symbol_yes);
break;
default:
;
}
}
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
{
if (!e1 || !e2 || e1->type != e2->type)
return;
__expr_eliminate_eq(e1->type, ep1, ep2);
e1 = expr_eliminate_yn(e1);
e2 = expr_eliminate_yn(e2);
}
#undef e1
#undef e2
int expr_eq(struct expr *e1, struct expr *e2)
{
int res, old_count;
if (e1->type != e2->type)
return 0;
switch (e1->type) {
case E_EQUAL:
case E_UNEQUAL:
return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
case E_SYMBOL:
return e1->left.sym == e2->left.sym;
case E_NOT:
return expr_eq(e1->left.expr, e2->left.expr);
case E_AND:
case E_OR:
e1 = expr_copy(e1);
e2 = expr_copy(e2);
old_count = trans_count;
expr_eliminate_eq(&e1, &e2);
res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
e1->left.sym == e2->left.sym);
expr_free(e1);
expr_free(e2);
trans_count = old_count;
return res;
case E_CHOICE:
case E_NONE:
/* panic */;
}
print_expr(0, e1, 0);
printf(" = ");
print_expr(0, e2, 0);
printf(" ?\n");
return 0;
}
struct expr *expr_eliminate_yn(struct expr *e)
{
struct expr *tmp;
if (e) switch (e->type) {
case E_AND:
e->left.expr = expr_eliminate_yn(e->left.expr);
e->right.expr = expr_eliminate_yn(e->right.expr);
if (e->left.expr->type == E_SYMBOL) {
if (e->left.expr->left.sym == &symbol_no) {
expr_free(e->left.expr);
expr_free(e->right.expr);
e->type = E_SYMBOL;
e->left.sym = &symbol_no;
e->right.expr = NULL;
return e;
} else if (e->left.expr->left.sym == &symbol_yes) {
free(e->left.expr);
tmp = e->right.expr;
*e = *(e->right.expr);
free(tmp);
return e;
}
}
if (e->right.expr->type == E_SYMBOL) {
if (e->right.expr->left.sym == &symbol_no) {
expr_free(e->left.expr);
expr_free(e->right.expr);
e->type = E_SYMBOL;
e->left.sym = &symbol_no;
e->right.expr = NULL;
return e;
} else if (e->right.expr->left.sym == &symbol_yes) {
free(e->right.expr);
tmp = e->left.expr;
*e = *(e->left.expr);
free(tmp);
return e;
}
}
break;
case E_OR:
e->left.expr = expr_eliminate_yn(e->left.expr);
e->right.expr = expr_eliminate_yn(e->right.expr);
if (e->left.expr->type == E_SYMBOL) {
if (e->left.expr->left.sym == &symbol_no) {
free(e->left.expr);
tmp = e->right.expr;
*e = *(e->right.expr);
free(tmp);
return e;
} else if (e->left.expr->left.sym == &symbol_yes) {
expr_free(e->left.expr);
expr_free(e->right.expr);
e->type = E_SYMBOL;
e->left.sym = &symbol_yes;
e->right.expr = NULL;
return e;
}
}
if (e->right.expr->type == E_SYMBOL) {
if (e->right.expr->left.sym == &symbol_no) {
free(e->right.expr);
tmp = e->left.expr;
*e = *(e->left.expr);
free(tmp);
return e;
} else if (e->right.expr->left.sym == &symbol_yes) {
expr_free(e->left.expr);
expr_free(e->right.expr);
e->type = E_SYMBOL;
e->left.sym = &symbol_yes;
e->right.expr = NULL;
return e;
}
}
break;
default:
;
}
return e;
}
/*
* bool FOO!=n => FOO
*/
struct expr *expr_trans_bool(struct expr *e)
{
if (!e)
return NULL;
switch (e->type) {
case E_AND:
case E_OR:
case E_NOT:
e->left.expr = expr_trans_bool(e->left.expr);
e->right.expr = expr_trans_bool(e->right.expr);
break;
case E_UNEQUAL:
// FOO!=n -> FOO
if (e->left.sym->type == S_TRISTATE) {
if (e->right.sym == &symbol_no) {
e->type = E_SYMBOL;
e->right.sym = NULL;
}
}
break;
default:
;
}
return e;
}
/*
* e1 || e2 -> ?
*/
struct expr *expr_join_or(struct expr *e1, struct expr *e2)
{
struct expr *tmp;
struct symbol *sym1, *sym2;
if (expr_eq(e1, e2))
return expr_copy(e1);
if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
return NULL;
if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
return NULL;
if (e1->type == E_NOT) {
tmp = e1->left.expr;
if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
return NULL;
sym1 = tmp->left.sym;
} else
sym1 = e1->left.sym;
if (e2->type == E_NOT) {
if (e2->left.expr->type != E_SYMBOL)
return NULL;
sym2 = e2->left.expr->left.sym;
} else
sym2 = e2->left.sym;
if (sym1 != sym2)
return NULL;
if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
return NULL;
if (sym1->type == S_TRISTATE) {
if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
(e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
// (a='y') || (a='m') -> (a!='n')
return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
}
if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
(e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
// (a='y') || (a='n') -> (a!='m')
return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
}
if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
(e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
// (a='m') || (a='n') -> (a!='y')
return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
}
}
if (sym1->type == S_BOOLEAN && sym1 == sym2) {
if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
(e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
return expr_alloc_symbol(&symbol_yes);
}
printf("optimize ");
print_expr(0, e1, 0);
printf(" || ");
print_expr(0, e2, 0);
printf(" ?\n");
return NULL;
}
struct expr *expr_join_and(struct expr *e1, struct expr *e2)
{
struct expr *tmp;
struct symbol *sym1, *sym2;
if (expr_eq(e1, e2))
return expr_copy(e1);
if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
return NULL;
if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
return NULL;
if (e1->type == E_NOT) {
tmp = e1->left.expr;
if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
return NULL;
sym1 = tmp->left.sym;
} else
sym1 = e1->left.sym;
if (e2->type == E_NOT) {
if (e2->left.expr->type != E_SYMBOL)
return NULL;
sym2 = e2->left.expr->left.sym;
} else
sym2 = e2->left.sym;
if (sym1 != sym2)
return NULL;
if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
return NULL;
if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
(e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
// (a) && (a='y') -> (a='y')
return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
(e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
// (a) && (a!='n') -> (a)
return expr_alloc_symbol(sym1);
if (sym1->type == S_TRISTATE) {
if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
sym2 = e1->right.sym;
if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
: expr_alloc_symbol(&symbol_no);
}
if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
sym2 = e2->right.sym;
if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
: expr_alloc_symbol(&symbol_no);
}
if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
(e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
// (a!='y') && (a!='n') -> (a='m')
return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
(e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
// (a!='y') && (a!='m') -> (a='n')
return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
(e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
// (a!='m') && (a!='n') -> (a='m')
return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
(e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
(e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
(e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
return NULL;
}
printf("optimize ");
print_expr(0, e1, 0);
printf(" && ");
print_expr(0, e2, 0);
printf(" ?\n");
return NULL;
}
static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
struct expr *tmp;
if (e1->type == type) {
expr_eliminate_dups1(type, &e1->left.expr, &e2);
expr_eliminate_dups1(type, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
expr_eliminate_dups1(type, &e1, &e2->left.expr);
expr_eliminate_dups1(type, &e1, &e2->right.expr);
return;
}
if (e1 == e2)
return;
switch (e1->type) {
case E_OR: case E_AND:
expr_eliminate_dups1(e1->type, &e1, &e1);
default:
;
}
switch (type) {
case E_OR:
tmp = expr_join_or(e1, e2);
if (tmp) {
expr_free(e1); expr_free(e2);
e1 = expr_alloc_symbol(&symbol_no);
e2 = tmp;
trans_count++;
}
break;
case E_AND:
tmp = expr_join_and(e1, e2);
if (tmp) {
expr_free(e1); expr_free(e2);
e1 = expr_alloc_symbol(&symbol_yes);
e2 = tmp;
trans_count++;
}
break;
default:
;
}
#undef e1
#undef e2
}
static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
struct expr *tmp, *tmp1, *tmp2;
if (e1->type == type) {
expr_eliminate_dups2(type, &e1->left.expr, &e2);
expr_eliminate_dups2(type, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
expr_eliminate_dups2(type, &e1, &e2->left.expr);
expr_eliminate_dups2(type, &e1, &e2->right.expr);
}
if (e1 == e2)
return;
switch (e1->type) {
case E_OR:
expr_eliminate_dups2(e1->type, &e1, &e1);
// (FOO || BAR) && (!FOO && !BAR) -> n
tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
tmp2 = expr_copy(e2);
tmp = expr_extract_eq_and(&tmp1, &tmp2);
if (expr_is_yes(tmp1)) {
expr_free(e1);
e1 = expr_alloc_symbol(&symbol_no);
trans_count++;
}
expr_free(tmp2);
expr_free(tmp1);
expr_free(tmp);
break;
case E_AND:
expr_eliminate_dups2(e1->type, &e1, &e1);
// (FOO && BAR) || (!FOO || !BAR) -> y
tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
tmp2 = expr_copy(e2);
tmp = expr_extract_eq_or(&tmp1, &tmp2);
if (expr_is_no(tmp1)) {
expr_free(e1);
e1 = expr_alloc_symbol(&symbol_yes);
trans_count++;
}
expr_free(tmp2);
expr_free(tmp1);
expr_free(tmp);
break;
default:
;
}
#undef e1
#undef e2
}
struct expr *expr_eliminate_dups(struct expr *e)
{
int oldcount;
if (!e)
return e;
oldcount = trans_count;
while (1) {
trans_count = 0;
switch (e->type) {
case E_OR: case E_AND:
expr_eliminate_dups1(e->type, &e, &e);
expr_eliminate_dups2(e->type, &e, &e);
default:
;
}
if (!trans_count)
break;
e = expr_eliminate_yn(e);
}
trans_count = oldcount;
return e;
}
struct expr *expr_transform(struct expr *e)
{
struct expr *tmp;
if (!e)
return NULL;
switch (e->type) {
case E_EQUAL:
case E_UNEQUAL:
case E_SYMBOL:
case E_CHOICE:
break;
default:
e->left.expr = expr_transform(e->left.expr);
e->right.expr = expr_transform(e->right.expr);
}
switch (e->type) {
case E_EQUAL:
if (e->left.sym->type != S_BOOLEAN)
break;
if (e->right.sym == &symbol_no) {
e->type = E_NOT;
e->left.expr = expr_alloc_symbol(e->left.sym);
e->right.sym = NULL;
break;
}
if (e->right.sym == &symbol_mod) {
printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
e->type = E_SYMBOL;
e->left.sym = &symbol_no;
e->right.sym = NULL;
break;
}
if (e->right.sym == &symbol_yes) {
e->type = E_SYMBOL;
e->right.sym = NULL;
break;
}
break;
case E_UNEQUAL:
if (e->left.sym->type != S_BOOLEAN)
break;
if (e->right.sym == &symbol_no) {
e->type = E_SYMBOL;
e->right.sym = NULL;
break;
}
if (e->right.sym == &symbol_mod) {
printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
e->type = E_SYMBOL;
e->left.sym = &symbol_yes;
e->right.sym = NULL;
break;
}
if (e->right.sym == &symbol_yes) {
e->type = E_NOT;
e->left.expr = expr_alloc_symbol(e->left.sym);
e->right.sym = NULL;
break;
}
break;
case E_NOT:
switch (e->left.expr->type) {
case E_NOT:
// !!a -> a
tmp = e->left.expr->left.expr;
free(e->left.expr);
free(e);
e = tmp;
e = expr_transform(e);
break;
case E_EQUAL:
case E_UNEQUAL:
// !a='x' -> a!='x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
break;
case E_OR:
// !(a || b) -> !a && !b
tmp = e->left.expr;
e->type = E_AND;
e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
tmp->type = E_NOT;
tmp->right.expr = NULL;
e = expr_transform(e);
break;
case E_AND:
// !(a && b) -> !a || !b
tmp = e->left.expr;
e->type = E_OR;
e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
tmp->type = E_NOT;
tmp->right.expr = NULL;
e = expr_transform(e);
break;
case E_SYMBOL:
if (e->left.expr->left.sym == &symbol_yes) {
// !'y' -> 'n'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = E_SYMBOL;
e->left.sym = &symbol_no;
break;
}
if (e->left.expr->left.sym == &symbol_mod) {
// !'m' -> 'm'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = E_SYMBOL;
e->left.sym = &symbol_mod;
break;
}
if (e->left.expr->left.sym == &symbol_no) {
// !'n' -> 'y'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = E_SYMBOL;
e->left.sym = &symbol_yes;
break;
}
break;
default:
;
}
break;
default:
;
}
return e;
}
int expr_contains_symbol(struct expr *dep, struct symbol *sym)
{
if (!dep)
return 0;
switch (dep->type) {
case E_AND:
case E_OR:
return expr_contains_symbol(dep->left.expr, sym) ||
expr_contains_symbol(dep->right.expr, sym);
case E_SYMBOL:
return dep->left.sym == sym;
case E_EQUAL:
case E_UNEQUAL:
return dep->left.sym == sym ||
dep->right.sym == sym;
case E_NOT:
return expr_contains_symbol(dep->left.expr, sym);
default:
;
}
return 0;
}
bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
{
if (!dep)
return false;
switch (dep->type) {
case E_AND:
return expr_depends_symbol(dep->left.expr, sym) ||
expr_depends_symbol(dep->right.expr, sym);
case E_SYMBOL:
return dep->left.sym == sym;
case E_EQUAL:
if (dep->left.sym == sym) {
if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
return true;
}
break;
case E_UNEQUAL:
if (dep->left.sym == sym) {
if (dep->right.sym == &symbol_no)
return true;
}
break;
default:
;
}
return false;
}
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
{
struct expr *tmp = NULL;
expr_extract_eq(E_AND, &tmp, ep1, ep2);
if (tmp) {
*ep1 = expr_eliminate_yn(*ep1);
*ep2 = expr_eliminate_yn(*ep2);
}
return tmp;
}
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
{
struct expr *tmp = NULL;
expr_extract_eq(E_OR, &tmp, ep1, ep2);
if (tmp) {
*ep1 = expr_eliminate_yn(*ep1);
*ep2 = expr_eliminate_yn(*ep2);
}
return tmp;
}
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
if (e1->type == type) {
expr_extract_eq(type, ep, &e1->left.expr, &e2);
expr_extract_eq(type, ep, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
expr_extract_eq(type, ep, ep1, &e2->left.expr);
expr_extract_eq(type, ep, ep1, &e2->right.expr);
return;
}
if (expr_eq(e1, e2)) {
*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
expr_free(e2);
if (type == E_AND) {
e1 = expr_alloc_symbol(&symbol_yes);
e2 = expr_alloc_symbol(&symbol_yes);
} else if (type == E_OR) {
e1 = expr_alloc_symbol(&symbol_no);
e2 = expr_alloc_symbol(&symbol_no);
}
}
#undef e1
#undef e2
}
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
{
struct expr *e1, *e2;
if (!e) {
e = expr_alloc_symbol(sym);
if (type == E_UNEQUAL)
e = expr_alloc_one(E_NOT, e);
return e;
}
switch (e->type) {
case E_AND:
e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
if (sym == &symbol_yes)
e = expr_alloc_two(E_AND, e1, e2);
if (sym == &symbol_no)
e = expr_alloc_two(E_OR, e1, e2);
if (type == E_UNEQUAL)
e = expr_alloc_one(E_NOT, e);
return e;
case E_OR:
e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
if (sym == &symbol_yes)
e = expr_alloc_two(E_OR, e1, e2);
if (sym == &symbol_no)
e = expr_alloc_two(E_AND, e1, e2);
if (type == E_UNEQUAL)
e = expr_alloc_one(E_NOT, e);
return e;
case E_NOT:
return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
case E_UNEQUAL:
case E_EQUAL:
if (type == E_EQUAL) {
if (sym == &symbol_yes)
return expr_copy(e);
if (sym == &symbol_mod)
return expr_alloc_symbol(&symbol_no);
if (sym == &symbol_no)
return expr_alloc_one(E_NOT, expr_copy(e));
} else {
if (sym == &symbol_yes)
return expr_alloc_one(E_NOT, expr_copy(e));
if (sym == &symbol_mod)
return expr_alloc_symbol(&symbol_yes);
if (sym == &symbol_no)
return expr_copy(e);
}
break;
case E_SYMBOL:
return expr_alloc_comp(type, e->left.sym, sym);
case E_CHOICE:
case E_NONE:
/* panic */;
}
return NULL;
}
tristate expr_calc_value(struct expr *e)
{
tristate val1, val2;
const char *str1, *str2;
if (!e)
return yes;
switch (e->type) {
case E_SYMBOL:
sym_calc_value(e->left.sym);
return S_TRI(e->left.sym->curr);
case E_AND:
val1 = expr_calc_value(e->left.expr);
val2 = expr_calc_value(e->right.expr);
return E_AND(val1, val2);
case E_OR:
val1 = expr_calc_value(e->left.expr);
val2 = expr_calc_value(e->right.expr);
return E_OR(val1, val2);
case E_NOT:
val1 = expr_calc_value(e->left.expr);
return E_NOT(val1);
case E_EQUAL:
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
return !strcmp(str1, str2) ? yes : no;
case E_UNEQUAL:
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
return !strcmp(str1, str2) ? no : yes;
default:
printf("expr_calc_value: %d?\n", e->type);
return no;
}
}
int expr_compare_type(enum expr_type t1, enum expr_type t2)
{
#if 0
return 1;
#else
if (t1 == t2)
return 0;
switch (t1) {
case E_EQUAL:
case E_UNEQUAL:
if (t2 == E_NOT)
return 1;
case E_NOT:
if (t2 == E_AND)
return 1;
case E_AND:
if (t2 == E_OR)
return 1;
case E_OR:
if (t2 == E_CHOICE)
return 1;
case E_CHOICE:
if (t2 == 0)
return 1;
default:
return -1;
}
printf("[%dgt%d?]", t1, t2);
return 0;
#endif
}
void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
{
if (!e) {
fn(data, "y");
return;
}
if (expr_compare_type(prevtoken, e->type) > 0)
fn(data, "(");
switch (e->type) {
case E_SYMBOL:
if (e->left.sym->name)
fn(data, e->left.sym->name);
else
fn(data, "<choice>");
break;
case E_NOT:
fn(data, "!");
expr_print(e->left.expr, fn, data, E_NOT);
break;
case E_EQUAL:
fn(data, e->left.sym->name);
fn(data, "=");
fn(data, e->right.sym->name);
break;
case E_UNEQUAL:
fn(data, e->left.sym->name);
fn(data, "!=");
fn(data, e->right.sym->name);
break;
case E_OR:
expr_print(e->left.expr, fn, data, E_OR);
fn(data, " || ");
expr_print(e->right.expr, fn, data, E_OR);
break;
case E_AND:
expr_print(e->left.expr, fn, data, E_AND);
fn(data, " && ");
expr_print(e->right.expr, fn, data, E_AND);
break;
case E_CHOICE:
if (e->left.expr) {
expr_print(e->left.expr, fn, data, E_CHOICE);
fn(data, " ^ ");
}
fn(data, e->right.sym->name);
break;
default:
{
char buf[32];
sprintf(buf, "<unknown type %d>", e->type);
fn(data, buf);
break;
}
}
if (expr_compare_type(prevtoken, e->type) > 0)
fn(data, ")");
}
static void expr_print_file_helper(void *data, const char *str)
{
fwrite(str, strlen(str), 1, data);
}
void expr_fprint(struct expr *e, FILE *out)
{
expr_print(e, expr_print_file_helper, out, E_NONE);
}
void print_expr(int mask, struct expr *e, int prevtoken)
{
if (!(cdebug & mask))
return;
expr_fprint(e, stdout);
}
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#ifndef EXPR_H
#define EXPR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
struct file {
struct file *next;
struct file *parent;
#ifdef CML1
struct statement *stmt;
struct statement *last_stmt;
#endif
char *name;
int lineno;
int flags;
};
#define FILE_BUSY 0x0001
#define FILE_SCANNED 0x0002
#define FILE_PRINTED 0x0004
typedef enum tristate {
no, mod, yes
} tristate;
enum expr_type {
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL
};
union expr_data {
struct expr *expr;
struct symbol *sym;
};
struct expr {
#ifdef CML1
int token;
#else
enum expr_type type;
#endif
union expr_data left, right;
};
#define E_TRI(ev) ((ev).tri)
#define E_EXPR(ev) ((ev).expr)
#define E_CALC(ev) (E_TRI(ev) = expr_calc_value(E_EXPR(ev)))
#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
#define E_NOT(dep) (2-(dep))
struct expr_value {
struct expr *expr;
tristate tri;
};
#define S_VAL(sv) ((sv).value)
#define S_TRI(sv) ((sv).tri)
#define S_EQ(sv1, sv2) (S_VAL(sv1) == S_VAL(sv2) || !strcmp(S_VAL(sv1), S_VAL(sv2)))
struct symbol_value {
void *value;
tristate tri;
};
enum symbol_type {
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
};
struct symbol {
struct symbol *next;
char *name;
char *help;
#ifdef CML1
int type;
#else
enum symbol_type type;
#endif
struct symbol_value curr, def;
tristate visible;
int flags;
struct property *prop;
struct expr *dep, *dep2;
struct menu *menu;
};
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
#ifdef CML1
#define SYMBOL_UNKNOWN S_UNKNOWN
#define SYMBOL_BOOLEAN S_BOOLEAN
#define SYMBOL_TRISTATE S_TRISTATE
#define SYMBOL_INT S_INT
#define SYMBOL_HEX S_HEX
#define SYMBOL_STRING S_STRING
#define SYMBOL_OTHER S_OTHER
#endif
#define SYMBOL_YES 0x0001
#define SYMBOL_MOD 0x0002
#define SYMBOL_NO 0x0004
#define SYMBOL_CONST 0x0007
#define SYMBOL_CHECK 0x0008
#define SYMBOL_CHOICE 0x0010
#define SYMBOL_CHOICEVAL 0x0020
#define SYMBOL_PRINTED 0x0040
#define SYMBOL_VALID 0x0080
#define SYMBOL_OPTIONAL 0x0100
#define SYMBOL_WRITE 0x0200
#define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257
#define SYMBOL_HASHMASK 0xff
enum prop_type {
P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE
};
struct property {
struct property *next;
struct symbol *sym;
#ifdef CML1
int token;
#else
enum prop_type type;
#endif
const char *text;
struct symbol *def;
struct expr_value visible;
struct expr *dep;
struct expr *dep2;
struct menu *menu;
struct file *file;
int lineno;
#ifdef CML1
struct property *next_pos;
#endif
};
#define for_all_properties(sym, st, tok) \
for (st = sym->prop; st; st = st->next) \
if (st->type == (tok))
#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT)
#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
struct menu {
struct menu *next;
struct menu *parent;
struct menu *list;
struct symbol *sym;
struct property *prompt;
struct expr *dep;
//char *help;
struct file *file;
int lineno;
//void *data;
};
#ifndef SWIG
extern struct file *file_list;
extern struct file *current_file;
struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym;
extern int cdebug;
extern int print_type;
struct expr *expr_alloc_symbol(struct symbol *sym);
#ifdef CML1
struct expr *expr_alloc_one(int token, struct expr *ce);
struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2);
struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2);
#else
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
#endif
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
struct expr *expr_copy(struct expr *org);
void expr_free(struct expr *e);
int expr_eq(struct expr *e1, struct expr *e2);
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
tristate expr_calc_value(struct expr *e);
struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_trans_bool(struct expr *e);
struct expr *expr_eliminate_dups(struct expr *e);
struct expr *expr_transform(struct expr *e);
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
void expr_fprint(struct expr *e, FILE *out);
void print_expr(int mask, struct expr *e, int prevtoken);
#ifdef CML1
static inline int expr_is_yes(struct expr *e)
{
return !e || (e->token == WORD && e->left.sym == &symbol_yes);
}
static inline int expr_is_no(struct expr *e)
{
return e && (e->token == WORD && e->left.sym == &symbol_no);
}
#else
static inline int expr_is_yes(struct expr *e)
{
return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
}
static inline int expr_is_no(struct expr *e)
{
return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
}
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* EXPR_H */
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
static const char *xpm_load[] = {
"22 22 5 1",
". c None",
"# c #000000",
"c c #838100",
"a c #ffff00",
"b c #ffffff",
"......................",
"......................",
"......................",
"............####....#.",
"...........#....##.##.",
"..................###.",
".................####.",
".####...........#####.",
"#abab##########.......",
"#babababababab#.......",
"#ababababababa#.......",
"#babababababab#.......",
"#ababab###############",
"#babab##cccccccccccc##",
"#abab##cccccccccccc##.",
"#bab##cccccccccccc##..",
"#ab##cccccccccccc##...",
"#b##cccccccccccc##....",
"###cccccccccccc##.....",
"##cccccccccccc##......",
"###############.......",
"......................"};
static const char *xpm_save[] = {
"22 22 5 1",
". c None",
"# c #000000",
"a c #838100",
"b c #c5c2c5",
"c c #cdb6d5",
"......................",
".####################.",
".#aa#bbbbbbbbbbbb#bb#.",
".#aa#bbbbbbbbbbbb#bb#.",
".#aa#bbbbbbbbbcbb####.",
".#aa#bbbccbbbbbbb#aa#.",
".#aa#bbbccbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aaa############aaa#.",
".#aaaaaaaaaaaaaaaaaa#.",
".#aaaaaaaaaaaaaaaaaa#.",
".#aaa#############aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
"..##################..",
"......................"};
static const char *xpm_back[] = {
"22 22 3 1",
". c None",
"# c #000083",
"a c #838183",
"......................",
"......................",
"......................",
"......................",
"......................",
"...........######a....",
"..#......##########...",
"..##...####......##a..",
"..###.###.........##..",
"..######..........##..",
"..#####...........##..",
"..######..........##..",
"..#######.........##..",
"..########.......##a..",
"...............a###...",
"...............###....",
"......................",
"......................",
"......................",
"......................",
"......................",
"......................"};
static const char *xpm_tree_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
"......................",
"......................",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......########........",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......########........",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......########........",
"......................",
"......................"};
static const char *xpm_single_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
"......................",
"......................",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"......................",
"......................"};
static const char *xpm_split_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
"......................",
"......................",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......................",
"......................"};
static const char *xpm_symbol_no[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" .......... ",
" "};
static const char *xpm_symbol_mod[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . . ",
" . .. . ",
" . .... . ",
" . .... . ",
" . .. . ",
" . . ",
" . . ",
" .......... ",
" "};
static const char *xpm_symbol_yes[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . . ",
" . . . ",
" . .. . ",
" . . .. . ",
" . .... . ",
" . .. . ",
" . . ",
" .......... ",
" "};
static const char *xpm_choice_no[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .... ",
" .. .. ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" .. .. ",
" .... ",
" "};
static const char *xpm_choice_yes[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .... ",
" .. .. ",
" . . ",
" . .. . ",
" . .... . ",
" . .... . ",
" . .. . ",
" . . ",
" .. .. ",
" .... ",
" "};
static const char *xpm_menu[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . .. . ",
" . .... . ",
" . ...... . ",
" . ...... . ",
" . .... . ",
" . .. . ",
" . . ",
" .......... ",
" "};
static const char *xpm_menu_inv[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" .......... ",
" .. ...... ",
" .. .... ",
" .. .. ",
" .. .. ",
" .. .... ",
" .. ...... ",
" .......... ",
" .......... ",
" "};
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include "lkc.h"
#define P(name,type,arg) type (*name ## _p) arg
#include "lkc_proto.h"
#undef P
void kconfig_load(void)
{
void *handle;
char *error;
handle = dlopen("./libkconfig.so", RTLD_LAZY);
if (!handle) {
handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
}
#define P(name,type,arg) \
{ \
name ## _p = dlsym(handle, #name); \
if ((error = dlerror())) { \
fprintf(stderr, "%s\n", error); \
exit(1); \
} \
}
#include "lkc_proto.h"
#undef P
}
#define yy_create_buffer zconf_create_buffer
#define yy_delete_buffer zconf_delete_buffer
#define yy_scan_buffer zconf_scan_buffer
#define yy_scan_string zconf_scan_string
#define yy_scan_bytes zconf_scan_bytes
#define yy_flex_debug zconf_flex_debug
#define yy_init_buffer zconf_init_buffer
#define yy_flush_buffer zconf_flush_buffer
#define yy_load_buffer_state zconf_load_buffer_state
#define yy_switch_to_buffer zconf_switch_to_buffer
#define yyin zconfin
#define yyleng zconfleng
#define yylex zconflex
#define yyout zconfout
#define yyrestart zconfrestart
#define yytext zconftext
/* A lexical scanner generated by flex */
/* Scanner skeleton version:
* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
*/
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#include <stdio.h>
#include <errno.h>
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
#ifdef c_plusplus
#ifndef __cplusplus
#define __cplusplus
#endif
#endif
#ifdef __cplusplus
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#endif
/* Use prototypes in function declarations. */
#define YY_USE_PROTOS
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#else /* ! __cplusplus */
#if __STDC__
#define YY_USE_PROTOS
#define YY_USE_CONST
#endif /* __STDC__ */
#endif /* ! __cplusplus */
#ifdef __TURBOC__
#pragma warn -rch
#pragma warn -use
#include <io.h>
#include <stdlib.h>
#define YY_USE_CONST
#define YY_USE_PROTOS
#endif
#ifdef YY_USE_CONST
#define yyconst const
#else
#define yyconst
#endif
#ifdef YY_USE_PROTOS
#define YY_PROTO(proto) proto
#else
#define YY_PROTO(proto) ()
#endif
/* Returned upon end-of-file. */
#define YY_NULL 0
/* Promotes a possibly negative, possibly signed char to an unsigned
* integer for use as an array index. If the signed char is negative,
* we want to instead treat it as an 8-bit unsigned char, hence the
* double cast.
*/
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
/* Enter a start condition. This macro really ought to take a parameter,
* but we do it the disgusting crufty way forced on us by the ()-less
* definition of BEGIN.
*/
#define BEGIN yy_start = 1 + 2 *
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yy_start - 1) / 2)
#define YYSTATE YY_START
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
/* Special action meaning "start processing a new file". */
#define YY_NEW_FILE yyrestart( yyin )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
#define YY_BUF_SIZE 16384
typedef struct yy_buffer_state *YY_BUFFER_STATE;
extern int yyleng;
extern FILE *yyin, *yyout;
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
/* The funky do-while in the following #define is used to turn the definition
* int a single C statement (which needs a semi-colon terminator). This
* avoids problems with code like:
*
* if ( condition_holds )
* yyless( 5 );
* else
* do_something_else();
*
* Prior to using the do-while the compiler would get upset at the
* "else" because it interpreted the "if" statement as being all
* done when it reached the ';' after the yyless() call.
*/
/* Return all but the first 'n' matched characters back to the input stream. */
#define yyless(n) \
do \
{ \
/* Undo effects of setting up yytext. */ \
*yy_cp = yy_hold_char; \
YY_RESTORE_YY_MORE_OFFSET \
yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
#define unput(c) yyunput( c, yytext_ptr )
/* The following is because we cannot portably get our hands on size_t
* (without autoconf's help, which isn't available because we want
* flex-generated scanners to compile on their own).
*/
typedef unsigned int yy_size_t;
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
yy_size_t yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
#define YY_BUFFER_NEW 0
#define YY_BUFFER_NORMAL 1
/* When an EOF's been seen but there's still some text to process
* then we mark the buffer as YY_EOF_PENDING, to indicate that we
* shouldn't try reading from the input source any more. We might
* still have a bunch of tokens to match, though, because of
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
* (via yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
};
static YY_BUFFER_STATE yy_current_buffer = 0;
/* We provide macros for accessing buffer states in case in the
* future we want to put the buffer states in a more general
* "scanner state".
*/
#define YY_CURRENT_BUFFER yy_current_buffer
/* yy_hold_char holds the character lost when yytext is formed. */
static char yy_hold_char;
static int yy_n_chars; /* number of characters read into yy_ch_buf */
int yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
static int yy_init = 1; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
/* Flag which is used to allow yywrap()'s to do buffer switches
* instead of setting up a fresh yyin. A bit of a hack ...
*/
static int yy_did_buffer_switch_on_eof;
void yyrestart YY_PROTO(( FILE *input_file ));
void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
void yy_load_buffer_state YY_PROTO(( void ));
YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
static void yy_flex_free YY_PROTO(( void * ));
#define yy_new_buffer yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! yy_current_buffer ) \
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
yy_current_buffer->yy_is_interactive = is_interactive; \
}
#define yy_set_bol(at_bol) \
{ \
if ( ! yy_current_buffer ) \
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
yy_current_buffer->yy_at_bol = at_bol; \
}
#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
#define yywrap() 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
typedef int yy_state_type;
extern char *yytext;
#define yytext_ptr yytext
static yyconst short yy_nxt[][37] =
{
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
},
{
11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12
},
{
11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12
},
{
11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
16, 16, 16, 18, 16, 16, 18, 19, 20, 21,
22, 18, 18, 23, 24, 18, 25, 18, 26, 27,
18, 28, 29, 30, 18, 18, 16
},
{
11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
16, 16, 16, 18, 16, 16, 18, 19, 20, 21,
22, 18, 18, 23, 24, 18, 25, 18, 26, 27,
18, 28, 29, 30, 18, 18, 16
},
{
11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31
},
{
11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31
},
{
11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34
},
{
11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34
},
{
11, 38, 38, 39, 40, 41, 38, 42, 41, 43,
44, 45, 46, 46, 47, 38, 46, 46, 46, 46,
46, 46, 46, 46, 48, 46, 46, 46, 49, 46,
46, 46, 46, 46, 46, 46, 50
},
{
11, 38, 38, 39, 40, 41, 38, 42, 41, 43,
44, 45, 46, 46, 47, 38, 46, 46, 46, 46,
46, 46, 46, 46, 48, 46, 46, 46, 49, 46,
46, 46, 46, 46, 46, 46, 50
},
{
-11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
-11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
-11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
-11, -11, -11, -11, -11, -11, -11
},
{
11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
-12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
-12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
-12, -12, -12, -12, -12, -12, -12
},
{
11, -13, 51, 52, -13, -13, 53, -13, -13, -13,
-13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
-13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
-13, -13, -13, -13, -13, -13, -13
},
{
11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
-14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
-14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
-14, -14, -14, -14, -14, -14, -14
},
{
11, 54, 54, 55, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54
},
{
11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
-16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
-16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
-16, -16, -16, -16, -16, -16, -16
},
{
11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
-17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
-17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
-17, -17, -17, -17, -17, -17, -17
},
{
11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
-18, -18, -18, 56, -18, -18, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -18
},
{
11, -19, -19, -19, -19, -19, -19, -19, -19, -19,
-19, -19, -19, 56, -19, -19, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 57, 56,
56, 56, 56, 56, 56, 56, -19
},
{
11, -20, -20, -20, -20, -20, -20, -20, -20, -20,
-20, -20, -20, 56, -20, -20, 56, 56, 56, 56,
56, 56, 56, 58, 56, 56, 56, 56, 59, 56,
56, 56, 56, 56, 56, 56, -20
},
{
11, -21, -21, -21, -21, -21, -21, -21, -21, -21,
-21, -21, -21, 56, -21, -21, 56, 56, 56, 56,
60, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -21
},
{
11, -22, -22, -22, -22, -22, -22, -22, -22, -22,
-22, -22, -22, 56, -22, -22, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 61, 56, 56,
56, 56, 56, 56, 56, 56, -22
},
{
11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
-23, -23, -23, 56, -23, -23, 56, 56, 56, 56,
62, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -23
},
{
11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
-24, -24, -24, 56, -24, -24, 56, 56, 56, 56,
56, 63, 56, 56, 56, 56, 56, 64, 56, 56,
56, 56, 56, 56, 56, 56, -24
},
{
11, -25, -25, -25, -25, -25, -25, -25, -25, -25,
-25, -25, -25, 56, -25, -25, 65, 56, 56, 56,
66, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -25
},
{
11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
-26, -26, -26, 56, -26, -26, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 67,
56, 56, 56, 56, 56, 56, -26
},
{
11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
-27, -27, -27, 56, -27, -27, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 68, 56, 56, 56, 56, -27
},
{
11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
-28, -28, -28, 56, -28, -28, 56, 56, 56, 56,
69, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -28
},
{
11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
-29, -29, -29, 56, -29, -29, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 70, 56,
56, 56, 56, 71, 56, 56, -29
},
{
11, -30, -30, -30, -30, -30, -30, -30, -30, -30,
-30, -30, -30, 56, -30, -30, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 72, 56, 56, 56, 56, -30
},
{
11, 73, 73, -31, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73
},
{
11, -32, 74, 75, -32, -32, -32, -32, -32, -32,
-32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-32, -32, -32, -32, -32, -32, -32
},
{
11, 76, -33, -33, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76
},
{
11, 77, 77, -34, 77, -34, 77, 77, -34, 77,
77, 77, 77, 77, 77, -34, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77
},
{
11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
-35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
-35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
-35, -35, -35, -35, -35, -35, -35
},
{
11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
-36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
-36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
-36, -36, -36, -36, -36, -36, -36
},
{
11, 78, 79, 80, 78, 78, 78, 78, 78, 78,
78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 78, 78, 78, 78
},
{
11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
-38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
-38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
-38, -38, -38, -38, -38, -38, -38
},
{
11, -39, -39, -39, -39, -39, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39
},
{
11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, 81, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40
},
{
11, -41, -41, -41, -41, -41, -41, -41, -41, -41,
-41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
-41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
-41, -41, -41, -41, -41, -41, -41
},
{
11, -42, -42, -42, -42, -42, -42, 82, -42, -42,
-42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
-42, -42, -42, -42, -42, -42, -42, -42, -42, -42,
-42, -42, -42, -42, -42, -42, -42
},
{
11, -43, -43, -43, -43, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43
},
{
11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
-44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
-44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
-44, -44, -44, -44, -44, -44, -44
},
{
11, -45, -45, -45, -45, -45, -45, -45, -45, -45,
-45, 83, 84, 84, -45, -45, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -45
},
{
11, -46, -46, -46, -46, -46, -46, -46, -46, -46,
-46, 84, 84, 84, -46, -46, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -46
},
{
11, -47, -47, -47, -47, -47, -47, -47, -47, -47,
-47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
-47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
-47, -47, -47, -47, -47, -47, -47
},
{
11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
-48, 84, 84, 84, -48, -48, 84, 84, 84, 84,
84, 85, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -48
},
{
11, -49, -49, -49, -49, -49, -49, -49, -49, -49,
-49, 84, 84, 84, -49, -49, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 86, 84, 84,
84, 84, 84, 84, 84, 84, -49
},
{
11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
-50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
-50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
-50, -50, -50, -50, -50, -50, 87
},
{
11, -51, 51, 52, -51, -51, 53, -51, -51, -51,
-51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
-51, -51, -51, -51, -51, -51, -51, -51, -51, -51,
-51, -51, -51, -51, -51, -51, -51
},
{
11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
-52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
-52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
-52, -52, -52, -52, -52, -52, -52
},
{
11, 54, 54, 55, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54
},
{
11, 54, 54, 55, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54
},
{
11, -55, -55, -55, -55, -55, -55, -55, -55, -55,
-55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
-55, -55, -55, -55, -55, -55, -55, -55, -55, -55,
-55, -55, -55, -55, -55, -55, -55
},
{
11, -56, -56, -56, -56, -56, -56, -56, -56, -56,
-56, -56, -56, 56, -56, -56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -56
},
{
11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
-57, -57, -57, 56, -57, -57, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 88, 56,
56, 56, 56, 56, 56, 56, -57
},
{
11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
-58, -58, -58, 56, -58, -58, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 89, 56,
56, 56, 56, 56, 56, 56, -58
},
{
11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
-59, -59, -59, 56, -59, -59, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 90, 91, 56, 56,
56, 56, 56, 56, 56, 56, -59
},
{
11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
-60, -60, -60, 56, -60, -60, 56, 56, 56, 56,
56, 92, 56, 56, 56, 56, 56, 56, 56, 93,
56, 56, 56, 56, 56, 56, -60
},
{
11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
-61, -61, -61, 56, -61, -61, 56, 56, 56, 94,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -61
},
{
11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
-62, -62, -62, 56, -62, -62, 56, 56, 56, 56,
56, 56, 56, 56, 56, 95, 56, 56, 56, 56,
56, 56, 56, 56, 56, 96, -62
},
{
11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
-63, -63, -63, 56, -63, -63, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -63
},
{
11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
-64, -64, -64, 56, -64, -64, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 97, 56, 56, -64
},
{
11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
-65, -65, -65, 56, -65, -65, 56, 56, 56, 56,
56, 56, 56, 56, 98, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -65
},
{
11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
-66, -66, -66, 56, -66, -66, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 99, 56, 56,
56, 56, 56, 56, 56, 56, -66
},
{
11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
-67, -67, -67, 56, -67, -67, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 100, 56, 56, -67
},
{
11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
-68, -68, -68, 56, -68, -68, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 101, 56,
56, 56, 56, 56, 56, 56, -68
},
{
11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
-69, -69, -69, 56, -69, -69, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
102, 56, 56, 56, 56, 56, -69
},
{
11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
-70, -70, -70, 56, -70, -70, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 103, 56, -70
},
{
11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
-71, -71, -71, 56, -71, -71, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 104, 56, 56, 56, 56, -71
},
{
11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
-72, -72, -72, 56, -72, -72, 56, 56, 56, 56,
56, 56, 56, 56, 105, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -72
},
{
11, 73, 73, -73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73
},
{
11, -74, 74, 75, -74, -74, -74, -74, -74, -74,
-74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
-74, -74, -74, -74, -74, -74, -74, -74, -74, -74,
-74, -74, -74, -74, -74, -74, -74
},
{
11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
-75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
-75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
-75, -75, -75, -75, -75, -75, -75
},
{
11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
-76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
-76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
-76, -76, -76, -76, -76, -76, -76
},
{
11, 77, 77, -77, 77, -77, 77, 77, -77, 77,
77, 77, 77, 77, 77, -77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77
},
{
11, -78, -78, -78, -78, -78, -78, -78, -78, -78,
-78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
-78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
-78, -78, -78, -78, -78, -78, -78
},
{
11, -79, 106, 80, -79, -79, -79, -79, -79, -79,
-79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
-79, -79, -79, -79, -79, -79, -79, -79, -79, -79,
-79, -79, -79, -79, -79, -79, -79
},
{
11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
-80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
-80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
-80, -80, -80, -80, -80, -80, -80
},
{
11, -81, -81, -81, -81, -81, -81, -81, -81, -81,
-81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
-81, -81, -81, -81, -81, -81, -81, -81, -81, -81,
-81, -81, -81, -81, -81, -81, -81
},
{
11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
-82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
-82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
-82, -82, -82, -82, -82, -82, -82
},
{
11, -83, -83, -83, -83, -83, -83, -83, -83, -83,
-83, 107, 84, 84, -83, -83, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -83
},
{
11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
-84, 84, 84, 84, -84, -84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -84
},
{
11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
-85, 84, 84, 84, -85, -85, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -85
},
{
11, -86, -86, -86, -86, -86, -86, -86, -86, -86,
-86, 84, 84, 84, -86, -86, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -86
},
{
11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
-87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
-87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
-87, -87, -87, -87, -87, -87, -87
},
{
11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
-88, -88, -88, 56, -88, -88, 56, 56, 56, 56,
56, 56, 56, 56, 56, 108, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -88
},
{
11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
-89, -89, -89, 56, -89, -89, 56, 56, 56, 56,
56, 56, 56, 56, 109, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -89
},
{
11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
-90, -90, -90, 56, -90, -90, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 110, 56, 56, 56,
56, 56, 56, 56, 56, 56, -90
},
{
11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
-91, -91, -91, 56, -91, -91, 56, 56, 56, 56,
56, 111, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -91
},
{
11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
-92, -92, -92, 56, -92, -92, 112, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -92
},
{
11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
-93, -93, -93, 56, -93, -93, 56, 56, 56, 56,
113, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -93
},
{
11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
-94, -94, -94, 56, -94, -94, 56, 56, 114, 56,
56, 56, 56, 56, 115, 56, 116, 56, 56, 56,
56, 56, 56, 56, 56, 56, -94
},
{
11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
-95, -95, -95, 56, -95, -95, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 117,
56, 56, 56, 56, 56, 56, -95
},
{
11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
-96, -96, -96, 56, -96, -96, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -96
},
{
11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
-97, -97, -97, 56, -97, -97, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -97
},
{
11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
-98, -98, -98, 56, -98, -98, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 118, 56, 56,
56, 56, 56, 56, 56, 56, -98
},
{
11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
-99, -99, -99, 56, -99, -99, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 119, 56, -99
},
{
11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
-100, -100, -100, 56, -100, -100, 56, 56, 56, 56,
56, 56, 56, 56, 120, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -100
},
{
11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
-101, -101, -101, 56, -101, -101, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 121, 56, 56, 56,
56, 56, 56, 56, 56, 56, -101
},
{
11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
-102, -102, -102, 56, -102, -102, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 122, 56, -102
},
{
11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
-103, -103, -103, 56, -103, -103, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 123, 56, 56, 56, 56, -103
},
{
11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
-104, -104, -104, 56, -104, -104, 56, 56, 56, 56,
56, 56, 56, 56, 124, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -104
},
{
11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
-105, -105, -105, 56, -105, -105, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 125, 56, 56, 56, -105
},
{
11, -106, 106, 80, -106, -106, -106, -106, -106, -106,
-106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
-106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
-106, -106, -106, -106, -106, -106, -106
},
{
11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
-107, 84, 84, 84, -107, -107, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, -107
},
{
11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
-108, -108, -108, 56, -108, -108, 56, 56, 56, 56,
126, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -108
},
{
11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
-109, -109, -109, 56, -109, -109, 56, 56, 127, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -109
},
{
11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
-110, -110, -110, 56, -110, -110, 56, 56, 56, 56,
128, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -110
},
{
11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
-111, -111, -111, 56, -111, -111, 56, 56, 56, 56,
56, 56, 56, 56, 129, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -111
},
{
11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
-112, -112, -112, 56, -112, -112, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 130, 56, -112
},
{
11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
-113, -113, -113, 56, -113, -113, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 131, 56, 56,
56, 56, 56, 56, 56, 56, -113
},
{
11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
-114, -114, -114, 56, -114, -114, 56, 56, 56, 56,
56, 56, 56, 132, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -114
},
{
11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
-115, -115, -115, 56, -115, -115, 56, 56, 56, 56,
56, 133, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -115
},
{
11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
-116, -116, -116, 56, -116, -116, 56, 56, 56, 56,
134, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -116
},
{
11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
-117, -117, -117, 56, -117, -117, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -117
},
{
11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
-118, -118, -118, 56, -118, -118, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 135, 56, 56, 56,
56, 56, 56, 56, 56, 56, -118
},
{
11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
-119, -119, -119, 56, -119, -119, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -119
},
{
11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
-120, -120, -120, 56, -120, -120, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 136, 56,
56, 56, 56, 56, 56, 56, -120
},
{
11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
-121, -121, -121, 56, -121, -121, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 137,
56, 56, 56, 56, 56, 56, -121
},
{
11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
-122, -122, -122, 56, -122, -122, 56, 56, 56, 56,
56, 56, 56, 56, 138, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -122
},
{
11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
-123, -123, -123, 56, -123, -123, 56, 56, 139, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -123
},
{
11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
-124, -124, -124, 56, -124, -124, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 140, 56, 56,
56, 56, 56, 56, 56, 56, -124
},
{
11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
-125, -125, -125, 56, -125, -125, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 141, 56, 56, -125
},
{
11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
-126, -126, -126, 56, -126, -126, 142, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -126
},
{
11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
-127, -127, -127, 56, -127, -127, 56, 56, 56, 56,
143, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -127
},
{
11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, 56, -128, -128, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 144, 56, 56,
56, 56, 56, 56, 56, 56, -128
},
{
11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
-129, -129, -129, 56, -129, -129, 56, 56, 56, 56,
56, 56, 145, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -129
},
{
11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
-130, -130, -130, 56, -130, -130, 56, 56, 56, 56,
56, 56, 56, 56, 56, 146, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -130
},
{
11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
-131, -131, -131, 56, -131, -131, 56, 56, 56, 147,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -131
},
{
11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
-132, -132, -132, 56, -132, -132, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 148, 56,
56, 56, 56, 56, 56, 56, -132
},
{
11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
-133, -133, -133, 56, -133, -133, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -133
},
{
11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
-134, -134, -134, 56, -134, -134, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 149, 56, 56,
56, 56, 56, 56, 56, 56, -134
},
{
11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
-135, -135, -135, 56, -135, -135, 56, 56, 56, 56,
150, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -135
},
{
11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
-136, -136, -136, 56, -136, -136, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 151, 56, 56,
56, 56, 56, 56, 56, 56, -136
},
{
11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
-137, -137, -137, 56, -137, -137, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 152, 56, 56, -137
},
{
11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
-138, -138, -138, 56, -138, -138, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 153, 56, 56, 56, 56, -138
},
{
11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
-139, -139, -139, 56, -139, -139, 56, 56, 56, 56,
154, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -139
},
{
11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
-140, -140, -140, 56, -140, -140, 56, 56, 56, 56,
56, 56, 155, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -140
},
{
11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
-141, -141, -141, 56, -141, -141, 156, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -141
},
{
11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
-142, -142, -142, 56, -142, -142, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 157, 56, 56,
56, 56, 56, 56, 56, 56, -142
},
{
11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
-143, -143, -143, 56, -143, -143, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -143
},
{
11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
-144, -144, -144, 56, -144, -144, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 158, 56, 56, -144
},
{
11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
-145, -145, -145, 56, -145, -145, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -145
},
{
11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
-146, -146, -146, 56, -146, -146, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 159, 56, 56, -146
},
{
11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
-147, -147, -147, 56, -147, -147, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 160, 56, 56, 56, -147
},
{
11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
-148, -148, -148, 56, -148, -148, 56, 56, 56, 56,
56, 56, 56, 56, 161, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -148
},
{
11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
-149, -149, -149, 56, -149, -149, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 162, 56, -149
},
{
11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
-150, -150, -150, 56, -150, -150, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 163, 56, 56,
56, 56, 56, 56, 56, 56, -150
},
{
11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
-151, -151, -151, 56, -151, -151, 164, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -151
},
{
11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
-152, -152, -152, 56, -152, -152, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -152
},
{
11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
-153, -153, -153, 56, -153, -153, 56, 56, 56, 56,
165, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -153
},
{
11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
-154, -154, -154, 56, -154, -154, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -154
},
{
11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
-155, -155, -155, 56, -155, -155, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -155
},
{
11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
-156, -156, -156, 56, -156, -156, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 166, 56, 56, -156
},
{
11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
-157, -157, -157, 56, -157, -157, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -157
},
{
11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
-158, -158, -158, 56, -158, -158, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -158
},
{
11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
-159, -159, -159, 56, -159, -159, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -159
},
{
11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
-160, -160, -160, 56, -160, -160, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -160
},
{
11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
-161, -161, -161, 56, -161, -161, 56, 56, 167, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -161
},
{
11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
-162, -162, -162, 56, -162, -162, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -162
},
{
11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
-163, -163, -163, 56, -163, -163, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 168, 56, -163
},
{
11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
-164, -164, -164, 56, -164, -164, 56, 56, 56, 56,
56, 56, 56, 56, 56, 169, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -164
},
{
11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
-165, -165, -165, 56, -165, -165, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 170, 56, 56, 56, -165
},
{
11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
-166, -166, -166, 56, -166, -166, 56, 56, 56, 56,
171, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -166
},
{
11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
-167, -167, -167, 56, -167, -167, 56, 56, 56, 56,
172, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -167
},
{
11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
-168, -168, -168, 56, -168, -168, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -168
},
{
11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
-169, -169, -169, 56, -169, -169, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -169
},
{
11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
-170, -170, -170, 56, -170, -170, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -170
},
{
11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
-171, -171, -171, 56, -171, -171, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -171
},
{
11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
-172, -172, -172, 56, -172, -172, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, -172
},
} ;
static yy_state_type yy_get_previous_state YY_PROTO(( void ));
static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
static int yy_get_next_buffer YY_PROTO(( void ));
static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yytext_ptr = yy_bp; \
yyleng = (int) (yy_cp - yy_bp); \
yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yy_c_buf_p = yy_cp;
#define YY_NUM_RULES 55
#define YY_END_OF_BUFFER 56
static yyconst short int yy_accept[173] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56, 5, 4, 3, 2, 29, 30, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
54, 51, 53, 45, 50, 46, 48, 44, 41, 35,
40, 44, 33, 34, 43, 43, 36, 43, 43, 44,
4, 3, 2, 2, 1, 28, 28, 28, 28, 28,
28, 28, 15, 28, 28, 28, 28, 28, 28, 28,
28, 28, 54, 51, 53, 52, 45, 49, 48, 47,
37, 31, 43, 43, 38, 39, 32, 28, 28, 28,
28, 28, 28, 28, 28, 26, 25, 28, 28, 28,
28, 28, 28, 28, 28, 48, 42, 23, 28, 28,
28, 28, 28, 28, 28, 28, 14, 28, 7, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 16, 28, 28, 28, 28, 28, 28, 28,
28, 28, 10, 28, 13, 28, 28, 28, 28, 28,
28, 21, 28, 9, 27, 28, 24, 12, 20, 17,
28, 8, 28, 28, 28, 28, 28, 6, 19, 18,
22, 11
} ;
static yyconst int yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 4, 5, 6, 1, 1, 7, 8, 9,
10, 1, 1, 1, 11, 12, 12, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 1, 1, 1,
14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1, 15, 1, 1, 13, 1, 16, 17, 18, 19,
20, 21, 22, 23, 24, 13, 13, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 13, 13, 35,
13, 13, 1, 36, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
} ;
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
*/
#define REJECT reject_used_but_not_detected
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
char *yytext;
#line 1 "zconf.l"
#define INITIAL 0
#define COMMAND 1
#define HELP 2
#define STRING 3
#define PARAM 4
#line 5 "zconf.l"
/*
* 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>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#include "zconf.tab.h"
#define START_STRSIZE 16
char *text;
static char *text_ptr;
static int text_size, text_asize;
struct buffer {
struct buffer *parent;
YY_BUFFER_STATE state;
};
struct buffer *current_buf;
static int last_ts, first_ts;
static void zconf_endhelp(void);
static struct buffer *zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
text_ptr = text;
text_size = 0;
*text_ptr = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
text = realloc(text, new_size);
text_asize = new_size;
text_ptr = text + text_size;
}
memcpy(text_ptr, str, size);
text_ptr += size;
text_size += size;
*text_ptr = 0;
}
void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
memcpy(text, str, size);
text[size] = 0;
}
#line 1726 "lex.zconf.c"
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int yywrap YY_PROTO(( void ));
#else
extern int yywrap YY_PROTO(( void ));
#endif
#endif
#ifndef YY_NO_UNPUT
static void yyunput YY_PROTO(( int c, char *buf_ptr ));
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
#endif
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen YY_PROTO(( yyconst char * ));
#endif
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput YY_PROTO(( void ));
#else
static int input YY_PROTO(( void ));
#endif
#endif
#if YY_STACK_USED
static int yy_start_stack_ptr = 0;
static int yy_start_stack_depth = 0;
static int *yy_start_stack = 0;
#ifndef YY_NO_PUSH_STATE
static void yy_push_state YY_PROTO(( int new_state ));
#endif
#ifndef YY_NO_POP_STATE
static void yy_pop_state YY_PROTO(( void ));
#endif
#ifndef YY_NO_TOP_STATE
static int yy_top_state YY_PROTO(( void ));
#endif
#else
#define YY_NO_PUSH_STATE 1
#define YY_NO_POP_STATE 1
#define YY_NO_TOP_STATE 1
#endif
#ifdef YY_MALLOC_DECL
YY_MALLOC_DECL
#else
#if __STDC__
#ifndef __cplusplus
#include <stdlib.h>
#endif
#else
/* Just try to get by without declaring the routines. This will fail
* miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
* or sizeof(void*) != sizeof(int).
*/
#endif
#endif
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 8192
#endif
/* Copy whatever the last rule matched to the standard output. */
#ifndef ECHO
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
* is returned in "result".
*/
#ifndef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
errno=0; \
while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
{ \
if( errno != EINTR) \
{ \
YY_FATAL_ERROR( "input in flex scanner failed" ); \
break; \
} \
errno=0; \
clearerr(yyin); \
}
#endif
/* No semi-colon after return; correct usage is to write "yyterminate();" -
* we don't want an extra ';' after the "return" because that will cause
* some compilers to complain about unreachable statements.
*/
#ifndef yyterminate
#define yyterminate() return YY_NULL
#endif
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
/* Report a fatal error. */
#ifndef YY_FATAL_ERROR
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
#endif
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL int yylex YY_PROTO(( void ))
#endif
/* Code executed at the beginning of each rule, after yytext and yyleng
* have been set up.
*/
#ifndef YY_USER_ACTION
#define YY_USER_ACTION
#endif
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
#define YY_BREAK break;
#endif
#define YY_RULE_SETUP \
YY_USER_ACTION
YY_DECL
{
register yy_state_type yy_current_state;
register char *yy_cp, *yy_bp;
register int yy_act;
#line 71 "zconf.l"
int str = 0;
int ts, i;
#line 1878 "lex.zconf.c"
if ( yy_init )
{
yy_init = 0;
#ifdef YY_USER_INIT
YY_USER_INIT;
#endif
if ( ! yy_start )
yy_start = 1; /* first start state */
if ( ! yyin )
yyin = stdin;
if ( ! yyout )
yyout = stdout;
if ( ! yy_current_buffer )
yy_current_buffer =
yy_create_buffer( yyin, YY_BUF_SIZE );
yy_load_buffer_state();
}
while ( 1 ) /* loops until end-of-file is reached */
{
yy_cp = yy_c_buf_p;
/* Support of yytext. */
*yy_cp = yy_hold_char;
/* yy_bp points to the position in yy_ch_buf of the start of
* the current run.
*/
yy_bp = yy_cp;
yy_current_state = yy_start;
yy_match:
while ( (yy_current_state = yy_nxt[yy_current_state][yy_ec[YY_SC_TO_UI(*yy_cp)]]) > 0 )
++yy_cp;
yy_current_state = -yy_current_state;
yy_find_action:
yy_act = yy_accept[yy_current_state];
YY_DO_BEFORE_ACTION;
do_action: /* This label is used only to access EOF actions. */
switch ( yy_act )
{ /* beginning of action switch */
case 1:
YY_RULE_SETUP
#line 75 "zconf.l"
current_file->lineno++;
YY_BREAK
case 2:
YY_RULE_SETUP
#line 76 "zconf.l"
YY_BREAK
case 3:
YY_RULE_SETUP
#line 78 "zconf.l"
current_file->lineno++; return T_EOL;
YY_BREAK
case 4:
YY_RULE_SETUP
#line 80 "zconf.l"
{
BEGIN(COMMAND);
}
YY_BREAK
case 5:
YY_RULE_SETUP
#line 84 "zconf.l"
{
unput(yytext[0]);
//printf("new config: ");
//symbol_end(NULL);
BEGIN(COMMAND);
}
YY_BREAK
case 6:
YY_RULE_SETUP
#line 93 "zconf.l"
BEGIN(PARAM); return T_MAINMENU;
YY_BREAK
case 7:
YY_RULE_SETUP
#line 94 "zconf.l"
BEGIN(PARAM); return T_MENU;
YY_BREAK
case 8:
YY_RULE_SETUP
#line 95 "zconf.l"
BEGIN(PARAM); return T_ENDMENU;
YY_BREAK
case 9:
YY_RULE_SETUP
#line 96 "zconf.l"
BEGIN(PARAM); return T_SOURCE;
YY_BREAK
case 10:
YY_RULE_SETUP
#line 97 "zconf.l"
BEGIN(PARAM); return T_CHOICE;
YY_BREAK
case 11:
YY_RULE_SETUP
#line 98 "zconf.l"
BEGIN(PARAM); return T_ENDCHOICE;
YY_BREAK
case 12:
YY_RULE_SETUP
#line 99 "zconf.l"
BEGIN(PARAM); return T_COMMENT;
YY_BREAK
case 13:
YY_RULE_SETUP
#line 100 "zconf.l"
BEGIN(PARAM); return T_CONFIG;
YY_BREAK
case 14:
YY_RULE_SETUP
#line 101 "zconf.l"
BEGIN(PARAM); return T_HELP;
YY_BREAK
case 15:
YY_RULE_SETUP
#line 102 "zconf.l"
BEGIN(PARAM); return T_IF;
YY_BREAK
case 16:
YY_RULE_SETUP
#line 103 "zconf.l"
BEGIN(PARAM); return T_ENDIF;
YY_BREAK
case 17:
YY_RULE_SETUP
#line 104 "zconf.l"
BEGIN(PARAM); return T_DEPENDS;
YY_BREAK
case 18:
YY_RULE_SETUP
#line 105 "zconf.l"
BEGIN(PARAM); return T_REQUIRES;
YY_BREAK
case 19:
YY_RULE_SETUP
#line 106 "zconf.l"
BEGIN(PARAM); return T_OPTIONAL;
YY_BREAK
case 20:
YY_RULE_SETUP
#line 107 "zconf.l"
BEGIN(PARAM); return T_DEFAULT;
YY_BREAK
case 21:
YY_RULE_SETUP
#line 108 "zconf.l"
BEGIN(PARAM); return T_PROMPT;
YY_BREAK
case 22:
YY_RULE_SETUP
#line 109 "zconf.l"
BEGIN(PARAM); return T_TRISTATE;
YY_BREAK
case 23:
YY_RULE_SETUP
#line 110 "zconf.l"
BEGIN(PARAM); return T_BOOLEAN;
YY_BREAK
case 24:
YY_RULE_SETUP
#line 111 "zconf.l"
BEGIN(PARAM); return T_BOOLEAN;
YY_BREAK
case 25:
YY_RULE_SETUP
#line 112 "zconf.l"
BEGIN(PARAM); return T_INT;
YY_BREAK
case 26:
YY_RULE_SETUP
#line 113 "zconf.l"
BEGIN(PARAM); return T_HEX;
YY_BREAK
case 27:
YY_RULE_SETUP
#line 114 "zconf.l"
BEGIN(PARAM); return T_STRING;
YY_BREAK
case 28:
YY_RULE_SETUP
#line 115 "zconf.l"
{
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
YY_BREAK
case 29:
YY_RULE_SETUP
#line 120 "zconf.l"
YY_BREAK
case 30:
YY_RULE_SETUP
#line 121 "zconf.l"
current_file->lineno++; BEGIN(INITIAL);
YY_BREAK
case 31:
YY_RULE_SETUP
#line 125 "zconf.l"
return T_AND;
YY_BREAK
case 32:
YY_RULE_SETUP
#line 126 "zconf.l"
return T_OR;
YY_BREAK
case 33:
YY_RULE_SETUP
#line 127 "zconf.l"
return T_OPEN_PAREN;
YY_BREAK
case 34:
YY_RULE_SETUP
#line 128 "zconf.l"
return T_CLOSE_PAREN;
YY_BREAK
case 35:
YY_RULE_SETUP
#line 129 "zconf.l"
return T_NOT;
YY_BREAK
case 36:
YY_RULE_SETUP
#line 130 "zconf.l"
return T_EQUAL;
YY_BREAK
case 37:
YY_RULE_SETUP
#line 131 "zconf.l"
return T_UNEQUAL;
YY_BREAK
case 38:
YY_RULE_SETUP
#line 132 "zconf.l"
return T_IF;
YY_BREAK
case 39:
YY_RULE_SETUP
#line 133 "zconf.l"
return T_ON;
YY_BREAK
case 40:
YY_RULE_SETUP
#line 134 "zconf.l"
{
str = yytext[0];
new_string();
BEGIN(STRING);
}
YY_BREAK
case 41:
YY_RULE_SETUP
#line 139 "zconf.l"
BEGIN(INITIAL); current_file->lineno++; return T_EOL;
YY_BREAK
case 42:
YY_RULE_SETUP
#line 140 "zconf.l"
/* ignore */
YY_BREAK
case 43:
YY_RULE_SETUP
#line 141 "zconf.l"
{
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
YY_BREAK
case 44:
YY_RULE_SETUP
#line 146 "zconf.l"
YY_BREAK
case 45:
YY_RULE_SETUP
#line 150 "zconf.l"
{
append_string(yytext, yyleng);
}
YY_BREAK
case 46:
YY_RULE_SETUP
#line 153 "zconf.l"
{
if (str == yytext[0]) {
BEGIN(PARAM);
zconflval.string = text;
//printf("s:%s\n", text);
return T_STRING;
} else
append_string(yytext, 1);
}
YY_BREAK
case 47:
YY_RULE_SETUP
#line 162 "zconf.l"
append_string(yytext+yyleng-1, 1); current_file->lineno++;
YY_BREAK
case 48:
YY_RULE_SETUP
#line 163 "zconf.l"
append_string(yytext+1, yyleng-1);
YY_BREAK
case 49:
YY_RULE_SETUP
#line 164 "zconf.l"
append_string(yytext+1, 1);
YY_BREAK
case 50:
YY_RULE_SETUP
#line 165 "zconf.l"
{
//printf(":%d: open string!\n", current_file->lineno+1);
exit(0);
}
YY_BREAK
case YY_STATE_EOF(STRING):
#line 169 "zconf.l"
{
//printf(":%d: open string!\n", current_file->lineno+1);
exit(0);
}
YY_BREAK
case 51:
YY_RULE_SETUP
#line 176 "zconf.l"
{
ts = 0;
for (i = 0; i < yyleng; i++) {
if (yytext[i] == '\t')
ts = (ts & ~7) + 8;
else
ts++;
}
last_ts = ts;
if (first_ts) {
if (ts < first_ts) {
zconf_endhelp();
return T_HELPTEXT;
}
ts -= first_ts;
while (ts > 8) {
append_string(" ", 8);
ts -= 8;
}
append_string(" ", ts);
}
}
YY_BREAK
case 52:
*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
yy_c_buf_p = yy_cp = yy_bp + 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
#line 199 "zconf.l"
{
current_file->lineno++;
zconf_endhelp();
return T_HELPTEXT;
}
YY_BREAK
case 53:
YY_RULE_SETUP
#line 204 "zconf.l"
{
current_file->lineno++;
append_string("\n", 1);
}
YY_BREAK
case 54:
YY_RULE_SETUP
#line 208 "zconf.l"
{
append_string(yytext, yyleng);
if (!first_ts)
first_ts = last_ts;
}
YY_BREAK
case YY_STATE_EOF(HELP):
#line 213 "zconf.l"
{
zconf_endhelp();
return T_HELPTEXT;
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(COMMAND):
case YY_STATE_EOF(PARAM):
#line 219 "zconf.l"
{
if (current_buf) {
zconf_endfile();
return T_EOF;
}
yyterminate();
}
YY_BREAK
case 55:
YY_RULE_SETUP
#line 227 "zconf.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
#line 2311 "lex.zconf.c"
case YY_END_OF_BUFFER:
{
/* Amount of text matched not including the EOB char. */
int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
/* Undo the effects of YY_DO_BEFORE_ACTION. */
*yy_cp = yy_hold_char;
YY_RESTORE_YY_MORE_OFFSET
if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
{
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
* yylex(). If so, then we have to assure
* consistency between yy_current_buffer and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
* back-up) that will match for the new input source.
*/
yy_n_chars = yy_current_buffer->yy_n_chars;
yy_current_buffer->yy_input_file = yyin;
yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
}
/* Note that here we test for yy_c_buf_p "<=" to the position
* of the first EOB in the buffer, since yy_c_buf_p will
* already have been incremented past the NUL character
* (since all states make transitions on EOB to the
* end-of-buffer state). Contrast this with the test
* in input().
*/
if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
{ /* This was really a NUL. */
yy_state_type yy_next_state;
yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
yy_current_state = yy_get_previous_state();
/* Okay, we're now positioned to make the NUL
* transition. We couldn't have
* yy_get_previous_state() go ahead and do it
* for us because it doesn't know how to deal
* with the possibility of jamming (and we don't
* want to build jamming into it because then it
* will run more slowly).
*/
yy_next_state = yy_try_NUL_trans( yy_current_state );
yy_bp = yytext_ptr + YY_MORE_ADJ;
if ( yy_next_state )
{
/* Consume the NUL. */
yy_cp = ++yy_c_buf_p;
yy_current_state = yy_next_state;
goto yy_match;
}
else
{
yy_cp = yy_c_buf_p;
goto yy_find_action;
}
}
else switch ( yy_get_next_buffer() )
{
case EOB_ACT_END_OF_FILE:
{
yy_did_buffer_switch_on_eof = 0;
if ( yywrap() )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
* yytext, we can now set up
* yy_c_buf_p so that if some total
* hoser (like flex itself) wants to
* call the scanner after we return the
* YY_NULL, it'll still work - another
* YY_NULL will get returned.
*/
yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
yy_act = YY_STATE_EOF(YY_START);
goto do_action;
}
else
{
if ( ! yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
}
break;
}
case EOB_ACT_CONTINUE_SCAN:
yy_c_buf_p =
yytext_ptr + yy_amount_of_matched_text;
yy_current_state = yy_get_previous_state();
yy_cp = yy_c_buf_p;
yy_bp = yytext_ptr + YY_MORE_ADJ;
goto yy_match;
case EOB_ACT_LAST_MATCH:
yy_c_buf_p =
&yy_current_buffer->yy_ch_buf[yy_n_chars];
yy_current_state = yy_get_previous_state();
yy_cp = yy_c_buf_p;
yy_bp = yytext_ptr + YY_MORE_ADJ;
goto yy_find_action;
}
break;
}
default:
YY_FATAL_ERROR(
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
} /* end of yylex */
/* yy_get_next_buffer - try to read in a new buffer
*
* Returns a code representing an action:
* EOB_ACT_LAST_MATCH -
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position
* EOB_ACT_END_OF_FILE - end of file
*/
static int yy_get_next_buffer()
{
register char *dest = yy_current_buffer->yy_ch_buf;
register char *source = yytext_ptr;
register int number_to_move, i;
int ret_val;
if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
YY_FATAL_ERROR(
"fatal flex scanner internal error--end of buffer missed" );
if ( yy_current_buffer->yy_fill_buffer == 0 )
{ /* Don't try to fill the buffer, so this is an EOF. */
if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
{
/* We matched a single character, the EOB, so
* treat this as a final EOF.
*/
return EOB_ACT_END_OF_FILE;
}
else
{
/* We matched some text prior to the EOB, first
* process it.
*/
return EOB_ACT_LAST_MATCH;
}
}
/* Try to read more data. */
/* First move last chars to start of buffer. */
number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
/* don't do the read, it's not guaranteed to return an EOF,
* just force an EOF
*/
yy_current_buffer->yy_n_chars = yy_n_chars = 0;
else
{
int num_to_read =
yy_current_buffer->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
{ /* Not enough room in the buffer - grow it. */
#ifdef YY_USES_REJECT
YY_FATAL_ERROR(
"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
#else
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = yy_current_buffer;
int yy_c_buf_p_offset =
(int) (yy_c_buf_p - b->yy_ch_buf);
if ( b->yy_is_our_buffer )
{
int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
else
b->yy_buf_size *= 2;
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
yy_flex_realloc( (void *) b->yy_ch_buf,
b->yy_buf_size + 2 );
}
else
/* Can't grow it, we don't own it. */
b->yy_ch_buf = 0;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
"fatal error - scanner input buffer overflow" );
yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
num_to_read = yy_current_buffer->yy_buf_size -
number_to_move - 1;
#endif
}
if ( num_to_read > YY_READ_BUF_SIZE )
num_to_read = YY_READ_BUF_SIZE;
/* Read in more data. */
YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
yy_n_chars, num_to_read );
yy_current_buffer->yy_n_chars = yy_n_chars;
}
if ( yy_n_chars == 0 )
{
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
yyrestart( yyin );
}
else
{
ret_val = EOB_ACT_LAST_MATCH;
yy_current_buffer->yy_buffer_status =
YY_BUFFER_EOF_PENDING;
}
}
else
ret_val = EOB_ACT_CONTINUE_SCAN;
yy_n_chars += number_to_move;
yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
return ret_val;
}
/* yy_get_previous_state - get the state just before the EOB char was reached */
static yy_state_type yy_get_previous_state()
{
register yy_state_type yy_current_state;
register char *yy_cp;
yy_current_state = yy_start;
for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
{
yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
}
return yy_current_state;
}
/* yy_try_NUL_trans - try to make a transition on the NUL character
*
* synopsis
* next_state = yy_try_NUL_trans( current_state );
*/
#ifdef YY_USE_PROTOS
static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
#else
static yy_state_type yy_try_NUL_trans( yy_current_state )
yy_state_type yy_current_state;
#endif
{
register int yy_is_jam;
yy_current_state = yy_nxt[yy_current_state][1];
yy_is_jam = (yy_current_state <= 0);
return yy_is_jam ? 0 : yy_current_state;
}
#ifndef YY_NO_UNPUT
#ifdef YY_USE_PROTOS
static void yyunput( int c, register char *yy_bp )
#else
static void yyunput( c, yy_bp )
int c;
register char *yy_bp;
#endif
{
register char *yy_cp = yy_c_buf_p;
/* undo effects of setting up yytext */
*yy_cp = yy_hold_char;
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
register int number_to_move = yy_n_chars + 2;
register char *dest = &yy_current_buffer->yy_ch_buf[
yy_current_buffer->yy_buf_size + 2];
register char *source =
&yy_current_buffer->yy_ch_buf[number_to_move];
while ( source > yy_current_buffer->yy_ch_buf )
*--dest = *--source;
yy_cp += (int) (dest - source);
yy_bp += (int) (dest - source);
yy_current_buffer->yy_n_chars =
yy_n_chars = yy_current_buffer->yy_buf_size;
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
YY_FATAL_ERROR( "flex scanner push-back overflow" );
}
*--yy_cp = (char) c;
yytext_ptr = yy_bp;
yy_hold_char = *yy_cp;
yy_c_buf_p = yy_cp;
}
#endif /* ifndef YY_NO_UNPUT */
#ifdef __cplusplus
static int yyinput()
#else
static int input()
#endif
{
int c;
*yy_c_buf_p = yy_hold_char;
if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
{
/* yy_c_buf_p now points to the character we want to return.
* If this occurs *before* the EOB characters, then it's a
* valid NUL; if not, then we've hit the end of the buffer.
*/
if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
/* This was really a NUL. */
*yy_c_buf_p = '\0';
else
{ /* need more input */
int offset = yy_c_buf_p - yytext_ptr;
++yy_c_buf_p;
switch ( yy_get_next_buffer() )
{
case EOB_ACT_LAST_MATCH:
/* This happens because yy_g_n_b()
* sees that we've accumulated a
* token and flags that we need to
* try matching the token before
* proceeding. But for input(),
* there's no matching to consider.
* So convert the EOB_ACT_LAST_MATCH
* to EOB_ACT_END_OF_FILE.
*/
/* Reset buffer status. */
yyrestart( yyin );
/* fall through */
case EOB_ACT_END_OF_FILE:
{
if ( yywrap() )
return EOF;
if ( ! yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
#ifdef __cplusplus
return yyinput();
#else
return input();
#endif
}
case EOB_ACT_CONTINUE_SCAN:
yy_c_buf_p = yytext_ptr + offset;
break;
}
}
}
c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
*yy_c_buf_p = '\0'; /* preserve yytext */
yy_hold_char = *++yy_c_buf_p;
return c;
}
#ifdef YY_USE_PROTOS
void yyrestart( FILE *input_file )
#else
void yyrestart( input_file )
FILE *input_file;
#endif
{
if ( ! yy_current_buffer )
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
yy_init_buffer( yy_current_buffer, input_file );
yy_load_buffer_state();
}
#ifdef YY_USE_PROTOS
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
#else
void yy_switch_to_buffer( new_buffer )
YY_BUFFER_STATE new_buffer;
#endif
{
if ( yy_current_buffer == new_buffer )
return;
if ( yy_current_buffer )
{
/* Flush out information for old buffer. */
*yy_c_buf_p = yy_hold_char;
yy_current_buffer->yy_buf_pos = yy_c_buf_p;
yy_current_buffer->yy_n_chars = yy_n_chars;
}
yy_current_buffer = new_buffer;
yy_load_buffer_state();
/* We don't actually know whether we did this switch during
* EOF (yywrap()) processing, but the only time this flag
* is looked at is after yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yy_did_buffer_switch_on_eof = 1;
}
#ifdef YY_USE_PROTOS
void yy_load_buffer_state( void )
#else
void yy_load_buffer_state()
#endif
{
yy_n_chars = yy_current_buffer->yy_n_chars;
yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
yyin = yy_current_buffer->yy_input_file;
yy_hold_char = *yy_c_buf_p;
}
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
#else
YY_BUFFER_STATE yy_create_buffer( file, size )
FILE *file;
int size;
#endif
{
YY_BUFFER_STATE b;
b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
yy_init_buffer( b, file );
return b;
}
#ifdef YY_USE_PROTOS
void yy_delete_buffer( YY_BUFFER_STATE b )
#else
void yy_delete_buffer( b )
YY_BUFFER_STATE b;
#endif
{
if ( ! b )
return;
if ( b == yy_current_buffer )
yy_current_buffer = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
yy_flex_free( (void *) b->yy_ch_buf );
yy_flex_free( (void *) b );
}
#ifndef _WIN32
#include <unistd.h>
#else
#ifndef YY_ALWAYS_INTERACTIVE
#ifndef YY_NEVER_INTERACTIVE
extern int isatty YY_PROTO(( int ));
#endif
#endif
#endif
#ifdef YY_USE_PROTOS
void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
#else
void yy_init_buffer( b, file )
YY_BUFFER_STATE b;
FILE *file;
#endif
{
yy_flush_buffer( b );
b->yy_input_file = file;
b->yy_fill_buffer = 1;
#if YY_ALWAYS_INTERACTIVE
b->yy_is_interactive = 1;
#else
#if YY_NEVER_INTERACTIVE
b->yy_is_interactive = 0;
#else
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
#endif
#endif
}
#ifdef YY_USE_PROTOS
void yy_flush_buffer( YY_BUFFER_STATE b )
#else
void yy_flush_buffer( b )
YY_BUFFER_STATE b;
#endif
{
if ( ! b )
return;
b->yy_n_chars = 0;
/* We always need two end-of-buffer characters. The first causes
* a transition to the end-of-buffer state. The second causes
* a jam in that state.
*/
b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
b->yy_buf_pos = &b->yy_ch_buf[0];
b->yy_at_bol = 1;
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == yy_current_buffer )
yy_load_buffer_state();
}
#ifndef YY_NO_SCAN_BUFFER
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
#else
YY_BUFFER_STATE yy_scan_buffer( base, size )
char *base;
yy_size_t size;
#endif
{
YY_BUFFER_STATE b;
if ( size < 2 ||
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
return 0;
b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
b->yy_input_file = 0;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
yy_switch_to_buffer( b );
return b;
}
#endif
#ifndef YY_NO_SCAN_STRING
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
#else
YY_BUFFER_STATE yy_scan_string( yy_str )
yyconst char *yy_str;
#endif
{
int len;
for ( len = 0; yy_str[len]; ++len )
;
return yy_scan_bytes( yy_str, len );
}
#endif
#ifndef YY_NO_SCAN_BYTES
#ifdef YY_USE_PROTOS
YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
#else
YY_BUFFER_STATE yy_scan_bytes( bytes, len )
yyconst char *bytes;
int len;
#endif
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = len + 2;
buf = (char *) yy_flex_alloc( n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
for ( i = 0; i < len; ++i )
buf[i] = bytes[i];
buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
b = yy_scan_buffer( buf, n );
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
*/
b->yy_is_our_buffer = 1;
return b;
}
#endif
#ifndef YY_NO_PUSH_STATE
#ifdef YY_USE_PROTOS
static void yy_push_state( int new_state )
#else
static void yy_push_state( new_state )
int new_state;
#endif
{
if ( yy_start_stack_ptr >= yy_start_stack_depth )
{
yy_size_t new_size;
yy_start_stack_depth += YY_START_STACK_INCR;
new_size = yy_start_stack_depth * sizeof( int );
if ( ! yy_start_stack )
yy_start_stack = (int *) yy_flex_alloc( new_size );
else
yy_start_stack = (int *) yy_flex_realloc(
(void *) yy_start_stack, new_size );
if ( ! yy_start_stack )
YY_FATAL_ERROR(
"out of memory expanding start-condition stack" );
}
yy_start_stack[yy_start_stack_ptr++] = YY_START;
BEGIN(new_state);
}
#endif
#ifndef YY_NO_POP_STATE
static void yy_pop_state()
{
if ( --yy_start_stack_ptr < 0 )
YY_FATAL_ERROR( "start-condition stack underflow" );
BEGIN(yy_start_stack[yy_start_stack_ptr]);
}
#endif
#ifndef YY_NO_TOP_STATE
static int yy_top_state()
{
return yy_start_stack[yy_start_stack_ptr - 1];
}
#endif
#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif
#ifdef YY_USE_PROTOS
static void yy_fatal_error( yyconst char msg[] )
#else
static void yy_fatal_error( msg )
char msg[];
#endif
{
(void) fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
/* Redefine yyless() so it works in section 3 code. */
#undef yyless
#define yyless(n) \
do \
{ \
/* Undo effects of setting up yytext. */ \
yytext[yyleng] = yy_hold_char; \
yy_c_buf_p = yytext + n; \
yy_hold_char = *yy_c_buf_p; \
*yy_c_buf_p = '\0'; \
yyleng = n; \
} \
while ( 0 )
/* Internal utility routines. */
#ifndef yytext_ptr
#ifdef YY_USE_PROTOS
static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
#else
static void yy_flex_strncpy( s1, s2, n )
char *s1;
yyconst char *s2;
int n;
#endif
{
register int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
#endif
#ifdef YY_NEED_STRLEN
#ifdef YY_USE_PROTOS
static int yy_flex_strlen( yyconst char *s )
#else
static int yy_flex_strlen( s )
yyconst char *s;
#endif
{
register int n;
for ( n = 0; s[n]; ++n )
;
return n;
}
#endif
#ifdef YY_USE_PROTOS
static void *yy_flex_alloc( yy_size_t size )
#else
static void *yy_flex_alloc( size )
yy_size_t size;
#endif
{
return (void *) malloc( size );
}
#ifdef YY_USE_PROTOS
static void *yy_flex_realloc( void *ptr, yy_size_t size )
#else
static void *yy_flex_realloc( ptr, size )
void *ptr;
yy_size_t size;
#endif
{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
* because both ANSI C and C++ allow castless assignment from
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
return (void *) realloc( (char *) ptr, size );
}
#ifdef YY_USE_PROTOS
static void yy_flex_free( void *ptr )
#else
static void yy_flex_free( ptr )
void *ptr;
#endif
{
free( ptr );
}
#if YY_MAIN
int main()
{
yylex();
return 0;
}
#endif
#line 227 "zconf.l"
void zconf_starthelp(void)
{
new_string();
last_ts = first_ts = 0;
BEGIN(HELP);
}
static void zconf_endhelp(void)
{
zconflval.string = text;
BEGIN(INITIAL);
}
void zconf_initscan(const char *name)
{
yyin = fopen(name, "r");
if (!yyin) {
printf("can't find file %s\n", name);
exit(1);
}
//fprintf(stderr, "zconf_initscan: %s\n", name);
current_buf = malloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
current_file->lineno = 1;
current_file->flags = FILE_BUSY;
}
void zconf_nextfile(const char *name)
{
struct file *file = file_lookup(name);
struct buffer *buf = malloc(sizeof(*buf));
memset(buf, 0, sizeof(*buf));
current_buf->state = YY_CURRENT_BUFFER;
yyin = fopen(name, "r");
if (!yyin) {
printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
exit(1);
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf;
current_buf = buf;
//fprintf(stderr, "zconf_nextfile: %s\n", name);
if (file->flags & FILE_BUSY) {
printf("recursive scan (%s)?\n", name);
exit(1);
}
if (file->flags & FILE_SCANNED) {
printf("file %s already scanned?\n", name);
exit(1);
}
file->flags |= FILE_BUSY;
file->lineno = 1;
file->parent = current_file;
current_file = file;
}
static struct buffer *zconf_endfile(void)
{
struct buffer *parent;
current_file->flags |= FILE_SCANNED;
current_file->flags &= ~FILE_BUSY;
current_file = current_file->parent;
parent = current_buf->parent;
if (parent) {
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(parent->state);
}
free(current_buf);
current_buf = parent;
return parent;
}
int zconf_lineno(void)
{
if (current_buf)
return current_file->lineno;
else
return 0;
}
char *zconf_curname(void)
{
if (current_buf)
return current_file->name;
else
return "<none>";
}
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#ifndef LKC_H
#define LKC_H
#include "expr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LKC_DIRECT_LINK
#define P(name,type,arg) extern type name arg
#else
#include "lkc_defs.h"
#define P(name,type,arg) extern type (*name ## _p) arg
#endif
#include "lkc_proto.h"
#undef P
void symbol_end(char *help);
int zconfparse(void);
void zconfdump(FILE *out);
extern int zconfdebug;
void zconf_starthelp(void);
void zconf_initscan(const char *name);
void zconf_nextfile(const char *name);
int zconf_lineno(void);
char *zconf_curname(void);
/* confdata.c */
extern const char conf_def_filename[];
extern char conf_filename[];
char *conf_get_default_confname(void);
/* kconfig_load.c */
void kconfig_load(void);
/* menu.c */
void menu_init(void);
void menu_add_menu(void);
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
struct property *create_prop(enum prop_type type);
void menu_add_dep(struct expr *dep);
struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep);
void menu_finalize(struct menu *parent);
void menu_set_type(int type);
struct file *file_lookup(const char *name);
int file_write_dep(const char *name);
extern struct menu *current_entry;
extern struct menu *current_menu;
/* symbol.c */
void sym_init(void);
void sym_clear_all_valid(void);
static inline tristate sym_get_tristate_value(struct symbol *sym)
{
return S_TRI(sym->curr);
}
static inline struct symbol *sym_get_choice_value(struct symbol *sym)
{
return (struct symbol *)S_VAL(sym->curr);
}
static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
{
return sym_set_tristate_value(chval, yes);
}
static inline bool sym_is_choice(struct symbol *sym)
{
return sym->flags & SYMBOL_CHOICE ? true : false;
}
static inline bool sym_is_choice_value(struct symbol *sym)
{
return sym->flags & SYMBOL_CHOICEVAL ? true : false;
}
static inline bool sym_is_optional(struct symbol *sym)
{
return sym->flags & SYMBOL_OPTIONAL ? true : false;
}
static inline bool sym_has_value(struct symbol *sym)
{
//return S_VAL(sym->def) != NULL;
return sym->flags & SYMBOL_NEW ? false : true;
}
#ifdef __cplusplus
}
#endif
#endif /* LKC_H */
/* confdata.c */
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
P(conf_write,int,(const char *name));
/* menu.c */
P(rootmenu,struct menu,);
P(menu_is_visible,bool,(struct menu *menu));
P(menu_get_prompt,const char *,(struct menu *menu));
P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
P(sym_change_count,int,);
P(sym_lookup,struct symbol *,(const char *name, int isconst));
P(sym_find,struct symbol *,(const char *name));
P(sym_type_name,const char *,(int type));
P(sym_calc_value,void,(struct symbol *sym));
P(sym_get_type,int,(struct symbol *sym));
P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
P(sym_is_changable,bool,(struct symbol *sym));
P(sym_get_choice_prop,struct property *,(struct symbol *sym));
P(sym_get_default_prop,struct property *,(struct symbol *sym));
P(sym_get_string_value,const char *,(struct symbol *sym));
P(prop_get_type_name,const char *,(enum prop_type type));
/* expr.c */
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken));
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
static char menu_backtitle[128];
static const char menu_instructions[] =
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
"Highlighted letters are hotkeys. "
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
"Press <Esc><Esc> to exit, <?> for Help. "
"Legend: [*] built-in [ ] excluded <M> module < > module capable",
radiolist_instructions[] =
"Use the arrow keys to navigate this window or "
"press the hotkey of the item you wish to select "
"followed by the <SPACE BAR>. "
"Press <?> for additional information about this option.",
inputbox_instructions_int[] =
"Please enter a decimal value. "
"Fractions will not be accepted. "
"Use the <TAB> key to move from the input field to the buttons below it.",
inputbox_instructions_hex[] =
"Please enter a hexadecimal value. "
"Use the <TAB> key to move from the input field to the buttons below it.",
inputbox_instructions_string[] =
"Please enter a string value. "
"Use the <TAB> key to move from the input field to the buttons below it.",
setmod_text[] =
"This feature depends on another which has been configured as a module.\n"
"As a result, this feature will be built as a module.",
nohelp_text[] =
"There is no help available for this kernel option.\n",
load_config_text[] =
"Enter the name of the configuration file you wish to load. "
"Accept the name shown to restore the configuration you "
"last retrieved. Leave blank to abort.",
load_config_help[] =
"\n"
"For various reasons, one may wish to keep several different kernel\n"
"configurations available on a single machine.\n"
"\n"
"If you have saved a previous configuration in a file other than the\n"
"kernel's default, entering the name of the file here will allow you\n"
"to modify that configuration.\n"
"\n"
"If you are uncertain, then you have probably never used alternate\n"
"configuration files. You should therefor leave this blank to abort.\n",
save_config_text[] =
"Enter a filename to which this configuration should be saved "
"as an alternate. Leave blank to abort.",
save_config_help[] =
"\n"
"For various reasons, one may wish to keep different kernel\n"
"configurations available on a single machine.\n"
"\n"
"Entering a file name here will allow you to later retrieve, modify\n"
"and use the current configuration as an alternate to whatever\n"
"configuration options you have selected at that time.\n"
"\n"
"If you are uncertain what all this means then you should probably\n"
"leave this blank.\n"
;
static char buf[4096], *bufptr = buf;
static char input_buf[4096];
static char *args[1024], **argptr = args;
static int indent = 0;
static int rows, cols;
static struct menu *current_menu;
static int child_count;
static int do_resize;
static void conf(struct menu *menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
static void show_readme(void);
static void cprint_init(void);
static int cprint1(const char *fmt, ...);
static void cprint_done(void);
static int cprint(const char *fmt, ...);
static void init_wsize(void)
{
struct winsize ws;
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
rows = 24;
cols = 80;
} else {
rows = ws.ws_row;
cols = ws.ws_col;
}
if (rows < 19 || cols < 80) {
fprintf(stderr, "Your display is too small to run Menuconfig!\n");
fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
exit(1);
}
rows -= 4;
cols -= 5;
}
static void cprint_init(void)
{
bufptr = buf;
argptr = args;
memset(args, 0, sizeof(args));
indent = 0;
child_count = 0;
cprint("./scripts/lxdialog/lxdialog");
cprint("--backtitle");
cprint(menu_backtitle);
}
static int cprint1(const char *fmt, ...)
{
va_list ap;
int res;
if (!*argptr)
*argptr = bufptr;
va_start(ap, fmt);
res = vsprintf(bufptr, fmt, ap);
va_end(ap);
bufptr += res;
return res;
}
static void cprint_done(void)
{
*bufptr++ = 0;
argptr++;
}
static int cprint(const char *fmt, ...)
{
va_list ap;
int res;
*argptr++ = bufptr;
va_start(ap, fmt);
res = vsprintf(bufptr, fmt, ap);
va_end(ap);
bufptr += res;
*bufptr++ = 0;
return res;
}
pid_t pid;
static void winch_handler(int sig)
{
if (!do_resize) {
kill(pid, SIGINT);
do_resize = 1;
}
}
static int exec_conf(void)
{
int pipefd[2], stat, size;
struct sigaction sa;
sigset_t sset, osset;
sigemptyset(&sset);
sigaddset(&sset, SIGINT);
sigprocmask(SIG_BLOCK, &sset, &osset);
signal(SIGINT, SIG_DFL);
sa.sa_handler = winch_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGWINCH, &sa, NULL);
*argptr++ = NULL;
pipe(pipefd);
pid = fork();
if (pid == 0) {
sigprocmask(SIG_SETMASK, &osset, NULL);
dup2(pipefd[1], 2);
close(pipefd[0]);
close(pipefd[1]);
execv(args[0], args);
_exit(EXIT_FAILURE);
}
close(pipefd[1]);
bufptr = input_buf;
while (1) {
size = input_buf + sizeof(input_buf) - bufptr;
size = read(pipefd[0], bufptr, size);
if (size <= 0) {
if (size < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
perror("read");
}
break;
}
bufptr += size;
}
*bufptr++ = 0;
close(pipefd[0]);
waitpid(pid, &stat, 0);
if (do_resize) {
init_wsize();
do_resize = 0;
sigprocmask(SIG_SETMASK, &osset, NULL);
return -1;
}
if (WIFSIGNALED(stat)) {
printf("\finterrupted(%d)\n", WTERMSIG(stat));
exit(1);
}
#if 0
printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
sleep(1);
#endif
sigpending(&sset);
if (sigismember(&sset, SIGINT)) {
printf("\finterrupted\n");
exit(1);
}
sigprocmask(SIG_SETMASK, &osset, NULL);
return WEXITSTATUS(stat);
}
static void build_conf(struct menu *menu)
{
struct symbol *sym;
struct property *prop;
struct menu *child;
int type, tmp, doint = 2;
tristate val;
char ch;
if (!menu_is_visible(menu))
return;
sym = menu->sym;
prop = menu->prompt;
if (!sym) {
if (prop && menu != current_menu) {
const char *prompt = menu_get_prompt(menu);
switch (prop->type) {
case P_MENU:
child_count++;
cprint("m%p", menu);
if (menu->parent != &rootmenu)
cprint1(" %*c", indent + 1, ' ');
cprint1("%s --->", prompt);
cprint_done();
return;
default:
if (prompt) {
child_count++;
cprint(":%p", menu);
cprint("---%*c%s", indent + 1, ' ', prompt);
}
}
} else
doint = 0;
goto conf_childs;
}
type = sym_get_type(sym);
if (sym_is_choice(sym)) {
struct symbol *def_sym = sym_get_choice_value(sym);
struct menu *def_menu = NULL;
child_count++;
for (child = menu->list; child; child = child->next) {
if (menu_is_visible(child) && child->sym == def_sym)
def_menu = child;
}
val = sym_get_tristate_value(sym);
if (sym_is_changable(sym)) {
cprint("t%p", menu);
switch (type) {
case S_BOOLEAN:
cprint1("[%c]", val == no ? ' ' : '*');
break;
case S_TRISTATE:
switch (val) {
case yes: ch = '*'; break;
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
cprint1("<%c>", ch);
break;
}
} else {
cprint("%c%p", def_menu ? 't' : ':', menu);
cprint1(" ");
}
cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
if (val == yes) {
if (def_menu) {
cprint1(" (%s)", menu_get_prompt(def_menu));
cprint1(" --->");
cprint_done();
if (def_menu->list) {
indent += 2;
build_conf(def_menu);
indent -= 2;
}
} else
cprint_done();
return;
}
cprint_done();
} else {
child_count++;
val = sym_get_tristate_value(sym);
if (sym_is_choice_value(sym) && val == yes) {
cprint(":%p", menu);
cprint1(" ");
} else {
switch (type) {
case S_BOOLEAN:
cprint("t%p", menu);
cprint1("[%c]", val == no ? ' ' : '*');
break;
case S_TRISTATE:
cprint("t%p", menu);
switch (val) {
case yes: ch = '*'; break;
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
cprint1("<%c>", ch);
break;
default:
cprint("s%p", menu);
tmp = cprint1("(%s)", sym_get_string_value(sym));
tmp = indent - tmp + 4;
if (tmp < 0)
tmp = 0;
cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
sym_has_value(sym) ? "" : " (NEW)");
cprint_done();
goto conf_childs;
}
}
cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
sym_has_value(sym) ? "" : " (NEW)");
cprint_done();
}
conf_childs:
indent += doint;
for (child = menu->list; child; child = child->next)
build_conf(child);
indent -= doint;
}
static void conf(struct menu *menu)
{
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
char active_entry[40];
int stat, type, i;
active_entry[0] = 0;
while (1) {
cprint_init();
cprint("--title");
cprint("%s", prompt ? prompt : "Main Menu");
cprint("--menu");
cprint(menu_instructions);
cprint("%d", rows);
cprint("%d", cols);
cprint("%d", rows - 10);
cprint("%s", active_entry);
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
if (menu == &rootmenu) {
cprint(":");
cprint("--- ");
cprint("L");
cprint("Load an Alternate Configuration File");
cprint("S");
cprint("Save Configuration to an Alternate File");
}
stat = exec_conf();
if (stat < 0)
continue;
if (stat == 1 || stat == 255)
break;
type = input_buf[0];
if (!type)
continue;
for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
;
if (i >= sizeof(active_entry))
i = sizeof(active_entry) - 1;
input_buf[i] = 0;
strcpy(active_entry, input_buf);
sym = NULL;
submenu = NULL;
if (sscanf(input_buf + 1, "%p", &submenu) == 1)
sym = submenu->sym;
switch (stat) {
case 0:
switch (type) {
case 'm':
conf(submenu);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
break;
case 's':
conf_string(submenu);
break;
case 'L':
conf_load();
break;
case 'S':
conf_save();
break;
}
break;
case 2:
if (sym)
show_help(submenu);
else
show_readme();
break;
case 3:
if (type == 't') {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
show_textbox(NULL, setmod_text, 6, 74);
}
break;
case 4:
if (type == 't')
sym_set_tristate_value(sym, no);
break;
case 5:
if (type == 't')
sym_set_tristate_value(sym, mod);
break;
case 6:
if (type == 't')
sym_toggle_tristate_value(sym);
break;
}
}
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
int fd;
fd = creat(".help.tmp", 0777);
write(fd, text, strlen(text));
close(fd);
do {
cprint_init();
if (title) {
cprint("--title");
cprint("%s", title);
}
cprint("--textbox");
cprint(".help.tmp");
cprint("%d", r);
cprint("%d", c);
} while (exec_conf() < 0);
unlink(".help.tmp");
}
static void show_helptext(const char *title, const char *text)
{
show_textbox(title, text, rows, cols);
}
static void show_help(struct menu *menu)
{
const char *help;
help = menu->sym->help;
if (!help)
help = nohelp_text;
show_helptext(menu_get_prompt(menu), help);
}
static void show_readme(void)
{
do {
cprint_init();
cprint("--textbox");
cprint("scripts/README.Menuconfig");
cprint("%d", rows);
cprint("%d", cols);
} while (exec_conf() == -1);
}
static void conf_choice(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
struct menu *child;
struct symbol *active;
int stat;
while (1) {
cprint_init();
cprint("--title");
cprint("%s", prompt ? prompt : "Main Menu");
cprint("--radiolist");
cprint(radiolist_instructions);
cprint("15");
cprint("70");
cprint("6");
current_menu = menu;
active = sym_get_choice_value(menu->sym);
for (child = menu->list; child; child = child->next) {
if (!menu_is_visible(child))
continue;
cprint("%p", child);
cprint("%s", menu_get_prompt(child));
cprint(child->sym == active ? "ON" : "OFF");
}
stat = exec_conf();
switch (stat) {
case 0:
if (sscanf(input_buf, "%p", &menu) != 1)
break;
sym_set_tristate_value(menu->sym, yes);
return;
case 1:
show_help(menu);
break;
case 255:
return;
}
}
}
static void conf_string(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
int stat;
while (1) {
cprint_init();
cprint("--title");
cprint("%s", prompt ? prompt : "Main Menu");
cprint("--inputbox");
switch (sym_get_type(menu->sym)) {
case S_INT:
cprint(inputbox_instructions_int);
break;
case S_HEX:
cprint(inputbox_instructions_hex);
break;
case S_STRING:
cprint(inputbox_instructions_string);
break;
default:
/* panic? */;
}
cprint("10");
cprint("75");
cprint("%s", sym_get_string_value(menu->sym));
stat = exec_conf();
switch (stat) {
case 0:
if (sym_set_string_value(menu->sym, input_buf))
return;
show_textbox(NULL, "You have made an invalid entry.", 5, 43);
break;
case 1:
show_help(menu);
break;
case 255:
return;
}
}
}
static void conf_load(void)
{
int stat;
while (1) {
cprint_init();
cprint("--inputbox");
cprint(load_config_text);
cprint("11");
cprint("55");
cprint("%s", conf_filename);
stat = exec_conf();
switch(stat) {
case 0:
if (!input_buf[0])
return;
if (!conf_read(input_buf))
return;
show_textbox(NULL, "File does not exist!", 5, 38);
break;
case 1:
show_helptext("Load Alternate Configuration", load_config_help);
break;
case 255:
return;
}
}
}
static void conf_save(void)
{
int stat;
while (1) {
cprint_init();
cprint("--inputbox");
cprint(save_config_text);
cprint("11");
cprint("55");
cprint("%s", conf_filename);
stat = exec_conf();
switch(stat) {
case 0:
if (!input_buf[0])
return;
if (!conf_write(input_buf))
return;
show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
break;
case 1:
show_helptext("Save Alternate Configuration", save_config_help);
break;
case 255:
return;
}
}
}
int main(int ac, char **av)
{
int stat;
conf_parse(av[1]);
conf_read(NULL);
sprintf(menu_backtitle, "Linux Kernel v%s.%s.%s%s Configuration",
getenv("VERSION"), getenv("PATCHLEVEL"),
getenv("SUBLEVEL"), getenv("EXTRAVERSION"));
init_wsize();
conf(&rootmenu);
do {
cprint_init();
cprint("--yesno");
cprint("Do you wish to save your new kernel configuration?");
cprint("5");
cprint("60");
stat = exec_conf();
} while (stat < 0);
if (stat == 0) {
conf_write(NULL);
printf("\n\n"
"*** End of Linux kernel configuration.\n"
"*** Check the top-level Makefile for additional configuration.\n"
"*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'.\n\n");
} else
printf("\n\nYour kernel configuration changes were NOT saved.\n\n");
return 0;
}
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <stdlib.h>
#include <string.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct menu rootmenu;
struct menu *current_menu, *current_entry;
static struct menu **last_entry_ptr;
struct file *file_list;
struct file *current_file;
void menu_init(void)
{
current_entry = current_menu = &rootmenu;
last_entry_ptr = &rootmenu.list;
}
void menu_add_entry(struct symbol *sym)
{
struct menu *menu;
menu = malloc(sizeof(*menu));
memset(menu, 0, sizeof(*menu));
menu->sym = sym;
menu->parent = current_menu;
menu->file = current_file;
menu->lineno = zconf_lineno();
*last_entry_ptr = menu;
last_entry_ptr = &menu->next;
current_entry = menu;
}
void menu_end_entry(void)
{
}
void menu_add_menu(void)
{
current_menu = current_entry;
last_entry_ptr = &current_entry->list;
}
void menu_end_menu(void)
{
last_entry_ptr = &current_menu->next;
current_menu = current_menu->parent;
}
void menu_add_dep(struct expr *dep)
{
current_entry->dep = expr_alloc_and(current_entry->dep, dep);
}
void menu_set_type(int type)
{
struct symbol *sym = current_entry->sym;
if (sym->type == type)
return;
if (sym->type == S_UNKNOWN) {
sym->type = type;
return;
}
fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n",
current_entry->file->name, current_entry->lineno,
sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type));
}
struct property *create_prop(enum prop_type type)
{
struct property *prop;
prop = malloc(sizeof(*prop));
memset(prop, 0, sizeof(*prop));
prop->type = type;
prop->file = current_file;
prop->lineno = zconf_lineno();
return prop;
}
struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep)
{
struct property *prop = create_prop(token);
struct property **propp;
prop->sym = current_entry->sym;
prop->menu = current_entry;
prop->text = prompt;
prop->def = def;
E_EXPR(prop->visible) = dep;
if (prompt)
current_entry->prompt = prop;
/* append property to the prop list of symbol */
if (prop->sym) {
for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
;
*propp = prop;
}
return prop;
}
void menu_add_prompt(int token, char *prompt, struct expr *dep)
{
current_entry->prompt = menu_add_prop(token, prompt, NULL, dep);
}
void menu_add_default(int token, struct symbol *def, struct expr *dep)
{
current_entry->prompt = menu_add_prop(token, NULL, def, dep);
}
void menu_finalize(struct menu *parent)
{
struct menu *menu, *last_menu;
struct symbol *sym;
struct property *prop;
struct expr *parentdep, *basedep, *dep, *dep2;
sym = parent->sym;
if (parent->list) {
if (sym && sym_is_choice(sym)) {
/* find the first choice value and find out choice type */
for (menu = parent->list; menu; menu = menu->next) {
if (menu->sym) {
current_entry = parent;
menu_set_type(menu->sym->type);
current_entry = menu;
menu_set_type(sym->type);
break;
}
}
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
parentdep = E_EXPR(parent->prompt->visible);
else
parentdep = parent->dep;
for (menu = parent->list; menu; menu = menu->next) {
basedep = expr_transform(menu->dep);
basedep = expr_alloc_and(expr_copy(parentdep), basedep);
basedep = expr_eliminate_dups(basedep);
menu->dep = basedep;
if (menu->sym)
prop = menu->sym->prop;
else
prop = menu->prompt;
for (; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
dep = expr_transform(E_EXPR(prop->visible));
dep = expr_alloc_and(expr_copy(basedep), dep);
dep = expr_eliminate_dups(dep);
if (menu->sym && menu->sym->type != S_TRISTATE)
dep = expr_trans_bool(dep);
E_EXPR(prop->visible) = dep;
}
}
for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu);
} else if (sym && parent->prompt) {
basedep = E_EXPR(parent->prompt->visible);
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep));
last_menu = NULL;
for (menu = parent->next; menu; menu = menu->next) {
dep = menu->prompt ? E_EXPR(menu->prompt->visible) : menu->dep;
if (!expr_contains_symbol(dep, sym))
break;
if (expr_depends_symbol(dep, sym))
goto next;
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
dep = expr_eliminate_dups(expr_transform(dep));
dep2 = expr_copy(basedep);
expr_eliminate_eq(&dep, &dep2);
expr_free(dep);
if (!expr_is_yes(dep2)) {
expr_free(dep2);
break;
}
expr_free(dep2);
next:
menu_finalize(menu);
menu->parent = parent;
last_menu = menu;
}
if (last_menu) {
parent->list = parent->next;
parent->next = last_menu->next;
last_menu->next = NULL;
}
}
for (menu = parent->list; menu; menu = menu->next) {
if (sym && sym_is_choice(sym) && menu->sym) {
menu->sym->flags |= SYMBOL_CHOICEVAL;
current_entry = menu;
menu_set_type(sym->type);
menu_add_prop(P_CHOICE, NULL, parent->sym, NULL);
prop = sym_get_choice_prop(parent->sym);
//dep = expr_alloc_one(E_CHOICE, dep);
//dep->right.sym = menu->sym;
prop->dep = expr_alloc_one(E_CHOICE, prop->dep);
prop->dep->right.sym = menu->sym;
}
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
for (last_menu = menu->list; ; last_menu = last_menu->next) {
last_menu->parent = parent;
if (!last_menu->next)
break;
}
last_menu->next = menu->next;
menu->next = menu->list;
menu->list = NULL;
}
}
}
bool menu_is_visible(struct menu *menu)
{
tristate visible;
if (!menu->prompt)
return false;
if (menu->sym) {
sym_calc_value(menu->sym);
visible = E_TRI(menu->prompt->visible);
} else
visible = E_CALC(menu->prompt->visible);
return visible != no;
}
const char *menu_get_prompt(struct menu *menu)
{
if (menu->prompt)
return menu->prompt->text;
else if (menu->sym)
return menu->sym->name;
return NULL;
}
struct menu *menu_get_root_menu(struct menu *menu)
{
return &rootmenu;
}
struct menu *menu_get_parent_menu(struct menu *menu)
{
enum prop_type type;
while (menu != &rootmenu) {
menu = menu->parent;
type = menu->prompt ? menu->prompt->type : 0;
if (type == P_MENU || type == P_ROOTMENU)
break;
}
return menu;
}
struct file *file_lookup(const char *name)
{
struct file *file;
for (file = file_list; file; file = file->next) {
if (!strcmp(name, file->name))
return file;
}
file = malloc(sizeof(*file));
memset(file, 0, sizeof(*file));
file->name = strdup(name);
file->next = file_list;
file_list = file;
return file;
}
int file_write_dep(const char *name)
{
struct file *file;
FILE *out;
if (!name)
name = "..config.cmd";
out = fopen("..config.tmp", "w");
if (!out)
return 1;
fprintf(out, "deps_config := \\\n");
for (file = file_list; file; file = file->next) {
if (file->next)
fprintf(out, "\t%s \\\n", file->name);
else
fprintf(out, "\t%s\n", file->name);
}
fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
fclose(out);
rename("..config.tmp", name);
return 0;
}
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <qapplication.h>
#include <qmainwindow.h>
#include <qtoolbar.h>
#include <qvbox.h>
#include <qsplitter.h>
#include <qlistview.h>
#include <qtextview.h>
#include <qlineedit.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qaction.h>
#include <qheader.h>
#include <qfiledialog.h>
#include <qregexp.h>
#include <stdlib.h>
#include "lkc.h"
#include "qconf.h"
#include "qconf.moc"
#include "images.c"
static QApplication *configApp;
/*
* update all the children of a menu entry
* removes/adds the entries from the parent widget as necessary
*
* parent: either the menu list widget or a menu entry widget
* menu: entry to be updated
*/
template <class P>
static void updateMenuList(P* parent, struct menu* menu)
{
struct menu* child;
ConfigList* list = parent->listView();
ConfigItem* item;
ConfigItem* last;
bool visible;
bool showAll = list->showAll;
enum listMode mode = list->mode;
enum prop_type type;
if (!menu) {
while ((item = parent->firstChild()))
delete item;
return;
}
last = 0;
for (child = menu->list; child; child = child->next) {
item = last ? last->nextSibling() : parent->firstChild();
type = child->prompt ? child->prompt->type : P_UNKNOWN;
switch (mode) {
case menuMode:
if (type != P_ROOTMENU)
goto hide;
break;
case symbolMode:
if (type == P_ROOTMENU)
goto hide;
break;
default:
break;
}
visible = menu_is_visible(child);
if (showAll || visible) {
if (!item || item->menu != child)
item = new ConfigItem(parent, last, child);
item->visible = visible;
item->updateMenu();
if (mode == fullMode || mode == menuMode ||
(type != P_MENU && type != P_ROOTMENU))
updateMenuList(item, child);
else
updateMenuList(item, 0);
last = item;
continue;
}
hide:
if (item && item->menu == child) {
last = parent->firstChild();
if (last == item)
last = 0;
else while (last->nextSibling() != item)
last = last->nextSibling();
delete item;
}
}
}
#if QT_VERSION >= 300
/*
* set the new data
* TODO check the value
*/
void ConfigItem::okRename(int col)
{
Parent::okRename(col);
sym_set_string_value(menu->sym, text(dataColIdx).latin1());
}
#endif
/*
* update the displayed of a menu entry
*/
void ConfigItem::updateMenu(void)
{
ConfigList* list;
struct symbol* sym;
QString prompt;
int type;
enum prop_type ptype;
tristate expr;
bool update;
list = listView();
update = doInit;
if (update)
doInit = false;
else
update = list->updateAll;
sym = menu->sym;
if (!sym) {
if (update) {
setText(promptColIdx, menu_get_prompt(menu));
ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
if ((ptype == P_ROOTMENU || ptype == P_MENU) &&
(list->mode == singleMode || list->mode == symbolMode))
setPixmap(promptColIdx, list->menuPix);
else
setPixmap(promptColIdx, 0);
}
return;
}
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_CHANGED) && !update)
return;
sym->flags &= ~SYMBOL_CHANGED;
setText(nameColIdx, menu->sym->name);
type = sym_get_type(sym);
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
char ch;
prompt = menu_get_prompt(menu);
if (!sym_is_changable(sym) && !list->showAll) {
setText(noColIdx, 0);
setText(modColIdx, 0);
setText(yesColIdx, 0);
break;
}
expr = sym_get_tristate_value(sym);
switch (expr) {
case yes:
if (sym_is_choice_value(sym) && type == S_BOOLEAN)
setPixmap(promptColIdx, list->choiceYesPix);
else
setPixmap(promptColIdx, list->symbolYesPix);
setText(yesColIdx, "Y");
ch = 'Y';
break;
case mod:
setPixmap(promptColIdx, list->symbolModPix);
setText(modColIdx, "M");
ch = 'M';
break;
default:
if (sym_is_choice_value(sym) && type == S_BOOLEAN)
setPixmap(promptColIdx, list->choiceNoPix);
else
setPixmap(promptColIdx, list->symbolNoPix);
setText(noColIdx, "N");
ch = 'N';
break;
}
if (expr != no)
setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
if (expr != mod)
setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
if (expr != yes)
setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
setText(dataColIdx, QChar(ch));
break;
case S_INT:
case S_HEX:
case S_STRING:
const char* data;
data = sym_get_string_value(sym);
#if QT_VERSION >= 300
setRenameEnabled(list->mapIdx(dataColIdx), TRUE);
#endif
setText(dataColIdx, data);
if (type == S_STRING)
prompt.sprintf("%s: %s", menu_get_prompt(menu), data);
else
prompt.sprintf("(%s) %s", data, menu_get_prompt(menu));
break;
}
if (!sym_has_value(sym) && visible)
prompt += " (NEW)";
setText(promptColIdx, prompt);
}
void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
{
ConfigList* list = listView();
if (visible) {
if (isSelected() && !list->hasFocus() && list->mode == menuMode)
Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
else
Parent::paintCell(p, cg, column, width, align);
} else
Parent::paintCell(p, list->disabledColorGroup, column, width, align);
}
/*
* construct a menu entry
*/
void ConfigItem::init(void)
{
ConfigList* list = listView();
#if QT_VERSION < 300
visible = TRUE;
#endif
//menu->data = this;
if (list->mode != fullMode)
setOpen(TRUE);
doInit= true;
}
/*
* destruct a menu entry
*/
ConfigItem::~ConfigItem(void)
{
//menu->data = 0;
}
void ConfigLineEdit::show(ConfigItem* i)
{
item = i;
if (sym_get_string_value(item->menu->sym))
setText(sym_get_string_value(item->menu->sym));
else
setText(0);
Parent::show();
setFocus();
}
void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
{
switch (e->key()) {
case Key_Escape:
break;
case Key_Return:
case Key_Enter:
sym_set_string_value(item->menu->sym, text().latin1());
emit lineChanged(item);
break;
default:
Parent::keyPressEvent(e);
return;
}
e->accept();
hide();
}
ConfigList::ConfigList(QWidget* p, ConfigView* cv)
: Parent(p), cview(cv),
updateAll(false),
symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv),
showAll(false), showName(false), showRange(false), showData(false),
rootEntry(0)
{
int i;
setSorting(-1);
setRootIsDecorated(TRUE);
disabledColorGroup = palette().active();
disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
inactivedColorGroup = palette().active();
inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
connect(this, SIGNAL(selectionChanged(void)),
SLOT(updateSelection(void)));
for (i = 0; i < colNr; i++)
colMap[i] = colRevMap[i] = -1;
addColumn(promptColIdx, "Option");
reinit();
}
void ConfigList::reinit(void)
{
removeColumn(dataColIdx);
removeColumn(yesColIdx);
removeColumn(modColIdx);
removeColumn(noColIdx);
removeColumn(nameColIdx);
if (showName)
addColumn(nameColIdx, "Name");
if (showRange) {
addColumn(noColIdx, "N");
addColumn(modColIdx, "M");
addColumn(yesColIdx, "Y");
}
if (showData)
addColumn(dataColIdx, "Value");
updateListAll();
}
void ConfigList::updateSelection(void)
{
struct menu *menu;
enum prop_type type;
ConfigItem* item = (ConfigItem*)selectedItem();
if (!item)
return;
cview->setHelp(item);
menu = item->menu;
type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU))
emit menuSelected(menu);
}
void ConfigList::updateList(ConfigItem* item)
{
(void)item; // unused so far
updateMenuList(this, rootEntry);
}
void ConfigList::setAllOpen(bool open)
{
QListViewItemIterator it(this);
for (; it.current(); it++)
it.current()->setOpen(open);
}
void ConfigList::setValue(ConfigItem* item, tristate val)
{
struct symbol* sym;
int type;
tristate oldval;
sym = item->menu->sym;
if (!sym)
return;
type = sym_get_type(sym);
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
oldval = sym_get_tristate_value(sym);
if (!sym_set_tristate_value(sym, val))
return;
if (oldval == no && item->menu->list)
item->setOpen(TRUE);
emit symbolChanged(item);
break;
}
}
void ConfigList::changeValue(ConfigItem* item)
{
struct symbol* sym;
struct menu* menu;
int type, oldexpr, newexpr;
menu = item->menu;
sym = menu->sym;
if (!sym) {
if (item->menu->list)
item->setOpen(!item->isOpen());
return;
}
type = sym_get_type(sym);
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
oldexpr = sym_get_tristate_value(sym);
newexpr = sym_toggle_tristate_value(sym);
if (item->menu->list) {
if (oldexpr == newexpr)
item->setOpen(!item->isOpen());
else if (oldexpr == no)
item->setOpen(TRUE);
}
if (oldexpr != newexpr)
emit symbolChanged(item);
break;
case S_INT:
case S_HEX:
case S_STRING:
#if QT_VERSION >= 300
if (colMap[dataColIdx] >= 0)
item->startRename(colMap[dataColIdx]);
else
#endif
lineEdit->show(item);
break;
}
}
void ConfigList::setRootMenu(struct menu *menu)
{
enum prop_type type;
if (rootEntry == menu)
return;
type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
if (type != P_MENU && type != P_ROOTMENU)
return;
updateMenuList(this, 0);
rootEntry = menu;
updateListAll();
setSelected(currentItem(), hasFocus());
}
void ConfigList::setParentMenu(void)
{
ConfigItem* item;
struct menu *oldroot, *newroot;
oldroot = rootEntry;
newroot = menu_get_parent_menu(oldroot);
if (newroot == oldroot)
return;
setRootMenu(newroot);
QListViewItemIterator it(this);
for (; (item = (ConfigItem*)it.current()); it++) {
if (item->menu == oldroot) {
setCurrentItem(item);
ensureItemVisible(item);
break;
}
}
}
void ConfigList::keyPressEvent(QKeyEvent* ev)
{
QListViewItem* i = currentItem();
ConfigItem* item;
struct menu *menu;
enum prop_type type;
if (ev->key() == Key_Escape && mode != fullMode) {
emit parentSelected();
ev->accept();
return;
}
if (!i) {
Parent::keyPressEvent(ev);
return;
}
item = (ConfigItem*)i;
switch (ev->key()) {
case Key_Return:
case Key_Enter:
menu = item->menu;
type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) {
emit menuSelected(menu);
break;
}
case Key_Space:
changeValue(item);
break;
case Key_N:
setValue(item, no);
break;
case Key_M:
setValue(item, mod);
break;
case Key_Y:
setValue(item, yes);
break;
default:
Parent::keyPressEvent(ev);
return;
}
ev->accept();
}
void ConfigList::contentsMousePressEvent(QMouseEvent* e)
{
//QPoint p(contentsToViewport(e->pos()));
//printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
QListView::contentsMousePressEvent(e);
}
void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
{
QPoint p(contentsToViewport(e->pos()));
ConfigItem* item = (ConfigItem*)itemAt(p);
struct menu *menu;
const QPixmap* pm;
int idx, x;
if (!item)
goto skip;
menu = item->menu;
x = header()->offset() + p.x();
idx = colRevMap[header()->sectionAt(x)];
switch (idx) {
case promptColIdx:
pm = item->pixmap(promptColIdx);
if (pm) {
int off = header()->sectionPos(0) + itemMargin() +
treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
if (x >= off && x < off + pm->width()) {
if (menu->sym)
changeValue(item);
else
emit menuSelected(menu);
}
}
break;
case noColIdx:
setValue(item, no);
break;
case modColIdx:
setValue(item, mod);
break;
case yesColIdx:
setValue(item, yes);
break;
case dataColIdx:
changeValue(item);
break;
}
skip:
//printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
QListView::contentsMouseReleaseEvent(e);
}
void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
{
//QPoint p(contentsToViewport(e->pos()));
//printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
QListView::contentsMouseMoveEvent(e);
}
void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
{
QPoint p(contentsToViewport(e->pos()));
ConfigItem* item = (ConfigItem*)itemAt(p);
struct menu *menu;
enum prop_type ptype;
if (!item)
goto skip;
menu = item->menu;
ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
if ((ptype == P_ROOTMENU || ptype == P_MENU) &&
(mode == singleMode || mode == symbolMode))
emit menuSelected(menu);
skip:
//printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
QListView::contentsMouseDoubleClickEvent(e);
}
void ConfigList::focusInEvent(QFocusEvent *e)
{
Parent::focusInEvent(e);
QListViewItem* item = currentItem();
if (!item)
return;
setSelected(item, TRUE);
emit gotFocus();
}
/*
* Construct the complete config widget
*/
ConfigView::ConfigView(void)
{
QMenuBar* menu;
QSplitter* split1;
QSplitter* split2;
showDebug = false;
split1 = new QSplitter(this);
split1->setOrientation(QSplitter::Horizontal);
setCentralWidget(split1);
menuList = new ConfigList(split1, this);
split2 = new QSplitter(split1);
split2->setOrientation(QSplitter::Vertical);
// create config tree
QVBox* box = new QVBox(split2);
configList = new ConfigList(box, this);
configList->lineEdit = new ConfigLineEdit(box);
configList->lineEdit->hide();
configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)),
configList, SLOT(updateList(ConfigItem*)));
configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)),
menuList, SLOT(updateList(ConfigItem*)));
configList->connect(configList->lineEdit, SIGNAL(lineChanged(ConfigItem*)),
SLOT(updateList(ConfigItem*)));
helpText = new QTextView(split2);
helpText->setTextFormat(Qt::RichText);
setTabOrder(configList, helpText);
configList->setFocus();
menu = menuBar();
toolBar = new QToolBar("Tools", this);
backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
connect(backAction, SIGNAL(activated()), SLOT(goBack()));
backAction->setEnabled(FALSE);
QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
connect(quitAction, SIGNAL(activated()), SLOT(close()));
QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
showNameAction->setToggleAction(TRUE);
showNameAction->setOn(configList->showName);
connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
showRangeAction->setToggleAction(TRUE);
showRangeAction->setOn(configList->showRange);
connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
showDataAction->setToggleAction(TRUE);
showDataAction->setOn(configList->showData);
connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
showAllAction->setToggleAction(TRUE);
showAllAction->setOn(configList->showAll);
connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
showDebugAction->setToggleAction(TRUE);
showDebugAction->setOn(showDebug);
connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
// init tool bar
backAction->addTo(toolBar);
toolBar->addSeparator();
loadAction->addTo(toolBar);
saveAction->addTo(toolBar);
toolBar->addSeparator();
singleViewAction->addTo(toolBar);
splitViewAction->addTo(toolBar);
fullViewAction->addTo(toolBar);
// create config menu
QPopupMenu* config = new QPopupMenu(this);
menu->insertItem("&File", config);
loadAction->addTo(config);
saveAction->addTo(config);
saveAsAction->addTo(config);
config->insertSeparator();
quitAction->addTo(config);
// create options menu
QPopupMenu* optionMenu = new QPopupMenu(this);
menu->insertItem("&Option", optionMenu);
showNameAction->addTo(optionMenu);
showRangeAction->addTo(optionMenu);
showDataAction->addTo(optionMenu);
optionMenu->insertSeparator();
showAllAction->addTo(optionMenu);
showDebugAction->addTo(optionMenu);
connect(configList, SIGNAL(menuSelected(struct menu *)),
SLOT(changeMenu(struct menu *)));
connect(configList, SIGNAL(parentSelected()),
SLOT(goBack()));
connect(menuList, SIGNAL(menuSelected(struct menu *)),
SLOT(changeMenu(struct menu *)));
connect(configList, SIGNAL(gotFocus(void)),
SLOT(listFocusChanged(void)));
connect(menuList, SIGNAL(gotFocus(void)),
SLOT(listFocusChanged(void)));
//showFullView();
showSplitView();
}
static QString print_filter(const char *str)
{
QRegExp re("[<>&\"\\n]");
QString res = str;
for (int i = 0; (i = res.find(re, i)) >= 0;) {
switch (res[i].latin1()) {
case '<':
res.replace(i, 1, "&lt;");
i += 4;
break;
case '>':
res.replace(i, 1, "&gt;");
i += 4;
break;
case '&':
res.replace(i, 1, "&amp;");
i += 5;
break;
case '"':
res.replace(i, 1, "&quot;");
i += 6;
break;
case '\n':
res.replace(i, 1, "<br>");
i += 4;
break;
}
}
return res;
}
static void expr_print_help(void *data, const char *str)
{
((QString*)data)->append(print_filter(str));
}
/*
* display a new help entry as soon as a new menu entry is selected
*/
void ConfigView::setHelp(QListViewItem* item)
{
struct symbol* sym;
struct menu* menu;
configList->lineEdit->hide();
if (item) {
QString head, debug, help;
menu = ((ConfigItem*)item)->menu;
sym = menu->sym;
if (sym) {
if (menu->prompt) {
head += "<big><b>";
head += print_filter(menu->prompt->text);
head += "</b></big>";
if (sym->name) {
head += " (";
head += print_filter(sym->name);
head += ")";
}
} else if (sym->name) {
head += "<big><b>";
head += print_filter(sym->name);
head += "</b></big>";
}
head += "<br><br>";
if (showDebug) {
debug += "type: ";
debug += print_filter(sym_type_name(sym->type));
debug += "<br>";
for (struct property *prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
case P_PROMPT:
debug += "prompt: ";
debug += print_filter(prop->text);
debug += "<br>";
if (prop->visible.expr) {
debug += "&nbsp;&nbsp;dep: ";
expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
debug += "<br>";
}
break;
case P_DEFAULT:
debug += "default: ";
if (sym_is_choice(sym))
debug += print_filter(prop->def->name);
else {
sym_calc_value(prop->def);
debug += print_filter(sym_get_string_value(prop->def));
}
debug += "<br>";
if (prop->visible.expr) {
debug += "&nbsp;&nbsp;dep: ";
expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
debug += "<br>";
}
break;
case P_CHOICE:
break;
default:
debug += "unknown property: ";
debug += prop_get_type_name(prop->type);
debug += "<br>";
}
}
debug += "<br>";
}
help = print_filter(sym->help);
} else if (menu->prompt) {
head += "<big><b>";
head += print_filter(menu->prompt->text);
head += "</b></big><br><br>";
if (showDebug) {
if (menu->prompt->visible.expr) {
debug += "&nbsp;&nbsp;dep: ";
expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
debug += "<br>";
}
}
}
helpText->setText(head + debug + help);
return;
}
helpText->setText(NULL);
}
void ConfigView::loadConfig(void)
{
QString s = QFileDialog::getOpenFileName(".config", NULL, this);
if (s.isNull())
return;
if (conf_read(s.latin1()))
QMessageBox::information(this, "qconf", "Unable to load configuration!");
}
void ConfigView::saveConfig(void)
{
if (conf_write(NULL))
QMessageBox::information(this, "qconf", "Unable to save configuration!");
}
void ConfigView::saveConfigAs(void)
{
QString s = QFileDialog::getSaveFileName(".config", NULL, this);
if (s.isNull())
return;
if (conf_write(s.latin1()))
QMessageBox::information(this, "qconf", "Unable to save configuration!");
}
void ConfigView::changeMenu(struct menu *menu)
{
configList->setRootMenu(menu);
backAction->setEnabled(TRUE);
}
void ConfigView::listFocusChanged(void)
{
if (menuList->hasFocus()) {
if (menuList->mode == menuMode)
configList->clearSelection();
setHelp(menuList->selectedItem());
} else if (configList->hasFocus()) {
setHelp(configList->selectedItem());
}
}
void ConfigView::goBack(void)
{
ConfigItem* item;
configList->setParentMenu();
if (configList->rootEntry == &rootmenu)
backAction->setEnabled(FALSE);
item = (ConfigItem*)menuList->selectedItem();
while (item) {
if (item->menu == configList->rootEntry) {
menuList->setSelected(item, TRUE);
break;
}
item = (ConfigItem*)item->parent();
}
}
void ConfigView::showSingleView(void)
{
menuList->hide();
menuList->setRootMenu(0);
configList->mode = singleMode;
if (configList->rootEntry == &rootmenu)
configList->updateListAll();
else
configList->setRootMenu(&rootmenu);
configList->setAllOpen(TRUE);
configList->setFocus();
}
void ConfigView::showSplitView(void)
{
configList->mode = symbolMode;
if (configList->rootEntry == &rootmenu)
configList->updateListAll();
else
configList->setRootMenu(&rootmenu);
configList->setAllOpen(TRUE);
configApp->processEvents();
menuList->mode = menuMode;
menuList->setRootMenu(&rootmenu);
menuList->show();
menuList->setAllOpen(TRUE);
menuList->setFocus();
}
void ConfigView::showFullView(void)
{
menuList->hide();
menuList->setRootMenu(0);
configList->mode = fullMode;
if (configList->rootEntry == &rootmenu)
configList->updateListAll();
else
configList->setRootMenu(&rootmenu);
configList->setAllOpen(FALSE);
configList->setFocus();
}
void ConfigView::setShowAll(bool b)
{
if (configList->showAll == b)
return;
configList->showAll = b;
configList->updateListAll();
menuList->showAll = b;
menuList->updateListAll();
}
void ConfigView::setShowDebug(bool b)
{
if (showDebug == b)
return;
showDebug = b;
}
void ConfigView::setShowName(bool b)
{
if (configList->showName == b)
return;
configList->showName = b;
configList->reinit();
}
void ConfigView::setShowRange(bool b)
{
if (configList->showRange == b)
return;
configList->showRange = b;
configList->reinit();
}
void ConfigView::setShowData(bool b)
{
if (configList->showData == b)
return;
configList->showData = b;
configList->reinit();
}
/*
* ask for saving configuration before quitting
* TODO ask only when something changed
*/
void ConfigView::closeEvent(QCloseEvent* e)
{
if (!sym_change_count) {
e->accept();
return;
}
QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
mb.setButtonText(QMessageBox::Yes, "&Save Changes");
mb.setButtonText(QMessageBox::No, "&Discard Changes");
mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
switch (mb.exec()) {
case QMessageBox::Yes:
conf_write(NULL);
case QMessageBox::No:
e->accept();
break;
case QMessageBox::Cancel:
e->ignore();
break;
}
}
void fixup_rootmenu(struct menu *menu)
{
struct menu *child;
if (!menu->prompt || menu->prompt->type != P_MENU)
return;
menu->prompt->type = P_ROOTMENU;
for (child = menu->list; child; child = child->next)
fixup_rootmenu(child);
}
int main(int ac, char** av)
{
ConfigView* v;
const char *name;
#ifndef LKC_DIRECT_LINK
kconfig_load();
#endif
configApp = new QApplication(ac, av);
if (ac > 1 && av[1][0] == '-') {
switch (av[1][1]) {
case 'a':
//showAll = 1;
break;
case 'h':
case '?':
printf("%s <config>\n", av[0]);
exit(0);
}
name = av[2];
} else
name = av[1];
conf_parse(name);
fixup_rootmenu(&rootmenu);
conf_read(NULL);
//zconfdump(stdout);
v = new ConfigView();
//zconfdump(stdout);
v->show();
configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
configApp->exec();
return 0;
}
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <qlistview.h>
class ConfigLineEdit;
class ConfigItem;
class ConfigView;
enum colIdx {
promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
};
enum listMode {
singleMode, menuMode, symbolMode, fullMode
};
class ConfigList : public QListView {
Q_OBJECT
typedef class QListView Parent;
public:
ConfigList(QWidget* p, ConfigView* cview);
void reinit(void);
ConfigLineEdit* lineEdit;
protected:
ConfigView* cview;
void keyPressEvent(QKeyEvent *e);
void contentsMousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e);
void contentsMouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e);
public slots:
void setRootMenu(struct menu *menu);
void updateList(ConfigItem *item);
void setValue(ConfigItem* item, tristate val);
void changeValue(ConfigItem* item);
void updateSelection(void);
signals:
void menuSelected(struct menu *menu);
void parentSelected(void);
void symbolChanged(ConfigItem* item);
void gotFocus(void);
public:
void updateListAll(void)
{
updateAll = true;
updateList(NULL);
updateAll = false;
}
ConfigList* listView()
{
return this;
}
ConfigItem* firstChild() const
{
return (ConfigItem *)Parent::firstChild();
}
int mapIdx(colIdx idx)
{
return colMap[idx];
}
void addColumn(colIdx idx, const QString& label)
{
colMap[idx] = Parent::addColumn(label);
colRevMap[colMap[idx]] = idx;
}
void removeColumn(colIdx idx)
{
int col = colMap[idx];
if (col >= 0) {
Parent::removeColumn(col);
colRevMap[col] = colMap[idx] = -1;
}
}
void setAllOpen(bool open);
void setParentMenu(void);
bool updateAll;
QPixmap symbolYesPix, symbolModPix, symbolNoPix;
QPixmap choiceYesPix, choiceNoPix, menuPix, menuInvPix;
bool showAll, showName, showRange, showData;
enum listMode mode;
struct menu *rootEntry;
QColorGroup disabledColorGroup;
QColorGroup inactivedColorGroup;
private:
int colMap[colNr];
int colRevMap[colNr];
};
class ConfigItem : public QListViewItem {
typedef class QListViewItem Parent;
public:
ConfigItem(QListView *parent, ConfigItem *after, struct menu *m)
: Parent(parent, after), menu(m)
{
init();
}
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m)
: Parent(parent, after), menu(m)
{
init();
}
~ConfigItem(void);
void init(void);
#if QT_VERSION >= 300
void okRename(int col);
#endif
void updateMenu(void);
ConfigList* listView() const
{
return (ConfigList*)Parent::listView();
}
ConfigItem* firstChild() const
{
return (ConfigItem *)Parent::firstChild();
}
ConfigItem* nextSibling() const
{
return (ConfigItem *)Parent::nextSibling();
}
void setText(colIdx idx, const QString& text)
{
Parent::setText(listView()->mapIdx(idx), text);
}
QString text(colIdx idx) const
{
return Parent::text(listView()->mapIdx(idx));
}
void setPixmap(colIdx idx, const QPixmap& pm)
{
Parent::setPixmap(listView()->mapIdx(idx), pm);
}
const QPixmap* pixmap(colIdx idx) const
{
return Parent::pixmap(listView()->mapIdx(idx));
}
void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
struct menu *menu;
bool visible;
bool doInit;
};
class ConfigLineEdit : public QLineEdit {
Q_OBJECT
typedef class QLineEdit Parent;
public:
ConfigLineEdit(QWidget * parent)
: QLineEdit(parent)
{ }
void show(ConfigItem *i);
void keyPressEvent(QKeyEvent *e);
signals:
void lineChanged(ConfigItem *item);
public:
ConfigItem *item;
};
class ConfigView : public QMainWindow {
Q_OBJECT
public:
ConfigView(void);
public slots:
void setHelp(QListViewItem* item);
void changeMenu(struct menu *);
void listFocusChanged(void);
void goBack(void);
void loadConfig(void);
void saveConfig(void);
void saveConfigAs(void);
void showSingleView(void);
void showSplitView(void);
void showFullView(void);
void setShowAll(bool);
void setShowDebug(bool);
void setShowRange(bool);
void setShowName(bool);
void setShowData(bool);
protected:
void closeEvent(QCloseEvent *e);
ConfigList *menuList;
ConfigList *configList;
QTextView *helpText;
QToolBar *toolBar;
QAction *backAction;
bool showDebug;
};
/*
* 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 <sys/utsname.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct symbol symbol_yes = {
name: "y",
curr: { "y", yes },
flags: SYMBOL_YES|SYMBOL_VALID,
}, symbol_mod = {
name: "m",
curr: { "m", mod },
flags: SYMBOL_MOD|SYMBOL_VALID,
}, symbol_no = {
name: "n",
curr: { "n", no },
flags: SYMBOL_NO|SYMBOL_VALID,
}, symbol_empty = {
name: "",
curr: { "", no },
flags: SYMBOL_VALID,
};
int sym_change_count;
struct symbol *modules_sym;
void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = create_prop(P_DEFAULT);
struct property **propp;
prop->sym = sym;
prop->def = sym_lookup(def, 1);
/* append property to the prop list of symbol */
if (prop->sym) {
for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
;
*propp = prop;
}
}
void sym_init(void)
{
struct symbol *sym;
struct utsname uts;
char *p;
static bool inited = false;
if (inited)
return;
inited = true;
uname(&uts);
sym = sym_lookup("ARCH", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("ARCH");
if (p)
sym_add_default(sym, p);
sym = sym_lookup("KERNELRELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("KERNELRELEASE");
if (p)
sym_add_default(sym, p);
sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
sym_add_default(sym, uts.release);
}
int sym_get_type(struct symbol *sym)
{
int type = sym->type;
if (type == S_TRISTATE) {
if (sym_is_choice_value(sym) && sym->visible == yes)
type = S_BOOLEAN;
else {
sym_calc_value(modules_sym);
if (S_TRI(modules_sym->curr) == no)
type = S_BOOLEAN;
}
}
return type;
}
const char *sym_type_name(int type)
{
switch (type) {
case S_BOOLEAN:
return "boolean";
case S_TRISTATE:
return "tristate";
case S_INT:
return "integer";
case S_HEX:
return "hex";
case S_STRING:
return "string";
case S_UNKNOWN:
return "unknown";
}
return "???";
}
struct property *sym_get_choice_prop(struct symbol *sym)
{
struct property *prop;
for_all_choices(sym, prop)
return prop;
return NULL;
}
struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
tristate visible;
for_all_defaults(sym, prop) {
visible = E_CALC(prop->visible);
if (visible != no)
return prop;
}
return NULL;
}
void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
tristate visible, oldvisible;
/* any prompt visible? */
oldvisible = sym->visible;
visible = no;
for_all_prompts(sym, prop)
visible = E_OR(visible, E_CALC(prop->visible));
if (oldvisible != visible) {
sym->visible = visible;
sym->flags |= SYMBOL_CHANGED;
}
}
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
struct property *prop, *def_prop;
struct symbol *def_sym;
struct expr *e;
if (sym->flags & SYMBOL_VALID)
return;
oldval = sym->curr;
switch (sym->type) {
case S_INT:
case S_HEX:
case S_STRING:
newval = symbol_empty.curr;
break;
case S_BOOLEAN:
case S_TRISTATE:
newval = symbol_no.curr;
break;
default:
S_VAL(newval) = sym->name;
S_TRI(newval) = no;
if (sym->flags & SYMBOL_CONST) {
goto out;
}
//newval = symbol_empty.curr;
// generate warning somewhere here later
//S_TRI(newval) = yes;
goto out;
}
sym->flags |= SYMBOL_VALID;
if (!sym_is_choice_value(sym))
sym->flags &= ~SYMBOL_WRITE;
sym_calc_visibility(sym);
/* set default if recursively called */
sym->curr = newval;
if (sym->visible != no) {
sym->flags |= SYMBOL_WRITE;
if (!sym_has_value(sym)) {
if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym);
if (prop) {
sym_calc_value(prop->def);
newval = prop->def->curr;
}
}
} else
newval = sym->def;
S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
/* if the symbol is visible and not optionial,
* possibly ignore old user choice. */
if (!sym_is_optional(sym) && S_TRI(newval) == no)
S_TRI(newval) = sym->visible;
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no;
}
} else {
prop = sym_get_default_prop(sym);
if (prop) {
sym->flags |= SYMBOL_WRITE;
sym_calc_value(prop->def);
newval = prop->def->curr;
}
}
switch (sym_get_type(sym)) {
case S_TRISTATE:
if (S_TRI(newval) != mod)
break;
sym_calc_value(modules_sym);
if (S_TRI(modules_sym->curr) == no)
S_TRI(newval) = yes;
break;
case S_BOOLEAN:
if (S_TRI(newval) == mod)
S_TRI(newval) = yes;
}
out:
sym->curr = newval;
if (sym_is_choice(sym) && S_TRI(newval) == yes) {
def_sym = S_VAL(sym->def);
if (def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible == no)
def_sym = NULL;
}
if (!def_sym) {
for_all_defaults(sym, def_prop) {
if (E_CALC(def_prop->visible) == no)
continue;
sym_calc_visibility(def_prop->def);
if (def_prop->def->visible != no) {
def_sym = def_prop->def;
break;
}
}
}
if (!def_sym) {
prop = sym_get_choice_prop(sym);
for (e = prop->dep; e; e = e->left.expr) {
sym_calc_visibility(e->right.sym);
if (e->right.sym->visible != no) {
def_sym = e->right.sym;
break;
}
}
}
S_VAL(newval) = def_sym;
}
if (memcmp(&oldval, &newval, sizeof(newval)))
sym->flags |= SYMBOL_CHANGED;
sym->curr = newval;
if (sym_is_choice(sym)) {
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
prop = sym_get_choice_prop(sym);
for (e = prop->dep; e; e = e->left.expr)
e->right.sym->flags |= flags;
}
}
void sym_clear_all_valid(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
sym_change_count++;
}
void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym->flags |= SYMBOL_CHANGED;
}
bool sym_tristate_within_range(struct symbol *sym, tristate val)
{
int type = sym_get_type(sym);
if (sym->visible == no)
return false;
if (type != S_BOOLEAN && type != S_TRISTATE)
return false;
switch (val) {
case no:
if (sym_is_choice_value(sym) && sym->visible == yes)
return false;
return sym_is_optional(sym);
case mod:
if (sym_is_choice_value(sym) && sym->visible == yes)
return false;
return type == S_TRISTATE;
case yes:
return type == S_BOOLEAN || sym->visible == yes;
}
return false;
}
bool sym_set_tristate_value(struct symbol *sym, tristate val)
{
tristate oldval = sym_get_tristate_value(sym);
if (oldval != val && !sym_tristate_within_range(sym, val))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
sym->flags |= SYMBOL_CHANGED;
}
if (sym_is_choice_value(sym) && val == yes) {
struct property *prop = sym_get_choice_prop(sym);
S_VAL(prop->def->def) = sym;
prop->def->flags &= ~SYMBOL_NEW;
}
S_TRI(sym->def) = val;
if (oldval != val) {
sym_clear_all_valid();
if (sym == modules_sym)
sym_set_all_changed();
}
return true;
}
tristate sym_toggle_tristate_value(struct symbol *sym)
{
tristate oldval, newval;
oldval = newval = sym_get_tristate_value(sym);
do {
switch (newval) {
case no:
newval = mod;
break;
case mod:
newval = yes;
break;
case yes:
newval = no;
break;
}
if (sym_set_tristate_value(sym, newval))
break;
} while (oldval != newval);
return newval;
}
bool sym_string_valid(struct symbol *sym, const char *str)
{
char ch;
switch (sym->type) {
case S_STRING:
return true;
case S_INT:
ch = *str++;
if (ch == '-')
ch = *str++;
if (!isdigit(ch))
return false;
if (ch == '0' && *str != 0)
return false;
while ((ch = *str++)) {
if (!isdigit(ch))
return false;
}
return true;
case S_HEX:
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
str += 2;
ch = *str++;
do {
if (!isxdigit(ch))
return false;
} while ((ch = *str++));
return true;
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
case 'y':
case 'Y':
return sym_tristate_within_range(sym, yes);
case 'm':
case 'M':
return sym_tristate_within_range(sym, mod);
case 'n':
case 'N':
return sym_tristate_within_range(sym, no);
}
return false;
default:
return false;
}
}
bool sym_set_string_value(struct symbol *sym, const char *newval)
{
const char *oldval;
char *val;
int size;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (newval[0]) {
case 'y':
case 'Y':
return sym_set_tristate_value(sym, yes);
case 'm':
case 'M':
return sym_set_tristate_value(sym, mod);
case 'n':
case 'N':
return sym_set_tristate_value(sym, no);
}
return false;
default:
;
}
if (!sym_string_valid(sym, newval))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
sym->flags |= SYMBOL_CHANGED;
}
oldval = S_VAL(sym->def);
size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2;
S_VAL(sym->def) = val = malloc(size);
*val++ = '0';
*val++ = 'x';
} else if (!oldval || strcmp(oldval, newval))
S_VAL(sym->def) = val = malloc(size);
else
return true;
strcpy(val, newval);
free((void *)oldval);
sym_clear_all_valid();
return true;
}
const char *sym_get_string_value(struct symbol *sym)
{
tristate val;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
val = sym_get_tristate_value(sym);
switch (val) {
case no:
return "n";
case mod:
return "m";
case yes:
return "y";
}
break;
default:
;
}
return (const char *)S_VAL(sym->curr);
}
bool sym_is_changable(struct symbol *sym)
{
if (sym->visible == no)
return false;
/* at least 'n' and 'y'/'m' is selectable */
if (sym_is_optional(sym))
return true;
/* no 'n', so 'y' and 'm' must be selectable */
if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
return true;
return false;
}
struct symbol *sym_lookup(const char *name, int isconst)
{
struct symbol *symbol;
const char *ptr;
char *new_name;
int hash = 0;
//printf("lookup: %s -> ", name);
if (name) {
if (name[0] && !name[1]) {
switch (name[0]) {
case 'y': return &symbol_yes;
case 'm': return &symbol_mod;
case 'n': return &symbol_no;
}
}
for (ptr = name; *ptr; ptr++)
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name)) {
if ((isconst && symbol->flags & SYMBOL_CONST) ||
(!isconst && !(symbol->flags & SYMBOL_CONST))) {
//printf("h:%p\n", symbol);
return symbol;
}
}
}
new_name = strdup(name);
} else {
new_name = NULL;
hash = 256;
}
symbol = malloc(sizeof(*symbol));
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
symbol->flags = SYMBOL_NEW;
if (isconst)
symbol->flags |= SYMBOL_CONST;
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
//printf("n:%p\n", symbol);
return symbol;
}
struct symbol *sym_find(const char *name)
{
struct symbol *symbol = NULL;
const char *ptr;
int hash = 0;
if (!name)
return NULL;
if (name[0] && !name[1]) {
switch (name[0]) {
case 'y': return &symbol_yes;
case 'm': return &symbol_mod;
case 'n': return &symbol_no;
}
}
for (ptr = name; *ptr; ptr++)
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name) &&
!(symbol->flags & SYMBOL_CONST))
break;
}
return symbol;
}
const char *prop_get_type_name(enum prop_type type)
{
switch (type) {
case P_PROMPT:
return "prompt";
case P_COMMENT:
return "comment";
case P_MENU:
return "menu";
case P_ROOTMENU:
return "rootmenu";
case P_DEFAULT:
return "default";
case P_CHOICE:
return "choice";
default:
return "unknown";
}
}
%option backup nostdinit noyywrap full ecs
%option 8bit backup nodefault perf-report perf-report
%x COMMAND HELP STRING PARAM
%{
/*
* 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>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#include "zconf.tab.h"
#define START_STRSIZE 16
char *text;
static char *text_ptr;
static int text_size, text_asize;
struct buffer {
struct buffer *parent;
YY_BUFFER_STATE state;
};
struct buffer *current_buf;
static int last_ts, first_ts;
static void zconf_endhelp(void);
static struct buffer *zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
text_ptr = text;
text_size = 0;
*text_ptr = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
text = realloc(text, new_size);
text_asize = new_size;
text_ptr = text + text_size;
}
memcpy(text_ptr, str, size);
text_ptr += size;
text_size += size;
*text_ptr = 0;
}
void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
memcpy(text, str, size);
text[size] = 0;
}
%}
ws [ \n\t]
n [A-Za-z0-9_]
%%
int str = 0;
int ts, i;
[ \t]*#.*\n current_file->lineno++;
[ \t]*#.*
[ \t]*\n current_file->lineno++; return T_EOL;
[ \t]+ {
BEGIN(COMMAND);
}
. {
unput(yytext[0]);
//printf("new config: ");
//symbol_end(NULL);
BEGIN(COMMAND);
}
<COMMAND>{
"mainmenu" BEGIN(PARAM); return T_MAINMENU;
"menu" BEGIN(PARAM); return T_MENU;
"endmenu" BEGIN(PARAM); return T_ENDMENU;
"source" BEGIN(PARAM); return T_SOURCE;
"choice" BEGIN(PARAM); return T_CHOICE;
"endchoice" BEGIN(PARAM); return T_ENDCHOICE;
"comment" BEGIN(PARAM); return T_COMMENT;
"config" BEGIN(PARAM); return T_CONFIG;
"help" BEGIN(PARAM); return T_HELP;
"if" BEGIN(PARAM); return T_IF;
"endif" BEGIN(PARAM); return T_ENDIF;
"depends" BEGIN(PARAM); return T_DEPENDS;
"requires" BEGIN(PARAM); return T_REQUIRES;
"optional" BEGIN(PARAM); return T_OPTIONAL;
"default" BEGIN(PARAM); return T_DEFAULT;
"prompt" BEGIN(PARAM); return T_PROMPT;
"tristate" BEGIN(PARAM); return T_TRISTATE;
"bool" BEGIN(PARAM); return T_BOOLEAN;
"boolean" BEGIN(PARAM); return T_BOOLEAN;
"int" BEGIN(PARAM); return T_INT;
"hex" BEGIN(PARAM); return T_HEX;
"string" BEGIN(PARAM); return T_STRING;
{n}+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
.
\n current_file->lineno++; BEGIN(INITIAL);
}
<PARAM>{
"&&" return T_AND;
"||" return T_OR;
"(" return T_OPEN_PAREN;
")" return T_CLOSE_PAREN;
"!" return T_NOT;
"=" return T_EQUAL;
"!=" return T_UNEQUAL;
"if" return T_IF;
"on" return T_ON;
\"|\' {
str = yytext[0];
new_string();
BEGIN(STRING);
}
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
--- /* ignore */
({n}|[-/.])+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
.
}
<STRING>{
[^'"\n\\]+ {
append_string(yytext, yyleng);
}
\'|\" {
if (str == yytext[0]) {
BEGIN(PARAM);
zconflval.string = text;
//printf("s:%s\n", text);
return T_STRING;
} else
append_string(yytext, 1);
}
\\[ \t]*\n append_string(yytext+yyleng-1, 1); current_file->lineno++;
\\[ \t]* append_string(yytext+1, yyleng-1);
\\. append_string(yytext+1, 1);
\n {
//printf(":%d: open string!\n", current_file->lineno+1);
exit(0);
}
<<EOF>> {
//printf(":%d: open string!\n", current_file->lineno+1);
exit(0);
}
}
<HELP>{
[ \t]+ {
ts = 0;
for (i = 0; i < yyleng; i++) {
if (yytext[i] == '\t')
ts = (ts & ~7) + 8;
else
ts++;
}
last_ts = ts;
if (first_ts) {
if (ts < first_ts) {
zconf_endhelp();
return T_HELPTEXT;
}
ts -= first_ts;
while (ts > 8) {
append_string(" ", 8);
ts -= 8;
}
append_string(" ", ts);
}
}
\n/[^ \t\n] {
current_file->lineno++;
zconf_endhelp();
return T_HELPTEXT;
}
[ \t]*\n {
current_file->lineno++;
append_string("\n", 1);
}
[^ \t\n].* {
append_string(yytext, yyleng);
if (!first_ts)
first_ts = last_ts;
}
<<EOF>> {
zconf_endhelp();
return T_HELPTEXT;
}
}
<<EOF>> {
if (current_buf) {
zconf_endfile();
return T_EOF;
}
yyterminate();
}
%%
void zconf_starthelp(void)
{
new_string();
last_ts = first_ts = 0;
BEGIN(HELP);
}
static void zconf_endhelp(void)
{
zconflval.string = text;
BEGIN(INITIAL);
}
void zconf_initscan(const char *name)
{
yyin = fopen(name, "r");
if (!yyin) {
printf("can't find file %s\n", name);
exit(1);
}
//fprintf(stderr, "zconf_initscan: %s\n", name);
current_buf = malloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
current_file->lineno = 1;
current_file->flags = FILE_BUSY;
}
void zconf_nextfile(const char *name)
{
struct file *file = file_lookup(name);
struct buffer *buf = malloc(sizeof(*buf));
memset(buf, 0, sizeof(*buf));
current_buf->state = YY_CURRENT_BUFFER;
yyin = fopen(name, "r");
if (!yyin) {
printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
exit(1);
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf;
current_buf = buf;
//fprintf(stderr, "zconf_nextfile: %s\n", name);
if (file->flags & FILE_BUSY) {
printf("recursive scan (%s)?\n", name);
exit(1);
}
if (file->flags & FILE_SCANNED) {
printf("file %s already scanned?\n", name);
exit(1);
}
file->flags |= FILE_BUSY;
file->lineno = 1;
file->parent = current_file;
current_file = file;
}
static struct buffer *zconf_endfile(void)
{
struct buffer *parent;
current_file->flags |= FILE_SCANNED;
current_file->flags &= ~FILE_BUSY;
current_file = current_file->parent;
parent = current_buf->parent;
if (parent) {
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(parent->state);
}
free(current_buf);
current_buf = parent;
return parent;
}
int zconf_lineno(void)
{
if (current_buf)
return current_file->lineno;
else
return 0;
}
char *zconf_curname(void)
{
if (current_buf)
return current_file->name;
else
return "<none>";
}
/* A Bison parser, made from zconf.y
by GNU bison 1.35. */
#define YYBISON 1 /* Identify Bison output. */
#define yyparse zconfparse
#define yylex zconflex
#define yyerror zconferror
#define yylval zconflval
#define yychar zconfchar
#define yydebug zconfdebug
#define yynerrs zconfnerrs
# define T_MAINMENU 257
# define T_MENU 258
# define T_ENDMENU 259
# define T_SOURCE 260
# define T_CHOICE 261
# define T_ENDCHOICE 262
# define T_COMMENT 263
# define T_CONFIG 264
# define T_HELP 265
# define T_HELPTEXT 266
# define T_IF 267
# define T_ENDIF 268
# define T_DEPENDS 269
# define T_REQUIRES 270
# define T_OPTIONAL 271
# define T_PROMPT 272
# define T_DEFAULT 273
# define T_TRISTATE 274
# define T_BOOLEAN 275
# define T_INT 276
# define T_HEX 277
# define T_WORD 278
# define T_STRING 279
# define T_UNEQUAL 280
# define T_EOF 281
# define T_EOL 282
# define T_CLOSE_PAREN 283
# define T_OPEN_PAREN 284
# define T_ON 285
# define T_OR 286
# define T_AND 287
# define T_EQUAL 288
# define T_NOT 289
#line 1 "zconf.y"
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
#define DEBUG_PARSE 0x0002
int cdebug = PRINTD;
extern int zconflex(void);
static void zconfprint(const char *err, ...);
static void zconferror(const char *err);
static bool zconf_endtoken(int token, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
#define YYERROR_VERBOSE
#line 32 "zconf.y"
#ifndef YYSTYPE
typedef union
{
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
} yystype;
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
#endif
#line 83 "zconf.y"
#define LKC_DIRECT_LINK
#include "lkc.h"
#ifndef YYDEBUG
# define YYDEBUG 1
#endif
#define YYFINAL 145
#define YYFLAG -32768
#define YYNTBASE 36
/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
#define YYTRANSLATE(x) ((unsigned)(x) <= 289 ? yytranslate[x] : 74)
/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
static const char yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35
};
#if YYDEBUG
static const short yyprhs[] =
{
0, 0, 1, 4, 6, 8, 10, 14, 16, 18,
20, 23, 25, 27, 29, 31, 33, 36, 40, 41,
45, 49, 52, 55, 58, 61, 64, 67, 70, 74,
78, 80, 84, 86, 91, 94, 95, 99, 103, 106,
109, 113, 115, 118, 119, 122, 125, 127, 133, 137,
138, 141, 144, 147, 150, 154, 156, 161, 164, 165,
168, 171, 174, 178, 181, 184, 187, 191, 194, 197,
198, 202, 205, 209, 212, 215, 216, 218, 222, 224,
226, 228, 230, 232, 234, 236, 237, 240, 242, 246,
250, 254, 257, 261, 265, 267
};
static const short yyrhs[] =
{
-1, 36, 37, 0, 38, 0, 46, 0, 57, 0,
3, 68, 70, 0, 5, 0, 14, 0, 8, 0,
1, 70, 0, 52, 0, 62, 0, 40, 0, 60,
0, 70, 0, 10, 24, 0, 39, 28, 41, 0,
0, 41, 42, 28, 0, 41, 66, 28, 0, 41,
64, 0, 41, 28, 0, 20, 67, 0, 21, 67,
0, 22, 67, 0, 23, 67, 0, 25, 67, 0,
18, 68, 71, 0, 19, 73, 71, 0, 7, 0,
43, 28, 47, 0, 69, 0, 44, 49, 45, 28,
0, 44, 49, 0, 0, 47, 48, 28, 0, 47,
66, 28, 0, 47, 64, 0, 47, 28, 0, 18,
68, 71, 0, 17, 0, 19, 73, 0, 0, 49,
38, 0, 13, 72, 0, 69, 0, 50, 28, 53,
51, 28, 0, 50, 28, 53, 0, 0, 53, 38,
0, 53, 57, 0, 53, 46, 0, 4, 68, 0,
54, 28, 65, 0, 69, 0, 55, 58, 56, 28,
0, 55, 58, 0, 0, 58, 38, 0, 58, 57,
0, 58, 46, 0, 58, 1, 28, 0, 6, 68,
0, 59, 28, 0, 9, 68, 0, 61, 28, 65,
0, 11, 28, 0, 63, 12, 0, 0, 65, 66,
28, 0, 65, 28, 0, 15, 31, 72, 0, 15,
72, 0, 16, 72, 0, 0, 68, 0, 68, 13,
72, 0, 24, 0, 25, 0, 5, 0, 8, 0,
14, 0, 28, 0, 27, 0, 0, 13, 72, 0,
73, 0, 73, 34, 73, 0, 73, 26, 73, 0,
30, 72, 29, 0, 35, 72, 0, 72, 32, 72,
0, 72, 33, 72, 0, 24, 0, 25, 0
};
#endif
#if YYDEBUG
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const short yyrline[] =
{
0, 88, 89, 92, 93, 94, 95, 96, 97, 98,
99, 102, 104, 105, 106, 107, 113, 121, 127, 129,
130, 131, 132, 135, 141, 147, 153, 159, 165, 171,
179, 188, 194, 202, 204, 210, 212, 213, 214, 215,
218, 224, 230, 237, 239, 244, 254, 262, 264, 270,
272, 273, 274, 279, 286, 292, 300, 302, 308, 310,
311, 312, 313, 316, 322, 329, 336, 343, 349, 356,
357, 358, 361, 366, 371, 379, 381, 385, 390, 391,
394, 395, 396, 399, 400, 402, 403, 406, 407, 408,
409, 410, 411, 412, 415, 416
};
#endif
#if (YYDEBUG) || defined YYERROR_VERBOSE
/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
static const char *const yytname[] =
{
"$", "error", "$undefined.", "T_MAINMENU", "T_MENU", "T_ENDMENU",
"T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
"T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", "T_REQUIRES",
"T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE", "T_BOOLEAN",
"T_INT", "T_HEX", "T_WORD", "T_STRING", "T_UNEQUAL", "T_EOF", "T_EOL",
"T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_OR", "T_AND", "T_EQUAL",
"T_NOT", "input", "block", "common_block", "config_entry_start",
"config_stmt", "config_option_list", "config_option", "choice",
"choice_entry", "choice_end", "choice_stmt", "choice_option_list",
"choice_option", "choice_block", "if", "if_end", "if_stmt", "if_block",
"menu", "menu_entry", "menu_end", "menu_stmt", "menu_block", "source",
"source_stmt", "comment", "comment_stmt", "help_start", "help",
"depends_list", "depends", "prompt_stmt_opt", "prompt", "end",
"nl_or_eof", "if_expr", "expr", "symbol", 0
};
#endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const short yyr1[] =
{
0, 36, 36, 37, 37, 37, 37, 37, 37, 37,
37, 38, 38, 38, 38, 38, 39, 40, 41, 41,
41, 41, 41, 42, 42, 42, 42, 42, 42, 42,
43, 44, 45, 46, 46, 47, 47, 47, 47, 47,
48, 48, 48, 49, 49, 50, 51, 52, 52, 53,
53, 53, 53, 54, 55, 56, 57, 57, 58, 58,
58, 58, 58, 59, 60, 61, 62, 63, 64, 65,
65, 65, 66, 66, 66, 67, 67, 67, 68, 68,
69, 69, 69, 70, 70, 71, 71, 72, 72, 72,
72, 72, 72, 72, 73, 73
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const short yyr2[] =
{
0, 0, 2, 1, 1, 1, 3, 1, 1, 1,
2, 1, 1, 1, 1, 1, 2, 3, 0, 3,
3, 2, 2, 2, 2, 2, 2, 2, 3, 3,
1, 3, 1, 4, 2, 0, 3, 3, 2, 2,
3, 1, 2, 0, 2, 2, 1, 5, 3, 0,
2, 2, 2, 2, 3, 1, 4, 2, 0, 2,
2, 2, 3, 2, 2, 2, 3, 2, 2, 0,
3, 2, 3, 2, 2, 0, 1, 3, 1, 1,
1, 1, 1, 1, 1, 0, 2, 1, 3, 3,
3, 2, 3, 3, 1, 1
};
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
doesn't specify something else to do. Zero means the default is an
error. */
static const short yydefact[] =
{
1, 0, 0, 0, 0, 7, 0, 30, 9, 0,
0, 0, 8, 84, 83, 2, 3, 0, 13, 0,
43, 4, 0, 11, 0, 58, 5, 0, 14, 0,
12, 15, 10, 78, 79, 0, 53, 63, 65, 16,
94, 95, 0, 0, 45, 87, 18, 35, 34, 49,
69, 0, 64, 69, 6, 0, 91, 0, 0, 0,
0, 17, 31, 80, 81, 82, 44, 0, 32, 48,
54, 0, 59, 61, 0, 60, 55, 66, 90, 92,
93, 89, 88, 0, 0, 0, 0, 0, 75, 75,
75, 75, 75, 22, 0, 0, 21, 0, 41, 0,
0, 39, 0, 38, 0, 33, 50, 52, 0, 51,
46, 71, 0, 62, 56, 67, 0, 73, 74, 85,
85, 23, 76, 24, 25, 26, 27, 19, 68, 20,
85, 42, 36, 37, 47, 70, 72, 0, 28, 29,
0, 40, 86, 77, 0, 0
};
static const short yydefgoto[] =
{
1, 15, 16, 17, 18, 61, 94, 19, 20, 67,
21, 62, 102, 48, 22, 108, 23, 69, 24, 25,
74, 26, 51, 27, 28, 29, 30, 95, 96, 70,
112, 121, 122, 68, 31, 138, 44, 45
};
static const short yypact[] =
{
-32768, 17, 41, 65, 65,-32768, 65,-32768,-32768, 65,
-11, 40,-32768,-32768,-32768,-32768,-32768, 13,-32768, 23,
-32768,-32768, 66,-32768, 72,-32768,-32768, 77,-32768, 81,
-32768,-32768,-32768,-32768,-32768, 41,-32768,-32768,-32768,-32768,
-32768,-32768, 40, 40, 64, 59,-32768,-32768, 98,-32768,
-32768, 49,-32768,-32768,-32768, 7,-32768, 40, 40, 67,
67, 99, 117,-32768,-32768,-32768,-32768, 85,-32768, 74,
18, 88,-32768,-32768, 95,-32768,-32768, 18,-32768, 96,
-32768,-32768,-32768, 102, 36, 40, 65, 67, 65, 65,
65, 65, 65,-32768, 103, 129,-32768, 114,-32768, 65,
67,-32768, 115,-32768, 116,-32768,-32768,-32768, 118,-32768,
-32768,-32768, 119,-32768,-32768,-32768, 40, 64, 64, 135,
135,-32768, 136,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
135,-32768,-32768,-32768,-32768,-32768, 64, 40,-32768,-32768,
40,-32768, 64, 64, 150,-32768
};
static const short yypgoto[] =
{
-32768,-32768, -37,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
-41,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
-32768, -32,-32768,-32768,-32768,-32768,-32768,-32768, 89, 100,
11, 48, 0, -22, 3, -118, -42, -52
};
#define YYLAST 153
static const short yytable[] =
{
55, 56, 139, 35, 36, 32, 37, 81, 82, 38,
73, 66, 141, 39, 72, 79, 80, 144, 2, 75,
3, 4, 5, 6, 7, 8, 9, 10, 107, 76,
11, 12, 106, 84, 85, 120, 78, 109, 54, 57,
58, 46, 117, 118, 13, 14, 111, 110, 131, -57,
71, 47, -57, 4, 63, 6, 7, 64, 9, 10,
40, 41, 11, 65, 40, 41, 42, 116, 13, 14,
42, 43, 97, 104, 136, 43, 13, 14, 4, 63,
6, 7, 64, 9, 10, 59, 119, 11, 65, 33,
34, 40, 41, 60, 49, 142, 57, 58, 143, 130,
50, 13, 14, 63, 6, 52, 64, 9, 10, 53,
83, 11, 65, 105, 84, 85, 113, 86, 87, 88,
89, 90, 91, 114, 92, 13, 14, 93, 83, 58,
115, 127, 84, 85, 98, 99, 100, 123, 124, 125,
126, 128, 129, 132, 133, 101, 134, 135, 137, 140,
145, 103, 0, 77
};
static const short yycheck[] =
{
42, 43, 120, 3, 4, 2, 6, 59, 60, 9,
51, 48, 130, 24, 51, 57, 58, 0, 1, 51,
3, 4, 5, 6, 7, 8, 9, 10, 69, 51,
13, 14, 69, 15, 16, 87, 29, 69, 35, 32,
33, 28, 84, 85, 27, 28, 28, 69, 100, 0,
1, 28, 3, 4, 5, 6, 7, 8, 9, 10,
24, 25, 13, 14, 24, 25, 30, 31, 27, 28,
30, 35, 61, 62, 116, 35, 27, 28, 4, 5,
6, 7, 8, 9, 10, 26, 86, 13, 14, 24,
25, 24, 25, 34, 28, 137, 32, 33, 140, 99,
28, 27, 28, 5, 6, 28, 8, 9, 10, 28,
11, 13, 14, 28, 15, 16, 28, 18, 19, 20,
21, 22, 23, 28, 25, 27, 28, 28, 11, 33,
28, 28, 15, 16, 17, 18, 19, 89, 90, 91,
92, 12, 28, 28, 28, 28, 28, 28, 13, 13,
0, 62, -1, 53
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/share/bison/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, 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 General Public License for more details.
You should have received a copy of the GNU 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. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* This is the parser code that is written into each bison parser when
the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
used when %semantic_parser is specified. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
variables, as they might otherwise be expanded by user macros.
There are some unavoidable exceptions within include files to
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
/* The parser invokes alloca or malloc; define the necessary symbols. */
# if YYSTACK_USE_ALLOCA
# define YYSTACK_ALLOC alloca
# else
# ifndef YYSTACK_USE_ALLOCA
# if defined (alloca) || defined (_ALLOCA_H)
# define YYSTACK_ALLOC alloca
# else
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
/* Pacify GCC's `empty if-body' warning. */
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# else
# if defined (__STDC__) || defined (__cplusplus)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# endif
# define YYSTACK_ALLOC malloc
# define YYSTACK_FREE free
# endif
#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
#if (! defined (yyoverflow) \
&& (! defined (__cplusplus) \
|| (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
short yyss;
YYSTYPE yyvs;
# if YYLSP_NEEDED
YYLTYPE yyls;
# endif
};
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# if YYLSP_NEEDED
# define YYSTACK_BYTES(N) \
((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAX)
# else
# define YYSTACK_BYTES(N) \
((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAX)
# endif
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
register YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (0)
# endif
# endif
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
elements in the stack, and YYPTR gives the new location of the
stack. Advance YYPTR to a properly aligned location for the next
stack. */
# define YYSTACK_RELOCATE(Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack, Stack, yysize); \
Stack = &yyptr->Stack; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (0)
#endif
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
# define YYSIZE_T __SIZE_TYPE__
#endif
#if ! defined (YYSIZE_T) && defined (size_t)
# define YYSIZE_T size_t
#endif
#if ! defined (YYSIZE_T)
# if defined (__STDC__) || defined (__cplusplus)
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# endif
#endif
#if ! defined (YYSIZE_T)
# define YYSIZE_T unsigned int
#endif
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(Token, Value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ \
yychar = (Token); \
yylval = (Value); \
yychar1 = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ \
yyerror ("syntax error: cannot back up"); \
YYERROR; \
} \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
are run).
When YYLLOC_DEFAULT is run, CURRENT is set the location of the
first token. By default, to implement support for ranges, extend
its range to the last symbol. */
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
Current.last_line = Rhs[N].last_line; \
Current.last_column = Rhs[N].last_column;
#endif
/* YYLEX -- calling `yylex' with the right arguments. */
#if YYPURE
# if YYLSP_NEEDED
# ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
# else
# define YYLEX yylex (&yylval, &yylloc)
# endif
# else /* !YYLSP_NEEDED */
# ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, YYLEX_PARAM)
# else
# define YYLEX yylex (&yylval)
# endif
# endif /* !YYLSP_NEEDED */
#else /* !YYPURE */
# define YYLEX yylex ()
#endif /* !YYPURE */
/* Enable debugging if requested. */
#if YYDEBUG
# ifndef YYFPRINTF
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
# define YYFPRINTF fprintf
# endif
# define YYDPRINTF(Args) \
do { \
if (yydebug) \
YYFPRINTF Args; \
} while (0)
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
#endif /* !YYDEBUG */
/* YYINITDEPTH -- initial size of the parser's stacks. */
#ifndef YYINITDEPTH
# define YYINITDEPTH 200
#endif
/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
if the built-in stack extension method is used).
Do not make this value too large; the results are undefined if
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
#if YYMAXDEPTH == 0
# undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
#ifdef YYERROR_VERBOSE
# ifndef yystrlen
# if defined (__GLIBC__) && defined (_STRING_H)
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
static YYSIZE_T
# if defined (__STDC__) || defined (__cplusplus)
yystrlen (const char *yystr)
# else
yystrlen (yystr)
const char *yystr;
# endif
{
register const char *yys = yystr;
while (*yys++ != '\0')
continue;
return yys - yystr - 1;
}
# endif
# endif
# ifndef yystpcpy
# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
# define yystpcpy stpcpy
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
static char *
# if defined (__STDC__) || defined (__cplusplus)
yystpcpy (char *yydest, const char *yysrc)
# else
yystpcpy (yydest, yysrc)
char *yydest;
const char *yysrc;
# endif
{
register char *yyd = yydest;
register const char *yys = yysrc;
while ((*yyd++ = *yys++) != '\0')
continue;
return yyd - 1;
}
# endif
# endif
#endif
#line 315 "/usr/share/bison/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
It should actually point to an object.
Grammar actions can access the variable by casting it
to the proper pointer type. */
#ifdef YYPARSE_PARAM
# if defined (__STDC__) || defined (__cplusplus)
# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
# define YYPARSE_PARAM_DECL
# else
# define YYPARSE_PARAM_ARG YYPARSE_PARAM
# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
# endif
#else /* !YYPARSE_PARAM */
# define YYPARSE_PARAM_ARG
# define YYPARSE_PARAM_DECL
#endif /* !YYPARSE_PARAM */
/* Prevent warning if -Wstrict-prototypes. */
#ifdef __GNUC__
# ifdef YYPARSE_PARAM
int yyparse (void *);
# else
int yyparse (void);
# endif
#endif
/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
variables are global, or local to YYPARSE. */
#define YY_DECL_NON_LSP_VARIABLES \
/* The lookahead symbol. */ \
int yychar; \
\
/* The semantic value of the lookahead symbol. */ \
YYSTYPE yylval; \
\
/* Number of parse errors so far. */ \
int yynerrs;
#if YYLSP_NEEDED
# define YY_DECL_VARIABLES \
YY_DECL_NON_LSP_VARIABLES \
\
/* Location data for the lookahead symbol. */ \
YYLTYPE yylloc;
#else
# define YY_DECL_VARIABLES \
YY_DECL_NON_LSP_VARIABLES
#endif
/* If nonreentrant, generate the variables here. */
#if !YYPURE
YY_DECL_VARIABLES
#endif /* !YYPURE */
int
yyparse (YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
/* If reentrant, generate the variables here. */
#if YYPURE
YY_DECL_VARIABLES
#endif /* !YYPURE */
register int yystate;
register int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Lookahead token as an internal (translated) token number. */
int yychar1 = 0;
/* Three stacks and their tools:
`yyss': related to states,
`yyvs': related to semantic values,
`yyls': related to locations.
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
short yyssa[YYINITDEPTH];
short *yyss = yyssa;
register short *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
register YYSTYPE *yyvsp;
#if YYLSP_NEEDED
/* The location stack. */
YYLTYPE yylsa[YYINITDEPTH];
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
#endif
#if YYLSP_NEEDED
# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
#else
# define YYPOPSTACK (yyvsp--, yyssp--)
#endif
YYSIZE_T yystacksize = YYINITDEPTH;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
#if YYLSP_NEEDED
YYLTYPE yyloc;
#endif
/* When reducing, the number of symbols on the RHS of the reduced
rule. */
int yylen;
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
yyssp = yyss;
yyvsp = yyvs;
#if YYLSP_NEEDED
yylsp = yyls;
#endif
goto yysetstate;
/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate. |
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks.
*/
yyssp++;
yysetstate:
*yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Get the current used size of the three stacks, in elements. */
YYSIZE_T yysize = yyssp - yyss + 1;
#ifdef yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. */
# if YYLSP_NEEDED
YYLTYPE *yyls1 = yyls;
/* This used to be a conditional around just the two extra args,
but that might be undefined if yyoverflow is a macro. */
yyoverflow ("parser stack overflow",
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yyls1, yysize * sizeof (*yylsp),
&yystacksize);
yyls = yyls1;
# else
yyoverflow ("parser stack overflow",
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
# endif
yyss = yyss1;
yyvs = yyvs1;
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
goto yyoverflowlab;
# else
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
goto yyoverflowlab;
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
{
short *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyoverflowlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
# if YYLSP_NEEDED
YYSTACK_RELOCATE (yyls);
# endif
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
#if YYLSP_NEEDED
yylsp = yyls + yysize - 1;
#endif
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
if (yyssp >= yyss + yystacksize - 1)
YYABORT;
}
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
goto yybackup;
/*-----------.
| yybackup. |
`-----------*/
yybackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* yyresume: */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* yychar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else
{
yychar1 = YYTRANSLATE (yychar);
#if YYDEBUG
/* We have to keep this `#if YYDEBUG', since we use variables
which are defined only if `YYDEBUG' is set. */
if (yydebug)
{
YYFPRINTF (stderr, "Next token is %d (%s",
yychar, yytname[yychar1]);
/* Give the individual parser a way to print the precise
meaning of a token, for further debugging info. */
# ifdef YYPRINT
YYPRINT (stderr, yychar, yylval);
# endif
YYFPRINTF (stderr, ")\n");
}
#endif
}
yyn += yychar1;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
goto yydefault;
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state.
Negative => reduce, -yyn is rule number.
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
YYDPRINTF ((stderr, "Shifting token %d (%s), ",
yychar, yytname[yychar1]));
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
#if YYLSP_NEEDED
*++yylsp = yylloc;
#endif
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
yystate = yyn;
goto yynewstate;
/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state. |
`-----------------------------------------------------------*/
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
goto yyreduce;
/*-----------------------------.
| yyreduce -- Do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'.
Otherwise, the following line sets YYVAL to the semantic value of
the lookahead token. This behavior is undocumented and Bison
users should not rely upon it. Assigning to YYVAL
unconditionally makes the parser a bit smaller, and it avoids a
GCC warning that YYVAL may be used uninitialized. */
yyval = yyvsp[1-yylen];
#if YYLSP_NEEDED
/* Similarly for the default location. Let the user run additional
commands if for instance locations are ranges. */
yyloc = yylsp[1-yylen];
YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
#endif
#if YYDEBUG
/* We have to keep this `#if YYDEBUG', since we use variables which
are defined only if `YYDEBUG' is set. */
if (yydebug)
{
int yyi;
YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
yyn, yyrline[yyn]);
/* Print the symbols being reduced, and their result. */
for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
}
#endif
switch (yyn) {
case 7:
#line 96 "zconf.y"
{ zconfprint("unexpected 'endmenu' statement"); ;
break;}
case 8:
#line 97 "zconf.y"
{ zconfprint("unexpected 'endif' statement"); ;
break;}
case 9:
#line 98 "zconf.y"
{ zconfprint("unexpected 'endchoice' statement"); ;
break;}
case 10:
#line 99 "zconf.y"
{ zconfprint("syntax error"); yyerrok; ;
break;}
case 16:
#line 114 "zconf.y"
{
struct symbol *sym = sym_lookup(yyvsp[0].string, 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[0].string);
;
break;}
case 17:
#line 122 "zconf.y"
{
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
;
break;}
case 22:
#line 133 "zconf.y"
{ ;
break;}
case 23:
#line 136 "zconf.y"
{
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
;
break;}
case 24:
#line 142 "zconf.y"
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
;
break;}
case 25:
#line 148 "zconf.y"
{
menu_set_type(S_INT);
printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
;
break;}
case 26:
#line 154 "zconf.y"
{
menu_set_type(S_HEX);
printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
;
break;}
case 27:
#line 160 "zconf.y"
{
menu_set_type(S_STRING);
printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
;
break;}
case 28:
#line 166 "zconf.y"
{
menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;
break;}
case 29:
#line 172 "zconf.y"
{
menu_add_prop(P_DEFAULT, NULL, yyvsp[-1].symbol, yyvsp[0].expr);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
;
break;}
case 30:
#line 180 "zconf.y"
{
struct symbol *sym = sym_lookup(NULL, 0);
sym->flags |= SYMBOL_CHOICE;
menu_add_entry(sym);
menu_add_prop(P_CHOICE, NULL, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
;
break;}
case 31:
#line 189 "zconf.y"
{
menu_end_entry();
menu_add_menu();
;
break;}
case 32:
#line 195 "zconf.y"
{
if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
;
break;}
case 34:
#line 205 "zconf.y"
{
printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
;
break;}
case 40:
#line 219 "zconf.y"
{
menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;
break;}
case 41:
#line 225 "zconf.y"
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
;
break;}
case 42:
#line 231 "zconf.y"
{
menu_add_prop(P_DEFAULT, NULL, yyvsp[0].symbol, NULL);
//current_choice->prop->def = $2;
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
;
break;}
case 45:
#line 245 "zconf.y"
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
//current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
menu_add_dep(yyvsp[0].expr);
menu_end_entry();
menu_add_menu();
;
break;}
case 46:
#line 255 "zconf.y"
{
if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
;
break;}
case 48:
#line 265 "zconf.y"
{
printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
;
break;}
case 53:
#line 280 "zconf.y"
{
menu_add_entry(NULL);
menu_add_prop(P_MENU, yyvsp[0].string, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
;
break;}
case 54:
#line 287 "zconf.y"
{
menu_end_entry();
menu_add_menu();
;
break;}
case 55:
#line 293 "zconf.y"
{
if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
;
break;}
case 57:
#line 303 "zconf.y"
{
printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
;
break;}
case 62:
#line 313 "zconf.y"
{ zconfprint("invalid menu option"); yyerrok; ;
break;}
case 63:
#line 317 "zconf.y"
{
yyval.string = yyvsp[0].string;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[0].string);
;
break;}
case 64:
#line 323 "zconf.y"
{
zconf_nextfile(yyvsp[-1].string);
;
break;}
case 65:
#line 330 "zconf.y"
{
menu_add_entry(NULL);
menu_add_prop(P_COMMENT, yyvsp[0].string, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
;
break;}
case 66:
#line 337 "zconf.y"
{
menu_end_entry();
;
break;}
case 67:
#line 344 "zconf.y"
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
zconf_starthelp();
;
break;}
case 68:
#line 350 "zconf.y"
{
current_entry->sym->help = yyvsp[0].string;
;
break;}
case 71:
#line 359 "zconf.y"
{ ;
break;}
case 72:
#line 362 "zconf.y"
{
menu_add_dep(yyvsp[0].expr);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
;
break;}
case 73:
#line 367 "zconf.y"
{
menu_add_dep(yyvsp[0].expr);
printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
;
break;}
case 74:
#line 372 "zconf.y"
{
menu_add_dep(yyvsp[0].expr);
printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
;
break;}
case 76:
#line 382 "zconf.y"
{
menu_add_prop(P_PROMPT, yyvsp[0].string, NULL, NULL);
;
break;}
case 77:
#line 386 "zconf.y"
{
menu_add_prop(P_PROMPT, yyvsp[-2].string, NULL, yyvsp[0].expr);
;
break;}
case 80:
#line 394 "zconf.y"
{ yyval.token = T_ENDMENU; ;
break;}
case 81:
#line 395 "zconf.y"
{ yyval.token = T_ENDCHOICE; ;
break;}
case 82:
#line 396 "zconf.y"
{ yyval.token = T_ENDIF; ;
break;}
case 85:
#line 402 "zconf.y"
{ yyval.expr = NULL; ;
break;}
case 86:
#line 403 "zconf.y"
{ yyval.expr = yyvsp[0].expr; ;
break;}
case 87:
#line 406 "zconf.y"
{ yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;
break;}
case 88:
#line 407 "zconf.y"
{ yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;
break;}
case 89:
#line 408 "zconf.y"
{ yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;
break;}
case 90:
#line 409 "zconf.y"
{ yyval.expr = yyvsp[-1].expr; ;
break;}
case 91:
#line 410 "zconf.y"
{ yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;
break;}
case 92:
#line 411 "zconf.y"
{ yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;
break;}
case 93:
#line 412 "zconf.y"
{ yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;
break;}
case 94:
#line 415 "zconf.y"
{ yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;
break;}
case 95:
#line 416 "zconf.y"
{ yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;
break;}
}
#line 705 "/usr/share/bison/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
#if YYLSP_NEEDED
yylsp -= yylen;
#endif
#if YYDEBUG
if (yydebug)
{
short *yyssp1 = yyss - 1;
YYFPRINTF (stderr, "state stack now");
while (yyssp1 != yyssp)
YYFPRINTF (stderr, " %d", *++yyssp1);
YYFPRINTF (stderr, "\n");
}
#endif
*++yyvsp = yyval;
#if YYLSP_NEEDED
*++yylsp = yyloc;
#endif
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#ifdef YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn < YYLAST)
{
YYSIZE_T yysize = 0;
char *yymsg;
int yyx, yycount;
yycount = 0;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
for (yyx = yyn < 0 ? -yyn : 0;
yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
if (yycheck[yyx + yyn] == yyx)
yysize += yystrlen (yytname[yyx]) + 15, yycount++;
yysize += yystrlen ("parse error, unexpected ") + 1;
yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
yymsg = (char *) YYSTACK_ALLOC (yysize);
if (yymsg != 0)
{
char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
if (yycount < 5)
{
yycount = 0;
for (yyx = yyn < 0 ? -yyn : 0;
yyx < (int) (sizeof (yytname) / sizeof (char *));
yyx++)
if (yycheck[yyx + yyn] == yyx)
{
const char *yyq = ! yycount ? ", expecting " : " or ";
yyp = yystpcpy (yyp, yyq);
yyp = yystpcpy (yyp, yytname[yyx]);
yycount++;
}
}
yyerror (yymsg);
YYSTACK_FREE (yymsg);
}
else
yyerror ("parse error; also virtual memory exhausted");
}
else
#endif /* defined (YYERROR_VERBOSE) */
yyerror ("parse error");
}
goto yyerrlab1;
/*--------------------------------------------------.
| yyerrlab1 -- error raised explicitly by an action |
`--------------------------------------------------*/
yyerrlab1:
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
/* return failure if at end of input */
if (yychar == YYEOF)
YYABORT;
YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
yychar, yytname[yychar1]));
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token after shifting the error
token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
/*-------------------------------------------------------------------.
| yyerrdefault -- current state does not do anything special for the |
| error token. |
`-------------------------------------------------------------------*/
yyerrdefault:
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
/* If its default is to accept any token, ok. Otherwise pop it. */
yyn = yydefact[yystate];
if (yyn)
goto yydefault;
#endif
/*---------------------------------------------------------------.
| yyerrpop -- pop the current state because it cannot handle the |
| error token |
`---------------------------------------------------------------*/
yyerrpop:
if (yyssp == yyss)
YYABORT;
yyvsp--;
yystate = *--yyssp;
#if YYLSP_NEEDED
yylsp--;
#endif
#if YYDEBUG
if (yydebug)
{
short *yyssp1 = yyss - 1;
YYFPRINTF (stderr, "Error: state stack now");
while (yyssp1 != yyssp)
YYFPRINTF (stderr, " %d", *++yyssp1);
YYFPRINTF (stderr, "\n");
}
#endif
/*--------------.
| yyerrhandle. |
`--------------*/
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
YYDPRINTF ((stderr, "Shifting error token, "));
*++yyvsp = yylval;
#if YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here. |
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
goto yyreturn;
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
yyresult = 1;
goto yyreturn;
/*---------------------------------------------.
| yyoverflowab -- parser overflow comes here. |
`---------------------------------------------*/
yyoverflowlab:
yyerror ("parser stack overflow");
yyresult = 2;
/* Fall through. */
yyreturn:
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
return yyresult;
}
#line 419 "zconf.y"
void conf_parse(const char *name)
{
zconf_initscan(name);
sym_init();
menu_init();
rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
//zconfdebug = 1;
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
modules_sym = sym_lookup("MODULES", 0);
sym_change_count = 1;
}
const char *zconf_tokenname(int token)
{
switch (token) {
case T_MENU: return "menu";
case T_ENDMENU: return "endmenu";
case T_CHOICE: return "choice";
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
}
return "<token>";
}
static bool zconf_endtoken(int token, int starttoken, int endtoken)
{
if (token != endtoken) {
zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfprint("location of the '%s'", zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
return true;
}
static void zconfprint(const char *err, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
fprintf(stderr, "\n");
}
static void zconferror(const char *err)
{
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
}
void print_quoted_string(FILE *out, const char *str)
{
const char *p;
int len;
putc('"', out);
while ((p = strchr(str, '"'))) {
len = p - str;
if (len)
fprintf(out, "%.*s", len, str);
fputs("\\\"", out);
str = p + 1;
}
fputs(str, out);
putc('"', out);
}
void print_symbol(FILE *out, struct menu *menu)
{
struct symbol *sym = menu->sym;
struct property *prop;
//sym->flags |= SYMBOL_PRINTED;
if (sym_is_choice(sym))
fprintf(out, "choice\n");
else
fprintf(out, "config %s\n", sym->name);
switch (sym->type) {
case S_BOOLEAN:
fputs(" boolean\n", out);
break;
case S_TRISTATE:
fputs(" tristate\n", out);
break;
case S_STRING:
fputs(" string\n", out);
break;
case S_INT:
fputs(" integer\n", out);
break;
case S_HEX:
fputs(" hex\n", out);
break;
default:
fputs(" ???\n", out);
break;
}
#if 0
if (!expr_is_yes(sym->dep)) {
fputs(" depends ", out);
expr_fprint(sym->dep, out);
fputc('\n', out);
}
#endif
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
switch (prop->type) {
case P_PROMPT:
fputs(" prompt ", out);
print_quoted_string(out, prop->text);
if (prop->def) {
fputc(' ', out);
if (prop->def->flags & SYMBOL_CONST)
print_quoted_string(out, prop->def->name);
else
fputs(prop->def->name, out);
}
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" if ", out);
expr_fprint(E_EXPR(prop->visible), out);
}
fputc('\n', out);
break;
case P_DEFAULT:
fputs( " default ", out);
print_quoted_string(out, prop->def->name);
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" if ", out);
expr_fprint(E_EXPR(prop->visible), out);
}
fputc('\n', out);
break;
case P_CHOICE:
fputs(" #choice value\n", out);
break;
default:
fprintf(out, " unknown prop %d!\n", prop->type);
break;
}
}
if (sym->help) {
int len = strlen(sym->help);
while (sym->help[--len] == '\n')
sym->help[len] = 0;
fprintf(out, " help\n%s\n", sym->help);
}
fputc('\n', out);
}
void zconfdump(FILE *out)
{
//struct file *file;
struct property *prop;
struct symbol *sym;
struct menu *menu;
menu = rootmenu.list;
while (menu) {
if ((sym = menu->sym))
print_symbol(out, menu);
else if ((prop = menu->prompt)) {
switch (prop->type) {
//case T_MAINMENU:
// fputs("\nmainmenu ", out);
// print_quoted_string(out, prop->text);
// fputs("\n", out);
// break;
case P_COMMENT:
fputs("\ncomment ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
case P_MENU:
fputs("\nmenu ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
//case T_SOURCE:
// fputs("\nsource ", out);
// print_quoted_string(out, prop->text);
// fputs("\n", out);
// break;
//case T_IF:
// fputs("\nif\n", out);
default:
;
}
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" depends ", out);
expr_fprint(E_EXPR(prop->visible), out);
fputc('\n', out);
}
fputs("\n", out);
}
if (menu->list)
menu = menu->list;
else if (menu->next)
menu = menu->next;
else while ((menu = menu->parent)) {
if (menu->prompt && menu->prompt->type == P_MENU)
fputs("\nendmenu\n", out);
if (menu->next) {
menu = menu->next;
break;
}
}
}
}
#include "lex.zconf.c"
#include "confdata.c"
#include "expr.c"
#include "symbol.c"
#include "menu.c"
#ifndef BISON_ZCONF_TAB_H
# define BISON_ZCONF_TAB_H
#ifndef YYSTYPE
typedef union
{
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
} yystype;
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
#endif
# define T_MAINMENU 257
# define T_MENU 258
# define T_ENDMENU 259
# define T_SOURCE 260
# define T_CHOICE 261
# define T_ENDCHOICE 262
# define T_COMMENT 263
# define T_CONFIG 264
# define T_HELP 265
# define T_HELPTEXT 266
# define T_IF 267
# define T_ENDIF 268
# define T_DEPENDS 269
# define T_REQUIRES 270
# define T_OPTIONAL 271
# define T_PROMPT 272
# define T_DEFAULT 273
# define T_TRISTATE 274
# define T_BOOLEAN 275
# define T_INT 276
# define T_HEX 277
# define T_WORD 278
# define T_STRING 279
# define T_UNEQUAL 280
# define T_EOF 281
# define T_EOL 282
# define T_CLOSE_PAREN 283
# define T_OPEN_PAREN 284
# define T_ON 285
# define T_OR 286
# define T_AND 287
# define T_EQUAL 288
# define T_NOT 289
extern YYSTYPE zconflval;
#endif /* not BISON_ZCONF_TAB_H */
%{
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
#define DEBUG_PARSE 0x0002
int cdebug = PRINTD;
extern int zconflex(void);
static void zconfprint(const char *err, ...);
static void zconferror(const char *err);
static bool zconf_endtoken(int token, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
#define YYERROR_VERBOSE
%}
%expect 36
%union
{
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
}
%token T_MAINMENU
%token T_MENU
%token T_ENDMENU
%token T_SOURCE
%token T_CHOICE
%token T_ENDCHOICE
%token T_COMMENT
%token T_CONFIG
%token T_HELP
%token <string> T_HELPTEXT
%token T_IF
%token T_ENDIF
%token T_DEPENDS
%token T_REQUIRES
%token T_OPTIONAL
%token T_PROMPT
%token T_DEFAULT
%token T_TRISTATE
%token T_BOOLEAN
%token T_INT
%token T_HEX
%token <string> T_WORD
%token <string> T_STRING
%token T_UNEQUAL
%token T_EOF
%token T_EOL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_ON
%left T_OR
%left T_AND
%left T_EQUAL T_UNEQUAL
%nonassoc T_NOT
%type <string> prompt
%type <string> source
%type <symbol> symbol
%type <expr> expr
%type <expr> if_expr
%type <token> end
%{
#define LKC_DIRECT_LINK
#include "lkc.h"
%}
%%
input: /* empty */
| input block
;
block: common_block
| choice_stmt
| menu_stmt
| T_MAINMENU prompt nl_or_eof
| T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
| T_ENDIF { zconfprint("unexpected 'endif' statement"); }
| T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
| error nl_or_eof { zconfprint("syntax error"); yyerrok; }
;
common_block:
if_stmt
| comment_stmt
| config_stmt
| source_stmt
| nl_or_eof
;
/* config entry */
config_entry_start: T_CONFIG T_WORD
{
struct symbol *sym = sym_lookup($2, 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
};
config_stmt: config_entry_start T_EOL config_option_list
{
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
};
config_option_list:
/* empty */
| config_option_list config_option T_EOL
| config_option_list depends T_EOL
| config_option_list help
| config_option_list T_EOL
{ };
config_option: T_TRISTATE prompt_stmt_opt
{
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
};
config_option: T_BOOLEAN prompt_stmt_opt
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_INT prompt_stmt_opt
{
menu_set_type(S_INT);
printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
};
config_option: T_HEX prompt_stmt_opt
{
menu_set_type(S_HEX);
printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
};
config_option: T_STRING prompt_stmt_opt
{
menu_set_type(S_STRING);
printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
};
config_option: T_PROMPT prompt if_expr
{
menu_add_prop(P_PROMPT, $2, NULL, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
config_option: T_DEFAULT symbol if_expr
{
menu_add_prop(P_DEFAULT, NULL, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
/* choice entry */
choice: T_CHOICE
{
struct symbol *sym = sym_lookup(NULL, 0);
sym->flags |= SYMBOL_CHOICE;
menu_add_entry(sym);
menu_add_prop(P_CHOICE, NULL, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
};
choice_entry: choice T_EOL choice_option_list
{
menu_end_entry();
menu_add_menu();
};
choice_end: end
{
if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
};
choice_stmt:
choice_entry choice_block choice_end T_EOL
| choice_entry choice_block
{
printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
choice_option_list:
/* empty */
| choice_option_list choice_option T_EOL
| choice_option_list depends T_EOL
| choice_option_list help
| choice_option_list T_EOL
;
choice_option: T_PROMPT prompt if_expr
{
menu_add_prop(P_PROMPT, $2, NULL, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
choice_option: T_OPTIONAL
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
};
choice_option: T_DEFAULT symbol
{
menu_add_prop(P_DEFAULT, NULL, $2, NULL);
//current_choice->prop->def = $2;
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
choice_block:
/* empty */
| choice_block common_block
;
/* if entry */
if: T_IF expr
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
//current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
menu_add_dep($2);
menu_end_entry();
menu_add_menu();
};
if_end: end
{
if (zconf_endtoken($1, T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
};
if_stmt:
if T_EOL if_block if_end T_EOL
| if T_EOL if_block
{
printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
if_block:
/* empty */
| if_block common_block
| if_block menu_stmt
| if_block choice_stmt
;
/* menu entry */
menu: T_MENU prompt
{
menu_add_entry(NULL);
menu_add_prop(P_MENU, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
};
menu_entry: menu T_EOL depends_list
{
menu_end_entry();
menu_add_menu();
};
menu_end: end
{
if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
};
menu_stmt:
menu_entry menu_block menu_end T_EOL
| menu_entry menu_block
{
printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
menu_block:
/* empty */
| menu_block common_block
| menu_block menu_stmt
| menu_block choice_stmt
| menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
;
source: T_SOURCE prompt
{
$$ = $2;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
};
source_stmt: source T_EOL
{
zconf_nextfile($1);
};
/* comment entry */
comment: T_COMMENT prompt
{
menu_add_entry(NULL);
menu_add_prop(P_COMMENT, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
};
comment_stmt: comment T_EOL depends_list
{
menu_end_entry();
};
/* help option */
help_start: T_HELP T_EOL
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
zconf_starthelp();
};
help: help_start T_HELPTEXT
{
current_entry->sym->help = $2;
};
/* depends option */
depends_list: /* empty */
| depends_list depends T_EOL
| depends_list T_EOL
{ };
depends: T_DEPENDS T_ON expr
{
menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
}
| T_DEPENDS expr
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
}
| T_REQUIRES expr
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
};
/* prompt statement */
prompt_stmt_opt:
/* empty */
| prompt
{
menu_add_prop(P_PROMPT, $1, NULL, NULL);
}
| prompt T_IF expr
{
menu_add_prop(P_PROMPT, $1, NULL, $3);
};
prompt: T_WORD
| T_STRING
;
end: T_ENDMENU { $$ = T_ENDMENU; }
| T_ENDCHOICE { $$ = T_ENDCHOICE; }
| T_ENDIF { $$ = T_ENDIF; }
;
nl_or_eof:
T_EOL | T_EOF;
if_expr: /* empty */ { $$ = NULL; }
| T_IF expr { $$ = $2; }
;
expr: symbol { $$ = expr_alloc_symbol($1); }
| symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
| T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
| expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
;
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
| T_STRING { $$ = sym_lookup($1, 1); free($1); }
;
%%
void conf_parse(const char *name)
{
zconf_initscan(name);
sym_init();
menu_init();
rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
//zconfdebug = 1;
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
modules_sym = sym_lookup("MODULES", 0);
sym_change_count = 1;
}
const char *zconf_tokenname(int token)
{
switch (token) {
case T_MENU: return "menu";
case T_ENDMENU: return "endmenu";
case T_CHOICE: return "choice";
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
}
return "<token>";
}
static bool zconf_endtoken(int token, int starttoken, int endtoken)
{
if (token != endtoken) {
zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfprint("location of the '%s'", zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
return true;
}
static void zconfprint(const char *err, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
fprintf(stderr, "\n");
}
static void zconferror(const char *err)
{
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
}
void print_quoted_string(FILE *out, const char *str)
{
const char *p;
int len;
putc('"', out);
while ((p = strchr(str, '"'))) {
len = p - str;
if (len)
fprintf(out, "%.*s", len, str);
fputs("\\\"", out);
str = p + 1;
}
fputs(str, out);
putc('"', out);
}
void print_symbol(FILE *out, struct menu *menu)
{
struct symbol *sym = menu->sym;
struct property *prop;
//sym->flags |= SYMBOL_PRINTED;
if (sym_is_choice(sym))
fprintf(out, "choice\n");
else
fprintf(out, "config %s\n", sym->name);
switch (sym->type) {
case S_BOOLEAN:
fputs(" boolean\n", out);
break;
case S_TRISTATE:
fputs(" tristate\n", out);
break;
case S_STRING:
fputs(" string\n", out);
break;
case S_INT:
fputs(" integer\n", out);
break;
case S_HEX:
fputs(" hex\n", out);
break;
default:
fputs(" ???\n", out);
break;
}
#if 0
if (!expr_is_yes(sym->dep)) {
fputs(" depends ", out);
expr_fprint(sym->dep, out);
fputc('\n', out);
}
#endif
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
switch (prop->type) {
case P_PROMPT:
fputs(" prompt ", out);
print_quoted_string(out, prop->text);
if (prop->def) {
fputc(' ', out);
if (prop->def->flags & SYMBOL_CONST)
print_quoted_string(out, prop->def->name);
else
fputs(prop->def->name, out);
}
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" if ", out);
expr_fprint(E_EXPR(prop->visible), out);
}
fputc('\n', out);
break;
case P_DEFAULT:
fputs( " default ", out);
print_quoted_string(out, prop->def->name);
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" if ", out);
expr_fprint(E_EXPR(prop->visible), out);
}
fputc('\n', out);
break;
case P_CHOICE:
fputs(" #choice value\n", out);
break;
default:
fprintf(out, " unknown prop %d!\n", prop->type);
break;
}
}
if (sym->help) {
int len = strlen(sym->help);
while (sym->help[--len] == '\n')
sym->help[len] = 0;
fprintf(out, " help\n%s\n", sym->help);
}
fputc('\n', out);
}
void zconfdump(FILE *out)
{
//struct file *file;
struct property *prop;
struct symbol *sym;
struct menu *menu;
menu = rootmenu.list;
while (menu) {
if ((sym = menu->sym))
print_symbol(out, menu);
else if ((prop = menu->prompt)) {
switch (prop->type) {
//case T_MAINMENU:
// fputs("\nmainmenu ", out);
// print_quoted_string(out, prop->text);
// fputs("\n", out);
// break;
case P_COMMENT:
fputs("\ncomment ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
case P_MENU:
fputs("\nmenu ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
//case T_SOURCE:
// fputs("\nsource ", out);
// print_quoted_string(out, prop->text);
// fputs("\n", out);
// break;
//case T_IF:
// fputs("\nif\n", out);
default:
;
}
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" depends ", out);
expr_fprint(E_EXPR(prop->visible), out);
fputc('\n', out);
}
fputs("\n", out);
}
if (menu->list)
menu = menu->list;
else if (menu->next)
menu = menu->next;
else while ((menu = menu->parent)) {
if (menu->prompt && menu->prompt->type == P_MENU)
fputs("\nendmenu\n", out);
if (menu->next) {
menu = menu->next;
break;
}
}
}
}
#include "lex.zconf.c"
#include "confdata.c"
#include "expr.c"
#include "symbol.c"
#include "menu.c"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment