In this section, several sample menus are presented which demonstrate techniques for creating useful menus.
The first example is a very simple menufile with a single menu. Our menu has two choices, Display Message and Return to System.
The first choice, when selected, displays Hello World! on the screen. The second choice terminates menu.
If the menufile is in a file called example1, run this menu by typing:
menu example1
Menu displays the screen shown below.
The menufile produced by menudef for this menu looks like:
menufile Untitled
menu m1
1,2 Sample Menu 1
4,9 Display Message
echo "Hello World!"
exit 1
+2,+0 Return to System
quit
Note that one choice executes the quit command to provide an exit from menu. All menus must have a quit or menu command to allow the operator to exit from the menu. The exit command in the Display Message choice forces a nonzero exit status that makes menu pause before redisplaying the menu. This is often useful when choice commands display information on the screen that would be overwritten if a menu were immediately redisplayed.
Menudef uses relative row and column numbers when practical. Inserting a new choice between other choices is easier when using relative row numbers, since you do not need to change the row numbers of the following choices.
The next example, example2, is the Demonstration Subscription System Menu. To run this menu, type:
menu example2
Menu displays the screen shown below.
The choices in this menu start with numbers, which allow the operator to select a choice by typing its number in a manner similar to many other menu systems.
The following is the text listing for menufile example2, created with menudef:
menufile Untitled
menu demo
1,2 Demonstration Subscription System
4,9 1 - Enter Magazines
form -qfuad ~mag
+1,+0 2 - Enter Subscriptions
bin/sform -qfuad ~subscrpt
+3,+0 3 - List Subscribers
grace ~subscrib
+1,+0 4 - List Subscriptions
grace ~sripts
+1,+0 5 - List Magazines
grace ~magazine
+1,+0 6 - List Subscriber Labels
grace ~labels
+3,+0 X - exit
quit
The next example, example3, puts the data entry, report and exit choices from example2 in separate columns. The resulting menu is shown below.
The operator can use the Up and Down Arrow keys to select choices in the data entry or report columns and can move between the data entry and report columns with the Left and Right Arrow keys. The exit choice, however, can only be reached by typing X, since the exit choice is not in the same row or column as any other choice. Placing a choice in a lone row and column may be useful if you want to insure that the operator intentionally selects a choice rather than accidentally selecting it.
Menu does not check for unreachable choices. For example, if the X - exit choice is rewritten as E1 - exit, the operator could not exit from the menu, since whenever E1 is typed, the menu cursor goes to the first choice starting with E1, E1 - Enter Magazines, rather than E1 - exit.
It is easy to create example3 from example2 with menudef by moving the choices with DELETE, UNDELETE and INSERT LINE. Note that some of the column numbers are relative, e.g., +0. This allows you to change the position of an entire column by changing just the first entry in that column. Here is the menufile example3:
menufile Untitle
menu demo
1,2 Demonstration Subscription System
4,9 Data Entry
+3,+0 E1 - Enter Magazines
form -qfuad ~mag
+2,+0 E2 - Enter Subscriptions
bin/sform -qfuad ~subscrpt
+2,+0 E3 - Enter Subscribers
form -qfuad ~sub
16,33 X - exit
quit
4,49 Reports
+3,+0 R1 - List Subscribers
grace ~subscrib
+2,+0 R2 - List Subscriptions
grace ~scripts
+2,+0 R3 - List Magazines
grace ~magazine
+2,+0 R5 - List Subscriber Labels
grace ~labels
Example4, allows the operator to list files and directories in the current working directory without typing DOS commands directly. Before displaying the menu, this menufile uses the menu commands to display the available files or directories. The C/Base ask(C-1) command is used to get responses from the operator. This is not the built-in command version of ask that is available using the built-in menu commands. The text menufile for example4 is as following:
menufile example4, BUILT_IN_COMMANDS=ON
if $# > 2
echo "usage: menu example4 [ filename ]"
exit 1
endif
if $# = 1
ask "Enter file name: " as string to name
else
set name to "$1"
endif
if ! file name
echo "File" :name: "does not exist"
ask "Create it (y/n)? " as boolean to response
if response
eval echo >$name
else
exit 1
endif
endif
set EDITOR to "edit"
menu main
1,1 Main menu
+1,+0 File Services - file $name
+3,10 1 - Change name of file
ask "Enter new file name: " as string to new
if file new
echo new : " already exists."
ask "Remove it (y/n)? " as boolean to response
if response
erase $new
else
exit 1
endif
endif
ask "Change ":name:" to ":new:"(y/n)?" as boolean to response
if response
rename $name $new
set name to new
else
exit 1
endif
+2,+0 2 - Display contents of file
grace - <$name
exit 1
+2,+0 3 - Display directory information of file
dir $name
exit 1
+2,+0 4 - Display name of file
echo "The current file name is " : name
exit 1
+2,+0 5 - Edit file
echo "Starting " : EDITOR : " on " : name : "..."
$EDITOR $name
exit 1
+2,+0 6 - Remove file
ask "Remove " :name:"(y/n)? " as boolean to response
if response
ask "Enter new file name: " as string to new
if ! file new
echo "File " : new : " does not exist."
ask "Create it (y/n)? " as boolean to response
if response
eval echo >$name
else
exit 1
endif
endif
erase $name
set name to new
endif
exit 1
+2,+0 7 - Select new file name
echo "The current file name is ": name
ask "Enter the new file name: " as string to new
if ! file new
echo "File " : new
ask "Create it (y/n)? " as boolean to response
if response
eval echo >$name
else
exit 1
endif
endif
set name to new
exit 1
+3,+0 8 - Exit
quit
To start example4, enter
menu example4
A menu can be reached from any other menu with the menu command, so groups of menus are not restricted to the typical tree structure. In this example, any of the menus can be directly reached from the current menu.
The ask(C-1) command is useful in choice commands to prompt the operator and get a response. Typically, ask is used in a shell variable assignment as:
ask "prompt" as "datatype" to Shvar
Shvar is a shell variable of your choosing; datatype is a data type listed in Table 8-21, and prompt is a string of characters, normally quoted. Ask displays the prompt on the screen and accepts input that matches the specified datatype. If the operator enters data that does not match the datatype, ask prompts the operator to reenter the data.
The menu commands following the menu dirs line are executed each time the Directory Services menu is displayed, as are the commands following the menu files line each time the File Services menu is displayed. In this example, the Directory Services or File Services menus are displayed whenever the menu dirs or menu files internal menu commands are executed.
When menu's built-in commands are disabled, menufile or menu commands cannot be used to change the current directory or shell variables that are used in other menus or choice commands, since each group of commands is executed by a separate shell.
Example5 demonstrates some of the built-in commands that are available with menu. If the menufile has the BUILT_IN_COMMANDS=toggle set to either ON or OFF, the -m flag is ignored. To start example5 type
menu example5 [filename]
The menufile is as follows:
menufile example5, BUILT_IN_COMMANDS=ON
if $# > 2
echo "usage: menu example4 [ filename ]"
exit 1
endif
if $# = 1
ask "Enter file name: " as string to name
else
set name to "$1"
endif
if ! file name
echo "File " :name: "does not exist"
ask "Create it (y/n)? " as boolean to response
if response
eval echo >$name
else
exit 1
endif
endif
set EDITOR to "edit"
menu main
1,1 Main menu
+1,+0 File Services - file $name
+3,10 1 - Change name of file
param change
if file new
echo new : " already exists."
ask "Remove it (y/n)? " as boolean to response
if response
erase $new
else
exit 1
endif
endif
ask "Change ":name:" to ":new:"(y/n)?" as boolean to response
if response
rename $name $new
set name to new
else
exit 1
endif
+2,+0 2 - Display contents of file
grace - <$name
exit 1
+2,+0 3 - Display directory information of file
dir $name
exit 1
+2,+0 4 - Display name of file
echo "The current file name is " : name
exit 1
+2,+0 5 - Edit file
echo "Starting " : EDITOR : " on " : name : "..."
$EDITOR $name
exit 1
+2,+0 6 - Remove file
param remove
if response
ask "Enter new file name: " as string to new
if ! file new
echo "File " : new : " does not exist."
ask "Create it (y/n)? " as boolean to response
if response
eval echo >$name
else
exit 1
endif
endif
erase $name
set name to new
endif
exit 1
+2,+0 7 - Select new file name
param new
if ! file new
echo "File " : new
ask "Create it (y/n)? " as boolean to response
if response
eval echo >$name
else
exit 1
endif
endif
set name to new
exit 1
+3,+0 8 - Exit
quit
param change
1,1 $0
4,10 Current name is '$name'
+2,+0 Enter new file name
6,35 new
FIELDSIZE=20
DATATYPE=string
REQUIRED
param remove
1,1 $0
4,10 When removing the current file '$name'
+1,+0 a new current file name must be set.
+2,+0 Do you wish to remove the current file?
+3,+0 If you intend to remove the current file '$name',
+1,+0 a new file name must be set for the file service menu.
+2,+0 Enter Name of New File
13,36 new
FIELDSIZE=20
DATATYPE=string
REQUIRED
7,52 ans
FIELDSIZE=3
DATATYPE=boolean
param newfile
1,1 $0
3,5 The current file name is $name
+2,+0 Enter the new file name
5,30 new
FIELDSIZE=20
DATATYPE=string
REQUIRED
When menu runs with our example5 menufile using the filename myname, the menu displayed is shown as follows:
This menufile makes use of the built-in menu commands available with menu. The ask and param menu commands are useful when input is required from the operator. Examples of both are in the menufile example5. Each time the menu choice 1 - Change name of file is selected, a parameter form is displayed like the one shown below.
Looking at the menufile for example5, you may notice that variables can be used in expressions in two ways. For example, the following two built-in echo commands display the same thing:
set color to "blue"
echo "The sky is " : color : " today."
echo "The sky is $color today."
There is a subtle difference, through. The variable color in the first echo command is concatenated between two string constants and is evaluated as an expression, while in the second echo command the value of color is substituted into the string constant. The substitution may occur anywhere, even in places where expressions are not allowed.
It is important to differentiate between substitutions and expressions. Menu evaluates expressions after any substitution. Once substitution has been performed, the expression is evaluated. Hence, substitution may alter how expressions are evaluated. For example, had the set command in the above example been:
set color to "light "" blue"
the following echo commands would look as follows after substitution:
echo "The sky is " : color : " today."
echo "The sky is light" "blue today."
The second echo statement will not work. In this case, menu detects an invalid expression, stops execution of the menu commands and displays an error.