Merge commit '00f1a4f432b3d8aad1aa270e91c44c57f03ef407'
[unleashed.git] / usr / src / cmd / genmsg / genmsg.y
blobf5451ab6fd79f3c8028d7848afac6146a4627321
1 %{
2 /*
3 * CDDL HEADER START
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <libintl.h>
31 #include <limits.h>
32 #include "genmsg.h"
33 extern int is_cat_found; /* from main.c */
34 extern int lineno; /* genmsg.l */
35 extern int msg_line; /* genmsg.l */
36 extern int end_of_cat; /* from genmsg.l */
37 extern void set_linemsgid(int, int); /* from genmsg.l */
38 extern void add_msg(int, int, char *, char *, int, int); /* from util.c */
39 extern void set_msgid(int, int);
40 extern int get_msgid(char *, int, int, char *);
41 extern void warning(char *);
42 extern void yyerror(char *);
43 extern int yylex(void);
45 static void do_catgets(int, int, char *);
46 static char *add_qstring(char *, char *);
49 %union {
50 char *str;
51 int id;
54 %token CATGETS
55 %token CONST
56 %token CATD
57 %token INT, CHAR, INC
58 %token <str> STR
59 %token <id> SETID, MSGID, DIGIT
60 %token <str> QSTR
62 %type <id> cast_setid, setid, cast_msgid, msgid, cast_digit, digit
63 %type <str> catd, arg_list, arg_def, arg_func, arg_exp, str,
64 cast_qstr, paren_qstr, qstr_list
66 %left '-' '+'
67 %left '*' '/'
68 %nonassoc UMINUS
72 genmsg_list: /* empty */
74 if (!IsActiveMode(ReplaceMode)) {
75 src_err(srcfile, (lineno - 1),
76 gettext("catgets not found"));
79 | genmsg { is_cat_found = TRUE; }
82 genmsg: catgets { end_of_cat = TRUE; }
83 | genmsg catgets { end_of_cat = TRUE; }
86 catgets: CATGETS '(' catd ',' cast_setid ',' cast_msgid ',' cast_qstr ')'
88 do_catgets($5, $7, $9); free($9);
90 | error
93 catd: '(' CATD ')' arg_list { $$ = $4; }
94 | '(' CONST CATD ')' arg_list { $$ = $5; }
95 | arg_list
98 arg_list: arg_def
99 | arg_list '-' '>' arg_def
100 | '(' arg_list '-' '>' arg_def ')' { $$ = $2; }
103 arg_def: arg_func
104 | arg_exp
105 | str
108 arg_func: '(' arg_func ')' { $$ = $2; }
109 | str '(' ')'
110 | str '(' str ')'
111 | str '(' cast_digit ')'
112 | str '(' cast_qstr ')' { free($3); }
115 arg_exp: '(' arg_exp ')' { $$ = $2; }
116 | str INC
117 | INC str { $$ = $2; }
120 str: '(' str ')' { $$ = $2; }
121 | '*' str { $$ = $2; }
122 | STR
125 cast_setid: '(' INT ')' setid { $$ = $4; }
126 | '(' CONST INT ')' setid { $$ = $5; }
127 | setid
130 setid: setid '+' setid { $$ = $1 + $3; }
131 | setid '-' setid { $$ = $1 - $3; }
132 | setid '*' setid { $$ = $1 * $3; }
133 | setid '/' setid
135 if ($3 == 0) {
136 yyerror(gettext("zero divide"));
137 } else {
138 $$ = $1 / $3;
141 | '-' setid %prec UMINUS { $$ = -$2; }
142 | '(' setid ')' { $$ = $2; }
143 | SETID
146 cast_msgid: '(' INT ')' msgid { $$ = $4; }
147 | '(' CONST INT ')' msgid { $$ = $5; }
148 | msgid
151 msgid: msgid '+' msgid { $$ = $1 + $3; }
152 | msgid '-' msgid { $$ = $1 - $3; }
153 | msgid '*' msgid { $$ = $1 * $3; }
154 | msgid '/' msgid
156 if ($3 == 0) {
157 yyerror(gettext("zero devide"));
158 } else {
159 $$ = $1 / $3;
162 | '-' msgid %prec UMINUS { $$ = -$2; }
163 | '(' msgid ')' { $$ = $2; }
164 | MSGID
167 cast_digit: '(' INT ')' digit { $$ = $4; }
168 | '(' CONST INT ')' digit { $$ = $5; }
169 | digit
172 digit: digit '+' digit { $$ = $1 + $3; }
173 | digit '-' digit { $$ = $1 - $3; }
174 | digit '*' digit { $$ = $1 * $3; }
175 | digit '/' digit
177 if ($3 == 0) {
178 yyerror(gettext("zero divide"));
179 } else {
180 $$ = $1 / $3;
183 | '-' digit %prec UMINUS { $$ = -$2; }
184 | '(' digit ')' { $$ = $2; }
185 | DIGIT
188 cast_qstr: '(' CHAR '*' ')' paren_qstr { $$ = $5; }
189 | '(' CONST CHAR '*' ')' paren_qstr { $$ = $6; }
190 | paren_qstr
193 paren_qstr: '(' qstr_list ')' { $$ = $2; }
194 | qstr_list
197 qstr_list: QSTR
198 | qstr_list QSTR { $$ = add_qstring($1, $2); }
203 static void
204 do_catgets(int setid, int msgid, char *str)
206 int id = msgid;
207 if (IsActiveMode(ReplaceMode)) {
208 return;
210 if (setid == 0 || setid > NL_SETMAX) {
211 src_err(srcfile, lineno,
212 gettext("improper set number: %d"), setid);
213 return;
215 if (IsActiveMode(ProjectMode)) {
216 set_msgid(setid, id);
217 add_msg(setid, id, str, srcfile, lineno, TRUE);
218 } else if (IsActiveMode(ReverseMode)) {
219 set_linemsgid(msg_line, NOMSGID);
220 } else if (IsActiveMode(AutoNumMode)) {
221 if (id == NOMSGID) {
222 id = get_msgid(srcfile, msg_line, setid, str);
223 set_linemsgid(msg_line, id);
225 if (id != NOMSGID) {
226 set_msgid(setid, id);
227 add_msg(setid, id, str, srcfile, lineno, FALSE);
229 } else if (id == NOMSGID) {
230 warning(gettext("improper message number: -1"));
231 } else {
232 add_msg(setid, id, str, srcfile, lineno, FALSE);
236 static char *
237 add_qstring(char *str, char *add)
239 int len = strlen(str) + strlen(add) + 3;
240 /* 3 includes '\', '\n' and '\0' */
241 char *tmp = malloc(len);
242 if (tmp == NULL) {
243 prg_err(gettext("fatal: out of memory"));
244 exit(EXIT_FAILURE);
246 (void) snprintf(tmp, len, "%s\\\n%s", str, add);
247 free(str);
248 free(add);
249 return (tmp);