Yet another major rework of the BusyBox config system, using the considerably

modified Kbuild system I put into uClibc.  With this, there should be no more
need to modify Rules.mak since I've moved all the interesting options into the
config system.  I think I've got everything updated, but you never know, I may
have made some mistakes, so watch closely.
 -Erik
This commit is contained in:
Eric Andersen
2002-12-05 08:41:41 +00:00
parent deca106b6d
commit c9f20d9fb9
69 changed files with 12882 additions and 3159 deletions

View File

@@ -1,705 +0,0 @@
#! /bin/sh
#
# This script is used to configure BusyBox.
#
# It was inspired by the challenge in the original Configure script
# to ``do something better'', combined with the actual need to ``do
# something better'' because the old configure script wasn't flexible
# enough.
#
# Raymond Chen was the original author of Configure.
# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
#
# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13
# with an empty IFS.
#
# 030995 (storner@osiris.ping.dk) - added support for tri-state answers,
# for selecting modules to compile.
#
# 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for
# use with a config.in modified for make menuconfig.
#
# 301195 (boldt@math.ucsb.edu) - added help text support
#
# 281295 Paul Gortmaker - make tri_state functions collapse to boolean
# if module support is not enabled.
#
# 010296 Aaron Ucko (ucko@vax1.rockhurst.edu) - fix int and hex to accept
# arbitrary ranges
#
# 150296 Dick Streefland (dicks@tasking.nl) - report new configuration
# items and ask for a value even when doing a "make oldconfig"
#
# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is
# chosen for an item, define the macro <option_name>_MODULE
#
# 090397 Axel Boldt (boldt@math.ucsb.edu) - avoid ? and + in regular
# expressions for GNU expr since version 1.15 and up use \? and \+.
#
# 300397 Phil Blundell (pjb27@cam.ac.uk) - added support for min/max
# arguments to "int", allow dep_tristate to take a list of dependencies
# rather than just one.
#
# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
# texts.
#
# 102598 Michael Chastain (mec@shout.net) - put temporary files in
# current directory, not in /tmp.
#
# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
# - Improve the exit message (Jeff Ronne).
#
# 7 October 2000, Ghozlane Toumi, <gtoumi@messel.emse.fr>
# added switches for "random" , "all yes" and "all modules"
#
#
# Make sure we're really running bash.
#
# I would really have preferred to write this script in a language with
# better string handling, but alas, bash is the only scripting language
# that I can be reasonable sure everybody has on their linux machine.
#
[ -z "$BASH" ] && { echo "Configure requires bash" 1>&2; exit 1; }
# Disable filename globbing once and for all.
# Enable function cacheing.
set -f -h
#
# Dummy functions for use with a config.in modified for menuconf
#
function mainmenu_option () {
:
}
function mainmenu_name () {
:
}
function endmenu () {
:
}
#
# returns a random number between 1 and $1
#
function rnd () {
rnd=$[ $RANDOM % $1 + 1 ]
}
#
# randomly chose a number in a config list (LIST_CONFIG_NAME)
# or in a range ( MIN_CONFIG_NAME MAX_CONFIG_NAME )
# ONLY if there is no forced default (and we are in an "auto" mode)
# we are limited by the range of values taken by "$RANDOM"
#
# rndval CONFIG_NAME
#
function rndval () {
[ "$AUTO" != "yes" -o -n "$old" ] && return
def_list=$(eval echo "\${LIST_$1}")
def_min=$(eval echo "\${MIN_$1}")
def_max=$(eval echo "\${MAX_$1}")
if [ -n "$def_list" ]; then
set -- $(echo $def_list | sed 's/,/ /g')
rnd $#
while [ $rnd -le $# ] ; do
def=$1
shift
done
return
fi
if [ -n "$def_min" -a -n "$def_max" ]; then
rnd $[ $def_max - $def_min ]
def=$[ $def_min + $rnd ]
fi
}
#
# help prints the corresponding help text from Configure.help to stdout
#
# help variable
#
function help () {
if [ -f docs/Configure.help ]
then
#first escape regexp special characters in the argument:
var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
#now pick out the right help text:
text=$(sed -n "/^$var[ ]*\$/,\${
/^$var[ ]*\$/c\\
${var}:\\
/^#/b
/^[^ ]/q
/<file:\\([^>]*\\)>/s//\\1/g
p
}" docs/Configure.help)
if [ -z "$text" ]
then
echo; echo " Sorry, no help available for this option yet.";echo
else
(echo; echo "$text") | ${PAGER:-more}
fi
else
echo;
echo " Can't access the file docs/Configure.help which"
echo " should contain the help texts."
echo
fi
}
#
# readln reads a line into $ans.
#
# readln prompt default oldval
#
function readln () {
if [ "$AUTO" = "yes" ]; then
echo -n "$1"
ans=$2
echo $ans
elif [ "$DEFAULT" = "-d" -a -n "$3" ]; then
echo "$1"
ans=$2
else
echo -n "$1"
[ -z "$3" ] && echo -n "(NEW) "
IFS='@' read ans || exit 1
[ -z "$ans" ] && ans=$2
fi
}
#
# comment does some pretty-printing
#
# comment 'xxx'
#
function comment () {
echo "*"; echo "* $1" ; echo "*"
(echo "" ; echo "#"; echo "# $1" ; echo "#") >>$CONFIG
(echo "" ; echo "/*"; echo " * $1" ; echo " */") >>$CONFIG_H
}
#
# define_bool sets the value of a boolean argument
#
# define_bool define value
#
function define_bool () {
define_tristate $1 $2
}
function define_tristate () {
case "$2" in
"y")
echo "$1=y" >>$CONFIG
echo "#define $1 1" >>$CONFIG_H
;;
"m")
echo "$1=m" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
echo "#define $1_MODULE 1" >>$CONFIG_H
;;
"n")
echo "# $1 is not set" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
;;
esac
eval "$1=$2"
}
#
# bool processes a boolean argument
#
# bool question define
#
function bool () {
old=$(eval echo "\${$2}")
def=${old:-'n'}
if [ "$AUTO" = "yes" -a -z "$old" ]; then
if [ "$RND" = "-r" ]; then
rnd 2
case $rnd in
"1") def="y" ;;
"2") def="n" ;;
esac
else
def=$DEF_ANS;
fi
fi
case "$def" in
"y" | "m") defprompt="Y/n/?"
def="y"
;;
"n") defprompt="N/y/?"
;;
esac
while :; do
readln "$1 ($2) [$defprompt] " "$def" "$old"
case "$ans" in
[yY] | [yY]es ) define_bool "$2" "y"
break;;
[nN] | [nN]o ) define_bool "$2" "n"
break;;
* ) help "$2"
;;
esac
done
}
#
# tristate processes a tristate argument
#
# tristate question define
#
function tristate () {
if [ "$CONFIG_MODULES" != "y" ]; then
bool "$1" "$2"
else
old=$(eval echo "\${$2}")
def=${old:-'n'}
if [ "$AUTO" = "yes" -a -z "$old" ]; then
if [ "$RND" = "-r" ]; then
rnd 3
case $rnd in
"1") def="y" ;;
"2") def="n" ;;
"3") def="m" ;;
esac
else
def=$DEF_ANS
fi
fi
case "$def" in
"y") defprompt="Y/m/n/?"
;;
"m") defprompt="M/n/y/?"
;;
"n") defprompt="N/y/m/?"
;;
esac
while :; do
readln "$1 ($2) [$defprompt] " "$def" "$old"
case "$ans" in
[yY] | [yY]es ) define_tristate "$2" "y"
break ;;
[nN] | [nN]o ) define_tristate "$2" "n"
break ;;
[mM] ) define_tristate "$2" "m"
break ;;
* ) help "$2"
;;
esac
done
fi
}
#
# dep_tristate processes a tristate argument that depends upon
# another option or options. If any of the options we depend upon is a
# module, then the only allowable options are M or N. If all are Y, then
# this is a normal tristate. This is used in cases where modules
# are nested, and one module requires the presence of something
# else in the kernel.
#
# dep_tristate question define default ...
#
function dep_tristate () {
old=$(eval echo "\${$2}")
def=${old:-'n'}
ques=$1
var=$2
need_module=0
shift 2
while [ $# -gt 0 ]; do
case "$1" in
n)
define_tristate "$var" "n"
return
;;
m)
need_module=1
;;
esac
shift
done
if [ $need_module = 1 ]; then
if [ "$CONFIG_MODULES" = "y" ]; then
if [ "$AUTO" = "yes" -a -z "$old" ]; then
if [ "$RND" = "-r" ]; then
rnd 2
case $rnd in
"1") def="m" ;;
"2") def="n" ;;
esac
else
def=$DEF_ANS
fi
fi
case "$def" in
"y" | "m") defprompt="M/n/?"
def="m"
;;
"n") defprompt="N/m/?"
;;
esac
while :; do
readln "$ques ($var) [$defprompt] " "$def" "$old"
case "$ans" in
[nN] | [nN]o ) define_tristate "$var" "n"
break ;;
[mM] ) define_tristate "$var" "m"
break ;;
[yY] | [yY]es ) echo
echo " This answer is not allowed, because it is not consistent with"
echo " your other choices."
echo " This driver depends on another one which you chose to compile"
echo " as a module. This means that you can either compile this one"
echo " as a module as well (with M) or leave it out altogether (N)."
echo
;;
* ) help "$var"
;;
esac
done
fi
else
tristate "$ques" "$var"
fi
}
function dep_bool () {
ques=$1
var=$2
shift 2
while [ $# -gt 0 ]; do
case "$1" in
m | n)
define_bool "$var" "n"
return
;;
esac
shift
done
bool "$ques" "$var"
}
function dep_mbool () {
ques=$1
var=$2
shift 2
while [ $# -gt 0 ]; do
case "$1" in
n)
define_bool "$var" "n"
return
;;
esac
shift
done
bool "$ques" "$var"
}
#
# define_int sets the value of a integer argument
#
# define_int define value
#
function define_int () {
echo "$1=$2" >>$CONFIG
echo "#define $1 ($2)" >>$CONFIG_H
eval "$1=$2"
}
#
# int processes an integer argument with optional limits
#
# int question define default [min max]
#
function int () {
old=$(eval echo "\${$2}")
def=${old:-$3}
if [ $# -gt 3 ]; then
min=$4
else
min=-10000000 # !!
fi
if [ $# -gt 4 ]; then
max=$5
else
max=10000000 # !!
fi
rndval $2
while :; do
readln "$1 ($2) [$def] " "$def" "$old"
if expr \( \( $ans + 0 \) \>= $min \) \& \( $ans \<= $max \) >/dev/null 2>&1 ; then
define_int "$2" "$ans"
break
else
help "$2"
fi
done
}
#
# define_hex sets the value of a hexadecimal argument
#
# define_hex define value
#
function define_hex () {
echo "$1=$2" >>$CONFIG
echo "#define $1 0x${2#*[x,X]}" >>$CONFIG_H
eval "$1=$2"
}
#
# hex processes an hexadecimal argument
#
# hex question define default
#
function hex () {
old=$(eval echo "\${$2}")
def=${old:-$3}
def=${def#*[x,X]}
rndval $2
while :; do
readln "$1 ($2) [$def] " "$def" "$old"
ans=${ans#*[x,X]}
if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then
define_hex "$2" "$ans"
break
else
help "$2"
fi
done
}
#
# define_string sets the value of a string argument
#
# define_string define value
#
function define_string () {
echo "$1=\"$2\"" >>$CONFIG
echo "#define $1 \"$2\"" >>$CONFIG_H
eval "$1=\"$2\""
}
#
# string processes a string argument
#
# string question define default
#
function string () {
old=$(eval echo "\${$2}")
def=${old:-$3}
while :; do
if [ "$old" = "?" ]; then
readln "$1 ($2) [$def] " "$def" ""
else
readln "$1 ($2) [$def] " "$def" "$old"
fi
if [ "$ans" = "?" ]; then
help "$2"
else
break
fi
done
define_string "$2" "$ans"
}
#
# choice processes a choice list (1-out-of-n)
#
# choice question choice-list default
#
# The choice list has a syntax of:
# NAME WHITESPACE VALUE { WHITESPACE NAME WHITESPACE VALUE }
# The user may enter any unique prefix of one of the NAMEs and
# choice will define VALUE as if it were a boolean option.
# VALUE must be in all uppercase. Normally, VALUE is of the
# form CONFIG_<something>. Thus, if the user selects <something>,
# the CPP symbol CONFIG_<something> will be defined and the
# shell variable CONFIG_<something> will be set to "y".
#
function choice () {
question="$1"
choices="$2"
old=
def=$3
# determine default answer:
names=""
set -- $choices
firstvar=$2
while [ -n "$2" ]; do
if [ -n "$names" ]; then
names="$names, $1"
else
names="$1"
fi
if [ "$(eval echo \"\${$2}\")" = "y" ]; then
old=$1
def=$1
fi
shift; shift
done
if [ "$RND" = "-r" -a -z "$old" ] ; then
set -- $choices
rnd $#
while [ $rnd -le $# ] ; do
def=$1
shift ; shift
done
fi
val=""
while [ -z "$val" ]; do
ambg=n
readln "$question ($names) [$def] " "$def" "$old"
ans=$(echo $ans | tr a-z A-Z)
set -- $choices
while [ -n "$1" ]; do
name=$(echo $1 | tr a-z A-Z)
case "$name" in
"$ans"* | */"$ans"* )
case "$name" in
"$ans" | */"$ans"/* | \
"$ans"/* | */"$ans" )
val="$2"
break # exact match
;;
esac
if [ -n "$val" ]; then
echo;echo \
" Sorry, \"$ans\" is ambiguous; please enter a longer string."
echo
val=""
ambg=y
break
else
val="$2"
fi;;
esac
shift; shift
done
if [ "$val" = "" -a "$ambg" = "n" ]; then
help "$firstvar"
fi
done
set -- $choices
while [ -n "$2" ]; do
if [ "$2" = "$val" ]; then
echo " defined $val"
define_bool "$2" "y"
else
define_bool "$2" "n"
fi
shift; shift
done
}
CONFIG=.tmpconfig
CONFIG_H=.tmpconfig.h
FORCE_DEFAULT=.force_default
trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2
#
# Make sure we start out with a clean slate.
#
echo "#" > $CONFIG
echo "# Automatically generated make config: don't edit" >> $CONFIG
echo "#" >> $CONFIG
echo "/*" > $CONFIG_H
echo " * Automatically generated C config: don't edit" >> $CONFIG_H
echo " */" >> $CONFIG_H
echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H
DEFAULT=""
if [ "$1" = "-d" ] ; then
DEFAULT="-d"
shift
fi
RND=""
DEF_ANS=""
AUTO=""
case "$1" in
-r) RND="-r" ; AUTO="yes" ; shift ;;
-y) DEF_ANS="y" ; AUTO="yes" ; shift ;;
-m) DEF_ANS="m" ; AUTO="yes" ; shift ;;
-n) DEF_ANS="n" ; AUTO="yes" ; shift ;;
esac
CONFIG_IN=./config.in
if [ "$1" != "" ] ; then
CONFIG_IN=$1
fi
DEFAULTS=sysdeps/$TARGET_OS/defconfig
if [ -f .config ]; then
DEFAULTS=.config
fi
if [ "$AUTO" != "yes" ]; then
if [ -f $DEFAULTS ]; then
echo "#"
echo "# Using defaults found in" $DEFAULTS
echo "#"
. $DEFAULTS
sed -e 's/# \(CONFIG_[^ ]*\) is not.*/\1=n/' <$DEFAULTS >.config-is-not.$$
. .config-is-not.$$
rm .config-is-not.$$
else
echo "#"
echo "# No defaults found"
echo "#"
fi
else
if [ -f $FORCE_DEFAULT ]; then
echo "#"
echo "# Forcing defaults found in $FORCE_DEFAULT"
echo "#"
sed -e '
s/# \(CONFIG_[^ ]*\) is not.*/\1=n/;
s/# range \(CONFIG_[^ ]*\) \([^ ][^ ]*\) \([^ ][^ ]*\)/MIN_\1=\2; MAX_\1=\3/;
s/# list \(CONFIG_[^ ]*\) \([^ ][^ ]*\)/LIST_\1=\2/
' <$FORCE_DEFAULT >.default_val.$$
. .default_val.$$
rm .default_val.$$
else
echo "#"
echo "# No defaults found"
echo "#"
fi
fi
. $CONFIG_IN
rm -f .config.old
if [ -f .config ]; then
mv .config .config.old
fi
mv .tmpconfig .config
mv .tmpconfig.h include/config.h
echo
echo "*** End of BusyBox configuration."
echo "*** Check the top-level Makefile for additional configuration."
if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
echo "*** Next, you must run 'make dep'."
else
echo "*** Next, you may run 'make', or 'make install'."
fi
echo
exit 0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
conf
mconf
lkc_defs.h
lex.zconf.c
zconf.tab.h
zconf.tab.c
lex.backup
zconf.output

