[I wrote]
> Mutating the language, long-term, so that it looks less like sh and
> more like a specialised language, is IMO a worthy goal.  And I think
> it can be done.  The main thing to deal with is adding an
> alternative syntax for 'if' statements which doesn't look like
> test(1).  More about that in a separate message.

I've come up with syntax I think I'm happy with.  It supports most of
the current [ ] based if statement semantics, can be implemented in
shell, and (most importantly for me) drops those $ signs.  This lays
the groundwork for stuff like better error checking and auto
(EXPERIMENTAL) tags.

I made a proof-of-concept patch for Menuconfig.  The Configure patch
would be very similar; God only knows what xconfig or mconfig would
require.

I've reused the syntax for a dependency line (the tail end of a
dep_bool / dep_mbool / dep_tristate), like so:

  if_dep <i>dependency line</i>
     ...
  endif

If the dependency line evaluates to 'm' or 'y', the body is executed.

Now with our current dep_* syntax, this isn't very powerful.  I've
made a few extensions which are, I believe, almost enough[*] to
displace the current use of test(1)-based 'if' statements.  Some of
this syntax is not really needed for dep_* lines, but I *really* like
having a single backend function for all of dep_bool, dep_tristate and
if_dep.

[*] "almost enough" because I haven't implemented an 'else'
    directive.  It would be trivial, but I'm not sure what to call it.
    'else' itself is a shell primitive, so the shell-based parsers
    (Configure, Menuconfig) wouldn't like it.

* '$CONFIG_FOO' can and should be replaced with 'CONFIG_FOO' without
  the $.  My current patch accepts both; eventually we might drop
  backwards compatibility.

* !CONFIG_FOO negates sense: !y==n, !n==y, !==y, !m==m.  The last
  !m==m is due to Roman's observation that it is useful to exclude two
  things from both being Y while allowing them to both be M.

* 'or' placed between dependencies functions as a logical OR, and
  takes very low precedence.  This complements the implicit AND
  performed between every pair of dependencies.

    x or x -> x, for any x
    n or m == m or n  -> m
    n or y == y or n  -> y
    m or y == y or m  -> y

* A=B evaluates to either Y or N, depending on whether A is logically
  equivalent to B.  It has higher precedence than the ! operator.
  Thus:

  CONFIG_FOO=m   evaluates to 'y' if CONFIG_FOO is m, 'n' otherwise
  CONFIG_BAR=n   evaluates to 'y' if CONFIG_BAR is n or empty, 'n' otherwise
  !CONFIG_BAZ=y  evaluates to 'n' if CONFIG_BAZ is y, 'y' otherwise


This syntax is fully backward-compatible.  Examples of use:

  if_dep CONFIG_X86 or CONFIG_X86_64 or CONFIG_IA64
     bool 'ACPI support' CONFIG_ACPI
  endif

  if_dep CONFIG_SOUND !CONFIG_SOUND_ALSA
     source sound/oss/Config.in
  endif

  dep_tristate 'Adaptec (new driver)' CONFIG_AIC7XXX_NEW !CONFIG_AIC7XXX_OLD
  dep_tristate 'Adaptec (old driver)' CONFIG_AIC7XXX_OLD !CONFIG_AIC7XXX_NEW


The one thing I wanted to specify but didn't is an 'else' statement.
The problem is that I can't think what to call it - can't use 'else'
because the shell-based parsers (Configure, Menuconfig) will choke on
it.  Any ideas?

Any other comments?  Am I going in totally the wrong direction?

Peter


--- 2.5.31/scripts/Menuconfig   2002-06-09 00:27:32.000000000 -0500
+++ 2.5.31w/scripts/Menuconfig  2002-08-14 21:00:27.000000000 -0500
@@ -73,7 +73,10 @@
 # - Support for multiple conditions in dep_tristate().
 # - Implemented new functions: define_tristate(), define_int(), define_hex(),
 #   define_string(), dep_bool().
-# 
+#
+# 14 Aug 2002, Peter Samuelson <[EMAIL PROTECTED]>
+# - add lots of new syntax for dependencies in 'dep_*' functions
+# - also use this syntax for a new 'if_dep' / 'endif' primitive
 
 
 #
