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