View File

@@ -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" <prompt> ["if" <expr>]
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" <symbol> ["if" <expr>]
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" <expr>
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:
<expr> ::= <symbol> (1)
<symbol> '=' <symbol> (2)
<symbol> '!=' <symbol> (3)
'(' <expr> ')' (4)
'!' <expr> (5)
<expr> '||' <expr> (6)
<expr> '&&' <expr> (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" <symbol>
<config options>
This defines a config symbol <symbol> and accepts any of above
attributes as options.
choices:
"choice"
<choice options>
<choice block>
"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" <prompt>
<comment options>
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" <prompt>
<menu options>
<menu block>
"endmenu"
This defines a menu block, see "Menu structure" above for more
information. The only possible options are dependencies.
if:
"if" <expr>
<if block>
"endif"
This defines an if block. The dependency expression <expr> is appended
to all enclosed menu entries.
source:
"source" <prompt>
This reads the specified configuration file. This file is always parsed.

102
scripts/config/Makefile Normal file
View File

@@ -0,0 +1,102 @@
# Makefile for BusyBox
#
# Copyright (C) 2002 Erik Andersen <andersen@codepoet.org>
TOPDIR=../../
include $(TOPDIR)Rules.mak
all: ncurses conf mconf
#HOSTCFLAGS=-Wall -g -O0
LIBS = -lncurses
ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
else
ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
else
ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
HOSTCFLAGS += -DCURSES_LOC="<ncurses.h>"
else
HOSTCFLAGS += -DCURSES_LOC="<curses.h>"
endif
endif
endif
CONF_SRC =conf.c zconf.tab.c
MCONF_SRC =mconf.c zconf.tab.c
LXDLG_SRC =checklist.c menubox.c textbox.c yesno.c inputbox.c util.c msgbox.c
CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC))
MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC))
LXDLG_OBJS=$(patsubst %.c,%.o, $(LXDLG_SRC))
conf: $(CONF_OBJS)
$(HOSTCC) $(HOSTCFLAGS) $(NATIVE_LDFLAGS) $^ -o $@
mconf: $(MCONF_OBJS) $(LXDLG_OBJS)
$(HOSTCC) $(HOSTCFLAGS) $(NATIVE_LDFLAGS) $^ -o $@ $(LIBS)
lkc_deps:=lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h
conf.o: conf.c $(lkc_deps)
mconf.o: mconf.c $(lkc_deps)
zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps)
lex.zconf.o: lex.zconf.c $(lkc_deps)
%.o : %.c
$(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
lkc_defs.h: lkc_proto.h
@sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
###
# The following requires flex/bison
# By default we use the _shipped versions, uncomment the
# following line if you are modifying the flex/bison src.
#LKC_GENPARSER := 1
ifdef LKC_GENPARSER
%.tab.c %.tab.h: %.y
bison -t -d -v -b $* -p $(notdir $*) $<
lex.%.c: %.l
flex -P$(notdir $*) -o$@ $<
else
lex.zconf.c: lex.zconf.c_shipped
cp lex.zconf.c_shipped lex.zconf.c
zconf.tab.c: zconf.tab.c_shipped
cp zconf.tab.c_shipped zconf.tab.c
zconf.tab.h: zconf.tab.h_shipped
cp zconf.tab.h_shipped zconf.tab.h
endif
.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

View File

@@ -118,7 +118,8 @@ print_buttons( WINDOW *dialog, int height, int width, int selected)
*/
int
dialog_checklist (const char *title, const char *prompt, int height, int width,
int list_height, int item_no, const char * const * items, int flag)
int list_height, int item_no, struct dialog_list_item ** items,
int flag)
{
int i, x, y, box_x, box_y;
@@ -137,7 +138,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = !strcasecmp (items[i * 3 + 2], "on");
status[i] = items[i]->selected;
if (!choice && status[i])
choice = i;
}
@@ -195,7 +196,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
/* 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 * 3 + 1]) + 4);
check_x = MAX (check_x, + strlen (items[i]->name) + 4);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
@@ -207,7 +208,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
/* Print the list */
for (i = 0; i < max_choice; i++) {
print_item (list, items[(scroll+i) * 3 + 1],
print_item (list, items[scroll + i]->name,
status[i+scroll], i, i == choice);
}
@@ -224,7 +225,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
key = wgetch (dialog);
for (i = 0; i < max_choice; i++)
if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
if (toupper(key) == toupper(items[scroll + i]->name[0]))
break;
@@ -237,14 +238,14 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
print_item (list, items[scroll * 3 + 1],
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 * 3 + 1],
print_item (list, items[scroll]->name,
status[scroll], 0, TRUE);
wnoutrefresh (list);
@@ -263,7 +264,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
/* Scroll list up */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
print_item (list, items[scroll + max_choice - 1]->name,
status[scroll + max_choice - 1],
max_choice - 1, FALSE);
scrollok (list, TRUE);
@@ -271,7 +272,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
scrollok (list, FALSE);
}
scroll++;
print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
print_item (list, items[scroll + max_choice - 1]->name,
status[scroll + max_choice - 1],
max_choice - 1, TRUE);
wnoutrefresh (list);
@@ -287,11 +288,11 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
}
if (i != choice) {
/* De-highlight current item */
print_item (list, items[(scroll + choice) * 3 + 1],
print_item (list, items[scroll + choice]->name,
status[scroll + choice], choice, FALSE);
/* Highlight new item */
choice = i;
print_item (list, items[(scroll + choice) * 3 + 1],
print_item (list, items[scroll + choice]->name,
status[scroll + choice], choice, TRUE);
wnoutrefresh (list);
wrefresh (dialog);
@@ -330,7 +331,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
status[i] = 0;
status[scroll + choice] = 1;
for (i = 0; i < max_choice; i++)
print_item (list, items[(scroll + i) * 3 + 1],
print_item (list, items[scroll + i]->name,
status[scroll + i], i, i == choice);
}
}
@@ -338,14 +339,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width,
wrefresh (dialog);
for (i = 0; i < item_no; i++) {
if (status[i]) {
if (flag == FLAG_CHECK) {
fprintf (stderr, "\"%s\" ", items[i * 3]);
} else {
fprintf (stderr, "%s", items[i * 3]);
}
}
items[i]->selected = status[i];
}
}
delwin (dialog);

566
scripts/config/conf.c Normal file
View File

@@ -0,0 +1,566 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
static void conf(struct menu *menu);
static void check_conf(struct menu *menu);
enum {
ask_all,
ask_new,
ask_silent,
set_default,
set_yes,
set_mod,
set_no,
set_random
} input_mode = ask_all;
static int indent = 1;
static int valid_stdin = 1;
static int conf_cnt;
static char line[128];
static struct menu *rootEntry;
static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
#if 0
static void printc(int ch)
{
static int sep = 0;
if (!sep) {
putchar('[');
sep = 1;
} else if (ch)
putchar('/');
if (!ch) {
putchar(']');
putchar(' ');
sep = 0;
} else
putchar(ch);
}
#endif
static void printo(const char *o)
{
static int sep = 0;
if (!sep) {
putchar('(');
sep = 1;
} else if (o) {
putchar(',');
putchar(' ');
}
if (!o) {
putchar(')');
putchar(' ');
sep = 0;
} else
printf("%s", o);
}
static void strip(char *str)
{
char *p = str;
int l;
while ((isspace((int)*p)))
p++;
l = strlen(p);
if (p != str)
memmove(str, p, l + 1);
if (!l)
return;
p = str + l - 1;
while ((isspace((int)*p)))
*p-- = 0;
}
static void conf_askvalue(struct symbol *sym, const char *def)
{
enum symbol_type type = sym_get_type(sym);
tristate val;
if (!sym_has_value(sym))
printf("(NEW) ");
line[0] = '\n';
line[1] = 0;
switch (input_mode) {
case ask_new:
case ask_silent:
if (sym_has_value(sym)) {
printf("%s\n", def);
return;
}
if (!valid_stdin && input_mode == ask_silent) {
printf("aborted!\n\n");
printf("Console input/output is redirected. ");
printf("Run 'make oldconfig' to update configuration.\n\n");
exit(1);
}
case ask_all:
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] == 0) {
help = nohelp_text;
if (menu->sym->help)
help = menu->sym->help;
printf("\n%s\n", menu->sym->help);
def = NULL;
break;
}
default:
line[strlen(line)-1] = 0;
def = line;
}
if (def && sym_set_string_value(sym, def))
return 0;
}
}
static int conf_sym(struct menu *menu)
{
struct symbol *sym = menu->sym;
int type;
tristate oldval, newval;
const char *help;
while (1) {
printf("%*s%s ", indent - 1, "", menu->prompt->text);
if (sym->name)
printf("(%s) ", sym->name);
type = sym_get_type(sym);
putchar('[');
oldval = sym_get_tristate_value(sym);
switch (oldval) {
case no:
putchar('N');
break;
case mod:
putchar('M');
break;
case yes:
putchar('Y');
break;
}
if (oldval != no && sym_tristate_within_range(sym, no))
printf("/n");
if (oldval != mod && sym_tristate_within_range(sym, mod))
printf("/m");
if (oldval != yes && sym_tristate_within_range(sym, yes))
printf("/y");
if (sym->help)
printf("/?");
printf("] ");
conf_askvalue(sym, sym_get_string_value(sym));
strip(line);
switch (line[0]) {
case 'n':
case 'N':
newval = no;
if (!line[1] || !strcmp(&line[1], "o"))
break;
continue;
case 'm':
case 'M':
newval = mod;
if (!line[1])
break;
continue;
case 'y':
case 'Y':
newval = yes;
if (!line[1] || !strcmp(&line[1], "es"))
break;
continue;
case 0:
newval = oldval;
break;
case '?':
goto help;
default:
continue;
}
if (sym_set_tristate_value(sym, newval))
return 0;
help:
help = nohelp_text;
if (sym->help)
help = sym->help;
printf("\n%s\n", help);
}
}
static int conf_choice(struct menu *menu)
{
struct symbol *sym, *def_sym;
struct menu *cmenu, *def_menu;
const char *help;
int type, len;
bool is_new;
sym = menu->sym;
type = sym_get_type(sym);
is_new = !sym_has_value(sym);
if (sym_is_changable(sym)) {
conf_sym(menu);
sym_calc_value(sym);
switch (sym_get_tristate_value(sym)) {
case no:
return 1;
case mod:
return 0;
case yes:
break;
}
} else {
sym->def = sym->curr;
if (S_TRI(sym->curr) == mod) {
printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
return 0;
}
}
while (1) {
printf("%*s%s ", indent - 1, "", menu_get_prompt(menu));
def_sym = sym_get_choice_value(sym);
def_menu = NULL;
for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
if (!menu_is_visible(cmenu))
continue;
printo(menu_get_prompt(cmenu));
if (cmenu->sym == def_sym)
def_menu = cmenu;
}
printo(NULL);
if (def_menu)
printf("[%s] ", menu_get_prompt(def_menu));
else {
printf("\n");
return 1;
}
switch (input_mode) {
case ask_new:
case ask_silent:
case ask_all:
conf_askvalue(sym, menu_get_prompt(def_menu));
strip(line);
break;
default:
line[0] = 0;
printf("\n");
}
if (line[0] == '?' && !line[1]) {
help = nohelp_text;
if (menu->sym->help)
help = menu->sym->help;
printf("\n%s\n", help);
continue;
}
if (line[0]) {
len = strlen(line);
line[len] = 0;
def_menu = NULL;
for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
if (!cmenu->sym || !menu_is_visible(cmenu))
continue;
if (!strncasecmp(line, menu_get_prompt(cmenu), len)) {
def_menu = cmenu;
break;
}
}
}
if (def_menu) {
sym_set_choice_value(sym, def_menu->sym);
if (def_menu->list) {
indent += 2;
conf(def_menu->list);
indent -= 2;
}
return 1;
}
}
}
static void conf(struct menu *menu)
{
struct symbol *sym;
struct property *prop;
struct menu *child;
if (!menu_is_visible(menu))
return;
sym = menu->sym;
prop = menu->prompt;
if (prop) {
const char *prompt;
switch (prop->type) {
case P_MENU:
if (input_mode == ask_silent && rootEntry != menu) {
check_conf(menu);
return;
}
case P_COMMENT:
prompt = menu_get_prompt(menu);
if (prompt)
printf("%*c\n%*c %s\n%*c\n",
indent, '*',
indent, '*', prompt,
indent, '*');
default:
;
}
}
if (!sym)
goto conf_childs;
if (sym_is_choice(sym)) {
conf_choice(menu);
if (S_TRI(sym->curr) != mod)
return;
goto conf_childs;
}
switch (sym->type) {
case S_INT:
case S_HEX:
case S_STRING:
conf_string(menu);
break;
default:
conf_sym(menu);
break;
}
conf_childs:
if (sym)
indent += 2;
for (child = menu->list; child; child = child->next)
conf(child);
if (sym)
indent -= 2;
}
static void check_conf(struct menu *menu)
{
struct symbol *sym;
struct menu *child;
if (!menu_is_visible(menu))
return;
sym = menu->sym;
if (!sym)
goto conf_childs;
if (sym_is_choice(sym)) {
if (!sym_has_value(sym)) {
if (!conf_cnt++)
printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
if (sym_get_tristate_value(sym) != mod)
return;
goto conf_childs;
}
if (!sym_has_value(sym)) {
if (!conf_cnt++)
printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
conf_childs:
for (child = menu->list; child; child = child->next)
check_conf(child);
}
int main(int ac, char **av)
{
const char *name;
struct stat tmpstat;
if (ac > 1 && av[1][0] == '-') {
switch (av[1][1]) {
case 'o':
input_mode = ask_new;
break;
case 's':
input_mode = ask_silent;
valid_stdin = isatty(0) && isatty(1) && isatty(2);
break;
case 'd':
input_mode = set_default;
break;
case 'n':
input_mode = set_no;
break;
case 'm':
input_mode = set_mod;
break;
case 'y':
input_mode = set_yes;
break;
case 'r':
input_mode = set_random;
srandom(time(NULL));
break;
case 'h':
case '?':
printf("%s [-o|-s] config\n", av[0]);
exit(0);
}
name = av[2];
} else
name = av[1];
conf_parse(name);
//zconfdump(stdout);
switch (input_mode) {
case set_default:
name = conf_get_default_confname();
if (conf_read(name)) {
printf("***\n"
"*** Can't find default configuration \"%s\"!\n"
"***\n", name);
exit(1);
}
break;
case ask_silent:
if (stat(".config", &tmpstat)) {
printf("***\n"
"*** You have not yet configured BusyBox!\n"
"***\n"
"*** Please run some configurator (e.g. \"make oldconfig\"\n"
"*** or \"make menuconfig\").\n"
"***\n");
exit(1);
}
case ask_all:
case ask_new:
conf_read(NULL);
break;
default:
break;
}
if (input_mode != ask_silent) {
rootEntry = &rootmenu;
conf(&rootmenu);
if (input_mode == ask_all) {
input_mode = ask_silent;
valid_stdin = 1;
}
}
do {
conf_cnt = 0;
check_conf(&rootmenu);
} while (conf_cnt);
conf_write(NULL);
return 0;
}

371
scripts/config/confdata.c Normal file
View File

@@ -0,0 +1,371 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*
* Allow 'n' as a symbol value.
* 2002-11-05 Petr Baudis <pasky@ucw.cz>
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
const char conf_def_filename[] = ".config";
const char conf_defname[] = "extra/Configs/Config.$TARGET_ARCH.default";
const char *conf_confnames[] = {
".config",
conf_defname,
NULL,
};
static char *conf_expand_value(const char *in)
{
struct symbol *sym;
const char *src;
static char res_value[SYMBOL_MAXLENGTH];
char *dst, name[SYMBOL_MAXLENGTH];
res_value[0] = 0;
dst = name;
while ((src = strchr(in, '$'))) {
strncat(res_value, in, src - in);
src++;
dst = name;
while (isalnum((int)*src) || *src == '_')
*dst++ = *src++;
*dst = 0;
sym = sym_lookup(name, 0);
sym_calc_value(sym);
strcat(res_value, sym_get_string_value(sym));
in = src;
}
strcat(res_value, in);
return res_value;
}
char *conf_get_default_confname(void)
{
return conf_expand_value(conf_defname);
}
int conf_read(const char *name)
{
FILE *in = NULL;
char line[1024];
char *p, *p2;
int lineno = 0;
struct symbol *sym;
struct property *prop;
struct expr *e;
int i;
if (name) {
in = fopen(name, "r");
} else {
const char **names = conf_confnames;
while ((name = *names++)) {
name = conf_expand_value(name);
in = fopen(name, "r");
if (in) {
printf("#\n"
"# using defaults found in %s\n"
"#\n", name);
break;
}
}
}
if (!in)
return 1;
for_all_symbols(i, sym) {
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
sym->flags &= ~SYMBOL_VALID;
switch (sym->type) {
case S_INT:
case S_HEX:
case S_STRING:
if (S_VAL(sym->def))
free(S_VAL(sym->def));
default:
S_VAL(sym->def) = NULL;
S_TRI(sym->def) = no;
;
}
}
while (fgets(line, sizeof(line), in)) {
lineno++;
switch (line[0]) {
case '\n':
break;
case ' ':
break;
case '#':
p = strchr(line, ' ');
if (!p)
continue;
*p++ = 0;
p = strchr(p, ' ');
if (!p)
continue;
*p++ = 0;
if (strncmp(p, "is not set", 10))
continue;
sym = sym_lookup(line+2, 0);
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
sym->def = symbol_no.curr;
sym->flags &= ~SYMBOL_NEW;
break;
default:
;
}
break;
case 'A' ... 'Z':
p = strchr(line, '=');
if (!p)
continue;
*p++ = 0;
p2 = strchr(p, '\n');
if (p2)
*p2 = 0;
sym = sym_find(line);
if (!sym) {
fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line);
break;
}
switch (sym->type) {
case S_TRISTATE:
if (p[0] == 'm') {
S_TRI(sym->def) = mod;
sym->flags &= ~SYMBOL_NEW;
break;
}
case S_BOOLEAN:
if (p[0] == 'y') {
S_TRI(sym->def) = yes;
sym->flags &= ~SYMBOL_NEW;
break;
}
if (p[0] == 'n') {
S_TRI(sym->def) = 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));
}
case S_INT:
case S_HEX:
if (sym_string_valid(sym, p)) {
S_VAL(sym->def) = strdup(p);
sym->flags &= ~SYMBOL_NEW;
} else
fprintf(stderr, "%s:%d:symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
break;
default:
;
}
if (sym_is_choice_value(sym)) {
prop = sym_get_choice_prop(sym);
switch (S_TRI(sym->def)) {
case mod:
if (S_TRI(prop->def->def) == yes)
/* warn? */;
break;
case yes:
if (S_TRI(prop->def->def) != no)
/* warn? */;
S_VAL(prop->def->def) = sym;
break;
case no:
break;
}
S_TRI(prop->def->def) = S_TRI(sym->def);
}
break;
default:
continue;
}
}
fclose(in);
for_all_symbols(i, sym) {
if (!sym_is_choice(sym))
continue;
prop = sym_get_choice_prop(sym);
for (e = prop->dep; e; e = e->left.expr)
sym->flags |= e->right.sym->flags & SYMBOL_NEW;
sym->flags &= ~SYMBOL_NEW;
}
sym_change_count = 1;
return 0;
}
int conf_write(const char *name)
{
FILE *out, *out_h;
struct symbol *sym;
struct menu *menu;
char oldname[128];
int type, l;
const char *str;
out = fopen(".tmpconfig", "w");
if (!out)
return 1;
out_h = fopen(".tmpconfig.h", "w");
if (!out_h)
return 1;
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
"#\n");
fprintf(out_h, "/*\n"
" * Automatically generated 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\n",
getenv("VERSION"),
getenv("BUILDTIME")
);
if (!sym_change_count)
sym_clear_all_valid();
menu = rootmenu.list;
while (menu) {
sym = menu->sym;
if (!sym) {
if (!menu_is_visible(menu))
goto next;
str = menu_get_prompt(menu);
fprintf(out, "\n"
"#\n"
"# %s\n"
"#\n", str);
fprintf(out_h, "\n"
"/*\n"
" * %s\n"
" */\n", str);
} else if (!(sym->flags & SYMBOL_CHOICE)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
goto next;
sym->flags &= ~SYMBOL_WRITE;
type = sym->type;
if (type == S_TRISTATE) {
sym_calc_value(modules_sym);
if (S_TRI(modules_sym->curr) == no)
type = S_BOOLEAN;
}
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
fprintf(out, "# %s is not set\n", sym->name);
fprintf(out_h, "#undef %s\n", sym->name);
break;
case mod:
#if 0
fprintf(out, "%s=m\n", sym->name);
fprintf(out_h, "#define __%s__MODULE 1\n", sym->name);
#endif
break;
case yes:
fprintf(out, "%s=y\n", sym->name);
fprintf(out_h, "#define %s 1\n", sym->name);
break;
}
break;
case S_STRING:
// fix me
str = sym_get_string_value(sym);
fprintf(out, "%s=\"", sym->name);
fprintf(out_h, "#define %s \"", sym->name);
do {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
fwrite(str, l, 1, out_h);
}
str += l;
while (*str == '\\' || *str == '"') {
fprintf(out, "\\%c", *str);
fprintf(out_h, "\\%c", *str);
str++;
}
} while (*str);
fputs("\"\n", out);
fputs("\"\n", out_h);
break;
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out, "%s=%s\n", sym->name, str);
fprintf(out_h, "#define %s 0x%s\n", sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "%s=%s\n", sym->name, str);
fprintf(out_h, "#define %s %s\n", sym->name, str);
break;
}
}
next:
if (menu->list) {
menu = menu->list;
continue;
}
if (menu->next)
menu = menu->next;
else while ((menu = menu->parent)) {
if (menu->next) {
menu = menu->next;
break;
}
}
}
fclose(out);
fclose(out_h);
if (!name) {
rename(".tmpconfig.h", "include/config.h");
name = conf_def_filename;
file_write_dep(NULL);
} else
unlink(".tmpconfig.h");
sprintf(oldname, "%s.old", name);
rename(name, oldname);
if (rename(".tmpconfig", name))
return 1;
sym_change_count = 0;
return 0;
}

