From 2d523c23175b8e8772c2e223d92513f836cde8a6 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sat, 9 Oct 2004 01:06:03 +0000 Subject: [PATCH] Major buildroot facelift, step one. -Erik --- .defconfig | 56 + Config.in | 70 + Makefile | 413 +- make/bzip2.mk | 2 +- make/gzip.mk | 2 +- make/mkdosfs.mk | 2 +- make/newt.mk | 2 +- make/sed.mk | 137 - make/slang.mk | 2 +- make/zlib.mk | 2 +- package/Config.in | 23 + package/Makefile.in | 60 + package/busybox/Config.in | 11 + package/busybox/Makefile.in | 3 + {sources => package/busybox}/busybox.config | 0 {make => package/busybox}/busybox.mk | 6 +- package/config/.cvsignore | 8 + package/config/Kconfig-language.txt | 255 ++ package/config/Makefile | 112 + package/config/checklist.c | 372 ++ package/config/colors.h | 161 + package/config/conf.c | 583 +++ package/config/confdata.c | 447 ++ package/config/dialog.h | 196 + package/config/expr.c | 1089 +++++ package/config/expr.h | 193 + package/config/inputbox.c | 240 ++ package/config/lex.zconf.c_shipped | 3688 +++++++++++++++++ package/config/lkc.h | 113 + package/config/lkc_proto.h | 39 + package/config/mconf.c | 713 ++++ package/config/menu.c | 431 ++ package/config/menubox.c | 436 ++ package/config/msgbox.c | 85 + package/config/symbol.c | 771 ++++ package/config/textbox.c | 556 +++ package/config/util.c | 375 ++ package/config/yesno.c | 118 + package/config/zconf.l | 366 ++ package/config/zconf.tab.c_shipped | 2127 ++++++++++ package/config/zconf.tab.h_shipped | 125 + package/config/zconf.y | 687 +++ package/sed/Config.in | 8 + package/sed/Makefile.in | 3 + package/sed/sed.mk | 83 + toolchain/Config.in | 62 + toolchain/Makefile.in | 7 + .../binutils/2.14.90.0.6/001-debian.patch | 0 .../2.14.90.0.6/100-uclibc-conf.patch | 0 .../2.14.90.0.6/200-build_modules.patch | 0 .../binutils/2.14.90.0.6/210-cflags.patch | 0 .../binutils/2.14.90.0.7/001-debian.patch | 0 .../2.14.90.0.7/100-uclibc-conf.patch | 0 .../2.14.90.0.7/200-build_modules.patch | 0 .../binutils/2.14.90.0.7/210-cflags.patch | 0 .../2.14.90.0.7/600-arm-textrel.patch | 0 .../binutils/2.14.90.0.8/001-debian.patch | 0 .../2.14.90.0.8/100-uclibc-conf.patch | 0 .../2.14.90.0.8/600-arm-textrel.patch | 0 .../2.15.90.0.1.1/100-uclibc-conf.patch | 0 .../2.15.90.0.1.1/600-arm-textrel.patch | 0 .../2.15.90.0.1/100-uclibc-conf.patch | 0 .../2.15.90.0.1/600-arm-textrel.patch | 0 .../2.15.90.0.2/100-uclibc-conf.patch | 0 .../2.15.90.0.2/600-arm-textrel.patch | 0 .../2.15.90.0.3/100-uclibc-conf.patch | 0 .../binutils/2.15.90.0.3/210-cflags.patch | 0 .../2.15.90.0.3/500-branch-likely.patch | 0 .../2.15.90.0.3/600-arm-textrel.patch | 0 .../2.15.91.0.1/100-uclibc-conf.patch | 0 .../2.15.91.0.1/600-arm-textrel.patch | 0 .../2.15.91.0.2/100-uclibc-conf.patch | 0 .../2.15.91.0.2/500-branch-likely.patch | 0 .../2.15.91.0.2/600-arm-textrel.patch | 0 .../700-binutils-20040817-linkonce.patch | 0 .../701-binutils-dup-sections.patch | 0 .../702-binutils-skip-comments.patch | 0 .../2.15.92.0.2/100-uclibc-conf.patch | 0 .../2.15.92.0.2/600-arm-textrel.patch | 0 .../702-binutils-skip-comments.patch | 0 .../binutils/2.15/100-uclibc-conf.patch | 0 .../binutils/2.15/600-arm-textrel.patch | 0 toolchain/binutils/Config.in | 57 + toolchain/binutils/Makefile.in | 2 + .../binutils/binutils.mk | 8 +- toolchain/ccache/Config.in | 14 + toolchain/ccache/Makefile.in | 3 + {make => toolchain/ccache}/ccache.mk | 0 .../gcc/2.95/050-debian-subset.patch | Bin .../gcc/2.95/050-debian-subset.patch.bz2 | Bin 0 -> 125297 bytes .../gcc/2.95/100-uclibc-conf.patch | 0 .../gcc/3.3.3/100-uclibc-conf.patch | 0 .../gcc/3.3.3/110-uclibc-conf.patch | 0 .../gcc/3.3.3/120-softfloat.patch | 0 .../gcc/3.3.3/200-uclibc-locale.patch | 0 .../gcc/3.3.3/500-loop.patch | 0 .../gcc/3.3.4/100-uclibc-conf.patch | 0 .../gcc/3.3.4/110-uclibc-conf.patch | 0 .../gcc/3.3.4/120-softfloat.patch | 0 .../gcc/3.3.4/200-uclibc-locale.patch | 0 .../gcc/3.3.4/specs-arm-soft-float | 0 .../gcc/3.3.4/specs-mips-soft-float | 0 .../gcc/3.3.4/specs-mipsel-soft-float | 0 .../gcc/3.3.4/specs-powerpc-soft-float | 0 .../gcc/3.4.0/100-uclibc-conf.patch | 0 .../gcc/3.4.0/200-uclibc-locale.patch | 0 .../gcc/3.4.0/arm-softfloat.patch.conditional | 0 .../gcc/3.4.1/100-uclibc-conf.patch | 0 .../gcc/3.4.1/200-uclibc-locale.patch | 0 .../gcc/3.4.1/400-mips-delay-slot.patch | 0 .../gcc/3.4.1/800-arm-bigendian.patch | 0 .../gcc/3.4.1/810-arm-bigendian-uclibc.patch | 0 .../gcc/3.4.1/arm-softfloat.patch.conditional | 0 .../gcc/3.4.2/100-uclibc-conf.patch | 0 .../gcc/3.4.2/200-uclibc-locale.patch | 0 .../gcc/3.4.2/400-mips-pr17565.patch | 0 .../gcc/3.4.2/401-ppc-eabi-typo.patch | 0 .../3.4.2/600-gcc34-arm-ldm-peephole.patch | 0 .../gcc/3.4.2/601-gcc34-arm-ldm.patch | 0 .../3.4.2/602-sdk-libstdc++-includes.patch | 0 .../gcc/3.4.2/700-pr15068-fix.patch | 0 .../gcc/3.4.2/800-arm-bigendian.patch | 0 .../gcc/3.4.2/810-arm-bigendian-uclibc.patch | 0 .../gcc/3.4.2/arm-softfloat.patch.conditional | 0 toolchain/gcc/Config.in | 67 + toolchain/gcc/Makefile.in | 27 + .../gcc}/STLport-4.5.3.patch | 0 {make => toolchain/gcc}/gcc-uclibc-2.95.mk | 2 +- {make => toolchain/gcc}/gcc-uclibc-3.x.mk | 14 +- .../gcc}/i386-gcc-soft-float.patch | 0 .../gdb/5.3/050-debian-subset.patch | 0 .../gdb/5.3/100-uclibc.patch | 0 .../gdb/6.1.1/100-uclibc-conf.patch | 0 .../gdb/6.1.1/200-uclibc-readline-conf.patch | 0 .../gdb/6.2.1/100-uclibc-conf.patch | 0 .../gdb/6.2.1/200-uclibc-readline-conf.patch | 0 .../gdb/6.2/100-uclibc-conf.patch | 0 .../gdb/6.2/200-uclibc-readline-conf.patch | 0 toolchain/gdb/Config.in | 45 + toolchain/gdb/Makefile.in | 10 + {make => toolchain/gdb}/gdb.mk | 0 toolchain/kernel-headers/Config.in | 25 + toolchain/kernel-headers/Makefile.in | 3 + .../kernel-headers}/kernel-headers.mk | 2 +- toolchain/uClibc/Config.in | 22 + {sources => toolchain/uClibc}/uClibc.config | 7 +- .../uClibc}/uClibc.config-locale | 0 {make => toolchain/uClibc}/uclibc.mk | 17 +- 148 files changed, 15085 insertions(+), 480 deletions(-) create mode 100644 .defconfig create mode 100644 Config.in delete mode 100644 make/sed.mk create mode 100644 package/Config.in create mode 100644 package/Makefile.in create mode 100644 package/busybox/Config.in create mode 100644 package/busybox/Makefile.in rename {sources => package/busybox}/busybox.config (100%) rename {make => package/busybox}/busybox.mk (91%) create mode 100644 package/config/.cvsignore create mode 100644 package/config/Kconfig-language.txt create mode 100644 package/config/Makefile create mode 100644 package/config/checklist.c create mode 100644 package/config/colors.h create mode 100644 package/config/conf.c create mode 100644 package/config/confdata.c create mode 100644 package/config/dialog.h create mode 100644 package/config/expr.c create mode 100644 package/config/expr.h create mode 100644 package/config/inputbox.c create mode 100644 package/config/lex.zconf.c_shipped create mode 100644 package/config/lkc.h create mode 100644 package/config/lkc_proto.h create mode 100644 package/config/mconf.c create mode 100644 package/config/menu.c create mode 100644 package/config/menubox.c create mode 100644 package/config/msgbox.c create mode 100644 package/config/symbol.c create mode 100644 package/config/textbox.c create mode 100644 package/config/util.c create mode 100644 package/config/yesno.c create mode 100644 package/config/zconf.l create mode 100644 package/config/zconf.tab.c_shipped create mode 100644 package/config/zconf.tab.h_shipped create mode 100644 package/config/zconf.y create mode 100644 package/sed/Config.in create mode 100644 package/sed/Makefile.in create mode 100644 package/sed/sed.mk create mode 100644 toolchain/Config.in create mode 100644 toolchain/Makefile.in rename {sources => toolchain}/binutils/2.14.90.0.6/001-debian.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.6/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.6/200-build_modules.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.6/210-cflags.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.7/001-debian.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.7/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.7/200-build_modules.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.7/210-cflags.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.7/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.8/001-debian.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.8/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.14.90.0.8/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.1.1/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.1.1/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.1/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.1/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.2/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.2/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.3/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.3/210-cflags.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.3/500-branch-likely.patch (100%) rename {sources => toolchain}/binutils/2.15.90.0.3/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.1/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.1/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.2/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.2/500-branch-likely.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.2/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.2/700-binutils-20040817-linkonce.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.2/701-binutils-dup-sections.patch (100%) rename {sources => toolchain}/binutils/2.15.91.0.2/702-binutils-skip-comments.patch (100%) rename {sources => toolchain}/binutils/2.15.92.0.2/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15.92.0.2/600-arm-textrel.patch (100%) rename {sources => toolchain}/binutils/2.15.92.0.2/702-binutils-skip-comments.patch (100%) rename {sources => toolchain}/binutils/2.15/100-uclibc-conf.patch (100%) rename {sources => toolchain}/binutils/2.15/600-arm-textrel.patch (100%) create mode 100644 toolchain/binutils/Config.in create mode 100644 toolchain/binutils/Makefile.in rename make/binutils-uclibc.mk => toolchain/binutils/binutils.mk (94%) create mode 100644 toolchain/ccache/Config.in create mode 100644 toolchain/ccache/Makefile.in rename {make => toolchain/ccache}/ccache.mk (100%) rename {sources => toolchain}/gcc/2.95/050-debian-subset.patch (100%) create mode 100644 toolchain/gcc/2.95/050-debian-subset.patch.bz2 rename {sources => toolchain}/gcc/2.95/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.3.3/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.3.3/110-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.3.3/120-softfloat.patch (100%) rename {sources => toolchain}/gcc/3.3.3/200-uclibc-locale.patch (100%) rename {sources => toolchain}/gcc/3.3.3/500-loop.patch (100%) rename {sources => toolchain}/gcc/3.3.4/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.3.4/110-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.3.4/120-softfloat.patch (100%) rename {sources => toolchain}/gcc/3.3.4/200-uclibc-locale.patch (100%) rename {sources => toolchain}/gcc/3.3.4/specs-arm-soft-float (100%) rename {sources => toolchain}/gcc/3.3.4/specs-mips-soft-float (100%) rename {sources => toolchain}/gcc/3.3.4/specs-mipsel-soft-float (100%) rename {sources => toolchain}/gcc/3.3.4/specs-powerpc-soft-float (100%) rename {sources => toolchain}/gcc/3.4.0/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.4.0/200-uclibc-locale.patch (100%) rename {sources => toolchain}/gcc/3.4.0/arm-softfloat.patch.conditional (100%) rename {sources => toolchain}/gcc/3.4.1/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.4.1/200-uclibc-locale.patch (100%) rename {sources => toolchain}/gcc/3.4.1/400-mips-delay-slot.patch (100%) rename {sources => toolchain}/gcc/3.4.1/800-arm-bigendian.patch (100%) rename {sources => toolchain}/gcc/3.4.1/810-arm-bigendian-uclibc.patch (100%) rename {sources => toolchain}/gcc/3.4.1/arm-softfloat.patch.conditional (100%) rename {sources => toolchain}/gcc/3.4.2/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gcc/3.4.2/200-uclibc-locale.patch (100%) rename {sources => toolchain}/gcc/3.4.2/400-mips-pr17565.patch (100%) rename {sources => toolchain}/gcc/3.4.2/401-ppc-eabi-typo.patch (100%) rename {sources => toolchain}/gcc/3.4.2/600-gcc34-arm-ldm-peephole.patch (100%) rename {sources => toolchain}/gcc/3.4.2/601-gcc34-arm-ldm.patch (100%) rename {sources => toolchain}/gcc/3.4.2/602-sdk-libstdc++-includes.patch (100%) rename {sources => toolchain}/gcc/3.4.2/700-pr15068-fix.patch (100%) rename {sources => toolchain}/gcc/3.4.2/800-arm-bigendian.patch (100%) rename {sources => toolchain}/gcc/3.4.2/810-arm-bigendian-uclibc.patch (100%) rename {sources => toolchain}/gcc/3.4.2/arm-softfloat.patch.conditional (100%) create mode 100644 toolchain/gcc/Config.in create mode 100644 toolchain/gcc/Makefile.in rename {sources => toolchain/gcc}/STLport-4.5.3.patch (100%) rename {make => toolchain/gcc}/gcc-uclibc-2.95.mk (99%) rename {make => toolchain/gcc}/gcc-uclibc-3.x.mk (93%) rename {sources => toolchain/gcc}/i386-gcc-soft-float.patch (100%) rename {sources => toolchain}/gdb/5.3/050-debian-subset.patch (100%) rename {sources => toolchain}/gdb/5.3/100-uclibc.patch (100%) rename {sources => toolchain}/gdb/6.1.1/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gdb/6.1.1/200-uclibc-readline-conf.patch (100%) rename {sources => toolchain}/gdb/6.2.1/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gdb/6.2.1/200-uclibc-readline-conf.patch (100%) rename {sources => toolchain}/gdb/6.2/100-uclibc-conf.patch (100%) rename {sources => toolchain}/gdb/6.2/200-uclibc-readline-conf.patch (100%) create mode 100644 toolchain/gdb/Config.in create mode 100644 toolchain/gdb/Makefile.in rename {make => toolchain/gdb}/gdb.mk (100%) create mode 100644 toolchain/kernel-headers/Config.in create mode 100644 toolchain/kernel-headers/Makefile.in rename {make => toolchain/kernel-headers}/kernel-headers.mk (97%) create mode 100644 toolchain/uClibc/Config.in rename {sources => toolchain/uClibc}/uClibc.config (94%) rename {sources => toolchain/uClibc}/uClibc.config-locale (100%) rename {make => toolchain/uClibc}/uclibc.mk (91%) diff --git a/.defconfig b/.defconfig new file mode 100644 index 0000000000..daf12f7de1 --- /dev/null +++ b/.defconfig @@ -0,0 +1,56 @@ +# +# Automatically generated make config: don't edit +# +BR2_HAVE_DOT_CONFIG=y +# BR2_arm is not set +# BR2_armeb is not set +# BR2_cris is not set +BR2_i386=y +# BR2_m68k is not set +# BR2_mips is not set +# BR2_mipsel is not set +# BR2_powerpc is not set +# BR2_sh is not set +# BR2_sparc is not set +BR2_ARCH="i386" +BR2_WGET="wget --passive-ftp" + +# +# Toolchain Options +# +BR2_KERNEL_HEADERS_2_4=y +# BR2_KERNEL_HEADERS_2_6 is not set +BR2_DEFAULT_KERNEL_HEADERS="2.4.27" +BR2_UCLIBC_VERSION_SNAPSHOT=y +BR2_USE_UCLIBC_SNAPSHOT="snapshot" +# BR2_ENABLE_LOCALE is not set +# BR2_BINUTILS_VERSION_2_14_90_0_6 is not set +# BR2_BINUTILS_VERSION_2_14_90_0_7 is not set +# BR2_BINUTILS_VERSION_2_14_90_0_8 is not set +# BR2_BINUTILS_VERSION_2_15 is not set +# BR2_BINUTILS_VERSION_2_15_90_0_1 is not set +# BR2_BINUTILS_VERSION_2_15_90_0_1_1 is not set +# BR2_BINUTILS_VERSION_2_15_90_0_2 is not set +# BR2_BINUTILS_VERSION_2_15_90_0_3 is not set +# BR2_BINUTILS_VERSION_2_15_91_0_1 is not set +BR2_BINUTILS_VERSION_2_15_91_0_2=y +# BR2_BINUTILS_VERSION_2_15_92_0_2 is not set +BR2_BINUTILS_VERSION="2.15.91.0.2" +# BR2_GCC_VERSION_2_95 is not set +# BR2_GCC_VERSION_3_3_3 is not set +# BR2_GCC_VERSION_3_3_4 is not set +# BR2_GCC_VERSION_3_4_0 is not set +# BR2_GCC_VERSION_3_4_1 is not set +BR2_GCC_VERSION_3_4_2=y +BR2_GCC_VERSION="3.4.2" +BR2_GCC_USE_SJLJ_EXCEPTIONS="--enable-sjlj-exceptions" +BR2_EXTRA_GCC_CONFIG_OPTIONS="" +# BR2_INSTALL_LIBSTDCPP is not set +BR2_HOST_CCACHE=y +BR2_PACKAGE_CCACHE=y +# BR2_PACKAGE_GDB is not set +# BR2_PACKAGE_GDB_SERVER is not set +# BR2_HOST_GDB is not set +BR2_ENABLE_MULTILIB=y +BR2_LARGEFILE=y +BR2_TARGET_OPTIMIZATION="-Os -pipe" diff --git a/Config.in b/Config.in new file mode 100644 index 0000000000..be95fbbe52 --- /dev/null +++ b/Config.in @@ -0,0 +1,70 @@ +# + +mainmenu "Buildroot2 Configuration" + +config BR2_HAVE_DOT_CONFIG + bool + default y + +choice + prompt "Target Architecture" + default BR2_i386 + help + Stuff + +config BR2_arm + bool "arm" + +config BR2_armeb + bool "armeb" + +config BR2_cris + bool "cris" + +config BR2_i386 + bool "i386" + +config BR2_m68k + bool "m68k" + +config BR2_mips + bool "mips" + +config BR2_mipsel + bool "mipsel" + +config BR2_powerpc + bool "powerpc" + +config BR2_sh + bool "sh4" + +config BR2_sparc + bool "sparc" + +endchoice + +config BR2_ARCH + string + default "arm" if BR2_arm + default "armeb" if BR2_armeb + default "cris" if BR2_cris + default "i386" if BR2_i386 + default "m68k" if BR2_m68k + default "mips" if BR2_mips + default "mipsel" if BR2_mipsel + default "powerpc" if BR2_powerpc + default "sh4" if BR2_sh + default "sparc" if BR2_sparc + + +config BR2_WGET + string + default "wget --passive-ftp" + + +source "toolchain/Config.in" + +source "package/Config.in" + + diff --git a/Makefile b/Makefile index 5cc7437700..ed0339c2c4 100644 --- a/Makefile +++ b/Makefile @@ -1,254 +1,53 @@ -# Makefile for a simple busybox/uClibc root filesystem +# Makefile for buildroot2 # -# Copyright (C) 2001-2004 Erik Andersen -# Copyright (C) 2002 by Tim Riker -# Copyright (C) 2004 Manuel Novoa III +# Copyright (C) 1999-2004 by Erik Andersen # # This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Library General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. +# 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 +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. +# General Public License for more details. # -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - - -############################################################# -# -# EDIT this stuff to suit your system and preferences -# -# Use := when possible to get precomputation, thereby -# speeding up the build process. -# -############################################################# - -# What sort of target system shall we compile this for? -# -ARCH:=i386 -#ARCH:=arm -#ARCH:=armeb -#ARCH:=mips -#ARCH:=mipsel -#ARCH:=powerpc -#ARCH:=sh4 -#ARCH:=cris -#ARCH:=sh64 -#ARCH:=m68k -#ARCH:=v850 -#ARCH:=sparc -#ARCH:=whatever - -# Choose the kernel headers to use for kernel-headers target. This is -# ignored if you are building your own kernel or using the system kernel. -# -#DEFAULT_KERNEL_HEADERS:=2.4.25 -DEFAULT_KERNEL_HEADERS:=2.4.27 -#DEFAULT_KERNEL_HEADERS:=2.6.7 -#DEFAULT_KERNEL_HEADERS:=2.6.8 - -# Choose gcc version. -# WARNING -- 2.95 currently only builds for i386, arm, mips*, and powerpc. -# WARNING -- 2.95 does not currently build natively for the target. -# -#GCC_VERSION:=2.95 -#GCC_VERSION:=3.3.3 -#GCC_VERSION:=3.3.4 -#GCC_VERSION:=3.4.0 -#GCC_VERSION:=3.4.1 -GCC_VERSION:=3.4.2 - -# Choose binutils version. -# -#BINUTILS_VERSION:=2.14.90.0.6 -#BINUTILS_VERSION:=2.14.90.0.7 -#BINUTILS_VERSION:=2.14.90.0.8 -#BINUTILS_VERSION:=2.15 -#BINUTILS_VERSION:=2.15.90.0.1 -#BINUTILS_VERSION:=2.15.90.0.1.1 -#BINUTILS_VERSION:=2.15.90.0.2 -#BINUTILS_VERSION:=2.15.90.0.3 -#BINUTILS_VERSION:=2.15.91.0.1 -BINUTILS_VERSION:=2.15.91.0.2 -#BINUTILS_VERSION:=2.15.92.0.2 - -# Choose gdb version. -# -#GDB_VERSION:=5.3 -GDB_VERSION:=6.1.1 -#GDB_VERSION:=6.2 -#GDB_VERSION:=6.2.1 - - -# Enable this to use the uClibc daily snapshot instead of a released -# version. Daily snapshots may contain new features and bugfixes. Or -# they may not even compile at all, depending on what Erik is doing. - -# Do you wish to use the latest release (), latest snapshot (snapshot), -# or the snapshot from a specific date (yyyymmdd)? Note that snapshots -# may contain new features and bugfixes. Or they may not even compile -# at all, depending on what Erik and Manuel are doing. -# -#USE_UCLIBC_SNAPSHOT:= -USE_UCLIBC_SNAPSHOT:=snapshot -#USE_UCLIBC_SNAPSHOT:=20040807 - -# Do you wish to use the latest release (), latest snapshot (snapshot), -# or the snapshot from a specific date (yyyymmdd)? Note that snapshots -# may contain new features and bugfixes. Or they may not even compile -# at all... +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -#USE_BUSYBOX_SNAPSHOT:= -USE_BUSYBOX_SNAPSHOT:=snapshot -#USE_BUSYBOX_SNAPSHOT:=20040807 - -# Enable large file (files > 2 GB) support -BUILD_WITH_LARGEFILE:=true - -# Command used to download source code -WGET:=wget --passive-ftp - -# Optimize toolchain for which type of CPU? -OPTIMIZE_FOR_CPU=$(ARCH) -#OPTIMIZE_FOR_CPU=i686 -# Note... gcc 2.95 does not seem to like anything higher than i586. -#OPTIMIZE_FOR_CPU=i586 -#OPTIMIZE_FOR_CPU=whatever - -# Might be worth experimenting with for gcc 3.4.x. -GCC_WITH_CPU:= -GCC_WITH_ARCH:= -GCC_WITH_TUNE:= - -#GCC_WITH_CPU:=--with-cpu= -#GCC_WITH_ARCH:=--with-arch= -#GCC_WITH_TUNE:=--with-tune= - -# Soft floating point options. -# Notes: -# Builds for gcc 3.4.x. -# Can build for gcc 3.3.x for mips, mipsel, powerpc, and arm (special) -# by using custom specs files (currently for 3.3.4 only). -# NOTE!!! The libfloat stuff is currently removed from uClibc. The -# arm soft float for 3.3.x will require reenabling it. -# (i386 support will be added back in at some point.) -# Only tested with multilib enabled. -# For i386, long double is the same as double (64 bits). While this -# is unusual for x86, it seemed the best approach considering the -# limitations in the gcc floating point emulation library. -# For arm, soft float uses the usual libfloat routines. -# (Un)comment the appropriate line below. -#SOFT_FLOAT:=true -SOFT_FLOAT:=false - -TARGET_OPTIMIZATION=-Os -pipe -TARGET_DEBUGGING= #-g - -# Currently the unwind stuff seems to work for staticly linked apps but -# not dynamic. So use setjmp/longjmp exceptions by default. -GCC_USE_SJLJ_EXCEPTIONS:=--enable-sjlj-exceptions -#GCC_USE_SJLJ_EXCEPTIONS:= - -# Any additional gcc options you may want to include.... -EXTRA_GCC_CONFIG_OPTIONS:= - -# Enable the following if you want locale/gettext/i18n support. -# NOTE! Currently the pregnerated locale stuff only works for x86! -#ENABLE_LOCALE:=true -ENABLE_LOCALE:=false - -# If you want multilib enabled, enable this... -MULTILIB:=--enable-multilib - -# Build/install c++ compiler and libstdc++? -INSTALL_LIBSTDCPP:=true - -# Build/install java compiler and libgcj? (requires c++) -# WARNING!!! DOES NOT BUILD FOR TARGET WITHOUT INTERVENTION!!! mjn3 -#INSTALL_LIBGCJ:=true -INSTALL_LIBGCJ:=false - -# For SMP machines some stuff can be run in parallel -#JLEVEL=-j3 -############################################################# -# -# The list of stuff to build for the target filesystem -# -############################################################# -TARGETS:=host-sed - -TARGETS+=uclibc-configured binutils gcc ccache - -# Are you building your own kernel? Perhaps you have a kernel -# you have already configured and you want to use that? The -# default is to just use a set of known working kernel headers. -# Unless you want to build a kernel, I recommend just using -# that... -TARGETS+=kernel-headers -#TARGETS+=linux - -# The default minimal set -TARGETS+=busybox #tinylogin - -# Openssh... -#TARGETS+=zlib openssl openssh -# Dropbear sshd is much smaller than openssl + openssh -#TARGETS+=dropbear_sshd - -# Everything needed to build a full uClibc development system! -#TARGETS+=coreutils findutils bash make diffutils patch sed -#TARGETS+=ed flex bison file gawk tar grep bzip2 +#-------------------------------------------------------------- +# Just run 'make menuconfig', configure stuff, then run 'make'. +# You shouldn't need to mess with anything beyond this point... +#-------------------------------------------------------------- +TOPDIR=./ +CONFIG_CONFIG_IN = Config.in +CONFIG_DEFCONFIG = .defconfig +CONFIG = package/config -#If you want a development system, you probably want gcc built -# with uClibc so it can run within your dev system... -#TARGETS+=gcc_target ccache_target +noconfig_targets := menuconfig config oldconfig randconfig \ + defconfig allyesconfig allnoconfig clean distclean \ + release tags -# Of course, if you are installing a development system, you -# may want some header files so you can compile stuff.... -#TARGETS+=ncurses-headers zlib-headers openssl-headers - -# More development system stuff for those that want it -#TARGETS+=m4 autoconf automake libtool - -# Some nice debugging tools for the host -#TARGETS+=gdbclient -# Some nice debugging tools for the target -#TARGETS+=gdbserver gdb_target -#TARGETS+=strace ltrace - -# The Valgrind debugger (x86 only) -#TARGETS+=valgrind - -# Some stuff for access points and firewalls -#TARGETS+=iptables hostap wtools dhcp_relay bridge -#TARGETS+=iproute2 netsnmp +# Pull in the user's configuration file +ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),) +-include $(TOPDIR).config +endif -# Run customize.mk at the very end to add your own special config. -# This is useful for making your own distro within the buildroot -# process. -# TARGETS+=customize +ifeq ($(strip $(BR2_HAVE_DOT_CONFIG)),y) ############################################################# # -# Pick your root filesystem type. +# The list of stuff to build for the target toolchain +# along with the packages to build for the target. # -############################################################# -#TARGETS+=ext2root - -# Must mount cramfs with 'ramdisk_blocksize=4096' -#TARGETS+=cramfsroot - -# You may need to edit make/jffs2root.mk to change target -# endian-ness or similar, but this is sufficient for most -# things as-is... -#TARGETS+=jffs2root +############################################################## +TARGETS:=host-sed kernel-headers uclibc-configured binutils gcc +include toolchain/Makefile.in +include toolchain/*/Makefile.in +include package/Makefile.in +include package/*/Makefile.in ############################################################# # @@ -257,86 +56,13 @@ TARGETS+=busybox #tinylogin # ############################################################# -ifeq ($(SOFT_FLOAT),true) -# gcc 3.4.x soft float configuration is different than previous versions. -ifeq ($(findstring 3.4.,$(GCC_VERSION)),3.4.) -SOFT_FLOAT_CONFIG_OPTION:=--with-float=soft -else -SOFT_FLOAT_CONFIG_OPTION:=--without-float -endif -TARGET_SOFT_FLOAT:=-msoft-float -ARCH_FPU_SUFFIX:=_nofpu -else -SOFT_FLOAT_CONFIG_OPTION:= -TARGET_SOFT_FLOAT:= -ARCH_FPU_SUFFIX:= -endif - -ifeq ($(INSTALL_LIBGCJ),true) -INSTALL_LIBSTDCPP:=true -endif - -# WARNING -- uClibc currently disables large file support on cris. -ifeq ("$(strip $(ARCH))","cris") -BUILD_WITH_LARGEFILE:=false -endif - -ifneq ($(BUILD_WITH_LARGEFILE),true) -DISABLE_LARGEFILE= --disable-largefile -endif -TARGET_CFLAGS=$(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING) - -HOSTCC:=gcc -BASE_DIR:=${shell pwd} -SOURCE_DIR:=$(BASE_DIR)/sources -DL_DIR:=$(SOURCE_DIR)/dl -PATCH_DIR=$(SOURCE_DIR)/patches -BUILD_DIR:=$(BASE_DIR)/build_$(ARCH)$(ARCH_FPU_SUFFIX) -TARGET_DIR:=$(BUILD_DIR)/root -STAGING_DIR=$(BUILD_DIR)/staging_dir -TOOL_BUILD_DIR=$(BASE_DIR)/toolchain_build_$(ARCH)$(ARCH_FPU_SUFFIX) -TARGET_PATH=$(STAGING_DIR)/bin:/bin:/sbin:/usr/bin:/usr/sbin -IMAGE:=$(BASE_DIR)/root_fs_$(ARCH)$(ARCH_FPU_SUFFIX) -REAL_GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-linux-uclibc -GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-linux -KERNEL_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc- -TARGET_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc- -TARGET_CC=$(TARGET_CROSS)gcc -STRIP=$(TARGET_CROSS)strip --remove-section=.comment --remove-section=.note - - -HOST_ARCH:=$(shell $(HOSTCC) -dumpmachine | sed -e s'/-.*//' \ - -e 's/sparc.*/sparc/' \ - -e 's/arm.*/arm/g' \ - -e 's/m68k.*/m68k/' \ - -e 's/ppc/powerpc/g' \ - -e 's/v850.*/v850/g' \ - -e 's/sh[234]/sh/' \ - -e 's/mips-.*/mips/' \ - -e 's/mipsel-.*/mipsel/' \ - -e 's/cris.*/cris/' \ - -e 's/i[3-9]86/i386/' \ - ) -GNU_HOST_NAME:=$(HOST_ARCH)-pc-linux-gnu -TARGET_CONFIGURE_OPTS=PATH=$(TARGET_PATH) \ - AR=$(TARGET_CROSS)ar \ - AS=$(TARGET_CROSS)as \ - LD=$(TARGET_CROSS)ld \ - NM=$(TARGET_CROSS)nm \ - CC=$(TARGET_CROSS)gcc \ - GCC=$(TARGET_CROSS)gcc \ - CXX=$(TARGET_CROSS)g++ \ - RANLIB=$(TARGET_CROSS)ranlib - -ifeq ($(ENABLE_LOCALE),true) -DISABLE_NLS:= -else -DISABLE_NLS:=--disable-nls -endif all: world +# In this section, we need .config +include .config.cmd + TARGETS_CLEAN:=$(patsubst %,%-clean,$(TARGETS)) TARGETS_SOURCE:=$(patsubst %,%-source,$(TARGETS)) TARGETS_DIRCLEAN:=$(patsubst %,%-dirclean,$(TARGETS)) @@ -347,6 +73,8 @@ world: $(DL_DIR) $(BUILD_DIR) $(STAGING_DIR) $(TARGET_DIR) $(TARGETS) $(TARGETS_CLEAN) $(TARGETS_DIRCLEAN) $(TARGETS_SOURCE) include make/*.mk +include toolchain/*/*.mk +#include package/*/*.mk ############################################################# # @@ -399,3 +127,64 @@ sourceball: rm -f buildroot.tar.bz2; \ tar -cvf buildroot.tar buildroot; \ bzip2 -9 buildroot.tar; \ + + +else # ifeq ($(strip $(BR2_HAVE_DOT_CONFIG)),y) + +all: menuconfig + +# configuration +# --------------------------------------------------------------------------- + +$(CONFIG)/conf: + $(MAKE) -C $(CONFIG) conf + -@if [ ! -f .config ] ; then \ + cp $(CONFIG_DEFCONFIG) .config; \ + fi +$(CONFIG)/mconf: + $(MAKE) -C $(CONFIG) ncurses conf mconf + -@if [ ! -f .config ] ; then \ + cp $(CONFIG_DEFCONFIG) .config; \ + fi + +menuconfig: $(CONFIG)/mconf + @$(CONFIG)/mconf $(CONFIG_CONFIG_IN) + +config: $(CONFIG)/conf + @$(CONFIG)/conf $(CONFIG_CONFIG_IN) + +oldconfig: $(CONFIG)/conf + @$(CONFIG)/conf -o $(CONFIG_CONFIG_IN) + +randconfig: $(CONFIG)/conf + @$(CONFIG)/conf -r $(CONFIG_CONFIG_IN) + +allyesconfig: $(CONFIG)/conf + #@$(CONFIG)/conf -y $(CONFIG_CONFIG_IN) + #sed -i -e "s/^CONFIG_DEBUG.*/# CONFIG_DEBUG is not set/" .config + @$(CONFIG)/conf -o $(CONFIG_CONFIG_IN) + +allnoconfig: $(CONFIG)/conf + @$(CONFIG)/conf -n $(CONFIG_CONFIG_IN) + +defconfig: $(CONFIG)/conf + @$(CONFIG)/conf -d $(CONFIG_CONFIG_IN) + +############################################################# +# +# Cleanup and misc junk +# +############################################################# +clean: + rm -f .config .config.old .config.cmd .tmpconfig.h + - $(MAKE) -C $(CONFIG) clean + +distclean: clean + rm -rf sources/* + +endif # ifeq ($(strip $(BR2_HAVE_DOT_CONFIG)),y) + +.PHONY: dummy subdirs release distclean clean config oldconfig \ + menuconfig tags check test depend + + diff --git a/make/bzip2.mk b/make/bzip2.mk index 299105a911..4152102dcd 100644 --- a/make/bzip2.mk +++ b/make/bzip2.mk @@ -20,7 +20,7 @@ $(BZIP2_DIR)/.unpacked: $(DL_DIR)/$(BZIP2_SOURCE) $(SED) "s,ln \$$(,ln -sf \$$(,g" $(BZIP2_DIR)/Makefile $(SED) "s,ln -s (lib.*),ln -sf \$$1 ; ln -sf libbz2.so.1.0.2 libbz2.so,g" \ $(BZIP2_DIR)/Makefile-libbz2_so -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),false) +ifeq ($(BR2_LARGEFILE),y) $(SED) "s,^BIGFILES,#BIGFILES,g" $(BZIP2_DIR)/Makefile $(SED) "s,^BIGFILES,#BIGFILES,g" $(BZIP2_DIR)/Makefile-libbz2_so endif diff --git a/make/gzip.mk b/make/gzip.mk index 8098dd9333..d5ea8dd8a6 100644 --- a/make/gzip.mk +++ b/make/gzip.mk @@ -10,7 +10,7 @@ GZIP_CAT:=zcat GZIP_BINARY:=$(GZIP_DIR)/gzip GZIP_TARGET_BINARY:=$(TARGET_DIR)/bin/zmore -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),false) +ifneq ($(BR2_LARGEFILE),y) GZIP_LARGEFILE="--disable-largefile" endif diff --git a/make/mkdosfs.mk b/make/mkdosfs.mk index 98288afed3..71d768bae4 100644 --- a/make/mkdosfs.mk +++ b/make/mkdosfs.mk @@ -9,7 +9,7 @@ MKDOSFS_DIR=$(BUILD_DIR)/dosfstools-2.8 MKDOSFS_CAT:=zcat MKDOSFS_BINARY:=mkdosfs/mkdosfs MKDOSFS_TARGET_BINARY:=sbin/mkdosfs -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true) +ifeq ($(BR2_LARGEFILE),y) MKDOSFS_CFLAGS="-Os -g -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" else MKDOSFS_CFLAGS="-Os -g" diff --git a/make/newt.mk b/make/newt.mk index cc2359e70d..0f804f1cda 100644 --- a/make/newt.mk +++ b/make/newt.mk @@ -7,7 +7,7 @@ NEWT_SOURCE=newt-0.51.0.tar.bz2 NEWT_SITE=http://www.uclibc.org/ NEWT_DIR=$(BUILD_DIR)/newt-0.51.0 NEWT_VERSION=0.51.0 -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true) +ifeq ($(BR2_LARGEFILE),y) NEWT_CFLAGS=-Os -g -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 else NEWT_CFLAGS=-Os -g diff --git a/make/sed.mk b/make/sed.mk deleted file mode 100644 index 31506650db..0000000000 --- a/make/sed.mk +++ /dev/null @@ -1,137 +0,0 @@ -############################################################# -# -# sed -# -############################################################# -SED_VER:=4.1.2 -SED_SOURCE:=sed-$(SED_VER).tar.gz -SED_SITE:=ftp://ftp.gnu.org/gnu/sed -SED_CAT:=zcat -SED_DIR1:=$(TOOL_BUILD_DIR)/sed-$(SED_VER) -SED_DIR2:=$(BUILD_DIR)/sed-$(SED_VER) -SED_BINARY:=sed/sed -SED_TARGET_BINARY:=bin/sed -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true) -SED_CPPFLAGS=-D_FILE_OFFSET_BITS=64 -endif -SED:=$(STAGING_DIR)/bin/sed -i -e - -HOST_SED_TARGET=$(shell ./sources/sedcheck.sh) - -$(DL_DIR)/$(SED_SOURCE): - mkdir -p $(DL_DIR) - $(WGET) -P $(DL_DIR) $(SED_SITE)/$(SED_SOURCE) - -sed-source: $(DL_DIR)/$(SED_SOURCE) - - -############################################################# -# -# build sed for use on the host system -# -############################################################# -$(SED_DIR1)/.unpacked: $(DL_DIR)/$(SED_SOURCE) - mkdir -p $(TOOL_BUILD_DIR) - mkdir -p $(STAGING_DIR)/bin; - $(SED_CAT) $(DL_DIR)/$(SED_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf - - touch $(SED_DIR1)/.unpacked - -$(SED_DIR1)/.configured: $(SED_DIR1)/.unpacked - (cd $(SED_DIR1); rm -rf config.cache; \ - ./configure \ - --prefix=$(STAGING_DIR) \ - --prefix=/usr \ - ); - touch $(SED_DIR1)/.configured - -$(SED_DIR1)/$(SED_BINARY): $(SED_DIR1)/.configured - $(MAKE) -C $(SED_DIR1) - -# This stuff is needed to work around GNU make deficiencies -build-sed-host-binary: $(SED_DIR1)/$(SED_BINARY) - @if [ -L $(STAGING_DIR)/$(SED_TARGET_BINARY) ] ; then \ - rm -f $(STAGING_DIR)/$(SED_TARGET_BINARY); fi; - @if [ ! -f $(STAGING_DIR)/$(SED_TARGET_BINARY) -o $(STAGING_DIR)/$(SED_TARGET_BINARY) \ - -ot $(SED_DIR1)/$(SED_BINARY) ] ; then \ - set -x; \ - mkdir -p $(STAGING_DIR)/bin; \ - $(MAKE) DESTDIR=$(STAGING_DIR) -C $(SED_DIR1) install; \ - mv $(STAGING_DIR)/usr/bin/sed $(STAGING_DIR)/bin/; \ - rm -rf $(STAGING_DIR)/share/locale $(STAGING_DIR)/usr/info \ - $(STAGING_DIR)/usr/man $(STAGING_DIR)/usr/share/doc; fi - -use-sed-host-binary: - @if [ -x /usr/bin/sed ]; then SED="/usr/bin/sed"; else \ - if [ -x /bin/sed ]; then SED="/bin/sed"; fi; fi; \ - mkdir -p $(STAGING_DIR)/bin; \ - rm -f $(STAGING_DIR)/$(SED_TARGET_BINARY); \ - ln -s $$SED $(STAGING_DIR)/$(SED_TARGET_BINARY) - -host-sed: $(HOST_SED_TARGET) - -host-sed-clean: - $(MAKE) DESTDIR=$(STAGING_DIR) -C $(SED_DIR1) uninstall - -$(MAKE) -C $(SED_DIR1) clean - -host-sed-dirclean: - rm -rf $(SED_DIR1) - - -############################################################# -# -# build sed for use on the target system -# -############################################################# -$(SED_DIR2)/.unpacked: $(DL_DIR)/$(SED_SOURCE) - $(SED_CAT) $(DL_DIR)/$(SED_SOURCE) | tar -C $(BUILD_DIR) -xvf - - touch $(SED_DIR2)/.unpacked - -$(SED_DIR2)/.configured: $(SED_DIR2)/.unpacked - (cd $(SED_DIR2); rm -rf config.cache; \ - $(TARGET_CONFIGURE_OPTS) \ - CFLAGS="$(TARGET_CFLAGS)" \ - CPPFLAGS="$(SED_CFLAGS)" \ - ./configure \ - --target=$(GNU_TARGET_NAME) \ - --host=$(GNU_TARGET_NAME) \ - --build=$(GNU_HOST_NAME) \ - --prefix=/usr \ - --exec-prefix=/usr \ - --bindir=/usr/bin \ - --sbindir=/usr/sbin \ - --libexecdir=/usr/lib \ - --sysconfdir=/etc \ - --datadir=/usr/share \ - --localstatedir=/var \ - --mandir=/usr/man \ - --infodir=/usr/info \ - $(DISABLE_NLS) \ - ); - touch $(SED_DIR2)/.configured - -$(SED_DIR2)/$(SED_BINARY): $(SED_DIR2)/.configured - $(MAKE) CC=$(TARGET_CC) -C $(SED_DIR2) - -# This stuff is needed to work around GNU make deficiencies -sed-target_binary: $(SED_DIR2)/$(SED_BINARY) - @if [ -L $(TARGET_DIR)/$(SED_TARGET_BINARY) ] ; then \ - rm -f $(TARGET_DIR)/$(SED_TARGET_BINARY); fi; - - @if [ ! -f $(SED_DIR2)/$(SED_BINARY) -o $(TARGET_DIR)/$(SED_TARGET_BINARY) \ - -ot $(SED_DIR2)/$(SED_BINARY) ] ; then \ - set -x; \ - $(MAKE) DESTDIR=$(TARGET_DIR) CC=$(TARGET_CC) -C $(SED_DIR2) install; \ - mv $(TARGET_DIR)/usr/bin/sed $(TARGET_DIR)/bin/; \ - rm -rf $(TARGET_DIR)/share/locale $(TARGET_DIR)/usr/info \ - $(TARGET_DIR)/usr/man $(TARGET_DIR)/usr/share/doc; fi - -sed: uclibc sed-target_binary - -sed-clean: - $(MAKE) DESTDIR=$(TARGET_DIR) CC=$(TARGET_CC) -C $(SED_DIR2) uninstall - -$(MAKE) -C $(SED_DIR2) clean - -sed-dirclean: - rm -rf $(SED_DIR2) - - diff --git a/make/slang.mk b/make/slang.mk index 17dcaddd59..6a1cb0632c 100644 --- a/make/slang.mk +++ b/make/slang.mk @@ -6,7 +6,7 @@ SLANG_SOURCE=slang-1.4.5-mini.tar.bz2 SLANG_SITE:=http://www.uclibc.org/ SLANG_DIR=$(BUILD_DIR)/slang-1.4.5-mini -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true) +ifeq ($(BR2_LARGEFILE),y) SLANG_CFLAGS=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 endif SLANG_CFLAGS+=-fPIC diff --git a/make/zlib.mk b/make/zlib.mk index 298c35abe9..27fe43d5cb 100644 --- a/make/zlib.mk +++ b/make/zlib.mk @@ -8,7 +8,7 @@ ZLIB_SOURCE=zlib-$(ZLIB_VER).tar.bz2 ZLIB_SITE=http://aleron.dl.sourceforge.net/sourceforge/libpng ZLIB_DIR=$(BUILD_DIR)/zlib-$(ZLIB_VER) ZLIB_CFLAGS= $(TARGET_CFLAGS) -fPIC -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true) +ifeq ($(BR2_LARGEFILE),y) ZLIB_CFLAGS+= -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 endif diff --git a/package/Config.in b/package/Config.in new file mode 100644 index 0000000000..4e429e74de --- /dev/null +++ b/package/Config.in @@ -0,0 +1,23 @@ +# + +menu "Package Selection" + +#source "package/bash/Config.in" +#source "package/coreutils/Config.in" +#source "package/make/Config.in" +source "package/busybox/Config.in" +#source "package/findutils/Config.in" +#source "package/diffutils/Config.in" +#source "package/patch/Config.in" +source "package/sed/Config.in" +#source "package/ed/Config.in" +#source "package/flex/Config.in" +#source "package/bison/Config.in" +#source "package/file/Config.in" +#source "package/gawk/Config.in" +#source "package/tar/Config.in" +#source "package/grep/Config.in" +#source "package/bzip2/Config.in" + +endmenu + diff --git a/package/Makefile.in b/package/Makefile.in new file mode 100644 index 0000000000..fa320393dd --- /dev/null +++ b/package/Makefile.in @@ -0,0 +1,60 @@ +# Strip off the annoying quoting +ARCH:=$(strip $(subst ",, $(BR2_ARCH))) +#" +WGET:=$(strip $(subst ",, $(BR2_WGET))) +#" + +ifneq ($(BR2_LARGEFILE),y) +DISABLE_LARGEFILE= --disable-largefile +endif +TARGET_CFLAGS=$(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING) + +HOSTCC:=gcc +BASE_DIR:=${shell pwd} +SOURCE_DIR:=$(BASE_DIR)/sources +DL_DIR:=$(SOURCE_DIR)/dl +PATCH_DIR=$(SOURCE_DIR)/patches +BUILD_DIR:=$(BASE_DIR)/build_$(ARCH)$(ARCH_FPU_SUFFIX) +TARGET_DIR:=$(BUILD_DIR)/root +STAGING_DIR=$(BUILD_DIR)/staging_dir +TOOL_BUILD_DIR=$(BASE_DIR)/toolchain_build_$(ARCH)$(ARCH_FPU_SUFFIX) +TARGET_PATH=$(STAGING_DIR)/bin:/bin:/sbin:/usr/bin:/usr/sbin +IMAGE:=$(BASE_DIR)/root_fs_$(ARCH)$(ARCH_FPU_SUFFIX) +REAL_GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-linux-uclibc +GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-linux +KERNEL_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc- +TARGET_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc- +TARGET_CC=$(TARGET_CROSS)gcc +STRIP=$(TARGET_CROSS)strip --remove-section=.comment --remove-section=.note + + +HOST_ARCH:=$(shell $(HOSTCC) -dumpmachine | sed -e s'/-.*//' \ + -e 's/sparc.*/sparc/' \ + -e 's/arm.*/arm/g' \ + -e 's/m68k.*/m68k/' \ + -e 's/ppc/powerpc/g' \ + -e 's/v850.*/v850/g' \ + -e 's/sh[234]/sh/' \ + -e 's/mips-.*/mips/' \ + -e 's/mipsel-.*/mipsel/' \ + -e 's/cris.*/cris/' \ + -e 's/i[3-9]86/i386/' \ + ) +GNU_HOST_NAME:=$(HOST_ARCH)-pc-linux-gnu +TARGET_CONFIGURE_OPTS=PATH=$(TARGET_PATH) \ + AR=$(TARGET_CROSS)ar \ + AS=$(TARGET_CROSS)as \ + LD=$(TARGET_CROSS)ld \ + NM=$(TARGET_CROSS)nm \ + CC=$(TARGET_CROSS)gcc \ + GCC=$(TARGET_CROSS)gcc \ + CXX=$(TARGET_CROSS)g++ \ + RANLIB=$(TARGET_CROSS)ranlib + +ifeq ($(ENABLE_LOCALE),true) +DISABLE_NLS:= +else +DISABLE_NLS:=--disable-nls +endif + + diff --git a/package/busybox/Config.in b/package/busybox/Config.in new file mode 100644 index 0000000000..befe2b890e --- /dev/null +++ b/package/busybox/Config.in @@ -0,0 +1,11 @@ +# + +config BR2_PACKAGE_BUSYBOX + bool "busybox" + default y + help + The Swiss Army Knife of embedded Linux. It slices, it dices, it + makes Julian Fries. + + Most people will answer Y. + diff --git a/package/busybox/Makefile.in b/package/busybox/Makefile.in new file mode 100644 index 0000000000..a8efafb8b4 --- /dev/null +++ b/package/busybox/Makefile.in @@ -0,0 +1,3 @@ +ifeq ($(strip $(BR2_PACKAGE_BUSYBOX)),y) +TARGETS+=busybox +endif diff --git a/sources/busybox.config b/package/busybox/busybox.config similarity index 100% rename from sources/busybox.config rename to package/busybox/busybox.config diff --git a/make/busybox.mk b/package/busybox/busybox.mk similarity index 91% rename from make/busybox.mk rename to package/busybox/busybox.mk index ecafc7da19..c6b3b0ad14 100644 --- a/make/busybox.mk +++ b/package/busybox/busybox.mk @@ -15,7 +15,7 @@ BUSYBOX_SOURCE:=busybox-1.00-rc2.tar.bz2 BUSYBOX_SITE:=http://www.busybox.net/downloads endif BUSYBOX_UNZIP=bzcat -BUSYBOX_CONFIG:=$(SOURCE_DIR)/busybox.config +BUSYBOX_CONFIG:=package/busybox/busybox.config $(DL_DIR)/$(BUSYBOX_SOURCE): $(WGET) -P $(DL_DIR) $(BUSYBOX_SITE)/$(BUSYBOX_SOURCE) @@ -25,11 +25,11 @@ busybox-source: $(DL_DIR)/$(BUSYBOX_SOURCE) $(BUSYBOX_CONFIG) $(BUSYBOX_DIR)/.configured: $(DL_DIR)/$(BUSYBOX_SOURCE) $(BUSYBOX_CONFIG) $(BUSYBOX_UNZIP) $(DL_DIR)/$(BUSYBOX_SOURCE) | tar -C $(BUILD_DIR) -xvf - # Allow busybox patches. - $(SOURCE_DIR)/patch-kernel.sh $(BUSYBOX_DIR) $(SOURCE_DIR) busybox-\*.patch + $(SOURCE_DIR)/patch-kernel.sh $(BUSYBOX_DIR) package/busybox busybox-\*.patch cp $(BUSYBOX_CONFIG) $(BUSYBOX_DIR)/.config $(SED) "s,^CROSS.*,CROSS=$(TARGET_CROSS)\n\ PREFIX=$(TARGET_DIR),;" $(BUSYBOX_DIR)/Rules.mak -ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true) +ifeq ($(BR2_LARGEFILE),y) $(SED) "s/^.*CONFIG_LFS.*/CONFIG_LFS=y/;" $(BUSYBOX_DIR)/.config else $(SED) "s/^.*CONFIG_LFS.*/CONFIG_LFS=n/;" $(BUSYBOX_DIR)/.config diff --git a/package/config/.cvsignore b/package/config/.cvsignore new file mode 100644 index 0000000000..e8bf7a75ba --- /dev/null +++ b/package/config/.cvsignore @@ -0,0 +1,8 @@ +conf +mconf +lkc_defs.h +lex.zconf.c +zconf.tab.h +zconf.tab.c +lex.backup +zconf.output diff --git a/package/config/Kconfig-language.txt b/package/config/Kconfig-language.txt new file mode 100644 index 0000000000..493749b32a --- /dev/null +++ b/package/config/Kconfig-language.txt @@ -0,0 +1,255 @@ +Introduction +------------ + +The configuration database is collection of configuration options +organized in a tree structure: + + +- Code maturity level options + | +- Prompt for development and/or incomplete code/drivers + +- General setup + | +- Networking support + | +- System V IPC + | +- BSD Process Accounting + | +- Sysctl support + +- Loadable module support + | +- Enable loadable module support + | +- Set version information on all module symbols + | +- Kernel module loader + +- ... + +Every entry has its own dependencies. These dependencies are used +to determine the visible of an entry. Any child entry is only +visible if its parent entry is also visible. + +Menu entries +------------ + +Most entries define a config option, all other entries help to organize +them. A single configuration option is defined like this: + +config MODVERSIONS + bool "Set version information on all module symbols" + depends MODULES + help + Usually, modules have to be recompiled whenever you switch to a new + kernel. ... + +Every line starts with a key word and can be followed by multiple +arguments. "config" starts a new config entry. The following lines +define attributes for this config option. Attributes can be the type of +the config option, input prompt, dependencies, help text and default +values. A config option can be defined multiple times with the same +name, but every definition can have only a single input prompt and the +type must not conflict. + +Menu attributes +--------------- + +A menu entry can have a number of attributes. Not all of them are +applicable everywhere (see syntax). + +- type definition: "bool"/"tristate"/"string"/"hex"/"integer" + Every config option must have a type. There are only two basic types: + tristate and string, the other types base on these two. The type + definition optionally accepts an input prompt, so these two examples + are equivalent: + + bool "Networking support" + and + bool + prompt "Networking support" + +- input prompt: "prompt" ["if" ] + Every menu entry can have at most one prompt, which is used to display + to the user. Optionally dependencies only for this prompt can be added + with "if". + +- default value: "default" ["if" ] + A config option can have any number of default values. If multiple + default values are visible, only the first defined one is active. + Default values are not limited to the menu entry, where they are + defined, this means the default can be defined somewhere else or be + overriden by an earlier definition. + The default value is only assigned to the config symbol if no other + value was set by the user (via the input prompt above). If an input + prompt is visible the default value is presented to the user and can + be overridden by him. + Optionally dependencies only for this default value can be added with + "if". + +- dependencies: "depends on"/"requires" + This defines a dependency for this menu entry. If multiple + dependencies are defined they are connected with '&&'. Dependencies + are applied to all other options within this menu entry (which also + accept "if" expression), so these two examples are equivalent: + + bool "foo" if BAR + default y if BAR + and + depends on BAR + bool "foo" + default y + +- help text: "help" + This defines a help text. The end of the help text is determined by + the level indentation, this means it ends at the first line which has + a smaller indentation than the first line of the help text. + + +Menu dependencies +----------------- + +Dependencies define the visibility of a menu entry and can also reduce +the input range of tristate symbols. The tristate logic used in the +expressions uses one more state than normal boolean logic to express the +module state. Dependency expressions have the following syntax: + + ::= (1) + '=' (2) + '!=' (3) + '(' ')' (4) + '!' (5) + '||' (6) + '&&' (7) + +Expressions are listed in decreasing order of precedence. + +(1) Convert the symbol into an expression. Boolean and tristate symbols + are simply converted into the respective expression values. All + other symbol types result in 'n'. +(2) If the values of both symbols are equal, it returns 'y', + otherwise 'n'. +(3) If the values of both symbols are equal, it returns 'n', + otherwise 'y'. +(4) Returns the value of the expression. Used to override precedence. +(5) Returns the result of (2-/expr/). +(6) Returns the result of min(/expr/, /expr/). +(7) Returns the result of max(/expr/, /expr/). + +An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 +respectively for calculations). A menu entry becomes visible when it's +expression evaluates to 'm' or 'y'. + +There are two type of symbols: constant and nonconstant symbols. +Nonconstant symbols are the most common ones and are defined with the +'config' statement. Nonconstant symbols consist entirely of alphanumeric +characters or underscores. +Constant symbols are only part of expressions. Constant symbols are +always surrounded by single or double quotes. Within the quote any +other character is allowed and the quotes can be escaped using '\'. + +Menu structure +-------------- + +The position of a menu entry in the tree is determined in two ways. First +it can be specified explicitely: + +menu "Network device support" + depends NET + +config NETDEVICES + ... + +endmenu + +All entries within the "menu" ... "endmenu" block become a submenu of +"Network device support". All subentries inherit the dependencies from +the menu entry, e.g. this means the dependency "NET" is added to the +dependency list of the config option NETDEVICES. + +The other way to generate the menu structure is done by analyzing the +dependencies. If a menu entry somehow depends on the previous entry, it +can be made a submenu of it. First the the previous (parent) symbol must +be part of the dependency list and then one of these two condititions +must be true: +- the child entry must become invisible, if the parent is set to 'n' +- the child entry must only be visible, if the parent is visible + +config MODULES + bool "Enable loadable module support" + +config MODVERSIONS + bool "Set version information on all module symbols" + depends MODULES + +comment "module support disabled" + depends !MODULES + +MODVERSIONS directly depends on MODULES, this means it's only visible if +MODULES is different from 'n'. The comment on the other hand is always +visible when MODULES it's visible (the (empty) dependency of MODULES is +also part of the comment dependencies). + + +Kconfig syntax +-------------- + +The configuration file describes a series of menu entries, where every +line starts with a keyword (except help texts). The following keywords +end a menu entry: +- config +- choice/endchoice +- comment +- menu/endmenu +- if/endif +- source +The first four also start the definition of a menu entry. + +config: + + "config" + + +This defines a config symbol and accepts any of above +attributes as options. + +choices: + + "choice" + + + "endchoice" + +This defines a choice group and accepts any of above attributes as +options. A choice can only be of type bool or tristate, while a boolean +choice only allows a single config entry to be selected, a tristate +choice also allows any number of config entries to be set to 'm'. This +can be used if multiple drivers for a single hardware exists and only a +single driver can be compiled/loaded into the kernel, but all drivers +can be compiled as modules. +A choice accepts another option "optional", which allows to set the +choice to 'n' and no entry needs to be selected. + +comment: + + "comment" + + +This defines a comment which is displayed to the user during the +configuration process and is also echoed to the output files. The only +possible options are dependencies. + +menu: + + "menu" + + + "endmenu" + +This defines a menu block, see "Menu structure" above for more +information. The only possible options are dependencies. + +if: + + "if" + + "endif" + +This defines an if block. The dependency expression is appended +to all enclosed menu entries. + +source: + + "source" + +This reads the specified configuration file. This file is always parsed. diff --git a/package/config/Makefile b/package/config/Makefile new file mode 100644 index 0000000000..455a33d233 --- /dev/null +++ b/package/config/Makefile @@ -0,0 +1,112 @@ +# Makefile for buildroot2 +# +# Copyright (C) 2002-2004 Erik Andersen + + +# Select the compiler needed to build binaries for your development system +HOSTCC = gcc +HOSTCFLAGS= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc. +LC_ALL:= C + + +all: ncurses conf mconf + +LIBS = -lncurses +ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) + HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) + HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h)) + HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h)) + HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) + HOSTNCURSES += -DCURSES_LOC="" +else + HOSTNCURSES += -DCURSES_LOC="" +endif +endif +endif +endif +endif + +CONF_SRC =conf.c +MCONF_SRC =mconf.c checklist.c menubox.c textbox.c yesno.c inputbox.c util.c msgbox.c +SHARED_SRC=zconf.tab.c +SHARED_DEPS:=lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h +CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC)) +MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC)) +SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC)) + +conf: $(CONF_OBJS) $(SHARED_OBJS) + $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ + +mconf: $(MCONF_OBJS) $(SHARED_OBJS) + $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ $(LIBS) + +$(CONF_OBJS): %.o : %.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@ + +$(MCONF_OBJS): %.o : %.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) $(HOSTNCURSES) -I. -c $< -o $@ + +lkc_defs.h: lkc_proto.h + @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + +### +# The following requires flex/bison +# By default we use the _shipped versions, uncomment the +# following line if you are modifying the flex/bison src. +#LKC_GENPARSER := 1 + +ifdef LKC_GENPARSER + +%.tab.c %.tab.h: %.y + bison -t -d -v -b $* -p $(notdir $*) $< + +lex.%.c: %.l + flex -P$(notdir $*) -o$@ $< +else + +lex.zconf.o: lex.zconf.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@ + +lex.zconf.c: lex.zconf.c_shipped + cp lex.zconf.c_shipped lex.zconf.c + +zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS) + $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@ + +zconf.tab.c: zconf.tab.c_shipped + cp zconf.tab.c_shipped zconf.tab.c + +zconf.tab.h: zconf.tab.h_shipped + cp zconf.tab.h_shipped zconf.tab.h +endif + +.PHONY: ncurses + +ncurses: + @echo "main() {}" > lxtemp.c + @if $(HOSTCC) lxtemp.c $(LIBS) ; then \ + rm -f lxtemp.c a.out; \ + else \ + rm -f lxtemp.c; \ + echo -e "\007" ;\ + echo ">> Unable to find the Ncurses libraries." ;\ + echo ">>" ;\ + echo ">> You must have Ncurses installed in order" ;\ + echo ">> to use 'make menuconfig'" ;\ + echo ;\ + exit 1 ;\ + fi + +clean: + rm -f *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) \ + conf mconf zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h + diff --git a/package/config/checklist.c b/package/config/checklist.c new file mode 100644 index 0000000000..4dbd16616d --- /dev/null +++ b/package/config/checklist.c @@ -0,0 +1,372 @@ +/* + * 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, checkflag; + +/* + * Print list item + */ +static void +print_item (WINDOW * win, const char *item, int status, + int choice, int selected) +{ + int i; + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); + for (i = 0; i < list_width; i++) + waddch (win, ' '); + + wmove (win, choice, check_x); + wattrset (win, selected ? check_selected_attr : check_attr); + if (checkflag == FLAG_CHECK) + wprintw (win, "[%c]", status ? 'X' : ' '); + else + wprintw (win, "(%c)", status ? 'X' : ' '); + + wattrset (win, selected ? tag_selected_attr : tag_attr); + mvwaddch(win, choice, item_x, item[0]); + wattrset (win, selected ? item_selected_attr : item_attr); + waddstr (win, (char *)item+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, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + 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, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + 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 + * The `flag' parameter is used to select between radiolist and checklist. + */ +int +dialog_checklist (const char *title, const char *prompt, int height, int width, + int list_height, int item_no, struct dialog_list_item ** items, + int flag) + +{ + int i, x, y, box_x, box_y; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; + WINDOW *dialog, *list; + + checkflag = flag; + + /* Allocate space for storing item on/off status */ + if ((status = malloc (sizeof (int) * item_no)) == NULL) { + endwin (); + fprintf (stderr, + "\nCan't allocate memory in dialog_checklist().\n"); + exit (-1); + } + + /* Initializes status */ + for (i = 0; i < item_no; i++) { + status[i] = (items[i]->selected == 1); /* ON */ + if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */ + choice = i + 1; + } + if (choice) + choice--; + + max_choice = MIN (list_height, item_no); + + /* 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, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + 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, + menubox_border_attr, menubox_attr); + + /* Find length of longest item in order to center checklist */ + check_x = 0; + for (i = 0; i < item_no; i++) + check_x = MAX (check_x, + strlen (items[i]->name) + 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++) { + print_item (list, items[scroll + i]->name, + status[i+scroll], i, i == choice); + } + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + print_buttons(dialog, height, width, 0); + + wnoutrefresh (list); + wnoutrefresh (dialog); + doupdate (); + + while (key != ESC) { + key = wgetch (dialog); + + for (i = 0; i < max_choice; i++) + if (toupper(key) == toupper(items[scroll + i]->name[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 */ + print_item (list, items[scroll]->name, + status[scroll], 0, FALSE); + scrollok (list, TRUE); + wscrl (list, -1); + scrollok (list, FALSE); + } + scroll--; + print_item (list, items[scroll]->name, + status[scroll], 0, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + 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_no - 1) + continue; + /* Scroll list up */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + print_item (list, items[scroll + max_choice - 1]->name, + status[scroll + max_choice - 1], + max_choice - 1, FALSE); + scrollok (list, TRUE); + scroll (list); + scrollok (list, FALSE); + } + scroll++; + print_item (list, items[scroll + max_choice - 1]->name, + status[scroll + max_choice - 1], + max_choice - 1, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice + 1; + } + if (i != choice) { + /* De-highlight current item */ + print_item (list, items[scroll + choice]->name, + status[scroll + choice], choice, FALSE); + /* Highlight new item */ + choice = i; + print_item (list, items[scroll + choice]->name, + status[scroll + choice], choice, TRUE); + wnoutrefresh (list); + wrefresh (dialog); + } + continue; /* wait for another key press */ + } + switch (key) { + case 'H': + case 'h': + case '?': + for (i = 0; i < item_no; i++) + items[i]->selected = 0; + items[scroll + choice]->selected = 1; + delwin (dialog); + free (status); + 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 'S': + case 's': + case ' ': + case '\n': + if (!button) { + if (flag == FLAG_CHECK) { + status[scroll + choice] = !status[scroll + choice]; + wmove (list, choice, check_x); + wattrset (list, check_selected_attr); + wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' '); + } else { + if (!status[scroll + choice]) { + for (i = 0; i < item_no; i++) + status[i] = 0; + status[scroll + choice] = 1; + for (i = 0; i < max_choice; i++) + print_item (list, items[scroll + i]->name, + status[scroll + i], i, i == choice); + } + } + wnoutrefresh (list); + wrefresh (dialog); + + for (i = 0; i < item_no; i++) { + items[i]->selected = status[i]; + } + } else { + for (i = 0; i < item_no; i++) + items[i]->selected = 0; + items[scroll + choice]->selected = 1; + } + delwin (dialog); + free (status); + return button; + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + + /* Now, update everything... */ + doupdate (); + } + + + delwin (dialog); + free (status); + return -1; /* ESC pressed */ +} diff --git a/package/config/colors.h b/package/config/colors.h new file mode 100644 index 0000000000..d34dd37c6f --- /dev/null +++ b/package/config/colors.h @@ -0,0 +1,161 @@ +/* + * colors.h -- color attribute definitions + * + * 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. + */ + + +/* + * Default color definitions + * + * *_FG = foreground + * *_BG = background + * *_HL = highlight? + */ +#define SCREEN_FG COLOR_CYAN +#define SCREEN_BG COLOR_BLUE +#define SCREEN_HL TRUE + +#define SHADOW_FG COLOR_BLACK +#define SHADOW_BG COLOR_BLACK +#define SHADOW_HL TRUE + +#define DIALOG_FG COLOR_BLACK +#define DIALOG_BG COLOR_WHITE +#define DIALOG_HL FALSE + +#define TITLE_FG COLOR_YELLOW +#define TITLE_BG COLOR_WHITE +#define TITLE_HL TRUE + +#define BORDER_FG COLOR_WHITE +#define BORDER_BG COLOR_WHITE +#define BORDER_HL TRUE + +#define BUTTON_ACTIVE_FG COLOR_WHITE +#define BUTTON_ACTIVE_BG COLOR_BLUE +#define BUTTON_ACTIVE_HL TRUE + +#define BUTTON_INACTIVE_FG COLOR_BLACK +#define BUTTON_INACTIVE_BG COLOR_WHITE +#define BUTTON_INACTIVE_HL FALSE + +#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE +#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE +#define BUTTON_KEY_ACTIVE_HL TRUE + +#define BUTTON_KEY_INACTIVE_FG COLOR_RED +#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE +#define BUTTON_KEY_INACTIVE_HL FALSE + +#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW +#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE +#define BUTTON_LABEL_ACTIVE_HL TRUE + +#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK +#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE +#define BUTTON_LABEL_INACTIVE_HL TRUE + +#define INPUTBOX_FG COLOR_BLACK +#define INPUTBOX_BG COLOR_WHITE +#define INPUTBOX_HL FALSE + +#define INPUTBOX_BORDER_FG COLOR_BLACK +#define INPUTBOX_BORDER_BG COLOR_WHITE +#define INPUTBOX_BORDER_HL FALSE + +#define SEARCHBOX_FG COLOR_BLACK +#define SEARCHBOX_BG COLOR_WHITE +#define SEARCHBOX_HL FALSE + +#define SEARCHBOX_TITLE_FG COLOR_YELLOW +#define SEARCHBOX_TITLE_BG COLOR_WHITE +#define SEARCHBOX_TITLE_HL TRUE + +#define SEARCHBOX_BORDER_FG COLOR_WHITE +#define SEARCHBOX_BORDER_BG COLOR_WHITE +#define SEARCHBOX_BORDER_HL TRUE + +#define POSITION_INDICATOR_FG COLOR_YELLOW +#define POSITION_INDICATOR_BG COLOR_WHITE +#define POSITION_INDICATOR_HL TRUE + +#define MENUBOX_FG COLOR_BLACK +#define MENUBOX_BG COLOR_WHITE +#define MENUBOX_HL FALSE + +#define MENUBOX_BORDER_FG COLOR_WHITE +#define MENUBOX_BORDER_BG COLOR_WHITE +#define MENUBOX_BORDER_HL TRUE + +#define ITEM_FG COLOR_BLACK +#define ITEM_BG COLOR_WHITE +#define ITEM_HL FALSE + +#define ITEM_SELECTED_FG COLOR_WHITE +#define ITEM_SELECTED_BG COLOR_BLUE +#define ITEM_SELECTED_HL TRUE + +#define TAG_FG COLOR_YELLOW +#define TAG_BG COLOR_WHITE +#define TAG_HL TRUE + +#define TAG_SELECTED_FG COLOR_YELLOW +#define TAG_SELECTED_BG COLOR_BLUE +#define TAG_SELECTED_HL TRUE + +#define TAG_KEY_FG COLOR_YELLOW +#define TAG_KEY_BG COLOR_WHITE +#define TAG_KEY_HL TRUE + +#define TAG_KEY_SELECTED_FG COLOR_YELLOW +#define TAG_KEY_SELECTED_BG COLOR_BLUE +#define TAG_KEY_SELECTED_HL TRUE + +#define CHECK_FG COLOR_BLACK +#define CHECK_BG COLOR_WHITE +#define CHECK_HL FALSE + +#define CHECK_SELECTED_FG COLOR_WHITE +#define CHECK_SELECTED_BG COLOR_BLUE +#define CHECK_SELECTED_HL TRUE + +#define UARROW_FG COLOR_GREEN +#define UARROW_BG COLOR_WHITE +#define UARROW_HL TRUE + +#define DARROW_FG COLOR_GREEN +#define DARROW_BG COLOR_WHITE +#define DARROW_HL TRUE + +/* End of default color definitions */ + +#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) +#define COLOR_NAME_LEN 10 +#define COLOR_COUNT 8 + +/* + * Global variables + */ + +typedef struct { + char name[COLOR_NAME_LEN]; + int value; +} color_names_st; + +extern color_names_st color_names[]; +extern int color_table[][3]; diff --git a/package/config/conf.c b/package/config/conf.c new file mode 100644 index 0000000000..46b7e08f7f --- /dev/null +++ b/package/config/conf.c @@ -0,0 +1,583 @@ +/* + * 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" + +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[] = "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 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'; + line[1] = 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) { + if (sym_is_changable(sym) && !sym_has_value(sym)) { + if (!conf_cnt++) + printf("*\n* Restart config...\n*\n"); + rootEntry = menu_get_parent_menu(menu); + conf(rootEntry); + } + if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod) + return; + } + + 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 '?': + printf("%s [-o|-s] config\n", av[0]); + exit(0); + } + } + name = av[i]; + if (!name) { + printf("%s: configuration file missing\n", av[0]); + } + 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 Buildroot!\n" + "***\n" + "*** Please run some configurator (e.g. \"make oldconfig\" or\n" + "*** \"make menuconfig\" or \"make config\").\n" + "***\n"); + exit(1); + } + case ask_all: + case ask_new: + conf_read(NULL); + break; + default: + break; + } + + if (input_mode != ask_silent) { + rootEntry = &rootmenu; + conf(&rootmenu); + if (input_mode == ask_all) { + input_mode = ask_silent; + valid_stdin = 1; + } + } + do { + conf_cnt = 0; + check_conf(&rootmenu); + } while (conf_cnt); + if (conf_write(NULL)) { + fprintf(stderr, "\n*** Error during writing of the Buildroot configuration.\n\n"); + return 1; + } + return 0; +} diff --git a/package/config/confdata.c b/package/config/confdata.c new file mode 100644 index 0000000000..fd3a345e26 --- /dev/null +++ b/package/config/confdata.c @@ -0,0 +1,447 @@ +/* + * 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" + +const char conf_def_filename[] = ".config"; + +const char conf_defname[] = "sysdeps/linux/defconfig"; + +const char *conf_confnames[] = { + ".config", + conf_defname, + NULL, +}; + +static char *conf_expand_value(const char *in) +{ + struct symbol *sym; + const char *src; + static char res_value[SYMBOL_MAXLENGTH]; + char *dst, name[SYMBOL_MAXLENGTH]; + + res_value[0] = 0; + dst = name; + while ((src = strchr(in, '$'))) { + strncat(res_value, in, src - in); + src++; + dst = name; + while (isalnum(*src) || *src == '_') + *dst++ = *src++; + *dst = 0; + sym = sym_lookup(name, 0); + sym_calc_value(sym); + strcat(res_value, sym_get_string_value(sym)); + in = src; + } + strcat(res_value, in); + + return res_value; +} + +char *conf_get_default_confname(void) +{ + 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(const char *name) +{ + FILE *in = NULL; + char line[1024]; + char *p, *p2; + int lineno = 0; + struct symbol *sym; + struct property *prop; + struct expr *e; + int i; + + if (name) { + in = zconf_fopen(name); + } else { + const char **names = conf_confnames; + while ((name = *names++)) { + name = conf_expand_value(name); + in = zconf_fopen(name); + if (in) { + printf("#\n" + "# using defaults found in %s\n" + "#\n", name); + break; + } + } + } + + if (!in) + return 1; + + for_all_symbols(i, sym) { + sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; + sym->flags &= ~SYMBOL_VALID; + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + if (sym->user.val) + free(sym->user.val); + default: + sym->user.val = NULL; + sym->user.tri = no; + } + } + + while (fgets(line, sizeof(line), in)) { + lineno++; + sym = NULL; + switch (line[0]) { + case '#': + if (line[1]!=' ') + continue; + p = strchr(line + 2, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + sym = sym_find(line + 2); + if (!sym) { + fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 2); + break; + } + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + default: + ; + } + break; + + case 'A' ... 'Z': + p = strchr(line, '='); + if (!p) + continue; + *p++ = 0; + p2 = strchr(p, '\n'); + if (p2) + *p2 = 0; + sym = sym_find(line); + if (!sym) { + fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line); + break; + } + switch (sym->type) { + case S_TRISTATE: + if (p[0] == 'm') { + sym->user.tri = mod; + sym->flags &= ~SYMBOL_NEW; + break; + } + case S_BOOLEAN: + if (p[0] == 'y') { + sym->user.tri = yes; + sym->flags &= ~SYMBOL_NEW; + break; + } + if (p[0] == 'n') { + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + } + break; + case S_STRING: + if (*p++ != '"') + break; + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { + if (*p2 == '"') { + *p2 = 0; + break; + } + memmove(p2, p2 + 1, strlen(p2)); + } + if (!p2) { + fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); + exit(1); + } + case S_INT: + case S_HEX: + if (sym_string_valid(sym, p)) { + sym->user.val = strdup(p); + sym->flags &= ~SYMBOL_NEW; + } else { + fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); + exit(1); + } + break; + default: + ; + } + break; + case '\n': + break; + default: + continue; + } + if (sym && sym_is_choice_value(sym)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->user.tri) { + case no: + break; + case mod: + if (cs->user.tri == yes) + /* warn? */; + break; + case yes: + if (cs->user.tri != no) + /* warn? */; + cs->user.val = sym; + break; + } + cs->user.tri = E_OR(cs->user.tri, sym->user.tri); + cs->flags &= ~SYMBOL_NEW; + } + } + fclose(in); + + if (modules_sym) + sym_calc_value(modules_sym); + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (sym_has_value(sym) && !sym_is_choice_value(sym)) { + if (sym->visible == no) + sym->flags |= SYMBOL_NEW; + switch (sym->type) { + case S_STRING: + case S_INT: + case S_HEX: + if (!sym_string_within_range(sym, sym->user.val)) + sym->flags |= SYMBOL_NEW; + default: + break; + } + } + if (!sym_is_choice(sym)) + continue; + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) + if (e->right.sym->visible != no) + sym->flags |= e->right.sym->flags & SYMBOL_NEW; + } + + sym_change_count = 1; + + return 0; +} + +int conf_write(const char *name) +{ + FILE *out, *out_h; + struct symbol *sym; + struct menu *menu; + const char *basename; + char dirname[128], tmpname[128], newname[128]; + int type, l; + const char *str; + + 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_def_filename; + } 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_def_filename; + } else + basename = name; + } else + basename = conf_def_filename; + + sprintf(newname, "%s.tmpconfig.%d", dirname, getpid()); + out = fopen(newname, "w"); + if (!out) + return 1; + out_h = NULL; + if (!name) { + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) + return 1; + } + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" + "#\n"); + if (out_h) { + fprintf(out_h, "/*\n" + " * Automatically generated header file: don't edit\n" + " */\n\n" + "#define AUTOCONF_INCLUDED\n\n" + "/* Version Number */\n" + "#define BB_VER \"%s\"\n" + "#define BB_BT \"%s\"\n", + getenv("VERSION"), + getenv("BUILDTIME")); + if (getenv("EXTRA_VERSION")) + fprintf(out_h, "#define BB_EXTRA_VERSION \"%s\"\n", + getenv("EXTRA_VERSION")); + fprintf(out_h, "\n"); + } + + if (!sym_change_count) + sym_clear_all_valid(); + + menu = rootmenu.list; + while (menu) { + sym = menu->sym; + if (!sym) { + if (!menu_is_visible(menu)) + goto next; + str = menu_get_prompt(menu); + fprintf(out, "\n" + "#\n" + "# %s\n" + "#\n", str); + if (out_h) + fprintf(out_h, "\n" + "/*\n" + " * %s\n" + " */\n", str); + } else if (!(sym->flags & SYMBOL_CHOICE)) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE)) + goto next; + sym->flags &= ~SYMBOL_WRITE; + type = sym->type; + if (type == S_TRISTATE) { + sym_calc_value(modules_sym); + if (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, "# %s is not set\n", sym->name); + if (out_h) + fprintf(out_h, "#undef %s\n", sym->name); + break; + case mod: +#if 0 + fprintf(out, "%s=m\n", sym->name); + if (out_h) + fprintf(out_h, "#define %s_MODULE 1\n", sym->name); +#endif + break; + case yes: + fprintf(out, "%s=y\n", sym->name); + if (out_h) + fprintf(out_h, "#define %s 1\n", sym->name); + break; + } + break; + case S_STRING: + // fix me + str = sym_get_string_value(sym); + fprintf(out, "%s=\"", sym->name); + if (out_h) + fprintf(out_h, "#define %s \"", sym->name); + do { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + if (out_h) + fwrite(str, l, 1, out_h); + } + str += l; + while (*str == '\\' || *str == '"') { + fprintf(out, "\\%c", *str); + if (out_h) + fprintf(out_h, "\\%c", *str); + str++; + } + } while (*str); + fputs("\"\n", out); + if (out_h) + fputs("\"\n", out_h); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "%s=%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define %s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "%s=%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define %s %s\n", sym->name, str); + break; + } + } + + next: + if (menu->list) { + menu = menu->list; + continue; + } + if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->next) { + menu = menu->next; + break; + } + } + } + fclose(out); + if (out_h) { + fclose(out_h); + rename(".tmpconfig.h", "include/config.h"); + file_write_dep(NULL); + } + if (!name || basename != conf_def_filename) { + if (!name) + name = conf_def_filename; + sprintf(tmpname, "%s.old", name); + rename(name, tmpname); + } + sprintf(tmpname, "%s%s", dirname, basename); + if (rename(newname, tmpname)) + return 1; + + sym_change_count = 0; + + return 0; +} diff --git a/package/config/dialog.h b/package/config/dialog.h new file mode 100644 index 0000000000..6486cc8f77 --- /dev/null +++ b/package/config/dialog.h @@ -0,0 +1,196 @@ + +/* + * 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 + +#ifdef CURSES_LOC +#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 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 + +/* + * Attribute names + */ +#define screen_attr attributes[0] +#define shadow_attr attributes[1] +#define dialog_attr attributes[2] +#define title_attr attributes[3] +#define border_attr attributes[4] +#define button_active_attr attributes[5] +#define button_inactive_attr attributes[6] +#define button_key_active_attr attributes[7] +#define button_key_inactive_attr attributes[8] +#define button_label_active_attr attributes[9] +#define button_label_inactive_attr attributes[10] +#define inputbox_attr attributes[11] +#define inputbox_border_attr attributes[12] +#define searchbox_attr attributes[13] +#define searchbox_title_attr attributes[14] +#define searchbox_border_attr attributes[15] +#define position_indicator_attr attributes[16] +#define menubox_attr attributes[17] +#define menubox_border_attr attributes[18] +#define item_attr attributes[19] +#define item_selected_attr attributes[20] +#define tag_attr attributes[21] +#define tag_selected_attr attributes[22] +#define tag_key_attr attributes[23] +#define tag_key_selected_attr attributes[24] +#define check_attr attributes[25] +#define check_selected_attr attributes[26] +#define uarrow_attr attributes[27] +#define darrow_attr attributes[28] + +/* number of attributes */ +#define ATTRIBUTE_COUNT 29 + +/* + * Global variables + */ +extern bool use_colors; + +extern chtype attributes[]; +#endif + +extern char *backtitle; + +struct dialog_list_item { + char *name; + int namelen; + char *tag; + int selected; /* Set to 1 by dialog_*() function. */ +}; + +/* + * Function prototypes + */ + +void init_dialog (void); +void end_dialog (void); +void dialog_clear (void); +#ifdef CURSES_LOC +void attr_clear (WINDOW * win, int height, int width, chtype attr); +void color_setup (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 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); +#endif + +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, int height, int width, + int menu_height, const char *choice, int item_no, + struct dialog_list_item ** items); +int dialog_checklist (const char *title, const char *prompt, int height, + int width, int list_height, int item_no, + struct dialog_list_item ** items, int flag); +extern unsigned char dialog_input_result[]; +int dialog_inputbox (const char *title, const char *prompt, int height, + int width, const char *init); + +struct dialog_list_item *first_sel_item(int item_no, + struct dialog_list_item ** items); + +/* + * 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') + */ +#ifdef CURSES_LOC +#define M_EVENT (KEY_MAX+1) +#endif + + +/* + * The `flag' parameter in checklist is used to select between + * radiolist and checklist + */ +#define FLAG_CHECK 1 +#define FLAG_RADIO 0 diff --git a/package/config/expr.c b/package/config/expr.c new file mode 100644 index 0000000000..10f45232b4 --- /dev/null +++ b/package/config/expr.c @@ -0,0 +1,1089 @@ +/* + * 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->flags & (SYMBOL_YES|SYMBOL_NO))) + return; + if (!expr_eq(e1, e2)) + return; + trans_count++; + expr_free(e1); expr_free(e2); + switch (type) { + case E_OR: + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + break; + case E_AND: + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + break; + default: + ; + } +} + +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) +{ + if (!e1 || !e2) + 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 *, const char *), void *data, int prevtoken) +{ + if (!e) { + fn(data, "y"); + return; + } + + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, "("); + switch (e->type) { + case E_SYMBOL: + if (e->left.sym->name) + fn(data, e->left.sym->name); + else + fn(data, ""); + break; + case E_NOT: + fn(data, "!"); + expr_print(e->left.expr, fn, data, E_NOT); + break; + case E_EQUAL: + fn(data, e->left.sym->name); + fn(data, "="); + fn(data, e->right.sym->name); + break; + case E_UNEQUAL: + fn(data, e->left.sym->name); + fn(data, "!="); + fn(data, e->right.sym->name); + break; + case E_OR: + expr_print(e->left.expr, fn, data, E_OR); + fn(data, " || "); + expr_print(e->right.expr, fn, data, E_OR); + break; + case E_AND: + expr_print(e->left.expr, fn, data, E_AND); + fn(data, " && "); + expr_print(e->right.expr, fn, data, E_AND); + break; + case E_CHOICE: + fn(data, e->right.sym->name); + if (e->left.expr) { + fn(data, " ^ "); + expr_print(e->left.expr, fn, data, E_CHOICE); + } + break; + case E_RANGE: + fn(data, "["); + fn(data, e->left.sym->name); + fn(data, " "); + fn(data, e->right.sym->name); + fn(data, "]"); + break; + default: + { + char buf[32]; + sprintf(buf, "", e->type); + fn(data, buf); + break; + } + } + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, ")"); +} + +static void expr_print_file_helper(void *data, const char *str) +{ + fwrite(str, strlen(str), 1, data); +} + +void expr_fprint(struct expr *e, FILE *out) +{ + expr_print(e, expr_print_file_helper, out, E_NONE); +} diff --git a/package/config/expr.h b/package/config/expr.h new file mode 100644 index 0000000000..cac51f6a86 --- /dev/null +++ b/package/config/expr.h @@ -0,0 +1,193 @@ +/* + * 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 +}; + +struct symbol { + struct symbol *next; + char *name; + char *help; + enum symbol_type type; + struct symbol_value curr, user; + 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_YES 0x0001 +#define SYMBOL_MOD 0x0002 +#define SYMBOL_NO 0x0004 +#define SYMBOL_CONST 0x0007 +#define SYMBOL_CHECK 0x0008 +#define SYMBOL_CHOICE 0x0010 +#define SYMBOL_CHOICEVAL 0x0020 +#define SYMBOL_PRINTED 0x0040 +#define SYMBOL_VALID 0x0080 +#define SYMBOL_OPTIONAL 0x0100 +#define SYMBOL_WRITE 0x0200 +#define SYMBOL_CHANGED 0x0400 +#define SYMBOL_NEW 0x0800 +#define SYMBOL_AUTO 0x1000 +#define SYMBOL_CHECKED 0x2000 +#define SYMBOL_CHECK_DONE 0x4000 +#define SYMBOL_WARNED 0x8000 + +#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 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); + +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 */ diff --git a/package/config/inputbox.c b/package/config/inputbox.c new file mode 100644 index 0000000000..fa7bebc693 --- /dev/null +++ b/package/config/inputbox.c @@ -0,0 +1,240 @@ +/* + * 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" + +unsigned 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; + unsigned char *instr = dialog_input_result; + WINDOW *dialog; + + /* 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, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + 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, + border_attr, dialog_attr); + + print_buttons(dialog, height, width, 0); + + /* Set up the initial value */ + wmove (dialog, box_y, box_x); + wattrset (dialog, inputbox_attr); + + if (!init) + instr[0] = '\0'; + else + strcpy (instr, init); + + 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 != 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, inputbox_attr); + 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, inputbox_attr); + 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 = ESC; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/package/config/lex.zconf.c_shipped b/package/config/lex.zconf.c_shipped new file mode 100644 index 0000000000..b877bb6b3c --- /dev/null +++ b/package/config/lex.zconf.c_shipped @@ -0,0 +1,3688 @@ + +#line 3 "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 31 +#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 defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#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 + +#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 = 1; /* 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(n) 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[][38] = + { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, + 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, + 27, 18, 28, 29, 30, 18, 18, 16 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, + 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, + 27, 18, 28, 29, 30, 18, 18, 16 + + }, + + { + 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31 + }, + + { + 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31 + }, + + { + 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, + 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, + + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34 + }, + + { + 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, + 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34 + }, + + { + 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, + 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 52 + + }, + + { + 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, + 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 52 + }, + + { + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11 + }, + + { + 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12 + }, + + { + 11, -13, 53, 54, -13, -13, 55, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13 + }, + + { + 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14 + + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16 + }, + + { + 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17 + }, + + { + 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, 58, -18, -18, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -18 + }, + + { + 11, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, 58, -19, -19, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, + 58, 58, 58, 58, 58, 58, 58, -19 + + }, + + { + 11, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, 58, -20, -20, 58, 58, 58, 58, + 58, 58, 58, 58, 60, 58, 58, 58, 58, 61, + 58, 58, 58, 58, 58, 58, 58, -20 + }, + + { + 11, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, 58, -21, -21, 58, 58, 58, 58, + 58, 62, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -21 + }, + + { + 11, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, 58, -22, -22, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 63, 58, + 58, 58, 58, 58, 58, 58, 58, -22 + }, + + { + 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, 58, -23, -23, 58, 58, 58, 58, + 58, 64, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -23 + }, + + { + 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, 58, -24, -24, 58, 58, 58, 58, + 58, 58, 65, 58, 58, 58, 58, 58, 66, 58, + 58, 58, 58, 58, 58, 58, 58, -24 + + }, + + { + 11, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, 58, -25, -25, 58, 67, 58, 58, + 58, 68, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -25 + }, + + { + 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, 58, -26, -26, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 69, 58, 58, 58, 58, 58, 58, -26 + }, + + { + 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, 58, -27, -27, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 70, 58, 58, 58, 58, -27 + }, + + { + 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, 58, -28, -28, 58, 71, 58, 58, + 58, 72, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -28 + }, + + { + 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, 58, -29, -29, 58, 58, 58, 58, + 58, 73, 58, 58, 58, 58, 58, 58, 58, 74, + 58, 58, 58, 58, 75, 58, 58, -29 + + }, + + { + 11, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, 58, -30, -30, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 76, 58, 58, 58, 58, -30 + }, + + { + 11, 77, 77, -31, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77 + }, + + { + 11, -32, 78, 79, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32 + }, + + { + 11, 80, -33, -33, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80 + }, + + { + 11, 81, 81, 82, 81, -34, 81, 81, -34, 81, + 81, 81, 81, 81, 81, -34, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81 + + }, + + { + 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35 + }, + + { + 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36 + }, + + { + 11, 83, 83, 84, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83 + }, + + { + 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38 + }, + + { + 11, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39 + + }, + + { + 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, + -40, -40, -40, -40, 85, -40, -40, -40, -40, -40, + -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, + -40, -40, -40, -40, -40, -40, -40, -40 + }, + + { + 11, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41 + }, + + { + 11, 86, 86, -42, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86 + }, + + { + 11, -43, -43, -43, -43, -43, -43, 87, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43 + }, + + { + 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44 + + }, + + { + 11, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45 + }, + + { + 11, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, 88, 89, 89, -46, -46, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -46 + }, + + { + 11, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, 89, 89, 89, -47, -47, 89, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -47 + }, + + { + 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48 + }, + + { + 11, -49, -49, 90, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49 + + }, + + { + 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, 89, 89, 89, -50, -50, 89, 89, 89, 89, + 89, 89, 91, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -50 + }, + + { + 11, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, 89, 89, 89, -51, -51, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 92, 89, + 89, 89, 89, 89, 89, 89, 89, -51 + }, + + { + 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, 93 + }, + + { + 11, -53, 53, 54, -53, -53, 55, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -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, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54 + + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + + -57, -57, -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, 58, 58, 58, + 58, 58, 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, 58, -59, -59, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 94, + 58, 58, 58, 58, 58, 58, 58, -59 + + }, + + { + 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, 58, -60, -60, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 95, + 58, 58, 58, 58, 58, 58, 58, -60 + }, + + { + 11, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, 58, -61, -61, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 96, 97, 58, + 58, 58, 58, 58, 58, 58, 58, -61 + }, + + { + 11, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, 58, -62, -62, 58, 58, 58, 58, + + 58, 58, 98, 58, 58, 58, 58, 58, 58, 58, + 99, 58, 58, 58, 58, 58, 58, -62 + }, + + { + 11, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, 58, -63, -63, 58, 100, 58, 58, + 101, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -63 + }, + + { + 11, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, 58, -64, -64, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 102, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 103, -64 + + }, + + { + 11, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, 58, -65, -65, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -65 + }, + + { + 11, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, 58, -66, -66, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 104, 58, 58, -66 + }, + + { + 11, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, 58, -67, -67, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 105, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -67 + }, + + { + 11, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, 58, -68, -68, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 106, 58, + 58, 58, 58, 58, 58, 58, 58, -68 + }, + + { + 11, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, 58, -69, -69, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 107, 58, 58, -69 + + }, + + { + 11, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, 58, -70, -70, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 108, + 58, 58, 58, 58, 58, 58, 58, -70 + }, + + { + 11, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, 58, -71, -71, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 109, 58, + 58, 58, 58, 58, 58, 58, 58, -71 + }, + + { + 11, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, 58, -72, -72, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 110, 58, 58, 58, 58, 58, -72 + }, + + { + 11, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, 58, -73, -73, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 111, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -73 + }, + + { + 11, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, 58, -74, -74, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 112, 58, -74 + + }, + + { + 11, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, 58, -75, -75, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 113, 58, 58, 58, 58, -75 + }, + + { + 11, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, 58, -76, -76, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 114, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -76 + }, + + { + 11, 77, 77, -77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77 + }, + + { + 11, -78, 78, 79, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78 + }, + + { + 11, 80, -79, -79, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80 + + }, + + { + 11, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80 + }, + + { + 11, 81, 81, 82, 81, -81, 81, 81, -81, 81, + 81, 81, 81, 81, 81, -81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81 + }, + + { + 11, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82 + }, + + { + 11, -83, -83, 84, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83 + }, + + { + 11, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84 + + }, + + { + 11, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85 + }, + + { + 11, 86, 86, -86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86 + }, + + { + 11, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87 + }, + + { + 11, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, 115, 89, 89, -88, -88, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -88 + }, + + { + 11, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, 89, 89, 89, -89, -89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -89 + + }, + + { + 11, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90 + }, + + { + 11, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, 89, 89, 89, -91, -91, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -91 + }, + + { + 11, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, 89, 89, 89, -92, -92, 89, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -92 + }, + + { + 11, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93 + }, + + { + 11, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, 58, -94, -94, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 116, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -94 + + }, + + { + 11, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, 58, -95, -95, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 117, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -95 + }, + + { + 11, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, 58, -96, -96, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 118, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -96 + }, + + { + 11, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, 58, -97, -97, 58, 58, 58, 58, + + 58, 58, 119, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -97 + }, + + { + 11, -98, -98, -98, -98, -98, -98, -98, -98, -98, + -98, -98, -98, 58, -98, -98, 120, 121, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -98 + }, + + { + 11, -99, -99, -99, -99, -99, -99, -99, -99, -99, + -99, -99, -99, 58, -99, -99, 58, 58, 58, 58, + 58, 122, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -99 + + }, + + { + 11, -100, -100, -100, -100, -100, -100, -100, -100, -100, + -100, -100, -100, 58, -100, -100, 58, 58, 123, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -100 + }, + + { + 11, -101, -101, -101, -101, -101, -101, -101, -101, -101, + -101, -101, -101, 58, -101, -101, 58, 58, 58, 124, + 58, 58, 58, 58, 58, 125, 58, 126, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -101 + }, + + { + 11, -102, -102, -102, -102, -102, -102, -102, -102, -102, + -102, -102, -102, 58, -102, -102, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 127, 58, 58, 58, 58, 58, 58, -102 + }, + + { + 11, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, 58, -103, -103, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -103 + }, + + { + 11, -104, -104, -104, -104, -104, -104, -104, -104, -104, + -104, -104, -104, 58, -104, -104, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -104 + + }, + + { + 11, -105, -105, -105, -105, -105, -105, -105, -105, -105, + -105, -105, -105, 58, -105, -105, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 128, 58, + 58, 58, 58, 58, 58, 58, 58, -105 + }, + + { + 11, -106, -106, -106, -106, -106, -106, -106, -106, -106, + -106, -106, -106, 58, -106, -106, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 129, 58, -106 + }, + + { + 11, -107, -107, -107, -107, -107, -107, -107, -107, -107, + -107, -107, -107, 58, -107, -107, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 130, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -107 + }, + + { + 11, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, 58, -108, -108, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 131, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -108 + }, + + { + 11, -109, -109, -109, -109, -109, -109, -109, -109, -109, + -109, -109, -109, 58, -109, -109, 58, 58, 58, 58, + 58, 58, 58, 132, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -109 + + }, + + { + 11, -110, -110, -110, -110, -110, -110, -110, -110, -110, + -110, -110, -110, 58, -110, -110, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 133, 58, -110 + }, + + { + 11, -111, -111, -111, -111, -111, -111, -111, -111, -111, + -111, -111, -111, 58, -111, -111, 58, 58, 58, 58, + 58, 134, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -111 + }, + + { + 11, -112, -112, -112, -112, -112, -112, -112, -112, -112, + -112, -112, -112, 58, -112, -112, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 135, 58, 58, 58, 58, -112 + }, + + { + 11, -113, -113, -113, -113, -113, -113, -113, -113, -113, + -113, -113, -113, 58, -113, -113, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 136, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -113 + }, + + { + 11, -114, -114, -114, -114, -114, -114, -114, -114, -114, + -114, -114, -114, 58, -114, -114, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 137, 58, 58, 58, -114 + + }, + + { + 11, -115, -115, -115, -115, -115, -115, -115, -115, -115, + -115, 89, 89, 89, -115, -115, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, -115 + }, + + { + 11, -116, -116, -116, -116, -116, -116, -116, -116, -116, + -116, -116, -116, 58, -116, -116, 58, 58, 58, 58, + 58, 138, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -116 + }, + + { + 11, -117, -117, -117, -117, -117, -117, -117, -117, -117, + -117, -117, -117, 58, -117, -117, 58, 58, 58, 139, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -117 + }, + + { + 11, -118, -118, -118, -118, -118, -118, -118, -118, -118, + -118, -118, -118, 58, -118, -118, 58, 58, 58, 58, + 58, 140, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -118 + }, + + { + 11, -119, -119, -119, -119, -119, -119, -119, -119, -119, + -119, -119, -119, 58, -119, -119, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 141, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -119 + + }, + + { + 11, -120, -120, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, 58, -120, -120, 58, 58, 142, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 143, 58, 58, -120 + }, + + { + 11, -121, -121, -121, -121, -121, -121, -121, -121, -121, + -121, -121, -121, 58, -121, -121, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 144, 58, -121 + }, + + { + 11, -122, -122, -122, -122, -122, -122, -122, -122, -122, + -122, -122, -122, 58, -122, -122, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 145, 58, + 58, 58, 58, 58, 58, 58, 58, -122 + }, + + { + 11, -123, -123, -123, -123, -123, -123, -123, -123, -123, + -123, -123, -123, 58, -123, -123, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 146, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -123 + }, + + { + 11, -124, -124, -124, -124, -124, -124, -124, -124, -124, + -124, -124, -124, 58, -124, -124, 58, 58, 58, 58, + 58, 58, 58, 58, 147, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -124 + + }, + + { + 11, -125, -125, -125, -125, -125, -125, -125, -125, -125, + -125, -125, -125, 58, -125, -125, 58, 58, 58, 58, + 58, 58, 148, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -125 + }, + + { + 11, -126, -126, -126, -126, -126, -126, -126, -126, -126, + -126, -126, -126, 58, -126, -126, 58, 58, 58, 58, + 58, 149, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -126 + }, + + { + 11, -127, -127, -127, -127, -127, -127, -127, -127, -127, + -127, -127, -127, 58, -127, -127, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -127 + }, + + { + 11, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, 58, -128, -128, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 150, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -128 + }, + + { + 11, -129, -129, -129, -129, -129, -129, -129, -129, -129, + -129, -129, -129, 58, -129, -129, 58, 58, 58, 151, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -129 + + }, + + { + 11, -130, -130, -130, -130, -130, -130, -130, -130, -130, + -130, -130, -130, 58, -130, -130, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 152, + 58, 58, 58, 58, 58, 58, 58, -130 + }, + + { + 11, -131, -131, -131, -131, -131, -131, -131, -131, -131, + -131, -131, -131, 58, -131, -131, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 153, 58, 58, 58, 58, 58, 58, -131 + }, + + { + 11, -132, -132, -132, -132, -132, -132, -132, -132, -132, + -132, -132, -132, 58, -132, -132, 58, 58, 58, 58, + + 58, 154, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -132 + }, + + { + 11, -133, -133, -133, -133, -133, -133, -133, -133, -133, + -133, -133, -133, 58, -133, -133, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 155, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -133 + }, + + { + 11, -134, -134, -134, -134, -134, -134, -134, -134, -134, + -134, -134, -134, 58, -134, -134, 58, 58, 58, 156, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -134 + + }, + + { + 11, -135, -135, -135, -135, -135, -135, -135, -135, -135, + -135, -135, -135, 58, -135, -135, 58, 58, 58, 157, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -135 + }, + + { + 11, -136, -136, -136, -136, -136, -136, -136, -136, -136, + -136, -136, -136, 58, -136, -136, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 158, 58, + 58, 58, 58, 58, 58, 58, 58, -136 + }, + + { + 11, -137, -137, -137, -137, -137, -137, -137, -137, -137, + -137, -137, -137, 58, -137, -137, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 159, 58, 58, -137 + }, + + { + 11, -138, -138, -138, -138, -138, -138, -138, -138, -138, + -138, -138, -138, 58, -138, -138, 58, 160, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -138 + }, + + { + 11, -139, -139, -139, -139, -139, -139, -139, -139, -139, + -139, -139, -139, 58, -139, -139, 58, 58, 58, 58, + 58, 161, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -139 + + }, + + { + 11, -140, -140, -140, -140, -140, -140, -140, -140, -140, + -140, -140, -140, 58, -140, -140, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 162, 58, + 58, 58, 58, 58, 58, 58, 58, -140 + }, + + { + 11, -141, -141, -141, -141, -141, -141, -141, -141, -141, + -141, -141, -141, 58, -141, -141, 58, 58, 58, 58, + 58, 58, 58, 163, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -141 + }, + + { + 11, -142, -142, -142, -142, -142, -142, -142, -142, -142, + -142, -142, -142, 58, -142, -142, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 164, + 58, 58, 58, 58, 58, 58, 58, -142 + }, + + { + 11, -143, -143, -143, -143, -143, -143, -143, -143, -143, + -143, -143, -143, 58, -143, -143, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 165, 58, 58, 58, 58, -143 + }, + + { + 11, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, 58, -144, -144, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 166, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -144 + + }, + + { + 11, -145, -145, -145, -145, -145, -145, -145, -145, -145, + -145, -145, -145, 58, -145, -145, 58, 58, 58, 58, + 167, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -145 + }, + + { + 11, -146, -146, -146, -146, -146, -146, -146, -146, -146, + -146, -146, -146, 58, -146, -146, 58, 58, 58, 58, + 58, 168, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -146 + }, + + { + 11, -147, -147, -147, -147, -147, -147, -147, -147, -147, + -147, -147, -147, 58, -147, -147, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 169, + 58, 58, 58, 58, 58, 58, 58, -147 + }, + + { + 11, -148, -148, -148, -148, -148, -148, -148, -148, -148, + -148, -148, -148, 58, -148, -148, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -148 + }, + + { + 11, -149, -149, -149, -149, -149, -149, -149, -149, -149, + -149, -149, -149, 58, -149, -149, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 170, 58, + 58, 58, 58, 58, 58, 58, 58, -149 + + }, + + { + 11, -150, -150, -150, -150, -150, -150, -150, -150, -150, + -150, -150, -150, 58, -150, -150, 58, 58, 58, 58, + 58, 171, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -150 + }, + + { + 11, -151, -151, -151, -151, -151, -151, -151, -151, -151, + -151, -151, -151, 58, -151, -151, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 172, + 58, 58, 58, 58, 58, 58, 58, -151 + }, + + { + 11, -152, -152, -152, -152, -152, -152, -152, -152, -152, + -152, -152, -152, 58, -152, -152, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 173, 58, + 58, 58, 58, 58, 58, 58, 58, -152 + }, + + { + 11, -153, -153, -153, -153, -153, -153, -153, -153, -153, + -153, -153, -153, 58, -153, -153, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 174, 58, 58, -153 + }, + + { + 11, -154, -154, -154, -154, -154, -154, -154, -154, -154, + -154, -154, -154, 58, -154, -154, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -154 + + }, + + { + 11, -155, -155, -155, -155, -155, -155, -155, -155, -155, + -155, -155, -155, 58, -155, -155, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 175, 58, 58, 58, 58, -155 + }, + + { + 11, -156, -156, -156, -156, -156, -156, -156, -156, -156, + -156, -156, -156, 58, -156, -156, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 176, 58, 58, -156 + }, + + { + 11, -157, -157, -157, -157, -157, -157, -157, -157, -157, + -157, -157, -157, 58, -157, -157, 58, 58, 58, 58, + + 58, 177, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -157 + }, + + { + 11, -158, -158, -158, -158, -158, -158, -158, -158, -158, + -158, -158, -158, 58, -158, -158, 58, 58, 58, 58, + 58, 58, 58, 178, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -158 + }, + + { + 11, -159, -159, -159, -159, -159, -159, -159, -159, -159, + -159, -159, -159, 58, -159, -159, 58, 179, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -159 + + }, + + { + 11, -160, -160, -160, -160, -160, -160, -160, -160, -160, + -160, -160, -160, 58, -160, -160, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 180, 58, + 58, 58, 58, 58, 58, 58, 58, -160 + }, + + { + 11, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, 58, -161, -161, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -161 + }, + + { + 11, -162, -162, -162, -162, -162, -162, -162, -162, -162, + -162, -162, -162, 58, -162, -162, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 181, 58, 58, -162 + }, + + { + 11, -163, -163, -163, -163, -163, -163, -163, -163, -163, + -163, -163, -163, 58, -163, -163, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -163 + }, + + { + 11, -164, -164, -164, -164, -164, -164, -164, -164, -164, + -164, -164, -164, 58, -164, -164, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 182, + 58, 58, 58, 58, 58, 58, 58, -164 + + }, + + { + 11, -165, -165, -165, -165, -165, -165, -165, -165, -165, + -165, -165, -165, 58, -165, -165, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 183, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -165 + }, + + { + 11, -166, -166, -166, -166, -166, -166, -166, -166, -166, + -166, -166, -166, 58, -166, -166, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 184, 58, 58, -166 + }, + + { + 11, -167, -167, -167, -167, -167, -167, -167, -167, -167, + -167, -167, -167, 58, -167, -167, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 185, 58, 58, 58, -167 + }, + + { + 11, -168, -168, -168, -168, -168, -168, -168, -168, -168, + -168, -168, -168, 58, -168, -168, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -168 + }, + + { + 11, -169, -169, -169, -169, -169, -169, -169, -169, -169, + -169, -169, -169, 58, -169, -169, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 186, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -169 + + }, + + { + 11, -170, -170, -170, -170, -170, -170, -170, -170, -170, + -170, -170, -170, 58, -170, -170, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 187, 58, -170 + }, + + { + 11, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -171, 58, -171, -171, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 188, 58, + 58, 58, 58, 58, 58, 58, 58, -171 + }, + + { + 11, -172, -172, -172, -172, -172, -172, -172, -172, -172, + -172, -172, -172, 58, -172, -172, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 189, 58, + 58, 58, 58, 58, 58, 58, 58, -172 + }, + + { + 11, -173, -173, -173, -173, -173, -173, -173, -173, -173, + -173, -173, -173, 58, -173, -173, 58, 190, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -173 + }, + + { + 11, -174, -174, -174, -174, -174, -174, -174, -174, -174, + -174, -174, -174, 58, -174, -174, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -174 + + }, + + { + 11, -175, -175, -175, -175, -175, -175, -175, -175, -175, + -175, -175, -175, 58, -175, -175, 58, 58, 58, 58, + 58, 191, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -175 + }, + + { + 11, -176, -176, -176, -176, -176, -176, -176, -176, -176, + -176, -176, -176, 58, -176, -176, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -176 + }, + + { + 11, -177, -177, -177, -177, -177, -177, -177, -177, -177, + -177, -177, -177, 58, -177, -177, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -177 + }, + + { + 11, -178, -178, -178, -178, -178, -178, -178, -178, -178, + -178, -178, -178, 58, -178, -178, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -178 + }, + + { + 11, -179, -179, -179, -179, -179, -179, -179, -179, -179, + -179, -179, -179, 58, -179, -179, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 192, 58, 58, -179 + + }, + + { + 11, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, 58, -180, -180, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -180 + }, + + { + 11, -181, -181, -181, -181, -181, -181, -181, -181, -181, + -181, -181, -181, 58, -181, -181, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -181 + }, + + { + 11, -182, -182, -182, -182, -182, -182, -182, -182, -182, + -182, -182, -182, 58, -182, -182, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 193, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -182 + }, + + { + 11, -183, -183, -183, -183, -183, -183, -183, -183, -183, + -183, -183, -183, 58, -183, -183, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 194, 58, 58, 58, -183 + }, + + { + 11, -184, -184, -184, -184, -184, -184, -184, -184, -184, + -184, -184, -184, 58, -184, -184, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -184 + + }, + + { + 11, -185, -185, -185, -185, -185, -185, -185, -185, -185, + -185, -185, -185, 58, -185, -185, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -185 + }, + + { + 11, -186, -186, -186, -186, -186, -186, -186, -186, -186, + -186, -186, -186, 58, -186, -186, 58, 58, 58, 195, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -186 + }, + + { + 11, -187, -187, -187, -187, -187, -187, -187, -187, -187, + -187, -187, -187, 58, -187, -187, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -187 + }, + + { + 11, -188, -188, -188, -188, -188, -188, -188, -188, -188, + -188, -188, -188, 58, -188, -188, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 196, 58, -188 + }, + + { + 11, -189, -189, -189, -189, -189, -189, -189, -189, -189, + -189, -189, -189, 58, -189, -189, 58, 58, 58, 58, + 58, 58, 197, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -189 + + }, + + { + 11, -190, -190, -190, -190, -190, -190, -190, -190, -190, + -190, -190, -190, 58, -190, -190, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 198, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -190 + }, + + { + 11, -191, -191, -191, -191, -191, -191, -191, -191, -191, + -191, -191, -191, 58, -191, -191, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 199, 58, 58, 58, -191 + }, + + { + 11, -192, -192, -192, -192, -192, -192, -192, -192, -192, + -192, -192, -192, 58, -192, -192, 58, 58, 58, 58, + + 58, 200, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -192 + }, + + { + 11, -193, -193, -193, -193, -193, -193, -193, -193, -193, + -193, -193, -193, 58, -193, -193, 58, 58, 58, 58, + 58, 201, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -193 + }, + + { + 11, -194, -194, -194, -194, -194, -194, -194, -194, -194, + -194, -194, -194, 58, -194, -194, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 202, 58, 58, -194 + + }, + + { + 11, -195, -195, -195, -195, -195, -195, -195, -195, -195, + -195, -195, -195, 58, -195, -195, 58, 58, 58, 58, + 58, 203, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -195 + }, + + { + 11, -196, -196, -196, -196, -196, -196, -196, -196, -196, + -196, -196, -196, 58, -196, -196, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -196 + }, + + { + 11, -197, -197, -197, -197, -197, -197, -197, -197, -197, + -197, -197, -197, 58, -197, -197, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 204, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -197 + }, + + { + 11, -198, -198, -198, -198, -198, -198, -198, -198, -198, + -198, -198, -198, 58, -198, -198, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -198 + }, + + { + 11, -199, -199, -199, -199, -199, -199, -199, -199, -199, + -199, -199, -199, 58, -199, -199, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -199 + + }, + + { + 11, -200, -200, -200, -200, -200, -200, -200, -200, -200, + -200, -200, -200, 58, -200, -200, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -200 + }, + + { + 11, -201, -201, -201, -201, -201, -201, -201, -201, -201, + -201, -201, -201, 58, -201, -201, 58, 205, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -201 + }, + + { + 11, -202, -202, -202, -202, -202, -202, -202, -202, -202, + -202, -202, -202, 58, -202, -202, 58, 206, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -202 + }, + + { + 11, -203, -203, -203, -203, -203, -203, -203, -203, -203, + -203, -203, -203, 58, -203, -203, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -203 + }, + + { + 11, -204, -204, -204, -204, -204, -204, -204, -204, -204, + -204, -204, -204, 58, -204, -204, 58, 58, 58, 58, + 58, 58, 58, 207, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -204 + + }, + + { + 11, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, -205, -205, 58, -205, -205, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 208, 58, + 58, 58, 58, 58, 58, 58, 58, -205 + }, + + { + 11, -206, -206, -206, -206, -206, -206, -206, -206, -206, + -206, -206, -206, 58, -206, -206, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 209, 58, 58, -206 + }, + + { + 11, -207, -207, -207, -207, -207, -207, -207, -207, -207, + -207, -207, -207, 58, -207, -207, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -207 + }, + + { + 11, -208, -208, -208, -208, -208, -208, -208, -208, -208, + -208, -208, -208, 58, -208, -208, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -208 + }, + + { + 11, -209, -209, -209, -209, -209, -209, -209, -209, -209, + -209, -209, -209, 58, -209, -209, 58, 58, 58, 58, + 58, 210, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -209 + + }, + + { + 11, -210, -210, -210, -210, -210, -210, -210, -210, -210, + -210, -210, -210, 58, -210, -210, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -210 + }, + + } ; + +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 64 +#define YY_END_OF_BUFFER 65 +/* 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[211] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 65, 5, 4, 3, 2, 36, 37, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 63, 60, 62, 55, 59, 58, 57, 53, 48, 42, + 47, 51, 53, 40, 41, 50, 50, 43, 53, 50, + 50, 53, 4, 3, 2, 2, 1, 35, 35, 35, + 35, 35, 35, 35, 16, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 63, 60, 62, 61, + 55, 54, 57, 56, 44, 51, 38, 50, 50, 52, + 45, 46, 39, 35, 35, 35, 35, 35, 35, 35, + + 35, 35, 30, 29, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 49, 25, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 15, 35, 7, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 17, 35, 35, + 35, 35, 35, 34, 35, 35, 35, 35, 35, 35, + 10, 35, 13, 35, 35, 35, 35, 33, 35, 35, + 35, 35, 35, 22, 35, 32, 9, 31, 35, 26, + 12, 35, 35, 21, 18, 35, 8, 35, 35, 35, + 35, 35, 27, 35, 35, 6, 35, 20, 19, 23, + + 35, 35, 11, 35, 35, 35, 14, 28, 35, 24 + } ; + +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, 16, 1, 17, 18, 19, 20, + + 21, 22, 23, 24, 25, 13, 13, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 13, 13, 36, + 13, 13, 1, 37, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 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 + +char *text; +static char *text_ptr; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static void zconf_endhelp(void); +static struct buffer *zconf_endfile(void); + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_ptr = text; + text_size = 0; + *text_ptr = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + text = realloc(text, new_size); + text_asize = new_size; + text_ptr = text + text_size; + } + memcpy(text_ptr, str, size); + text_ptr += size; + text_size += size; + *text_ptr = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +#define INITIAL 0 +#define COMMAND 1 +#define HELP 2 +#define STRING 3 +#define PARAM 4 + +/* 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 + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* 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) = 0; + +#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 */ +YY_RULE_SETUP +current_file->lineno++; + YY_BREAK +case 2: +YY_RULE_SETUP + + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +current_file->lineno++; return T_EOL; + 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 +BEGIN(PARAM); return T_MAINMENU; + YY_BREAK +case 7: +YY_RULE_SETUP +BEGIN(PARAM); return T_MENU; + YY_BREAK +case 8: +YY_RULE_SETUP +BEGIN(PARAM); return T_ENDMENU; + YY_BREAK +case 9: +YY_RULE_SETUP +BEGIN(PARAM); return T_SOURCE; + YY_BREAK +case 10: +YY_RULE_SETUP +BEGIN(PARAM); return T_CHOICE; + YY_BREAK +case 11: +YY_RULE_SETUP +BEGIN(PARAM); return T_ENDCHOICE; + YY_BREAK +case 12: +YY_RULE_SETUP +BEGIN(PARAM); return T_COMMENT; + YY_BREAK +case 13: +YY_RULE_SETUP +BEGIN(PARAM); return T_CONFIG; + YY_BREAK +case 14: +YY_RULE_SETUP +BEGIN(PARAM); return T_MENUCONFIG; + YY_BREAK +case 15: +YY_RULE_SETUP +BEGIN(PARAM); return T_HELP; + YY_BREAK +case 16: +YY_RULE_SETUP +BEGIN(PARAM); return T_IF; + YY_BREAK +case 17: +YY_RULE_SETUP +BEGIN(PARAM); return T_ENDIF; + YY_BREAK +case 18: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEPENDS; + YY_BREAK +case 19: +YY_RULE_SETUP +BEGIN(PARAM); return T_REQUIRES; + YY_BREAK +case 20: +YY_RULE_SETUP +BEGIN(PARAM); return T_OPTIONAL; + YY_BREAK +case 21: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEFAULT; + YY_BREAK +case 22: +YY_RULE_SETUP +BEGIN(PARAM); return T_PROMPT; + YY_BREAK +case 23: +YY_RULE_SETUP +BEGIN(PARAM); return T_TRISTATE; + YY_BREAK +case 24: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEF_TRISTATE; + YY_BREAK +case 25: +YY_RULE_SETUP +BEGIN(PARAM); return T_BOOLEAN; + YY_BREAK +case 26: +YY_RULE_SETUP +BEGIN(PARAM); return T_BOOLEAN; + YY_BREAK +case 27: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEF_BOOLEAN; + YY_BREAK +case 28: +YY_RULE_SETUP +BEGIN(PARAM); return T_DEF_BOOLEAN; + YY_BREAK +case 29: +YY_RULE_SETUP +BEGIN(PARAM); return T_INT; + YY_BREAK +case 30: +YY_RULE_SETUP +BEGIN(PARAM); return T_HEX; + YY_BREAK +case 31: +YY_RULE_SETUP +BEGIN(PARAM); return T_STRING; + YY_BREAK +case 32: +YY_RULE_SETUP +BEGIN(PARAM); return T_SELECT; + YY_BREAK +case 33: +YY_RULE_SETUP +BEGIN(PARAM); return T_SELECT; + YY_BREAK +case 34: +YY_RULE_SETUP +BEGIN(PARAM); return T_RANGE; + YY_BREAK +case 35: +YY_RULE_SETUP +{ + alloc_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD; + } + YY_BREAK +case 36: +YY_RULE_SETUP + + YY_BREAK +case 37: +/* rule 37 can match eol */ +YY_RULE_SETUP +current_file->lineno++; BEGIN(INITIAL); + YY_BREAK + +case 38: +YY_RULE_SETUP +return T_AND; + YY_BREAK +case 39: +YY_RULE_SETUP +return T_OR; + YY_BREAK +case 40: +YY_RULE_SETUP +return T_OPEN_PAREN; + YY_BREAK +case 41: +YY_RULE_SETUP +return T_CLOSE_PAREN; + YY_BREAK +case 42: +YY_RULE_SETUP +return T_NOT; + YY_BREAK +case 43: +YY_RULE_SETUP +return T_EQUAL; + YY_BREAK +case 44: +YY_RULE_SETUP +return T_UNEQUAL; + YY_BREAK +case 45: +YY_RULE_SETUP +return T_IF; + YY_BREAK +case 46: +YY_RULE_SETUP +return T_ON; + YY_BREAK +case 47: +YY_RULE_SETUP +{ + str = zconftext[0]; + new_string(); + BEGIN(STRING); + } + YY_BREAK +case 48: +/* rule 48 can match eol */ +YY_RULE_SETUP +BEGIN(INITIAL); current_file->lineno++; return T_EOL; + YY_BREAK +case 49: +YY_RULE_SETUP +/* ignore */ + YY_BREAK +case 50: +YY_RULE_SETUP +{ + alloc_string(zconftext, zconfleng); + zconflval.string = text; + return T_WORD; + } + YY_BREAK +case 51: +YY_RULE_SETUP +/* comment */ + YY_BREAK +case 52: +/* rule 52 can match eol */ +YY_RULE_SETUP +current_file->lineno++; + YY_BREAK +case 53: +YY_RULE_SETUP + + YY_BREAK +case YY_STATE_EOF(PARAM): +{ + BEGIN(INITIAL); + } + YY_BREAK + +case 54: +/* rule 54 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 55: +YY_RULE_SETUP +{ + append_string(zconftext, zconfleng); + } + YY_BREAK +case 56: +/* rule 56 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 57: +YY_RULE_SETUP +{ + append_string(zconftext + 1, zconfleng - 1); + } + YY_BREAK +case 58: +YY_RULE_SETUP +{ + if (str == zconftext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(zconftext, 1); + } + YY_BREAK +case 59: +/* rule 59 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 60: +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 61: +/* rule 61 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 62: +/* rule 62 can match eol */ +YY_RULE_SETUP +{ + current_file->lineno++; + append_string("\n", 1); + } + YY_BREAK +case 63: +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_buf) { + zconf_endfile(); + return T_EOF; + } + fclose(zconfin); + yyterminate(); +} + YY_BREAK +case 64: +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 + { + size_t 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 str 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 * str ) +{ + + return zconf_scan_bytes(str,strlen(str) ); +} + +/** 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 * bytes, int 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 = len + 2; + buf = (char *) zconfalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[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 ; +} + +/* 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; + + 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" + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef yytext_ptr +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +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 struct buffer *zconf_endfile(void) +{ + struct buffer *parent; + + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + + parent = current_buf->parent; + if (parent) { + fclose(zconfin); + zconf_delete_buffer(YY_CURRENT_BUFFER); + zconf_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; + + return parent; +} + +int zconf_lineno(void) +{ + if (current_buf) + return current_file->lineno - 1; + else + return 0; +} + +char *zconf_curname(void) +{ + if (current_buf) + return current_file->name; + else + return ""; +} + diff --git a/package/config/lkc.h b/package/config/lkc.h new file mode 100644 index 0000000000..dd040f7a86 --- /dev/null +++ b/package/config/lkc.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef LKC_H +#define LKC_H + +#include "expr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LKC_DIRECT_LINK +#define P(name,type,arg) extern type name arg +#else +#include "lkc_defs.h" +#define P(name,type,arg) extern type (*name ## _p) arg +#endif +#include "lkc_proto.h" +#undef P + +#define SRCTREE "srctree" + +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 */ +extern const char conf_def_filename[]; +extern char conf_filename[]; + +char *conf_get_default_confname(void); + +/* kconfig_load.c */ +void kconfig_load(void); + +/* menu.c */ +void menu_init(void); +void menu_add_menu(void); +void menu_end_menu(void); +void menu_add_entry(struct symbol *sym); +void menu_end_entry(void); +void menu_add_dep(struct expr *dep); +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); +void 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_finalize(struct menu *parent); +void menu_set_type(int type); +struct file *file_lookup(const char *name); +int file_write_dep(const char *name); + +extern struct menu *current_entry; +extern struct menu *current_menu; + +/* symbol.c */ +void sym_init(void); +void sym_clear_all_valid(void); +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_NEW ? false : true; +} + +#ifdef __cplusplus +} +#endif + +#endif /* LKC_H */ diff --git a/package/config/lkc_proto.h b/package/config/lkc_proto.h new file mode 100644 index 0000000000..97c79178ee --- /dev/null +++ b/package/config/lkc_proto.h @@ -0,0 +1,39 @@ + +/* confdata.c */ +P(conf_parse,void,(const char *name)); +P(conf_read,int,(const char *name)); +P(conf_write,int,(const char *name)); + +/* menu.c */ +P(rootmenu,struct menu,); + +P(menu_is_visible,bool,(struct menu *menu)); +P(menu_get_prompt,const char *,(struct menu *menu)); +P(menu_get_root_menu,struct menu *,(struct menu *menu)); +P(menu_get_parent_menu,struct menu *,(struct menu *menu)); + +/* symbol.c */ +P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); +P(sym_change_count,int,); + +P(sym_lookup,struct symbol *,(const char *name, int isconst)); +P(sym_find,struct symbol *,(const char *name)); +P(sym_type_name,const char *,(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 *, const char *), void *data, int prevtoken)); diff --git a/package/config/mconf.c b/package/config/mconf.c new file mode 100644 index 0000000000..0db6f8f6c8 --- /dev/null +++ b/package/config/mconf.c @@ -0,0 +1,713 @@ +/* + * 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 + * + * Directly use liblxdialog library routines. + * 2002-11-14 Petr Baudis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog.h" + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static char menu_backtitle[128]; +static const char menu_instructions[] = + "Arrow keys navigate the menu. " + " selects submenus --->. " + "Highlighted letters are hotkeys. " + "Pressing selectes a feature, while will exclude a feature. " + "Press to exit, for Help. " + "Legend: [*] feature is selected [ ] feature is excluded", +radiolist_instructions[] = + "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[] = + "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[] = + "Please enter a hexadecimal value. " + "Use the key to move from the input field to the buttons below it.", +inputbox_instructions_string[] = + "Please enter a string value. " + "Use the key to move from the input field to the buttons below it.", +setmod_text[] = + "This feature depends on another which has been configured as a module.\n" + "As a result, this feature will be built as a module.", +nohelp_text[] = + "There is no help available for this option.\n", +load_config_text[] = + "Enter the name of the configuration file you wish to load. " + "Accept the name shown to restore the configuration you " + "last retrieved. Leave blank to abort.", +load_config_help[] = + "\n" + "For various reasons, one may wish to keep several different Buildroot\n" + "configurations available on a single machine.\n" + "\n" + "If you have saved a previous configuration in a file other than the\n" + "Buildroot's default, entering the name of the file here will allow you\n" + "to modify that configuration.\n" + "\n" + "If you are uncertain, then you have probably never used alternate\n" + "configuration files. You should therefor leave this blank to abort.\n", +save_config_text[] = + "Enter a filename to which this configuration should be saved " + "as an alternate. Leave blank to abort.", +save_config_help[] = + "\n" + "For various reasons, one may wish to keep different Buildroot\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", +top_menu_help[] = + "\n" + "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" + "\n" + "You may also use the and keys to scroll\n" + "unseen options into view.\n" +; + +static char filename[PATH_MAX+1] = ".config"; +static int indent = 0; +static struct termios ios_org; +static int rows, cols; +static struct menu *current_menu; +static int child_count; +static int single_menu_mode; + +static struct dialog_list_item *items[16384]; /* FIXME: This ought to be dynamic. */ +static int item_no; + +static void conf(struct menu *menu); +static void conf_choice(struct menu *menu); +static void conf_string(struct menu *menu); +static void conf_load(void); +static void conf_save(void); +static void show_textbox(const char *title, const char *text, int r, int c); +static void show_helptext(const char *title, const char *text); +static void show_help(struct menu *menu); +static void show_readme(void); + +static void init_wsize(void) +{ + struct winsize ws; + char *env; + + if (ioctl(1, TIOCGWINSZ, &ws) == -1) { + rows = 24; + cols = 80; + } else { + 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, "Your display is too small to run Menuconfig!\n"); + fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); + exit(1); + } + + rows -= 4; + cols -= 5; +} + +static void cinit(void) +{ + item_no = 0; +} + +static void cmake(void) +{ + items[item_no] = malloc(sizeof(struct dialog_list_item)); + memset(items[item_no], 0, sizeof(struct dialog_list_item)); + items[item_no]->tag = malloc(32); items[item_no]->tag[0] = 0; + items[item_no]->name = malloc(512); items[item_no]->name[0] = 0; + items[item_no]->namelen = 0; + item_no++; +} + +static int cprint_name(const char *fmt, ...) +{ + va_list ap; + int res; + + if (!item_no) + cmake(); + va_start(ap, fmt); + res = vsnprintf(items[item_no - 1]->name + items[item_no - 1]->namelen, + 512 - items[item_no - 1]->namelen, fmt, ap); + if (res > 0) + items[item_no - 1]->namelen += res; + va_end(ap); + + return res; +} + +static int cprint_tag(const char *fmt, ...) +{ + va_list ap; + int res; + + if (!item_no) + cmake(); + va_start(ap, fmt); + res = vsnprintf(items[item_no - 1]->tag, 32, fmt, ap); + va_end(ap); + + return res; +} + +static void cdone(void) +{ + int i; + + for (i = 0; i < item_no; i++) { + free(items[i]->tag); + free(items[i]->name); + free(items[i]); + } + + item_no = 0; +} + +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++; + cmake(); + cprint_tag("m%p", menu); + + if (single_menu_mode) { + cprint_name("%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); + } else { + cprint_name(" %*c%s --->", indent + 1, ' ', prompt); + } + + if (single_menu_mode && menu->data) + goto conf_childs; + return; + default: + if (prompt) { + child_count++; + cmake(); + cprint_tag(":%p", menu); + cprint_name("---%*c%s", indent + 1, ' ', prompt); + } + } + } else + doint = 0; + goto conf_childs; + } + + cmake(); + type = sym_get_type(sym); + if (sym_is_choice(sym)) { + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + child_count++; + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) && child->sym == def_sym) + def_menu = child; + } + + val = sym_get_tristate_value(sym); + if (sym_is_changable(sym)) { + cprint_tag("t%p", menu); + switch (type) { + case S_BOOLEAN: + cprint_name("[%c]", val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + cprint_name("<%c>", ch); + break; + } + } else { + cprint_tag("%c%p", def_menu ? 't' : ':', menu); + cprint_name(" "); + } + + cprint_name("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + if (val == yes) { + if (def_menu) { + cprint_name(" (%s)", menu_get_prompt(def_menu)); + cprint_name(" --->"); + if (def_menu->list) { + indent += 2; + build_conf(def_menu); + indent -= 2; + } + } + return; + } + } else { + child_count++; + val = sym_get_tristate_value(sym); + if (sym_is_choice_value(sym) && val == yes) { + cprint_tag(":%p", menu); + cprint_name(" "); + } else { + switch (type) { + case S_BOOLEAN: + cprint_tag("t%p", menu); + if (sym_is_changable(sym)) + cprint_name("[%c]", val == no ? ' ' : '*'); + else + cprint_name("---"); + break; + case S_TRISTATE: + cprint_tag("t%p", menu); + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + if (sym_is_changable(sym)) + cprint_name("<%c>", ch); + else + cprint_name("---"); + break; + default: + cprint_tag("s%p", menu); + tmp = cprint_name("(%s)", sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + cprint_name("%*c%s%s", tmp, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + goto conf_childs; + } + } + cprint_name("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + if (menu->prompt->type == P_MENU) { + cprint_name(" --->"); + 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 dialog_list_item *active_item = NULL; + struct menu *submenu; + const char *prompt = menu_get_prompt(menu); + struct symbol *sym; + char active_entry[40]; + int stat, type; + + unlink("lxdialog.scrltmp"); + active_entry[0] = 0; + while (1) { + indent = 0; + child_count = 0; + current_menu = menu; + cdone(); cinit(); + build_conf(menu); + if (!child_count) + break; + if (menu == &rootmenu) { + cmake(); cprint_tag(":"); cprint_name("--- "); + cmake(); cprint_tag("L"); cprint_name("Load an Alternate Configuration File"); + cmake(); cprint_tag("S"); cprint_name("Save Configuration to an Alternate File"); + } + dialog_clear(); + stat = dialog_menu(prompt ? prompt : "Main Menu", + menu_instructions, rows, cols, rows - 10, + active_entry, item_no, items); + if (stat < 0) + return; + + if (stat == 1 || stat == 255) + break; + + active_item = first_sel_item(item_no, items); + if (!active_item) + continue; + active_item->selected = 0; + strncpy(active_entry, active_item->tag, sizeof(active_entry)); + active_entry[sizeof(active_entry)-1] = 0; + type = active_entry[0]; + if (!type) + continue; + + sym = NULL; + submenu = NULL; + if (sscanf(active_entry + 1, "%p", &submenu) == 1) + sym = submenu->sym; + + switch (stat) { + case 0: + switch (type) { + 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_readme(); + break; + case 3: + if (type == 't') { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + show_textbox(NULL, setmod_text, 6, 74); + } + break; + case 4: + if (type == 't') + sym_set_tristate_value(sym, no); + break; + case 5: + if (type == 't') + sym_set_tristate_value(sym, mod); + break; + case 6: + if (type == 't') + sym_toggle_tristate_value(sym); + else if (type == 'm') + conf(submenu); + break; + } + } +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + int fd; + + fd = creat(".help.tmp", 0777); + write(fd, text, strlen(text)); + close(fd); + while (dialog_textbox(title, ".help.tmp", r, c) < 0) + ; + unlink(".help.tmp"); +} + +static void show_helptext(const char *title, const char *text) +{ + show_textbox(title, text, rows, cols); +} + +static void show_help(struct menu *menu) +{ + const char *help; + char *helptext; + struct symbol *sym = menu->sym; + + help = sym->help; + if (!help) + help = nohelp_text; + if (sym->name) { + helptext = malloc(strlen(sym->name) + strlen(help) + 16); + sprintf(helptext, "%s:\n\n%s", sym->name, help); + show_helptext(menu_get_prompt(menu), helptext); + free(helptext); + } else + show_helptext(menu_get_prompt(menu), help); +} + +static void show_readme(void) +{ + show_helptext("Help", top_menu_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) { + current_menu = menu; + cdone(); cinit(); + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) + continue; + cmake(); + cprint_tag("%p", child); + cprint_name("%s", menu_get_prompt(child)); + if (child->sym == sym_get_choice_value(menu->sym)) + items[item_no - 1]->selected = 1; /* ON */ + else if (child->sym == active) + items[item_no - 1]->selected = 2; /* SELECTED */ + else + items[item_no - 1]->selected = 0; /* OFF */ + } + + switch (dialog_checklist(prompt ? prompt : "Main Menu", + radiolist_instructions, 15, 70, 6, + item_no, items, FLAG_RADIO)) { + case 0: + if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) != 1) + break; + sym_set_tristate_value(child->sym, yes); + return; + case 1: + if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) == 1) { + show_help(child); + active = child->sym; + } else + show_help(menu); + break; + case 255: + return; + } + } +} + +static void conf_string(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + + while (1) { + char *heading; + + switch (sym_get_type(menu->sym)) { + case S_INT: + heading = (char *) inputbox_instructions_int; + break; + case S_HEX: + heading = (char *) inputbox_instructions_hex; + break; + case S_STRING: + heading = (char *) inputbox_instructions_string; + break; + default: + heading = "Internal mconf error!"; + /* panic? */; + } + + switch (dialog_inputbox(prompt ? prompt : "Main Menu", + heading, 10, 75, + sym_get_string_value(menu->sym))) { + 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 255: + return; + } + } +} + +static void conf_load(void) +{ + while (1) { + switch (dialog_inputbox(NULL, load_config_text, 11, 55, + filename)) { + 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 255: + return; + } + } +} + +static void conf_save(void) +{ + while (1) { + switch (dialog_inputbox(NULL, save_config_text, 11, 55, + filename)) { + 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 255: + return; + } + } +} + +static void conf_cleanup(void) +{ + tcsetattr(1, TCSAFLUSH, &ios_org); + unlink(".help.tmp"); +} + +static void winch_handler(int sig) +{ + struct winsize ws; + + if (ioctl(1, TIOCGWINSZ, &ws) == -1) { + rows = 24; + cols = 80; + } else { + rows = ws.ws_row; + cols = ws.ws_col; + } + + if (rows < 19 || cols < 80) { + end_dialog(); + fprintf(stderr, "Your display is too small to run Menuconfig!\n"); + fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); + exit(1); + } + + rows -= 4; + cols -= 5; + +} + +int main(int ac, char **av) +{ + int stat; + char *mode; + struct symbol *sym; + + conf_parse(av[1]); + conf_read(NULL); + + sym = sym_lookup("VERSION", 0); + sym_calc_value(sym); + snprintf(menu_backtitle, 128, "Buildroot 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(); + init_dialog(); + signal(SIGWINCH, winch_handler); + conf(&rootmenu); + end_dialog(); + + /* Restart dialog to act more like when lxdialog was still separate */ + init_dialog(); + do { + stat = dialog_yesno(NULL, + "Do you wish to save your new Buildroot configuration?", 5, 60); + } while (stat < 0); + end_dialog(); + + if (stat == 0) { + conf_write(NULL); + printf("\n\n" + "*** End of Buildroot configuration.\n" + "*** Check the top-level Makefile for additional configuration options.\n\n"); + } else + printf("\n\nYour Buildroot configuration changes were NOT saved.\n\n"); + + return 0; +} diff --git a/package/config/menu.c b/package/config/menu.c new file mode 100644 index 0000000000..6425296fc3 --- /dev/null +++ b/package/config/menu.c @@ -0,0 +1,431 @@ +/* + * 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; +struct menu *current_menu, *current_entry; +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) +{ +} + +void menu_add_menu(void) +{ + current_menu = current_entry; + last_entry_ptr = ¤t_entry->list; +} + +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'\n", + 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->text = prompt; + prop->expr = expr; + prop->visible.expr = menu_check_dep(dep); + + if (prompt) { + if (current_entry->prompt) + menu_warn(current_entry, "prompt redefined\n"); + current_entry->prompt = prop; + } + + return prop; +} + +void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) +{ + 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 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 (!sym_string_valid(sym, prop->expr->left.sym->name) || + !sym_string_valid(sym, prop->expr->right.sym->name)) + 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\n"); + + if (sym_is_choice(sym) && !parent->prompt) + menu_warn(parent, "choice must have a prompt\n"); + + /* 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; +} + +struct file *file_lookup(const char *name) +{ + struct file *file; + + for (file = file_list; file; file = file->next) { + if (!strcmp(name, file->name)) + return file; + } + + file = malloc(sizeof(*file)); + memset(file, 0, sizeof(*file)); + file->name = strdup(name); + file->next = file_list; + file_list = file; + return file; +} + +int file_write_dep(const char *name) +{ + struct file *file; + FILE *out; + + if (!name) + name = ".config.cmd"; + out = fopen(".config.tmp", "w"); + if (!out) + return 1; + fprintf(out, "deps_config := \\\n"); + for (file = file_list; file; file = file->next) { + if (file->next) + fprintf(out, "\t%s \\\n", file->name); + else + fprintf(out, "\t%s\n", file->name); + } + fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n"); + fclose(out); + rename(".config.tmp", name); + return 0; +} + diff --git a/package/config/menubox.c b/package/config/menubox.c new file mode 100644 index 0000000000..431f09fc99 --- /dev/null +++ b/package/config/menubox.c @@ -0,0 +1,436 @@ +/* + * 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 +print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey) +{ + int j; + char menu_item[menu_width+1]; + + strncpy(menu_item, item, menu_width); + menu_item[menu_width] = 0; + j = first_alpha(menu_item, "YyNnMm"); + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); +#if OLD_NCURSES + { + int i; + for (i = 0; i < menu_width; i++) + waddch (win, ' '); + } +#else + wclrtoeol(win); +#endif + wattrset (win, selected ? item_selected_attr : item_attr); + mvwaddstr (win, choice, item_x, menu_item); + if (hotkey) { + wattrset (win, selected ? tag_key_selected_attr : tag_key_attr); + mvwaddch(win, choice, item_x+j, menu_item[j]); + } + if (selected) { + wmove (win, choice, item_x+1); + wrefresh (win); + } +} + +/* + * 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, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + 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 + height < item_no)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + wmove(win, cur_y, cur_x); +} + +/* + * 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); +} + +/* + * Display a menu for choosing among a number of options + */ +int +dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *current, int item_no, + struct dialog_list_item ** items) +{ + int i, j, x, y, box_x, box_y; + int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice; + WINDOW *dialog, *menu; + FILE *f; + + max_choice = MIN (menu_height, item_no); + + /* 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, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + wbkgdset (dialog, dialog_attr & A_COLOR); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + 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, + menubox_border_attr, menubox_attr); + + /* + * Find length of longest item in order to center menu. + * Set 'choice' to default item. + */ + item_x = 0; + for (i = 0; i < item_no; i++) { + item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2)); + if (strcmp(current, items[i]->tag) == 0) choice = i; + } + + item_x = (menu_width - item_x) / 2; + + /* get the scroll info from the temp file */ + if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) { + if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) && + (scroll+max_choice > choice) && (scroll >= 0) && + (scroll+max_choice <= item_no) ) { + first_item = scroll; + choice = choice - scroll; + fclose(f); + } else { + scroll=0; + remove("lxdialog.scrltmp"); + fclose(f); + f=NULL; + } + } + if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) { + if (choice >= item_no-max_choice/2) + scroll = first_item = item_no-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 (menu, items[first_item + i]->name, i, i == choice, + (items[first_item + i]->tag[0] != ':')); + } + + wnoutrefresh (menu); + + print_arrows(dialog, item_no, 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 != ESC) { + key = wgetch(menu); + + if (key < 256 && isalpha(key)) key = tolower(key); + + if (strchr("ynm", key)) + i = max_choice; + else { + for (i = choice+1; i < max_choice; i++) { + j = first_alpha(items[scroll + i]->name, "YyNnMm>"); + if (key == tolower(items[scroll + i]->name[j])) + break; + } + if (i == max_choice) + for (i = 0; i < max_choice; i++) { + j = first_alpha(items[scroll + i]->name, "YyNnMm>"); + if (key == tolower(items[scroll + i]->name[j])) + break; + } + } + + if (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE) { + + print_item (menu, items[scroll + choice]->name, choice, FALSE, + (items[scroll + choice]->tag[0] != ':')); + + if (key == KEY_UP || key == '-') { + if (choice < 2 && scroll) { + /* Scroll menu down */ + scrollok (menu, TRUE); + wscrl (menu, -1); + scrollok (menu, FALSE); + + scroll--; + + print_item (menu, items[scroll]->name, 0, FALSE, + (items[scroll]->tag[0] != ':')); + } else + choice = MAX(choice - 1, 0); + + } else if (key == KEY_DOWN || key == '+') { + + print_item (menu, items[scroll + choice]->name, choice, FALSE, + (items[scroll + choice]->tag[0] != ':')); + + if ((choice > max_choice-3) && + (scroll + max_choice < item_no) + ) { + /* Scroll menu up */ + scrollok (menu, TRUE); + scroll (menu); + scrollok (menu, FALSE); + + scroll++; + + print_item (menu, items[scroll + max_choice - 1]->name, + max_choice-1, FALSE, + (items[scroll + max_choice - 1]->tag[0] != ':')); + } 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) { + wscrl (menu, -1); + scroll--; + print_item (menu, items[scroll]->name, 0, FALSE, + (items[scroll]->tag[0] != ':')); + } else { + if (choice > 0) + choice--; + } + } + scrollok (menu, FALSE); + + } else if (key == KEY_NPAGE) { + for (i=0; (i < max_choice); i++) { + if (scroll+max_choice < item_no) { + scrollok (menu, TRUE); + scroll(menu); + scrollok (menu, FALSE); + scroll++; + print_item (menu, items[scroll + max_choice - 1]->name, + max_choice-1, FALSE, + (items[scroll + max_choice - 1]->tag[0] != ':')); + } else { + if (choice+1 < max_choice) + choice++; + } + } + + } else + choice = i; + + print_item (menu, items[scroll + choice]->name, choice, TRUE, + (items[scroll + choice]->tag[0] != ':')); + + print_arrows(dialog, item_no, 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': + /* save scroll info */ + if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) { + fprintf(f,"%d\n",scroll); + fclose(f); + } + delwin (dialog); + items[scroll + choice]->selected = 1; + switch (key) { + case 's': return 3; + case 'y': return 3; + case 'n': return 4; + case 'm': return 5; + case ' ': return 6; + } + return 0; + case 'h': + case '?': + button = 2; + case '\n': + delwin (dialog); + items[scroll + choice]->selected = 1; + + remove("lxdialog.scrltmp"); + return button; + case 'e': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + remove("lxdialog.scrltmp"); + return -1; /* ESC pressed */ +} diff --git a/package/config/msgbox.c b/package/config/msgbox.c new file mode 100644 index 0000000000..93692e1fbc --- /dev/null +++ b/package/config/msgbox.c @@ -0,0 +1,85 @@ +/* + * msgbox.c -- implements the message box and info 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. + */ + +#include "dialog.h" + +/* + * Display a message box. Program will pause and display an "OK" button + * if the parameter 'pause' is non-zero. + */ +int +dialog_msgbox (const char *title, const char *prompt, int height, int width, + int pause) +{ + int i, x, y, key = 0; + WINDOW *dialog; + + /* 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, dialog_attr, border_attr); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 2); + + if (pause) { + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + print_button (dialog, " Ok ", + height - 2, width / 2 - 4, TRUE); + + wrefresh (dialog); + while (key != ESC && key != '\n' && key != ' ' && + key != 'O' && key != 'o' && key != 'X' && key != 'x') + key = wgetch (dialog); + } else { + key = '\n'; + wrefresh (dialog); + } + + delwin (dialog); + return key == ESC ? -1 : 0; +} diff --git a/package/config/symbol.c b/package/config/symbol.c new file mode 100644 index 0000000000..a9fae9c13a --- /dev/null +++ b/package/config/symbol.c @@ -0,0 +1,771 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +struct symbol symbol_yes = { + .name = "y", + .curr = { "y", yes }, + .flags = SYMBOL_YES|SYMBOL_VALID, +}, symbol_mod = { + .name = "m", + .curr = { "m", mod }, + .flags = SYMBOL_MOD|SYMBOL_VALID, +}, symbol_no = { + .name = "n", + .curr = { "n", no }, + .flags = SYMBOL_NO|SYMBOL_VALID, +}, symbol_empty = { + .name = "", + .curr = { "", no }, + .flags = SYMBOL_VALID, +}; + +int sym_change_count; +struct symbol *modules_sym; +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; + char *p; + static bool inited = false; + + if (inited) + return; + inited = true; + + sym = sym_lookup("VERSION", 0); + sym->type = S_STRING; + sym->flags |= SYMBOL_AUTO; + p = getenv("VERSION"); + if (p) + sym_add_default(sym, p); + + sym = sym_lookup("TARGET_ARCH", 0); + sym->type = S_STRING; + sym->flags |= SYMBOL_AUTO; + p = getenv("TARGET_ARCH"); + if (p) + sym_add_default(sym, p); + +} + +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 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->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->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->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); + + if (memcmp(&oldval, &sym->curr, sizeof(oldval))) + sym_set_changed(sym); + if (modules_sym == sym) + 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_NEW) { + sym->flags &= ~SYMBOL_NEW; + sym_set_changed(sym); + } + if (sym_is_choice_value(sym) && val == yes) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + + cs->user.val = sym; + cs->flags &= ~SYMBOL_NEW; + } + + sym->user.tri = val; + if (oldval != val) { + sym_clear_all_valid(); + if (sym == modules_sym) + sym_set_all_changed(); + } + + return true; +} + +tristate sym_toggle_tristate_value(struct symbol *sym) +{ + tristate oldval, newval; + + oldval = newval = sym_get_tristate_value(sym); + do { + switch (newval) { + case no: + newval = mod; + break; + case mod: + newval = yes; + break; + case yes: + newval = no; + break; + } + if (sym_set_tristate_value(sym, newval)) + break; + } while (oldval != newval); + return newval; +} + +bool sym_string_valid(struct symbol *sym, const char *str) +{ + char ch; + + switch (sym->type) { + case S_STRING: + return true; + case S_INT: + ch = *str++; + if (ch == '-') + ch = *str++; + if (!isdigit(ch)) + return false; + if (ch == '0' && *str != 0) + return false; + while ((ch = *str++)) { + if (!isdigit(ch)) + return false; + } + return true; + case S_HEX: + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + str += 2; + ch = *str++; + do { + if (!isxdigit(ch)) + return false; + } while ((ch = *str++)); + return true; + case S_BOOLEAN: + case S_TRISTATE: + switch (str[0]) { + case 'y': case 'Y': + 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 >= strtol(prop->expr->left.sym->name, NULL, 10) && + val <= strtol(prop->expr->right.sym->name, NULL, 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 >= strtol(prop->expr->left.sym->name, NULL, 16) && + val <= strtol(prop->expr->right.sym->name, NULL, 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_NEW) { + sym->flags &= ~SYMBOL_NEW; + sym_set_changed(sym); + } + + oldval = sym->user.val; + size = strlen(newval) + 1; + if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { + size += 2; + sym->user.val = val = malloc(size); + *val++ = '0'; + *val++ = 'x'; + } else if (!oldval || strcmp(oldval, newval)) + sym->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; + symbol->flags = SYMBOL_NEW; + 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_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_DONE) + return NULL; + if (sym->flags & SYMBOL_CHECK) { + printf("Warning! Found recursive dependency: %s", sym->name); + return sym; + } + + 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); + 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"; +} diff --git a/package/config/textbox.c b/package/config/textbox.c new file mode 100644 index 0000000000..a5a460b5cc --- /dev/null +++ b/package/config/textbox.c @@ -0,0 +1,556 @@ +/* + * 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, int height, int width); + +static int hscroll, fd, file_size, bytes_read; +static int begin_reached = 1, end_reached, page_length; +static char *buf, *page; + +/* + * Display text from a file in a dialog box. + */ +int +dialog_textbox (const char *title, const char *file, int height, int width) +{ + int i, x, y, cur_x, cur_y, fpos, key = 0; + int passed_end; + char search_term[MAX_LEN + 1]; + WINDOW *dialog, *text; + + search_term[0] = '\0'; /* no search term entered yet */ + + /* Open input file for reading */ + if ((fd = open (file, O_RDONLY)) == -1) { + endwin (); + fprintf (stderr, + "\nCan't open input file in dialog_textbox().\n"); + exit (-1); + } + /* Get file size. Actually, 'file_size' is the real file size - 1, + since it's only the last byte offset from the beginning */ + if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { + endwin (); + fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); + exit (-1); + } + /* Restore file pointer to beginning of file after getting file size */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + /* Allocate space for read buffer */ + if ((buf = malloc (BUF_SIZE + 1)) == NULL) { + endwin (); + fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; /* mark end of valid data */ + page = buf; /* page is pointer to start of page to be displayed */ + + /* 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 text region, used for scrolling text */ + text = subwin (dialog, height - 4, width - 2, y + 1, x + 1); + wattrset (text, dialog_attr); + wbkgdset (text, dialog_attr & A_COLOR); + + keypad (text, TRUE); + + /* register the new window, along with its borders */ + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + wbkgdset (dialog, dialog_attr & A_COLOR); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + 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 (text, height - 4, width - 2, dialog_attr); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + + while ((key != ESC) && (key != '\n')) { + key = wgetch (dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': + delwin (dialog); + free (buf); + close (fd); + return 0; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + /* First page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Yes, we have to read it in */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'G': /* Last page */ + case KEY_END: + + end_reached = 1; + /* Last page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos < file_size) { /* Yes, we have to read it in */ + if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf + bytes_read; + back_lines (height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + 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 (text, TRUE); + wscrl (text, -1); /* Scroll text region down one line */ + scrollok (text, FALSE); + page_length = 0; + passed_end = 0; + for (i = 0; i < height - 4; i++) { + if (!i) { + /* print first line of page */ + print_line (text, 0, width - 2); + wnoutrefresh (text); + } 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, height, width); + 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 + height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: + if (!end_reached) { + begin_reached = 0; + scrollok (text, TRUE); + scroll (text); /* Scroll text region up one line */ + scrollok (text, FALSE); + print_line (text, height - 5, width - 2); + wnoutrefresh (text); + print_position (dialog, height, width); + 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; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + 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); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + 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); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case ESC: + break; + } + } + + delwin (dialog); + free (buf); + close (fd); + return 1; /* ESC pressed */ +} + +/* + * Go back 'n' lines in text file. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void +back_lines (int n) +{ + int i, fpos; + + begin_reached = 0; + /* We have to distinguish between end_reached and !end_reached + since at end of file, the line is not ended by a '\n'. + The code inside 'if' basically does a '--page' to move one + character backward so as to skip '\n' of the previous line */ + if (!end_reached) { + /* Either beginning of buffer or beginning of file reached? */ + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Not beginning of file yet */ + /* We've reached beginning of buffer, but not beginning of + file yet, so read previous part of file into buffer. + Note that we only move backward for BUF_SIZE/2 bytes, + but not BUF_SIZE bytes to avoid re-reading again in + print_page() later */ + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) + == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + if (*(--page) != '\n') { /* '--page' here */ + /* Something's wrong... */ + endwin (); + fprintf (stderr, "\nInternal error in back_lines().\n"); + exit (-1); + } + } + /* Go back 'n' lines */ + for (i = 0; i < n; i++) + do { + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), + SEEK_CUR) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer" + " in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in " + "back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + } 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, fpos; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + /* Either end of file or end of buffer reached */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "get_line().\n"); + exit (-1); + } + if (fpos < file_size) { /* Not end of file yet */ + /* We've reached end of buffer, but not end of file yet, + so read next part of file into buffer */ + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in get_line().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + page = buf; + } else { + 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 height, int width) +{ + int fpos, percent; + + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in print_position().\n"); + exit (-1); + } + wattrset (win, position_indicator_attr); + wbkgdset (win, position_indicator_attr & A_COLOR); + percent = !file_size ? + 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; + wmove (win, height - 3, width - 9); + wprintw (win, "(%3d%%)", percent); +} diff --git a/package/config/util.c b/package/config/util.c new file mode 100644 index 0000000000..0a2f827570 --- /dev/null +++ b/package/config/util.c @@ -0,0 +1,375 @@ +/* + * 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" + + +/* use colors by default? */ +bool use_colors = 1; + +char *backtitle = NULL; + +const char *dialog_result; + +/* + * Attribute values, default is for mono display + */ +chtype attributes[] = +{ + A_NORMAL, /* screen_attr */ + A_NORMAL, /* shadow_attr */ + A_NORMAL, /* dialog_attr */ + A_BOLD, /* title_attr */ + A_NORMAL, /* border_attr */ + A_REVERSE, /* button_active_attr */ + A_DIM, /* button_inactive_attr */ + A_REVERSE, /* button_key_active_attr */ + A_BOLD, /* button_key_inactive_attr */ + A_REVERSE, /* button_label_active_attr */ + A_NORMAL, /* button_label_inactive_attr */ + A_NORMAL, /* inputbox_attr */ + A_NORMAL, /* inputbox_border_attr */ + A_NORMAL, /* searchbox_attr */ + A_BOLD, /* searchbox_title_attr */ + A_NORMAL, /* searchbox_border_attr */ + A_BOLD, /* position_indicator_attr */ + A_NORMAL, /* menubox_attr */ + A_NORMAL, /* menubox_border_attr */ + A_NORMAL, /* item_attr */ + A_REVERSE, /* item_selected_attr */ + A_BOLD, /* tag_attr */ + A_REVERSE, /* tag_selected_attr */ + A_BOLD, /* tag_key_attr */ + A_REVERSE, /* tag_key_selected_attr */ + A_BOLD, /* check_attr */ + A_REVERSE, /* check_selected_attr */ + A_BOLD, /* uarrow_attr */ + A_BOLD /* darrow_attr */ +}; + + +#include "colors.h" + +/* + * Table of color values + */ +int color_table[][3] = +{ + {SCREEN_FG, SCREEN_BG, SCREEN_HL}, + {SHADOW_FG, SHADOW_BG, SHADOW_HL}, + {DIALOG_FG, DIALOG_BG, DIALOG_HL}, + {TITLE_FG, TITLE_BG, TITLE_HL}, + {BORDER_FG, BORDER_BG, BORDER_HL}, + {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, + {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, + {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, + {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, + {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, + {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, + BUTTON_LABEL_INACTIVE_HL}, + {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, + {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, + {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, + {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, + {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, + {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, + {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, + {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, + {ITEM_FG, ITEM_BG, ITEM_HL}, + {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, + {TAG_FG, TAG_BG, TAG_HL}, + {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, + {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, + {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, + {CHECK_FG, CHECK_BG, CHECK_HL}, + {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, + {UARROW_FG, UARROW_BG, UARROW_HL}, + {DARROW_FG, DARROW_BG, DARROW_HL}, +}; /* color_table */ + +/* + * 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, screen_attr); + /* Display background title if it exists ... - SLH */ + if (backtitle != NULL) { + int i; + + wattrset (stdscr, screen_attr); + mvwaddstr (stdscr, 0, 1, (char *)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 (void) +{ + initscr (); /* Init curses */ + keypad (stdscr, TRUE); + cbreak (); + noecho (); + + + if (use_colors) /* Set up colors */ + color_setup (); + + + dialog_clear (); +} + +/* + * Setup for color display + */ +void +color_setup (void) +{ + int i; + + if (has_colors ()) { /* Terminal supports color? */ + start_color (); + + /* Initialize color pairs */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + init_pair (i + 1, color_table[i][0], color_table[i][1]); + + /* Setup color attributes */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + attributes[i] = C_ATTR (color_table[i][2], i + 1); + } +} + +/* + * End using dialog functions. + */ +void +end_dialog (void) +{ + endwin (); +} + + +/* + * 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 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 ? button_active_attr : button_inactive_attr); + waddstr (win, "<"); + temp = strspn (label, " "); + label += temp; + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + for (i = 0; i < temp; i++) + waddch (win, ' '); + wattrset (win, selected ? button_key_active_attr + : button_key_inactive_attr); + waddch (win, label[0]); + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + waddstr (win, (char *)label + 1); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + 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, shadow_attr); + 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; +} + +/* + * Get the first selected item in the dialog_list_item list. + */ +struct dialog_list_item * +first_sel_item(int item_no, struct dialog_list_item ** items) +{ + int i; + + for (i = 0; i < item_no; i++) { + if (items[i]->selected) + return items[i]; + } + + return NULL; +} diff --git a/package/config/yesno.c b/package/config/yesno.c new file mode 100644 index 0000000000..11fcc25f51 --- /dev/null +++ b/package/config/yesno.c @@ -0,0 +1,118 @@ +/* + * 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; + + /* 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, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + print_buttons(dialog, height, width, 0); + + while (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 ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/package/config/zconf.l b/package/config/zconf.l new file mode 100644 index 0000000000..55517b2877 --- /dev/null +++ b/package/config/zconf.l @@ -0,0 +1,366 @@ +%option backup nostdinit noyywrap never-interactive full ecs +%option 8bit backup nodefault perf-report perf-report +%x COMMAND HELP STRING PARAM +%{ +/* + * 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 + +char *text; +static char *text_ptr; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +static int last_ts, first_ts; + +static void zconf_endhelp(void); +static struct buffer *zconf_endfile(void); + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_ptr = text; + text_size = 0; + *text_ptr = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + text = realloc(text, new_size); + text_asize = new_size; + text_ptr = text + text_size; + } + memcpy(text_ptr, str, size); + text_ptr += size; + text_size += size; + *text_ptr = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} +%} + +ws [ \n\t] +n [A-Za-z0-9_] + +%% + int str = 0; + int ts, i; + +[ \t]*#.*\n current_file->lineno++; +[ \t]*#.* + +[ \t]*\n current_file->lineno++; return T_EOL; + +[ \t]+ { + BEGIN(COMMAND); +} + +. { + unput(yytext[0]); + BEGIN(COMMAND); +} + + +{ + "mainmenu" BEGIN(PARAM); return T_MAINMENU; + "menu" BEGIN(PARAM); return T_MENU; + "endmenu" BEGIN(PARAM); return T_ENDMENU; + "source" BEGIN(PARAM); return T_SOURCE; + "choice" BEGIN(PARAM); return T_CHOICE; + "endchoice" BEGIN(PARAM); return T_ENDCHOICE; + "comment" BEGIN(PARAM); return T_COMMENT; + "config" BEGIN(PARAM); return T_CONFIG; + "menuconfig" BEGIN(PARAM); return T_MENUCONFIG; + "help" BEGIN(PARAM); return T_HELP; + "if" BEGIN(PARAM); return T_IF; + "endif" BEGIN(PARAM); return T_ENDIF; + "depends" BEGIN(PARAM); return T_DEPENDS; + "requires" BEGIN(PARAM); return T_REQUIRES; + "optional" BEGIN(PARAM); return T_OPTIONAL; + "default" BEGIN(PARAM); return T_DEFAULT; + "prompt" BEGIN(PARAM); return T_PROMPT; + "tristate" BEGIN(PARAM); return T_TRISTATE; + "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE; + "bool" BEGIN(PARAM); return T_BOOLEAN; + "boolean" BEGIN(PARAM); return T_BOOLEAN; + "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN; + "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN; + "int" BEGIN(PARAM); return T_INT; + "hex" BEGIN(PARAM); return T_HEX; + "string" BEGIN(PARAM); return T_STRING; + "select" BEGIN(PARAM); return T_SELECT; + "enable" BEGIN(PARAM); return T_SELECT; + "range" BEGIN(PARAM); return T_RANGE; + {n}+ { + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + . + \n current_file->lineno++; BEGIN(INITIAL); +} + +{ + "&&" return T_AND; + "||" return T_OR; + "(" return T_OPEN_PAREN; + ")" return T_CLOSE_PAREN; + "!" return T_NOT; + "=" return T_EQUAL; + "!=" return T_UNEQUAL; + "if" return T_IF; + "on" return T_ON; + \"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); + } + \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; + --- /* ignore */ + ({n}|[-/.])+ { + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + #.* /* comment */ + \\\n current_file->lineno++; + . + <> { + BEGIN(INITIAL); + } +} + +{ + [^'"\\\n]+/\n { + append_string(yytext, yyleng); + zconflval.string = text; + return T_WORD_QUOTE; + } + [^'"\\\n]+ { + append_string(yytext, yyleng); + } + \\.?/\n { + append_string(yytext + 1, yyleng - 1); + zconflval.string = text; + return T_WORD_QUOTE; + } + \\.? { + append_string(yytext + 1, yyleng - 1); + } + \'|\" { + if (str == yytext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(yytext, 1); + } + \n { + printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + current_file->lineno++; + BEGIN(INITIAL); + return T_EOL; + } + <> { + BEGIN(INITIAL); + } +} + +{ + [ \t]+ { + ts = 0; + for (i = 0; i < yyleng; i++) { + if (yytext[i] == '\t') + ts = (ts & ~7) + 8; + else + ts++; + } + last_ts = ts; + if (first_ts) { + if (ts < first_ts) { + zconf_endhelp(); + return T_HELPTEXT; + } + ts -= first_ts; + while (ts > 8) { + append_string(" ", 8); + ts -= 8; + } + append_string(" ", ts); + } + } + [ \t]*\n/[^ \t\n] { + current_file->lineno++; + zconf_endhelp(); + return T_HELPTEXT; + } + [ \t]*\n { + current_file->lineno++; + append_string("\n", 1); + } + [^ \t\n].* { + append_string(yytext, yyleng); + if (!first_ts) + first_ts = last_ts; + } + <> { + zconf_endhelp(); + return T_HELPTEXT; + } +} + +<> { + if (current_buf) { + zconf_endfile(); + return T_EOF; + } + fclose(yyin); + yyterminate(); +} + +%% +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) +{ + yyin = zconf_fopen(name); + if (!yyin) { + 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; + yyin = zconf_fopen(name); + if (!yyin) { + printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + if (file->flags & FILE_BUSY) { + printf("recursive scan (%s)?\n", name); + exit(1); + } + if (file->flags & FILE_SCANNED) { + printf("file %s already scanned?\n", name); + exit(1); + } + file->flags |= FILE_BUSY; + file->lineno = 1; + file->parent = current_file; + current_file = file; +} + +static struct buffer *zconf_endfile(void) +{ + struct buffer *parent; + + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + + parent = current_buf->parent; + if (parent) { + fclose(yyin); + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(parent->state); + } + free(current_buf); + current_buf = parent; + + return parent; +} + +int zconf_lineno(void) +{ + if (current_buf) + return current_file->lineno - 1; + else + return 0; +} + +char *zconf_curname(void) +{ + if (current_buf) + return current_file->name; + else + return ""; +} diff --git a/package/config/zconf.tab.c_shipped b/package/config/zconf.tab.c_shipped new file mode 100644 index 0000000000..83dbf9ed57 --- /dev/null +++ b/package/config/zconf.tab.c_shipped @@ -0,0 +1,2127 @@ +/* A Bison parser, made by GNU Bison 1.875a. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* 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 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + 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_DEFAULT = 275, + T_TRISTATE = 276, + T_DEF_TRISTATE = 277, + T_BOOLEAN = 278, + T_DEF_BOOLEAN = 279, + T_STRING = 280, + T_INT = 281, + T_HEX = 282, + T_WORD = 283, + T_WORD_QUOTE = 284, + T_UNEQUAL = 285, + T_EOF = 286, + T_EOL = 287, + T_CLOSE_PAREN = 288, + T_OPEN_PAREN = 289, + T_ON = 290, + T_SELECT = 291, + T_RANGE = 292, + T_OR = 293, + T_AND = 294, + T_EQUAL = 295, + T_NOT = 296 + }; +#endif +#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_DEFAULT 275 +#define T_TRISTATE 276 +#define T_DEF_TRISTATE 277 +#define T_BOOLEAN 278 +#define T_DEF_BOOLEAN 279 +#define T_STRING 280 +#define T_INT 281 +#define T_HEX 282 +#define T_WORD 283 +#define T_WORD_QUOTE 284 +#define T_UNEQUAL 285 +#define T_EOF 286 +#define T_EOL 287 +#define T_CLOSE_PAREN 288 +#define T_OPEN_PAREN 289 +#define T_ON 290 +#define T_SELECT 291 +#define T_RANGE 292 +#define T_OR 293 +#define T_AND 294 +#define T_EQUAL 295 +#define T_NOT 296 + + + + +/* 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 printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +extern int zconflex(void); +static void zconfprint(const char *err, ...); +static void zconferror(const char *err); +static bool zconf_endtoken(int token, int starttoken, int endtoken); + +struct symbol *symbol_hash[257]; + +#define YYERROR_VERBOSE + + +/* 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 + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) + +typedef union YYSTYPE { + int token; + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; +} YYSTYPE; +/* Line 191 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. */ + + +#define LKC_DIRECT_LINK +#include "lkc.h" + + +/* Line 214 of yacc.c. */ + + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short 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) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 201 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 42 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 41 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 104 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 182 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 296 + +#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, 36, 37, 38, 39, 40, 41 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 17, 19, + 21, 23, 26, 28, 30, 32, 34, 36, 38, 42, + 45, 49, 52, 53, 56, 59, 62, 65, 69, 74, + 78, 83, 87, 91, 95, 100, 105, 110, 116, 119, + 122, 124, 128, 131, 132, 135, 138, 141, 144, 149, + 153, 157, 160, 165, 166, 169, 173, 175, 179, 182, + 183, 186, 189, 192, 196, 199, 201, 205, 208, 209, + 212, 215, 218, 222, 226, 228, 232, 235, 238, 241, + 242, 245, 248, 253, 257, 261, 262, 265, 267, 269, + 272, 275, 278, 280, 282, 283, 286, 288, 292, 296, + 300, 303, 307, 311, 313 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 43, 0, -1, -1, 43, 44, -1, 45, -1, 55, + -1, 66, -1, 3, 77, 79, -1, 5, -1, 15, + -1, 8, -1, 1, 79, -1, 61, -1, 71, -1, + 47, -1, 49, -1, 69, -1, 79, -1, 10, 28, + 32, -1, 46, 50, -1, 11, 28, 32, -1, 48, + 50, -1, -1, 50, 51, -1, 50, 75, -1, 50, + 73, -1, 50, 32, -1, 21, 76, 32, -1, 22, + 81, 80, 32, -1, 23, 76, 32, -1, 24, 81, + 80, 32, -1, 26, 76, 32, -1, 27, 76, 32, + -1, 25, 76, 32, -1, 19, 77, 80, 32, -1, + 20, 81, 80, 32, -1, 36, 28, 80, 32, -1, + 37, 82, 82, 80, 32, -1, 7, 32, -1, 52, + 56, -1, 78, -1, 53, 58, 54, -1, 53, 58, + -1, -1, 56, 57, -1, 56, 75, -1, 56, 73, + -1, 56, 32, -1, 19, 77, 80, 32, -1, 21, + 76, 32, -1, 23, 76, 32, -1, 18, 32, -1, + 20, 28, 80, 32, -1, -1, 58, 45, -1, 14, + 81, 32, -1, 78, -1, 59, 62, 60, -1, 59, + 62, -1, -1, 62, 45, -1, 62, 66, -1, 62, + 55, -1, 4, 77, 32, -1, 63, 74, -1, 78, + -1, 64, 67, 65, -1, 64, 67, -1, -1, 67, + 45, -1, 67, 66, -1, 67, 55, -1, 67, 1, + 32, -1, 6, 77, 32, -1, 68, -1, 9, 77, + 32, -1, 70, 74, -1, 12, 32, -1, 72, 13, + -1, -1, 74, 75, -1, 74, 32, -1, 16, 35, + 81, 32, -1, 16, 81, 32, -1, 17, 81, 32, + -1, -1, 77, 80, -1, 28, -1, 29, -1, 5, + 79, -1, 8, 79, -1, 15, 79, -1, 32, -1, + 31, -1, -1, 14, 81, -1, 82, -1, 82, 40, + 82, -1, 82, 30, 82, -1, 34, 81, 33, -1, + 41, 81, -1, 81, 38, 81, -1, 81, 39, 81, + -1, 28, -1, 29, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 94, 94, 95, 98, 99, 100, 101, 102, 103, + 104, 105, 109, 110, 111, 112, 113, 114, 120, 128, + 134, 142, 152, 154, 155, 156, 157, 160, 166, 173, + 179, 186, 192, 198, 204, 210, 216, 222, 230, 239, + 245, 254, 255, 261, 263, 264, 265, 266, 269, 275, + 281, 287, 293, 299, 301, 306, 315, 324, 325, 331, + 333, 334, 335, 340, 347, 353, 362, 363, 369, 371, + 372, 373, 374, 377, 383, 390, 397, 404, 410, 417, + 418, 419, 422, 427, 432, 440, 442, 447, 448, 451, + 452, 453, 457, 457, 459, 460, 463, 464, 465, 466, + 467, 468, 469, 472, 473 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[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_DEFAULT", "T_TRISTATE", + "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT", + "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL", + "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR", + "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block", + "common_block", "config_entry_start", "config_stmt", + "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", + "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", + "choice_option_list", "choice_option", "choice_block", "if", "if_end", + "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt", + "menu_block", "source", "source_stmt", "comment", "comment_stmt", + "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", + "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short 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, 291, 292, 293, 294, + 295, 296 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, + 44, 44, 45, 45, 45, 45, 45, 45, 46, 47, + 48, 49, 50, 50, 50, 50, 50, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, + 54, 55, 55, 56, 56, 56, 56, 56, 57, 57, + 57, 57, 57, 58, 58, 59, 60, 61, 61, 62, + 62, 62, 62, 63, 64, 65, 66, 66, 67, 67, + 67, 67, 67, 68, 69, 70, 71, 72, 73, 74, + 74, 74, 75, 75, 75, 76, 76, 77, 77, 78, + 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, + 81, 81, 81, 82, 82 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 3, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, + 3, 2, 0, 2, 2, 2, 2, 3, 4, 3, + 4, 3, 3, 3, 4, 4, 4, 5, 2, 2, + 1, 3, 2, 0, 2, 2, 2, 2, 4, 3, + 3, 2, 4, 0, 2, 3, 1, 3, 2, 0, + 2, 2, 2, 3, 2, 1, 3, 2, 0, 2, + 2, 2, 3, 3, 1, 3, 2, 2, 2, 0, + 2, 2, 4, 3, 3, 0, 2, 1, 1, 2, + 2, 2, 1, 1, 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[] = +{ + 2, 0, 1, 0, 0, 0, 8, 0, 0, 10, + 0, 0, 0, 0, 9, 93, 92, 3, 4, 22, + 14, 22, 15, 43, 53, 5, 59, 12, 79, 68, + 6, 74, 16, 79, 13, 17, 11, 87, 88, 0, + 0, 0, 38, 0, 0, 0, 103, 104, 0, 0, + 0, 96, 19, 21, 39, 42, 58, 64, 0, 76, + 7, 63, 73, 75, 18, 20, 0, 100, 55, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, + 85, 0, 85, 85, 85, 26, 0, 0, 23, 0, + 25, 24, 0, 0, 0, 85, 85, 47, 44, 46, + 45, 0, 0, 0, 54, 41, 40, 60, 62, 57, + 61, 56, 81, 80, 0, 69, 71, 66, 70, 65, + 99, 101, 102, 98, 97, 77, 0, 0, 0, 94, + 94, 0, 94, 94, 0, 94, 0, 0, 0, 94, + 0, 78, 51, 94, 94, 0, 0, 89, 90, 91, + 72, 0, 83, 84, 0, 0, 0, 27, 86, 0, + 29, 0, 33, 31, 32, 0, 94, 0, 0, 49, + 50, 82, 95, 34, 35, 28, 30, 36, 0, 48, + 52, 37 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 1, 17, 18, 19, 20, 21, 22, 52, 88, + 23, 24, 105, 25, 54, 98, 55, 26, 109, 27, + 56, 28, 29, 117, 30, 58, 31, 32, 33, 34, + 89, 90, 57, 91, 131, 132, 106, 35, 155, 50, + 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -99 +static const short yypact[] = +{ + -99, 48, -99, 38, 46, 46, -99, 46, -29, -99, + 46, -17, -3, -11, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, -99, -99, -99, -99, -99, 38, + 12, 15, -99, 18, 51, 62, -99, -99, -11, -11, + 4, -24, 138, 138, 160, 121, 110, -4, 81, -4, + -99, -99, -99, -99, -99, -99, -19, -99, -99, -11, + -11, 70, 70, 73, 32, -11, 46, -11, 46, -11, + 46, -11, 46, 46, 46, -99, 36, 70, -99, 95, + -99, -99, 96, 46, 106, 46, 46, -99, -99, -99, + -99, 38, 38, 38, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, 112, -99, -99, -99, -99, -99, + -99, 117, -99, -99, -99, -99, -11, 33, 65, 131, + 1, 119, 131, 1, 136, 1, 153, 154, 155, 131, + 70, -99, -99, 131, 131, 156, 157, -99, -99, -99, + -99, 101, -99, -99, -11, 158, 159, -99, -99, 161, + -99, 162, -99, -99, -99, 163, 131, 164, 165, -99, + -99, -99, 99, -99, -99, -99, -99, -99, 166, -99, + -99, -99 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -99, -99, -99, 111, -99, -99, -99, -99, 178, -99, + -99, -99, -99, 91, -99, -99, -99, -99, -99, -99, + -99, -99, -99, -99, 115, -99, -99, -99, -99, -99, + -99, 146, 168, 89, 27, 0, 126, -1, -98, -48, + -63 +}; + +/* 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 -68 +static const short yytable[] = +{ + 66, 67, 36, 42, 39, 40, 71, 41, 123, 124, + 43, 44, 74, 75, 120, 154, 72, 46, 47, 69, + 70, 121, 122, 48, 140, 45, 127, 128, 112, 130, + 49, 133, 156, 135, 158, 159, 68, 161, 60, 69, + 70, 165, 69, 70, 61, 167, 168, 62, 2, 3, + 63, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 46, 47, 13, 14, 139, 152, 48, 126, 178, 15, + 16, 69, 70, 49, 37, 38, 129, 166, 151, 15, + 16, -67, 114, 64, -67, 5, 101, 7, 8, 102, + 10, 11, 12, 143, 65, 13, 103, 153, 46, 47, + 147, 148, 149, 69, 70, 125, 172, 134, 141, 136, + 137, 138, 15, 16, 5, 101, 7, 8, 102, 10, + 11, 12, 145, 146, 13, 103, 101, 7, 142, 102, + 10, 11, 12, 171, 144, 13, 103, 69, 70, 69, + 70, 15, 16, 100, 150, 154, 113, 108, 113, 116, + 73, 157, 15, 16, 74, 75, 70, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 104, 107, 160, 115, + 85, 110, 73, 118, 86, 87, 74, 75, 92, 93, + 94, 95, 111, 96, 119, 162, 163, 164, 169, 170, + 173, 174, 97, 175, 176, 177, 179, 180, 181, 53, + 99, 59 +}; + +static const unsigned char yycheck[] = +{ + 48, 49, 3, 32, 4, 5, 30, 7, 71, 72, + 10, 28, 16, 17, 33, 14, 40, 28, 29, 38, + 39, 69, 70, 34, 87, 28, 74, 75, 32, 77, + 41, 79, 130, 81, 132, 133, 32, 135, 39, 38, + 39, 139, 38, 39, 32, 143, 144, 32, 0, 1, + 32, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 28, 29, 14, 15, 28, 32, 34, 35, 166, 31, + 32, 38, 39, 41, 28, 29, 76, 140, 126, 31, + 32, 0, 1, 32, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 93, 32, 14, 15, 32, 28, 29, + 101, 102, 103, 38, 39, 32, 154, 80, 13, 82, + 83, 84, 31, 32, 4, 5, 6, 7, 8, 9, + 10, 11, 95, 96, 14, 15, 5, 6, 32, 8, + 9, 10, 11, 32, 28, 14, 15, 38, 39, 38, + 39, 31, 32, 54, 32, 14, 57, 56, 59, 58, + 12, 32, 31, 32, 16, 17, 39, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 55, 56, 32, 58, + 32, 56, 12, 58, 36, 37, 16, 17, 18, 19, + 20, 21, 56, 23, 58, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 21, + 54, 33 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 43, 0, 1, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 14, 15, 31, 32, 44, 45, 46, + 47, 48, 49, 52, 53, 55, 59, 61, 63, 64, + 66, 68, 69, 70, 71, 79, 79, 28, 29, 77, + 77, 77, 32, 77, 28, 28, 28, 29, 34, 41, + 81, 82, 50, 50, 56, 58, 62, 74, 67, 74, + 79, 32, 32, 32, 32, 32, 81, 81, 32, 38, + 39, 30, 40, 12, 16, 17, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 32, 36, 37, 51, 72, + 73, 75, 18, 19, 20, 21, 23, 32, 57, 73, + 75, 5, 8, 15, 45, 54, 78, 45, 55, 60, + 66, 78, 32, 75, 1, 45, 55, 65, 66, 78, + 33, 81, 81, 82, 82, 32, 35, 81, 81, 77, + 81, 76, 77, 81, 76, 81, 76, 76, 76, 28, + 82, 13, 32, 77, 28, 76, 76, 79, 79, 79, + 32, 81, 32, 32, 14, 80, 80, 32, 80, 80, + 32, 80, 32, 32, 32, 80, 82, 80, 80, 32, + 32, 32, 81, 32, 32, 32, 32, 32, 80, 32, + 32, 32 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#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 YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *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 int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* 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 YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, 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 + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#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 +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !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]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + 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 lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead 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 +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int 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 yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register 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 *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 ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# 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 lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead 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); + YYDSYMPRINTF ("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 lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* 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: + + { zconfprint("unexpected 'endmenu' statement"); ;} + break; + + case 9: + + { zconfprint("unexpected 'endif' statement"); ;} + break; + + case 10: + + { zconfprint("unexpected 'endchoice' statement"); ;} + break; + + case 11: + + { zconfprint("syntax error"); yyerrok; ;} + break; + + case 18: + + { + 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 19: + + { + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 20: + + { + 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 21: + + { + 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 27: + + { + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 28: + + { + menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 29: + + { + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 30: + + { + menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 31: + + { + menu_set_type(S_INT); + printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 32: + + { + menu_set_type(S_HEX); + printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 33: + + { + menu_set_type(S_STRING); + printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 34: + + { + menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 35: + + { + menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 36: + + { + 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 37: + + { + 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 38: + + { + 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 39: + + { + menu_end_entry(); + menu_add_menu(); +;} + break; + + case 40: + + { + if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 42: + + { + printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +;} + break; + + case 48: + + { + menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 49: + + { + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 50: + + { + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 51: + + { + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 52: + + { + 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()); +;} + break; + + case 55: + + { + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep(yyvsp[-1].expr); + menu_end_entry(); + menu_add_menu(); +;} + break; + + case 56: + + { + if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 58: + + { + printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +;} + break; + + case 63: + + { + menu_add_entry(NULL); + menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 64: + + { + menu_end_entry(); + menu_add_menu(); +;} + break; + + case 65: + + { + if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +;} + break; + + case 67: + + { + printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +;} + break; + + case 72: + + { zconfprint("invalid menu option"); yyerrok; ;} + break; + + case 73: + + { + yyval.string = yyvsp[-1].string; + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); +;} + break; + + case 74: + + { + zconf_nextfile(yyvsp[0].string); +;} + break; + + case 75: + + { + menu_add_entry(NULL); + menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 76: + + { + menu_end_entry(); +;} + break; + + case 77: + + { + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +;} + break; + + case 78: + + { + current_entry->sym->help = yyvsp[0].string; +;} + break; + + case 82: + + { + menu_add_dep(yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 83: + + { + menu_add_dep(yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 84: + + { + menu_add_dep(yyvsp[-1].expr); + printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 86: + + { + menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr); +;} + break; + + case 89: + + { yyval.token = T_ENDMENU; ;} + break; + + case 90: + + { yyval.token = T_ENDCHOICE; ;} + break; + + case 91: + + { yyval.token = T_ENDIF; ;} + break; + + case 94: + + { yyval.expr = NULL; ;} + break; + + case 95: + + { yyval.expr = yyvsp[0].expr; ;} + break; + + case 96: + + { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;} + break; + + case 97: + + { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} + break; + + case 98: + + { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} + break; + + case 99: + + { yyval.expr = yyvsp[-1].expr; ;} + break; + + case 100: + + { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;} + break; + + case 101: + + { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 102: + + { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 103: + + { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;} + break; + + case 104: + + { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;} + break; + + + } + +/* Line 999 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) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +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; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#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("MODULES", 0); + rootmenu.prompt = menu_add_prop(P_MENU, "Buildroot Configuration", NULL, NULL); + + //zconfdebug = 1; + zconfparse(); + if (zconfnerrs) + exit(1); + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) + printf("\n"); + else + sym->flags |= SYMBOL_CHECK_DONE; + } + + sym_change_count = 1; +} + +const char *zconf_tokenname(int token) +{ + switch (token) { + case T_MENU: return "menu"; + case T_ENDMENU: return "endmenu"; + case T_CHOICE: return "choice"; + case T_ENDCHOICE: return "endchoice"; + case T_IF: return "if"; + case T_ENDIF: return "endif"; + } + return ""; +} + +static bool zconf_endtoken(int token, int starttoken, int endtoken) +{ + if (token != endtoken) { + zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + if (current_menu->file != current_file) { + zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfprint("location of the '%s'", zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconferror(const char *err) +{ + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +} + +void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + 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 "confdata.c" +#include "expr.c" +#include "symbol.c" +#include "menu.c" + + diff --git a/package/config/zconf.tab.h_shipped b/package/config/zconf.tab.h_shipped new file mode 100644 index 0000000000..3b191ef599 --- /dev/null +++ b/package/config/zconf.tab.h_shipped @@ -0,0 +1,125 @@ +/* A Bison parser, made from zconf.y, by GNU bison 1.75. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef BISON_ZCONF_TAB_H +# define BISON_ZCONF_TAB_H + +/* 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_HELP = 266, + T_HELPTEXT = 267, + T_IF = 268, + T_ENDIF = 269, + T_DEPENDS = 270, + T_REQUIRES = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_DEFAULT = 274, + T_TRISTATE = 275, + T_BOOLEAN = 276, + T_INT = 277, + T_HEX = 278, + T_WORD = 279, + T_STRING = 280, + T_UNEQUAL = 281, + T_EOF = 282, + T_EOL = 283, + T_CLOSE_PAREN = 284, + T_OPEN_PAREN = 285, + T_ON = 286, + T_OR = 287, + T_AND = 288, + T_EQUAL = 289, + T_NOT = 290 + }; +#endif +#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_HELP 266 +#define T_HELPTEXT 267 +#define T_IF 268 +#define T_ENDIF 269 +#define T_DEPENDS 270 +#define T_REQUIRES 271 +#define T_OPTIONAL 272 +#define T_PROMPT 273 +#define T_DEFAULT 274 +#define T_TRISTATE 275 +#define T_BOOLEAN 276 +#define T_INT 277 +#define T_HEX 278 +#define T_WORD 279 +#define T_STRING 280 +#define T_UNEQUAL 281 +#define T_EOF 282 +#define T_EOL 283 +#define T_CLOSE_PAREN 284 +#define T_OPEN_PAREN 285 +#define T_ON 286 +#define T_OR 287 +#define T_AND 288 +#define T_EQUAL 289 +#define T_NOT 290 + + + + +#ifndef YYSTYPE +#line 33 "zconf.y" +typedef union { + int token; + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; +} yystype; +/* Line 1281 of /usr/share/bison/yacc.c. */ +#line 118 "zconf.tab.h" +# define YYSTYPE yystype +#endif + +extern YYSTYPE zconflval; + + +#endif /* not BISON_ZCONF_TAB_H */ + diff --git a/package/config/zconf.y b/package/config/zconf.y new file mode 100644 index 0000000000..f354c89e6c --- /dev/null +++ b/package/config/zconf.y @@ -0,0 +1,687 @@ +%{ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include + +#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) + +#define PRINTD 0x0001 +#define DEBUG_PARSE 0x0002 + +int cdebug = PRINTD; + +extern int zconflex(void); +static void zconfprint(const char *err, ...); +static void zconferror(const char *err); +static bool zconf_endtoken(int token, int starttoken, int endtoken); + +struct symbol *symbol_hash[257]; + +#define YYERROR_VERBOSE +%} +%expect 40 + +%union +{ + int token; + char *string; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; +} + +%token T_MAINMENU +%token T_MENU +%token T_ENDMENU +%token T_SOURCE +%token T_CHOICE +%token T_ENDCHOICE +%token T_COMMENT +%token T_CONFIG +%token T_MENUCONFIG +%token T_HELP +%token T_HELPTEXT +%token T_IF +%token T_ENDIF +%token T_DEPENDS +%token T_REQUIRES +%token T_OPTIONAL +%token T_PROMPT +%token T_DEFAULT +%token T_TRISTATE +%token T_DEF_TRISTATE +%token T_BOOLEAN +%token T_DEF_BOOLEAN +%token T_STRING +%token T_INT +%token T_HEX +%token T_WORD +%token T_WORD_QUOTE +%token T_UNEQUAL +%token T_EOF +%token T_EOL +%token T_CLOSE_PAREN +%token T_OPEN_PAREN +%token T_ON +%token T_SELECT +%token T_RANGE + +%left T_OR +%left T_AND +%left T_EQUAL T_UNEQUAL +%nonassoc T_NOT + +%type prompt +%type source +%type symbol +%type expr +%type if_expr +%type end + +%{ +#define LKC_DIRECT_LINK +#include "lkc.h" +%} +%% +input: /* empty */ + | input block +; + +block: common_block + | choice_stmt + | menu_stmt + | T_MAINMENU prompt nl_or_eof + | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); } + | T_ENDIF { zconfprint("unexpected 'endif' statement"); } + | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); } + | error nl_or_eof { zconfprint("syntax error"); yyerrok; } +; + +common_block: + if_stmt + | comment_stmt + | config_stmt + | menuconfig_stmt + | source_stmt + | nl_or_eof +; + + +/* config/menuconfig entry */ + +config_entry_start: T_CONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +config_stmt: config_entry_start config_option_list +{ + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +menuconfig_stmt: menuconfig_entry_start config_option_list +{ + 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()); +}; + +config_option_list: + /* empty */ + | config_option_list config_option + | config_option_list depends + | config_option_list help + | config_option_list T_EOL +; + +config_option: T_TRISTATE prompt_stmt_opt T_EOL +{ + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEF_TRISTATE expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_BOOLEAN prompt_stmt_opt T_EOL +{ + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEF_BOOLEAN expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_INT prompt_stmt_opt T_EOL +{ + menu_set_type(S_INT); + printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_HEX prompt_stmt_opt T_EOL +{ + menu_set_type(S_HEX); + printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_STRING prompt_stmt_opt T_EOL +{ + menu_set_type(S_STRING); + printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEFAULT expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_SELECT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_RANGE symbol symbol if_expr T_EOL +{ + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +}; + +/* choice entry */ + +choice: T_CHOICE T_EOL +{ + 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()); +}; + +choice_entry: choice choice_option_list +{ + menu_end_entry(); + menu_add_menu(); +}; + +choice_end: end +{ + if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +}; + +choice_stmt: + choice_entry choice_block choice_end + | choice_entry choice_block +{ + printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +}; + +choice_option_list: + /* empty */ + | choice_option_list choice_option + | choice_option_list depends + | choice_option_list help + | choice_option_list T_EOL +; + +choice_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_TRISTATE prompt_stmt_opt T_EOL +{ + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_BOOLEAN prompt_stmt_opt T_EOL +{ + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_OPTIONAL T_EOL +{ + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_DEFAULT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); +}; + +choice_block: + /* empty */ + | choice_block common_block +; + +/* if entry */ + +if: T_IF expr T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep($2); + menu_end_entry(); + menu_add_menu(); +}; + +if_end: end +{ + if (zconf_endtoken($1, T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +}; + +if_stmt: + if if_block if_end + | if if_block +{ + printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +}; + +if_block: + /* empty */ + | if_block common_block + | if_block menu_stmt + | if_block choice_stmt +; + +/* menu entry */ + +menu: T_MENU prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prop(P_MENU, $2, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +}; + +menu_entry: menu depends_list +{ + menu_end_entry(); + menu_add_menu(); +}; + +menu_end: end +{ + if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +}; + +menu_stmt: + menu_entry menu_block menu_end + | menu_entry menu_block +{ + printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); + zconfnerrs++; +}; + +menu_block: + /* empty */ + | menu_block common_block + | menu_block menu_stmt + | menu_block choice_stmt + | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; } +; + +source: T_SOURCE prompt T_EOL +{ + $$ = $2; + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +source_stmt: source +{ + zconf_nextfile($1); +}; + +/* comment entry */ + +comment: T_COMMENT prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prop(P_COMMENT, $2, NULL, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +}; + +comment_stmt: comment depends_list +{ + menu_end_entry(); +}; + +/* help option */ + +help_start: T_HELP T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +}; + +help: help_start T_HELPTEXT +{ + current_entry->sym->help = $2; +}; + +/* depends option */ + +depends_list: /* empty */ + | depends_list depends + | depends_list T_EOL +; + +depends: T_DEPENDS T_ON expr T_EOL +{ + menu_add_dep($3); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +} + | T_DEPENDS expr T_EOL +{ + menu_add_dep($2); + printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); +} + | T_REQUIRES expr T_EOL +{ + menu_add_dep($2); + printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); +}; + +/* prompt statement */ + +prompt_stmt_opt: + /* empty */ + | prompt if_expr +{ + menu_add_prop(P_PROMPT, $1, NULL, $2); +}; + +prompt: T_WORD + | T_WORD_QUOTE +; + +end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } + | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } + | T_ENDIF nl_or_eof { $$ = T_ENDIF; } +; + +nl_or_eof: + T_EOL | T_EOF; + +if_expr: /* empty */ { $$ = NULL; } + | T_IF expr { $$ = $2; } +; + +expr: symbol { $$ = expr_alloc_symbol($1); } + | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } + | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } + | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } + | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } + | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } + | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } +; + +symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } + | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); } +; + +%% + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + sym_init(); + menu_init(); + modules_sym = sym_lookup("MODULES", 0); + rootmenu.prompt = menu_add_prop(P_MENU, "Buildroot Configuration", NULL, NULL); + + //zconfdebug = 1; + zconfparse(); + if (zconfnerrs) + exit(1); + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) + printf("\n"); + else + sym->flags |= SYMBOL_CHECK_DONE; + } + + sym_change_count = 1; +} + +const char *zconf_tokenname(int token) +{ + switch (token) { + case T_MENU: return "menu"; + case T_ENDMENU: return "endmenu"; + case T_CHOICE: return "choice"; + case T_ENDCHOICE: return "endchoice"; + case T_IF: return "if"; + case T_ENDIF: return "endif"; + } + return ""; +} + +static bool zconf_endtoken(int token, int starttoken, int endtoken) +{ + if (token != endtoken) { + zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + if (current_menu->file != current_file) { + zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); + zconfprint("location of the '%s'", zconf_tokenname(starttoken)); + zconfnerrs++; + return false; + } + return true; +} + +static void zconfprint(const char *err, ...) +{ + va_list ap; + + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconferror(const char *err) +{ + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +} + +void print_quoted_string(FILE *out, const char *str) +{ + const char *p; + int len; + + putc('"', out); + while ((p = strchr(str, '"'))) { + len = p - str; + if (len) + fprintf(out, "%.*s", len, str); + fputs("\\\"", out); + str = p + 1; + } + fputs(str, out); + putc('"', out); +} + +void print_symbol(FILE *out, struct menu *menu) +{ + struct symbol *sym = menu->sym; + struct property *prop; + + 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 "confdata.c" +#include "expr.c" +#include "symbol.c" +#include "menu.c" diff --git a/package/sed/Config.in b/package/sed/Config.in new file mode 100644 index 0000000000..2a38d62d6c --- /dev/null +++ b/package/sed/Config.in @@ -0,0 +1,8 @@ +# + +config BR2_PACKAGE_SED + bool "sed" + default n + help + Most people will answer Y. + diff --git a/package/sed/Makefile.in b/package/sed/Makefile.in new file mode 100644 index 0000000000..6738e4f246 --- /dev/null +++ b/package/sed/Makefile.in @@ -0,0 +1,3 @@ +ifeq ($(strip $(BR2_PACKAGE_SED)),y) +TARGETS+=sed +endif diff --git a/package/sed/sed.mk b/package/sed/sed.mk new file mode 100644 index 0000000000..e197bca3ec --- /dev/null +++ b/package/sed/sed.mk @@ -0,0 +1,83 @@ +############################################################# +# +# sed +# +############################################################# +SED_VER:=4.1.2 +SED_SOURCE:=sed-$(SED_VER).tar.gz +SED_SITE:=ftp://ftp.gnu.org/gnu/sed +SED_CAT:=zcat +SED_DIR:=$(BUILD_DIR)/sed-$(SED_VER) +SED_BINARY:=sed/sed +SED_TARGET_BINARY:=bin/sed +ifeq ($(BR2_LARGEFILE),y) +SED_CPPFLAGS=-D_FILE_OFFSET_BITS=64 +endif +SED:=$(STAGING_DIR)/bin/sed -i -e + + +$(DL_DIR)/$(SED_SOURCE): + mkdir -p $(DL_DIR) + $(WGET) -P $(DL_DIR) $(SED_SITE)/$(SED_SOURCE) + +sed-source: $(DL_DIR)/$(SED_SOURCE) + + +############################################################# +# +# build sed for use on the target system +# +############################################################# +$(SED_DIR)/.unpacked: $(DL_DIR)/$(SED_SOURCE) + $(SED_CAT) $(DL_DIR)/$(SED_SOURCE) | tar -C $(BUILD_DIR) -xvf - + touch $(SED_DIR)/.unpacked + +$(SED_DIR)/.configured: $(SED_DIR)/.unpacked + (cd $(SED_DIR); rm -rf config.cache; \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS)" \ + CPPFLAGS="$(SED_CFLAGS)" \ + ./configure \ + --target=$(GNU_TARGET_NAME) \ + --host=$(GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --prefix=/usr \ + --exec-prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/sbin \ + --libexecdir=/usr/lib \ + --sysconfdir=/etc \ + --datadir=/usr/share \ + --localstatedir=/var \ + --mandir=/usr/man \ + --infodir=/usr/info \ + $(DISABLE_NLS) \ + ); + touch $(SED_DIR)/.configured + +$(SED_DIR)/$(SED_BINARY): $(SED_DIR)/.configured + $(MAKE) CC=$(TARGET_CC) -C $(SED_DIR) + +# This stuff is needed to work around GNU make deficiencies +sed-target_binary: $(SED_DIR)/$(SED_BINARY) + @if [ -L $(TARGET_DIR)/$(SED_TARGET_BINARY) ] ; then \ + rm -f $(TARGET_DIR)/$(SED_TARGET_BINARY); fi; + + @if [ ! -f $(SED_DIR)/$(SED_BINARY) -o $(TARGET_DIR)/$(SED_TARGET_BINARY) \ + -ot $(SED_DIR)/$(SED_BINARY) ] ; then \ + set -x; \ + $(MAKE) DESTDIR=$(TARGET_DIR) CC=$(TARGET_CC) -C $(SED_DIR) install; \ + mv $(TARGET_DIR)/usr/bin/sed $(TARGET_DIR)/bin/; \ + rm -rf $(TARGET_DIR)/share/locale $(TARGET_DIR)/usr/info \ + $(TARGET_DIR)/usr/man $(TARGET_DIR)/usr/share/doc; fi + +sed: uclibc sed-target_binary + +sed-clean: + $(MAKE) DESTDIR=$(TARGET_DIR) CC=$(TARGET_CC) -C $(SED_DIR) uninstall + -$(MAKE) -C $(SED_DIR) clean + +sed-dirclean: + rm -rf $(SED_DIR) + + diff --git a/toolchain/Config.in b/toolchain/Config.in new file mode 100644 index 0000000000..c2411020f6 --- /dev/null +++ b/toolchain/Config.in @@ -0,0 +1,62 @@ +# + +menu "Toolchain Options" + + +source "toolchain/kernel-headers/Config.in" +source "toolchain/uClibc/Config.in" +source "toolchain/binutils/Config.in" +source "toolchain/gcc/Config.in" +source "toolchain/ccache/Config.in" +source "toolchain/gdb/Config.in" + + +config BR2_ENABLE_MULTILIB + bool "Enable multilib support?" + default y + help + If you want multilib enabled, enable this... + +config BR2_LARGEFILE + bool "Enable large file (files > 2 GB) support?" + depends on !BR2_cris + default y + help + Enable large file (files > 2 GB) support + +config BR2_SOFT_FLOAT + bool "Use software floating point by default" + default n + depends on BR2_arm || BR2_mips || BR2_powerpc + help + If your target CPU does not have a Floating Point Unit (FPU) or a + kernel FPU emulator, but you still wish to support floating point + functions, then everything will need to be compiled with soft floating + point support (-msoft-float). + + Most people will answer N. + +config SOFT_FLOAT + string + depends on BR2_SOFT_FLOAT + default "true" + +config BR2_TARGET_OPTIMIZATION + string + default "-Os -pipe" + help + Currently the unwind stuff seems to work for staticly linked apps + but not dynamic. So use setjmp/longjmp exceptions by default. + +# Might be worth experimenting with for gcc 3.4.x. +#GCC_WITH_CPU:= +#GCC_WITH_ARCH:= +#GCC_WITH_TUNE:= + +#GCC_WITH_CPU:=--with-cpu= +#GCC_WITH_ARCH:=--with-arch= +#GCC_WITH_TUNE:=--with-tune= + + +endmenu + diff --git a/toolchain/Makefile.in b/toolchain/Makefile.in new file mode 100644 index 0000000000..5b2d7f213d --- /dev/null +++ b/toolchain/Makefile.in @@ -0,0 +1,7 @@ +ifeq ($(BR2_ENABLE_MULTILIB),y) +MULTILIB:=--enable-multilib +endif + + +# FIXME -- this is temporary +OPTIMIZE_FOR_CPU=$(ARCH) diff --git a/sources/binutils/2.14.90.0.6/001-debian.patch b/toolchain/binutils/2.14.90.0.6/001-debian.patch similarity index 100% rename from sources/binutils/2.14.90.0.6/001-debian.patch rename to toolchain/binutils/2.14.90.0.6/001-debian.patch diff --git a/sources/binutils/2.14.90.0.6/100-uclibc-conf.patch b/toolchain/binutils/2.14.90.0.6/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.14.90.0.6/100-uclibc-conf.patch rename to toolchain/binutils/2.14.90.0.6/100-uclibc-conf.patch diff --git a/sources/binutils/2.14.90.0.6/200-build_modules.patch b/toolchain/binutils/2.14.90.0.6/200-build_modules.patch similarity index 100% rename from sources/binutils/2.14.90.0.6/200-build_modules.patch rename to toolchain/binutils/2.14.90.0.6/200-build_modules.patch diff --git a/sources/binutils/2.14.90.0.6/210-cflags.patch b/toolchain/binutils/2.14.90.0.6/210-cflags.patch similarity index 100% rename from sources/binutils/2.14.90.0.6/210-cflags.patch rename to toolchain/binutils/2.14.90.0.6/210-cflags.patch diff --git a/sources/binutils/2.14.90.0.7/001-debian.patch b/toolchain/binutils/2.14.90.0.7/001-debian.patch similarity index 100% rename from sources/binutils/2.14.90.0.7/001-debian.patch rename to toolchain/binutils/2.14.90.0.7/001-debian.patch diff --git a/sources/binutils/2.14.90.0.7/100-uclibc-conf.patch b/toolchain/binutils/2.14.90.0.7/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.14.90.0.7/100-uclibc-conf.patch rename to toolchain/binutils/2.14.90.0.7/100-uclibc-conf.patch diff --git a/sources/binutils/2.14.90.0.7/200-build_modules.patch b/toolchain/binutils/2.14.90.0.7/200-build_modules.patch similarity index 100% rename from sources/binutils/2.14.90.0.7/200-build_modules.patch rename to toolchain/binutils/2.14.90.0.7/200-build_modules.patch diff --git a/sources/binutils/2.14.90.0.7/210-cflags.patch b/toolchain/binutils/2.14.90.0.7/210-cflags.patch similarity index 100% rename from sources/binutils/2.14.90.0.7/210-cflags.patch rename to toolchain/binutils/2.14.90.0.7/210-cflags.patch diff --git a/sources/binutils/2.14.90.0.7/600-arm-textrel.patch b/toolchain/binutils/2.14.90.0.7/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.14.90.0.7/600-arm-textrel.patch rename to toolchain/binutils/2.14.90.0.7/600-arm-textrel.patch diff --git a/sources/binutils/2.14.90.0.8/001-debian.patch b/toolchain/binutils/2.14.90.0.8/001-debian.patch similarity index 100% rename from sources/binutils/2.14.90.0.8/001-debian.patch rename to toolchain/binutils/2.14.90.0.8/001-debian.patch diff --git a/sources/binutils/2.14.90.0.8/100-uclibc-conf.patch b/toolchain/binutils/2.14.90.0.8/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.14.90.0.8/100-uclibc-conf.patch rename to toolchain/binutils/2.14.90.0.8/100-uclibc-conf.patch diff --git a/sources/binutils/2.14.90.0.8/600-arm-textrel.patch b/toolchain/binutils/2.14.90.0.8/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.14.90.0.8/600-arm-textrel.patch rename to toolchain/binutils/2.14.90.0.8/600-arm-textrel.patch diff --git a/sources/binutils/2.15.90.0.1.1/100-uclibc-conf.patch b/toolchain/binutils/2.15.90.0.1.1/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.90.0.1.1/100-uclibc-conf.patch rename to toolchain/binutils/2.15.90.0.1.1/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.90.0.1.1/600-arm-textrel.patch b/toolchain/binutils/2.15.90.0.1.1/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.90.0.1.1/600-arm-textrel.patch rename to toolchain/binutils/2.15.90.0.1.1/600-arm-textrel.patch diff --git a/sources/binutils/2.15.90.0.1/100-uclibc-conf.patch b/toolchain/binutils/2.15.90.0.1/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.90.0.1/100-uclibc-conf.patch rename to toolchain/binutils/2.15.90.0.1/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.90.0.1/600-arm-textrel.patch b/toolchain/binutils/2.15.90.0.1/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.90.0.1/600-arm-textrel.patch rename to toolchain/binutils/2.15.90.0.1/600-arm-textrel.patch diff --git a/sources/binutils/2.15.90.0.2/100-uclibc-conf.patch b/toolchain/binutils/2.15.90.0.2/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.90.0.2/100-uclibc-conf.patch rename to toolchain/binutils/2.15.90.0.2/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.90.0.2/600-arm-textrel.patch b/toolchain/binutils/2.15.90.0.2/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.90.0.2/600-arm-textrel.patch rename to toolchain/binutils/2.15.90.0.2/600-arm-textrel.patch diff --git a/sources/binutils/2.15.90.0.3/100-uclibc-conf.patch b/toolchain/binutils/2.15.90.0.3/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.90.0.3/100-uclibc-conf.patch rename to toolchain/binutils/2.15.90.0.3/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.90.0.3/210-cflags.patch b/toolchain/binutils/2.15.90.0.3/210-cflags.patch similarity index 100% rename from sources/binutils/2.15.90.0.3/210-cflags.patch rename to toolchain/binutils/2.15.90.0.3/210-cflags.patch diff --git a/sources/binutils/2.15.90.0.3/500-branch-likely.patch b/toolchain/binutils/2.15.90.0.3/500-branch-likely.patch similarity index 100% rename from sources/binutils/2.15.90.0.3/500-branch-likely.patch rename to toolchain/binutils/2.15.90.0.3/500-branch-likely.patch diff --git a/sources/binutils/2.15.90.0.3/600-arm-textrel.patch b/toolchain/binutils/2.15.90.0.3/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.90.0.3/600-arm-textrel.patch rename to toolchain/binutils/2.15.90.0.3/600-arm-textrel.patch diff --git a/sources/binutils/2.15.91.0.1/100-uclibc-conf.patch b/toolchain/binutils/2.15.91.0.1/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.91.0.1/100-uclibc-conf.patch rename to toolchain/binutils/2.15.91.0.1/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.91.0.1/600-arm-textrel.patch b/toolchain/binutils/2.15.91.0.1/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.91.0.1/600-arm-textrel.patch rename to toolchain/binutils/2.15.91.0.1/600-arm-textrel.patch diff --git a/sources/binutils/2.15.91.0.2/100-uclibc-conf.patch b/toolchain/binutils/2.15.91.0.2/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.91.0.2/100-uclibc-conf.patch rename to toolchain/binutils/2.15.91.0.2/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.91.0.2/500-branch-likely.patch b/toolchain/binutils/2.15.91.0.2/500-branch-likely.patch similarity index 100% rename from sources/binutils/2.15.91.0.2/500-branch-likely.patch rename to toolchain/binutils/2.15.91.0.2/500-branch-likely.patch diff --git a/sources/binutils/2.15.91.0.2/600-arm-textrel.patch b/toolchain/binutils/2.15.91.0.2/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.91.0.2/600-arm-textrel.patch rename to toolchain/binutils/2.15.91.0.2/600-arm-textrel.patch diff --git a/sources/binutils/2.15.91.0.2/700-binutils-20040817-linkonce.patch b/toolchain/binutils/2.15.91.0.2/700-binutils-20040817-linkonce.patch similarity index 100% rename from sources/binutils/2.15.91.0.2/700-binutils-20040817-linkonce.patch rename to toolchain/binutils/2.15.91.0.2/700-binutils-20040817-linkonce.patch diff --git a/sources/binutils/2.15.91.0.2/701-binutils-dup-sections.patch b/toolchain/binutils/2.15.91.0.2/701-binutils-dup-sections.patch similarity index 100% rename from sources/binutils/2.15.91.0.2/701-binutils-dup-sections.patch rename to toolchain/binutils/2.15.91.0.2/701-binutils-dup-sections.patch diff --git a/sources/binutils/2.15.91.0.2/702-binutils-skip-comments.patch b/toolchain/binutils/2.15.91.0.2/702-binutils-skip-comments.patch similarity index 100% rename from sources/binutils/2.15.91.0.2/702-binutils-skip-comments.patch rename to toolchain/binutils/2.15.91.0.2/702-binutils-skip-comments.patch diff --git a/sources/binutils/2.15.92.0.2/100-uclibc-conf.patch b/toolchain/binutils/2.15.92.0.2/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15.92.0.2/100-uclibc-conf.patch rename to toolchain/binutils/2.15.92.0.2/100-uclibc-conf.patch diff --git a/sources/binutils/2.15.92.0.2/600-arm-textrel.patch b/toolchain/binutils/2.15.92.0.2/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15.92.0.2/600-arm-textrel.patch rename to toolchain/binutils/2.15.92.0.2/600-arm-textrel.patch diff --git a/sources/binutils/2.15.92.0.2/702-binutils-skip-comments.patch b/toolchain/binutils/2.15.92.0.2/702-binutils-skip-comments.patch similarity index 100% rename from sources/binutils/2.15.92.0.2/702-binutils-skip-comments.patch rename to toolchain/binutils/2.15.92.0.2/702-binutils-skip-comments.patch diff --git a/sources/binutils/2.15/100-uclibc-conf.patch b/toolchain/binutils/2.15/100-uclibc-conf.patch similarity index 100% rename from sources/binutils/2.15/100-uclibc-conf.patch rename to toolchain/binutils/2.15/100-uclibc-conf.patch diff --git a/sources/binutils/2.15/600-arm-textrel.patch b/toolchain/binutils/2.15/600-arm-textrel.patch similarity index 100% rename from sources/binutils/2.15/600-arm-textrel.patch rename to toolchain/binutils/2.15/600-arm-textrel.patch diff --git a/toolchain/binutils/Config.in b/toolchain/binutils/Config.in new file mode 100644 index 0000000000..95dc057585 --- /dev/null +++ b/toolchain/binutils/Config.in @@ -0,0 +1,57 @@ +# Choose binutils version. +# + +choice + prompt "Binutils Version" + default BR2_BINUTILS_VERSION_2_15_91_0_2 + help + Select the version of binutils you wish to use. + + config BR2_BINUTILS_VERSION_2_14_90_0_6 + bool "binutils 2.14.90.0.6" + + config BR2_BINUTILS_VERSION_2_14_90_0_7 + bool "binutils 2.14.90.0.7" + + config BR2_BINUTILS_VERSION_2_14_90_0_8 + bool "binutils 2.14.90.0.8" + + config BR2_BINUTILS_VERSION_2_15 + bool "binutils 2.15" + + config BR2_BINUTILS_VERSION_2_15_90_0_1 + bool "binutils 2.15.90.0.1" + + config BR2_BINUTILS_VERSION_2_15_90_0_1_1 + bool "binutils 2.15.90.0.1.1" + + config BR2_BINUTILS_VERSION_2_15_90_0_2 + bool "binutils 2.15.90.0.2" + + config BR2_BINUTILS_VERSION_2_15_90_0_3 + bool "binutils 2.15.90.0.3" + + config BR2_BINUTILS_VERSION_2_15_91_0_1 + bool "binutils 2.15.91.0.1" + + config BR2_BINUTILS_VERSION_2_15_91_0_2 + bool "binutils 2.15.91.0.2" + + config BR2_BINUTILS_VERSION_2_15_92_0_2 + bool "binutils 2.15.92.0.2" + +endchoice + +config BR2_BINUTILS_VERSION + string + default "2.14.90.0.6" if BR2_BINUTILS_VERSION_2_14_90_0_6 + default "2.14.90.0.7" if BR2_BINUTILS_VERSION_2_14_90_0_7 + default "2.15.90.0.8" if BR2_BINUTILS_VERSION_2_15 + default "2.15.90.0.1" if BR2_BINUTILS_VERSION_2_15_90_0_1 + default "2.15.90.0.0.1.1" if BR2_BINUTILS_VERSION_2_15_90_0_1_1 + default "2.15.90.0.2" if BR2_BINUTILS_VERSION_2_15_90_0_2 + default "2.15.90.0.3" if BR2_BINUTILS_VERSION_2_15_90_0_3 + default "2.15.91.0.1" if BR2_BINUTILS_VERSION_2_15_91_0_1 + default "2.15.91.0.2" if BR2_BINUTILS_VERSION_2_15_91_0_2 + default "2.15.92.0.2" if BR2_BINUTILS_VERSION_2_15_92_0_2 + diff --git a/toolchain/binutils/Makefile.in b/toolchain/binutils/Makefile.in new file mode 100644 index 0000000000..63902890a5 --- /dev/null +++ b/toolchain/binutils/Makefile.in @@ -0,0 +1,2 @@ +BINUTILS_VERSION:=$(strip $(subst ",, $(BR2_BINUTILS_VERSION))) +#" diff --git a/make/binutils-uclibc.mk b/toolchain/binutils/binutils.mk similarity index 94% rename from make/binutils-uclibc.mk rename to toolchain/binutils/binutils.mk index 6199990d5c..fbd0196994 100644 --- a/make/binutils-uclibc.mk +++ b/toolchain/binutils/binutils.mk @@ -33,7 +33,7 @@ $(BINUTILS_DIR)/.unpacked: $(DL_DIR)/$(BINUTILS_SOURCE) $(BINUTILS_DIR)/.patched: $(BINUTILS_DIR)/.unpacked # Apply appropriate binutils patches. - $(SOURCE_DIR)/patch-kernel.sh $(BINUTILS_DIR) $(SOURCE_DIR)/binutils/$(BINUTILS_VERSION) \*.patch + $(SOURCE_DIR)/patch-kernel.sh $(BINUTILS_DIR) toolchain/binutils/$(BINUTILS_VERSION) \*.patch touch $(BINUTILS_DIR)/.patched $(BINUTILS_DIR1)/.configured: $(BINUTILS_DIR)/.patched @@ -54,7 +54,7 @@ $(BINUTILS_DIR1)/binutils/objdump: $(BINUTILS_DIR1)/.configured # Make install will put gettext data in staging_dir/share/locale. # Unfortunatey, it isn't configureable. -$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/ld: $(BINUTILS_DIR1)/binutils/objdump +$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/ld: $(BINUTILS_DIR1)/binutils/objdump $(MAKE) $(JLEVEL) -C $(BINUTILS_DIR1) install binutils-dependancies: @@ -111,7 +111,7 @@ $(BINUTILS_DIR2)/binutils/objdump: $(BINUTILS_DIR2)/.configured PATH=$(TARGET_PATH) \ $(MAKE) $(JLEVEL) -C $(BINUTILS_DIR2) all -$(TARGET_DIR)/usr/bin/ld: $(BINUTILS_DIR2)/binutils/objdump +$(TARGET_DIR)/usr/bin/ld: $(BINUTILS_DIR2)/binutils/objdump PATH=$(TARGET_PATH) \ $(MAKE) $(JLEVEL) DESTDIR=$(TARGET_DIR) \ tooldir=/usr build_tooldir=/usr \ @@ -119,7 +119,7 @@ $(TARGET_DIR)/usr/bin/ld: $(BINUTILS_DIR2)/binutils/objdump #rm -rf $(TARGET_DIR)/share/locale $(TARGET_DIR)/usr/info \ # $(TARGET_DIR)/usr/man $(TARGET_DIR)/usr/share/doc -$(STRIP) $(TARGET_DIR)/usr/$(REAL_GNU_TARGET_NAME)/bin/* > /dev/null 2>&1 - -$(STRIP) $(TARGET_DIR)/usr/bin/* > /dev/null 2>&1 + -$(STRIP) $(TARGET_DIR)/usr/bin/* > /dev/null 2>&1 binutils_target: $(GCC_DEPENDANCY) $(TARGET_DIR)/usr/bin/ld diff --git a/toolchain/ccache/Config.in b/toolchain/ccache/Config.in new file mode 100644 index 0000000000..6798072d62 --- /dev/null +++ b/toolchain/ccache/Config.in @@ -0,0 +1,14 @@ +# + +config BR2_HOST_CCACHE + bool "Enable ccache support?" + default y + help + Enable ccache support? + +config BR2_PACKAGE_CCACHE + bool "Enable ccache support for the Target?" + default y + help + Enable ccache support? + diff --git a/toolchain/ccache/Makefile.in b/toolchain/ccache/Makefile.in new file mode 100644 index 0000000000..6fa95d4220 --- /dev/null +++ b/toolchain/ccache/Makefile.in @@ -0,0 +1,3 @@ +ifeq ($(strip $(BR2_HOST_CCACHE)),y) +TARGETS+=ccache +endif diff --git a/make/ccache.mk b/toolchain/ccache/ccache.mk similarity index 100% rename from make/ccache.mk rename to toolchain/ccache/ccache.mk diff --git a/sources/gcc/2.95/050-debian-subset.patch b/toolchain/gcc/2.95/050-debian-subset.patch similarity index 100% rename from sources/gcc/2.95/050-debian-subset.patch rename to toolchain/gcc/2.95/050-debian-subset.patch diff --git a/toolchain/gcc/2.95/050-debian-subset.patch.bz2 b/toolchain/gcc/2.95/050-debian-subset.patch.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..4dffd849b6f04932803a1bab09990953c6691399 GIT binary patch literal 125297 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 t&-jAej)~hul(~0_hoQIS3 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

tK?hXX=R4dcNM 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

)YUsTDeRW~>ei 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