MENUC(1) | General Commands Manual | MENUC(1) |
menuc
—
menuc |
[-o name]
file |
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.
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
preprocessor symbol 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⟩, is
optional ‘(endwin)
’ and specifies that
the curses endwin(3) 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, dynamic messages and argument expansion in menus available. All these option default to off (or static only).
Static menus are the ones defined by the menu definitions and do not change at run time. 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. See below for a detailed explanation of dynamic menus.
To enable internationalization by loading message files at run time one needs to add the declaration:
allow dynamic messages;
To allow argument expansion on static menu strings (see below for a detailed explanation), one needs to add the declaration:
allow expand;
The next element is a code block to execute if the curses screen can not be successfully initialized. The declaration
error
action
⟨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.
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 default
declaration defines default
options for menus. The general format is:
default
⟨comma separated option
list⟩;
The supported options are:
y =
startyx =
startxh =
heightw =
widthtitle
textbox
clear
exit
exitstring
textdefault
exit
shortcut
scrollable
<
’ and
‘>
’ keys will scroll the
displayed menu lines.always
scroll
sub
menu
continuous
title
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 preprocessor symbol 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 menu
element is the actual static menu
definitions. The format and order for a menu definition is:
menu
⟨name ⟩ ⟨options ⟩;
⟨expand action ⟩
⟨display action ⟩
⟨menu items ⟩
⟨exit action ⟩
⟨help text ⟩
Menu 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 expand action is optional and only available if the global
option allow expand
has been declared (see above).
For an example see below.
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 preprocessor symbol 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:
sub menu
⟨name⟩
next 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.
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 0 /* For opt_flags */ #define OPT_SUB 1 #define OPT_ENDWIN 2 #define OPT_EXIT 4 #define OPT_IGNORE 8 #define OPT_NOSHORT 16 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 #define MC_CONTINUOUS 256 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);
If allow expand
has been declared, the
menudesc structure contains another member,
expand_act:
void (*expand_act)(struct menudesc *,
void *);
This function (if not null) is called once when initializing a menu, before the display action post_act is called.
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. A null
help pointer will disable the help feature for the
menu. And finally, exitstr is the text for the exit
line of the menu. If it's null, string “Exit” is used.
opt_action
member. This functions return
one of three possible values:
enable expansion
declaration in effect, static
menus may be customized before being displayed. This allows parameter
substition or special formatting of the menu item strings without having to
resort to a full dynamic menu. Expanded strings are stored in the
opt_exp_name member of struct
menu_ent. This string is prefered over the non-expanded
string opt_name when displaying the menu. The expand
action code is responsible for filling this pointers. When leaving the menu,
all opt_exp_name pointers that are populated will be
automatically freed by calling
free(3).
A very simple (and nonsensial) example for an expand option would be:
expand action { int i; for (i = 0; i < menu->numopts; i++) { const char *s = MSG_XLAT(menu->opts[i].opt_name); if (s == NULL) continue; char *t = strdup(s); t[0] = tolower((unsigned char)t[0]); menu->opts[i].opt_exp_name = t; } };
MENUDEF
menuc
. The current location defaults to
/usr/share/misc.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 { };
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.
February 25, 2019 | NetBSD 9.2 |