NAME
menuc —
menu compiler
SYNOPSIS
DESCRIPTION
This implements a curses based menu system. A source file that describes menus,
their options, and how to process the options is given to
menuc and produces both a .c and a .h file that implement
the menu system. The standard base name of the files is
menu_defs. The
-o
name can be used to specify a different base name.
ENVIRONMENT
-
-
MENUDEF
- Can be set to point to a different set of definition files
for menuc. The current location defaults to
/usr/share/misc.
The input
file defines static menus and options for
processing those menus. It also contains comments, initial C code that is
required to provide for definitions and other code necessary for the menu
system, and an option declaration if dynamic menus are requested.
Comments may appear anywhere in the input
file and are
like a space in the input. They are like C comments starting with
/* and ending with
*/. They are unlike C
comments in that they may be nested. A comment does not end until a matching
end comment is found.
In many places, C code is included in the definition
file.
All C code is passed verbatim to the C output file.
menuc
comments do not start in C code and comments in the C code are passed verbatim
to the output. The C comments are not recognized by
menuc.
In all cases, C code starts with a left brace (
{) and ends
with the matching right brace (
}). It is important to
recognize that in code segments, any brace will be counted, even if it is in a
C comment inside the code.
The
file contains an initial (and optional) code block
followed by any number of menu definition elements in any order. The initial
code block usually contains includes of header files used by code in the menu
code blocks later in the
file. If
USER_MENU_INIT
is #defined, then it will be evaluated
before the rest of the menu is initialised, if it evaluates to a non-zero
value then the initialisation will fail. The file is free format, so the
actual formatting of the input
file is to the taste of
the programmer.
All other C code that will appear in an
action. This will be
specified as ⟨
action⟩ in later text. Such an
action will appear as:
action <opt_endwin>
<code>
in the
file. The
⟨
opt_endwin⟩, if present is:
(endwin)
and specifies that the curses
endwin() function should be
called before executing the code and then reinstating the current curses
window after the code has been run. The ⟨
code⟩
is as described above.
There are four kinds of menu definition elements. The first one just declares
whether the programmer wants dynamic menus available. The default is static
menus only. The static menus are the ones defined by the menu definitions and
do not change at run time. The dynamic menus provide the programmer with a
method to create and modify menus during the running of the program. To
include dynamic menus, one needs only add the declaration:
allow dynamic menus;
The semicolon is required to terminate this declaration. This declaration may
appear anywhere in the
file, but usually appears before
any menus are defined.
The next element is a code block to execute if the curses screen can not be
successfully initialized. The declaration
error code;
tells the menu system to execute the associated code block if the initialization
fails. If no code is provided, a default code block is used that prints
Could not initialize curses.
and exits. This element may appear anywhere in the
file
but usually appears before any menus are defined.
The next element defines default options for menus. Each menu is built from a
list of options. These options include the location of the upper left corner
of the menu, whether there is a "box" drawn around the menu, whether
the menu is scrollable, the menu's title, whether shortcut letters are
allowed, whether a standard exit option should be included in the menu and
text associated with the standard exit option. The general format is:
default <comma separated option
list>;
The supported options are:
-
-
- x =
startx
- The column number of the upper left corner of the menu
window. If startx is -1 the menu will be centered
horizontally.
-
-
- y =
starty
- The row number of the upper left corner of the menu window.
If starty is negative then the menu will be placed
below any message text, but in at least row
-starty.
-
-
- h =
height
- Specifies the number of menu entries to be displayed. If
zero, the height will be based on the number of entries.
-
-
- h =
width
- Specifies the width of the menu window. If zero, the width
will be that of the longest menu text line.
-
-
- title
text
- The specified text will be displayed
at the top of the menu window (inside any box).
-
-
- box
- If specified, draw a box around the menu.
-
-
- clear
- If specified, clear the window before performing the
action.
-
-
- exit
- If specified add an addition option to exit the menu.
-
-
- exitstring
text
- The menu label for the exit option.
If not specified defaults to "exit".
-
-
- default
exit
- If specified, place the cursor on the
exit line of the menu, instead of the top line.
-
-
- shortcut
- If specified, add alphabetic tags to each menu line.
-
-
- scrollable
- If specified, and the menu has more lines than will fit in
its window, then only part of the menu will be displayed and the
‘<’ and ‘>’ keys will scroll the displayed
menu lines.
-
-
- always
scroll
- If specified, allow for the scroll message line even if the
menu doesn't appear to have too many lines. Useful for dynamic menus, when
the number of entries isn't known when the menu window is created..
-
-
- sub
menu
- If specified, the screen contents that the menu window
overwrites are saved and restored when the menu exits.
The
box,
clear,
exit,
default exit,
shortcut,
scrollable,
always scroll, and
sub menu options can be preceded by
no in
order to negate a default.
The
text arguments can be either a quoted text string or a
name #defined to something suitable for initialising a const char * field.
The default declaration may appear multiple times. Each time, it sets the
default values for menu definitions that follow in the
file. In each menu definition, any or all of these
default definitions may be overridden for that menu.
The final element is the actual static menu definitions. The format and order
for a menu definition is:
menu <name> <options> ;
<display action>
<menu items>
<exit action>
<help text>
Names are unquoted strings of alpha-numeric and underscore characters. They must
start with an alpha character. In C source, a menu named “foo” is
appears as “MENU_foo”. (Capitalization is important.) This is
important, because the menu is displayed and processed by calling the function
process_menu (MENU_foo, arg);
The options are a comma separated list of options as in the
“default” declaration. These override the options from the most
recent default declaration.
The display action is optional and provides C code to execute at each and every
time the menu is displayed for processing. If it is included, the format is:
display <action>;
The bulk of the menu definition is the specification of the menu items. The
general format of a menu item is:
option <string>,
<element_list>;
The ⟨
string⟩ is the text displayed for the menu
item, this must be a quoted string or a name #defined to something that will
initialise a const char * field. There may be an arbitrary number of these
items. (If there are shortcuts in the menu, a practical limit of 51 should be
recognized. It produces shortcuts a to w, y, z, and A to Z. x is the shortcut
for the exit item.)
The ⟨
element_list⟩ is a comma separated list of
what to do when the item is selected. They may appear in any order.
The first element processed when a menu item is selected is the associated
action. The next element to be processed is the sub or next menu option. They
are declared as:
next menu <name>
sub menu <name>
The difference between these two is that a sub menu will return to the current
menu when exited. The next menu will just replace the current menu and when
exited, will return to where the current menu would have gone. Only one of
menu element may be used for each menu item. Finally, after processing both
the action and a sub menu, the current menu will be exited if the element
exit
is specified.
Note: If
exit is specified,
next menu will not work because the menu system will exit the
current menu, even if current has been set by
next menu.
After all menu items, the final two menu definition elements may appear. The
exit action is optional and provides C code to execute in the process of
exiting a menu. If it is included, the format is:
exit <action>;
The final part of the menu definition is the optional help string. The format
is:
help <text>;
This text is displayed in a full page help window if the question mark is typed.
The actual help text starts with a left brace (
{) and ends
with the matching right brace (
}). The braces are not
included in the help string, but all other characters between them are
included. Newlines in the code translate to newlines in the help text.
Alternatively, the name of a const char * variable may be given.
If requested,
menuc supports dynamic menus by allowing the
user to create new menus. The related definitions for using dynamic menus are:
struct menudesc;
typedef
struct menu_ent {
const char *opt_name;
int opt_menu;
int opt_flags;
int (*opt_action)(struct menudesc *, void *);
} menu_ent ;
/* For opt_menu */
#define OPT_NOMENU -1
/* For opt_flags */
#define OPT_SUB 1
#define OPT_ENDWIN 2
#define OPT_EXIT 4
typedef
struct menudesc {
const char *title;
int y, x;
int h, w;
int mopt;
int numopts;
int cursel;
int topline;
menu_ent *opts;
WINDOW *mw;
WINDOW *sv_mw;
const char *helpstr;
const char *exitstr;
void (*post_act)(struct menudesc *, void *);
void (*exit_act)(struct menudesc *, void *);
void (*draw_line)(struct menudesc *, int, void *);
} menudesc ;
/* defines for mopt field. */
#define MC_NOEXITOPT 1
#define MC_NOBOX 2
#define MC_SCROLL 4
#define MC_NOSHORTCUT 8
#define MC_NOCLEAR 16
#define MC_DFLTEXIT 32
#define MC_ALWAYS_SCROLL 64
#define MC_SUBMENU 128
int new_menu(const char *title, menu_ent *opts, int numopts,
int x, int y, int h, int w, int mopt,
void (*post_act)(struct menudesc *, void *),
void (*draw_line)(struct menudesc *, int, void *),
void (*exit_act)(struct menudesc *, void *),
const char *help, const char *exitstr);
void free_menu (int menu_no);
The
title is the title displayed at the top of the menu.
The
opts is an array of menu entry definitions that has
numopts elements. The programmer must build this array
and fill in all of the fields before processing calling
process_menu() for the new menu. The fields of the
opts may change at any time. For example,
opt_name may change as a result of selecting that option.
When the menu is redisplayed, the new text is printed. Arguments,
x,
y,
h, and
w are the same as the options in the menu description.
mopt is the boolean options. Note, box, clear, exit and
shortcuts are enabled by default. You need to add option flags to turn them
off or turn on scrollable menus. The options
post_act,
and
exit_act are function pointers to the display action
and the exit action. If they are
NULL
, no call will be
made.
draw_line will be called to display the menu line
if the corresponding opt_name field is
NULL
.
help is the text to display in a help screen. And
finally,
exitstr is the text for the 'exit' line of the
menu. If
NULL
, "Exit" is used. A
NULL
help pointer will disable the help feature for
the menu.
FILES
- /usr/share/misc/menu_sys.def
EXAMPLES
The following is a simple menu definition file. It is complete in that the
output of
menuc may be compiled into a complete program. For
example, if the following was in a file called
example.mc,
an executable program could be produced by the following commands.
menuc -o example example.mc
cc -o example example.c -lcurses
A much more complete example is available with the source distribution in a
subdirectory called
testm.
/* This is an example menu definition file for menuc. */
{
#include <stdio.h>
#include <unistd.h>
/* Main program! This is often in a different file. */
int
main()
{
process_menu (MENU_main, NULL);
endwin();
return 0;
}
/* Example initialize function! */
void
init_main()
{
}
}
default x=20, y=10, box, scrollable, exit;
error action {
fprintf (stderr, "Example Menu: Could not initialize curses.");
exit(1);
};
menu main, title "Main Menu", no exit, no shortcut;
display action { init_main(); };
option "Option 1",
action (endwin) {
printf ("That was option 1!");
sleep(3);
};
option "Sub Menu", sub menu othermenu;
option "Next Menu", next menu othermenu;
option "Quit", exit;
help {
This is a simple help screen for an example menu definition file.
};
menu othermenu, title "Sub/Next Menu", x=5, y=5, no box;
option "Do Nothing!", action { };
SEE ALSO
msgc(1)
AUTHORS
Philip A. Nelson for Piermont Information Systems Inc.
Initial ideas for this were developed and implemented in Pascal at the Leiden
University, Netherlands, in the summer of 1980.
BUGS
Both
menuc and
msgc are probably only used
by
sysinst. The features of both have been tailored for
sysinst, and further changes are likely to occur.