menuc - menu compiler
menuc [-o name] file
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.
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 necssary 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. 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 sucessfully 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
appers 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 options appear in three forms:
variable = value
[no] switch
variable string
The variables for the first form are x, y, h, and w. These specify the
upper left (x,y) and the height (h) and width (w) of the menu window.
The upper left is in the curses coordinate system. If not specified, the
upper left is the upper left of the screen and the height and width of
the menu window is computed from the menu definition.
Options of the second form turn on or off (with the optional no) features
of the menu system. The box option turns on a box around the menu window.
The exit opton enables the standard exit option in the menus. The
scrollable option allows the menu to be scrollable if the menu window is
smaller than the number of menu options. The shortcut option prints a
single character shortcut with each menu option.
The third sets text variables. The variable title sets the text title
for the menus. The varible exitstring sets the text for the exit menu
option.
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 string>
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);
The options are a comma separated list of options as in the NaNdeclaration.
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. There may be an
arbitrary number of these items. (If there are shortcuts in the menu, a
practical limit of 51 should be recoginzed. 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.
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 {
char *opt_name;
int opt_menu;
int opt_flags;
int (*opt_action)(struct menudesc *);
} 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 {
char *title;
int y, x;
int h, w;
int mopt;
int numopts;
int cursel;
int topline;
menu_ent *opts;
WINDOW *mw;
char *helpstr;
char *exitstr;
void (*post_act)(void);
void (*exit_act)(void);
} menudesc ;
/* defines for mopt field. */
#define MC_NOEXITOPT 1
#define MC_NOBOX 2
#define MC_SCROLL 4
#define MC_NOSHORTCUT 8
int new_menu (char * title, menu_ent * opts, int numopts,
int x, int y, int h, int w, int mopt,
void (*post_act)(void), void (*exit_act)(void), char * help);
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, 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 the display action and the exit action. If
they are NULL, no call will be made. And finally, help is the text to
display in a help screen. A NULL help pointer will disable the help feature
for the menu.
/usr/share/misc/menu_sys.def
The following is a simple menu definition file. It is complete in that
the output of NaNmay be compiled into a complete program. For example,
if the following was in a file called NaNan 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);
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.\n");
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!\n");
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 { };
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.
BSD September 26, 1997 BSD
[ Back ] |