summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-10-09 00:00:47 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-10-09 00:00:47 +0000
commitd6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch)
treee2be02f33984c48ec019c654051d27964e42c441 /scripts
parent609d1e803baf519487233b765eb487f9ec227a18 (diff)
Merge with 2.3.19.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Configure33
-rw-r--r--scripts/MAKEDEV.ide12
-rw-r--r--scripts/Menuconfig130
-rw-r--r--scripts/checkconfig.pl10
-rw-r--r--scripts/header.tk147
-rw-r--r--scripts/lxdialog/Makefile7
-rw-r--r--scripts/mkdep.c107
-rw-r--r--scripts/tail.tk6
-rw-r--r--scripts/tkcond.c479
-rw-r--r--scripts/tkgen.c937
-rw-r--r--scripts/tkparse.c282
-rw-r--r--scripts/tkparse.h48
-rw-r--r--scripts/ver_linux2
13 files changed, 1664 insertions, 536 deletions
diff --git a/scripts/Configure b/scripts/Configure
index 80eefc7e1..0f89d25a9 100644
--- a/scripts/Configure
+++ b/scripts/Configure
@@ -143,6 +143,10 @@ function comment () {
# define_bool define value
#
function define_bool () {
+ define_tristate $1 $2
+}
+
+function define_tristate () {
case "$2" in
"y")
echo "$1=y" >>$CONFIG
@@ -213,11 +217,11 @@ function tristate () {
while :; do
readln "$1 ($2) [$defprompt] " "$def" "$old"
case "$ans" in
- [yY] | [yY]es ) define_bool "$2" "y"
+ [yY] | [yY]es ) define_tristate "$2" "y"
break ;;
- [nN] | [nN]o ) define_bool "$2" "n"
+ [nN] | [nN]o ) define_tristate "$2" "n"
break ;;
- [mM] ) define_bool "$2" "m"
+ [mM] ) define_tristate "$2" "m"
break ;;
* ) help "$2"
;;
@@ -246,7 +250,7 @@ function dep_tristate () {
while [ $# -gt 0 ]; do
case "$1" in
n)
- define_bool "$var" "n"
+ define_tristate "$var" "n"
return
;;
m)
@@ -268,9 +272,9 @@ function dep_tristate () {
while :; do
readln "$ques ($var) [$defprompt] " "$def" "$old"
case "$ans" in
- [nN] | [nN]o ) define_bool "$var" "n"
+ [nN] | [nN]o ) define_tristate "$var" "n"
break ;;
- [mM] ) define_bool "$var" "m"
+ [mM] ) define_tristate "$var" "m"
break ;;
[yY] | [yY]es ) echo
echo " This answer is not allowed, because it is not consistent with"
@@ -290,6 +294,23 @@ function dep_tristate () {
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"
+}
+
#
# define_int sets the value of a integer argument
#
diff --git a/scripts/MAKEDEV.ide b/scripts/MAKEDEV.ide
index 6476860b7..feecb99bb 100644
--- a/scripts/MAKEDEV.ide
+++ b/scripts/MAKEDEV.ide
@@ -29,6 +29,18 @@ 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
diff --git a/scripts/Menuconfig b/scripts/Menuconfig
index a25722756..f7e3ef118 100644
--- a/scripts/Menuconfig
+++ b/scripts/Menuconfig
@@ -68,6 +68,12 @@
#
# 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().
+#
#
@@ -132,6 +138,22 @@ 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.
@@ -188,13 +210,52 @@ function tristate () {
# else in the kernel.
#
function dep_tristate () {
- if [ "$3" = "y" ]; then
- tristate "$1" "$2"
- else if [ "$3" = "m" ]; then
- mod_bool "$1" "$2"
+ 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_bool "$2" n
- fi; fi
+ 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
}
#
@@ -633,12 +694,13 @@ function parser(ifile,menu) {
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) >"MCmenu"menu_no
+ menu_no, $0) >newmenu
- parser(ifile, "MCmenu"menu_no)
+ parser(ifile, newmenu)
}
else if ($1 ~ "endmenu") {
printf("}\n") >>menu
@@ -988,13 +1050,37 @@ save_configuration () {
function tristate () {
set_x_info "$2" "n"
- eval define_bool "$2" "$x"
+ eval define_tristate "$2" "$x"
}
function dep_tristate () {
set_x_info "$2" "n"
- if [ "$3" = "m" -a "$x" = "y" ]; then x="m"; fi
- define_bool "$2" "$x"
+ 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 int () {
@@ -1015,7 +1101,29 @@ save_configuration () {
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
diff --git a/scripts/checkconfig.pl b/scripts/checkconfig.pl
index b82aa1a8b..fc352e436 100644
--- a/scripts/checkconfig.pl
+++ b/scripts/checkconfig.pl
@@ -25,12 +25,12 @@ foreach $file (@ARGV)
m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
# Pick up definitions.
- if ( m/^#/o )
+ if ( m/^\s*#/o )
{
- $iLinuxConfig = $. if m/^#\s*include\s*<linux\/config\.h>/o;
- $configList{uc $1} = 1 if m/^#\s*include\s*<config\/(\S*)\.h>/o;
- $configList{$1} = 1 if m/^#\s*define\s+CONFIG_(\w*)/o;
- $configList{$1} = 1 if m/^#\s*undef\s+CONFIG_(\w*)/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.
diff --git a/scripts/header.tk b/scripts/header.tk
index 8226fe3a7..adb5e0d41 100644
--- a/scripts/header.tk
+++ b/scripts/header.tk
@@ -32,7 +32,7 @@ proc cget { w option } {
proc vfix { var } {
global $var
if [ catch {eval concat $$var} ] {
- set $var 0
+ set $var 4
}
}
@@ -42,6 +42,7 @@ proc vfix { var } {
set CONSTANT_Y 1
set CONSTANT_M 2
set CONSTANT_N 0
+set CONSTANT_E 4
#
# Create a "reference" object to steal colors from.
@@ -67,9 +68,11 @@ proc mainmenu_name { text } {
proc menu_option { w menu_num text } {
global menus_per_column
- if { $menu_num <= $menus_per_column } then {
+ 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 { $menu_num <= [expr 2 * $menus_per_column] } then {
+ } elseif { $processed_top_level <= [expr 2 * $menus_per_column] } then {
set myframe middle
} else {
set myframe right
@@ -211,7 +214,7 @@ proc read_config { filename } {
}
close $file1
update_choices
- update_mainmenu .rdupd
+ update_mainmenu
}
proc write_comment { file1 file2 text } {
puts $file1 ""
@@ -223,17 +226,49 @@ proc write_comment { file1 file2 text } {
puts $file2 " */"
}
-proc write_tristate { file1 file2 varname variable dep } {
- if { $variable == 0 } \
- then { puts $file1 "# $varname is not set"; \
- puts $file2 "#undef $varname"} \
- elseif { $variable == 2 || ($dep == 2 && $variable == 1) } \
+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 } {
+ set var [sync_tristate $var $dep]
+ if {$dep == 2} then {
+ set var 0
+ }
+ return $var
+}
+
+proc write_tristate { file1 file2 varname variable deplist } {
+ set variable [sync_tristate $variable [effective_dep $deplist]]
+ 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 == 1 && $dep != 2 } \
- then { puts $file1 "$varname=y"; \
- puts $file2 "#define $varname 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)." \
}
@@ -245,7 +280,7 @@ proc write_int { file1 file2 varname variable dep } {
puts $file2 "#undef $varname"} \
else {
puts $file1 "$varname=$variable"; \
- puts $file2 "#define $varname $variable"; \
+ puts $file2 "#define $varname ($variable)"; \
}
}
@@ -255,7 +290,8 @@ proc write_hex { file1 file2 varname variable dep } {
puts $file2 "#undef $varname"} \
else {
puts $file1 "$varname=$variable"; \
- puts $file2 "#define $varname 0x$variable"; \
+ puts -nonewline $file2 "#define $varname 0x"; \
+ puts $file2 [exec echo $variable | sed s/^0\[xX\]//]; \
}
}
@@ -282,11 +318,11 @@ proc option_name {w mnum line text helpidx} {
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_menu$mnum .menu$mnum"
+ -relief groove -width 2 -command "update_active"
radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \
- -relief groove -width 2 -command "update_menu$mnum .menu$mnum"
+ -relief groove -width 2 -command "update_active"
radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \
- -relief groove -width 2 -command "update_menu$mnum .menu$mnum"
+ -relief groove -width 2 -command "update_active"
option_name $w $mnum $line $text $variable
@@ -296,11 +332,11 @@ proc toggle_switch2 {w mnum line text variable} {
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_menu$mnum .menu$mnum"
+ -relief groove -width 2 -command "update_active"
radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \
- -relief groove -width 2 -command "update_menu$mnum .menu$mnum"
+ -relief groove -width 2 -command "update_active"
radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \
- -relief groove -width 2 -command "update_menu$mnum .menu$mnum"
+ -relief groove -width 2 -command "update_active"
option_name $w $mnum $line $text $variable
@@ -322,10 +358,14 @@ proc tristate {w mnum line text variable } {
pack $w.x$line -anchor w -fill both -expand on
}
-proc dep_tristate {w mnum line text variable depend } {
+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 \
@@ -358,6 +398,18 @@ proc minimenu { w mnum line text variable helpidx } {
pack $w.x$line -anchor w -fill both -expand on
}
+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 line text } {
#nothing done for comments now.
}
@@ -417,7 +469,7 @@ ${var}:\\
#
frame $w.f2
button $w.f2.ok -text "OK" \
- -width 10 -command "destroy $w; focus $oldFocus"
+ -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
@@ -458,6 +510,55 @@ proc wrapup {w } {
}
+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.
@@ -468,3 +569,5 @@ frame .f0.left
frame .f0.middle
frame .f0.right
+set active_menus [list]
+set processed_top_level 0
diff --git a/scripts/lxdialog/Makefile b/scripts/lxdialog/Makefile
index 90e192a55..2bad7a12f 100644
--- a/scripts/lxdialog/Makefile
+++ b/scripts/lxdialog/Makefile
@@ -30,8 +30,11 @@ all: ncurses lxdialog
lxdialog: $(OBJS)
ncurses:
- @x=`find /lib/ /usr/lib/ /usr/local/lib/ -maxdepth 1 -name 'libncurses.*'` ;\
- if [ ! "$$x" ]; then \
+ @echo "main() {}" > lxtemp.c
+ @if $(CC) -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 ">>" ;\
diff --git a/scripts/mkdep.c b/scripts/mkdep.c
index 8b009041b..e1884e0a6 100644
--- a/scripts/mkdep.c
+++ b/scripts/mkdep.c
@@ -8,6 +8,16 @@
* 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.
*/
#include <ctype.h>
@@ -21,9 +31,7 @@
#include <sys/stat.h>
#include <sys/types.h>
-#ifndef MAP_AUTOGROW
-#define MAP_AUTOGROW 0
-#endif
+
char __depname[512] = "\n\t@touch ";
#define depname (__depname+9)
@@ -68,7 +76,7 @@ void grow_config(int len)
while (len_config + len > size_config) {
str_config = realloc(str_config, size_config *= 2);
if (str_config == NULL)
- { perror("malloc"); exit(1); }
+ { perror("malloc config"); exit(1); }
}
}
@@ -95,22 +103,11 @@ int is_defined_config(const char * name, int len)
/*
* Add a new value to the configuration string.
*/
-void define_config(int convert, const char * name, int len)
+void define_config(const char * name, int len)
{
grow_config(len + 1);
memcpy(str_config+len_config, name, len);
-
- if (convert) {
- int i;
- for (i = 0; i < len; i++) {
- char c = str_config[len_config+i];
- if (isupper(c)) c = tolower(c);
- if (c == '_') c = '/';
- str_config[len_config+i] = c;
- }
- }
-
len_config += len;
str_config[len_config++] = '\n';
}
@@ -123,7 +120,56 @@ void define_config(int convert, const char * name, int len)
void clear_config(void)
{
len_config = 0;
- define_config(0, "", 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)
+{
+ if (str_precious == NULL) {
+ len_precious = 0;
+ size_precious = 4096;
+ str_precious = malloc(4096);
+ if (str_precious == NULL)
+ { perror("malloc precious"); exit(1); }
+ }
+
+ while (len_precious + len > size_precious) {
+ 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;
}
@@ -139,7 +185,7 @@ void handle_include(int type, const char * name, int len)
return;
if (len >= 7 && !memcmp(name, "config/", 7))
- define_config(0, name+7, len-7-2);
+ define_config(name+7, len-7-2);
memcpy(path->buffer+path->len, name, len);
path->buffer[path->len+len] = '\0';
@@ -178,7 +224,7 @@ void use_config(const char * name, int len)
if (is_defined_config(pc, len))
return;
- define_config(0, pc, len);
+ define_config(pc, len);
if (!hasdep) {
hasdep = 1;
@@ -195,7 +241,8 @@ void use_config(const char * name, int len)
* Thus, there is one memory access per sizeof(unsigned long) characters.
*/
-#if defined(__alpha__) || defined(__i386__) || defined(__MIPSEL__) || defined(__arm__)
+#if defined(__alpha__) || defined(__i386__) || defined(__ia64__) || defined(__MIPSEL__) \
+ || defined(__arm__)
#define LE_MACHINE
#endif
@@ -362,7 +409,13 @@ pound_u:
GETNEXT NOTCASE('f', __start);
goto pound_define_undef;
-/* #\s*(define|undef)\s*CONFIG_(\w*) */
+/*
+ * #\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);
@@ -381,7 +434,6 @@ pound_define_undef_CONFIG_word:
GETNEXT
if (isalnum(current) || current == '_')
goto pound_define_undef_CONFIG_word;
- define_config(1, map_dot, next - map_dot - 1);
goto __start;
/* \<CONFIG_(\w*) */
@@ -445,7 +497,7 @@ void do_depend(const char * filename, const char * command)
mapsize = st.st_size;
mapsize = (mapsize+pagesizem1) & ~pagesizem1;
- map = mmap(NULL, mapsize, PROT_READ, MAP_AUTOGROW | MAP_PRIVATE, fd, 0);
+ map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
if ((long) map == -1) {
perror("mkdep: mmap");
close(fd);
@@ -460,8 +512,11 @@ void do_depend(const char * filename, const char * command)
hasdep = 0;
clear_config();
state_machine(map, map+st.st_size);
- if (hasdep)
+ if (hasdep) {
puts(command);
+ if (*command)
+ define_precious(filename);
+ }
munmap(map, mapsize);
close(fd);
@@ -503,5 +558,9 @@ int main(int argc, char **argv)
}
do_depend(filename, command);
}
+ if (len_precious) {
+ *(str_precious+len_precious) = '\0';
+ printf(".PRECIOUS:%s\n", str_precious);
+ }
return 0;
}
diff --git a/scripts/tail.tk b/scripts/tail.tk
index f088fee42..7ca01f252 100644
--- a/scripts/tail.tk
+++ b/scripts/tail.tk
@@ -29,10 +29,12 @@ if { [file readable .config] == 1} then {
read_config $defaults
}
-update_mainmenu .f0
+update_define 1 $total_menus 0
+update_mainmenu
button .f0.right.save -anchor w -text "Save and Exit" \
- -command { writeconfig .config include/linux/autoconf.h; wrapup .wrap }
+ -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" \
-command { maybe_exit .maybe }
diff --git a/scripts/tkcond.c b/scripts/tkcond.c
index 89069daad..f1a36bb25 100644
--- a/scripts/tkcond.c
+++ b/scripts/tkcond.c
@@ -14,6 +14,12 @@
* 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.
@@ -28,73 +34,88 @@
/*
- * Transform op_variable to op_kvariable.
- *
- * This works, but it's gross, speed-wise. It would benefit greatly
- * from a simple hash table that maps names to cfg.
- *
- * Note well: this is actually better than the loop structure xconfig
- * has been staggering along with for three years, which performs
- * this whole procedure inside *another* loop on active conditionals.
+ * Mark variables which are defined anywhere.
*/
-void transform_to_kvariable( struct kconfig * scfg )
+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 )
{
- struct condition * cond;
-
- for ( cond = cfg->cond; cond != NULL; cond = cond->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_tristate
+ || cfg->token == token_hex
+ || cfg->token == token_int
+ || cfg->token == token_string
+ || cfg->token == token_tristate
+ || cfg->token == token_unset )
{
- if ( cond->op == op_variable )
+ if ( cfg->nameindex > 0 ) /* paranoid */
{
- /* Here's where it gets DISGUSTING. */
- struct kconfig * cfg1;
-
- for ( cfg1 = scfg; cfg1 != NULL; cfg1 = cfg1->next )
- {
- if ( cfg1->token == token_bool
- || cfg1->token == token_choice_item
- || cfg1->token == token_dep_tristate
- || cfg1->token == token_hex
- || cfg1->token == token_int
- || cfg1->token == token_string
- || cfg1->token == token_tristate )
- {
- if ( strcmp( cond->str, cfg1->optionname ) == 0 )
- {
- cond->op = op_kvariable;
- cond->str = NULL;
- cond->cfg = cfg1;
- break;
- }
- }
- }
+ vartable[cfg->nameindex].defined = 1;
}
+ }
+ }
+}
-#if 0
- /*
- * Maybe someday this will be useful, but right now it
- * gives a lot of false positives on files like
- * drivers/video/Config.in that are meant for more
- * than one architecture. Turn it on if you want to play
- * with it though; it does work. -- mec
- */
- if ( cond->op == op_variable )
+
+
+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 )
{
- if ( strcmp( cond->str, "ARCH" ) != 0
- && strcmp( cond->str, "CONSTANT_Y" ) != 0
- && strcmp( cond->str, "CONSTANT_M" ) != 0
- && strcmp( cond->str, "CONSTANT_N" ) != 0 )
+ condb->op = (condb->op == op_eq) ? op_neq : op_eq;
+ conda->op = op_nuked;
+ if ( prev )
{
- fprintf( stderr, "warning: $%s used but not defined\n",
- cond->str );
+ prev->next = conda->next;
}
+ else
+ {
+ condition = conda->next;
+ }
+ conda->next = NULL;
+ free_cond( conda );
+ conda = condb;
}
-#endif
}
+ prev = conda;
}
+ return condition;
}
@@ -103,27 +124,65 @@ void transform_to_kvariable( struct kconfig * scfg )
* Make a new condition chain by joining the current condition stack with
* the "&&" operator for glue.
*/
-struct condition * join_condition_stack( struct condition * conditions [],
+static struct condition * join_condition_stack( struct condition * conditions [],
int depth )
{
struct condition * cond_list;
struct condition * cond_last;
- int i;
+ 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;
+ }
- /* add a '(' */
- cnew = malloc( sizeof(*cnew) );
- memset( cnew, 0, sizeof(*cnew) );
- cnew->op = op_lparen;
- if ( cond_last == NULL )
- { cond_list = 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
- { cond_last->next = cnew; cond_last = cnew; }
+ {
+ add_paren = 0;
+ }
/* duplicate the chain */
for ( cond = conditions [i]; cond != NULL; cond = cond->next )
@@ -132,27 +191,23 @@ struct condition * join_condition_stack( struct condition * conditions [],
cnew->next = NULL;
cnew->op = cond->op;
cnew->str = cond->str ? strdup( cond->str ) : NULL;
- cnew->cfg = cond->cfg;
- cond_last->next = cnew;
- cond_last = cnew;
+ cnew->nameindex = cond->nameindex;
+ if ( cond_last == NULL )
+ { cond_list = cond_last = cnew; }
+ else
+ { cond_last->next = cnew; cond_last = cnew; }
}
- /* add a ')' */
- cnew = malloc( sizeof(*cnew) );
- memset( cnew, 0, sizeof(*cnew) );
- cnew->op = op_rparen;
- cond_last->next = cnew;
- cond_last = cnew;
-
- /* if i have another condition, add an '&&' operator */
- if ( i < depth - 1 )
+ if ( add_paren )
{
+ /* add a ')' */
cnew = malloc( sizeof(*cnew) );
memset( cnew, 0, sizeof(*cnew) );
- cnew->op = op_and;
+ cnew->op = op_rparen;
cond_last->next = cnew;
cond_last = cnew;
}
+ is_first = 0;
}
/*
@@ -171,7 +226,7 @@ struct condition * join_condition_stack( struct condition * conditions [],
cond1e = cond1d->next; if ( cond1e == NULL ) break;
cond1f = cond1e->next; if ( cond1f == NULL ) break;
- if ( cond1b->op == op_kvariable
+ if ( cond1b->op == op_variable
&& ( cond1c->op == op_eq || cond1c->op == op_neq )
&& cond1d->op == op_constant
&& cond1e->op == op_rparen )
@@ -189,8 +244,8 @@ struct condition * join_condition_stack( struct condition * conditions [],
cond2f = cond2e->next;
/* look for match */
- if ( cond2b->op == op_kvariable
- && cond2b->cfg == cond1b->cfg
+ if ( cond2b->op == op_variable
+ && cond2b->nameindex == cond1b->nameindex
&& cond2c->op == cond1c->op
&& cond2d->op == op_constant
&& strcmp( cond2d->str, cond1d->str ) == 0
@@ -219,64 +274,159 @@ struct condition * join_condition_stack( struct condition * conditions [],
}
}
+join_done:
return cond_list;
}
+static char * current_arch = NULL;
+
/*
- * This is the main transformation function.
+ * Eliminating conditions with ARCH = <not current>.
*/
-void fix_conditionals( struct kconfig * scfg )
+static struct condition *eliminate_other_arch( struct condition *list )
{
- struct kconfig * cfg;
-
- /*
- * Transform op_variable to op_kvariable.
- */
- transform_to_kvariable( scfg );
-
- /*
- * Transform conditions that use variables from "choice" statements.
- * Choice values appear to the user as a collection of booleans, and the
- * script can test the individual booleans. But internally, all I have is
- * the N-way value of an unnamed temporary for the whole statement. So I
- * have to tranform '"$CONFIG_M386" != "y"'
- * into '"$tmpvar_N" != "CONFIG_M386"'.
- */
- for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
+ struct condition *cond1a = list, *cond1b = NULL, *cond1c = NULL, *cond1d = NULL;
+ if ( current_arch == NULL )
+ current_arch = getenv( "ARCH" );
+ if ( current_arch == NULL )
{
- struct condition * cond;
-
- for ( cond = cfg->cond; cond != NULL; cond = cond->next )
+ 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 ( cond->op == op_kvariable && cond->cfg->token == token_choice_item )
+ if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))
+ || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) )
{
- /*
- * Look two more tokens down for the comparison token.
- * It has to be "y" for this trick to work.
- *
- * If you get this error, don't even think about relaxing the
- * strcmp test. You will produce incorrect TK code. Instead,
- * look for the place in your Config.in script where you are
- * comparing a 'choice' variable to a value other than 'y',
- * and rewrite the comparison to be '= "y"' or '!= "y"'.
- */
- struct condition * cond2 = cond->next->next;
- const char * label;
-
- if ( strcmp( cond2->str, "y" ) != 0 )
+ /* 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 )
{
- fprintf( stderr, "tkparse choked in fix_choice_cond\n" );
- exit( 1 );
+ 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;
- label = cond->cfg->label;
- cond->cfg = cond->cfg->cfg_parent;
- cond2->str = strdup( label );
+ 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.
@@ -290,16 +440,19 @@ void fix_conditionals( struct kconfig * scfg )
{
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++] = cfg->cond;
+ cond_stack [depth++] =
+ remove_bang( eliminate_other_arch( cfg->cond ) );
cfg->cond = NULL;
break;
@@ -325,6 +478,8 @@ void fix_conditionals( struct kconfig * scfg )
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;
}
}
}
@@ -336,25 +491,109 @@ void fix_conditionals( struct kconfig * scfg )
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_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_tristate:
/*
* Same as the other simple statements, plus an additional
* condition for the dependency.
*/
- cond_stack [depth] = cfg->cond;
- cfg->cond = join_condition_stack( cond_stack, depth+1 );
+ 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/scripts/tkgen.c b/scripts/tkgen.c
index 279072d78..4a50a82a4 100644
--- a/scripts/tkgen.c
+++ b/scripts/tkgen.c
@@ -92,33 +92,58 @@
*
* 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 flag )
+static void start_proc( char * label, int menu_num, int toplevel )
{
- if ( flag )
+ 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( "\tcatch {destroy $w}\n" );
+ 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" );
@@ -127,16 +152,41 @@ static void start_proc( char * label, int menu_num, int flag )
/*
* Attach the "Prev", "Next" and "OK" buttons at the end of the window.
*/
- printf( "\tset oldFocus [focus]\n" );
printf( "\tframe $w.f\n" );
- printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" );
- printf( "\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\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\" \\\n" );
- printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 );
+ printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; " );
+ /*
+ * We are checking which windows should be destroyed and which are
+ * common parrents 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 );
if ( menu_num == tot_menu_num )
printf( "\t$w.f.next configure -state disabled\n" );
printf( "\tbutton $w.f.prev -text \"Prev\" \\\n" );
- printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num-1, menu_num-1 );
+ 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" );
printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" );
@@ -177,12 +227,11 @@ static void start_proc( char * label, int menu_num, int flag )
* a global declaration so we know whether we need to insert one for a
* given function or not.
*/
-void clear_globalflags( struct kconfig * scfg )
+static void clear_globalflags(void)
{
- struct kconfig * cfg;
-
- for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
- cfg->global_written = 0;
+ int i;
+ for ( i = 1; i <= max_varnum; i++ )
+ vartable[i].global_written = 0;
}
@@ -194,7 +243,7 @@ void clear_globalflags( struct kconfig * scfg )
*/
void global( const char *var )
{
- printf( "\tglobal %s; vfix %s\n", var, var );
+ printf( "\tglobal %s\n", var );
}
@@ -207,6 +256,21 @@ 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;
+ }
+ else
+ {
+ if ( cfg->token == token_string || cfg->token == token_mainmenu_option )
+ return;
+ }
/*
* First write any global declarations we need for this conditional.
@@ -219,14 +283,10 @@ void generate_if( struct kconfig * cfg, struct condition * ocond,
break;
case op_variable:
- global( cond->str );
- break;
-
- case op_kvariable:
- if ( ! cond->cfg->global_written )
+ if ( ! vartable[cond->nameindex].global_written )
{
- cond->cfg->global_written = 1;
- global( cond->cfg->optionname );
+ vartable[cond->nameindex].global_written = 1;
+ global( vartable[cond->nameindex].name );
}
break;
}
@@ -235,10 +295,10 @@ void generate_if( struct kconfig * cfg, struct condition * ocond,
/*
* Now write this option.
*/
- if ( ! cfg->global_written && cfg->optionname != NULL )
+ if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written )
{
- cfg->global_written = 1;
- global( cfg->optionname );
+ vartable[cfg->nameindex].global_written = 1;
+ global( vartable[cfg->nameindex].name );
}
/*
@@ -262,156 +322,310 @@ void generate_if( struct kconfig * cfg, struct condition * ocond,
case op_rparen: printf( ")" ); break;
case op_variable:
- printf( "$%s", cond->str );
- break;
-
- case op_kvariable:
- printf( "$%s", cond->cfg->optionname );
+ 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 { " );
+ printf( "} then {" );
/*
* Generate a procedure call to write the value.
* This code depends on procedures in header.tk.
*/
- switch ( cfg->token )
+ if ( line_num >= -1 )
{
- default:
- printf( " }\n" );
- break;
-
- case token_bool:
- printf( ".menu%d.config.f.x%d.y configure -state normal;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.n configure -state normal;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.l configure -state normal;",
- menu_num, line_num );
- printf( "set %s [expr $%s&15];",
- cfg->optionname, cfg->optionname );
- printf( "} else { ");
- printf( ".menu%d.config.f.x%d.y configure -state disabled;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.n configure -state disabled;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.l configure -state disabled;",
- menu_num, line_num );
- printf( "set %s [expr $%s|16];}\n",
- cfg->optionname, cfg->optionname );
- break;
+ switch ( cfg->token )
+ {
+ default:
+ printf( " }\n" );
+ break;
- case token_choice_header:
- fprintf( stderr, "Internal error on token_choice_header\n" );
- exit( 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];",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+ printf( "if {$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( "}; " );
+ 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_item:
- fprintf( stderr, "Internal error on token_choice_item\n" );
- exit( 1 );
+ 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_define_bool:
- printf( "set %s %s } \n",
- cfg->optionname, cfg->value );
- break;
+ case token_choice_item:
+ fprintf( stderr, "Internal error on token_choice_item\n" );
+ exit( 1 );
- case token_dep_tristate:
- case token_tristate:
- if ( cfg->token == token_dep_tristate )
- {
- global( cfg->depend );
- printf( "if { $%s != 1 && $%s != 0 } then {",
- cfg->depend, cfg->depend );
- printf( ".menu%d.config.f.x%d.y configure -state disabled;",
+ 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( ".menu%d.config.f.x%d.y configure -state normal;",
- menu_num, line_num);
+ printf( "configure_entry .menu%d.config.f.x%d normal {y}",
+ menu_num, line_num );
printf( "}; " );
- }
- else
- {
- printf( ".menu%d.config.f.x%d.y configure -state normal;",
+ 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_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
+ {
+ switch ( cfg->token )
+ {
+ default:
+ printf( " }\n" );
+ break;
+
+ 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];",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+ 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( "} else {");
+ printf( "set %s [expr $%s|16]}\n",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+ break;
- printf( ".menu%d.config.f.x%d.n configure -state normal;",
- menu_num, line_num );
- printf( "global CONFIG_MODULES; if {($CONFIG_MODULES == 1)} then { .menu%d.config.f.x%d.m configure -state normal };",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.l configure -state normal;",
- menu_num, line_num );
+ 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];",
- cfg->optionname, cfg->optionname );
- printf( "} else { " );
- printf( ".menu%d.config.f.x%d.y configure -state disabled;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.n configure -state disabled;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.m configure -state disabled;",
- menu_num, line_num );
- printf( ".menu%d.config.f.x%d.l configure -state disabled;",
- menu_num, line_num );
+ printf( "set %s [expr $%s&15]",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+ printf( "} else {" );
/*
* Clear the disable bit to enable the correct radiobutton.
*/
- printf( "set %s [expr $%s|16];}\n",
- cfg->optionname, cfg->optionname );
- break;
+ printf( "set %s [expr $%s|16]}\n",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
+ 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_hex:
+ case token_int:
+ if ( cfg->value && *cfg->value == '$' )
+ {
+ int index = get_varnum( cfg->value+1 );
+ printf( "\n" );
+ if ( ! vartable[index].global_written )
+ {
+ global( vartable[index].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_mainmenu_option:
- printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n",
- menu_num, menu_num );
- 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;
+
/*
* Generate global declaration for this symbol.
*/
if ( cfg->token != token_comment )
{
- if ( ! cfg->global_written )
+ 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 )
{
- cfg->global_written = 1;
- printf( "\tglobal %s\n", cfg->optionname );
+ 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) );
}
}
@@ -426,14 +640,10 @@ void generate_writeconfig( struct kconfig * cfg )
break;
case op_variable:
- global( cond->str );
- break;
-
- case op_kvariable:
- if ( ! cond->cfg->global_written )
+ if ( ! vartable[cond->nameindex].global_written )
{
- cond->cfg->global_written = 1;
- global( cond->cfg->optionname );
+ vartable[cond->nameindex].global_written = 1;
+ global( vartable[cond->nameindex].name );
}
break;
}
@@ -442,7 +652,6 @@ void generate_writeconfig( struct kconfig * cfg )
/*
* Generate indentation.
*/
- if ( cfg->token != token_choice_header )
printf( "\t" );
/*
@@ -466,17 +675,14 @@ void generate_writeconfig( struct kconfig * cfg )
case op_rparen: printf( ")" ); break;
case op_variable:
- printf( "$%s", cond->str );
- break;
-
- case op_kvariable:
- printf( "$%s", cond->cfg->optionname );
+ 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;
@@ -499,10 +705,8 @@ void generate_writeconfig( struct kconfig * cfg )
case token_bool:
case token_tristate:
- if ( cfg->cond )
- printf( " " );
- printf( "write_tristate $cfg $autocfg %s $%s $notmod",
- cfg->optionname, cfg->optionname );
+ printf( "write_tristate $cfg $autocfg %s $%s [list $notmod]",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
if ( cfg->cond != NULL )
printf( " }" );
printf( "\n" );
@@ -520,12 +724,15 @@ void generate_writeconfig( struct kconfig * cfg )
cfg1 != NULL && cfg1->token == token_choice_item;
cfg1 = cfg1->next )
{
- printf("\tif { $%s == \"%s\" } then { write_tristate $cfg $autocfg %s 1 $notmod } else { write_tristate $cfg $autocfg %s 0 $notmod }\n",
- cfg->optionname, cfg1->label,
- cfg1->optionname,
- cfg1->optionname );
+ printf("\n\tif { $tmpvar_%d == \"%s\" } then { write_tristate $cfg $autocfg %s 1 [list $notmod] } else { write_tristate $cfg $autocfg %s 0 [list $notmod] }",
+ -(cfg->nameindex), cfg1->label,
+ vartable[cfg1->nameindex].name,
+ vartable[cfg1->nameindex].name );
}
}
+ if ( cfg->cond != NULL )
+ printf( "}" );
+ printf( "\n" );
break;
case token_choice_item:
@@ -541,53 +748,74 @@ void generate_writeconfig( struct kconfig * cfg )
break;
case token_define_bool:
+ case token_define_tristate:
if ( cfg->cond == NULL )
{
- printf( "write_tristate $cfg $autocfg %s $%s $notmod\n",
- cfg->optionname, cfg->optionname );
+ printf( "write_tristate $cfg $autocfg %s $%s [list $notmod]\n",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
}
else
{
- printf( "write_tristate $cfg $autocfg %s %s $notmod }\n",
- cfg->optionname, cfg->value );
+ printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] }\n",
+ vartable[cfg->nameindex].name, cfg->value );
}
break;
+ case token_dep_bool:
case token_dep_tristate:
- if ( cfg->cond )
- printf( " " );
- printf( "write_tristate $cfg $autocfg %s $%s $%s",
- cfg->optionname, cfg->optionname, cfg->depend );
+ 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( "]" );
if ( cfg->cond != NULL )
printf( " }" );
- printf( " \n" );
+ printf( "\n" );
break;
- case token_hex:
+ 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( " }" );
+ printf( "\n" );
+ break;
+
+ case token_hex:
printf( "write_hex $cfg $autocfg %s $%s $notmod",
- cfg->optionname, cfg->optionname );
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
if ( cfg->cond != NULL )
printf( " }" );
printf( "\n" );
break;
case token_int:
- if ( cfg->cond != NULL )
- printf( " " );
printf( "write_int $cfg $autocfg %s $%s $notmod",
- cfg->optionname, cfg->optionname );
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
if ( cfg->cond != NULL )
printf( " }" );
printf( "\n" );
break;
case token_string:
- if ( cfg->cond != NULL )
- printf( " " );
- printf( "write_string $cfg $autocfg %s $%s $notmod",
- cfg->optionname, cfg->optionname );
+ printf( "write_string $cfg $autocfg %s \"$%s\" $notmod",
+ vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
if ( cfg->cond != NULL )
printf( " }" );
printf( "\n" );
@@ -595,6 +823,112 @@ void generate_writeconfig( struct kconfig * cfg )
}
}
+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 );
+ }
+ }
+ }
+
+ 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_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" );
+}
/*
@@ -603,13 +937,24 @@ void generate_writeconfig( struct kconfig * cfg )
static void end_proc( struct kconfig * scfg, int menu_num )
{
struct kconfig * cfg;
+ int i;
printf( "\n\n\n" );
printf( "\tfocus $w\n" );
- printf( "\tupdate_menu%d $w.config.f\n",
- menu_num );
+ printf( "\tupdate_active\n" );
printf( "\tglobal winx; global winy\n" );
- printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\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( "\twm geometry $w +$winx+$winy\n" );
/*
@@ -660,27 +1005,12 @@ static void end_proc( struct kconfig * scfg, int menu_num )
* 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 {w} {\n", menu_num );
- printf( "\tupdate_define\n" );
+ printf( "proc update_menu%d {} {\n", menu_num );
/*
* Clear all of the booleans that are defined in this menu.
*/
- clear_globalflags( scfg );
- for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
- {
- if ( cfg->menu_number == menu_num && cfg->token == token_define_bool
- && cfg->optionname != NULL )
- {
- if ( ! cfg->global_written )
- {
- cfg->global_written = 1;
- printf( "\tglobal %s\n", cfg->optionname );
- printf( "\tset %s 0\n", cfg->optionname );
- }
- }
- }
-
+ clear_globalflags();
for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
{
if ( cfg->menu_number == menu_num
@@ -688,28 +1018,47 @@ static void end_proc( struct kconfig * scfg, int menu_num )
&& 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
{
- /*
- * Treat tristate like conditional here.
- */
- if ( cfg->token == token_dep_tristate )
+ if ( cfg->token == token_tristate )
{
- global( cfg->depend );
- printf( "\tif {$%s != 1 && $%s != 0 } then { .menu%d.config.f.x%d.y configure -state disabled } else { .menu%d.config.f.x%d.y configure -state normal}\n",
- cfg->depend, cfg->depend,
+ 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.
@@ -718,18 +1067,20 @@ void dump_tk_script( struct kconfig * scfg )
{
int menu_depth;
int menu_num [64];
- struct kconfig * menu_first [256];
- struct kconfig * menu_last [256];
- int imenu;
+ int imenu, i;
+ int top_level_num = 0;
struct kconfig * cfg;
struct kconfig * cfg1 = NULL;
const char * name = "No Name";
/*
- * Thread the menu pointers so I can walk each menu separately.
- */
+ * 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 )
@@ -744,14 +1095,22 @@ void dump_tk_script( struct kconfig * scfg )
case token_mainmenu_option:
if ( ++menu_depth >= 64 )
{ fprintf( stderr, "menus too deep\n" ); exit( 1 ); }
- if ( ++tot_menu_num >= 256 )
+ 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 ); }
@@ -760,19 +1119,24 @@ void dump_tk_script( struct kconfig * scfg )
case token_bool:
case token_choice_header:
case token_choice_item:
+ case token_dep_bool:
case token_dep_tristate:
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 ); }
- menu_last [menu_num [menu_depth]]->menu_next = cfg;
- menu_last [menu_num [menu_depth]] = cfg;
- cfg->menu_next = NULL;
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;
}
}
@@ -784,7 +1148,21 @@ void dump_tk_script( struct kconfig * scfg )
* one blank button
* add two to round up for division
*/
- printf( "set menus_per_column %d\n\n", (tot_menu_num + 4 + 1 + 2) / 3 );
+ 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.
@@ -793,24 +1171,33 @@ void dump_tk_script( struct kconfig * scfg )
for ( imenu = 1; imenu <= tot_menu_num; ++imenu )
{
int menu_line = 0;
+ int nr_submenu = imenu;
- clear_globalflags( scfg );
- start_proc( menu_first[imenu]->label, imenu, 1 );
+ clear_globalflags();
+ start_proc( menu_first[imenu]->label, imenu,
+ !menu_first[imenu]->menu_number );
- for ( cfg = menu_first[imenu]; cfg != NULL; cfg = cfg->menu_next )
+ for ( cfg = menu_first[imenu]->next; cfg != NULL && cfg != menu_last[imenu]; cfg = cfg->next )
{
- cfg->menu_number = imenu;
-
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_bool:
cfg->menu_line = menu_line++;
printf( "\tbool $w.config.f %d %d \"%s\" %s\n",
cfg->menu_number, cfg->menu_line, cfg->label,
- cfg->optionname );
+ vartable[cfg->nameindex].name );
break;
case token_choice_header:
@@ -819,54 +1206,61 @@ void dump_tk_script( struct kconfig * scfg )
* help text from Documentation/Configure.help.
*/
cfg->menu_line = menu_line++;
- printf( "\tglobal %s\n", cfg->optionname );
- printf( "\tminimenu $w.config.f %d %d \"%s\" %s %s\n",
+ 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->optionname, cfg->next->optionname );
+ -(cfg->nameindex), vartable[cfg->next->nameindex].name );
printf( "\tmenu $w.config.f.x%d.x.menu\n", cfg->menu_line );
cfg1 = cfg;
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 %s -value \"%s\" -command \"update_menu%d .menu%d.config.f\"\n",
- cfg1->menu_line, cfg->label, cfg1->optionname,
- cfg->label, cfg1->menu_number, cfg1->menu_number );
+ 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 );
+ break;
+
+ case token_dep_bool:
+ 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 %s\n",
+ printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s\n",
cfg->menu_number, cfg->menu_line, cfg->label,
- cfg->optionname, cfg->depend );
+ 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,
- cfg->optionname );
+ 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,
- cfg->optionname );
+ 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,
- cfg->optionname );
+ 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,
- cfg->optionname );
+ vartable[cfg->nameindex].name );
break;
}
}
@@ -875,36 +1269,21 @@ void dump_tk_script( struct kconfig * scfg )
}
/*
- * The top level menu also needs an update function. When we exit a
+ * 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( scfg );
- printf( "proc update_mainmenu {w} {\n" );
- for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
+ clear_globalflags();
+ printf( "proc update_mainmenu {} {\n" );
+ for ( imenu = 1; imenu <= tot_menu_num; imenu++ )
{
- if ( cfg->token == token_mainmenu_option && cfg->cond != NULL )
- generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line );
+ 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" );
-#if 0
- /*
- * Generate code to set the variables that are "defined".
- */
- for ( cfg = config; cfg != NULL; cfg = cfg->next )
- {
- if ( cfg->token == token_define_bool )
- {
- if ( cfg->cond != NULL )
- generate_if( cfg, cfg->cond, menu_num, cfg->menu_line );
- else
- printf( "\twrite_define %s %s\n", cfg->optionname, cfg->value );
- }
- }
- #endif
-
+ clear_globalflags();
/*
* Generate code to load the default settings into the variables.
* The script in tail.tk will attempt to load .config,
@@ -919,27 +1298,50 @@ void dump_tk_script( struct kconfig * scfg )
case token_bool:
case token_choice_item:
+ case token_dep_bool:
case token_dep_tristate:
case token_tristate:
- printf( "set %s 0\n", cfg->optionname );
+ 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 %s \"(not set)\"\n", cfg->optionname );
+ printf( "set tmpvar_%d \"(not set)\"\n", -(cfg->nameindex) );
break;
case token_hex:
case token_int:
- printf( "set %s %s\n", cfg->optionname, cfg->value ? cfg->value : "0");
+ 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:
- printf( "set %s \"%s\"\n", cfg->optionname, cfg->value ? cfg->value : "");
+ 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" );
@@ -956,7 +1358,7 @@ void dump_tk_script( struct kconfig * scfg )
printf( "\tputs $autocfg \" */\"\n" );
printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" );
- clear_globalflags( scfg );
+ clear_globalflags();
for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
{
switch ( cfg->token )
@@ -968,6 +1370,11 @@ void dump_tk_script( struct kconfig * scfg )
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_hex:
case token_int:
@@ -996,7 +1403,8 @@ void dump_tk_script( struct kconfig * scfg )
cfg1 = cfg1->next )
{
printf( "\tglobal %s; set %s 0\n",
- cfg1->optionname, cfg1->optionname );
+ vartable[cfg1->nameindex].name,
+ vartable[cfg1->nameindex].name );
}
}
}
@@ -1007,41 +1415,22 @@ void dump_tk_script( struct kconfig * scfg )
{
if ( cfg->token == token_choice_header )
{
- printf( "\tglobal %s\n", cfg->optionname );
+ 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", cfg1->optionname );
- printf( "\tif { $%s == 1 } then { set %s \"%s\" }\n",
- cfg1->optionname, cfg->optionname, cfg1->label );
+ 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" );
- printf( "proc update_define { } {\n" );
- clear_globalflags( scfg );
- for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
- {
- if ( cfg->token == token_define_bool )
- {
- cfg->global_written = 1;
- printf( "\tglobal %s\n", cfg->optionname );
- }
- }
-
- for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
- {
- if( cfg->token == token_define_bool )
- {
- if ( cfg->cond == NULL )
- printf( "\tset %s %s\n", cfg->optionname, cfg->value );
- else
- generate_if( cfg, cfg->cond, -1, 0 );
- }
- }
- printf( "}\n\n\n" );
+ generate_update_var( scfg, 0 );
/*
* That's it. We are done. The output of this file will have header.tk
diff --git a/scripts/tkparse.c b/scripts/tkparse.c
index 4b593fd0a..86924a08d 100644
--- a/scripts/tkparse.c
+++ b/scripts/tkparse.c
@@ -29,6 +29,17 @@
* 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.
@@ -51,8 +62,6 @@ static void do_source( const char * );
int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); }
#define strcmp my_strcmp
-
-
/*
* Report a syntax error.
*/
@@ -65,6 +74,30 @@ static void syntax_error( const char * msg )
/*
+ * Find index of a specyfic variable in the symbol table.
+ * Create a new entry if it does not exist yet.
+ */
+#define VARTABLE_SIZE 2048
+struct variable vartable[VARTABLE_SIZE];
+int max_varnum = 0;
+
+int get_varnum( char * name )
+{
+ int i;
+
+ for ( i = 1; i <= max_varnum; i++ )
+ if ( strcmp( vartable[i].name, name ) == 0 )
+ return i;
+ if (max_varnum > VARTABLE_SIZE-1)
+ syntax_error( "Too many variables defined." );
+ 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 )
@@ -138,6 +171,7 @@ static const char * get_qstring( const char * pnt, char ** label )
}
+
/*
* Tokenize an 'if' statement condition.
*/
@@ -145,6 +179,7 @@ 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' )
@@ -170,30 +205,53 @@ static struct condition * tokenize_if( const char * pnt )
cond = malloc( sizeof(*cond) );
memset( cond, 0, sizeof(*cond) );
if ( last == NULL )
- { list = last = cond; }
+ { list = last = cond; prev = NULL; }
else
- { last->next = cond; last = cond; }
+ { prev = last; last->next = cond; last = cond; }
/* determine the token value */
if ( *pnt == '-' && pnt[1] == 'a' )
- { cond->op = op_and; pnt += 2; continue; }
+ {
+ 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' )
- { cond->op = op_or; pnt += 2; continue; }
+ {
+ 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] == '=' )
- { cond->op = op_neq; pnt += 2; continue; }
+ {
+ if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
+ syntax_error( "incorrect argument" );
+ cond->op = op_neq; pnt += 2; continue;
+ }
if ( *pnt == '=' )
- { cond->op = op_eq; pnt += 1; continue; }
+ {
+ if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
+ syntax_error( "incorrect argument" );
+ cond->op = op_eq; pnt += 1; continue;
+ }
if ( *pnt == '!' )
- { cond->op = op_bang; pnt += 1; continue; }
+ {
+ 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 == '$' )
@@ -217,7 +275,15 @@ static struct condition * tokenize_if( const char * pnt )
char * str = malloc( pnt - word + 1 );
memcpy( str, word, pnt - word );
str [pnt - word] = '\0';
- cond->str = str;
+ if ( cond->op == op_variable )
+ {
+ cond->nameindex = get_varnum( str );
+ free( str );
+ }
+ else /* op_constant */
+ {
+ cond->str = str;
+ }
}
pnt++;
@@ -241,6 +307,7 @@ static const char * tokenize_choices( struct kconfig * cfg_choose,
for ( ; ; )
{
struct kconfig * cfg;
+ char * buffer = malloc( 64 );
/* skip whitespace */
while ( *pnt == ' ' || *pnt == '\t' )
@@ -262,7 +329,8 @@ static const char * tokenize_choices( struct kconfig * cfg_choose,
pnt = get_string( pnt, &cfg->label );
while ( *pnt == ' ' || *pnt == '\t' )
pnt++;
- pnt = get_string( pnt, &cfg->optionname );
+ pnt = get_string( pnt, &buffer );
+ cfg->nameindex = get_varnum( buffer );
}
return pnt;
@@ -270,8 +338,6 @@ static const char * tokenize_choices( struct kconfig * cfg_choose,
-
-
/*
* Tokenize one line.
*/
@@ -280,6 +346,8 @@ 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' )
@@ -313,6 +381,11 @@ static void tokenize_line( const char * pnt )
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_tristate, "dep_tristate" );
break;
@@ -371,11 +444,13 @@ static void tokenize_line( const char * pnt )
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" );
@@ -404,8 +479,9 @@ static void tokenize_line( const char * pnt )
case token_bool:
case token_tristate:
- pnt = get_qstring ( pnt, &cfg->label );
- pnt = get_string ( pnt, &cfg->optionname );
+ pnt = get_qstring ( pnt, &cfg->label );
+ pnt = get_string ( pnt, &buffer );
+ cfg->nameindex = get_varnum( buffer );
break;
case token_choice_header:
@@ -417,9 +493,7 @@ static void tokenize_line( const char * pnt )
pnt = get_qstring ( pnt, &choice_list );
pnt = get_string ( pnt, &cfg->value );
- cfg->optionname = malloc( 32 );
- sprintf( cfg->optionname, "tmpvar_%d", choose_number++ );
-
+ cfg->nameindex = -(choose_number++);
tokenize_choices( cfg, choice_list );
free( choice_list );
}
@@ -436,56 +510,133 @@ static void tokenize_line( const char * pnt )
break;
case token_define_bool:
- pnt = get_string( pnt, &cfg->optionname );
+ case token_define_tristate:
+ pnt = get_string( pnt, &buffer );
+ cfg->nameindex = get_varnum( buffer );
while ( *pnt == ' ' || *pnt == '\t' )
pnt++;
- if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0";
- else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1";
- else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2";
+ 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_qstring( pnt, &cfg->value );
+ break;
+
+ case token_dep_bool:
case token_dep_tristate:
- pnt = get_qstring ( pnt, &cfg->label );
- pnt = get_string ( pnt, &cfg->optionname );
+ pnt = get_qstring ( pnt, &cfg->label );
+ 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' ) )
- {
- /* dep_tristate 'foo' CONFIG_FOO m */
- if ( pnt[0] == 'Y' || pnt[0] == 'y' )
- cfg->depend = strdup( "CONSTANT_Y" );
- else if ( pnt[0] == 'M' || pnt[0] == 'm' )
- cfg->depend = strdup( "CONSTANT_M" );
+ 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
- cfg->depend = strdup( "CONSTANT_N" );
- pnt++;
- }
- else if ( *pnt == '$' )
- {
- pnt++;
- pnt = get_string( pnt, &cfg->depend );
- }
- else
- {
- syntax_error( "can't handle dep_tristate condition" );
- }
+ {
+ syntax_error( "can't handle dep_bool/dep_tristate condition" );
+ }
+ dep_ptr = &(*dep_ptr)->next;
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+ } while ( *pnt );
/*
- * Create a conditional for this object's dependency.
+ * Create a conditional for this object's dependencies.
*/
{
char fake_if [1024];
- sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then",
- cfg->depend, cfg->depend );
- cfg->cond = tokenize_if( fake_if );
+ 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_tristate )
+ sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then",
+ dep->name, dep->name, dep->name );
+ else
+ sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then",
+ 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;
@@ -496,15 +647,17 @@ static void tokenize_line( const char * pnt )
case token_hex:
case token_int:
- pnt = get_qstring ( pnt, &cfg->label );
- pnt = get_string ( pnt, &cfg->optionname );
- pnt = get_string ( pnt, &cfg->value );
+ 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, &cfg->optionname );
- pnt = get_qstring ( pnt, &cfg->value );
+ pnt = get_qstring ( pnt, &cfg->label );
+ pnt = get_string ( pnt, &buffer );
+ cfg->nameindex = get_varnum( buffer );
+ pnt = get_qstring ( pnt, &cfg->value );
break;
case token_if:
@@ -521,8 +674,25 @@ static void tokenize_line( const char * pnt )
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;
}
diff --git a/scripts/tkparse.h b/scripts/tkparse.h
index 0478effed..ecb31b654 100644
--- a/scripts/tkparse.h
+++ b/scripts/tkparse.h
@@ -14,6 +14,11 @@ enum e_token
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_tristate,
token_else,
token_endmenu,
@@ -46,7 +51,8 @@ enum operator
op_rparen,
op_constant,
op_variable,
- op_kvariable,
+ op_true,
+ op_false,
op_nuked
};
@@ -55,21 +61,29 @@ enum operator
* Some operators take strings:
*
* op_constant "foo"
- * op_variable "$ARCH", "$CONFIG_PMAC"
- * op_kvariable "$CONFIG_EXPERIMENTAL"
+ * op_variable "$ARCH", "$CONFIG_PMAC", "$CONFIG_EXPERIMENTAL"
*
* Most "$..." constructs refer to a variable which is defined somewhere
- * in the script, so they become op_kvariable's instead. Note that it
- * is legal to test variables which are never defined, such as variables
- * that are meaningful only on other architectures.
+ * 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, op_variable */
- struct kconfig * cfg; /* op_kvariable */
+ struct condition * next;
+ enum operator op;
+ const char * str; /* op_constant */
+ int nameindex; /* op_variable */
+};
+
+/*
+ * Dependency list for dep_bool, dep_tristate
+ */
+
+struct dependency
+{
+ char * name;
+ struct dependency * next;
};
/*
@@ -80,21 +94,28 @@ struct kconfig
{
struct kconfig * next;
enum e_token token;
- char * optionname;
+ int nameindex;
char * label;
char * value;
struct condition * cond;
- char * depend; /* token_dep_tristate */
+ struct dependency * depend; /* token_dep_tristate */
struct kconfig * cfg_parent; /* token_choice_item */
/* used only in tkgen.c */
- char global_written;
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
@@ -102,3 +123,4 @@ struct kconfig
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/scripts/ver_linux b/scripts/ver_linux
index a1b8642a4..b885791dd 100644
--- a/scripts/ver_linux
+++ b/scripts/ver_linux
@@ -5,7 +5,7 @@
# differ on your system.
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH
-echo '-- Versions installed: (if some fields are empty or looks'
+echo '-- Versions installed: (if some fields are empty or look'
echo '-- unusual then possibly you have very old versions)'
uname -a
insmod -V 2>&1 | awk 'NR==1 {print "Kernel modules ",$NF}'