@@ -112,6 +115,67 @@
     eval info="\$INFO_$1"
 }
 
+
+# Reduce a dependency line down to a single char [ymn].
+# Terms are implicitly ANDed together: 'y m' = 'm y' = m, '... n' = 'n ...' = n
+# Each term can be:
+#   'y', 'm', 'n'      interpreted as-is
+#   'CONFIG_FOO'       reduces to value of CONFIG_FOO, or 'n' if unset
+#   'or'               OR operator, lower precedence than the implicit AND
+#      specifics:      'y or ...' = '... or y' = y
+#      if no 'y':      'm or ...' = '... or m' = m
+#   term=value         tested for equality, replaced with 'y' or 'n'
+#   !term              "negate" value of term: y->n, n->y, m->m, ''->y
+# Note that there is no grouping construct.
+# Use boolean transforms, or nest conditionals.
+function dep_calc () {
+       local neg arg ordep
+       if [ "$nest_ifdep" = n ]; then
+               cur_dep=n;
+               return 1;
+       fi
+       ordep=n
+       cur_dep=y       # return value
+       for arg; do
+         neg=;
+         case "$arg" in
+           or)
+             case $ordep in
+               n) ordep=$cur_dep ;;
+               m) [ $cur_dep = y ] && ordep=y ;;
+             esac
+             cur_dep=y; continue ;;
+           !*)
+             neg=N; arg=${arg#?} ;;
+         esac
+         case "$arg" in
+           'CONFIG_'*) eval arg=\$$arg ;;
+         esac
+         case "$arg" in
+           y=y | m=m | n=n | n= | =n) arg=y ;;
+           *=*) arg=n ;;
+         esac
+         case "$cur_dep/$neg/$arg" in
+           y//m | y/N/m) cur_dep=m ;;
+           *//n | */N/y) cur_dep=n ;;
+         esac
+       done
+       case "$cur_dep/$ordep" in
+         n/* | m/y) cur_dep=$ordep ;;
+       esac
+}
+
+function if_dep () {
+       dep_calc "$@"
+       nest_stack="$nest_ifdep $nest_stack"
+       nest_ifdep=$cur_dep
+}
+
+function endif () {
+       nest_ifdep=${nest_stack%%' '*}
+       nest_stack=${nest_stack#*' '}
+}
+
 #
 # Load the functions used by the config.in files.
 #
@@ -127,6 +191,7 @@
 # Additional comments
 #
 function comment () {
+       dep_calc || return
        comment_ctr=$[ comment_ctr + 1 ]
        echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
 }
@@ -135,22 +200,27 @@
 # Define a boolean to a specific value.
 #
 function define_bool () {
+       dep_calc || return
        eval $1=$2
 }
 
 function define_tristate () {
+       dep_calc || return
        eval $1=$2
 }
 
 function define_hex () {
+       dep_calc || return
        eval $1=$2
 }
 
 function define_int () {
+       dep_calc || return
        eval $1=$2
 }
 
 function define_string () {
+       dep_calc || return
        eval $1="$2"
 }
 
@@ -159,6 +229,7 @@
 # which calls our local bool function.
 #
 function bool () {
+       dep_calc || return
        set_x_info "$2" "n"
 
        case $x in
@@ -178,6 +249,7 @@
 # Collapses to a boolean (Yes/No) if module support is disabled.
 #
 function tristate () {
+       dep_calc || return
        if [ "$CONFIG_MODULES" != "y" ]
        then
                bool "$1" "$2"
@@ -210,28 +282,13 @@
 #       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
+       ques=$1  var=$2;  shift 2
+       dep_calc "$@" || return
+       case $cur_dep in
+         y) tristate "$ques" "$var" ;;
+         m) mod_bool "$ques" "$var" ;;
+         n) define_tristate "$var" n ;;
+       esac
 }
 
 #
@@ -239,49 +296,28 @@
 #   (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
+       ques=$1  var=$2;  shift 2
+       dep_calc "$@" || return
+       case $cur_dep in
+         y) bool "$ques" "$var" ;;
+         *) define_bool "$var" n ;;
+       esac
 }
 
 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
+       ques=$1  var=$2;  shift 2
+       dep_calc "$@" || return
+       case $cur_dep in
+         y|m) bool "$ques" "$var" ;;
+         n) define_bool "$var" n ;;
+       esac
 }
 
 #
 # Add a menu item which will call our local int function.
 # 
 function int () {
+       dep_calc || return
        set_x_info "$2" "$3"
 
        echo -ne "'$2' '($x) $1$info' " >>MCmenu
@@ -293,6 +329,7 @@
 # Add a menu item which will call our local hex function.
 # 
 function hex () {
+       dep_calc || return
        set_x_info "$2" "$3"
        x=${x##*[x,X]}
 
@@ -305,6 +342,7 @@
 # Add a menu item which will call our local string function.
 # 
 function string () {
+       dep_calc || return
        set_x_info "$2" "$3"
 
        echo -ne "'$2' '     $1: \"$x\"$info' " >>MCmenu
@@ -316,6 +354,7 @@
 # Add a menu item which will call our local One-of-Many choice list.
 #
 function choice () {
+       dep_calc || return
        #
        # Need to remember params cause they're gonna get reset.
        #
@@ -1066,90 +1105,81 @@
        # Nested function definitions, YIPEE!
        #
        function bool () {
+               dep_calc || return
                set_x_info "$2" "n"
                eval define_bool "$2" "$x"
        }
 
        function tristate () {
+               dep_calc || return
                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
+               var=$2;  shift 2
+               dep_calc "$@" || return
+               set_x_info "$var" "n"
+               case $cur_dep$x in
+                       my) x=m ;;
+                       n*) x=n ;;
+               esac
                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
+               var=$2;  shift 2
+               dep_calc "$@" || return
+               set_x_info "$var" "n"
+               [ $cur_dep = y ] || x=n
                define_bool "$var" "$x"
        }
 
        function dep_mbool () {
+               var=$2;  shift 2
+               dep_calc "$@" || return
                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
+               [ $cur_dep = n ] && x=n
                define_bool "$var" "$x"
        }
 
        function int () {
+               dep_calc || return
                set_x_info "$2" "$3"
                echo "$2=$x"            >>$CONFIG
                echo "#define $2 ($x)"  >>$CONFIG_H
        }
 
        function hex () {
+               dep_calc || return
                set_x_info "$2" "$3"
                echo "$2=$x"                     >>$CONFIG
                echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H
        }
 
        function string () {
+               dep_calc || return
                set_x_info "$2" "$3"
                echo "$2=\"$x\""                         >>$CONFIG
                echo "#define $2 \"$x\""        >>$CONFIG_H
        }
 
        function define_hex () {
+               dep_calc || return
                eval $1="$2"
                        echo "$1=$2"                    >>$CONFIG
                echo "#define $1 0x${2##*[x,X]}"        >>$CONFIG_H
        }
 
        function define_int () {
+               dep_calc || return
                eval $1="$2"
                echo "$1=$2"                    >>$CONFIG
                echo "#define $1 ($2)"          >>$CONFIG_H
        }
 
        function define_string () {
+               dep_calc || return
                eval $1="$2"
                echo "$1=\"$2\""                >>$CONFIG
                echo "#define $1 \"$2\""        >>$CONFIG_H
@@ -1160,6 +1190,7 @@
        }
 
        function define_tristate () {
+               dep_calc || return
                eval $1="$2"
 
                case "$2" in
@@ -1188,6 +1219,7 @@
        }
 
        function choice () {
+               dep_calc || return
                #
                # Find the first choice that's already set to 'y'
                #
@@ -1236,6 +1268,7 @@
        }
 
        function mainmenu_option () {
+               dep_calc || return
                comment_is_option=TRUE
        }
 
@@ -1244,6 +1277,7 @@
        }
 
        function comment () {
+               dep_calc || return
                if [ "$comment_is_option" ]
                then
                        comment_is_option=


-------------------------------------------------------
This sf.net email is sponsored by: Dice - The leading online job board
for high-tech professionals. Search and apply for tech jobs today!
http://seeker.dice.com/seeker.epl?rel_code=31
_______________________________________________
kbuild-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/kbuild-devel

Reply via email to