The Form and Menu Language is a high-level "shell-like" language for defining forms, menus, and text frames for your application. A form, menu, or text frame definition is stored in an ASCII file, called a "frame definition file," made up of statements recognized by the Form and Menu Language Interpreter--the fmli command. Frame definition files can contain fixed descriptions of the contents of the frame and/or code that will dynamically generate the contents. When fmli is invoked for the scripts you have written, the frame definition files are parsed, and the frames that will be displayed on the screen are generated.
This chapter summarizes the syntax of the various elements of the Form and Menu Language.
The following sections discuss the general rules and the conventions which apply to the Form and Menu Language. Specifics of syntax for particular elements of the language are covered in the appropriate sections.
On the fmli command line, frame definition files are recognized as arguments only when they are named in accordance with the following conventions:
where name can be any string that conforms to the UNIX system file naming conventions.
In a frame definition file, however, file name arguments to the open command can follow the above conventions, or they can have any valid UNIX system file name as long as one of the type casts, MENU, FORM, or TEXT, is used to identify the king of frame definition file being opened (see "Type Casts" in this chapter for more information).
Comments can be included by beginning a line with the pound sign character. A pound sign, #, when it is the first non-white-space character on a line, causes all following text up to a newline to be ignored by FMLI. (Inside single quotes (` '), double quotes (" "), and backquotes (` `), the pound sign has no special meaning. Thus, comments cannot be included in backquoted expressions.)
Some elements of the Form and Menu Language are case-insensitive, and some are case-sensitive.
The case-insensitive elements are
The case-sensitive elements are
A file type cast is an identifier that indicates to FMLI the type of frame definition file being opened when the file's name does not follow the naming conventions for frame definition files. There are three type casts for frame definition files: MENU, FORM, and TEXT. Each can be used as the first argument to the open command. For example,
action=open form user.address
identifies user.address as a form definition file. A frame definition file can be identified by using both the file naming convention and a type cast, although only one or the other is required.
Note the file type casts cannot be used to identify the initial frame(s) to open when fmli is invoked.
FMLI defines default times when descriptors will be evaluated. Some are evaluated only once (when a frame is opened, for example), and some more than once (when a frame is opened and whenever it is made current, for example). In some cases, this approach may cause inefficiency. Consequently, two casts are provided to control this; const and vary. If either of these casts are used, they must appear immediately after the equal sign (=) on the descriptor line. The use of const can make a form, menu, or text operation more efficient, especially when the value of a descriptor is a backquoted expression which calls UNIX system commands.
For example, the Boolean descriptor show can be used in a form definition file to define whether a field will be displayed. It is evaluated whenever any navigation occurs in the form. The show descriptor in a form frame is often a calculated value. For example, a form might include a field which should only be filled in by root. You could define the value of show to be determined by the value of the environment variable LOGNAME:
show=`if [ $LOGNAME != root ]; then echo FALSE; else echo TRUE; fi`
When this form definition file is read, show descriptor will never be re-evaluated as long as the frame remains opened, unless an update command is executed, either explicitly or as a result of a checkworld. For example,
show=const `if [ $LOGNAME != root]; then echo FALSE; else echo TRUE; fi`
defines show as whatever the conditional statement evaluates to when the frame is opened.
The const cast should be used with caution because you are assuming that the descriptor's value will always be constant and will never need to be re-evaluated.
If the vary cast is used on a descriptor line, then any time that descriptor is referenced, a new value will be recalculated rather than the result of the last calculation being taken. vary is useful to force descriptors that are normally evaluated only once, such as rmenu, to be re-evaluated when a subsequent reference to the descriptor is made.
Special characters in FMLI scripts are:
double quote |
" |
single quote |
' |
backslash |
\ |
vertical bar |
| |
backquote |
` |
dollar sign |
$ |
ampersand |
& |
semicolon |
; |
pound sign |
# |
(in the first non-whitespace column of a line) | |
right-angle bracket |
> |
left-angle bracket |
< |
<newline> | |
<space> | |
<tab> | |
left brace |
{ |
right brace |
} |
(in the rmenu descriptor only) | |
integer 2 (when followed by>) |
2 |
Some FMLI built-in utilities, such as regex and fmlgrep, have other special characters.
FMLI supports quoting mechanisms, similar to those used in the UNIX system shell, for disabling the meaning of special characters in a string. Each quoting mechanism has a different function, as defined below.
CAUTION: If a statement run in a backquoted expression changes the ssty (1) setting, the FMLI session may be corrupted. Frames may not display correctly and the FMLI command line may not function (the latter occurs if RETURN is mapped to LINEFEED or to LINEFEED RETURN).
Backquoted expressions may be coded as the value of a descriptor. They are evaluated at the time the descriptor is evaluated. When a backquoted expression produces output, it is considered part of the descriptor. This output must not produce an illegal value on the descriptor line. For instance if a variable, MYVAR, is set to hello, then:
action=`echo $MYVAR`open menu Mymenu
will be equivalent to:
action=helloopen menu Mymenu
This produces an illegal descriptor value since helloopen is not a known FMLI command, and descriptors of type command must evaluate to a known FMLI command. As a result, the terminal will beep.
In addition to using backquoted expressions on descriptor lines, you can code them as "stand-alone" backquoted expression is one that starts a line, and it is evaluated when the frame definition file is opened, reread, or updated; before any descriptors are evaluated. Thus, if a stand-alone backquoted expression produces output to the message line, the output will appear before the frame being parsed is posted.
It is important to note that information can be passed to or from UNIX executables and FMLI built-in commands using backquoted expressions. For example a menu item with the following definition of the action descriptor; action=`date | message ` nop, passes the output of the UNIX system date command to the FMLI built-in utility message, which displays it on the message line.
Using this feature of the Form and Menu Language, you can generate the entire contents of a frame dynamically at run time. For an example of a menu generated this way, see the regex manual page and "Creating a Dynamic Menu" in Chapter 3.
NOTE: In backquoted expressions, executables that expect standard input must be run via the run built-in utility. For example, if a user selects a menu item which has its action descriptor coded as action=`vi mufile`nop, the FMLI session will appear to hang. The same action, coded as action='run vi myfile' nop executes properly.
Several statements, utilizing FMLI built-in utilities or UNIX executables, may appear inside a single backquoted expression, separated by one of the following operators:
NOTE: FMLI does not allow statement grouping by using parentheses, such as can be done in the UNIX shell, i.e., statement1 && (statement2; statement3).
The input of a statement may be redirected from a file by using <file. Similarly, the output of a statement may be sent to a file by using > file, or by using >> file to append output to the end of a file.
The output from standard error may be redirected by using 2> file to send it to a file, or by using 2>> file to append it to the end of a file.
As in the UNIX shell, whitespace between > or < and file is optional.
In general, FMLI does not generate messages on syntax errors. Anything it doesn't understand is ignored. However, some of the built-in utilities such as fmlgrep, and the FMLI conditional statement, generate their own syntax error messages. For example, a misspelled descriptor will be ignored, but a syntax error in a use of fmlgrep may cause an error message. In addition, correctly coded descriptors will be ignored if they are used in the wrong context. For example, the selected descriptor will be ignored in a single-select menu (because selected has no meaning in that context).
When creating a new form, menu or text frame, all quotes and backquotes must match. Quoting mismatches may cause the frame to never appear, appear incorrectly, or cause an fmli session to terminate (exit).
The Form and Menu Language Interpreter recognizes user-defined variables, and a set of read-only special FMLI variables (known as built-in variables), as well as UNIX shell variables such as HOME or MAIL.
Variables in FMLI ar global. That is, variables defined in one frame or application-level definition file are exported to all other frame definition files or application level files after the set command has been executed. if a frame is not opened during the execution of an FMLI session, variables defined in it are not available.
User-defined variables are names to which you may assign string values using the FMLI built-in utility set(1F) (see the set manual page for complete details on its use). You can assign values to variables in the local environment, available to the current FMLI session only:
set -1 name=value
NOTE: Local variables are available to all frames of your application, not just the frame in which they are set.
Or a variable can be made available to any application/process by placing the variable in a file, thus allowing another application (e.g., another FMLI application) to retrieve the information:
set -ffilename name=value
where name is a sequence of letters, digits, and underscores that begins with a letter or an underscore, value is a string, and filename is the pathname to a file that contains lines of the form name=value. If it does not already exist, filename will be created. Note that no spaces surround the equal sign (=).
The built-in utility set can also be used to set variables in the UNIX environment and export them to the current session and to its child processes:
set -e name=value
The built-in utility unset can be used to remove a variable assignment (see the set(1F) manual page for complete details on its use.)
The built-in variables are a set of special, read-only variables that are pre-defined in the Form and Menu Language. These built-in variables can only be referenced, but never set, in frame definition files. The built-in variables are as follows:
In frame definition files and application level files, variables are referenced by prefixing either $ or $! to the variable name.
When you use the $name notation, the variable is evaluated only once. This implies that special characters lose their special meaning when they are coded in the values of strings. For example if you assigned a variable, VAR, the following value:
`set -l VAR="`date' $HOME" '
and then requested FMLI to display the value of $VAR, the value displayed would be the following:
`date' $HOME
When you use the $!name notation, the variable will be evaluated multiple times--as long as special characters remain in the expression. For example, if the variable VAR had the same value assigned as shown above, but you requested FMLI to display the value of $!VAR, the value displayed would be (for example);
Thu Sep 29 14:43:41 EDT 1989 /usr/loginID
The $! notation should never be used when referencing the built-in variables (especially F1, F2, etc.), because it is impossible to guard against users entering special characters in form fields.
NOTE: Prior to Release 4.0, only the $ notation existed for variable evaluation, and that notation exhibited the behavior now defined for $!.
For previously written FMLI applications now being run under FMLI Release 4.0, a Boolean descriptor, use_incorrect_pre4.0_behavior can be set in the initialization file, which will cause fmli to ignore the $! notation and interpret & in the old way. The default value (if not defined in the initialization file) for use_incorrect_pre4.0_behavior if FALSE.
This descriptor, and consequently the ability to make the $ notation behave like the $! notation, will be removed in the next release of FMLI.
When a variable is evaluated that does not specifically reference a file, two environments are searched:
local environment
This environment is specific to the current FMLI process (variables set with set -l). This is similar to an unexported shell variable.
UNIX system environment
The UNIX system environment is the standard UNIX environment.
Whenever "environment" is referred to in this text, these environments are searched in the order listed.
Variable names must be referenced using one of the following formats:
$variable or ${variable}
Look for variable in the environment and evaluate to the value of that variable.
NOTE: The built-in variable Fn must be used with the format {Fn} for fields greater than the ninth, i.e., {F10}, {F11}, etc.
${variable:-default}
Look for variable in the environment and if it is found evaluate to its value. If it is not found, evaluate to default.
${(filename)variable}
Look for a line of the format variable=value in the file filename. If such a line is found, evaluate to value.
${(filename)variable:-default}
Same as above, except if variable is not found anywhere, evaluate to default.
Note that filename and default may themselves be variables, such as ${($HOME/.variables)NAME:-$LOGNAME}
Descriptors are the basic building blocks of the Form and Menu Language. Each descriptor defines a particular attribute that you can customize for the type of frame you are defining. The three types of frames that you can define--menus, forms, and text frames--each have their own set of descriptors, as do the initialization file, the commands file, and the alias file.
The general syntax of descriptor statements in the Form and Menu Language is
descriptor=value
where descriptor is any valid descriptor for the frame definition file or application level definition file you are writing, and value is a value of the type expected by the descriptor, which may include backquoted expressions that evaluate to part, or all, of the descriptor value, as well as FMLI commands and their arguments. For example, if the variable LOGNAME evaluates to joe, then
name=hello there $LOGNAME --today is `date'
results in the value of the name descriptor being
hello there joe --today is sun Aug 27 16:07:23 EDT 1989.
Note that there are no spaces around the equal sign (=) in a descriptor statement.
The types of descriptors are the following:
NOTE: If the integer value assigned to a descriptor that determines the offset of a frame or any of its components is greater than the boundaries of the screen work area, the frame will not be posted. The begrow and begcol descriptors are the exceptions to this. They default to any.
Menu, form, and text-frame definition files have similar rules governing the order in which descriptors are defined.
The following table lists the frame descriptors that can be used in a menu definition file. None of these descriptors is required in a menu definition file. If any are used they can be in any order, but they must precede the item descriptors.
Frame Descriptors for Menu Definition Files
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
altslks |
FALSE |
Boolean |
When menu is opened/updated |
begcol |
any |
position |
When menu is opened/updated |
begrow |
any |
position |
When menu is opened/updated |
close |
no default |
null |
When menu is closed for any reason |
columns |
calculated value ** |
integer |
When menu is opened/updated |
done |
no default |
command |
Upon ENTER in a multi-select menu or when a single select menu is closed |
framemsg |
no default |
string |
When menu is opened/updated |
help |
no default |
command |
When user asks for help |
init |
TRUE |
Boolean |
When menu is opened/updated |
interrupt |
inherited value * |
Boolean |
When an interruptible descriptor is evaluated |
lifetime |
longterm |
string |
When menu is opened, closed, made current, or made noncurrent |
oninterrupt |
inherited value * |
command |
After a descriptor is interrupted |
menu |
Menu |
string |
When menu is opened |
multiselect |
FALSE |
Boolean |
When menu is opened/updated |
reread |
FALSE |
Boolean |
When a checkworld occurs |
rows |
calculated value ** |
integer |
When menu is opened/updated |
The table below lists the item descriptors that can be used in a menu definition file. In each set of item descriptors, name is required and must be the first descriptor.
Item Descriptors for Menu Definition Files
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
action |
no default |
command |
When item is selected |
description |
no default |
string |
When menu is opened/updated |
inactive |
FALSE |
Boolean |
When menu is opened/updated |
interrupt |
inherited value * |
Boolean |
When action descriptor is evaluated |
itemmsg |
no default |
string |
When item is navigated to |
lininfo |
no default |
string |
When item is navigated to |
name |
no default |
string |
When menu is opened/updated |
oninnterrupt |
inherited value * |
command |
After action descriptor is interrupted |
selected |
FALSE |
Boolean |
When menu is opened/updated |
show |
TRUE |
Boolean |
When menu is opened/updated |
The table below lists the descriptors that can be used to define screen-labeled function keys in a menu definition file. The name and button descriptors must be defined, and name must be first in each set of SLK descriptors.
SLK Descriptors for Menu Definition Files
DESCRIPTORS |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
action |
no default |
command |
When SLK is pressed |
button |
no default |
integer |
When menu is opened/updated |
interrupt |
inherited value * |
Boolean |
When SLK action descriptor is evaluated |
name |
no default |
string |
When menu is opened/updated |
oninterrupt |
inherited value * |
command |
After SLK action descriptor is interrupted |
`message Operation interrupted!`nop.
The table below lists the frame descriptors that can be used in a form definition file. None of these descriptors is required in a form definition file. If any are used they can be in any order, but they must precede the field descriptors.
Frame Descriptors for Form Definition Files
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
altslks |
FALSE |
Boolean |
When form is opened/updated |
begcol |
any |
position |
When form is opened/updated |
begrow |
any |
position |
When form is opened/updated |
close |
no default |
null |
When form is closed |
done |
no default |
command |
When user selects SAVE |
form |
Form |
string |
When form is opened |
framemsg |
no default |
string |
When form is opened/updated |
help |
no default |
command |
When user asks for help |
init |
TRUE |
Boolean |
When form is opened/updated |
interrupt |
inherited value* |
Boolean |
When an interruptible descriptor is evaluated |
lifetime |
longterm |
string |
When form is opened, closed, made current, made non-current |
oninterrupt |
inherited value* |
command |
After a descriptor is interrupted |
reread |
FALSE |
Boolean |
When checkworld occurs |
The table below lists the field descriptors that can be used in a form definition file. In each set of field descriptors the name descriptor is required and must be first.
Field Descriptors for Form Definition Files
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
autoadvance |
FALSE |
Boolean |
When form is opened/closed |
choicemsg |
no default |
string |
When choices command is run |
columns |
-1 *** |
integer |
When form is opened/closed |
fieldmsg |
no default |
string |
When field is navigated to |
fcol |
-1 ** |
integer |
When form is opened/updated |
frow |
-1 ** |
integer |
When form is opened/updated |
inactive |
FALSE |
Boolean |
When form is opened, made current, updated, saved |
invalidmsg |
Input is not valid |
string |
When valid evaluates to false |
lininfo |
no default |
string |
When this field is navigated to |
menuonly |
FALSE |
Boolean |
When form is opened/updated |
name |
no default |
string |
When form is opened/updated |
ncol |
-1 ** |
integer |
When form is opened/updated |
noecho |
FALSE |
Boolean |
When form is opened/updated |
nrow |
-1 ** |
integer |
When form is opened/updated |
page |
1 ** |
integer |
When form is opened/updated |
rmenu |
no default |
command |
When form is opened/updated |
rows |
1 ** |
integer |
When form is opened/updated |
scroll |
FALSE |
Boolean |
When form is opened/updated |
show |
TRUE |
Boolean |
When any navigation occurs |
valid |
TRUE |
Boolean |
When RETURN is pressed on the field, when any value with a greater field number is changed, or when form is saved |
value |
no default |
string |
When form is opened/updated |
wrap |
FALSE |
Boolean |
When form is opened/updated |
The following table lists the SLK descriptors that can be used in a form definition file. When they appear in a form definition file, they must be the last descriptors in the file. The name and button descriptors must be defined, and name must be the first descriptor in each set of SLK descriptors.
SLK Descriptors for Form Definition Files
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
action |
no default |
command |
When SLK is pressed |
button |
no default |
integer |
When form is opened/updated |
interrupt |
inherited value * |
Boolean |
When SLK action descriptor is evaluated |
name |
no default |
string |
When form is opened/updated |
oninterrupt |
inherited value * |
command |
After SLK action descriptor is interrupted |
The following table lists the frame descriptors that can be used in a text-frame definition file. None of these descriptors is required in a text frame definition file. If any are used they can be in any order, but they must precede the SLK descriptors. Note that the only kinds of descriptors in text frame definition in text frame definition files are frame descriptors and SLK descriptors. (Text frames do not have an equivalent to item or field descriptors.)
Frame Descriptors for Text-Frame Definition Files
DESCRIPTORS |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
altslks |
FALSE |
Boolean |
When text frame is opened/updated |
begrow |
any |
position |
When text frame is opened/updated |
begcol |
any |
position |
When text frame is opened/updated |
close |
no default |
null |
When text frame is closed |
columns |
30 |
integer |
When text frame is opened/updated |
done |
TRUE |
Boolean |
When text frame is closed |
edit |
FALSE |
Boolean |
When text frame is opened/updated |
framemsg |
no default |
string |
When text frame is opened/updated |
header |
no default |
string |
When text frame is opened/updated |
help |
no default |
command |
When user asks for help |
init |
TRUE |
Boolean |
When text frame is opened/updated |
interrupt |
inherited value * |
Boolean |
When an interruptible descriptor is evaluated |
lifetime |
longterm |
string |
When text frame is opened, closed, made current, or made non-current |
oninterrupt |
inherited value* |
command |
After a descriptor is interrupted |
reread |
FALSE |
Boolean |
When text frame is opened/updated |
rows |
10 |
integer |
When text frame is opened/updated |
text |
no default |
string |
When text frame is opened/updated |
title |
Text |
string |
When text frame is opened |
wrap |
TRUE |
Boolean |
When text frame is opened/updated |
The following table lists the SLK descriptors that can be used in a text-frame definition file. When they are used in a text-frame definition file, they must be the last descriptors in the file. The name and button descriptors must be defined, and name must be the first descriptor in each set of SLK descriptors.
SLK Descriptors for Text-Frame Definition Files
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
action |
no default |
command |
When SLK is pressed |
button |
no default |
integer |
When text frame is opened/updated |
interrupt |
inherited value * |
Boolean |
When SLK action descriptor is evaluated |
name |
no default |
string |
When text frame is opened/updated |
oninterrupt |
inherited value * |
command |
After SLK action descriptor is interrupted |
There are three kinds of application level files; the initialization file, the commands file, and the alias file. The rules which govern the order of descriptors are different for each and are covered in the appropriate section.
Most descriptors for application level files are evaluated at initialization time. "Initialization time" can be one of the following: when the FMLI application session is started via the fmli command, and when the FMLI built-in utility reinit(1F) is executed. (The reinit utility parses and evaluates the descriptors in the file names as its argument and continues running the current application.)
The rules governing the order in which descriptors are defined in an initialization file are the following:
application descriptors
Descriptors that apply to the application as a whole must be defined first. There can be only one set of application descriptors in an initialization file. In that set, each application descriptor should be defined once. If defined more than once, then the last instance of the descriptor in the set is used. Application descriptors fall into four functional groups:introductory frame descriptors
application SLK descriptors
Descriptors that apply to application SLKs (the name that appears on the screen label as well as the function assigned to the function key) must be defined last in the initialization file. There can be multiple sets of application SLK descriptors--as many sets as there are SLKs you are defining. In each set, however, a descriptor should be defined only once.
The following tables summarize the valid descriptors for the four functional groups of application descriptors and show their default value, the type of value expected, and the default evaluation time. (See Chapter 4, "Application Level Definition Files" for discussions of what these descriptors do and how to use them.)
The following table lists the descriptors that can be used to define an introductory frame in an intialization file.
Introductory Frame Descriptors for the Initialization File
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
columns |
50 |
position |
At initialization time |
rows |
10 |
position |
At initialization time |
text |
no default |
string |
At initialization time |
title |
no default |
string |
At initialization time |
The table below lists the descriptors that can be used to define the banner line in an initialization file.
Banner Line Descriptors for the Initialization File
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
bancol |
center |
position |
At initialization time |
banner |
no default |
string |
At initialization time |
working |
Working |
string |
At initialization time |
The table below lists the descriptors that can be used to define general features of the application as a whole.
General Descriptors for the Initialization File
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
interrupt |
FALSE |
Boolean |
When an interruptible descriptor is evaluated |
nobang |
FALSE |
Boolean |
At initialization time |
oninterrupt |
'message Operation Interrupted!' nop |
command |
After a descriptor is interrupted |
permanentmsg |
no default |
string |
At initialization time |
slk_layout |
3-2-3 |
layout |
At initialization time |
toggle |
3 |
integer |
At initialization time |
NOTE: Prior to FMLI Release 4.0, only the $ notation existed for variable evaluation, and that notation exhibited the behavior now defined for $!.
For previously written FMLI applications now being run under FMLI Release 4.0, a Boolean descriptor, use_incorrect_pre4.0_behavior can be set in the general descriptors section of an initialization file, which will cause fmli to ignore the $! notation and interpret $ in the way defined for $!. The default-if-not-defined value for use_incorrect_pre4.0_behavior is FALSE.
This descriptor, and consequently that ability to make the $ notation behave like the $! notation, will be removed in the next release of FMLI.
The following table lists the descriptors that can be used to define the colors of various elements of the FMLI screen display in an initialization file.
Color Descriptors for the Initialization File
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
active_border |
white |
color |
At initialization time |
active_title_bar |
black |
color |
At initialization time |
active_title_text |
white |
color |
At initialization time |
banner_text |
white |
color |
At initialization time |
highlight_bar |
black |
color |
At initialization time |
highlight_bar_text |
white |
color |
At initialization time |
inactive_border |
white |
color |
At initialization time |
inactive_title_text |
white |
color |
At initialization time |
inactive_title_bar |
black |
color |
At initialization time |
screen |
black |
color |
At initialization time |
slk_text |
white |
color |
At initialization time |
slk_bar |
black |
color |
At initialization time |
window_text |
white |
color |
At initialization time |
The following table lists the descriptors used to define SLKs in the intialization file. When used in an initialization file, they must be the last descriptors in the file. The name and button descriptors must be defined, and name must be the first descriptor in each set of SLK descriptors.
Application SLK Descriptors for the Initialization File
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
action |
no default |
command |
When SLK is pressed |
button |
no default |
integer |
At initialization time |
interrupt |
inherited value * |
Boolean |
When a SLK action descriptor is evaluated |
name |
no default |
string |
At initialization time |
oninterrupt |
inherited value* |
command |
After a SLK action descriptor is interrupted |
The commands file has only one set of descriptors, and that set can be defined multiple times. The maximum sets of descriptors that can be defined in a commands file is 64. The name descriptor must be first in each set and is required. Each descriptor should be defined only once in each set. If defined more than once, only the last instance is used.
The following table lists the descriptors that can be used in a commands file to redefine or disable FMLI commands, and define new commands.
Commands File Descriptors
DESCRIPTOR |
DEFAULT IF NOT DEFINED |
TYPE |
DEFAULT EVALUATION TIME |
action |
no default * |
command |
At initialization time |
help |
no default |
command |
When user asks for help |
interrupt |
inherited value * |
Boolean |
When an action descriptor is evaluated |
name |
no default |
string |
At initialization time |
oninterrupt |
inherited value ** |
command |
After the action descriptor is interrupted |
An FMLI command is a command that is part of the Form and Menu Language and which forces a screen related operation to occur. FMLI commands cannot be executed in backquoted expressions; however, a backquoted expression can generate an FMLI command. Only descriptors of type command can evaluate to an FMLI command: action, done, help, oninterrupt, and rmenu. A command descriptor must evaluate to a single FMLI command. If it does not, the terminal bell will sound. The FMLI commands that take arguments are noted (See "What This Book is About" for an explanation of syntax notation).
NOTE: The maximum number of arguments that may be given in an FMLI command is 25. Remember, however, that a frame can only reference the first 10 arguments (ARG0-ARG9).
The following list briefly describes all the FMLI commands.
cancel [frameID...]
The cancel command evaluates the close descriptor of the current frame and attempts to close the frame. When selected from the Command Menu it closed the previously current frame. cancel closes a frame without executing the done descriptor.
The frameID argument can be an integer identifying a frame, the title of a frame (as defined in the menu, form, or title descriptors), or the pathname of a frame definition file. If frameID is a pathname, it can be relative of full, but it must match the pathname used when the frame was opened. If frameID is the title of a frame, it cannot include spaces. If frameID is not given, cancel closes the current frame.
cleanup
The cleanup command evaluates the lifetime descriptor of all open frames and closes those for which lifetime evaluates to shortterm or longterm.
close [frameID...]
The close command evaluates the lifetime, close and done descriptors of all frames named in the frameID argument list and closes them. Frames named as arguments when fmli is invoked, and those frames in which the lifetime descriptor evaluates to immortal (which means they close only when the user exits from the FMLI application) will remain open.
The close command has essentially the same functionality as the cancel command, and is a useful alternative when the cancel command has been disabled in the commands file. (Recall that disabling a command in the commands file makes it unavailable to developers as well as to users.)
The argument frameID must be an integer identifying the frame, or the pathname of the frame to close. If frameID is a pathname, it can be relative or full, but it must match the pathname used when the frame was opened. frameID can also be the title of a frame, if the title has no spaces in it. If frameID is not given, close removes the current frame.
checkworld
The checkworld command evaluates the reread descriptor for all open frames: any frame whose reread descriptor evaluates to TRUE is updated (see update command). This command is initiated by the SIGALRM signal every MAILCHECK seconds. It is also initiated by many other events, such as executing the open, close, goto, run, unix-system commands, and frame-to-frame navigation. When the checkworld command is executed, the message line clears. (This side-effect may confuse users, especially when they are not aware that a SIGALRM has occurred. A warning in your user documents may be warranted.)
choices
The choices command evaluates the rmenu and choicemsg descriptors (if defined), in the set of field descriptors defining the current field. If neither is defined, a message informs the user that no choices are available.
cmd-menu
The cmd-menu command opens the Command Menu frame, displaying it in the center of the work area.
done
The done command evaluates the done descriptor (if it has been defined) in a frame. In menu frames and in form frames, done is a descriptor of type command, but in text frames done is a descriptor of type Boolean. If done evaluates to FALSE in a text frame, the text frame stays open.
exit
The exit command evaluates the close descriptor for all open frames, except those named as arguments when fmli is invoked, and terminates the FMLI session.
frm-mgmt [cmd [franeID] ]
The frm-mgmt command allows you to move, reshape, or list currently open frames. It takes a maximum of two arguments; where cmd can be one of the sub-commands list, move, or reshape, and frameID is an integer or a pathname identifying the frame (menu or text frames only) to act on if cmd is move or reshape. If frameID is a pathname, it can be relative or full, but it must match the pathname used when the frame was opened. frameID is not given, a menu is displayed in the work area, from which a user can select list, move, or reshape. If the argument list is supplied, a frame will display a list of currently open frames. Selecting a frame from this list causes navigation to that frame. The argument lies does not accept a frameID option.
The argument move allows a frame to be moved to a different location in the work area. The argument reshape will not work on a form frame, but menu frames or text frames can be reshaped and/or moved to a different location in the work area. If the frameID argument is not supplied to the sub-commands move and reshape, the operation occurs for the current frame when frm-mgmt is used on a descriptor line, or for the most recently current frame when a user selects frm-mgmt from the Command Menu or Command line. If frameID is supplied, the operation occurs for the open frame with that frameID.
goto [frameID]
The goto command makes another frame current. frameID is the number of a frame or the pathname of the frame definition file. The pathname can be relative or full, but it must match the pathname used to open the frame. frameID can be the title of a frame if the title includes no spaces. Users should only be told about the frame number argument and the title type of argument.
The goto command is run when the command line is current and an integer is entered. For example, CTRL-j 2 equates to goto 2.
help
The help command evaluates the help descriptor if one has been defined for the current frame. If one hasn't been defined the indicator flashes.
mark
The mark command marks or unmarks the current item in menus for which the multiselect descriptor evaluates to TRUE.
nextpage
The nextpage command pages forward one page in the current frame, if that frame understands paging, and if the user is not on the last page of the frame. If the user is on the last page of the frame the terminal bell sounds. In forms, a page comprises all fields defined to be on a given page of the form (via the page descriptor). In menus and text frames, a page is a frameful of information.
next-frm
The next-frm command makes the "next frame" the current frame. FMLI keeps a list of each frame that has been the current frame: the "next frame" in the list is the last frame opened from the current frame. Since the "next frame" is always relative to the current frame the order of the list does not always follow frame ID order.
nop
The nop command does nothing. Because descriptors of type command must eventually evaluate to an FMLI command, nop is useful in those cases where you want to specify a backquoted expression to evaluate, but you do not want to execute a FMLI command. The terminal will beep when a descriptor of type command does not evaluate to an FMLI command. Including nop in the descriptor definition will prevent the terminal from beeping, while invoking no other operation.
open [type] filename [arg...]
The open command opens a frame. The argument type can be one of the file type casts MENU, FORM, or TEXT, and indicates the type of frame that is to be opened. The argument filename is the pathname of the frame definition file to be opened. The argument arg is a parameter that will be passed to the frame. In the following example:
OPEN FORM $MYOBJECTS/myform ARG1 ARG2
open opens a frame definition file $MYOBJECTS/myform, identified as a form frame definition file by the file type cast FORM, and passes the parameters ARG1 and ARG2 to it. An example of passing parameters can be found in "Creating a Dynamic Menu" in Chapter 3.
prev-frm
The prev-frm command makes the "previous frame" the current frame. FMLI keeps a list of each frame that has been the current frame: the "previous frame" in the lists is the frame from which the current frame was opened. Since the "previous frame" is always relative to the current frame the order of the list does not always follow frame ID order.
prevpage
The prevpage command pages backward one page in the current frame, if that frame understands paging, and if the user is not in the first page of the frame. In forms, a page comprises all fields defined to be on a given page of the form (via the page descriptor). In menus and text frames, a page is a screen-full of information. If the user is in the first page of the frame the terminal bell sounds.
refresh
The refresh command redraws the terminal screen. For example, refresh can be used if a broadcast message from the operating system corrupts the FMLI screen.
release
The release command displays on the message line the release number of the version of FMLI you are currently running. The release command is meant to be used from the command line. Partial matching cannot be used with release (the command name must be typed in full).
reset
The reset command resets the current field to its default value (its value when the frame was opened).
togslk
The togslk command causes FMLI to display the set of SLKs that is not currently being displayed. It is a toggle between the two sets.
unix-system
The unix-system command brings up the UNIX system shell in full screen mode.
update [frameID [mkcurr]]
The update command forces a frame definition file to be re-read regardless of the absence or value of the reread descriptor. If there are differences between what is read and what is on the screen, the frame will be re-drawn. update will not re-read the menu, form, or title descriptors. It takes two optional arguments; where frameID is an integer or a pathname identifying the frame to update. If frameID is a pathname, it can be relative or full, but it must match the pathname used when the frame was opened. frameID can also be the title of a frame, if the title has no spaces in it. The argument mkcurr determines if the frame will be made current once the update is done. The argument mkcurr must be a Boolean value; if it is not given, it defaults to FALSE. If no arguments are given, update updates the current frame.
After update is executed in a menu frame, the cursor is positioned on the first menu item. In a form frame, the cursor is positioned on the first field of the first page of the form. In a text frame, the cursor is positioned on the first line of text.
A subset of the FMLI command can be executed by users selecting them from the Command Menu.
Command Menu cancel next-frm cleanup prev-from exit refresh frm-mgmt unix-system goto update help
In addition, all FMLI commands can be executed from the command line. (Users can access the command line in an FMLI application by pressing CTRL-j or CTRL-f c.) FMLI commands that appear in the Command Menu or that are assigned to screen-labeled function keys should be explained in your user documentation. However, you should not document commands you do not want your users to use.
See Chapter 4, "Application Level Definition Files", for information about how you can add commands to, and disable command in the Command Menu and how you can redefine the action assigned to a screen-labeled function key as well as the screen label for it.
WARNING: When you disable an FMLI command in the commands file, the command becomes unavailable not only to users, but to developers. That is, you cannot use that command in frame definition files or application level files. In particular, do not disable the exit command.
Some FMLI commands also map directly to default screen-labeled function keys as shown in the table below.
Default Assignments of FMLI Commands to Function Keys
Screen-Labeled Function Key |
Menu Frame |
Form Frame |
Text Frame |
Choices Menu |
Command Menu |
F1 |
help |
help |
help |
help |
|
F2 |
mark* |
choices |
prevpage | ||
F3 |
enter |
save |
nextpage |
enter | |
F4 |
prev-frm |
prev-frm |
prev-frm | ||
F5 |
next-frm |
next-frm |
next-frm | ||
F6 |
cancel |
cancel |
cancel |
cancel |
cancel |
F7 |
cmd-menu |
cmd-menu |
cmd-menu | ||
F8 |
chg-keys** |
chg-keys** |
chg-keys** |
chg-keys** |
chg-keys** |
F16 |
chg-keys** |
chg-keys |
chg-keys** |
chg-keys** |
chg-keys** |
Built-in utilities provide often-needed programming functionality. By building them into FMLI they are more efficient to use than similar utilities provided in UNIX System V Release 4.0 (that is, there is no need to fork a process to run them). FMLI recognizes built-in utilities in stand-alone backquoted expressions, and in backquoted expressions on descriptor lines.
FMLI built-in utilities return a Boolean value. It is FALSE if either the string false or non-zero integer is returned, TRUE if 0 or any other string is returned. However, Boolean arguments to a utility follow standard format.
Below is a brief summary of the FMLI built-in utilities. There are manual pages for each of these.
echo
The echo utility outputs its operands.
fmlcut
The fmlcut utility is used to cut out selected fields of each line of a file. It has essentially the same functionality as the UNIX utility cut. It has been included as an FMLI built-in utility for performance reasons.
fmlgrep
The fmlgrep utility is used to search for a certain pattern in a file. It has essentially the same functionality as the UNIX utility grep. It has been included as an FMLI built-in utility for performance reasons.
fmlexpr
The fmlexpr utility evaluates its arguments as an expression, thus providing arithmetic and logical operations on integers, local operations on strings, and some pattern matching facilities. It evaluates a single expression and writes the result to standard output. It has essentially the same functionality as the UNIX utility expr. It has been included as an FMLI built-in utility for performance reasons.
getitems
The getitems utility takes as its only argument a delimiter string. It returns a list of the currently selected items, separated by the delimiter supplied.
getfrm
The getfrm utility returns the current frame number. It takes no arguments.
indicator
The indicator utility allows you to control the "working" indicator and bell, and allows you to define your won indicators on the banner line.
message
The message utility outputs its operands to the FMLI message line. The -t option outputs a "transient" message (lasts until another key is pressed), the -f option outputs a "frame permanent" message (lasts as long as the frame is current), and the -p option outputs a "permanent" message (lasts until another message is displayed, and reappears after that message clears). The terminal bell can also be made to sound.
pathconv
The pathconv utility converts an alias to a full pathname. It can also produce a shortened version of a pathname suitable for use as a frame title.
readfile, longline
The readfile utility reads the file passed as its argument and writes it to standard output. After a call to readfile, a call to longline will return the length (including carriage return) of the longest line in the previously read file. The longline utility can also take a file name argument, in which case it will return the length of the longest line in that file.
regex
The regex utility performs regular expression matching on its string input (utilizing regex(3X)). The regex utility is useful to dynamically generate the contents of a frame (see examples in Chapter 3). It can be used to approximate many of the capabilities of cut(1), paste(1), and grep(1), and some of the capabilities of sed(1).
reinit
The reinit utility takes as an argument the name of an initialization file. It is used to make global changes to the FMLI session while staying in the current application.
run
The run utility is used to invoke an executable in full screen mode.
set, unset
These utilities set and unset variables either in the FMLI process, the UNIX system environment, or in files.
setcolor
The setcolor utility allows you to redefine an existing color, or define new colors if your terminal allows more than the eight colors already defined in FMLI.
shell
The shell utility is used to run a command using the UNIX system shell. Although it is not often needed in an FMLI application, it is useful when an application has an executable with the same name as an FMLI built-in or to run a UNIX system shell built-in.
test
The test utility checks to see if a condition is true. test is useful in conditional statements. It has essentially the same format as test in the UNIX system shell.
Five other built-ins allow a frame or several frames (that is, form frames, menu frames, or text frames) to communicate to an external process through a pipe. The Form and Menu Language Interpreter will send strings to the external process and interpret the process;'s output accordingly. This capability if referred to as "co-processing," and the built-in co-processing utilities are as follows:
cocreate
The cocreate utility initializes communication to an independent co-process using named pipes.
cosend
The cosend utility sends strings from FMLI to the coprocess. The -n option performs a "no wait" condition that sends text, but doesn't block for a response.
cocheck
The cocheck utility checks the incoming pipe for information. It returns TRUE or FALSE.
coreceive
The coreceive utility performs a "no wait" read on the pipe. It takes a process ID as an argument.
codestroy
The codestroy utility terminates the communication.
For more information about how these co-processing utilities are used, see the coproc(1F) manual page.
The Form and Menu Language provides a conditional statement for use within backquoted expressions that has the following syntax:
if list then list [elif list then list] ...[else list] fi
where list is an optional newline, followed by a sequence of one or more FMLI statements, each of which must end with a semicolon.
Like conditional statements in the UNIX system shell language, the list following if is executed, and if the last command in the list has a zero exit status, then the list that follows then is executed. However, if the list following if has a non-zero exit status, the list following else will be executed. Multiple tests can be executed by using the elif clause. Conditional statements may be nested.
Output of a statement executed within an FMLI conditional construct can be redirected to a file specified after the statement.
The exit status of the conditional statement is the exit status of the last command executed in any then clause or else clause. If no such command was executed, the conditional statement returns a zero exit status.
NOTE: The FMLI conditional statement differs from the UNIX shell language conditional statement in some respects. The UNIX shell language allows either a newline, a semi-colon, or both, to end a statement, whereas FMLI only allows a semi-colon. Output of statements executed within an FMLI conditional construct cannot be piped to a statement following the fi of the construct. Similarly, output redirection of a file specified after the fi of the construct does not work. An FMLI conditional statement cannot occur following the $$ or || operators in a given backquoted expression.
(See "Built-In Utilities", in this chapter, and the manual pages for information on test and fmlexpr.)
Conditional statements are useful when only one of several actions is appropriate, based on user input. For example, assume that you have defined a form in which a user must enter either 1 or 2 in the first field to display one of two appropriate text frames. A conditional statement can be used to display an appropriate error message via the use of the descriptor invalidmsg, when the user enters an invalid response.
invalidmsg=`if [$F1 -gt 2]; then echo "APPLID:nnn: Selection code has to be less than 3"; else echo "APPPLID:nnn: Selection code has to be more than 0"; fi'
where $F1 (an FMLI built-in variable) evaluates to the current value of the first field, APPLID is the name of your application, and nnn is the message sequence number.
Another conditional statement can be used to open the text frame requested by the user. The descriptor done in the same form definition file would be defined as follows:
done=`if [$F1 = 1]; then echo "open text dir.explain"; else echo "open text file.explain"; fi'
Prior to Release 4.0 of FMLI, the only way an executable invoked from within an FMLI application could be interrupted was if it was invoked as an argument to the built-in utility run (except when the -s option is specified).
In Release 4.0 of FMLI, executables initiated in a backquoted expression that is the value of either the action or done descriptors--wherever they occur in your application--can also be designated as interruptible through the use of the interrupt descriptor. No other descriptors of type command (help, remenu, and oninterrupt) are affected by the interrupt descriptor.
The Boolean descriptor interrupt defines whether or not an executable can be interrupted by the user. It always defaults to FALSE. A companion to interrupt, the command descriptor oninterrupt, defines what will be done when the interrupt signal (SIGINT) is received. It always defaults to `message Operation interrupted!'nop. The value of oninterrupt can be any action normally permitted for a command descriptor (both backquoted expressions and FMLI commands). The oninterrupt descriptor is ignored if interrupt has not been defined anywhere in your application of if interrupt evaluates to FALSE.
Depending on the kind of frame definition file or application level file they are used in, these two descriptors are independently subject to one several inheritance hierarchies (see the following table, a table of inheritance hierarchies for interrupt and oninterrupt).
NOTE: The status of the interrupt descriptor only affects executables in backquoted expressions. Its status does not affect FMLI commands (such as cancel), built-in utilities other than run (such as shell), or any of their child processes. Nor does it affect processes run from FMLI that "take over the screen," such as the shell obtained by using the unix-system command from the command menu. (In these cases, interrupt handling is done by the full-screen application.)
The interrupt status in effect for an action or done descriptor applies to all executables in the descriptor. However, if the executable that is being executed when the interrupt signal is received has itself been coded to ignore interrupts, it will complete its normal execution, but remaining commands in the descriptor will not be executed. (FMLI built-in utilities behave the same as executable utilities that have been coded to ignore interrupts.) When an executable is interrupted, any commands (built-in utilities and FMLI commands, as well as other executables) remaining in the descriptor are ignored by the Interpreter. Instead, whatever you have defined to be the value of the oninterrup descriptor will be executed.
The scope of interrupt is independent from the scope of oninterrupte, and each depends on where it is coded. The highest level in the inheritance hierarchy is the one in effect for the current action or done descriptor. For example, coding interrup=true once, in the general descriptors section of an initialization file, means that all executables in any action or done descriptor anywhere in your application (including any in the commands file or defined for SLKs) can be interrupted by the user.
Continuing this example, if interrupt=false is then coded with the frame descriptors in a menu definition file, then the status of FALSE is inherited by all items defined for that menu, while all executables in all other frames remain interruptible. Going one step further, if interrupt=true is coded with the item descriptors for one item in that menu, then executables coded in that item's action descriptor will be interruptible by users, and all other items will remain uninterruptible. Inheritance of the value of the oninterrupt descriptor is handled the same way, but is completely distinct from the interrupt descriptor.
Theses descriptors can also be defined in the commands file (see Chapter 4 for a discussion of the commands file). If interrupt or oninterrupt are not defined for a command in the commands file, that command will inherit the value of interrupt and/or oninterrupt defined with the general descriptors in the initialization file. I not defined there, the FMLI default value is inherited.
Inheritance of these two descriptors is handled slightly differently for screen-labeled function keys. Redefining a SLK in a frame definition file completely overrides a definition of it you may have coded in the initialization file. For example, if you define interrupt for a particular SLK in the initialization file, but do not include interrupt in a re-definition of that SLK in a frame definition file, the SLK will inherit the value of the interrupt descriptor defined at the next lower inheritance level (from the frame descriptors if defined there, then from the general descriptors in the initialization file if defined there, then from the FMLI defaults).
The following table summarizes the inheritance hierarchies for both descriptors wherever they can be used:
Inheritance Hierarchies used to determine the values of interrupt and oninterrupt when interrupt key is pressed
Executables Coded In | ||||
Inheritance |
action Descriptor in: |
done |
||
Level |
menu items |
SLK definitions |
Command definitions |
Descriptor in: any frame |
1 (lowest) |
FMLI defaults |
FMLI defaults |
FMLI defaults |
FMLI defaults |
2 |
values coded with the general descriptors in an initialization file |
values coded with the general descriptors in an initialization file |
values coded with the general descriptors in an initialization file |
values coded with the general descriptors in an initialization file |
3 |
values coded with the frame descriptors in a menu definition file |
values coded with the frame descriptors in a menu definition file |
values coded in the commands file |
values coded with the frame descriptors in a menu definition file |
4 |
values coded with the item descriptors in a menu definition file |
values coded with the SLK descriptors in an initialization file* |
n/a |
n/a |
5 (highest) |
n/a |
values coded with the SLK descriptors in a frame definition file |
n/a |
n/a |
The terminal display attributes and the alternate character set defined in curses(3X) are supported in FMLI. If the terminal your application is being run on does not have these capabilities then they are approximated as best as possible by curses. If the terminal is capable of outputting graphic characters, inverse video, bol/dim, etc., then these attributes will be available in FMLI, in the following places:
The character sequence to turn a terminal attribute on in FMLI applications is of the form \+xx. To turn the attribute off, the form \-xx is used. If xx is not a valid FMLI character sequence for a terminal attribute, the entire character sequence, as coded, is output.
The following table lists the FMLI character sequence names and maps them to the application curses defined constant.
Table of FMLI Character Sequences for Display Attributes
FMLI Character Sequence |
curses defined constant |
Description |
so |
A_STANDOUT |
terminal's best highlighting mode |
ul |
A_UNDERLINE |
underlining |
rv |
A_REVERSE |
reverse video |
bk |
A_BLINK |
blinking |
dm |
A_DIM |
half bright |
bd |
A_BOLD |
extra bright or bold |
ac |
A-ALTCHARSET |
alternate character set |
nm |
A_NORMAL |
reset all attributes to off |
If the alternate character set attribute has been turned on in the text to be displayed (using /+ac), the alternate character set for line drawing (glyphs) will be displayed. This character set is shown in the table below.
Alternate Character Set
Character |
Default* |
Glyph Description |
a |
+ |
upper right corner** |
b |
+ |
lower right corner** |
c |
+ |
lower left corner** |
d |
+ |
upper left corner** |
1 |
+ |
top tee** |
2 |
+ |
right tee** |
3 |
+ |
bottom tee** |
4 |
+ |
left tee** |
- |
- |
horizontal line** |
| |
| |
vertical line** |
+ |
+ |
plus** |
< |
< |
arrow pointing left** |
> |
> |
arrow pointing right** |
v |
v |
arrow pointing down** |
^ |
^ |
arrow pointing up** |
# |
: |
checkerboard (stipple)** |
O |
# |
solid square block |
I |
# |
lantern symbol |
' |
+ |
diamond |
f |
' |
degree symbol |
g |
# |
plus/minus |
h |
# |
board of squares |
o |
- |
scan line 1 |
s |
_ |
scan line 9 |
~ |
o |
bullet |
An example of the sue of terminal display attributes is given in "Example Text Frame Definition Files", in Chapter 3.