Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
.\"	$NetBSD: menuc.1,v 1.39 2021/11/07 09:48:08 andvar Exp $
.\"
.\" Copyright 1997 Piermont Information Systems Inc.
.\" All rights reserved.
.\"
.\" Written by Philip A. Nelson for Piermont Information Systems Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\" 3. The name of Piermont Information Systems Inc. may not be used to endorse
.\"    or promote products derived from this software without specific prior
.\"    written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd February 25, 2019
.Dt MENUC 1
.Os
.Sh NAME
.Nm menuc
.Nd menu compiler
.Sh SYNOPSIS
.Nm
.Op Fl o Ar name
.Ar file
.Sh 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
.Nm
and produces both a .c and a .h file that implement the menu system.
The standard base name of the files is
.Pa menu_defs .
The
.Fl o Ar name
can be used to specify a different base name.
.Sh MENU DESCRIPTIONS
The input
.Ar 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.
.Pp
Comments may appear anywhere in the input file
and are like a space in the input.
They are like C comments starting with
.Li "/*"
and ending with
.Li "*/" .
They are unlike C comments in that they may be nested.
A comment does not end until a matching end comment is found.
.Pp
In many places, C code is included in the definition file.
All C code is passed verbatim to the C output file.
.Nm
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
.Nm .
In all cases, C code starts with a left brace
.Pq Ql \&{
and ends with the matching right brace
.Pq Ql \&} .
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.
.Pp
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
.Dv 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.
.Pp
All other C code that will appear in an
.Em action .
This will be specified as
.Aq Em action
in later text.
Such an action will appear as:
.Pp
.D1 Li action Ao Em opt_endwin Ac Ao Em code Ac
.Pp
in the file.
The
.Aq Em opt_endwin ,
is optional
.Ql "(endwin)"
and specifies that the curses
.Xr endwin 3
function should be called before executing the code and
then reinstating the current curses window after the
code has been run.
The
.Aq Em code
is as described above.
.Pp
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).
.Pp
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:
.Pp
.Dl "allow dynamic menus;"
.Pp
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.
.Pp
To enable internationalization by loading message files at
run time one needs to add the declaration:
.Pp
.Dl "allow dynamic messages;"
.Pp
To allow argument expansion on static menu strings (see below for a
detailed explanation), one needs to add the declaration:
.Pp
.Dl "allow expand;"
.Pp
The next element is a code block to execute if the curses
screen can not be successfully initialized.
The declaration
.Pp
.D1 Li error Li action Ao Em code Ac Ns Li \&;
.Pp
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
.Dq Could not initialize curses.
and exits.
This element may appear anywhere in the file
but usually appears before any menus are defined.
.Pp
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
.Dq 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.
.Pp
The
.Ic default
declaration defines default options for menus.
The general format is:
.Pp
.D1 Li default Ao Em comma separated option list Ac Ns Li \&;
.Pp
The supported options are:
.Bl -tag -width ".Ic exitstring Va text" -offset indent
.It Ic y = Va starty
The row number of the upper left corner of the menu window.
If
.Va starty
is negative then the menu will be placed below any message text, but
in at least row
.Va -starty .
.It Ic x = Va startx
The column number of the upper left corner of the menu window.
If
.Va startx
is -1 the menu will be centered horizontally.
.It Ic h = Va height
Specifies the number of menu entries to be displayed.
If zero, the height will be based on the number of entries.
.It Ic w = Va width
Specifies the width of the menu window.
If zero, the width will be that of the longest menu text line.
.It Ic title Va text
The specified
.Va text
will be displayed at the top of the menu window (inside any box).
.It Ic box
If specified, draw a box around the menu.
.It Ic clear
If specified, clear the window before performing the
.Va action .
.It Ic exit
If specified, add an additional option to exit the menu.
.It Ic exitstring Va text
The menu label for the
.Va exit
option.
If not specified defaults to
.Dq "Exit" .
.It Ic default exit
If specified, place the cursor on the exit
line of the menu, instead of the top line.
.It Ic shortcut
If specified, add alphabetic tags to each menu line.
.It Ic 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
.Ql <
and
.Ql >
keys will scroll the displayed menu lines.
.It Ic 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.
.It Ic sub menu
If specified, the screen contents that the menu window overwrites are saved
and restored when the menu exits.
.It Ic continuous title
If specified there is no vertical space between the title and the menu
content.
.El
.Pp
The
.Ic box , clear , exit , default exit , shortcut , scrollable , always scroll ,
and
.Ic sub menu
options can be preceded by
.Ic no
in order to negate a default.
.Pp
The
.Va text
arguments can be either a quoted text string or a preprocessor symbol defined
to something suitable for initialising a
.Vt "const char *"
field.
.Pp
The
.Ic 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.
.Pp
The
.Ic menu
element is the actual static menu definitions.
The format and order for a menu definition is:
.Bd -unfilled -offset indent
.Li menu Ao Em name Ac Ao Em options Ac Ns Li \&;
.Li " " Aq Em expand action
.Li " " Aq Em display action
.Li " " Aq Em menu items
.Li " " Aq Em exit action
.Li " " Aq Em help text
.Ed
.Pp
Menu names are unquoted strings of alpha-numeric and underscore
characters.
They must start with an alpha character.
In C source, a menu named
.Dq foo
is appears as
.Li MENU_foo .
(Capitalization is important.)
This is important, because the menu is displayed and processed by
calling the function
.Pp
.Dl "process_menu(MENU_foo, arg);"
.Pp
The options are a comma separated list of options as in the
.Ic default
declaration.
These override the options from the most recent default declaration.
.Pp
The expand action is optional and only available if the global option
.Ic allow expand
has been declared (see above).
For an example see below.
.Pp
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:
.Pp
.Dl display Ao Em action Ac Ns Li \&;
.Pp
The bulk of the menu definition is the specification
of the menu items.
The general format of a menu item is:
.Pp
.Dl option Ao Em string Ac Ns Li \&, Ao Em element_list Ac Ns Li \&;
.Pp
The
.Aq Em 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
.Vt "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
.Sq a
to
.Sq w ,
.Sq y ,
.Sq z ,
and
.Sq A
to
.Sq Z .
.Sq x
is the shortcut for the exit item.)
.Pp
The
.Aq Em element_list
is a comma separated list of what to do when the item is selected.
They may appear in any order.
.Pp
The first element processed when a menu item
is selected is the associated action.
The next element to be processed is the
.Ic sub
or
.Ic next menu
option.
They are declared as:
.Pp
.Dl sub menu Aq Em name
and
.Dl next menu Aq Em name
.Pp
The difference between these two is that a
.Dq sub
menu will return to the current menu when exited.
The
.Dq next
menu will just replace the current
menu and when exited, will return to where the
current menu would have gone.
Only one of
.Ic 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
.Pp
.Dl exit
.Pp
is specified.
.Em Note :
If
.Ic exit
is specified,
.Ic next menu
will not work because
the menu system will exit the
.Em current
menu, even if current has been set by
.Ic next menu .
.Pp
After all menu items, the final two menu definition
elements may appear.
The
.Aq Em exit action
is optional and provides C code to
execute in the process of exiting a menu.
If it is included, the format is:
.Pp
.Dl exit Ao Em action Ac Ns Li \&;
.Pp
The final part of the menu definition is the optional
.Aq Em help string .
The format is:
.Pp
.Dl help Ao Em text Ac Ns Li \&;
.Pp
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
.Pq Ql \&{
and ends with the matching right brace
.Pq Ql \&} .
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
.Vt const char *
variable may be given.
.Sh DYNAMIC MENUS
If requested,
.Nm
supports dynamic menus by allowing the user to create new
menus.
The related definitions for using dynamic menus are:
.Bd -literal
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);
.Ed
.Pp
If
.Ic allow expand
has been declared, the
.Vt menudesc
structure contains another member,
.Fa expand_act :
.Pp
.Dl "void (*expand_act)(struct menudesc *, void *);"
.Pp
This function (if not null) is called once when initializing
a menu, before the display action
.Fa post_act
is called.
.Pp
The
.Fa title
is the title displayed at the top of the menu.
The
.Fa opts
is an array of menu entry definitions that has
.Fa numopts
elements.
The programmer must build this array and
fill in all of the fields before processing calling
.Fn process_menu
for the new menu.
The fields of the
.Fa opts
may change at any time.
For example,
.Fa opt_name
may change as a result of selecting that option.
When the menu is redisplayed, the new text is printed.
Arguments
.Fa x , y , h ,
and
.Fa w
are the same as the options in the menu description.
.Fa mopt
is the boolean options.
Note,
.Ic box ,
.Ic clear ,
.Ic exit
and
.Ic shortcuts
are enabled by default.
You need to add option flags to turn them off or turn on scrollable menus.
The options
.Fa post_act ,
and
.Fa exit_act
are function pointers to the display action and the exit action.
If they are null,
no call will be made.
.Fa draw_line
will be called to display the menu line if the corresponding
.Fa opt_name
field is null.
.Fa help
is the text to display in a help screen.
A null
.Fa help
pointer will disable the help feature for the menu.
And finally,
.Fa exitstr
is the text for the exit line of the menu.
If it's null, string
.Dq Exit
is used.
.Sh MENU ITEM ACTIONS
When creating dynamic menus, the programmer supplies function pointers
for the menu items
.Dv opt_action
member.
This functions return one of three possible values:
.Bl -tag -width "-1" -compact
.It 0
process sub menu (if set) and continue with the current (or new) menu
as usual.
.It 1
exit the current menu.
This is equivalent to specifying
.Dq exit
in a non-dynamic menu specification.
.It -1
do not handle the current item any further and restart handling the (same)
menu.
This return value is used when actions modify the menu definition on the
fly, e.g. adding or removing additional menu items.
The action may set
.Dq cursel
to jump to an arbitrary menu item (in the modified menu).
.El
.Sh MENU ITEM EXPANSION
With the
.Ic enable expansion
declaration in effect, static menus may be customized before being displayed.
This allows parameter substitution or special formatting of the menu item
strings without having to resort to a full dynamic menu.
Expanded strings are stored in the
.Fa opt_exp_name
member of struct
.Vt menu_ent .
This string is preferred over the non-expanded string
.Fa opt_name
when displaying the menu.
The expand action code is responsible for filling this pointers.
When leaving the menu, all
.Fa opt_exp_name
pointers that are populated will be automatically freed by calling
.Xr free 3 .
.Pp
A very simple (and nonsensical) example for an expand option would
be:
.Bd -literal -offset indent
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;
	}
};
.Ed
which would force the first character of all menu items to lower case.
The
.Xr free 3
call for the
.Xr strdup 3
call in above code is automatically handled on menu exit.
.Sh ENVIRONMENT
.Bl -tag -width ".Ev MENUDEF"
.It Ev MENUDEF
Can be set to point to a different set of definition files for
.Nm .
The current location defaults to
.Pa /usr/share/misc .
.El
.Sh FILES
.Bl -item
.It
.Pa /usr/share/misc/menu_sys.def
.El
.Sh EXAMPLES
The following is a simple menu definition file.
It is complete in that the output of
.Nm
may be compiled into a complete program.
For example, if the following was in a file called
.Pa example.mc ,
an executable program could be produced by the following commands.
.Bd -literal -offset indent
menuc -o example example.mc
cc -o example example.c -lcurses
.Ed
.Pp
A much more complete example is available with the source
distribution in a subdirectory called
.Pa testm .
.Bd -literal
/* 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 { };
.Ed
.Sh SEE ALSO
.Xr msgc 1
.Sh AUTHORS
.An 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.
.Sh BUGS
Both
.Nm
and
.Nm msgc
are probably only used by
.Nm sysinst .
The features of both have been tailored for
.Nm sysinst ,
and further changes are likely to occur.