xref: /netbsd-src/usr.bin/menuc/parse.y (revision c9e3ec3ad513aaa4fc10b614cc4105c8055817ae)
1 /*	$NetBSD: parse.y,v 1.19 2019/06/23 22:48:15 christos Exp $	*/
2 
3 /*
4  * Copyright 1997 Piermont Information Systems Inc.
5  * All rights reserved.
6  *
7  * Written by Philip A. Nelson for Piermont Information Systems Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
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. The name of Piermont Information Systems Inc. may not be used to endorse
18  *    or promote products derived from this software without specific prior
19  *    written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 
36 %{
37 
38 #include <stdio.h>
39 #include "defs.h"
40 
41 static id_rec *cur_menu;
42 static optn_info *cur_optn;
43 #define OPT_NOMENU 0
44 
45 %}
46 
47 %union {
48 	char *s_value;
49 	int   i_value;
50 	optn_info *optn_value;
51 	action a_value;
52 }
53 
54 
55 %token <i_value> X Y W H NO BOX SUB HELP MENU NEXT EXIT ACTION ENDWIN OPTION
56 %token <i_value> TITLE DEFAULT DISPLAY ERROR EXITSTRING EXPAND ALLOW DYNAMIC
57 		 MENUS SCROLLABLE SHORTCUT CLEAR MESSAGES ALWAYS SCROLL
58 		 CONTINUOUS
59 %token <s_value> STRING NAME CODE INT_CONST CHAR_CONST
60 
61 %type <s_value> init_code system helpstr text
62 %type <optn_value> option option_list
63 %type <i_value> act_opt
64 %type <a_value> action exitact
65 
66 %start system
67 
68 %%
69 
70 system : init_code menu_list
71 	 { check_defined();
72 	   if (!had_errors)
73 		   write_menu_file($1);
74 	 }
75        ;
76 
77 init_code : /* empty */ { $$ = ""; }
78 	  | CODE
79 	  ;
80 
81 menu_list :  /* empty */
82 	  |  menu_list menu_def
83 	  |  menu_list default_def
84 	  |  menu_list initerror_def
85 	  |  menu_list expand_def
86 	  |  menu_list dynamic_def
87 	  |  menu_list msgxlat_def
88 	  ;
89 
90 dynamic_def : ALLOW DYNAMIC MENUS ';'
91 		{ do_dynamic = 1; }
92 
93 expand_def : ALLOW EXPAND ';'
94 		{ do_expands = 1; }
95 
96 msgxlat_def : ALLOW DYNAMIC MESSAGES ';'
97 		{ do_msgxlat = 1; }
98 
99 initerror_def : ERROR action ';'
100 		{ error_act = $2; }
101 
102 default_def : DEFAULT
103 		{ cur_menu = &default_menu; }
104 	      opt opt_list ";"
105 
106 menu_def  :  MENU NAME
107 		{ cur_menu = get_menu ($2);
108 		  if (cur_menu->info != NULL)
109 			  yyerror ("Menu %s defined twice", $2);
110 		  else {
111 			  cur_menu->info = malloc (sizeof (menu_info));
112 			  *(cur_menu->info) = default_info;
113 		  }
114 		}
115 	     opts ";" expaction dispact option_list exitact helpstr
116 		{ optn_info *t;
117 		  cur_menu->info->optns = NULL;
118 		  while ($8 != NULL) {
119 			  t = $8;
120 			  $8 = $8->next;
121 			  t->next = cur_menu->info->optns;
122 			  cur_menu->info->optns = t;
123 			  cur_menu->info->numopt++;
124 		  }
125 		}
126 	  ;
127 
128 opts	  : /* empty */
129 	  | opt_list
130 	  ;
131 
132 opt_list  : "," opt
133 	  | opt_list "," opt
134 	  ;
135 
136 text	  : NAME | STRING
137 
138 opt	  : NO EXIT		{ cur_menu->info->mopt |= MC_NOEXITOPT; }
139 	  | EXIT		{ cur_menu->info->mopt &= ~MC_NOEXITOPT; }
140 	  | NO BOX		{ cur_menu->info->mopt |= MC_NOBOX; }
141 	  | BOX			{ cur_menu->info->mopt &= ~MC_NOBOX; }
142 	  | NO SCROLLABLE	{ cur_menu->info->mopt &= ~MC_SCROLL; }
143 	  | SCROLLABLE		{ cur_menu->info->mopt |= MC_SCROLL; }
144 	  | NO SHORTCUT 	{ cur_menu->info->mopt |= MC_NOSHORTCUT; }
145 	  | SHORTCUT 		{ cur_menu->info->mopt &= ~MC_NOSHORTCUT; }
146 	  | NO CLEAR 		{ cur_menu->info->mopt |= MC_NOCLEAR; }
147 	  | CLEAR 		{ cur_menu->info->mopt &= ~MC_NOCLEAR; }
148 	  | NO DEFAULT EXIT	{ cur_menu->info->mopt &= ~MC_DFLTEXIT; }
149 	  | DEFAULT EXIT 	{ cur_menu->info->mopt |= MC_DFLTEXIT; }
150 	  | NO ALWAYS SCROLL	{ cur_menu->info->mopt &= ~MC_ALWAYS_SCROLL; }
151 	  | ALWAYS SCROLL 	{ cur_menu->info->mopt |= MC_ALWAYS_SCROLL; }
152 	  | NO SUB MENU		{ cur_menu->info->mopt &= ~MC_SUBMENU; }
153 	  | SUB MENU 		{ cur_menu->info->mopt |= MC_SUBMENU; }
154 	  | CONTINUOUS TITLE	{ cur_menu->info->mopt |= MC_CONTINUOUS; }
155 	  | X "=" INT_CONST	{ cur_menu->info->x = atoi($3); }
156 	  | Y "=" INT_CONST	{ cur_menu->info->y = atoi($3); }
157 	  | W "=" INT_CONST	{ cur_menu->info->w = atoi($3); }
158 	  | H "=" INT_CONST	{ cur_menu->info->h = atoi($3); }
159 	  | TITLE text	 	{ cur_menu->info->title = $2; }
160 	  | EXITSTRING text	{ cur_menu->info->exitstr = $2;
161 				  cur_menu->info->mopt &= ~MC_NOEXITOPT; }
162 	  ;
163 
164 option_list : option
165 	  | option_list option  { $2->next = $1; $$ = $2; }
166 	  ;
167 
168 option	  : OPTION
169 		{ cur_optn = calloc(1, sizeof(*cur_optn));
170 		  cur_optn->optact.code = "";
171 		}
172 	    option_legend ","
173 	    elem_list ";"
174 		{ $$ = cur_optn; }
175 	  ;
176 
177 option_legend : text	{ cur_optn->name = $1; }
178 	  | CODE	{ cur_optn->name = $1; cur_optn->name_is_code = TRUE;}
179 
180 elem_list : elem
181 	  | elem_list "," elem
182 	  ;
183 
184 elem	  : NEXT MENU NAME
185 		{ id_rec *t = get_menu ($3);
186 		  if (cur_optn->menu != OPT_NOMENU)
187 			  yyerror ("Double sub/next menu definition");
188 		  else {
189 			  cur_optn->menu = t->menu_no;
190 		  }
191 		}
192 	  | SUB MENU NAME
193 		{ id_rec *t = get_menu ($3);
194 		  if (cur_optn->menu != OPT_NOMENU)
195 			  yyerror ("Double sub/next menu definition");
196 		  else {
197 			  cur_optn->menu = t->menu_no;
198 			  cur_optn->issub = TRUE;
199 		  }
200 		}
201 	  | action	{ cur_optn->optact = $1; }
202 	  | EXIT	{ cur_optn->doexit = TRUE; }
203 	  ;
204 
205 action	  : ACTION act_opt CODE
206 		{ $$.code = $3;
207 		  $$.endwin = $2;
208 		}
209 	  ;
210 
211 act_opt	  : /* empty */		{ $$ = 0; }
212 	  | "(" ENDWIN ")"	{ $$ = 1; }
213 	  ;
214 
215 expaction : /* empty */ 	{ cur_menu->info->expact.code = ""; }
216 	  | EXPAND action ";"	{ if (!do_expands) yyerror ("Menu expands "
217 	  						     "not enabled");
218 	  			  cur_menu->info->expact = $2; }
219 	  ;
220 
221 dispact	  : /* empty */ 	{ cur_menu->info->postact.code = ""; }
222 	  | DISPLAY action ";"	{ cur_menu->info->postact = $2; }
223 	  ;
224 
225 
226 exitact	  : /* empty */ 	{ cur_menu->info->exitact.code = ""; }
227 	  | EXIT action	";"	{ cur_menu->info->exitact = $2; }
228 	  ;
229 
230 helpstr	  : /* empty */ 	{ cur_menu->info->helpstr = NULL; }
231 	  | HELP CODE ";" 	{ asprintf(&cur_menu->info->helpstr, "\"%s\"", $2); }
232 	  | HELP text ";" 	{ cur_menu->info->helpstr = $2; }
233 	  ;
234