1 /* $NetBSD: mdb.c,v 1.43 2006/10/23 19:29:48 he Exp $ */
4 * Copyright 1997 Piermont Information Systems Inc.
7 * Written by Philip A. Nelson for Piermont Information Systems Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software develooped for the NetBSD Project by
20 * Piermont Information Systems Inc.
21 * 4. The name of Piermont Information Systems Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35 * THE POSSIBILITY OF SUCH DAMAGE.
39 /* mdb.c - menu database manipulation */
41 #if HAVE_NBTOOL_CONFIG_H
42 #include "nbtool_config.h"
45 #include <sys/cdefs.h>
47 #if defined(__RCSID) && !defined(lint)
48 __RCSID("$NetBSD: mdb.c,v 1.43 2006/10/23 19:29:48 he Exp $");
57 #include "pathnames.h"
62 static int menu_no
= 0;
63 static id_rec
*menus
[MAX
];
71 /* get_menu returns a pointer to a newly created id_rec or an old one. */
78 temp
= find_id (root
, name
);
82 temp
= (id_rec
*) malloc (sizeof(id_rec
));
83 temp
->id
= strdup(name
);
85 temp
->menu_no
= menu_no
;
86 menus
[menu_no
++] = temp
;
87 insert_id (&root
, temp
);
89 (void) fprintf (stderr
, "Too many menus. "
99 /* Verify that all menus are defined. */
106 for (i
=0; i
<menu_no
; i
++)
108 yyerror ("Menu '%s' undefined.", menus
[i
]->id
);
112 /* Write out the menu file. */
114 write_menu_file (char *initcode
)
132 /* Generate file names */
133 snprintf (hname
, 1024, "%s.h", out_name
);
134 nlen
= strlen(hname
);
135 if (hname
[nlen
-2] != '.' || hname
[nlen
-1] != 'h') {
136 (void) fprintf (stderr
, "%s: name `%s` too long.\n",
137 prog_name
, out_name
);
140 snprintf (cname
, 1024, "%s.c", out_name
);
142 /* Open the menu_sys file first. */
143 sys_prefix
= getenv ("MENUDEF");
144 if (sys_prefix
== NULL
)
145 sys_prefix
= _PATH_DEFSYSPREFIX
;
146 snprintf (sname
, 1024, "%s/%s", sys_prefix
, sys_name
);
147 sys_file
= fopen (sname
, "r");
148 if (sys_file
== NULL
) {
149 (void) fprintf (stderr
, "%s: could not open %s.\n",
154 /* Output the .h file first. */
155 out_file
= fopen (hname
, "w");
156 if (out_file
== NULL
) {
157 (void) fprintf (stderr
, "%s: could not open %s.\n",
163 (void) fprintf (out_file
, "%s",
164 "/* menu system definitions. */\n"
166 "#ifndef MENU_DEFS_H\n"
167 "#define MENU_DEFS_H\n"
168 "#include <stdlib.h>\n"
169 "#include <string.h>\n"
170 "#include <ctype.h>\n"
171 "#include <curses.h>\n\n"
175 (void)fprintf(out_file
, "#define MSG_XLAT(x) msg_string(x)\n");
177 (void)fprintf(out_file
, "#define MSG_XLAT(x) (x)\n");
179 (void)fprintf(out_file
, "#define DYNAMIC_MENUS\n");
180 if (do_dynamic
|| do_msgxlat
)
181 (void)fprintf(out_file
, "\n");
183 (void)fprintf(out_file
,
184 "typedef struct menudesc menudesc;\n"
185 "typedef struct menu_ent menu_ent;\n"
186 "struct menu_ent {\n"
187 " const char *opt_name;\n"
190 " int (*opt_action)(menudesc *, void *);\n"
192 "#define OPT_SUB 1\n"
193 "#define OPT_ENDWIN 2\n"
194 "#define OPT_EXIT 4\n"
195 "#define OPT_IGNORE 8\n"
196 "#define OPT_NOMENU -1\n\n"
197 "struct menudesc {\n"
198 " const char *title;\n"
208 " const char *helpstr;\n"
209 " const char *exitstr;\n"
210 " void (*post_act)(menudesc *, void *);\n"
211 " void (*exit_act)(menudesc *, void *);\n"
212 " void (*draw_line)(menudesc *, int, void *);\n"
215 "/* defines for mopt field. */\n"
217 #define MC_OPT(x) "#define " #x " " STR(x) "\n"
221 MC_OPT(MC_NOSHORTCUT
)
224 MC_OPT(MC_ALWAYS_SCROLL
)
231 (void) fprintf (out_file
, "%s",
234 "int menu_init(void);\n"
235 "void process_menu(int, void *);\n"
236 "void __menu_initerror(void);\n"
240 (void) fprintf (out_file
, "%s",
241 "int new_menu(const char *, menu_ent *, int, \n"
242 "\tint, int, int, int, int,\n"
243 "\tvoid (*)(menudesc *, void *), "
244 "void (*)(menudesc *, int, void *),\n"
245 "\tvoid (*)(menudesc *, void *), "
246 "const char *, const char *);\n"
247 "void free_menu(int);\n"
248 "void set_menu_numopts(int, int);\n"
251 (void) fprintf (out_file
, "\n/* Menu names */\n");
252 for (i
=0; i
<menu_no
; i
++) {
253 (void) fprintf (out_file
, "#define MENU_%s\t%d\n",
258 (void) fprintf (out_file
, "\n#define DYN_MENU_START\t%d",
261 (void) fprintf (out_file
, "\n#define MAX_STRLEN %d\n"
262 "#endif\n", max_strlen
);
266 out_file
= fopen (cname
, "w");
267 if (out_file
== NULL
) {
268 (void) fprintf (stderr
, "%s: could not open %s.\n",
274 fprintf (out_file
, "#include \"%s\"\n\n", hname
);
275 fprintf (out_file
, "%s\n\n", initcode
);
277 /* data definitions */
280 for (i
=0; i
<menu_no
; i
++) {
281 if (strlen(menus
[i
]->info
->postact
.code
)) {
282 (void) fprintf (out_file
,
284 "static void menu_%d_postact(menudesc *menu, void *arg)\n{\n", i
);
285 if (menus
[i
]->info
->postact
.endwin
)
286 (void) fprintf (out_file
, "\tendwin();\n");
287 (void) fprintf (out_file
,
289 menus
[i
]->info
->postact
.code
);
291 if (strlen(menus
[i
]->info
->exitact
.code
)) {
292 (void) fprintf (out_file
,
294 "static void menu_%d_exitact(menudesc *menu, void *arg)\n{\n", i
);
295 if (menus
[i
]->info
->exitact
.endwin
)
296 (void) fprintf (out_file
, "\tendwin();\n");
297 (void) fprintf (out_file
, "\t%s\n}\n\n",
298 menus
[i
]->info
->exitact
.code
);
301 toptn
= menus
[i
]->info
->optns
;
302 for (;toptn
!= NULL
; j
++, toptn
= toptn
->next
) {
303 if (strlen(toptn
->optact
.code
) == 0)
306 (void) fprintf (out_file
,
308 "static int opt_act_%d_%d(menudesc *m, void *arg)\n"
309 "{\n\t%s\n\treturn %s;\n}\n\n",
310 i
, j
, toptn
->optact
.code
,
311 (toptn
->doexit
? "1" : "0"));
317 for (i
=0; i
<menu_no
; i
++) {
318 if (menus
[i
]->info
->numopt
> 53) {
319 (void) fprintf (stderr
, "Menu %s has "
320 "too many options.\n",
321 menus
[i
]->info
->title
);
324 (void) fprintf (out_file
,
325 "static menu_ent optent%d[] = {\n", i
);
327 for (j
= 0, toptn
= menus
[i
]->info
->optns
; toptn
;
328 toptn
= toptn
->next
, j
++) {
329 name_is_code
+= toptn
->name_is_code
;
330 (void) fprintf (out_file
, "\t{%s,%d,%d,",
331 toptn
->name_is_code
? "0" : toptn
->name
,
333 (toptn
->issub
? OPT_SUB
: 0)
334 +(toptn
->doexit
? OPT_EXIT
: 0)
335 +(toptn
->optact
.endwin
? OPT_ENDWIN
: 0));
336 if (strlen(toptn
->optact
.code
))
337 (void) fprintf (out_file
, "opt_act_%d_%d}",
340 (void) fprintf (out_file
, "NULL}");
341 (void) fprintf (out_file
, "%s\n",
342 (toptn
->next
? "," : ""));
344 (void) fprintf (out_file
, "\t};\n\n");
347 menus
[i
]->info
->name_is_code
= 1;
348 fprintf(out_file
, "static void menu_%d_legend("
349 "menudesc *menu, int opt, void *arg)\n{\n"
350 "\tswitch (opt) {\n", i
);
351 for (j
= 0, toptn
= menus
[i
]->info
->optns
; toptn
;
352 toptn
= toptn
->next
, j
++) {
353 if (!toptn
->name_is_code
)
355 fprintf(out_file
, "\tcase %d:\n\t\t{%s};\n"
356 "\t\tbreak;\n", j
, toptn
->name
);
358 fprintf(out_file
, "\t}\n}\n\n");
365 (void) fprintf (out_file
, "static int num_menus = %d;\n", menu_no
);
368 (void) fprintf (out_file
, "static struct menudesc menu_def[] = {\n");
369 for (i
=0; i
<menu_no
; i
++) {
370 (void) fprintf (out_file
,
371 "\t{%s,%d,%d,%d,%d,%d,%d,0,0,optent%d,NULL,NULL,",
372 menus
[i
]->info
->title
, menus
[i
]->info
->y
,
373 menus
[i
]->info
->x
, menus
[i
]->info
->h
,
374 menus
[i
]->info
->w
, menus
[i
]->info
->mopt
,
375 menus
[i
]->info
->numopt
, i
);
376 if (menus
[i
]->info
->helpstr
== NULL
)
377 (void) fprintf (out_file
, "NULL");
379 tmpstr
= menus
[i
]->info
->helpstr
;
381 (void)fprintf(out_file
, "%s", tmpstr
);
383 /* Skip an initial newline. */
384 if (tmpstr
[1] == '\n')
386 (void) fprintf (out_file
, "\n");
388 if (*tmpstr
!= '\n') {
389 fputc (*tmpstr
++, out_file
);
392 (void) fprintf (out_file
, "\\n\"\n\"");
397 (void) fprintf (out_file
, ",");
398 if (menus
[i
]->info
->mopt
& MC_NOEXITOPT
)
399 (void) fprintf (out_file
, "NULL");
400 else if (menus
[i
]->info
->exitstr
!= NULL
)
401 (void) fprintf (out_file
, "%s",
402 menus
[i
]->info
->exitstr
);
404 (void) fprintf (out_file
, "\"Exit\"");
405 if (strlen(menus
[i
]->info
->postact
.code
))
406 (void) fprintf (out_file
, ",menu_%d_postact", i
);
408 (void) fprintf (out_file
, ",NULL");
409 if (strlen(menus
[i
]->info
->exitact
.code
))
410 (void) fprintf (out_file
, ",menu_%d_exitact", i
);
412 (void) fprintf (out_file
, ",NULL");
413 if (menus
[i
]->info
->name_is_code
)
414 (void) fprintf (out_file
, ",menu_%d_legend", i
);
416 (void) fprintf (out_file
, ",NULL");
418 (void) fprintf (out_file
, "},\n");
421 (void) fprintf (out_file
, "{NULL, 0, 0, 0, 0, 0, 0, 0, 0, "
422 "NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};\n\n");
424 /* __menu_initerror: initscr failed. */
425 (void) fprintf (out_file
,
426 "/* __menu_initerror: initscr failed. */\n"
427 "void __menu_initerror (void) {\n");
428 if (error_act
.code
== NULL
) {
429 (void) fprintf (out_file
,
430 "\t(void) fprintf (stderr, "
431 "\"%%s: Could not initialize curses\\n\", "
436 if (error_act
.endwin
)
437 (void) fprintf (out_file
, "\tendwin();\n");
438 (void) fprintf (out_file
, "%s\n}\n", error_act
.code
);
441 /* Copy menu_sys.def file. */
442 while ((ch
= fgetc(sys_file
)) != '\014') /* Control-L */
446 while ((ch
= fgetc(sys_file
)) != '\n')
448 while ((ch
= fgetc(sys_file
)) != EOF
)