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]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
36 extern int is_cat_found; /* from main.c */
37 extern void add_comment(Mode, char *); /* from util.c */
42 * msg_line stores the line number where a msgid is to be replaced.
46 int end_of_cat = TRUE;
49 * In preprocessor mode, genmsg has to parse both the original
50 * soruce code and the code which a preprocessor generates.
51 * While genmsg is parsing the original source code, 'pound_is_mine'
54 int pound_is_mine = FALSE;
60 void set_linemsgid(int, int);
61 int get_linemsgid(int);
64 * cat_field indicates which token is currently parsed by lex.
74 * This will be turned on when '-' is found in the catgets message
77 static int save_minus = FALSE;
79 static char *skip_quoted(int skip_ch);
80 static char *skip_comment(void);
81 static void parse_cppline(char *);
86 [0-9a-zA-Z\_\.]catgets {
87 if (IsActiveMode(ReplaceMode)) {
88 (void) fprintf(newfp, "%s", yytext);
92 catgets[0-9a-zA-Z\_\.] {
93 if (IsActiveMode(ReplaceMode)) {
94 (void) fprintf(newfp, "%s", yytext);
101 * If the previous catgets
102 * state is on, turn it off
107 if (IsActiveMode(ReplaceMode)) {
108 (void) fprintf(newfp, "%s", yytext);
110 if (!IsActiveMode(ReplaceMode) ||
111 !IsActiveMode(PreProcessMode)) {
114 cat_field = CatdField;
119 <CAT>\, { /* punctuation */
121 if (IsActiveMode(ReplaceMode)) {
122 (void) fprintf(newfp, "%c", yytext[0]);
131 <CAT>[+*/();>] { /* punctuation */
132 if (IsActiveMode(ReplaceMode)) {
133 (void) fprintf(newfp, "%c", yytext[0]);
143 if (IsActiveMode(ReplaceMode)) {
144 (void) fprintf(newfp, "%s", yytext);
154 if (IsActiveMode(ReplaceMode)) {
155 (void) fprintf(newfp, "%s", yytext);
165 if (IsActiveMode(ReplaceMode)) {
166 (void) fprintf(newfp, "%s", yytext);
176 if (IsActiveMode(ReplaceMode)) {
177 (void) fprintf(newfp, "%s", yytext);
187 if (IsActiveMode(ReplaceMode)) {
188 (void) fprintf(newfp, "%s", yytext);
198 if (IsActiveMode(ReplaceMode)) {
199 (void) fprintf(newfp, "%s", yytext);
208 <CAT>\" { /* extract quoted string */
209 yylval.str = skip_quoted('"');
210 if (IsActiveMode(ReplaceMode)) {
211 (void) fprintf(newfp, "\"%s\"", yylval.str);
213 if (end_of_cat) { /* just in case */
221 <CAT>- { /* punctuation */
222 if (IsActiveMode(ReplaceMode)) {
223 if (cat_field == MsgidField &&
224 get_linemsgid(lineno) != NOLINEMSG) {
225 save_minus = TRUE; /* be replaced. */
227 (void) fprintf(newfp, "%c", yytext[0]);
230 if (end_of_cat) { /* just in case */
237 <CAT>[0-9]+ { /* numbers */
240 yylval.id = atoi(yytext);
241 if (IsActiveMode(ReplaceMode)) {
242 (void) fprintf(newfp, "%s", yytext);
251 yylval.id = atoi(yytext);
252 if (IsActiveMode(ReplaceMode)) {
253 int id = get_linemsgid(lineno);
254 if (id == NOLINEMSG) {
255 (void) fprintf(newfp, "%s",
257 } else if (id == NOMSGID &&
258 IsActiveMode(ReverseMode)) {
259 (void) fprintf(newfp, "%d",
261 } else if (save_minus == TRUE &&
263 (void) fprintf(newfp, "%d", id);
264 } else { /* just in case */
265 (void) fprintf(newfp, "%s",
279 yylval.id = atoi(yytext);
280 if (IsActiveMode(ReplaceMode)) {
281 (void) fprintf(newfp, "%s", yytext);
291 <CAT>[a-zA-Z0-9_\&][a-zA-Z0-9_\>\&\.]* {
292 if (IsActiveMode(ReplaceMode)) {
293 (void) fprintf(newfp, "%s", yytext);
304 if (IsActiveMode(ReplaceMode)) {
305 (void) fprintf(newfp, "\n");
312 <CAT>. { /* not interested */
313 if (IsActiveMode(ReplaceMode)) {
314 (void) fprintf(newfp, "%c", yytext[0]);
321 -((([ \t]+)1)|1) { /* -1 */
322 if (end_of_cat == FALSE) {
324 } else if (IsActiveMode(ReplaceMode)) {
325 if (IsActiveMode(PreProcessMode)) {
326 int id = get_linemsgid(lineno);
327 if (id == NOLINEMSG) {
328 (void) fprintf(newfp, "%s",
330 } else { /* could be -1. */
331 (void) fprintf(newfp, "%d", id);
334 (void) fprintf(newfp, "%s", yytext);
340 if (IsActiveMode(ReplaceMode)) {
341 if (IsActiveMode(PreProcessMode) &&
342 IsActiveMode(ReverseMode)) {
343 int id = get_linemsgid(lineno);
344 if (id == NOLINEMSG) {
345 (void) fprintf(newfp, "%s",
347 } else if (id == NOMSGID) {
348 (void) fprintf(newfp, "%d", id);
351 (void) fprintf(newfp, "%s", yytext);
356 ^#[ \t]*[0-9]+.*\n { /* pound for c-preprocessor */
357 if (IsActiveMode(PreProcessMode)) {
358 if (IsActiveMode(ReplaceMode)) {
359 (void) fprintf(newfp, "%s", yytext);
361 parse_cppline(yytext);
363 } else if (IsActiveMode(ReplaceMode)) {
364 (void) fprintf(newfp, "%s", yytext);
369 "/*" { /* skip a comment block */
370 char *comment = skip_comment();
371 if (IsActiveMode(ReplaceMode)) {
372 (void) fprintf(newfp, "%s", comment);
374 if (IsActiveMode(MsgCommentMode)) {
375 add_comment(MsgCommentMode, comment);
377 if (IsActiveMode(SetCommentMode)) {
378 add_comment(SetCommentMode, comment);
384 "//".*\n { /* skip a c++ comment */
385 if (IsActiveMode(ReplaceMode)) {
386 (void) fprintf(newfp, "%s", yytext);
388 if (IsActiveMode(MsgCommentMode)) {
389 add_comment(MsgCommentMode, yytext);
391 if (IsActiveMode(SetCommentMode)) {
392 add_comment(SetCommentMode, yytext);
398 \" { /* skip quoted string */
399 char *qstr = skip_quoted('"');
400 if (IsActiveMode(ReplaceMode)) {
401 (void) fprintf(newfp, "\"%s\"", qstr);
406 \' { /* skip single-quoted character */
407 char *qchr = skip_quoted('\'');
408 if (IsActiveMode(ReplaceMode)) {
409 (void) fprintf(newfp, "\'%s\'", qchr);
415 if (IsActiveMode(ReplaceMode)) {
416 (void) fprintf(newfp, "\n");
422 if (IsActiveMode(ReplaceMode)) {
423 (void) fprintf(newfp, "%c", yytext[0]);
430 skip_quoted(int skip_ch)
432 char *buf, *ptr; /* saved buffer and its pointer */
433 int bsize = BUFSIZ; /* growing buffer size */
434 int i = 0; /* counter */
435 int c, old = 0; /* input character */
437 if ((buf = ptr = malloc(bsize)) == NULL) {
438 prg_err(gettext("fatal: out of memory"));
444 if ((buf = realloc(buf, bsize)) == NULL) {
445 prg_err(gettext("fatal: out of memory"));
451 if (c == skip_ch && old != '\\') {
453 } else if (c == '\n') {
456 if (skip_ch == '"') {
457 warning(gettext("warning: unmatched \""));
458 } else if (skip_ch == '\'') {
459 warning(gettext("warning: unmatched '"));
461 /* Should not happen */
463 "warning: unmatched character"));
481 char *buf, *ptr; /* saved buffer and its pointer */
482 int bsize = BUFSIZ; /* growing buffer size */
483 int i = 0; /* counter */
484 int c, old = 0; /* input character */
486 if ((buf = ptr = malloc(bsize)) == NULL) {
487 prg_err(gettext("fatal: out of memory"));
495 if ((buf = realloc(buf, bsize)) == NULL) {
496 prg_err(gettext("fatal: out of memory"));
502 if (c == '/' && old == '*') {
505 } else if (c == '\n') {
508 warning(gettext("warning: unmatched /*"));
518 * parse_cppline() parses the line control information that a C
519 * preprocessor generates to indicate the location in the original
520 * file. See the cpp man in the details.
523 parse_cppline(char *str)
528 char *altfile = NULL;
532 if (len >= sizeof (file)) {
533 if ((altfile = malloc(len + 1)) == NULL) {
534 prg_err(gettext("fatal: out of memory"));
541 /* LINTED: E_SEC_SCANF_UNBOUNDED_COPY */
542 n = sscanf(str, "%c%d%s", &ch, &line, pfile);
544 /* 'file' is a quoted string but 'srcfile' is not. */
545 len = strlen(pfile) - 2;
548 if (n == 3 && (strncmp(pfile, srcfile, len) == 0)) {
549 pound_is_mine = TRUE;
551 } else if (n == 2 && (pound_is_mine == TRUE)) {
554 pound_is_mine = FALSE;
565 static LineMsgID line_msgid[NL_MSGMAX];
566 static int line_msgcnt;
573 pound_is_mine = FALSE;
580 (void) memset(line_msgid, 0, sizeof (LineMsgID) * NL_MSGMAX);
584 set_linemsgid(int line, int msgid)
586 if (line_msgcnt >= NL_MSGMAX) {
589 line_msgid[line_msgcnt].line = line;
590 line_msgid[line_msgcnt].msgid = msgid;
595 get_linemsgid(int line)
599 right = line_msgcnt - 1;
600 while (left <= right) {
601 i = (left + right) >> 1;
602 if (line < line_msgid[i].line) {
604 } else if (line > line_msgid[i].line) {
607 return (line_msgid[i].msgid);
616 if ((IsActiveMode(PreProcessMode) && pound_is_mine == FALSE) ||
617 IsActiveMode(ReplaceMode)) {
620 src_err(srcfile, lineno, gettext("%s before or at: %s"), s, yytext);
626 if ((IsActiveMode(PreProcessMode) && pound_is_mine == FALSE) ||
627 IsActiveMode(ReplaceMode)) {
630 src_err(srcfile, lineno, "%s", s);