diff options
author | Oliver Schinagl <oliver@schinagl.nl> | 2011-04-27 13:13:05 (GMT) |
---|---|---|
committer | Oliver Schinagl <oliver@schinagl.nl> | 2011-04-27 13:13:05 (GMT) |
commit | cb589e64ddfbc502e8b1189ec7253c43b42cd183 (patch) | |
tree | a45aa4df23db84c279f39bd2c894ecf6bada0289 /uClinux-2.4.31-uc0/scripts | |
parent | d53ae4b2067e5e7c4f5a0b9a234a89e0582c2e84 (diff) | |
download | openipcam-cb589e64ddfbc502e8b1189ec7253c43b42cd183.zip openipcam-cb589e64ddfbc502e8b1189ec7253c43b42cd183.tar.gz openipcam-cb589e64ddfbc502e8b1189ec7253c43b42cd183.tar.bz2 |
linux-2.4.31 with uCLinux uc0 pre-patched
Diffstat (limited to 'uClinux-2.4.31-uc0/scripts')
44 files changed, 12443 insertions, 0 deletions
diff --git a/uClinux-2.4.31-uc0/scripts/Configure b/uClinux-2.4.31-uc0/scripts/Configure new file mode 100644 index 0000000..1a3af43 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/Configure @@ -0,0 +1,578 @@ +#! /bin/sh +# +# This script is used to configure the Linux kernel. +# +# 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). + +# +# 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 () { + : +} + +# +# help prints the corresponding help text from Configure.help to stdout +# +# help variable +# +function help () { + if [ -f Documentation/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 + }" Documentation/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 Documentation/Configure.help which" + echo " should contain the help texts." + echo + fi +} + + +# +# readln reads a line into $ans. +# +# readln prompt default oldval +# +function readln () { + if [ "$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'} + 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'} + 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 + 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 +# +function int () { + old=$(eval echo "\${$2}") + def=${old:-$3} + while :; do + readln "$1 ($2) [$def] " "$def" "$old" + if expr "$ans" : '[0-9]*$' > /dev/null; 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} + while :; do + readln "$1 ($2) [$def] " "$def" "$old" + if expr "$ans" : '0x[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then + define_hex "$2" "$ans" + break + else + if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then + define_hex "$2" "0x$ans" + break + else + help "$2" + fi + 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 + + 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 +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 + +CONFIG_IN=./config.in +if [ "$1" != "" ] ; then + CONFIG_IN=$1 +fi + +DEFAULTS=arch/$ARCH/defconfig +if [ -f .config ]; then + DEFAULTS=.config +fi + +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 + +. $CONFIG_IN + +rm -f .config.old +if [ -f .config ]; then + mv .config .config.old +fi +mv .tmpconfig .config +mv .tmpconfig.h include/linux/autoconf.h + +echo +echo "*** End of Linux kernel 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 bzImage', 'make bzdisk', or 'make install'." +fi +echo + +exit 0 diff --git a/uClinux-2.4.31-uc0/scripts/Lindent b/uClinux-2.4.31-uc0/scripts/Lindent new file mode 100644 index 0000000..0bababd --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/Lindent @@ -0,0 +1,2 @@ +#!/bin/sh +indent -kr -i8 -ts8 -sob -l80 -ss -bs -psl "$@" diff --git a/uClinux-2.4.31-uc0/scripts/MAKEDEV.ide b/uClinux-2.4.31-uc0/scripts/MAKEDEV.ide new file mode 100644 index 0000000..feecb99 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/MAKEDEV.ide @@ -0,0 +1,49 @@ +#!/bin/sh +# +# This script creates the proper /dev/ entries for IDE devices +# on the primary, secondary, tertiary, and quaternary interfaces. +# See ../Documentation/ide.txt for more information. +# +makedev () { + rm -f /dev/$1 + echo mknod /dev/$1 $2 $3 $4 + mknod /dev/$1 $2 $3 $4 + chown root:disk /dev/$1 + chmod 660 /dev/$1 +} + +makedevs () { + rm -f /dev/$1* + makedev $1 b $2 $3 + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + do + makedev $1$part b $2 `expr $3 + $part` + done +} + +makedevs hda 3 0 +makedevs hdb 3 64 +makedevs hdc 22 0 +makedevs hdd 22 64 +makedevs hde 33 0 +makedevs hdf 33 64 +makedevs hdg 34 0 +makedevs hdh 34 64 +makedevs hdi 56 0 +makedevs hdj 56 64 +makedevs hdk 57 0 +makedevs hdl 57 64 +makedevs hdm 88 0 +makedevs hdn 88 64 +makedevs hdo 89 0 +makedevs hdp 89 64 +makedevs hdq 90 0 +makedevs hdr 90 64 +makedevs hds 91 0 +makedevs hdt 91 64 + +for tape in 0 1 2 3 4 5 6 7 +do + makedev ht$tape c 37 $tape + makedev nht$tape c 37 `expr $tape + 128` +done diff --git a/uClinux-2.4.31-uc0/scripts/Makefile b/uClinux-2.4.31-uc0/scripts/Makefile new file mode 100644 index 0000000..d6d231d --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/Makefile @@ -0,0 +1,45 @@ +HEADER=header.tk +TAIL=tail.tk + +# Previous versions always remade kconfig.tk because they always depended +# on soundscript. This runs fairly fast, and I can't find all the +# Config.in files to depend on anyways. So I'll force it to remake. + +kconfig.tk: dummy + +kconfig.tk: ${TOPDIR}/Makefile ${TOPDIR}/arch/${ARCH}/config.in \ + tkparse ${HEADER} ${TAIL} + @if [ -f /usr/local/bin/wish ]; then \ + echo '#!'"/usr/local/bin/wish -f" > kconfig.tk; \ + else \ + echo '#!'"/usr/bin/wish -f" > kconfig.tk; \ + fi + cat ${HEADER} >> ./kconfig.tk + ./tkparse < ../arch/${ARCH}/config.in >> kconfig.tk + echo "set defaults \"arch/${ARCH}/defconfig\"" >> kconfig.tk + echo "set ARCH \"${ARCH}\"" >> kconfig.tk + cat ${TAIL} >> kconfig.tk + chmod 755 kconfig.tk + +tkparse: tkparse.o tkcond.o tkgen.o + ${HOSTCC} -o tkparse tkparse.o tkcond.o tkgen.o + +tkparse.o: tkparse.c tkparse.h + +tkcond.o: tkcond.c tkparse.h + +tkgen.o: tkgen.c tkparse.h + +tkparse.o tkcond.o tkgen.o: + $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $(@:.o=.c) + +docproc.o: docproc.c + $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $(@:.o=.c) + +docproc: docproc.o + ${HOSTCC} -o docproc docproc.o + +clean: + rm -f *~ kconfig.tk *.o tkparse mkdep split-include docproc + +include $(TOPDIR)/Rules.make diff --git a/uClinux-2.4.31-uc0/scripts/Menuconfig b/uClinux-2.4.31-uc0/scripts/Menuconfig new file mode 100644 index 0000000..64eb94d --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/Menuconfig @@ -0,0 +1,1474 @@ +#! /bin/sh +# +# This script is used to configure the linux kernel. +# +# It was inspired by a desire to not have to hit <enter> 9 million times +# or startup the X server just to change a single kernel parameter. +# +# This script attempts to parse the configuration files, which are +# scattered throughout the kernel source tree, and creates a temporary +# set of mini scripts which are in turn used to create nested menus and +# radiolists. +# +# It uses a very modified/mutilated version of the "dialog" utility +# written by Savio Lam (lam836@cs.cuhk.hk). Savio is not responsible +# for this script or the version of dialog used by this script. +# Please do not contact him with questions. The official version of +# dialog is available at sunsite.unc.edu or a sunsite mirror. +# +# Portions of this script were borrowed from the original Configure +# script. +# +# William Roadcap was the original author of Menuconfig. +# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. +# +# 070497 Bernhard Kaindl (bkaindl@netway.at) - get default values for +# new bool, tristate and dep_tristate parameters from the defconfig file. +# new configuration parameters are marked with '(NEW)' as in make config. +# +# 180697 Bernhard Kaindl (bkaindl@netway.at) - added the needed support +# for string options. They are handled like the int and hex options. +# +# 081297 Pavel Machek (pavel@atrey.karlin.mff.cuni.cz) - better error +# handling +# +# 131197 Michael Chastain (mec@shout.net) - output all lines for a +# choice list, not just the selected one. This makes the output +# the same as Configure output, which is important for smart config +# dependencies. +# +# 101297 Michael Chastain (mec@shout.net) - remove sound driver cruft. +# +# 221297 Michael Chastain (mec@shout.net) - make define_bool actually +# define its arguments so that later tests on them work right. +# +# 160198 Michael Chastain (mec@shout.net) - fix bug with 'c' command +# (complement existing value) when used on virgin uninitialized variables. +# +# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help +# texts. +# +# 12 Dec 1998, Michael Elizabeth Chastain (mec@shout.net) +# Remove a /tmp security hole in get_def (also makes it faster). +# Give uninitialized variables canonical values rather than null value. +# Change a lot of places to call set_x_info uniformly. +# Take out message about preparing version (old sound driver cruft). +# +# 13 Dec 1998, Riley H Williams <Riley@Williams.Name> +# When an error occurs, actually display the error message as well as +# our comments thereon. +# +# 31 Dec 1998, Michael Elizabeth Chastain (mec@shout.net) +# Fix mod_bool to honor $CONFIG_MODULES. +# Fix dep_tristate to call define_bool when dependency is "n". +# +# 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) +# Blow away lxdialog.scrltmp on entry to activate_menu. This protects +# against people who use commands like ' ' to select menus. +# +# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net> +# - Improve the exit message (Jeff Ronne). +# +# 06 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl> +# - Support for multiple conditions in dep_tristate(). +# - Implemented new functions: define_tristate(), define_int(), define_hex(), +# define_string(), dep_bool(). +# +# 12 November 2001, Keith Owens <kaos@ocs.com.au> +# Escape double quotes on eval so the quotes are still there on the second +# evaluation, required to handle strings with special characters. +# + + +# +# Change this to TRUE if you prefer all kernel options listed +# in a single menu rather than the standard menu hierarchy. +# +single_menu_mode= + +# +# Make sure we're really running bash. +# +[ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; } + +# +# Cache function definitions, turn off posix compliance +# +set -h +o posix + + + +# Given a configuration variable, set the global variable $x to its value, +# and the global variable $info to the string " (NEW)" if this is a new +# variable. +# +# This function looks for: (1) the current value, or (2) the default value +# from the arch-dependent defconfig file, or (3) a default passed by the caller. + +function set_x_info () { + eval x=\$$1 + if [ -z "$x" ]; then + eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" arch/$ARCH/defconfig` + eval x=\${$1:-\"$2\"} + eval $1=$x + eval INFO_$1="' (NEW)'" + fi + eval info=\"\$INFO_$1\" +} + +# +# Load the functions used by the config.in files. +# +# I do this because these functions must be redefined depending +# on whether they are being called for interactive use or for +# saving a configuration to a file. +# +# Thank the heavens bash supports nesting function definitions. +# +load_functions () { + +# +# Additional comments +# +function comment () { + comment_ctr=$[ comment_ctr + 1 ] + echo -ne "': $comment_ctr' '--- $1' " >>MCmenu +} + +# +# Define a boolean to a specific value. +# +function define_bool () { + eval $1=$2 +} + +function define_tristate () { + eval $1=$2 +} + +function define_hex () { + eval $1=$2 +} + +function define_int () { + eval $1=$2 +} + +function define_string () { + eval $1=\"$2\" +} + +# +# Create a boolean (Yes/No) function for our current menu +# which calls our local bool function. +# +function bool () { + set_x_info "$2" "n" + + case $x in + y|m) flag="*" ;; + n) flag=" " ;; + esac + + echo -ne "'$2' '[$flag] $1$info' " >>MCmenu + + echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists +} + +# +# Create a tristate (Yes/No/Module) radiolist function +# which calls our local tristate function. +# +# Collapses to a boolean (Yes/No) if module support is disabled. +# +function tristate () { + if [ "$CONFIG_MODULES" != "y" ] + then + bool "$1" "$2" + else + set_x_info "$2" "n" + + case $x in + y) flag="*" ;; + m) flag="M" ;; + *) flag=" " ;; + esac + + echo -ne "'$2' '<$flag> $1$info' " >>MCmenu + + echo -e " + function $2 () { l_tristate '$2' \"\$1\" ;}" >>MCradiolists + fi +} + +# +# Create a tristate radiolist function which is dependent on +# another kernel configuration option. +# +# Quote from the original configure script: +# +# If the option we depend upon is a module, +# then the only allowable options are M or N. If 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. +# +function dep_tristate () { + ques="$1" + var="$2" + dep=y + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + elif [ "$1" = m ]; then + dep=m + shift + else + dep=n + shift $# + fi + done + if [ "$dep" = y ]; then + tristate "$ques" "$var" + elif [ "$dep" = m ]; then + mod_bool "$ques" "$var" + else + define_tristate "$var" n + fi +} + +# +# Same as above, but now only Y and N are allowed as dependency +# (i.e. third and next arguments). +# +function dep_bool () { + ques="$1" + var="$2" + dep=y + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + else + dep=n + shift $# + fi + done + if [ "$dep" = y ]; then + bool "$ques" "$var" + else + define_bool "$var" n + fi +} + +function dep_mbool () { + ques="$1" + var="$2" + dep=y + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y -o "$1" = m ]; then + shift + else + dep=n + shift $# + fi + done + if [ "$dep" = y ]; then + bool "$ques" "$var" + else + define_bool "$var" n + fi +} + +# +# Add a menu item which will call our local int function. +# +function int () { + set_x_info "$2" "$3" + + echo -ne "'$2' '($x) $1$info' " >>MCmenu + + echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists +} + +# +# Add a menu item which will call our local hex function. +# +function hex () { + set_x_info "$2" "$3" + x=${x##*[x,X]} + + echo -ne "'$2' '($x) $1$info' " >>MCmenu + + echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists +} + +# +# Add a menu item which will call our local string function. +# +function string () { + set_x_info "$2" "$3" + + echo -ne "'$2' ' $1: \"$x\"$info' " >>MCmenu + + echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists +} + +# +# Add a menu item which will call our local One-of-Many choice list. +# +function choice () { + # + # Need to remember params cause they're gonna get reset. + # + title=$1 + choices=$2 + default=$3 + current= + + # + # Find out if one of the choices is already set. + # If it's not then make it the default. + # + set -- $choices + firstchoice=$2 + + while [ -n "$2" ] + do + if eval [ \"_\$$2\" = \"_y\" ] + then + current=$1 + break + fi + shift ; shift + done + + : ${current:=$default} + + echo -ne "'$firstchoice' '($current) $title' " >>MCmenu + + echo -e " + function $firstchoice () \ + { l_choice '$title' \"$choices\" \"$current\" ;}" >>MCradiolists +} + +} # END load_functions() + + + + + +# +# Extract available help for an option from Configure.help +# and send it to standard output. +# +# Most of this function was borrowed from the original kernel +# Configure script. +# +function extract_help () { + if [ -f Documentation/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 + s/^ // + /<file:\\([^>]*\\)>/s//\\1/g + p + }" Documentation/Configure.help) + + if [ -z "$text" ] + then + echo "There is no help available for this kernel option." + return 1 + else + echo "$text" + fi + else + echo "There is no help available for this kernel option." + return 1 + fi +} + +# +# Activate a help dialog. +# +function help () { + if extract_help $1 >help.out + then + $DIALOG --backtitle "$backtitle" --title "$2"\ + --textbox help.out $ROWS $COLS + else + $DIALOG --backtitle "$backtitle" \ + --textbox help.out $ROWS $COLS + fi + rm -f help.out +} + +# +# Show the README file. +# +function show_readme () { + $DIALOG --backtitle "$backtitle" \ + --textbox scripts/README.Menuconfig $ROWS $COLS +} + +# +# Begin building the dialog menu command and Initialize the +# Radiolist function file. +# +function menu_name () { + echo -ne "$DIALOG --title '$1'\ + --backtitle '$backtitle' \ + --menu '$menu_instructions' \ + $ROWS $COLS $((ROWS-10)) \ + '$default' " >MCmenu + >MCradiolists +} + +# +# Add a submenu option to the menu currently under construction. +# +function submenu () { + echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu +} + +# +# Handle a boolean (Yes/No) option. +# +function l_bool () { + if [ -n "$2" ] + then + case "$2" in + y|m) eval $1=y ;; + c) eval x=\$$1 + case $x in + y) eval $1=n ;; + n) eval $1=y ;; + *) eval $1=y ;; + esac ;; + *) eval $1=n ;; + esac + else + echo -ne "\007" + fi +} + +# +# Same as bool() except options are (Module/No) +# +function mod_bool () { + if [ "$CONFIG_MODULES" != "y" ]; then + define_bool "$2" "n" + else + set_x_info "$2" "n" + + case $x in + y|m) flag='M' ;; + *) flag=' ' ;; + esac + + echo -ne "'$2' '<$flag> $1$info' " >>MCmenu + + echo -e "function $2 () { l_mod_bool '$2' \"\$1\" ;}" >>MCradiolists + fi +} + +# +# Same as l_bool() except options are (Module/No) +# +function l_mod_bool() { + if [ -n "$2" ] + then + case "$2" in + y) echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --infobox "\ +This feature depends on another which has been configured as a module. \ +As a result, this feature will be built as a module." 4 70 + sleep 5 + eval $1=m ;; + m) eval $1=m ;; + c) eval x=\$$1 + case $x in + m) eval $1=n ;; + n) eval $1=m ;; + *) eval $1=m ;; + esac ;; + *) eval $1=n ;; + esac + else + echo -ne "\007" + fi +} + +# +# Handle a tristate (Yes/No/Module) option. +# +function l_tristate () { + if [ -n "$2" ] + then + eval x=\$$1 + + case "$2" in + y) eval $1=y ;; + m) eval $1=m ;; + c) eval x=\$$1 + case $x in + y) eval $1=n ;; + n) eval $1=m ;; + m) eval $1=y ;; + *) eval $1=y ;; + esac ;; + *) eval $1=n ;; + esac + else + echo -ne "\007" + fi +} + +# +# Create a dialog for entering an integer into a kernel option. +# +function l_int () { + while true + do + if $DIALOG --title "$1" \ + --backtitle "$backtitle" \ + --inputbox "$inputbox_instructions_int" \ + 10 75 "$4" 2>MCdialog.out + then + answer="`cat MCdialog.out`" + answer="${answer:-$3}" + + # Semantics of + and ? in GNU expr changed, so + # we avoid them: + if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null + then + eval $2=\"$answer\" + else + eval $2=\"$3\" + echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --infobox "You have made an invalid entry." 3 43 + sleep 2 + fi + + break + fi + + help "$2" "$1" + done +} + +# +# Create a dialog for entering a hexadecimal into a kernel option. +# +function l_hex () { + while true + do + if $DIALOG --title "$1" \ + --backtitle "$backtitle" \ + --inputbox "$inputbox_instructions_hex" \ + 10 75 "$4" 2>MCdialog.out + then + answer="`cat MCdialog.out`" + answer="${answer:-$3}" + answer="${answer##*[x,X]}" + + if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null + then + eval $2=\"$answer\" + else + eval $2=\"$3\" + echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --infobox "You have made an invalid entry." 3 43 + sleep 2 + fi + + break + fi + + help "$2" "$1" + done +} + +# +# Create a dialog for entering a string into a kernel option. +# +function l_string () { + while true + do + if $DIALOG --title "$1" \ + --backtitle "$backtitle" \ + --inputbox "$inputbox_instructions_string" \ + 10 75 "$4" 2>MCdialog.out + then + answer="`cat MCdialog.out`" + answer="${answer:-$3}" + + # + # Someone may add a nice check for the entered + # string here... + # + eval $2=\"$answer\" + + break + fi + + help "$2" "$1" + done +} + + +# +# Handle a one-of-many choice list. +# +function l_choice () { + # + # Need to remember params cause they're gonna get reset. + # + title="$1" + choices="$2" + current="$3" + chosen= + + # + # Scan current value of choices and set radiolist switches. + # + list= + set -- $choices + firstchoice=$2 + while [ -n "$2" ] + do + case "$1" in + "$current"*) if [ -z "$chosen" ]; then + list="$list $2 $1 ON " + chosen=1 + else + list="$list $2 $1 OFF " + fi ;; + *) list="$list $2 $1 OFF " ;; + esac + + shift ; shift + done + + while true + do + if $DIALOG --title "$title" \ + --backtitle "$backtitle" \ + --radiolist "$radiolist_instructions" \ + 15 70 6 $list 2>MCdialog.out + then + choice=`cat MCdialog.out` + break + fi + + help "$firstchoice" "$title" + done + + # + # Now set the boolean value of each option based on + # the selection made from the radiolist. + # + set -- $choices + while [ -n "$2" ] + do + if [ "$2" = "$choice" ] + then + eval $2=\"y\" + else + eval $2=\"n\" + fi + + shift ; shift + done +} + +# +# Call awk, and watch for error codes, etc. +# +function callawk () { +awk "$1" || { echo "Awk died with error code $?. Giving up."; exit 1; } +} + +# +# A faster awk based recursive parser. (I hope) +# +function parser1 () { +callawk ' +BEGIN { + menu_no = 0 + comment_is_option = 0 + parser("'$CONFIG_IN'","MCmenu0") +} + +function parser(ifile,menu) { + + while ((getline <ifile) > 0) { + if ($1 == "mainmenu_option") { + comment_is_option = "1" + } + else if ($1 == "comment" && comment_is_option == "1") { + comment_is_option= "0" + sub($1,"",$0) + ++menu_no + + printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu + + newmenu = sprintf("MCmenu%d", menu_no); + printf( "function MCmenu%s () {\n"\ + "default=$1\n"\ + "menu_name %s\n",\ + menu_no, $0) >newmenu + + parser(ifile, newmenu) + } + else if ($0 ~ /^#|\$MAKE|mainmenu_name/) { + printf("") >>menu + } + else if ($1 ~ "endmenu") { + printf("}\n") >>menu + return + } + else if ($1 == "source") { + parser($2,menu) + } + else { + print >>menu + } + } +}' +} + +# +# Secondary parser for single menu mode. +# +function parser2 () { +callawk ' +BEGIN { + parser("'$CONFIG_IN'","MCmenu0") +} + +function parser(ifile,menu) { + + while ((getline <ifile) > 0) { + if ($0 ~ /^#|$MAKE|mainmenu_name/) { + printf("") >>menu + } + else if ($1 ~ /mainmenu_option|endmenu/) { + printf("") >>menu + } + else if ($1 == "source") { + parser($2,menu) + } + else { + print >>menu + } + } +}' +} + +# +# Parse all the config.in files into mini scripts. +# +function parse_config_files () { + rm -f MCmenu* + + echo "function MCmenu0 () {" >MCmenu0 + echo 'default=$1' >>MCmenu0 + echo "menu_name 'Main Menu'" >>MCmenu0 + + if [ "_$single_menu_mode" = "_TRUE" ] + then + parser2 + else + parser1 + fi + + echo "comment ''" >>MCmenu0 + echo "g_alt_config" >>MCmenu0 + echo "s_alt_config" >>MCmenu0 + + echo "}" >>MCmenu0 + + # + # These mini scripts must be sourced into the current + # environment in order for all of this to work. Leaving + # them on the disk as executables screws up the recursion + # in activate_menu(), among other things. Once they are + # sourced we can discard them. + # + for i in MCmenu* + do + echo -n "." + source ./$i + done + rm -f MCmenu* +} + +# +# This is the menu tree's bootstrap. +# +# Executes the parsed menus on demand and creates a set of functions, +# one per configuration option. These functions will in turn execute +# dialog commands or recursively call other menus. +# +function activate_menu () { + rm -f lxdialog.scrltmp + while true + do + comment_ctr=0 #So comment lines get unique tags + + $1 "$default" 2> MCerror #Create the lxdialog menu & functions + + if [ "$?" != "0" ] + then + clear + cat <<EOM + +Menuconfig has encountered a possible error in one of the kernel's +configuration files and is unable to continue. Here is the error +report: + +EOM + sed 's/^/ Q> /' MCerror + cat <<EOM + +Please report this to the maintainer <mec@shout.net>. You may also +send a problem report to <linux-kernel@vger.kernel.org>. + +Please indicate the kernel version you are trying to configure and +which menu you were trying to enter when this error occurred. + +EOM + cleanup + exit 1 + fi + rm -f MCerror + + . ./MCradiolists #Source the menu's functions + + . ./MCmenu 2>MCdialog.out #Activate the lxdialog menu + ret=$? + + read selection <MCdialog.out + + case "$ret" in + 0|3|4|5|6) + defaults="$selection$defaults" #pseudo stack + case "$ret" in + 0) eval $selection ;; + 3) eval $selection y ;; + 4) eval $selection n ;; + 5) eval $selection m ;; + 6) eval $selection c ;; + esac + default="${defaults%%*}" defaults="${defaults#*}" + ;; + 2) + default="${selection%%\ *}" + + case "$selection" in + *"-->"*|*"alt_config"*) + show_readme ;; + *) + eval help $selection ;; + esac + ;; + 255|1) + break + ;; + 139) + stty sane + clear + cat <<EOM + +There seems to be a problem with the lxdialog companion utility which is +built prior to running Menuconfig. Usually this is an indicator that you +have upgraded/downgraded your ncurses libraries and did not remove the +old ncurses header file(s) in /usr/include or /usr/include/ncurses. + +It is VERY important that you have only one set of ncurses header files +and that those files are properly version matched to the ncurses libraries +installed on your machine. + +You may also need to rebuild lxdialog. This can be done by moving to +the /usr/src/linux/scripts/lxdialog directory and issuing the +"make clean all" command. + +If you have verified that your ncurses install is correct, you may email +the maintainer <mec@shout.net> or post a message to +<linux-kernel@vger.kernel.org> for additional assistance. + +EOM + cleanup + exit 139 + ;; + esac + done +} + +# +# Create a menu item to load an alternate configuration file. +# +g_alt_config () { + echo -n "get_alt_config 'Load an Alternate Configuration File' "\ + >>MCmenu +} + +# +# Get alternate config file name and load the +# configuration from it. +# +get_alt_config () { + set -f ## Switch file expansion OFF + + while true + do + ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}" + + $DIALOG --backtitle "$backtitle" \ + --inputbox "\ +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."\ + 11 55 "$ALT_CONFIG" 2>MCdialog.out + + if [ "$?" = "0" ] + then + ALT_CONFIG=`cat MCdialog.out` + + [ "_" = "_$ALT_CONFIG" ] && break + + if eval [ -r \"$ALT_CONFIG\" ] + then + eval load_config_file \"$ALT_CONFIG\" + break + else + echo -ne "\007" + $DIALOG --backtitle "$backtitle" \ + --infobox "File does not exist!" 3 38 + sleep 2 + fi + else + cat <<EOM >help.out + +For various reasons, one may wish to keep several different kernel +configurations available on a single machine. + +If you have saved a previous configuration in a file other than the +kernel's default, entering the name of the file here will allow you +to modify that configuration. + +If you are uncertain, then you have probably never used alternate +configuration files. You should therefor leave this blank to abort. + +EOM + $DIALOG --backtitle "$backtitle"\ + --title "Load Alternate Configuration"\ + --textbox help.out $ROWS $COLS + fi + done + + set +f ## Switch file expansion ON + rm -f help.out MCdialog.out +} + +# +# Create a menu item to store an alternate config file. +# +s_alt_config () { + echo -n "save_alt_config 'Save Configuration to an Alternate File' "\ + >>MCmenu +} + +# +# Get an alternate config file name and save the current +# configuration to it. +# +save_alt_config () { + set -f ## Switch file expansion OFF + + while true + do + $DIALOG --backtitle "$backtitle" \ + --inputbox "\ +Enter a filename to which this configuration should be saved \ +as an alternate. Leave blank to abort."\ + 10 55 "$ALT_CONFIG" 2>MCdialog.out + + if [ "$?" = "0" ] + then + ALT_CONFIG=`cat MCdialog.out` + + [ "_" = "_$ALT_CONFIG" ] && break + + if eval touch $ALT_CONFIG 2>/dev/null + then + eval save_configuration $ALT_CONFIG + load_functions ## RELOAD + break + else + echo -ne "\007" + $DIALOG --backtitle "$backtitle" \ + --infobox "Can't create file! Probably a nonexistent directory." 3 60 + sleep 2 + fi + else + cat <<EOM >help.out + +For various reasons, one may wish to keep different kernel +configurations available on a single machine. + +Entering a file name here will allow you to later retrieve, modify +and use the current configuration as an alternate to whatever +configuration options you have selected at that time. + +If you are uncertain what all this means then you should probably +leave this blank. +EOM + $DIALOG --backtitle "$backtitle"\ + --title "Save Alternate Configuration"\ + --textbox help.out $ROWS $COLS + fi + done + + set +f ## Switch file expansion ON + rm -f help.out MCdialog.out +} + +# +# Load config options from a file. +# Converts all "# OPTION is not set" lines to "OPTION=n" lines +# +function load_config_file () { + awk ' + /# .* is not set.*/ { printf("%s=n\n", $2) } + ! /# .* is not set.*/ { print } + ' $1 >.tmpconfig + + source ./.tmpconfig + rm -f .tmpconfig +} + +# +# Just what it says. +# +save_configuration () { + echo + echo -n "Saving your kernel configuration." + + # + # Now, let's redefine the configuration functions for final + # output to the config files. + # + # Nested function definitions, YIPEE! + # + function bool () { + set_x_info "$2" "n" + eval define_bool \"$2\" \"$x\" + } + + function tristate () { + set_x_info "$2" "n" + eval define_tristate \"$2\" \"$x\" + } + + function dep_tristate () { + set_x_info "$2" "n" + var="$2" + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + elif [ "$1" = m -a "$x" != n ]; then + x=m; shift + else + x=n; shift $# + fi + done + define_tristate "$var" "$x" + } + + function dep_bool () { + set_x_info "$2" "n" + var="$2" + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y ]; then + shift + else + x=n; shift $# + fi + done + define_bool "$var" "$x" + } + + function dep_mbool () { + set_x_info "$2" "n" + var="$2" + shift 2 + while [ $# -gt 0 ]; do + if [ "$1" = y -o "$1" = m ]; then + shift + else + x=n; shift $# + fi + done + define_bool "$var" "$x" + } + + function int () { + set_x_info "$2" "$3" + echo "$2=$x" >>$CONFIG + echo "#define $2 ($x)" >>$CONFIG_H + } + + function hex () { + set_x_info "$2" "$3" + echo "$2=$x" >>$CONFIG + echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H + } + + function string () { + set_x_info "$2" "$3" + echo "$2=\"$x\"" >>$CONFIG + echo "#define $2 \"$x\"" >>$CONFIG_H + } + + function define_hex () { + eval $1=\"$2\" + echo "$1=$2" >>$CONFIG + echo "#define $1 0x${2##*[x,X]}" >>$CONFIG_H + } + + function define_int () { + eval $1=\"$2\" + echo "$1=$2" >>$CONFIG + echo "#define $1 ($2)" >>$CONFIG_H + } + + function define_string () { + eval $1=\"$2\" + echo "$1=\"$2\"" >>$CONFIG + echo "#define $1 \"$2\"" >>$CONFIG_H + } + + function define_bool () { + define_tristate "$1" "$2" + } + + function define_tristate () { + eval $1=\"$2\" + + case "$2" in + y) + echo "$1=y" >>$CONFIG + echo "#define $1 1" >>$CONFIG_H + ;; + + m) + if [ "$CONFIG_MODULES" = "y" ] + then + echo "$1=m" >>$CONFIG + echo "#undef $1" >>$CONFIG_H + echo "#define $1_MODULE 1" >>$CONFIG_H + else + echo "$1=y" >>$CONFIG + echo "#define $1 1" >>$CONFIG_H + fi + ;; + + n) + echo "# $1 is not set" >>$CONFIG + echo "#undef $1" >>$CONFIG_H + ;; + esac + } + + function choice () { + # + # Find the first choice that's already set to 'y' + # + choices="$2" + default="$3" + current= + chosen= + + set -- $choices + while [ -n "$2" ] + do + if eval [ \"_\$$2\" = \"_y\" ] + then + current=$1 + break + fi + shift ; shift + done + + # + # Use the default if none were set. + # + : ${current:=$default} + + # + # Output all choices (to be compatible with other configs). + # + set -- $choices + while [ -n "$2" ] + do + case "$1" in + "$current"*) if [ -z "$chosen" ]; then + define_bool "$2" "y" + chosen=1 + else + define_bool "$2" "n" + fi ;; + *) define_bool "$2" "n" ;; + esac + shift ; shift + done + } + + function mainmenu_name () { + : + } + + function mainmenu_option () { + comment_is_option=TRUE + } + + function endmenu () { + : + } + + function comment () { + if [ "$comment_is_option" ] + then + comment_is_option= + echo >>$CONFIG + echo "#" >>$CONFIG + echo "# $1" >>$CONFIG + echo "#" >>$CONFIG + + echo >>$CONFIG_H + echo "/*" >>$CONFIG_H + echo " * $1" >>$CONFIG_H + echo " */" >>$CONFIG_H + fi + } + + echo -n "." + + DEF_CONFIG="${1:-.config}" + DEF_CONFIG_H="include/linux/autoconf.h" + + CONFIG=.tmpconfig + CONFIG_H=.tmpconfig.h + + echo "#" >$CONFIG + echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG + echo "#" >>$CONFIG + + echo "/*" >$CONFIG_H + echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H + echo " */" >>$CONFIG_H + echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H + + echo -n "." + if . $CONFIG_IN >>.menuconfig.log 2>&1 + then + if [ "$DEF_CONFIG" = ".config" ] + then + mv $CONFIG_H $DEF_CONFIG_H + fi + + if [ -f "$DEF_CONFIG" ] + then + rm -f ${DEF_CONFIG}.old + mv $DEF_CONFIG ${DEF_CONFIG}.old + fi + + mv $CONFIG $DEF_CONFIG + + return 0 + else + return 1 + fi +} + +# +# Remove temporary files +# +cleanup () { + cleanup1 + cleanup2 +} + +cleanup1 () { + rm -f MCmenu* MCradiolists MCdialog.out help.out +} + +cleanup2 () { + rm -f .tmpconfig .tmpconfig.h +} + +set_geometry () { + # Some distributions export these with incorrect values + # which can really screw up some ncurses programs. + LINES= COLUMNS= + + ROWS=${1:-24} COLS=${2:-80} + + # Just in case the nasty rlogin bug returns. + # + [ $ROWS = 0 ] && ROWS=24 + [ $COLS = 0 ] && COLS=80 + + if [ $ROWS -lt 19 -o $COLS -lt 80 ] + then + echo -e "\n\007Your display is too small to run Menuconfig!" + echo "It must be at least 19 lines by 80 columns." + exit 1 + fi + + ROWS=$((ROWS-4)) COLS=$((COLS-5)) +} + + +set_geometry `stty size 2>/dev/null` + +menu_instructions="\ +Arrow keys navigate the menu. \ +<Enter> selects submenus --->. \ +Highlighted letters are hotkeys. \ +Pressing <Y> includes, <N> excludes, <M> modularizes features. \ +Press <Esc><Esc> to exit, <?> for Help. \ +Legend: [*] built-in [ ] excluded <M> module < > module capable" + +radiolist_instructions="\ +Use the arrow keys to navigate this window or \ +press the hotkey of the item you wish to select \ +followed by the <SPACE BAR>. +Press <?> for additional information about this option." + +inputbox_instructions_int="\ +Please enter a decimal value. \ +Fractions will not be accepted. \ +Use the <TAB> key to move from the input field to the buttons below it." + +inputbox_instructions_hex="\ +Please enter a hexadecimal value. \ +Use the <TAB> key to move from the input field to the buttons below it." + +inputbox_instructions_string="\ +Please enter a string value. \ +Use the <TAB> key to move from the input field to the buttons below it." + +DIALOG="./scripts/lxdialog/lxdialog" + +kernel_version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" + +backtitle="Linux Kernel v$kernel_version Configuration" + +trap "cleanup ; exit 1" 1 2 15 + + +# +# Locate default files. +# +CONFIG_IN=./config.in +if [ "$1" != "" ] ; then + CONFIG_IN=$1 +fi + +DEFAULTS=arch/$ARCH/defconfig +if [ -f .config ]; then + DEFAULTS=.config +fi + +if [ -f $DEFAULTS ] +then + echo "Using defaults found in" $DEFAULTS + load_config_file $DEFAULTS +else + echo "No defaults found" +fi + + +# Fresh new log. +>.menuconfig.log + +# Load the functions used by the config.in files. +echo -n "Preparing scripts: functions" +load_functions + +if [ ! -e $CONFIG_IN ] +then + echo "Your main config.in file ($CONFIG_IN) does not exist" + exit 1 +fi + +if [ ! -x $DIALOG ] +then + echo "Your lxdialog utility does not exist" + exit 1 +fi + +# +# Read config.in files and parse them into one shell function per menu. +# +echo -n ", parsing" +parse_config_files $CONFIG_IN + +echo "done." +# +# Start the ball rolling from the top. +# +activate_menu MCmenu0 + +# +# All done! +# +cleanup1 + +# +# Confirm and Save +# +if $DIALOG --backtitle "$backtitle" \ + --yesno "Do you wish to save your new kernel configuration?" 5 60 +then + save_configuration + echo + echo + echo "*** End of Linux kernel 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 bzImage', 'make bzdisk', or 'make install'." + fi + echo +else + echo + echo + echo Your kernel configuration changes were NOT saved. + echo +fi + +# Remove log if empty. +if [ ! -s .menuconfig.log ] ; then + rm -f .menuconfig.log +fi + +exit 0 diff --git a/uClinux-2.4.31-uc0/scripts/README.Menuconfig b/uClinux-2.4.31-uc0/scripts/README.Menuconfig new file mode 100644 index 0000000..5c28589 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/README.Menuconfig @@ -0,0 +1,194 @@ +Menuconfig gives the Linux kernel configuration a long needed face +lift. Featuring text based color menus and dialogs, it does not +require X Windows. With this utility you can easily select a kernel +option to modify without sifting through 100 other options. + +Overview +-------- +Some kernel features may be built directly into the kernel. +Some may be made into loadable runtime modules. Some features +may be completely removed altogether. There are also certain +kernel parameters which are not really features, but must be +entered in as decimal or hexadecimal numbers or possibly text. + +Menu items beginning with [*], <M> or [ ] represent features +configured to be built in, modularized or removed respectively. +Pointed brackets <> represent module capable features. + more... + +To change any of these features, highlight it with the cursor +keys and press <Y> to build it in, <M> to make it a module or +<N> to removed it. You may also press the <Space Bar> to cycle +through the available options (ie. Y->N->M->Y). + +Items beginning with numbers or other text within parenthesis can +be changed by highlighting the item and pressing <Enter>. Then +enter the new parameter into the dialog box that pops up. + + +Some additional keyboard hints: + +Menus +---------- +o Use the Up/Down arrow keys (cursor keys) to highlight the item + you wish to change or submenu wish to select and press <Enter>. + Submenus are designated by "--->". + + Shortcut: Press the option's highlighted letter (hotkey). + Pressing a hotkey more than once will sequence + through all visible items which use that hotkey. + + You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll + unseen options into view. + +o To exit a menu use the cursor keys to highlight the <Exit> button + and press <ENTER>. + + Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey + using those letters. You may press a single <ESC>, but + there is a delayed response which you may find annoying. + + Also, the <TAB> and cursor keys will cycle between <Select>, + <Exit> and <Help> + +o To get help with an item, use the cursor keys to highlight <Help> + and Press <ENTER>. + + Shortcut: Press <H> or <?>. + + +Radiolists (Choice lists) +----------- +o Use the cursor keys to select the option you wish to set and press + <S> or the <SPACE BAR>. + + Shortcut: Press the first letter of the option you wish to set then + press <S> or <SPACE BAR>. + +o To see available help for the item, use the cursor keys to highlight + <Help> and Press <ENTER>. + + Shortcut: Press <H> or <?>. + + Also, the <TAB> and cursor keys will cycle between <Select> and + <Help> + + +Data Entry +----------- +o Enter the requested information and press <ENTER> + If you are entering hexadecimal values, it is not necessary to + add the '0x' prefix to the entry. + +o For help, use the <TAB> or cursor keys to highlight the help option + and press <ENTER>. You can try <TAB><H> as well. + + +Text Box (Help Window) +-------- +o Use the cursor keys to scroll up/down/left/right. The VI editor + keys h,j,k,l function here as do <SPACE BAR> and <B> for those + who are familiar with less and lynx. + +o Press <E>, <X>, <Enter> or <Esc><Esc> to exit. + + +Final Acceptance +---------------- +With the exception of the old style sound configuration, +YOUR CHANGES ARE NOT FINAL. You will be given a last chance to +confirm them prior to exiting Menuconfig. + +If Menuconfig quits with an error while saving your configuration, +you may look in the file /usr/src/linux/.menuconfig.log for +information which may help you determine the cause. + +Alternate Configuration Files +----------------------------- +Menuconfig supports the use of alternate configuration files for +those who, for various reasons, find it necessary to switch +between different kernel configurations. + +At the end of the main menu you will find two options. One is +for saving the current configuration to a file of your choosing. +The other option is for loading a previously saved alternate +configuration. + +Even if you don't use alternate configuration files, but you +find during a Menuconfig session that you have completely messed +up your settings, you may use the "Load Alternate..." option to +restore your previously saved settings from ".config" without +restarting Menuconfig. + +Other information +----------------- +The windowing utility, lxdialog, will only be rebuilt if your kernel +source tree is fresh, or changes are patched into it via a kernel +patch or you do 'make mrproper'. If changes to lxdialog are patched +in, most likely the rebuild time will be short. You may force a +complete rebuild of lxdialog by changing to it's directory and doing +'make clean all' + +If you use Menuconfig in an XTERM window make sure you have your +$TERM variable set to point to a xterm definition which supports color. +Otherwise, Menuconfig will look rather bad. Menuconfig will not +display correctly in a RXVT window because rxvt displays only one +intensity of color, bright. + +Menuconfig will display larger menus on screens or xterms which are +set to display more than the standard 25 row by 80 column geometry. +In order for this to work, the "stty size" command must be able to +display the screen's current row and column geometry. I STRONGLY +RECOMMEND that you make sure you do NOT have the shell variables +LINES and COLUMNS exported into your environment. Some distributions +export those variables via /etc/profile. Some ncurses programs can +become confused when those variables (LINES & COLUMNS) don't reflect +the true screen size. + + +NOTICE: lxdialog requires the ncurses libraries to compile. If you + don't already have ncurses you really should get it. + + The makefile for lxdialog attempts to find your ncurses + header file. Although it should find the header for older + versions of ncurses, it is probably a good idea to get the + latest ncurses anyway. + + If you have upgraded your ncurses libraries, MAKE SURE you + remove the old ncurses header files. If you don't you + will most certainly get a segmentation fault. + +WARNING: It is not recommended that you change any defines in + lxdialog's header files. If you have a grayscale display and + are brave, you may tinker with color.h to tune the colors to + your preference. + +COMPATIBILITY ISSUE: + There have been some compatibility problems reported with + older versions of bash and sed. I am trying to work these + out but it is preferable that you upgrade those utilities. + + +******** IMPORTANT, OPTIONAL ALTERNATE PERSONALITY AVAILABLE ******** +******** ******** +If you prefer to have all of the kernel options listed in a single +menu, rather than the default multimenu hierarchy, you may edit the +Menuconfig script and change the line "single_menu_mode=" to +"single_menu_mode=TRUE". + +This mode is not recommended unless you have a fairly fast machine. +********************************************************************* + + +Propaganda +---------- +The windowing support utility (lxdialog) is a VERY modified version of +the dialog utility by Savio Lam <lam836@cs.cuhk.hk>. Although lxdialog +is significantly different from dialog, I have left Savio's copyrights +intact. Please DO NOT contact Savio with questions about lxdialog. +He will not be able to assist. + +William Roadcap was the original author of Menuconfig. +Michael Elizabeth Chastain <mec@shout.net> is the current maintainer. + +<END OF FILE> diff --git a/uClinux-2.4.31-uc0/scripts/checkconfig.pl b/uClinux-2.4.31-uc0/scripts/checkconfig.pl new file mode 100644 index 0000000..ca1f231 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/checkconfig.pl @@ -0,0 +1,65 @@ +#! /usr/bin/perl +# +# checkconfig: find uses of CONFIG_* names without matching definitions. +# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>. + +use integer; + +$| = 1; + +foreach $file (@ARGV) +{ + # Open this file. + open(FILE, $file) || die "Can't open $file: $!\n"; + + # Initialize variables. + my $fInComment = 0; + my $fInString = 0; + my $fUseConfig = 0; + my $iLinuxConfig = 0; + my %configList = (); + + LINE: while ( <FILE> ) + { + # Strip comments. + $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); + m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); + + # Pick up definitions. + if ( m/^\s*#/o ) + { + $iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o; + $configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o; + } + + # Strip strings. + $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next); + m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1))); + + # Pick up definitions. + if ( m/^\s*#/o ) + { + $iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o; + $configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o; + $configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o; + $configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o; + } + + # Look for usages. + next unless m/CONFIG_/o; + WORD: while ( m/\bCONFIG_(\w+)/og ) + { + $fUseConfig = 1; + last LINE if $iLinuxConfig; + next WORD if exists $configList{$1}; + print "$file: $.: need CONFIG_$1.\n"; + $configList{$1} = 0; + } + } + + # Report superfluous includes. + if ( $iLinuxConfig && ! $fUseConfig ) + { print "$file: $iLinuxConfig: linux/config.h not needed.\n"; } + + close(FILE); +} diff --git a/uClinux-2.4.31-uc0/scripts/checkhelp.pl b/uClinux-2.4.31-uc0/scripts/checkhelp.pl new file mode 100644 index 0000000..e765233 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/checkhelp.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# checkhelp.pl - finds configuration options that have no +# corresponding section in the help file +# +# made by Meelis Roos (mroos@tartu.cyber.ee) + +# read the help file +@options=split /\n/, `grep '^CONFIG' Documentation/Configure.help`; +die "Can't read Documentation/Configure.help\n" if $#options == -1; + +#read all the files +foreach $file (@ARGV) +{ + open (FILE, $file) || die "Can't open $file: $!\n"; + while (<FILE>) { + # repeat until no CONFIG_* are left + while (/^\s*(bool|tristate|dep_tristate|string|int|hex).*' *(.*)'.*(CONFIG_\w*)/) { + $what=$3; + $name=$2; + s/$3//; + @found = grep (/$what$/, @options); + if ($#found == -1) { + next if $nohelp{$what}; + print "$name\n$what\n No help for $what\n\n"; + $nohelp{$what}=1; + } + } + } + close (FILE); +} diff --git a/uClinux-2.4.31-uc0/scripts/checkincludes.pl b/uClinux-2.4.31-uc0/scripts/checkincludes.pl new file mode 100644 index 0000000..8e6b716 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/checkincludes.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +# +# checkincludes: Find files included more than once in (other) files. +# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. + +foreach $file (@ARGV) { + open(FILE, $file) or die "Cannot open $file: $!.\n"; + + my %includedfiles = (); + + while (<FILE>) { + if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { + ++$includedfiles{$1}; + } + } + + foreach $filename (keys %includedfiles) { + if ($includedfiles{$filename} > 1) { + print "$file: $filename is included more than once.\n"; + } + } + + close(FILE); +} diff --git a/uClinux-2.4.31-uc0/scripts/docgen b/uClinux-2.4.31-uc0/scripts/docgen new file mode 100644 index 0000000..a718305 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/docgen @@ -0,0 +1,10 @@ +#!/bin/sh +set -e +if [ -z "$scripts_objtree" ] +then + X=`$TOPDIR/scripts/gen-all-syms "$*"` + $TOPDIR/scripts/docproc $X +else + X=`${scripts_objtree}gen-all-syms "$*"` + TOPDIR=. ${scripts_objtree}docproc $X +fi diff --git a/uClinux-2.4.31-uc0/scripts/docproc.c b/uClinux-2.4.31-uc0/scripts/docproc.c new file mode 100644 index 0000000..8e7632a --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/docproc.c @@ -0,0 +1,104 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + +/* + * A simple filter for the templates + */ + +int main(int argc, char *argv[]) +{ + char buf[1024]; + char *vec[8192]; + char *fvec[200]; + char **svec; + char type[64]; + int i; + int vp=2; + int ret=0; + pid_t pid; + + + if(chdir(getenv("TOPDIR"))) + { + perror("chdir"); + exit(1); + } + + /* + * Build the exec array ahead of time. + */ + vec[0]="kernel-doc"; + vec[1]="-docbook"; + for(i=1;vp<8189;i++) + { + if(argv[i]==NULL) + break; + vec[vp++]=type; + vec[vp++]=argv[i]; + } + vec[vp++]=buf+2; + vec[vp++]=NULL; + + /* + * Now process the template + */ + + while(fgets(buf, 1024, stdin)) + { + if(*buf!='!') { + printf("%s", buf); + continue; + } + + fflush(stdout); + svec = vec; + if(buf[1]=='E') + strcpy(type, "-function"); + else if(buf[1]=='I') + strcpy(type, "-nofunction"); + else if(buf[1]=='F') { + int snarf = 0; + fvec[0] = "kernel-doc"; + fvec[1] = "-docbook"; + strcpy (type, "-function"); + vp = 2; + for (i = 2; buf[i]; i++) { + if (buf[i] == ' ' || buf[i] == '\n') { + buf[i] = '\0'; + snarf = 1; + continue; + } + + if (snarf) { + snarf = 0; + fvec[vp++] = type; + fvec[vp++] = &buf[i]; + } + } + fvec[vp++] = &buf[2]; + fvec[vp] = NULL; + svec = fvec; + } else + { + fprintf(stderr, "Unknown ! escape.\n"); + exit(1); + } + switch(pid=fork()) + { + case -1: + perror("fork"); + exit(1); + case 0: + execvp("scripts/kernel-doc", svec); + perror("exec scripts/kernel-doc"); + exit(1); + default: + waitpid(pid, &ret ,0); + } + } + exit(ret); +} diff --git a/uClinux-2.4.31-uc0/scripts/extract-ikconfig b/uClinux-2.4.31-uc0/scripts/extract-ikconfig new file mode 100644 index 0000000..6670d02 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/extract-ikconfig @@ -0,0 +1,17 @@ +#! /bin/bash -x +# extracts .config info from a [b]zImage file +# uses: binoffset (new), dd, zcat, strings, grep +# $arg1 is [b]zImage filename + +HDR=`binoffset $1 0x1f 0x8b 0x08 0x0` +PID=$$ +TMPFILE="$1.vmlin.$PID" + +# dd if=$1 bs=1 skip=$HDR | zcat - | strings /dev/stdin \ +# | grep "[A-Za-z_0-9]=[ynm]$" | sed "s/^/CONFIG_/" > $1.oldconfig.$PID +# exit + +dd if=$1 bs=1 skip=$HDR | zcat - > $TMPFILE +strings $TMPFILE | grep "^[\#[:blank:]]*CONFIG_[A-Za-z_0-9]*" > $1.oldconfig.$PID +wc $1.oldconfig.$PID +rm $TMPFILE diff --git a/uClinux-2.4.31-uc0/scripts/gen-all-syms b/uClinux-2.4.31-uc0/scripts/gen-all-syms new file mode 100644 index 0000000..b15b160 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/gen-all-syms @@ -0,0 +1,7 @@ +#!/bin/sh +for i in $* +do + grep "EXPORT_SYMBOL.*(.*)" "$i" \ + | sed -e "s/EXPORT_SYMBOL.*(/ /" \ + | sed -e "s/).*$//" | sed -e "s/^ //" +done diff --git a/uClinux-2.4.31-uc0/scripts/header.tk b/uClinux-2.4.31-uc0/scripts/header.tk new file mode 100644 index 0000000..2cc9c7e --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/header.tk @@ -0,0 +1,637 @@ +# FILE: header.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1999, Michael Elizabeth Chastain, <mec@shout.net> +# - Remove unused do_cmd function (part of the 2.0 sound support). +# - Arrange buttons in three columns for better screen fitting. +# - Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like: +# dep_tristate 'foo' CONFIG_FOO m +# +# 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net> +# - Shut vfix the hell up. +# +# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net> +# - Improve the exit message (Jeff Ronne). + +# +# This is a handy replacement for ".widget cget" that requires neither tk4 +# nor additional source code uglification. +# +proc cget { w option } { + return "[lindex [$w configure $option] 4]" +} + +# +# Function to compensate for broken config.in scripts like the sound driver, +# which make dependencies on variables that are never even conditionally +# defined. +# +proc vfix { var } { + global $var + if [ catch {eval concat $$var} ] { + set $var 4 + } +} + +# +# Constant values used by certain dep_tristate commands. +# +set CONSTANT_Y 1 +set CONSTANT_M 2 +set CONSTANT_N 0 +set CONSTANT_E 4 + +# +# Create a "reference" object to steal colors from. +# +button .ref + +# +# On monochrome displays, -disabledforeground is blank by default; that's +# bad. Fill it with -foreground instead. +# +if { [cget .ref -disabledforeground] == "" } { + .ref configure -disabledforeground [cget .ref -foreground] +} + + +# +# Define some macros we will need to parse the config.in file. +# + +proc mainmenu_name { text } { + wm title . "$text" +} + +proc menu_option { w menu_num text } { + global menus_per_column + global processed_top_level + set processed_top_level [expr $processed_top_level + 1] + if { $processed_top_level <= $menus_per_column } then { + set myframe left + } elseif { $processed_top_level <= [expr 2 * $menus_per_column] } then { + set myframe middle + } else { + set myframe right + } + button .f0.x$menu_num -anchor w -text "$text" \ + -command "$w .$w \"$text\"" + pack .f0.x$menu_num -pady 0 -side top -fill x -in .f0.$myframe +} + +proc load_configfile { w title func } { + catch {destroy $w} + toplevel $w -class Dialog + global loadfile + frame $w.x + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + label $w.x.l -text "Enter filename:" -relief raised + entry $w.x.x -width 35 -relief sunken -borderwidth 2 \ + -textvariable loadfile + pack $w.x.l $w.x.x -anchor w -side left + pack $w.x -side top -pady 10 + wm title $w "$title" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "destroy $w; focus $oldFocus;$func .fileio" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +bind all <Alt-q> {maybe_exit .maybe} + +proc maybe_exit { w } { + catch {destroy $w} + toplevel $w -class Dialog + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + message $w.m -width 400 -aspect 300 \ + -text "Changes will be lost. Are you sure?" -relief flat + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Are you sure?" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "exit" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + bind $w <Return> "exit" + bind $w <Escape> "destroy $w; focus $oldFocus" + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc read_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 && [file readable $loadfile] == 1 } then { + read_config $loadfile + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to read file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Bummer" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc write_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 + && ([file writable $loadfile] == 1 || ([file exists $loadfile] == 0 && [file writable [file dirname $loadfile]] == 1)) } then { + writeconfig $loadfile /dev/null + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to write file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc read_config { filename } { + set file1 [open $filename r] + clear_choices + while { [gets $file1 line] >= 0} { + if [regexp {([0-9A-Za-z_]+)=([ynm])} $line foo var value] { + if { $value == "y" } then { set cmd "global $var; set $var 1" } + if { $value == "n" } then { set cmd "global $var; set $var 0" } + if { $value == "m" } then { set cmd "global $var; set $var 2" } + eval $cmd + } + if [regexp {# ([0-9A-Za-z_]+) is not set} $line foo var] { + set cmd "global $var; set $var 0" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)=([0-9A-Fa-f]+)} $line foo var value] { + set cmd "global $var; set $var $value" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] { + set cmd "global $var; set $var \"$value\"" + eval $cmd + } + } + close $file1 + update_choices + update_mainmenu +} +proc write_comment { file1 file2 text } { + puts $file1 "" + puts $file1 "#" + puts $file1 "# $text" + puts $file1 "#" + puts $file2 "/*" + puts $file2 " * $text" + puts $file2 " */" +} + +proc effective_dep { deplist } { + global CONFIG_MODULES + set depend 1 + foreach i $deplist { + if {$i == 0} then {set depend 0} + if {$i == 2 && $depend == 1} then {set depend 2} + } + if {$depend == 2 && $CONFIG_MODULES == 0} then {set depend 0} + return $depend +} + +proc sync_tristate { var dep } { + global CONFIG_MODULES + if {$dep == 0 && ($var == 1 || $var == 2)} then { + set var 0 + } elseif {$dep == 2 && $var == 1} then { + set var 2 + } elseif {$var == 2 && $CONFIG_MODULES == 0} then { + if {$dep == 1} then {set var 1} else {set var 0} + } + return $var +} + +proc sync_bool { var dep modset } { + set var [sync_tristate $var $dep] + if {$dep == 2 && $var == 2} then { + set var $modset + } + return $var +} + +proc write_tristate { file1 file2 varname variable deplist modset } { + set variable [sync_tristate $variable [effective_dep $deplist]] + if { $variable == 2 } \ + then { set variable $modset } + if { $variable == 1 } \ + then { puts $file1 "$varname=y"; \ + puts $file2 "#define $varname 1" } \ + elseif { $variable == 2 } \ + then { puts $file1 "$varname=m"; \ + puts $file2 "#undef $varname"; \ + puts $file2 "#define ${varname}_MODULE 1" } \ + elseif { $variable == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { \ + puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ + } +} + +proc write_int { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname ($variable)"; \ + } +} + +proc write_hex { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts -nonewline $file2 "#define $varname 0x"; \ + puts $file2 [exec echo $variable | sed s/^0\[xX\]//]; \ + } +} + +proc write_string { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=\"$variable\""; \ + puts $file2 "#define $varname \"$variable\""; \ + } +} + +proc option_name {w mnum line text helpidx} { + button $w.x$line.l -text "$text" -relief groove -anchor w + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] + button $w.x$line.help -text "Help" -relief raised \ + -command "dohelp .dohelp $helpidx .menu$mnum" + pack $w.x$line.help -side right -fill y + pack $w.x$line.l -side right -fill both -expand on +} + +proc toggle_switch2 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_active" + radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_active" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_active" + + option_name $w $mnum $line $text $variable + + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc toggle_switch3 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_active" + radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_active" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_active" + + option_name $w $mnum $line $text $variable + + global CONFIG_MODULES + if {($CONFIG_MODULES == 0)} then { + $w.x$line.m configure -state disabled + } + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc bool {w mnum line text variable} { + toggle_switch2 $w $mnum $line $text $variable + $w.x$line.m configure -state disabled + pack $w.x$line -anchor w -fill both -expand on +} + +proc tristate {w mnum line text variable } { + toggle_switch3 $w $mnum $line $text $variable + pack $w.x$line -anchor w -fill both -expand on +} + +proc dep_tristate {w mnum line text variable } { + tristate $w $mnum $line $text $variable +} + +proc dep_bool {w mnum line text variable } { + bool $w $mnum $line $text $variable +} + +proc int { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc hex { w mnum line text variable } { + int $w $mnum $line $text $variable +} + +proc istring { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc minimenu { w mnum line text variable helpidx } { + frame $w.x$line + menubutton $w.x$line.x -textvariable $variable -menu \ + $w.x$line.x.menu -relief raised \ + -anchor w + option_name $w $mnum $line $text $helpidx + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc menusplit {w m n} { + if { $n > 2 } then { + update idletasks + set menuoptsize [expr [$m yposition 2] - [$m yposition 1]] + set maxsize [winfo screenheight $w] + set splitpoint [expr $maxsize * 4 / 5 / $menuoptsize - 1] + for {set i [expr $splitpoint + 1]} {$i <= $n} {incr i $splitpoint} { + $m entryconfigure $i -columnbreak 1 + } + } +} + +proc menutitle {text menu w} { + wm title $w "$text" +} + +proc submenu { w mnum line text subnum } { + frame $w.x$line + button $w.x$line.l -text "" -width 15 -relief groove + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] -state disabled + button $w.x$line.m -text "$text" -relief raised -anchor w \ + -command "catch {destroy .menu$subnum}; menu$subnum .menu$subnum \"$text\"" + pack $w.x$line.l -side left -fill both + pack $w.x$line.m -anchor w -side right -fill both -expand on + pack $w.x$line -anchor w -fill both -expand on +} + +proc comment {w mnum line text } { + frame $w.x$line + button $w.x$line.l -text "" -width 15 -relief groove + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] -state disabled + button $w.x$line.m -text "$text" -relief groove -anchor w + $w.x$line.m configure -activefore [cget $w.x$line.m -fg] \ + -activeback [cget $w.x$line.m -bg] + pack $w.x$line.l -side left -fill both + pack $w.x$line.m -anchor w -side right -fill both -expand on + pack $w.x$line -anchor w -fill both -expand on +} + +proc dohelp {w var parent} { + catch {destroy $w} + toplevel $w -class Dialog + + set filefound 0 + set found 0 + set lineno 0 + + if { [file readable Documentation/Configure.help] == 1} then { + set filefound 1 + # First escape sed regexp special characters in var: + set var [exec echo "$var" | sed s/\[\]\[\/.^$*\]/\\\\&/g] + # Now pick out right help text: + set message [exec sed -n " + /^$var\[ \]*\$/,\${ + /^$var\[ \]*\$/c\\ +${var}:\\ + + /^#/b + /^\[^ \]/q + s/^ // + /<file:\\(\[^>\]*\\)>/s//\\1/g + p + } + " Documentation/Configure.help] + set found [expr [string length "$message"] > 0] + } + + frame $w.f1 + pack $w.f1 -fill both -expand on + + # Do the OK button + # + set oldFocus [focus] + frame $w.f2 + button $w.f2.ok -text "OK" \ + -width 10 -command "destroy $w; catch {focus $oldFocus}" + pack $w.f2.ok -side bottom -pady 6 -anchor n + pack $w.f2 -side bottom -padx 10 -anchor s + + scrollbar $w.f1.vscroll -command "$w.f1.canvas yview" + pack $w.f1.vscroll -side right -fill y + + canvas $w.f1.canvas -relief flat -borderwidth 0 \ + -yscrollcommand "$w.f1.vscroll set" + frame $w.f1.f + pack $w.f1.canvas -side right -fill y -expand on + + if { $found == 0 } then { + if { $filefound == 0 } then { + message $w.f1.f.m -width 750 -aspect 300 -relief flat -text \ + "No help available - unable to open file Documentation/Configure.help. This file should have come with your kernel." + } else { + message $w.f1.f.m -width 400 -aspect 300 -relief flat -text \ + "No help available for $var" + } + label $w.f1.bm -bitmap error + wm title $w "RTFM" + } else { + text $w.f1.f.m -width 73 -relief flat -wrap word + $w.f1.f.m insert 0.0 $message + $w.f1.f.m conf -state disabled -height [$w.f1.f.m index end] + + label $w.f1.bm -bitmap info + wm title $w "Configuration help" + } + pack $w.f1.f.m -side left + pack $w.f1.bm $w.f1.f -side left -padx 10 + + focus $w + set winx [expr [winfo x $parent]+20] + set winy [expr [winfo y $parent]+20] + wm geometry $w +$winx+$winy + set sizok [expr [winfo reqheight $w.f2.ok] + 12] + set maxy [expr [winfo screenheight .] * 3 / 4] + set canvtotal [winfo reqheight $w.f1.f.m] + if [expr $sizok + $canvtotal < $maxy] { + set sizy $canvtotal + } else { + set sizy [expr $maxy - $sizok] + } + $w.f1.canvas configure -height $sizy -width [winfo reqwidth $w.f1.f.m] \ + -scrollregion "0 0 [winfo reqwidth $w.f1.f.m] \ + [winfo reqheight $w.f1.f.m]" + $w.f1.canvas create window 0 0 -anchor nw -window $w.f1.f + update idletasks + + set maxy [winfo screenheight .] + if [expr $sizok + $canvtotal < $maxy] { + set sizy [expr $sizok + $canvtotal] + } else { + set sizy $maxy + } + wm maxsize $w [winfo width $w] $sizy +} + +bind all <Alt-s> { catch {exec cp -f .config .config.old}; \ + writeconfig .config include/linux/autoconf.h; wrapup .wrap } + +proc wrapup {w } { + catch {destroy $w} + toplevel $w -class Dialog + + global CONFIG_MODVERSIONS; vfix CONFIG_MODVERSIONS + if { ([file exists .hdepend] != 1) || ($CONFIG_MODVERSIONS == 1) } then { + message $w.m -width 400 -aspect 300 -relief raised -text \ + "End of Linux kernel configuration. Check the top-level Makefile for additional configuration. Next, you must run 'make dep'." + } else { + message $w.m -width 400 -aspect 300 -relief raised -text \ + "End of Linux kernel configuration. Check the top-level Makefile for additional configuration. Next, you may 'make bzImage', 'make bzdisk', or 'make bzlilo.'" + } + label $w.bm -bitmap info + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Kernel build instructions" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "exit" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + bind $w <Return> "exit" + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + +} + +proc unregister_active {num} { + global active_menus + set index [lsearch -exact $active_menus $num] + if {$index != -1} then {set active_menus [lreplace $active_menus $index $index]} +} + +proc update_active {} { + global active_menus total_menus + set max 0 + if {[llength $active_menus] > 0} then { + set max [lindex $active_menus end] + update_define [toplevel_menu [lindex $active_menus 0]] $max 0 + } + foreach i $active_menus { + if {[winfo exists .menu$i] == 0} then { + unregister_active $i + } else { + update_menu$i + } + } + update_define [expr $max + 1] $total_menus 1 + update_mainmenu +} + +proc configure_entry {w option items} { + foreach i $items { + $w.$i configure -state $option + } +} + +proc validate_int {name val default} { + if {([exec echo $val | sed s/^-//g | tr -d \[:digit:\] ] != "")} then { + global $name; set $name $default + } +} + +proc validate_hex {name val default} { + if {([exec echo $val | tr -d \[:xdigit:\] ] != "")} then { + global $name; set $name $default + } +} + +proc update_define {first last allow_update} { + for {set i $first} {$i <= $last} {incr i} { + update_define_menu$i + if {$allow_update == 1} then update + } +} + +# +# Next set up the particulars for the top level menu, and define a few +# buttons which we will stick down at the bottom. +# + +frame .f0 +frame .f0.left +frame .f0.middle +frame .f0.right + +set active_menus [list] +set processed_top_level 0 diff --git a/uClinux-2.4.31-uc0/scripts/kernel-doc b/uClinux-2.4.31-uc0/scripts/kernel-doc new file mode 100644 index 0000000..60ca4fc --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/kernel-doc @@ -0,0 +1,1723 @@ +#!/usr/bin/perl -w + +use strict; + +## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## +## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## +## Copyright (C) 2001 Simon Huggins ## +## ## +## #define enhancements by Armin Kuster <akuster@mvista.com> ## +## Copyright (c) 2000 MontaVista Software, Inc. ## +## ## +## This software falls under the GNU General Public License. ## +## Please read the COPYING file for more information ## + +# w.o. 03-11-2000: added the '-filelist' option. + +# 18/01/2001 - Cleanups +# Functions prototyped as foo(void) same as foo() +# Stop eval'ing where we don't need to. +# -- huggie@earth.li + +# 27/06/2001 - Allowed whitespace after initial "/**" and +# allowed comments before function declarations. +# -- Christian Kreibich <ck@whoop.org> + +# Still to do: +# - add perldoc documentation +# - Look more closely at some of the scarier bits :) + +# 26/05/2001 - Support for separate source and object trees. +# Return error code. +# Keith Owens <kaos@ocs.com.au> + +# 23/09/2001 - Added support for typedefs, structs, enums and unions +# Support for Context section; can be terminated using empty line +# Small fixes (like spaces vs. \s in regex) +# -- Tim Jansen <tim@tjansen.de> + + +# +# This will read a 'c' file and scan for embedded comments in the +# style of gnome comments (+minor extensions - see below). +# + +# Note: This only supports 'c'. + +# usage: +# kerneldoc [ -docbook | -html | -text | -man ] +# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile +# or +# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile +# +# Set output format using one of -docbook -html -text or -man. Default is man. +# +# -function funcname +# If set, then only generate documentation for the given function(s). All +# other functions are ignored. +# +# -nofunction funcname +# If set, then only generate documentation for the other function(s). All +# other functions are ignored. Cannot be used with -function together +# (yes thats a bug - perl hackers can fix it 8)) +# +# c files - list of 'c' files to process +# +# All output goes to stdout, with errors to stderr. + +# +# format of comments. +# In the following table, (...)? signifies optional structure. +# (...)* signifies 0 or more structure elements +# /** +# * function_name(:)? (- short description)? +# (* @parameterx: (description of parameter x)?)* +# (* a blank line)? +# * (Description:)? (Description of function)? +# * (section header: (section description)? )* +# (*)?*/ +# +# So .. the trivial example would be: +# +# /** +# * my_function +# **/ +# +# If the Description: header tag is ommitted, then there must be a blank line +# after the last parameter specification. +# e.g. +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * +# * Does my stuff explained. +# */ +# +# or, could also use: +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * Description: Does my stuff explained. +# */ +# etc. +# +# Beside functions you can also write documentation for structs, unions, +# enums and typedefs. Instead of the function name you must write the name +# of the declaration; the struct/union/enum/typedef must always precede +# the name. Nesting of declarations is not supported. +# Use the argument mechanism to document members or constants. In +# structs and unions you must declare one member per declaration +# (comma-separated members are not allowed - the parser does not support +# this). +# e.g. +# /** +# * struct my_struct - short description +# * @a: first member +# * @b: second member +# * +# * Longer description +# */ +# struct my_struct { +# int a; +# int b; +# }; +# +# All descriptions can be multiline, except the short function description. +# +# You can also add additional sections. When documenting kernel functions you +# should document the "Context:" of the function, e.g. whether the functions +# can be called form interrupts. Unlike other sections you can end it with an +# empty line. +# Example-sections should contain the string EXAMPLE so that they are marked +# appropriately in DocBook. +# +# Example: +# /** +# * user_function - function that can only be called in user context +# * @a: some argument +# * Context: !in_interrupt() +# * +# * Some description +# * Example: +# * user_function(22); +# */ +# ... +# +# +# All descriptive text is further processed, scanning for the following special +# patterns, which are highlighted appropriately. +# +# 'funcname()' - function +# '$ENVVAR' - environmental variable +# '&struct_name' - name of a structure (up to two words including 'struct') +# '@parameter' - name of a parameter +# '%CONST' - name of a constant. + +my $errors = 0; + +# match expressions used to find embedded type information +my $type_constant = '\%([-_\w]+)'; +my $type_func = '(\w+)\(\)'; +my $type_param = '\@(\w+)'; +my $type_struct = '\&((struct\s*)?[_\w]+)'; +my $type_env = '(\$\w+)'; + +# Output conversion substitutions. +# One for each output format + +# these work fairly well +my %highlights_html = ( $type_constant, "<i>\$1</i>", + $type_func, "<b>\$1</b>", + $type_struct, "<i>\$1</i>", + $type_param, "<tt><b>\$1</b></tt>" ); +my $blankline_html = "<p>"; + +# sgml, docbook format +my %highlights_sgml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>", + $type_constant, "<constant>\$1</constant>", + $type_func, "<function>\$1</function>", + $type_struct, "<structname>\$1</structname>", + $type_env, "<envar>\$1</envar>", + $type_param, "<parameter>\$1</parameter>" ); +my $blankline_sgml = "</para><para>\n"; + +# gnome, docbook format +my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>", + $type_func, "<function>\$1</function>", + $type_struct, "<structname>\$1</structname>", + $type_env, "<envar>\$1</envar>", + $type_param, "<parameter>\$1</parameter>" ); +my $blankline_gnome = "</para><para>\n"; + +# these are pretty rough +my %highlights_man = ( $type_constant, "\$1", + $type_func, "\\\\fB\$1\\\\fP", + $type_struct, "\\\\fI\$1\\\\fP", + $type_param, "\\\\fI\$1\\\\fP" ); +my $blankline_man = ""; + +# text-mode +my %highlights_text = ( $type_constant, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_param, "\$1" ); +my $blankline_text = ""; + + +sub usage { + print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n"; + print " [ -function funcname [ -function funcname ...] ]\n"; + print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; + print " c source file(s) > outputfile\n"; + exit 1; +} + +# read arguments +if ($#ARGV==-1) { + usage(); +} + +my $verbose = 0; +my $output_mode = "man"; +my %highlights = %highlights_man; +my $blankline = $blankline_man; +my $modulename = "Kernel API"; +my $function_only = 0; +my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', + 'November', 'December')[(localtime)[4]] . + " " . ((localtime)[5]+1900); + +# Essentially these are globals +# They probably want to be tidied up made more localised or summat. +# CAVEAT EMPTOR! Some of the others I localised may not want to be which +# could cause "use of undefined value" or other bugs. +my ($function, %function_table,%parametertypes,$declaration_purpose); +my ($type,$declaration_name,$return_type); +my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map); + +# Generated docbook code is inserted in a template at a point where +# docbook v3.1 requires a non-zero sequence of RefEntry's; see: +# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html +# We keep track of number of generated entries and generate a dummy +# if needs be to ensure the expanded template can be postprocessed +# into html. +my $section_counter = 0; + +my $lineprefix=""; + +# states +# 0 - normal code +# 1 - looking for function name +# 2 - scanning field start. +# 3 - scanning prototype. +# 4 - documentation block +my $state; + +#declaration types: can be +# 'function', 'struct', 'union', 'enum', 'typedef' +my $decl_type; + +my $doc_special = "\@\%\$\&"; + +my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. +my $doc_end = '\*/'; +my $doc_com = '\s*\*\s*'; +my $doc_decl = $doc_com.'(\w+)'; +my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)'; +my $doc_content = $doc_com.'(.*)'; +my $doc_block = $doc_com.'DOC:\s*(.*)?'; + +my %constants; +my %parameterdescs; +my @parameterlist; +my %sections; +my @sectionlist; + +my $contents = ""; +my $section_default = "Description"; # default section +my $section_intro = "Introduction"; +my $section = $section_default; +my $section_context = "Context"; + +my $undescribed = "-- undescribed --"; + +reset_state(); + +while ($ARGV[0] =~ m/^-(.*)/) { + my $cmd = shift @ARGV; + if ($cmd eq "-html") { + $output_mode = "html"; + %highlights = %highlights_html; + $blankline = $blankline_html; + } elsif ($cmd eq "-man") { + $output_mode = "man"; + %highlights = %highlights_man; + $blankline = $blankline_man; + } elsif ($cmd eq "-text") { + $output_mode = "text"; + %highlights = %highlights_text; + $blankline = $blankline_text; + } elsif ($cmd eq "-docbook") { + $output_mode = "sgml"; + %highlights = %highlights_sgml; + $blankline = $blankline_sgml; + } elsif ($cmd eq "-gnome") { + $output_mode = "gnome"; + %highlights = %highlights_gnome; + $blankline = $blankline_gnome; + } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document + $modulename = shift @ARGV; + } elsif ($cmd eq "-function") { # to only output specific functions + $function_only = 1; + $function = shift @ARGV; + $function_table{$function} = 1; + } elsif ($cmd eq "-nofunction") { # to only output specific functions + $function_only = 2; + $function = shift @ARGV; + $function_table{$function} = 1; + } elsif ($cmd eq "-v") { + $verbose = 1; + } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + usage(); + } elsif ($cmd eq '-filelist') { + $filelist = shift @ARGV; + } +} + + +# generate a sequence of code that will splice in highlighting information +# using the s// operator. +my $dohighlight = ""; +foreach my $pattern (keys %highlights) { +# print "scanning pattern $pattern ($highlights{$pattern})\n"; + $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n"; +} + +## +# dumps section contents to arrays/hashes intended for that purpose. +# +sub dump_section { + my $name = shift; + my $contents = join "\n", @_; + + if ($name =~ m/$type_constant/) { + $name = $1; +# print STDERR "constant section '$1' = '$contents'\n"; + $constants{$name} = $contents; + } elsif ($name =~ m/$type_param/) { +# print STDERR "parameter def '$1' = '$contents'\n"; + $name = $1; + $parameterdescs{$name} = $contents; + } else { +# print STDERR "other section '$name' = '$contents'\n"; + $sections{$name} = $contents; + push @sectionlist, $name; + } +} + +## +# output function +# +# parameterdescs, a hash. +# function => "function name" +# parameterlist => @list of parameters +# parameterdescs => %parameter descriptions +# sectionlist => @list of sections +# sections => %descriont descriptions +# + +sub output_highlight { + my $contents = join "\n",@_; + my $line; + +# DEBUG +# if (!defined $contents) { +# use Carp; +# confess "output_highlight got called with no args?\n"; +# } + + eval $dohighlight; + die $@ if $@; + foreach $line (split "\n", $contents) { + if ($line eq ""){ + print $lineprefix, $blankline; + } else { + $line =~ s/\\\\\\/\&/g; + print $lineprefix, $line; + } + print "\n"; + } +} + +#output sections in html +sub output_section_html(%) { + my %args = %{$_[0]}; + my $section; + + foreach $section (@{$args{'sectionlist'}}) { + print "<h3>$section</h3>\n"; + print "<blockquote>\n"; + output_highlight($args{'sections'}{$section}); + print "</blockquote>\n"; + } +} + +# output enum in html +sub output_enum_html(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "<h2>enum ".$args{'enum'}."</h2>\n"; + + print "<b>enum ".$args{'enum'}."</b> {<br>\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <b>".$parameter."</b>"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ",\n"; + } + print "<br>"; + } + print "};<br>\n"; + + print "<h3>Constants</h3>\n"; + print "<dl>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "<dt><b>".$parameter."</b>\n"; + print "<dd>"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + print "</dl>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output tyepdef in html +sub output_typedef_html(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "<h2>typedef ".$args{'typedef'}."</h2>\n"; + + print "<b>typedef ".$args{'typedef'}."</b>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output struct in html +sub output_struct_html(%) { + my %args = %{$_[0]}; + my ($parameter); + + print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n"; + print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print " <i>$1</i> <b>$parameter</b>$2;<br>\n"; + } else { + print " <i>$type</i> <b>$parameter</b>;<br>\n"; + } + } + print "};<br>\n"; + + print "<h3>Members</h3>\n"; + print "<dl>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "<dt><b>".$parameter."</b>\n"; + print "<dd>"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + print "</dl>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output function in html +sub output_function_html(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + print "<h2>Function</h2>\n"; + + print "<i>".$args{'functiontype'}."</i>\n"; + print "<b>".$args{'function'}."</b>\n"; + print "("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print "<i>$1</i><b>$parameter</b>) <i>($2)</i>"; + } else { + print "<i>".$type."</i> <b>".$parameter."</b>"; + } + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ",\n"; + } + } + print ")\n"; + + print "<h3>Arguments</h3>\n"; + print "<dl>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "<dt><b>".$parameter."</b>\n"; + print "<dd>"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + print "</dl>\n"; + output_section_html(@_); + print "<hr>\n"; +} + +# output intro in html +sub output_intro_html(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + foreach $section (@{$args{'sectionlist'}}) { + print "<h3>$section</h3>\n"; + print "<ul>\n"; + output_highlight($args{'sections'}{$section}); + print "</ul>\n"; + } + print "<hr>\n"; +} + +sub output_section_sgml(%) { + my %args = %{$_[0]}; + my $section; + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "<refsect1>\n <title>$section</title>\n <para>\n"; + if ($section =~ m/EXAMPLE/i) { + print "<example><para>\n"; + } + output_highlight($args{'sections'}{$section}); + if ($section =~ m/EXAMPLE/i) { + print "</para></example>\n"; + } + print " </para>\n</refsect1>\n"; + } +} + +# output function in sgml DocBook +sub output_function_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $id; + + $id = "API-".$args{'function'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>".$args{'function'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <funcsynopsis><funcprototype>\n"; + print " <funcdef>".$args{'functiontype'}." "; + print "<function>".$args{'function'}." </function></funcdef>\n"; + + $count = 0; + if ($#{$args{'parameterlist'}} >= 0) { + foreach $parameter (@{$args{'parameterlist'}}) { + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print " <paramdef>$1<parameter>$parameter</parameter>)\n"; + print " <funcparams>$2</funcparams></paramdef>\n"; + } else { + print " <paramdef>".$type; + print " <parameter>$parameter</parameter></paramdef>\n"; + } + } + } else { + print " <void>\n"; + } + print " </funcprototype></funcsynopsis>\n"; + print "</refsynopsisdiv>\n"; + + # print parameters + print "<refsect1>\n <title>Arguments</title>\n"; + if ($#{$args{'parameterlist'}} >= 0) { + print " <variablelist>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n"; + print " <listitem>\n <para>\n"; + $lineprefix=" "; + output_highlight($args{'parameterdescs'}{$parameter}); + print " </para>\n </listitem>\n </varlistentry>\n"; + } + print " </variablelist>\n"; + } else { + print " <para>\n None\n </para>\n"; + } + print "</refsect1>\n"; + + output_section_sgml(@_); + print "</refentry>\n\n"; +} + +# output struct in sgml DocBook +sub output_struct_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $id; + + $id = "API-struct-".$args{'struct'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <programlisting>\n"; + print $args{'type'}." ".$args{'struct'}." {\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print " $1 $parameter ($2);\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print " $1 $parameter$2;\n"; + } else { + print " ".$type." ".$parameter.";\n"; + } + } + print "};"; + print " </programlisting>\n"; + print "</refsynopsisdiv>\n"; + + print " <refsect1>\n"; + print " <title>Members</title>\n"; + + print " <variablelist>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print " <varlistentry>"; + print " <term>$parameter</term>\n"; + print " <listitem><para>\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + print " </para></listitem>\n"; + print " </varlistentry>\n"; + } + print " </variablelist>\n"; + print " </refsect1>\n"; + + output_section_sgml(@_); + + print "</refentry>\n\n"; +} + +# output enum in sgml DocBook +sub output_enum_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $id; + + $id = "API-enum-".$args{'enum'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>enum ".$args{'enum'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <programlisting>\n"; + print "enum ".$args{'enum'}." {\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print " $parameter"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ","; + } + print "\n"; + } + print "};"; + print " </programlisting>\n"; + print "</refsynopsisdiv>\n"; + + print "<refsect1>\n"; + print " <title>Constants</title>\n"; + print " <variablelist>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <varlistentry>"; + print " <term>$parameter</term>\n"; + print " <listitem><para>\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + print " </para></listitem>\n"; + print " </varlistentry>\n"; + } + print " </variablelist>\n"; + print "</refsect1>\n"; + + output_section_sgml(@_); + + print "</refentry>\n\n"; +} + +# output typedef in sgml DocBook +sub output_typedef_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $id; + + $id = "API-typedef-".$args{'typedef'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>typedef ".$args{'typedef'}."</refname>\n"; + print " <refpurpose>\n"; + print " "; + output_highlight ($args{'purpose'}); + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n"; + print "</refsynopsisdiv>\n"; + + output_section_sgml(@_); + + print "</refentry>\n\n"; +} + +# output in sgml DocBook +sub output_intro_sgml(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + my $id = $args{'module'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "<refsect1>\n <title>$section</title>\n <para>\n"; + if ($section =~ m/EXAMPLE/i) { + print "<example><para>\n"; + } + output_highlight($args{'sections'}{$section}); + if ($section =~ m/EXAMPLE/i) { + print "</para></example>\n"; + } + print " </para>\n</refsect1>\n"; + } + + print "\n\n"; +} + +# output in sgml DocBook +sub output_function_gnome { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $id; + + $id = $args{'module'}."-".$args{'function'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<sect2>\n"; + print " <title id=\"$id\">".$args{'function'}."</title>\n"; + + print " <funcsynopsis>\n"; + print " <funcdef>".$args{'functiontype'}." "; + print "<function>".$args{'function'}." "; + print "</function></funcdef>\n"; + + $count = 0; + if ($#{$args{'parameterlist'}} >= 0) { + foreach $parameter (@{$args{'parameterlist'}}) { + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print " <paramdef>$1 <parameter>$parameter</parameter>)\n"; + print " <funcparams>$2</funcparams></paramdef>\n"; + } else { + print " <paramdef>".$type; + print " <parameter>$parameter</parameter></paramdef>\n"; + } + } + } else { + print " <void>\n"; + } + print " </funcsynopsis>\n"; + if ($#{$args{'parameterlist'}} >= 0) { + print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n"; + print "<tgroup cols=\"2\">\n"; + print "<colspec colwidth=\"2*\">\n"; + print "<colspec colwidth=\"8*\">\n"; + print "<tbody>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n"; + print " <entry>\n"; + $lineprefix=" "; + output_highlight($args{'parameterdescs'}{$parameter}); + print " </entry></row>\n"; + } + print " </tbody></tgroup></informaltable>\n"; + } else { + print " <para>\n None\n </para>\n"; + } + + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "<simplesect>\n <title>$section</title>\n"; + if ($section =~ m/EXAMPLE/i) { + print "<example><programlisting>\n"; + } else { + } + print "<para>\n"; + output_highlight($args{'sections'}{$section}); + print "</para>\n"; + if ($section =~ m/EXAMPLE/i) { + print "</programlisting></example>\n"; + } else { + } + print " </simplesect>\n"; + } + + print "</sect2>\n\n"; +} + +## +# output function in man +sub output_function_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"25 May 1998\" \"Kernel Hacker's Manual\" LINUX\n"; + + print ".SH NAME\n"; + print $args{'function'}." \\- ".$args{'purpose'}."\n"; + + print ".SH SYNOPSIS\n"; + print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n"; + $count = 0; + my $parenth = "("; + my $post = ","; + foreach my $parameter (@{$args{'parameterlist'}}) { + if ($count == $#{$args{'parameterlist'}}) { + $post = ");"; + } + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n"; + } else { + $type =~ s/([^\*])$/$1 /; + print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n"; + } + $count++; + $parenth = ""; + } + + print ".SH ARGUMENTS\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print ".IP \"".$parameter."\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"", uc $section, "\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output enum in man +sub output_enum_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n"; + + print ".SH SYNOPSIS\n"; + print "enum ".$args{'enum'}." {\n"; + $count = 0; + foreach my $parameter (@{$args{'parameterlist'}}) { + print ".br\n.BI \" $parameter\"\n"; + if ($count == $#{$args{'parameterlist'}}) { + print "\n};\n"; + last; + } + else { + print ", \n.br\n"; + } + $count++; + } + + print ".SH Constants\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print ".IP \"".$parameter."\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output struct in man +sub output_struct_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n"; + + print ".SH SYNOPSIS\n"; + print $args{'type'}." ".$args{'struct'}." {\n"; + + foreach my $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "\n.br\n"; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print ".BI \" ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print ".BI \" ".$1."\" ".$parameter.$2." \""."\"\n;\n"; + } else { + $type =~ s/([^\*])$/$1 /; + print ".BI \" ".$type."\" ".$parameter." \""."\"\n;\n"; + } + print "\n.br\n"; + } + print "};\n.br\n"; + + print ".SH Arguments\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print ".IP \"".$parameter."\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output typedef in man +sub output_typedef_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n"; + + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +sub output_intro_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output in text +sub output_function_text(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print "Function:\n\n"; + my $start=$args{'functiontype'}." ".$args{'function'}." ("; + print $start; + my $count = 0; + foreach my $parameter (@{$args{'parameterlist'}}) { + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print $1.$parameter.") (".$2; + } else { + print $type." ".$parameter; + } + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ",\n"; + print " " x length($start); + } else { + print ");\n\n"; + } + } + + print "Arguments:\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print $parameter."\n\t".$args{'parameterdescs'}{$parameter}."\n"; + } + output_section_text(@_); +} + +#output sections in text +sub output_section_text(%) { + my %args = %{$_[0]}; + my $section; + + print "\n"; + foreach $section (@{$args{'sectionlist'}}) { + print "$section:\n\n"; + output_highlight($args{'sections'}{$section}); + } + print "\n\n"; +} + +# output enum in text +sub output_enum_text(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "Enum:\n\n"; + + print "enum ".$args{'enum'}." {\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print "\t$parameter"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ","; + } + print "\n"; + } + print "};\n\n"; + + print "Constants:\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "$parameter\n\t"; + print $args{'parameterdescs'}{$parameter}."\n"; + } + + output_section_text(@_); +} + +# output typedef in text +sub output_typedef_text(%) { + my %args = %{$_[0]}; + my ($parameter); + my $count; + print "Typedef:\n\n"; + + print "typedef ".$args{'typedef'}."\n"; + output_section_text(@_); +} + +# output struct as text +sub output_struct_text(%) { + my %args = %{$_[0]}; + my ($parameter); + + print $args{'type'}." ".$args{'struct'}.":\n\n"; + print $args{'type'}." ".$args{'struct'}." {\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { + # pointer-to-function + print "\t$1 $parameter) ($2);\n"; + } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + print "\t$1 $parameter$2;\n"; + } else { + print "\t".$type." ".$parameter.";\n"; + } + } + print "};\n\n"; + + print "Members:\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($args{'parameterdescs'}{$parameter} ne $undescribed) || next; + print "$parameter\n\t"; + print $args{'parameterdescs'}{$parameter}."\n"; + } + print "\n"; + output_section_text(@_); +} + +sub output_intro_text(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + foreach $section (@{$args{'sectionlist'}}) { + print " $section:\n"; + print " -> "; + output_highlight($args{'sections'}{$section}); + } +} + +## +# generic output function for typedefs +sub output_declaration { + no strict 'refs'; + my $name = shift; + my $functype = shift; + my $func = "output_${functype}_$output_mode"; + if (($function_only==0) || + ( $function_only == 1 && defined($function_table{$name})) || + ( $function_only == 2 && !defined($function_table{$name}))) + { + &$func(@_); + $section_counter++; + } +} + +## +# generic output function - calls the right one based +# on current output mode. +sub output_intro { + no strict 'refs'; + my $func = "output_intro_".$output_mode; + &$func(@_); + $section_counter++; +} + +## +# takes a declaration (struct, union, enum, typedef) and +# invokes the right handler. NOT called for functions. +sub dump_declaration($$) { + no strict 'refs'; + my ($prototype, $file) = @_; + my $func = "dump_".$decl_type; + &$func(@_); +} + +sub dump_union($$) { + dump_struct(@_); +} + +sub dump_struct($$) { + my $x = shift; + my $file = shift; + + if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { + $declaration_name = $2; + my $members = $3; + + # ignore embedded structs or unions + $members =~ s/{.*}//g; + + create_parameterlist($members, ';', $file); + + output_declaration($declaration_name, + 'struct', + {'struct' => $declaration_name, + 'module' => $modulename, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose, + 'type' => $decl_type + }); + } + else { + print STDERR "Error(${file}:$.): Cannot parse struct or union!\n"; + ++$errors; + } +} + +sub dump_enum($$) { + my $x = shift; + my $file = shift; + + if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { + $declaration_name = $1; + my $members = $2; + + foreach my $arg (split ',', $members) { + $arg =~ s/^\s*(\w+).*/$1/; + push @parameterlist, $arg; + if (!$parameterdescs{$arg}) { + $parameterdescs{$arg} = $undescribed; + print STDERR "Warning(${file}:$.): Enum value '$arg' ". + "not described in enum '$declaration_name'\n"; + } + + } + + output_declaration($declaration_name, + 'enum', + {'enum' => $declaration_name, + 'module' => $modulename, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } + else { + print STDERR "Error(${file}:$.): Cannot parse enum!\n"; + ++$errors; + } +} + +sub dump_typedef($$) { + my $x = shift; + my $file = shift; + + while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { + $x =~ s/\(*.\)\s*;$/;/; + $x =~ s/\[*.\]\s*;$/;/; + } + + if ($x =~ /typedef.*\s+(\w+)\s*;/) { + $declaration_name = $1; + + output_declaration($declaration_name, + 'typedef', + {'typedef' => $declaration_name, + 'module' => $modulename, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } + else { + print STDERR "Error(${file}:$.): Cannot parse typedef!\n"; + ++$errors; + } +} + +sub create_parameterlist($$$) { + my $args = shift; + my $splitter = shift; + my $file = shift; + my $type; + my $param; + + while ($args =~ /(\([^\),]+),/) { + $args =~ s/(\([^\),]+),/$1#/g; + } + + foreach my $arg (split($splitter, $args)) { + # strip leading/trailing spaces + $arg =~ s/^\s*//; + $arg =~ s/\s*$//; + $arg =~ s/\s+/ /; + + if ($arg =~ m/\(/) { + # pointer-to-function + $arg =~ tr/#/,/; + $arg =~ m/[^\(]+\(\*([^\)]+)\)/; + $param = $1; + $type = $arg; + $type =~ s/([^\(]+\(\*)$param/$1/; + } else { + # evil magic to get fixed array parameters to work + $arg =~ s/(.+\s+)(.+)\[.*/$1* $2/; + my @args = split('\s', $arg); + + $param = pop @args; + if ($param =~ m/^(\*+)(.*)/) { + $param = $2; + push @args, $1; + } + elsif ($param =~ m/(.*?)\s*:\s*(\d+)/) { + $param = $1; + push @args, ":$2"; + } + $type = join " ", @args; + } + + if ($type eq "" && $param eq "...") + { + $type="..."; + $param="..."; + $parameterdescs{"..."} = "variable arguments"; + } + elsif ($type eq "" && ($param eq "" or $param eq "void")) + { + $type=""; + $param="void"; + $parameterdescs{void} = "no arguments"; + } + if (defined $type && $type && !defined $parameterdescs{$param}) { + $parameterdescs{$param} = $undescribed; + + if (($type eq 'function') || ($type eq 'enum')) { + print STDERR "Warning(${file}:$.): Function parameter ". + "or member '$param' not " . + "described in '$declaration_name'\n"; + } + ++$errors; + } + + push @parameterlist, $param; + $parametertypes{$param} = $type; + } +} + +## +# takes a function prototype and the name of the current file being +# processed and spits out all the details stored in the global +# arrays/hashes. +sub dump_function($$) { + my $prototype = shift; + my $file = shift; + + $prototype =~ s/^static +//; + $prototype =~ s/^extern +//; + $prototype =~ s/^inline +//; + $prototype =~ s/^__inline__ +//; + $prototype =~ s/^#define +//; #ak added + + # Yes, this truly is vile. We are looking for: + # 1. Return type (may be nothing if we're looking at a macro) + # 2. Function name + # 3. Function parameters. + # + # All the while we have to watch out for function pointer parameters + # (which IIRC is what the two sections are for), C types (these + # regexps don't even start to express all the possibilities), and + # so on. + # + # If you mess with these regexps, it's a good idea to check that + # the following functions' documentation still comes out right: + # - parport_register_device (function pointer parameters) + # - atomic_set (macro) + # - pci_match_device (long return type) + + if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || + $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || + $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || + $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || + $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) { + $return_type = $1; + $declaration_name = $2; + my $args = $3; + + create_parameterlist($args, ',', $file); + } else { + print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n"; + ++$errors; + return; + } + + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); +} + +sub process_file($); + +# Read the file that maps relative names to absolute names for +# separate source and object directories and for shadow trees. +if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { + my ($relname, $absname); + while(<SOURCE_MAP>) { + chop(); + ($relname, $absname) = (split())[0..1]; + $relname =~ s:^/+::; + $source_map{$relname} = $absname; + } + close(SOURCE_MAP); +} + +if ($filelist) { + open(FLIST,"<$filelist") or die "Can't open file list $filelist"; + while(<FLIST>) { + chop; + process_file($_); + } +} + +foreach (@ARGV) { + chomp; + process_file($_); +} + +exit($errors); + +sub reset_state { + $function = ""; + %constants = (); + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + + $state = 0; +} + +sub process_state3_function($$) { + my $x = shift; + my $file = shift; + + if ($x =~ m#\s*/\*\s+MACDOC\s*#io) { + # do nothing + } + elsif ($x =~ /([^\{]*)/) { + $prototype .= $1; + } + if (($x =~ /\{/) || ($x =~ /\#/) || ($x =~ /;/)) { + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $prototype =~ s@^\s+@@gos; # strip leading spaces + dump_function($prototype,$file); + reset_state(); + } +} + +sub process_state3_type($$) { + my $x = shift; + my $file = shift; + + $x =~ s@/\*.*?\*/@@gos; # strip comments. + $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $x =~ s@^\s+@@gos; # strip leading spaces + $x =~ s@\s+$@@gos; # strip trailing spaces + + while (1) { + if ( $x =~ /([^{};]*)([{};])(.*)/ ) { + $prototype .= $1 . $2; + ($2 eq '{') && $brcount++; + ($2 eq '}') && $brcount--; + if (($2 eq ';') && ($brcount == 0)) { + dump_declaration($prototype,$file); + reset_state(); + last; + } + $x = $3; + } else { + $prototype .= $x; + last; + } + } +} + +sub process_file($) { + my ($file) = @_; + my $identifier; + my $func; + my $initial_section_counter = $section_counter; + + if (defined($source_map{$file})) { + $file = $source_map{$file}; + } + + if (!open(IN,"<$file")) { + print STDERR "Error: Cannot open file $file\n"; + ++$errors; + return; + } + + $section_counter = 0; + while (<IN>) { + if ($state == 0) { + if (/$doc_start/o) { + $state = 1; # next line is always the function name + } + } elsif ($state == 1) { # this line is the function name (always) + if (/$doc_block/o) { + $state = 4; + $contents = ""; + if ( $1 eq "" ) { + $section = $section_intro; + } else { + $section = $1; + } + } + elsif (/$doc_decl/o) { + $identifier = $1; + if (/\s*([\w\s]+?)\s*-/) { + $identifier = $1; + } + + $state = 2; + if (/-(.*)/) { + $declaration_purpose = $1; + } else { + $declaration_purpose = ""; + } + if ($identifier =~ m/^struct/) { + $decl_type = 'struct'; + } elsif ($identifier =~ m/^union/) { + $decl_type = 'union'; + } elsif ($identifier =~ m/^enum/) { + $decl_type = 'enum'; + } elsif ($identifier =~ m/^typedef/) { + $decl_type = 'typedef'; + } else { + $decl_type = 'function'; + } + + if ($verbose) { + print STDERR "Info(${file}:$.): Scanning doc for $identifier\n"; + } + } else { + print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.", + " - I thought it was a doc line\n"; + ++$errors; + $state = 0; + } + } elsif ($state == 2) { # look for head: lines, and include content + if (/$doc_sect/o) { + $newsection = $1; + $newcontents = $2; + + if ($contents ne "") { + $contents =~ s/\&/\\\\\\amp;/g; + $contents =~ s/\</\\\\\\lt;/g; + $contents =~ s/\>/\\\\\\gt;/g; + dump_section($section, $contents); + $section = $section_default; + } + + $contents = $newcontents; + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + } elsif (/$doc_end/) { + + if ($contents ne "") { + $contents =~ s/\&/\\\\\\amp;/g; + $contents =~ s/\</\\\\\\lt;/g; + $contents =~ s/\>/\\\\\\gt;/g; + dump_section($section, $contents); + $section = $section_default; + $contents = ""; + } + + $prototype = ""; + $state = 3; + $brcount = 0; +# print STDERR "end of doc comment, looking for prototype\n"; + } elsif (/$doc_content/) { + # miguel-style comment kludge, look for blank lines after + # @parameter line to signify start of description + if ($1 eq "" && + ($section =~ m/^@/ || $section eq $section_context)) { + $contents =~ s/\&/\\\\\\amp;/g; + $contents =~ s/\</\\\\\\lt;/g; + $contents =~ s/\>/\\\\\\gt;/g; + dump_section($section, $contents); + $section = $section_default; + $contents = ""; + } else { + $contents .= $1."\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "Warning(${file}:$.): bad line: $_"; + ++$errors; + } + } elsif ($state == 3) { # scanning for function { (end of prototype) + if ($decl_type eq 'function') { + process_state3_function($_, $file); + } else { + process_state3_type($_, $file); + } + } elsif ($state == 4) { + # Documentation block + if (/$doc_block/) { + dump_section($section, $contents); + output_intro({'sectionlist' => \@sectionlist, + 'sections' => \%sections }); + $contents = ""; + $function = ""; + %constants = (); + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + if ( $1 eq "" ) { + $section = $section_intro; + } else { + $section = $1; + } + } + elsif (/$doc_end/) + { + dump_section($section, $contents); + output_intro({'sectionlist' => \@sectionlist, + 'sections' => \%sections }); + $contents = ""; + $function = ""; + %constants = (); + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + $state = 0; + } + elsif (/$doc_content/) + { + if ( $1 eq "" ) + { + $contents .= $blankline; + } + else + { + $contents .= $1 . "\n"; + } + } + } + } + if ($initial_section_counter == $section_counter) { + print STDERR "Warning(${file}): no structured comments found\n"; + if ($output_mode eq "sgml") { + # The template wants at least one RefEntry here; make one. + print "<refentry>\n"; + print " <refnamediv>\n"; + print " <refname>\n"; + print " ${file}\n"; + print " </refname>\n"; + print " <refpurpose>\n"; + print " Document generation inconsistency\n"; + print " </refpurpose>\n"; + print " </refnamediv>\n"; + print " <refsect1>\n"; + print " <title>\n"; + print " Oops\n"; + print " </title>\n"; + print " <warning>\n"; + print " <para>\n"; + print " The template for this document tried to insert\n"; + print " the structured comment from the file\n"; + print " <filename>${file}</filename> at this point,\n"; + print " but none was found.\n"; + print " This dummy section is inserted to allow\n"; + print " generation to continue.\n"; + print " </para>\n"; + print " </warning>\n"; + print " </refsect1>\n"; + print "</refentry>\n"; + } + } +} diff --git a/uClinux-2.4.31-uc0/scripts/ksymoops/README b/uClinux-2.4.31-uc0/scripts/ksymoops/README new file mode 100644 index 0000000..f6cb06e --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/ksymoops/README @@ -0,0 +1,8 @@ +ksymoops has been removed from the kernel. It was always meant to be a +free standing utility, not linked to any particular kernel version. +The latest version can be found in +ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together +with patches to other utilities in order to give more accurate Oops +debugging. + +Keith Owens <kaos@ocs.com.au> Sat Jun 19 10:30:34 EST 1999 diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/BIG.FAT.WARNING b/uClinux-2.4.31-uc0/scripts/lxdialog/BIG.FAT.WARNING new file mode 100644 index 0000000..a8999d8 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/BIG.FAT.WARNING @@ -0,0 +1,4 @@ +This is NOT the official version of dialog. This version has been +significantly modified from the original. It is for use by the Linux +kernel configuration script. Please do not bother Savio Lam with +questions about this program. diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/Makefile b/uClinux-2.4.31-uc0/scripts/lxdialog/Makefile new file mode 100644 index 0000000..ed8d17c --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/Makefile @@ -0,0 +1,46 @@ +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) + +ncurses: + @echo "main() {}" > lxtemp.c + @if $(HOSTCC) -lncurses lxtemp.c ; 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 diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/checklist.c b/uClinux-2.4.31-uc0/scripts/lxdialog/checklist.c new file mode 100644 index 0000000..4f78688 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/checklist.c @@ -0,0 +1,369 @@ +/* + * checklist.c -- implements the checklist box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension + * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static int list_width, check_x, item_x, checkflag; + +/* + * Print list item + */ +static void +print_item (WINDOW * win, const char *item, int status, + int choice, int selected) +{ + int i; + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); + for (i = 0; i < list_width; i++) + waddch (win, ' '); + + wmove (win, choice, check_x); + wattrset (win, selected ? check_selected_attr : check_attr); + if (checkflag == FLAG_CHECK) + wprintw (win, "[%c]", status ? 'X' : ' '); + else + wprintw (win, "(%c)", status ? 'X' : ' '); + + wattrset (win, selected ? tag_selected_attr : tag_attr); + mvwaddch(win, choice, item_x, item[0]); + wattrset (win, selected ? item_selected_attr : item_attr); + waddstr (win, (char *)item+1); + if (selected) { + wmove (win, choice, check_x+1); + wrefresh (win); + } +} + +/* + * Print the scroll indicators. + */ +static void +print_arrows (WINDOW * win, int choice, int item_no, int scroll, + int y, int x, int height) +{ + wmove(win, y, x); + + if (scroll > 0) { + wattrset (win, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + choice < item_no - 1)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } +} + +/* + * Display the termination buttons + */ +static void +print_buttons( WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button (dialog, "Select", y, x, selected == 0); + print_button (dialog, " Help ", y, x + 14, selected == 1); + + wmove(dialog, y, x+1 + 14*selected); + wrefresh (dialog); +} + +/* + * Display a dialog box with a list of options that can be turned on or off + * The `flag' parameter is used to select between radiolist and checklist. + */ +int +dialog_checklist (const char *title, const char *prompt, int height, int width, + int list_height, int item_no, const char * const * items, int flag) + +{ + int i, x, y, box_x, box_y; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; + WINDOW *dialog, *list; + + checkflag = flag; + + /* Allocate space for storing item on/off status */ + if ((status = malloc (sizeof (int) * item_no)) == NULL) { + endwin (); + fprintf (stderr, + "\nCan't allocate memory in dialog_checklist().\n"); + exit (-1); + } + + /* Initializes status */ + for (i = 0; i < item_no; i++) { + status[i] = !strcasecmp (items[i * 3 + 2], "on"); + if (!choice && status[i]) + choice = i; + } + + max_choice = MIN (list_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + list_width = width - 6; + box_y = height - list_height - 5; + box_x = (width - list_width) / 2 - 1; + + /* create new window for the list */ + list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1); + + keypad (list, TRUE); + + /* draw a box around the list items */ + draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2, + menubox_border_attr, menubox_attr); + + /* Find length of longest item in order to center checklist */ + check_x = 0; + for (i = 0; i < item_no; i++) + check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4); + + check_x = (list_width - check_x) / 2; + item_x = check_x + 4; + + if (choice >= list_height) { + scroll = choice - list_height + 1; + choice -= scroll; + } + + /* Print the list */ + for (i = 0; i < max_choice; i++) { + print_item (list, items[(scroll+i) * 3 + 1], + status[i+scroll], i, i == choice); + } + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + print_buttons(dialog, height, width, 0); + + wnoutrefresh (list); + wnoutrefresh (dialog); + doupdate (); + + while (key != ESC) { + key = wgetch (dialog); + + for (i = 0; i < max_choice; i++) + if (toupper(key) == toupper(items[(scroll+i)*3+1][0])) + break; + + + if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || + key == '+' || key == '-' ) { + if (key == KEY_UP || key == '-') { + if (!choice) { + if (!scroll) + continue; + /* Scroll list down */ + if (list_height > 1) { + /* De-highlight current first item */ + print_item (list, items[scroll * 3 + 1], + status[scroll], 0, FALSE); + scrollok (list, TRUE); + wscrl (list, -1); + scrollok (list, FALSE); + } + scroll--; + print_item (list, items[scroll * 3 + 1], + status[scroll], 0, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice - 1; + } else if (key == KEY_DOWN || key == '+') { + if (choice == max_choice - 1) { + if (scroll + choice >= item_no - 1) + continue; + /* Scroll list up */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + print_item (list, items[(scroll + max_choice - 1) * 3 + 1], + status[scroll + max_choice - 1], + max_choice - 1, FALSE); + scrollok (list, TRUE); + scroll (list); + scrollok (list, FALSE); + } + scroll++; + print_item (list, items[(scroll + max_choice - 1) * 3 + 1], + status[scroll + max_choice - 1], + max_choice - 1, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice + 1; + } + if (i != choice) { + /* De-highlight current item */ + print_item (list, items[(scroll + choice) * 3 + 1], + status[scroll + choice], choice, FALSE); + /* Highlight new item */ + choice = i; + print_item (list, items[(scroll + choice) * 3 + 1], + status[scroll + choice], choice, TRUE); + wnoutrefresh (list); + wrefresh (dialog); + } + continue; /* wait for another key press */ + } + switch (key) { + case 'H': + case 'h': + case '?': + delwin (dialog); + free (status); + return 1; + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case 'S': + case 's': + case ' ': + case '\n': + if (!button) { + if (flag == FLAG_CHECK) { + status[scroll + choice] = !status[scroll + choice]; + wmove (list, choice, check_x); + wattrset (list, check_selected_attr); + wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' '); + } else { + if (!status[scroll + choice]) { + for (i = 0; i < item_no; i++) + status[i] = 0; + status[scroll + choice] = 1; + for (i = 0; i < max_choice; i++) + print_item (list, items[(scroll + i) * 3 + 1], + status[scroll + i], i, i == choice); + } + } + wnoutrefresh (list); + 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]); + } + + } + } + } + delwin (dialog); + free (status); + return button; + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + + /* Now, update everything... */ + doupdate (); + } + + + delwin (dialog); + free (status); + return -1; /* ESC pressed */ +} diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/colors.h b/uClinux-2.4.31-uc0/scripts/lxdialog/colors.h new file mode 100644 index 0000000..d34dd37 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/colors.h @@ -0,0 +1,161 @@ +/* + * colors.h -- color attribute definitions + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +/* + * Default color definitions + * + * *_FG = foreground + * *_BG = background + * *_HL = highlight? + */ +#define SCREEN_FG COLOR_CYAN +#define SCREEN_BG COLOR_BLUE +#define SCREEN_HL TRUE + +#define SHADOW_FG COLOR_BLACK +#define SHADOW_BG COLOR_BLACK +#define SHADOW_HL TRUE + +#define DIALOG_FG COLOR_BLACK +#define DIALOG_BG COLOR_WHITE +#define DIALOG_HL FALSE + +#define TITLE_FG COLOR_YELLOW +#define TITLE_BG COLOR_WHITE +#define TITLE_HL TRUE + +#define BORDER_FG COLOR_WHITE +#define BORDER_BG COLOR_WHITE +#define BORDER_HL TRUE + +#define BUTTON_ACTIVE_FG COLOR_WHITE +#define BUTTON_ACTIVE_BG COLOR_BLUE +#define BUTTON_ACTIVE_HL TRUE + +#define BUTTON_INACTIVE_FG COLOR_BLACK +#define BUTTON_INACTIVE_BG COLOR_WHITE +#define BUTTON_INACTIVE_HL FALSE + +#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE +#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE +#define BUTTON_KEY_ACTIVE_HL TRUE + +#define BUTTON_KEY_INACTIVE_FG COLOR_RED +#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE +#define BUTTON_KEY_INACTIVE_HL FALSE + +#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW +#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE +#define BUTTON_LABEL_ACTIVE_HL TRUE + +#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK +#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE +#define BUTTON_LABEL_INACTIVE_HL TRUE + +#define INPUTBOX_FG COLOR_BLACK +#define INPUTBOX_BG COLOR_WHITE +#define INPUTBOX_HL FALSE + +#define INPUTBOX_BORDER_FG COLOR_BLACK +#define INPUTBOX_BORDER_BG COLOR_WHITE +#define INPUTBOX_BORDER_HL FALSE + +#define SEARCHBOX_FG COLOR_BLACK +#define SEARCHBOX_BG COLOR_WHITE +#define SEARCHBOX_HL FALSE + +#define SEARCHBOX_TITLE_FG COLOR_YELLOW +#define SEARCHBOX_TITLE_BG COLOR_WHITE +#define SEARCHBOX_TITLE_HL TRUE + +#define SEARCHBOX_BORDER_FG COLOR_WHITE +#define SEARCHBOX_BORDER_BG COLOR_WHITE +#define SEARCHBOX_BORDER_HL TRUE + +#define POSITION_INDICATOR_FG COLOR_YELLOW +#define POSITION_INDICATOR_BG COLOR_WHITE +#define POSITION_INDICATOR_HL TRUE + +#define MENUBOX_FG COLOR_BLACK +#define MENUBOX_BG COLOR_WHITE +#define MENUBOX_HL FALSE + +#define MENUBOX_BORDER_FG COLOR_WHITE +#define MENUBOX_BORDER_BG COLOR_WHITE +#define MENUBOX_BORDER_HL TRUE + +#define ITEM_FG COLOR_BLACK +#define ITEM_BG COLOR_WHITE +#define ITEM_HL FALSE + +#define ITEM_SELECTED_FG COLOR_WHITE +#define ITEM_SELECTED_BG COLOR_BLUE +#define ITEM_SELECTED_HL TRUE + +#define TAG_FG COLOR_YELLOW +#define TAG_BG COLOR_WHITE +#define TAG_HL TRUE + +#define TAG_SELECTED_FG COLOR_YELLOW +#define TAG_SELECTED_BG COLOR_BLUE +#define TAG_SELECTED_HL TRUE + +#define TAG_KEY_FG COLOR_YELLOW +#define TAG_KEY_BG COLOR_WHITE +#define TAG_KEY_HL TRUE + +#define TAG_KEY_SELECTED_FG COLOR_YELLOW +#define TAG_KEY_SELECTED_BG COLOR_BLUE +#define TAG_KEY_SELECTED_HL TRUE + +#define CHECK_FG COLOR_BLACK +#define CHECK_BG COLOR_WHITE +#define CHECK_HL FALSE + +#define CHECK_SELECTED_FG COLOR_WHITE +#define CHECK_SELECTED_BG COLOR_BLUE +#define CHECK_SELECTED_HL TRUE + +#define UARROW_FG COLOR_GREEN +#define UARROW_BG COLOR_WHITE +#define UARROW_HL TRUE + +#define DARROW_FG COLOR_GREEN +#define DARROW_BG COLOR_WHITE +#define DARROW_HL TRUE + +/* End of default color definitions */ + +#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) +#define COLOR_NAME_LEN 10 +#define COLOR_COUNT 8 + +/* + * Global variables + */ + +typedef struct { + char name[COLOR_NAME_LEN]; + int value; +} color_names_st; + +extern color_names_st color_names[]; +extern int color_table[][3]; diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/dialog.h b/uClinux-2.4.31-uc0/scripts/lxdialog/dialog.h new file mode 100644 index 0000000..0e30d00 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/dialog.h @@ -0,0 +1,184 @@ + +/* + * dialog.h -- common declarations for all dialog modules + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +#include CURSES_LOC + +/* + * Colors in ncurses 1.9.9e do not work properly since foreground and + * background colors are OR'd rather than separately masked. This version + * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible + * with standard curses. The simplest fix (to make this work with standard + * curses) uses the wbkgdset() function, not used in the original hack. + * Turn it off if we're building with 1.9.9e, since it just confuses things. + */ +#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) +#define OLD_NCURSES 1 +#undef wbkgdset +#define wbkgdset(w,p) /*nothing*/ +#else +#define OLD_NCURSES 0 +#endif + +#define TR(params) _tracef params + +#define ESC 27 +#define TAB 9 +#define MAX_LEN 2048 +#define BUF_SIZE (10*1024) +#define MIN(x,y) (x < y ? x : y) +#define MAX(x,y) (x > y ? x : y) + + +#ifndef ACS_ULCORNER +#define ACS_ULCORNER '+' +#endif +#ifndef ACS_LLCORNER +#define ACS_LLCORNER '+' +#endif +#ifndef ACS_URCORNER +#define ACS_URCORNER '+' +#endif +#ifndef ACS_LRCORNER +#define ACS_LRCORNER '+' +#endif +#ifndef ACS_HLINE +#define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +#define ACS_VLINE '|' +#endif +#ifndef ACS_LTEE +#define ACS_LTEE '+' +#endif +#ifndef ACS_RTEE +#define ACS_RTEE '+' +#endif +#ifndef ACS_UARROW +#define ACS_UARROW '^' +#endif +#ifndef ACS_DARROW +#define ACS_DARROW 'v' +#endif + +/* + * Attribute names + */ +#define screen_attr attributes[0] +#define shadow_attr attributes[1] +#define dialog_attr attributes[2] +#define title_attr attributes[3] +#define border_attr attributes[4] +#define button_active_attr attributes[5] +#define button_inactive_attr attributes[6] +#define button_key_active_attr attributes[7] +#define button_key_inactive_attr attributes[8] +#define button_label_active_attr attributes[9] +#define button_label_inactive_attr attributes[10] +#define inputbox_attr attributes[11] +#define inputbox_border_attr attributes[12] +#define searchbox_attr attributes[13] +#define searchbox_title_attr attributes[14] +#define searchbox_border_attr attributes[15] +#define position_indicator_attr attributes[16] +#define menubox_attr attributes[17] +#define menubox_border_attr attributes[18] +#define item_attr attributes[19] +#define item_selected_attr attributes[20] +#define tag_attr attributes[21] +#define tag_selected_attr attributes[22] +#define tag_key_attr attributes[23] +#define tag_key_selected_attr attributes[24] +#define check_attr attributes[25] +#define check_selected_attr attributes[26] +#define uarrow_attr attributes[27] +#define darrow_attr attributes[28] + +/* number of attributes */ +#define ATTRIBUTE_COUNT 29 + +/* + * Global variables + */ +extern bool use_colors; +extern bool use_shadow; + +extern chtype attributes[]; + +extern const char *backtitle; + +/* + * 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); +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); + +int first_alpha (const char *string, const char *exempt); +int dialog_yesno (const char *title, const char *prompt, int height, int width); +int dialog_msgbox (const char *title, const char *prompt, int height, + int width, int pause); +int dialog_textbox (const char *title, const char *file, int height, int width); +int dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *choice, int item_no, + const char * const * 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); +extern unsigned char dialog_input_result[]; +int dialog_inputbox (const char *title, const char *prompt, int height, + int width, const char *init); + +/* + * This is the base for fictitious keys, which activate + * the buttons. + * + * Mouse-generated keys are the following: + * -- the first 32 are used as numbers, in addition to '0'-'9' + * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') + * -- uppercase chars are used to invoke the button (M_EVENT + 'O') + */ +#define M_EVENT (KEY_MAX+1) + + +/* + * The `flag' parameter in checklist is used to select between + * radiolist and checklist + */ +#define FLAG_CHECK 1 +#define FLAG_RADIO 0 diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/inputbox.c b/uClinux-2.4.31-uc0/scripts/lxdialog/inputbox.c new file mode 100644 index 0000000..fa7bebc --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/inputbox.c @@ -0,0 +1,240 @@ +/* + * inputbox.c -- implements the input box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +unsigned char dialog_input_result[MAX_LEN + 1]; + +/* + * Print the termination buttons + */ +static void +print_buttons(WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button (dialog, " Ok ", y, x, selected==0); + print_button (dialog, " Help ", y, x + 14, selected==1); + + wmove(dialog, y, x+1+14*selected); + wrefresh(dialog); +} + +/* + * Display a dialog box for inputing a string + */ +int +dialog_inputbox (const char *title, const char *prompt, int height, int width, + const char *init) +{ + int i, x, y, box_y, box_x, box_width; + int input_x = 0, scroll = 0, key = 0, button = -1; + unsigned char *instr = dialog_input_result; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + /* Draw the input field box */ + box_width = width - 6; + getyx (dialog, y, x); + box_y = y + 2; + box_x = (width - box_width) / 2; + draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, + border_attr, dialog_attr); + + print_buttons(dialog, height, width, 0); + + /* Set up the initial value */ + wmove (dialog, box_y, box_x); + wattrset (dialog, inputbox_attr); + + if (!init) + instr[0] = '\0'; + else + strcpy (instr, init); + + input_x = strlen (instr); + + if (input_x >= box_width) { + scroll = input_x - box_width + 1; + input_x = box_width - 1; + for (i = 0; i < box_width - 1; i++) + waddch (dialog, instr[scroll + i]); + } else + waddstr (dialog, instr); + + wmove (dialog, box_y, box_x + input_x); + + wrefresh (dialog); + + while (key != ESC) { + key = wgetch (dialog); + + if (button == -1) { /* Input box selected */ + switch (key) { + case TAB: + case KEY_UP: + case KEY_DOWN: + break; + case KEY_LEFT: + continue; + case KEY_RIGHT: + continue; + case KEY_BACKSPACE: + case 127: + if (input_x || scroll) { + wattrset (dialog, inputbox_attr); + if (!input_x) { + scroll = scroll < box_width - 1 ? + 0 : scroll - (box_width - 1); + wmove (dialog, box_y, box_x); + for (i = 0; i < box_width; i++) + waddch (dialog, instr[scroll + input_x + i] ? + instr[scroll + input_x + i] : ' '); + input_x = strlen (instr) - scroll; + } else + input_x--; + instr[scroll + input_x] = '\0'; + mvwaddch (dialog, box_y, input_x + box_x, ' '); + wmove (dialog, box_y, input_x + box_x); + wrefresh (dialog); + } + continue; + default: + if (key < 0x100 && isprint (key)) { + if (scroll + input_x < MAX_LEN) { + wattrset (dialog, inputbox_attr); + instr[scroll + input_x] = key; + instr[scroll + input_x + 1] = '\0'; + if (input_x == box_width - 1) { + scroll++; + wmove (dialog, box_y, box_x); + for (i = 0; i < box_width - 1; i++) + waddch (dialog, instr[scroll + i]); + } else { + wmove (dialog, box_y, input_x++ + box_x); + waddch (dialog, key); + } + wrefresh (dialog); + } else + flash (); /* Alarm user about overflow */ + continue; + } + } + } + switch (key) { + case 'O': + case 'o': + delwin (dialog); + return 0; + case 'H': + case 'h': + delwin (dialog); + return 1; + case KEY_UP: + case KEY_LEFT: + switch (button) { + case -1: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 0: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove (dialog, box_y, box_x + input_x); + wrefresh (dialog); + break; + case 1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + } + break; + case TAB: + case KEY_DOWN: + case KEY_RIGHT: + switch (button) { + case -1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + case 0: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 1: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove (dialog, box_y, box_x + input_x); + wrefresh (dialog); + break; + } + break; + case ' ': + case '\n': + delwin (dialog); + return (button == -1 ? 0 : button); + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/lxdialog.c b/uClinux-2.4.31-uc0/scripts/lxdialog/lxdialog.c new file mode 100644 index 0000000..6f4c1fd --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/lxdialog.c @@ -0,0 +1,226 @@ +/* + * 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); +} + diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/menubox.c b/uClinux-2.4.31-uc0/scripts/lxdialog/menubox.c new file mode 100644 index 0000000..a234e9f --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/menubox.c @@ -0,0 +1,443 @@ +/* + * menubox.c -- implements the menu box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Changes by Clifford Wolf (god@clifford.at) + * + * [ 1998-06-13 ] + * + * *) A bugfix for the Page-Down problem + * + * *) Formerly when I used Page Down and Page Up, the cursor would be set + * to the first position in the menu box. Now lxdialog is a bit + * smarter and works more like other menu systems (just have a look at + * it). + * + * *) Formerly if I selected something my scrolling would be broken because + * lxdialog is re-invoked by the Menuconfig shell script, can't + * remember the last scrolling position, and just sets it so that the + * cursor is at the bottom of the box. Now it writes the temporary file + * lxdialog.scrltmp which contains this information. The file is + * deleted by lxdialog if the user leaves a submenu or enters a new + * one, but it would be nice if Menuconfig could make another "rm -f" + * just to be sure. Just try it out - you will recognise a difference! + * + * [ 1998-06-14 ] + * + * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files + * and menus change their size on the fly. + * + * *) If for some reason the last scrolling position is not saved by + * lxdialog, it sets the scrolling so that the selected item is in the + * middle of the menu box, not at the bottom. + * + * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) + * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus. + * This fixes a bug in Menuconfig where using ' ' to descend into menus + * would leave mis-synchronized lxdialog.scrltmp files lying around, + * fscanf would read in 'scroll', and eventually that value would get used. + */ + +#include "dialog.h" + +static int menu_width, item_x; + +/* + * Print menu item + */ +static void +print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey) +{ + int j; + char menu_item[menu_width+1]; + + strncpy(menu_item, item, menu_width); + menu_item[menu_width] = 0; + j = first_alpha(menu_item, "YyNnMm"); + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); +#if OLD_NCURSES + { + int i; + for (i = 0; i < menu_width; i++) + waddch (win, ' '); + } +#else + wclrtoeol(win); +#endif + wattrset (win, selected ? item_selected_attr : item_attr); + mvwaddstr (win, choice, item_x, menu_item); + if (hotkey) { + wattrset (win, selected ? tag_key_selected_attr : tag_key_attr); + mvwaddch(win, choice, item_x+j, menu_item[j]); + } + if (selected) { + wmove (win, choice, item_x+1); + wrefresh (win); + } +} + +/* + * Print the scroll indicators. + */ +static void +print_arrows (WINDOW * win, int item_no, int scroll, + int y, int x, int height) +{ + int cur_y, cur_x; + + getyx(win, cur_y, cur_x); + + wmove(win, y, x); + + if (scroll > 0) { + wattrset (win, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + height < item_no)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + wmove(win, cur_y, cur_x); +} + +/* + * Display the termination buttons. + */ +static void +print_buttons (WINDOW *win, int height, int width, int selected) +{ + int x = width / 2 - 16; + int y = height - 2; + + print_button (win, "Select", y, x, selected == 0); + print_button (win, " Exit ", y, x + 12, selected == 1); + print_button (win, " Help ", y, x + 24, selected == 2); + + wmove(win, y, x+1+12*selected); + wrefresh (win); +} + +/* + * Display a menu for choosing among a number of options + */ +int +dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *current, int item_no, + const char * const * items) + +{ + int i, j, x, y, box_x, box_y; + int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice; + WINDOW *dialog, *menu; + FILE *f; + + max_choice = MIN (menu_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + wbkgdset (dialog, dialog_attr & A_COLOR); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + menu_width = width - 6; + box_y = height - menu_height - 5; + box_x = (width - menu_width) / 2 - 1; + + /* create new window for the menu */ + menu = subwin (dialog, menu_height, menu_width, + y + box_y + 1, x + box_x + 1); + keypad (menu, TRUE); + + /* draw a box around the menu items */ + draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2, + menubox_border_attr, menubox_attr); + + /* + * Find length of longest item in order to center menu. + * Set 'choice' to default item. + */ + item_x = 0; + for (i = 0; i < item_no; i++) { + item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2)); + if (strcmp(current, items[i*2]) == 0) choice = i; + } + + item_x = (menu_width - item_x) / 2; + + /* get the scroll info from the temp file */ + if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) { + if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) && + (scroll+max_choice > choice) && (scroll >= 0) && + (scroll+max_choice <= item_no) ) { + first_item = scroll; + choice = choice - scroll; + fclose(f); + } else { + scroll=0; + remove("lxdialog.scrltmp"); + fclose(f); + f=NULL; + } + } + if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) { + if (choice >= item_no-max_choice/2) + scroll = first_item = item_no-max_choice; + else + scroll = first_item = choice - max_choice/2; + choice = choice - scroll; + } + + /* Print the menu */ + for (i=0; i < max_choice; i++) { + print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice, + (items[(first_item + i)*2][0] != ':')); + } + + wnoutrefresh (menu); + + print_arrows(dialog, item_no, scroll, + box_y, box_x+item_x+1, menu_height); + + print_buttons (dialog, height, width, 0); + wmove (menu, choice, item_x+1); + wrefresh (menu); + + while (key != ESC) { + key = wgetch(menu); + + if (key < 256 && isalpha(key)) key = tolower(key); + + if (strchr("ynm", key)) + i = max_choice; + else { + for (i = choice+1; i < max_choice; i++) { + j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); + if (key == tolower(items[(scroll+i)*2+1][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])) + break; + } + } + + if (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE) { + + print_item (menu, items[(scroll+choice)*2+1], choice, FALSE, + (items[(scroll+choice)*2][0] != ':')); + + if (key == KEY_UP || key == '-') { + if (choice < 2 && scroll) { + /* Scroll menu down */ + scrollok (menu, TRUE); + wscrl (menu, -1); + scrollok (menu, FALSE); + + scroll--; + + print_item (menu, items[scroll * 2 + 1], 0, FALSE, + (items[scroll*2][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] != ':')); + + if ((choice > max_choice-3) && + (scroll + max_choice < item_no) + ) { + /* Scroll menu up */ + scrollok (menu, TRUE); + scroll (menu); + scrollok (menu, FALSE); + + scroll++; + + print_item (menu, items[(scroll+max_choice-1)*2+1], + max_choice-1, FALSE, + (items[(scroll+max_choice-1)*2][0] != ':')); + } else + choice = MIN(choice+1, max_choice-1); + + } else if (key == KEY_PPAGE) { + scrollok (menu, TRUE); + for (i=0; (i < max_choice); i++) { + if (scroll > 0) { + wscrl (menu, -1); + scroll--; + print_item (menu, items[scroll * 2 + 1], 0, FALSE, + (items[scroll*2][0] != ':')); + } else { + if (choice > 0) + choice--; + } + } + scrollok (menu, FALSE); + + } else if (key == KEY_NPAGE) { + for (i=0; (i < max_choice); i++) { + if (scroll+max_choice < item_no) { + scrollok (menu, TRUE); + scroll(menu); + scrollok (menu, FALSE); + scroll++; + print_item (menu, items[(scroll+max_choice-1)*2+1], + max_choice-1, FALSE, + (items[(scroll+max_choice-1)*2][0] != ':')); + } else { + if (choice+1 < max_choice) + choice++; + } + } + + } else + choice = i; + + print_item (menu, items[(scroll+choice)*2+1], choice, TRUE, + (items[(scroll+choice)*2][0] != ':')); + + print_arrows(dialog, item_no, scroll, + box_y, box_x+item_x+1, menu_height); + + wnoutrefresh (dialog); + wrefresh (menu); + + continue; /* wait for another key press */ + } + + switch (key) { + case KEY_LEFT: + case TAB: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 2 : (button > 2 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (menu); + break; + case ' ': + case 's': + case 'y': + case 'n': + case 'm': + /* save scroll info */ + if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) { + fprintf(f,"%d\n",scroll); + fclose(f); + } + delwin (dialog); + fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); + switch (key) { + case 's': return 3; + case 'y': return 3; + case 'n': return 4; + case 'm': return 5; + case ' ': return 6; + } + return 0; + case 'h': + case '?': + button = 2; + case '\n': + delwin (dialog); + 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]); + + remove("lxdialog.scrltmp"); + return button; + case 'e': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + remove("lxdialog.scrltmp"); + return -1; /* ESC pressed */ +} diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/msgbox.c b/uClinux-2.4.31-uc0/scripts/lxdialog/msgbox.c new file mode 100644 index 0000000..93692e1 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/msgbox.c @@ -0,0 +1,85 @@ +/* + * msgbox.c -- implements the message box and info box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display a message box. Program will pause and display an "OK" button + * if the parameter 'pause' is non-zero. + */ +int +dialog_msgbox (const char *title, const char *prompt, int height, int width, + int pause) +{ + int i, x, y, key = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 2); + + if (pause) { + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + print_button (dialog, " Ok ", + height - 2, width / 2 - 4, TRUE); + + wrefresh (dialog); + while (key != ESC && key != '\n' && key != ' ' && + key != 'O' && key != 'o' && key != 'X' && key != 'x') + key = wgetch (dialog); + } else { + key = '\n'; + wrefresh (dialog); + } + + delwin (dialog); + return key == ESC ? -1 : 0; +} diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/textbox.c b/uClinux-2.4.31-uc0/scripts/lxdialog/textbox.c new file mode 100644 index 0000000..ecf5541 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/textbox.c @@ -0,0 +1,556 @@ +/* + * textbox.c -- implements the text box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static void back_lines (int n); +static void print_page (WINDOW * win, int height, int width); +static void print_line (WINDOW * win, int row, int width); +static char *get_line (void); +static void print_position (WINDOW * win, int height, int width); + +static int hscroll = 0, fd, file_size, bytes_read; +static int begin_reached = 1, end_reached = 0, page_length; +static char *buf, *page; + +/* + * Display text from a file in a dialog box. + */ +int +dialog_textbox (const char *title, const char *file, int height, int width) +{ + int i, x, y, cur_x, cur_y, fpos, key = 0; + int passed_end; + char search_term[MAX_LEN + 1]; + WINDOW *dialog, *text; + + search_term[0] = '\0'; /* no search term entered yet */ + + /* Open input file for reading */ + if ((fd = open (file, O_RDONLY)) == -1) { + endwin (); + fprintf (stderr, + "\nCan't open input file in dialog_textbox().\n"); + exit (-1); + } + /* Get file size. Actually, 'file_size' is the real file size - 1, + since it's only the last byte offset from the beginning */ + if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { + endwin (); + fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); + exit (-1); + } + /* Restore file pointer to beginning of file after getting file size */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + /* Allocate space for read buffer */ + if ((buf = malloc (BUF_SIZE + 1)) == NULL) { + endwin (); + fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; /* mark end of valid data */ + page = buf; /* page is pointer to start of page to be displayed */ + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + /* Create window for text region, used for scrolling text */ + text = subwin (dialog, height - 4, width - 2, y + 1, x + 1); + wattrset (text, dialog_attr); + wbkgdset (text, dialog_attr & A_COLOR); + + keypad (text, TRUE); + + /* register the new window, along with its borders */ + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + wbkgdset (dialog, dialog_attr & A_COLOR); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE); + wnoutrefresh (dialog); + getyx (dialog, cur_y, cur_x); /* Save cursor position */ + + /* Print first page of text */ + attr_clear (text, height - 4, width - 2, dialog_attr); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + + while ((key != ESC) && (key != '\n')) { + key = wgetch (dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': + delwin (dialog); + free (buf); + close (fd); + return 0; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + /* First page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Yes, we have to read it in */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'G': /* Last page */ + case KEY_END: + + end_reached = 1; + /* Last page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos < file_size) { /* Yes, we have to read it in */ + if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf + bytes_read; + back_lines (height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + break; + case 'K': /* Previous line */ + case 'k': + case KEY_UP: + if (!begin_reached) { + back_lines (page_length + 1); + + /* We don't call print_page() here but use scrolling to ensure + faster screen update. However, 'end_reached' and + 'page_length' should still be updated, and 'page' should + point to start of next page. This is done by calling + get_line() in the following 'for' loop. */ + scrollok (text, TRUE); + wscrl (text, -1); /* Scroll text region down one line */ + scrollok (text, FALSE); + page_length = 0; + passed_end = 0; + for (i = 0; i < height - 4; i++) { + if (!i) { + /* print first line of page */ + print_line (text, 0, width - 2); + wnoutrefresh (text); + } else + /* Called to update 'end_reached' and 'page' */ + get_line (); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'B': /* Previous page */ + case 'b': + case KEY_PPAGE: + if (begin_reached) + break; + back_lines (page_length + height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: + if (!end_reached) { + begin_reached = 0; + scrollok (text, TRUE); + scroll (text); /* Scroll text region up one line */ + scrollok (text, FALSE); + print_line (text, height - 5, width - 2); + wnoutrefresh (text); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case KEY_NPAGE: /* Next page */ + case ' ': + if (end_reached) + break; + + begin_reached = 0; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case '0': /* Beginning of line */ + case 'H': /* Scroll left */ + case 'h': + case KEY_LEFT: + if (hscroll <= 0) + break; + + if (key == '0') + hscroll = 0; + else + hscroll--; + /* Reprint current page to scroll horizontally */ + back_lines (page_length); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'L': /* Scroll right */ + case 'l': + case KEY_RIGHT: + if (hscroll >= MAX_LEN) + break; + hscroll++; + /* Reprint current page to scroll horizontally */ + back_lines (page_length); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case ESC: + break; + } + } + + delwin (dialog); + free (buf); + close (fd); + return -1; /* ESC pressed */ +} + +/* + * Go back 'n' lines in text file. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void +back_lines (int n) +{ + int i, fpos; + + begin_reached = 0; + /* We have to distinguish between end_reached and !end_reached + since at end of file, the line is not ended by a '\n'. + The code inside 'if' basically does a '--page' to move one + character backward so as to skip '\n' of the previous line */ + if (!end_reached) { + /* Either beginning of buffer or beginning of file reached? */ + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Not beginning of file yet */ + /* We've reached beginning of buffer, but not beginning of + file yet, so read previous part of file into buffer. + Note that we only move backward for BUF_SIZE/2 bytes, + but not BUF_SIZE bytes to avoid re-reading again in + print_page() later */ + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) + == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + if (*(--page) != '\n') { /* '--page' here */ + /* Something's wrong... */ + endwin (); + fprintf (stderr, "\nInternal error in back_lines().\n"); + exit (-1); + } + } + /* Go back 'n' lines */ + for (i = 0; i < n; i++) + do { + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), + SEEK_CUR) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer" + " in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in " + "back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + } while (*(--page) != '\n'); + page++; +} + +/* + * Print a new page of text. Called by dialog_textbox(). + */ +static void +print_page (WINDOW * win, int height, int width) +{ + int i, passed_end = 0; + + page_length = 0; + for (i = 0; i < height; i++) { + print_line (win, i, width); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + wnoutrefresh (win); +} + +/* + * Print a new line of text. Called by dialog_textbox() and print_page(). + */ +static void +print_line (WINDOW * win, int row, int width) +{ + int y, x; + char *line; + + line = get_line (); + line += MIN (strlen (line), hscroll); /* Scroll horizontally */ + wmove (win, row, 0); /* move cursor to correct line */ + waddch (win, ' '); + waddnstr (win, line, MIN (strlen (line), width - 2)); + + getyx (win, y, x); + /* Clear 'residue' of previous line */ +#if OLD_NCURSES + { + int i; + for (i = 0; i < width - x; i++) + waddch (win, ' '); + } +#else + wclrtoeol(win); +#endif +} + +/* + * Return current line of text. Called by dialog_textbox() and print_line(). + * 'page' should point to start of current line before calling, and will be + * updated to point to start of next line. + */ +static char * +get_line (void) +{ + int i = 0, fpos; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + /* Either end of file or end of buffer reached */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "get_line().\n"); + exit (-1); + } + if (fpos < file_size) { /* Not end of file yet */ + /* We've reached end of buffer, but not end of file yet, + so read next part of file into buffer */ + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in get_line().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + page = buf; + } else { + if (!end_reached) + end_reached = 1; + break; + } + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { + /* Truncate lines longer than MAX_LEN characters */ + if (i == MAX_LEN) + line[i++] = '\0'; + page++; + } + } + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) + page++; /* move pass '\n' */ + + return line; +} + +/* + * Print current position + */ +static void +print_position (WINDOW * win, int height, int width) +{ + int fpos, percent; + + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in print_position().\n"); + exit (-1); + } + wattrset (win, position_indicator_attr); + wbkgdset (win, position_indicator_attr & A_COLOR); + percent = !file_size ? + 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; + wmove (win, height - 3, width - 9); + wprintw (win, "(%3d%%)", percent); +} diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/util.c b/uClinux-2.4.31-uc0/scripts/lxdialog/util.c new file mode 100644 index 0000000..b3a7af9 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/util.c @@ -0,0 +1,359 @@ +/* + * util.c + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + + +/* use colors by default? */ +bool use_colors = 1; + +const char *backtitle = NULL; + +const char *dialog_result; + +/* + * Attribute values, default is for mono display + */ +chtype attributes[] = +{ + A_NORMAL, /* screen_attr */ + A_NORMAL, /* shadow_attr */ + A_NORMAL, /* dialog_attr */ + A_BOLD, /* title_attr */ + A_NORMAL, /* border_attr */ + A_REVERSE, /* button_active_attr */ + A_DIM, /* button_inactive_attr */ + A_REVERSE, /* button_key_active_attr */ + A_BOLD, /* button_key_inactive_attr */ + A_REVERSE, /* button_label_active_attr */ + A_NORMAL, /* button_label_inactive_attr */ + A_NORMAL, /* inputbox_attr */ + A_NORMAL, /* inputbox_border_attr */ + A_NORMAL, /* searchbox_attr */ + A_BOLD, /* searchbox_title_attr */ + A_NORMAL, /* searchbox_border_attr */ + A_BOLD, /* position_indicator_attr */ + A_NORMAL, /* menubox_attr */ + A_NORMAL, /* menubox_border_attr */ + A_NORMAL, /* item_attr */ + A_REVERSE, /* item_selected_attr */ + A_BOLD, /* tag_attr */ + A_REVERSE, /* tag_selected_attr */ + A_BOLD, /* tag_key_attr */ + A_REVERSE, /* tag_key_selected_attr */ + A_BOLD, /* check_attr */ + A_REVERSE, /* check_selected_attr */ + A_BOLD, /* uarrow_attr */ + A_BOLD /* darrow_attr */ +}; + + +#include "colors.h" + +/* + * Table of color values + */ +int color_table[][3] = +{ + {SCREEN_FG, SCREEN_BG, SCREEN_HL}, + {SHADOW_FG, SHADOW_BG, SHADOW_HL}, + {DIALOG_FG, DIALOG_BG, DIALOG_HL}, + {TITLE_FG, TITLE_BG, TITLE_HL}, + {BORDER_FG, BORDER_BG, BORDER_HL}, + {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, + {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, + {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, + {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, + {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, + {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, + BUTTON_LABEL_INACTIVE_HL}, + {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, + {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, + {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, + {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, + {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, + {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, + {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, + {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, + {ITEM_FG, ITEM_BG, ITEM_HL}, + {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, + {TAG_FG, TAG_BG, TAG_HL}, + {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, + {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, + {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, + {CHECK_FG, CHECK_BG, CHECK_HL}, + {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, + {UARROW_FG, UARROW_BG, UARROW_HL}, + {DARROW_FG, DARROW_BG, DARROW_HL}, +}; /* color_table */ + +/* + * Set window to attribute 'attr' + */ +void +attr_clear (WINDOW * win, int height, int width, chtype attr) +{ + int i, j; + + wattrset (win, attr); + for (i = 0; i < height; i++) { + wmove (win, i, 0); + for (j = 0; j < width; j++) + waddch (win, ' '); + } + touchwin (win); +} + +void dialog_clear (void) +{ + attr_clear (stdscr, LINES, COLS, screen_attr); + /* Display background title if it exists ... - SLH */ + if (backtitle != NULL) { + int i; + + wattrset (stdscr, screen_attr); + mvwaddstr (stdscr, 0, 1, (char *)backtitle); + wmove (stdscr, 1, 1); + for (i = 1; i < COLS - 1; i++) + waddch (stdscr, ACS_HLINE); + } + wnoutrefresh (stdscr); +} + +/* + * Do some initialization for dialog + */ +void +init_dialog (void) +{ + initscr (); /* Init curses */ + keypad (stdscr, TRUE); + cbreak (); + noecho (); + + + if (use_colors) /* Set up colors */ + color_setup (); + + + dialog_clear (); +} + +/* + * Setup for color display + */ +void +color_setup (void) +{ + int i; + + if (has_colors ()) { /* Terminal supports color? */ + start_color (); + + /* Initialize color pairs */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + init_pair (i + 1, color_table[i][0], color_table[i][1]); + + /* Setup color attributes */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + attributes[i] = C_ATTR (color_table[i][2], i + 1); + } +} + +/* + * End using dialog functions. + */ +void +end_dialog (void) +{ + endwin (); +} + + +/* + * Print a string of text in a window, automatically wrap around to the + * next line if the string is too long to fit on one line. Newline + * characters '\n' are replaced by spaces. We start on a new line + * if there is no room for at least 4 nonblanks following a double-space. + */ +void +print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) +{ + int newl, cur_x, cur_y; + int i, prompt_len, room, wlen; + char tempstr[MAX_LEN + 1], *word, *sp, *sp2; + + strcpy (tempstr, prompt); + + prompt_len = strlen(tempstr); + + /* + * Remove newlines + */ + for(i=0; i<prompt_len; i++) { + if(tempstr[i] == '\n') tempstr[i] = ' '; + } + + if (prompt_len <= width - x * 2) { /* If prompt is short */ + wmove (win, y, (width - prompt_len) / 2); + waddstr (win, tempstr); + } else { + cur_x = x; + cur_y = y; + newl = 1; + word = tempstr; + while (word && *word) { + sp = index(word, ' '); + if (sp) + *sp++ = 0; + + /* Wrap to next line if either the word does not fit, + or it is the first word of a new sentence, and it is + short, and the next word does not fit. */ + room = width - cur_x; + wlen = strlen(word); + if (wlen > room || + (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room + && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { + cur_y++; + cur_x = x; + } + wmove (win, cur_y, cur_x); + waddstr (win, word); + getyx (win, cur_y, cur_x); + cur_x++; + if (sp && *sp == ' ') { + cur_x++; /* double space */ + while (*++sp == ' '); + newl = 1; + } else + newl = 0; + word = sp; + } + } +} + +/* + * Print a button + */ +void +print_button (WINDOW * win, const char *label, int y, int x, int selected) +{ + int i, temp; + + wmove (win, y, x); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + waddstr (win, "<"); + temp = strspn (label, " "); + label += temp; + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + for (i = 0; i < temp; i++) + waddch (win, ' '); + wattrset (win, selected ? button_key_active_attr + : button_key_inactive_attr); + waddch (win, label[0]); + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + waddstr (win, (char *)label + 1); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + waddstr (win, ">"); + wmove (win, y, x + temp + 1); +} + +/* + * Draw a rectangular box with line drawing characters + */ +void +draw_box (WINDOW * win, int y, int x, int height, int width, + chtype box, chtype border) +{ + int i, j; + + wattrset (win, 0); + for (i = 0; i < height; i++) { + wmove (win, y + i, x); + for (j = 0; j < width; j++) + if (!i && !j) + waddch (win, border | ACS_ULCORNER); + else if (i == height - 1 && !j) + waddch (win, border | ACS_LLCORNER); + else if (!i && j == width - 1) + waddch (win, box | ACS_URCORNER); + else if (i == height - 1 && j == width - 1) + waddch (win, box | ACS_LRCORNER); + else if (!i) + waddch (win, border | ACS_HLINE); + else if (i == height - 1) + waddch (win, box | ACS_HLINE); + else if (!j) + waddch (win, border | ACS_VLINE); + else if (j == width - 1) + waddch (win, box | ACS_VLINE); + else + waddch (win, box | ' '); + } +} + +/* + * Draw shadows along the right and bottom edge to give a more 3D look + * to the boxes + */ +void +draw_shadow (WINDOW * win, int y, int x, int height, int width) +{ + int i; + + if (has_colors ()) { /* Whether terminal supports color? */ + wattrset (win, shadow_attr); + wmove (win, y + height, x + 2); + for (i = 0; i < width; i++) + waddch (win, winch (win) & A_CHARTEXT); + for (i = y + 1; i < y + height + 1; i++) { + wmove (win, i, x + width); + waddch (win, winch (win) & A_CHARTEXT); + waddch (win, winch (win) & A_CHARTEXT); + } + wnoutrefresh (win); + } +} + +/* + * Return the position of the first alphabetic character in a string. + */ +int +first_alpha(const char *string, const char *exempt) +{ + int i, in_paren=0, c; + + for (i = 0; i < strlen(string); i++) { + c = tolower(string[i]); + + if (strchr("<[(", c)) ++in_paren; + if (strchr(">])", c)) --in_paren; + + if ((! in_paren) && isalpha(c) && + strchr(exempt, c) == 0) + return i; + } + + return 0; +} diff --git a/uClinux-2.4.31-uc0/scripts/lxdialog/yesno.c b/uClinux-2.4.31-uc0/scripts/lxdialog/yesno.c new file mode 100644 index 0000000..11fcc25 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/lxdialog/yesno.c @@ -0,0 +1,118 @@ +/* + * yesno.c -- implements the yes/no box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display termination buttons + */ +static void +print_buttons(WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 10; + int y = height - 2; + + print_button (dialog, " Yes ", y, x, selected == 0); + print_button (dialog, " No ", y, x + 13, selected == 1); + + wmove(dialog, y, x+1 + 13*selected ); + wrefresh (dialog); +} + +/* + * Display a dialog box with two buttons - Yes and No + */ +int +dialog_yesno (const char *title, const char *prompt, int height, int width) +{ + int i, x, y, key = 0, button = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL && strlen(title) >= width-2 ) { + /* truncate long title -- mec */ + char * title2 = malloc(width-2+1); + memcpy( title2, title, width-2 ); + title2[width-2] = '\0'; + title = title2; + } + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + print_buttons(dialog, height, width, 0); + + while (key != ESC) { + key = wgetch (dialog); + switch (key) { + case 'Y': + case 'y': + delwin (dialog); + return 0; + case 'N': + case 'n': + delwin (dialog); + return 1; + + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case ' ': + case '\n': + delwin (dialog); + return button; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/uClinux-2.4.31-uc0/scripts/makelst b/uClinux-2.4.31-uc0/scripts/makelst new file mode 100644 index 0000000..a76ca78 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/makelst @@ -0,0 +1,22 @@ +#!/bin/bash +# A script to dump mixed source code & assembly +# with correct relocations from System.map +# Requires the following lines in Rules.make. +# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) +# William Stearns <wstearns@pobox.com> +#%.lst: %.c +# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $< +# $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP) +# +# Copyright (C) 2000 IBM Corporation +# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) +# + +t1=`$3 --syms $2/$1.o | grep .text | grep " F " | head -n 1` +t2=`echo $t1 | gawk '{ print $6 }'` +t3=`grep $t2 $2/System.map` +t4=`echo $t3 | gawk '{ print $1 }'` +t5=`echo $t1 | gawk '{ print $1 }'` +t6=`echo $t4 - $t5 | sed -e s/a/A/g -e s/b/B/g -e s/c/C/g -e s/d/D/g -e s/e/E/g -e s/f/F/g` +t7=`( echo ibase=16 ; echo $t6 ) | bc` +$3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst diff --git a/uClinux-2.4.31-uc0/scripts/mkconfigs.c b/uClinux-2.4.31-uc0/scripts/mkconfigs.c new file mode 100644 index 0000000..d073bd4 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/mkconfigs.c @@ -0,0 +1,181 @@ +/*************************************************************************** + * mkconfigs.c + * (C) 2002 Randy Dunlap <rddunlap@osdl.org> + +# 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. + +# Rules for scripts/mkconfigs.c input.config output.c +# to generate configs.c from linux/.config: +# - drop lines that begin with '#' +# - drop blank lines +# - lines that use double-quotes must \\-escape-quote them + +################## skeleton configs.c file: #################### + +#include <linux/init.h> +#include <linux/module.h> + +static char *configs[] __initdata = + + <insert lines selected lines of .config, quoted, with added '\n'>, + +; + +################### end configs.c file ###################### + + * Changelog for ver. 0.2, 2002-02-15, rddunlap@osdl.org: + - strip leading "CONFIG_" from config option strings; + - use "static" and "__attribute__((unused))"; + - don't use EXPORT_SYMBOL(); + - separate each config line with \newline instead of space; + + * Changelog for ver. 0.3, 2002-02-18, rddunlap@osdl.org: + - keep all "not set" comment lines from .config so that 'make *config' + will be happy, but don't keep other comments; + - keep leading "CONFIG_" on each line; + +****************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#define VERSION "0.2" +#define LINE_SIZE 1000 + +int include_all_lines = 1; // whether to include "=n" lines in the output + +void usage (const char *progname) +{ + fprintf (stderr, "%s ver. %s\n", progname, VERSION); + fprintf (stderr, "usage: %s input.config.name path/configs.c\n", + progname); + exit (1); +} + +void make_intro (FILE *sourcefile) +{ + fprintf (sourcefile, "#include <linux/init.h>\n"); +///// fprintf (sourcefile, "#include <linux/module.h>\n"); + fprintf (sourcefile, "\n"); +///// fprintf (sourcefile, "char *configs[] __initdata = {\n"); + fprintf (sourcefile, "static char __attribute__ ((unused)) *configs[] __initdata = {\n"); + fprintf (sourcefile, " \"CONFIG_BEGIN=n\\n\" ,\n"); +} + +void make_ending (FILE *sourcefile) +{ + fprintf (sourcefile, " \"CONFIG_END=n\\n\"\n"); + fprintf (sourcefile, "};\n"); +///// fprintf (sourcefile, "EXPORT_SYMBOL (configs);\n"); +} + +void make_lines (FILE *configfile, FILE *sourcefile) +{ + char cfgline[LINE_SIZE]; + char *ch; + + while (fgets (cfgline, LINE_SIZE, configfile)) { + /* kill the trailing newline in cfgline */ + cfgline[strlen (cfgline) - 1] = '\0'; + + /* don't keep #-only line or an empty/blank line */ + if ((cfgline[0] == '#' && cfgline[1] == '\0') || + cfgline[0] == '\0') + continue; + + if (!include_all_lines && + cfgline[0] == '#') // strip out all comment lines + continue; + + /* really only want to keep lines that begin with + * "CONFIG_" or "# CONFIG_" */ + if (strncmp (cfgline, "CONFIG_", 7) && + strncmp (cfgline, "# CONFIG_", 9)) + continue; + + /* + * use strchr() to check for "-quote in cfgline; + * if not found, output the line, quoted; + * if found, output a char at a time, with \\-quote + * preceding double-quote chars + */ + if (!strchr (cfgline, '"')) { + fprintf (sourcefile, " \"%s\\n\" ,\n", cfgline); + continue; + } + + /* go to char-at-a-time mode for this config and + * precede any double-quote with a backslash */ + fprintf (sourcefile, " \""); /* lead-in */ + for (ch = cfgline; *ch; ch++) { + if (*ch == '"') + fputc ('\\', sourcefile); + fputc (*ch, sourcefile); + } + fprintf (sourcefile, "\\n\" ,\n"); + } +} + +void make_configs (FILE *configfile, FILE *sourcefile) +{ + make_intro (sourcefile); + make_lines (configfile, sourcefile); + make_ending (sourcefile); +} + +int main (int argc, char *argv[]) +{ + char *progname = argv[0]; + char *configname, *sourcename; + FILE *configfile, *sourcefile; + + if (argc != 3) + usage (progname); + + configname = argv[1]; + sourcename = argv[2]; + + configfile = fopen (configname, "r"); + if (!configfile) { + fprintf (stderr, "%s: cannot open '%s'\n", + progname, configname); + exit (2); + } + sourcefile = fopen (sourcename, "w"); + if (!sourcefile) { + fprintf (stderr, "%s: cannot open '%s'\n", + progname, sourcename); + exit (2); + } + + make_configs (configfile, sourcefile); + + if (fclose (sourcefile)) { + fprintf (stderr, "%s: error %d closing '%s'\n", + progname, errno, sourcename); + exit (3); + } + if (fclose (configfile)) { + fprintf (stderr, "%s: error %d closing '%s'\n", + progname, errno, configname); + exit (3); + } + + exit (0); +} + +/* end mkconfigs.c */ diff --git a/uClinux-2.4.31-uc0/scripts/mkdep.c b/uClinux-2.4.31-uc0/scripts/mkdep.c new file mode 100644 index 0000000..99f6197 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/mkdep.c @@ -0,0 +1,632 @@ +/* + * Originally by Linus Torvalds. + * Smart CONFIG_* processing by Werner Almesberger, Michael Chastain. + * + * Usage: mkdep cflags -- file ... + * + * Read source files and output makefile dependency lines for them. + * I make simple dependency lines for #include <*.h> and #include "*.h". + * I also find instances of CONFIG_FOO and generate dependencies + * like include/config/foo.h. + * + * 1 August 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Keith Owens reported a bug in smart config processing. There used + * to be an optimization for "#define CONFIG_FOO ... #ifdef CONFIG_FOO", + * so that the file would not depend on CONFIG_FOO because the file defines + * this symbol itself. But this optimization is bogus! Consider this code: + * "#if 0 \n #define CONFIG_FOO \n #endif ... #ifdef CONFIG_FOO". Here + * the definition is inactivated, but I still used it. It turns out this + * actually happens a few times in the kernel source. The simple way to + * fix this problem is to remove this particular optimization. + * + * 2.3.99-pre1, Andrew Morton <andrewm@uow.edu.au> + * - Changed so that 'filename.o' depends upon 'filename.[cS]'. This is so that + * missing source files are noticed, rather than silently ignored. + * + * 2.4.2-pre3, Keith Owens <kaos@ocs.com.au> + * - Accept cflags followed by '--' followed by filenames. mkdep extracts -I + * options from cflags and looks in the specified directories as well as the + * defaults. Only -I is supported, no attempt is made to handle -idirafter, + * -isystem, -I- etc. + */ + +#include <ctype.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + + + +char __depname[512] = "\n\t@touch "; +#define depname (__depname+9) +int hasdep; + +struct path_struct { + int len; + char *buffer; +}; +struct path_struct *path_array; +int paths; + + +/* Current input file */ +static const char *g_filename; + +/* + * This records all the configuration options seen. + * In perl this would be a hash, but here it's a long string + * of values separated by newlines. This is simple and + * extremely fast. + */ +char * str_config = NULL; +int size_config = 0; +int len_config = 0; + +static void +do_depname(void) +{ + if (!hasdep) { + hasdep = 1; + printf("%s:", depname); + if (g_filename) + printf(" %s", g_filename); + } +} + +/* + * Grow the configuration string to a desired length. + * Usually the first growth is plenty. + */ +void grow_config(int len) +{ + while (len_config + len > size_config) { + if (size_config == 0) + size_config = 2048; + str_config = realloc(str_config, size_config *= 2); + if (str_config == NULL) + { perror("malloc config"); exit(1); } + } +} + + + +/* + * Lookup a value in the configuration string. + */ +int is_defined_config(const char * name, int len) +{ + const char * pconfig; + const char * plast = str_config + len_config - len; + for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { + if (pconfig[ -1] == '\n' + && pconfig[len] == '\n' + && !memcmp(pconfig, name, len)) + return 1; + } + return 0; +} + + + +/* + * Add a new value to the configuration string. + */ +void define_config(const char * name, int len) +{ + grow_config(len + 1); + + memcpy(str_config+len_config, name, len); + len_config += len; + str_config[len_config++] = '\n'; +} + + + +/* + * Clear the set of configuration strings. + */ +void clear_config(void) +{ + len_config = 0; + define_config("", 0); +} + + + +/* + * This records all the precious .h filenames. No need for a hash, + * it's a long string of values enclosed in tab and newline. + */ +char * str_precious = NULL; +int size_precious = 0; +int len_precious = 0; + + + +/* + * Grow the precious string to a desired length. + * Usually the first growth is plenty. + */ +void grow_precious(int len) +{ + while (len_precious + len > size_precious) { + if (size_precious == 0) + size_precious = 2048; + str_precious = realloc(str_precious, size_precious *= 2); + if (str_precious == NULL) + { perror("malloc"); exit(1); } + } +} + + + +/* + * Add a new value to the precious string. + */ +void define_precious(const char * filename) +{ + int len = strlen(filename); + grow_precious(len + 4); + *(str_precious+len_precious++) = '\t'; + memcpy(str_precious+len_precious, filename, len); + len_precious += len; + memcpy(str_precious+len_precious, " \\\n", 3); + len_precious += 3; +} + + + +/* + * Handle an #include line. + */ +void handle_include(int start, const char * name, int len) +{ + struct path_struct *path; + int i; + + if (len == 14 && !memcmp(name, "linux/config.h", len)) + return; + + if (len >= 7 && !memcmp(name, "config/", 7)) + define_config(name+7, len-7-2); + + for (i = start, path = path_array+start; i < paths; ++i, ++path) { + memcpy(path->buffer+path->len, name, len); + path->buffer[path->len+len] = '\0'; + if (access(path->buffer, F_OK) == 0) { + do_depname(); + printf(" \\\n %s", path->buffer); + return; + } + } + +} + + + +/* + * Add a path to the list of include paths. + */ +void add_path(const char * name) +{ + struct path_struct *path; + char resolved_path[PATH_MAX+1]; + const char *name2; + + if (strcmp(name, ".")) { + name2 = realpath(name, resolved_path); + if (!name2) { + fprintf(stderr, "realpath(%s) failed, %m\n", name); + exit(1); + } + } + else { + name2 = ""; + } + + path_array = realloc(path_array, (++paths)*sizeof(*path_array)); + if (!path_array) { + fprintf(stderr, "cannot expand path_arry\n"); + exit(1); + } + + path = path_array+paths-1; + path->len = strlen(name2); + path->buffer = malloc(path->len+1+256+1); + if (!path->buffer) { + fprintf(stderr, "cannot allocate path buffer\n"); + exit(1); + } + strcpy(path->buffer, name2); + if (path->len && *(path->buffer+path->len-1) != '/') { + *(path->buffer+path->len) = '/'; + *(path->buffer+(++(path->len))) = '\0'; + } +} + + + +/* + * Record the use of a CONFIG_* word. + */ +void use_config(const char * name, int len) +{ + char *pc; + int i; + + pc = path_array[paths-1].buffer + path_array[paths-1].len; + memcpy(pc, "config/", 7); + pc += 7; + + for (i = 0; i < len; i++) { + char c = name[i]; + if (isupper((int)c)) c = tolower((int)c); + if (c == '_') c = '/'; + pc[i] = c; + } + pc[len] = '\0'; + + if (is_defined_config(pc, len)) + return; + + define_config(pc, len); + + do_depname(); + printf(" \\\n $(wildcard %s.h)", path_array[paths-1].buffer); +} + + + +/* + * Macros for stunningly fast map-based character access. + * __buf is a register which holds the current word of the input. + * Thus, there is one memory access per sizeof(unsigned long) characters. + */ + +#if defined(__alpha__) || defined(__i386__) || defined(__ia64__) || defined(__x86_64__) || defined(__MIPSEL__) \ + || defined(__arm__) +#define LE_MACHINE +#endif + +#ifdef LE_MACHINE +#define next_byte(x) (x >>= 8) +#define current ((unsigned char) __buf) +#else +#define next_byte(x) (x <<= 8) +#define current (__buf >> 8*(sizeof(unsigned long)-1)) +#endif + +#define GETNEXT { \ + next_byte(__buf); \ + if ((unsigned long) next % sizeof(unsigned long) == 0) { \ + if (next >= end) \ + break; \ + __buf = * (unsigned long *) next; \ + } \ + next++; \ +} + +/* + * State machine macros. + */ +#define CASE(c,label) if (current == c) goto label +#define NOTCASE(c,label) if (current != c) goto label + +/* + * Yet another state machine speedup. + */ +#define MAX2(a,b) ((a)>(b)?(a):(b)) +#define MIN2(a,b) ((a)<(b)?(a):(b)) +#define MAX5(a,b,c,d,e) (MAX2(a,MAX2(b,MAX2(c,MAX2(d,e))))) +#define MIN5(a,b,c,d,e) (MIN2(a,MIN2(b,MIN2(c,MIN2(d,e))))) + + + +/* + * The state machine looks for (approximately) these Perl regular expressions: + * + * m|\/\*.*?\*\/| + * m|\/\/.*| + * m|'.*?'| + * m|".*?"| + * m|#\s*include\s*"(.*?)"| + * m|#\s*include\s*<(.*?>"| + * m|#\s*(?define|undef)\s*CONFIG_(\w*)| + * m|(?!\w)CONFIG_| + * + * About 98% of the CPU time is spent here, and most of that is in + * the 'start' paragraph. Because the current characters are + * in a register, the start loop usually eats 4 or 8 characters + * per memory read. The MAX5 and MIN5 tests dispose of most + * input characters with 1 or 2 comparisons. + */ +void state_machine(const char * map, const char * end) +{ + const char * next = map; + const char * map_dot; + unsigned long __buf = 0; + + for (;;) { +start: + GETNEXT +__start: + if (current > MAX5('/','\'','"','#','C')) goto start; + if (current < MIN5('/','\'','"','#','C')) goto start; + CASE('/', slash); + CASE('\'', squote); + CASE('"', dquote); + CASE('#', pound); + CASE('C', cee); + goto start; + +/* // */ +slash_slash: + GETNEXT + CASE('\n', start); + NOTCASE('\\', slash_slash); + GETNEXT + goto slash_slash; + +/* / */ +slash: + GETNEXT + CASE('/', slash_slash); + NOTCASE('*', __start); +slash_star_dot_star: + GETNEXT +__slash_star_dot_star: + NOTCASE('*', slash_star_dot_star); + GETNEXT + NOTCASE('/', __slash_star_dot_star); + goto start; + +/* '.*?' */ +squote: + GETNEXT + CASE('\'', start); + NOTCASE('\\', squote); + GETNEXT + goto squote; + +/* ".*?" */ +dquote: + GETNEXT + CASE('"', start); + NOTCASE('\\', dquote); + GETNEXT + goto dquote; + +/* #\s* */ +pound: + GETNEXT + CASE(' ', pound); + CASE('\t', pound); + CASE('i', pound_i); + CASE('d', pound_d); + CASE('u', pound_u); + goto __start; + +/* #\s*i */ +pound_i: + GETNEXT NOTCASE('n', __start); + GETNEXT NOTCASE('c', __start); + GETNEXT NOTCASE('l', __start); + GETNEXT NOTCASE('u', __start); + GETNEXT NOTCASE('d', __start); + GETNEXT NOTCASE('e', __start); + goto pound_include; + +/* #\s*include\s* */ +pound_include: + GETNEXT + CASE(' ', pound_include); + CASE('\t', pound_include); + map_dot = next; + CASE('"', pound_include_dquote); + CASE('<', pound_include_langle); + goto __start; + +/* #\s*include\s*"(.*)" */ +pound_include_dquote: + GETNEXT + CASE('\n', start); + NOTCASE('"', pound_include_dquote); + handle_include(0, map_dot, next - map_dot - 1); + goto start; + +/* #\s*include\s*<(.*)> */ +pound_include_langle: + GETNEXT + CASE('\n', start); + NOTCASE('>', pound_include_langle); + handle_include(1, map_dot, next - map_dot - 1); + goto start; + +/* #\s*d */ +pound_d: + GETNEXT NOTCASE('e', __start); + GETNEXT NOTCASE('f', __start); + GETNEXT NOTCASE('i', __start); + GETNEXT NOTCASE('n', __start); + GETNEXT NOTCASE('e', __start); + goto pound_define_undef; + +/* #\s*u */ +pound_u: + GETNEXT NOTCASE('n', __start); + GETNEXT NOTCASE('d', __start); + GETNEXT NOTCASE('e', __start); + GETNEXT NOTCASE('f', __start); + goto pound_define_undef; + +/* + * #\s*(define|undef)\s*CONFIG_(\w*) + * + * this does not define the word, because it could be inside another + * conditional (#if 0). But I do parse the word so that this instance + * does not count as a use. -- mec + */ +pound_define_undef: + GETNEXT + CASE(' ', pound_define_undef); + CASE('\t', pound_define_undef); + + NOTCASE('C', __start); + GETNEXT NOTCASE('O', __start); + GETNEXT NOTCASE('N', __start); + GETNEXT NOTCASE('F', __start); + GETNEXT NOTCASE('I', __start); + GETNEXT NOTCASE('G', __start); + GETNEXT NOTCASE('_', __start); + + map_dot = next; +pound_define_undef_CONFIG_word: + GETNEXT + if (isalnum(current) || current == '_') + goto pound_define_undef_CONFIG_word; + goto __start; + +/* \<CONFIG_(\w*) */ +cee: + if (next >= map+2 && (isalnum((int)next[-2]) || next[-2] == '_')) + goto start; + GETNEXT NOTCASE('O', __start); + GETNEXT NOTCASE('N', __start); + GETNEXT NOTCASE('F', __start); + GETNEXT NOTCASE('I', __start); + GETNEXT NOTCASE('G', __start); + GETNEXT NOTCASE('_', __start); + + map_dot = next; +cee_CONFIG_word: + GETNEXT + if (isalnum(current) || current == '_') + goto cee_CONFIG_word; + use_config(map_dot, next - map_dot - 1); + goto __start; + } +} + + + +/* + * Generate dependencies for one file. + */ +void do_depend(const char * filename, const char * command) +{ + int mapsize; +#ifndef __CYGWIN__ + int pagesizem1 = getpagesize()-1; +#endif + int fd; + struct stat st; + char * map; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror(filename); + return; + } + + fstat(fd, &st); + if (st.st_size == 0) { + fprintf(stderr,"%s is empty\n",filename); + close(fd); + return; + } + + mapsize = st.st_size; +#ifndef __CYGWIN__ + mapsize = (mapsize+pagesizem1) & ~pagesizem1; +#endif + map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0); + if ((long) map == -1) { + perror("mkdep: mmap"); + close(fd); + return; + } + if ((unsigned long) map % sizeof(unsigned long) != 0) + { + fprintf(stderr, "do_depend: map not aligned\n"); + exit(1); + } + + hasdep = 0; + clear_config(); + state_machine(map, map+st.st_size); + if (hasdep) { + puts(command); + if (*command) + define_precious(filename); + } + + munmap(map, mapsize); + close(fd); +} + + + +/* + * Generate dependencies for all files. + */ +int main(int argc, char **argv) +{ + int len; + const char *hpath; + + hpath = getenv("HPATH"); + if (!hpath) { + fputs("mkdep: HPATH not set in environment. " + "Don't bypass the top level Makefile.\n", stderr); + return 1; + } + + add_path("."); /* for #include "..." */ + + while (++argv, --argc > 0) { + if (strncmp(*argv, "-I", 2) == 0) { + if (*((*argv)+2)) { + add_path((*argv)+2); + } + else { + ++argv; + --argc; + add_path(*argv); + } + } + else if (strcmp(*argv, "--") == 0) { + break; + } + } + + add_path(hpath); /* must be last entry, for config files */ + + while (--argc > 0) { + const char * filename = *++argv; + const char * command = __depname; + g_filename = 0; + len = strlen(filename); + memcpy(depname, filename, len+1); + if (len > 2 && filename[len-2] == '.') { + if (filename[len-1] == 'c' || filename[len-1] == 'S') { + depname[len-1] = 'o'; + g_filename = filename; + command = ""; + } + } + do_depend(filename, command); + } + if (len_precious) { + *(str_precious+len_precious) = '\0'; + printf(".PRECIOUS:%s\n", str_precious); + } + return 0; +} diff --git a/uClinux-2.4.31-uc0/scripts/mkspec b/uClinux-2.4.31-uc0/scripts/mkspec new file mode 100644 index 0000000..57c9bc4 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/mkspec @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Output a simple RPM spec file that uses no fancy features requring +# RPM v4. This is intended to work with any RPM distro. +# +# The only gothic bit here is redefining install_post to avoid +# stripping the symbols from files in the kernel which we want +# +# Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net> +# +# That's the voodoo to see if it's a x86. +ISX86=`arch | grep -ie i.86` +if [ ! -z $ISX86 ]; then + PC=1 +else + PC=0 +fi +# starting to output the spec +if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then + PROVIDES=kernel-drm +fi + +PROVIDES="$PROVIDES kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" + +echo "Name: kernel" +echo "Summary: The Linux Kernel" +echo "Version: "$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION | sed -e "s/-//g" +# we need to determine the NEXT version number so that uname and +# rpm -q will agree +echo "Release: `. scripts/mkversion`" +echo "License: GPL" +echo "Group: System Environment/Kernel" +echo "Vendor: The Linux Community" +echo "URL: http://www.kernel.org" +echo -n "Source: kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL" +echo "$EXTRAVERSION.tar.gz" | sed -e "s/-//g" +echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root" +echo "Provides: $PROVIDES" +echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" +echo "" +echo "%description" +echo "The Linux Kernel, the operating system core itself" +echo "" +echo "%prep" +echo "%setup -q" +echo "" +echo "%build" +# This is the first 'disagreement' between x86 and other archs. +if [ $PC = 1 ]; then + echo "make oldconfig dep clean bzImage modules" +else + echo "make oldconfig dep clean vmlinux modules" +fi +# Back on track +echo "" +echo "%install" +echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules' +echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make modules_install' +# And that's the second +if [ $PC = 1 ]; then + echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" +else + echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" +fi +# Back on track, again +echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" +echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" +echo "" +echo "%clean" +echo '#echo -rf $RPM_BUILD_ROOT' +echo "" +echo "%files" +echo '%defattr (-, root, root)' +echo "%dir /lib/modules" +echo "/lib/modules/$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" +echo "/boot/*" +echo "" diff --git a/uClinux-2.4.31-uc0/scripts/mkuboot.sh b/uClinux-2.4.31-uc0/scripts/mkuboot.sh new file mode 100644 index 0000000..52a17ab --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/mkuboot.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# +# Build U-Boot image when `mkimage' tool is available. +# + +MKIMAGE=$(type -path mkimage) + +if [ -z "${MKIMAGE}" ]; then + # Doesn't exist + echo '"mkimage" command not found - U-Boot images will not be built' >&2 + exit 0; +fi + +# Call "mkimage" to create U-Boot image +${MKIMAGE} "$@" diff --git a/uClinux-2.4.31-uc0/scripts/mkversion b/uClinux-2.4.31-uc0/scripts/mkversion new file mode 100644 index 0000000..c12addc --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/mkversion @@ -0,0 +1,6 @@ +if [ ! -f .version ] +then + echo 1 +else + expr 0`cat .version` + 1 +fi diff --git a/uClinux-2.4.31-uc0/scripts/patch-kernel b/uClinux-2.4.31-uc0/scripts/patch-kernel new file mode 100644 index 0000000..3f316b6 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/patch-kernel @@ -0,0 +1,202 @@ +#! /bin/sh +# Script to apply kernel patches. +# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] +# The source directory defaults to /usr/src/linux, and the patch +# directory defaults to the current directory. +# e.g. +# scripts/patch-kernel . .. +# Update the kernel tree in the current directory using patches in the +# directory above to the latest Linus kernel +# scripts/patch-kernel . .. -ac +# Get the latest Linux kernel and patch it with the latest ac patch +# scripts/patch-kernel . .. 2.4.9 +# Gets standard kernel 2.4.9 +# scripts/patch-kernel . .. 2.4.9 -ac +# Gets 2.4.9 with latest ac patches +# scripts/patch-kernel . .. 2.4.9 -ac11 +# Gets 2.4.9 with ac patch ac11 +# Note: It uses the patches relative to the Linus kernels, not the +# ac to ac relative patches +# +# It determines the current kernel version from the top-level Makefile. +# It then looks for patches for the next sublevel in the patch directory. +# This is applied using "patch -p1 -s" from within the kernel directory. +# A check is then made for "*.rej" files to see if the patch was +# successful. If it is, then all of the "*.orig" files are removed. +# +# Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995. +# +# Added support for handling multiple types of compression. What includes +# gzip, bzip, bzip2, zip, compress, and plaintext. +# +# Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997. +# +# Added ability to stop at a given version number +# Put the full version number (i.e. 2.3.31) as the last parameter +# Dave Gilbert <linux@treblig.org>, 11th December 1999. + +# Fixed previous patch so that if we are already at the correct version +# not to patch up. +# +# Added -ac option, use -ac or -ac9 (say) to stop at a particular version +# Dave Gilbert <linux@treblig.org>, 29th September 2001. + +# Set directories from arguments, or use defaults. +sourcedir=${1-/usr/src/linux} +patchdir=${2-.} +stopvers=${3-imnotaversion} + +if [ "$1" = -h -o "$1" = --help -o ! -r "$sourcedir/Makefile" ]; then +cat << USAGE +usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] + The source directory defaults to /usr/src/linux, and + the patch directory defaults to the current directory. +USAGE +exit 1 +fi + +# See if we have any -ac options +for PARM in $* +do + case $PARM in + -ac*) + gotac=$PARM; + + esac; +done + +# --------------------------------------------------------------------------- +# Find a file, first parameter is basename of file +# it tries many compression mechanisms and sets variables to say how to get it +findFile () { + filebase=$1; + + if [ -r ${filebase}.gz ]; then + ext=".gz" + name="gzip" + uncomp="gunzip -dc" + elif [ -r ${filebase}.bz ]; then + ext=".bz" + name="bzip" + uncomp="bunzip -dc" + elif [ -r ${filebase}.bz2 ]; then + ext=".bz2" + name="bzip2" + uncomp="bunzip2 -dc" + elif [ -r ${filebase}.zip ]; then + ext=".zip" + name="zip" + uncomp="unzip -d" + elif [ -r ${filebase}.Z ]; then + ext=".Z" + name="uncompress" + uncomp="uncompress -c" + elif [ -r ${filebase} ]; then + ext="" + name="plaintext" + uncomp="cat" + else + return 1; + fi + + return 0; +} + +# --------------------------------------------------------------------------- +# Apply a patch and check it goes in cleanly +# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension + +applyPatch () { + echo -n "Applying $1 (${name})... " + if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir + then + echo "done." + else + echo "failed. Clean up yourself." + return 1; + fi + if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] + then + echo "Aborting. Reject files found." + return 1; + fi + # Remove backup files + find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; + + return 0; +} + +# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTERVERSION +eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $sourcedir/Makefile` +if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] +then + echo "unable to determine current kernel version" >&2 + exit 1 +fi + +echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}" + +if [ x$EXTRAVERSION != "x" ] +then + echo "I'm sorry but patch-kernel can't work with a kernel source tree that is not a base version" + exit 1; +fi + +while : +do + CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" + if [ $stopvers = $CURRENTFULLVERSION ] + then + echo "Stoping at $CURRENTFULLVERSION base as requested." + break + fi + + SUBLEVEL=`expr $SUBLEVEL + 1` + FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" + + patch=patch-$FULLVERSION + + # See if the file exists and find extension + findFile $patchdir/${patch} || break + + # Apply the patch and check all is OK + applyPatch $patch || break +done + +if [ x$gotac != x ]; then + # Out great user wants the -ac patches + # They could have done -ac (get latest) or -acxx where xx=version they want + if [ $gotac == "-ac" ] + then + # They want the latest version + HIGHESTPATCH=0 + for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.* + do + ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'` + # Check it is actually a recognised patch type + findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break + + if [ $ACVALUE -gt $HIGHESTPATCH ] + then + HIGHESTPATCH=$ACVALUE + fi + done + + if [ $HIGHESTPATCH -ne 0 ] + then + findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break + applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} + else + echo "No ac patches found" + fi + else + # They want an exact version + findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || { + echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum." + exit 1 + } + applyPatch patch-${CURRENTFULLVERSION}${gotac} + fi +fi + + diff --git a/uClinux-2.4.31-uc0/scripts/pathdown.sh b/uClinux-2.4.31-uc0/scripts/pathdown.sh new file mode 100644 index 0000000..97424c2 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/pathdown.sh @@ -0,0 +1,17 @@ +#!/bin/sh +UP= +DN=${PWD:?} +TP=${TOPDIR:?} + +if [ "$VIRTUAL_TOPDIR" ]; then +TP=${VIRTUAL_TOPDIR:?} +fi + +while [ ! $TP/$UP/. -ef $DN ] ;do + UP=`basename $PWD`/$UP + cd .. + if [ "$PWD" = "/" ]; then echo "Lost"; exit 1; fi +done + +echo $UP +exit 0 diff --git a/uClinux-2.4.31-uc0/scripts/split-include.c b/uClinux-2.4.31-uc0/scripts/split-include.c new file mode 100644 index 0000000..4637d68 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/split-include.c @@ -0,0 +1,226 @@ +/* + * split-include.c + * + * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>. + * This is a C version of syncdep.pl by Werner Almesberger. + * + * This program takes autoconf.h as input and outputs a directory full + * of one-line include files, merging onto the old values. + * + * Think of the configuration options as key-value pairs. Then there + * are five cases: + * + * key old value new value action + * + * KEY-1 VALUE-1 VALUE-1 leave file alone + * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file + * KEY-3 - VALUE-3 write VALUE-3 into file + * KEY-4 VALUE-4 - write an empty file + * KEY-5 (empty) - leave old empty file alone + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define ERROR_EXIT(strExit) \ + { \ + const int errnoSave = errno; \ + fprintf(stderr, "%s: ", str_my_name); \ + errno = errnoSave; \ + perror((strExit)); \ + exit(1); \ + } + + + +int main(int argc, const char * argv []) +{ + const char * str_my_name; + const char * str_file_autoconf; + const char * str_dir_config; + + FILE * fp_config; + FILE * fp_target; + FILE * fp_find; + + int buffer_size; + + char * line; + char * old_line; + char * list_target; + char * ptarget; + + struct stat stat_buf; + + /* Check arg count. */ + if (argc != 3) + { + fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]); + exit(1); + } + + str_my_name = argv[0]; + str_file_autoconf = argv[1]; + str_dir_config = argv[2]; + + /* Find a buffer size. */ + if (stat(str_file_autoconf, &stat_buf) != 0) + ERROR_EXIT(str_file_autoconf); + buffer_size = 2 * stat_buf.st_size + 4096; + + /* Allocate buffers. */ + if ( (line = malloc(buffer_size)) == NULL + || (old_line = malloc(buffer_size)) == NULL + || (list_target = malloc(buffer_size)) == NULL ) + ERROR_EXIT(str_file_autoconf); + + /* Open autoconfig file. */ + if ((fp_config = fopen(str_file_autoconf, "r")) == NULL) + ERROR_EXIT(str_file_autoconf); + + /* Make output directory if needed. */ + if (stat(str_dir_config, &stat_buf) != 0) + { + if (mkdir(str_dir_config, 0755) != 0) + ERROR_EXIT(str_dir_config); + } + + /* Change to output directory. */ + if (chdir(str_dir_config) != 0) + ERROR_EXIT(str_dir_config); + + /* Put initial separator into target list. */ + ptarget = list_target; + *ptarget++ = '\n'; + + /* Read config lines. */ + while (fgets(line, buffer_size, fp_config)) + { + const char * str_config; + int is_same; + int itarget; + + if (line[0] != '#') + continue; + if ((str_config = strstr(line, "CONFIG_")) == NULL) + continue; + + /* Make the output file name. */ + str_config += sizeof("CONFIG_") - 1; + for (itarget = 0; !isspace((int)str_config[itarget]); itarget++) + { + char c = str_config[itarget]; + if (isupper((int)c)) c = tolower((int)c); + if (c == '_') c = '/'; + ptarget[itarget] = c; + } + ptarget[itarget++] = '.'; + ptarget[itarget++] = 'h'; + ptarget[itarget++] = '\0'; + + /* Check for existing file. */ + is_same = 0; + if ((fp_target = fopen(ptarget, "r")) != NULL) + { + fgets(old_line, buffer_size, fp_target); + if (fclose(fp_target) != 0) + ERROR_EXIT(ptarget); + if (!strcmp(line, old_line)) + is_same = 1; + } + + if (!is_same) + { + /* Auto-create directories. */ + int islash; + for (islash = 0; islash < itarget; islash++) + { + if (ptarget[islash] == '/') + { + ptarget[islash] = '\0'; + if (stat(ptarget, &stat_buf) != 0 + && mkdir(ptarget, 0755) != 0) + ERROR_EXIT( ptarget ); + ptarget[islash] = '/'; + } + } + + /* Write the file. */ + if ((fp_target = fopen(ptarget, "w" )) == NULL) + ERROR_EXIT(ptarget); + fputs(line, fp_target); + if (ferror(fp_target) || fclose(fp_target) != 0) + ERROR_EXIT(ptarget); + } + + /* Update target list */ + ptarget += itarget; + *(ptarget-1) = '\n'; + } + + /* + * Close autoconfig file. + * Terminate the target list. + */ + if (fclose(fp_config) != 0) + ERROR_EXIT(str_file_autoconf); + *ptarget = '\0'; + + /* + * Fix up existing files which have no new value. + * This is Case 4 and Case 5. + * + * I re-read the tree and filter it against list_target. + * This is crude. But it avoids data copies. Also, list_target + * is compact and contiguous, so it easily fits into cache. + * + * Notice that list_target contains strings separated by \n, + * with a \n before the first string and after the last. + * fgets gives the incoming names a terminating \n. + * So by having an initial \n, strstr will find exact matches. + */ + + fp_find = popen("find * -type f -name \"*.h\" -print", "r"); + if (fp_find == 0) + ERROR_EXIT( "find" ); + + line[0] = '\n'; + while (fgets(line+1, buffer_size, fp_find)) + { + if (strstr(list_target, line) == NULL) + { + /* + * This is an old file with no CONFIG_* flag in autoconf.h. + */ + + /* First strip the \n. */ + line[strlen(line)-1] = '\0'; + + /* Grab size. */ + if (stat(line+1, &stat_buf) != 0) + ERROR_EXIT(line); + + /* If file is not empty, make it empty and give it a fresh date. */ + if (stat_buf.st_size != 0) + { + if ((fp_target = fopen(line+1, "w")) == NULL) + ERROR_EXIT(line); + if (fclose(fp_target) != 0) + ERROR_EXIT(line); + } + } + } + + if (pclose(fp_find) != 0) + ERROR_EXIT("find"); + + return 0; +} diff --git a/uClinux-2.4.31-uc0/scripts/split-man b/uClinux-2.4.31-uc0/scripts/split-man new file mode 100644 index 0000000..04e2316 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/split-man @@ -0,0 +1,33 @@ +#!/usr/bin/perl +# +# split-man: create man pages from kernel-doc -man output +# +# Author: Tim Waugh <twaugh@redhat.com> +# Modified by: Christoph Hellwig <hch@infradead.org> +# + +use strict; + +die "$0: where do I put the results?\n" unless ($#ARGV >= 0); +die "$0: can't create $ARGV[0]: $!\n" unless mkdir $ARGV[0], 0777; + +my $state = 0; + +while (<STDIN>) { + s/&(\w+)/\\fB\1\\fP/g; # fix smgl uglinesses + if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) { + close OUT unless ($state++ == 0); + my $fn = "$ARGV[0]/$1.9"; + if (open OUT, ">$fn") { + print STDERR "creating $fn\n"; + } else { + die "can't open $fn: $!\n"; + } + + print OUT $_; + } elsif ($state != 0) { + print OUT $_; + } +} + +close OUT; diff --git a/uClinux-2.4.31-uc0/scripts/tail.tk b/uClinux-2.4.31-uc0/scripts/tail.tk new file mode 100644 index 0000000..49d7aa3 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/tail.tk @@ -0,0 +1,89 @@ +# FILE: tail.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1998, Michael Elizabeth Chastain, <mec@shout.net> +# Arrange buttons in three columns for better screen fitting. +# + +# +# Read the user's settings from .config. These will override whatever is +# in config.in. Don't do this if the user specified a -D to force +# the defaults. +# +if { [file readable .config] == 1} then { + if { $argc > 0 } then { + if { [lindex $argv 0] != "-D" } then { + read_config .config + } + else + { + read_config $defaults + } + } else { + read_config .config + } +} else { + read_config $defaults +} + +update_define 1 $total_menus 0 +update_mainmenu + +button .f0.right.save -anchor w -text "Save and Exit" -underline 0\ + -command { catch {exec cp -f .config .config.old}; \ + writeconfig .config include/linux/autoconf.h; wrapup .wrap } + +button .f0.right.quit -anchor w -text "Quit Without Saving" -underline 0\ + -command { maybe_exit .maybe } + +button .f0.right.load -anchor w -text "Load Configuration from File" \ + -command { load_configfile .load "Load Configuration from file" read_config_file +} + +button .f0.right.store -anchor w -text "Store Configuration to File" \ + -command { load_configfile .load "Store Configuration to file" write_config_file } + +# +# Now pack everything. +# + +pack .f0.right.store .f0.right.load .f0.right.quit .f0.right.save \ + -padx 0 -pady 0 -side bottom -fill x +pack .f0.left .f0.middle .f0.right -side left -padx 5 -pady 0 -fill y +pack .f0 -padx 5 -pady 5 + +update idletasks +set winy [expr 10 + [winfo reqheight .f0]] +set scry [lindex [wm maxsize .] 1] +set winx [expr 10 + [winfo reqwidth .f0]] +set scrx [lindex [wm maxsize .] 0] +if {$winx < $scrx} then {set maxx -1} else {set maxx $winx} +if {$winy < $scry} then {set maxy -1} else {set maxy $winy} +.f0 configure -width $winx -height $winy +wm maxsize . $maxx $maxy + +# +# If we cannot write our config files, disable the write button. +# +if { [file exists .config] == 1 } then { + if { [file writable .config] == 0 } then { + .f0.right.save configure -state disabled + } + } else { + if { [file writable .] == 0 } then { + .f0.right.save configure -state disabled + } + } + +if { [file exists include/linux/autoconf.h] == 1 } then { + if { [file writable include/linux/autoconf.h] == 0 } then { + .f0.right.save configure -state disabled + } + } else { + if { [file writable include/linux/] == 0 } then { + .f0.right.save configure -state disabled + } + } diff --git a/uClinux-2.4.31-uc0/scripts/tkcond.c b/uClinux-2.4.31-uc0/scripts/tkcond.c new file mode 100644 index 0000000..34c923f --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/tkcond.c @@ -0,0 +1,602 @@ +/* + * tkcond.c + * + * Eric Youngdale was the original author of xconfig. + * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. + * + * This file takes the tokenized statement list and transforms 'if ...' + * statements. For each simple statement, I find all of the 'if' statements + * that enclose it, and attach the aggregate conditionals of those 'if' + * statements to the cond list of the simple statement. + * + * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Steam-clean this file. I tested this by generating kconfig.tk for + * every architecture and comparing it character-for-character against + * the output of the old tkparse. + * + * 07 July 1999, Andrzej M. Krzysztofowicz <ankry@mif.pg.gda.pl> + * - kvariables removed; all variables are stored in a single table now + * - some elimination of options non-valid for current architecture + * implemented. + * - negation (!) eliminated from conditions + * + * TO DO: + * - xconfig is at the end of its life cycle. Contact <mec@shout.net> if + * you are interested in working on the replacement. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "tkparse.h" + + + +/* + * Mark variables which are defined anywhere. + */ +static void mark_variables( struct kconfig * scfg ) +{ + struct kconfig * cfg; + int i; + + for ( i = 1; i <= max_varnum; i++ ) + vartable[i].defined = 0; + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_bool + || cfg->token == token_choice_item + || cfg->token == token_define_bool + || cfg->token == token_define_hex + || cfg->token == token_define_int + || cfg->token == token_define_string + || cfg->token == token_define_tristate + || cfg->token == token_dep_bool + || cfg->token == token_dep_mbool + || cfg->token == token_dep_tristate + || cfg->token == token_hex + || cfg->token == token_int + || cfg->token == token_string + || cfg->token == token_tristate + || cfg->token == token_unset ) + { + if ( cfg->nameindex > 0 ) /* paranoid */ + { + vartable[cfg->nameindex].defined = 1; + } + } + } +} + + + +static void free_cond( struct condition *cond ) +{ + struct condition *tmp, *tmp1; + for ( tmp = cond; tmp; tmp = tmp1 ) + { + tmp1 = tmp->next; + free( (void*)tmp ); + } +} + + + +/* + * Remove the bang operator from a condition to avoid priority problems. + * "!" has different priorities as "test" command argument and in + * a tk script. + */ +static struct condition * remove_bang( struct condition * condition ) +{ + struct condition * conda, * condb, * prev = NULL; + + for ( conda = condition; conda; conda = conda->next ) + { + if ( conda->op == op_bang && conda->next && + ( condb = conda->next->next ) ) + { + if ( condb->op == op_eq || condb->op == op_neq ) + { + condb->op = (condb->op == op_eq) ? op_neq : op_eq; + conda->op = op_nuked; + if ( prev ) + { + prev->next = conda->next; + } + else + { + condition = conda->next; + } + conda->next = NULL; + free_cond( conda ); + conda = condb; + } + } + prev = conda; + } + return condition; +} + + + +/* + * Make a new condition chain by joining the current condition stack with + * the "&&" operator for glue. + */ +static struct condition * join_condition_stack( struct condition * conditions [], + int depth ) +{ + struct condition * cond_list; + struct condition * cond_last; + int i, is_first = 1; + + cond_list = cond_last = NULL; + + for ( i = 0; i < depth; i++ ) + { + if ( conditions[i]->op == op_false ) + { + struct condition * cnew; + + /* It is always false condition */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_false; + cond_list = cond_last = cnew; + goto join_done; + } + } + for ( i = 0; i < depth; i++ ) + { + struct condition * cond; + struct condition * cnew; + int add_paren; + + /* omit always true conditions */ + if ( conditions[i]->op == op_true ) + continue; + + /* if i have another condition, add an '&&' operator */ + if ( !is_first ) + { + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_and; + cond_last->next = cnew; + cond_last = cnew; + } + + if ( conditions[i]->op != op_lparen ) + { + /* add a '(' */ + add_paren = 1; + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_lparen; + if ( cond_last == NULL ) + { cond_list = cond_last = cnew; } + else + { cond_last->next = cnew; cond_last = cnew; } + } + else + { + add_paren = 0; + } + + /* duplicate the chain */ + for ( cond = conditions [i]; cond != NULL; cond = cond->next ) + { + cnew = malloc( sizeof(*cnew) ); + cnew->next = NULL; + cnew->op = cond->op; + cnew->str = cond->str ? strdup( cond->str ) : NULL; + cnew->nameindex = cond->nameindex; + if ( cond_last == NULL ) + { cond_list = cond_last = cnew; } + else + { cond_last->next = cnew; cond_last = cnew; } + } + + if ( add_paren ) + { + /* add a ')' */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_rparen; + cond_last->next = cnew; + cond_last = cnew; + } + is_first = 0; + } + + /* + * Remove duplicate conditions. + */ + { + struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f; + + for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next ) + { + if ( cond1->op == op_lparen ) + { + cond1b = cond1 ->next; if ( cond1b == NULL ) break; + cond1c = cond1b->next; if ( cond1c == NULL ) break; + cond1d = cond1c->next; if ( cond1d == NULL ) break; + cond1e = cond1d->next; if ( cond1e == NULL ) break; + cond1f = cond1e->next; if ( cond1f == NULL ) break; + + if ( cond1b->op == op_variable + && ( cond1c->op == op_eq || cond1c->op == op_neq ) + && cond1d->op == op_constant + && cond1e->op == op_rparen ) + { + struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f; + + for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next ) + { + if ( cond2->op == op_lparen ) + { + cond2b = cond2 ->next; if ( cond2b == NULL ) break; + cond2c = cond2b->next; if ( cond2c == NULL ) break; + cond2d = cond2c->next; if ( cond2d == NULL ) break; + cond2e = cond2d->next; if ( cond2e == NULL ) break; + cond2f = cond2e->next; + + /* look for match */ + if ( cond2b->op == op_variable + && cond2b->nameindex == cond1b->nameindex + && cond2c->op == cond1c->op + && cond2d->op == op_constant + && strcmp( cond2d->str, cond1d->str ) == 0 + && cond2e->op == op_rparen ) + { + /* one of these must be followed by && */ + if ( cond1f->op == op_and + || ( cond2f != NULL && cond2f->op == op_and ) ) + { + /* nuke the first duplicate */ + cond1 ->op = op_nuked; + cond1b->op = op_nuked; + cond1c->op = op_nuked; + cond1d->op = op_nuked; + cond1e->op = op_nuked; + if ( cond1f->op == op_and ) + cond1f->op = op_nuked; + else + cond2f->op = op_nuked; + } + } + } + } + } + } + } + } + +join_done: + return cond_list; +} + + + +static char * current_arch = NULL; + +/* + * Eliminating conditions with ARCH = <not current>. + */ +static struct condition *eliminate_other_arch( struct condition *list ) +{ + struct condition *cond1a = list, *cond1b = NULL, *cond1c = NULL, *cond1d = NULL; + if ( current_arch == NULL ) + current_arch = getenv( "ARCH" ); + if ( current_arch == NULL ) + { + fprintf( stderr, "error: ARCH undefined\n" ); + exit( 1 ); + } + if ( cond1a->op == op_variable + && ! strcmp( vartable[cond1a->nameindex].name, "ARCH" ) ) + { + cond1b = cond1a->next; if ( cond1b == NULL ) goto done; + cond1c = cond1b->next; if ( cond1c == NULL ) goto done; + cond1d = cond1c->next; + if ( cond1c->op == op_constant && cond1d == NULL ) + { + if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for another architecture */ + cond1a->op = op_false; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for current architecture */ + cond1a->op = op_true; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + } + else if ( cond1c->op == op_constant && cond1d->op == op_or ) + { + if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for another architecture */ + cond1b = cond1d->next; + cond1d->next = NULL; + free_cond( cond1a ); + return eliminate_other_arch( cond1b ); + } + else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for current architecture */ + cond1a->op = op_true; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + } + else if ( cond1c->op == op_constant && cond1d->op == op_and ) + { + if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for another architecture */ + int l_par = 0; + + for ( cond1c = cond1d->next; cond1c; cond1c = cond1c->next ) + { + if ( cond1c->op == op_lparen ) + l_par++; + else if ( cond1c->op == op_rparen ) + l_par--; + else if ( cond1c->op == op_or && l_par == 0 ) + /* Expression too complex - don't touch */ + return cond1a; + else if ( l_par < 0 ) + { + fprintf( stderr, "incorrect condition: programming error ?\n" ); + exit( 1 ); + } + } + cond1a->op = op_false; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) + || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) + { + /* This is for current architecture */ + cond1b = cond1d->next; + cond1d->next = NULL; + free_cond( cond1a ); + return eliminate_other_arch( cond1b ); + } + } + } + if ( cond1a->op == op_variable && ! vartable[cond1a->nameindex].defined ) + { + cond1b = cond1a->next; if ( cond1b == NULL ) goto done; + cond1c = cond1b->next; if ( cond1c == NULL ) goto done; + cond1d = cond1c->next; + + if ( cond1c->op == op_constant + && ( cond1d == NULL || cond1d->op == op_and ) ) /*???*/ + { + if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ) + { + cond1a->op = op_false; + cond1a->next = NULL; + free_cond( cond1b ); + return cond1a; + } + } + else if ( cond1c->op == op_constant && cond1d->op == op_or ) + { + if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ) + { + cond1b = cond1d->next; + cond1d->next = NULL; + free_cond( cond1a ); + return eliminate_other_arch( cond1b ); + } + } + } +done: + return list; +} + + + +/* + * This is the main transformation function. + */ +void fix_conditionals( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + /* + * Transform op_variable to op_kvariable. + */ + mark_variables( scfg ); + + /* + * Walk the statement list, maintaining a stack of current conditions. + * token_if push its condition onto the stack. + * token_else invert the condition on the top of the stack. + * token_endif pop the stack. + * + * For a simple statement, create a condition chain by joining together + * all of the conditions on the stack. + */ + { + struct condition * cond_stack [32]; + int depth = 0; + struct kconfig * prev = NULL; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + int good = 1; + switch ( cfg->token ) + { + default: + break; + + case token_if: + cond_stack [depth++] = + remove_bang( eliminate_other_arch( cfg->cond ) ); + cfg->cond = NULL; + break; + + case token_else: + { + /* + * Invert the condition chain. + * + * Be careful to transfrom op_or to op_and1, not op_and. + * I will need this later in the code that removes + * duplicate conditions. + */ + struct condition * cond; + + for ( cond = cond_stack [depth-1]; + cond != NULL; + cond = cond->next ) + { + switch( cond->op ) + { + default: break; + case op_and: cond->op = op_or; break; + case op_or: cond->op = op_and1; break; + case op_neq: cond->op = op_eq; break; + case op_eq: cond->op = op_neq; break; + case op_true: cond->op = op_false;break; + case op_false:cond->op = op_true; break; + } + } + } + break; + + case token_fi: + --depth; + break; + + case token_bool: + case token_choice_item: + case token_choice_header: + case token_comment: + case token_define_bool: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_define_tristate: + case token_endmenu: + case token_hex: + case token_int: + case token_mainmenu_option: + case token_string: + case token_tristate: + case token_unset: + cfg->cond = join_condition_stack( cond_stack, depth ); + if ( cfg->cond && cfg->cond->op == op_false ) + { + good = 0; + if ( prev ) + prev->next = cfg->next; + else + scfg = cfg->next; + } + break; + + case token_dep_bool: + case token_dep_mbool: + case token_dep_tristate: + /* + * Same as the other simple statements, plus an additional + * condition for the dependency. + */ + if ( cfg->cond ) + { + cond_stack [depth] = eliminate_other_arch( cfg->cond ); + cfg->cond = join_condition_stack( cond_stack, depth+1 ); + } + else + { + cfg->cond = join_condition_stack( cond_stack, depth ); + } + if ( cfg->cond && cfg->cond->op == op_false ) + { + good = 0; + if ( prev ) + prev->next = cfg->next; + else + scfg = cfg->next; + } + break; + } + if ( good ) + prev = cfg; + } + } +} + + + +#if 0 +void dump_condition( struct condition *list ) +{ + struct condition *tmp; + for ( tmp = list; tmp; tmp = tmp->next ) + { + switch (tmp->op) + { + default: + break; + case op_variable: + printf( " %s", vartable[tmp->nameindex].name ); + break; + case op_constant: + printf( " %s", tmp->str ); + break; + case op_eq: + printf( " =" ); + break; + case op_bang: + printf( " !" ); + break; + case op_neq: + printf( " !=" ); + break; + case op_and: + case op_and1: + printf( " -a" ); + break; + case op_or: + printf( " -o" ); + break; + case op_true: + printf( " TRUE" ); + break; + case op_false: + printf( " FALSE" ); + break; + case op_lparen: + printf( " (" ); + break; + case op_rparen: + printf( " )" ); + break; + } + } + printf( "\n" ); +} +#endif diff --git a/uClinux-2.4.31-uc0/scripts/tkgen.c b/uClinux-2.4.31-uc0/scripts/tkgen.c new file mode 100644 index 0000000..235141e --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/tkgen.c @@ -0,0 +1,1536 @@ +/* Generate tk script based upon config.in + * + * Version 1.0 + * Eric Youngdale + * 10/95 + * + * 1996 01 04 + * Avery Pennarun - Aesthetic improvements. + * + * 1996 01 24 + * Avery Pennarun - Bugfixes and more aesthetics. + * + * 1996 03 08 + * Avery Pennarun - The int and hex config.in commands work right. + * - Choice buttons are more user-friendly. + * - Disabling a text entry line greys it out properly. + * - dep_tristate now works like in Configure. (not pretty) + * - No warnings in gcc -Wall. (Fixed some "interesting" bugs.) + * - Faster/prettier "Help" lookups. + * + * 1996 03 15 + * Avery Pennarun - Added new sed script from Axel Boldt to make help even + * faster. (Actually awk is downright slow on some machines.) + * - Fixed a bug I introduced into Choice dependencies. Thanks + * to Robert Krawitz for pointing this out. + * + * 1996 03 16 + * Avery Pennarun - basic "do_make" support added to let sound config work. + * + * 1996 03 25 + * Axel Boldt - Help now works on "choice" buttons. + * + * 1996 04 06 + * Avery Pennarun - Improved sound config stuff. (I think it actually works + * now!) + * - Window-resize-limits don't use ugly /usr/lib/tk4.0 hack. + * - int/hex work with tk3 again. (The "cget" error.) + * - Next/Prev buttons switch between menus. I can't take + * much credit for this; the code was already there, but + * ifdef'd out for some reason. It flickers a lot, but + * I suspect there's no "easy" fix for that. + * - Labels no longer highlight as you move the mouse over + * them (although you can still press them... oh well.) + * - Got rid of the last of the literal color settings, to + * help out people with mono X-Windows systems. + * (Apparently there still are some out there!) + * - Tabstops seem sensible now. + * + * 1996 04 14 + * Avery Pennarun - Reduced flicker when creating windows, even with "update + * idletasks" hack. + * + * 1997 12 08 + * Michael Chastain - Remove sound driver special cases. + * + * 1997 11 15 + * Michael Chastain - For choice buttons, write values for all options, + * not just the single chosen one. This is compatible + * with 'make config' and 'make oldconfig', and is + * needed so smart-config dependencies work if the + * user switches from one configuration method to + * another. + * + * 1998 03 09 + * Axel Boldt - Smaller layout of main menu - it's still too big for 800x600. + * - Display help in text window to allow for cut and paste. + * - Allow for empty lines in help texts. + * - update_define should not set all variables unconditionally to + * 0: they may have been set to 1 elsewhere. CONFIG_NETLINK is + * an example. + * + * 1999 01 04 + * Michael Elizabeth Chastain <mec@shout.net> + * - Call clear_globalflags when writing out update_mainmenu. + * This fixes the missing global/vfix lines for ARCH=alpha on 2.2.0-pre4. + * + * 8 January 1999, Michael Elizabeth Chastain <mec@shout.net> + * - Emit menus_per_column + * + * 14 January 1999, Michael Elizabeth Chastain <mec@shout.net> + * - Steam-clean this file. I tested this by generating kconfig.tk for every + * architecture and comparing it character-for-character against the output + * of the old tkparse. + * - Fix flattening of nested menus. The old code simply assigned items to + * the most recent token_mainmenu_option, without paying attention to scope. + * For example: "menu-1 bool-a menu-2 bool-b endmenu bool-c bool-d endmenu". + * The old code would put bool-a in menu-1, bool-b in menu-2, and bool-c + * and bool-d in *menu-2*. This hosed the nested submenus in + * drives/net/Config.in and other places. + * - Fix menu line wraparound at 128 menus (some fool used a 'char' for + * a counter). + * + * 23 January 1999, Michael Elizabeth Chastain <mec@shout.net> + * - Remove bug-compatible code. + * + * 07 July 1999, Andrzej M. Krzysztofowicz <ankry@mif.pg.gda.pl> + * Some bugfixes, including + * - disabling "m" options when CONFIG_MODULES is set to "n" as well as "y" + * option in dep_tristate when dependency is set to "m", + * - deactivating choices which should not be available, + * - basic validation for int and hex introduced if the entered one is not + * valid, + * - updates of all opened menus instead of the active only. I was afraid + * that it would slow down updates, but I don't even see any speed difference + * on my machine. If it slows you can still work with only a single menu + * opened, + * - fixed error when focussing non-existent window (especially Help windows), + * Higher level submenus implemented. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include "tkparse.h" + + +/* + * Total number of menus. + */ +static int tot_menu_num = 0; + +/* + * Pointers to mainmenu_option and endmenu of each menu. + */ +struct kconfig * menu_first [100]; +struct kconfig * menu_last [100]; + +/* + * Generate portion of wish script for the beginning of a submenu. + * The guts get filled in with the various options. + */ +static void start_proc( char * label, int menu_num, int toplevel ) +{ + if ( toplevel ) + printf( "menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label ); + printf( "proc menu%d {w title} {\n", menu_num ); + printf( "\tset oldFocus [focus]\n" ); + if ( menu_first[menu_num]->menu_number != 0 ) + printf( "\tcatch {focus .menu%d}\n", + menu_first[menu_num]->menu_number ); + printf( "\tcatch {destroy $w; unregister_active %d}\n", menu_num ); + printf( "\ttoplevel $w -class Dialog\n" ); + printf( "\twm withdraw $w\n" ); + printf( "\tglobal active_menus\n" ); + printf( "\tset active_menus [lsort -integer [linsert $active_menus end %d]]\n", menu_num ); + printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" ); + printf( "\t\t\"%s\" -relief raised\n", label ); + printf( "\tpack $w.m -pady 10 -side top -padx 10\n" ); + printf( "\twm title $w \"%s\" \n\n", label ); + + printf( "\tbind $w <Escape> \"catch {focus $oldFocus}; destroy $w; unregister_active %d; break\"\n", menu_num); + + printf("\tset nextscript "); + printf("\"catch {focus $oldFocus}; " ); + /* + * We are checking which windows should be destroyed and which are + * common parents with the next one. Remember that menu_num field + * in mainmenu_option record reports number of its *parent* menu. + */ + if ( menu_num < tot_menu_num + && menu_first[menu_num + 1]->menu_number != menu_num ) + { + int to_destr; + + printf( "destroy $w; unregister_active %d; ", menu_num ); + to_destr = menu_first[menu_num]->menu_number; + while ( to_destr > 0 && menu_first[menu_num + 1]->menu_number != to_destr ) + { + printf( "catch {destroy .menu%d}; unregister_active %d; ", + to_destr, to_destr ); + to_destr = menu_first[to_destr]->menu_number; + } + } + printf( "menu%d .menu%d \\\"$title\\\"\"\n", + menu_num+1, menu_num+1 ); + + /* + * Attach the "Prev", "Next" and "OK" buttons at the end of the window. + */ + printf( "\tframe $w.f\n" ); + if ( toplevel ) + printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); + else + printf( "\tbutton $w.f.back -text \"OK\" \\\n" ); + printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d\"\n", + menu_num ); + printf( "\tbutton $w.f.next -text \"Next\" -underline 0\\\n" ); + printf( "\t\t-width 15 -command $nextscript\n"); + + if ( menu_num == tot_menu_num ) { + printf( "\t$w.f.next configure -state disabled\n" ); + /* + * this is a bit hackish but Alt-n must be rebound + * otherwise if the user press Alt-n on the last menu + * it will give him/her the next menu of one of the + * previous options + */ + printf( "\tbind all <Alt-n> \"puts \\\"no more menus\\\" \"\n"); + } + else + { + /* + * I should be binding to $w not all - but if I do nehat I get the error "unknown path" + */ + printf( "\tbind all <Alt-n> $nextscript\n"); + } + printf( "\tbutton $w.f.prev -text \"Prev\" -underline 0\\\n" ); + printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\"\"\n", + menu_num, menu_num-1, menu_num-1 ); + if ( menu_num == 1 ) { + printf( "\t$w.f.prev configure -state disabled\n" ); + } + else + { + printf( "\tbind $w <Alt-p> \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\";break\"\n", + menu_num, menu_num-1, menu_num-1 ); + } + printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" ); + printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" ); + + /* + * Lines between canvas and other areas of the window. + */ + printf( "\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n" ); + printf( "\tpack $w.topline -side top -fill x\n\n" ); + printf( "\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n" ); + printf( "\tpack $w.botline -side bottom -fill x\n\n" ); + + /* + * The "config" frame contains the canvas and a scrollbar. + */ + printf( "\tframe $w.config\n" ); + printf( "\tpack $w.config -fill y -expand on\n\n" ); + printf( "\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n" ); + printf( "\tpack $w.config.vscroll -side right -fill y\n\n" ); + + /* + * The scrollable canvas itself, where the real work (and mess) gets done. + */ + printf( "\tcanvas $w.config.canvas -height 1\\\n" ); + printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" ); + printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" ); + printf( "\tframe $w.config.f\n" ); + printf( "\tbind $w <Key-Down> \"$w.config.canvas yview scroll 1 unit;break;\"\n"); + printf( "\tbind $w <Key-Up> \"$w.config.canvas yview scroll -1 unit;break;\"\n"); + printf( "\tbind $w <Key-Next> \"$w.config.canvas yview scroll 1 page;break;\"\n"); + printf( "\tbind $w <Key-Prior> \"$w.config.canvas yview scroll -1 page;break;\"\n"); + printf( "\tbind $w <Key-Home> \"$w.config.canvas yview moveto 0;break;\"\n"); + printf( "\tbind $w <Key-End> \"$w.config.canvas yview moveto 1 ;break;\"\n"); + printf( "\tpack $w.config.canvas -side right -fill y\n" ); + printf("\n\n"); +} + + + +/* + * Each proc we create needs a global declaration for any global variables we + * use. To minimize the size of the file, we set a flag each time we output + * a global declaration so we know whether we need to insert one for a + * given function or not. + */ +static void clear_globalflags(void) +{ + int i; + for ( i = 1; i <= max_varnum; i++ ) + vartable[i].global_written = 0; +} + + + +/* + * Output a "global" line for a given variable. Also include the + * call to "vfix". (If vfix is not needed, then it's fine to just printf + * a "global" line). + */ +void global( const char *var ) +{ + printf( "\tglobal %s\n", var ); +} + + + +/* + * This function walks the chain of conditions that we got from cond.c + * and creates a TCL conditional to enable/disable a given widget. + */ +void generate_if( struct kconfig * cfg, struct condition * ocond, + int menu_num, int line_num ) +{ + struct condition * cond; + struct dependency * tmp; + struct kconfig * cfg1; + + if ( line_num >= -1 ) + { + if ( cfg->token == token_define_bool || cfg->token == token_define_hex + || cfg->token == token_define_int || cfg->token == token_define_string + || cfg->token == token_define_tristate || cfg->token == token_unset ) + return; + if ( cfg->token == token_comment && line_num == -1 ) + return; + } + else + { + if ( cfg->token == token_string || cfg->token == token_mainmenu_option ) + return; + } + + /* + * First write any global declarations we need for this conditional. + */ + for ( cond = ocond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: + break; + + case op_variable: + if ( ! vartable[cond->nameindex].global_written ) + { + vartable[cond->nameindex].global_written = 1; + global( vartable[cond->nameindex].name ); + } + break; + } + } + + /* + * Now write this option. + */ + if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + global( vartable[cfg->nameindex].name ); + } + + /* + * Generate the body of the conditional. + */ + printf( "\tif {" ); + for ( cond = ocond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: + break; + + case op_bang: printf( " ! " ); break; + case op_eq: printf( " == " ); break; + case op_neq: printf( " != " ); break; + case op_and: printf( " && " ); break; + case op_and1: printf( " && " ); break; + case op_or: printf( " || " ); break; + case op_lparen: printf( "(" ); break; + case op_rparen: printf( ")" ); break; + + case op_variable: + printf( "$%s", vartable[cond->nameindex].name ); + break; + + case op_constant: + if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); + else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); + else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else if ( strcmp( cond->str, "" ) == 0 ) printf( "4" ); + else + printf( "\"%s\"", cond->str ); + break; + } + } + printf( "} then {" ); + + /* + * Generate a procedure call to write the value. + * This code depends on procedures in header.tk. + */ + if ( line_num >= -1 ) + { + int modtoyes = 0; + + switch ( cfg->token ) + { + default: + printf( " }\n" ); + break; + + case token_dep_mbool: + modtoyes = 1; + case token_dep_bool: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, + modtoyes ); + printf( "if {$tmpvar_dep != 1" ); + if (modtoyes) + printf( " && $tmpvar_dep != 2" ); + printf( "} then {configure_entry .menu%d.config.f.x%d disabled {y};", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {y};", + menu_num, line_num ); + printf( "}; " ); + case token_bool: + if ( cfg->token == token_bool ) + printf( "\n\t" ); + printf( "configure_entry .menu%d.config.f.x%d normal {n l", + menu_num, line_num ); + if ( cfg->token == token_bool ) + printf( " y" ); + printf( "}" ); + printf( "} else {"); + printf( "configure_entry .menu%d.config.f.x%d disabled {y n l}}\n", + menu_num, line_num ); + break; + + case token_choice_header: + printf( "configure_entry .menu%d.config.f.x%d normal {x l}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {x l}", + menu_num, line_num ); + printf( "}\n" ); + break; + + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_dep_tristate: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]];set %s [sync_tristate $%s $tmpvar_dep];", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "\tif {$tmpvar_dep != 1} then {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {y}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {y}", + menu_num, line_num ); + printf( "}; " ); + printf( "if {$tmpvar_dep == 0} then {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {m}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {m}", + menu_num, line_num ); + printf( "}; " ); + case token_tristate: + if ( cfg->token == token_tristate ) + { + printf( "\n\tconfigure_entry .menu%d.config.f.x%d normal {y}; ", + menu_num, line_num ); + } + printf( "if {($CONFIG_MODULES == 1)} then {" ); + printf( "configure_entry .menu%d.config.f.x%d normal {m}} else {", + menu_num, line_num ); + printf( "configure_entry .menu%d.config.f.x%d disabled {m}}; ", + menu_num, line_num ); + printf( "configure_entry .menu%d.config.f.x%d normal {n l}", + menu_num, line_num ); + + /* + * Or in a bit to the variable - this causes all of the radiobuttons + * to be deselected (i.e. not be red). + */ + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {y n m l}}\n", + menu_num, line_num ); + break; + + case token_hex: + case token_int: + case token_string: + printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state normal; ", + menu_num, line_num ); + printf( "} else {" ); + printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ]; ", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled}\n", + menu_num, line_num ); + break; + + case token_comment: + case token_mainmenu_option: + if ( line_num >= 0 ) + { + printf( "configure_entry .menu%d.config.f.x%d normal {m}", + menu_num, line_num ); + printf( "} else {" ); + printf( "configure_entry .menu%d.config.f.x%d disabled {m}}\n", + menu_num, line_num ); + } + else + printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n", + menu_num, menu_num ); + break; + } + } + else + { + int modtoyes = 0; + + switch ( cfg->token ) + { + default: + printf( " }\n" ); + break; + + case token_dep_mbool: + modtoyes = 1; + case token_dep_bool: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, + modtoyes ); + case token_bool: + if ( cfg->token == token_bool ) + printf( "\n\t" ); + printf( "set %s [expr $%s&15]", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "}\n"); + break; + + case token_choice_header: + printf( "} else {" ); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + printf( "set %s 4;", vartable[cfg1->nameindex].name ); + printf( "}\n" ); + break; + + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_define_bool: + case token_define_tristate: + if ( ! vartable[get_varnum( cfg->value )].global_written ) + { + global( cfg->value ); + } + printf( "set %s $%s }\n", + vartable[cfg->nameindex].name, cfg->value ); + break; + + case token_define_hex: + case token_define_int: + printf( "set %s %s }\n", + vartable[cfg->nameindex].name, cfg->value ); + break; + + case token_define_string: + printf( "set %s \"%s\" }\n", + vartable[cfg->nameindex].name, cfg->value ); + break; + + case token_dep_tristate: + printf( "\n" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + if ( ! vartable[get_varnum( tmp->name )].global_written ) + { + global( tmp->name ); + } + printf( "\tset tmpvar_dep [effective_dep [list" ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "]]; set %s [sync_tristate $%s $tmpvar_dep]; ", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + case token_tristate: + if ( cfg->token == token_tristate ) + printf( "if {($CONFIG_MODULES == 0) && ($%s == 2)} then {set %s 1}; ", + vartable[cfg->nameindex].name, + vartable[cfg->nameindex].name ); + /* + * Or in a bit to the variable - this causes all of the radiobuttons + * to be deselected (i.e. not be red). + */ + printf( "set %s [expr $%s&15]", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + printf( "}\n" ); + break; + + case token_hex: + case token_int: + if ( cfg->value && *cfg->value == '$' ) + { + int i = get_varnum( cfg->value+1 ); + printf( "\n" ); + if ( ! vartable[i].global_written ) + { + global( vartable[i].name ); + } + printf( "\t" ); + } + if ( cfg->token == token_hex ) + printf( "validate_hex " ); + else if ( cfg->token == token_int ) + printf( "validate_int " ); + printf( "%s \"$%s\" %s}\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, + cfg->value ); + break; + + case token_unset: + printf( "set %s 4}\n", vartable[cfg->nameindex].name ); + break; + } + } +} + + +/* + * Generate a line that writes a variable to the output file. + */ +void generate_writeconfig( struct kconfig * cfg ) +{ + struct condition * cond; + struct dependency * tmp; + int depmod = 2; + + /* + * Generate global declaration for this symbol. + */ + if ( cfg->token != token_comment ) + { + if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + global( vartable[cfg->nameindex].name ); + } + if ( cfg->token == token_define_tristate || cfg->token == token_define_bool ) + { + if ( ! vartable[get_varnum( cfg->value )].global_written ) + { + vartable[get_varnum( cfg->value )].global_written = 1; + global( cfg->value ); + } + } + else if ( cfg->nameindex <= 0 && cfg->token == token_choice_header ) + { + printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); + } + } + + /* + * Generate global declarations for the condition chain. + */ + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + switch( cond->op ) + { + default: + break; + + case op_variable: + if ( ! vartable[cond->nameindex].global_written ) + { + vartable[cond->nameindex].global_written = 1; + global( vartable[cond->nameindex].name ); + } + break; + } + } + + /* + * Generate indentation. + */ + printf( "\t" ); + + /* + * Generate the conditional. + */ + if ( cfg->cond != NULL ) + { + printf( "if {" ); + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: break; + case op_bang: printf( " ! " ); break; + case op_eq: printf( " == " ); break; + case op_neq: printf( " != " ); break; + case op_and: printf( " && " ); break; + case op_and1: printf( " && " ); break; + case op_or: printf( " || " ); break; + case op_lparen: printf( "(" ); break; + case op_rparen: printf( ")" ); break; + + case op_variable: + printf( "$%s", vartable[cond->nameindex].name ); + break; + + case op_constant: + if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); + else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); + else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else if ( strcmp( cond->str, "" ) == 0 ) printf( "4" ); + else + printf( "\"%s\"", cond->str ); + break; + } + } + printf( "} then {" ); + } + + /* + * Generate a procedure call to write the value. + * This code depends on the write_* procedures in header.tk. + */ + switch ( cfg->token ) + { + default: + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_bool: + case token_tristate: + printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_choice_header: + /* + * This is funky code -- it fails if there were any conditionals. + * Fortunately all the conditionals got stripped off somewhere + * else. + */ + { + struct kconfig * cfg1; + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf("\n\tif { $tmpvar_%d == \"%s\" } then { write_tristate $cfg $autocfg %s 1 [list $notmod] 2 } else { write_tristate $cfg $autocfg %s 0 [list $notmod] 2 }", + -(cfg->nameindex), cfg1->label, + vartable[cfg1->nameindex].name, + vartable[cfg1->nameindex].name ); + } + } + if ( cfg->cond != NULL ) + printf( "}" ); + printf( "\n" ); + break; + + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_comment: + printf( "write_comment $cfg $autocfg \"%s\"", + cfg->label ); + if ( cfg->cond != NULL ) + printf( "}" ); + printf( "\n" ); + break; + + case token_define_bool: + case token_define_tristate: + if ( cfg->cond == NULL ) + { + printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + } + else + { + printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2 }\n", + vartable[cfg->nameindex].name, cfg->value ); + } + break; + + case token_dep_mbool: + depmod = 1; + case token_dep_bool: + case token_dep_tristate: + printf( "write_tristate $cfg $autocfg %s $%s [list", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + for ( tmp = cfg->depend; tmp; tmp = tmp->next ) + printf( " $%s", tmp->name ); + printf( "] %d", depmod ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_define_hex: + printf( "write_hex $cfg $autocfg %s %s $notmod", + vartable[cfg->nameindex].name, cfg->value ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_define_int: + printf( "write_int $cfg $autocfg %s %s $notmod", + vartable[cfg->nameindex].name, cfg->value ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_define_string: + printf( "write_string $cfg $autocfg %s \"%s\" $notmod", + vartable[cfg->nameindex].name, cfg->value ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_hex: + printf( "write_hex $cfg $autocfg %s $%s $notmod", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_int: + printf( "write_int $cfg $autocfg %s $%s $notmod", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_string: + printf( "write_string $cfg $autocfg %s \"$%s\" $notmod", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + } +} + +static void generate_update_var( struct kconfig * scfg, int menu_num ) +{ + struct kconfig * cfg; + + if ( menu_num>0 ) + { + printf( "proc update_define_menu%d {} {\n", menu_num ); + printf( "\tupdate_define_mainmenu\n" ); + } + else + printf( "proc update_define_mainmenu {} {\n" ); + clear_globalflags(); + global( "CONFIG_MODULES" ); + vartable[ get_varnum( "CONFIG_MODULES" ) ].global_written = 1; + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num && (cfg->token == token_define_bool || cfg->token == token_define_tristate + || cfg->token == token_define_hex || cfg->token == token_define_int + || cfg->token == token_define_string || cfg->token == token_unset + || cfg->token == token_tristate) ) + { + if ( ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + global( vartable[cfg->nameindex].name ); + } + } + } + +/* + * set all conditional bool/tristates to off unless changed later + */ + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) { + if (cfg->menu_number != menu_num) + continue; + if (!cfg->cond) + continue; + switch (cfg->token) { + case token_bool: + case token_tristate: + if (! vartable[cfg->nameindex].global_written) { + vartable[cfg->nameindex].global_written = 1; + global(vartable[cfg->nameindex].name); + } + printf("set %s [expr $%s|16]\n", vartable[cfg->nameindex].name, + vartable[cfg->nameindex].name); + break; + default: + break; + } + } + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + char tmp[20]; + struct kconfig * cfg1; + + if ( cfg->menu_number == menu_num ) + { + switch ( cfg->token ) + { + default: + case token_choice_item: + break; + case token_choice_header: + sprintf( tmp, "tmpvar_%d", -(cfg->nameindex) ); + global( tmp ); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + vartable[cfg1->nameindex].global_written = 1; + global( vartable[cfg1->nameindex].name ); + printf( "\tif {$tmpvar_%d == \"%s\"} then {set %s 1} else {set %s 0}\n", + -(cfg->nameindex), cfg1->label, + vartable[cfg1->nameindex].name, + vartable[cfg1->nameindex].name ); + } + break; + case token_bool: + case token_define_bool: + case token_define_tristate: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_dep_bool: + case token_dep_tristate: + case token_dep_mbool: + case token_int: + case token_hex: + case token_mainmenu_option: + case token_tristate: + case token_unset: + if ( cfg->cond != NULL ) + generate_if( cfg, cfg->cond, menu_num, -2 ); + else switch ( cfg->token ) + { + case token_tristate: + printf( "\n\tif {($CONFIG_MODULES == 0)} then {if {($%s == 2)} then {set %s 1}}\n", + vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); + break; + case token_define_bool: + case token_define_tristate: + if ( ! vartable[get_varnum( cfg->value )].global_written ) + { + vartable[get_varnum( cfg->value )].global_written = 1; + global( cfg->value ); + } + printf( "\tset %s $%s\n", vartable[cfg->nameindex].name, + cfg->value ); + break; + case token_define_hex: + case token_define_int: + printf( "\tset %s %s\n", vartable[cfg->nameindex].name, + cfg->value ); + break; + case token_define_string: + printf( "\tset %s \"%s\"\n", vartable[cfg->nameindex].name, + cfg->value ); + break; + case token_unset: + printf( "\tset %s 4\n", vartable[cfg->nameindex].name ); + default: + break; + } + } + } + } + printf( "}\n\n\n" ); +} + + +/* + * Generates the end of a menu procedure. + */ +static void end_proc( struct kconfig * scfg, int menu_num ) +{ + struct kconfig * cfg; + + printf( "\n\n\n" ); + printf( "\tfocus $w\n" ); + printf( "\tupdate_active\n" ); + printf( "\tglobal winx; global winy\n" ); + if ( menu_first[menu_num]->menu_number != 0 ) + { + printf( "\tif {[winfo exists .menu%d] == 0} then ", + menu_first[menu_num]->menu_number ); + printf( "{menu%d .menu%d \"%s\"}\n", + menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number, + menu_first[menu_first[menu_num]->menu_number]->label ); + printf( "\tset winx [expr [winfo x .menu%d]+30]; set winy [expr [winfo y .menu%d]+30]\n", + menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number ); + } + else + printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" ); + printf( "\tif {[winfo exists $w]} then {wm geometry $w +$winx+$winy}\n" ); + + /* + * Now that the whole window is in place, we need to wait for an "update" + * so we can tell the canvas what its virtual size should be. + * + * Unfortunately, this causes some ugly screen-flashing because the whole + * window is drawn, and then it is immediately resized. It seems + * unavoidable, though, since "frame" objects won't tell us their size + * until after an update, and "canvas" objects can't automatically pack + * around frames. Sigh. + */ + printf( "\tupdate idletasks\n" ); + printf( "\tif {[winfo exists $w]} then {$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" ); + printf( "\t$w.config.canvas configure \\\n" ); + printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" ); + printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" ); + printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" ); + + /* + * If the whole canvas will fit in 3/4 of the screen height, do it; + * otherwise, resize to around 1/2 the screen and let us scroll. + */ + printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" ); + printf( "\tset scry [expr [winfo screenh $w] / 2]\n" ); + printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" ); + printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" ); + printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" ); + printf( "\t\t$w.config.canvas configure -height $canvtotal\n" ); + printf( "\t} else {\n" ); + printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" ); + printf( "\t\t}\n\t}\n" ); + + /* + * Limit the min/max window size. Height can vary, but not width, + * because of the limitations of canvas and our laziness. + */ + printf( "\tupdate idletasks\n" ); + printf( "\tif {[winfo exists $w]} then {\n\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" ); + printf( "\twm minsize $w [winfo width $w] 100\n\n" ); + printf( "\twm deiconify $w\n" ); + printf( "}\n}\n\n" ); + + /* + * Now we generate the companion procedure for the menu we just + * generated. This procedure contains all of the code to + * disable/enable widgets based upon the settings of the other + * widgets, and will be called first when the window is mapped, + * and each time one of the buttons in the window are clicked. + */ + printf( "proc update_menu%d {} {\n", menu_num ); + + /* + * Clear all of the booleans that are defined in this menu. + */ + clear_globalflags(); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num + && cfg->token != token_mainmenu_option + && cfg->token != token_choice_item ) + { + if ( cfg->cond != NULL ) + { + int i; + if ( (cfg->token == token_tristate || cfg->token == token_dep_tristate) + && ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written ) + { + global( "CONFIG_MODULES" ); + vartable[i].global_written = 1; + } + generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + } + else + { + if ( cfg->token == token_tristate ) + { + int i; + if ( ! vartable[cfg->nameindex].global_written ) + { + vartable[cfg->nameindex].global_written = 1; + printf( "\tglobal %s\n", vartable[cfg->nameindex].name ); + } + if ( ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written ) + { + global( "CONFIG_MODULES" ); + vartable[i].global_written = 1; + } + printf( "\n\tif {($CONFIG_MODULES == 1)} then {configure_entry .menu%d.config.f.x%d normal {m}} else {configure_entry .menu%d.config.f.x%d disabled {m}}\n", + menu_num, cfg->menu_line, + menu_num, cfg->menu_line ); + } + } + } + else if ( cfg->token == token_mainmenu_option + && cfg->menu_number == menu_num + && cfg->cond != NULL ) + { + generate_if( cfg, cfg->cond, menu_num, cfg->menu_line ); + } + } + printf("}\n\n\n"); + + generate_update_var( scfg, menu_num ); +} + +/* + * This is the top level function for generating the tk script. + */ +void dump_tk_script( struct kconfig * scfg ) +{ + int menu_depth; + int menu_num [64]; + int imenu, i; + int top_level_num = 0; + struct kconfig * cfg; + struct kconfig * cfg1 = NULL; + const char * name = "No Name"; + + /* + * Mark begin and end of each menu so I can omit submenus when walking + * over a parent menu. + */ + tot_menu_num = 0; + menu_depth = 0; + menu_num [0] = 0; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_mainmenu_name: + name = cfg->label; + break; + + case token_mainmenu_option: + if ( ++menu_depth >= 64 ) + { fprintf( stderr, "menus too deep\n" ); exit( 1 ); } + if ( ++tot_menu_num >= 100 ) + { fprintf( stderr, "too many menus\n" ); exit( 1 ); } + menu_num [menu_depth] = tot_menu_num; + menu_first [tot_menu_num] = cfg; + menu_last [tot_menu_num] = cfg; + /* + * Note, that menu_number is set to the number of parent + * (upper level) menu. + */ + cfg->menu_number = menu_num[menu_depth - 1]; + if ( menu_depth == 1 ) + ++top_level_num; + break; + + case token_endmenu: + menu_last [menu_num [menu_depth]] = cfg; + /* flatten menus with proper scoping */ + if ( --menu_depth < 0 ) + { fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); } + break; + + case token_bool: + case token_choice_header: + case token_choice_item: + case token_comment: + case token_dep_bool: + case token_dep_tristate: + case token_dep_mbool: + case token_hex: + case token_int: + case token_string: + case token_tristate: + cfg->menu_number = menu_num[menu_depth]; + if ( menu_depth == 0 ) + { fprintf( stderr, "statement not in menu\n" ); exit( 1 ); } + break; + + case token_define_bool: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_define_tristate: + case token_unset: + cfg->menu_number = menu_num[menu_depth]; + break; + } + } + + /* + * Generate menus per column setting. + * There are: + * four extra buttons for save/quit/load/store; + * one blank button + * add two to round up for division + */ + printf( "set menus_per_column %d\n", (top_level_num + 4 + 1 + 2) / 3 ); + printf( "set total_menus %d\n\n", tot_menu_num ); + + printf( "proc toplevel_menu {num} {\n" ); + for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) + { + int parent = 1; + + if ( menu_first[imenu]->menu_number == 0 ) + parent = menu_first[imenu]->menu_number; + else + printf( "\tif {$num == %d} then {return %d}\n", + imenu, menu_first[imenu]->menu_number ); + } + printf( "\treturn $num\n}\n\n" ); + + /* + * Generate the menus. + */ + printf( "mainmenu_name \"%s\"\n", name ); + for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) + { + int menu_line = 0; + int nr_submenu = imenu; + int menu_name_omitted = 0; + int opt_count = 0; + + clear_globalflags(); + start_proc( menu_first[imenu]->label, imenu, + !menu_first[imenu]->menu_number ); + + for ( cfg = menu_first[imenu]->next; cfg != NULL && cfg != menu_last[imenu]; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_mainmenu_option: + while ( menu_first[++nr_submenu]->menu_number > imenu ) + ; + cfg->menu_line = menu_line++; + printf( "\tsubmenu $w.config.f %d %d \"%s\" %d\n", + cfg->menu_number, cfg->menu_line, cfg->label, nr_submenu ); + cfg = menu_last[nr_submenu]; + break; + + case token_comment: + if ( !cfg->menu_line && !menu_name_omitted ) + { + cfg->menu_line = -1; + menu_name_omitted = 1; + } + else + { + menu_name_omitted = 1; + cfg->menu_line = menu_line++; + printf( "\tcomment $w.config.f %d %d \"%s\"\n", + cfg->menu_number, cfg->menu_line, cfg->label ); + } + break; + + case token_bool: + cfg->menu_line = menu_line++; + printf( "\tbool $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + + case token_choice_header: + /* + * I need the first token_choice_item to pick out the right + * help text from Documentation/Configure.help. + */ + cfg->menu_line = menu_line++; + printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); + printf( "\tminimenu $w.config.f %d %d \"%s\" tmpvar_%d %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + -(cfg->nameindex), vartable[cfg->next->nameindex].name ); + printf( "\tmenu $w.config.f.x%d.x.menu -tearoffcommand \"menutitle \\\"%s\\\"\"\n", + cfg->menu_line, cfg->label ); + cfg1 = cfg; + opt_count = 0; + break; + + case token_choice_item: + /* note: no menu line; uses choice header menu line */ + printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable tmpvar_%d -value \"%s\" -command \"update_active\"\n", + cfg1->menu_line, cfg->label, -(cfg1->nameindex), + cfg->label ); + opt_count++; + if ( cfg->next && cfg->next->token != token_choice_item ) { + /* last option in the menu */ + printf( "\tmenusplit $w $w.config.f.x%d.x.menu %d\n", + cfg1->menu_line, opt_count ); + } + break; + + case token_dep_bool: + case token_dep_mbool: + cfg->menu_line = menu_line++; + printf( "\tdep_bool $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + + case token_dep_tristate: + cfg->menu_line = menu_line++; + printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + + case token_hex: + cfg->menu_line = menu_line++; + printf( "\thex $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + + case token_int: + cfg->menu_line = menu_line++; + printf( "\tint $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + + case token_string: + cfg->menu_line = menu_line++; + printf( "\tistring $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + + case token_tristate: + cfg->menu_line = menu_line++; + printf( "\ttristate $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + vartable[cfg->nameindex].name ); + break; + } + } + + end_proc( scfg, imenu ); + } + + /* + * The top level menu also needs an update function. When we update a + * submenu, we may need to disable one or more of the submenus on + * the top level menu, and this procedure will ensure that things are + * correct. + */ + clear_globalflags(); + printf( "proc update_mainmenu {} {\n" ); + for ( imenu = 1; imenu <= tot_menu_num; imenu++ ) + { + if ( menu_first[imenu]->cond != NULL && menu_first[imenu]->menu_number == 0 ) + generate_if( menu_first[imenu], menu_first[imenu]->cond, imenu, -1 ); + } + printf( "}\n\n\n" ); + + clear_globalflags(); + /* + * Generate code to load the default settings into the variables. + * The script in tail.tk will attempt to load .config, + * which may override these settings, but that's OK. + */ + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_bool: + case token_choice_item: + case token_dep_bool: + case token_dep_tristate: + case token_dep_mbool: + case token_tristate: + if ( ! vartable[cfg->nameindex].global_written ) + { + printf( "set %s 0\n", vartable[cfg->nameindex].name ); + vartable[cfg->nameindex].global_written = 1; + } + break; + + case token_choice_header: + printf( "set tmpvar_%d \"(not set)\"\n", -(cfg->nameindex) ); + break; + + case token_hex: + case token_int: + if ( ! vartable[cfg->nameindex].global_written ) + { + printf( "set %s %s\n", vartable[cfg->nameindex].name, cfg->value ? cfg->value : "0" ); + vartable[cfg->nameindex].global_written = 1; + } + break; + + case token_string: + if ( ! vartable[cfg->nameindex].global_written ) + { + printf( "set %s \"%s\"\n", vartable[cfg->nameindex].name, cfg->value ); + vartable[cfg->nameindex].global_written = 1; + } + break; + } + } + + /* + * Define to an empty value all other variables (which are never defined) + */ + for ( i = 1; i <= max_varnum; i++ ) + { + if ( ! vartable[i].global_written + && strncmp( vartable[i].name, "CONSTANT_", 9 ) ) + printf( "set %s 4\n", vartable[i].name ); + } + + /* + * Generate a function to write all of the variables to a file. + */ + printf( "proc writeconfig {file1 file2} {\n" ); + printf( "\tset cfg [open $file1 w]\n" ); + printf( "\tset autocfg [open $file2 w]\n" ); + printf( "\tset notmod 1\n" ); + printf( "\tset notset 0\n" ); + printf( "\tputs $cfg \"#\"\n"); + printf( "\tputs $cfg \"# Automatically generated make config: don't edit\"\n"); + printf( "\tputs $cfg \"#\"\n" ); + + printf( "\tputs $autocfg \"/*\"\n" ); + printf( "\tputs $autocfg \" * Automatically generated C config: don't edit\"\n" ); + printf( "\tputs $autocfg \" */\"\n" ); + printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" ); + + clear_globalflags(); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_bool: + case token_choice_header: + case token_comment: + case token_define_bool: + case token_define_hex: + case token_define_int: + case token_define_string: + case token_define_tristate: + case token_dep_bool: + case token_dep_tristate: + case token_dep_mbool: + case token_hex: + case token_int: + case token_string: + case token_tristate: + generate_writeconfig( cfg ); + break; + } + } + printf( "\tclose $cfg\n" ); + printf( "\tclose $autocfg\n" ); + printf( "}\n\n\n" ); + + /* + * Generate a simple function that updates the master choice + * variable depending upon what values were loaded from a .config + * file. + */ + printf( "proc clear_choices { } {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_choice_header ) + { + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf( "\tglobal %s; set %s 0\n", + vartable[cfg1->nameindex].name, + vartable[cfg1->nameindex].name ); + } + } + } + printf( "}\n\n\n" ); + + printf( "proc update_choices { } {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_choice_header ) + { + printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); + printf("\tset tmpvar_%d \"%s\"\n", -(cfg->nameindex), cfg->value); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf( "\tglobal %s\n", vartable[cfg1->nameindex].name ); + printf( "\tif { $%s == 1 } then { set tmpvar_%d \"%s\" }\n", + vartable[cfg1->nameindex].name, + -(cfg->nameindex), cfg1->label ); + } + } + } + printf( "}\n\n\n" ); + + generate_update_var( scfg, 0 ); + + /* + * That's it. We are done. The output of this file will have header.tk + * prepended and tail.tk appended to create an executable wish script. + */ +} diff --git a/uClinux-2.4.31-uc0/scripts/tkparse.c b/uClinux-2.4.31-uc0/scripts/tkparse.c new file mode 100644 index 0000000..502d090 --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/tkparse.c @@ -0,0 +1,834 @@ +/* + * tkparse.c + * + * Eric Youngdale was the original author of xconfig. + * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. + * + * Parse a config.in file and translate it to a wish script. + * This task has three parts: + * + * tkparse.c tokenize the input + * tkcond.c transform 'if ...' statements + * tkgen.c generate output + * + * Change History + * + * 7 January 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Teach dep_tristate about a few literals, such as: + * dep_tristate 'foo' CONFIG_FOO m + * Also have it print an error message and exit on some parse failures. + * + * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Don't fclose stdin. Thanks to Tony Hoyle for nailing this one. + * + * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Steam-clean this file. I tested this by generating kconfig.tk for + * every architecture and comparing it character-for-character against + * the output of the old tkparse. + * + * 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net> + * - Remove bug-compatible code. + * + * 07 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl> + * - Submenus implemented, + * - plenty of option updating/displaying fixes, + * - dep_bool, define_hex, define_int, define_string, define_tristate and + * undef implemented, + * - dep_tristate fixed to support multiple dependencies, + * - handling of variables with an empty value implemented, + * - value checking for int and hex fields, + * - more checking during condition parsing; choice variables are treated as + * all others now, + * + * TO DO: + * - xconfig is at the end of its life cycle. Contact <mec@shout.net> if + * you are interested in working on the replacement. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "tkparse.h" + +static struct kconfig * config_list = NULL; +static struct kconfig * config_last = NULL; +static const char * current_file = "<unknown file>"; +static int lineno = 0; + +static void do_source( const char * ); + +#undef strcmp +int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); } +#define strcmp my_strcmp + +/* + * Report a syntax error. + */ +static void syntax_error( const char * msg ) +{ + fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg ); + exit( 1 ); +} + +static void syntax_warning( const char * msg ) +{ + fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg ); +} + + + +/* + * Find index of a specific variable in the symbol table. + * Create a new entry if it does not exist yet. + */ +struct variable *vartable; +int max_varnum = 0; +static int vartable_size = 0; + +int get_varnum( char * name ) +{ + int i; + + for ( i = 1; i <= max_varnum; i++ ) + if ( strcmp( vartable[i].name, name ) == 0 ) + return i; + while (max_varnum+1 >= vartable_size) { + vartable = realloc(vartable, (vartable_size += 1000)*sizeof(*vartable)); + if (!vartable) { + fprintf(stderr, "tkparse realloc vartable failed\n"); + exit(1); + } + } + vartable[++max_varnum].name = malloc( strlen( name )+1 ); + strcpy( vartable[max_varnum].name, name ); + return max_varnum; +} + + + +/* + * Get a string. + */ +static const char * get_string( const char * pnt, char ** label ) +{ + const char * word; + + word = pnt; + for ( ; ; ) + { + if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' ) + break; + pnt++; + } + + *label = malloc( pnt - word + 1 ); + memcpy( *label, word, pnt - word ); + (*label)[pnt - word] = '\0'; + + if ( *pnt != '\0' ) + pnt++; + return pnt; +} + + + +/* + * Get a quoted string. + * Insert a '\' before any characters that need quoting. + */ +static const char * get_qstring( const char * pnt, char ** label ) +{ + char quote_char; + char newlabel [16384]; + char * pnt1; + + /* advance to the open quote */ + for ( ; ; ) + { + if ( *pnt == '\0' ) + return pnt; + quote_char = *pnt++; + if ( quote_char == '"' || quote_char == '\'' ) + break; + } + + /* copy into an intermediate buffer */ + pnt1 = newlabel; + for ( ; ; ) + { + if ( *pnt == '\0' ) + syntax_error( "unterminated quoted string" ); + if ( *pnt == quote_char && pnt[-1] != '\\' ) + break; + + /* copy the character, quoting if needed */ + if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' ) + *pnt1++ = '\\'; + *pnt1++ = *pnt++; + } + + /* copy the label into a permanent location */ + *pnt1++ = '\0'; + *label = (char *) malloc( pnt1 - newlabel ); + memcpy( *label, newlabel, pnt1 - newlabel ); + + /* skip over last quote and next whitespace */ + pnt++; + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + return pnt; +} + + + +/* + * Get a quoted or unquoted string. It is recognized by the first + * non-white character. '"' and '"' are not allowed inside the string. + */ +static const char * get_qnqstring( const char * pnt, char ** label ) +{ + char quote_char; + + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + if ( *pnt == '\0' ) + return pnt; + quote_char = *pnt; + if ( quote_char == '"' || quote_char == '\'' ) + return get_qstring( pnt, label ); + else + return get_string( pnt, label ); +} + + + +/* + * Tokenize an 'if' statement condition. + */ +static struct condition * tokenize_if( const char * pnt ) +{ + struct condition * list; + struct condition * last; + struct condition * prev; + + /* eat the open bracket */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt != '[' ) + syntax_error( "bad 'if' condition" ); + pnt++; + + list = last = NULL; + for ( ; ; ) + { + struct condition * cond; + + /* advance to the next token */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == '\0' ) + syntax_error( "unterminated 'if' condition" ); + if ( *pnt == ']' ) + return list; + + /* allocate a new token */ + cond = malloc( sizeof(*cond) ); + memset( cond, 0, sizeof(*cond) ); + if ( last == NULL ) + { list = last = cond; prev = NULL; } + else + { prev = last; last->next = cond; last = cond; } + + /* determine the token value */ + if ( *pnt == '-' && pnt[1] == 'a' ) + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_and; pnt += 2; continue; + } + + if ( *pnt == '-' && pnt[1] == 'o' ) + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_or; pnt += 2; continue; + } + + if ( *pnt == '!' && pnt[1] == '=' ) + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_neq; pnt += 2; continue; + } + + if ( *pnt == '=' ) + { + if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) + syntax_error( "incorrect argument" ); + cond->op = op_eq; pnt += 1; continue; + } + + if ( *pnt == '!' ) + { + if ( prev && ( prev->op != op_and && prev->op != op_or + && prev->op != op_bang ) ) + syntax_error( "incorrect argument" ); + cond->op = op_bang; pnt += 1; continue; + } + + if ( *pnt == '"' ) + { + const char * word; + + if ( prev && ( prev->op == op_variable || prev->op == op_constant ) ) + syntax_error( "incorrect argument" ); + /* advance to the word */ + pnt++; + if ( *pnt == '$' ) + { cond->op = op_variable; pnt++; } + else + { cond->op = op_constant; } + + /* find the end of the word */ + word = pnt; + for ( ; ; ) + { + if ( *pnt == '\0' ) + syntax_error( "unterminated double quote" ); + if ( *pnt == '"' ) + break; + pnt++; + } + + /* store a copy of this word */ + { + char * str = malloc( pnt - word + 1 ); + memcpy( str, word, pnt - word ); + str [pnt - word] = '\0'; + if ( cond->op == op_variable ) + { + cond->nameindex = get_varnum( str ); + free( str ); + } + else /* op_constant */ + { + cond->str = str; + } + } + + pnt++; + continue; + } + + /* unknown token */ + syntax_error( "bad if condition" ); + } +} + + + +/* + * Tokenize a choice list. Choices appear as pairs of strings; + * note that I am parsing *inside* the double quotes. Ugh. + */ +static const char * tokenize_choices( struct kconfig * cfg_choose, + const char * pnt ) +{ + int default_checked = 0; + for ( ; ; ) + { + struct kconfig * cfg; + char * buffer = malloc( 64 ); + + /* skip whitespace */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == '\0' ) + return pnt; + + /* allocate a new kconfig line */ + cfg = malloc( sizeof(*cfg) ); + memset( cfg, 0, sizeof(*cfg) ); + if ( config_last == NULL ) + { config_last = config_list = cfg; } + else + { config_last->next = cfg; config_last = cfg; } + + /* fill out the line */ + cfg->token = token_choice_item; + cfg->cfg_parent = cfg_choose; + pnt = get_string( pnt, &cfg->label ); + if ( ! default_checked && + ! strncmp( cfg->label, cfg_choose->value, strlen( cfg_choose->value ) ) ) + { + default_checked = 1; + free( cfg_choose->value ); + cfg_choose->value = cfg->label; + } + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + } + if ( ! default_checked ) + syntax_error( "bad 'choice' default value" ); + return pnt; +} + + + +/* + * Tokenize one line. + */ +static void tokenize_line( const char * pnt ) +{ + static struct kconfig * last_menuoption = NULL; + enum e_token token; + struct kconfig * cfg; + struct dependency ** dep_ptr; + char * buffer = malloc( 64 ); + + /* skip white space */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + /* + * categorize the next token + */ + +#define match_token(t, s) \ + if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; } + + token = token_UNKNOWN; + switch ( *pnt ) + { + default: + break; + + case '#': + case '\0': + return; + + case 'b': + match_token( token_bool, "bool" ); + break; + + case 'c': + match_token( token_choice_header, "choice" ); + match_token( token_comment, "comment" ); + break; + + case 'd': + match_token( token_define_bool, "define_bool" ); + match_token( token_define_hex, "define_hex" ); + match_token( token_define_int, "define_int" ); + match_token( token_define_string, "define_string" ); + match_token( token_define_tristate, "define_tristate" ); + match_token( token_dep_bool, "dep_bool" ); + match_token( token_dep_mbool, "dep_mbool" ); + match_token( token_dep_tristate, "dep_tristate" ); + break; + + case 'e': + match_token( token_else, "else" ); + match_token( token_endmenu, "endmenu" ); + break; + + case 'f': + match_token( token_fi, "fi" ); + break; + + case 'h': + match_token( token_hex, "hex" ); + break; + + case 'i': + match_token( token_if, "if" ); + match_token( token_int, "int" ); + break; + + case 'm': + match_token( token_mainmenu_name, "mainmenu_name" ); + match_token( token_mainmenu_option, "mainmenu_option" ); + break; + + case 's': + match_token( token_source, "source" ); + match_token( token_string, "string" ); + break; + + case 't': + match_token( token_then, "then" ); + match_token( token_tristate, "tristate" ); + break; + + case 'u': + match_token( token_unset, "unset" ); + break; + } + +#undef match_token + + if ( token == token_source ) + { + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + do_source( pnt ); + return; + } + + if ( token == token_then ) + { + if ( config_last != NULL && config_last->token == token_if ) + return; + syntax_error( "bogus 'then'" ); + } + +#if 0 + if ( token == token_unset ) + { + fprintf( stderr, "Ignoring 'unset' command\n" ); + return; + } +#endif + + if ( token == token_UNKNOWN ) + syntax_error( "unknown command" ); + + /* + * Allocate an item. + */ + cfg = malloc( sizeof(*cfg) ); + memset( cfg, 0, sizeof(*cfg) ); + if ( config_last == NULL ) + { config_last = config_list = cfg; } + else + { config_last->next = cfg; config_last = cfg; } + + /* + * Tokenize the arguments. + */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + cfg->token = token; + switch ( token ) + { + default: + syntax_error( "unknown token" ); + + case token_bool: + case token_tristate: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + break; + + case token_choice_header: + { + static int choose_number = 0; + char * choice_list; + + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_qstring ( pnt, &choice_list ); + pnt = get_string ( pnt, &cfg->value ); + cfg->nameindex = -(choose_number++); + tokenize_choices( cfg, choice_list ); + free( choice_list ); + } + break; + + case token_comment: + pnt = get_qstring(pnt, &cfg->label); + if ( last_menuoption != NULL ) + { + pnt = get_qstring(pnt, &cfg->label); + if (cfg->label == NULL) + syntax_error( "missing comment text" ); + last_menuoption->label = cfg->label; + last_menuoption = NULL; + } + break; + + case token_define_bool: + case token_define_tristate: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' + || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) + && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) + { + if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = strdup( "CONSTANT_N" ); + else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = strdup( "CONSTANT_Y" ); + else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = strdup( "CONSTANT_M" ); + } + else if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &cfg->value ); + } + else + { + syntax_error( "unknown define_bool value" ); + } + get_varnum( cfg->value ); + break; + + case token_define_hex: + case token_define_int: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_string( pnt, &cfg->value ); + break; + + case token_define_string: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_qnqstring( pnt, &cfg->value ); + if (cfg->value == NULL) + syntax_error( "missing value" ); + break; + + case token_dep_bool: + case token_dep_mbool: + case token_dep_tristate: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + dep_ptr = &(cfg->depend); + + do { + *dep_ptr = (struct dependency *) malloc( sizeof( struct dependency ) ); + (*dep_ptr)->next = NULL; + + if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' + || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) + && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) + { + /* dep_tristate 'foo' CONFIG_FOO m */ + if ( pnt[0] == 'Y' || pnt[0] == 'y' ) + (*dep_ptr)->name = strdup( "CONSTANT_Y" ); + else if ( pnt[0] == 'N' || pnt[0] == 'n' ) + (*dep_ptr)->name = strdup( "CONSTANT_N" ); + else + (*dep_ptr)->name = strdup( "CONSTANT_M" ); + pnt++; + get_varnum( (*dep_ptr)->name ); + } + else if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &(*dep_ptr)->name ); + get_varnum( (*dep_ptr)->name ); + } + else + { + syntax_error( "can't handle dep_bool/dep_mbool/dep_tristate condition" ); + } + dep_ptr = &(*dep_ptr)->next; + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + } while ( *pnt ); + + /* + * Create a conditional for this object's dependencies. + */ + { + char fake_if [8192]; + struct dependency * dep; + struct condition ** cond_ptr; + int first = 1; + + cond_ptr = &(cfg->cond); + for ( dep = cfg->depend; dep; dep = dep->next ) + { + if ( token == token_dep_tristate + && ! strcmp( dep->name, "CONSTANT_M" ) ) + { + continue; + } + if ( first ) + { + first = 0; + } + else + { + *cond_ptr = malloc( sizeof(struct condition) ); + memset( *cond_ptr, 0, sizeof(struct condition) ); + (*cond_ptr)->op = op_and; + cond_ptr = &(*cond_ptr)->next; + } + *cond_ptr = malloc( sizeof(struct condition) ); + memset( *cond_ptr, 0, sizeof(struct condition) ); + (*cond_ptr)->op = op_lparen; + if ( token == token_dep_bool ) + sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then", + dep->name, dep->name ); + else + sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then", + dep->name, dep->name, dep->name ); + (*cond_ptr)->next = tokenize_if( fake_if ); + while ( *cond_ptr ) + cond_ptr = &(*cond_ptr)->next; + *cond_ptr = malloc( sizeof(struct condition) ); + memset( *cond_ptr, 0, sizeof(struct condition) ); + (*cond_ptr)->op = op_rparen; + cond_ptr = &(*cond_ptr)->next; + } + } + break; + + case token_else: + case token_endmenu: + case token_fi: + break; + + case token_hex: + case token_int: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_string ( pnt, &cfg->value ); + break; + + case token_string: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + pnt = get_qnqstring ( pnt, &cfg->value ); + if (cfg->value == NULL) + syntax_error( "missing initial value" ); + break; + + case token_if: + cfg->cond = tokenize_if( pnt ); + break; + + case token_mainmenu_name: + pnt = get_qstring( pnt, &cfg->label ); + break; + + case token_mainmenu_option: + if ( strncmp( pnt, "next_comment", 12 ) == 0 ) + last_menuoption = cfg; + else + pnt = get_qstring( pnt, &cfg->label ); + break; + + case token_unset: + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + while (*pnt) + { + cfg->next = (struct kconfig *) malloc( sizeof(struct kconfig) ); + memset( cfg->next, 0, sizeof(struct kconfig) ); + cfg = cfg->next; + cfg->token = token_unset; + pnt = get_string( pnt, &buffer ); + cfg->nameindex = get_varnum( buffer ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + } + break; + } + return; +} + + + +/* + * Implement the "source" command. + */ +static void do_source( const char * filename ) +{ + char buffer [16384]; + FILE * infile; + const char * old_file; + int old_lineno; + int offset; + + /* open the file */ + if ( strcmp( filename, "-" ) == 0 ) + infile = stdin; + else + infile = fopen( filename, "r" ); + + /* if that failed, try ../filename */ + if ( infile == NULL ) + { + sprintf( buffer, "../%s", filename ); + infile = fopen( buffer, "r" ); + } + + if ( infile == NULL ) + { + sprintf( buffer, "unable to open %s", filename ); + syntax_warning( buffer ); + return; + } + + /* push the new file name and line number */ + old_file = current_file; + old_lineno = lineno; + current_file = filename; + lineno = 0; + + /* read and process lines */ + for ( offset = 0; ; ) + { + char * pnt; + + /* read a line */ + fgets( buffer + offset, sizeof(buffer) - offset, infile ); + if ( feof( infile ) ) + break; + lineno++; + + /* strip the trailing return character */ + pnt = buffer + strlen(buffer) - 1; + if ( *pnt == '\n' ) + *pnt-- = '\0'; + + /* eat \ NL pairs */ + if ( *pnt == '\\' ) + { + offset = pnt - buffer; + continue; + } + + /* tokenize this line */ + tokenize_line( buffer ); + offset = 0; + } + + /* that's all, folks */ + if ( infile != stdin ) + fclose( infile ); + current_file = old_file; + lineno = old_lineno; + return; +} + + + +/* + * Main program. + */ +int main( int argc, const char * argv [] ) +{ + do_source ( "-" ); + fix_conditionals ( config_list ); + dump_tk_script ( config_list ); + free(vartable); + return 0; +} diff --git a/uClinux-2.4.31-uc0/scripts/tkparse.h b/uClinux-2.4.31-uc0/scripts/tkparse.h new file mode 100644 index 0000000..2ded97e --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/tkparse.h @@ -0,0 +1,127 @@ +/* + * tkparse.h + */ + +/* + * Token types (mostly statement types). + */ + +enum e_token +{ + token_UNKNOWN, + token_bool, + token_choice_header, + token_choice_item, + token_comment, + token_define_bool, + token_define_hex, + token_define_int, + token_define_string, + token_define_tristate, + token_dep_bool, + token_dep_mbool, + token_dep_tristate, + token_else, + token_endmenu, + token_fi, + token_hex, + token_if, + token_int, + token_mainmenu_name, + token_mainmenu_option, + token_source, + token_string, + token_then, + token_tristate, + token_unset, +}; + +/* + * Operator types for conditionals. + */ + +enum operator +{ + op_eq, + op_neq, + op_and, + op_and1, + op_or, + op_bang, + op_lparen, + op_rparen, + op_constant, + op_variable, + op_true, + op_false, + op_nuked +}; + +/* + * Conditions come in linked lists. + * Some operators take strings: + * + * op_constant "foo" + * op_variable "$ARCH", "$CONFIG_PMAC", "$CONFIG_EXPERIMENTAL" + * + * Most "$..." constructs refer to a variable which is defined somewhere + * in the script. Note that it is legal to test variables which are never + * defined, such as variables that are meaningful only on other architectures. + */ + +struct condition +{ + struct condition * next; + enum operator op; + const char * str; /* op_constant */ + int nameindex; /* op_variable */ +}; + +/* + * Dependency list for dep_bool, dep_mbool, dep_tristate + */ + +struct dependency +{ + char * name; + struct dependency * next; +}; + +/* + * A statement from a config.in file + */ + +struct kconfig +{ + struct kconfig * next; + enum e_token token; + int nameindex; + char * label; + char * value; + struct condition * cond; + struct dependency * depend; /* token_dep_tristate */ + struct kconfig * cfg_parent; /* token_choice_item */ + + /* used only in tkgen.c */ + int menu_number; + int menu_line; + struct kconfig * menu_next; +}; + +struct variable +{ + char * name; + char defined; + char global_written; +}; + +extern struct variable *vartable; +extern int max_varnum; + +/* + * Prototypes + */ + +extern void fix_conditionals ( struct kconfig * scfg ); /* tkcond.c */ +extern void dump_tk_script ( struct kconfig * scfg ); /* tkgen.c */ +extern int get_varnum ( char * name ); /* tkparse.c */ diff --git a/uClinux-2.4.31-uc0/scripts/ver_linux b/uClinux-2.4.31-uc0/scripts/ver_linux new file mode 100644 index 0000000..7c32eec --- /dev/null +++ b/uClinux-2.4.31-uc0/scripts/ver_linux @@ -0,0 +1,85 @@ +#!/bin/sh +# Before running this script please ensure that your PATH is +# typical as you use for compilation/istallation. I use +# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may +# differ on your system. +# +PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:$PATH +echo 'If some fields are empty or look unusual you may have an old version.' +echo 'Compare to the current minimal requirements in Documentation/Changes.' +echo ' ' + +uname -a +echo ' ' + +gcc --version 2>&1| head -n 1 | grep -v gcc | awk \ +'NR==1{print "Gnu C ", $1}' + +gcc --version 2>&1| grep gcc | awk \ +'NR==1{print "Gnu C ", $3}' + +make --version 2>&1 | awk -F, '{print $1}' | awk \ + '/GNU Make/{print "Gnu make ",$NF}' + +ld -v 2>&1 | awk -F\) '{print $1}' | awk \ + '/BFD/{print "binutils ",$NF}' + +fdformat --version | awk -F\- '{print "util-linux ", $NF}' + +mount --version | awk -F\- '{print "mount ", $NF}' + +insmod -V 2>&1 | awk 'NR==1 {print "modutils ",$NF}' + +tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \ +'NR==1 {print "e2fsprogs ", $2}' + +fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \ +'NR==1 {print "jfsutils ", $3}' + +reiserfsck -V 2>&1 | grep reiserfsprogs | awk \ +'NR==1{print "reiserfsprogs ", $NF}' + +xfs_db -V 2>&1 | grep version | awk \ +'NR==1{print "xfsprogs ", $3}' + +cardmgr -V 2>&1| grep version | awk \ +'NR==1{print "pcmcia-cs ", $3}' + +quota -V 2>&1 | grep version | awk \ +'NR==1{print "quota-tools ", $NF}' + +pppd --version 2>&1| grep version | awk \ +'NR==1{print "PPP ", $3}' + +isdnctrl 2>&1 | grep version | awk \ +'NR==1{print "isdn4k-utils ", $NF}' + +ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \ +-e 's/\.so$//' | awk -F'[.-]' '{print "Linux C Library " \ +$(NF-2)"."$(NF-1)"."$NF}' + +ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -1 | awk \ +'NR==1{print "Dynamic linker (ldd) ", $NF}' + +ls -l /usr/lib/lib{g,stdc}++.so 2>/dev/null | awk -F. \ + '{print "Linux C++ Library " $4"."$5"."$6}' + +ps --version 2>&1 | awk 'NR==1{print "Procps ", $NF}' + +ifconfig --version 2>&1 | grep tools | awk \ +'NR==1{print "Net-tools ", $NF}' + +# Kbd needs 'loadkeys -h', +loadkeys -h 2>&1 | awk \ +'(NR==1 && ($3 !~ /option/)) {print "Kbd ", $3}' + +# while console-tools needs 'loadkeys -V'. +loadkeys -V 2>&1 | awk \ +'(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools ", $3}' + +expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}' + +if [ -e /proc/modules ]; then + X=`cat /proc/modules | sed -e "s/ .*$//"` + echo "Modules Loaded "$X +fi |