root/Configure

/* [previous][next][first][last][top][bottom][index][help] */
#! /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.
#
# Please send comments / questions / bug fixes to raymondc@microsoft.com.
#
# Each line in the config file is a command.
#
#       # internal comment
#
#               Lines beginning with a `#' are ignored.
#
#       : message
#
#               `:' causes the line to be echoed to the screen.
#
#       * external comment
#
#               `*' causes the line to be placed in the output
#               configuration file as a comment as well as being
#               echoed to the screen.
#
#       if condition
#               ... commands ...
#       else
#               ... commands ...
#       fi
#
#               This does the obvious thing.  The `else' clause is
#               optional.  Conditionals can be nested.
#
#               The `condition' can be any valid bash expression.
#               They typically involve tests against environment
#               variables set by configuration options.  For example,
#
#               if [ "$CONFIG_SCSI" = "y" ]
#                       ...More stuff...
#               fi
#
#               Note!  That there is no `then' keyword.
#
#       bool 'prompt' CONFIG_VARIABLE default
#
#               This prompts the user for a boolean value.
#               The prompt may not contain an apostrophe.
#               `default' should be either `y' or `n'.
#               The user's response is recorded in four places.
#
#               In .config, if `y'
#                       CONFIG_VARIABLE = CONFIG_VARIABLE
#               In .config, if `n'
#                       # CONFIG_VARIABLE is not set
#                       
#               In autoconf.h, if `y'
#                       #define CONFIG_VARIABLE 1
#               In autoconf.h, if `n'
#                       #undef CONFIG_VARIABLE
#
#               In config.in, if `y'
#                       bool 'prompt' CONFIG_VARIABLE y
#               In config.in, if `n'
#                       bool 'prompt' CONFIG_VARIABLE n
#
#               In the environment of the Configure script, if `y'
#                       CONFIG_VARIABLE = y
#               In the environment of the Configure script, if `n'
#                       CONFIG_VARIABLE = n
#
#               The value is placed into the environment of the Configure
#               script so that later parts of config.in can use the `if'
#               command to inspect the results of previous queries.
#
#       int 'prompt' CONFIG_VARIABLE default
#
#               This prompts the user for an integer value.
#               The prompt may not contain an apostrophe.
#               `default' should be an integer.
#
#               The response is recorded as follows.
#
#               In .config
#                       CONFIG_VARIABLE = response
#               In autoconf.h
#                       #define CONFIG_VARIABLE (response)
#               In config.in
#                       int 'prompt' CONFIG_VARIABLE response
#               In the environment of the Configure script
#                       CONFIG_VARIABLE = response
#
# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13
# with an empty IFS.

#
# 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

#
# readln reads a line into $ans.
#
#       readln prompt default
#
function readln () {
        echo -n "$1"
        IFS='@' read ans </dev/tty || exit 1
        [ -z "$ans" ] && ans=$2
}

# bool processes a boolean argument
#
#       bool tail
#
function bool () {
        # Slimier hack to get bash to rescan a line.
        eval "set -- $1"
        ans=""
        while [ "$ans" != "y" -a "$ans" != "n" ]; do
                readln "$1 ($2) [$3] " "$3"
        done
        if [ "$ans" = "y" ]; then
                echo "$2 = $2" >>$CONFIG
                echo "#define $2 1" >>$CONFIG_H
        else
                echo "# $2 is not set" >>$CONFIG
                echo "#undef $2" >>$CONFIG_H
        fi
        raw_input_line="bool '$1' $2 $ans"
        eval "$2=$ans"
}

# int processes an integer argument
#
#       int tail
#
function int () {
        # Slimier hack to get bash to rescan a line.
        eval "set -- $1"
        ans="x"
        while [ $[$ans+0] != "$ans" ]; do
                readln "$1 ($2) [$3] " "$3"
        done
        echo "$2 = $ans" >>$CONFIG
        echo "#define $2 ($ans)" >>$CONFIG_H
        raw_input_line="int '$1' $2 $ans"
        eval "$2=$ans"
}

CONFIG=.config~
CONFIG_H=include/linux/autoconf.h

#
# Make sure we start out with a clean slate.
#
> config.new
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

stack=''
branch='t'

while IFS='@' read raw_input_line
do
        # Slimy hack to get bash to rescan a line.
        read cmd rest <<-END_OF_COMMAND
                $raw_input_line
        END_OF_COMMAND

        if [ "$cmd" = "*" ]; then
                if [ "$branch" = "t" ]; then
                        echo "$raw_input_line"
                        echo "# $rest" >>$CONFIG
                        if [ "$prevcmd" != "*" ]; then
                                echo >>$CONFIG_H
                                echo "/* $rest" >>$CONFIG_H
                        else
                                echo " * $rest" >>$CONFIG_H
                        fi
                        prevcmd="*"
                fi
        else
                [ "$prevcmd" = "*" ] && echo " */" >>$CONFIG_H
                prevcmd=""
                case "$cmd" in
                :)      [ "$branch" = "t" ] && echo "$raw_input_line" ;;
                int)    [ "$branch" = "t" ] && int "$rest" ;;
                bool)   [ "$branch" = "t" ] && bool "$rest" ;;
                exec)   [ "$branch" = "t" ] && ( sh -c "$rest" ) ;;
                if)     stack="$branch $stack"
                        if [ "$branch" = "t" ] && eval "$rest"; then
                                branch=t
                        else
                                branch=f
                        fi ;;
                else)   if [ "$branch" = "t" ]; then
                                branch=f
                        else
                                read branch rest <<-END_OF_STACK
                                        $stack
                                END_OF_STACK
                        fi ;;
                fi)     [ -z "$stack" ] && echo "Error!  Extra fi." 1>&2
                        read branch stack <<-END_OF_STACK
                                $stack
                        END_OF_STACK
                        ;;
                esac
        fi
        echo "$raw_input_line" >>config.new
done
[ "$prevcmd" = "*" ] && echo " */" >>$CONFIG_H

[ -z "$stack" ] || echo "Error!  Untermiated if." 1>&2

mv config.in config.old
mv config.new config.in

echo
echo "The linux kernel is now hopefully configured for your setup."
echo "Check the top-level Makefile for additional configuration,"
echo "and do a 'make dep ; make clean' if you want to be sure all"
echo "the files are correctly re-made"
echo

exit 0

/* [previous][next][first][last][top][bottom][index][help] */