# HG changeset patch # User Rob Landley # Date 1193856963 18000 # Node ID 31ebe00423247fe87ca633e1e54f1786de1ab590 # Parent 41d57d7ba5e101cf060f04c24037d52fadbb7f98 Put these back until uClibc's kconfig builds without curses. diff -r 41d57d7ba5e1 -r 31ebe0042324 sources/patches/uClibc-newkconfig.patch --- /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=""' ++ elif [ -f /usr/include/ncurses/curses.h ]; then ++ echo '-I/usr/include/ncurses -DCURSES_LOC=""' ++ elif [ -f /usr/include/ncurses.h ]; then ++ echo '-DCURSES_LOC=""' ++ else ++ echo '-DCURSES_LOC=""' ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++#include ++ ++#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, ""); ++ 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, "", 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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#ifndef EXPR_H ++#define EXPR_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include ++#ifndef __cplusplus ++#include ++#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="" $(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 ++#include ++#include ++#include ++ ++/* end standard C headers. */ ++ ++/* flex integer type definitions */ ++ ++#ifndef FLEXINT_H ++#define FLEXINT_H ++ ++/* C99 systems have . 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 ++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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#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 : ""; ++} ++ +--- /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 ++ * 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 ++#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 ++ * 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 ++ * ++ * i18n, 2005, Arnaldo Carvalho de Melo ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 [*], 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 to build it in, to make it a module or\n" ++" to removed it. You may also press the 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 .\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 and keys to scroll\n" ++" unseen options into view.\n" ++"\n" ++"o To exit a menu use the cursor keys to highlight the button\n" ++" and press .\n" ++"\n" ++" Shortcut: Press or or if there is no hotkey\n" ++" using those letters. You may press a single , but\n" ++" there is a delayed response which you may find annoying.\n" ++"\n" ++" Also, the and cursor keys will cycle between and\n" ++" \n" ++"\n" ++"\n" ++"Data Entry\n" ++"-----------\n" ++"o Enter the requested information and press \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 or cursor keys to highlight the help option\n" ++" and press . You can try 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 and for those\n" ++" who are familiar with less and lynx.\n" ++"\n" ++"o Press , , or 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" ++" 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= 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. " ++ " selects submenus --->. " ++ "Highlighted letters are hotkeys. " ++ "Pressing includes, excludes, modularizes features. " ++ "Press to exit, for Help, for Search. " ++ "Legend: [*] built-in [ ] excluded 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 . " ++ "Press for additional information about this option."), ++inputbox_instructions_int[] = N_( ++ "Please enter a decimal value. " ++ "Fractions will not be accepted. " ++ "Use the key to move from the input field to the buttons below it."), ++inputbox_instructions_hex[] = N_( ++ "Please enter a hexadecimal value. " ++ "Use the key to move from the input field to the buttons below it."), ++inputbox_instructions_string[] = N_( ++ "Please enter a string value. " ++ "Use the 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 ( [=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 : "", ++ 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" ++ " 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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++ ++#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 = ¤t_entry->list; ++ return current_menu = current_entry; ++} ++ ++void menu_end_menu(void) ++{ ++ last_entry_ptr = ¤t_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 : "", ++ 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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ * Copyright (C) 2002-2005 Sam Ravnborg ++ * ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#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 ." ++#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 ++ * Released under the terms of the GNU GPL v2.0. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 /* 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 /* 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 /* 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. */ ++static const unsigned char yydefact[] = ++{ ++ 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, ++ 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, ++ 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, ++ 84, 21, 8, 11, 93, 94, 0, 0, 95, 0, ++ 48, 96, 0, 0, 0, 109, 110, 0, 0, 0, ++ 102, 97, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 98, 7, 71, 79, 80, 27, 29, 0, ++ 106, 0, 0, 64, 0, 0, 9, 10, 0, 0, ++ 0, 0, 0, 91, 0, 0, 0, 44, 0, 37, ++ 36, 32, 33, 0, 35, 34, 0, 0, 91, 0, ++ 56, 57, 53, 55, 54, 63, 51, 50, 68, 70, ++ 66, 69, 65, 86, 87, 85, 76, 78, 74, 77, ++ 73, 99, 105, 107, 108, 104, 103, 26, 82, 0, ++ 0, 0, 100, 0, 100, 100, 100, 0, 0, 0, ++ 83, 60, 100, 0, 100, 0, 89, 90, 0, 0, ++ 38, 92, 0, 0, 100, 46, 43, 25, 0, 59, ++ 0, 88, 101, 39, 40, 41, 0, 0, 45, 58, ++ 61, 42, 47 ++}; ++ ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const short int yydefgoto[] = ++{ ++ -1, 1, 2, 25, 26, 100, 27, 28, 29, 30, ++ 64, 101, 102, 148, 178, 31, 32, 116, 33, 66, ++ 112, 67, 34, 120, 35, 68, 36, 37, 128, 38, ++ 70, 39, 40, 41, 103, 104, 69, 105, 143, 144, ++ 42, 73, 159, 59, 60 ++}; ++ ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -135 ++static const short int yypact[] = ++{ ++ -135, 2, 170, -135, -14, 56, 56, -8, 56, 24, ++ 67, 56, 7, 14, 62, 97, -135, -135, -135, -135, ++ -135, -135, -135, 156, -135, 166, -135, -135, -135, -135, ++ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, ++ -135, -135, -135, -135, -135, -135, 138, 151, -135, 152, ++ -135, -135, 163, 167, 176, -135, -135, 62, 62, 185, ++ -19, -135, 188, 190, 42, 103, 194, 85, 70, 222, ++ 70, 132, -135, 191, -135, -135, -135, -135, -135, 127, ++ -135, 62, 62, 191, 104, 104, -135, -135, 193, 203, ++ 9, 62, 56, 56, 62, 161, 104, -135, 196, -135, ++ -135, -135, -135, 233, -135, -135, 204, 56, 56, 221, ++ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, ++ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, ++ -135, -135, -135, 219, -135, -135, -135, -135, -135, 62, ++ 209, 212, 240, 224, 240, -1, 240, 104, 41, 225, ++ -135, -135, 240, 226, 240, 218, -135, -135, 62, 227, ++ -135, -135, 228, 229, 240, 230, -135, -135, 231, -135, ++ 232, -135, 112, -135, -135, -135, 234, 56, -135, -135, ++ -135, -135, -135 ++}; ++ ++/* YYPGOTO[NTERM-NUM]. */ ++static const short int yypgoto[] = ++{ ++ -135, -135, -135, -135, 94, -45, -135, -135, -135, -135, ++ 237, -135, -135, -135, -135, -135, -135, -135, -54, -135, ++ -135, -135, -135, -135, -135, -135, -135, -135, -135, 1, ++ -135, -135, -135, -135, -135, 195, 235, -44, 159, -5, ++ 98, 210, -134, -53, -77 ++}; ++ ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If zero, do what YYDEFACT says. ++ If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -82 ++static const short int yytable[] = ++{ ++ 46, 47, 3, 49, 79, 80, 52, 135, 136, 84, ++ 161, 162, 163, 158, 119, 85, 127, 43, 168, 147, ++ 170, 111, 114, 48, 124, 125, 124, 125, 133, 134, ++ 176, 81, 82, 53, 139, 55, 56, 140, 141, 57, ++ 54, 145, -28, 88, 58, -28, -28, -28, -28, -28, ++ -28, -28, -28, -28, 89, 50, -28, -28, 90, 91, ++ -28, 92, 93, 94, 95, 96, 97, 165, 98, 121, ++ 164, 129, 166, 99, 6, 7, 8, 9, 10, 11, ++ 12, 13, 44, 45, 14, 15, 155, 142, 55, 56, ++ 7, 8, 57, 10, 11, 12, 13, 58, 51, 14, ++ 15, 24, 152, -30, 88, 172, -30, -30, -30, -30, ++ -30, -30, -30, -30, -30, 89, 24, -30, -30, 90, ++ 91, -30, 92, 93, 94, 95, 96, 97, 61, 98, ++ 55, 56, -81, 88, 99, -81, -81, -81, -81, -81, ++ -81, -81, -81, -81, 81, 82, -81, -81, 90, 91, ++ -81, -81, -81, -81, -81, -81, 132, 62, 98, 81, ++ 82, 115, 118, 123, 126, 117, 122, 63, 130, 72, ++ -2, 4, 182, 5, 6, 7, 8, 9, 10, 11, ++ 12, 13, 74, 75, 14, 15, 16, 146, 17, 18, ++ 19, 20, 21, 22, 76, 88, 23, 149, 77, -49, ++ -49, 24, -49, -49, -49, -49, 89, 78, -49, -49, ++ 90, 91, 106, 107, 108, 109, 72, 81, 82, 86, ++ 98, 87, 131, 88, 137, 110, -72, -72, -72, -72, ++ -72, -72, -72, -72, 138, 151, -72, -72, 90, 91, ++ 156, 81, 82, 157, 81, 82, 150, 154, 98, 171, ++ 81, 82, 82, 123, 158, 160, 167, 169, 173, 174, ++ 175, 113, 179, 180, 177, 181, 65, 153, 0, 83, ++ 0, 0, 0, 0, 0, 71 ++}; ++ ++static const short int yycheck[] = ++{ ++ 5, 6, 0, 8, 57, 58, 11, 84, 85, 28, ++ 144, 145, 146, 14, 68, 34, 70, 31, 152, 96, ++ 154, 66, 66, 31, 69, 69, 71, 71, 81, 82, ++ 164, 32, 33, 26, 25, 26, 27, 90, 91, 30, ++ 26, 94, 0, 1, 35, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 12, 31, 14, 15, 16, 17, ++ 18, 19, 20, 21, 22, 23, 24, 26, 26, 68, ++ 147, 70, 31, 31, 4, 5, 6, 7, 8, 9, ++ 10, 11, 26, 27, 14, 15, 139, 92, 26, 27, ++ 5, 6, 30, 8, 9, 10, 11, 35, 31, 14, ++ 15, 31, 107, 0, 1, 158, 3, 4, 5, 6, ++ 7, 8, 9, 10, 11, 12, 31, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 31, 26, ++ 26, 27, 0, 1, 31, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 32, 33, 14, 15, 16, 17, ++ 18, 19, 20, 21, 22, 23, 29, 1, 26, 32, ++ 33, 67, 68, 31, 70, 67, 68, 1, 70, 31, ++ 0, 1, 177, 3, 4, 5, 6, 7, 8, 9, ++ 10, 11, 31, 31, 14, 15, 16, 26, 18, 19, ++ 20, 21, 22, 23, 31, 1, 26, 1, 31, 5, ++ 6, 31, 8, 9, 10, 11, 12, 31, 14, 15, ++ 16, 17, 18, 19, 20, 21, 31, 32, 33, 31, ++ 26, 31, 31, 1, 31, 31, 4, 5, 6, 7, ++ 8, 9, 10, 11, 31, 31, 14, 15, 16, 17, ++ 31, 32, 33, 31, 32, 33, 13, 26, 26, 31, ++ 32, 33, 33, 31, 14, 31, 31, 31, 31, 31, ++ 31, 66, 31, 31, 34, 31, 29, 108, -1, 59, ++ -1, -1, -1, -1, -1, 40 ++}; ++ ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const unsigned char yystos[] = ++{ ++ 0, 37, 38, 0, 1, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 14, 15, 16, 18, 19, 20, ++ 21, 22, 23, 26, 31, 39, 40, 42, 43, 44, ++ 45, 51, 52, 54, 58, 60, 62, 63, 65, 67, ++ 68, 69, 76, 31, 26, 27, 75, 75, 31, 75, ++ 31, 31, 75, 26, 26, 26, 27, 30, 35, 79, ++ 80, 31, 1, 1, 46, 46, 55, 57, 61, 72, ++ 66, 72, 31, 77, 31, 31, 31, 31, 31, 79, ++ 79, 32, 33, 77, 28, 34, 31, 31, 1, 12, ++ 16, 17, 19, 20, 21, 22, 23, 24, 26, 31, ++ 41, 47, 48, 70, 71, 73, 18, 19, 20, 21, ++ 31, 41, 56, 71, 73, 40, 53, 76, 40, 54, ++ 59, 65, 76, 31, 41, 73, 40, 54, 64, 65, ++ 76, 31, 29, 79, 79, 80, 80, 31, 31, 25, ++ 79, 79, 75, 74, 75, 79, 26, 80, 49, 1, ++ 13, 31, 75, 74, 26, 79, 31, 31, 14, 78, ++ 31, 78, 78, 78, 80, 26, 31, 31, 78, 31, ++ 78, 31, 79, 31, 31, 31, 78, 34, 50, 31, ++ 31, 31, 75 ++}; ++ ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ ++ ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. */ ++ ++#define YYFAIL goto yyerrlab ++ ++#define YYRECOVERING() (!!yyerrstatus) ++ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ yytoken = YYTRANSLATE (yychar); \ ++ YYPOPSTACK; \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ ++ yyerror (YY_("syntax error: cannot back up")); \ ++ YYERROR; \ ++ } \ ++while (0) ++ ++ ++#define YYTERROR 1 ++#define YYERRCODE 256 ++ ++ ++/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. ++ If N is 0, then set CURRENT to the empty location which ends ++ the previous symbol: RHS[0] (always defined). */ ++ ++#define YYRHSLOC(Rhs, K) ((Rhs)[K]) ++#ifndef YYLLOC_DEFAULT ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ do \ ++ if (N) \ ++ { \ ++ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ ++ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ ++ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ ++ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ ++ } \ ++ else \ ++ { \ ++ (Current).first_line = (Current).last_line = \ ++ YYRHSLOC (Rhs, 0).last_line; \ ++ (Current).first_column = (Current).last_column = \ ++ YYRHSLOC (Rhs, 0).last_column; \ ++ } \ ++ while (0) ++#endif ++ ++ ++/* YY_LOCATION_PRINT -- Print the location on the stream. ++ This macro was not mandated originally: define only if we know ++ we won't break user code: when these are the locations we know. */ ++ ++#ifndef YY_LOCATION_PRINT ++# if YYLTYPE_IS_TRIVIAL ++# define YY_LOCATION_PRINT(File, Loc) \ ++ fprintf (File, "%d.%d-%d.%d", \ ++ (Loc).first_line, (Loc).first_column, \ ++ (Loc).last_line, (Loc).last_column) ++# else ++# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++# endif ++#endif ++ ++ ++/* YYLEX -- calling `yylex' with the right arguments. */ ++ ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (YYLEX_PARAM) ++#else ++# define YYLEX yylex () ++#endif ++ ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf ++# endif ++ ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (0) ++ ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yysymprint (stderr, \ ++ Type, Value); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (0) ++ ++/*------------------------------------------------------------------. ++| yy_stack_print -- Print the state stack from its BOTTOM up to its | ++| TOP (included). | ++`------------------------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_stack_print (short int *bottom, short int *top) ++#else ++static void ++yy_stack_print (bottom, top) ++ short int *bottom; ++ short int *top; ++#endif ++{ ++ YYFPRINTF (stderr, "Stack now"); ++ for (/* Nothing. */; bottom <= top; ++bottom) ++ YYFPRINTF (stderr, " %d", *bottom); ++ YYFPRINTF (stderr, "\n"); ++} ++ ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (0) ++ ++ ++/*------------------------------------------------. ++| Report that the YYRULE is going to be reduced. | ++`------------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yy_reduce_print (int yyrule) ++#else ++static void ++yy_reduce_print (yyrule) ++ int yyrule; ++#endif ++{ ++ int yyi; ++ unsigned long int yylno = yyrline[yyrule]; ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", ++ yyrule - 1, yylno); ++ /* Print the symbols being reduced, and their result. */ ++ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) ++ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); ++ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); ++} ++ ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (Rule); \ ++} while (0) ++ ++/* Nonzero means print parse trace. It is left uninitialized so that ++ multiple parsers can coexist. */ ++int yydebug; ++#else /* !YYDEBUG */ ++# define YYDPRINTF(Args) ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) ++# define YY_STACK_PRINT(Bottom, Top) ++# define YY_REDUCE_PRINT(Rule) ++#endif /* !YYDEBUG */ ++ ++ ++/* YYINITDEPTH -- initial size of the parser's stacks. */ ++#ifndef YYINITDEPTH ++# define YYINITDEPTH 200 ++#endif ++ ++/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only ++ if the built-in stack extension method is used). ++ ++ Do not make this value too large; the results are undefined if ++ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) ++ evaluated with infinite-precision integer arithmetic. */ ++ ++#ifndef YYMAXDEPTH ++# define YYMAXDEPTH 10000 ++#endif ++ ++ ++ ++#if YYERROR_VERBOSE ++ ++# ifndef yystrlen ++# if defined (__GLIBC__) && defined (_STRING_H) ++# define yystrlen strlen ++# else ++/* Return the length of YYSTR. */ ++static YYSIZE_T ++# if defined (__STDC__) || defined (__cplusplus) ++yystrlen (const char *yystr) ++# else ++yystrlen (yystr) ++ const char *yystr; ++# endif ++{ ++ const char *yys = yystr; ++ ++ while (*yys++ != '\0') ++ continue; ++ ++ return yys - yystr - 1; ++} ++# endif ++# endif ++ ++# ifndef yystpcpy ++# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) ++# define yystpcpy stpcpy ++# else ++/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in ++ YYDEST. */ ++static char * ++# if defined (__STDC__) || defined (__cplusplus) ++yystpcpy (char *yydest, const char *yysrc) ++# else ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++# endif ++{ ++ char *yyd = yydest; ++ const char *yys = yysrc; ++ ++ while ((*yyd++ = *yys++) != '\0') ++ continue; ++ ++ return yyd - 1; ++} ++# endif ++# endif ++ ++# ifndef yytnamerr ++/* Copy to YYRES the contents of YYSTR after stripping away unnecessary ++ quotes and backslashes, so that it's suitable for yyerror. The ++ heuristic is that double-quoting is unnecessary unless the string ++ contains an apostrophe, a comma, or backslash (other than ++ backslash-backslash). YYSTR is taken from yytname. If YYRES is ++ null, do not copy; instead, return the length of what the result ++ would have been. */ ++static YYSIZE_T ++yytnamerr (char *yyres, const char *yystr) ++{ ++ if (*yystr == '"') ++ { ++ size_t yyn = 0; ++ char const *yyp = yystr; ++ ++ for (;;) ++ switch (*++yyp) ++ { ++ case '\'': ++ case ',': ++ goto do_not_strip_quotes; ++ ++ case '\\': ++ if (*++yyp != '\\') ++ goto do_not_strip_quotes; ++ /* Fall through. */ ++ default: ++ if (yyres) ++ yyres[yyn] = *yyp; ++ yyn++; ++ break; ++ ++ case '"': ++ if (yyres) ++ yyres[yyn] = '\0'; ++ return yyn; ++ } ++ do_not_strip_quotes: ; ++ } ++ ++ if (! yyres) ++ return yystrlen (yystr); ++ ++ return yystpcpy (yyres, yystr) - yyres; ++} ++# endif ++ ++#endif /* YYERROR_VERBOSE */ ++ ++ ++ ++#if YYDEBUG ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yysymprint (yyoutput, yytype, yyvaluep) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ if (yytype < YYNTOKENS) ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ ++ ++# ifdef YYPRINT ++ if (yytype < YYNTOKENS) ++ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# endif ++ switch (yytype) ++ { ++ default: ++ break; ++ } ++ YYFPRINTF (yyoutput, ")"); ++} ++ ++#endif /* ! YYDEBUG */ ++/*-----------------------------------------------. ++| Release the memory associated to this symbol. | ++`-----------------------------------------------*/ ++ ++#if defined (__STDC__) || defined (__cplusplus) ++static void ++yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) ++#else ++static void ++yydestruct (yymsg, yytype, yyvaluep) ++ const char *yymsg; ++ int yytype; ++ YYSTYPE *yyvaluep; ++#endif ++{ ++ /* Pacify ``unused variable'' warnings. */ ++ (void) yyvaluep; ++ ++ if (!yymsg) ++ yymsg = "Deleting"; ++ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); ++ ++ switch (yytype) ++ { ++ case 52: /* "choice_entry" */ ++ ++ { ++ fprintf(stderr, "%s:%d: missing end statement for this entry\n", ++ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); ++ if (current_menu == (yyvaluep->menu)) ++ menu_end_menu(); ++}; ++ ++ break; ++ case 58: /* "if_entry" */ ++ ++ { ++ fprintf(stderr, "%s:%d: missing end statement for this entry\n", ++ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); ++ if (current_menu == (yyvaluep->menu)) ++ menu_end_menu(); ++}; ++ ++ break; ++ case 63: /* "menu_entry" */ ++ ++ { ++ fprintf(stderr, "%s:%d: missing end statement for this entry\n", ++ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); ++ if (current_menu == (yyvaluep->menu)) ++ menu_end_menu(); ++}; ++ ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++ ++/* Prevent warnings from -Wmissing-prototypes. */ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM); ++# else ++int yyparse (); ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ ++ ++ ++ ++/* The look-ahead symbol. */ ++int yychar; ++ ++/* The semantic value of the look-ahead symbol. */ ++YYSTYPE yylval; ++ ++/* Number of syntax errors so far. */ ++int yynerrs; ++ ++ ++ ++/*----------. ++| yyparse. | ++`----------*/ ++ ++#ifdef YYPARSE_PARAM ++# if defined (__STDC__) || defined (__cplusplus) ++int yyparse (void *YYPARSE_PARAM) ++# else ++int yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++# endif ++#else /* ! YYPARSE_PARAM */ ++#if defined (__STDC__) || defined (__cplusplus) ++int ++yyparse (void) ++#else ++int ++yyparse () ++ ; ++#endif ++#endif ++{ ++ ++ int yystate; ++ int yyn; ++ int yyresult; ++ /* Number of tokens to shift before error messages enabled. */ ++ int yyerrstatus; ++ /* Look-ahead token as an internal (translated) token number. */ ++ int yytoken = 0; ++ ++ /* Three stacks and their tools: ++ `yyss': related to states, ++ `yyvs': related to semantic values, ++ `yyls': related to locations. ++ ++ Refer to the stacks thru separate pointers, to allow yyoverflow ++ to reallocate them elsewhere. */ ++ ++ /* The state stack. */ ++ short int yyssa[YYINITDEPTH]; ++ short int *yyss = yyssa; ++ short int *yyssp; ++ ++ /* The semantic value stack. */ ++ YYSTYPE yyvsa[YYINITDEPTH]; ++ YYSTYPE *yyvs = yyvsa; ++ YYSTYPE *yyvsp; ++ ++ ++ ++#define YYPOPSTACK (yyvsp--, yyssp--) ++ ++ YYSIZE_T yystacksize = YYINITDEPTH; ++ ++ /* The variables used to return semantic value and location from the ++ action routines. */ ++ YYSTYPE yyval; ++ ++ ++ /* When reducing, the number of symbols on the RHS of the reduced ++ rule. */ ++ int yylen; ++ ++ YYDPRINTF ((stderr, "Starting parse\n")); ++ ++ yystate = 0; ++ yyerrstatus = 0; ++ yynerrs = 0; ++ yychar = YYEMPTY; /* Cause a token to be read. */ ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ ++ goto yysetstate; ++ ++/*------------------------------------------------------------. ++| yynewstate -- Push a new state, which is found in yystate. | ++`------------------------------------------------------------*/ ++ yynewstate: ++ /* In all cases, when you get here, the value and location stacks ++ have just been pushed. so pushing a state here evens the stacks. ++ */ ++ yyssp++; ++ ++ yysetstate: ++ *yyssp = yystate; ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ { ++ /* Get the current used size of the three stacks, in elements. */ ++ YYSIZE_T yysize = yyssp - yyss + 1; ++ ++#ifdef yyoverflow ++ { ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ short int *yyss1 = yyss; ++ ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow (YY_("memory exhausted"), ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ ++ &yystacksize); ++ ++ yyss = yyss1; ++ yyvs = yyvs1; ++ } ++#else /* no yyoverflow */ ++# ifndef YYSTACK_RELOCATE ++ goto yyexhaustedlab; ++# else ++ /* Extend the stack our own way. */ ++ if (YYMAXDEPTH <= yystacksize) ++ goto yyexhaustedlab; ++ yystacksize *= 2; ++ if (YYMAXDEPTH < yystacksize) ++ yystacksize = YYMAXDEPTH; ++ ++ { ++ short int *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyexhaustedlab; ++ YYSTACK_RELOCATE (yyss); ++ YYSTACK_RELOCATE (yyvs); ++ ++# undef YYSTACK_RELOCATE ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); ++ } ++# endif ++#endif /* no yyoverflow */ ++ ++ yyssp = yyss + yysize - 1; ++ yyvsp = yyvs + yysize - 1; ++ ++ ++ YYDPRINTF ((stderr, "Stack size increased to %lu\n", ++ (unsigned long int) yystacksize)); ++ ++ if (yyss + yystacksize - 1 <= yyssp) ++ YYABORT; ++ } ++ ++ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); ++ ++ goto yybackup; ++ ++/*-----------. ++| yybackup. | ++`-----------*/ ++yybackup: ++ ++/* Do appropriate processing given the current state. */ ++/* Read a look-ahead token if we need one and don't already have one. */ ++/* yyresume: */ ++ ++ /* First try to decide what to do without reference to look-ahead token. */ ++ ++ yyn = yypact[yystate]; ++ if (yyn == YYPACT_NINF) ++ goto yydefault; ++ ++ /* Not known => get a look-ahead token if don't already have one. */ ++ ++ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ ++ if (yychar == YYEMPTY) ++ { ++ YYDPRINTF ((stderr, "Reading a token: ")); ++ yychar = YYLEX; ++ } ++ ++ if (yychar <= YYEOF) ++ { ++ yychar = yytoken = YYEOF; ++ YYDPRINTF ((stderr, "Now at end of input.\n")); ++ } ++ else ++ { ++ yytoken = YYTRANSLATE (yychar); ++ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); ++ } ++ ++ /* If the proper action on seeing token YYTOKEN is to reduce or to ++ detect an error, take that action. */ ++ yyn += yytoken; ++ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) ++ goto yydefault; ++ yyn = yytable[yyn]; ++ if (yyn <= 0) ++ { ++ if (yyn == 0 || yyn == YYTABLE_NINF) ++ goto yyerrlab; ++ yyn = -yyn; ++ goto yyreduce; ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ /* Shift the look-ahead token. */ ++ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); ++ ++ /* Discard the token being shifted unless it is eof. */ ++ if (yychar != YYEOF) ++ yychar = YYEMPTY; ++ ++ *++yyvsp = yylval; ++ ++ ++ /* Count tokens shifted since error; after three, turn off error ++ status. */ ++ if (yyerrstatus) ++ yyerrstatus--; ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-----------------------------------------------------------. ++| yydefault -- do the default action for the current state. | ++`-----------------------------------------------------------*/ ++yydefault: ++ yyn = yydefact[yystate]; ++ if (yyn == 0) ++ goto yyerrlab; ++ goto yyreduce; ++ ++ ++/*-----------------------------. ++| yyreduce -- Do a reduction. | ++`-----------------------------*/ ++yyreduce: ++ /* yyn is the number of a rule to reduce with. */ ++ yylen = yyr2[yyn]; ++ ++ /* If YYLEN is nonzero, implement the default value of the action: ++ `$$ = $1'. ++ ++ Otherwise, the following line sets YYVAL to garbage. ++ This behavior is undocumented and Bison ++ users should not rely upon it. Assigning to YYVAL ++ unconditionally makes the parser a bit smaller, and it avoids a ++ GCC warning that YYVAL may be used uninitialized. */ ++ yyval = yyvsp[1-yylen]; ++ ++ ++ YY_REDUCE_PRINT (yyn); ++ switch (yyn) ++ { ++ case 8: ++ ++ { zconf_error("unexpected end statement"); ;} ++ break; ++ ++ case 9: ++ ++ { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;} ++ break; ++ ++ case 10: ++ ++ { ++ zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name); ++;} ++ break; ++ ++ case 11: ++ ++ { zconf_error("invalid statement"); ;} ++ break; ++ ++ case 25: ++ ++ { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;} ++ break; ++ ++ case 26: ++ ++ { zconf_error("invalid option"); ;} ++ break; ++ ++ case 27: ++ ++ { ++ struct symbol *sym = sym_lookup((yyvsp[-1].string), 0); ++ sym->flags |= SYMBOL_OPTIONAL; ++ menu_add_entry(sym); ++ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); ++;} ++ break; ++ ++ case 28: ++ ++ { ++ menu_end_entry(); ++ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 29: ++ ++ { ++ struct symbol *sym = sym_lookup((yyvsp[-1].string), 0); ++ sym->flags |= SYMBOL_OPTIONAL; ++ menu_add_entry(sym); ++ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); ++;} ++ break; ++ ++ case 30: ++ ++ { ++ if (current_entry->prompt) ++ current_entry->prompt->type = P_MENU; ++ else ++ zconfprint("warning: menuconfig statement without prompt"); ++ menu_end_entry(); ++ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 38: ++ ++ { ++ menu_set_type((yyvsp[-2].id)->stype); ++ printd(DEBUG_PARSE, "%s:%d:type(%u)\n", ++ zconf_curname(), zconf_lineno(), ++ (yyvsp[-2].id)->stype); ++;} ++ break; ++ ++ case 39: ++ ++ { ++ menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 40: ++ ++ { ++ menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr)); ++ if ((yyvsp[-3].id)->stype != S_UNKNOWN) ++ menu_set_type((yyvsp[-3].id)->stype); ++ printd(DEBUG_PARSE, "%s:%d:default(%u)\n", ++ zconf_curname(), zconf_lineno(), ++ (yyvsp[-3].id)->stype); ++;} ++ break; ++ ++ case 41: ++ ++ { ++ menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 42: ++ ++ { ++ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 45: ++ ++ { ++ struct kconf_id *id = kconf_id_lookup((yyvsp[-1].string), strlen((yyvsp[-1].string))); ++ if (id && id->flags & TF_OPTION) ++ menu_add_option(id->token, (yyvsp[0].string)); ++ else ++ zconfprint("warning: ignoring unknown option %s", (yyvsp[-1].string)); ++ free((yyvsp[-1].string)); ++;} ++ break; ++ ++ case 46: ++ ++ { (yyval.string) = NULL; ;} ++ break; ++ ++ case 47: ++ ++ { (yyval.string) = (yyvsp[0].string); ;} ++ break; ++ ++ case 48: ++ ++ { ++ struct symbol *sym = sym_lookup(NULL, 0); ++ sym->flags |= SYMBOL_CHOICE; ++ menu_add_entry(sym); ++ menu_add_expr(P_CHOICE, NULL, NULL); ++ printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 49: ++ ++ { ++ (yyval.menu) = menu_add_menu(); ++;} ++ break; ++ ++ case 50: ++ ++ { ++ if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) { ++ menu_end_menu(); ++ printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); ++ } ++;} ++ break; ++ ++ case 58: ++ ++ { ++ menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 59: ++ ++ { ++ if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) { ++ menu_set_type((yyvsp[-2].id)->stype); ++ printd(DEBUG_PARSE, "%s:%d:type(%u)\n", ++ zconf_curname(), zconf_lineno(), ++ (yyvsp[-2].id)->stype); ++ } else ++ YYERROR; ++;} ++ break; ++ ++ case 60: ++ ++ { ++ current_entry->sym->flags |= SYMBOL_OPTIONAL; ++ printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 61: ++ ++ { ++ if ((yyvsp[-3].id)->stype == S_UNKNOWN) { ++ menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:default\n", ++ zconf_curname(), zconf_lineno()); ++ } else ++ YYERROR; ++;} ++ break; ++ ++ case 64: ++ ++ { ++ printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); ++ menu_add_entry(NULL); ++ menu_add_dep((yyvsp[-1].expr)); ++ (yyval.menu) = menu_add_menu(); ++;} ++ break; ++ ++ case 65: ++ ++ { ++ if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) { ++ menu_end_menu(); ++ printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); ++ } ++;} ++ break; ++ ++ case 71: ++ ++ { ++ menu_add_entry(NULL); ++ menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL); ++ printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 72: ++ ++ { ++ (yyval.menu) = menu_add_menu(); ++;} ++ break; ++ ++ case 73: ++ ++ { ++ if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) { ++ menu_end_menu(); ++ printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); ++ } ++;} ++ break; ++ ++ case 79: ++ ++ { ++ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); ++ zconf_nextfile((yyvsp[-1].string)); ++;} ++ break; ++ ++ case 80: ++ ++ { ++ menu_add_entry(NULL); ++ menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL); ++ printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 81: ++ ++ { ++ menu_end_entry(); ++;} ++ break; ++ ++ case 82: ++ ++ { ++ printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); ++ zconf_starthelp(); ++;} ++ break; ++ ++ case 83: ++ ++ { ++ current_entry->sym->help = (yyvsp[0].string); ++;} ++ break; ++ ++ case 88: ++ ++ { ++ menu_add_dep((yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 89: ++ ++ { ++ menu_add_dep((yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 90: ++ ++ { ++ menu_add_dep((yyvsp[-1].expr)); ++ printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); ++;} ++ break; ++ ++ case 92: ++ ++ { ++ menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr)); ++;} ++ break; ++ ++ case 95: ++ ++ { (yyval.id) = (yyvsp[-1].id); ;} ++ break; ++ ++ case 96: ++ ++ { (yyval.id) = (yyvsp[-1].id); ;} ++ break; ++ ++ case 97: ++ ++ { (yyval.id) = (yyvsp[-1].id); ;} ++ break; ++ ++ case 100: ++ ++ { (yyval.expr) = NULL; ;} ++ break; ++ ++ case 101: ++ ++ { (yyval.expr) = (yyvsp[0].expr); ;} ++ break; ++ ++ case 102: ++ ++ { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;} ++ break; ++ ++ case 103: ++ ++ { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} ++ break; ++ ++ case 104: ++ ++ { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} ++ break; ++ ++ case 105: ++ ++ { (yyval.expr) = (yyvsp[-1].expr); ;} ++ break; ++ ++ case 106: ++ ++ { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;} ++ break; ++ ++ case 107: ++ ++ { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} ++ break; ++ ++ case 108: ++ ++ { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} ++ break; ++ ++ case 109: ++ ++ { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;} ++ break; ++ ++ case 110: ++ ++ { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;} ++ break; ++ ++ ++ default: break; ++ } ++ ++/* Line 1126 of yacc.c. */ ++ ++ ++ yyvsp -= yylen; ++ yyssp -= yylen; ++ ++ ++ YY_STACK_PRINT (yyss, yyssp); ++ ++ *++yyvsp = yyval; ++ ++ ++ /* Now `shift' the result of the reduction. Determine what state ++ that goes to, based on the state we popped back to and the rule ++ number reduced by. */ ++ ++ yyn = yyr1[yyn]; ++ ++ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; ++ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) ++ yystate = yytable[yystate]; ++ else ++ yystate = yydefgoto[yyn - YYNTOKENS]; ++ ++ goto yynewstate; ++ ++ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ ++yyerrlab: ++ /* If not already recovering from an error, report this error. */ ++ if (!yyerrstatus) ++ { ++ ++yynerrs; ++#if YYERROR_VERBOSE ++ yyn = yypact[yystate]; ++ ++ if (YYPACT_NINF < yyn && yyn < YYLAST) ++ { ++ int yytype = YYTRANSLATE (yychar); ++ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); ++ YYSIZE_T yysize = yysize0; ++ YYSIZE_T yysize1; ++ int yysize_overflow = 0; ++ char *yymsg = 0; ++# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 ++ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; ++ int yyx; ++ ++#if 0 ++ /* This is so xgettext sees the translatable formats that are ++ constructed on the fly. */ ++ YY_("syntax error, unexpected %s"); ++ YY_("syntax error, unexpected %s, expecting %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); ++#endif ++ char *yyfmt; ++ char const *yyf; ++ static char const yyunexpected[] = "syntax error, unexpected %s"; ++ static char const yyexpecting[] = ", expecting %s"; ++ static char const yyor[] = " or %s"; ++ char yyformat[sizeof yyunexpected ++ + sizeof yyexpecting - 1 ++ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) ++ * (sizeof yyor - 1))]; ++ char const *yyprefix = yyexpecting; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 1; ++ ++ yyarg[0] = yytname[yytype]; ++ yyfmt = yystpcpy (yyformat, yyunexpected); ++ ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) ++ { ++ yycount = 1; ++ yysize = yysize0; ++ yyformat[sizeof yyunexpected - 1] = '\0'; ++ break; ++ } ++ yyarg[yycount++] = yytname[yyx]; ++ yysize1 = yysize + yytnamerr (0, yytname[yyx]); ++ yysize_overflow |= yysize1 < yysize; ++ yysize = yysize1; ++ yyfmt = yystpcpy (yyfmt, yyprefix); ++ yyprefix = yyor; ++ } ++ ++ yyf = YY_(yyformat); ++ yysize1 = yysize + yystrlen (yyf); ++ yysize_overflow |= yysize1 < yysize; ++ yysize = yysize1; ++ ++ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) ++ yymsg = (char *) YYSTACK_ALLOC (yysize); ++ if (yymsg) ++ { ++ /* Avoid sprintf, as that infringes on the user's name space. ++ Don't have undefined behavior even if the translation ++ produced a string with the wrong number of "%s"s. */ ++ char *yyp = yymsg; ++ int yyi = 0; ++ while ((*yyp = *yyf)) ++ { ++ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) ++ { ++ yyp += yytnamerr (yyp, yyarg[yyi++]); ++ yyf += 2; ++ } ++ else ++ { ++ yyp++; ++ yyf++; ++ } ++ } ++ yyerror (yymsg); ++ YYSTACK_FREE (yymsg); ++ } ++ else ++ { ++ yyerror (YY_("syntax error")); ++ goto yyexhaustedlab; ++ } ++ } ++ else ++#endif /* YYERROR_VERBOSE */ ++ yyerror (YY_("syntax error")); ++ } ++ ++ ++ ++ if (yyerrstatus == 3) ++ { ++ /* If just tried and failed to reuse look-ahead token after an ++ error, discard it. */ ++ ++ if (yychar <= YYEOF) ++ { ++ /* Return failure if at end of input. */ ++ if (yychar == YYEOF) ++ YYABORT; ++ } ++ else ++ { ++ yydestruct ("Error: discarding", yytoken, &yylval); ++ yychar = YYEMPTY; ++ } ++ } ++ ++ /* Else will try to reuse look-ahead token after shifting the error ++ token. */ ++ goto yyerrlab1; ++ ++ ++/*---------------------------------------------------. ++| yyerrorlab -- error raised explicitly by YYERROR. | ++`---------------------------------------------------*/ ++yyerrorlab: ++ ++ /* Pacify compilers like GCC when the user code never invokes ++ YYERROR and the label yyerrorlab therefore never appears in user ++ code. */ ++ if (0) ++ goto yyerrorlab; ++ ++yyvsp -= yylen; ++ yyssp -= yylen; ++ yystate = *yyssp; ++ goto yyerrlab1; ++ ++ ++/*-------------------------------------------------------------. ++| yyerrlab1 -- common code for both syntax error and YYERROR. | ++`-------------------------------------------------------------*/ ++yyerrlab1: ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ ++ for (;;) ++ { ++ yyn = yypact[yystate]; ++ if (yyn != YYPACT_NINF) ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } ++ ++ /* Pop the current state because it cannot handle the error token. */ ++ if (yyssp == yyss) ++ YYABORT; ++ ++ ++ yydestruct ("Error: popping", yystos[yystate], yyvsp); ++ YYPOPSTACK; ++ yystate = *yyssp; ++ YY_STACK_PRINT (yyss, yyssp); ++ } ++ ++ if (yyn == YYFINAL) ++ YYACCEPT; ++ ++ *++yyvsp = yylval; ++ ++ ++ /* Shift the error token. */ ++ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); ++ ++ yystate = yyn; ++ goto yynewstate; ++ ++ ++/*-------------------------------------. ++| yyacceptlab -- YYACCEPT comes here. | ++`-------------------------------------*/ ++yyacceptlab: ++ yyresult = 0; ++ goto yyreturn; ++ ++/*-----------------------------------. ++| yyabortlab -- YYABORT comes here. | ++`-----------------------------------*/ ++yyabortlab: ++ yyresult = 1; ++ goto yyreturn; ++ ++#ifndef yyoverflow ++/*-------------------------------------------------. ++| yyexhaustedlab -- memory exhaustion comes here. | ++`-------------------------------------------------*/ ++yyexhaustedlab: ++ yyerror (YY_("memory exhausted")); ++ yyresult = 2; ++ /* Fall through. */ ++#endif ++ ++yyreturn: ++ if (yychar != YYEOF && yychar != YYEMPTY) ++ yydestruct ("Cleanup: discarding lookahead", ++ yytoken, &yylval); ++ while (yyssp != yyss) ++ { ++ yydestruct ("Cleanup: popping", ++ yystos[*yyssp], yyvsp); ++ YYPOPSTACK; ++ } ++#ifndef yyoverflow ++ if (yyss != yyssa) ++ YYSTACK_FREE (yyss); ++#endif ++ return yyresult; ++} ++ ++ ++ ++ ++ ++void conf_parse(const char *name) ++{ ++ struct symbol *sym; ++ int i; ++ ++ zconf_initscan(name); ++ ++ sym_init(); ++ menu_init(); ++ modules_sym = sym_lookup(NULL, 0); ++ modules_sym->type = S_BOOLEAN; ++ modules_sym->flags |= SYMBOL_AUTO; ++ rootmenu.prompt = menu_add_prompt(P_MENU, PROJECT_NAME" Configuration", NULL); ++ ++#if YYDEBUG ++ if (getenv("ZCONF_DEBUG")) ++ zconfdebug = 1; ++#endif ++ zconfparse(); ++ if (zconfnerrs) ++ exit(1); ++ if (!modules_sym->prop) { ++ struct property *prop; ++ ++ prop = prop_alloc(P_DEFAULT, modules_sym); ++ prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); ++ } ++ menu_finalize(&rootmenu); ++ for_all_symbols(i, sym) { ++ sym_check_deps(sym); ++ } ++ ++ sym_change_count = 1; ++} ++ ++const char *zconf_tokenname(int token) ++{ ++ switch (token) { ++ case T_MENU: return "menu"; ++ case T_ENDMENU: return "endmenu"; ++ case T_CHOICE: return "choice"; ++ case T_ENDCHOICE: return "endchoice"; ++ case T_IF: return "if"; ++ case T_ENDIF: return "endif"; ++ case T_DEPENDS: return "depends"; ++ } ++ return ""; ++} ++ ++static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) ++{ ++ if (id->token != endtoken) { ++ zconf_error("unexpected '%s' within %s block", ++ kconf_id_strings + id->name, zconf_tokenname(starttoken)); ++ zconfnerrs++; ++ return false; ++ } ++ if (current_menu->file != current_file) { ++ zconf_error("'%s' in different file than '%s'", ++ kconf_id_strings + id->name, zconf_tokenname(starttoken)); ++ fprintf(stderr, "%s:%d: location of the '%s'\n", ++ current_menu->file->name, current_menu->lineno, ++ zconf_tokenname(starttoken)); ++ zconfnerrs++; ++ return false; ++ } ++ return true; ++} ++ ++static void zconfprint(const char *err, ...) ++{ ++ va_list ap; ++ ++ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); ++ va_start(ap, err); ++ vfprintf(stderr, err, ap); ++ va_end(ap); ++ fprintf(stderr, "\n"); ++} ++ ++static void zconf_error(const char *err, ...) ++{ ++ va_list ap; ++ ++ zconfnerrs++; ++ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); ++ va_start(ap, err); ++ vfprintf(stderr, err, ap); ++ va_end(ap); ++ fprintf(stderr, "\n"); ++} ++ ++static void zconferror(const char *err) ++{ ++#if YYDEBUG ++ fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); ++#endif ++} ++ ++void print_quoted_string(FILE *out, const char *str) ++{ ++ const char *p; ++ int len; ++ ++ putc('"', out); ++ while ((p = strchr(str, '"'))) { ++ len = p - str; ++ if (len) ++ fprintf(out, "%.*s", len, str); ++ fputs("\\\"", out); ++ str = p + 1; ++ } ++ fputs(str, out); ++ putc('"', out); ++} ++ ++void print_symbol(FILE *out, struct menu *menu) ++{ ++ struct symbol *sym = menu->sym; ++ struct property *prop; ++ ++ if (sym_is_choice(sym)) ++ fprintf(out, "choice\n"); ++ else ++ fprintf(out, "config %s\n", sym->name); ++ switch (sym->type) { ++ case S_BOOLEAN: ++ fputs(" boolean\n", out); ++ break; ++ case S_TRISTATE: ++ fputs(" tristate\n", out); ++ break; ++ case S_STRING: ++ fputs(" string\n", out); ++ break; ++ case S_INT: ++ fputs(" integer\n", out); ++ break; ++ case S_HEX: ++ fputs(" hex\n", out); ++ break; ++ default: ++ fputs(" ???\n", out); ++ break; ++ } ++ for (prop = sym->prop; prop; prop = prop->next) { ++ if (prop->menu != menu) ++ continue; ++ switch (prop->type) { ++ case P_PROMPT: ++ fputs(" prompt ", out); ++ print_quoted_string(out, prop->text); ++ if (!expr_is_yes(prop->visible.expr)) { ++ fputs(" if ", out); ++ expr_fprint(prop->visible.expr, out); ++ } ++ fputc('\n', out); ++ break; ++ case P_DEFAULT: ++ fputs( " default ", out); ++ expr_fprint(prop->expr, out); ++ if (!expr_is_yes(prop->visible.expr)) { ++ fputs(" if ", out); ++ expr_fprint(prop->visible.expr, out); ++ } ++ fputc('\n', out); ++ break; ++ case P_CHOICE: ++ fputs(" #choice value\n", out); ++ break; ++ default: ++ fprintf(out, " unknown prop %d!\n", prop->type); ++ break; ++ } ++ } ++ if (sym->help) { ++ int len = strlen(sym->help); ++ while (sym->help[--len] == '\n') ++ sym->help[len] = 0; ++ fprintf(out, " help\n%s\n", sym->help); ++ } ++ fputc('\n', out); ++} ++ ++void zconfdump(FILE *out) ++{ ++ struct property *prop; ++ struct symbol *sym; ++ struct menu *menu; ++ ++ menu = rootmenu.list; ++ while (menu) { ++ if ((sym = menu->sym)) ++ print_symbol(out, menu); ++ else if ((prop = menu->prompt)) { ++ switch (prop->type) { ++ case P_COMMENT: ++ fputs("\ncomment ", out); ++ print_quoted_string(out, prop->text); ++ fputs("\n", out); ++ break; ++ case P_MENU: ++ fputs("\nmenu ", out); ++ print_quoted_string(out, prop->text); ++ fputs("\n", out); ++ break; ++ default: ++ ; ++ } ++ if (!expr_is_yes(prop->visible.expr)) { ++ fputs(" depends ", out); ++ expr_fprint(prop->visible.expr, out); ++ fputc('\n', out); ++ } ++ fputs("\n", out); ++ } ++ ++ if (menu->list) ++ menu = menu->list; ++ else if (menu->next) ++ menu = menu->next; ++ else while ((menu = menu->parent)) { ++ if (menu->prompt && menu->prompt->type == P_MENU) ++ fputs("\nendmenu\n", out); ++ if (menu->next) { ++ menu = menu->next; ++ break; ++ } ++ } ++ } ++} ++ ++#include "lex.zconf.c" ++#include "util.c" ++#include "confdata.c" ++#include "expr.c" ++#include "symbol.c" ++#include "menu.c" ++ ++ +Binary files /dev/null and uclibc/kconfig/conf differ diff -r 41d57d7ba5e1 -r 31ebe0042324 sources/patches/uClibc-usenewkconfig.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/patches/uClibc-usenewkconfig.patch Wed Oct 31 13:56:03 2007 -0500 @@ -0,0 +1,90 @@ +diff -r 34a75fcd5a9b Makefile.in +--- a/Makefile.in Sun Mar 11 23:06:39 2007 +0000 ++++ b/Makefile.in Fri Mar 16 15:47:35 2007 -0400 +@@ -36,7 +36,7 @@ include $(top_srcdir)extra/locale/Makefi + # last included to catch all the objects added by others (locales/threads) + include $(top_srcdir)libc/Makefile.in + +-include/bits/uClibc_config.h: extra/config/conf .config ++include/bits/uClibc_config.h: kconfig/conf .config + $(Q)$(INSTALL) -d $(dir $@) + $(Q)@$< -o $(top_srcdir)extra/Configs/Config.in + +@@ -290,42 +291,7 @@ include/bits: + include/bits: + $(INSTALL) -d include/bits + +-# configuration +-# --------------------------------------------------------------------------- +-extra/config/conf extra/config/mconf: include/bits +- $(Q)$(MAKE) -C extra/config $(notdir $@) +- +-menuconfig: extra/config/mconf include/bits +- $(Q)./extra/config/mconf extra/Configs/Config.in +- +-config: extra/config/conf include/bits +- $(Q)./extra/config/conf extra/Configs/Config.in +- +-oldconfig: extra/config/conf include/bits +- $(Q)./extra/config/conf -o extra/Configs/Config.in +- +-silentoldconfig: extra/config/conf include/bits +- $(Q)./extra/config/conf -s extra/Configs/Config.in +- +-randconfig: extra/config/conf include/bits +- $(Q)./extra/config/conf -r extra/Configs/Config.in +- +-allyesconfig: extra/config/conf include/bits +- $(Q)./extra/config/conf -y extra/Configs/Config.in +- sed -i -e "s/^DODEBUG=.*/# DODEBUG is not set/" .config +- sed -i -e "s/^DOASSERTS=.*/# DOASSERTS is not set/" .config +- sed -i -e "s/^SUPPORT_LD_DEBUG_EARLY=.*/# SUPPORT_LD_DEBUG_EARLY is not set/" .config +- sed -i -e "s/^SUPPORT_LD_DEBUG=.*/# SUPPORT_LD_DEBUG is not set/" .config +- sed -i -e "s/^UCLIBC_MJN3_ONLY=.*/# UCLIBC_MJN3_ONLY is not set/" .config +- $(Q)./extra/config/conf -o extra/Configs/Config.in +- +-allnoconfig: extra/config/conf include/bits +- $(Q)./extra/config/conf -n extra/Configs/Config.in +- +-defconfig: extra/config/conf include/bits +- $(Q)./extra/config/conf -d extra/Configs/Config.in +- +-clean: ++clean:: + $(Q)$(RM) -r lib include/bits + $(RM) lib*/*.a ldso/*/*.a libpthread/*/*.a + $(RM) include/fpu_control.h include/dl-osinfo.h include/hp-timing.h +@@ -349,7 +315,6 @@ distclean: clean + -find . \( -name core -o -name \*.orig -o -name \*~ \) -exec $(RM) {} \; + $(RM) .config .config.old .config.cmd + $(RM) extra/locale/*.tgz +- $(MAKE) -C extra/config distclean + + dist release: + $(RM) -r ../uClibc-$(VERSION) ../uClibc-$(VERSION).tar.bz2 +@@ -359,3 +324,5 @@ dist release: + + test check: + $(Q)$(MAKE) -C test ++ ++include $(top_srcdir)kconfig/Makefile +diff -r 34a75fcd5a9b Makerules +--- a/Makerules Sun Mar 11 23:06:39 2007 +0000 ++++ b/Makerules Mon Mar 12 15:35:07 2007 -0400 +@@ -279,7 +279,7 @@ CRTS_COMPAT := + $(do_ar) + + .PHONY: dummy create +-clean: objclean-y headers_clean-y ++clean:: objclean-y headers_clean-y + + objclean-y: $(objclean-y) + headers_clean-y: $(headers_clean-y) +diff -r 34a75fcd5a9b extra/Makefile.in +--- a/extra/Makefile.in Sun Mar 11 23:06:39 2007 +0000 ++++ b/extra/Makefile.in Mon Mar 12 15:47:38 2007 -0400 +@@ -6,4 +6,3 @@ + # + + include $(top_srcdir)extra/locale/Makefile.in +-include $(top_srcdir)extra/config/Makefile.in