changeset 241:31ebe0042324

Put these back until uClibc's kconfig builds without curses.
author Rob Landley <rob@landley.net>
date Wed, 31 Oct 2007 13:56:03 -0500
parents 41d57d7ba5e1
children c3d2fd8b45cf
files sources/patches/uClibc-newkconfig.patch sources/patches/uClibc-usenewkconfig.patch
diffstat 2 files changed, 12882 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/patches/uClibc-newkconfig.patch	Wed Oct 31 13:56:03 2007 -0500
@@ -0,0 +1,12792 @@
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/BIG.FAT.WARNING	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,4 @@
++This is NOT the official version of dialog.  This version has been
++significantly modified from the original.  It is for use by the Linux
++kernel configuration script.  Please do not bother Savio Lam with 
++questions about this program.
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/check-lxdialog.sh	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,84 @@
++#!/bin/sh
++# Check ncurses compatibility
++
++# What library to link
++ldflags()
++{
++	$cc -print-file-name=libncursesw.so | grep -q /
++	if [ $? -eq 0 ]; then
++		echo '-lncursesw'
++		exit
++	fi
++	$cc -print-file-name=libncurses.so | grep -q /
++	if [ $? -eq 0 ]; then
++		echo '-lncurses'
++		exit
++	fi
++	$cc -print-file-name=libcurses.so | grep -q /
++	if [ $? -eq 0 ]; then
++		echo '-lcurses'
++		exit
++	fi
++	exit 1
++}
++
++# Where is ncurses.h?
++ccflags()
++{
++	if [ -f /usr/include/ncurses/ncurses.h ]; then
++		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
++	elif [ -f /usr/include/ncurses/curses.h ]; then
++		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
++	elif [ -f /usr/include/ncurses.h ]; then
++		echo '-DCURSES_LOC="<ncurses.h>"'
++	else
++		echo '-DCURSES_LOC="<curses.h>"'
++	fi
++}
++
++# Temp file, try to clean up after us
++tmp=.lxdialog.tmp
++trap "rm -f $tmp" 0 1 2 3 15
++
++# Check if we can link to ncurses
++check() {
++	echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null
++	if [ $? != 0 ]; then
++		echo " *** Unable to find the ncurses libraries."          1>&2
++		echo " *** make menuconfig require the ncurses libraries"  1>&2
++		echo " *** "                                               1>&2
++		echo " *** Install ncurses (ncurses-devel) and try again"  1>&2
++		echo " *** "                                               1>&2
++		exit 1
++	fi
++}
++
++usage() {
++	printf "Usage: $0 [-check compiler options|-header|-library]\n"
++}
++
++if [ $# == 0 ]; then
++	usage
++	exit 1
++fi
++
++cc=""
++case "$1" in
++	"-check")
++		shift
++		cc="$@"
++		check
++		;;
++	"-ccflags")
++		ccflags
++		;;
++	"-ldflags")
++		shift
++		cc="$@"
++		ldflags
++		;;
++	"*")
++		usage
++		exit 1
++		;;
++esac
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/checklist.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,325 @@
++/*
++ *  checklist.c -- implements the checklist box
++ *
++ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
++ *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
++ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include "dialog.h"
++
++static int list_width, check_x, item_x;
++
++/*
++ * Print list item
++ */
++static void print_item(WINDOW * win, int choice, int selected)
++{
++	int i;
++
++	/* Clear 'residue' of last item */
++	wattrset(win, dlg.menubox.atr);
++	wmove(win, choice, 0);
++	for (i = 0; i < list_width; i++)
++		waddch(win, ' ');
++
++	wmove(win, choice, check_x);
++	wattrset(win, selected ? dlg.check_selected.atr
++		 : dlg.check.atr);
++	wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
++
++	wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
++	mvwaddch(win, choice, item_x, item_str()[0]);
++	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
++	waddstr(win, (char *)item_str() + 1);
++	if (selected) {
++		wmove(win, choice, check_x + 1);
++		wrefresh(win);
++	}
++}
++
++/*
++ * Print the scroll indicators.
++ */
++static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
++	     int y, int x, int height)
++{
++	wmove(win, y, x);
++
++	if (scroll > 0) {
++		wattrset(win, dlg.uarrow.atr);
++		waddch(win, ACS_UARROW);
++		waddstr(win, "(-)");
++	} else {
++		wattrset(win, dlg.menubox.atr);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++	}
++
++	y = y + height + 1;
++	wmove(win, y, x);
++
++	if ((height < item_no) && (scroll + choice < item_no - 1)) {
++		wattrset(win, dlg.darrow.atr);
++		waddch(win, ACS_DARROW);
++		waddstr(win, "(+)");
++	} else {
++		wattrset(win, dlg.menubox_border.atr);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++	}
++}
++
++/*
++ *  Display the termination buttons
++ */
++static void print_buttons(WINDOW * dialog, int height, int width, int selected)
++{
++	int x = width / 2 - 11;
++	int y = height - 2;
++
++	print_button(dialog, "Select", y, x, selected == 0);
++	print_button(dialog, " Help ", y, x + 14, selected == 1);
++
++	wmove(dialog, y, x + 1 + 14 * selected);
++	wrefresh(dialog);
++}
++
++/*
++ * Display a dialog box with a list of options that can be turned on or off
++ * in the style of radiolist (only one option turned on at a time).
++ */
++int dialog_checklist(const char *title, const char *prompt, int height,
++		     int width, int list_height)
++{
++	int i, x, y, box_x, box_y;
++	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
++	WINDOW *dialog, *list;
++
++	/* which item to highlight */
++	item_foreach() {
++		if (item_is_tag('X'))
++			choice = item_n();
++		if (item_is_selected()) {
++			choice = item_n();
++			break;
++		}
++	}
++
++do_resize:
++	if (getmaxy(stdscr) < (height + 6))
++		return -ERRDISPLAYTOOSMALL;
++	if (getmaxx(stdscr) < (width + 6))
++		return -ERRDISPLAYTOOSMALL;
++
++	max_choice = MIN(list_height, item_count());
++
++	/* center dialog box on screen */
++	x = (COLS - width) / 2;
++	y = (LINES - height) / 2;
++
++	draw_shadow(stdscr, y, x, height, width);
++
++	dialog = newwin(height, width, y, x);
++	keypad(dialog, TRUE);
++
++	draw_box(dialog, 0, 0, height, width,
++		 dlg.dialog.atr, dlg.border.atr);
++	wattrset(dialog, dlg.border.atr);
++	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
++	for (i = 0; i < width - 2; i++)
++		waddch(dialog, ACS_HLINE);
++	wattrset(dialog, dlg.dialog.atr);
++	waddch(dialog, ACS_RTEE);
++
++	print_title(dialog, title, width);
++
++	wattrset(dialog, dlg.dialog.atr);
++	print_autowrap(dialog, prompt, width - 2, 1, 3);
++
++	list_width = width - 6;
++	box_y = height - list_height - 5;
++	box_x = (width - list_width) / 2 - 1;
++
++	/* create new window for the list */
++	list = subwin(dialog, list_height, list_width, y + box_y + 1,
++	              x + box_x + 1);
++
++	keypad(list, TRUE);
++
++	/* draw a box around the list items */
++	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
++	         dlg.menubox_border.atr, dlg.menubox.atr);
++
++	/* Find length of longest item in order to center checklist */
++	check_x = 0;
++	item_foreach()
++		check_x = MAX(check_x, strlen(item_str()) + 4);
++
++	check_x = (list_width - check_x) / 2;
++	item_x = check_x + 4;
++
++	if (choice >= list_height) {
++		scroll = choice - list_height + 1;
++		choice -= scroll;
++	}
++
++	/* Print the list */
++	for (i = 0; i < max_choice; i++) {
++		item_set(scroll + i);
++		print_item(list, i, i == choice);
++	}
++
++	print_arrows(dialog, choice, item_count(), scroll,
++		     box_y, box_x + check_x + 5, list_height);
++
++	print_buttons(dialog, height, width, 0);
++
++	wnoutrefresh(dialog);
++	wnoutrefresh(list);
++	doupdate();
++
++	while (key != KEY_ESC) {
++		key = wgetch(dialog);
++
++		for (i = 0; i < max_choice; i++) {
++			item_set(i + scroll);
++			if (toupper(key) == toupper(item_str()[0]))
++				break;
++		}
++
++		if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
++		    key == '+' || key == '-') {
++			if (key == KEY_UP || key == '-') {
++				if (!choice) {
++					if (!scroll)
++						continue;
++					/* Scroll list down */
++					if (list_height > 1) {
++						/* De-highlight current first item */
++						item_set(scroll);
++						print_item(list, 0, FALSE);
++						scrollok(list, TRUE);
++						wscrl(list, -1);
++						scrollok(list, FALSE);
++					}
++					scroll--;
++					item_set(scroll);
++					print_item(list, 0, TRUE);
++					print_arrows(dialog, choice, item_count(),
++						     scroll, box_y, box_x + check_x + 5, list_height);
++
++					wnoutrefresh(dialog);
++					wrefresh(list);
++
++					continue;	/* wait for another key press */
++				} else
++					i = choice - 1;
++			} else if (key == KEY_DOWN || key == '+') {
++				if (choice == max_choice - 1) {
++					if (scroll + choice >= item_count() - 1)
++						continue;
++					/* Scroll list up */
++					if (list_height > 1) {
++						/* De-highlight current last item before scrolling up */
++						item_set(scroll + max_choice - 1);
++						print_item(list,
++							    max_choice - 1,
++							    FALSE);
++						scrollok(list, TRUE);
++						wscrl(list, 1);
++						scrollok(list, FALSE);
++					}
++					scroll++;
++					item_set(scroll + max_choice - 1);
++					print_item(list, max_choice - 1, TRUE);
++
++					print_arrows(dialog, choice, item_count(),
++						     scroll, box_y, box_x + check_x + 5, list_height);
++
++					wnoutrefresh(dialog);
++					wrefresh(list);
++
++					continue;	/* wait for another key press */
++				} else
++					i = choice + 1;
++			}
++			if (i != choice) {
++				/* De-highlight current item */
++				item_set(scroll + choice);
++				print_item(list, choice, FALSE);
++				/* Highlight new item */
++				choice = i;
++				item_set(scroll + choice);
++				print_item(list, choice, TRUE);
++				wnoutrefresh(dialog);
++				wrefresh(list);
++			}
++			continue;	/* wait for another key press */
++		}
++		switch (key) {
++		case 'H':
++		case 'h':
++		case '?':
++			button = 1;
++			/* fall-through */
++		case 'S':
++		case 's':
++		case ' ':
++		case '\n':
++			item_foreach()
++				item_set_selected(0);
++			item_set(scroll + choice);
++			item_set_selected(1);
++			delwin(list);
++			delwin(dialog);
++			return button;
++		case TAB:
++		case KEY_LEFT:
++		case KEY_RIGHT:
++			button = ((key == KEY_LEFT ? --button : ++button) < 0)
++			    ? 1 : (button > 1 ? 0 : button);
++
++			print_buttons(dialog, height, width, button);
++			wrefresh(dialog);
++			break;
++		case 'X':
++		case 'x':
++			key = KEY_ESC;
++			break;
++		case KEY_ESC:
++			key = on_key_esc(dialog);
++			break;
++		case KEY_RESIZE:
++			delwin(list);
++			delwin(dialog);
++			on_key_resize();
++			goto do_resize;
++		}
++
++		/* Now, update everything... */
++		doupdate();
++	}
++	delwin(list);
++	delwin(dialog);
++	return key;		/* ESC pressed */
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/dialog.h	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,224 @@
++/*
++ *  dialog.h -- common declarations for all dialog modules
++ *
++ *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <sys/types.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <string.h>
++#include <stdbool.h>
++
++#ifdef __sun__
++#define CURS_MACROS
++#endif
++#include CURSES_LOC
++
++/*
++ * Colors in ncurses 1.9.9e do not work properly since foreground and
++ * background colors are OR'd rather than separately masked.  This version
++ * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
++ * with standard curses.  The simplest fix (to make this work with standard
++ * curses) uses the wbkgdset() function, not used in the original hack.
++ * Turn it off if we're building with 1.9.9e, since it just confuses things.
++ */
++#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
++#define OLD_NCURSES 1
++#undef  wbkgdset
++#define wbkgdset(w,p)		/*nothing */
++#else
++#define OLD_NCURSES 0
++#endif
++
++#define TR(params) _tracef params
++
++#define KEY_ESC 27
++#define TAB 9
++#define MAX_LEN 2048
++#define BUF_SIZE (10*1024)
++#define MIN(x,y) (x < y ? x : y)
++#define MAX(x,y) (x > y ? x : y)
++
++#ifndef ACS_ULCORNER
++#define ACS_ULCORNER '+'
++#endif
++#ifndef ACS_LLCORNER
++#define ACS_LLCORNER '+'
++#endif
++#ifndef ACS_URCORNER
++#define ACS_URCORNER '+'
++#endif
++#ifndef ACS_LRCORNER
++#define ACS_LRCORNER '+'
++#endif
++#ifndef ACS_HLINE
++#define ACS_HLINE '-'
++#endif
++#ifndef ACS_VLINE
++#define ACS_VLINE '|'
++#endif
++#ifndef ACS_LTEE
++#define ACS_LTEE '+'
++#endif
++#ifndef ACS_RTEE
++#define ACS_RTEE '+'
++#endif
++#ifndef ACS_UARROW
++#define ACS_UARROW '^'
++#endif
++#ifndef ACS_DARROW
++#define ACS_DARROW 'v'
++#endif
++
++/* error return codes */
++#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
++
++/*
++ *   Color definitions
++ */
++struct dialog_color {
++	chtype atr;	/* Color attribute */
++	int fg;		/* foreground */
++	int bg;		/* background */
++	int hl;		/* highlight this item */
++};
++
++struct dialog_info {
++	const char *backtitle;
++	struct dialog_color screen;
++	struct dialog_color shadow;
++	struct dialog_color dialog;
++	struct dialog_color title;
++	struct dialog_color border;
++	struct dialog_color button_active;
++	struct dialog_color button_inactive;
++	struct dialog_color button_key_active;
++	struct dialog_color button_key_inactive;
++	struct dialog_color button_label_active;
++	struct dialog_color button_label_inactive;
++	struct dialog_color inputbox;
++	struct dialog_color inputbox_border;
++	struct dialog_color searchbox;
++	struct dialog_color searchbox_title;
++	struct dialog_color searchbox_border;
++	struct dialog_color position_indicator;
++	struct dialog_color menubox;
++	struct dialog_color menubox_border;
++	struct dialog_color item;
++	struct dialog_color item_selected;
++	struct dialog_color tag;
++	struct dialog_color tag_selected;
++	struct dialog_color tag_key;
++	struct dialog_color tag_key_selected;
++	struct dialog_color check;
++	struct dialog_color check_selected;
++	struct dialog_color uarrow;
++	struct dialog_color darrow;
++};
++
++/*
++ * Global variables
++ */
++extern struct dialog_info dlg;
++extern char dialog_input_result[];
++
++/*
++ * Function prototypes
++ */
++
++/* item list as used by checklist and menubox */
++void item_reset(void);
++void item_make(const char *fmt, ...);
++void item_add_str(const char *fmt, ...);
++void item_set_tag(char tag);
++void item_set_data(void *p);
++void item_set_selected(int val);
++int item_activate_selected(void);
++void *item_data(void);
++char item_tag(void);
++
++/* item list manipulation for lxdialog use */
++#define MAXITEMSTR 200
++struct dialog_item {
++	char str[MAXITEMSTR];	/* promtp displayed */
++	char tag;
++	void *data;	/* pointer to menu item - used by menubox+checklist */
++	int selected;	/* Set to 1 by dialog_*() function if selected. */
++};
++
++/* list of lialog_items */
++struct dialog_list {
++	struct dialog_item node;
++	struct dialog_list *next;
++};
++
++extern struct dialog_list *item_cur;
++extern struct dialog_list item_nil;
++extern struct dialog_list *item_head;
++
++int item_count(void);
++void item_set(int n);
++int item_n(void);
++const char *item_str(void);
++int item_is_selected(void);
++int item_is_tag(char tag);
++#define item_foreach() \
++	for (item_cur = item_head ? item_head: item_cur; \
++	     item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
++
++/* generic key handlers */
++int on_key_esc(WINDOW *win);
++int on_key_resize(void);
++
++void init_dialog(const char *backtitle);
++void reset_dialog(void);
++void end_dialog(void);
++void attr_clear(WINDOW * win, int height, int width, chtype attr);
++void dialog_clear(void);
++void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
++void print_button(WINDOW * win, const char *label, int y, int x, int selected);
++void print_title(WINDOW *dialog, const char *title, int width);
++void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box,
++	      chtype border);
++void draw_shadow(WINDOW * win, int y, int x, int height, int width);
++
++int first_alpha(const char *string, const char *exempt);
++int dialog_yesno(const char *title, const char *prompt, int height, int width);
++int dialog_msgbox(const char *title, const char *prompt, int height,
++		  int width, int pause);
++int dialog_textbox(const char *title, const char *file, int height, int width);
++int dialog_menu(const char *title, const char *prompt,
++		const void *selected, int *s_scroll);
++int dialog_checklist(const char *title, const char *prompt, int height,
++		     int width, int list_height);
++extern char dialog_input_result[];
++int dialog_inputbox(const char *title, const char *prompt, int height,
++		    int width, const char *init);
++
++/*
++ * This is the base for fictitious keys, which activate
++ * the buttons.
++ *
++ * Mouse-generated keys are the following:
++ *   -- the first 32 are used as numbers, in addition to '0'-'9'
++ *   -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
++ *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
++ */
++#define M_EVENT (KEY_MAX+1)
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/inputbox.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,238 @@
++/*
++ *  inputbox.c -- implements the input box
++ *
++ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include "dialog.h"
++
++char dialog_input_result[MAX_LEN + 1];
++
++/*
++ *  Print the termination buttons
++ */
++static void print_buttons(WINDOW * dialog, int height, int width, int selected)
++{
++	int x = width / 2 - 11;
++	int y = height - 2;
++
++	print_button(dialog, "  Ok  ", y, x, selected == 0);
++	print_button(dialog, " Help ", y, x + 14, selected == 1);
++
++	wmove(dialog, y, x + 1 + 14 * selected);
++	wrefresh(dialog);
++}
++
++/*
++ * Display a dialog box for inputing a string
++ */
++int dialog_inputbox(const char *title, const char *prompt, int height, int width,
++                    const char *init)
++{
++	int i, x, y, box_y, box_x, box_width;
++	int input_x = 0, scroll = 0, key = 0, button = -1;
++	char *instr = dialog_input_result;
++	WINDOW *dialog;
++
++	if (!init)
++		instr[0] = '\0';
++	else
++		strcpy(instr, init);
++
++do_resize:
++	if (getmaxy(stdscr) <= (height - 2))
++		return -ERRDISPLAYTOOSMALL;
++	if (getmaxx(stdscr) <= (width - 2))
++		return -ERRDISPLAYTOOSMALL;
++
++	/* center dialog box on screen */
++	x = (COLS - width) / 2;
++	y = (LINES - height) / 2;
++
++	draw_shadow(stdscr, y, x, height, width);
++
++	dialog = newwin(height, width, y, x);
++	keypad(dialog, TRUE);
++
++	draw_box(dialog, 0, 0, height, width,
++		 dlg.dialog.atr, dlg.border.atr);
++	wattrset(dialog, dlg.border.atr);
++	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
++	for (i = 0; i < width - 2; i++)
++		waddch(dialog, ACS_HLINE);
++	wattrset(dialog, dlg.dialog.atr);
++	waddch(dialog, ACS_RTEE);
++
++	print_title(dialog, title, width);
++
++	wattrset(dialog, dlg.dialog.atr);
++	print_autowrap(dialog, prompt, width - 2, 1, 3);
++
++	/* Draw the input field box */
++	box_width = width - 6;
++	getyx(dialog, y, x);
++	box_y = y + 2;
++	box_x = (width - box_width) / 2;
++	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
++		 dlg.border.atr, dlg.dialog.atr);
++
++	print_buttons(dialog, height, width, 0);
++
++	/* Set up the initial value */
++	wmove(dialog, box_y, box_x);
++	wattrset(dialog, dlg.inputbox.atr);
++
++	input_x = strlen(instr);
++
++	if (input_x >= box_width) {
++		scroll = input_x - box_width + 1;
++		input_x = box_width - 1;
++		for (i = 0; i < box_width - 1; i++)
++			waddch(dialog, instr[scroll + i]);
++	} else {
++		waddstr(dialog, instr);
++	}
++
++	wmove(dialog, box_y, box_x + input_x);
++
++	wrefresh(dialog);
++
++	while (key != KEY_ESC) {
++		key = wgetch(dialog);
++
++		if (button == -1) {	/* Input box selected */
++			switch (key) {
++			case TAB:
++			case KEY_UP:
++			case KEY_DOWN:
++				break;
++			case KEY_LEFT:
++				continue;
++			case KEY_RIGHT:
++				continue;
++			case KEY_BACKSPACE:
++			case 127:
++				if (input_x || scroll) {
++					wattrset(dialog, dlg.inputbox.atr);
++					if (!input_x) {
++						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
++						wmove(dialog, box_y, box_x);
++						for (i = 0; i < box_width; i++)
++							waddch(dialog,
++							       instr[scroll + input_x + i] ?
++							       instr[scroll + input_x + i] : ' ');
++						input_x = strlen(instr) - scroll;
++					} else
++						input_x--;
++					instr[scroll + input_x] = '\0';
++					mvwaddch(dialog, box_y, input_x + box_x, ' ');
++					wmove(dialog, box_y, input_x + box_x);
++					wrefresh(dialog);
++				}
++				continue;
++			default:
++				if (key < 0x100 && isprint(key)) {
++					if (scroll + input_x < MAX_LEN) {
++						wattrset(dialog, dlg.inputbox.atr);
++						instr[scroll + input_x] = key;
++						instr[scroll + input_x + 1] = '\0';
++						if (input_x == box_width - 1) {
++							scroll++;
++							wmove(dialog, box_y, box_x);
++							for (i = 0; i < box_width - 1; i++)
++								waddch(dialog, instr [scroll + i]);
++						} else {
++							wmove(dialog, box_y, input_x++ + box_x);
++							waddch(dialog, key);
++						}
++						wrefresh(dialog);
++					} else
++						flash();	/* Alarm user about overflow */
++					continue;
++				}
++			}
++		}
++		switch (key) {
++		case 'O':
++		case 'o':
++			delwin(dialog);
++			return 0;
++		case 'H':
++		case 'h':
++			delwin(dialog);
++			return 1;
++		case KEY_UP:
++		case KEY_LEFT:
++			switch (button) {
++			case -1:
++				button = 1;	/* Indicates "Cancel" button is selected */
++				print_buttons(dialog, height, width, 1);
++				break;
++			case 0:
++				button = -1;	/* Indicates input box is selected */
++				print_buttons(dialog, height, width, 0);
++				wmove(dialog, box_y, box_x + input_x);
++				wrefresh(dialog);
++				break;
++			case 1:
++				button = 0;	/* Indicates "OK" button is selected */
++				print_buttons(dialog, height, width, 0);
++				break;
++			}
++			break;
++		case TAB:
++		case KEY_DOWN:
++		case KEY_RIGHT:
++			switch (button) {
++			case -1:
++				button = 0;	/* Indicates "OK" button is selected */
++				print_buttons(dialog, height, width, 0);
++				break;
++			case 0:
++				button = 1;	/* Indicates "Cancel" button is selected */
++				print_buttons(dialog, height, width, 1);
++				break;
++			case 1:
++				button = -1;	/* Indicates input box is selected */
++				print_buttons(dialog, height, width, 0);
++				wmove(dialog, box_y, box_x + input_x);
++				wrefresh(dialog);
++				break;
++			}
++			break;
++		case ' ':
++		case '\n':
++			delwin(dialog);
++			return (button == -1 ? 0 : button);
++		case 'X':
++		case 'x':
++			key = KEY_ESC;
++			break;
++		case KEY_ESC:
++			key = on_key_esc(dialog);
++			break;
++		case KEY_RESIZE:
++			delwin(dialog);
++			on_key_resize();
++			goto do_resize;
++		}
++	}
++
++	delwin(dialog);
++	return KEY_ESC;		/* ESC pressed */
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/menubox.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,434 @@
++/*
++ *  menubox.c -- implements the menu box
++ *
++ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++/*
++ *  Changes by Clifford Wolf (god@clifford.at)
++ *
++ *  [ 1998-06-13 ]
++ *
++ *    *)  A bugfix for the Page-Down problem
++ *
++ *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
++ *        to the first position in the menu box.  Now lxdialog is a bit
++ *        smarter and works more like other menu systems (just have a look at
++ *        it).
++ *
++ *    *)  Formerly if I selected something my scrolling would be broken because
++ *        lxdialog is re-invoked by the Menuconfig shell script, can't
++ *        remember the last scrolling position, and just sets it so that the
++ *        cursor is at the bottom of the box.  Now it writes the temporary file
++ *        lxdialog.scrltmp which contains this information. The file is
++ *        deleted by lxdialog if the user leaves a submenu or enters a new
++ *        one, but it would be nice if Menuconfig could make another "rm -f"
++ *        just to be sure.  Just try it out - you will recognise a difference!
++ *
++ *  [ 1998-06-14 ]
++ *
++ *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
++ *        and menus change their size on the fly.
++ *
++ *    *)  If for some reason the last scrolling position is not saved by
++ *        lxdialog, it sets the scrolling so that the selected item is in the
++ *        middle of the menu box, not at the bottom.
++ *
++ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
++ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
++ * This fixes a bug in Menuconfig where using ' ' to descend into menus
++ * would leave mis-synchronized lxdialog.scrltmp files lying around,
++ * fscanf would read in 'scroll', and eventually that value would get used.
++ */
++
++#include "dialog.h"
++
++static int menu_width, item_x;
++
++/*
++ * Print menu item
++ */
++static void do_print_item(WINDOW * win, const char *item, int line_y,
++                          int selected, int hotkey)
++{
++	int j;
++	char *menu_item = malloc(menu_width + 1);
++
++	strncpy(menu_item, item, menu_width - item_x);
++	menu_item[menu_width - item_x] = '\0';
++	j = first_alpha(menu_item, "YyNnMmHh");
++
++	/* Clear 'residue' of last item */
++	wattrset(win, dlg.menubox.atr);
++	wmove(win, line_y, 0);
++#if OLD_NCURSES
++	{
++		int i;
++		for (i = 0; i < menu_width; i++)
++			waddch(win, ' ');
++	}
++#else
++	wclrtoeol(win);
++#endif
++	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
++	mvwaddstr(win, line_y, item_x, menu_item);
++	if (hotkey) {
++		wattrset(win, selected ? dlg.tag_key_selected.atr
++			 : dlg.tag_key.atr);
++		mvwaddch(win, line_y, item_x + j, menu_item[j]);
++	}
++	if (selected) {
++		wmove(win, line_y, item_x + 1);
++	}
++	free(menu_item);
++	wrefresh(win);
++}
++
++#define print_item(index, choice, selected)				\
++do {									\
++	item_set(index);						\
++	do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
++} while (0)
++
++/*
++ * Print the scroll indicators.
++ */
++static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
++			 int height)
++{
++	int cur_y, cur_x;
++
++	getyx(win, cur_y, cur_x);
++
++	wmove(win, y, x);
++
++	if (scroll > 0) {
++		wattrset(win, dlg.uarrow.atr);
++		waddch(win, ACS_UARROW);
++		waddstr(win, "(-)");
++	} else {
++		wattrset(win, dlg.menubox.atr);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++	}
++
++	y = y + height + 1;
++	wmove(win, y, x);
++	wrefresh(win);
++
++	if ((height < item_no) && (scroll + height < item_no)) {
++		wattrset(win, dlg.darrow.atr);
++		waddch(win, ACS_DARROW);
++		waddstr(win, "(+)");
++	} else {
++		wattrset(win, dlg.menubox_border.atr);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++		waddch(win, ACS_HLINE);
++	}
++
++	wmove(win, cur_y, cur_x);
++	wrefresh(win);
++}
++
++/*
++ * Display the termination buttons.
++ */
++static void print_buttons(WINDOW * win, int height, int width, int selected)
++{
++	int x = width / 2 - 16;
++	int y = height - 2;
++
++	print_button(win, "Select", y, x, selected == 0);
++	print_button(win, " Exit ", y, x + 12, selected == 1);
++	print_button(win, " Help ", y, x + 24, selected == 2);
++
++	wmove(win, y, x + 1 + 12 * selected);
++	wrefresh(win);
++}
++
++/* scroll up n lines (n may be negative) */
++static void do_scroll(WINDOW *win, int *scroll, int n)
++{
++	/* Scroll menu up */
++	scrollok(win, TRUE);
++	wscrl(win, n);
++	scrollok(win, FALSE);
++	*scroll = *scroll + n;
++	wrefresh(win);
++}
++
++/*
++ * Display a menu for choosing among a number of options
++ */
++int dialog_menu(const char *title, const char *prompt,
++                const void *selected, int *s_scroll)
++{
++	int i, j, x, y, box_x, box_y;
++	int height, width, menu_height;
++	int key = 0, button = 0, scroll = 0, choice = 0;
++	int first_item =  0, max_choice;
++	WINDOW *dialog, *menu;
++
++do_resize:
++	height = getmaxy(stdscr);
++	width = getmaxx(stdscr);
++	if (height < 15 || width < 65)
++		return -ERRDISPLAYTOOSMALL;
++
++	height -= 4;
++	width  -= 5;
++	menu_height = height - 10;
++
++	max_choice = MIN(menu_height, item_count());
++
++	/* center dialog box on screen */
++	x = (COLS - width) / 2;
++	y = (LINES - height) / 2;
++
++	draw_shadow(stdscr, y, x, height, width);
++
++	dialog = newwin(height, width, y, x);
++	keypad(dialog, TRUE);
++
++	draw_box(dialog, 0, 0, height, width,
++		 dlg.dialog.atr, dlg.border.atr);
++	wattrset(dialog, dlg.border.atr);
++	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
++	for (i = 0; i < width - 2; i++)
++		waddch(dialog, ACS_HLINE);
++	wattrset(dialog, dlg.dialog.atr);
++	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
++	waddch(dialog, ACS_RTEE);
++
++	print_title(dialog, title, width);
++
++	wattrset(dialog, dlg.dialog.atr);
++	print_autowrap(dialog, prompt, width - 2, 1, 3);
++
++	menu_width = width - 6;
++	box_y = height - menu_height - 5;
++	box_x = (width - menu_width) / 2 - 1;
++
++	/* create new window for the menu */
++	menu = subwin(dialog, menu_height, menu_width,
++		      y + box_y + 1, x + box_x + 1);
++	keypad(menu, TRUE);
++
++	/* draw a box around the menu items */
++	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
++		 dlg.menubox_border.atr, dlg.menubox.atr);
++
++	if (menu_width >= 80)
++		item_x = (menu_width - 70) / 2;
++	else
++		item_x = 4;
++
++	/* Set choice to default item */
++	item_foreach()
++		if (selected && (selected == item_data()))
++			choice = item_n();
++	/* get the saved scroll info */
++	scroll = *s_scroll;
++	if ((scroll <= choice) && (scroll + max_choice > choice) &&
++	   (scroll >= 0) && (scroll + max_choice <= item_count())) {
++		first_item = scroll;
++		choice = choice - scroll;
++	} else {
++		scroll = 0;
++	}
++	if ((choice >= max_choice)) {
++		if (choice >= item_count() - max_choice / 2)
++			scroll = first_item = item_count() - max_choice;
++		else
++			scroll = first_item = choice - max_choice / 2;
++		choice = choice - scroll;
++	}
++
++	/* Print the menu */
++	for (i = 0; i < max_choice; i++) {
++		print_item(first_item + i, i, i == choice);
++	}
++
++	wnoutrefresh(menu);
++
++	print_arrows(dialog, item_count(), scroll,
++		     box_y, box_x + item_x + 1, menu_height);
++
++	print_buttons(dialog, height, width, 0);
++	wmove(menu, choice, item_x + 1);
++	wrefresh(menu);
++
++	while (key != KEY_ESC) {
++		key = wgetch(menu);
++
++		if (key < 256 && isalpha(key))
++			key = tolower(key);
++
++		if (strchr("ynmh", key))
++			i = max_choice;
++		else {
++			for (i = choice + 1; i < max_choice; i++) {
++				item_set(scroll + i);
++				j = first_alpha(item_str(), "YyNnMmHh");
++				if (key == tolower(item_str()[j]))
++					break;
++			}
++			if (i == max_choice)
++				for (i = 0; i < max_choice; i++) {
++					item_set(scroll + i);
++					j = first_alpha(item_str(), "YyNnMmHh");
++					if (key == tolower(item_str()[j]))
++						break;
++				}
++		}
++
++		if (i < max_choice ||
++		    key == KEY_UP || key == KEY_DOWN ||
++		    key == '-' || key == '+' ||
++		    key == KEY_PPAGE || key == KEY_NPAGE) {
++			/* Remove highligt of current item */
++			print_item(scroll + choice, choice, FALSE);
++
++			if (key == KEY_UP || key == '-') {
++				if (choice < 2 && scroll) {
++					/* Scroll menu down */
++					do_scroll(menu, &scroll, -1);
++
++					print_item(scroll, 0, FALSE);
++				} else
++					choice = MAX(choice - 1, 0);
++
++			} else if (key == KEY_DOWN || key == '+') {
++				print_item(scroll+choice, choice, FALSE);
++
++				if ((choice > max_choice - 3) &&
++				    (scroll + max_choice < item_count())) {
++					/* Scroll menu up */
++					do_scroll(menu, &scroll, 1);
++
++					print_item(scroll+max_choice - 1,
++						   max_choice - 1, FALSE);
++				} else
++					choice = MIN(choice + 1, max_choice - 1);
++
++			} else if (key == KEY_PPAGE) {
++				scrollok(menu, TRUE);
++				for (i = 0; (i < max_choice); i++) {
++					if (scroll > 0) {
++						do_scroll(menu, &scroll, -1);
++						print_item(scroll, 0, FALSE);
++					} else {
++						if (choice > 0)
++							choice--;
++					}
++				}
++
++			} else if (key == KEY_NPAGE) {
++				for (i = 0; (i < max_choice); i++) {
++					if (scroll + max_choice < item_count()) {
++						do_scroll(menu, &scroll, 1);
++						print_item(scroll+max_choice-1,
++							   max_choice - 1, FALSE);
++					} else {
++						if (choice + 1 < max_choice)
++							choice++;
++					}
++				}
++			} else
++				choice = i;
++
++			print_item(scroll + choice, choice, TRUE);
++
++			print_arrows(dialog, item_count(), scroll,
++				     box_y, box_x + item_x + 1, menu_height);
++
++			wnoutrefresh(dialog);
++			wrefresh(menu);
++
++			continue;	/* wait for another key press */
++		}
++
++		switch (key) {
++		case KEY_LEFT:
++		case TAB:
++		case KEY_RIGHT:
++			button = ((key == KEY_LEFT ? --button : ++button) < 0)
++			    ? 2 : (button > 2 ? 0 : button);
++
++			print_buttons(dialog, height, width, button);
++			wrefresh(menu);
++			break;
++		case ' ':
++		case 's':
++		case 'y':
++		case 'n':
++		case 'm':
++		case '/':
++			/* save scroll info */
++			*s_scroll = scroll;
++			delwin(menu);
++			delwin(dialog);
++			item_set(scroll + choice);
++			item_set_selected(1);
++			switch (key) {
++			case 's':
++				return 3;
++			case 'y':
++				return 3;
++			case 'n':
++				return 4;
++			case 'm':
++				return 5;
++			case ' ':
++				return 6;
++			case '/':
++				return 7;
++			}
++			return 0;
++		case 'h':
++		case '?':
++			button = 2;
++		case '\n':
++			*s_scroll = scroll;
++			delwin(menu);
++			delwin(dialog);
++			item_set(scroll + choice);
++			item_set_selected(1);
++			return button;
++		case 'e':
++		case 'x':
++			key = KEY_ESC;
++			break;
++		case KEY_ESC:
++			key = on_key_esc(menu);
++			break;
++		case KEY_RESIZE:
++			on_key_resize();
++			delwin(menu);
++			delwin(dialog);
++			goto do_resize;
++		}
++	}
++	delwin(menu);
++	delwin(dialog);
++	return key;		/* ESC pressed */
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/textbox.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,391 @@
++/*
++ *  textbox.c -- implements the text box
++ *
++ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include "dialog.h"
++
++static void back_lines(int n);
++static void print_page(WINDOW * win, int height, int width);
++static void print_line(WINDOW * win, int row, int width);
++static char *get_line(void);
++static void print_position(WINDOW * win);
++
++static int hscroll;
++static int begin_reached, end_reached, page_length;
++static const char *buf;
++static const char *page;
++
++/*
++ * refresh window content
++ */
++static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
++							  int cur_y, int cur_x)
++{
++	print_page(box, boxh, boxw);
++	print_position(dialog);
++	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
++	wrefresh(dialog);
++}
++
++
++/*
++ * Display text from a file in a dialog box.
++ */
++int dialog_textbox(const char *title, const char *tbuf,
++		   int initial_height, int initial_width)
++{
++	int i, x, y, cur_x, cur_y, key = 0;
++	int height, width, boxh, boxw;
++	int passed_end;
++	WINDOW *dialog, *box;
++
++	begin_reached = 1;
++	end_reached = 0;
++	page_length = 0;
++	hscroll = 0;
++	buf = tbuf;
++	page = buf;	/* page is pointer to start of page to be displayed */
++
++do_resize:
++	getmaxyx(stdscr, height, width);
++	if (height < 8 || width < 8)
++		return -ERRDISPLAYTOOSMALL;
++	if (initial_height != 0)
++		height = initial_height;
++	else
++		if (height > 4)
++			height -= 4;
++		else
++			height = 0;
++	if (initial_width != 0)
++		width = initial_width;
++	else
++		if (width > 5)
++			width -= 5;
++		else
++			width = 0;
++
++	/* center dialog box on screen */
++	x = (COLS - width) / 2;
++	y = (LINES - height) / 2;
++
++	draw_shadow(stdscr, y, x, height, width);
++
++	dialog = newwin(height, width, y, x);
++	keypad(dialog, TRUE);
++
++	/* Create window for box region, used for scrolling text */
++	boxh = height - 4;
++	boxw = width - 2;
++	box = subwin(dialog, boxh, boxw, y + 1, x + 1);
++	wattrset(box, dlg.dialog.atr);
++	wbkgdset(box, dlg.dialog.atr & A_COLOR);
++
++	keypad(box, TRUE);
++
++	/* register the new window, along with its borders */
++	draw_box(dialog, 0, 0, height, width,
++		 dlg.dialog.atr, dlg.border.atr);
++
++	wattrset(dialog, dlg.border.atr);
++	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
++	for (i = 0; i < width - 2; i++)
++		waddch(dialog, ACS_HLINE);
++	wattrset(dialog, dlg.dialog.atr);
++	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
++	waddch(dialog, ACS_RTEE);
++
++	print_title(dialog, title, width);
++
++	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
++	wnoutrefresh(dialog);
++	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
++
++	/* Print first page of text */
++	attr_clear(box, boxh, boxw, dlg.dialog.atr);
++	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
++
++	while ((key != KEY_ESC) && (key != '\n')) {
++		key = wgetch(dialog);
++		switch (key) {
++		case 'E':	/* Exit */
++		case 'e':
++		case 'X':
++		case 'x':
++			delwin(box);
++			delwin(dialog);
++			return 0;
++		case 'g':	/* First page */
++		case KEY_HOME:
++			if (!begin_reached) {
++				begin_reached = 1;
++				page = buf;
++				refresh_text_box(dialog, box, boxh, boxw,
++						 cur_y, cur_x);
++			}
++			break;
++		case 'G':	/* Last page */
++		case KEY_END:
++
++			end_reached = 1;
++			/* point to last char in buf */
++			page = buf + strlen(buf);
++			back_lines(boxh);
++			refresh_text_box(dialog, box, boxh, boxw,
++					 cur_y, cur_x);
++			break;
++		case 'K':	/* Previous line */
++		case 'k':
++		case KEY_UP:
++			if (!begin_reached) {
++				back_lines(page_length + 1);
++
++				/* We don't call print_page() here but use
++				 * scrolling to ensure faster screen update.
++				 * However, 'end_reached' and 'page_length'
++				 * should still be updated, and 'page' should
++				 * point to start of next page. This is done
++				 * by calling get_line() in the following
++				 * 'for' loop. */
++				scrollok(box, TRUE);
++				wscrl(box, -1);	/* Scroll box region down one line */
++				scrollok(box, FALSE);
++				page_length = 0;
++				passed_end = 0;
++				for (i = 0; i < boxh; i++) {
++					if (!i) {
++						/* print first line of page */
++						print_line(box, 0, boxw);
++						wnoutrefresh(box);
++					} else
++						/* Called to update 'end_reached' and 'page' */
++						get_line();
++					if (!passed_end)
++						page_length++;
++					if (end_reached && !passed_end)
++						passed_end = 1;
++				}
++
++				print_position(dialog);
++				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
++				wrefresh(dialog);
++			}
++			break;
++		case 'B':	/* Previous page */
++		case 'b':
++		case KEY_PPAGE:
++			if (begin_reached)
++				break;
++			back_lines(page_length + boxh);
++			refresh_text_box(dialog, box, boxh, boxw,
++					 cur_y, cur_x);
++			break;
++		case 'J':	/* Next line */
++		case 'j':
++		case KEY_DOWN:
++			if (!end_reached) {
++				begin_reached = 0;
++				scrollok(box, TRUE);
++				scroll(box);	/* Scroll box region up one line */
++				scrollok(box, FALSE);
++				print_line(box, boxh - 1, boxw);
++				wnoutrefresh(box);
++				print_position(dialog);
++				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
++				wrefresh(dialog);
++			}
++			break;
++		case KEY_NPAGE:	/* Next page */
++		case ' ':
++			if (end_reached)
++				break;
++
++			begin_reached = 0;
++			refresh_text_box(dialog, box, boxh, boxw,
++					 cur_y, cur_x);
++			break;
++		case '0':	/* Beginning of line */
++		case 'H':	/* Scroll left */
++		case 'h':
++		case KEY_LEFT:
++			if (hscroll <= 0)
++				break;
++
++			if (key == '0')
++				hscroll = 0;
++			else
++				hscroll--;
++			/* Reprint current page to scroll horizontally */
++			back_lines(page_length);
++			refresh_text_box(dialog, box, boxh, boxw,
++					 cur_y, cur_x);
++			break;
++		case 'L':	/* Scroll right */
++		case 'l':
++		case KEY_RIGHT:
++			if (hscroll >= MAX_LEN)
++				break;
++			hscroll++;
++			/* Reprint current page to scroll horizontally */
++			back_lines(page_length);
++			refresh_text_box(dialog, box, boxh, boxw,
++					 cur_y, cur_x);
++			break;
++		case KEY_ESC:
++			key = on_key_esc(dialog);
++			break;
++		case KEY_RESIZE:
++			back_lines(height);
++			delwin(box);
++			delwin(dialog);
++			on_key_resize();
++			goto do_resize;
++		}
++	}
++	delwin(box);
++	delwin(dialog);
++	return key;		/* ESC pressed */
++}
++
++/*
++ * Go back 'n' lines in text. Called by dialog_textbox().
++ * 'page' will be updated to point to the desired line in 'buf'.
++ */
++static void back_lines(int n)
++{
++	int i;
++
++	begin_reached = 0;
++	/* Go back 'n' lines */
++	for (i = 0; i < n; i++) {
++		if (*page == '\0') {
++			if (end_reached) {
++				end_reached = 0;
++				continue;
++			}
++		}
++		if (page == buf) {
++			begin_reached = 1;
++			return;
++		}
++		page--;
++		do {
++			if (page == buf) {
++				begin_reached = 1;
++				return;
++			}
++			page--;
++		} while (*page != '\n');
++		page++;
++	}
++}
++
++/*
++ * Print a new page of text. Called by dialog_textbox().
++ */
++static void print_page(WINDOW * win, int height, int width)
++{
++	int i, passed_end = 0;
++
++	page_length = 0;
++	for (i = 0; i < height; i++) {
++		print_line(win, i, width);
++		if (!passed_end)
++			page_length++;
++		if (end_reached && !passed_end)
++			passed_end = 1;
++	}
++	wnoutrefresh(win);
++}
++
++/*
++ * Print a new line of text. Called by dialog_textbox() and print_page().
++ */
++static void print_line(WINDOW * win, int row, int width)
++{
++	int y, x;
++	char *line;
++
++	line = get_line();
++	line += MIN(strlen(line), hscroll);	/* Scroll horizontally */
++	wmove(win, row, 0);	/* move cursor to correct line */
++	waddch(win, ' ');
++	waddnstr(win, line, MIN(strlen(line), width - 2));
++
++	getyx(win, y, x);
++	/* Clear 'residue' of previous line */
++#if OLD_NCURSES
++	{
++		int i;
++		for (i = 0; i < width - x; i++)
++			waddch(win, ' ');
++	}
++#else
++	wclrtoeol(win);
++#endif
++}
++
++/*
++ * Return current line of text. Called by dialog_textbox() and print_line().
++ * 'page' should point to start of current line before calling, and will be
++ * updated to point to start of next line.
++ */
++static char *get_line(void)
++{
++	int i = 0;
++	static char line[MAX_LEN + 1];
++
++	end_reached = 0;
++	while (*page != '\n') {
++		if (*page == '\0') {
++			if (!end_reached) {
++				end_reached = 1;
++				break;
++			}
++		} else if (i < MAX_LEN)
++			line[i++] = *(page++);
++		else {
++			/* Truncate lines longer than MAX_LEN characters */
++			if (i == MAX_LEN)
++				line[i++] = '\0';
++			page++;
++		}
++	}
++	if (i <= MAX_LEN)
++		line[i] = '\0';
++	if (!end_reached)
++		page++;		/* move pass '\n' */
++
++	return line;
++}
++
++/*
++ * Print current position
++ */
++static void print_position(WINDOW * win)
++{
++	int percent;
++
++	wattrset(win, dlg.position_indicator.atr);
++	wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
++	percent = (page - buf) * 100 / strlen(buf);
++	wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
++	wprintw(win, "(%3d%%)", percent);
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/util.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,642 @@
++/*
++ *  util.c
++ *
++ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include "dialog.h"
++
++struct dialog_info dlg;
++
++static void set_mono_theme(void)
++{
++	dlg.screen.atr = A_NORMAL;
++	dlg.shadow.atr = A_NORMAL;
++	dlg.dialog.atr = A_NORMAL;
++	dlg.title.atr = A_BOLD;
++	dlg.border.atr = A_NORMAL;
++	dlg.button_active.atr = A_REVERSE;
++	dlg.button_inactive.atr = A_DIM;
++	dlg.button_key_active.atr = A_REVERSE;
++	dlg.button_key_inactive.atr = A_BOLD;
++	dlg.button_label_active.atr = A_REVERSE;
++	dlg.button_label_inactive.atr = A_NORMAL;
++	dlg.inputbox.atr = A_NORMAL;
++	dlg.inputbox_border.atr = A_NORMAL;
++	dlg.searchbox.atr = A_NORMAL;
++	dlg.searchbox_title.atr = A_BOLD;
++	dlg.searchbox_border.atr = A_NORMAL;
++	dlg.position_indicator.atr = A_BOLD;
++	dlg.menubox.atr = A_NORMAL;
++	dlg.menubox_border.atr = A_NORMAL;
++	dlg.item.atr = A_NORMAL;
++	dlg.item_selected.atr = A_REVERSE;
++	dlg.tag.atr = A_BOLD;
++	dlg.tag_selected.atr = A_REVERSE;
++	dlg.tag_key.atr = A_BOLD;
++	dlg.tag_key_selected.atr = A_REVERSE;
++	dlg.check.atr = A_BOLD;
++	dlg.check_selected.atr = A_REVERSE;
++	dlg.uarrow.atr = A_BOLD;
++	dlg.darrow.atr = A_BOLD;
++}
++
++#define DLG_COLOR(dialog, f, b, h) \
++do {                               \
++	dlg.dialog.fg = (f);       \
++	dlg.dialog.bg = (b);       \
++	dlg.dialog.hl = (h);       \
++} while (0)
++
++static void set_classic_theme(void)
++{
++	DLG_COLOR(screen,                COLOR_CYAN,   COLOR_BLUE,   true);
++	DLG_COLOR(shadow,                COLOR_BLACK,  COLOR_BLACK,  true);
++	DLG_COLOR(dialog,                COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(title,                 COLOR_YELLOW, COLOR_WHITE,  true);
++	DLG_COLOR(border,                COLOR_WHITE,  COLOR_WHITE,  true);
++	DLG_COLOR(button_active,         COLOR_WHITE,  COLOR_BLUE,   true);
++	DLG_COLOR(button_inactive,       COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(button_key_active,     COLOR_WHITE,  COLOR_BLUE,   true);
++	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_WHITE,  false);
++	DLG_COLOR(button_label_active,   COLOR_YELLOW, COLOR_BLUE,   true);
++	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_WHITE,  true);
++	DLG_COLOR(inputbox,              COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(inputbox_border,       COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(searchbox,             COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(searchbox_title,       COLOR_YELLOW, COLOR_WHITE,  true);
++	DLG_COLOR(searchbox_border,      COLOR_WHITE,  COLOR_WHITE,  true);
++	DLG_COLOR(position_indicator,    COLOR_YELLOW, COLOR_WHITE,  true);
++	DLG_COLOR(menubox,               COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(menubox_border,        COLOR_WHITE,  COLOR_WHITE,  true);
++	DLG_COLOR(item,                  COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(item_selected,         COLOR_WHITE,  COLOR_BLUE,   true);
++	DLG_COLOR(tag,                   COLOR_YELLOW, COLOR_WHITE,  true);
++	DLG_COLOR(tag_selected,          COLOR_YELLOW, COLOR_BLUE,   true);
++	DLG_COLOR(tag_key,               COLOR_YELLOW, COLOR_WHITE,  true);
++	DLG_COLOR(tag_key_selected,      COLOR_YELLOW, COLOR_BLUE,   true);
++	DLG_COLOR(check,                 COLOR_BLACK,  COLOR_WHITE,  false);
++	DLG_COLOR(check_selected,        COLOR_WHITE,  COLOR_BLUE,   true);
++	DLG_COLOR(uarrow,                COLOR_GREEN,  COLOR_WHITE,  true);
++	DLG_COLOR(darrow,                COLOR_GREEN,  COLOR_WHITE,  true);
++}
++
++static void set_blackbg_theme(void)
++{
++	DLG_COLOR(screen, COLOR_RED,   COLOR_BLACK, true);
++	DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
++	DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
++	DLG_COLOR(title,  COLOR_RED,   COLOR_BLACK, false);
++	DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
++
++	DLG_COLOR(button_active,         COLOR_YELLOW, COLOR_RED,   false);
++	DLG_COLOR(button_inactive,       COLOR_YELLOW, COLOR_BLACK, false);
++	DLG_COLOR(button_key_active,     COLOR_YELLOW, COLOR_RED,   true);
++	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_BLACK, false);
++	DLG_COLOR(button_label_active,   COLOR_WHITE,  COLOR_RED,   false);
++	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_BLACK, true);
++
++	DLG_COLOR(inputbox,         COLOR_YELLOW, COLOR_BLACK, false);
++	DLG_COLOR(inputbox_border,  COLOR_YELLOW, COLOR_BLACK, false);
++
++	DLG_COLOR(searchbox,        COLOR_YELLOW, COLOR_BLACK, false);
++	DLG_COLOR(searchbox_title,  COLOR_YELLOW, COLOR_BLACK, true);
++	DLG_COLOR(searchbox_border, COLOR_BLACK,  COLOR_BLACK, true);
++
++	DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK,  false);
++
++	DLG_COLOR(menubox,          COLOR_YELLOW, COLOR_BLACK, false);
++	DLG_COLOR(menubox_border,   COLOR_BLACK,  COLOR_BLACK, true);
++
++	DLG_COLOR(item,             COLOR_WHITE, COLOR_BLACK, false);
++	DLG_COLOR(item_selected,    COLOR_WHITE, COLOR_RED,   false);
++
++	DLG_COLOR(tag,              COLOR_RED,    COLOR_BLACK, false);
++	DLG_COLOR(tag_selected,     COLOR_YELLOW, COLOR_RED,   true);
++	DLG_COLOR(tag_key,          COLOR_RED,    COLOR_BLACK, false);
++	DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED,   true);
++
++	DLG_COLOR(check,            COLOR_YELLOW, COLOR_BLACK, false);
++	DLG_COLOR(check_selected,   COLOR_YELLOW, COLOR_RED,   true);
++
++	DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
++	DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
++}
++
++static void set_bluetitle_theme(void)
++{
++	set_classic_theme();
++	DLG_COLOR(title,               COLOR_BLUE,   COLOR_WHITE, true);
++	DLG_COLOR(button_key_active,   COLOR_YELLOW, COLOR_BLUE,  true);
++	DLG_COLOR(button_label_active, COLOR_WHITE,  COLOR_BLUE,  true);
++	DLG_COLOR(searchbox_title,     COLOR_BLUE,   COLOR_WHITE, true);
++	DLG_COLOR(position_indicator,  COLOR_BLUE,   COLOR_WHITE, true);
++	DLG_COLOR(tag,                 COLOR_BLUE,   COLOR_WHITE, true);
++	DLG_COLOR(tag_key,             COLOR_BLUE,   COLOR_WHITE, true);
++
++}
++
++/*
++ * Select color theme
++ */
++static int set_theme(const char *theme)
++{
++	int use_color = 1;
++	if (!theme)
++		set_bluetitle_theme();
++	else if (strcmp(theme, "classic") == 0)
++		set_classic_theme();
++	else if (strcmp(theme, "bluetitle") == 0)
++		set_bluetitle_theme();
++	else if (strcmp(theme, "blackbg") == 0)
++		set_blackbg_theme();
++	else if (strcmp(theme, "mono") == 0)
++		use_color = 0;
++
++	return use_color;
++}
++
++static void init_one_color(struct dialog_color *color)
++{
++	static int pair = 0;
++
++	pair++;
++	init_pair(pair, color->fg, color->bg);
++	if (color->hl)
++		color->atr = A_BOLD | COLOR_PAIR(pair);
++	else
++		color->atr = COLOR_PAIR(pair);
++}
++
++static void init_dialog_colors(void)
++{
++	init_one_color(&dlg.screen);
++	init_one_color(&dlg.shadow);
++	init_one_color(&dlg.dialog);
++	init_one_color(&dlg.title);
++	init_one_color(&dlg.border);
++	init_one_color(&dlg.button_active);
++	init_one_color(&dlg.button_inactive);
++	init_one_color(&dlg.button_key_active);
++	init_one_color(&dlg.button_key_inactive);
++	init_one_color(&dlg.button_label_active);
++	init_one_color(&dlg.button_label_inactive);
++	init_one_color(&dlg.inputbox);
++	init_one_color(&dlg.inputbox_border);
++	init_one_color(&dlg.searchbox);
++	init_one_color(&dlg.searchbox_title);
++	init_one_color(&dlg.searchbox_border);
++	init_one_color(&dlg.position_indicator);
++	init_one_color(&dlg.menubox);
++	init_one_color(&dlg.menubox_border);
++	init_one_color(&dlg.item);
++	init_one_color(&dlg.item_selected);
++	init_one_color(&dlg.tag);
++	init_one_color(&dlg.tag_selected);
++	init_one_color(&dlg.tag_key);
++	init_one_color(&dlg.tag_key_selected);
++	init_one_color(&dlg.check);
++	init_one_color(&dlg.check_selected);
++	init_one_color(&dlg.uarrow);
++	init_one_color(&dlg.darrow);
++}
++
++/*
++ * Setup for color display
++ */
++static void color_setup(const char *theme)
++{
++	if (set_theme(theme)) {
++		if (has_colors()) {	/* Terminal supports color? */
++			start_color();
++			init_dialog_colors();
++		}
++	}
++	else
++	{
++		set_mono_theme();
++	}
++}
++
++/*
++ * Set window to attribute 'attr'
++ */
++void attr_clear(WINDOW * win, int height, int width, chtype attr)
++{
++	int i, j;
++
++	wattrset(win, attr);
++	for (i = 0; i < height; i++) {
++		wmove(win, i, 0);
++		for (j = 0; j < width; j++)
++			waddch(win, ' ');
++	}
++	touchwin(win);
++}
++
++void dialog_clear(void)
++{
++	attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
++	/* Display background title if it exists ... - SLH */
++	if (dlg.backtitle != NULL) {
++		int i;
++
++		wattrset(stdscr, dlg.screen.atr);
++		mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
++		wmove(stdscr, 1, 1);
++		for (i = 1; i < COLS - 1; i++)
++			waddch(stdscr, ACS_HLINE);
++	}
++	wnoutrefresh(stdscr);
++}
++
++/*
++ * Do some initialization for dialog
++ */
++void init_dialog(const char *backtitle)
++{
++	dlg.backtitle = backtitle;
++	color_setup(getenv("MENUCONFIG_COLOR"));
++}
++
++void reset_dialog(void)
++{
++	initscr();		/* Init curses */
++	keypad(stdscr, TRUE);
++	cbreak();
++	noecho();
++	dialog_clear();
++}
++
++/*
++ * End using dialog functions.
++ */
++void end_dialog(void)
++{
++	endwin();
++}
++
++/* Print the title of the dialog. Center the title and truncate
++ * tile if wider than dialog (- 2 chars).
++ **/
++void print_title(WINDOW *dialog, const char *title, int width)
++{
++	if (title) {
++		int tlen = MIN(width - 2, strlen(title));
++		wattrset(dialog, dlg.title.atr);
++		mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
++		mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
++		waddch(dialog, ' ');
++	}
++}
++
++/*
++ * Print a string of text in a window, automatically wrap around to the
++ * next line if the string is too long to fit on one line. Newline
++ * characters '\n' are replaced by spaces.  We start on a new line
++ * if there is no room for at least 4 nonblanks following a double-space.
++ */
++void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
++{
++	int newl, cur_x, cur_y;
++	int i, prompt_len, room, wlen;
++	char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
++
++	strcpy(tempstr, prompt);
++
++	prompt_len = strlen(tempstr);
++
++	/*
++	 * Remove newlines
++	 */
++	for (i = 0; i < prompt_len; i++) {
++		if (tempstr[i] == '\n')
++			tempstr[i] = ' ';
++	}
++
++	if (prompt_len <= width - x * 2) {	/* If prompt is short */
++		wmove(win, y, (width - prompt_len) / 2);
++		waddstr(win, tempstr);
++	} else {
++		cur_x = x;
++		cur_y = y;
++		newl = 1;
++		word = tempstr;
++		while (word && *word) {
++			sp = index(word, ' ');
++			if (sp)
++				*sp++ = 0;
++
++			/* Wrap to next line if either the word does not fit,
++			   or it is the first word of a new sentence, and it is
++			   short, and the next word does not fit. */
++			room = width - cur_x;
++			wlen = strlen(word);
++			if (wlen > room ||
++			    (newl && wlen < 4 && sp
++			     && wlen + 1 + strlen(sp) > room
++			     && (!(sp2 = index(sp, ' '))
++				 || wlen + 1 + (sp2 - sp) > room))) {
++				cur_y++;
++				cur_x = x;
++			}
++			wmove(win, cur_y, cur_x);
++			waddstr(win, word);
++			getyx(win, cur_y, cur_x);
++			cur_x++;
++			if (sp && *sp == ' ') {
++				cur_x++;	/* double space */
++				while (*++sp == ' ') ;
++				newl = 1;
++			} else
++				newl = 0;
++			word = sp;
++		}
++	}
++}
++
++/*
++ * Print a button
++ */
++void print_button(WINDOW * win, const char *label, int y, int x, int selected)
++{
++	int i, temp;
++
++	wmove(win, y, x);
++	wattrset(win, selected ? dlg.button_active.atr
++		 : dlg.button_inactive.atr);
++	waddstr(win, "<");
++	temp = strspn(label, " ");
++	label += temp;
++	wattrset(win, selected ? dlg.button_label_active.atr
++		 : dlg.button_label_inactive.atr);
++	for (i = 0; i < temp; i++)
++		waddch(win, ' ');
++	wattrset(win, selected ? dlg.button_key_active.atr
++		 : dlg.button_key_inactive.atr);
++	waddch(win, label[0]);
++	wattrset(win, selected ? dlg.button_label_active.atr
++		 : dlg.button_label_inactive.atr);
++	waddstr(win, (char *)label + 1);
++	wattrset(win, selected ? dlg.button_active.atr
++		 : dlg.button_inactive.atr);
++	waddstr(win, ">");
++	wmove(win, y, x + temp + 1);
++}
++
++/*
++ * Draw a rectangular box with line drawing characters
++ */
++void
++draw_box(WINDOW * win, int y, int x, int height, int width,
++	 chtype box, chtype border)
++{
++	int i, j;
++
++	wattrset(win, 0);
++	for (i = 0; i < height; i++) {
++		wmove(win, y + i, x);
++		for (j = 0; j < width; j++)
++			if (!i && !j)
++				waddch(win, border | ACS_ULCORNER);
++			else if (i == height - 1 && !j)
++				waddch(win, border | ACS_LLCORNER);
++			else if (!i && j == width - 1)
++				waddch(win, box | ACS_URCORNER);
++			else if (i == height - 1 && j == width - 1)
++				waddch(win, box | ACS_LRCORNER);
++			else if (!i)
++				waddch(win, border | ACS_HLINE);
++			else if (i == height - 1)
++				waddch(win, box | ACS_HLINE);
++			else if (!j)
++				waddch(win, border | ACS_VLINE);
++			else if (j == width - 1)
++				waddch(win, box | ACS_VLINE);
++			else
++				waddch(win, box | ' ');
++	}
++}
++
++/*
++ * Draw shadows along the right and bottom edge to give a more 3D look
++ * to the boxes
++ */
++void draw_shadow(WINDOW * win, int y, int x, int height, int width)
++{
++	int i;
++
++	if (has_colors()) {	/* Whether terminal supports color? */
++		wattrset(win, dlg.shadow.atr);
++		wmove(win, y + height, x + 2);
++		for (i = 0; i < width; i++)
++			waddch(win, winch(win) & A_CHARTEXT);
++		for (i = y + 1; i < y + height + 1; i++) {
++			wmove(win, i, x + width);
++			waddch(win, winch(win) & A_CHARTEXT);
++			waddch(win, winch(win) & A_CHARTEXT);
++		}
++		wnoutrefresh(win);
++	}
++}
++
++/*
++ *  Return the position of the first alphabetic character in a string.
++ */
++int first_alpha(const char *string, const char *exempt)
++{
++	int i, in_paren = 0, c;
++
++	for (i = 0; i < strlen(string); i++) {
++		c = tolower(string[i]);
++
++		if (strchr("<[(", c))
++			++in_paren;
++		if (strchr(">])", c) && in_paren > 0)
++			--in_paren;
++
++		if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
++			return i;
++	}
++
++	return 0;
++}
++
++/*
++ * ncurses uses ESC to detect escaped char sequences. This resutl in
++ * a small timeout before ESC is actually delivered to the application.
++ * lxdialog suggest <ESC> <ESC> which is correctly translated to two
++ * times esc. But then we need to ignore the second esc to avoid stepping
++ * out one menu too much. Filter away all escaped key sequences since
++ * keypad(FALSE) turn off ncurses support for escape sequences - and thats
++ * needed to make notimeout() do as expected.
++ */
++int on_key_esc(WINDOW *win)
++{
++	int key;
++	int key2;
++	int key3;
++
++	nodelay(win, TRUE);
++	keypad(win, FALSE);
++	key = wgetch(win);
++	key2 = wgetch(win);
++	do {
++		key3 = wgetch(win);
++	} while (key3 != ERR);
++	nodelay(win, FALSE);
++	keypad(win, TRUE);
++	if (key == KEY_ESC && key2 == ERR)
++		return KEY_ESC;
++	else if (key != ERR && key != KEY_ESC && key2 == ERR)
++		ungetch(key);
++
++	return -1;
++}
++
++/* redraw screen in new size */
++int on_key_resize(void)
++{
++	dialog_clear();
++	return KEY_RESIZE;
++}
++
++struct dialog_list *item_cur;
++struct dialog_list item_nil;
++struct dialog_list *item_head;
++
++void item_reset(void)
++{
++	struct dialog_list *p, *next;
++
++	for (p = item_head; p; p = next) {
++		next = p->next;
++		free(p);
++	}
++	item_head = NULL;
++	item_cur = &item_nil;
++}
++
++void item_make(const char *fmt, ...)
++{
++	va_list ap;
++	struct dialog_list *p = malloc(sizeof(*p));
++
++	if (item_head)
++		item_cur->next = p;
++	else
++		item_head = p;
++	item_cur = p;
++	memset(p, 0, sizeof(*p));
++
++	va_start(ap, fmt);
++	vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
++	va_end(ap);
++}
++
++void item_add_str(const char *fmt, ...)
++{
++	va_list ap;
++        size_t avail;
++
++	avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
++
++	va_start(ap, fmt);
++	vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
++		  avail, fmt, ap);
++	item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
++	va_end(ap);
++}
++
++void item_set_tag(char tag)
++{
++	item_cur->node.tag = tag;
++}
++void item_set_data(void *ptr)
++{
++	item_cur->node.data = ptr;
++}
++
++void item_set_selected(int val)
++{
++	item_cur->node.selected = val;
++}
++
++int item_activate_selected(void)
++{
++	item_foreach()
++		if (item_is_selected())
++			return 1;
++	return 0;
++}
++
++void *item_data(void)
++{
++	return item_cur->node.data;
++}
++
++char item_tag(void)
++{
++	return item_cur->node.tag;
++}
++
++int item_count(void)
++{
++	int n = 0;
++	struct dialog_list *p;
++
++	for (p = item_head; p; p = p->next)
++		n++;
++	return n;
++}
++
++void item_set(int n)
++{
++	int i = 0;
++	item_foreach()
++		if (i++ == n)
++			return;
++}
++
++int item_n(void)
++{
++	int n = 0;
++	struct dialog_list *p;
++
++	for (p = item_head; p; p = p->next) {
++		if (p == item_cur)
++			return n;
++		n++;
++	}
++	return 0;
++}
++
++const char *item_str(void)
++{
++	return item_cur->node.str;
++}
++
++int item_is_selected(void)
++{
++	return (item_cur->node.selected != 0);
++}
++
++int item_is_tag(char tag)
++{
++	return (item_cur->node.tag == tag);
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lxdialog/yesno.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,114 @@
++/*
++ *  yesno.c -- implements the yes/no box
++ *
++ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
++ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
++ *
++ *  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
++ *  of the License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include "dialog.h"
++
++/*
++ * Display termination buttons
++ */
++static void print_buttons(WINDOW * dialog, int height, int width, int selected)
++{
++	int x = width / 2 - 10;
++	int y = height - 2;
++
++	print_button(dialog, " Yes ", y, x, selected == 0);
++	print_button(dialog, "  No  ", y, x + 13, selected == 1);
++
++	wmove(dialog, y, x + 1 + 13 * selected);
++	wrefresh(dialog);
++}
++
++/*
++ * Display a dialog box with two buttons - Yes and No
++ */
++int dialog_yesno(const char *title, const char *prompt, int height, int width)
++{
++	int i, x, y, key = 0, button = 0;
++	WINDOW *dialog;
++
++do_resize:
++	if (getmaxy(stdscr) < (height + 4))
++		return -ERRDISPLAYTOOSMALL;
++	if (getmaxx(stdscr) < (width + 4))
++		return -ERRDISPLAYTOOSMALL;
++
++	/* center dialog box on screen */
++	x = (COLS - width) / 2;
++	y = (LINES - height) / 2;
++
++	draw_shadow(stdscr, y, x, height, width);
++
++	dialog = newwin(height, width, y, x);
++	keypad(dialog, TRUE);
++
++	draw_box(dialog, 0, 0, height, width,
++		 dlg.dialog.atr, dlg.border.atr);
++	wattrset(dialog, dlg.border.atr);
++	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
++	for (i = 0; i < width - 2; i++)
++		waddch(dialog, ACS_HLINE);
++	wattrset(dialog, dlg.dialog.atr);
++	waddch(dialog, ACS_RTEE);
++
++	print_title(dialog, title, width);
++
++	wattrset(dialog, dlg.dialog.atr);
++	print_autowrap(dialog, prompt, width - 2, 1, 3);
++
++	print_buttons(dialog, height, width, 0);
++
++	while (key != KEY_ESC) {
++		key = wgetch(dialog);
++		switch (key) {
++		case 'Y':
++		case 'y':
++			delwin(dialog);
++			return 0;
++		case 'N':
++		case 'n':
++			delwin(dialog);
++			return 1;
++
++		case TAB:
++		case KEY_LEFT:
++		case KEY_RIGHT:
++			button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);
++
++			print_buttons(dialog, height, width, button);
++			wrefresh(dialog);
++			break;
++		case ' ':
++		case '\n':
++			delwin(dialog);
++			return button;
++		case KEY_ESC:
++			key = on_key_esc(dialog);
++			break;
++		case KEY_RESIZE:
++			delwin(dialog);
++			on_key_resize();
++			goto do_resize;
++		}
++	}
++
++	delwin(dialog);
++	return key;		/* ESC pressed */
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/conf.c	2006-10-31 12:18:24.000000000 -0500
+@@ -0,0 +1,624 @@
++/*
++ * 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 <stdio.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;
++char *defconfig_file;
++
++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[] = N_("Sorry, no help available for this option yet.\n");
++
++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 check_stdin(void)
++{
++	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);
++	}
++}
++
++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;
++
++	if (!sym_is_changable(sym)) {
++		printf("%s\n", def);
++		line[0] = '\n';
++		line[1] = 0;
++		return;
++	}
++
++	switch (input_mode) {
++	case set_no:
++	case set_mod:
++	case set_yes:
++	case set_random:
++		if (sym_has_value(sym)) {
++			printf("%s\n", def);
++			return;
++		}
++		break;
++	case ask_new:
++	case ask_silent:
++		if (sym_has_value(sym)) {
++			printf("%s\n", def);
++			return;
++		}
++		check_stdin();
++	case ask_all:
++		fflush(stdout);
++		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] == '\n') {
++				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 *child;
++	int type;
++	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 {
++		switch (sym_get_tristate_value(sym)) {
++		case no:
++			return 1;
++		case mod:
++			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
++			return 0;
++		case yes:
++			break;
++		}
++	}
++
++	while (1) {
++		int cnt, def;
++
++		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
++		def_sym = sym_get_choice_value(sym);
++		cnt = def = 0;
++		line[0] = 0;
++		for (child = menu->list; child; child = child->next) {
++			if (!menu_is_visible(child))
++				continue;
++			if (!child->sym) {
++				printf("%*c %s\n", indent, '*', menu_get_prompt(child));
++				continue;
++			}
++			cnt++;
++			if (child->sym == def_sym) {
++				def = cnt;
++				printf("%*c", indent, '>');
++			} else
++				printf("%*c", indent, ' ');
++			printf(" %d. %s", cnt, menu_get_prompt(child));
++			if (child->sym->name)
++				printf(" (%s)", child->sym->name);
++			if (!sym_has_value(child->sym))
++				printf(" (NEW)");
++			printf("\n");
++		}
++		printf("%*schoice", indent - 1, "");
++		if (cnt == 1) {
++			printf("[1]: 1\n");
++			goto conf_childs;
++		}
++		printf("[1-%d", cnt);
++		if (sym->help)
++			printf("?");
++		printf("]: ");
++		switch (input_mode) {
++		case ask_new:
++		case ask_silent:
++			if (!is_new) {
++				cnt = def;
++				printf("%d\n", cnt);
++				break;
++			}
++			check_stdin();
++		case ask_all:
++			fflush(stdout);
++			fgets(line, 128, stdin);
++			strip(line);
++			if (line[0] == '?') {
++				printf("\n%s\n", menu->sym->help ?
++					menu->sym->help : nohelp_text);
++				continue;
++			}
++			if (!line[0])
++				cnt = def;
++			else if (isdigit(line[0]))
++				cnt = atoi(line);
++			else
++				continue;
++			break;
++		case set_random:
++			def = (random() % cnt) + 1;
++		case set_default:
++		case set_yes:
++		case set_mod:
++		case set_no:
++			cnt = def;
++			printf("%d\n", cnt);
++			break;
++		}
++
++	conf_childs:
++		for (child = menu->list; child; child = child->next) {
++			if (!child->sym || !menu_is_visible(child))
++				continue;
++			if (!--cnt)
++				break;
++		}
++		if (!child)
++			continue;
++		if (line[strlen(line) - 1] == '?') {
++			printf("\n%s\n", child->sym->help ?
++				child->sym->help : nohelp_text);
++			continue;
++		}
++		sym_set_choice_value(sym, child->sym);
++		if (child->list) {
++			indent += 2;
++			conf(child->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 (sym->curr.tri != 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 && !sym_has_value(sym)) {
++		if (sym_is_changable(sym) ||
++		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
++			if (!conf_cnt++)
++				printf(_("*\n* Restart config...\n*\n"));
++			rootEntry = menu_get_parent_menu(menu);
++			conf(rootEntry);
++		}
++	}
++
++	for (child = menu->list; child; child = child->next)
++		check_conf(child);
++}
++
++int main(int ac, char **av)
++{
++	int i = 1;
++	const char *name;
++	struct stat tmpstat;
++
++	if (ac > i && av[i][0] == '-') {
++		switch (av[i++][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 'D':
++			input_mode = set_default;
++			defconfig_file = av[i++];
++			if (!defconfig_file) {
++				printf(_("%s: No default config file specified\n"),
++					av[0]);
++				exit(1);
++			}
++			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 '?':
++			fprintf(stderr, "See README for usage info\n");
++			exit(0);
++		}
++	}
++  	name = av[i];
++	if (!name) {
++		printf(_("%s: Kconfig file missing\n"), av[0]);
++		exit(1);
++	}
++	conf_parse(name);
++	//zconfdump(stdout);
++	switch (input_mode) {
++	case set_default:
++		if (!defconfig_file)
++			defconfig_file = conf_get_default_confname();
++		if (conf_read(defconfig_file)) {
++			printf("***\n"
++				"*** Can't find default configuration \"%s\"!\n"
++				"***\n", defconfig_file);
++			exit(1);
++		}
++		break;
++	case ask_silent:
++		if (stat(".config", &tmpstat)) {
++			printf(_("***\n"
++				"*** You have not yet configured your "PROJECT_NAME"!\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;
++	case set_no:
++	case set_mod:
++	case set_yes:
++	case set_random:
++		name = getenv("KCONFIG_ALLCONFIG");
++		if (name && !stat(name, &tmpstat)) {
++			conf_read_simple(name, S_DEF_USER);
++			break;
++		}
++		switch (input_mode) {
++		case set_no:	 name = "allno.config"; break;
++		case set_mod:	 name = "allmod.config"; break;
++		case set_yes:	 name = "allyes.config"; break;
++		case set_random: name = "allrandom.config"; break;
++		default: break;
++		}
++		if (!stat(name, &tmpstat))
++			conf_read_simple(name, S_DEF_USER);
++		else if (!stat("all.config", &tmpstat))
++			conf_read_simple("all.config", S_DEF_USER);
++		break;
++	default:
++		break;
++	}
++
++	if (input_mode != ask_silent) {
++		rootEntry = &rootmenu;
++		conf(&rootmenu);
++		if (input_mode == ask_all) {
++			input_mode = ask_silent;
++			valid_stdin = 1;
++		}
++	} else if (sym_change_count) {
++		name = getenv("KCONFIG_NOSILENTUPDATE");
++		if (name && *name) {
++			fprintf(stderr, _("\n*** "PROJECT_NAME" configuration requires explicit update.\n\n"));
++			return 1;
++		}
++	} else
++		goto skip_check;
++
++	do {
++		conf_cnt = 0;
++		check_conf(&rootmenu);
++	} while (conf_cnt);
++
++	if (!conf_write(NULL)) {
++skip_check:
++		if (!(input_mode == ask_silent && conf_write_autoconf()))
++			return 0;
++	}
++	fprintf(stderr, _("\n*** Error writing "PROJECT_NAME" configuration.\n\n"));
++	return 1;
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/confdata.c	2007-03-16 15:41:07.000000000 -0400
+@@ -0,0 +1,806 @@
++/*
++ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
++ * Released under the terms of the GNU GPL v2.0.
++ */
++
++#include <sys/stat.h>
++#include <ctype.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <time.h>
++#include <unistd.h>
++
++#define LKC_DIRECT_LINK
++#include "lkc.h"
++
++static void conf_warning(const char *fmt, ...)
++	__attribute__ ((format (printf, 1, 2)));
++
++static const char *conf_filename;
++static int conf_lineno, conf_warnings, conf_unsaved;
++
++#ifndef conf_defname
++const char conf_defname[] = "arch/$ARCH/defconfig";
++#endif
++
++#ifndef CONFIG_PREFIX
++#define CONFIG_PREFIX "CONFIG_"
++#endif
++
++static void conf_warning(const char *fmt, ...)
++{
++	va_list ap;
++	va_start(ap, fmt);
++	fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
++	vfprintf(stderr, fmt, ap);
++	fprintf(stderr, "\n");
++	va_end(ap);
++	conf_warnings++;
++}
++
++const char *conf_get_configname(void)
++{
++	char *name = getenv("KCONFIG_CONFIG");
++
++	return name ? name : ".config";
++}
++
++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)
++{
++	struct stat buf;
++	static char fullname[PATH_MAX+1];
++	char *env, *name;
++
++	name = conf_expand_value(conf_defname);
++	env = getenv(SRCTREE);
++	if (env) {
++		sprintf(fullname, "%s/%s", env, name);
++		if (!stat(fullname, &buf))
++			return fullname;
++	}
++	return name;
++}
++
++int conf_read_simple(const char *name, int def)
++{
++	FILE *in = NULL;
++	char line[1024];
++	char *p, *p2;
++	struct symbol *sym;
++	int i, def_flags;
++
++	if (name) {
++		in = zconf_fopen(name);
++	} else {
++		struct property *prop;
++
++		name = conf_get_configname();
++		in = zconf_fopen(name);
++		if (in)
++			goto load;
++		sym_change_count++;
++		if (!sym_defconfig_list)
++			return 1;
++
++		for_all_defaults(sym_defconfig_list, prop) {
++			if (expr_calc_value(prop->visible.expr) == no ||
++			    prop->expr->type != E_SYMBOL)
++				continue;
++			name = conf_expand_value(prop->expr->left.sym->name);
++			in = zconf_fopen(name);
++			if (in) {
++				printf(_("#\n"
++					 "# using defaults found in %s\n"
++					 "#\n"), name);
++				goto load;
++			}
++		}
++	}
++	if (!in)
++		return 1;
++
++load:
++	conf_filename = name;
++	conf_lineno = 0;
++	conf_warnings = 0;
++	conf_unsaved = 0;
++
++	def_flags = SYMBOL_DEF << def;
++	for_all_symbols(i, sym) {
++		sym->flags |= SYMBOL_CHANGED;
++		sym->flags &= ~(def_flags|SYMBOL_VALID);
++		if (sym_is_choice(sym))
++			sym->flags |= def_flags;
++		switch (sym->type) {
++		case S_INT:
++		case S_HEX:
++		case S_STRING:
++			if (sym->def[def].val)
++				free(sym->def[def].val);
++		default:
++			sym->def[def].val = NULL;
++			sym->def[def].tri = no;
++		}
++	}
++
++	while (fgets(line, sizeof(line), in)) {
++		conf_lineno++;
++		sym = NULL;
++		switch (line[0]) {
++		case '#':
++			if (line[1]!=' ' || memcmp(line + 2, CONFIG_PREFIX,
++					       	strlen(CONFIG_PREFIX))) {
++				continue;
++			}
++			p = strchr(line + 2 + strlen(CONFIG_PREFIX), ' ');
++			if (!p)
++				continue;
++			*p++ = 0;
++			if (strncmp(p, "is not set", 10))
++				continue;
++			if (def == S_DEF_USER) {
++				sym = sym_find(line + 2 + strlen(CONFIG_PREFIX));
++				if (!sym) {
++					conf_warning("trying to assign nonexistent symbol %s", line + 2 + strlen(CONFIG_PREFIX));
++					break;
++				}
++			} else {
++				sym = sym_lookup(line + 9, 0);
++				if (sym->type == S_UNKNOWN)
++					sym->type = S_BOOLEAN;
++			}
++			if (sym->flags & def_flags) {
++				conf_warning("trying to reassign symbol %s", sym->name);
++				break;
++			}
++			switch (sym->type) {
++			case S_BOOLEAN:
++			case S_TRISTATE:
++				sym->def[def].tri = no;
++				sym->flags |= def_flags;
++				break;
++			default:
++				;
++			}
++			break;
++		case 'A' ... 'Z':
++			if (memcmp(line, CONFIG_PREFIX, strlen(CONFIG_PREFIX))) {
++				conf_warning("unexpected data");
++				continue;
++			}
++			p = strchr(line + strlen(CONFIG_PREFIX), '=');
++			if (!p)
++				continue;
++			*p++ = 0;
++			p2 = strchr(p, '\n');
++			if (p2) {
++				*p2-- = 0;
++				if (*p2 == '\r')
++					*p2 = 0;
++			}
++			if (def == S_DEF_USER) {
++				sym = sym_find(line + strlen(CONFIG_PREFIX));
++				if (!sym) {
++					conf_warning("trying to assign nonexistent symbol %s", line + 7);
++					break;
++				}
++			} else {
++				sym = sym_lookup(line + strlen(CONFIG_PREFIX), 0);
++				if (sym->type == S_UNKNOWN)
++					sym->type = S_OTHER;
++			}
++			if (sym->flags & def_flags) {
++				conf_warning("trying to reassign symbol %s", sym->name);
++				break;
++			}
++			switch (sym->type) {
++			case S_TRISTATE:
++				if (p[0] == 'm') {
++					sym->def[def].tri = mod;
++					sym->flags |= def_flags;
++					break;
++				}
++			case S_BOOLEAN:
++				if (p[0] == 'y') {
++					sym->def[def].tri = yes;
++					sym->flags |= def_flags;
++					break;
++				}
++				if (p[0] == 'n') {
++					sym->def[def].tri = no;
++					sym->flags |= def_flags;
++					break;
++				}
++				conf_warning("symbol value '%s' invalid for %s", p, sym->name);
++				break;
++			case S_OTHER:
++				if (*p != '"') {
++					for (p2 = p; *p2 && !isspace(*p2); p2++)
++						;
++					sym->type = S_STRING;
++					goto done;
++				}
++			case S_STRING:
++				if (*p++ != '"')
++					break;
++				for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
++					if (*p2 == '"') {
++						*p2 = 0;
++						break;
++					}
++					memmove(p2, p2 + 1, strlen(p2));
++				}
++				if (!p2) {
++					conf_warning("invalid string found");
++					continue;
++				}
++			case S_INT:
++			case S_HEX:
++			done:
++				if (sym_string_valid(sym, p)) {
++					sym->def[def].val = strdup(p);
++					sym->flags |= def_flags;
++				} else {
++					conf_warning("symbol value '%s' invalid for %s", p, sym->name);
++					continue;
++				}
++				break;
++			default:
++				;
++			}
++			break;
++		case '\r':
++		case '\n':
++			break;
++		default:
++			conf_warning("unexpected data");
++			continue;
++		}
++		if (sym && sym_is_choice_value(sym)) {
++			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
++			switch (sym->def[def].tri) {
++			case no:
++				break;
++			case mod:
++				if (cs->def[def].tri == yes) {
++					conf_warning("%s creates inconsistent choice state", sym->name);
++					cs->flags &= ~def_flags;
++				}
++				break;
++			case yes:
++				if (cs->def[def].tri != no) {
++					conf_warning("%s creates inconsistent choice state", sym->name);
++					cs->flags &= ~def_flags;
++				} else
++					cs->def[def].val = sym;
++				break;
++			}
++			cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
++		}
++	}
++	fclose(in);
++
++	if (modules_sym)
++		sym_calc_value(modules_sym);
++	return 0;
++}
++
++int conf_read(const char *name)
++{
++	struct symbol *sym;
++	struct property *prop;
++	struct expr *e;
++	int i, flags;
++
++	sym_change_count = 0;
++
++	if (conf_read_simple(name, S_DEF_USER))
++		return 1;
++
++	for_all_symbols(i, sym) {
++		sym_calc_value(sym);
++		if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
++			goto sym_ok;
++		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
++			/* check that calculated value agrees with saved value */
++			switch (sym->type) {
++			case S_BOOLEAN:
++			case S_TRISTATE:
++				if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
++					break;
++				if (!sym_is_choice(sym))
++					goto sym_ok;
++			default:
++				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
++					goto sym_ok;
++				break;
++			}
++		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
++			/* no previous value and not saved */
++			goto sym_ok;
++		conf_unsaved++;
++		/* maybe print value in verbose mode... */
++	sym_ok:
++		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
++			if (sym->visible == no)
++				sym->flags &= ~SYMBOL_DEF_USER;
++			switch (sym->type) {
++			case S_STRING:
++			case S_INT:
++			case S_HEX:
++				if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
++					sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
++			default:
++				break;
++			}
++		}
++		if (!sym_is_choice(sym))
++			continue;
++		prop = sym_get_choice_prop(sym);
++		flags = sym->flags;
++		for (e = prop->expr; e; e = e->left.expr)
++			if (e->right.sym->visible != no)
++				flags &= e->right.sym->flags;
++		sym->flags &= flags | ~SYMBOL_DEF_USER;
++	}
++
++	sym_change_count += conf_warnings || conf_unsaved;
++
++	return 0;
++}
++
++struct menu *next_menu(struct menu *menu)
++{
++	if (menu->list) return menu->list;
++	do {
++		if (menu->next) {
++			menu = menu->next;
++			break;
++		}
++	} while ((menu = menu->parent));
++
++	return menu;
++}
++
++#define SYMBOL_FORCEWRITE (1<<31)
++
++int conf_write(const char *name)
++{
++	FILE *out;
++	struct symbol *sym;
++	struct menu *menu;
++	const char *basename;
++	char dirname[128], tmpname[128], newname[128];
++	int type, l, writetype;
++	const char *str;
++	time_t now;
++	int use_timestamp = 1;
++	char *env;
++
++	dirname[0] = 0;
++	if (name && name[0]) {
++		struct stat st;
++		char *slash;
++
++		if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
++			strcpy(dirname, name);
++			strcat(dirname, "/");
++			basename = conf_get_configname();
++		} else if ((slash = strrchr(name, '/'))) {
++			int size = slash - name + 1;
++			memcpy(dirname, name, size);
++			dirname[size] = 0;
++			if (slash[1])
++				basename = slash + 1;
++			else
++				basename = conf_get_configname();
++		} else
++			basename = name;
++	} else
++		basename = conf_get_configname();
++
++	sprintf(newname, "%s%s", dirname, basename);
++	env = getenv("KCONFIG_OVERWRITECONFIG");
++	if (!env || !*env) {
++		sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
++		out = fopen(tmpname, "w");
++	} else {
++		*tmpname = 0;
++		out = fopen(newname, "w");
++	}
++	if (!out)
++		return 1;
++
++	sym = sym_lookup("KCONFIG_VERSION", 0);
++	sym_calc_value(sym);
++	time(&now);
++	env = getenv("KCONFIG_NOTIMESTAMP");
++	if (env && *env)
++		use_timestamp = 0;
++
++	fprintf(out, _("#\n"
++		       "# Automatically generated make config: don't edit\n"
++		       "# "PROJECT_NAME" version: %s\n"
++		       "%s%s"
++		       "#\n"),
++		     sym_get_string_value(sym),
++		     use_timestamp ? "# " : "",
++		     use_timestamp ? ctime(&now) : "");
++
++	if (!sym_change_count)
++		sym_clear_all_valid();
++
++	// Write out all symbols (even in closed sub-menus).
++	if (0) {
++		for (menu = rootmenu.list; menu; menu = next_menu(menu))
++			if (menu->sym) menu->sym->flags |= SYMBOL_FORCEWRITE;
++		writetype = SYMBOL_FORCEWRITE;
++
++	// Don't write  out symbols in closed menus.
++
++	} else writetype = SYMBOL_WRITE;
++
++
++	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);
++		} else if (!(sym->flags & SYMBOL_CHOICE)) {
++			sym_calc_value(sym);
++			if (!(sym->flags & writetype))
++				goto next;
++			sym->flags &= ~writetype;
++			type = sym->type;
++			if (type == S_TRISTATE) {
++				sym_calc_value(modules_sym);
++				if (modules_sym->curr.tri == no)
++					type = S_BOOLEAN;
++			}
++			switch (type) {
++			case S_BOOLEAN:
++			case S_TRISTATE:
++				switch (sym_get_tristate_value(sym)) {
++				case no:
++					fprintf(out, "# "CONFIG_PREFIX"%s is not set\n", sym->name);
++					break;
++				case mod:
++					fprintf(out, CONFIG_PREFIX"%s=m\n", sym->name);
++					break;
++				case yes:
++					fprintf(out, CONFIG_PREFIX"%s=y\n", sym->name);
++					break;
++				}
++				break;
++			case S_STRING:
++				str = sym_get_string_value(sym);
++				fprintf(out, CONFIG_PREFIX"%s=\"", sym->name);
++				while (1) {
++					l = strcspn(str, "\"\\");
++					if (l) {
++						fwrite(str, l, 1, out);
++						str += l;
++					}
++					if (!*str)
++						break;
++					fprintf(out, "\\%c", *str++);
++				}
++				fputs("\"\n", out);
++				break;
++			case S_HEX:
++				str = sym_get_string_value(sym);
++				if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
++					fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, *str ? str : "0");
++					break;
++				}
++			case S_INT:
++				str = sym_get_string_value(sym);
++				fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, *str ? str : "0");
++				break;
++			}
++		}
++
++	next:
++		if (writetype == SYMBOL_WRITE) {
++			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;
++				}
++			}
++		} else
++			menu = next_menu(menu);
++	}
++	fclose(out);
++
++	if (*tmpname) {
++		strcat(dirname, basename);
++		strcat(dirname, ".old");
++		rename(newname, dirname);
++		if (rename(tmpname, newname))
++			return 1;
++	}
++
++	printf(_("#\n"
++		 "# configuration written to %s\n"
++		 "#\n"), newname);
++
++	sym_change_count = 0;
++
++	return 0;
++}
++
++int conf_split_config(void)
++{
++	char *name, path[128];
++	char *s, *d, c;
++	struct symbol *sym;
++	struct stat sb;
++	int res, i, fd;
++
++	name = getenv("KCONFIG_AUTOCONFIG");
++	if (!name)
++		name = "include/config/auto.conf";
++	conf_read_simple(name, S_DEF_AUTO);
++
++	if (chdir("include/config"))
++		return 1;
++
++	res = 0;
++	for_all_symbols(i, sym) {
++		sym_calc_value(sym);
++		if ((sym->flags & SYMBOL_AUTO) || !sym->name)
++			continue;
++		if (sym->flags & SYMBOL_WRITE) {
++			if (sym->flags & SYMBOL_DEF_AUTO) {
++				/*
++				 * symbol has old and new value,
++				 * so compare them...
++				 */
++				switch (sym->type) {
++				case S_BOOLEAN:
++				case S_TRISTATE:
++					if (sym_get_tristate_value(sym) ==
++					    sym->def[S_DEF_AUTO].tri)
++						continue;
++					break;
++				case S_STRING:
++				case S_HEX:
++				case S_INT:
++					if (!strcmp(sym_get_string_value(sym),
++						    sym->def[S_DEF_AUTO].val))
++						continue;
++					break;
++				default:
++					break;
++				}
++			} else {
++				/*
++				 * If there is no old value, only 'no' (unset)
++				 * is allowed as new value.
++				 */
++				switch (sym->type) {
++				case S_BOOLEAN:
++				case S_TRISTATE:
++					if (sym_get_tristate_value(sym) == no)
++						continue;
++					break;
++				default:
++					break;
++				}
++			}
++		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
++			/* There is neither an old nor a new value. */
++			continue;
++		/* else
++		 *	There is an old value, but no new value ('no' (unset)
++		 *	isn't saved in auto.conf, so the old value is always
++		 *	different from 'no').
++		 */
++
++		/* Replace all '_' and append ".h" */
++		s = sym->name;
++		d = path;
++		while ((c = *s++)) {
++			c = tolower(c);
++			*d++ = (c == '_') ? '/' : c;
++		}
++		strcpy(d, ".h");
++
++		/* Assume directory path already exists. */
++		fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
++		if (fd == -1) {
++			if (errno != ENOENT) {
++				res = 1;
++				break;
++			}
++			/*
++			 * Create directory components,
++			 * unless they exist already.
++			 */
++			d = path;
++			while ((d = strchr(d, '/'))) {
++				*d = 0;
++				if (stat(path, &sb) && mkdir(path, 0755)) {
++					res = 1;
++					goto out;
++				}
++				*d++ = '/';
++			}
++			/* Try it again. */
++			fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
++			if (fd == -1) {
++				res = 1;
++				break;
++			}
++		}
++		close(fd);
++	}
++out:
++	if (chdir("../.."))
++		return 1;
++
++	return res;
++}
++
++int conf_write_autoconf(void)
++{
++	struct symbol *sym;
++	const char *str;
++	char *name;
++	FILE *out, *out_h;
++	time_t now;
++	int i, l;
++
++	sym_clear_all_valid();
++
++	file_write_dep("include/config/auto.conf.cmd");
++
++	if (conf_split_config())
++		return 1;
++
++	out = fopen(".tmpconfig", "w");
++	if (!out)
++		return 1;
++
++	out_h = fopen(".tmpconfig.h", "w");
++	if (!out_h) {
++		fclose(out);
++		return 1;
++	}
++
++	sym = sym_lookup("KCONFIG_VERSION", 0);
++	sym_calc_value(sym);
++	time(&now);
++	fprintf(out, "#\n"
++		     "# Automatically generated make config: don't edit\n"
++		     "# "PROJECT_NAME" version: %s\n"
++		     "# %s"
++		     "#\n",
++		     sym_get_string_value(sym), ctime(&now));
++	fprintf(out_h, "/*\n"
++		       " * Automatically generated C config: don't edit\n"
++		       " * "PROJECT_NAME" version: %s\n"
++		       " * %s"
++		       " */\n"
++		       // "#define AUTOCONF_INCLUDED\n"
++		       , sym_get_string_value(sym), ctime(&now));
++
++	for_all_symbols(i, sym) {
++		sym_calc_value(sym);
++		if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
++			continue;
++		switch (sym->type) {
++		case S_BOOLEAN:
++		case S_TRISTATE:
++			switch (sym_get_tristate_value(sym)) {
++			case no:
++				break;
++			case mod:
++				fprintf(out, CONFIG_PREFIX"%s=m\n", sym->name);
++				fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
++				break;
++			case yes:
++				fprintf(out, CONFIG_PREFIX"%s=y\n", sym->name);
++				fprintf(out_h, "#define "CONFIG_PREFIX"%s 1\n", sym->name);
++				break;
++			}
++			break;
++		case S_STRING:
++			str = sym_get_string_value(sym);
++			fprintf(out, CONFIG_PREFIX"%s=\"", sym->name);
++			fprintf(out_h, "#define "CONFIG_PREFIX"%s \"", sym->name);
++			while (1) {
++				l = strcspn(str, "\"\\");
++				if (l) {
++					fwrite(str, l, 1, out);
++					fwrite(str, l, 1, out_h);
++					str += l;
++				}
++				if (!*str)
++					break;
++				fprintf(out, "\\%c", *str);
++				fprintf(out_h, "\\%c", *str);
++				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_PREFIX"%s=%s\n", sym->name, str);
++				fprintf(out_h, "#define "CONFIG_PREFIX"%s 0x%s\n", sym->name, str);
++				break;
++			}
++		case S_INT:
++			str = sym_get_string_value(sym);
++			fprintf(out, CONFIG_PREFIX"%s=%s\n", sym->name, str);
++			fprintf(out_h, "#define "CONFIG_PREFIX"%s %s\n", sym->name, str);
++			break;
++		default:
++			break;
++		}
++	}
++	fclose(out);
++	fclose(out_h);
++
++	name = getenv("KCONFIG_AUTOHEADER");
++	if (!name)
++		name = "include/linux/autoconf.h";
++	if (rename(".tmpconfig.h", name))
++		return 1;
++	name = getenv("KCONFIG_AUTOCONFIG");
++	if (!name)
++		name = "include/config/auto.conf";
++	/*
++	 * This must be the last step, kbuild has a dependency on auto.conf
++	 * and this marks the successful completion of the previous steps.
++	 */
++	if (rename(".tmpconfig", name))
++		return 1;
++
++	return 0;
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/expr.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,1100 @@
++/*
++ * 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"
++
++#define DEBUG_EXPR	0
++
++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_alloc_or(struct expr *e1, struct expr *e2)
++{
++	if (!e1)
++		return e2;
++	return e2 ? expr_alloc_two(E_OR, 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 == &symbol_yes || e1->left.sym == &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)
++		return;
++	switch (e1->type) {
++	case E_OR:
++	case E_AND:
++		__expr_eliminate_eq(e1->type, ep1, ep2);
++	default:
++		;
++	}
++	if (e1->type != e2->type) switch (e2->type) {
++	case E_OR:
++	case E_AND:
++		__expr_eliminate_eq(e2->type, ep1, ep2);
++	default:
++		;
++	}
++	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_RANGE:
++	case E_NONE:
++		/* panic */;
++	}
++
++	if (DEBUG_EXPR) {
++		expr_fprint(e1, stdout);
++		printf(" = ");
++		expr_fprint(e2, stdout);
++		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);
++	}
++
++	if (DEBUG_EXPR) {
++		printf("optimize (");
++		expr_fprint(e1, stdout);
++		printf(") || (");
++		expr_fprint(e2, stdout);
++		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 ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
++	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
++		// (a) && (a!='m') -> (a='y')
++		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
++
++	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;
++	}
++
++	if (DEBUG_EXPR) {
++		printf("optimize (");
++		expr_fprint(e1, stdout);
++		printf(") && (");
++		expr_fprint(e2, stdout);
++		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_RANGE:
++	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 e->left.sym->curr.tri;
++	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 *, struct symbol *, const char *), void *data, int prevtoken)
++{
++	if (!e) {
++		fn(data, NULL, "y");
++		return;
++	}
++
++	if (expr_compare_type(prevtoken, e->type) > 0)
++		fn(data, NULL, "(");
++	switch (e->type) {
++	case E_SYMBOL:
++		if (e->left.sym->name)
++			fn(data, e->left.sym, e->left.sym->name);
++		else
++			fn(data, NULL, "<choice>");
++		break;
++	case E_NOT:
++		fn(data, NULL, "!");
++		expr_print(e->left.expr, fn, data, E_NOT);
++		break;
++	case E_EQUAL:
++		fn(data, e->left.sym, e->left.sym->name);
++		fn(data, NULL, "=");
++		fn(data, e->right.sym, e->right.sym->name);
++		break;
++	case E_UNEQUAL:
++		fn(data, e->left.sym, e->left.sym->name);
++		fn(data, NULL, "!=");
++		fn(data, e->right.sym, e->right.sym->name);
++		break;
++	case E_OR:
++		expr_print(e->left.expr, fn, data, E_OR);
++		fn(data, NULL, " || ");
++		expr_print(e->right.expr, fn, data, E_OR);
++		break;
++	case E_AND:
++		expr_print(e->left.expr, fn, data, E_AND);
++		fn(data, NULL, " && ");
++		expr_print(e->right.expr, fn, data, E_AND);
++		break;
++	case E_CHOICE:
++		fn(data, e->right.sym, e->right.sym->name);
++		if (e->left.expr) {
++			fn(data, NULL, " ^ ");
++			expr_print(e->left.expr, fn, data, E_CHOICE);
++		}
++		break;
++	case E_RANGE:
++		fn(data, NULL, "[");
++		fn(data, e->left.sym, e->left.sym->name);
++		fn(data, NULL, " ");
++		fn(data, e->right.sym, e->right.sym->name);
++		fn(data, NULL, "]");
++		break;
++	default:
++	  {
++		char buf[32];
++		sprintf(buf, "<unknown type %d>", e->type);
++		fn(data, NULL, buf);
++		break;
++	  }
++	}
++	if (expr_compare_type(prevtoken, e->type) > 0)
++		fn(data, NULL, ")");
++}
++
++static void expr_print_file_helper(void *data, struct symbol *sym, 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);
++}
++
++static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
++{
++	str_append((struct gstr*)data, str);
++}
++
++void expr_gstr_print(struct expr *e, struct gstr *gs)
++{
++	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/expr.h	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,202 @@
++/*
++ * 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;
++	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, E_RANGE
++};
++
++union expr_data {
++	struct expr *expr;
++	struct symbol *sym;
++};
++
++struct expr {
++	enum expr_type type;
++	union expr_data left, right;
++};
++
++#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;
++};
++
++struct symbol_value {
++	void *val;
++	tristate tri;
++};
++
++enum symbol_type {
++	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
++};
++
++enum {
++	S_DEF_USER,		/* main user value */
++	S_DEF_AUTO,
++};
++
++struct symbol {
++	struct symbol *next;
++	char *name;
++	char *help;
++	enum symbol_type type;
++	struct symbol_value curr;
++	struct symbol_value def[4];
++	tristate visible;
++	int flags;
++	struct property *prop;
++	struct expr *dep, *dep2;
++	struct expr_value rev_dep;
++};
++
++#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)
++
++#define SYMBOL_CONST		0x0001
++#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_AUTO		0x1000
++#define SYMBOL_CHECKED		0x2000
++#define SYMBOL_WARNED		0x8000
++#define SYMBOL_DEF		0x10000
++#define SYMBOL_DEF_USER		0x10000
++#define SYMBOL_DEF_AUTO		0x20000
++#define SYMBOL_DEF3		0x40000
++#define SYMBOL_DEF4		0x80000
++
++#define SYMBOL_MAXLENGTH	256
++#define SYMBOL_HASHSIZE		257
++#define SYMBOL_HASHMASK		0xff
++
++enum prop_type {
++	P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
++};
++
++struct property {
++	struct property *next;
++	struct symbol *sym;
++	enum prop_type type;
++	const char *text;
++	struct expr_value visible;
++	struct expr *expr;
++	struct menu *menu;
++	struct file *file;
++	int lineno;
++};
++
++#define for_all_properties(sym, st, tok) \
++	for (st = sym->prop; st; st = st->next) \
++		if (st->type == (tok))
++#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)
++#define for_all_prompts(sym, st) \
++	for (st = sym->prop; st; st = st->next) \
++		if (st->text)
++
++struct menu {
++	struct menu *next;
++	struct menu *parent;
++	struct menu *list;
++	struct symbol *sym;
++	struct property *prompt;
++	struct expr *dep;
++	unsigned int flags;
++	//char *help;
++	struct file *file;
++	int lineno;
++	void *data;
++};
++
++#define MENU_CHANGED		0x0001
++#define MENU_ROOT		0x0002
++
++#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 struct symbol *sym_defconfig_list;
++extern int cdebug;
++struct expr *expr_alloc_symbol(struct symbol *sym);
++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);
++struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
++struct expr *expr_alloc_or(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);
++struct gstr; /* forward */
++void expr_gstr_print(struct expr *e, struct gstr *gs);
++
++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
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* EXPR_H */
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/Makefile	2007-03-16 14:37:17.000000000 -0400
+@@ -0,0 +1,69 @@
++# ===========================================================================
++# Kernel configuration targets
++# These targets are used from top-level makefile
++
++KCONFIG_TOP = $(top_srcdir)/extra/Configs/Config.in
++KCONFIG_CFLAGS = '-DCONFIG_PREFIX=""' '-DPROJECT_NAME="uClibc"' \
++		'-Dconf_defname = "extra/Configs/defconfigs/$$ARCH"'
++obj = $(top_builddir)/kconfig
++PHONY += clean help oldconfig menuconfig config silentoldconfig \
++	randconfig allyesconfig allnoconfig allmodconfig defconfig
++
++menuconfig: $(obj)/mconf
++	$< $(KCONFIG_TOP)
++
++config: $(obj)/conf
++	$< $(KCONFIG_TOP)
++
++oldconfig: $(obj)/conf
++	$< -o $(KCONFIG_TOP)
++
++silentoldconfig: $(obj)/conf
++	$< -s $(KCONFIG_TOP)
++
++randconfig: $(obj)/conf
++	$< -r $(KCONFIG_TOP)
++
++allyesconfig: $(obj)/conf
++	$< -y $(KCONFIG_TOP)
++
++allnoconfig: $(obj)/conf
++	$< -n $(KCONFIG_TOP)
++
++defconfig: $(obj)/conf
++	$< -d $(KCONFIG_TOP)
++
++# Help text used by make help
++help::
++	@echo  '  config	  - Update current config utilising a line-oriented program'
++	@echo  '  menuconfig	  - Update current config utilising a menu based program'
++	@echo  '  oldconfig	  - Update current config utilising a provided .config as base'
++	@echo  '  silentoldconfig - Same as oldconfig, but quietly'
++	@echo  '  randconfig	  - New config with random answer to all options'
++	@echo  '  defconfig	  - New config with default answer to all options'
++	@echo  '  allyesconfig	  - New config where all options are accepted with yes'
++	@echo  '  allnoconfig	  - New config where all options are answered with no'
++
++# Cheesy build
++
++SHIPPED = $(top_srcdir)/kconfig/zconf.tab.c $(top_srcdir)/kconfig/lex.zconf.c \
++	$(top_srcdir)/kconfig/zconf.hash.c
++
++%.c: %.c_shipped
++	@ln -s $(notdir $<) $@
++
++gen_config.h: .config
++
++KCONFIG_CFLAGS += $(top_srcdir)/kconfig/zconf.tab.c -DKBUILD_NO_NLS=1
++
++kconfig/mconf: $(SHIPPED)
++	$(HOSTCC) -o $@ $(top_srcdir)/kconfig/mconf.c \
++		$(wildcard $(top_srcdir)/kconfig/lxdialog/*.c) \
++		-lcurses -DCURSES_LOC="<ncurses.h>" $(KCONFIG_CFLAGS)
++
++kconfig/conf: $(SHIPPED)
++	$(HOSTCC) -o $@ $(top_srcdir)/kconfig/conf.c $(KCONFIG_CFLAGS)
++
++clean::
++	rm -f $(wildcard $(top_srcdir)/kconfig/*zconf*.c) $(SHIPPED) \
++		$(top_srcdir)/kconfig/conf $(top_srcdir)/kconfig/mconf
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lex.zconf.c_shipped	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,2350 @@
++
++#line 3 "scripts/kconfig/lex.zconf.c"
++
++#define  YY_INT_ALIGNED short int
++
++/* A lexical scanner generated by flex */
++
++#define FLEX_SCANNER
++#define YY_FLEX_MAJOR_VERSION 2
++#define YY_FLEX_MINOR_VERSION 5
++#define YY_FLEX_SUBMINOR_VERSION 33
++#if YY_FLEX_SUBMINOR_VERSION > 0
++#define FLEX_BETA
++#endif
++
++/* First, we deal with  platform-specific or compiler-specific issues. */
++
++/* begin standard C headers. */
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <stdlib.h>
++
++/* end standard C headers. */
++
++/* flex integer type definitions */
++
++#ifndef FLEXINT_H
++#define FLEXINT_H
++
++/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
++
++#if __STDC_VERSION__ >= 199901L
++
++/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
++ * if you want the limit (max/min) macros for int types.
++ */
++#ifndef __STDC_LIMIT_MACROS
++#define __STDC_LIMIT_MACROS 1
++#endif
++
++#include <inttypes.h>
++typedef int8_t flex_int8_t;
++typedef uint8_t flex_uint8_t;
++typedef int16_t flex_int16_t;
++typedef uint16_t flex_uint16_t;
++typedef int32_t flex_int32_t;
++typedef uint32_t flex_uint32_t;
++#else
++typedef signed char flex_int8_t;
++typedef short int flex_int16_t;
++typedef int flex_int32_t;
++typedef unsigned char flex_uint8_t; 
++typedef unsigned short int flex_uint16_t;
++typedef unsigned int flex_uint32_t;
++#endif /* ! C99 */
++
++/* Limits of integral types. */
++#ifndef INT8_MIN
++#define INT8_MIN               (-128)
++#endif
++#ifndef INT16_MIN
++#define INT16_MIN              (-32767-1)
++#endif
++#ifndef INT32_MIN
++#define INT32_MIN              (-2147483647-1)
++#endif
++#ifndef INT8_MAX
++#define INT8_MAX               (127)
++#endif
++#ifndef INT16_MAX
++#define INT16_MAX              (32767)
++#endif
++#ifndef INT32_MAX
++#define INT32_MAX              (2147483647)
++#endif
++#ifndef UINT8_MAX
++#define UINT8_MAX              (255U)
++#endif
++#ifndef UINT16_MAX
++#define UINT16_MAX             (65535U)
++#endif
++#ifndef UINT32_MAX
++#define UINT32_MAX             (4294967295U)
++#endif
++
++#endif /* ! FLEXINT_H */
++
++#ifdef __cplusplus
++
++/* The "const" storage-class-modifier is valid. */
++#define YY_USE_CONST
++
++#else	/* ! __cplusplus */
++
++#if __STDC__
++
++#define YY_USE_CONST
++
++#endif	/* __STDC__ */
++#endif	/* ! __cplusplus */
++
++#ifdef YY_USE_CONST
++#define yyconst const
++#else
++#define yyconst
++#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 zconfrestart(zconfin  )
++
++#define YY_END_OF_BUFFER_CHAR 0
++
++/* Size of default input buffer. */
++#ifndef YY_BUF_SIZE
++#define YY_BUF_SIZE 16384
++#endif
++
++/* The state buf must be large enough to hold one state per character in the main buffer.
++ */
++#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
++
++#ifndef YY_TYPEDEF_YY_BUFFER_STATE
++#define YY_TYPEDEF_YY_BUFFER_STATE
++typedef struct yy_buffer_state *YY_BUFFER_STATE;
++#endif
++
++extern int zconfleng;
++
++extern FILE *zconfin, *zconfout;
++
++#define EOB_ACT_CONTINUE_SCAN 0
++#define EOB_ACT_END_OF_FILE 1
++#define EOB_ACT_LAST_MATCH 2
++
++    #define YY_LESS_LINENO(n)
++    
++/* Return all but the first "n" matched characters back to the input stream. */
++#define yyless(n) \
++	do \
++		{ \
++		/* Undo effects of setting up zconftext. */ \
++        int yyless_macro_arg = (n); \
++        YY_LESS_LINENO(yyless_macro_arg);\
++		*yy_cp = (yy_hold_char); \
++		YY_RESTORE_YY_MORE_OFFSET \
++		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
++		YY_DO_BEFORE_ACTION; /* set up zconftext 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).
++ */
++
++#ifndef YY_TYPEDEF_YY_SIZE_T
++#define YY_TYPEDEF_YY_SIZE_T
++typedef unsigned int yy_size_t;
++#endif
++
++#ifndef YY_STRUCT_YY_BUFFER_STATE
++#define YY_STRUCT_YY_BUFFER_STATE
++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;
++
++    int yy_bs_lineno; /**< The line count. */
++    int yy_bs_column; /**< The column count. */
++    
++	/* 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 zconfrestart()), so that the user can continue scanning by
++	 * just pointing zconfin at a new input file.
++	 */
++#define YY_BUFFER_EOF_PENDING 2
++
++	};
++#endif /* !YY_STRUCT_YY_BUFFER_STATE */
++
++/* Stack of input buffers. */
++static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
++static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
++static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
++
++/* 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".
++ *
++ * Returns the top of the stack, or NULL.
++ */
++#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
++                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
++                          : NULL)
++
++/* Same as previous macro, but useful when we know that the buffer stack is not
++ * NULL or when we need an lvalue. For internal use only.
++ */
++#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
++
++/* yy_hold_char holds the character lost when zconftext is formed. */
++static char yy_hold_char;
++static int yy_n_chars;		/* number of characters read into yy_ch_buf */
++int zconfleng;
++
++/* Points to current character in buffer. */
++static char *yy_c_buf_p = (char *) 0;
++static int yy_init = 0;		/* whether we need to initialize */
++static int yy_start = 0;	/* start state number */
++
++/* Flag which is used to allow zconfwrap()'s to do buffer switches
++ * instead of setting up a fresh zconfin.  A bit of a hack ...
++ */
++static int yy_did_buffer_switch_on_eof;
++
++void zconfrestart (FILE *input_file  );
++void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
++YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size  );
++void zconf_delete_buffer (YY_BUFFER_STATE b  );
++void zconf_flush_buffer (YY_BUFFER_STATE b  );
++void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer  );
++void zconfpop_buffer_state (void );
++
++static void zconfensure_buffer_stack (void );
++static void zconf_load_buffer_state (void );
++static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file  );
++
++#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
++
++YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size  );
++YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str  );
++YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len  );
++
++void *zconfalloc (yy_size_t  );
++void *zconfrealloc (void *,yy_size_t  );
++void zconffree (void *  );
++
++#define yy_new_buffer zconf_create_buffer
++
++#define yy_set_interactive(is_interactive) \
++	{ \
++	if ( ! YY_CURRENT_BUFFER ){ \
++        zconfensure_buffer_stack (); \
++		YY_CURRENT_BUFFER_LVALUE =    \
++            zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
++	} \
++	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
++	}
++
++#define yy_set_bol(at_bol) \
++	{ \
++	if ( ! YY_CURRENT_BUFFER ){\
++        zconfensure_buffer_stack (); \
++		YY_CURRENT_BUFFER_LVALUE =    \
++            zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
++	} \
++	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
++	}
++
++#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
++
++/* Begin user sect3 */
++
++#define zconfwrap() 1
++#define YY_SKIP_YYWRAP
++
++typedef unsigned char YY_CHAR;
++
++FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
++
++typedef int yy_state_type;
++
++extern int zconflineno;
++
++int zconflineno = 1;
++
++extern char *zconftext;
++#define yytext_ptr zconftext
++static yyconst flex_int16_t yy_nxt[][17] =
++    {
++    {
++        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
++    },
++
++    {
++       11,   12,   13,   14,   12,   12,   15,   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,   16
++    },
++
++    {
++       11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
++       16,   16,   16,   18,   16,   16,   16
++
++    },
++
++    {
++       11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
++       19,   19,   19,   19,   19,   19,   19
++    },
++
++    {
++       11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
++       19,   19,   19,   19,   19,   19,   19
++    },
++
++    {
++       11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
++       22,   22,   22,   22,   22,   25,   22
++    },
++
++    {
++       11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
++       22,   22,   22,   22,   22,   25,   22
++    },
++
++    {
++       11,   26,   26,   27,   28,   29,   30,   31,   29,   32,
++       33,   34,   35,   35,   36,   37,   38
++
++    },
++
++    {
++       11,   26,   26,   27,   28,   29,   30,   31,   29,   32,
++       33,   34,   35,   35,   36,   37,   38
++    },
++
++    {
++      -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
++    },
++
++    {
++       11,  -13,   39,   40,  -13,  -13,   41,  -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
++
++    },
++
++    {
++       11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
++       42,   42,   42,   42,   42,   42,   42
++    },
++
++    {
++       11,  -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
++    },
++
++    {
++       11,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
++      -18,  -18,  -18,   44,  -18,  -18,  -18
++    },
++
++    {
++       11,   45,   45,  -19,   45,   45,   45,   45,   45,   45,
++       45,   45,   45,   45,   45,   45,   45
++
++    },
++
++    {
++       11,  -20,   46,   47,  -20,  -20,  -20,  -20,  -20,  -20,
++      -20,  -20,  -20,  -20,  -20,  -20,  -20
++    },
++
++    {
++       11,   48,  -21,  -21,   48,   48,   48,   48,   48,   48,
++       48,   48,   48,   48,   48,   48,   48
++    },
++
++    {
++       11,   49,   49,   50,   49,  -22,   49,   49,  -22,   49,
++       49,   49,   49,   49,   49,  -22,   49
++    },
++
++    {
++       11,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
++      -23,  -23,  -23,  -23,  -23,  -23,  -23
++    },
++
++    {
++       11,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
++      -24,  -24,  -24,  -24,  -24,  -24,  -24
++
++    },
++
++    {
++       11,   51,   51,   52,   51,   51,   51,   51,   51,   51,
++       51,   51,   51,   51,   51,   51,   51
++    },
++
++    {
++       11,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
++      -26,  -26,  -26,  -26,  -26,  -26,  -26
++    },
++
++    {
++       11,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
++      -27,  -27,  -27,  -27,  -27,  -27,  -27
++    },
++
++    {
++       11,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,
++      -28,  -28,  -28,  -28,   53,  -28,  -28
++    },
++
++    {
++       11,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
++      -29,  -29,  -29,  -29,  -29,  -29,  -29
++
++    },
++
++    {
++       11,   54,   54,  -30,   54,   54,   54,   54,   54,   54,
++       54,   54,   54,   54,   54,   54,   54
++    },
++
++    {
++       11,  -31,  -31,  -31,  -31,  -31,  -31,   55,  -31,  -31,
++      -31,  -31,  -31,  -31,  -31,  -31,  -31
++    },
++
++    {
++       11,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,
++      -32,  -32,  -32,  -32,  -32,  -32,  -32
++    },
++
++    {
++       11,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
++      -33,  -33,  -33,  -33,  -33,  -33,  -33
++    },
++
++    {
++       11,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,
++      -34,   56,   57,   57,  -34,  -34,  -34
++
++    },
++
++    {
++       11,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
++      -35,   57,   57,   57,  -35,  -35,  -35
++    },
++
++    {
++       11,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
++      -36,  -36,  -36,  -36,  -36,  -36,  -36
++    },
++
++    {
++       11,  -37,  -37,   58,  -37,  -37,  -37,  -37,  -37,  -37,
++      -37,  -37,  -37,  -37,  -37,  -37,  -37
++    },
++
++    {
++       11,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
++      -38,  -38,  -38,  -38,  -38,  -38,   59
++    },
++
++    {
++       11,  -39,   39,   40,  -39,  -39,   41,  -39,  -39,  -39,
++      -39,  -39,  -39,  -39,  -39,  -39,  -39
++
++    },
++
++    {
++       11,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,
++      -40,  -40,  -40,  -40,  -40,  -40,  -40
++    },
++
++    {
++       11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
++       42,   42,   42,   42,   42,   42,   42
++    },
++
++    {
++       11,   42,   42,   43,   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
++    },
++
++    {
++       11,  -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,   45,   45,   45,   45,   45,   45
++    },
++
++    {
++       11,  -46,   46,   47,  -46,  -46,  -46,  -46,  -46,  -46,
++      -46,  -46,  -46,  -46,  -46,  -46,  -46
++    },
++
++    {
++       11,   48,  -47,  -47,   48,   48,   48,   48,   48,   48,
++       48,   48,   48,   48,   48,   48,   48
++    },
++
++    {
++       11,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
++      -48,  -48,  -48,  -48,  -48,  -48,  -48
++    },
++
++    {
++       11,   49,   49,   50,   49,  -49,   49,   49,  -49,   49,
++       49,   49,   49,   49,   49,  -49,   49
++
++    },
++
++    {
++       11,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
++      -50,  -50,  -50,  -50,  -50,  -50,  -50
++    },
++
++    {
++       11,  -51,  -51,   52,  -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
++    },
++
++    {
++       11,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
++      -53,  -53,  -53,  -53,  -53,  -53,  -53
++    },
++
++    {
++       11,   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
++    },
++
++    {
++       11,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,
++      -56,   60,   57,   57,  -56,  -56,  -56
++    },
++
++    {
++       11,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
++      -57,   57,   57,   57,  -57,  -57,  -57
++    },
++
++    {
++       11,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
++      -58,  -58,  -58,  -58,  -58,  -58,  -58
++    },
++
++    {
++       11,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,
++      -59,  -59,  -59,  -59,  -59,  -59,  -59
++
++    },
++
++    {
++       11,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
++      -60,   57,   57,   57,  -60,  -60,  -60
++    },
++
++    } ;
++
++static yy_state_type yy_get_previous_state (void );
++static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
++static int yy_get_next_buffer (void );
++static void yy_fatal_error (yyconst char msg[]  );
++
++/* Done after the current pattern has been matched and before the
++ * corresponding action - sets up zconftext.
++ */
++#define YY_DO_BEFORE_ACTION \
++	(yytext_ptr) = yy_bp; \
++	zconfleng = (size_t) (yy_cp - yy_bp); \
++	(yy_hold_char) = *yy_cp; \
++	*yy_cp = '\0'; \
++	(yy_c_buf_p) = yy_cp;
++
++#define YY_NUM_RULES 33
++#define YY_END_OF_BUFFER 34
++/* This struct is not used in this scanner,
++   but its presence is necessary. */
++struct yy_trans_info
++	{
++	flex_int32_t yy_verify;
++	flex_int32_t yy_nxt;
++	};
++static yyconst flex_int16_t yy_accept[61] =
++    {   0,
++        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
++       34,    5,    4,    2,    3,    7,    8,    6,   32,   29,
++       31,   24,   28,   27,   26,   22,   17,   13,   16,   20,
++       22,   11,   12,   19,   19,   14,   22,   22,    4,    2,
++        3,    3,    1,    6,   32,   29,   31,   30,   24,   23,
++       26,   25,   15,   20,    9,   19,   19,   21,   10,   18
++    } ;
++
++static yyconst flex_int32_t 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,   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,   16,    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
++    } ;
++
++extern int zconf_flex_debug;
++int zconf_flex_debug = 0;
++
++/* 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 *zconftext;
++
++/*
++ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
++ * Released under the terms of the GNU GPL v2.0.
++ */
++
++#include <limits.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#define LKC_DIRECT_LINK
++#include "lkc.h"
++
++#define START_STRSIZE	16
++
++static struct {
++	struct file *file;
++	int lineno;
++} current_pos;
++
++static char *text;
++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 void zconf_endfile(void);
++
++void new_string(void)
++{
++	text = malloc(START_STRSIZE);
++	text_asize = START_STRSIZE;
++	text_size = 0;
++	*text = 0;
++}
++
++void append_string(const char *str, int size)
++{
++	int new_size = text_size + size + 1;
++	if (new_size > text_asize) {
++		new_size += START_STRSIZE - 1;
++		new_size &= -START_STRSIZE;
++		text = realloc(text, new_size);
++		text_asize = new_size;
++	}
++	memcpy(text + text_size, str, size);
++	text_size += size;
++	text[text_size] = 0;
++}
++
++void alloc_string(const char *str, int size)
++{
++	text = malloc(size + 1);
++	memcpy(text, str, size);
++	text[size] = 0;
++}
++
++#define INITIAL 0
++#define COMMAND 1
++#define HELP 2
++#define STRING 3
++#define PARAM 4
++
++#ifndef YY_NO_UNISTD_H
++/* Special case for "unistd.h", since it is non-ANSI. We include it way
++ * down here because we want the user's section 1 to have been scanned first.
++ * The user has a chance to override it with an option.
++ */
++#include <unistd.h>
++#endif
++
++#ifndef YY_EXTRA_TYPE
++#define YY_EXTRA_TYPE void *
++#endif
++
++static int yy_init_globals (void );
++
++/* Macros after this point can all be overridden by user definitions in
++ * section 1.
++ */
++
++#ifndef YY_SKIP_YYWRAP
++#ifdef __cplusplus
++extern "C" int zconfwrap (void );
++#else
++extern int zconfwrap (void );
++#endif
++#endif
++
++    static void yyunput (int c,char *buf_ptr  );
++    
++#ifndef yytext_ptr
++static void yy_flex_strncpy (char *,yyconst char *,int );
++#endif
++
++#ifdef YY_NEED_STRLEN
++static int yy_flex_strlen (yyconst char * );
++#endif
++
++#ifndef YY_NO_INPUT
++
++#ifdef __cplusplus
++static int yyinput (void );
++#else
++static int input (void );
++#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( zconftext, zconfleng, 1, zconfout )
++#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(zconfin), (char *) buf, max_size )) < 0 ) \
++	{ \
++		if( errno != EINTR) \
++		{ \
++			YY_FATAL_ERROR( "input in flex scanner failed" ); \
++			break; \
++		} \
++		errno=0; \
++		clearerr(zconfin); \
++	}\
++\
++
++#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
++
++/* end tables serialization structures and prototypes */
++
++/* Default declaration of generated scanner - a define so the user can
++ * easily add parameters.
++ */
++#ifndef YY_DECL
++#define YY_DECL_IS_OURS 1
++
++extern int zconflex (void);
++
++#define YY_DECL int zconflex (void)
++#endif /* !YY_DECL */
++
++/* Code executed at the beginning of each rule, after zconftext and zconfleng
++ * 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
++
++/** The main scanner function which does all the work.
++ */
++YY_DECL
++{
++	register yy_state_type yy_current_state;
++	register char *yy_cp, *yy_bp;
++	register int yy_act;
++    
++	int str = 0;
++	int ts, i;
++
++	if ( !(yy_init) )
++		{
++		(yy_init) = 1;
++
++#ifdef YY_USER_INIT
++		YY_USER_INIT;
++#endif
++
++		if ( ! (yy_start) )
++			(yy_start) = 1;	/* first start state */
++
++		if ( ! zconfin )
++			zconfin = stdin;
++
++		if ( ! zconfout )
++			zconfout = stdout;
++
++		if ( ! YY_CURRENT_BUFFER ) {
++			zconfensure_buffer_stack ();
++			YY_CURRENT_BUFFER_LVALUE =
++				zconf_create_buffer(zconfin,YY_BUF_SIZE );
++		}
++
++		zconf_load_buffer_state( );
++		}
++
++	while ( 1 )		/* loops until end-of-file is reached */
++		{
++		yy_cp = (yy_c_buf_p);
++
++		/* Support of zconftext. */
++		*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:
++/* rule 1 can match eol */
++case 2:
++/* rule 2 can match eol */
++YY_RULE_SETUP
++{
++	current_file->lineno++;
++	return T_EOL;
++}
++	YY_BREAK
++case 3:
++YY_RULE_SETUP
++
++	YY_BREAK
++case 4:
++YY_RULE_SETUP
++{
++	BEGIN(COMMAND);
++}
++	YY_BREAK
++case 5:
++YY_RULE_SETUP
++{
++	unput(zconftext[0]);
++	BEGIN(COMMAND);
++}
++	YY_BREAK
++
++case 6:
++YY_RULE_SETUP
++{
++		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
++		BEGIN(PARAM);
++		current_pos.file = current_file;
++		current_pos.lineno = current_file->lineno;
++		if (id && id->flags & TF_COMMAND) {
++			zconflval.id = id;
++			return id->token;
++		}
++		alloc_string(zconftext, zconfleng);
++		zconflval.string = text;
++		return T_WORD;
++	}
++	YY_BREAK
++case 7:
++YY_RULE_SETUP
++
++	YY_BREAK
++case 8:
++/* rule 8 can match eol */
++YY_RULE_SETUP
++{
++		BEGIN(INITIAL);
++		current_file->lineno++;
++		return T_EOL;
++	}
++	YY_BREAK
++
++case 9:
++YY_RULE_SETUP
++return T_AND;
++	YY_BREAK
++case 10:
++YY_RULE_SETUP
++return T_OR;
++	YY_BREAK
++case 11:
++YY_RULE_SETUP
++return T_OPEN_PAREN;
++	YY_BREAK
++case 12:
++YY_RULE_SETUP
++return T_CLOSE_PAREN;
++	YY_BREAK
++case 13:
++YY_RULE_SETUP
++return T_NOT;
++	YY_BREAK
++case 14:
++YY_RULE_SETUP
++return T_EQUAL;
++	YY_BREAK
++case 15:
++YY_RULE_SETUP
++return T_UNEQUAL;
++	YY_BREAK
++case 16:
++YY_RULE_SETUP
++{
++		str = zconftext[0];
++		new_string();
++		BEGIN(STRING);
++	}
++	YY_BREAK
++case 17:
++/* rule 17 can match eol */
++YY_RULE_SETUP
++BEGIN(INITIAL); current_file->lineno++; return T_EOL;
++	YY_BREAK
++case 18:
++YY_RULE_SETUP
++/* ignore */
++	YY_BREAK
++case 19:
++YY_RULE_SETUP
++{
++		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
++		if (id && id->flags & TF_PARAM) {
++			zconflval.id = id;
++			return id->token;
++		}
++		alloc_string(zconftext, zconfleng);
++		zconflval.string = text;
++		return T_WORD;
++	}
++	YY_BREAK
++case 20:
++YY_RULE_SETUP
++/* comment */
++	YY_BREAK
++case 21:
++/* rule 21 can match eol */
++YY_RULE_SETUP
++current_file->lineno++;
++	YY_BREAK
++case 22:
++YY_RULE_SETUP
++
++	YY_BREAK
++case YY_STATE_EOF(PARAM):
++{
++		BEGIN(INITIAL);
++	}
++	YY_BREAK
++
++case 23:
++/* rule 23 can match eol */
++*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
++(yy_c_buf_p) = yy_cp -= 1;
++YY_DO_BEFORE_ACTION; /* set up zconftext again */
++YY_RULE_SETUP
++{
++		append_string(zconftext, zconfleng);
++		zconflval.string = text;
++		return T_WORD_QUOTE;
++	}
++	YY_BREAK
++case 24:
++YY_RULE_SETUP
++{
++		append_string(zconftext, zconfleng);
++	}
++	YY_BREAK
++case 25:
++/* rule 25 can match eol */
++*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
++(yy_c_buf_p) = yy_cp -= 1;
++YY_DO_BEFORE_ACTION; /* set up zconftext again */
++YY_RULE_SETUP
++{
++		append_string(zconftext + 1, zconfleng - 1);
++		zconflval.string = text;
++		return T_WORD_QUOTE;
++	}
++	YY_BREAK
++case 26:
++YY_RULE_SETUP
++{
++		append_string(zconftext + 1, zconfleng - 1);
++	}
++	YY_BREAK
++case 27:
++YY_RULE_SETUP
++{
++		if (str == zconftext[0]) {
++			BEGIN(PARAM);
++			zconflval.string = text;
++			return T_WORD_QUOTE;
++		} else
++			append_string(zconftext, 1);
++	}
++	YY_BREAK
++case 28:
++/* rule 28 can match eol */
++YY_RULE_SETUP
++{
++		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
++		current_file->lineno++;
++		BEGIN(INITIAL);
++		return T_EOL;
++	}
++	YY_BREAK
++case YY_STATE_EOF(STRING):
++{
++		BEGIN(INITIAL);
++	}
++	YY_BREAK
++
++case 29:
++YY_RULE_SETUP
++{
++		ts = 0;
++		for (i = 0; i < zconfleng; i++) {
++			if (zconftext[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 30:
++/* rule 30 can match eol */
++*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
++(yy_c_buf_p) = yy_cp -= 1;
++YY_DO_BEFORE_ACTION; /* set up zconftext again */
++YY_RULE_SETUP
++{
++		current_file->lineno++;
++		zconf_endhelp();
++		return T_HELPTEXT;
++	}
++	YY_BREAK
++case 31:
++/* rule 31 can match eol */
++YY_RULE_SETUP
++{
++		current_file->lineno++;
++		append_string("\n", 1);
++	}
++	YY_BREAK
++case 32:
++YY_RULE_SETUP
++{
++		append_string(zconftext, zconfleng);
++		if (!first_ts)
++			first_ts = last_ts;
++	}
++	YY_BREAK
++case YY_STATE_EOF(HELP):
++{
++		zconf_endhelp();
++		return T_HELPTEXT;
++	}
++	YY_BREAK
++
++case YY_STATE_EOF(INITIAL):
++case YY_STATE_EOF(COMMAND):
++{
++	if (current_file) {
++		zconf_endfile();
++		return T_EOL;
++	}
++	fclose(zconfin);
++	yyterminate();
++}
++	YY_BREAK
++case 33:
++YY_RULE_SETUP
++YY_FATAL_ERROR( "flex scanner jammed" );
++	YY_BREAK
++
++	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_LVALUE->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 zconfin at a new source and called
++			 * zconflex().  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_LVALUE->yy_n_chars;
++			YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
++			YY_CURRENT_BUFFER_LVALUE->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_LVALUE->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 ( zconfwrap( ) )
++					{
++					/* Note: because we've taken care in
++					 * yy_get_next_buffer() to have set up
++					 * zconftext, 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_LVALUE->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 zconflex */
++
++/* 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 (void)
++{
++    	register char *dest = YY_CURRENT_BUFFER_LVALUE->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_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
++		YY_FATAL_ERROR(
++		"fatal flex scanner internal error--end of buffer missed" );
++
++	if ( YY_CURRENT_BUFFER_LVALUE->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_LVALUE->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_LVALUE->yy_n_chars = (yy_n_chars) = 0;
++
++	else
++		{
++			int num_to_read =
++			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
++
++		while ( num_to_read <= 0 )
++			{ /* Not enough room in the buffer - grow it. */
++
++			/* 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. */
++					zconfrealloc((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_LVALUE->yy_buf_size -
++						number_to_move - 1;
++
++			}
++
++		if ( num_to_read > YY_READ_BUF_SIZE )
++			num_to_read = YY_READ_BUF_SIZE;
++
++		/* Read in more data. */
++		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
++			(yy_n_chars), num_to_read );
++
++		YY_CURRENT_BUFFER_LVALUE->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;
++			zconfrestart(zconfin  );
++			}
++
++		else
++			{
++			ret_val = EOB_ACT_LAST_MATCH;
++			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
++				YY_BUFFER_EOF_PENDING;
++			}
++		}
++
++	else
++		ret_val = EOB_ACT_CONTINUE_SCAN;
++
++	(yy_n_chars) += number_to_move;
++	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
++	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
++
++	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->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 (void)
++{
++	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 );
++ */
++    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
++{
++	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;
++}
++
++    static void yyunput (int c, register char * yy_bp )
++{
++	register char *yy_cp;
++    
++    yy_cp = (yy_c_buf_p);
++
++	/* undo effects of setting up zconftext */
++	*yy_cp = (yy_hold_char);
++
++	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->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_LVALUE->yy_ch_buf[
++					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
++		register char *source =
++				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
++
++		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
++			*--dest = *--source;
++
++		yy_cp += (int) (dest - source);
++		yy_bp += (int) (dest - source);
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
++			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
++
++		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->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;
++}
++
++#ifndef YY_NO_INPUT
++#ifdef __cplusplus
++    static int yyinput (void)
++#else
++    static int input  (void)
++#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_LVALUE->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. */
++					zconfrestart(zconfin );
++
++					/*FALLTHROUGH*/
++
++				case EOB_ACT_END_OF_FILE:
++					{
++					if ( zconfwrap( ) )
++						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 zconftext */
++	(yy_hold_char) = *++(yy_c_buf_p);
++
++	return c;
++}
++#endif	/* ifndef YY_NO_INPUT */
++
++/** Immediately switch to a different input stream.
++ * @param input_file A readable stream.
++ * 
++ * @note This function does not reset the start condition to @c INITIAL .
++ */
++    void zconfrestart  (FILE * input_file )
++{
++    
++	if ( ! YY_CURRENT_BUFFER ){
++        zconfensure_buffer_stack ();
++		YY_CURRENT_BUFFER_LVALUE =
++            zconf_create_buffer(zconfin,YY_BUF_SIZE );
++	}
++
++	zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
++	zconf_load_buffer_state( );
++}
++
++/** Switch to a different input buffer.
++ * @param new_buffer The new input buffer.
++ * 
++ */
++    void zconf_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
++{
++    
++	/* TODO. We should be able to replace this entire function body
++	 * with
++	 *		zconfpop_buffer_state();
++	 *		zconfpush_buffer_state(new_buffer);
++     */
++	zconfensure_buffer_stack ();
++	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_LVALUE->yy_buf_pos = (yy_c_buf_p);
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
++		}
++
++	YY_CURRENT_BUFFER_LVALUE = new_buffer;
++	zconf_load_buffer_state( );
++
++	/* We don't actually know whether we did this switch during
++	 * EOF (zconfwrap()) processing, but the only time this flag
++	 * is looked at is after zconfwrap() is called, so it's safe
++	 * to go ahead and always set it.
++	 */
++	(yy_did_buffer_switch_on_eof) = 1;
++}
++
++static void zconf_load_buffer_state  (void)
++{
++    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
++	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
++	zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
++	(yy_hold_char) = *(yy_c_buf_p);
++}
++
++/** Allocate and initialize an input buffer state.
++ * @param file A readable stream.
++ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
++ * 
++ * @return the allocated buffer state.
++ */
++    YY_BUFFER_STATE zconf_create_buffer  (FILE * file, int  size )
++{
++	YY_BUFFER_STATE b;
++    
++	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
++	if ( ! b )
++		YY_FATAL_ERROR( "out of dynamic memory in zconf_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 *) zconfalloc(b->yy_buf_size + 2  );
++	if ( ! b->yy_ch_buf )
++		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
++
++	b->yy_is_our_buffer = 1;
++
++	zconf_init_buffer(b,file );
++
++	return b;
++}
++
++/** Destroy the buffer.
++ * @param b a buffer created with zconf_create_buffer()
++ * 
++ */
++    void zconf_delete_buffer (YY_BUFFER_STATE  b )
++{
++    
++	if ( ! b )
++		return;
++
++	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
++		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
++
++	if ( b->yy_is_our_buffer )
++		zconffree((void *) b->yy_ch_buf  );
++
++	zconffree((void *) b  );
++}
++
++/* Initializes or reinitializes a buffer.
++ * This function is sometimes called more than once on the same buffer,
++ * such as during a zconfrestart() or at EOF.
++ */
++    static void zconf_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
++
++{
++	int oerrno = errno;
++    
++	zconf_flush_buffer(b );
++
++	b->yy_input_file = file;
++	b->yy_fill_buffer = 1;
++
++    /* If b is the current buffer, then zconf_init_buffer was _probably_
++     * called from zconfrestart() or through yy_get_next_buffer.
++     * In that case, we don't want to reset the lineno or column.
++     */
++    if (b != YY_CURRENT_BUFFER){
++        b->yy_bs_lineno = 1;
++        b->yy_bs_column = 0;
++    }
++
++        b->yy_is_interactive = 0;
++    
++	errno = oerrno;
++}
++
++/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
++ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
++ * 
++ */
++    void zconf_flush_buffer (YY_BUFFER_STATE  b )
++{
++    	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 )
++		zconf_load_buffer_state( );
++}
++
++/** Pushes the new state onto the stack. The new state becomes
++ *  the current state. This function will allocate the stack
++ *  if necessary.
++ *  @param new_buffer The new state.
++ *  
++ */
++void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
++{
++    	if (new_buffer == NULL)
++		return;
++
++	zconfensure_buffer_stack();
++
++	/* This block is copied from zconf_switch_to_buffer. */
++	if ( YY_CURRENT_BUFFER )
++		{
++		/* Flush out information for old buffer. */
++		*(yy_c_buf_p) = (yy_hold_char);
++		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
++		}
++
++	/* Only push if top exists. Otherwise, replace top. */
++	if (YY_CURRENT_BUFFER)
++		(yy_buffer_stack_top)++;
++	YY_CURRENT_BUFFER_LVALUE = new_buffer;
++
++	/* copied from zconf_switch_to_buffer. */
++	zconf_load_buffer_state( );
++	(yy_did_buffer_switch_on_eof) = 1;
++}
++
++/** Removes and deletes the top of the stack, if present.
++ *  The next element becomes the new top.
++ *  
++ */
++void zconfpop_buffer_state (void)
++{
++    	if (!YY_CURRENT_BUFFER)
++		return;
++
++	zconf_delete_buffer(YY_CURRENT_BUFFER );
++	YY_CURRENT_BUFFER_LVALUE = NULL;
++	if ((yy_buffer_stack_top) > 0)
++		--(yy_buffer_stack_top);
++
++	if (YY_CURRENT_BUFFER) {
++		zconf_load_buffer_state( );
++		(yy_did_buffer_switch_on_eof) = 1;
++	}
++}
++
++/* Allocates the stack if it does not exist.
++ *  Guarantees space for at least one push.
++ */
++static void zconfensure_buffer_stack (void)
++{
++	int num_to_alloc;
++    
++	if (!(yy_buffer_stack)) {
++
++		/* First allocation is just for 2 elements, since we don't know if this
++		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
++		 * immediate realloc on the next call.
++         */
++		num_to_alloc = 1;
++		(yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
++								(num_to_alloc * sizeof(struct yy_buffer_state*)
++								);
++		
++		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
++				
++		(yy_buffer_stack_max) = num_to_alloc;
++		(yy_buffer_stack_top) = 0;
++		return;
++	}
++
++	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
++
++		/* Increase the buffer to prepare for a possible push. */
++		int grow_size = 8 /* arbitrary grow size */;
++
++		num_to_alloc = (yy_buffer_stack_max) + grow_size;
++		(yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
++								((yy_buffer_stack),
++								num_to_alloc * sizeof(struct yy_buffer_state*)
++								);
++
++		/* zero only the new slots.*/
++		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
++		(yy_buffer_stack_max) = num_to_alloc;
++	}
++}
++
++/** Setup the input buffer state to scan directly from a user-specified character buffer.
++ * @param base the character buffer
++ * @param size the size in bytes of the character buffer
++ * 
++ * @return the newly allocated buffer state object. 
++ */
++YY_BUFFER_STATE zconf_scan_buffer  (char * base, yy_size_t  size )
++{
++	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) zconfalloc(sizeof( struct yy_buffer_state )  );
++	if ( ! b )
++		YY_FATAL_ERROR( "out of dynamic memory in zconf_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;
++
++	zconf_switch_to_buffer(b  );
++
++	return b;
++}
++
++/** Setup the input buffer state to scan a string. The next call to zconflex() will
++ * scan from a @e copy of @a str.
++ * @param yystr a NUL-terminated string to scan
++ * 
++ * @return the newly allocated buffer state object.
++ * @note If you want to scan bytes that may contain NUL values, then use
++ *       zconf_scan_bytes() instead.
++ */
++YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
++{
++    
++	return zconf_scan_bytes(yystr,strlen(yystr) );
++}
++
++/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
++ * scan from a @e copy of @a bytes.
++ * @param bytes the byte buffer to scan
++ * @param len the number of bytes in the buffer pointed to by @a bytes.
++ * 
++ * @return the newly allocated buffer state object.
++ */
++YY_BUFFER_STATE zconf_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
++{
++	YY_BUFFER_STATE b;
++	char *buf;
++	yy_size_t n;
++	int i;
++    
++	/* Get memory for full buffer, including space for trailing EOB's. */
++	n = _yybytes_len + 2;
++	buf = (char *) zconfalloc(n  );
++	if ( ! buf )
++		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
++
++	for ( i = 0; i < _yybytes_len; ++i )
++		buf[i] = yybytes[i];
++
++	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
++
++	b = zconf_scan_buffer(buf,n );
++	if ( ! b )
++		YY_FATAL_ERROR( "bad buffer in zconf_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;
++}
++
++#ifndef YY_EXIT_FAILURE
++#define YY_EXIT_FAILURE 2
++#endif
++
++static void yy_fatal_error (yyconst char* msg )
++{
++    	(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 zconftext. */ \
++        int yyless_macro_arg = (n); \
++        YY_LESS_LINENO(yyless_macro_arg);\
++		zconftext[zconfleng] = (yy_hold_char); \
++		(yy_c_buf_p) = zconftext + yyless_macro_arg; \
++		(yy_hold_char) = *(yy_c_buf_p); \
++		*(yy_c_buf_p) = '\0'; \
++		zconfleng = yyless_macro_arg; \
++		} \
++	while ( 0 )
++
++/* Accessor  methods (get/set functions) to struct members. */
++
++/** Get the current line number.
++ * 
++ */
++int zconfget_lineno  (void)
++{
++        
++    return zconflineno;
++}
++
++/** Get the input stream.
++ * 
++ */
++FILE *zconfget_in  (void)
++{
++        return zconfin;
++}
++
++/** Get the output stream.
++ * 
++ */
++FILE *zconfget_out  (void)
++{
++        return zconfout;
++}
++
++/** Get the length of the current token.
++ * 
++ */
++int zconfget_leng  (void)
++{
++        return zconfleng;
++}
++
++/** Get the current token.
++ * 
++ */
++
++char *zconfget_text  (void)
++{
++        return zconftext;
++}
++
++/** Set the current line number.
++ * @param line_number
++ * 
++ */
++void zconfset_lineno (int  line_number )
++{
++    
++    zconflineno = line_number;
++}
++
++/** Set the input stream. This does not discard the current
++ * input buffer.
++ * @param in_str A readable stream.
++ * 
++ * @see zconf_switch_to_buffer
++ */
++void zconfset_in (FILE *  in_str )
++{
++        zconfin = in_str ;
++}
++
++void zconfset_out (FILE *  out_str )
++{
++        zconfout = out_str ;
++}
++
++int zconfget_debug  (void)
++{
++        return zconf_flex_debug;
++}
++
++void zconfset_debug (int  bdebug )
++{
++        zconf_flex_debug = bdebug ;
++}
++
++static int yy_init_globals (void)
++{
++        /* Initialization is the same as for the non-reentrant scanner.
++     * This function is called from zconflex_destroy(), so don't allocate here.
++     */
++
++    (yy_buffer_stack) = 0;
++    (yy_buffer_stack_top) = 0;
++    (yy_buffer_stack_max) = 0;
++    (yy_c_buf_p) = (char *) 0;
++    (yy_init) = 0;
++    (yy_start) = 0;
++
++/* Defined in main.c */
++#ifdef YY_STDINIT
++    zconfin = stdin;
++    zconfout = stdout;
++#else
++    zconfin = (FILE *) 0;
++    zconfout = (FILE *) 0;
++#endif
++
++    /* For future reference: Set errno on error, since we are called by
++     * zconflex_init()
++     */
++    return 0;
++}
++
++/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
++int zconflex_destroy  (void)
++{
++    
++    /* Pop the buffer stack, destroying each element. */
++	while(YY_CURRENT_BUFFER){
++		zconf_delete_buffer(YY_CURRENT_BUFFER  );
++		YY_CURRENT_BUFFER_LVALUE = NULL;
++		zconfpop_buffer_state();
++	}
++
++	/* Destroy the stack itself. */
++	zconffree((yy_buffer_stack) );
++	(yy_buffer_stack) = NULL;
++
++    /* Reset the globals. This is important in a non-reentrant scanner so the next time
++     * zconflex() is called, initialization will occur. */
++    yy_init_globals( );
++
++    return 0;
++}
++
++/*
++ * Internal utility routines.
++ */
++
++#ifndef yytext_ptr
++static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
++{
++	register int i;
++	for ( i = 0; i < n; ++i )
++		s1[i] = s2[i];
++}
++#endif
++
++#ifdef YY_NEED_STRLEN
++static int yy_flex_strlen (yyconst char * s )
++{
++	register int n;
++	for ( n = 0; s[n]; ++n )
++		;
++
++	return n;
++}
++#endif
++
++void *zconfalloc (yy_size_t  size )
++{
++	return (void *) malloc( size );
++}
++
++void *zconfrealloc  (void * ptr, yy_size_t  size )
++{
++	/* 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 );
++}
++
++void zconffree (void * ptr )
++{
++	free( (char *) ptr );	/* see zconfrealloc() for (char *) cast */
++}
++
++#define YYTABLES_NAME "yytables"
++
++void zconf_starthelp(void)
++{
++	new_string();
++	last_ts = first_ts = 0;
++	BEGIN(HELP);
++}
++
++static void zconf_endhelp(void)
++{
++	zconflval.string = text;
++	BEGIN(INITIAL);
++}
++
++/*
++ * Try to open specified file with following names:
++ * ./name
++ * $(srctree)/name
++ * The latter is used when srctree is separate from objtree
++ * when compiling the kernel.
++ * Return NULL if file is not found.
++ */
++FILE *zconf_fopen(const char *name)
++{
++	char *env, fullname[PATH_MAX+1];
++	FILE *f;
++
++	f = fopen(name, "r");
++	if (!f && name[0] != '/') {
++		env = getenv(SRCTREE);
++		if (env) {
++			sprintf(fullname, "%s/%s", env, name);
++			f = fopen(fullname, "r");
++		}
++	}
++	return f;
++}
++
++void zconf_initscan(const char *name)
++{
++	zconfin = zconf_fopen(name);
++	if (!zconfin) {
++		printf("can't find file %s\n", name);
++		exit(1);
++	}
++
++	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;
++	zconfin = zconf_fopen(name);
++	if (!zconfin) {
++		printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
++		exit(1);
++	}
++	zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
++	buf->parent = current_buf;
++	current_buf = buf;
++
++	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 void 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) {
++		fclose(zconfin);
++		zconf_delete_buffer(YY_CURRENT_BUFFER);
++		zconf_switch_to_buffer(parent->state);
++	}
++	free(current_buf);
++	current_buf = parent;
++}
++
++int zconf_lineno(void)
++{
++	return current_pos.lineno;
++}
++
++char *zconf_curname(void)
++{
++	return current_pos.file ? current_pos.file->name : "<none>";
++}
++
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lkc.h	2007-03-12 22:49:17.000000000 -0400
+@@ -0,0 +1,155 @@
++/*
++ * 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
++
++// Make some warnings go away
++#define YYENABLE_NLS 0
++#define YYLTYPE_IS_TRIVIAL 0
++
++#include "expr.h"
++
++#ifndef KBUILD_NO_NLS
++# include <libintl.h>
++#else
++# define gettext(Msgid) ((const char *) (Msgid))
++# define textdomain(Domainname) ((const char *) (Domainname))
++# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
++#endif
++
++#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
++
++#define SRCTREE "srctree"
++
++#define PACKAGE "linux"
++#define LOCALEDIR "/usr/share/locale"
++
++#define _(text) gettext(text)
++#define N_(text) (text)
++
++
++#define TF_COMMAND	0x0001
++#define TF_PARAM	0x0002
++#define TF_OPTION	0x0004
++
++#define T_OPT_MODULES		1
++#define T_OPT_DEFCONFIG_LIST	2
++
++struct kconf_id {
++	int name;
++	int token;
++	unsigned int flags;
++	enum symbol_type stype;
++};
++
++int zconfparse(void);
++void zconfdump(FILE *out);
++
++extern int zconfdebug;
++void zconf_starthelp(void);
++FILE *zconf_fopen(const char *name);
++void zconf_initscan(const char *name);
++void zconf_nextfile(const char *name);
++int zconf_lineno(void);
++char *zconf_curname(void);
++
++/* confdata.c */
++char *conf_get_default_confname(void);
++
++/* kconfig_load.c */
++void kconfig_load(void);
++
++/* menu.c */
++void menu_init(void);
++struct menu *menu_add_menu(void);
++void menu_end_menu(void);
++void menu_add_entry(struct symbol *sym);
++void menu_end_entry(void);
++void menu_add_dep(struct expr *dep);
++struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
++struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
++void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
++void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
++void menu_add_option(int token, char *arg);
++void menu_finalize(struct menu *parent);
++void menu_set_type(int type);
++
++/* util.c */
++struct file *file_lookup(const char *name);
++int file_write_dep(const char *name);
++
++struct gstr {
++	size_t len;
++	char  *s;
++};
++struct gstr str_new(void);
++struct gstr str_assign(const char *s);
++void str_free(struct gstr *gs);
++void str_append(struct gstr *gs, const char *s);
++void str_printf(struct gstr *gs, const char *fmt, ...);
++const char *str_get(struct gstr *gs);
++
++/* symbol.c */
++void sym_init(void);
++void sym_clear_all_valid(void);
++void sym_set_all_changed(void);
++void sym_set_changed(struct symbol *sym);
++struct symbol *sym_check_deps(struct symbol *sym);
++struct property *prop_alloc(enum prop_type type, struct symbol *sym);
++struct symbol *prop_get_symbol(struct property *prop);
++
++static inline tristate sym_get_tristate_value(struct symbol *sym)
++{
++	return sym->curr.tri;
++}
++
++
++static inline struct symbol *sym_get_choice_value(struct symbol *sym)
++{
++	return (struct symbol *)sym->curr.val;
++}
++
++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 sym->flags & SYMBOL_DEF_USER ? true : false;
++}
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* LKC_H */
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/lkc_proto.h	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,42 @@
++
++/* confdata.c */
++P(conf_parse,void,(const char *name));
++P(conf_read,int,(const char *name));
++P(conf_read_simple,int,(const char *name, int));
++P(conf_write,int,(const char *name));
++P(conf_write_autoconf,int,(void));
++
++/* 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_re_search,struct symbol **,(const char *pattern));
++P(sym_type_name,const char *,(enum symbol_type type));
++P(sym_calc_value,void,(struct symbol *sym));
++P(sym_get_type,enum symbol_type,(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_string_within_range,bool,(struct symbol *sym, const char *str));
++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 *, struct symbol *, const char *), void *data, int prevtoken));
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/mconf.c	2007-03-12 21:09:02.000000000 -0400
+@@ -0,0 +1,919 @@
++/*
++ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
++ * Released under the terms of the GNU GPL v2.0.
++ *
++ * Introduced single menu mode (show all sub-menus in one large tree).
++ * 2002-11-06 Petr Baudis <pasky@ucw.cz>
++ *
++ * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ */
++
++#include <sys/ioctl.h>
++#include <sys/wait.h>
++#include <ctype.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <signal.h>
++#include <stdarg.h>
++#include <stdlib.h>
++#include <string.h>
++#include <termios.h>
++#include <unistd.h>
++#include <locale.h>
++
++#define LKC_DIRECT_LINK
++#include "lkc.h"
++#include "lxdialog/dialog.h"
++
++static char menu_backtitle[128];
++static const char mconf_readme[] = N_(
++"Overview\n"
++"--------\n"
++"Some features may be built directly into the project.\n"
++"Some may be made into loadable runtime modules.  Some features\n"
++"may be completely removed altogether.  There are also certain\n"
++"parameters which are not really features, but must be\n"
++"entered in as decimal or hexadecimal numbers or possibly text.\n"
++"\n"
++"Menu items beginning with [*], <M> or [ ] represent features\n"
++"configured to be built in, modularized or removed respectively.\n"
++"Pointed brackets <> represent module capable features.\n"
++"\n"
++"To change any of these features, highlight it with the cursor\n"
++"keys and press <Y> to build it in, <M> to make it a module or\n"
++"<N> to removed it.  You may also press the <Space Bar> to cycle\n"
++"through the available options (ie. Y->N->M->Y).\n"
++"\n"
++"Some additional keyboard hints:\n"
++"\n"
++"Menus\n"
++"----------\n"
++"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
++"   you wish to change or submenu wish to select and press <Enter>.\n"
++"   Submenus are designated by \"--->\".\n"
++"\n"
++"   Shortcut: Press the option's highlighted letter (hotkey).\n"
++"             Pressing a hotkey more than once will sequence\n"
++"             through all visible items which use that hotkey.\n"
++"\n"
++"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
++"   unseen options into view.\n"
++"\n"
++"o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
++"   and press <ENTER>.\n"
++"\n"
++"   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
++"             using those letters.  You may press a single <ESC>, but\n"
++"             there is a delayed response which you may find annoying.\n"
++"\n"
++"   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
++"   <Exit> and <Help>\n"
++"\n"
++"o  To get help with an item, use the cursor keys to highlight <Help>\n"
++"   and Press <ENTER>.\n"
++"\n"
++"   Shortcut: Press <H> or <?>.\n"
++"\n"
++"\n"
++"Radiolists  (Choice lists)\n"
++"-----------\n"
++"o  Use the cursor keys to select the option you wish to set and press\n"
++"   <S> or the <SPACE BAR>.\n"
++"\n"
++"   Shortcut: Press the first letter of the option you wish to set then\n"
++"             press <S> or <SPACE BAR>.\n"
++"\n"
++"o  To see available help for the item, use the cursor keys to highlight\n"
++"   <Help> and Press <ENTER>.\n"
++"\n"
++"   Shortcut: Press <H> or <?>.\n"
++"\n"
++"   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
++"   <Help>\n"
++"\n"
++"\n"
++"Data Entry\n"
++"-----------\n"
++"o  Enter the requested information and press <ENTER>\n"
++"   If you are entering hexadecimal values, it is not necessary to\n"
++"   add the '0x' prefix to the entry.\n"
++"\n"
++"o  For help, use the <TAB> or cursor keys to highlight the help option\n"
++"   and press <ENTER>.  You can try <TAB><H> as well.\n"
++"\n"
++"\n"
++"Text Box    (Help Window)\n"
++"--------\n"
++"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
++"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
++"   who are familiar with less and lynx.\n"
++"\n"
++"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
++"\n"
++"\n"
++"Alternate Configuration Files\n"
++"-----------------------------\n"
++"Menuconfig supports the use of alternate configuration files for\n"
++"those who, for various reasons, find it necessary to switch\n"
++"between different configurations.\n"
++"\n"
++"At the end of the main menu you will find two options.  One is\n"
++"for saving the current configuration to a file of your choosing.\n"
++"The other option is for loading a previously saved alternate\n"
++"configuration.\n"
++"\n"
++"Even if you don't use alternate configuration files, but you\n"
++"find during a Menuconfig session that you have completely messed\n"
++"up your settings, you may use the \"Load Alternate...\" option to\n"
++"restore your previously saved settings from \".config\" without\n"
++"restarting Menuconfig.\n"
++"\n"
++"Other information\n"
++"-----------------\n"
++"If you use Menuconfig in an XTERM window make sure you have your\n"
++"$TERM variable set to point to a xterm definition which supports color.\n"
++"Otherwise, Menuconfig will look rather bad.  Menuconfig will not\n"
++"display correctly in a RXVT window because rxvt displays only one\n"
++"intensity of color, bright.\n"
++"\n"
++"Menuconfig will display larger menus on screens or xterms which are\n"
++"set to display more than the standard 25 row by 80 column geometry.\n"
++"In order for this to work, the \"stty size\" command must be able to\n"
++"display the screen's current row and column geometry.  I STRONGLY\n"
++"RECOMMEND that you make sure you do NOT have the shell variables\n"
++"LINES and COLUMNS exported into your environment.  Some distributions\n"
++"export those variables via /etc/profile.  Some ncurses programs can\n"
++"become confused when those variables (LINES & COLUMNS) don't reflect\n"
++"the true screen size.\n"
++"\n"
++"Optional personality available\n"
++"------------------------------\n"
++"If you prefer to have all of the options listed in a single\n"
++"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
++"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
++"\n"
++"make MENUCONFIG_MODE=single_menu menuconfig\n"
++"\n"
++"<Enter> will then unroll the appropriate category, or enfold it if it\n"
++"is already unrolled.\n"
++"\n"
++"Note that this mode can eventually be a little more CPU expensive\n"
++"(especially with a larger number of unrolled categories) than the\n"
++"default mode.\n"
++"\n"
++"Different color themes available\n"
++"--------------------------------\n"
++"It is possible to select different color themes using the variable\n"
++"MENUCONFIG_COLOR. To select a theme use:\n"
++"\n"
++"make MENUCONFIG_COLOR=<theme> menuconfig\n"
++"\n"
++"Available themes are\n"
++" mono       => selects colors suitable for monochrome displays\n"
++" blackbg    => selects a color scheme with black background\n"
++" classic    => theme with blue background. The classic look\n"
++" bluetitle  => a LCD friendly version of classic. (default)\n"
++"\n"),
++menu_instructions[] = N_(
++	"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, </> for Search.  "
++	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"),
++radiolist_instructions[] = N_(
++	"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[] = N_(
++	"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[] = N_(
++	"Please enter a hexadecimal value. "
++	"Use the <TAB> key to move from the input field to the buttons below it."),
++inputbox_instructions_string[] = N_(
++	"Please enter a string value. "
++	"Use the <TAB> key to move from the input field to the buttons below it."),
++setmod_text[] = N_(
++	"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[] = N_(
++	"There is no help available for this option.\n"),
++load_config_text[] = N_(
++	"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_(
++	"\n"
++	"For various reasons, one may wish to keep several different\n"
++	"configurations available on a single machine.\n"
++	"\n"
++	"If you have saved a previous configuration in a file other than the\n"
++	"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[] = N_(
++	"Enter a filename to which this configuration should be saved "
++	"as an alternate.  Leave blank to abort."),
++save_config_help[] = N_(
++	"\n"
++	"For various reasons, one may wish to keep different\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"),
++search_help[] = N_(
++	"\n"
++	"Search for CONFIG_ symbols and display their relations.\n"
++	"Regular expressions are allowed.\n"
++	"Example: search for \"^FOO\"\n"
++	"Result:\n"
++	"-----------------------------------------------------------------\n"
++	"Symbol: FOO [=m]\n"
++	"Prompt: Foo bus is used to drive the bar HW\n"
++	"Defined at drivers/pci/Kconfig:47\n"
++	"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
++	"Location:\n"
++	"  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
++	"    -> PCI support (PCI [=y])\n"
++	"      -> PCI access mode (<choice> [=y])\n"
++	"Selects: LIBCRC32\n"
++	"Selected by: BAR\n"
++	"-----------------------------------------------------------------\n"
++	"o The line 'Prompt:' shows the text used in the menu structure for\n"
++	"  this CONFIG_ symbol\n"
++	"o The 'Defined at' line tell at what file / line number the symbol\n"
++	"  is defined\n"
++	"o The 'Depends on:' line tell what symbols needs to be defined for\n"
++	"  this symbol to be visible in the menu (selectable)\n"
++	"o The 'Location:' lines tell where in the menu structure this symbol\n"
++	"  is located\n"
++	"    A location followed by a [=y] indicate that this is a selectable\n"
++	"    menu item - and current value is displayed inside brackets.\n"
++	"o The 'Selects:' line tell what symbol will be automatically\n"
++	"  selected if this symbol is selected (y or m)\n"
++	"o The 'Selected by' line tell what symbol has selected this symbol\n"
++	"\n"
++	"Only relevant lines are shown.\n"
++	"\n\n"
++	"Search examples:\n"
++	"Examples: USB	=> find all CONFIG_ symbols containing USB\n"
++	"          ^USB => find all CONFIG_ symbols starting with USB\n"
++	"          USB$ => find all CONFIG_ symbols ending with USB\n"
++	"\n");
++
++static char filename[PATH_MAX+1] = ".config";
++static int indent;
++static struct termios ios_org;
++static int rows = 0, cols = 0;
++static struct menu *current_menu;
++static int child_count;
++static int single_menu_mode;
++
++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 init_wsize(void)
++{
++	struct winsize ws;
++	char *env;
++
++	if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
++		rows = ws.ws_row;
++		cols = ws.ws_col;
++	}
++
++	if (!rows) {
++		env = getenv("LINES");
++		if (env)
++			rows = atoi(env);
++		if (!rows)
++			rows = 24;
++	}
++	if (!cols) {
++		env = getenv("COLUMNS");
++		if (env)
++			cols = atoi(env);
++		if (!cols)
++			cols = 80;
++	}
++
++	if (rows < 19 || cols < 80) {
++		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
++		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
++		exit(1);
++	}
++
++	rows -= 4;
++	cols -= 5;
++}
++
++static void get_prompt_str(struct gstr *r, struct property *prop)
++{
++	int i, j;
++	struct menu *submenu[8], *menu;
++
++	str_printf(r, "Prompt: %s\n", prop->text);
++	str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
++		prop->menu->lineno);
++	if (!expr_is_yes(prop->visible.expr)) {
++		str_append(r, "  Depends on: ");
++		expr_gstr_print(prop->visible.expr, r);
++		str_append(r, "\n");
++	}
++	menu = prop->menu->parent;
++	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
++		submenu[i++] = menu;
++	if (i > 0) {
++		str_printf(r, "  Location:\n");
++		for (j = 4; --i >= 0; j += 2) {
++			menu = submenu[i];
++			str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
++			if (menu->sym) {
++				str_printf(r, " (%s [=%s])", menu->sym->name ?
++					menu->sym->name : "<choice>",
++					sym_get_string_value(menu->sym));
++			}
++			str_append(r, "\n");
++		}
++	}
++}
++
++static void get_symbol_str(struct gstr *r, struct symbol *sym)
++{
++	bool hit;
++	struct property *prop;
++
++	str_printf(r, "Symbol: %s [=%s]\n", sym->name,
++	                               sym_get_string_value(sym));
++	for_all_prompts(sym, prop)
++		get_prompt_str(r, prop);
++	hit = false;
++	for_all_properties(sym, prop, P_SELECT) {
++		if (!hit) {
++			str_append(r, "  Selects: ");
++			hit = true;
++		} else
++			str_printf(r, " && ");
++		expr_gstr_print(prop->expr, r);
++	}
++	if (hit)
++		str_append(r, "\n");
++	if (sym->rev_dep.expr) {
++		str_append(r, "  Selected by: ");
++		expr_gstr_print(sym->rev_dep.expr, r);
++		str_append(r, "\n");
++	}
++	str_append(r, "\n\n");
++}
++
++static struct gstr get_relations_str(struct symbol **sym_arr)
++{
++	struct symbol *sym;
++	struct gstr res = str_new();
++	int i;
++
++	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
++		get_symbol_str(&res, sym);
++	if (!i)
++		str_append(&res, "No matches found.\n");
++	return res;
++}
++
++static void search_conf(void)
++{
++	struct symbol **sym_arr;
++	struct gstr res;
++	int dres;
++again:
++	dialog_clear();
++	dres = dialog_inputbox(_("Search Configuration Parameter"),
++			      _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
++			      10, 75, "");
++	switch (dres) {
++	case 0:
++		break;
++	case 1:
++		show_helptext(_("Search Configuration"), search_help);
++		goto again;
++	default:
++		return;
++	}
++
++	sym_arr = sym_re_search(dialog_input_result);
++	res = get_relations_str(sym_arr);
++	free(sym_arr);
++	show_textbox(_("Search Results"), str_get(&res), 0, 0);
++	str_free(&res);
++}
++
++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++;
++				if (single_menu_mode) {
++					item_make("%s%*c%s",
++						  menu->data ? "-->" : "++>",
++						  indent + 1, ' ', prompt);
++				} else
++					item_make("   %*c%s  --->", indent + 1, ' ', prompt);
++
++				item_set_tag('m');
++				item_set_data(menu);
++				if (single_menu_mode && menu->data)
++					goto conf_childs;
++				return;
++			default:
++				if (prompt) {
++					child_count++;
++					item_make("---%*c%s", indent + 1, ' ', prompt);
++					item_set_tag(':');
++					item_set_data(menu);
++				}
++			}
++		} 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)) {
++			switch (type) {
++			case S_BOOLEAN:
++				item_make("[%c]", val == no ? ' ' : '*');
++				break;
++			case S_TRISTATE:
++				switch (val) {
++				case yes: ch = '*'; break;
++				case mod: ch = 'M'; break;
++				default:  ch = ' '; break;
++				}
++				item_make("<%c>", ch);
++				break;
++			}
++			item_set_tag('t');
++			item_set_data(menu);
++		} else {
++			item_make("   ");
++			item_set_tag(def_menu ? 't' : ':');
++			item_set_data(menu);
++		}
++
++		item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
++		if (val == yes) {
++			if (def_menu) {
++				item_add_str(" (%s)", menu_get_prompt(def_menu));
++				item_add_str("  --->");
++				if (def_menu->list) {
++					indent += 2;
++					build_conf(def_menu);
++					indent -= 2;
++				}
++			}
++			return;
++		}
++	} else {
++		if (menu == current_menu) {
++			item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
++			item_set_tag(':');
++			item_set_data(menu);
++			goto conf_childs;
++		}
++		child_count++;
++		val = sym_get_tristate_value(sym);
++		if (sym_is_choice_value(sym) && val == yes) {
++			item_make("   ");
++			item_set_tag(':');
++			item_set_data(menu);
++		} else {
++			switch (type) {
++			case S_BOOLEAN:
++				if (sym_is_changable(sym))
++					item_make("[%c]", val == no ? ' ' : '*');
++				else
++					item_make("---");
++				item_set_tag('t');
++				item_set_data(menu);
++				break;
++			case S_TRISTATE:
++				switch (val) {
++				case yes: ch = '*'; break;
++				case mod: ch = 'M'; break;
++				default:  ch = ' '; break;
++				}
++				if (sym_is_changable(sym))
++					item_make("<%c>", ch);
++				else
++					item_make("---");
++				item_set_tag('t');
++				item_set_data(menu);
++				break;
++			default:
++				tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
++				item_make("(%s)", sym_get_string_value(sym));
++				tmp = indent - tmp + 4;
++				if (tmp < 0)
++					tmp = 0;
++				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
++					     (sym_has_value(sym) || !sym_is_changable(sym)) ?
++					     "" : " (NEW)");
++				item_set_tag('s');
++				item_set_data(menu);
++				goto conf_childs;
++			}
++		}
++		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
++			  (sym_has_value(sym) || !sym_is_changable(sym)) ?
++			  "" : " (NEW)");
++		if (menu->prompt->type == P_MENU) {
++			item_add_str("  --->");
++			return;
++		}
++	}
++
++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;
++	struct menu *active_menu = NULL;
++	int res;
++	int s_scroll = 0;
++
++	while (1) {
++		item_reset();
++		current_menu = menu;
++		build_conf(menu);
++		if (!child_count)
++			break;
++		if (menu == &rootmenu) {
++			item_make("--- ");
++			item_set_tag(':');
++			item_make(_("    Load an Alternate Configuration File"));
++			item_set_tag('L');
++			item_make(_("    Save an Alternate Configuration File"));
++			item_set_tag('S');
++		}
++		dialog_clear();
++		res = dialog_menu(prompt ? prompt : _("Main Menu"),
++				  _(menu_instructions),
++				  active_menu, &s_scroll);
++		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
++			break;
++		if (!item_activate_selected())
++			continue;
++		if (!item_tag())
++			continue;
++
++		submenu = item_data();
++		active_menu = item_data();
++		if (submenu)
++			sym = submenu->sym;
++		else
++			sym = NULL;
++
++		switch (res) {
++		case 0:
++			switch (item_tag()) {
++			case 'm':
++				if (single_menu_mode)
++					submenu->data = (void *) (long) !submenu->data;
++				else
++					conf(submenu);
++				break;
++			case 't':
++				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
++					conf_choice(submenu);
++				else if (submenu->prompt->type == P_MENU)
++					conf(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_helptext("README", _(mconf_readme));
++			break;
++		case 3:
++			if (item_is_tag('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 (item_is_tag('t'))
++				sym_set_tristate_value(sym, no);
++			break;
++		case 5:
++			if (item_is_tag('t'))
++				sym_set_tristate_value(sym, mod);
++			break;
++		case 6:
++			if (item_is_tag('t'))
++				sym_toggle_tristate_value(sym);
++			else if (item_is_tag('m'))
++				conf(submenu);
++			break;
++		case 7:
++			search_conf();
++			break;
++		}
++	}
++}
++
++static void show_textbox(const char *title, const char *text, int r, int c)
++{
++	dialog_clear();
++	dialog_textbox(title, text, r, c);
++}
++
++static void show_helptext(const char *title, const char *text)
++{
++	show_textbox(title, text, 0, 0);
++}
++
++static void show_help(struct menu *menu)
++{
++	struct gstr help = str_new();
++	struct symbol *sym = menu->sym;
++
++	if (sym->help)
++	{
++		if (sym->name) {
++			str_printf(&help, "CONFIG_%s:\n\n", sym->name);
++			str_append(&help, _(sym->help));
++			str_append(&help, "\n");
++		}
++	} else {
++		str_append(&help, nohelp_text);
++	}
++	get_symbol_str(&help, sym);
++	show_helptext(menu_get_prompt(menu), str_get(&help));
++	str_free(&help);
++}
++
++static void conf_choice(struct menu *menu)
++{
++	const char *prompt = menu_get_prompt(menu);
++	struct menu *child;
++	struct symbol *active;
++
++	active = sym_get_choice_value(menu->sym);
++	while (1) {
++		int res;
++		int selected;
++		item_reset();
++
++		current_menu = menu;
++		for (child = menu->list; child; child = child->next) {
++			if (!menu_is_visible(child))
++				continue;
++			item_make("%s", menu_get_prompt(child));
++			item_set_data(child);
++			if (child->sym == active)
++				item_set_selected(1);
++			if (child->sym == sym_get_choice_value(menu->sym))
++				item_set_tag('X');
++		}
++		dialog_clear();
++		res = dialog_checklist(prompt ? prompt : _("Main Menu"),
++					_(radiolist_instructions),
++					 15, 70, 6);
++		selected = item_activate_selected();
++		switch (res) {
++		case 0:
++			if (selected) {
++				child = item_data();
++				sym_set_tristate_value(child->sym, yes);
++			}
++			return;
++		case 1:
++			if (selected) {
++				child = item_data();
++				show_help(child);
++				active = child->sym;
++			} else
++				show_help(menu);
++			break;
++		case KEY_ESC:
++			return;
++		case -ERRDISPLAYTOOSMALL:
++			return;
++		}
++	}
++}
++
++static void conf_string(struct menu *menu)
++{
++	const char *prompt = menu_get_prompt(menu);
++
++	while (1) {
++		int res;
++		char *heading;
++
++		switch (sym_get_type(menu->sym)) {
++		case S_INT:
++			heading = _(inputbox_instructions_int);
++			break;
++		case S_HEX:
++			heading = _(inputbox_instructions_hex);
++			break;
++		case S_STRING:
++			heading = _(inputbox_instructions_string);
++			break;
++		default:
++			heading = "Internal mconf error!";
++		}
++		dialog_clear();
++		res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
++				      heading, 10, 75,
++				      sym_get_string_value(menu->sym));
++		switch (res) {
++		case 0:
++			if (sym_set_string_value(menu->sym, dialog_input_result))
++				return;
++			show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
++			break;
++		case 1:
++			show_help(menu);
++			break;
++		case KEY_ESC:
++			return;
++		}
++	}
++}
++
++static void conf_load(void)
++{
++
++	while (1) {
++		int res;
++		dialog_clear();
++		res = dialog_inputbox(NULL, load_config_text,
++				      11, 55, filename);
++		switch(res) {
++		case 0:
++			if (!dialog_input_result[0])
++				return;
++			if (!conf_read(dialog_input_result))
++				return;
++			show_textbox(NULL, _("File does not exist!"), 5, 38);
++			break;
++		case 1:
++			show_helptext(_("Load Alternate Configuration"), load_config_help);
++			break;
++		case KEY_ESC:
++			return;
++		}
++	}
++}
++
++static void conf_save(void)
++{
++	while (1) {
++		int res;
++		dialog_clear();
++		res = dialog_inputbox(NULL, save_config_text,
++				      11, 55, filename);
++		switch(res) {
++		case 0:
++			if (!dialog_input_result[0])
++				return;
++			if (!conf_write(dialog_input_result))
++				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 KEY_ESC:
++			return;
++		}
++	}
++}
++
++static void conf_cleanup(void)
++{
++	tcsetattr(1, TCSAFLUSH, &ios_org);
++}
++
++int main(int ac, char **av)
++{
++	struct symbol *sym;
++	char *mode;
++	int res;
++
++	setlocale(LC_ALL, "");
++	bindtextdomain(PACKAGE, LOCALEDIR);
++	textdomain(PACKAGE);
++
++	conf_parse(av[1] ? av[1] : "");
++	conf_read(NULL);
++
++	sym = sym_lookup("KERNELVERSION", 0);
++	sym_calc_value(sym);
++	sprintf(menu_backtitle, _(PROJECT_NAME" v%s Configuration"),
++		sym_get_string_value(sym));
++
++	mode = getenv("MENUCONFIG_MODE");
++	if (mode) {
++		if (!strcasecmp(mode, "single_menu"))
++			single_menu_mode = 1;
++	}
++
++	tcgetattr(1, &ios_org);
++	atexit(conf_cleanup);
++	init_wsize();
++	reset_dialog();
++	init_dialog(menu_backtitle);
++	do {
++		conf(&rootmenu);
++		dialog_clear();
++		res = dialog_yesno(NULL,
++				   _("Do you wish to save your "
++				     "new "PROJECT_NAME" configuration?\n"
++				     "<ESC><ESC> to continue."),
++				   6, 60);
++	} while (res == KEY_ESC);
++	end_dialog();
++	if (res == 0) {
++		if (conf_write(NULL)) {
++			fprintf(stderr, _("\n\n"
++				"Error writing "PROJECT_NAME" configuration.\n"
++				"Your configuration changes were NOT saved."
++				"\n\n"));
++			return 1;
++		}
++		printf(_("\n\n"
++			"*** End of "PROJECT_NAME" configuration.\n"
++			"*** Execute 'make' to build, or try 'make help'."
++			"\n\n"));
++	} else {
++		fprintf(stderr, _("\n\n"
++			"Your configuration changes were NOT saved."
++			"\n\n"));
++	}
++
++	return 0;
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/menu.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,419 @@
++/*
++ * 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;
++static struct menu **last_entry_ptr;
++
++struct file *file_list;
++struct file *current_file;
++
++static void menu_warn(struct menu *menu, const char *fmt, ...)
++{
++	va_list ap;
++	va_start(ap, fmt);
++	fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
++	vfprintf(stderr, fmt, ap);
++	fprintf(stderr, "\n");
++	va_end(ap);
++}
++
++static void prop_warn(struct property *prop, const char *fmt, ...)
++{
++	va_list ap;
++	va_start(ap, fmt);
++	fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
++	vfprintf(stderr, fmt, ap);
++	fprintf(stderr, "\n");
++	va_end(ap);
++}
++
++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)
++{
++}
++
++struct menu *menu_add_menu(void)
++{
++	menu_end_entry();
++	last_entry_ptr = &current_entry->list;
++	return current_menu = current_entry;
++}
++
++void menu_end_menu(void)
++{
++	last_entry_ptr = &current_menu->next;
++	current_menu = current_menu->parent;
++}
++
++struct expr *menu_check_dep(struct expr *e)
++{
++	if (!e)
++		return e;
++
++	switch (e->type) {
++	case E_NOT:
++		e->left.expr = menu_check_dep(e->left.expr);
++		break;
++	case E_OR:
++	case E_AND:
++		e->left.expr = menu_check_dep(e->left.expr);
++		e->right.expr = menu_check_dep(e->right.expr);
++		break;
++	case E_SYMBOL:
++		/* change 'm' into 'm' && MODULES */
++		if (e->left.sym == &symbol_mod)
++			return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
++		break;
++	default:
++		break;
++	}
++	return e;
++}
++
++void menu_add_dep(struct expr *dep)
++{
++	current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_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;
++	}
++	menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'",
++	    sym->name ? sym->name : "<choice>",
++	    sym_type_name(sym->type), sym_type_name(type));
++}
++
++struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
++{
++	struct property *prop = prop_alloc(type, current_entry->sym);
++
++	prop->menu = current_entry;
++	prop->expr = expr;
++	prop->visible.expr = menu_check_dep(dep);
++
++	if (prompt) {
++		if (isspace(*prompt)) {
++			prop_warn(prop, "leading whitespace ignored");
++			while (isspace(*prompt))
++				prompt++;
++		}
++		if (current_entry->prompt)
++			prop_warn(prop, "prompt redefined");
++		current_entry->prompt = prop;
++	}
++	prop->text = prompt;
++
++	return prop;
++}
++
++struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
++{
++	return menu_add_prop(type, prompt, NULL, dep);
++}
++
++void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
++{
++	menu_add_prop(type, NULL, expr, dep);
++}
++
++void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
++{
++	menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
++}
++
++void menu_add_option(int token, char *arg)
++{
++	struct property *prop;
++
++	switch (token) {
++	case T_OPT_MODULES:
++		prop = prop_alloc(P_DEFAULT, modules_sym);
++		prop->expr = expr_alloc_symbol(current_entry->sym);
++		break;
++	case T_OPT_DEFCONFIG_LIST:
++		if (!sym_defconfig_list)
++			sym_defconfig_list = current_entry->sym;
++		else if (sym_defconfig_list != current_entry->sym)
++			zconf_error("trying to redefine defconfig symbol");
++		break;
++	}
++}
++
++static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
++{
++	return sym2->type == S_INT || sym2->type == S_HEX ||
++	       (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
++}
++
++void sym_check_prop(struct symbol *sym)
++{
++	struct property *prop;
++	struct symbol *sym2;
++	for (prop = sym->prop; prop; prop = prop->next) {
++		switch (prop->type) {
++		case P_DEFAULT:
++			if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
++			    prop->expr->type != E_SYMBOL)
++				prop_warn(prop,
++				    "default for config symbol '%'"
++				    " must be a single symbol", sym->name);
++			break;
++		case P_SELECT:
++			sym2 = prop_get_symbol(prop);
++			if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
++				prop_warn(prop,
++				    "config symbol '%s' uses select, but is "
++				    "not boolean or tristate", sym->name);
++			else if (sym2->type == S_UNKNOWN)
++				prop_warn(prop,
++				    "'select' used by config symbol '%s' "
++				    "refer to undefined symbol '%s'",
++				    sym->name, sym2->name);
++			else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
++				prop_warn(prop,
++				    "'%s' has wrong type. 'select' only "
++				    "accept arguments of boolean and "
++				    "tristate type", sym2->name);
++			break;
++		case P_RANGE:
++			if (sym->type != S_INT && sym->type != S_HEX)
++				prop_warn(prop, "range is only allowed "
++				                "for int or hex symbols");
++			if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
++			    !menu_range_valid_sym(sym, prop->expr->right.sym))
++				prop_warn(prop, "range is invalid");
++			break;
++		default:
++			;
++		}
++	}
++}
++
++void menu_finalize(struct menu *parent)
++{
++	struct menu *menu, *last_menu;
++	struct symbol *sym;
++	struct property *prop;
++	struct expr *parentdep, *basedep, *dep, *dep2, **ep;
++
++	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 = parent->prompt->visible.expr;
++		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(prop->visible.expr);
++				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);
++				prop->visible.expr = dep;
++				if (prop->type == P_SELECT) {
++					struct symbol *es = prop_get_symbol(prop);
++					es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
++							expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
++				}
++			}
++		}
++		for (menu = parent->list; menu; menu = menu->next)
++			menu_finalize(menu);
++	} else if (sym) {
++		basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
++		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 ? menu->prompt->visible.expr : 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;
++			if (!menu->prompt)
++				menu_warn(menu, "choice value must have a prompt");
++			for (prop = menu->sym->prop; prop; prop = prop->next) {
++				if (prop->type == P_PROMPT && prop->menu != menu) {
++					prop_warn(prop, "choice values "
++					    "currently only support a "
++					    "single prompt");
++				}
++				if (prop->type == P_DEFAULT)
++					prop_warn(prop, "defaults for choice "
++					    "values not supported");
++			}
++			current_entry = menu;
++			menu_set_type(sym->type);
++			menu_add_symbol(P_CHOICE, sym, NULL);
++			prop = sym_get_choice_prop(sym);
++			for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
++				;
++			*ep = expr_alloc_one(E_CHOICE, NULL);
++			(*ep)->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;
++		}
++	}
++
++	if (sym && !(sym->flags & SYMBOL_WARNED)) {
++		if (sym->type == S_UNKNOWN)
++			menu_warn(parent, "config symbol defined without type");
++
++		if (sym_is_choice(sym) && !parent->prompt)
++			menu_warn(parent, "choice must have a prompt");
++
++		/* Check properties connected to this symbol */
++		sym_check_prop(sym);
++		sym->flags |= SYMBOL_WARNED;
++	}
++
++	if (sym && !sym_is_optional(sym) && parent->prompt) {
++		sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
++				expr_alloc_and(parent->prompt->visible.expr,
++					expr_alloc_symbol(&symbol_mod)));
++	}
++}
++
++bool menu_is_visible(struct menu *menu)
++{
++	struct menu *child;
++	struct symbol *sym;
++	tristate visible;
++
++	if (!menu->prompt)
++		return false;
++	sym = menu->sym;
++	if (sym) {
++		sym_calc_value(sym);
++		visible = menu->prompt->visible.tri;
++	} else
++		visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
++
++	if (visible != no)
++		return true;
++	if (!sym || sym_get_tristate_value(menu->sym) == no)
++		return false;
++
++	for (child = menu->list; child; child = child->next)
++		if (menu_is_visible(child))
++			return true;
++	return false;
++}
++
++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;
++
++	for (; menu != &rootmenu; menu = menu->parent) {
++		type = menu->prompt ? menu->prompt->type : 0;
++		if (type == P_MENU)
++			break;
++	}
++	return menu;
++}
++
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/symbol.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,882 @@
++/*
++ * 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 <regex.h>
++#include <sys/utsname.h>
++
++#define LKC_DIRECT_LINK
++#include "lkc.h"
++
++struct symbol symbol_yes = {
++	.name = "y",
++	.curr = { "y", yes },
++	.flags = SYMBOL_CONST|SYMBOL_VALID,
++}, symbol_mod = {
++	.name = "m",
++	.curr = { "m", mod },
++	.flags = SYMBOL_CONST|SYMBOL_VALID,
++}, symbol_no = {
++	.name = "n",
++	.curr = { "n", no },
++	.flags = SYMBOL_CONST|SYMBOL_VALID,
++}, symbol_empty = {
++	.name = "",
++	.curr = { "", no },
++	.flags = SYMBOL_VALID,
++};
++
++int sym_change_count;
++struct symbol *sym_defconfig_list;
++struct symbol *modules_sym;
++tristate modules_val;
++
++void sym_add_default(struct symbol *sym, const char *def)
++{
++	struct property *prop = prop_alloc(P_DEFAULT, sym);
++
++	prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
++}
++
++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("KERNELVERSION", 0);
++	sym->type = S_STRING;
++	sym->flags |= SYMBOL_AUTO;
++	p = getenv("KERNELVERSION");
++	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);
++}
++
++enum symbol_type sym_get_type(struct symbol *sym)
++{
++	enum symbol_type type = sym->type;
++
++	if (type == S_TRISTATE) {
++		if (sym_is_choice_value(sym) && sym->visible == yes)
++			type = S_BOOLEAN;
++		else if (modules_val == no)
++			type = S_BOOLEAN;
++	}
++	return type;
++}
++
++const char *sym_type_name(enum symbol_type 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";
++	case S_OTHER:
++		break;
++	}
++	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;
++
++	for_all_defaults(sym, prop) {
++		prop->visible.tri = expr_calc_value(prop->visible.expr);
++		if (prop->visible.tri != no)
++			return prop;
++	}
++	return NULL;
++}
++
++struct property *sym_get_range_prop(struct symbol *sym)
++{
++	struct property *prop;
++
++	for_all_properties(sym, prop, P_RANGE) {
++		prop->visible.tri = expr_calc_value(prop->visible.expr);
++		if (prop->visible.tri != no)
++			return prop;
++	}
++	return NULL;
++}
++
++static int sym_get_range_val(struct symbol *sym, int base)
++{
++	sym_calc_value(sym);
++	switch (sym->type) {
++	case S_INT:
++		base = 10;
++		break;
++	case S_HEX:
++		base = 16;
++		break;
++	default:
++		break;
++	}
++	return strtol(sym->curr.val, NULL, base);
++}
++
++static void sym_validate_range(struct symbol *sym)
++{
++	struct property *prop;
++	int base, val, val2;
++	char str[64];
++
++	switch (sym->type) {
++	case S_INT:
++		base = 10;
++		break;
++	case S_HEX:
++		base = 16;
++		break;
++	default:
++		return;
++	}
++	prop = sym_get_range_prop(sym);
++	if (!prop)
++		return;
++	val = strtol(sym->curr.val, NULL, base);
++	val2 = sym_get_range_val(prop->expr->left.sym, base);
++	if (val >= val2) {
++		val2 = sym_get_range_val(prop->expr->right.sym, base);
++		if (val <= val2)
++			return;
++	}
++	if (sym->type == S_INT)
++		sprintf(str, "%d", val2);
++	else
++		sprintf(str, "0x%x", val2);
++	sym->curr.val = strdup(str);
++}
++
++static void sym_calc_visibility(struct symbol *sym)
++{
++	struct property *prop;
++	tristate tri;
++
++	/* any prompt visible? */
++	tri = no;
++	for_all_prompts(sym, prop) {
++		prop->visible.tri = expr_calc_value(prop->visible.expr);
++		tri = E_OR(tri, prop->visible.tri);
++	}
++	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
++		tri = yes;
++	if (sym->visible != tri) {
++		sym->visible = tri;
++		sym_set_changed(sym);
++	}
++	if (sym_is_choice_value(sym))
++		return;
++	tri = no;
++	if (sym->rev_dep.expr)
++		tri = expr_calc_value(sym->rev_dep.expr);
++	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
++		tri = yes;
++	if (sym->rev_dep.tri != tri) {
++		sym->rev_dep.tri = tri;
++		sym_set_changed(sym);
++	}
++}
++
++static struct symbol *sym_calc_choice(struct symbol *sym)
++{
++	struct symbol *def_sym;
++	struct property *prop;
++	struct expr *e;
++
++	/* is the user choice visible? */
++	def_sym = sym->def[S_DEF_USER].val;
++	if (def_sym) {
++		sym_calc_visibility(def_sym);
++		if (def_sym->visible != no)
++			return def_sym;
++	}
++
++	/* any of the defaults visible? */
++	for_all_defaults(sym, prop) {
++		prop->visible.tri = expr_calc_value(prop->visible.expr);
++		if (prop->visible.tri == no)
++			continue;
++		def_sym = prop_get_symbol(prop);
++		sym_calc_visibility(def_sym);
++		if (def_sym->visible != no)
++			return def_sym;
++	}
++
++	/* just get the first visible value */
++	prop = sym_get_choice_prop(sym);
++	for (e = prop->expr; e; e = e->left.expr) {
++		def_sym = e->right.sym;
++		sym_calc_visibility(def_sym);
++		if (def_sym->visible != no)
++			return def_sym;
++	}
++
++	/* no choice? reset tristate value */
++	sym->curr.tri = no;
++	return NULL;
++}
++
++void sym_calc_value(struct symbol *sym)
++{
++	struct symbol_value newval, oldval;
++	struct property *prop;
++	struct expr *e;
++
++	if (!sym)
++		return;
++
++	if (sym->flags & SYMBOL_VALID)
++		return;
++	sym->flags |= SYMBOL_VALID;
++
++	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:
++		sym->curr.val = sym->name;
++		sym->curr.tri = no;
++		return;
++	}
++	if (!sym_is_choice_value(sym))
++		sym->flags &= ~SYMBOL_WRITE;
++
++	sym_calc_visibility(sym);
++
++	/* set default if recursively called */
++	sym->curr = newval;
++
++	switch (sym_get_type(sym)) {
++	case S_BOOLEAN:
++	case S_TRISTATE:
++		if (sym_is_choice_value(sym) && sym->visible == yes) {
++			prop = sym_get_choice_prop(sym);
++			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
++		} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
++			sym->flags |= SYMBOL_WRITE;
++			if (sym_has_value(sym))
++				newval.tri = sym->def[S_DEF_USER].tri;
++			else if (!sym_is_choice(sym)) {
++				prop = sym_get_default_prop(sym);
++				if (prop)
++					newval.tri = expr_calc_value(prop->expr);
++			}
++			newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
++		} else if (!sym_is_choice(sym)) {
++			prop = sym_get_default_prop(sym);
++			if (prop) {
++				sym->flags |= SYMBOL_WRITE;
++				newval.tri = expr_calc_value(prop->expr);
++			}
++		}
++		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
++			newval.tri = yes;
++		break;
++	case S_STRING:
++	case S_HEX:
++	case S_INT:
++		if (sym->visible != no) {
++			sym->flags |= SYMBOL_WRITE;
++			if (sym_has_value(sym)) {
++				newval.val = sym->def[S_DEF_USER].val;
++				break;
++			}
++		}
++		prop = sym_get_default_prop(sym);
++		if (prop) {
++			struct symbol *ds = prop_get_symbol(prop);
++			if (ds) {
++				sym->flags |= SYMBOL_WRITE;
++				sym_calc_value(ds);
++				newval.val = ds->curr.val;
++			}
++		}
++		break;
++	default:
++		;
++	}
++
++	sym->curr = newval;
++	if (sym_is_choice(sym) && newval.tri == yes)
++		sym->curr.val = sym_calc_choice(sym);
++	sym_validate_range(sym);
++
++	if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
++		sym_set_changed(sym);
++		if (modules_sym == sym) {
++			sym_set_all_changed();
++			modules_val = modules_sym->curr.tri;
++		}
++	}
++
++	if (sym_is_choice(sym)) {
++		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
++		prop = sym_get_choice_prop(sym);
++		for (e = prop->expr; e; e = e->left.expr) {
++			e->right.sym->flags |= flags;
++			if (flags & SYMBOL_CHANGED)
++				sym_set_changed(e->right.sym);
++		}
++	}
++}
++
++void sym_clear_all_valid(void)
++{
++	struct symbol *sym;
++	int i;
++
++	for_all_symbols(i, sym)
++		sym->flags &= ~SYMBOL_VALID;
++	sym_change_count++;
++	if (modules_sym)
++		sym_calc_value(modules_sym);
++}
++
++void sym_set_changed(struct symbol *sym)
++{
++	struct property *prop;
++
++	sym->flags |= SYMBOL_CHANGED;
++	for (prop = sym->prop; prop; prop = prop->next) {
++		if (prop->menu)
++			prop->menu->flags |= MENU_CHANGED;
++	}
++}
++
++void sym_set_all_changed(void)
++{
++	struct symbol *sym;
++	int i;
++
++	for_all_symbols(i, sym)
++		sym_set_changed(sym);
++}
++
++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;
++
++	if (type == S_BOOLEAN && val == mod)
++		return false;
++	if (sym->visible <= sym->rev_dep.tri)
++		return false;
++	if (sym_is_choice_value(sym) && sym->visible == yes)
++		return val == yes;
++	return val >= sym->rev_dep.tri && val <= sym->visible;
++}
++
++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_DEF_USER)) {
++		sym->flags |= SYMBOL_DEF_USER;
++		sym_set_changed(sym);
++	}
++	/*
++	 * setting a choice value also resets the new flag of the choice
++	 * symbol and all other choice values.
++	 */
++	if (sym_is_choice_value(sym) && val == yes) {
++		struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
++		struct property *prop;
++		struct expr *e;
++
++		cs->def[S_DEF_USER].val = sym;
++		cs->flags |= SYMBOL_DEF_USER;
++		prop = sym_get_choice_prop(cs);
++		for (e = prop->expr; e; e = e->left.expr) {
++			if (e->right.sym->visible != no)
++				e->right.sym->flags |= SYMBOL_DEF_USER;
++		}
++	}
++
++	sym->def[S_DEF_USER].tri = val;
++	if (oldval != val)
++		sym_clear_all_valid();
++
++	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)
++{
++	signed 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':
++		case 'm': case 'M':
++		case 'n': case 'N':
++			return true;
++		}
++		return false;
++	default:
++		return false;
++	}
++}
++
++bool sym_string_within_range(struct symbol *sym, const char *str)
++{
++	struct property *prop;
++	int val;
++
++	switch (sym->type) {
++	case S_STRING:
++		return sym_string_valid(sym, str);
++	case S_INT:
++		if (!sym_string_valid(sym, str))
++			return false;
++		prop = sym_get_range_prop(sym);
++		if (!prop)
++			return true;
++		val = strtol(str, NULL, 10);
++		return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
++		       val <= sym_get_range_val(prop->expr->right.sym, 10);
++	case S_HEX:
++		if (!sym_string_valid(sym, str))
++			return false;
++		prop = sym_get_range_prop(sym);
++		if (!prop)
++			return true;
++		val = strtol(str, NULL, 16);
++		return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
++		       val <= sym_get_range_val(prop->expr->right.sym, 16);
++	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_within_range(sym, newval))
++		return false;
++
++	if (!(sym->flags & SYMBOL_DEF_USER)) {
++		sym->flags |= SYMBOL_DEF_USER;
++		sym_set_changed(sym);
++	}
++
++	oldval = sym->def[S_DEF_USER].val;
++	size = strlen(newval) + 1;
++	if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
++		size += 2;
++		sym->def[S_DEF_USER].val = val = malloc(size);
++		*val++ = '0';
++		*val++ = 'x';
++	} else if (!oldval || strcmp(oldval, newval))
++		sym->def[S_DEF_USER].val = 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 *)sym->curr.val;
++}
++
++bool sym_is_changable(struct symbol *sym)
++{
++	return sym->visible > sym->rev_dep.tri;
++}
++
++struct symbol *sym_lookup(const char *name, int isconst)
++{
++	struct symbol *symbol;
++	const char *ptr;
++	char *new_name;
++	int hash = 0;
++
++	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)))
++					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;
++	if (isconst)
++		symbol->flags |= SYMBOL_CONST;
++
++	symbol->next = symbol_hash[hash];
++	symbol_hash[hash] = 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;
++}
++
++struct symbol **sym_re_search(const char *pattern)
++{
++	struct symbol *sym, **sym_arr = NULL;
++	int i, cnt, size;
++	regex_t re;
++
++	cnt = size = 0;
++	/* Skip if empty */
++	if (strlen(pattern) == 0)
++		return NULL;
++	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
++		return NULL;
++
++	for_all_symbols(i, sym) {
++		if (sym->flags & SYMBOL_CONST || !sym->name)
++			continue;
++		if (regexec(&re, sym->name, 0, NULL, 0))
++			continue;
++		if (cnt + 1 >= size) {
++			void *tmp = sym_arr;
++			size += 16;
++			sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
++			if (!sym_arr) {
++				free(tmp);
++				return NULL;
++			}
++		}
++		sym_arr[cnt++] = sym;
++	}
++	if (sym_arr)
++		sym_arr[cnt] = NULL;
++	regfree(&re);
++
++	return sym_arr;
++}
++
++
++struct symbol *sym_check_deps(struct symbol *sym);
++
++static struct symbol *sym_check_expr_deps(struct expr *e)
++{
++	struct symbol *sym;
++
++	if (!e)
++		return NULL;
++	switch (e->type) {
++	case E_OR:
++	case E_AND:
++		sym = sym_check_expr_deps(e->left.expr);
++		if (sym)
++			return sym;
++		return sym_check_expr_deps(e->right.expr);
++	case E_NOT:
++		return sym_check_expr_deps(e->left.expr);
++	case E_EQUAL:
++	case E_UNEQUAL:
++		sym = sym_check_deps(e->left.sym);
++		if (sym)
++			return sym;
++		return sym_check_deps(e->right.sym);
++	case E_SYMBOL:
++		return sym_check_deps(e->left.sym);
++	default:
++		break;
++	}
++	printf("Oops! How to check %d?\n", e->type);
++	return NULL;
++}
++
++struct symbol *sym_check_deps(struct symbol *sym)
++{
++	struct symbol *sym2;
++	struct property *prop;
++
++	if (sym->flags & SYMBOL_CHECK) {
++		printf("Warning! Found recursive dependency: %s", sym->name);
++		return sym;
++	}
++	if (sym->flags & SYMBOL_CHECKED)
++		return NULL;
++
++	sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
++	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
++	if (sym2)
++		goto out;
++
++	for (prop = sym->prop; prop; prop = prop->next) {
++		if (prop->type == P_CHOICE || prop->type == P_SELECT)
++			continue;
++		sym2 = sym_check_expr_deps(prop->visible.expr);
++		if (sym2)
++			goto out;
++		if (prop->type != P_DEFAULT || sym_is_choice(sym))
++			continue;
++		sym2 = sym_check_expr_deps(prop->expr);
++		if (sym2)
++			goto out;
++	}
++out:
++	if (sym2) {
++		printf(" %s", sym->name);
++		if (sym2 == sym) {
++			printf("\n");
++			sym2 = NULL;
++		}
++	}
++	sym->flags &= ~SYMBOL_CHECK;
++	return sym2;
++}
++
++struct property *prop_alloc(enum prop_type type, struct symbol *sym)
++{
++	struct property *prop;
++	struct property **propp;
++
++	prop = malloc(sizeof(*prop));
++	memset(prop, 0, sizeof(*prop));
++	prop->type = type;
++	prop->sym = sym;
++	prop->file = current_file;
++	prop->lineno = zconf_lineno();
++
++	/* append property to the prop list of symbol */
++	if (sym) {
++		for (propp = &sym->prop; *propp; propp = &(*propp)->next)
++			;
++		*propp = prop;
++	}
++
++	return prop;
++}
++
++struct symbol *prop_get_symbol(struct property *prop)
++{
++	if (prop->expr && (prop->expr->type == E_SYMBOL ||
++			   prop->expr->type == E_CHOICE))
++		return prop->expr->left.sym;
++	return NULL;
++}
++
++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_DEFAULT:
++		return "default";
++	case P_CHOICE:
++		return "choice";
++	case P_SELECT:
++		return "select";
++	case P_RANGE:
++		return "range";
++	case P_UNKNOWN:
++		break;
++	}
++	return "unknown";
++}
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/util.c	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,111 @@
++/*
++ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
++ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
++ *
++ * Released under the terms of the GNU GPL v2.0.
++ */
++
++#include <string.h>
++#include "lkc.h"
++
++/* file already present in list? If not add it */
++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;
++}
++
++/* write a dependency file as used by kbuild to track dependencies */
++int file_write_dep(const char *name)
++{
++	struct file *file;
++	FILE *out;
++
++	if (!name)
++		name = ".kconfig.d";
++	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, "\ninclude/config/auto.conf: \\\n"
++		     "\t$(deps_config)\n\n"
++		     "$(deps_config): ;\n");
++	fclose(out);
++	rename("..config.tmp", name);
++	return 0;
++}
++
++
++/* Allocate initial growable sting */
++struct gstr str_new(void)
++{
++	struct gstr gs;
++	gs.s = malloc(sizeof(char) * 64);
++	gs.len = 16;
++	strcpy(gs.s, "\0");
++	return gs;
++}
++
++/* Allocate and assign growable string */
++struct gstr str_assign(const char *s)
++{
++	struct gstr gs;
++	gs.s = strdup(s);
++	gs.len = strlen(s) + 1;
++	return gs;
++}
++
++/* Free storage for growable string */
++void str_free(struct gstr *gs)
++{
++	if (gs->s)
++		free(gs->s);
++	gs->s = NULL;
++	gs->len = 0;
++}
++
++/* Append to growable string */
++void str_append(struct gstr *gs, const char *s)
++{
++	size_t l = strlen(gs->s) + strlen(s) + 1;
++	if (l > gs->len) {
++		gs->s   = realloc(gs->s, l);
++		gs->len = l;
++	}
++	strcat(gs->s, s);
++}
++
++/* Append printf formatted string to growable string */
++void str_printf(struct gstr *gs, const char *fmt, ...)
++{
++	va_list ap;
++	char s[10000]; /* big enough... */
++	va_start(ap, fmt);
++	vsnprintf(s, sizeof(s), fmt, ap);
++	str_append(gs, s);
++	va_end(ap);
++}
++
++/* Retrieve value of growable string */
++const char *str_get(struct gstr *gs)
++{
++	return gs->s;
++}
++
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/zconf.hash.c_shipped	2006-10-23 19:02:02.000000000 -0400
+@@ -0,0 +1,242 @@
++/* ANSI-C code produced by gperf version 3.0.1 */
++/* Command-line: gperf  */
++/* Computed positions: -k'1,3' */
++
++#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
++      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
++      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
++      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
++      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
++      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
++      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
++      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
++      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
++      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
++      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
++      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
++      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
++      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
++      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
++      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
++      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
++      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
++      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
++      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
++      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
++      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
++      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
++/* The character set is not based on ISO-646.  */
++#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
++#endif
++
++struct kconf_id;
++/* maximum key range = 45, duplicates = 0 */
++
++#ifdef __GNUC__
++__inline
++#else
++#ifdef __cplusplus
++inline
++#endif
++#endif
++static unsigned int
++kconf_id_hash (register const char *str, register unsigned int len)
++{
++  static unsigned char asso_values[] =
++    {
++      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, 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, 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, 25, 30, 15,
++       0, 15,  0, 47,  5, 15, 47, 47, 30, 20,
++       5,  0, 25, 15,  0,  0, 10, 35, 47, 47,
++       5, 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, 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, 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, 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
++    };
++  register int hval = len;
++
++  switch (hval)
++    {
++      default:
++        hval += asso_values[(unsigned char)str[2]];
++      /*FALLTHROUGH*/
++      case 2:
++      case 1:
++        hval += asso_values[(unsigned char)str[0]];
++        break;
++    }
++  return hval;
++}
++
++struct kconf_id_strings_t
++  {
++    char kconf_id_strings_str2[sizeof("on")];
++    char kconf_id_strings_str6[sizeof("string")];
++    char kconf_id_strings_str7[sizeof("default")];
++    char kconf_id_strings_str8[sizeof("def_bool")];
++    char kconf_id_strings_str10[sizeof("range")];
++    char kconf_id_strings_str11[sizeof("def_boolean")];
++    char kconf_id_strings_str12[sizeof("def_tristate")];
++    char kconf_id_strings_str13[sizeof("hex")];
++    char kconf_id_strings_str14[sizeof("defconfig_list")];
++    char kconf_id_strings_str16[sizeof("option")];
++    char kconf_id_strings_str17[sizeof("if")];
++    char kconf_id_strings_str18[sizeof("optional")];
++    char kconf_id_strings_str20[sizeof("endif")];
++    char kconf_id_strings_str21[sizeof("choice")];
++    char kconf_id_strings_str22[sizeof("endmenu")];
++    char kconf_id_strings_str23[sizeof("requires")];
++    char kconf_id_strings_str24[sizeof("endchoice")];
++    char kconf_id_strings_str26[sizeof("config")];
++    char kconf_id_strings_str27[sizeof("modules")];
++    char kconf_id_strings_str28[sizeof("int")];
++    char kconf_id_strings_str29[sizeof("menu")];
++    char kconf_id_strings_str31[sizeof("prompt")];
++    char kconf_id_strings_str32[sizeof("depends")];
++    char kconf_id_strings_str33[sizeof("tristate")];
++    char kconf_id_strings_str34[sizeof("bool")];
++    char kconf_id_strings_str35[sizeof("menuconfig")];
++    char kconf_id_strings_str36[sizeof("select")];
++    char kconf_id_strings_str37[sizeof("boolean")];
++    char kconf_id_strings_str39[sizeof("help")];
++    char kconf_id_strings_str41[sizeof("source")];
++    char kconf_id_strings_str42[sizeof("comment")];
++    char kconf_id_strings_str43[sizeof("mainmenu")];
++    char kconf_id_strings_str46[sizeof("enable")];
++  };
++static struct kconf_id_strings_t kconf_id_strings_contents =
++  {
++    "on",
++    "string",
++    "default",
++    "def_bool",
++    "range",
++    "def_boolean",
++    "def_tristate",
++    "hex",
++    "defconfig_list",
++    "option",
++    "if",
++    "optional",
++    "endif",
++    "choice",
++    "endmenu",
++    "requires",
++    "endchoice",
++    "config",
++    "modules",
++    "int",
++    "menu",
++    "prompt",
++    "depends",
++    "tristate",
++    "bool",
++    "menuconfig",
++    "select",
++    "boolean",
++    "help",
++    "source",
++    "comment",
++    "mainmenu",
++    "enable"
++  };
++#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
++#ifdef __GNUC__
++__inline
++#endif
++struct kconf_id *
++kconf_id_lookup (register const char *str, register unsigned int len)
++{
++  enum
++    {
++      TOTAL_KEYWORDS = 33,
++      MIN_WORD_LENGTH = 2,
++      MAX_WORD_LENGTH = 14,
++      MIN_HASH_VALUE = 2,
++      MAX_HASH_VALUE = 46
++    };
++
++  static struct kconf_id wordlist[] =
++    {
++      {-1}, {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,		T_ON,		TF_PARAM},
++      {-1}, {-1}, {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6,		T_TYPE,		TF_COMMAND, S_STRING},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10,		T_RANGE,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,	T_DEFAULT,	TF_COMMAND, S_TRISTATE},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,		T_TYPE,		TF_COMMAND, S_HEX},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,	T_OPT_DEFCONFIG_LIST,TF_OPTION},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,		T_OPTION,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,		T_IF,		TF_COMMAND|TF_PARAM},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,	T_OPTIONAL,	TF_COMMAND},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20,		T_ENDIF,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,		T_CHOICE,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,	T_ENDMENU,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,	T_REQUIRES,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24,	T_ENDCHOICE,	TF_COMMAND},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,		T_CONFIG,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,	T_OPT_MODULES,	TF_OPTION},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,		T_TYPE,		TF_COMMAND, S_INT},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29,		T_MENU,		TF_COMMAND},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,		T_PROMPT,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,	T_DEPENDS,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,	T_TYPE,		TF_COMMAND, S_TRISTATE},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34,		T_TYPE,		TF_COMMAND, S_BOOLEAN},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,	T_MENUCONFIG,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,		T_SELECT,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,	T_TYPE,		TF_COMMAND, S_BOOLEAN},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39,		T_HELP,		TF_COMMAND},
++      {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,		T_SOURCE,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,	T_COMMENT,	TF_COMMAND},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43,	T_MAINMENU,	TF_COMMAND},
++      {-1}, {-1},
++      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46,		T_SELECT,	TF_COMMAND}
++    };
++
++  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
++    {
++      register int key = kconf_id_hash (str, len);
++
++      if (key <= MAX_HASH_VALUE && key >= 0)
++        {
++          register int o = wordlist[key].name;
++          if (o >= 0)
++            {
++              register const char *s = o + kconf_id_strings;
++
++              if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
++                return &wordlist[key];
++            }
++        }
++    }
++  return 0;
++}
++
+--- /dev/null	2006-05-30 21:33:22.000000000 -0400
++++ uclibc/kconfig/zconf.tab.c_shipped	2006-10-31 12:11:38.000000000 -0500
+@@ -0,0 +1,2345 @@
++/* A Bison parser, made by GNU Bison 2.1.  */
++
++/* Skeleton parser for Yacc-like parsing with Bison,
++   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, 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.  */
++
++/* Written by Richard Stallman by simplifying the original so called
++   ``semantic'' parser.  */
++
++/* 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.  */
++
++/* Identify Bison output.  */
++#define YYBISON 1
++
++/* Bison version.  */
++#define YYBISON_VERSION "2.1"
++
++/* Skeleton name.  */
++#define YYSKELETON_NAME "yacc.c"
++
++/* Pure parsers.  */
++#define YYPURE 0
++
++/* Using locations.  */
++#define YYLSP_NEEDED 0
++
++/* Substitute the variable and function names.  */
++#define yyparse zconfparse
++#define yylex   zconflex
++#define yyerror zconferror
++#define yylval  zconflval
++#define yychar  zconfchar
++#define yydebug zconfdebug
++#define yynerrs zconfnerrs
++
++
++/* Tokens.  */
++#ifndef YYTOKENTYPE
++# define YYTOKENTYPE
++   /* Put the tokens into the symbol table, so that GDB and other debuggers
++      know about them.  */
++   enum yytokentype {
++     T_MAINMENU = 258,
++     T_MENU = 259,
++     T_ENDMENU = 260,
++     T_SOURCE = 261,
++     T_CHOICE = 262,
++     T_ENDCHOICE = 263,
++     T_COMMENT = 264,
++     T_CONFIG = 265,
++     T_MENUCONFIG = 266,
++     T_HELP = 267,
++     T_HELPTEXT = 268,
++     T_IF = 269,
++     T_ENDIF = 270,
++     T_DEPENDS = 271,
++     T_REQUIRES = 272,
++     T_OPTIONAL = 273,
++     T_PROMPT = 274,
++     T_TYPE = 275,
++     T_DEFAULT = 276,
++     T_SELECT = 277,
++     T_RANGE = 278,
++     T_OPTION = 279,
++     T_ON = 280,
++     T_WORD = 281,
++     T_WORD_QUOTE = 282,
++     T_UNEQUAL = 283,
++     T_CLOSE_PAREN = 284,
++     T_OPEN_PAREN = 285,
++     T_EOL = 286,
++     T_OR = 287,
++     T_AND = 288,
++     T_EQUAL = 289,
++     T_NOT = 290
++   };
++#endif
++/* Tokens.  */
++#define T_MAINMENU 258
++#define T_MENU 259
++#define T_ENDMENU 260
++#define T_SOURCE 261
++#define T_CHOICE 262
++#define T_ENDCHOICE 263
++#define T_COMMENT 264
++#define T_CONFIG 265
++#define T_MENUCONFIG 266
++#define T_HELP 267
++#define T_HELPTEXT 268
++#define T_IF 269
++#define T_ENDIF 270
++#define T_DEPENDS 271
++#define T_REQUIRES 272
++#define T_OPTIONAL 273
++#define T_PROMPT 274
++#define T_TYPE 275
++#define T_DEFAULT 276
++#define T_SELECT 277
++#define T_RANGE 278
++#define T_OPTION 279
++#define T_ON 280
++#define T_WORD 281
++#define T_WORD_QUOTE 282
++#define T_UNEQUAL 283
++#define T_CLOSE_PAREN 284
++#define T_OPEN_PAREN 285
++#define T_EOL 286
++#define T_OR 287
++#define T_AND 288
++#define T_EQUAL 289
++#define T_NOT 290
++
++
++
++
++/* Copy the first part of user declarations.  */
++
++
++/*
++ * 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 LKC_DIRECT_LINK
++#include "lkc.h"
++
++#include "zconf.hash.c"
++
++#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 zconf_error(const char *err, ...);
++static void zconferror(const char *err);
++static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
++
++struct symbol *symbol_hash[257];
++
++static struct menu *current_menu, *current_entry;
++
++#define YYDEBUG 0
++#if YYDEBUG
++#define YYERROR_VERBOSE
++#endif
++
++
++/* Enabling traces.  */
++#ifndef YYDEBUG
++# define YYDEBUG 0
++#endif
++
++/* Enabling verbose error messages.  */
++#ifdef YYERROR_VERBOSE
++# undef YYERROR_VERBOSE
++# define YYERROR_VERBOSE 1
++#else
++# define YYERROR_VERBOSE 0
++#endif
++
++/* Enabling the token table.  */
++#ifndef YYTOKEN_TABLE
++# define YYTOKEN_TABLE 0
++#endif
++
++#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
++
++typedef union YYSTYPE {
++	char *string;
++	struct file *file;
++	struct symbol *symbol;
++	struct expr *expr;
++	struct menu *menu;
++	struct kconf_id *id;
++} YYSTYPE;
++/* Line 196 of yacc.c.  */
++
++# define yystype YYSTYPE /* obsolescent; will be withdrawn */
++# define YYSTYPE_IS_DECLARED 1
++# define YYSTYPE_IS_TRIVIAL 1
++#endif
++
++
++
++/* Copy the second part of user declarations.  */
++
++
++/* Line 219 of yacc.c.  */
++
++
++#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) && (defined (__STDC__) || defined (__cplusplus))
++# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
++# define YYSIZE_T size_t
++#endif
++#if ! defined (YYSIZE_T)
++# define YYSIZE_T unsigned int
++#endif
++
++#ifndef YY_
++# if YYENABLE_NLS
++#  if ENABLE_NLS
++#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
++#   define YY_(msgid) dgettext ("bison-runtime", msgid)
++#  endif
++# endif
++# ifndef YY_
++#  define YY_(msgid) msgid
++# endif
++#endif
++
++#if ! defined (yyoverflow) || YYERROR_VERBOSE
++
++/* The parser invokes alloca or malloc; define the necessary symbols.  */
++
++# ifdef YYSTACK_USE_ALLOCA
++#  if YYSTACK_USE_ALLOCA
++#   ifdef __GNUC__
++#    define YYSTACK_ALLOC __builtin_alloca
++#   else
++#    define YYSTACK_ALLOC alloca
++#    if defined (__STDC__) || defined (__cplusplus)
++#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
++#     define YYINCLUDED_STDLIB_H
++#    endif
++#   endif
++#  endif
++# endif
++
++# ifdef YYSTACK_ALLOC
++   /* Pacify GCC's `empty if-body' warning. */
++#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
++#  ifndef YYSTACK_ALLOC_MAXIMUM
++    /* The OS might guarantee only one guard page at the bottom of the stack,
++       and a page size can be as small as 4096 bytes.  So we cannot safely
++       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
++       to allow for a few compiler-allocated temporary stack slots.  */
++#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
++#  endif
++# else
++#  define YYSTACK_ALLOC YYMALLOC
++#  define YYSTACK_FREE YYFREE
++#  ifndef YYSTACK_ALLOC_MAXIMUM
++#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
++#  endif
++#  ifdef __cplusplus
++extern "C" {
++#  endif
++#  ifndef YYMALLOC
++#   define YYMALLOC malloc
++#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
++	&& (defined (__STDC__) || defined (__cplusplus)))
++void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
++#   endif
++#  endif
++#  ifndef YYFREE
++#   define YYFREE free
++#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
++	&& (defined (__STDC__) || defined (__cplusplus)))
++void free (void *); /* INFRINGES ON USER NAME SPACE */
++#   endif
++#  endif
++#  ifdef __cplusplus
++}
++#  endif
++# endif
++#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
++
++
++#if (! defined (yyoverflow) \
++     && (! defined (__cplusplus) \
++	 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
++
++/* A type that is properly aligned for any stack member.  */
++union yyalloc
++{
++  short int yyss;
++  YYSTYPE yyvs;
++  };
++
++/* The size of the maximum gap between one aligned stack and the next.  */
++# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
++
++/* The size of an array large to enough to hold all stacks, each with
++   N elements.  */
++# define YYSTACK_BYTES(N) \
++     ((N) * (sizeof (short int) + sizeof (YYSTYPE))			\
++      + YYSTACK_GAP_MAXIMUM)
++
++/* Copy COUNT objects from FROM to TO.  The source and destination do
++   not overlap.  */
++# ifndef YYCOPY
++#  if defined (__GNUC__) && 1 < __GNUC__
++#   define YYCOPY(To, From, Count) \
++      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
++#  else
++#   define YYCOPY(To, From, Count)		\
++      do					\
++	{					\
++	  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_MAXIMUM; \
++	yyptr += yynewbytes / sizeof (*yyptr);				\
++      }									\
++    while (0)
++
++#endif
++
++#if defined (__STDC__) || defined (__cplusplus)
++   typedef signed char yysigned_char;
++#else
++   typedef short int yysigned_char;
++#endif
++
++/* YYFINAL -- State number of the termination state. */
++#define YYFINAL  3
++/* YYLAST -- Last index in YYTABLE.  */
++#define YYLAST   275
++
++/* YYNTOKENS -- Number of terminals. */
++#define YYNTOKENS  36
++/* YYNNTS -- Number of nonterminals. */
++#define YYNNTS  45
++/* YYNRULES -- Number of rules. */
++#define YYNRULES  110
++/* YYNRULES -- Number of states. */
++#define YYNSTATES  183
++
++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
++#define YYUNDEFTOK  2
++#define YYMAXUTOK   290
++
++#define YYTRANSLATE(YYX)						\
++  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
++
++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
++static const unsigned 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,     2,     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
++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
++   YYRHS.  */
++static const unsigned short int yyprhs[] =
++{
++       0,     0,     3,     5,     6,     9,    12,    15,    20,    23,
++      28,    33,    37,    39,    41,    43,    45,    47,    49,    51,
++      53,    55,    57,    59,    61,    63,    67,    70,    74,    77,
++      81,    84,    85,    88,    91,    94,    97,   100,   103,   107,
++     112,   117,   122,   128,   132,   133,   137,   138,   141,   144,
++     147,   149,   153,   154,   157,   160,   163,   166,   169,   174,
++     178,   181,   186,   187,   190,   194,   196,   200,   201,   204,
++     207,   210,   214,   217,   219,   223,   224,   227,   230,   233,
++     237,   241,   244,   247,   250,   251,   254,   257,   260,   265,
++     269,   273,   274,   277,   279,   281,   284,   287,   290,   292,
++     295,   296,   299,   301,   305,   309,   313,   316,   320,   324,
++     326
++};
++
++/* YYRHS -- A `-1'-separated list of the rules' RHS. */
++static const yysigned_char yyrhs[] =
++{
++      37,     0,    -1,    38,    -1,    -1,    38,    40,    -1,    38,
++      54,    -1,    38,    65,    -1,    38,     3,    75,    77,    -1,
++      38,    76,    -1,    38,    26,     1,    31,    -1,    38,    39,
++       1,    31,    -1,    38,     1,    31,    -1,    16,    -1,    19,
++      -1,    20,    -1,    22,    -1,    18,    -1,    23,    -1,    21,
++      -1,    31,    -1,    60,    -1,    69,    -1,    43,    -1,    45,
++      -1,    67,    -1,    26,     1,    31,    -1,     1,    31,    -1,
++      10,    26,    31,    -1,    42,    46,    -1,    11,    26,    31,
++      -1,    44,    46,    -1,    -1,    46,    47,    -1,    46,    48,
++      -1,    46,    73,    -1,    46,    71,    -1,    46,    41,    -1,
++      46,    31,    -1,    20,    74,    31,    -1,    19,    75,    78,
++      31,    -1,    21,    79,    78,    31,    -1,    22,    26,    78,
++      31,    -1,    23,    80,    80,    78,    31,    -1,    24,    49,
++      31,    -1,    -1,    49,    26,    50,    -1,    -1,    34,    75,
++      -1,     7,    31,    -1,    51,    55,    -1,    76,    -1,    52,
++      57,    53,    -1,    -1,    55,    56,    -1,    55,    73,    -1,
++      55,    71,    -1,    55,    31,    -1,    55,    41,    -1,    19,
++      75,    78,    31,    -1,    20,    74,    31,    -1,    18,    31,
++      -1,    21,    26,    78,    31,    -1,    -1,    57,    40,    -1,
++      14,    79,    77,    -1,    76,    -1,    58,    61,    59,    -1,
++      -1,    61,    40,    -1,    61,    65,    -1,    61,    54,    -1,
++       4,    75,    31,    -1,    62,    72,    -1,    76,    -1,    63,
++      66,    64,    -1,    -1,    66,    40,    -1,    66,    65,    -1,
++      66,    54,    -1,     6,    75,    31,    -1,     9,    75,    31,
++      -1,    68,    72,    -1,    12,    31,    -1,    70,    13,    -1,
++      -1,    72,    73,    -1,    72,    31,    -1,    72,    41,    -1,
++      16,    25,    79,    31,    -1,    16,    79,    31,    -1,    17,
++      79,    31,    -1,    -1,    75,    78,    -1,    26,    -1,    27,
++      -1,     5,    31,    -1,     8,    31,    -1,    15,    31,    -1,
++      31,    -1,    77,    31,    -1,    -1,    14,    79,    -1,    80,
++      -1,    80,    34,    80,    -1,    80,    28,    80,    -1,    30,
++      79,    29,    -1,    35,    79,    -1,    79,    32,    79,    -1,
++      79,    33,    79,    -1,    26,    -1,    27,    -1
++};
++
++/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
++static const unsigned short int yyrline[] =
++{
++       0,   105,   105,   107,   109,   110,   111,   112,   113,   114,
++     115,   119,   123,   123,   123,   123,   123,   123,   123,   127,
++     128,   129,   130,   131,   132,   136,   137,   143,   151,   157,
++     165,   175,   177,   178,   179,   180,   181,   182,   185,   193,
++     199,   209,   215,   221,   224,   226,   237,   238,   243,   252,
++     257,   265,   268,   270,   271,   272,   273,   274,   277,   283,
++     294,   300,   310,   312,   317,   325,   333,   336,   338,   339,
++     340,   345,   352,   357,   365,   368,   370,   371,   372,   375,
++     383,   390,   397,   403,   410,   412,   413,   414,   417,   422,
++     427,   435,   437,   442,   443,   446,   447,   448,   452,   453,
++     456,   457,   460,   461,   462,   463,   464,   465,   466,   469,
++     470
++};
++#endif
++
++#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
++/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
++   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
++static const char *const yytname[] =
++{
++  "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
++  "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
++  "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
++  "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
++  "T_SELECT", "T_RANGE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE",
++  "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND",
++  "T_EQUAL", "T_NOT", "$accept", "input", "stmt_list", "option_name",
++  "common_stmt", "option_error", "config_entry_start", "config_stmt",
++  "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
++  "config_option", "symbol_option", "symbol_option_list",
++  "symbol_option_arg", "choice", "choice_entry", "choice_end",
++  "choice_stmt", "choice_option_list", "choice_option", "choice_block",
++  "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry",
++  "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment",
++  "comment_stmt", "help_start", "help", "depends_list", "depends",
++  "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
++};
++#endif
++
++# ifdef YYPRINT
++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
++   token YYLEX-NUM.  */
++static const unsigned short int yytoknum[] =
++{
++       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
++     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
++     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
++     285,   286,   287,   288,   289,   290
++};
++# endif
++
++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
++static const unsigned char yyr1[] =
++{
++       0,    36,    37,    38,    38,    38,    38,    38,    38,    38,
++      38,    38,    39,    39,    39,    39,    39,    39,    39,    40,
++      40,    40,    40,    40,    40,    41,    41,    42,    43,    44,
++      45,    46,    46,    46,    46,    46,    46,    46,    47,    47,
++      47,    47,    47,    48,    49,    49,    50,    50,    51,    52,
++      53,    54,    55,    55,    55,    55,    55,    55,    56,    56,
++      56,    56,    57,    57,    58,    59,    60,    61,    61,    61,
++      61,    62,    63,    64,    65,    66,    66,    66,    66,    67,
++      68,    69,    70,    71,    72,    72,    72,    72,    73,    73,
++      73,    74,    74,    75,    75,    76,    76,    76,    77,    77,
++      78,    78,    79,    79,    79,    79,    79,    79,    79,    80,
++      80
++};
++
++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
++static const unsigned char yyr2[] =
++{
++       0,     2,     1,     0,     2,     2,     2,     4,     2,     4,
++       4,     3,     1,     1,     1,     1,     1,     1,     1,     1,
++       1,     1,     1,     1,     1,     3,     2,     3,     2,     3,
++       2,     0,     2,     2,     2,     2,     2,     2,     3,     4,
++       4,     4,     5,     3,     0,     3,     0,     2,     2,     2,
++       1,     3,     0,     2,     2,     2,     2,     2,     4,     3,
++       2,     4,     0,     2,     3,     1,     3,     0,     2,     2,
++       2,     3,     2,     1,     3,     0,     2,     2,     2,     3,
++       3,     2,     2,     2,     0,     2,     2,     2,     4,     3,
++       3,     0,     2,     1,     1,     2,     2,     2,     1,     2,
++       0,     2,     1,     3,     3,     3,     2,     3,     3,     1,
++       1
++};
++
++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
++   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
++   means the default is an error.  */