xref: /illumos-gate/usr/src/cmd/genmsg/genmsg.y (revision 40cb5e5daa7b80bb70fcf8dadfb20f9281566331)
1 %{
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License, Version 1.0 only
7  * (the "License").  You may not use this file except in compliance
8  * with the License.
9  *
10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11  * or http://www.opensolaris.org/os/licensing.
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  *
23  * Copyright (c) 1995 by Sun Microsystems, Inc.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <stdio.h>
29 #include <libintl.h>
30 #include "genmsg.h"
31 extern int is_cat_found;		/* from main.c */
32 extern int lineno;			/* genmsg.l */
33 extern int msg_line;			/* genmsg.l */
34 extern int end_of_cat;			/* from genmsg.l */
35 extern void set_linemsgid(int, int);	/* from genmsg.l */
36 extern void add_msg(int, int, char *, char*, int, int);	/* from util.c */
37 
38 static void do_catgets(int, int, char*);
39 static char *add_qstring(char *, char*);
40 %}
41 
42 %union {
43 	char *str;
44 	int id;
45 }
46 
47 %token CATGETS
48 %token CONST
49 %token CATD
50 %token INT, CHAR, INC
51 %token <str> STR
52 %token <id> SETID, MSGID, DIGIT
53 %token <str> QSTR
54 
55 %type <id> cast_setid, setid, cast_msgid, msgid, cast_digit, digit
56 %type <str> catd, arg_list, arg_def, arg_func, arg_exp, str,
57 	cast_qstr, paren_qstr, qstr_list
58 
59 %left '-' '+'
60 %left '*' '/'
61 %nonassoc UMINUS
62 
63 %%
64 
65 genmsg_list:	/* empty */
66 		{
67 			if (!IsActiveMode(ReplaceMode)) {
68 				src_err(srcfile, (lineno - 1),
69 					gettext("catgets not found"));
70 			}
71 		}
72 	|	genmsg			{ is_cat_found = TRUE; }
73 	;
74 
75 genmsg:		catgets			{ end_of_cat = TRUE; }
76 	|	genmsg catgets		{ end_of_cat = TRUE; }
77 	;
78 
79 catgets:       CATGETS '(' catd ',' cast_setid ',' cast_msgid ',' cast_qstr ')'
80 		{
81 			do_catgets($5, $7, $9); free($9);
82 		}
83 	|	error
84 	;
85 
86 catd:		'(' CATD ')' arg_list		{ $$ = $4; }
87 	|	'(' CONST CATD ')' arg_list	{ $$ = $5; }
88 	|	arg_list
89 	;
90 
91 arg_list:	arg_def
92 	|	arg_list '-' '>' arg_def
93 	|	'(' arg_list '-' '>' arg_def ')'{ $$ = $2; }
94 	;
95 
96 arg_def:	arg_func
97 	|	arg_exp
98 	|	str
99 	;
100 
101 arg_func:	'(' arg_func ')'	{ $$ = $2; }
102 	|	str '(' ')'
103 	|	str '(' str ')'
104 	|	str '(' cast_digit ')'
105 	|	str '(' cast_qstr ')'	{ free($3); }
106 	;
107 
108 arg_exp:	'(' arg_exp ')'		{ $$ = $2; }
109 	|	str INC
110 	|	INC str			{ $$ = $2; }
111 	;
112 
113 str:		'(' str ')'		{ $$ = $2; }
114 	|	'*' str			{ $$ = $2; }
115 	|	STR
116 	;
117 
118 cast_setid:	'(' INT ')' setid	{ $$ = $4; }
119 	|	'(' CONST INT ')' setid	{ $$ = $5; }
120 	|	setid
121 	;
122 
123 setid:		setid '+' setid		{ $$ = $1 + $3; }
124 	|	setid '-' setid		{ $$ = $1 - $3; }
125 	|	setid '*' setid		{ $$ = $1 * $3; }
126 	|	setid '/' setid
127 		{
128 			if ($3 == 0) {
129 				yyerror(gettext("zero divide"));
130 			} else {
131 				$$ = $1 / $3;
132 			}
133 		}
134 	|	'-' setid %prec UMINUS	{ $$ = -$2; }
135 	|	'(' setid ')'		{ $$ = $2; }
136 	|	SETID
137 	;
138 
139 cast_msgid:	'(' INT ')' msgid	{ $$ = $4; }
140 	|	'(' CONST INT ')' msgid	{ $$ = $5; }
141 	|	msgid
142 	;
143 
144 msgid:		msgid '+' msgid		{ $$ = $1 + $3; }
145 	|	msgid '-' msgid		{ $$ = $1 - $3; }
146 	|	msgid '*' msgid		{ $$ = $1 * $3; }
147 	|	msgid '/' msgid
148 		{
149 			if ($3 == 0) {
150 				yyerror(gettext("zero devide"));
151 			} else {
152 				$$ = $1 / $3;
153 			}
154 		}
155 	|	'-' msgid %prec UMINUS	{ $$ = -$2; }
156 	|	'(' msgid ')'		{ $$ = $2; }
157 	|	MSGID
158 	;
159 
160 cast_digit:	'(' INT ')' digit	{ $$ = $4; }
161 	|	'(' CONST INT ')' digit	{ $$ = $5; }
162 	|	digit
163 	;
164 
165 digit:		digit '+' digit		{ $$ = $1 + $3; }
166 	|	digit '-' digit		{ $$ = $1 - $3; }
167 	|	digit '*' digit		{ $$ = $1 * $3; }
168 	|	digit '/' digit
169 		{
170 			if ($3 == 0) {
171 				yyerror(gettext("zero divide"));
172 			} else {
173 				$$ = $1 / $3;
174 			}
175 		}
176 	|	'-' digit %prec UMINUS	{ $$ = -$2; }
177 	|	'(' digit ')'		{ $$ = $2; }
178 	|	DIGIT
179 	;
180 
181 cast_qstr:	'(' CHAR '*' ')' paren_qstr		{ $$ = $5; }
182 	|	'(' CONST CHAR '*' ')' paren_qstr	{ $$ = $6; }
183 	|	paren_qstr
184 	;
185 
186 paren_qstr:	'(' qstr_list ')'	{ $$ = $2; }
187 	|	qstr_list
188 	;
189 
190 qstr_list:	QSTR
191 	|	qstr_list QSTR		{ $$ = add_qstring($1, $2); }
192 	;
193 
194 %%
195 
196 static void
197 do_catgets(int setid, int msgid, char *str)
198 {
199 	int id = msgid;
200 	if (IsActiveMode(ReplaceMode)) {
201 		return;
202 	}
203 	if (setid == 0 || setid > NL_SETMAX) {
204 		src_err(srcfile, lineno,
205 			gettext("improper set number: %d"), setid);
206 		return;
207 	}
208 	if (IsActiveMode(ProjectMode)) {
209 		set_msgid(setid, id);
210 		add_msg(setid, id, str, srcfile, lineno, TRUE);
211 	} else if (IsActiveMode(ReverseMode)) {
212 		set_linemsgid(msg_line, NOMSGID);
213 	} else if (IsActiveMode(AutoNumMode)) {
214 		if (id == NOMSGID) {
215 			id = get_msgid(srcfile, msg_line, setid, str);
216 			set_linemsgid(msg_line, id);
217 		}
218 		if (id != NOMSGID) {
219 			set_msgid(setid, id);
220 			add_msg(setid, id, str, srcfile, lineno, FALSE);
221 		}
222 	} else if (id == NOMSGID) {
223 		warning(gettext("improper message number: -1"));
224 	} else {
225 		add_msg(setid, id, str, srcfile, lineno, FALSE);
226 	}
227 }
228 
229 static char *
230 add_qstring(char *str, char *add)
231 {
232 	int len1 = strlen(str);
233 	int len2 = strlen(add);
234 	/* 3 includes '\', '\n' and '\0' */
235 	char *tmp = malloc(len1 + len2 + 3);
236 	if (!tmp) {
237 		prg_err(gettext("fatal: out of memory"));
238 		exit(EXIT_FAILURE);
239 	}
240 	sprintf(tmp, "%s\\\n%s", str, add);
241 	free(str);
242 	free(add);
243 	return tmp;
244 }
245