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 (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <stdio.h> 28 #include <libintl.h> 29 #include <limits.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 extern void set_msgid(int, int); 38 extern int get_msgid(char *, int, int, char *); 39 extern void warning(char *); 40 extern int yyerror(const char *); 41 extern int yylex(void); 42 43 static void do_catgets(int, int, char *); 44 static char *add_qstring(char *, char *); 45 %} 46 47 %union { 48 char *str; 49 int id; 50 } 51 52 %token CATGETS 53 %token CONST 54 %token CATD 55 %token INT CHAR INC 56 %token <str> STR 57 %token <id> SETID MSGID DIGIT 58 %token <str> QSTR 59 60 %type <id> cast_setid setid cast_msgid msgid cast_digit digit 61 %type <str> catd arg_list arg_def arg_func arg_exp str 62 %type <str> cast_qstr paren_qstr qstr_list 63 64 %left '-' '+' 65 %left '*' '/' 66 %nonassoc UMINUS 67 68 %% 69 70 genmsg_list: /* empty */ 71 { 72 if (!IsActiveMode(ReplaceMode)) { 73 src_err(srcfile, (lineno - 1), 74 gettext("catgets not found")); 75 } 76 } 77 | genmsg { is_cat_found = TRUE; } 78 ; 79 80 genmsg: catgets { end_of_cat = TRUE; } 81 | genmsg catgets { end_of_cat = TRUE; } 82 ; 83 84 catgets: CATGETS '(' catd ',' cast_setid ',' cast_msgid ',' cast_qstr ')' 85 { 86 do_catgets($5, $7, $9); free($9); 87 } 88 | error 89 ; 90 91 catd: '(' CATD ')' arg_list { $$ = $4; } 92 | '(' CONST CATD ')' arg_list { $$ = $5; } 93 | arg_list 94 ; 95 96 arg_list: arg_def 97 | arg_list '-' '>' arg_def 98 | '(' arg_list '-' '>' arg_def ')' { $$ = $2; } 99 ; 100 101 arg_def: arg_func 102 | arg_exp 103 | str 104 ; 105 106 arg_func: '(' arg_func ')' { $$ = $2; } 107 | str '(' ')' 108 | str '(' str ')' 109 | str '(' cast_digit ')' 110 | str '(' cast_qstr ')' { free($3); } 111 ; 112 113 arg_exp: '(' arg_exp ')' { $$ = $2; } 114 | str INC 115 | INC str { $$ = $2; } 116 ; 117 118 str: '(' str ')' { $$ = $2; } 119 | '*' str { $$ = $2; } 120 | STR 121 ; 122 123 cast_setid: '(' INT ')' setid { $$ = $4; } 124 | '(' CONST INT ')' setid { $$ = $5; } 125 | setid 126 ; 127 128 setid: setid '+' setid { $$ = $1 + $3; } 129 | setid '-' setid { $$ = $1 - $3; } 130 | setid '*' setid { $$ = $1 * $3; } 131 | setid '/' setid 132 { 133 if ($3 == 0) { 134 (void) yyerror(gettext("zero divide")); 135 } else { 136 $$ = $1 / $3; 137 } 138 } 139 | '-' setid %prec UMINUS { $$ = -$2; } 140 | '(' setid ')' { $$ = $2; } 141 | SETID 142 ; 143 144 cast_msgid: '(' INT ')' msgid { $$ = $4; } 145 | '(' CONST INT ')' msgid { $$ = $5; } 146 | msgid 147 ; 148 149 msgid: msgid '+' msgid { $$ = $1 + $3; } 150 | msgid '-' msgid { $$ = $1 - $3; } 151 | msgid '*' msgid { $$ = $1 * $3; } 152 | msgid '/' msgid 153 { 154 if ($3 == 0) { 155 (void) yyerror(gettext("zero divide")); 156 } else { 157 $$ = $1 / $3; 158 } 159 } 160 | '-' msgid %prec UMINUS { $$ = -$2; } 161 | '(' msgid ')' { $$ = $2; } 162 | MSGID 163 ; 164 165 cast_digit: '(' INT ')' digit { $$ = $4; } 166 | '(' CONST INT ')' digit { $$ = $5; } 167 | digit 168 ; 169 170 digit: digit '+' digit { $$ = $1 + $3; } 171 | digit '-' digit { $$ = $1 - $3; } 172 | digit '*' digit { $$ = $1 * $3; } 173 | digit '/' digit 174 { 175 if ($3 == 0) { 176 (void) yyerror(gettext("zero divide")); 177 } else { 178 $$ = $1 / $3; 179 } 180 } 181 | '-' digit %prec UMINUS { $$ = -$2; } 182 | '(' digit ')' { $$ = $2; } 183 | DIGIT 184 ; 185 186 cast_qstr: '(' CHAR '*' ')' paren_qstr { $$ = $5; } 187 | '(' CONST CHAR '*' ')' paren_qstr { $$ = $6; } 188 | paren_qstr 189 ; 190 191 paren_qstr: '(' qstr_list ')' { $$ = $2; } 192 | qstr_list 193 ; 194 195 qstr_list: QSTR 196 | qstr_list QSTR { $$ = add_qstring($1, $2); } 197 ; 198 199 %% 200 201 static void 202 do_catgets(int setid, int msgid, char *str) 203 { 204 int id = msgid; 205 if (IsActiveMode(ReplaceMode)) { 206 return; 207 } 208 if (setid == 0 || setid > NL_SETMAX) { 209 src_err(srcfile, lineno, 210 gettext("improper set number: %d"), setid); 211 return; 212 } 213 if (IsActiveMode(ProjectMode)) { 214 set_msgid(setid, id); 215 add_msg(setid, id, str, srcfile, lineno, TRUE); 216 } else if (IsActiveMode(ReverseMode)) { 217 set_linemsgid(msg_line, NOMSGID); 218 } else if (IsActiveMode(AutoNumMode)) { 219 if (id == NOMSGID) { 220 id = get_msgid(srcfile, msg_line, setid, str); 221 set_linemsgid(msg_line, id); 222 } 223 if (id != NOMSGID) { 224 set_msgid(setid, id); 225 add_msg(setid, id, str, srcfile, lineno, FALSE); 226 } 227 } else if (id == NOMSGID) { 228 warning(gettext("improper message number: -1")); 229 } else { 230 add_msg(setid, id, str, srcfile, lineno, FALSE); 231 } 232 } 233 234 static char * 235 add_qstring(char *str, char *add) 236 { 237 int len = strlen(str) + strlen(add) + 3; 238 /* 3 includes '\', '\n' and '\0' */ 239 char *tmp = malloc(len); 240 if (tmp == NULL) { 241 prg_err(gettext("fatal: out of memory")); 242 exit(EXIT_FAILURE); 243 } 244 (void) snprintf(tmp, len, "%s\\\n%s", str, add); 245 free(str); 246 free(add); 247 return (tmp); 248 } 249