Eric Andersen | bdfd0d7 | 2001-10-24 05:00:29 +0000 | [diff] [blame] | 1 | #! /bin/sh |
| 2 | # |
| 3 | # This script is used to configure BusyBox. |
| 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 <rhw@memalpha.cx> |
| 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 | # 22 October 2001, Erik Andersen <andersee@debian.org> |
| 78 | # - Adjusted for busybox (modified hard coded kernel specific paths, |
| 79 | # and everything to do with modules (tristates, modbools, etc). |
| 80 | |
| 81 | |
| 82 | # |
| 83 | # Change this to TRUE if you prefer all options listed |
| 84 | # in a single menu rather than the standard menu hierarchy. |
| 85 | # |
| 86 | single_menu_mode= |
| 87 | |
| 88 | # |
| 89 | # Make sure we're really running bash. |
| 90 | # |
| 91 | [ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; } |
| 92 | |
| 93 | # |
| 94 | # Cache function definitions, turn off posix compliance |
| 95 | # |
| 96 | set -h +o posix |
| 97 | |
| 98 | |
| 99 | |
| 100 | # Given a configuration variable, set the global variable $x to its value, |
| 101 | # and the global variable $info to the string " (NEW)" if this is a new |
| 102 | # variable. |
| 103 | # |
| 104 | # This function looks for: (1) the current value, or (2) the default value |
| 105 | # from the arch-dependent defconfig file, or (3) a default passed by the caller. |
| 106 | |
| 107 | function set_x_info () { |
| 108 | eval x=\$$1 |
| 109 | if [ -z "$x" ]; then |
| 110 | eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" sysdeps/$TARGET_OS/defconfig` |
| 111 | eval x=\${$1:-"$2"} |
| 112 | eval $1=$x |
| 113 | eval INFO_$1="' (NEW)'" |
| 114 | fi |
| 115 | eval info="\$INFO_$1" |
| 116 | } |
| 117 | |
| 118 | # |
| 119 | # Load the functions used by the config.in files. |
| 120 | # |
| 121 | # I do this because these functions must be redefined depending |
| 122 | # on whether they are being called for interactive use or for |
| 123 | # saving a configuration to a file. |
| 124 | # |
| 125 | # Thank the heavens bash supports nesting function definitions. |
| 126 | # |
| 127 | load_functions () { |
| 128 | |
| 129 | # |
| 130 | # Additional comments |
| 131 | # |
| 132 | function comment () { |
| 133 | comment_ctr=$[ comment_ctr + 1 ] |
| 134 | echo -ne "': $comment_ctr' '--- $1' " >>MCmenu |
| 135 | } |
| 136 | |
| 137 | # |
| 138 | # Define a boolean to a specific value. |
| 139 | # |
| 140 | function define_bool () { |
| 141 | eval $1=$2 |
| 142 | } |
| 143 | |
| 144 | function define_hex () { |
| 145 | eval $1=$2 |
| 146 | } |
| 147 | |
| 148 | function define_int () { |
| 149 | eval $1=$2 |
| 150 | } |
| 151 | |
| 152 | function define_string () { |
| 153 | eval $1="$2" |
| 154 | } |
| 155 | |
| 156 | # |
| 157 | # Create a boolean (Yes/No) function for our current menu |
| 158 | # which calls our local bool function. |
| 159 | # |
| 160 | function bool () { |
| 161 | set_x_info "$2" "n" |
| 162 | |
| 163 | case $x in |
| 164 | y|m) flag="*" ;; |
| 165 | n) flag=" " ;; |
| 166 | esac |
| 167 | |
| 168 | echo -ne "'$2' '[$flag] $1$info' " >>MCmenu |
| 169 | |
| 170 | echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists |
| 171 | } |
| 172 | |
| 173 | # |
| 174 | # Same as above, but now only Y and N are allowed as dependency |
| 175 | # (i.e. third and next arguments). |
| 176 | # |
| 177 | function dep_bool () { |
| 178 | ques="$1" |
| 179 | var="$2" |
| 180 | dep=y |
| 181 | shift 2 |
| 182 | while [ $# -gt 0 ]; do |
| 183 | if [ "$1" = y ]; then |
| 184 | shift |
| 185 | else |
| 186 | dep=n |
| 187 | shift $# |
| 188 | fi |
| 189 | done |
| 190 | if [ "$dep" = y ]; then |
| 191 | bool "$ques" "$var" |
| 192 | else |
| 193 | define_bool "$var" n |
| 194 | fi |
| 195 | } |
| 196 | |
| 197 | function dep_mbool () { |
| 198 | ques="$1" |
| 199 | var="$2" |
| 200 | dep=y |
| 201 | shift 2 |
| 202 | while [ $# -gt 0 ]; do |
| 203 | if [ "$1" = y -o "$1" = m ]; then |
| 204 | shift |
| 205 | else |
| 206 | dep=n |
| 207 | shift $# |
| 208 | fi |
| 209 | done |
| 210 | if [ "$dep" = y ]; then |
| 211 | bool "$ques" "$var" |
| 212 | else |
| 213 | define_bool "$var" n |
| 214 | fi |
| 215 | } |
| 216 | |
| 217 | # |
| 218 | # Add a menu item which will call our local int function. |
| 219 | # |
| 220 | function int () { |
| 221 | set_x_info "$2" "$3" |
| 222 | |
| 223 | echo -ne "'$2' '($x) $1$info' " >>MCmenu |
| 224 | |
| 225 | echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists |
| 226 | } |
| 227 | |
| 228 | # |
| 229 | # Add a menu item which will call our local hex function. |
| 230 | # |
| 231 | function hex () { |
| 232 | set_x_info "$2" "$3" |
| 233 | x=${x##*[x,X]} |
| 234 | |
| 235 | echo -ne "'$2' '($x) $1$info' " >>MCmenu |
| 236 | |
| 237 | echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists |
| 238 | } |
| 239 | |
| 240 | # |
| 241 | # Add a menu item which will call our local string function. |
| 242 | # |
| 243 | function string () { |
| 244 | set_x_info "$2" "$3" |
| 245 | |
| 246 | echo -ne "'$2' ' $1: \"$x\"$info' " >>MCmenu |
| 247 | |
| 248 | echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists |
| 249 | } |
| 250 | |
| 251 | # |
| 252 | # Add a menu item which will call our local One-of-Many choice list. |
| 253 | # |
| 254 | function choice () { |
| 255 | # |
| 256 | # Need to remember params cause they're gonna get reset. |
| 257 | # |
| 258 | title=$1 |
| 259 | choices=$2 |
| 260 | default=$3 |
| 261 | current= |
| 262 | |
| 263 | # |
| 264 | # Find out if one of the choices is already set. |
| 265 | # If it's not then make it the default. |
| 266 | # |
| 267 | set -- $choices |
| 268 | firstchoice=$2 |
| 269 | |
| 270 | while [ -n "$2" ] |
| 271 | do |
| 272 | if eval [ "_\$$2" = "_y" ] |
| 273 | then |
| 274 | current=$1 |
| 275 | break |
| 276 | fi |
| 277 | shift ; shift |
| 278 | done |
| 279 | |
| 280 | : ${current:=$default} |
| 281 | |
| 282 | echo -ne "'$firstchoice' '($current) $title' " >>MCmenu |
| 283 | |
| 284 | echo -e " |
| 285 | function $firstchoice () \ |
| 286 | { l_choice '$title' \"$choices\" \"$current\" ;}" >>MCradiolists |
| 287 | } |
| 288 | |
| 289 | } # END load_functions() |
| 290 | |
| 291 | |
| 292 | |
| 293 | |
| 294 | |
| 295 | # |
| 296 | # Extract available help for an option from Configure.help |
| 297 | # and send it to standard output. |
| 298 | # |
| 299 | # Most of this function was borrowed from the original kernel |
| 300 | # Configure script. |
| 301 | # |
| 302 | function extract_help () { |
| 303 | if [ -f docs/Configure.help ] |
| 304 | then |
| 305 | #first escape regexp special characters in the argument: |
| 306 | var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g') |
| 307 | #now pick out the right help text: |
| 308 | text=$(sed -n "/^$var[ ]*\$/,\${ |
| 309 | /^$var[ ]*\$/c\\ |
| 310 | ${var}:\\ |
| 311 | |
| 312 | /^#/b |
| 313 | /^[^ ]/q |
| 314 | s/^ // |
| 315 | /<file:\\([^>]*\\)>/s//\\1/g |
| 316 | p |
| 317 | }" docs/Configure.help) |
| 318 | |
| 319 | if [ -z "$text" ] |
| 320 | then |
| 321 | echo "There is no help available for this option." |
| 322 | return 1 |
| 323 | else |
| 324 | echo "$text" |
| 325 | fi |
| 326 | else |
| 327 | echo "There is no help available for this option." |
| 328 | return 1 |
| 329 | fi |
| 330 | } |
| 331 | |
| 332 | # |
| 333 | # Activate a help dialog. |
| 334 | # |
| 335 | function help () { |
| 336 | if extract_help $1 >help.out |
| 337 | then |
| 338 | $DIALOG --backtitle "$backtitle" --title "$2"\ |
| 339 | --textbox help.out $ROWS $COLS |
| 340 | else |
| 341 | $DIALOG --backtitle "$backtitle" \ |
| 342 | --textbox help.out $ROWS $COLS |
| 343 | fi |
| 344 | rm -f help.out |
| 345 | } |
| 346 | |
| 347 | # |
| 348 | # Show the README file. |
| 349 | # |
| 350 | function show_readme () { |
| 351 | $DIALOG --backtitle "$backtitle" \ |
| 352 | --textbox scripts/README.Menuconfig $ROWS $COLS |
| 353 | } |
| 354 | |
| 355 | # |
| 356 | # Begin building the dialog menu command and Initialize the |
| 357 | # Radiolist function file. |
| 358 | # |
| 359 | function menu_name () { |
| 360 | echo -ne "$DIALOG --title '$1'\ |
| 361 | --backtitle '$backtitle' \ |
| 362 | --menu '$menu_instructions' \ |
| 363 | $ROWS $COLS $((ROWS-10)) \ |
| 364 | '$default' " >MCmenu |
| 365 | >MCradiolists |
| 366 | } |
| 367 | |
| 368 | # |
| 369 | # Add a submenu option to the menu currently under construction. |
| 370 | # |
| 371 | function submenu () { |
| 372 | echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu |
| 373 | } |
| 374 | |
| 375 | # |
| 376 | # Handle a boolean (Yes/No) option. |
| 377 | # |
| 378 | function l_bool () { |
| 379 | if [ -n "$2" ] |
| 380 | then |
| 381 | case "$2" in |
| 382 | y|m) eval $1=y ;; |
| 383 | c) eval x=\$$1 |
| 384 | case $x in |
| 385 | y) eval $1=n ;; |
| 386 | n) eval $1=y ;; |
| 387 | *) eval $1=y ;; |
| 388 | esac ;; |
| 389 | *) eval $1=n ;; |
| 390 | esac |
| 391 | else |
| 392 | echo -ne "\007" |
| 393 | fi |
| 394 | } |
| 395 | |
| 396 | # |
| 397 | # Create a dialog for entering an integer into a option. |
| 398 | # |
| 399 | function l_int () { |
| 400 | while true |
| 401 | do |
| 402 | if $DIALOG --title "$1" \ |
| 403 | --backtitle "$backtitle" \ |
| 404 | --inputbox "$inputbox_instructions_int" \ |
| 405 | 10 75 "$4" 2>MCdialog.out |
| 406 | then |
| 407 | answer="`cat MCdialog.out`" |
| 408 | answer="${answer:-$3}" |
| 409 | |
| 410 | # Semantics of + and ? in GNU expr changed, so |
| 411 | # we avoid them: |
| 412 | if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null |
| 413 | then |
| 414 | eval $2="$answer" |
| 415 | else |
| 416 | eval $2="$3" |
| 417 | echo -en "\007" |
| 418 | ${DIALOG} --backtitle "$backtitle" \ |
| 419 | --infobox "You have made an invalid entry." 3 43 |
| 420 | sleep 2 |
| 421 | fi |
| 422 | |
| 423 | break |
| 424 | fi |
| 425 | |
| 426 | help "$2" "$1" |
| 427 | done |
| 428 | } |
| 429 | |
| 430 | # |
| 431 | # Create a dialog for entering a hexadecimal into an option. |
| 432 | # |
| 433 | function l_hex () { |
| 434 | while true |
| 435 | do |
| 436 | if $DIALOG --title "$1" \ |
| 437 | --backtitle "$backtitle" \ |
| 438 | --inputbox "$inputbox_instructions_hex" \ |
| 439 | 10 75 "$4" 2>MCdialog.out |
| 440 | then |
| 441 | answer="`cat MCdialog.out`" |
| 442 | answer="${answer:-$3}" |
| 443 | answer="${answer##*[x,X]}" |
| 444 | |
| 445 | if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null |
| 446 | then |
| 447 | eval $2="$answer" |
| 448 | else |
| 449 | eval $2="$3" |
| 450 | echo -en "\007" |
| 451 | ${DIALOG} --backtitle "$backtitle" \ |
| 452 | --infobox "You have made an invalid entry." 3 43 |
| 453 | sleep 2 |
| 454 | fi |
| 455 | |
| 456 | break |
| 457 | fi |
| 458 | |
| 459 | help "$2" "$1" |
| 460 | done |
| 461 | } |
| 462 | |
| 463 | # |
| 464 | # Create a dialog for entering a string into an option. |
| 465 | # |
| 466 | function l_string () { |
| 467 | while true |
| 468 | do |
| 469 | if $DIALOG --title "$1" \ |
| 470 | --backtitle "$backtitle" \ |
| 471 | --inputbox "$inputbox_instructions_string" \ |
| 472 | 10 75 "$4" 2>MCdialog.out |
| 473 | then |
| 474 | answer="`cat MCdialog.out`" |
| 475 | answer="${answer:-$3}" |
| 476 | |
| 477 | # |
| 478 | # Someone may add a nice check for the entered |
| 479 | # string here... |
| 480 | # |
| 481 | eval $2=\"$answer\" |
| 482 | |
| 483 | break |
| 484 | fi |
| 485 | |
| 486 | help "$2" "$1" |
| 487 | done |
| 488 | } |
| 489 | |
| 490 | |
| 491 | # |
| 492 | # Handle a one-of-many choice list. |
| 493 | # |
| 494 | function l_choice () { |
| 495 | # |
| 496 | # Need to remember params cause they're gonna get reset. |
| 497 | # |
| 498 | title="$1" |
| 499 | choices="$2" |
| 500 | current="$3" |
| 501 | chosen= |
| 502 | |
| 503 | # |
| 504 | # Scan current value of choices and set radiolist switches. |
| 505 | # |
| 506 | list= |
| 507 | set -- $choices |
| 508 | firstchoice=$2 |
| 509 | while [ -n "$2" ] |
| 510 | do |
| 511 | case "$1" in |
| 512 | "$current"*) if [ -z "$chosen" ]; then |
| 513 | list="$list $2 $1 ON " |
| 514 | chosen=1 |
| 515 | else |
| 516 | list="$list $2 $1 OFF " |
| 517 | fi ;; |
| 518 | *) list="$list $2 $1 OFF " ;; |
| 519 | esac |
| 520 | |
| 521 | shift ; shift |
| 522 | done |
| 523 | |
| 524 | while true |
| 525 | do |
| 526 | if $DIALOG --title "$title" \ |
| 527 | --backtitle "$backtitle" \ |
| 528 | --radiolist "$radiolist_instructions" \ |
| 529 | 15 70 6 $list 2>MCdialog.out |
| 530 | then |
| 531 | choice=`cat MCdialog.out` |
| 532 | break |
| 533 | fi |
| 534 | |
| 535 | help "$firstchoice" "$title" |
| 536 | done |
| 537 | |
| 538 | # |
| 539 | # Now set the boolean value of each option based on |
| 540 | # the selection made from the radiolist. |
| 541 | # |
| 542 | set -- $choices |
| 543 | while [ -n "$2" ] |
| 544 | do |
| 545 | if [ "$2" = "$choice" ] |
| 546 | then |
| 547 | eval $2="y" |
| 548 | else |
| 549 | eval $2="n" |
| 550 | fi |
| 551 | |
| 552 | shift ; shift |
| 553 | done |
| 554 | } |
| 555 | |
| 556 | # |
| 557 | # Call awk, and watch for error codes, etc. |
| 558 | # |
| 559 | function callawk () { |
| 560 | awk "$1" || echo "Awk died with error code $?. Giving up." || exit 1 |
| 561 | } |
| 562 | |
| 563 | # |
| 564 | # A faster awk based recursive parser. (I hope) |
| 565 | # |
| 566 | function parser1 () { |
| 567 | callawk ' |
| 568 | BEGIN { |
| 569 | menu_no = 0 |
| 570 | comment_is_option = 0 |
| 571 | parser("'$CONFIG_IN'","MCmenu0") |
| 572 | } |
| 573 | |
| 574 | function parser(ifile,menu) { |
| 575 | |
| 576 | while (getline <ifile) { |
| 577 | if ($1 == "mainmenu_option") { |
| 578 | comment_is_option = "1" |
| 579 | } |
| 580 | else if ($1 == "comment" && comment_is_option == "1") { |
| 581 | comment_is_option= "0" |
| 582 | sub($1,"",$0) |
| 583 | ++menu_no |
| 584 | |
| 585 | printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu |
| 586 | |
| 587 | newmenu = sprintf("MCmenu%d", menu_no); |
| 588 | printf( "function MCmenu%s () {\n"\ |
| 589 | "default=$1\n"\ |
| 590 | "menu_name %s\n",\ |
| 591 | menu_no, $0) >newmenu |
| 592 | |
| 593 | parser(ifile, newmenu) |
| 594 | } |
| 595 | else if ($0 ~ /^#|\$MAKE|mainmenu_name/) { |
| 596 | printf("") >>menu |
| 597 | } |
| 598 | else if ($1 ~ "endmenu") { |
| 599 | printf("}\n") >>menu |
| 600 | return |
| 601 | } |
| 602 | else if ($1 == "source") { |
| 603 | parser($2,menu) |
| 604 | } |
| 605 | else { |
| 606 | print >>menu |
| 607 | } |
| 608 | } |
| 609 | }' |
| 610 | } |
| 611 | |
| 612 | # |
| 613 | # Secondary parser for single menu mode. |
| 614 | # |
| 615 | function parser2 () { |
| 616 | callawk ' |
| 617 | BEGIN { |
| 618 | parser("'$CONFIG_IN'","MCmenu0") |
| 619 | } |
| 620 | |
| 621 | function parser(ifile,menu) { |
| 622 | |
| 623 | while (getline <ifile) { |
| 624 | if ($0 ~ /^#|$MAKE|mainmenu_name/) { |
| 625 | printf("") >>menu |
| 626 | } |
| 627 | else if ($1 ~ /mainmenu_option|endmenu/) { |
| 628 | printf("") >>menu |
| 629 | } |
| 630 | else if ($1 == "source") { |
| 631 | parser($2,menu) |
| 632 | } |
| 633 | else { |
| 634 | print >>menu |
| 635 | } |
| 636 | } |
| 637 | }' |
| 638 | } |
| 639 | |
| 640 | # |
| 641 | # Parse all the config.in files into mini scripts. |
| 642 | # |
| 643 | function parse_config_files () { |
| 644 | rm -f MCmenu* |
| 645 | |
| 646 | echo "function MCmenu0 () {" >MCmenu0 |
| 647 | echo 'default=$1' >>MCmenu0 |
| 648 | echo "menu_name 'Main Menu'" >>MCmenu0 |
| 649 | |
| 650 | if [ "_$single_menu_mode" = "_TRUE" ] |
| 651 | then |
| 652 | parser2 |
| 653 | else |
| 654 | parser1 |
| 655 | fi |
| 656 | |
| 657 | echo "comment ''" >>MCmenu0 |
| 658 | echo "g_alt_config" >>MCmenu0 |
| 659 | echo "s_alt_config" >>MCmenu0 |
| 660 | |
| 661 | echo "}" >>MCmenu0 |
| 662 | |
| 663 | # |
| 664 | # These mini scripts must be sourced into the current |
| 665 | # environment in order for all of this to work. Leaving |
| 666 | # them on the disk as executables screws up the recursion |
| 667 | # in activate_menu(), among other things. Once they are |
| 668 | # sourced we can discard them. |
| 669 | # |
| 670 | for i in MCmenu* |
| 671 | do |
| 672 | echo -n "." |
| 673 | source ./$i |
| 674 | done |
| 675 | rm -f MCmenu* |
| 676 | } |
| 677 | |
| 678 | # |
| 679 | # This is the menu tree's bootstrap. |
| 680 | # |
| 681 | # Executes the parsed menus on demand and creates a set of functions, |
| 682 | # one per configuration option. These functions will in turn execute |
| 683 | # dialog commands or recursively call other menus. |
| 684 | # |
| 685 | function activate_menu () { |
| 686 | rm -f lxdialog.scrltmp |
| 687 | while true |
| 688 | do |
| 689 | comment_ctr=0 #So comment lines get unique tags |
| 690 | |
| 691 | $1 "$default" 2> MCerror #Create the lxdialog menu & functions |
| 692 | |
| 693 | if [ "$?" != "0" ] |
| 694 | then |
| 695 | clear |
| 696 | cat <<EOM |
| 697 | |
| 698 | Menuconfig has encountered a possible error in one of BusyBox's |
| 699 | configuration files and is unable to continue. Here is the error |
| 700 | report: |
| 701 | |
| 702 | EOM |
| 703 | sed 's/^/ Q> /' MCerror |
| 704 | cat <<EOM |
| 705 | |
| 706 | Please report this to the maintainer <mec@shout.net>. You may also |
| 707 | send a problem report to <busybox@oss.lineo.com>. |
| 708 | |
| 709 | Please indicate the BusyBox version you are trying to configure and |
| 710 | which menu you were trying to enter when this error occurred. |
| 711 | |
| 712 | EOM |
| 713 | cleanup |
| 714 | exit 1 |
| 715 | fi |
| 716 | rm -f MCerror |
| 717 | |
| 718 | . ./MCradiolists #Source the menu's functions |
| 719 | |
| 720 | . ./MCmenu 2>MCdialog.out #Activate the lxdialog menu |
| 721 | ret=$? |
| 722 | |
| 723 | read selection <MCdialog.out |
| 724 | |
| 725 | case "$ret" in |
| 726 | 0|3|4|5|6) |
| 727 | defaults="$selection$defaults" #pseudo stack |
| 728 | case "$ret" in |
| 729 | 0) eval $selection ;; |
| 730 | 3) eval $selection y ;; |
| 731 | 4) eval $selection n ;; |
| 732 | 5) eval $selection m ;; |
| 733 | 6) eval $selection c ;; |
| 734 | esac |
| 735 | default="${defaults%%*}" defaults="${defaults#*}" |
| 736 | ;; |
| 737 | 2) |
| 738 | default="${selection%%\ *}" |
| 739 | |
| 740 | case "$selection" in |
| 741 | *"-->"*|*"alt_config"*) |
| 742 | show_readme ;; |
| 743 | *) |
| 744 | eval help $selection ;; |
| 745 | esac |
| 746 | ;; |
| 747 | 255|1) |
| 748 | break |
| 749 | ;; |
| 750 | 139) |
| 751 | stty sane |
| 752 | clear |
| 753 | cat <<EOM |
| 754 | |
| 755 | There seems to be a problem with the lxdialog companion utility which is |
| 756 | built prior to running Menuconfig. Usually this is an indicator that you |
| 757 | have upgraded/downgraded your ncurses libraries and did not remove the |
| 758 | old ncurses header file(s) in /usr/include or /usr/include/ncurses. |
| 759 | |
| 760 | It is VERY important that you have only one set of ncurses header files |
| 761 | and that those files are properly version matched to the ncurses libraries |
| 762 | installed on your machine. |
| 763 | |
| 764 | You may also need to rebuild lxdialog. This can be done by moving to |
| 765 | the /usr/src/linux/scripts/lxdialog directory and issuing the |
| 766 | "make clean all" command. |
| 767 | |
| 768 | If you have verified that your ncurses install is correct, you may email |
| 769 | the maintainer <andersen@codepoet.org> or post a message to |
| 770 | <busybox@oss.lineo.com> for additional assistance. |
| 771 | |
| 772 | EOM |
| 773 | cleanup |
| 774 | exit 139 |
| 775 | ;; |
| 776 | esac |
| 777 | done |
| 778 | } |
| 779 | |
| 780 | # |
| 781 | # Create a menu item to load an alternate configuration file. |
| 782 | # |
| 783 | g_alt_config () { |
| 784 | echo -n "get_alt_config 'Load an Alternate Configuration File' "\ |
| 785 | >>MCmenu |
| 786 | } |
| 787 | |
| 788 | # |
| 789 | # Get alternate config file name and load the |
| 790 | # configuration from it. |
| 791 | # |
| 792 | get_alt_config () { |
| 793 | set -f ## Switch file expansion OFF |
| 794 | |
| 795 | while true |
| 796 | do |
| 797 | ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}" |
| 798 | |
| 799 | $DIALOG --backtitle "$backtitle" \ |
| 800 | --inputbox "\ |
| 801 | Enter the name of the configuration file you wish to load. \ |
| 802 | Accept the name shown to restore the configuration you \ |
| 803 | last retrieved. Leave blank to abort."\ |
| 804 | 11 55 "$ALT_CONFIG" 2>MCdialog.out |
| 805 | |
| 806 | if [ "$?" = "0" ] |
| 807 | then |
| 808 | ALT_CONFIG=`cat MCdialog.out` |
| 809 | |
| 810 | [ "_" = "_$ALT_CONFIG" ] && break |
| 811 | |
| 812 | if eval [ -r "$ALT_CONFIG" ] |
| 813 | then |
| 814 | eval load_config_file "$ALT_CONFIG" |
| 815 | break |
| 816 | else |
| 817 | echo -ne "\007" |
| 818 | $DIALOG --backtitle "$backtitle" \ |
| 819 | --infobox "File does not exist!" 3 38 |
| 820 | sleep 2 |
| 821 | fi |
| 822 | else |
| 823 | cat <<EOM >help.out |
| 824 | |
| 825 | For various reasons, one may wish to keep several different BusyBox |
| 826 | configurations available on a single machine. |
| 827 | |
| 828 | If you have saved a previous configuration in a file other than the |
| 829 | busybox default, entering the name of the file here will allow you |
| 830 | to modify that configuration. |
| 831 | |
| 832 | If you are uncertain, then you have probably never used alternate |
| 833 | configuration files. You should therefor leave this blank to abort. |
| 834 | |
| 835 | EOM |
| 836 | $DIALOG --backtitle "$backtitle"\ |
| 837 | --title "Load Alternate Configuration"\ |
| 838 | --textbox help.out $ROWS $COLS |
| 839 | fi |
| 840 | done |
| 841 | |
| 842 | set +f ## Switch file expansion ON |
| 843 | rm -f help.out MCdialog.out |
| 844 | } |
| 845 | |
| 846 | # |
| 847 | # Create a menu item to store an alternate config file. |
| 848 | # |
| 849 | s_alt_config () { |
| 850 | echo -n "save_alt_config 'Save Configuration to an Alternate File' "\ |
| 851 | >>MCmenu |
| 852 | } |
| 853 | |
| 854 | # |
| 855 | # Get an alternate config file name and save the current |
| 856 | # configuration to it. |
| 857 | # |
| 858 | save_alt_config () { |
| 859 | set -f ## Switch file expansion OFF |
| 860 | |
| 861 | while true |
| 862 | do |
| 863 | $DIALOG --backtitle "$backtitle" \ |
| 864 | --inputbox "\ |
| 865 | Enter a filename to which this configuration should be saved \ |
| 866 | as an alternate. Leave blank to abort."\ |
| 867 | 10 55 "$ALT_CONFIG" 2>MCdialog.out |
| 868 | |
| 869 | if [ "$?" = "0" ] |
| 870 | then |
| 871 | ALT_CONFIG=`cat MCdialog.out` |
| 872 | |
| 873 | [ "_" = "_$ALT_CONFIG" ] && break |
| 874 | |
| 875 | if eval touch $ALT_CONFIG 2>/dev/null |
| 876 | then |
| 877 | eval save_configuration $ALT_CONFIG |
| 878 | load_functions ## RELOAD |
| 879 | break |
| 880 | else |
| 881 | echo -ne "\007" |
| 882 | $DIALOG --backtitle "$backtitle" \ |
| 883 | --infobox "Can't create file! Probably a nonexistent directory." 3 60 |
| 884 | sleep 2 |
| 885 | fi |
| 886 | else |
| 887 | cat <<EOM >help.out |
| 888 | |
| 889 | For various reasons, one may wish to keep different BusyBox |
| 890 | configurations available on a single machine. |
| 891 | |
| 892 | Entering a file name here will allow you to later retrieve, modify |
| 893 | and use the current configuration as an alternate to whatever |
| 894 | configuration options you have selected at that time. |
| 895 | |
| 896 | If you are uncertain what all this means then you should probably |
| 897 | leave this blank. |
| 898 | EOM |
| 899 | $DIALOG --backtitle "$backtitle"\ |
| 900 | --title "Save Alternate Configuration"\ |
| 901 | --textbox help.out $ROWS $COLS |
| 902 | fi |
| 903 | done |
| 904 | |
| 905 | set +f ## Switch file expansion ON |
| 906 | rm -f help.out MCdialog.out |
| 907 | } |
| 908 | |
| 909 | # |
| 910 | # Load config options from a file. |
| 911 | # Converts all "# OPTION is not set" lines to "OPTION=n" lines |
| 912 | # |
| 913 | function load_config_file () { |
| 914 | awk ' |
| 915 | /# .* is not set.*/ { printf("%s=n\n", $2) } |
| 916 | ! /# .* is not set.*/ { print } |
| 917 | ' $1 >.tmpconfig |
| 918 | |
| 919 | source ./.tmpconfig |
| 920 | rm -f .tmpconfig |
| 921 | } |
| 922 | |
| 923 | # |
| 924 | # Just what it says. |
| 925 | # |
| 926 | save_configuration () { |
| 927 | echo |
| 928 | echo -n "Saving your BusyBox configuration." |
| 929 | |
| 930 | # |
| 931 | # Now, let's redefine the configuration functions for final |
| 932 | # output to the config files. |
| 933 | # |
| 934 | # Nested function definitions, YIPEE! |
| 935 | # |
| 936 | function bool () { |
| 937 | set_x_info "$2" "n" |
| 938 | eval define_bool "$2" "$x" |
| 939 | } |
| 940 | |
| 941 | function dep_bool () { |
| 942 | set_x_info "$2" "n" |
| 943 | var="$2" |
| 944 | shift 2 |
| 945 | while [ $# -gt 0 ]; do |
| 946 | if [ "$1" = y ]; then |
| 947 | shift |
| 948 | else |
| 949 | x=n; shift $# |
| 950 | fi |
| 951 | done |
| 952 | define_bool "$var" "$x" |
| 953 | } |
| 954 | |
| 955 | function int () { |
| 956 | set_x_info "$2" "$3" |
| 957 | echo "$2=$x" >>$CONFIG |
| 958 | echo "#define $2 ($x)" >>$CONFIG_H |
| 959 | } |
| 960 | |
| 961 | function hex () { |
| 962 | set_x_info "$2" "$3" |
| 963 | echo "$2=$x" >>$CONFIG |
| 964 | echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H |
| 965 | } |
| 966 | |
| 967 | function string () { |
| 968 | set_x_info "$2" "$3" |
| 969 | echo "$2=\"$x\"" >>$CONFIG |
| 970 | echo "#define $2 \"$x\"" >>$CONFIG_H |
| 971 | } |
| 972 | |
| 973 | function define_hex () { |
| 974 | eval $1="$2" |
| 975 | echo "$1=$2" >>$CONFIG |
| 976 | echo "#define $1 0x${2##*[x,X]}" >>$CONFIG_H |
| 977 | } |
| 978 | |
| 979 | function define_int () { |
| 980 | eval $1="$2" |
| 981 | echo "$1=$2" >>$CONFIG |
| 982 | echo "#define $1 ($2)" >>$CONFIG_H |
| 983 | } |
| 984 | |
| 985 | function define_string () { |
| 986 | eval $1="$2" |
| 987 | echo "$1=\"$2\"" >>$CONFIG |
| 988 | echo "#define $1 \"$2\"" >>$CONFIG_H |
| 989 | } |
| 990 | |
| 991 | function define_bool () { |
| 992 | define_tristate "$1" "$2" |
| 993 | } |
| 994 | |
| 995 | function define_tristate () { |
| 996 | eval $1="$2" |
| 997 | |
| 998 | case "$2" in |
| 999 | y) |
| 1000 | echo "$1=y" >>$CONFIG |
| 1001 | echo "#define $1 1" >>$CONFIG_H |
| 1002 | ;; |
| 1003 | |
| 1004 | n) |
| 1005 | echo "# $1 is not set" >>$CONFIG |
| 1006 | echo "#undef $1" >>$CONFIG_H |
| 1007 | ;; |
| 1008 | esac |
| 1009 | } |
| 1010 | |
| 1011 | function choice () { |
| 1012 | # |
| 1013 | # Find the first choice that's already set to 'y' |
| 1014 | # |
| 1015 | choices="$2" |
| 1016 | default="$3" |
| 1017 | current= |
| 1018 | chosen= |
| 1019 | |
| 1020 | set -- $choices |
| 1021 | while [ -n "$2" ] |
| 1022 | do |
| 1023 | if eval [ "_\$$2" = "_y" ] |
| 1024 | then |
| 1025 | current=$1 |
| 1026 | break |
| 1027 | fi |
| 1028 | shift ; shift |
| 1029 | done |
| 1030 | |
| 1031 | # |
| 1032 | # Use the default if none were set. |
| 1033 | # |
| 1034 | : ${current:=$default} |
| 1035 | |
| 1036 | # |
| 1037 | # Output all choices (to be compatible with other configs). |
| 1038 | # |
| 1039 | set -- $choices |
| 1040 | while [ -n "$2" ] |
| 1041 | do |
| 1042 | case "$1" in |
| 1043 | "$current"*) if [ -z "$chosen" ]; then |
| 1044 | define_bool "$2" "y" |
| 1045 | chosen=1 |
| 1046 | else |
| 1047 | define_bool "$2" "n" |
| 1048 | fi ;; |
| 1049 | *) define_bool "$2" "n" ;; |
| 1050 | esac |
| 1051 | shift ; shift |
| 1052 | done |
| 1053 | } |
| 1054 | |
| 1055 | function mainmenu_name () { |
| 1056 | : |
| 1057 | } |
| 1058 | |
| 1059 | function mainmenu_option () { |
| 1060 | comment_is_option=TRUE |
| 1061 | } |
| 1062 | |
| 1063 | function endmenu () { |
| 1064 | : |
| 1065 | } |
| 1066 | |
| 1067 | function comment () { |
| 1068 | if [ "$comment_is_option" ] |
| 1069 | then |
| 1070 | comment_is_option= |
| 1071 | echo >>$CONFIG |
| 1072 | echo "#" >>$CONFIG |
| 1073 | echo "# $1" >>$CONFIG |
| 1074 | echo "#" >>$CONFIG |
| 1075 | |
| 1076 | echo >>$CONFIG_H |
| 1077 | echo "/*" >>$CONFIG_H |
| 1078 | echo " * $1" >>$CONFIG_H |
| 1079 | echo " */" >>$CONFIG_H |
| 1080 | fi |
| 1081 | } |
| 1082 | |
| 1083 | echo -n "." |
| 1084 | |
| 1085 | DEF_CONFIG="${1:-.config}" |
| 1086 | DEF_CONFIG_H="include/config.h" |
| 1087 | |
| 1088 | CONFIG=.tmpconfig |
| 1089 | CONFIG_H=.tmpconfig.h |
| 1090 | |
| 1091 | echo "#" >$CONFIG |
| 1092 | echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG |
| 1093 | echo "#" >>$CONFIG |
| 1094 | |
| 1095 | echo "/*" >$CONFIG_H |
| 1096 | echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H |
| 1097 | echo " */" >>$CONFIG_H |
| 1098 | echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H |
| 1099 | |
| 1100 | echo -n "." |
| 1101 | if . $CONFIG_IN >>.menuconfig.log 2>&1 |
| 1102 | then |
| 1103 | if [ "$DEF_CONFIG" = ".config" ] |
| 1104 | then |
| 1105 | mv $CONFIG_H $DEF_CONFIG_H |
| 1106 | fi |
| 1107 | |
| 1108 | if [ -f "$DEF_CONFIG" ] |
| 1109 | then |
| 1110 | rm -f ${DEF_CONFIG}.old |
| 1111 | mv $DEF_CONFIG ${DEF_CONFIG}.old |
| 1112 | fi |
| 1113 | |
| 1114 | mv $CONFIG $DEF_CONFIG |
| 1115 | |
| 1116 | return 0 |
| 1117 | else |
| 1118 | return 1 |
| 1119 | fi |
| 1120 | } |
| 1121 | |
| 1122 | # |
| 1123 | # Remove temporary files |
| 1124 | # |
| 1125 | cleanup () { |
| 1126 | cleanup1 |
| 1127 | cleanup2 |
| 1128 | } |
| 1129 | |
| 1130 | cleanup1 () { |
| 1131 | rm -f MCmenu* MCradiolists MCdialog.out help.out |
| 1132 | } |
| 1133 | |
| 1134 | cleanup2 () { |
| 1135 | rm -f .tmpconfig .tmpconfig.h |
| 1136 | } |
| 1137 | |
| 1138 | set_geometry () { |
| 1139 | # Some distributions export these with incorrect values |
| 1140 | # which can really screw up some ncurses programs. |
| 1141 | LINES= COLUMNS= |
| 1142 | |
| 1143 | ROWS=${1:-24} COLS=${2:-80} |
| 1144 | |
| 1145 | # Just in case the nasty rlogin bug returns. |
| 1146 | # |
| 1147 | [ $ROWS = 0 ] && ROWS=24 |
| 1148 | [ $COLS = 0 ] && COLS=80 |
| 1149 | |
| 1150 | if [ $ROWS -lt 19 -o $COLS -lt 80 ] |
| 1151 | then |
| 1152 | echo -e "\n\007Your display is too small to run Menuconfig!" |
| 1153 | echo "It must be at least 19 lines by 80 columns." |
| 1154 | exit 1 |
| 1155 | fi |
| 1156 | |
| 1157 | ROWS=$((ROWS-4)) COLS=$((COLS-5)) |
| 1158 | } |
| 1159 | |
| 1160 | |
| 1161 | set_geometry `stty size 2>/dev/null` |
| 1162 | |
| 1163 | menu_instructions="\ |
| 1164 | Arrow keys navigate the menu. \ |
| 1165 | Pressing <Enter> selects submenus --->. \ |
| 1166 | Highlighted letters are hotkeys. \ |
| 1167 | Pressing <Y> includes, and <N> excludes. \ |
| 1168 | Press <Esc><Esc> to exit, <?> for Help. \ |
| 1169 | Legend: [*] built-in [ ] excluded " |
| 1170 | |
| 1171 | radiolist_instructions="\ |
| 1172 | Use the arrow keys to navigate this window or \ |
| 1173 | press the hotkey of the item you wish to select \ |
| 1174 | followed by the <SPACE BAR>. |
| 1175 | Press <?> for additional information about this option." |
| 1176 | |
| 1177 | inputbox_instructions_int="\ |
| 1178 | Please enter a decimal value. \ |
| 1179 | Fractions will not be accepted. \ |
| 1180 | Use the <TAB> key to move from the input field to the buttons below it." |
| 1181 | |
| 1182 | inputbox_instructions_hex="\ |
| 1183 | Please enter a hexadecimal value. \ |
| 1184 | Use the <TAB> key to move from the input field to the buttons below it." |
| 1185 | |
| 1186 | inputbox_instructions_string="\ |
| 1187 | Please enter a string value. \ |
| 1188 | Use the <TAB> key to move from the input field to the buttons below it." |
| 1189 | |
| 1190 | DIALOG="./scripts/lxdialog/lxdialog" |
| 1191 | |
| 1192 | bb_version="${VERSION}" |
| 1193 | backtitle="BusyBox v$bb_version Configuration" |
| 1194 | |
| 1195 | trap "cleanup ; exit 1" 1 2 15 |
| 1196 | |
| 1197 | |
| 1198 | # |
| 1199 | # Locate default files. |
| 1200 | # |
| 1201 | CONFIG_IN=./config.in |
| 1202 | if [ "$1" != "" ] ; then |
| 1203 | CONFIG_IN=$1 |
| 1204 | fi |
| 1205 | |
| 1206 | DEFAULTS=sysdeps/$TARGET_OS/defconfig |
| 1207 | if [ -f .config ]; then |
| 1208 | DEFAULTS=.config |
| 1209 | fi |
| 1210 | |
| 1211 | if [ -f $DEFAULTS ] |
| 1212 | then |
| 1213 | echo "Using defaults found in" $DEFAULTS |
| 1214 | load_config_file $DEFAULTS |
| 1215 | else |
| 1216 | echo "No defaults found" |
| 1217 | fi |
| 1218 | |
| 1219 | |
| 1220 | # Fresh new log. |
| 1221 | >.menuconfig.log |
| 1222 | |
| 1223 | # Load the functions used by the config.in files. |
| 1224 | echo -n "Preparing scripts: functions" |
| 1225 | load_functions |
| 1226 | |
| 1227 | if [ ! -e $CONFIG_IN ] |
| 1228 | then |
| 1229 | echo "Your main config.in file ($CONFIG_IN) does not exist" |
| 1230 | exit 1 |
| 1231 | fi |
| 1232 | |
| 1233 | if [ ! -x $DIALOG ] |
| 1234 | then |
| 1235 | echo "Your lxdialog utility does not exist" |
| 1236 | exit 1 |
| 1237 | fi |
| 1238 | |
| 1239 | # |
| 1240 | # Read config.in files and parse them into one shell function per menu. |
| 1241 | # |
| 1242 | echo -n ", parsing" |
| 1243 | parse_config_files $CONFIG_IN |
| 1244 | |
| 1245 | echo "done." |
| 1246 | # |
| 1247 | # Start the ball rolling from the top. |
| 1248 | # |
| 1249 | activate_menu MCmenu0 |
| 1250 | |
| 1251 | # |
| 1252 | # All done! |
| 1253 | # |
| 1254 | cleanup1 |
| 1255 | |
| 1256 | # |
| 1257 | # Confirm and Save |
| 1258 | # |
| 1259 | if $DIALOG --backtitle "$backtitle" \ |
| 1260 | --yesno "Do you wish to save your new BusyBox configuration?" 5 60 |
| 1261 | then |
| 1262 | save_configuration |
| 1263 | echo |
| 1264 | echo |
| 1265 | echo "*** End of BusyBox configuration." |
| 1266 | echo "*** Check the top-level Makefile for additional configuration." |
| 1267 | if [ ! -f .hdepend ] ; then |
| 1268 | echo "*** Next, you must run 'make dep'." |
| 1269 | else |
| 1270 | echo "*** Next, you should run 'make' or 'make install'." |
| 1271 | fi |
| 1272 | echo |
| 1273 | else |
| 1274 | echo |
| 1275 | echo |
| 1276 | echo Your BusyBox configuration changes were NOT saved. |
| 1277 | echo |
| 1278 | fi |
| 1279 | |
| 1280 | # Remove log if empty. |
| 1281 | if [ ! -s .menuconfig.log ] ; then |
| 1282 | rm -f .menuconfig.log |
| 1283 | fi |
| 1284 | |
| 1285 | exit 0 |