View File

@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#ifdef CURSES_LOC
#include CURSES_LOC
/*
@@ -125,29 +126,35 @@
* Global variables
*/
extern bool use_colors;
extern bool use_shadow;
extern chtype attributes[];
#endif
extern const char *backtitle;
extern char *backtitle;
struct dialog_list_item {
char *name;
int namelen;
char *tag;
int selected; /* Set to 1 by dialog_*() function. */
};
/*
* Function prototypes
*/
extern void create_rc (const char *filename);
extern int parse_rc (void);
void init_dialog (void);
void end_dialog (void);
void attr_clear (WINDOW * win, int height, int width, chtype attr);
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);
@@ -156,14 +163,17 @@ int dialog_msgbox (const char *title, const char *prompt, int height,
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,
const char * const * items);
struct dialog_list_item ** items);
int dialog_checklist (const char *title, const char *prompt, int height,
int width, int list_height, int item_no,
const char * const * items, int flag);
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.
@@ -173,7 +183,9 @@ int dialog_inputbox (const char *title, const char *prompt, int height,
* -- 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
/*

1054
scripts/config/expr.c Normal file

File diff suppressed because it is too large Load Diff

242
scripts/config/expr.h Normal file
View File

@@ -0,0 +1,242 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#ifndef EXPR_H
#define EXPR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
struct file {
struct file *next;
struct file *parent;
#ifdef CML1
struct statement *stmt;
struct statement *last_stmt;
#endif
char *name;
int lineno;
int flags;
};
#define FILE_BUSY 0x0001
#define FILE_SCANNED 0x0002
#define FILE_PRINTED 0x0004
typedef enum tristate {
no, mod, yes
} tristate;
enum expr_type {
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL
};
union expr_data {
struct expr *expr;
struct symbol *sym;
};
struct expr {
#ifdef CML1
int token;
#else
enum expr_type type;
#endif
union expr_data left, right;
};
#define E_TRI(ev) ((ev).tri)
#define E_EXPR(ev) ((ev).expr)
#define E_CALC(ev) (E_TRI(ev) = expr_calc_value(E_EXPR(ev)))
#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
#define E_NOT(dep) (2-(dep))
struct expr_value {
struct expr *expr;
tristate tri;
};
#define S_VAL(sv) ((sv).value)
#define S_TRI(sv) ((sv).tri)
#define S_EQ(sv1, sv2) (S_VAL(sv1) == S_VAL(sv2) || !strcmp(S_VAL(sv1), S_VAL(sv2)))
struct symbol_value {
void *value;
tristate tri;
};
enum symbol_type {
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
};
struct symbol {
struct symbol *next;
char *name;
char *help;
#ifdef CML1
int type;
#else
enum symbol_type type;
#endif
struct symbol_value curr, def;
tristate visible;
int flags;
struct property *prop;
struct expr *dep, *dep2;
struct menu *menu;
};
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
#ifdef CML1
#define SYMBOL_UNKNOWN S_UNKNOWN
#define SYMBOL_BOOLEAN S_BOOLEAN
#define SYMBOL_TRISTATE S_TRISTATE
#define SYMBOL_INT S_INT
#define SYMBOL_HEX S_HEX
#define SYMBOL_STRING S_STRING
#define SYMBOL_OTHER S_OTHER
#endif
#define SYMBOL_YES 0x0001
#define SYMBOL_MOD 0x0002
#define SYMBOL_NO 0x0004
#define SYMBOL_CONST 0x0007
#define SYMBOL_CHECK 0x0008
#define SYMBOL_CHOICE 0x0010
#define SYMBOL_CHOICEVAL 0x0020
#define SYMBOL_PRINTED 0x0040
#define SYMBOL_VALID 0x0080
#define SYMBOL_OPTIONAL 0x0100
#define SYMBOL_WRITE 0x0200
#define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257
#define SYMBOL_HASHMASK 0xff
enum prop_type {
P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE
};
struct property {
struct property *next;
struct symbol *sym;
#ifdef CML1
int token;
#else
enum prop_type type;
#endif
const char *text;
struct symbol *def;
struct expr_value visible;
struct expr *dep;
struct expr *dep2;
struct menu *menu;
struct file *file;
int lineno;
#ifdef CML1
struct property *next_pos;
#endif
};
#define for_all_properties(sym, st, tok) \
for (st = sym->prop; st; st = st->next) \
if (st->type == (tok))
#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT)
#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
struct menu {
struct menu *next;
struct menu *parent;
struct menu *list;
struct symbol *sym;
struct property *prompt;
struct expr *dep;
//char *help;
struct file *file;
int lineno;
void *data;
};
#ifndef SWIG
extern struct file *file_list;
extern struct file *current_file;
struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym;
extern int cdebug;
extern int print_type;
struct expr *expr_alloc_symbol(struct symbol *sym);
#ifdef CML1
struct expr *expr_alloc_one(int token, struct expr *ce);
struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2);
struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2);
#else
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
#endif
struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
struct expr *expr_copy(struct expr *org);
void expr_free(struct expr *e);
int expr_eq(struct expr *e1, struct expr *e2);
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
tristate expr_calc_value(struct expr *e);
struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_trans_bool(struct expr *e);
struct expr *expr_eliminate_dups(struct expr *e);
struct expr *expr_transform(struct expr *e);
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
void expr_fprint(struct expr *e, FILE *out);
void print_expr(int mask, struct expr *e, int prevtoken);
#ifdef CML1
static inline int expr_is_yes(struct expr *e)
{
return !e || (e->token == WORD && e->left.sym == &symbol_yes);
}
static inline int expr_is_no(struct expr *e)
{
return e && (e->token == WORD && e->left.sym == &symbol_no);
}
#else
static inline int expr_is_yes(struct expr *e)
{
return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
}
static inline int expr_is_no(struct expr *e)
{
return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
}
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* EXPR_H */

File diff suppressed because it is too large Load Diff

106
scripts/config/lkc.h Normal file
View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#ifndef LKC_H
#define LKC_H
#include "expr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LKC_DIRECT_LINK
#define P(name,type,arg) extern type name arg
#else
#include "lkc_defs.h"
#define P(name,type,arg) extern type (*name ## _p) arg
#endif
#include "lkc_proto.h"
#undef P
void symbol_end(char *help);
int zconfparse(void);
void zconfdump(FILE *out);
extern int zconfdebug;
void zconf_starthelp(void);
void zconf_initscan(const char *name);
void zconf_nextfile(const char *name);
int zconf_lineno(void);
char *zconf_curname(void);
/* confdata.c */
extern const char conf_def_filename[];
extern char conf_filename[];
char *conf_get_default_confname(void);
/* kconfig_load.c */
void kconfig_load(void);
/* menu.c */
void menu_init(void);
void menu_add_menu(void);
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
struct property *create_prop(enum prop_type type);
void menu_add_dep(struct expr *dep);
struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep);
void menu_finalize(struct menu *parent);
void menu_set_type(int type);
struct file *file_lookup(const char *name);
int file_write_dep(const char *name);
extern struct menu *current_entry;
extern struct menu *current_menu;
/* symbol.c */
void sym_init(void);
void sym_clear_all_valid(void);
static inline tristate sym_get_tristate_value(struct symbol *sym)
{
return S_TRI(sym->curr);
}
static inline struct symbol *sym_get_choice_value(struct symbol *sym)
{
return (struct symbol *)S_VAL(sym->curr);
}
static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
{
return sym_set_tristate_value(chval, yes);
}
static inline bool sym_is_choice(struct symbol *sym)
{
return sym->flags & SYMBOL_CHOICE ? true : false;
}
static inline bool sym_is_choice_value(struct symbol *sym)
{
return sym->flags & SYMBOL_CHOICEVAL ? true : false;
}
static inline bool sym_is_optional(struct symbol *sym)
{
return sym->flags & SYMBOL_OPTIONAL ? true : false;
}
static inline bool sym_has_value(struct symbol *sym)
{
//return S_VAL(sym->def) != NULL;
return sym->flags & SYMBOL_NEW ? false : true;
}
#ifdef __cplusplus
}
#endif
#endif /* LKC_H */

