xref: /titanic_44/usr/src/cmd/genmsg/genmsg.l (revision ad8ef92ae01ac09e533731f5a517162c634308b4)
17c478bd9Sstevel@tonic-gate %{
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  * CDDL HEADER START
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
66e54a631Smuffin  * Common Development and Distribution License (the "License").
76e54a631Smuffin  * You may not use this file except in compliance with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
216e54a631Smuffin  */
226e54a631Smuffin /*
236e54a631Smuffin  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
246e54a631Smuffin  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate #include <limits.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
317c478bd9Sstevel@tonic-gate #include <libintl.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include "genmsg.h"
347c478bd9Sstevel@tonic-gate #include "y.tab.h"
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate extern int is_cat_found;	/* from main.c */
377c478bd9Sstevel@tonic-gate extern void add_comment(Mode, char *);	/* from util.c */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate int lineno = 1;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * msg_line stores the line number where a msgid is to be replaced.
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate int msg_line = 0;
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate int end_of_cat = TRUE;
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * In preprocessor mode, genmsg has to parse both the original
507c478bd9Sstevel@tonic-gate  * soruce code and the code which a preprocessor generates.
517c478bd9Sstevel@tonic-gate  * While genmsg is parsing the original source code,  'pound_is_mine'
527c478bd9Sstevel@tonic-gate  * is set to TRUE.
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate int pound_is_mine = FALSE;
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate void warning(char *);
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate #define	NOLINEMSG	-2
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate void set_linemsgid(int, int);
617c478bd9Sstevel@tonic-gate int get_linemsgid(int);
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /*
647c478bd9Sstevel@tonic-gate  * cat_field indicates which token is currently parsed by lex.
657c478bd9Sstevel@tonic-gate  */
667c478bd9Sstevel@tonic-gate #define	CatdField	0
677c478bd9Sstevel@tonic-gate #define	SetidField	1
687c478bd9Sstevel@tonic-gate #define	MsgidField	2
697c478bd9Sstevel@tonic-gate #define	StrField	3
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate static int cat_field;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * This will be turned on when '-' is found in the catgets message
757c478bd9Sstevel@tonic-gate  * number field.
767c478bd9Sstevel@tonic-gate  */
777c478bd9Sstevel@tonic-gate static int save_minus = FALSE;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate static char *skip_quoted(int skip_ch);
807c478bd9Sstevel@tonic-gate static char *skip_comment(void);
817c478bd9Sstevel@tonic-gate static void parse_cppline(char *);
827c478bd9Sstevel@tonic-gate %}
837c478bd9Sstevel@tonic-gate %s CAT
847c478bd9Sstevel@tonic-gate %%
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate [0-9a-zA-Z\_\.]catgets	{
877c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
886e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
897c478bd9Sstevel@tonic-gate 			}
907c478bd9Sstevel@tonic-gate 		}
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate catgets[0-9a-zA-Z\_\.]	{
937c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
946e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
957c478bd9Sstevel@tonic-gate 			}
967c478bd9Sstevel@tonic-gate 		}
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate catgets		{
996e54a631Smuffin 			if (end_of_cat) {
1006e54a631Smuffin 				/*
1016e54a631Smuffin 				 * If the previous catgets
1027c478bd9Sstevel@tonic-gate 				 * state is on, turn it off
1037c478bd9Sstevel@tonic-gate 				 * first.
1047c478bd9Sstevel@tonic-gate 				 */
1057c478bd9Sstevel@tonic-gate 				BEGIN 0;
1067c478bd9Sstevel@tonic-gate 			}
1077c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1086e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
1097c478bd9Sstevel@tonic-gate 			}
1106e54a631Smuffin 			if (!IsActiveMode(ReplaceMode) ||
1116e54a631Smuffin 			    !IsActiveMode(PreProcessMode)) {
1127c478bd9Sstevel@tonic-gate 				BEGIN CAT;
1137c478bd9Sstevel@tonic-gate 				end_of_cat = FALSE;
1147c478bd9Sstevel@tonic-gate 				cat_field = CatdField;
1156e54a631Smuffin 				return (CATGETS);
1167c478bd9Sstevel@tonic-gate 			}
1177c478bd9Sstevel@tonic-gate 		}
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate <CAT>\,		{	/* punctuation */
1207c478bd9Sstevel@tonic-gate 			cat_field++;
1217c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1226e54a631Smuffin 				(void) fprintf(newfp, "%c", yytext[0]);
1237c478bd9Sstevel@tonic-gate 			}
1247c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1257c478bd9Sstevel@tonic-gate 				BEGIN 0;
1267c478bd9Sstevel@tonic-gate 			} else {
1276e54a631Smuffin 				return (yytext[0]);
1287c478bd9Sstevel@tonic-gate 			}
1297c478bd9Sstevel@tonic-gate 		}
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate <CAT>[+*/();>]	{	/* punctuation */
1327c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1336e54a631Smuffin 				(void) fprintf(newfp, "%c", yytext[0]);
1347c478bd9Sstevel@tonic-gate 			}
1357c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1367c478bd9Sstevel@tonic-gate 				BEGIN 0;
1377c478bd9Sstevel@tonic-gate 			} else {
1386e54a631Smuffin 				return (yytext[0]);
1397c478bd9Sstevel@tonic-gate 			}
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate <CAT>const	{
1437c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1446e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
1457c478bd9Sstevel@tonic-gate 			}
1467c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1477c478bd9Sstevel@tonic-gate 				BEGIN 0;
1487c478bd9Sstevel@tonic-gate 			} else {
1496e54a631Smuffin 				return (CONST);
1507c478bd9Sstevel@tonic-gate 			}
1517c478bd9Sstevel@tonic-gate 		}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate <CAT>nl_catd	{
1547c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1556e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
1567c478bd9Sstevel@tonic-gate 			}
1577c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1587c478bd9Sstevel@tonic-gate 				BEGIN 0;
1597c478bd9Sstevel@tonic-gate 			} else {
1606e54a631Smuffin 				return (CATD);
1617c478bd9Sstevel@tonic-gate 			}
1627c478bd9Sstevel@tonic-gate 		}
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate <CAT>char	{
1657c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1666e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
1677c478bd9Sstevel@tonic-gate 			}
1687c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1697c478bd9Sstevel@tonic-gate 				BEGIN 0;
1707c478bd9Sstevel@tonic-gate 			} else {
1716e54a631Smuffin 				return (CHAR);
1727c478bd9Sstevel@tonic-gate 			}
1737c478bd9Sstevel@tonic-gate 		}
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate <CAT>int	{
1767c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1776e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
1787c478bd9Sstevel@tonic-gate 			}
1797c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1807c478bd9Sstevel@tonic-gate 				BEGIN 0;
1817c478bd9Sstevel@tonic-gate 			} else {
1826e54a631Smuffin 				return (INT);
1837c478bd9Sstevel@tonic-gate 			}
1847c478bd9Sstevel@tonic-gate 		}
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate <CAT>\+\+	{
1877c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1886e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
1897c478bd9Sstevel@tonic-gate 			}
1907c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
1917c478bd9Sstevel@tonic-gate 				BEGIN 0;
1927c478bd9Sstevel@tonic-gate 			} else {
1936e54a631Smuffin 				return (INC);
1947c478bd9Sstevel@tonic-gate 			}
1957c478bd9Sstevel@tonic-gate 		}
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate <CAT>\-\-	{
1987c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
1996e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
2007c478bd9Sstevel@tonic-gate 			}
2017c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
2027c478bd9Sstevel@tonic-gate 				BEGIN 0;
2037c478bd9Sstevel@tonic-gate 			} else {
2046e54a631Smuffin 				return (INC);
2057c478bd9Sstevel@tonic-gate 			}
2067c478bd9Sstevel@tonic-gate 		}
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate <CAT>\"		{	/* extract quoted string */
2097c478bd9Sstevel@tonic-gate 			yylval.str = skip_quoted('"');
2107c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
2116e54a631Smuffin 				(void) fprintf(newfp, "\"%s\"", yylval.str);
2127c478bd9Sstevel@tonic-gate 			}
2137c478bd9Sstevel@tonic-gate 			if (end_of_cat) { /* just in case */
2147c478bd9Sstevel@tonic-gate 				BEGIN 0;
2157c478bd9Sstevel@tonic-gate 				free(yylval.str);
2167c478bd9Sstevel@tonic-gate 			} else {
2176e54a631Smuffin 				return (QSTR);
2187c478bd9Sstevel@tonic-gate 			}
2197c478bd9Sstevel@tonic-gate 		}
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate <CAT>-		{	/* punctuation */
2227c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
2237c478bd9Sstevel@tonic-gate 				if (cat_field == MsgidField &&
2247c478bd9Sstevel@tonic-gate 					get_linemsgid(lineno) != NOLINEMSG) {
2257c478bd9Sstevel@tonic-gate 					save_minus = TRUE; /*  be replaced. */
2267c478bd9Sstevel@tonic-gate 				} else {
2276e54a631Smuffin 					(void) fprintf(newfp, "%c", yytext[0]);
2287c478bd9Sstevel@tonic-gate 				}
2297c478bd9Sstevel@tonic-gate 			}
2307c478bd9Sstevel@tonic-gate 			if (end_of_cat) { /* just in case */
2317c478bd9Sstevel@tonic-gate 				BEGIN 0;
2327c478bd9Sstevel@tonic-gate 			} else {
2336e54a631Smuffin 				return (yytext[0]);
2347c478bd9Sstevel@tonic-gate 			}
2357c478bd9Sstevel@tonic-gate 		}
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate <CAT>[0-9]+	{	/* numbers */
2387c478bd9Sstevel@tonic-gate 			switch (cat_field) {
2397c478bd9Sstevel@tonic-gate 			case SetidField:
2407c478bd9Sstevel@tonic-gate 				yylval.id = atoi(yytext);
2417c478bd9Sstevel@tonic-gate 				if (IsActiveMode(ReplaceMode)) {
2426e54a631Smuffin 					(void) fprintf(newfp, "%s", yytext);
2437c478bd9Sstevel@tonic-gate 				}
2447c478bd9Sstevel@tonic-gate 				if (end_of_cat) {
2457c478bd9Sstevel@tonic-gate 					BEGIN 0;
2467c478bd9Sstevel@tonic-gate 				} else {
2476e54a631Smuffin 					return (SETID);
2487c478bd9Sstevel@tonic-gate 				}
2496e54a631Smuffin 				break;
2507c478bd9Sstevel@tonic-gate 			case MsgidField:
2517c478bd9Sstevel@tonic-gate 				yylval.id = atoi(yytext);
2527c478bd9Sstevel@tonic-gate 				if (IsActiveMode(ReplaceMode)) {
2537c478bd9Sstevel@tonic-gate 					int id = get_linemsgid(lineno);
2547c478bd9Sstevel@tonic-gate 					if (id == NOLINEMSG) {
2556e54a631Smuffin 						(void) fprintf(newfp, "%s",
2566e54a631Smuffin 						    yytext);
2577c478bd9Sstevel@tonic-gate 					} else if (id == NOMSGID &&
2587c478bd9Sstevel@tonic-gate 						IsActiveMode(ReverseMode)) {
2596e54a631Smuffin 						(void) fprintf(newfp, "%d",
2606e54a631Smuffin 						    NOMSGID);
2617c478bd9Sstevel@tonic-gate 					} else if (save_minus == TRUE &&
2627c478bd9Sstevel@tonic-gate 						yylval.id == 1) {
2636e54a631Smuffin 						(void) fprintf(newfp, "%d", id);
2647c478bd9Sstevel@tonic-gate 					} else { /* just in case */
2656e54a631Smuffin 						(void) fprintf(newfp, "%s",
2666e54a631Smuffin 						    yytext);
2677c478bd9Sstevel@tonic-gate 					}
2687c478bd9Sstevel@tonic-gate 					save_minus = FALSE;
2697c478bd9Sstevel@tonic-gate 				} else {
2707c478bd9Sstevel@tonic-gate 					msg_line = lineno;
2717c478bd9Sstevel@tonic-gate 				}
2727c478bd9Sstevel@tonic-gate 				if (end_of_cat) {
2737c478bd9Sstevel@tonic-gate 					BEGIN 0;
2747c478bd9Sstevel@tonic-gate 				} else {
2756e54a631Smuffin 					return (MSGID);
2767c478bd9Sstevel@tonic-gate 				}
2776e54a631Smuffin 				break;
2787c478bd9Sstevel@tonic-gate 			default:
2797c478bd9Sstevel@tonic-gate 				yylval.id = atoi(yytext);
2807c478bd9Sstevel@tonic-gate 				if (IsActiveMode(ReplaceMode)) {
2816e54a631Smuffin 					(void) fprintf(newfp, "%s", yytext);
2827c478bd9Sstevel@tonic-gate 				}
2837c478bd9Sstevel@tonic-gate 				if (end_of_cat) {
2847c478bd9Sstevel@tonic-gate 					BEGIN 0;
2857c478bd9Sstevel@tonic-gate 				} else {
2866e54a631Smuffin 					return (DIGIT);
2877c478bd9Sstevel@tonic-gate 				}
2887c478bd9Sstevel@tonic-gate 			}
2897c478bd9Sstevel@tonic-gate 		}
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate <CAT>[a-zA-Z0-9_\&][a-zA-Z0-9_\>\&\.]*	{
2927c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
2936e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
2947c478bd9Sstevel@tonic-gate 			}
2957c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
2967c478bd9Sstevel@tonic-gate 				BEGIN 0;
2977c478bd9Sstevel@tonic-gate 			} else {
2986e54a631Smuffin 				return (STR);
2997c478bd9Sstevel@tonic-gate 			}
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate <CAT>\n		{
3037c478bd9Sstevel@tonic-gate 			lineno++;
3047c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
3056e54a631Smuffin 				(void) fprintf(newfp, "\n");
3067c478bd9Sstevel@tonic-gate 			}
3077c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
3087c478bd9Sstevel@tonic-gate 				BEGIN 0;
3097c478bd9Sstevel@tonic-gate 			}
3107c478bd9Sstevel@tonic-gate 		}
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate <CAT>.		{	/* not interested */
3137c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
3146e54a631Smuffin 				(void) fprintf(newfp, "%c", yytext[0]);
3157c478bd9Sstevel@tonic-gate 			}
3167c478bd9Sstevel@tonic-gate 			if (end_of_cat) {
3177c478bd9Sstevel@tonic-gate 				BEGIN 0;
3187c478bd9Sstevel@tonic-gate 			}
3197c478bd9Sstevel@tonic-gate 		}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate -((([ \t]+)1)|1) {	/* -1 */
3227c478bd9Sstevel@tonic-gate 			if (end_of_cat == FALSE) {
323*ad8ef92aSMilan Jurik 				REJECT
3247c478bd9Sstevel@tonic-gate 			} else if (IsActiveMode(ReplaceMode)) {
3257c478bd9Sstevel@tonic-gate 				if (IsActiveMode(PreProcessMode)) {
3267c478bd9Sstevel@tonic-gate 					int id = get_linemsgid(lineno);
3277c478bd9Sstevel@tonic-gate 					if (id == NOLINEMSG) {
3286e54a631Smuffin 						(void) fprintf(newfp, "%s",
3296e54a631Smuffin 						    yytext);
3307c478bd9Sstevel@tonic-gate 					} else { /* could be -1. */
3316e54a631Smuffin 						(void) fprintf(newfp, "%d", id);
3327c478bd9Sstevel@tonic-gate 					}
3337c478bd9Sstevel@tonic-gate 				} else {
3346e54a631Smuffin 					(void) fprintf(newfp, "%s", yytext);
3357c478bd9Sstevel@tonic-gate 				}
3367c478bd9Sstevel@tonic-gate 			}
3377c478bd9Sstevel@tonic-gate 		}
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate [0-9]+		{
3407c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
3417c478bd9Sstevel@tonic-gate 				if (IsActiveMode(PreProcessMode) &&
3427c478bd9Sstevel@tonic-gate 					IsActiveMode(ReverseMode)) {
3437c478bd9Sstevel@tonic-gate 					int id = get_linemsgid(lineno);
3447c478bd9Sstevel@tonic-gate 					if (id == NOLINEMSG) {
3456e54a631Smuffin 						(void) fprintf(newfp, "%s",
3466e54a631Smuffin 						    yytext);
3477c478bd9Sstevel@tonic-gate 					} else if (id == NOMSGID) {
3486e54a631Smuffin 						(void) fprintf(newfp, "%d", id);
3497c478bd9Sstevel@tonic-gate 					}
3507c478bd9Sstevel@tonic-gate 				} else {
3516e54a631Smuffin 					(void) fprintf(newfp, "%s", yytext);
3527c478bd9Sstevel@tonic-gate 				}
3537c478bd9Sstevel@tonic-gate 			}
3547c478bd9Sstevel@tonic-gate 		}
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate ^#[ \t]*[0-9]+.*\n	{	/* pound for c-preprocessor */
3577c478bd9Sstevel@tonic-gate 			if (IsActiveMode(PreProcessMode)) {
3587c478bd9Sstevel@tonic-gate 				if (IsActiveMode(ReplaceMode)) {
3596e54a631Smuffin 					(void) fprintf(newfp, "%s", yytext);
3607c478bd9Sstevel@tonic-gate 				} else {
3617c478bd9Sstevel@tonic-gate 					parse_cppline(yytext);
3627c478bd9Sstevel@tonic-gate 				}
3637c478bd9Sstevel@tonic-gate 			} else if (IsActiveMode(ReplaceMode)) {
3646e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
3657c478bd9Sstevel@tonic-gate 			}
3667c478bd9Sstevel@tonic-gate 			lineno++;
3677c478bd9Sstevel@tonic-gate 		}
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate "/*"		{	/* skip a comment block */
3707c478bd9Sstevel@tonic-gate 			char *comment = skip_comment();
3717c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
3726e54a631Smuffin 				(void) fprintf(newfp, "%s", comment);
3737c478bd9Sstevel@tonic-gate 			} else {
3747c478bd9Sstevel@tonic-gate 				if (IsActiveMode(MsgCommentMode)) {
3757c478bd9Sstevel@tonic-gate 					add_comment(MsgCommentMode, comment);
3767c478bd9Sstevel@tonic-gate 				}
3777c478bd9Sstevel@tonic-gate 				if (IsActiveMode(SetCommentMode)) {
3787c478bd9Sstevel@tonic-gate 					add_comment(SetCommentMode, comment);
3797c478bd9Sstevel@tonic-gate 				}
3807c478bd9Sstevel@tonic-gate 			}
3817c478bd9Sstevel@tonic-gate 			free(comment);
3827c478bd9Sstevel@tonic-gate 		}
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate "//".*\n	{	/* skip a c++ comment */
3857c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
3866e54a631Smuffin 				(void) fprintf(newfp, "%s", yytext);
3877c478bd9Sstevel@tonic-gate 			} else {
3887c478bd9Sstevel@tonic-gate 				if (IsActiveMode(MsgCommentMode)) {
3897c478bd9Sstevel@tonic-gate 					add_comment(MsgCommentMode, yytext);
3907c478bd9Sstevel@tonic-gate 				}
3917c478bd9Sstevel@tonic-gate 				if (IsActiveMode(SetCommentMode)) {
3927c478bd9Sstevel@tonic-gate 					add_comment(SetCommentMode, yytext);
3937c478bd9Sstevel@tonic-gate 				}
3947c478bd9Sstevel@tonic-gate 			}
3957c478bd9Sstevel@tonic-gate 			lineno++;
3967c478bd9Sstevel@tonic-gate 		}
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate \"		{	/* skip quoted string */
3997c478bd9Sstevel@tonic-gate 			char *qstr = skip_quoted('"');
4007c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
4016e54a631Smuffin 				(void) fprintf(newfp, "\"%s\"", qstr);
4027c478bd9Sstevel@tonic-gate 			}
4037c478bd9Sstevel@tonic-gate 			free(qstr);
4047c478bd9Sstevel@tonic-gate 		}
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate \'		{	/* skip single-quoted character */
4077c478bd9Sstevel@tonic-gate 			char *qchr = skip_quoted('\'');
4087c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
4096e54a631Smuffin 				(void) fprintf(newfp, "\'%s\'", qchr);
4107c478bd9Sstevel@tonic-gate 			}
4117c478bd9Sstevel@tonic-gate 			free(qchr);
4127c478bd9Sstevel@tonic-gate 		}
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate \n		{
4157c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
4166e54a631Smuffin 				(void) fprintf(newfp, "\n");
4177c478bd9Sstevel@tonic-gate 			}
4187c478bd9Sstevel@tonic-gate 			lineno++;
4197c478bd9Sstevel@tonic-gate 		}
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate .		{
4227c478bd9Sstevel@tonic-gate 			if (IsActiveMode(ReplaceMode)) {
4236e54a631Smuffin 				(void) fprintf(newfp, "%c", yytext[0]);
4247c478bd9Sstevel@tonic-gate 			}
4257c478bd9Sstevel@tonic-gate 		}
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate %%
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate static char *
4307c478bd9Sstevel@tonic-gate skip_quoted(int skip_ch)
4317c478bd9Sstevel@tonic-gate {
4327c478bd9Sstevel@tonic-gate 	char *buf, *ptr;	/* saved buffer and its pointer */
4337c478bd9Sstevel@tonic-gate 	int bsize = BUFSIZ;	/* growing buffer size */
4347c478bd9Sstevel@tonic-gate 	int i = 0;		/* counter */
4357c478bd9Sstevel@tonic-gate 	int c, old = 0;		/* input character */
4367c478bd9Sstevel@tonic-gate 
4376e54a631Smuffin 	if ((buf = ptr = malloc(bsize)) == NULL) {
4387c478bd9Sstevel@tonic-gate 		prg_err(gettext("fatal: out of memory"));
4397c478bd9Sstevel@tonic-gate 		exit(EXIT_FAILURE);
4407c478bd9Sstevel@tonic-gate 	}
4417c478bd9Sstevel@tonic-gate 	for (; ; i++) {
4427c478bd9Sstevel@tonic-gate 		if (i == bsize) {
4437c478bd9Sstevel@tonic-gate 			bsize += BUFSIZ;
4446e54a631Smuffin 			if ((buf = realloc(buf, bsize)) == NULL) {
4457c478bd9Sstevel@tonic-gate 				prg_err(gettext("fatal: out of memory"));
4467c478bd9Sstevel@tonic-gate 				exit(EXIT_FAILURE);
4477c478bd9Sstevel@tonic-gate 			}
4487c478bd9Sstevel@tonic-gate 			ptr = buf + i;
4497c478bd9Sstevel@tonic-gate 		}
4507c478bd9Sstevel@tonic-gate 		c = input();
4517c478bd9Sstevel@tonic-gate 		if (c == skip_ch && old != '\\') {
4527c478bd9Sstevel@tonic-gate 			break;
4537c478bd9Sstevel@tonic-gate 		} else if (c == '\n') {
4547c478bd9Sstevel@tonic-gate 			lineno++;
4557c478bd9Sstevel@tonic-gate 		} else if (c == 0) {
4567c478bd9Sstevel@tonic-gate 			if (skip_ch == '"') {
4577c478bd9Sstevel@tonic-gate 				warning(gettext("warning: unmatched \""));
4587c478bd9Sstevel@tonic-gate 			} else if (skip_ch == '\'') {
4597c478bd9Sstevel@tonic-gate 				warning(gettext("warning: unmatched '"));
4607c478bd9Sstevel@tonic-gate 			} else {
4617c478bd9Sstevel@tonic-gate 				/* Should not happen */
4626e54a631Smuffin 				warning(gettext(
4636e54a631Smuffin 				    "warning: unmatched character"));
4647c478bd9Sstevel@tonic-gate 			}
4657c478bd9Sstevel@tonic-gate 			break;
4667c478bd9Sstevel@tonic-gate 		}
4677c478bd9Sstevel@tonic-gate 		*ptr++ = c;
4687c478bd9Sstevel@tonic-gate 		if (old == '\\') {
4697c478bd9Sstevel@tonic-gate 			old = '\0';
4707c478bd9Sstevel@tonic-gate 		} else {
4717c478bd9Sstevel@tonic-gate 			old = c;
4727c478bd9Sstevel@tonic-gate 		}
4737c478bd9Sstevel@tonic-gate 	}
4747c478bd9Sstevel@tonic-gate 	*ptr = '\0';
4756e54a631Smuffin 	return (buf);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate static char *
4797c478bd9Sstevel@tonic-gate skip_comment(void)
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate 	char *buf, *ptr;	/* saved buffer and its pointer */
4827c478bd9Sstevel@tonic-gate 	int bsize = BUFSIZ;	/* growing buffer size */
4837c478bd9Sstevel@tonic-gate 	int i = 0;		/* counter */
4847c478bd9Sstevel@tonic-gate 	int c, old = 0;		/* input character */
4857c478bd9Sstevel@tonic-gate 
4866e54a631Smuffin 	if ((buf = ptr = malloc(bsize)) == NULL) {
4877c478bd9Sstevel@tonic-gate 		prg_err(gettext("fatal: out of memory"));
4887c478bd9Sstevel@tonic-gate 		exit(EXIT_FAILURE);
4897c478bd9Sstevel@tonic-gate 	}
4907c478bd9Sstevel@tonic-gate 	*ptr++ = '/';	i++;
4917c478bd9Sstevel@tonic-gate 	*ptr++ = '*';	i++;
4927c478bd9Sstevel@tonic-gate 	for (; ; i++) {
4937c478bd9Sstevel@tonic-gate 		if (i == bsize) {
4947c478bd9Sstevel@tonic-gate 			bsize += BUFSIZ;
4956e54a631Smuffin 			if ((buf = realloc(buf, bsize)) == NULL) {
4967c478bd9Sstevel@tonic-gate 				prg_err(gettext("fatal: out of memory"));
4977c478bd9Sstevel@tonic-gate 				exit(EXIT_FAILURE);
4987c478bd9Sstevel@tonic-gate 			}
4997c478bd9Sstevel@tonic-gate 			ptr = buf + i;
5007c478bd9Sstevel@tonic-gate 		}
5017c478bd9Sstevel@tonic-gate 		c = input();
5027c478bd9Sstevel@tonic-gate 		if (c == '/' && old == '*') {
5037c478bd9Sstevel@tonic-gate 			*ptr++ = c;
5047c478bd9Sstevel@tonic-gate 			break;
5057c478bd9Sstevel@tonic-gate 		} else if (c == '\n') {
5067c478bd9Sstevel@tonic-gate 			lineno++;
5077c478bd9Sstevel@tonic-gate 		} else if (c == 0) {
5087c478bd9Sstevel@tonic-gate 			warning(gettext("warning: unmatched /*"));
5097c478bd9Sstevel@tonic-gate 			break;
5107c478bd9Sstevel@tonic-gate 		}
5117c478bd9Sstevel@tonic-gate 		*ptr++ = old = c;
5127c478bd9Sstevel@tonic-gate 	}
5137c478bd9Sstevel@tonic-gate 	*ptr = '\0';
5146e54a631Smuffin 	return (buf);
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate  * parse_cppline() parses the line control information that a C
5197c478bd9Sstevel@tonic-gate  * preprocessor generates to indicate the location in the original
5207c478bd9Sstevel@tonic-gate  * file.  See the cpp man in the details.
5217c478bd9Sstevel@tonic-gate  */
5227c478bd9Sstevel@tonic-gate static void
5237c478bd9Sstevel@tonic-gate parse_cppline(char *str)
5247c478bd9Sstevel@tonic-gate {
5257c478bd9Sstevel@tonic-gate 	int n, line, len;
5267c478bd9Sstevel@tonic-gate 	char ch;
5276e54a631Smuffin 	char file[BUFSIZ];
5286e54a631Smuffin 	char *altfile = NULL;
5296e54a631Smuffin 	char *pfile;
5307c478bd9Sstevel@tonic-gate 
5316e54a631Smuffin 	len = strlen(str);
5326e54a631Smuffin 	if (len >= sizeof (file)) {
5336e54a631Smuffin 		if ((altfile = malloc(len + 1)) == NULL) {
5346e54a631Smuffin 			prg_err(gettext("fatal: out of memory"));
5356e54a631Smuffin 			exit(EXIT_FAILURE);
5366e54a631Smuffin 		}
5376e54a631Smuffin 		pfile = altfile;
5386e54a631Smuffin 	} else {
5396e54a631Smuffin 		pfile = file;
5406e54a631Smuffin 	}
5416e54a631Smuffin 	/* LINTED: E_SEC_SCANF_UNBOUNDED_COPY */
5426e54a631Smuffin 	n = sscanf(str, "%c%d%s", &ch, &line, pfile);
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate 	/* 'file' is a quoted string but 'srcfile' is not. */
5456e54a631Smuffin 	len = strlen(pfile) - 2;
5466e54a631Smuffin 
5477c478bd9Sstevel@tonic-gate 	pfile++;
5487c478bd9Sstevel@tonic-gate 	if (n == 3 && (strncmp(pfile, srcfile, len) == 0)) {
5497c478bd9Sstevel@tonic-gate 		pound_is_mine = TRUE;
5507c478bd9Sstevel@tonic-gate 		lineno = line - 1;
5517c478bd9Sstevel@tonic-gate 	} else if (n == 2 && (pound_is_mine == TRUE)) {
5527c478bd9Sstevel@tonic-gate 		lineno = line - 1;
5537c478bd9Sstevel@tonic-gate 	} else {
5547c478bd9Sstevel@tonic-gate 		pound_is_mine = FALSE;
5557c478bd9Sstevel@tonic-gate 	}
5566e54a631Smuffin 	if (altfile)
5576e54a631Smuffin 		free(altfile);
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate typedef struct {
5617c478bd9Sstevel@tonic-gate 	int line;
5627c478bd9Sstevel@tonic-gate 	int msgid;
5637c478bd9Sstevel@tonic-gate } LineMsgID;
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate static LineMsgID line_msgid[NL_MSGMAX];
5667c478bd9Sstevel@tonic-gate static int line_msgcnt;
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate void
5697c478bd9Sstevel@tonic-gate init_lex(void)
5707c478bd9Sstevel@tonic-gate {
5717c478bd9Sstevel@tonic-gate 	lineno = 1;
5727c478bd9Sstevel@tonic-gate 	end_of_cat = TRUE;
5737c478bd9Sstevel@tonic-gate 	pound_is_mine = FALSE;
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate void
5777c478bd9Sstevel@tonic-gate init_linemsgid(void)
5787c478bd9Sstevel@tonic-gate {
5797c478bd9Sstevel@tonic-gate 	line_msgcnt = 0;
5806e54a631Smuffin 	(void) memset(line_msgid, 0, sizeof (LineMsgID) * NL_MSGMAX);
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate void
5847c478bd9Sstevel@tonic-gate set_linemsgid(int line, int msgid)
5857c478bd9Sstevel@tonic-gate {
5867c478bd9Sstevel@tonic-gate 	if (line_msgcnt >= NL_MSGMAX) {
5877c478bd9Sstevel@tonic-gate 		return; /* oops */
5887c478bd9Sstevel@tonic-gate 	}
5897c478bd9Sstevel@tonic-gate 	line_msgid[line_msgcnt].line = line;
5907c478bd9Sstevel@tonic-gate 	line_msgid[line_msgcnt].msgid = msgid;
5917c478bd9Sstevel@tonic-gate 	line_msgcnt++;
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate int
5957c478bd9Sstevel@tonic-gate get_linemsgid(int line)
5967c478bd9Sstevel@tonic-gate {
5976e54a631Smuffin 	int i, left, right;
5987c478bd9Sstevel@tonic-gate 	left = 0;
5997c478bd9Sstevel@tonic-gate 	right = line_msgcnt - 1;
6007c478bd9Sstevel@tonic-gate 	while (left <= right) {
6017c478bd9Sstevel@tonic-gate 		i = (left + right) >> 1;
6027c478bd9Sstevel@tonic-gate 		if (line < line_msgid[i].line) {
6037c478bd9Sstevel@tonic-gate 			right = i - 1;
6047c478bd9Sstevel@tonic-gate 		} else if (line > line_msgid[i].line) {
6057c478bd9Sstevel@tonic-gate 			left = i + 1;
6067c478bd9Sstevel@tonic-gate 		} else {
6076e54a631Smuffin 			return (line_msgid[i].msgid);
6087c478bd9Sstevel@tonic-gate 		}
6097c478bd9Sstevel@tonic-gate 	}
6106e54a631Smuffin 	return (NOLINEMSG);
6117c478bd9Sstevel@tonic-gate }
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate void
6147c478bd9Sstevel@tonic-gate yyerror(char *s)
6157c478bd9Sstevel@tonic-gate {
6167c478bd9Sstevel@tonic-gate 	if ((IsActiveMode(PreProcessMode) && pound_is_mine == FALSE) ||
6177c478bd9Sstevel@tonic-gate 	    IsActiveMode(ReplaceMode)) {
6187c478bd9Sstevel@tonic-gate 		return;
6197c478bd9Sstevel@tonic-gate 	}
6207c478bd9Sstevel@tonic-gate 	src_err(srcfile, lineno, gettext("%s before or at: %s"), s, yytext);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate void
6247c478bd9Sstevel@tonic-gate warning(char *s)
6257c478bd9Sstevel@tonic-gate {
6267c478bd9Sstevel@tonic-gate 	if ((IsActiveMode(PreProcessMode) && pound_is_mine == FALSE) ||
6277c478bd9Sstevel@tonic-gate 	    IsActiveMode(ReplaceMode)) {
6287c478bd9Sstevel@tonic-gate 		return;
6297c478bd9Sstevel@tonic-gate 	}
6307c478bd9Sstevel@tonic-gate 	src_err(srcfile, lineno, "%s", s);
6317c478bd9Sstevel@tonic-gate }
632