xref: /titanic_41/usr/src/cmd/exstr/exstr.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.2	*/
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate #include <stdio.h>
29*7c478bd9Sstevel@tonic-gate #include <ctype.h>
30*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
31*7c478bd9Sstevel@tonic-gate #include <signal.h>
32*7c478bd9Sstevel@tonic-gate #include <setjmp.h>
33*7c478bd9Sstevel@tonic-gate #include <string.h>
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate /* external functions */
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate extern	char 	*malloc();
38*7c478bd9Sstevel@tonic-gate extern	int	getopt();
39*7c478bd9Sstevel@tonic-gate extern	void	exit();
40*7c478bd9Sstevel@tonic-gate extern	int	atoi();
41*7c478bd9Sstevel@tonic-gate extern	int	_filbuf();
42*7c478bd9Sstevel@tonic-gate extern	char	*optarg;
43*7c478bd9Sstevel@tonic-gate extern	int	optind, opterr;
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate /* static functions */
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate static	void	extract();
48*7c478bd9Sstevel@tonic-gate static	void	replace();
49*7c478bd9Sstevel@tonic-gate static	void	yankstr();
50*7c478bd9Sstevel@tonic-gate static	void	badformat();
51*7c478bd9Sstevel@tonic-gate static	void	prstr();
52*7c478bd9Sstevel@tonic-gate static	int	getachar();
53*7c478bd9Sstevel@tonic-gate static  void	usage();
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate /* static variables */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate static	int	eflg;		/* find strings in source file(s) */
58*7c478bd9Sstevel@tonic-gate static	int	dflg;           /* use replaced string a second argument */
59*7c478bd9Sstevel@tonic-gate static  int	rflg;		/* replace strings by function calls */
60*7c478bd9Sstevel@tonic-gate static  int	errflg;         /* syntax error on command line */
61*7c478bd9Sstevel@tonic-gate static  char	*Fname;		/* name of source file */
62*7c478bd9Sstevel@tonic-gate static  int	Lineno;		/* line number in source file */
63*7c478bd9Sstevel@tonic-gate static	int	Posno;		/* character position within line */
64*7c478bd9Sstevel@tonic-gate static  int	flag;           /* sets when newline is encountered */
65*7c478bd9Sstevel@tonic-gate static  jmp_buf	to_eof;
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate main(argc, argv)
69*7c478bd9Sstevel@tonic-gate int	argc;
70*7c478bd9Sstevel@tonic-gate char	*argv[];
71*7c478bd9Sstevel@tonic-gate {
72*7c478bd9Sstevel@tonic-gate 	int	ch;
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate 	while ((ch = getopt(argc, argv, "erd")) != -1)
75*7c478bd9Sstevel@tonic-gate 		switch(ch) {
76*7c478bd9Sstevel@tonic-gate 		    case 'e':
77*7c478bd9Sstevel@tonic-gate 			if (rflg)
78*7c478bd9Sstevel@tonic-gate 				errflg++;
79*7c478bd9Sstevel@tonic-gate 			else
80*7c478bd9Sstevel@tonic-gate 				eflg++;
81*7c478bd9Sstevel@tonic-gate 			continue;
82*7c478bd9Sstevel@tonic-gate 		    case 'r':
83*7c478bd9Sstevel@tonic-gate 			if (eflg)
84*7c478bd9Sstevel@tonic-gate 				errflg++;
85*7c478bd9Sstevel@tonic-gate 			else
86*7c478bd9Sstevel@tonic-gate 				rflg++;
87*7c478bd9Sstevel@tonic-gate 			continue;
88*7c478bd9Sstevel@tonic-gate 		    case 'd':
89*7c478bd9Sstevel@tonic-gate 			if (eflg)
90*7c478bd9Sstevel@tonic-gate 				errflg++;
91*7c478bd9Sstevel@tonic-gate 			else
92*7c478bd9Sstevel@tonic-gate 				dflg++;
93*7c478bd9Sstevel@tonic-gate 			continue;
94*7c478bd9Sstevel@tonic-gate 		    default:
95*7c478bd9Sstevel@tonic-gate 			errflg++;
96*7c478bd9Sstevel@tonic-gate 		}
97*7c478bd9Sstevel@tonic-gate 	if (optind ==  argc || errflg)
98*7c478bd9Sstevel@tonic-gate 		usage();
99*7c478bd9Sstevel@tonic-gate 	if (!rflg)
100*7c478bd9Sstevel@tonic-gate 		for(;optind<argc;optind++)
101*7c478bd9Sstevel@tonic-gate 			extract(argv[optind]);
102*7c478bd9Sstevel@tonic-gate 	else  {
103*7c478bd9Sstevel@tonic-gate 		if (optind+1 != argc)
104*7c478bd9Sstevel@tonic-gate 			usage();
105*7c478bd9Sstevel@tonic-gate 		replace(argv[optind]);
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 	exit(0);
108*7c478bd9Sstevel@tonic-gate }
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate static	void
111*7c478bd9Sstevel@tonic-gate extract(name)
112*7c478bd9Sstevel@tonic-gate char	*name;
113*7c478bd9Sstevel@tonic-gate {
114*7c478bd9Sstevel@tonic-gate 	if (freopen(name,"r",stdin) == NULL) {
115*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,"exstr: ERROR: couldn't open file '%s'\n",name);
116*7c478bd9Sstevel@tonic-gate 		exit(1);
117*7c478bd9Sstevel@tonic-gate 	}
118*7c478bd9Sstevel@tonic-gate 	Fname = name;
119*7c478bd9Sstevel@tonic-gate 	flag = 1;
120*7c478bd9Sstevel@tonic-gate 	Lineno = 0;
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate 	if (setjmp(to_eof) != 0)
123*7c478bd9Sstevel@tonic-gate 		return;
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 	for (;;) {
126*7c478bd9Sstevel@tonic-gate 		char ch;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 		ch = getachar();
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		switch (ch) {
131*7c478bd9Sstevel@tonic-gate 		case '#':
132*7c478bd9Sstevel@tonic-gate 			if (Posno != 0)
133*7c478bd9Sstevel@tonic-gate 				continue;
134*7c478bd9Sstevel@tonic-gate 			do {
135*7c478bd9Sstevel@tonic-gate 				ch = getachar();
136*7c478bd9Sstevel@tonic-gate 			} while (isspace(ch));
137*7c478bd9Sstevel@tonic-gate 			if (ch == 'd')
138*7c478bd9Sstevel@tonic-gate 				continue;
139*7c478bd9Sstevel@tonic-gate 			while (getachar() != '\n');
140*7c478bd9Sstevel@tonic-gate 			break;
141*7c478bd9Sstevel@tonic-gate 		case '"':
142*7c478bd9Sstevel@tonic-gate 			yankstr();
143*7c478bd9Sstevel@tonic-gate 			break;
144*7c478bd9Sstevel@tonic-gate 		case '\'':
145*7c478bd9Sstevel@tonic-gate 			while ((ch = getachar()) != '\'')
146*7c478bd9Sstevel@tonic-gate 				if (ch == '\\')
147*7c478bd9Sstevel@tonic-gate 					ch = getachar();
148*7c478bd9Sstevel@tonic-gate 			break;
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 		case '/':
151*7c478bd9Sstevel@tonic-gate 			ch = getachar();
152*7c478bd9Sstevel@tonic-gate 			if (ch == '*') {
153*7c478bd9Sstevel@tonic-gate 				int level = 0;
154*7c478bd9Sstevel@tonic-gate 				while(level != 2) {
155*7c478bd9Sstevel@tonic-gate 					ch = getachar();
156*7c478bd9Sstevel@tonic-gate 					if (level == 0 && ch == '*')
157*7c478bd9Sstevel@tonic-gate 						level++;
158*7c478bd9Sstevel@tonic-gate 					else if (level == 1 && ch == '/')
159*7c478bd9Sstevel@tonic-gate 						level++;
160*7c478bd9Sstevel@tonic-gate 					else
161*7c478bd9Sstevel@tonic-gate 						level = 0;
162*7c478bd9Sstevel@tonic-gate 				}
163*7c478bd9Sstevel@tonic-gate 			}
164*7c478bd9Sstevel@tonic-gate 			break;
165*7c478bd9Sstevel@tonic-gate 		}
166*7c478bd9Sstevel@tonic-gate 	}
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate static	void
170*7c478bd9Sstevel@tonic-gate yankstr()
171*7c478bd9Sstevel@tonic-gate {
172*7c478bd9Sstevel@tonic-gate 	char cc;
173*7c478bd9Sstevel@tonic-gate 	char dbuf[BUFSIZ];
174*7c478bd9Sstevel@tonic-gate 	register char *dp = dbuf;
175*7c478bd9Sstevel@tonic-gate 	int saved_posno;
176*7c478bd9Sstevel@tonic-gate 	int saved_lineno;
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	saved_posno = Posno;
179*7c478bd9Sstevel@tonic-gate 	saved_lineno = Lineno;
180*7c478bd9Sstevel@tonic-gate 	while ((cc = getachar()) != '"') {
181*7c478bd9Sstevel@tonic-gate 		if(cc == '\\') {
182*7c478bd9Sstevel@tonic-gate 			*dp++ = cc;
183*7c478bd9Sstevel@tonic-gate 			cc = getachar();
184*7c478bd9Sstevel@tonic-gate 		}
185*7c478bd9Sstevel@tonic-gate 		if (cc == '\n') {
186*7c478bd9Sstevel@tonic-gate 			dp--;
187*7c478bd9Sstevel@tonic-gate 			continue;
188*7c478bd9Sstevel@tonic-gate 		}
189*7c478bd9Sstevel@tonic-gate 		*dp++ = cc;
190*7c478bd9Sstevel@tonic-gate 	}
191*7c478bd9Sstevel@tonic-gate 	*dp = 0;
192*7c478bd9Sstevel@tonic-gate 	prstr(dbuf,saved_lineno,saved_posno);
193*7c478bd9Sstevel@tonic-gate }
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate static	void
196*7c478bd9Sstevel@tonic-gate prstr(cp, lineno, posno)
197*7c478bd9Sstevel@tonic-gate register char *cp;
198*7c478bd9Sstevel@tonic-gate {
199*7c478bd9Sstevel@tonic-gate 	if (eflg)
200*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stdout, "%s:%d:%d:::%s\n", Fname, lineno, posno, cp);
201*7c478bd9Sstevel@tonic-gate 	else
202*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stdout, "%s:%s\n", Fname, cp);
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate }
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate static	void
207*7c478bd9Sstevel@tonic-gate usage()
208*7c478bd9Sstevel@tonic-gate {
209*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stderr, "usage: exstr [-e] files\n");
210*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stderr, "or   : exstr -r [-d] file\n");
211*7c478bd9Sstevel@tonic-gate 	exit(1);
212*7c478bd9Sstevel@tonic-gate }
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate static	int
215*7c478bd9Sstevel@tonic-gate getachar()
216*7c478bd9Sstevel@tonic-gate {
217*7c478bd9Sstevel@tonic-gate 	int cc;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	cc = getchar();
220*7c478bd9Sstevel@tonic-gate 	if (flag) {
221*7c478bd9Sstevel@tonic-gate 		Lineno++;
222*7c478bd9Sstevel@tonic-gate 		Posno = 0;
223*7c478bd9Sstevel@tonic-gate 		flag = 0;
224*7c478bd9Sstevel@tonic-gate 	} else
225*7c478bd9Sstevel@tonic-gate 		Posno++;
226*7c478bd9Sstevel@tonic-gate 	if (cc == EOF)
227*7c478bd9Sstevel@tonic-gate 		longjmp(to_eof, 1);
228*7c478bd9Sstevel@tonic-gate 	if (cc == '\n')
229*7c478bd9Sstevel@tonic-gate 		flag = 1;
230*7c478bd9Sstevel@tonic-gate 	return(cc);
231*7c478bd9Sstevel@tonic-gate }
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate static void
235*7c478bd9Sstevel@tonic-gate replace(name)
236*7c478bd9Sstevel@tonic-gate char	*name;
237*7c478bd9Sstevel@tonic-gate {
238*7c478bd9Sstevel@tonic-gate 	char	linebuf[BUFSIZ];	/* buffer to read lines from source file */
239*7c478bd9Sstevel@tonic-gate 	char	*cp;
240*7c478bd9Sstevel@tonic-gate 	int	curlineno;		/* line number in strings file */
241*7c478bd9Sstevel@tonic-gate 	int	curposno;		/* character position in string file */
242*7c478bd9Sstevel@tonic-gate 	int	savelineno = 0;
243*7c478bd9Sstevel@tonic-gate 	int	curmsgno;		/* message number in strings file */
244*7c478bd9Sstevel@tonic-gate 	int	wrong_msg;		/* invalid message number */
245*7c478bd9Sstevel@tonic-gate 	int	cont_str = 0;		/* string continues in the next line */
246*7c478bd9Sstevel@tonic-gate 	char	*repstr;
247*7c478bd9Sstevel@tonic-gate 	char	repbuf[BUFSIZ], *repbufp;
248*7c478bd9Sstevel@tonic-gate 	char	curline[BUFSIZ];
249*7c478bd9Sstevel@tonic-gate 	char	outbuf[BUFSIZ];
250*7c478bd9Sstevel@tonic-gate 	char	*inp;			/* keeps track of character position within input file */
251*7c478bd9Sstevel@tonic-gate 	char	*outp;			/* keeps track of character position within output buffer */
252*7c478bd9Sstevel@tonic-gate 	char	*msgfile;
253*7c478bd9Sstevel@tonic-gate 	FILE	*fi;			/* input source file pointer */
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate 	inp = linebuf;
256*7c478bd9Sstevel@tonic-gate 	outp = outbuf;
257*7c478bd9Sstevel@tonic-gate 	linebuf[0] = '\0';
258*7c478bd9Sstevel@tonic-gate 	/* open input C source file */
259*7c478bd9Sstevel@tonic-gate 	if ((fi = fopen(name,"r")) == (FILE *)NULL) {
260*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,"exstr: ERROR: couldn't open file '%s'\n",name);
261*7c478bd9Sstevel@tonic-gate 		exit(1);
262*7c478bd9Sstevel@tonic-gate 	}
263*7c478bd9Sstevel@tonic-gate 	Fname = name;
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stdout, "extern char *gettxt();\n");
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	/* process file containing the list of strings */
268*7c478bd9Sstevel@tonic-gate 	while (fgets(repbuf,sizeof repbuf, stdin) != (char *)NULL) {
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 		wrong_msg = 0;
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 		/* save a copy of the current line */
273*7c478bd9Sstevel@tonic-gate 		(void)strcpy(curline, repbuf);
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 		/* take apart the input string */
276*7c478bd9Sstevel@tonic-gate 		repbufp = strchr(repbuf,':');
277*7c478bd9Sstevel@tonic-gate 		if (repbufp == (char *)NULL)
278*7c478bd9Sstevel@tonic-gate 			badformat(curline);
279*7c478bd9Sstevel@tonic-gate 		*repbufp++ = '\0';
280*7c478bd9Sstevel@tonic-gate 		/* verify that string belongs to the input C source file */
281*7c478bd9Sstevel@tonic-gate 		if (strcmp(repbuf, name) != NULL)
282*7c478bd9Sstevel@tonic-gate 			continue;
283*7c478bd9Sstevel@tonic-gate 		repstr = strchr(repbufp,':');
284*7c478bd9Sstevel@tonic-gate 		if (repstr == (char *)NULL)
285*7c478bd9Sstevel@tonic-gate 			badformat(curline);
286*7c478bd9Sstevel@tonic-gate 		*repstr++ = '\0';
287*7c478bd9Sstevel@tonic-gate 		curlineno = atoi(repbufp);
288*7c478bd9Sstevel@tonic-gate 		if (curlineno < savelineno) {
289*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "exstr: ERROR: stdin: line out of order\n");
290*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "%s", curline);
291*7c478bd9Sstevel@tonic-gate 			exit(1);
292*7c478bd9Sstevel@tonic-gate 		}
293*7c478bd9Sstevel@tonic-gate 		savelineno = curlineno;
294*7c478bd9Sstevel@tonic-gate 		repbufp = repstr;
295*7c478bd9Sstevel@tonic-gate 		repstr = strchr(repbufp,':');
296*7c478bd9Sstevel@tonic-gate 		if (repstr == (char *)NULL)
297*7c478bd9Sstevel@tonic-gate 			badformat(curline);
298*7c478bd9Sstevel@tonic-gate 		repstr[strlen(repstr) - 1 ] = '\0';
299*7c478bd9Sstevel@tonic-gate 		*repstr++ = '\0';
300*7c478bd9Sstevel@tonic-gate 		curposno = atoi(repbufp);
301*7c478bd9Sstevel@tonic-gate 		repbufp = repstr;
302*7c478bd9Sstevel@tonic-gate 		repstr = strchr(repbufp,':');
303*7c478bd9Sstevel@tonic-gate 		if (repstr == (char *)NULL)
304*7c478bd9Sstevel@tonic-gate 			badformat(curline);
305*7c478bd9Sstevel@tonic-gate 		*repstr++ = '\0';
306*7c478bd9Sstevel@tonic-gate 		msgfile = repbufp;
307*7c478bd9Sstevel@tonic-gate 		if ( strlen(msgfile) > (size_t) 14 || *msgfile == '\0' ){
308*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "exstr: ERROR: stdin: invalid message file name '%s'\n", msgfile);
309*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "%s", curline);
310*7c478bd9Sstevel@tonic-gate 			exit(1);
311*7c478bd9Sstevel@tonic-gate 		}
312*7c478bd9Sstevel@tonic-gate 		repbufp = repstr;
313*7c478bd9Sstevel@tonic-gate 		repstr = strchr(repbufp,':');
314*7c478bd9Sstevel@tonic-gate 		if (repstr == (char *)NULL)
315*7c478bd9Sstevel@tonic-gate 			badformat(curline);
316*7c478bd9Sstevel@tonic-gate 		*repstr++ = '\0';
317*7c478bd9Sstevel@tonic-gate 		cp = repbufp;
318*7c478bd9Sstevel@tonic-gate 		while(*cp)
319*7c478bd9Sstevel@tonic-gate 			if(!isdigit(*cp++)) {
320*7c478bd9Sstevel@tonic-gate 				wrong_msg++;
321*7c478bd9Sstevel@tonic-gate 				break;
322*7c478bd9Sstevel@tonic-gate 			}
323*7c478bd9Sstevel@tonic-gate 		if ( *repbufp == '\0' || wrong_msg ) {
324*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "exstr: ERROR: stdin: invalid message number '%s'\n", repbufp);
325*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "%s", curline);
326*7c478bd9Sstevel@tonic-gate 			exit(1);
327*7c478bd9Sstevel@tonic-gate 			}
328*7c478bd9Sstevel@tonic-gate 		curmsgno = atoi(repbufp);
329*7c478bd9Sstevel@tonic-gate 
330*7c478bd9Sstevel@tonic-gate 		/* move up to this line */
331*7c478bd9Sstevel@tonic-gate 		while (Lineno != curlineno ) {
332*7c478bd9Sstevel@tonic-gate 			if (outp != outbuf) {
333*7c478bd9Sstevel@tonic-gate 				while(*inp != '\0')
334*7c478bd9Sstevel@tonic-gate 					*outp++ = *inp++;
335*7c478bd9Sstevel@tonic-gate 				*outp = '\0';
336*7c478bd9Sstevel@tonic-gate 				(void)fputs(outbuf,stdout);
337*7c478bd9Sstevel@tonic-gate 			} else if (*linebuf != '\0')
338*7c478bd9Sstevel@tonic-gate 				(void)fputs(linebuf,stdout);
339*7c478bd9Sstevel@tonic-gate 			outp = outbuf;
340*7c478bd9Sstevel@tonic-gate 			inp = linebuf;
341*7c478bd9Sstevel@tonic-gate 			if (fgets(linebuf, sizeof linebuf, fi) == (char *)NULL) {
342*7c478bd9Sstevel@tonic-gate 				(void)fprintf(stderr, "read error\n");
343*7c478bd9Sstevel@tonic-gate 				exit(1);
344*7c478bd9Sstevel@tonic-gate 			}
345*7c478bd9Sstevel@tonic-gate 			Lineno++;
346*7c478bd9Sstevel@tonic-gate 			Posno = 0;
347*7c478bd9Sstevel@tonic-gate 		}
348*7c478bd9Sstevel@tonic-gate 		if (Posno > curposno) {
349*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr, "Bad input record line number %d\n",Lineno);
350*7c478bd9Sstevel@tonic-gate 			exit(1);
351*7c478bd9Sstevel@tonic-gate 		}
352*7c478bd9Sstevel@tonic-gate 		while (Posno != curposno) {
353*7c478bd9Sstevel@tonic-gate 			*outp++ = *inp++;
354*7c478bd9Sstevel@tonic-gate 			Posno++;
355*7c478bd9Sstevel@tonic-gate 		}
356*7c478bd9Sstevel@tonic-gate 		if (*inp != '"') {
357*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "exstr: ERROR: cannot replace string '%s' in line (%d) of file (%s)\n", repstr, Lineno, Fname);
358*7c478bd9Sstevel@tonic-gate 			exit(1);
359*7c478bd9Sstevel@tonic-gate 		}
360*7c478bd9Sstevel@tonic-gate 		/* check if string continues in next line */
361*7c478bd9Sstevel@tonic-gate 		while (inp[strlen(inp)-2] == '\\' && inp[strlen(inp)-1] == '\n') {
362*7c478bd9Sstevel@tonic-gate 			if (fgets(linebuf,sizeof linebuf, fi) == (char *)NULL) {
363*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "exstr: ERROR: read error in file (%s)\n", Fname);
364*7c478bd9Sstevel@tonic-gate 				exit(1);
365*7c478bd9Sstevel@tonic-gate 			}
366*7c478bd9Sstevel@tonic-gate 			cont_str++;
367*7c478bd9Sstevel@tonic-gate 			Lineno++;
368*7c478bd9Sstevel@tonic-gate 		}
369*7c478bd9Sstevel@tonic-gate 		if (cont_str) {
370*7c478bd9Sstevel@tonic-gate 			cp = linebuf;
371*7c478bd9Sstevel@tonic-gate 			while (*cp != '\0' && *cp++ != '"') ;
372*7c478bd9Sstevel@tonic-gate 			if (*cp == '\0') {
373*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "exstr: ERROR: cannot replace string '%s' in line (%d) of file (%s)\n", repstr, Lineno, Fname);
374*7c478bd9Sstevel@tonic-gate 				exit(1);
375*7c478bd9Sstevel@tonic-gate 			}
376*7c478bd9Sstevel@tonic-gate 			inp = cp;
377*7c478bd9Sstevel@tonic-gate 			Posno = cp - linebuf;
378*7c478bd9Sstevel@tonic-gate 		}
379*7c478bd9Sstevel@tonic-gate 		if (dflg)
380*7c478bd9Sstevel@tonic-gate 			outp += sprintf(outp,"gettxt(\"%s:%d\", \"%s\")",msgfile, curmsgno, repstr);
381*7c478bd9Sstevel@tonic-gate 		else
382*7c478bd9Sstevel@tonic-gate 			outp += sprintf(outp,"gettxt(\"%s:%d\", \"\")",msgfile,curmsgno);
383*7c478bd9Sstevel@tonic-gate 		if (!cont_str) {
384*7c478bd9Sstevel@tonic-gate 			inp += strlen(repstr)+2;
385*7c478bd9Sstevel@tonic-gate 			Posno += strlen(repstr)+2;
386*7c478bd9Sstevel@tonic-gate 		}
387*7c478bd9Sstevel@tonic-gate 		else
388*7c478bd9Sstevel@tonic-gate 			cont_str = 0;
389*7c478bd9Sstevel@tonic-gate 	}
390*7c478bd9Sstevel@tonic-gate 	if (outp != outbuf) {
391*7c478bd9Sstevel@tonic-gate 		while(*inp != '\0')
392*7c478bd9Sstevel@tonic-gate 			*outp++ = *inp++;
393*7c478bd9Sstevel@tonic-gate 		*outp = '\0';
394*7c478bd9Sstevel@tonic-gate 		(void)fputs(outbuf,stdout);
395*7c478bd9Sstevel@tonic-gate 	}
396*7c478bd9Sstevel@tonic-gate 	while(fgets(linebuf,sizeof linebuf, fi) != (char *)NULL)
397*7c478bd9Sstevel@tonic-gate 		(void)fputs(linebuf, stdout);
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate }
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate static	void
402*7c478bd9Sstevel@tonic-gate badformat(line)
403*7c478bd9Sstevel@tonic-gate char  	*line;
404*7c478bd9Sstevel@tonic-gate {
405*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stderr, "exstr: ERROR: stdin: Badly formatted replacement string\n%s", line);
406*7c478bd9Sstevel@tonic-gate 	exit(1);
407*7c478bd9Sstevel@tonic-gate }
408