View File

@@ -0,0 +1,38 @@
/* confdata.c */
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
P(conf_write,int,(const char *name));
/* menu.c */
P(rootmenu,struct menu,);
P(menu_is_visible,bool,(struct menu *menu));
P(menu_get_prompt,const char *,(struct menu *menu));
P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
P(sym_change_count,int,);
P(sym_lookup,struct symbol *,(const char *name, int isconst));
P(sym_find,struct symbol *,(const char *name));
P(sym_type_name,const char *,(int type));
P(sym_calc_value,void,(struct symbol *sym));
P(sym_get_type,int,(struct symbol *sym));
P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
P(sym_is_changable,bool,(struct symbol *sym));
P(sym_get_choice_prop,struct property *,(struct symbol *sym));
P(sym_get_default_prop,struct property *,(struct symbol *sym));
P(sym_get_string_value,const char *,(struct symbol *sym));
P(prop_get_type_name,const char *,(enum prop_type type));
/* expr.c */
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken));

669
scripts/config/mconf.c Normal file
View File

@@ -0,0 +1,669 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*
* Introduced single menu mode (show all sub-menus in one large tree).
* 2002-11-06 Petr Baudis <pasky@ucw.cz>
*
* Directly use liblxdialog library routines.
* 2002-11-14 Petr Baudis <pasky@ucw.cz>
*/
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/termios.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "dialog.h"
#define LKC_DIRECT_LINK
#include "lkc.h"
static const char menu_instructions[] =
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
"Highlighted letters are hotkeys. "
"Pressing <Y> selectes a feature, while <N> will exclude a feature. "
"Press <Esc><Esc> 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 <SPACE BAR>. "
"Press <?> for additional information about this option.",
inputbox_instructions_int[] =
"Please enter a decimal value. "
"Fractions will not be accepted. "
"Use the <TAB> key to move from the input field to the buttons below it.",
inputbox_instructions_hex[] =
"Please enter a hexadecimal value. "
"Use the <TAB> key to move from the input field to the buttons below it.",
inputbox_instructions_string[] =
"Please enter a string value. "
"Use the <TAB> key to move from the input field to the buttons below it.",
setmod_text[] =
"This feature depends on another which has been configured as a module.\n"
"As a result, this feature will be built as a module.",
nohelp_text[] =
"There is no help available for this 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 BusyBox\n"
"configurations available on a single machine.\n"
"\n"
"If you have saved a previous configuration in a file other than the\n"
"BusyBox 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 BusyBox\n"
"configurations available on a single machine.\n"
"\n"
"Entering a file name here will allow you to later retrieve, modify\n"
"and use the current configuration as an alternate to whatever\n"
"configuration options you have selected at that time.\n"
"\n"
"If you are uncertain what all this means then you should probably\n"
"leave this blank.\n"
;
static char 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;
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
rows = 24;
cols = 80;
} else {
rows = ws.ws_row;
cols = ws.ws_col;
}
if (rows < 19 || cols < 80) {
fprintf(stderr, "Your display is too small to run Menuconfig!\n");
fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
exit(1);
}
rows -= 4;
cols -= 5;
}
static void 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 {
if (menu->parent != &rootmenu)
cprint_name(" %*c", indent + 1, ' ');
cprint_name("%s --->", 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);
cprint_name("[%c]", val == no ? ' ' : '*');
break;
case S_TRISTATE:
cprint_tag("t%p", menu);
switch (val) {
case yes: ch = '*'; break;
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
cprint_name("<%c>", ch);
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) ? "" : " (NEW)");
goto conf_childs;
}
}
cprint_name("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
sym_has_value(sym) ? "" : " (NEW)");
}
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 = (submenu->data)? NULL : (void *)1;
else
conf(submenu);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
break;
case 's':
conf_string(submenu);
break;
case 'L':
conf_load();
break;
case 'S':
conf_save();
break;
}
break;
case 2:
if (sym)
show_help(submenu);
else
show_readme();
break;
case 3:
if (type == 't') {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
show_textbox(NULL, setmod_text, 6, 74);
}
break;
case 4:
if (type == 't')
sym_set_tristate_value(sym, no);
break;
case 5:
if (type == 't')
sym_set_tristate_value(sym, mod);
break;
case 6:
if (type == 't')
sym_toggle_tristate_value(sym);
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)
{
while (dialog_textbox(NULL, "scripts/README.Menuconfig", rows, cols) < 0)
;
}
static void conf_choice(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
struct menu *child;
struct symbol *active;
while (1) {
current_menu = menu;
active = sym_get_choice_value(menu->sym);
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));
items[item_no - 1]->selected = (child->sym == active);
}
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", &menu) != 1)
break;
sym_set_tristate_value(menu->sym, yes);
return;
case 1:
show_help(menu);
break;
case 255:
return;
}
}
}
static void conf_string(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
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");
unlink("lxdialog.scrltmp");
}
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);
backtitle = malloc(128);
sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
snprintf(backtitle, 128, "BusyBox 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 BusyBox configuration?", 5, 60);
} while (stat < 0);
end_dialog();
if (stat == 0) {
conf_write(NULL);
printf("\n\n"
"*** End of BusyBox configuration.\n"
"*** Check the top-level Makefile for additional configuration options.\n\n");
} else
printf("\n\nYour BusyBox configuration changes were NOT saved.\n\n");
return 0;
}

