64eb94daed5bcff226757808f8df97c954d45fa1
[linux-2.4.git] / Menuconfig
1 #! /bin/sh
2 #
3 # This script is used to configure the linux kernel.
4 #
5 # It was inspired by a desire to not have to hit <enter> 9 million times
6 # or startup the X server just to change a single kernel parameter.  
7 #
8 # This script attempts to parse the configuration files, which are
9 # scattered throughout the kernel source tree, and creates a temporary
10 # set of mini scripts which are in turn used to create nested menus and
11 # radiolists.
12 #
13 # It uses a very modified/mutilated version of the "dialog" utility
14 # written by Savio Lam (lam836@cs.cuhk.hk). Savio is not responsible
15 # for this script or the version of dialog used by this script.
16 # Please do not contact him with questions. The official version of 
17 # dialog is available at sunsite.unc.edu or a sunsite mirror.
18 #
19 # Portions of this script were borrowed from the original Configure
20 # script.
21 #
22 # William Roadcap was the original author of Menuconfig.
23 # Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
24 #
25 # 070497 Bernhard Kaindl (bkaindl@netway.at) - get default values for
26 # new bool, tristate and dep_tristate parameters from the defconfig file.
27 # new configuration parameters are marked with '(NEW)' as in make config.
28 #
29 # 180697 Bernhard Kaindl (bkaindl@netway.at) - added the needed support
30 # for string options. They are handled like the int and hex options.
31 #
32 # 081297 Pavel Machek (pavel@atrey.karlin.mff.cuni.cz) - better error 
33 # handling
34 #
35 # 131197 Michael Chastain (mec@shout.net) - output all lines for a
36 # choice list, not just the selected one.  This makes the output
37 # the same as Configure output, which is important for smart config
38 # dependencies.
39 #
40 # 101297 Michael Chastain (mec@shout.net) - remove sound driver cruft.
41 #
42 # 221297 Michael Chastain (mec@shout.net) - make define_bool actually
43 # define its arguments so that later tests on them work right.
44 #
45 # 160198 Michael Chastain (mec@shout.net) - fix bug with 'c' command
46 # (complement existing value) when used on virgin uninitialized variables.
47 #
48 # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
49 # texts.
50 #
51 # 12 Dec 1998, Michael Elizabeth Chastain (mec@shout.net)
52 # Remove a /tmp security hole in get_def (also makes it faster).
53 # Give uninitialized variables canonical values rather than null value.
54 # Change a lot of places to call set_x_info uniformly.
55 # Take out message about preparing version (old sound driver cruft).
56 #
57 # 13 Dec 1998, Riley H Williams <Riley@Williams.Name>
58 # When an error occurs, actually display the error message as well as
59 # our comments thereon.
60 #
61 # 31 Dec 1998, Michael Elizabeth Chastain (mec@shout.net)
62 # Fix mod_bool to honor $CONFIG_MODULES.
63 # Fix dep_tristate to call define_bool when dependency is "n".
64 #
65 # 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
66 # Blow away lxdialog.scrltmp on entry to activate_menu.  This protects
67 # against people who use commands like ' ' to select menus.
68 #
69 # 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
70 # - Improve the exit message (Jeff Ronne).
71 #
72 # 06 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl>
73 # - Support for multiple conditions in dep_tristate().
74 # - Implemented new functions: define_tristate(), define_int(), define_hex(),
75 #   define_string(), dep_bool().
76 #
77 # 12 November 2001, Keith Owens <kaos@ocs.com.au>
78 # Escape double quotes on eval so the quotes are still there on the second
79 # evaluation, required to handle strings with special characters.
80
81
82
83 #
84 # Change this to TRUE if you prefer all kernel options listed
85 # in a single menu rather than the standard menu hierarchy.
86 #
87 single_menu_mode=
88
89 #
90 # Make sure we're really running bash.
91 #
92 [ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; }
93
94 #
95 # Cache function definitions, turn off posix compliance
96 #
97 set -h +o posix
98
99
100
101 # Given a configuration variable, set the global variable $x to its value,
102 # and the global variable $info to the string " (NEW)" if this is a new
103 # variable.
104 #
105 # This function looks for: (1) the current value, or (2) the default value
106 # from the arch-dependent defconfig file, or (3) a default passed by the caller.
107
108 function set_x_info () {
109     eval x=\$$1
110     if [ -z "$x" ]; then
111         eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" arch/$ARCH/defconfig`
112         eval x=\${$1:-\"$2\"}
113         eval $1=$x
114         eval INFO_$1="' (NEW)'"
115     fi
116     eval info=\"\$INFO_$1\"
117 }
118
119 #
120 # Load the functions used by the config.in files.
121 #
122 # I do this because these functions must be redefined depending
123 # on whether they are being called for interactive use or for
124 # saving a configuration to a file.
125 #
126 # Thank the heavens bash supports nesting function definitions.
127 #
128 load_functions () {
129
130 #
131 # Additional comments
132 #
133 function comment () {
134         comment_ctr=$[ comment_ctr + 1 ]
135         echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
136 }
137
138 #
139 # Define a boolean to a specific value.
140 #
141 function define_bool () {
142         eval $1=$2
143 }
144
145 function define_tristate () {
146         eval $1=$2
147 }
148
149 function define_hex () {
150         eval $1=$2
151 }
152
153 function define_int () {
154         eval $1=$2
155 }
156
157 function define_string () {
158         eval $1=\"$2\"
159 }
160
161 #
162 # Create a boolean (Yes/No) function for our current menu
163 # which calls our local bool function.
164 #
165 function bool () {
166         set_x_info "$2" "n"
167
168         case $x in
169         y|m)    flag="*" ;;
170         n)      flag=" " ;;
171         esac
172
173         echo -ne "'$2' '[$flag] $1$info' " >>MCmenu
174
175         echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists
176 }
177
178 #
179 # Create a tristate (Yes/No/Module) radiolist function
180 # which calls our local tristate function.
181 #
182 # Collapses to a boolean (Yes/No) if module support is disabled.
183 #
184 function tristate () {
185         if [ "$CONFIG_MODULES" != "y" ]
186         then
187                 bool "$1" "$2"
188         else
189                 set_x_info "$2" "n"
190         
191                 case $x in
192                 y) flag="*" ;;
193                 m) flag="M" ;;
194                 *) flag=" " ;;
195                 esac
196         
197                 echo -ne "'$2' '<$flag> $1$info' " >>MCmenu
198         
199                 echo -e "
200                 function $2 () { l_tristate '$2' \"\$1\" ;}" >>MCradiolists
201         fi
202 }
203
204 #
205 # Create a tristate radiolist function which is dependent on
206 # another kernel configuration option.
207 #
208 # Quote from the original configure script:
209 #
210 #       If the option we depend upon is a module,
211 #       then the only allowable options are M or N.  If Y, then
212 #       this is a normal tristate.  This is used in cases where modules
213 #       are nested, and one module requires the presence of something
214 #       else in the kernel.
215 #
216 function dep_tristate () {
217         ques="$1"
218         var="$2"
219         dep=y
220         shift 2
221         while [ $# -gt 0 ]; do
222                 if   [ "$1" = y ]; then
223                         shift
224                 elif [ "$1" = m ]; then
225                         dep=m
226                         shift
227                 else
228                         dep=n
229                         shift $#
230                 fi
231         done
232         if [ "$dep" = y ]; then
233             tristate "$ques" "$var"
234         elif [ "$dep" = m ]; then
235             mod_bool "$ques" "$var"
236         else 
237             define_tristate "$var" n
238         fi
239 }
240
241 #
242 #   Same as above, but now only Y and N are allowed as dependency
243 #   (i.e. third and next arguments).
244 #
245 function dep_bool () {
246         ques="$1"
247         var="$2"
248         dep=y
249         shift 2
250         while [ $# -gt 0 ]; do
251                 if [ "$1" = y ]; then
252                         shift
253                 else
254                         dep=n
255                         shift $#
256                 fi
257         done
258         if [ "$dep" = y ]; then
259             bool "$ques" "$var"
260         else 
261             define_bool "$var" n
262         fi
263 }
264
265 function dep_mbool () {
266         ques="$1"
267         var="$2"
268         dep=y
269         shift 2
270         while [ $# -gt 0 ]; do
271                 if [ "$1" = y -o "$1" = m ]; then
272                         shift
273                 else
274                         dep=n
275                         shift $#
276                 fi
277         done
278         if [ "$dep" = y ]; then
279             bool "$ques" "$var"
280         else 
281             define_bool "$var" n
282         fi
283 }
284
285 #
286 # Add a menu item which will call our local int function.
287
288 function int () {
289         set_x_info "$2" "$3"
290
291         echo -ne "'$2' '($x) $1$info' " >>MCmenu
292
293         echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists
294 }
295
296 #
297 # Add a menu item which will call our local hex function.
298
299 function hex () {
300         set_x_info "$2" "$3"
301         x=${x##*[x,X]}
302
303         echo -ne "'$2' '($x) $1$info' " >>MCmenu
304
305         echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists
306 }
307
308 #
309 # Add a menu item which will call our local string function.
310
311 function string () {
312         set_x_info "$2" "$3"
313
314         echo -ne "'$2' '     $1: \"$x\"$info' " >>MCmenu
315
316         echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists
317 }
318
319 #
320 # Add a menu item which will call our local One-of-Many choice list.
321 #
322 function choice () {
323         #
324         # Need to remember params cause they're gonna get reset.
325         #
326         title=$1
327         choices=$2
328         default=$3
329         current=
330
331         #
332         # Find out if one of the choices is already set.
333         # If it's not then make it the default.
334         #
335         set -- $choices
336         firstchoice=$2
337
338         while [ -n "$2" ]
339         do
340                 if eval [ \"_\$$2\" = \"_y\" ]
341                 then
342                         current=$1
343                         break
344                 fi
345                 shift ; shift
346         done
347
348         : ${current:=$default}
349
350         echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
351
352         echo -e "
353         function $firstchoice () \
354                 { l_choice '$title' \"$choices\" \"$current\" ;}" >>MCradiolists
355 }
356
357 } # END load_functions()
358
359
360
361
362
363 #
364 # Extract available help for an option from Configure.help
365 # and send it to standard output.
366 #
367 # Most of this function was borrowed from the original kernel
368 # Configure script.
369 #
370 function extract_help () {
371   if [ -f Documentation/Configure.help ]
372   then
373      #first escape regexp special characters in the argument:
374      var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
375      #now pick out the right help text:
376      text=$(sed -n "/^$var[     ]*\$/,\${
377                         /^$var[         ]*\$/c\\
378 ${var}:\\
379
380                         /^#/b
381                         /^[^    ]/q
382                         s/^  //
383                         /<file:\\([^>]*\\)>/s//\\1/g
384                         p
385                     }" Documentation/Configure.help)
386
387      if [ -z "$text" ]
388      then
389           echo "There is no help available for this kernel option."
390           return 1
391      else
392           echo "$text"
393      fi
394   else
395          echo "There is no help available for this kernel option."
396          return 1
397   fi
398 }
399
400 #
401 # Activate a help dialog.
402 #
403 function help () {
404         if extract_help $1 >help.out
405         then
406                 $DIALOG --backtitle "$backtitle" --title "$2"\
407                         --textbox help.out $ROWS $COLS
408         else
409                 $DIALOG --backtitle "$backtitle" \
410                         --textbox help.out $ROWS $COLS
411         fi
412         rm -f help.out
413 }
414
415 #
416 # Show the README file.
417 #
418 function show_readme () {
419         $DIALOG --backtitle "$backtitle" \
420                 --textbox scripts/README.Menuconfig $ROWS $COLS
421 }
422
423 #
424 # Begin building the dialog menu command and Initialize the 
425 # Radiolist function file.
426 #
427 function menu_name () {
428         echo -ne "$DIALOG --title '$1'\
429                         --backtitle '$backtitle' \
430                         --menu '$menu_instructions' \
431                         $ROWS $COLS $((ROWS-10)) \
432                         '$default' " >MCmenu
433         >MCradiolists
434 }
435
436 #
437 # Add a submenu option to the menu currently under construction.
438 #
439 function submenu () {
440         echo -ne "'activate_menu $2' '$1  --->' " >>MCmenu
441 }
442
443 #
444 # Handle a boolean (Yes/No) option.
445 #
446 function l_bool () {
447         if [ -n "$2" ]
448         then
449                 case "$2" in
450                 y|m)    eval $1=y ;;
451                 c)      eval x=\$$1
452                         case $x in
453                         y) eval $1=n ;;
454                         n) eval $1=y ;;
455                         *) eval $1=y ;;
456                         esac ;;
457                 *)      eval $1=n ;;
458                 esac
459         else
460                 echo -ne "\007"
461         fi
462 }
463
464 #
465 # Same as bool() except options are (Module/No)
466 #
467 function mod_bool () {
468         if [ "$CONFIG_MODULES" != "y" ]; then
469             define_bool "$2" "n"
470         else
471             set_x_info "$2" "n"
472  
473             case $x in
474             y|m) flag='M' ;;
475             *)   flag=' ' ;;
476             esac
477  
478             echo -ne "'$2' '<$flag> $1$info' " >>MCmenu
479  
480             echo -e "function $2 () { l_mod_bool '$2' \"\$1\" ;}" >>MCradiolists
481         fi
482 }
483
484 #
485 # Same as l_bool() except options are (Module/No)
486 #
487 function l_mod_bool() {
488         if [ -n "$2" ]
489         then
490                 case "$2" in
491                 y)      echo -en "\007"
492                         ${DIALOG} --backtitle "$backtitle" \
493                                   --infobox "\
494 This feature depends on another which has been configured as a module.  \
495 As a result, this feature will be built as a module." 4 70
496                         sleep 5
497                         eval $1=m ;;
498                 m)      eval $1=m ;;
499                 c)      eval x=\$$1
500                         case $x in
501                         m) eval $1=n ;;
502                         n) eval $1=m ;;
503                         *) eval $1=m ;;
504                         esac ;;
505                 *)      eval $1=n ;;
506                 esac
507         else
508                 echo -ne "\007"
509         fi
510 }
511
512 #
513 # Handle a tristate (Yes/No/Module) option.
514 #
515 function l_tristate () {
516         if [ -n "$2" ]
517         then
518                 eval x=\$$1
519
520                 case "$2" in
521                 y) eval $1=y ;;
522                 m) eval $1=m ;;
523                 c) eval x=\$$1
524                    case $x in
525                    y) eval $1=n ;;
526                    n) eval $1=m ;;
527                    m) eval $1=y ;;
528                    *) eval $1=y ;;
529                    esac ;;
530                 *) eval $1=n ;;
531                 esac
532         else
533                 echo -ne "\007"
534         fi
535 }
536
537 #
538 # Create a dialog for entering an integer into a kernel option.
539 #
540 function l_int () {
541         while true
542         do
543                 if $DIALOG --title "$1" \
544                         --backtitle "$backtitle" \
545                         --inputbox "$inputbox_instructions_int" \
546                         10 75 "$4" 2>MCdialog.out
547                 then
548                         answer="`cat MCdialog.out`"
549                         answer="${answer:-$3}"
550
551                         # Semantics of + and ? in GNU expr changed, so
552                         # we avoid them:
553                         if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null
554                         then
555                                 eval $2=\"$answer\"
556                         else
557                                 eval $2=\"$3\"
558                                 echo -en "\007"
559                                 ${DIALOG} --backtitle "$backtitle" \
560                                         --infobox "You have made an invalid entry." 3 43
561                                 sleep 2
562                         fi
563
564                         break
565                 fi
566
567                 help "$2" "$1"
568         done
569 }
570
571 #
572 # Create a dialog for entering a hexadecimal into a kernel option.
573 #
574 function l_hex () {
575         while true
576         do
577                 if $DIALOG --title "$1" \
578                         --backtitle "$backtitle" \
579                         --inputbox "$inputbox_instructions_hex" \
580                         10 75 "$4" 2>MCdialog.out
581                 then
582                         answer="`cat MCdialog.out`"
583                         answer="${answer:-$3}"
584                         answer="${answer##*[x,X]}"
585
586                         if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null
587                         then
588                                 eval $2=\"$answer\"
589                         else
590                                 eval $2=\"$3\"
591                                 echo -en "\007"
592                                 ${DIALOG} --backtitle "$backtitle" \
593                                         --infobox "You have made an invalid entry." 3 43
594                                 sleep 2
595                         fi
596
597                         break
598                 fi
599
600                 help "$2" "$1"
601         done
602 }
603
604 #
605 # Create a dialog for entering a string into a kernel option.
606 #
607 function l_string () {
608         while true
609         do
610                 if $DIALOG --title "$1" \
611                         --backtitle "$backtitle" \
612                         --inputbox "$inputbox_instructions_string" \
613                         10 75 "$4" 2>MCdialog.out
614                 then
615                         answer="`cat MCdialog.out`"
616                         answer="${answer:-$3}"
617
618                         #
619                         # Someone may add a nice check for the entered
620                         # string here...
621                         #
622                         eval $2=\"$answer\"
623
624                         break
625                 fi
626
627                 help "$2" "$1"
628         done
629 }
630
631
632 #
633 # Handle a one-of-many choice list.
634 #
635 function l_choice () {
636         #
637         # Need to remember params cause they're gonna get reset.
638         #
639         title="$1"
640         choices="$2"
641         current="$3"
642         chosen=
643
644         #
645         # Scan current value of choices and set radiolist switches.
646         #
647         list=
648         set -- $choices
649         firstchoice=$2
650         while [ -n "$2" ]
651         do
652                 case "$1" in
653                 "$current"*)    if [ -z "$chosen" ]; then
654                                         list="$list $2 $1 ON "
655                                         chosen=1
656                                 else
657                                         list="$list $2 $1 OFF "
658                                 fi  ;;
659                 *)              list="$list $2 $1 OFF " ;;
660                 esac
661                         
662                 shift ; shift
663         done
664
665         while true
666         do
667                 if $DIALOG --title "$title" \
668                         --backtitle "$backtitle" \
669                         --radiolist "$radiolist_instructions" \
670                         15 70 6 $list 2>MCdialog.out
671                 then
672                         choice=`cat MCdialog.out`
673                         break
674                 fi
675
676                 help "$firstchoice" "$title"
677         done
678
679         #
680         # Now set the boolean value of each option based on
681         # the selection made from the radiolist.
682         #
683         set -- $choices
684         while [ -n "$2" ]
685         do
686                 if [ "$2" = "$choice" ]
687                 then
688                         eval $2=\"y\"
689                 else
690                         eval $2=\"n\"
691                 fi
692                 
693                 shift ; shift
694         done
695 }
696
697 #
698 # Call awk, and watch for error codes, etc.
699 #
700 function callawk () {
701 awk "$1" || { echo "Awk died with error code $?. Giving up."; exit 1; }
702 }
703
704 #
705 # A faster awk based recursive parser. (I hope)
706 #
707 function parser1 () {
708 callawk '
709 BEGIN {
710         menu_no = 0
711         comment_is_option = 0
712         parser("'$CONFIG_IN'","MCmenu0")
713 }
714
715 function parser(ifile,menu) {
716
717         while ((getline <ifile) > 0) {
718                 if ($1 == "mainmenu_option") {
719                         comment_is_option = "1"
720                 }
721                 else if ($1 == "comment" && comment_is_option == "1") {
722                         comment_is_option= "0"
723                         sub($1,"",$0)
724                         ++menu_no
725
726                         printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu
727
728                         newmenu = sprintf("MCmenu%d", menu_no);
729                         printf( "function MCmenu%s () {\n"\
730                                 "default=$1\n"\
731                                 "menu_name %s\n",\
732                                  menu_no, $0) >newmenu
733
734                         parser(ifile, newmenu)
735                 }
736                 else if ($0 ~ /^#|\$MAKE|mainmenu_name/) {
737                         printf("") >>menu
738                 }
739                 else if ($1 ~ "endmenu") {
740                         printf("}\n") >>menu
741                         return
742                 } 
743                 else if ($1 == "source") {
744                         parser($2,menu)
745                 }
746                 else {
747                         print >>menu
748                 }
749         }
750 }'
751 }
752
753 #
754 # Secondary parser for single menu mode.
755 #
756 function parser2 () {
757 callawk '
758 BEGIN {
759         parser("'$CONFIG_IN'","MCmenu0")
760 }
761
762 function parser(ifile,menu) {
763
764         while ((getline <ifile) > 0) {
765                 if ($0 ~ /^#|$MAKE|mainmenu_name/) {
766                         printf("") >>menu
767                 }
768                 else if ($1 ~ /mainmenu_option|endmenu/) {
769                         printf("") >>menu
770                 } 
771                 else if ($1 == "source") {
772                         parser($2,menu)
773                 }
774                 else {
775                         print >>menu
776                 }
777         }
778 }'
779 }
780
781 #
782 # Parse all the config.in files into mini scripts.
783 #
784 function parse_config_files () {
785         rm -f MCmenu*
786
787         echo "function MCmenu0 () {" >MCmenu0
788         echo 'default=$1' >>MCmenu0
789         echo "menu_name 'Main Menu'" >>MCmenu0
790
791         if [ "_$single_menu_mode" = "_TRUE" ]
792         then
793                 parser2
794         else
795                 parser1
796         fi
797
798         echo "comment ''"       >>MCmenu0
799         echo "g_alt_config"     >>MCmenu0
800         echo "s_alt_config"     >>MCmenu0
801
802         echo "}" >>MCmenu0
803
804         #
805         # These mini scripts must be sourced into the current
806         # environment in order for all of this to work.  Leaving
807         # them on the disk as executables screws up the recursion
808         # in activate_menu(), among other things.  Once they are
809         # sourced we can discard them.
810         #
811         for i in MCmenu*
812         do
813                 echo -n "."
814                 source ./$i
815         done
816         rm -f MCmenu*
817 }
818
819 #
820 # This is the menu tree's bootstrap.
821 #
822 # Executes the parsed menus on demand and creates a set of functions,
823 # one per configuration option.  These functions will in turn execute
824 # dialog commands or recursively call other menus.
825 #
826 function activate_menu () {
827         rm -f lxdialog.scrltmp
828         while true
829         do
830                 comment_ctr=0           #So comment lines get unique tags
831
832                 $1 "$default" 2> MCerror #Create the lxdialog menu & functions
833
834                 if [ "$?" != "0" ]
835                 then
836                         clear
837                         cat <<EOM
838
839 Menuconfig has encountered a possible error in one of the kernel's
840 configuration files and is unable to continue.  Here is the error
841 report:
842
843 EOM
844                         sed 's/^/ Q> /' MCerror
845                         cat <<EOM
846
847 Please report this to the maintainer <mec@shout.net>.  You may also
848 send a problem report to <linux-kernel@vger.kernel.org>.
849
850 Please indicate the kernel version you are trying to configure and
851 which menu you were trying to enter when this error occurred.
852
853 EOM
854                         cleanup
855                         exit 1
856                 fi
857                 rm -f MCerror
858
859                 . ./MCradiolists                #Source the menu's functions
860
861                 . ./MCmenu 2>MCdialog.out       #Activate the lxdialog menu
862                 ret=$?
863
864                 read selection <MCdialog.out
865
866                 case "$ret" in
867                 0|3|4|5|6)
868                         defaults="$selection\12$defaults"  #pseudo stack
869                         case "$ret" in
870                         0) eval $selection   ;;
871                         3) eval $selection y ;;
872                         4) eval $selection n ;;
873                         5) eval $selection m ;;
874                         6) eval $selection c ;;
875                         esac
876                         default="${defaults%%\12*}" defaults="${defaults#*\12}"
877                         ;;
878                 2)      
879                         default="${selection%%\ *}"
880
881                         case "$selection" in
882                         *"-->"*|*"alt_config"*)
883                                 show_readme ;;
884                         *)
885                                 eval help $selection ;;
886                         esac
887                         ;;
888                 255|1)
889                         break
890                         ;;
891                 139)
892                         stty sane
893                         clear
894                         cat <<EOM
895
896 There seems to be a problem with the lxdialog companion utility which is
897 built prior to running Menuconfig.  Usually this is an indicator that you
898 have upgraded/downgraded your ncurses libraries and did not remove the 
899 old ncurses header file(s) in /usr/include or /usr/include/ncurses.
900
901 It is VERY important that you have only one set of ncurses header files
902 and that those files are properly version matched to the ncurses libraries 
903 installed on your machine.
904
905 You may also need to rebuild lxdialog.  This can be done by moving to
906 the /usr/src/linux/scripts/lxdialog directory and issuing the 
907 "make clean all" command.
908
909 If you have verified that your ncurses install is correct, you may email
910 the maintainer <mec@shout.net> or post a message to
911 <linux-kernel@vger.kernel.org> for additional assistance. 
912
913 EOM
914                         cleanup
915                         exit 139
916                         ;;
917                 esac
918         done
919 }
920
921 #
922 # Create a menu item to load an alternate configuration file.
923 #
924 g_alt_config () {
925         echo -n "get_alt_config 'Load an Alternate Configuration File' "\
926                 >>MCmenu
927 }
928
929 #
930 # Get alternate config file name and load the 
931 # configuration from it.
932 #
933 get_alt_config () {
934         set -f ## Switch file expansion OFF
935
936         while true
937         do
938                 ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}"
939
940                 $DIALOG --backtitle "$backtitle" \
941                         --inputbox "\
942 Enter the name of the configuration file you wish to load.  \
943 Accept the name shown to restore the configuration you \
944 last retrieved.  Leave blank to abort."\
945                         11 55 "$ALT_CONFIG" 2>MCdialog.out
946
947                 if [ "$?" = "0" ]
948                 then
949                         ALT_CONFIG=`cat MCdialog.out`
950
951                         [ "_" = "_$ALT_CONFIG" ] && break
952
953                         if eval [ -r \"$ALT_CONFIG\" ]
954                         then
955                                 eval load_config_file \"$ALT_CONFIG\"
956                                 break
957                         else
958                                 echo -ne "\007"
959                                 $DIALOG --backtitle "$backtitle" \
960                                         --infobox "File does not exist!"  3 38
961                                 sleep 2
962                         fi
963                 else
964                         cat <<EOM >help.out
965
966 For various reasons, one may wish to keep several different kernel
967 configurations available on a single machine.  
968
969 If you have saved a previous configuration in a file other than the
970 kernel's default, entering the name of the file here will allow you
971 to modify that configuration.
972
973 If you are uncertain, then you have probably never used alternate 
974 configuration files.  You should therefor leave this blank to abort.
975
976 EOM
977                         $DIALOG --backtitle "$backtitle"\
978                                 --title "Load Alternate Configuration"\
979                                 --textbox help.out $ROWS $COLS
980                 fi
981         done
982
983         set +f ## Switch file expansion ON
984         rm -f help.out MCdialog.out
985 }
986
987 #
988 # Create a menu item to store an alternate config file.
989 #
990 s_alt_config () {
991         echo -n "save_alt_config 'Save Configuration to an Alternate File' "\
992                  >>MCmenu
993 }
994
995 #
996 # Get an alternate config file name and save the current
997 # configuration to it.
998 #
999 save_alt_config () {
1000         set -f  ## Switch file expansion OFF
1001                         
1002         while true
1003         do
1004                 $DIALOG --backtitle "$backtitle" \
1005                         --inputbox "\
1006 Enter a filename to which this configuration should be saved \
1007 as an alternate.  Leave blank to abort."\
1008                         10 55 "$ALT_CONFIG" 2>MCdialog.out
1009
1010                 if [ "$?" = "0" ]
1011                 then
1012                         ALT_CONFIG=`cat MCdialog.out`
1013
1014                         [ "_" = "_$ALT_CONFIG" ] && break
1015
1016                         if eval touch $ALT_CONFIG 2>/dev/null
1017                         then
1018                                 eval save_configuration $ALT_CONFIG
1019                                 load_functions  ## RELOAD
1020                                 break
1021                         else
1022                                 echo -ne "\007"
1023                                 $DIALOG --backtitle "$backtitle" \
1024                                         --infobox "Can't create file!  Probably a nonexistent directory." 3 60
1025                                 sleep 2
1026                         fi
1027                 else
1028                         cat <<EOM >help.out
1029
1030 For various reasons, one may wish to keep different kernel
1031 configurations available on a single machine.  
1032
1033 Entering a file name here will allow you to later retrieve, modify
1034 and use the current configuration as an alternate to whatever 
1035 configuration options you have selected at that time.
1036
1037 If you are uncertain what all this means then you should probably
1038 leave this blank.
1039 EOM
1040                         $DIALOG --backtitle "$backtitle"\
1041                                 --title "Save Alternate Configuration"\
1042                                 --textbox help.out $ROWS $COLS
1043                 fi
1044         done
1045
1046         set +f  ## Switch file expansion ON
1047         rm -f help.out MCdialog.out
1048 }
1049
1050 #
1051 # Load config options from a file.
1052 # Converts all "# OPTION is not set" lines to "OPTION=n" lines
1053 #
1054 function load_config_file () {
1055         awk '
1056           /# .* is not set.*/ { printf("%s=n\n", $2) }
1057         ! /# .* is not set.*/ { print }
1058         ' $1 >.tmpconfig
1059
1060         source ./.tmpconfig
1061         rm -f .tmpconfig
1062 }
1063
1064 #
1065 # Just what it says.
1066 #
1067 save_configuration () {
1068         echo
1069         echo -n "Saving your kernel configuration."
1070
1071         #
1072         # Now, let's redefine the configuration functions for final
1073         # output to the config files.
1074         #
1075         # Nested function definitions, YIPEE!
1076         #
1077         function bool () {
1078                 set_x_info "$2" "n"
1079                 eval define_bool \"$2\" \"$x\"
1080         }
1081
1082         function tristate () {
1083                 set_x_info "$2" "n"
1084                 eval define_tristate \"$2\" \"$x\"
1085         }
1086
1087         function dep_tristate () {
1088                 set_x_info "$2" "n"
1089                 var="$2"
1090                 shift 2
1091                 while [ $# -gt 0 ]; do
1092                         if   [ "$1" = y ]; then
1093                                 shift
1094                         elif [ "$1" = m -a "$x" != n ]; then
1095                                 x=m; shift
1096                         else 
1097                                 x=n; shift $#
1098                         fi
1099                 done
1100                 define_tristate "$var" "$x"
1101         }
1102
1103         function dep_bool () {
1104                 set_x_info "$2" "n"
1105                 var="$2"
1106                 shift 2
1107                 while [ $# -gt 0 ]; do
1108                         if   [ "$1" = y ]; then
1109                                 shift
1110                         else 
1111                                 x=n; shift $#
1112                         fi
1113                 done
1114                 define_bool "$var" "$x"
1115         }
1116
1117         function dep_mbool () {
1118                 set_x_info "$2" "n"
1119                 var="$2"
1120                 shift 2
1121                 while [ $# -gt 0 ]; do
1122                         if   [ "$1" = y -o "$1" = m ]; then
1123                                 shift
1124                         else 
1125                                 x=n; shift $#
1126                         fi
1127                 done
1128                 define_bool "$var" "$x"
1129         }
1130
1131         function int () {
1132                 set_x_info "$2" "$3"
1133                 echo "$2=$x"            >>$CONFIG
1134                 echo "#define $2 ($x)"  >>$CONFIG_H
1135         }
1136
1137         function hex () {
1138                 set_x_info "$2" "$3"
1139                 echo "$2=$x"                     >>$CONFIG
1140                 echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H
1141         }
1142
1143         function string () {
1144                 set_x_info "$2" "$3"
1145                 echo "$2=\"$x\""                         >>$CONFIG
1146                 echo "#define $2 \"$x\""        >>$CONFIG_H
1147         }
1148
1149         function define_hex () {
1150                 eval $1=\"$2\"
1151                 echo "$1=$2"                    >>$CONFIG
1152                 echo "#define $1 0x${2##*[x,X]}"        >>$CONFIG_H
1153         }
1154
1155         function define_int () {
1156                 eval $1=\"$2\"
1157                 echo "$1=$2"                    >>$CONFIG
1158                 echo "#define $1 ($2)"          >>$CONFIG_H
1159         }
1160
1161         function define_string () {
1162                 eval $1=\"$2\"
1163                 echo "$1=\"$2\""                >>$CONFIG
1164                 echo "#define $1 \"$2\""        >>$CONFIG_H
1165         }
1166
1167         function define_bool () {
1168                 define_tristate "$1" "$2"
1169         }
1170
1171         function define_tristate () {
1172                 eval $1=\"$2\"
1173
1174                 case "$2" in
1175                 y)
1176                         echo "$1=y"             >>$CONFIG
1177                         echo "#define $1 1"     >>$CONFIG_H
1178                         ;;
1179
1180                 m)
1181                         if [ "$CONFIG_MODULES" = "y" ]
1182                         then
1183                                 echo "$1=m"                >>$CONFIG
1184                                 echo "#undef  $1"          >>$CONFIG_H
1185                                 echo "#define $1_MODULE 1" >>$CONFIG_H
1186                         else
1187                                 echo "$1=y"             >>$CONFIG
1188                                 echo "#define $1 1"     >>$CONFIG_H
1189                         fi
1190                         ;;
1191
1192                 n)
1193                         echo "# $1 is not set"  >>$CONFIG
1194                         echo "#undef  $1"       >>$CONFIG_H
1195                         ;;
1196                 esac
1197         }
1198
1199         function choice () {
1200                 #
1201                 # Find the first choice that's already set to 'y'
1202                 #
1203                 choices="$2"
1204                 default="$3"
1205                 current=
1206                 chosen=
1207
1208                 set -- $choices
1209                 while [ -n "$2" ]
1210                 do
1211                         if eval [ \"_\$$2\" = \"_y\" ]
1212                         then
1213                                 current=$1
1214                                 break
1215                         fi
1216                         shift ; shift
1217                 done
1218
1219                 #
1220                 # Use the default if none were set.  
1221                 #
1222                 : ${current:=$default}
1223
1224                 #
1225                 # Output all choices (to be compatible with other configs).
1226                 #
1227                 set -- $choices
1228                 while [ -n "$2" ]
1229                 do
1230                         case "$1" in
1231                         "$current"*)    if [ -z "$chosen" ]; then
1232                                                 define_bool "$2" "y"
1233                                                 chosen=1
1234                                         else
1235                                                 define_bool "$2" "n"
1236                                         fi ;;
1237                         *)              define_bool "$2" "n" ;;
1238                         esac
1239                         shift ; shift
1240                 done
1241         }
1242
1243         function mainmenu_name () {
1244                 :
1245         }
1246
1247         function mainmenu_option () {
1248                 comment_is_option=TRUE
1249         }
1250
1251         function endmenu () {
1252                 :
1253         }
1254
1255         function comment () {
1256                 if [ "$comment_is_option" ]
1257                 then
1258                         comment_is_option=
1259                         echo        >>$CONFIG
1260                         echo "#"    >>$CONFIG
1261                         echo "# $1" >>$CONFIG
1262                         echo "#"    >>$CONFIG
1263
1264                         echo         >>$CONFIG_H
1265                         echo "/*"    >>$CONFIG_H
1266                         echo " * $1" >>$CONFIG_H
1267                         echo " */"   >>$CONFIG_H
1268                 fi
1269         }
1270
1271         echo -n "."
1272
1273         DEF_CONFIG="${1:-.config}"
1274         DEF_CONFIG_H="include/linux/autoconf.h"
1275
1276         CONFIG=.tmpconfig
1277         CONFIG_H=.tmpconfig.h
1278
1279         echo "#" >$CONFIG
1280         echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG
1281         echo "#" >>$CONFIG
1282
1283         echo "/*" >$CONFIG_H
1284         echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H
1285         echo " */" >>$CONFIG_H
1286         echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H
1287
1288         echo -n "."
1289         if . $CONFIG_IN >>.menuconfig.log 2>&1
1290         then
1291                 if [ "$DEF_CONFIG" = ".config" ]
1292                 then
1293                         mv $CONFIG_H $DEF_CONFIG_H
1294                 fi
1295
1296                 if [ -f "$DEF_CONFIG" ]
1297                 then
1298                         rm -f ${DEF_CONFIG}.old
1299                         mv $DEF_CONFIG ${DEF_CONFIG}.old
1300                 fi
1301
1302                 mv $CONFIG $DEF_CONFIG
1303                         
1304                 return 0
1305         else
1306                 return 1
1307         fi
1308 }
1309
1310 #
1311 # Remove temporary files
1312 #
1313 cleanup () {
1314         cleanup1
1315         cleanup2
1316 }
1317
1318 cleanup1 () {
1319         rm -f MCmenu* MCradiolists MCdialog.out help.out
1320 }
1321
1322 cleanup2 () {
1323         rm -f .tmpconfig .tmpconfig.h
1324 }
1325
1326 set_geometry () {
1327         # Some distributions export these with incorrect values
1328         # which can really screw up some ncurses programs.
1329         LINES=  COLUMNS=
1330
1331         ROWS=${1:-24}  COLS=${2:-80} 
1332
1333         # Just in case the nasty rlogin bug returns.
1334         #
1335         [ $ROWS = 0 ] && ROWS=24
1336         [ $COLS = 0 ] && COLS=80
1337
1338         if [ $ROWS -lt 19 -o $COLS -lt 80 ]
1339         then
1340                 echo -e "\n\007Your display is too small to run Menuconfig!"
1341                 echo "It must be at least 19 lines by 80 columns."
1342                 exit 1
1343         fi 
1344
1345         ROWS=$((ROWS-4))  COLS=$((COLS-5))
1346 }
1347
1348
1349 set_geometry `stty size 2>/dev/null`
1350
1351 menu_instructions="\
1352 Arrow keys navigate the menu.  \
1353 <Enter> selects submenus --->.  \
1354 Highlighted letters are hotkeys.  \
1355 Pressing <Y> includes, <N> excludes, <M> modularizes features.  \
1356 Press <Esc><Esc> to exit, <?> for Help.  \
1357 Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"
1358
1359 radiolist_instructions="\
1360 Use the arrow keys to navigate this window or \
1361 press the hotkey of the item you wish to select \
1362 followed by the <SPACE BAR>.
1363 Press <?> for additional information about this option."
1364
1365 inputbox_instructions_int="\
1366 Please enter a decimal value. \
1367 Fractions will not be accepted.  \
1368 Use the <TAB> key to move from the input field to the buttons below it."
1369
1370 inputbox_instructions_hex="\
1371 Please enter a hexadecimal value. \
1372 Use the <TAB> key to move from the input field to the buttons below it."
1373
1374 inputbox_instructions_string="\
1375 Please enter a string value. \
1376 Use the <TAB> key to move from the input field to the buttons below it."
1377
1378 DIALOG="./scripts/lxdialog/lxdialog"
1379
1380 kernel_version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}"
1381
1382 backtitle="Linux Kernel v$kernel_version Configuration"
1383
1384 trap "cleanup ; exit 1" 1 2 15
1385
1386
1387 #
1388 # Locate default files.
1389 #
1390 CONFIG_IN=./config.in
1391 if [ "$1" != "" ] ; then
1392         CONFIG_IN=$1
1393 fi
1394
1395 DEFAULTS=arch/$ARCH/defconfig
1396 if [ -f .config ]; then
1397   DEFAULTS=.config
1398 fi
1399
1400 if [ -f $DEFAULTS ]
1401 then
1402   echo "Using defaults found in" $DEFAULTS
1403   load_config_file $DEFAULTS
1404 else
1405   echo "No defaults found"
1406 fi
1407
1408
1409 # Fresh new log.
1410 >.menuconfig.log
1411
1412 # Load the functions used by the config.in files.
1413 echo -n "Preparing scripts: functions" 
1414 load_functions
1415
1416 if [ ! -e $CONFIG_IN ]
1417 then
1418         echo "Your main config.in file ($CONFIG_IN) does not exist"
1419         exit 1
1420 fi
1421
1422 if [ ! -x $DIALOG ]
1423 then
1424         echo "Your lxdialog utility does not exist"
1425         exit 1
1426 fi
1427
1428 #
1429 # Read config.in files and parse them into one shell function per menu.
1430 #
1431 echo -n ", parsing"
1432 parse_config_files $CONFIG_IN
1433
1434 echo "done."
1435 #
1436 # Start the ball rolling from the top.
1437 #
1438 activate_menu MCmenu0
1439
1440 #
1441 # All done!
1442 #
1443 cleanup1
1444
1445 #
1446 # Confirm and Save
1447 #
1448 if $DIALOG --backtitle "$backtitle" \
1449            --yesno "Do you wish to save your new kernel configuration?" 5 60
1450 then
1451         save_configuration
1452         echo
1453         echo
1454         echo "*** End of Linux kernel configuration."
1455         echo "*** Check the top-level Makefile for additional configuration."
1456         if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
1457             echo "*** Next, you must run 'make dep'."
1458         else
1459             echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'."
1460         fi
1461         echo
1462 else
1463         echo
1464         echo 
1465         echo Your kernel configuration changes were NOT saved.
1466         echo
1467 fi
1468
1469 # Remove log if empty.
1470 if [ ! -s .menuconfig.log ] ; then
1471         rm -f .menuconfig.log
1472 fi
1473
1474 exit 0