309
scripts/config/menu.c Normal file
View File

@@ -0,0 +1,309 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <stdlib.h>
#include <string.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct menu rootmenu;
struct menu *current_menu, *current_entry;
static struct menu **last_entry_ptr;
struct file *file_list;
struct file *current_file;
void menu_init(void)
{
current_entry = current_menu = &rootmenu;
last_entry_ptr = &rootmenu.list;
}
void menu_add_entry(struct symbol *sym)
{
struct menu *menu;
menu = malloc(sizeof(*menu));
memset(menu, 0, sizeof(*menu));
menu->sym = sym;
menu->parent = current_menu;
menu->file = current_file;
menu->lineno = zconf_lineno();
*last_entry_ptr = menu;
last_entry_ptr = &menu->next;
current_entry = menu;
}
void menu_end_entry(void)
{
}
void menu_add_menu(void)
{
current_menu = current_entry;
last_entry_ptr = &current_entry->list;
}
void menu_end_menu(void)
{
last_entry_ptr = &current_menu->next;
current_menu = current_menu->parent;
}
void menu_add_dep(struct expr *dep)
{
current_entry->dep = expr_alloc_and(current_entry->dep, dep);
}
void menu_set_type(int type)
{
struct symbol *sym = current_entry->sym;
if (sym->type == type)
return;
if (sym->type == S_UNKNOWN) {
sym->type = type;
return;
}
fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n",
current_entry->file->name, current_entry->lineno,
sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type));
}
struct property *create_prop(enum prop_type type)
{
struct property *prop;
prop = malloc(sizeof(*prop));
memset(prop, 0, sizeof(*prop));
prop->type = type;
prop->file = current_file;
prop->lineno = zconf_lineno();
return prop;
}
struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep)
{
struct property *prop = create_prop(token);
struct property **propp;
prop->sym = current_entry->sym;
prop->menu = current_entry;
prop->text = prompt;
prop->def = def;
E_EXPR(prop->visible) = dep;
if (prompt)
current_entry->prompt = prop;
/* append property to the prop list of symbol */
if (prop->sym) {
for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
;
*propp = prop;
}
return prop;
}
void menu_add_prompt(int token, char *prompt, struct expr *dep)
{
current_entry->prompt = menu_add_prop(token, prompt, NULL, dep);
}
void menu_add_default(int token, struct symbol *def, struct expr *dep)
{
current_entry->prompt = menu_add_prop(token, NULL, def, dep);
}
void menu_finalize(struct menu *parent)
{
struct menu *menu, *last_menu;
struct symbol *sym;
struct property *prop;
struct expr *parentdep, *basedep, *dep, *dep2;
sym = parent->sym;
if (parent->list) {
if (sym && sym_is_choice(sym)) {
/* find the first choice value and find out choice type */
for (menu = parent->list; menu; menu = menu->next) {
if (menu->sym) {
current_entry = parent;
menu_set_type(menu->sym->type);
current_entry = menu;
menu_set_type(sym->type);
break;
}
}
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
parentdep = E_EXPR(parent->prompt->visible);
else
parentdep = parent->dep;
for (menu = parent->list; menu; menu = menu->next) {
basedep = expr_transform(menu->dep);
basedep = expr_alloc_and(expr_copy(parentdep), basedep);
basedep = expr_eliminate_dups(basedep);
menu->dep = basedep;
if (menu->sym)
prop = menu->sym->prop;
else
prop = menu->prompt;
for (; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
dep = expr_transform(E_EXPR(prop->visible));
dep = expr_alloc_and(expr_copy(basedep), dep);
dep = expr_eliminate_dups(dep);
if (menu->sym && menu->sym->type != S_TRISTATE)
dep = expr_trans_bool(dep);
E_EXPR(prop->visible) = dep;
}
}
for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu);
} else if (sym && parent->prompt) {
basedep = E_EXPR(parent->prompt->visible);
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep));
last_menu = NULL;
for (menu = parent->next; menu; menu = menu->next) {
dep = menu->prompt ? E_EXPR(menu->prompt->visible) : menu->dep;
if (!expr_contains_symbol(dep, sym))
break;
if (expr_depends_symbol(dep, sym))
goto next;
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
dep = expr_eliminate_dups(expr_transform(dep));
dep2 = expr_copy(basedep);
expr_eliminate_eq(&dep, &dep2);
expr_free(dep);
if (!expr_is_yes(dep2)) {
expr_free(dep2);
break;
}
expr_free(dep2);
next:
menu_finalize(menu);
menu->parent = parent;
last_menu = menu;
}
if (last_menu) {
parent->list = parent->next;
parent->next = last_menu->next;
last_menu->next = NULL;
}
}
for (menu = parent->list; menu; menu = menu->next) {
if (sym && sym_is_choice(sym) && menu->sym) {
menu->sym->flags |= SYMBOL_CHOICEVAL;
current_entry = menu;
menu_set_type(sym->type);
menu_add_prop(P_CHOICE, NULL, parent->sym, NULL);
prop = sym_get_choice_prop(parent->sym);
//dep = expr_alloc_one(E_CHOICE, dep);
//dep->right.sym = menu->sym;
prop->dep = expr_alloc_one(E_CHOICE, prop->dep);
prop->dep->right.sym = menu->sym;
}
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
for (last_menu = menu->list; ; last_menu = last_menu->next) {
last_menu->parent = parent;
if (!last_menu->next)
break;
}
last_menu->next = menu->next;
menu->next = menu->list;
menu->list = NULL;
}
}
}
bool menu_is_visible(struct menu *menu)
{
tristate visible;
if (!menu->prompt)
return false;
if (menu->sym) {
sym_calc_value(menu->sym);
visible = E_TRI(menu->prompt->visible);
} else
visible = E_CALC(menu->prompt->visible);
return visible != no;
}
const char *menu_get_prompt(struct menu *menu)
{
if (menu->prompt)
return menu->prompt->text;
else if (menu->sym)
return menu->sym->name;
return NULL;
}
struct menu *menu_get_root_menu(struct menu *menu)
{
return &rootmenu;
}
struct menu *menu_get_parent_menu(struct menu *menu)
{
enum prop_type type;
while (menu != &rootmenu) {
menu = menu->parent;
type = menu->prompt ? menu->prompt->type : 0;
if (type == P_MENU || type == P_ROOTMENU)
break;
}
return menu;
}
struct file *file_lookup(const char *name)
{
struct file *file;
for (file = file_list; file; file = file->next) {
if (!strcmp(name, file->name))
return file;
}
file = malloc(sizeof(*file));
memset(file, 0, sizeof(*file));
file->name = strdup(name);
file->next = file_list;
file_list = file;
return file;
}
int file_write_dep(const char *name)
{
struct file *file;
FILE *out;
if (!name)
name = ".config.cmd";
out = fopen(".config.tmp", "w");
if (!out)
return 1;
fprintf(out, "deps_config := \\\n");
for (file = file_list; file; file = file->next) {
if (file->next)
fprintf(out, "\t%s \\\n", file->name);
else
fprintf(out, "\t%s\n", file->name);
}
fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n");
fclose(out);
rename(".config.tmp", name);
return 0;
}

View File

@@ -93,7 +93,7 @@ print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey
}
if (selected) {
wmove (win, choice, item_x+1);
wrefresh (win);
wnoutrefresh (win);
}
}
@@ -165,8 +165,7 @@ print_buttons (WINDOW *win, int height, int width, int selected)
int
dialog_menu (const char *title, const char *prompt, int height, int width,
int menu_height, const char *current, int item_no,
const char * const * items)
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;
@@ -230,8 +229,8 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
*/
item_x = 0;
for (i = 0; i < item_no; i++) {
item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
if (strcmp(current, items[i*2]) == 0) choice = 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;
@@ -261,8 +260,8 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
/* Print the menu */
for (i=0; i < max_choice; i++) {
print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
(items[(first_item + i)*2][0] != ':'));
print_item (menu, items[first_item + i]->name, i, i == choice,
(items[first_item + i]->tag[0] != ':'));
}
wnoutrefresh (menu);
@@ -283,14 +282,14 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
i = max_choice;
else {
for (i = choice+1; i < max_choice; i++) {
j = first_alpha(items[(scroll+i)*2+1], "YyNnMm");
if (key == tolower(items[(scroll+i)*2+1][j]))
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)*2+1], "YyNnMm");
if (key == tolower(items[(scroll+i)*2+1][j]))
j = first_alpha(items[scroll + i]->name, "YyNnMm>");
if (key == tolower(items[scroll + i]->name[j]))
break;
}
}
@@ -300,8 +299,8 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
key == '-' || key == '+' ||
key == KEY_PPAGE || key == KEY_NPAGE) {
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
(items[(scroll+choice)*2][0] != ':'));
print_item (menu, items[scroll + choice]->name, choice, FALSE,
(items[scroll + choice]->tag[0] != ':'));
if (key == KEY_UP || key == '-') {
if (choice < 2 && scroll) {
@@ -312,15 +311,15 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
scroll--;
print_item (menu, items[scroll * 2 + 1], 0, FALSE,
(items[scroll*2][0] != ':'));
print_item (menu, items[scroll * 2]->name, 0, FALSE,
(items[scroll * 2]->tag[0] != ':'));
} else
choice = MAX(choice - 1, 0);
} else if (key == KEY_DOWN || key == '+') {
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
(items[(scroll+choice)*2][0] != ':'));
print_item (menu, items[scroll + choice]->name, choice, FALSE,
(items[scroll + choice]->tag[0] != ':'));
if ((choice > max_choice-3) &&
(scroll + max_choice < item_no)
@@ -332,9 +331,9 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
scroll++;
print_item (menu, items[(scroll+max_choice-1)*2+1],
print_item (menu, items[scroll + max_choice - 1]->name,
max_choice-1, FALSE,
(items[(scroll+max_choice-1)*2][0] != ':'));
(items[scroll + max_choice - 1]->tag[0] != ':'));
} else
choice = MIN(choice+1, max_choice-1);
@@ -344,8 +343,8 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
if (scroll > 0) {
wscrl (menu, -1);
scroll--;
print_item (menu, items[scroll * 2 + 1], 0, FALSE,
(items[scroll*2][0] != ':'));
print_item (menu, items[scroll * 2]->name, 0, FALSE,
(items[scroll * 2]->tag[0] != ':'));
} else {
if (choice > 0)
choice--;
@@ -360,9 +359,9 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
scroll(menu);
scrollok (menu, FALSE);
scroll++;
print_item (menu, items[(scroll+max_choice-1)*2+1],
print_item (menu, items[scroll + max_choice - 1]->name,
max_choice-1, FALSE,
(items[(scroll+max_choice-1)*2][0] != ':'));
(items[scroll + max_choice - 1]->tag[0] != ':'));
} else {
if (choice+1 < max_choice)
choice++;
@@ -372,8 +371,8 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
} else
choice = i;
print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
(items[(scroll+choice)*2][0] != ':'));
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);
@@ -405,7 +404,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
fclose(f);
}
delwin (dialog);
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
items[scroll + choice]->selected = 1;
switch (key) {
case 's': return 3;
case 'y': return 3;
@@ -419,13 +418,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
button = 2;
case '\n':
delwin (dialog);
if (button == 2)
fprintf(stderr, "%s \"%s\"\n",
items[(scroll + choice) * 2],
items[(scroll + choice) * 2 + 1] +
first_alpha(items[(scroll + choice) * 2 + 1],""));
else
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
items[scroll + choice]->selected = 1;
remove("lxdialog.scrltmp");
return button;

629
scripts/config/symbol.c Normal file
View File

@@ -0,0 +1,629 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct symbol symbol_yes = {
name: "y",
curr: { "y", yes },
flags: SYMBOL_YES|SYMBOL_VALID,
}, symbol_mod = {
name: "m",
curr: { "m", mod },
flags: SYMBOL_MOD|SYMBOL_VALID,
}, symbol_no = {
name: "n",
curr: { "n", no },
flags: SYMBOL_NO|SYMBOL_VALID,
}, symbol_empty = {
name: "",
curr: { "", no },
flags: SYMBOL_VALID,
};
int sym_change_count;
struct symbol *modules_sym;
void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = create_prop(P_DEFAULT);
struct property **propp;
prop->sym = sym;
prop->def = sym_lookup(def, 1);
/* append property to the prop list of symbol */
if (prop->sym) {
for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
;
*propp = prop;
}
}
void sym_init(void)
{
struct symbol *sym;
struct utsname uts;
char *p;
static bool inited = false;
if (inited)
return;
inited = true;
uname(&uts);
#if 0
sym = sym_lookup("ARCH", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("ARCH");
if (p)
sym_add_default(sym, p);
#endif
sym = sym_lookup("VERSION", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("VERSION");
if (p)
sym_add_default(sym, p);
#if 0
sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
sym_add_default(sym, uts.release);
#endif
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);
}
int sym_get_type(struct symbol *sym)
{
int type = sym->type;
if (type == S_TRISTATE) {
if (sym_is_choice_value(sym) && sym->visible == yes)
type = S_BOOLEAN;
else {
sym_calc_value(modules_sym);
if (S_TRI(modules_sym->curr) == no)
type = S_BOOLEAN;
}
}
return type;
}
const char *sym_type_name(int type)
{
switch (type) {
case S_BOOLEAN:
return "boolean";
case S_TRISTATE:
return "tristate";
case S_INT:
return "integer";
case S_HEX:
return "hex";
case S_STRING:
return "string";
case S_UNKNOWN:
return "unknown";
}
return "???";
}
struct property *sym_get_choice_prop(struct symbol *sym)
{
struct property *prop;
for_all_choices(sym, prop)
return prop;
return NULL;
}
struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
tristate visible;
for_all_defaults(sym, prop) {
visible = E_CALC(prop->visible);
if (visible != no)
return prop;
}
return NULL;
}
void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
tristate visible, oldvisible;
/* any prompt visible? */
oldvisible = sym->visible;
visible = no;
for_all_prompts(sym, prop)
visible = E_OR(visible, E_CALC(prop->visible));
if (oldvisible != visible) {
sym->visible = visible;
sym->flags |= SYMBOL_CHANGED;
}
}
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
struct property *prop, *def_prop;
struct symbol *def_sym;
struct expr *e;
if (sym->flags & SYMBOL_VALID)
return;
oldval = sym->curr;
switch (sym->type) {
case S_INT:
case S_HEX:
case S_STRING:
newval = symbol_empty.curr;
break;
case S_BOOLEAN:
case S_TRISTATE:
newval = symbol_no.curr;
break;
default:
S_VAL(newval) = sym->name;
S_TRI(newval) = no;
if (sym->flags & SYMBOL_CONST) {
goto out;
}
//newval = symbol_empty.curr;
// generate warning somewhere here later
//S_TRI(newval) = yes;
goto out;
}
sym->flags |= SYMBOL_VALID;
if (!sym_is_choice_value(sym))
sym->flags &= ~SYMBOL_WRITE;
sym_calc_visibility(sym);
/* set default if recursively called */
sym->curr = newval;
if (sym->visible != no) {
sym->flags |= SYMBOL_WRITE;
if (!sym_has_value(sym)) {
if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym);
if (prop) {
sym_calc_value(prop->def);
newval = prop->def->curr;
}
}
} else
newval = sym->def;
S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
/* if the symbol is visible and not optionial,
* possibly ignore old user choice. */
if (!sym_is_optional(sym) && S_TRI(newval) == no)
S_TRI(newval) = sym->visible;
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no;
}
} else {
prop = sym_get_default_prop(sym);
if (prop) {
sym->flags |= SYMBOL_WRITE;
sym_calc_value(prop->def);
newval = prop->def->curr;
}
}
switch (sym_get_type(sym)) {
case S_TRISTATE:
if (S_TRI(newval) != mod)
break;
sym_calc_value(modules_sym);
if (S_TRI(modules_sym->curr) == no)
S_TRI(newval) = yes;
break;
case S_BOOLEAN:
if (S_TRI(newval) == mod)
S_TRI(newval) = yes;
}
out:
sym->curr = newval;
if (sym_is_choice(sym) && S_TRI(newval) == yes) {
def_sym = S_VAL(sym->def);
if (def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible == no)
def_sym = NULL;
}
if (!def_sym) {
for_all_defaults(sym, def_prop) {
if (E_CALC(def_prop->visible) == no)
continue;
sym_calc_visibility(def_prop->def);
if (def_prop->def->visible != no) {
def_sym = def_prop->def;
break;
}
}
}
if (!def_sym) {
prop = sym_get_choice_prop(sym);
for (e = prop->dep; e; e = e->left.expr) {
sym_calc_visibility(e->right.sym);
if (e->right.sym->visible != no) {
def_sym = e->right.sym;
break;
}
}
}
S_VAL(newval) = def_sym;
}
if (memcmp(&oldval, &newval, sizeof(newval)))
sym->flags |= SYMBOL_CHANGED;
sym->curr = newval;
if (sym_is_choice(sym)) {
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
prop = sym_get_choice_prop(sym);
for (e = prop->dep; e; e = e->left.expr)
e->right.sym->flags |= flags;
}
}
void sym_clear_all_valid(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
sym_change_count++;
}
void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym->flags |= SYMBOL_CHANGED;
}
bool sym_tristate_within_range(struct symbol *sym, tristate val)
{
int type = sym_get_type(sym);
if (sym->visible == no)
return false;
if (type != S_BOOLEAN && type != S_TRISTATE)
return false;
switch (val) {
case no:
if (sym_is_choice_value(sym) && sym->visible == yes)
return false;
return sym_is_optional(sym);
case mod:
if (sym_is_choice_value(sym) && sym->visible == yes)
return false;
return type == S_TRISTATE;
case yes:
return type == S_BOOLEAN || sym->visible == yes;
}
return false;
}
bool sym_set_tristate_value(struct symbol *sym, tristate val)
{
tristate oldval = sym_get_tristate_value(sym);
if (oldval != val && !sym_tristate_within_range(sym, val))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
sym->flags |= SYMBOL_CHANGED;
}
if (sym_is_choice_value(sym) && val == yes) {
struct property *prop = sym_get_choice_prop(sym);
S_VAL(prop->def->def) = sym;
prop->def->flags &= ~SYMBOL_NEW;
}
S_TRI(sym->def) = val;
if (oldval != val) {
sym_clear_all_valid();
if (sym == modules_sym)
sym_set_all_changed();
}
return true;
}
tristate sym_toggle_tristate_value(struct symbol *sym)
{
tristate oldval, newval;
oldval = newval = sym_get_tristate_value(sym);
do {
switch (newval) {
case no:
newval = mod;
break;
case mod:
newval = yes;
break;
case yes:
newval = no;
break;
}
if (sym_set_tristate_value(sym, newval))
break;
} while (oldval != newval);
return newval;
}
bool sym_string_valid(struct symbol *sym, const char *str)
{
char ch;
switch (sym->type) {
case S_STRING:
return true;
case S_INT:
ch = *str++;
if (ch == '-')
ch = *str++;
if (!isdigit((int)ch))
return false;
if (ch == '0' && *str != 0)
return false;
while ((ch = *str++)) {
if (!isdigit((int)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((int)ch))
return false;
} while ((ch = *str++));
return true;
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
case 'y':
case 'Y':
return sym_tristate_within_range(sym, yes);
case 'm':
case 'M':
return sym_tristate_within_range(sym, mod);
case 'n':
case 'N':
return sym_tristate_within_range(sym, no);
}
return false;
default:
return false;
}
}
bool sym_set_string_value(struct symbol *sym, const char *newval)
{
const char *oldval;
char *val;
int size;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (newval[0]) {
case 'y':
case 'Y':
return sym_set_tristate_value(sym, yes);
case 'm':
case 'M':
return sym_set_tristate_value(sym, mod);
case 'n':
case 'N':
return sym_set_tristate_value(sym, no);
}
return false;
default:
;
}
if (!sym_string_valid(sym, newval))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
sym->flags |= SYMBOL_CHANGED;
}
oldval = S_VAL(sym->def);
size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2;
S_VAL(sym->def) = val = malloc(size);
*val++ = '0';
*val++ = 'x';
} else if (!oldval || strcmp(oldval, newval))
S_VAL(sym->def) = val = malloc(size);
else
return true;
strcpy(val, newval);
free((void *)oldval);
sym_clear_all_valid();
return true;
}
const char *sym_get_string_value(struct symbol *sym)
{
tristate val;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
val = sym_get_tristate_value(sym);
switch (val) {
case no:
return "n";
case mod:
return "m";
case yes:
return "y";
}
break;
default:
;
}
return (const char *)S_VAL(sym->curr);
}
bool sym_is_changable(struct symbol *sym)
{
if (sym->visible == no)
return false;
/* at least 'n' and 'y'/'m' is selectable */
if (sym_is_optional(sym))
return true;
/* no 'n', so 'y' and 'm' must be selectable */
if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
return true;
return false;
}
struct symbol *sym_lookup(const char *name, int isconst)
{
struct symbol *symbol;
const char *ptr;
char *new_name;
int hash = 0;
//printf("lookup: %s -> ", name);
if (name) {
if (name[0] && !name[1]) {
switch (name[0]) {
case 'y': return &symbol_yes;
case 'm': return &symbol_mod;
case 'n': return &symbol_no;
}
}
for (ptr = name; *ptr; ptr++)
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name)) {
if ((isconst && symbol->flags & SYMBOL_CONST) ||
(!isconst && !(symbol->flags & SYMBOL_CONST))) {
//printf("h:%p\n", symbol);
return symbol;
}
}
}
new_name = strdup(name);
} else {
new_name = NULL;
hash = 256;
}
symbol = malloc(sizeof(*symbol));
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
symbol->flags = SYMBOL_NEW;
if (isconst)
symbol->flags |= SYMBOL_CONST;
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
//printf("n:%p\n", symbol);
return symbol;
}
struct symbol *sym_find(const char *name)
{
struct symbol *symbol = NULL;
const char *ptr;
int hash = 0;
if (!name)
return NULL;
if (name[0] && !name[1]) {
switch (name[0]) {
case 'y': return &symbol_yes;
case 'm': return &symbol_mod;
case 'n': return &symbol_no;
}
}
for (ptr = name; *ptr; ptr++)
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name) &&
!(symbol->flags & SYMBOL_CONST))
break;
}
return symbol;
}
const char *prop_get_type_name(enum prop_type type)
{
switch (type) {
case P_PROMPT:
return "prompt";
case P_COMMENT:
return "comment";
case P_MENU:
return "menu";
case P_ROOTMENU:
return "rootmenu";
case P_DEFAULT:
return "default";
case P_CHOICE:
return "choice";
default:
return "unknown";
}
}

View File

@@ -317,7 +317,7 @@ dialog_textbox (const char *title, const char *file, int height, int width)
delwin (dialog);
free (buf);
close (fd);
return -1; /* ESC pressed */
return 1; /* ESC pressed */
}
/*

View File

@@ -25,7 +25,7 @@
/* use colors by default? */
bool use_colors = 1;
const char *backtitle = NULL;
char *backtitle = NULL;
const char *dialog_result;
@@ -357,3 +357,19 @@ first_alpha(const char *string, const char *exempt)
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;
}

332
scripts/config/zconf.l Normal file
View File

@@ -0,0 +1,332 @@
%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 <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#include "zconf.tab.h"
#define START_STRSIZE 16
char *text;
static char *text_ptr;
static int text_size, text_asize;
struct buffer {
struct buffer *parent;
YY_BUFFER_STATE state;
};
struct buffer *current_buf;
static int last_ts, first_ts;
static void zconf_endhelp(void);
static struct buffer *zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
text_ptr = text;
text_size = 0;
*text_ptr = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
text = realloc(text, new_size);
text_asize = new_size;
text_ptr = text + text_size;
}
memcpy(text_ptr, str, size);
text_ptr += size;
text_size += size;
*text_ptr = 0;
}
void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
memcpy(text, str, size);
text[size] = 0;
}
%}
ws [ \n\t]
n [A-Za-z0-9_]
%%
int str = 0;
int ts, i;
[ \t]*#.*\n current_file->lineno++;
[ \t]*#.*
[ \t]*\n current_file->lineno++; return T_EOL;
[ \t]+ {
BEGIN(COMMAND);
}
. {
unput(yytext[0]);
BEGIN(COMMAND);
}
<COMMAND>{
"mainmenu" BEGIN(PARAM); return T_MAINMENU;
"menu" BEGIN(PARAM); return T_MENU;
"endmenu" BEGIN(PARAM); return T_ENDMENU;
"source" BEGIN(PARAM); return T_SOURCE;
"choice" BEGIN(PARAM); return T_CHOICE;
"endchoice" BEGIN(PARAM); return T_ENDCHOICE;
"comment" BEGIN(PARAM); return T_COMMENT;
"config" BEGIN(PARAM); return T_CONFIG;
"help" BEGIN(PARAM); return T_HELP;
"if" BEGIN(PARAM); return T_IF;
"endif" BEGIN(PARAM); return T_ENDIF;
"depends" BEGIN(PARAM); return T_DEPENDS;
"requires" BEGIN(PARAM); return T_REQUIRES;
"optional" BEGIN(PARAM); return T_OPTIONAL;
"default" BEGIN(PARAM); return T_DEFAULT;
"prompt" BEGIN(PARAM); return T_PROMPT;
"tristate" BEGIN(PARAM); return T_TRISTATE;
"bool" BEGIN(PARAM); return T_BOOLEAN;
"boolean" BEGIN(PARAM); return T_BOOLEAN;
"int" BEGIN(PARAM); return T_INT;
"hex" BEGIN(PARAM); return T_HEX;
"string" BEGIN(PARAM); return T_STRING;
{n}+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
.
\n current_file->lineno++; BEGIN(INITIAL);
}
<PARAM>{
"&&" return T_AND;
"||" return T_OR;
"(" return T_OPEN_PAREN;
")" return T_CLOSE_PAREN;
"!" return T_NOT;
"=" return T_EQUAL;
"!=" return T_UNEQUAL;
"if" return T_IF;
"on" return T_ON;
\"|\' {
str = yytext[0];
new_string();
BEGIN(STRING);
}
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
--- /* ignore */
({n}|[-/.])+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
.
<<EOF>> {
BEGIN(INITIAL);
}
}
<STRING>{
[^'"\\\n]+/\n {
append_string(yytext, yyleng);
zconflval.string = text;
return T_STRING;
}
[^'"\\\n]+ {
append_string(yytext, yyleng);
}
\\.?/\n {
append_string(yytext+1, yyleng);
zconflval.string = text;
return T_STRING;
}
\\.? {
append_string(yytext+1, yyleng);
}
\'|\" {
if (str == yytext[0]) {
BEGIN(PARAM);
zconflval.string = text;
return T_STRING;
} else
append_string(yytext, 1);
}
\n {
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
BEGIN(INITIAL);
return T_EOL;
}
<<EOF>> {
BEGIN(INITIAL);
}
}
<HELP>{
[ \t]+ {
ts = 0;
for (i = 0; i < yyleng; i++) {
if (yytext[i] == '\t')
ts = (ts & ~7) + 8;
else
ts++;
}
last_ts = ts;
if (first_ts) {
if (ts < first_ts) {
zconf_endhelp();
return T_HELPTEXT;
}
ts -= first_ts;
while (ts > 8) {
append_string(" ", 8);
ts -= 8;
}
append_string(" ", ts);
}
}
\n/[^ \t\n] {
current_file->lineno++;
zconf_endhelp();
return T_HELPTEXT;
}
[ \t]*\n {
current_file->lineno++;
append_string("\n", 1);
}
[^ \t\n].* {
append_string(yytext, yyleng);
if (!first_ts)
first_ts = last_ts;
}
<<EOF>> {
zconf_endhelp();
return T_HELPTEXT;
}
}
<<EOF>> {
if (current_buf) {
zconf_endfile();
return T_EOF;
}
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);
}
void zconf_initscan(const char *name)
{
yyin = fopen(name, "r");
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 = fopen(name, "r");
if (!yyin) {
printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
exit(1);
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf;
current_buf = buf;
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;
else
return 0;
}
char *zconf_curname(void)
{
if (current_buf)
return current_file->name;
else
return "<none>";
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

651
scripts/config/zconf.y Normal file
View File

@@ -0,0 +1,651 @@
%{
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
#define DEBUG_PARSE 0x0002
int cdebug = PRINTD;
extern int zconflex(void);
static void zconfprint(const char *err, ...);
static void zconferror(const char *err);
static bool zconf_endtoken(int token, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
#define YYERROR_VERBOSE
%}
%expect 36
%union
{
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
}
%token T_MAINMENU
%token T_MENU
%token T_ENDMENU
%token T_SOURCE
%token T_CHOICE
%token T_ENDCHOICE
%token T_COMMENT
%token T_CONFIG
%token T_HELP
%token <string> T_HELPTEXT
%token T_IF
%token T_ENDIF
%token T_DEPENDS
%token T_REQUIRES
%token T_OPTIONAL
%token T_PROMPT
%token T_DEFAULT
%token T_TRISTATE
%token T_BOOLEAN
%token T_INT
%token T_HEX
%token <string> T_WORD
%token <string> T_STRING
%token T_UNEQUAL
%token T_EOF
%token T_EOL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_ON
%left T_OR
%left T_AND
%left T_EQUAL T_UNEQUAL
%nonassoc T_NOT
%type <string> prompt
%type <string> source
%type <symbol> symbol
%type <expr> expr
%type <expr> if_expr
%type <token> end
%{
#define LKC_DIRECT_LINK
#include "lkc.h"
%}
%%
input: /* empty */
| input block
;
block: common_block
| choice_stmt
| menu_stmt
| T_MAINMENU prompt nl_or_eof
| T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
| T_ENDIF { zconfprint("unexpected 'endif' statement"); }
| T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
| error nl_or_eof { zconfprint("syntax error"); yyerrok; }
;
common_block:
if_stmt
| comment_stmt
| config_stmt
| source_stmt
| nl_or_eof
;
/* config entry */
config_entry_start: T_CONFIG T_WORD
{
struct symbol *sym = sym_lookup($2, 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
};
config_stmt: config_entry_start T_EOL config_option_list
{
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
};
config_option_list:
/* empty */
| config_option_list config_option T_EOL
| config_option_list depends T_EOL
| config_option_list help
| config_option_list T_EOL
{ };
config_option: T_TRISTATE prompt_stmt_opt
{
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
};
config_option: T_BOOLEAN prompt_stmt_opt
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_INT prompt_stmt_opt
{
menu_set_type(S_INT);
printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
};
config_option: T_HEX prompt_stmt_opt
{
menu_set_type(S_HEX);
printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
};
config_option: T_STRING prompt_stmt_opt
{
menu_set_type(S_STRING);
printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
};
config_option: T_PROMPT prompt if_expr
{
menu_add_prop(P_PROMPT, $2, NULL, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
config_option: T_DEFAULT symbol if_expr
{
menu_add_prop(P_DEFAULT, NULL, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
/* choice entry */
choice: T_CHOICE
{
struct symbol *sym = sym_lookup(NULL, 0);
sym->flags |= SYMBOL_CHOICE;
menu_add_entry(sym);
menu_add_prop(P_CHOICE, NULL, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
};
choice_entry: choice T_EOL choice_option_list
{
menu_end_entry();
menu_add_menu();
};
choice_end: end
{
if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
};
choice_stmt:
choice_entry choice_block choice_end T_EOL
| choice_entry choice_block
{
printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
choice_option_list:
/* empty */
| choice_option_list choice_option T_EOL
| choice_option_list depends T_EOL
| choice_option_list help
| choice_option_list T_EOL
;
choice_option: T_PROMPT prompt if_expr
{
menu_add_prop(P_PROMPT, $2, NULL, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
choice_option: T_OPTIONAL
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
};
choice_option: T_DEFAULT symbol
{
menu_add_prop(P_DEFAULT, NULL, $2, NULL);
//current_choice->prop->def = $2;
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
choice_block:
/* empty */
| choice_block common_block
;
/* if entry */
if: T_IF expr
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
//current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
menu_add_dep($2);
menu_end_entry();
menu_add_menu();
};
if_end: end
{
if (zconf_endtoken($1, T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
};
if_stmt:
if T_EOL if_block if_end T_EOL
| if T_EOL if_block
{
printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
if_block:
/* empty */
| if_block common_block
| if_block menu_stmt
| if_block choice_stmt
;
/* menu entry */
menu: T_MENU prompt
{
menu_add_entry(NULL);
menu_add_prop(P_MENU, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
};
menu_entry: menu T_EOL depends_list
{
menu_end_entry();
menu_add_menu();
};
menu_end: end
{
if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
};
menu_stmt:
menu_entry menu_block menu_end T_EOL
| menu_entry menu_block
{
printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
menu_block:
/* empty */
| menu_block common_block
| menu_block menu_stmt
| menu_block choice_stmt
| menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
;
source: T_SOURCE prompt
{
$$ = $2;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
};
source_stmt: source T_EOL
{
zconf_nextfile($1);
};
/* comment entry */
comment: T_COMMENT prompt
{
menu_add_entry(NULL);
menu_add_prop(P_COMMENT, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
};
comment_stmt: comment T_EOL depends_list
{
menu_end_entry();
};
/* help option */
help_start: T_HELP T_EOL
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
zconf_starthelp();
};
help: help_start T_HELPTEXT
{
current_entry->sym->help = $2;
};
/* depends option */
depends_list: /* empty */
| depends_list depends T_EOL
| depends_list T_EOL
{ };
depends: T_DEPENDS T_ON expr
{
menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
}
| T_DEPENDS expr
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
}
| T_REQUIRES expr
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
};
/* prompt statement */
prompt_stmt_opt:
/* empty */
| prompt
{
menu_add_prop(P_PROMPT, $1, NULL, NULL);
}
| prompt T_IF expr
{
menu_add_prop(P_PROMPT, $1, NULL, $3);
};
prompt: T_WORD
| T_STRING
;
end: T_ENDMENU { $$ = T_ENDMENU; }
| T_ENDCHOICE { $$ = T_ENDCHOICE; }
| T_ENDIF { $$ = T_ENDIF; }
;
nl_or_eof:
T_EOL | T_EOF;
if_expr: /* empty */ { $$ = NULL; }
| T_IF expr { $$ = $2; }
;
expr: symbol { $$ = expr_alloc_symbol($1); }
| symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
| T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
| expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
;
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
| T_STRING { $$ = sym_lookup($1, 1); free($1); }
;
%%
void conf_parse(const char *name)
{
zconf_initscan(name);
sym_init();
menu_init();
rootmenu.prompt = menu_add_prop(P_MENU, "BusyBox Configuration", NULL, NULL);
//zconfdebug = 1;
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
modules_sym = sym_lookup("MODULES", 0);
sym_change_count = 1;
}
const char *zconf_tokenname(int token)
{
switch (token) {
case T_MENU: return "menu";
case T_ENDMENU: return "endmenu";
case T_CHOICE: return "choice";
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
}
return "<token>";
}
static bool zconf_endtoken(int token, int starttoken, int endtoken)
{
if (token != endtoken) {
zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfprint("location of the '%s'", zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
return true;
}
static void zconfprint(const char *err, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
fprintf(stderr, "\n");
}
static void zconferror(const char *err)
{
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
}
void print_quoted_string(FILE *out, const char *str)
{
const char *p;
int len;
putc('"', out);
while ((p = strchr(str, '"'))) {
len = p - str;
if (len)
fprintf(out, "%.*s", len, str);
fputs("\\\"", out);
str = p + 1;
}
fputs(str, out);
putc('"', out);
}
void print_symbol(FILE *out, struct menu *menu)
{
struct symbol *sym = menu->sym;
struct property *prop;
//sym->flags |= SYMBOL_PRINTED;
if (sym_is_choice(sym))
fprintf(out, "choice\n");
else
fprintf(out, "config %s\n", sym->name);
switch (sym->type) {
case S_BOOLEAN:
fputs(" boolean\n", out);
break;
case S_TRISTATE:
fputs(" tristate\n", out);
break;
case S_STRING:
fputs(" string\n", out);
break;
case S_INT:
fputs(" integer\n", out);
break;
case S_HEX:
fputs(" hex\n", out);
break;
default:
fputs(" ???\n", out);
break;
}
#if 0
if (!expr_is_yes(sym->dep)) {
fputs(" depends ", out);
expr_fprint(sym->dep, out);
fputc('\n', out);
}
#endif
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
switch (prop->type) {
case P_PROMPT:
fputs(" prompt ", out);
print_quoted_string(out, prop->text);
if (prop->def) {
fputc(' ', out);
if (prop->def->flags & SYMBOL_CONST)
print_quoted_string(out, prop->def->name);
else
fputs(prop->def->name, out);
}
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" if ", out);
expr_fprint(E_EXPR(prop->visible), out);
}
fputc('\n', out);
break;
case P_DEFAULT:
fputs( " default ", out);
print_quoted_string(out, prop->def->name);
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" if ", out);
expr_fprint(E_EXPR(prop->visible), out);
}
fputc('\n', out);
break;
case P_CHOICE:
fputs(" #choice value\n", out);
break;
default:
fprintf(out, " unknown prop %d!\n", prop->type);
break;
}
}
if (sym->help) {
int len = strlen(sym->help);
while (sym->help[--len] == '\n')
sym->help[len] = 0;
fprintf(out, " help\n%s\n", sym->help);
}
fputc('\n', out);
}
void zconfdump(FILE *out)
{
//struct file *file;
struct property *prop;
struct symbol *sym;
struct menu *menu;
menu = rootmenu.list;
while (menu) {
if ((sym = menu->sym))
print_symbol(out, menu);
else if ((prop = menu->prompt)) {
switch (prop->type) {
//case T_MAINMENU:
// fputs("\nmainmenu ", out);
// print_quoted_string(out, prop->text);
// fputs("\n", out);
// break;
case P_COMMENT:
fputs("\ncomment ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
case P_MENU:
fputs("\nmenu ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
//case T_SOURCE:
// fputs("\nsource ", out);
// print_quoted_string(out, prop->text);
// fputs("\n", out);
// break;
//case T_IF:
// fputs("\nif\n", out);
default:
;
}
if (!expr_is_yes(E_EXPR(prop->visible))) {
fputs(" depends ", out);
expr_fprint(E_EXPR(prop->visible), out);
fputc('\n', out);
}
fputs("\n", out);
}
if (menu->list)
menu = menu->list;
else if (menu->next)
menu = menu->next;
else while ((menu = menu->parent)) {
if (menu->prompt && menu->prompt->type == P_MENU)
fputs("\nendmenu\n", out);
if (menu->next) {
menu = menu->next;
break;
}
}
}
}
#include "lex.zconf.c"
#include "confdata.c"
#include "expr.c"
#include "symbol.c"
#include "menu.c"

View File

@@ -1 +0,0 @@
lxdialog

View File

@@ -1,4 +0,0 @@
This is NOT the official version of dialog. This version has been
significantly modified from the original. It is for use by the Linux
kernel configuration script. Please do not bother Savio Lam with
questions about this program.

View File

@@ -1,48 +0,0 @@
HOSTCFLAGS += -DLOCALE
LIBS = -lncurses
ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
else
ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
else
ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
HOSTCFLAGS += -DCURSES_LOC="<ncurses.h>"
else
HOSTCFLAGS += -DCURSES_LOC="<curses.h>"
endif
endif
endif
OBJS = checklist.o menubox.o textbox.o yesno.o inputbox.o \
util.o lxdialog.o msgbox.o
%.o: %.c
$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<
all: ncurses lxdialog
lxdialog: $(OBJS)
$(HOSTCC) -o lxdialog $(OBJS) $(LIBS)
.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 core *.o *~ lxdialog

View File

@@ -1,71 +0,0 @@
lxdialog-hostcflags += -DLOCALE
lxdialog-libs = -lncurses
ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
lxdialog-hostcflags += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
else
ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
lxdialog-hostcflags += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
else
ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
lxdialog-hostcflags += -DCURSES_LOC="<ncurses.h>"
else
lxdialog-hostcflags += -DCURSES_LOC="<curses.h>"
endif
endif
endif
$(tmp_config)lxdialog-ncurses:
@mkdir -p $(lxdialog-objtree)
@( \
cd $(lxdialog-objtree) && \
echo "main() {}" > lxtemp.c && \
if $(HOSTCC) -lncurses lxtemp.c ; then \
rm -f lxtemp.c a.out && \
mkdir -p $(@D) && \
touch $@; \
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 ; \
)
lxdialog-objs := $(lxdialog-objtree)checklist.o $(lxdialog-objtree)menubox.o \
$(lxdialog-objtree)textbox.o $(lxdialog-objtree)yesno.o \
$(lxdialog-objtree)inputbox.o $(lxdialog-objtree)util.o \
$(lxdialog-objtree)lxdialog.o $(lxdialog-objtree)msgbox.o
$(lxdialog-objtree)checklist.o: $(lxdialog-srctree)checklist.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)menubox.o: $(lxdialog-srctree)menubox.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)textbox.o: $(lxdialog-srctree)textbox.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)yesno.o: $(lxdialog-srctree)yesno.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)inputbox.o: $(lxdialog-srctree)inputbox.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)util.o: $(lxdialog-srctree)util.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)lxdialog.o: $(lxdialog-srctree)lxdialog.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)msgbox.o: $(lxdialog-srctree)msgbox.c $(tmp_config)lxdialog-ncurses
$(HOSTCC) $(HOSTCFLAGS) $(lxdialog-hostcflags) -c -o $@ $<
$(lxdialog-objtree)lxdialog: $(lxdialog-objs)
$(HOSTCC) -o $@ $(lxdialog-objs) $(lxdialog-libs)
MRPROPER += $(lxdialog-objtree)lxdialog

View File

@@ -1,226 +0,0 @@
/*
* dialog - Display simple dialog boxes from shell scripts
*
* 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 Usage (const char *name);
typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
struct Mode {
char *name;
int argmin, argmax, argmod;
jumperFn *jumper;
};
jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
jumperFn j_msgbox, j_infobox;
static struct Mode modes[] =
{
{"--menu", 9, 0, 3, j_menu},
{"--checklist", 9, 0, 3, j_checklist},
{"--radiolist", 9, 0, 3, j_radiolist},
{"--yesno", 5,5,1, j_yesno},
{"--textbox", 5,5,1, j_textbox},
{"--inputbox", 5, 6, 1, j_inputbox},
{"--msgbox", 5, 5, 1, j_msgbox},
{"--infobox", 5, 5, 1, j_infobox},
{NULL, 0, 0, 0, NULL}
};
static struct Mode *modePtr;
#ifdef LOCALE
#include <locale.h>
#endif
int
main (int argc, const char * const * argv)
{
int offset = 0, clear_screen = 0, end_common_opts = 0, retval;
const char *title = NULL;
#ifdef LOCALE
(void) setlocale (LC_ALL, "");
#endif
#ifdef TRACE
trace(TRACE_CALLS|TRACE_UPDATE);
#endif
if (argc < 2) {
Usage (argv[0]);
exit (-1);
}
while (offset < argc - 1 && !end_common_opts) { /* Common options */
if (!strcmp (argv[offset + 1], "--title")) {
if (argc - offset < 3 || title != NULL) {
Usage (argv[0]);
exit (-1);
} else {
title = argv[offset + 2];
offset += 2;
}
} else if (!strcmp (argv[offset + 1], "--backtitle")) {
if (backtitle != NULL) {
Usage (argv[0]);
exit (-1);
} else {
backtitle = argv[offset + 2];
offset += 2;
}
} else if (!strcmp (argv[offset + 1], "--clear")) {
if (clear_screen) { /* Hey, "--clear" can't appear twice! */
Usage (argv[0]);
exit (-1);
} else if (argc == 2) { /* we only want to clear the screen */
init_dialog ();
refresh (); /* init_dialog() will clear the screen for us */
end_dialog ();
return 0;
} else {
clear_screen = 1;
offset++;
}
} else /* no more common options */
end_common_opts = 1;
}
if (argc - 1 == offset) { /* no more options */
Usage (argv[0]);
exit (-1);
}
/* use a table to look for the requested mode, to avoid code duplication */
for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
if (!strcmp (argv[offset + 1], modePtr->name))
break;
if (!modePtr->name)
Usage (argv[0]);
if (argc - offset < modePtr->argmin)
Usage (argv[0]);
if (modePtr->argmax && argc - offset > modePtr->argmax)
Usage (argv[0]);
init_dialog ();
retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
if (clear_screen) { /* clear screen before exit */
attr_clear (stdscr, LINES, COLS, screen_attr);
refresh ();
}
end_dialog();
exit (retval);
}
/*
* Print program usage
*/
static void
Usage (const char *name)
{
fprintf (stderr, "\
\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
\n modified/gutted for use as a Linux kernel config tool by \
\n William Roadcap (roadcapw@cfw.com)\
\n\
\n* Display dialog boxes from shell scripts *\
\n\
\nUsage: %s --clear\
\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
\n\
\nBox options:\
\n\
\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
\n --textbox <file> <height> <width>\
\n --inputbox <text> <height> <width> [<init>]\
\n --yesno <text> <height> <width>\
\n", name, name);
exit (-1);
}
/*
* These are the program jumpers
*/
int
j_menu (const char *t, int ac, const char * const * av)
{
return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
}
int
j_checklist (const char *t, int ac, const char * const * av)
{
return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
}
int
j_radiolist (const char *t, int ac, const char * const * av)
{
return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
}
int
j_textbox (const char *t, int ac, const char * const * av)
{
return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
}
int
j_yesno (const char *t, int ac, const char * const * av)
{
return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
}
int
j_inputbox (const char *t, int ac, const char * const * av)
{
int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
ac == 6 ? av[5] : (char *) NULL);
if (ret == 0)
fprintf(stderr, dialog_input_result);
return ret;
}
int
j_msgbox (const char *t, int ac, const char * const * av)
{
return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
}
int
j_infobox (const char *t, int ac, const char * const * av)
{
return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
}