xref: /titanic_50/usr/src/cmd/deroff/deroff.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 /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <assert.h>
34*7c478bd9Sstevel@tonic-gate #include <errno.h>
35*7c478bd9Sstevel@tonic-gate #include <stdio.h>
36*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
37*7c478bd9Sstevel@tonic-gate #include <string.h>
38*7c478bd9Sstevel@tonic-gate #include <locale.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/varargs.h>
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate /*
42*7c478bd9Sstevel@tonic-gate  * Deroff command -- strip troff, eqn, and Tbl sequences from a file.
43*7c478bd9Sstevel@tonic-gate  * Has three flags argument, -w, to cause output one word per line
44*7c478bd9Sstevel@tonic-gate  * rather than in the original format.
45*7c478bd9Sstevel@tonic-gate  * -mm (or -ms) causes the corresponding macro's to be interpreted
46*7c478bd9Sstevel@tonic-gate  * so that just sentences are output
47*7c478bd9Sstevel@tonic-gate  * -ml  also gets rid of lists.
48*7c478bd9Sstevel@tonic-gate  * -i causes deroff to ignore .so and .nx commands.
49*7c478bd9Sstevel@tonic-gate  * Deroff follows .so and .nx commands, removes contents of macro
50*7c478bd9Sstevel@tonic-gate  * definitions, equations (both .EQ ... .EN and $...$),
51*7c478bd9Sstevel@tonic-gate  * Tbl command sequences, and Troff backslash constructions.
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  * All input is through the C macro; the most recently read character
54*7c478bd9Sstevel@tonic-gate  * is in c.
55*7c478bd9Sstevel@tonic-gate  */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate #define	C	((c = getc(infile)) == EOF ? eof() : \
58*7c478bd9Sstevel@tonic-gate 		    ((c == ldelim) && (filesp == files) ? skeqn() : c))
59*7c478bd9Sstevel@tonic-gate #define	C1	((c = getc(infile)) == EOF ? eof() : c)
60*7c478bd9Sstevel@tonic-gate #define	SKIP	while (C != '\n')
61*7c478bd9Sstevel@tonic-gate #define	SKIP_TO_COM	SKIP; SKIP; pc = c; \
62*7c478bd9Sstevel@tonic-gate 			while ((C != '.') || (pc != '\n') || \
63*7c478bd9Sstevel@tonic-gate 			    (C > 'Z')) { \
64*7c478bd9Sstevel@tonic-gate 				pc = c; \
65*7c478bd9Sstevel@tonic-gate 			}
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate #define	YES 1
68*7c478bd9Sstevel@tonic-gate #define	NO 0
69*7c478bd9Sstevel@tonic-gate #define	MS 0
70*7c478bd9Sstevel@tonic-gate #define	MM 1
71*7c478bd9Sstevel@tonic-gate #define	ONE 1
72*7c478bd9Sstevel@tonic-gate #define	TWO 2
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate #define	NOCHAR -2
75*7c478bd9Sstevel@tonic-gate #define	SPECIAL 0
76*7c478bd9Sstevel@tonic-gate #define	APOS 1
77*7c478bd9Sstevel@tonic-gate #define	DIGIT 2
78*7c478bd9Sstevel@tonic-gate #define	LETTER 3
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate #define	MAXLINESZ	512
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate static int wordflag = NO;
83*7c478bd9Sstevel@tonic-gate static int msflag = NO;
84*7c478bd9Sstevel@tonic-gate static int iflag = NO;
85*7c478bd9Sstevel@tonic-gate static int mac = MM;
86*7c478bd9Sstevel@tonic-gate static int disp = 0;
87*7c478bd9Sstevel@tonic-gate static int inmacro = NO;
88*7c478bd9Sstevel@tonic-gate static int intable = NO;
89*7c478bd9Sstevel@tonic-gate static int lindx;
90*7c478bd9Sstevel@tonic-gate static size_t linesize = MAXLINESZ;
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate static char chars[128];  /* SPECIAL, APOS, DIGIT, or LETTER */
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate static char *line = NULL;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate static char c;
97*7c478bd9Sstevel@tonic-gate static int pc;
98*7c478bd9Sstevel@tonic-gate static int ldelim	= NOCHAR;
99*7c478bd9Sstevel@tonic-gate static int rdelim	= NOCHAR;
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate static int argc;
102*7c478bd9Sstevel@tonic-gate static char **argv;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate extern int optind;
105*7c478bd9Sstevel@tonic-gate extern char *optarg;
106*7c478bd9Sstevel@tonic-gate static char fname[50];
107*7c478bd9Sstevel@tonic-gate static FILE *files[15];
108*7c478bd9Sstevel@tonic-gate static FILE **filesp;
109*7c478bd9Sstevel@tonic-gate static FILE *infile;
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate static void backsl(void);
112*7c478bd9Sstevel@tonic-gate static void comline(void);
113*7c478bd9Sstevel@tonic-gate static char *copys(char *);
114*7c478bd9Sstevel@tonic-gate static int eof(void);
115*7c478bd9Sstevel@tonic-gate static void eqn(void);
116*7c478bd9Sstevel@tonic-gate static void fatal(const char *, ...);
117*7c478bd9Sstevel@tonic-gate static void fatal_msg(char *);
118*7c478bd9Sstevel@tonic-gate static void getfname(void);
119*7c478bd9Sstevel@tonic-gate static void macro(void);
120*7c478bd9Sstevel@tonic-gate static FILE *opn(char *);
121*7c478bd9Sstevel@tonic-gate static void putmac(char *, int);
122*7c478bd9Sstevel@tonic-gate static void putwords(int);
123*7c478bd9Sstevel@tonic-gate static void regline(int, int);
124*7c478bd9Sstevel@tonic-gate static void sce(void);
125*7c478bd9Sstevel@tonic-gate static int skeqn();
126*7c478bd9Sstevel@tonic-gate static void sdis(char, char);
127*7c478bd9Sstevel@tonic-gate static void stbl(void);
128*7c478bd9Sstevel@tonic-gate static void tbl(void);
129*7c478bd9Sstevel@tonic-gate static void usage(void);
130*7c478bd9Sstevel@tonic-gate static void work(void);
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate void
133*7c478bd9Sstevel@tonic-gate main(int ac, char **av)
134*7c478bd9Sstevel@tonic-gate {
135*7c478bd9Sstevel@tonic-gate 	int i;
136*7c478bd9Sstevel@tonic-gate 	int errflg = 0;
137*7c478bd9Sstevel@tonic-gate 	int optchar;
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
140*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
141*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
142*7c478bd9Sstevel@tonic-gate #endif
143*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
144*7c478bd9Sstevel@tonic-gate 	argc = ac;
145*7c478bd9Sstevel@tonic-gate 	argv = av;
146*7c478bd9Sstevel@tonic-gate 	while ((optchar = getopt(argc, argv, "wim:")) != EOF) {
147*7c478bd9Sstevel@tonic-gate 		switch (optchar) {
148*7c478bd9Sstevel@tonic-gate 		case 'w':
149*7c478bd9Sstevel@tonic-gate 			wordflag = YES;
150*7c478bd9Sstevel@tonic-gate 			break;
151*7c478bd9Sstevel@tonic-gate 		case 'm':
152*7c478bd9Sstevel@tonic-gate 			msflag = YES;
153*7c478bd9Sstevel@tonic-gate 			if (*optarg == 'm')
154*7c478bd9Sstevel@tonic-gate 				mac = MM;
155*7c478bd9Sstevel@tonic-gate 			else if (*optarg == 's')
156*7c478bd9Sstevel@tonic-gate 				mac = MS;
157*7c478bd9Sstevel@tonic-gate 			else if (*optarg == 'l')
158*7c478bd9Sstevel@tonic-gate 				disp = 1;
159*7c478bd9Sstevel@tonic-gate 			else
160*7c478bd9Sstevel@tonic-gate 				errflg++;
161*7c478bd9Sstevel@tonic-gate 			break;
162*7c478bd9Sstevel@tonic-gate 		case 'i':
163*7c478bd9Sstevel@tonic-gate 			iflag = YES;
164*7c478bd9Sstevel@tonic-gate 			break;
165*7c478bd9Sstevel@tonic-gate 		case '?':
166*7c478bd9Sstevel@tonic-gate 			errflg++;
167*7c478bd9Sstevel@tonic-gate 		}
168*7c478bd9Sstevel@tonic-gate 	}
169*7c478bd9Sstevel@tonic-gate 	if (errflg)
170*7c478bd9Sstevel@tonic-gate 		usage();
171*7c478bd9Sstevel@tonic-gate 	if (optind == argc)
172*7c478bd9Sstevel@tonic-gate 		infile = stdin;
173*7c478bd9Sstevel@tonic-gate 	else
174*7c478bd9Sstevel@tonic-gate 		infile = opn(argv[optind++]);
175*7c478bd9Sstevel@tonic-gate 	files[0] = infile;
176*7c478bd9Sstevel@tonic-gate 	filesp = &files[0];
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	for (i = 'a'; i <= 'z'; ++i)
179*7c478bd9Sstevel@tonic-gate 		chars[i] = LETTER;
180*7c478bd9Sstevel@tonic-gate 	for (i = 'A'; i <= 'Z'; ++i)
181*7c478bd9Sstevel@tonic-gate 		chars[i] = LETTER;
182*7c478bd9Sstevel@tonic-gate 	for (i = '0'; i <= '9'; ++i)
183*7c478bd9Sstevel@tonic-gate 		chars[i] = DIGIT;
184*7c478bd9Sstevel@tonic-gate 	chars['\''] = APOS;
185*7c478bd9Sstevel@tonic-gate 	chars['&'] = APOS;
186*7c478bd9Sstevel@tonic-gate 	work();
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate static int
195*7c478bd9Sstevel@tonic-gate skeqn()
196*7c478bd9Sstevel@tonic-gate {
197*7c478bd9Sstevel@tonic-gate 	while ((c = getc(infile)) != rdelim) {
198*7c478bd9Sstevel@tonic-gate 		if (c == EOF) {
199*7c478bd9Sstevel@tonic-gate 			c = eof();
200*7c478bd9Sstevel@tonic-gate 		} else if (c == '"') {
201*7c478bd9Sstevel@tonic-gate 			while ((c = getc(infile)) != '"') {
202*7c478bd9Sstevel@tonic-gate 				if (c == EOF) {
203*7c478bd9Sstevel@tonic-gate 					c = eof();
204*7c478bd9Sstevel@tonic-gate 				} else if (c == '\\') {
205*7c478bd9Sstevel@tonic-gate 					if ((c = getc(infile)) == EOF) {
206*7c478bd9Sstevel@tonic-gate 						c = eof();
207*7c478bd9Sstevel@tonic-gate 					}
208*7c478bd9Sstevel@tonic-gate 				}
209*7c478bd9Sstevel@tonic-gate 			}
210*7c478bd9Sstevel@tonic-gate 		}
211*7c478bd9Sstevel@tonic-gate 	}
212*7c478bd9Sstevel@tonic-gate 	if (msflag) {
213*7c478bd9Sstevel@tonic-gate 		return (c = 'x');
214*7c478bd9Sstevel@tonic-gate 	}
215*7c478bd9Sstevel@tonic-gate 	return (c = ' ');
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate /* Functions calling opn() should ensure 'p' is non-null */
220*7c478bd9Sstevel@tonic-gate static FILE *
221*7c478bd9Sstevel@tonic-gate opn(char *p)
222*7c478bd9Sstevel@tonic-gate {
223*7c478bd9Sstevel@tonic-gate 	FILE *fd;
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate 	assert(p != NULL);
226*7c478bd9Sstevel@tonic-gate 	if ((fd = fopen(p, "r")) == NULL)
227*7c478bd9Sstevel@tonic-gate 		fatal(gettext("Cannot open file %s: %s\n"), p, strerror(errno));
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	return (fd);
230*7c478bd9Sstevel@tonic-gate }
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate static int
235*7c478bd9Sstevel@tonic-gate eof(void)
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 	if (infile != stdin)
238*7c478bd9Sstevel@tonic-gate 		(void) fclose(infile);
239*7c478bd9Sstevel@tonic-gate 	if (filesp > files) {
240*7c478bd9Sstevel@tonic-gate 		infile = *--filesp;
241*7c478bd9Sstevel@tonic-gate 	} else if (optind < argc) {
242*7c478bd9Sstevel@tonic-gate 		infile = opn(argv[optind++]);
243*7c478bd9Sstevel@tonic-gate 	} else {
244*7c478bd9Sstevel@tonic-gate 		exit(0);
245*7c478bd9Sstevel@tonic-gate 	}
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate 	return (C);
248*7c478bd9Sstevel@tonic-gate }
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate static void
253*7c478bd9Sstevel@tonic-gate getfname(void)
254*7c478bd9Sstevel@tonic-gate {
255*7c478bd9Sstevel@tonic-gate 	char *p;
256*7c478bd9Sstevel@tonic-gate 	struct chain {
257*7c478bd9Sstevel@tonic-gate 		struct chain *nextp;
258*7c478bd9Sstevel@tonic-gate 		char *datap;
259*7c478bd9Sstevel@tonic-gate 	};
260*7c478bd9Sstevel@tonic-gate 	struct chain *q;
261*7c478bd9Sstevel@tonic-gate 	static struct chain *namechain = NULL;
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate 	while (C == ' ')
264*7c478bd9Sstevel@tonic-gate 		;
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	for (p = fname; ((*p = c) != '\n') && (c != ' ') && (c != '\t') &&
267*7c478bd9Sstevel@tonic-gate 	    (c != '\\'); ++p) {
268*7c478bd9Sstevel@tonic-gate 		(void) C;
269*7c478bd9Sstevel@tonic-gate 	}
270*7c478bd9Sstevel@tonic-gate 	*p = '\0';
271*7c478bd9Sstevel@tonic-gate 	while (c != '\n') {
272*7c478bd9Sstevel@tonic-gate 		(void) C;
273*7c478bd9Sstevel@tonic-gate 	}
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 	/* see if this name has already been used */
276*7c478bd9Sstevel@tonic-gate 	for (q = namechain; q; q = q->nextp)
277*7c478bd9Sstevel@tonic-gate 		if (strcmp(fname, q->datap) != 0) {
278*7c478bd9Sstevel@tonic-gate 			fname[0] = '\0';
279*7c478bd9Sstevel@tonic-gate 			return;
280*7c478bd9Sstevel@tonic-gate 		}
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate 	q = (struct chain *)calloc(1, sizeof (*namechain));
283*7c478bd9Sstevel@tonic-gate 	q->nextp = namechain;
284*7c478bd9Sstevel@tonic-gate 	q->datap = copys(fname);
285*7c478bd9Sstevel@tonic-gate 	namechain = q;
286*7c478bd9Sstevel@tonic-gate }
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate /*
290*7c478bd9Sstevel@tonic-gate  * Functions calling fatal() should ensure 'format' and
291*7c478bd9Sstevel@tonic-gate  * arguments are non-null.
292*7c478bd9Sstevel@tonic-gate  */
293*7c478bd9Sstevel@tonic-gate static void
294*7c478bd9Sstevel@tonic-gate fatal(const char *format, ...)
295*7c478bd9Sstevel@tonic-gate {
296*7c478bd9Sstevel@tonic-gate 	va_list	alist;
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	assert(format != NULL);
299*7c478bd9Sstevel@tonic-gate 	(void) fputs(gettext("deroff: "), stderr);
300*7c478bd9Sstevel@tonic-gate 	va_start(alist, format);
301*7c478bd9Sstevel@tonic-gate 	(void) vfprintf(stderr, format, alist);
302*7c478bd9Sstevel@tonic-gate 	exit(1);
303*7c478bd9Sstevel@tonic-gate }
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate /* Functions calling fatal_msg() should ensure 's' is non-null */
306*7c478bd9Sstevel@tonic-gate static void
307*7c478bd9Sstevel@tonic-gate fatal_msg(char *s)
308*7c478bd9Sstevel@tonic-gate {
309*7c478bd9Sstevel@tonic-gate 	assert(s != NULL);
310*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("deroff: %s\n"), s);
311*7c478bd9Sstevel@tonic-gate 	exit(1);
312*7c478bd9Sstevel@tonic-gate }
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate static void
315*7c478bd9Sstevel@tonic-gate usage(void)
316*7c478bd9Sstevel@tonic-gate {
317*7c478bd9Sstevel@tonic-gate 	(void) fputs(gettext(
318*7c478bd9Sstevel@tonic-gate 	    "usage: deroff [ -w ] [ -m (m s l) ] [ -i ] "
319*7c478bd9Sstevel@tonic-gate 	    "[ file ] ... \n"), stderr);
320*7c478bd9Sstevel@tonic-gate 	exit(1);
321*7c478bd9Sstevel@tonic-gate }
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate static void
324*7c478bd9Sstevel@tonic-gate work(void)
325*7c478bd9Sstevel@tonic-gate {
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 	for (;;) {
328*7c478bd9Sstevel@tonic-gate 		if ((C == '.') || (c == '\''))
329*7c478bd9Sstevel@tonic-gate 			comline();
330*7c478bd9Sstevel@tonic-gate 		else
331*7c478bd9Sstevel@tonic-gate 			regline(NO, TWO);
332*7c478bd9Sstevel@tonic-gate 	}
333*7c478bd9Sstevel@tonic-gate }
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate static void
337*7c478bd9Sstevel@tonic-gate regline(int macline, int cnst)
338*7c478bd9Sstevel@tonic-gate {
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 	if (line == NULL) {
341*7c478bd9Sstevel@tonic-gate 		if ((line = (char *)malloc(linesize * sizeof (char))) == NULL) {
342*7c478bd9Sstevel@tonic-gate 			fatal_msg(gettext("Cannot allocate memory"));
343*7c478bd9Sstevel@tonic-gate 		}
344*7c478bd9Sstevel@tonic-gate 	}
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	lindx = 0;
347*7c478bd9Sstevel@tonic-gate 	line[lindx] = c;
348*7c478bd9Sstevel@tonic-gate 	for (;;) {
349*7c478bd9Sstevel@tonic-gate 		if (c == '\\') {
350*7c478bd9Sstevel@tonic-gate 			line[lindx] = ' ';
351*7c478bd9Sstevel@tonic-gate 			backsl();
352*7c478bd9Sstevel@tonic-gate 			if (c == '%') {	/* no blank for hyphenation char */
353*7c478bd9Sstevel@tonic-gate 				lindx--;
354*7c478bd9Sstevel@tonic-gate 			}
355*7c478bd9Sstevel@tonic-gate 		}
356*7c478bd9Sstevel@tonic-gate 		if (c == '\n') {
357*7c478bd9Sstevel@tonic-gate 			break;
358*7c478bd9Sstevel@tonic-gate 		}
359*7c478bd9Sstevel@tonic-gate 		/*
360*7c478bd9Sstevel@tonic-gate 		 * We're just about to add another character to the line
361*7c478bd9Sstevel@tonic-gate 		 * buffer so ensure we don't overrun it.
362*7c478bd9Sstevel@tonic-gate 		 */
363*7c478bd9Sstevel@tonic-gate 		if (++lindx >= linesize - 1) {
364*7c478bd9Sstevel@tonic-gate 			linesize = linesize * 2;
365*7c478bd9Sstevel@tonic-gate 			if ((line = (char *)realloc(line,
366*7c478bd9Sstevel@tonic-gate 			    linesize * sizeof (char))) == NULL) {
367*7c478bd9Sstevel@tonic-gate 				fatal_msg(gettext("Cannot allocate memory"));
368*7c478bd9Sstevel@tonic-gate 			}
369*7c478bd9Sstevel@tonic-gate 		}
370*7c478bd9Sstevel@tonic-gate 		if (intable && (c == 'T')) {
371*7c478bd9Sstevel@tonic-gate 			line[lindx] = C;
372*7c478bd9Sstevel@tonic-gate 			if ((c == '{') || (c == '}')) {
373*7c478bd9Sstevel@tonic-gate 				line[lindx - 1] = ' ';
374*7c478bd9Sstevel@tonic-gate 				line[lindx] = C;
375*7c478bd9Sstevel@tonic-gate 			}
376*7c478bd9Sstevel@tonic-gate 		} else {
377*7c478bd9Sstevel@tonic-gate 			line[lindx] = C;
378*7c478bd9Sstevel@tonic-gate 		}
379*7c478bd9Sstevel@tonic-gate 	}
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 	line[lindx] = '\0';
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate 	if (line[0] != '\0') {
384*7c478bd9Sstevel@tonic-gate 		if (wordflag) {
385*7c478bd9Sstevel@tonic-gate 			putwords(macline);
386*7c478bd9Sstevel@tonic-gate 		} else if (macline) {
387*7c478bd9Sstevel@tonic-gate 			putmac(line, cnst);
388*7c478bd9Sstevel@tonic-gate 		} else {
389*7c478bd9Sstevel@tonic-gate 			(void) puts(line);
390*7c478bd9Sstevel@tonic-gate 		}
391*7c478bd9Sstevel@tonic-gate 	}
392*7c478bd9Sstevel@tonic-gate }
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate static void
398*7c478bd9Sstevel@tonic-gate putmac(char *s, int cnst)
399*7c478bd9Sstevel@tonic-gate {
400*7c478bd9Sstevel@tonic-gate 	char *t;
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 	while (*s) {
403*7c478bd9Sstevel@tonic-gate 		while ((*s == ' ') || (*s == '\t')) {
404*7c478bd9Sstevel@tonic-gate 			(void) putchar(*s++);
405*7c478bd9Sstevel@tonic-gate 		}
406*7c478bd9Sstevel@tonic-gate 		for (t = s; (*t != ' ') && (*t != '\t') && (*t != '\0'); ++t)
407*7c478bd9Sstevel@tonic-gate 			;
408*7c478bd9Sstevel@tonic-gate 		if (*s == '\"')
409*7c478bd9Sstevel@tonic-gate 			s++;
410*7c478bd9Sstevel@tonic-gate 		if ((t > s + cnst) && (chars[s[0]] == LETTER) &&
411*7c478bd9Sstevel@tonic-gate 		    (chars[s[1]] == LETTER)) {
412*7c478bd9Sstevel@tonic-gate 			while (s < t) {
413*7c478bd9Sstevel@tonic-gate 				if (*s == '\"')
414*7c478bd9Sstevel@tonic-gate 					s++;
415*7c478bd9Sstevel@tonic-gate 				else
416*7c478bd9Sstevel@tonic-gate 					(void) putchar(*s++);
417*7c478bd9Sstevel@tonic-gate 			}
418*7c478bd9Sstevel@tonic-gate 		} else {
419*7c478bd9Sstevel@tonic-gate 			s = t;
420*7c478bd9Sstevel@tonic-gate 		}
421*7c478bd9Sstevel@tonic-gate 	}
422*7c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
423*7c478bd9Sstevel@tonic-gate }
424*7c478bd9Sstevel@tonic-gate 
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate static void
428*7c478bd9Sstevel@tonic-gate putwords(int macline)	/* break into words for -w option */
429*7c478bd9Sstevel@tonic-gate {
430*7c478bd9Sstevel@tonic-gate 	char *p, *p1;
431*7c478bd9Sstevel@tonic-gate 	int i, nlet;
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 	for (p1 = line; ; ) {
434*7c478bd9Sstevel@tonic-gate 		/* skip initial specials ampersands and apostrophes */
435*7c478bd9Sstevel@tonic-gate 		while (chars[*p1] < DIGIT) {
436*7c478bd9Sstevel@tonic-gate 			if (*p1++ == '\0')
437*7c478bd9Sstevel@tonic-gate 				return;
438*7c478bd9Sstevel@tonic-gate 		}
439*7c478bd9Sstevel@tonic-gate 		nlet = 0;
440*7c478bd9Sstevel@tonic-gate 		for (p = p1; (i = chars[*p]) != SPECIAL; ++p) {
441*7c478bd9Sstevel@tonic-gate 			if (i == LETTER)
442*7c478bd9Sstevel@tonic-gate 				++nlet;
443*7c478bd9Sstevel@tonic-gate 		}
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 		if ((!macline && (nlet > 1)) /* MDM definition of word */ ||
446*7c478bd9Sstevel@tonic-gate 		    (macline && (nlet > 2) && (chars[p1[0]] == LETTER) &&
447*7c478bd9Sstevel@tonic-gate 		    (chars[p1[1]] == LETTER))) {
448*7c478bd9Sstevel@tonic-gate 			/* delete trailing ampersands and apostrophes */
449*7c478bd9Sstevel@tonic-gate 			while ((p[-1] == '\'') || (p[-1] == '&')) {
450*7c478bd9Sstevel@tonic-gate 				--p;
451*7c478bd9Sstevel@tonic-gate 			}
452*7c478bd9Sstevel@tonic-gate 			while (p1 < p) {
453*7c478bd9Sstevel@tonic-gate 				(void) putchar(*p1++);
454*7c478bd9Sstevel@tonic-gate 			}
455*7c478bd9Sstevel@tonic-gate 			(void) putchar('\n');
456*7c478bd9Sstevel@tonic-gate 		} else {
457*7c478bd9Sstevel@tonic-gate 			p1 = p;
458*7c478bd9Sstevel@tonic-gate 		}
459*7c478bd9Sstevel@tonic-gate 	}
460*7c478bd9Sstevel@tonic-gate }
461*7c478bd9Sstevel@tonic-gate 
462*7c478bd9Sstevel@tonic-gate 
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate static void
465*7c478bd9Sstevel@tonic-gate comline(void)
466*7c478bd9Sstevel@tonic-gate {
467*7c478bd9Sstevel@tonic-gate 	int c1, c2;
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate com:
470*7c478bd9Sstevel@tonic-gate 	while ((C == ' ') || (c == '\t'))
471*7c478bd9Sstevel@tonic-gate 		;
472*7c478bd9Sstevel@tonic-gate comx:
473*7c478bd9Sstevel@tonic-gate 	if ((c1 = c) == '\n')
474*7c478bd9Sstevel@tonic-gate 		return;
475*7c478bd9Sstevel@tonic-gate 	c2 = C;
476*7c478bd9Sstevel@tonic-gate 	if ((c1 == '.') && (c2 != '.'))
477*7c478bd9Sstevel@tonic-gate 		inmacro = NO;
478*7c478bd9Sstevel@tonic-gate 	if (c2 == '\n')
479*7c478bd9Sstevel@tonic-gate 		return;
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	if ((c1 == 'E') && (c2 == 'Q') && (filesp == files)) {
482*7c478bd9Sstevel@tonic-gate 		eqn();
483*7c478bd9Sstevel@tonic-gate 	} else if ((c1 == 'T') && ((c2 == 'S') || (c2 == 'C') ||
484*7c478bd9Sstevel@tonic-gate 	    (c2 == '&')) && (filesp == files)) {
485*7c478bd9Sstevel@tonic-gate 		if (msflag) {
486*7c478bd9Sstevel@tonic-gate 			stbl();
487*7c478bd9Sstevel@tonic-gate 		} else {
488*7c478bd9Sstevel@tonic-gate 			tbl();
489*7c478bd9Sstevel@tonic-gate 		}
490*7c478bd9Sstevel@tonic-gate 	} else if ((c1 == 'T') && (c2 == 'E')) {
491*7c478bd9Sstevel@tonic-gate 		intable = NO;
492*7c478bd9Sstevel@tonic-gate 	} else if (!inmacro && (c1 == 'd') && (c2 == 'e')) {
493*7c478bd9Sstevel@tonic-gate 		macro();
494*7c478bd9Sstevel@tonic-gate 	} else if (!inmacro && (c1 == 'i') && (c2 == 'g')) {
495*7c478bd9Sstevel@tonic-gate 		macro();
496*7c478bd9Sstevel@tonic-gate 	} else if (!inmacro && (c1 == 'a') && (c2 == 'm')) {
497*7c478bd9Sstevel@tonic-gate 		macro();
498*7c478bd9Sstevel@tonic-gate 	} else if ((c1 == 's') && (c2 == 'o')) {
499*7c478bd9Sstevel@tonic-gate 		if (iflag) {
500*7c478bd9Sstevel@tonic-gate 			SKIP;
501*7c478bd9Sstevel@tonic-gate 		} else {
502*7c478bd9Sstevel@tonic-gate 			getfname();
503*7c478bd9Sstevel@tonic-gate 			if (fname[0]) {
504*7c478bd9Sstevel@tonic-gate 				infile = *++filesp = opn(fname);
505*7c478bd9Sstevel@tonic-gate 			}
506*7c478bd9Sstevel@tonic-gate 		}
507*7c478bd9Sstevel@tonic-gate 	} else if ((c1 == 'n') && (c2 == 'x')) {
508*7c478bd9Sstevel@tonic-gate 		if (iflag) {
509*7c478bd9Sstevel@tonic-gate 			SKIP;
510*7c478bd9Sstevel@tonic-gate 		} else {
511*7c478bd9Sstevel@tonic-gate 			getfname();
512*7c478bd9Sstevel@tonic-gate 			if (fname[0] == '\0') {
513*7c478bd9Sstevel@tonic-gate 				exit(0);
514*7c478bd9Sstevel@tonic-gate 			}
515*7c478bd9Sstevel@tonic-gate 			if (infile != stdin) {
516*7c478bd9Sstevel@tonic-gate 				(void) fclose(infile);
517*7c478bd9Sstevel@tonic-gate 			}
518*7c478bd9Sstevel@tonic-gate 			infile = *filesp = opn(fname);
519*7c478bd9Sstevel@tonic-gate 		}
520*7c478bd9Sstevel@tonic-gate 	} else if ((c1 == 'h') && (c2 == 'w')) {
521*7c478bd9Sstevel@tonic-gate 		SKIP;
522*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'T') && (c2 == 'L')) {
523*7c478bd9Sstevel@tonic-gate 		SKIP_TO_COM;
524*7c478bd9Sstevel@tonic-gate 		goto comx;
525*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'N') && (c2 == 'R')) {
526*7c478bd9Sstevel@tonic-gate 		SKIP;
527*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'A') && ((c2 == 'U') || (c2 == 'I'))) {
528*7c478bd9Sstevel@tonic-gate 		if (mac == MM) {
529*7c478bd9Sstevel@tonic-gate 			SKIP;
530*7c478bd9Sstevel@tonic-gate 		} else {
531*7c478bd9Sstevel@tonic-gate 			SKIP_TO_COM;
532*7c478bd9Sstevel@tonic-gate 			goto comx;
533*7c478bd9Sstevel@tonic-gate 		}
534*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'F') && (c2 == 'S')) {
535*7c478bd9Sstevel@tonic-gate 		SKIP_TO_COM;
536*7c478bd9Sstevel@tonic-gate 		goto comx;
537*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'S') && (c2 == 'H')) {
538*7c478bd9Sstevel@tonic-gate 		SKIP_TO_COM;
539*7c478bd9Sstevel@tonic-gate 		goto comx;
540*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'N') && (c2 == 'H')) {
541*7c478bd9Sstevel@tonic-gate 		SKIP_TO_COM;
542*7c478bd9Sstevel@tonic-gate 		goto comx;
543*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'O') && (c2 == 'K')) {
544*7c478bd9Sstevel@tonic-gate 		SKIP_TO_COM;
545*7c478bd9Sstevel@tonic-gate 		goto comx;
546*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'N') && (c2 == 'D')) {
547*7c478bd9Sstevel@tonic-gate 		SKIP;
548*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (mac == MM) && (c1 == 'H') &&
549*7c478bd9Sstevel@tonic-gate 	    ((c2 == ' ') || (c2 == 'U'))) {
550*7c478bd9Sstevel@tonic-gate 		SKIP;
551*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (mac == MM) && (c2 == 'L')) {
552*7c478bd9Sstevel@tonic-gate 		if (disp || (c1 == 'R')) {
553*7c478bd9Sstevel@tonic-gate 			sdis('L', 'E');
554*7c478bd9Sstevel@tonic-gate 		} else {
555*7c478bd9Sstevel@tonic-gate 			SKIP;
556*7c478bd9Sstevel@tonic-gate 			(void) putchar('.');
557*7c478bd9Sstevel@tonic-gate 		}
558*7c478bd9Sstevel@tonic-gate 	} else if (msflag && ((c1 == 'D') || (c1 == 'N') ||
559*7c478bd9Sstevel@tonic-gate 	    (c1 == 'K') || (c1 == 'P')) && (c2 == 'S')) {
560*7c478bd9Sstevel@tonic-gate 		sdis(c1, 'E');		/* removed RS-RE */
561*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'K' && c2 == 'F')) {
562*7c478bd9Sstevel@tonic-gate 		sdis(c1, 'E');
563*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'n') && (c2 == 'f')) {
564*7c478bd9Sstevel@tonic-gate 		sdis('f', 'i');
565*7c478bd9Sstevel@tonic-gate 	} else if (msflag && (c1 == 'c') && (c2 == 'e')) {
566*7c478bd9Sstevel@tonic-gate 		sce();
567*7c478bd9Sstevel@tonic-gate 	} else {
568*7c478bd9Sstevel@tonic-gate 		if ((c1 == '.') && (c2 == '.')) {
569*7c478bd9Sstevel@tonic-gate 			while (C == '.')
570*7c478bd9Sstevel@tonic-gate 				;
571*7c478bd9Sstevel@tonic-gate 		}
572*7c478bd9Sstevel@tonic-gate 		++inmacro;
573*7c478bd9Sstevel@tonic-gate 		if ((c1 <= 'Z') && msflag) {
574*7c478bd9Sstevel@tonic-gate 			regline(YES, ONE);
575*7c478bd9Sstevel@tonic-gate 		} else {
576*7c478bd9Sstevel@tonic-gate 			regline(YES, TWO);
577*7c478bd9Sstevel@tonic-gate 		}
578*7c478bd9Sstevel@tonic-gate 		--inmacro;
579*7c478bd9Sstevel@tonic-gate 	}
580*7c478bd9Sstevel@tonic-gate }
581*7c478bd9Sstevel@tonic-gate 
582*7c478bd9Sstevel@tonic-gate 
583*7c478bd9Sstevel@tonic-gate 
584*7c478bd9Sstevel@tonic-gate static void
585*7c478bd9Sstevel@tonic-gate macro(void)
586*7c478bd9Sstevel@tonic-gate {
587*7c478bd9Sstevel@tonic-gate 	if (msflag) {
588*7c478bd9Sstevel@tonic-gate 		/* look for  .. */
589*7c478bd9Sstevel@tonic-gate 		do {
590*7c478bd9Sstevel@tonic-gate 			SKIP;
591*7c478bd9Sstevel@tonic-gate 		} while ((C != '.') || (C != '.') || (C == '.'));
592*7c478bd9Sstevel@tonic-gate 		if (c != '\n') {
593*7c478bd9Sstevel@tonic-gate 			SKIP;
594*7c478bd9Sstevel@tonic-gate 		}
595*7c478bd9Sstevel@tonic-gate 		return;
596*7c478bd9Sstevel@tonic-gate 	}
597*7c478bd9Sstevel@tonic-gate 	SKIP;
598*7c478bd9Sstevel@tonic-gate 	inmacro = YES;
599*7c478bd9Sstevel@tonic-gate }
600*7c478bd9Sstevel@tonic-gate 
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate 
603*7c478bd9Sstevel@tonic-gate 
604*7c478bd9Sstevel@tonic-gate static void
605*7c478bd9Sstevel@tonic-gate sdis(char a1, char a2)
606*7c478bd9Sstevel@tonic-gate {
607*7c478bd9Sstevel@tonic-gate 	int c1, c2;
608*7c478bd9Sstevel@tonic-gate 	int eqnf;
609*7c478bd9Sstevel@tonic-gate 	int notdone = 1;
610*7c478bd9Sstevel@tonic-gate 	eqnf = 1;
611*7c478bd9Sstevel@tonic-gate 	SKIP;
612*7c478bd9Sstevel@tonic-gate 	while (notdone) {
613*7c478bd9Sstevel@tonic-gate 		while (C != '.')
614*7c478bd9Sstevel@tonic-gate 			SKIP;
615*7c478bd9Sstevel@tonic-gate 		if ((c1 = C) == '\n')
616*7c478bd9Sstevel@tonic-gate 			continue;
617*7c478bd9Sstevel@tonic-gate 		if ((c2 = C) == '\n')
618*7c478bd9Sstevel@tonic-gate 			continue;
619*7c478bd9Sstevel@tonic-gate 		if ((c1 == a1) && (c2 == a2)) {
620*7c478bd9Sstevel@tonic-gate 			SKIP;
621*7c478bd9Sstevel@tonic-gate 			if (eqnf)
622*7c478bd9Sstevel@tonic-gate 				(void) putchar('.');
623*7c478bd9Sstevel@tonic-gate 			(void) putchar('\n');
624*7c478bd9Sstevel@tonic-gate 			return;
625*7c478bd9Sstevel@tonic-gate 		} else if ((a1 == 'D') && (c1 == 'E') && (c2 == 'Q')) {
626*7c478bd9Sstevel@tonic-gate 			eqn();
627*7c478bd9Sstevel@tonic-gate 			eqnf = 0;
628*7c478bd9Sstevel@tonic-gate 		} else {
629*7c478bd9Sstevel@tonic-gate 			SKIP;
630*7c478bd9Sstevel@tonic-gate 		}
631*7c478bd9Sstevel@tonic-gate 	}
632*7c478bd9Sstevel@tonic-gate }
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate static void
635*7c478bd9Sstevel@tonic-gate tbl(void)
636*7c478bd9Sstevel@tonic-gate {
637*7c478bd9Sstevel@tonic-gate 	while (C != '.')
638*7c478bd9Sstevel@tonic-gate 		;
639*7c478bd9Sstevel@tonic-gate 	SKIP;
640*7c478bd9Sstevel@tonic-gate 	intable = YES;
641*7c478bd9Sstevel@tonic-gate }
642*7c478bd9Sstevel@tonic-gate 
643*7c478bd9Sstevel@tonic-gate static void
644*7c478bd9Sstevel@tonic-gate stbl(void)
645*7c478bd9Sstevel@tonic-gate {
646*7c478bd9Sstevel@tonic-gate 	while (C != '.')
647*7c478bd9Sstevel@tonic-gate 		;
648*7c478bd9Sstevel@tonic-gate 	SKIP_TO_COM;
649*7c478bd9Sstevel@tonic-gate 	if ((c != 'T') || (C != 'E')) {
650*7c478bd9Sstevel@tonic-gate 		SKIP;
651*7c478bd9Sstevel@tonic-gate 		pc = c;
652*7c478bd9Sstevel@tonic-gate 		while ((C != '.') || (pc != '\n') ||
653*7c478bd9Sstevel@tonic-gate 		    (C != 'T') || (C != 'E')) {
654*7c478bd9Sstevel@tonic-gate 			pc = c;
655*7c478bd9Sstevel@tonic-gate 		}
656*7c478bd9Sstevel@tonic-gate 	}
657*7c478bd9Sstevel@tonic-gate }
658*7c478bd9Sstevel@tonic-gate 
659*7c478bd9Sstevel@tonic-gate static void
660*7c478bd9Sstevel@tonic-gate eqn(void)
661*7c478bd9Sstevel@tonic-gate {
662*7c478bd9Sstevel@tonic-gate 	int c1, c2;
663*7c478bd9Sstevel@tonic-gate 	int dflg;
664*7c478bd9Sstevel@tonic-gate 	int last;
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate 	last = 0;
667*7c478bd9Sstevel@tonic-gate 	dflg = 1;
668*7c478bd9Sstevel@tonic-gate 	SKIP;
669*7c478bd9Sstevel@tonic-gate 
670*7c478bd9Sstevel@tonic-gate 	for (;;) {
671*7c478bd9Sstevel@tonic-gate 		if ((C1 == '.') || (c == '\'')) {
672*7c478bd9Sstevel@tonic-gate 			while ((C1 == ' ') || (c == '\t'))
673*7c478bd9Sstevel@tonic-gate 				;
674*7c478bd9Sstevel@tonic-gate 			if ((c == 'E') && (C1 == 'N')) {
675*7c478bd9Sstevel@tonic-gate 				SKIP;
676*7c478bd9Sstevel@tonic-gate 				if (msflag && dflg) {
677*7c478bd9Sstevel@tonic-gate 					(void) putchar('x');
678*7c478bd9Sstevel@tonic-gate 					(void) putchar(' ');
679*7c478bd9Sstevel@tonic-gate 					if (last) {
680*7c478bd9Sstevel@tonic-gate 						(void) putchar('.');
681*7c478bd9Sstevel@tonic-gate 						(void) putchar(' ');
682*7c478bd9Sstevel@tonic-gate 					}
683*7c478bd9Sstevel@tonic-gate 				}
684*7c478bd9Sstevel@tonic-gate 				return;
685*7c478bd9Sstevel@tonic-gate 			}
686*7c478bd9Sstevel@tonic-gate 		} else if (c == 'd') {	/* look for delim */
687*7c478bd9Sstevel@tonic-gate 			if ((C1 == 'e') && (C1 == 'l')) {
688*7c478bd9Sstevel@tonic-gate 				if ((C1 == 'i') && (C1 == 'm')) {
689*7c478bd9Sstevel@tonic-gate 					while (C1 == ' ')
690*7c478bd9Sstevel@tonic-gate 						;
691*7c478bd9Sstevel@tonic-gate 					if (((c1 = c) == '\n') ||
692*7c478bd9Sstevel@tonic-gate 					    ((c2 = C1) == '\n') ||
693*7c478bd9Sstevel@tonic-gate 					    ((c1 == 'o') && (c2 == 'f') &&
694*7c478bd9Sstevel@tonic-gate 					    (C1 == 'f'))) {
695*7c478bd9Sstevel@tonic-gate 						ldelim = NOCHAR;
696*7c478bd9Sstevel@tonic-gate 						rdelim = NOCHAR;
697*7c478bd9Sstevel@tonic-gate 					} else {
698*7c478bd9Sstevel@tonic-gate 						ldelim = c1;
699*7c478bd9Sstevel@tonic-gate 						rdelim = c2;
700*7c478bd9Sstevel@tonic-gate 					}
701*7c478bd9Sstevel@tonic-gate 				}
702*7c478bd9Sstevel@tonic-gate 				dflg = 0;
703*7c478bd9Sstevel@tonic-gate 			}
704*7c478bd9Sstevel@tonic-gate 		}
705*7c478bd9Sstevel@tonic-gate 
706*7c478bd9Sstevel@tonic-gate 		if (c != '\n') {
707*7c478bd9Sstevel@tonic-gate 			while (C1 != '\n') {
708*7c478bd9Sstevel@tonic-gate 				if (c == '.') {
709*7c478bd9Sstevel@tonic-gate 					last = 1;
710*7c478bd9Sstevel@tonic-gate 				} else {
711*7c478bd9Sstevel@tonic-gate 					last = 0;
712*7c478bd9Sstevel@tonic-gate 				}
713*7c478bd9Sstevel@tonic-gate 			}
714*7c478bd9Sstevel@tonic-gate 		}
715*7c478bd9Sstevel@tonic-gate 	}
716*7c478bd9Sstevel@tonic-gate }
717*7c478bd9Sstevel@tonic-gate 
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate 
720*7c478bd9Sstevel@tonic-gate static void
721*7c478bd9Sstevel@tonic-gate backsl(void)	/* skip over a complete backslash construction */
722*7c478bd9Sstevel@tonic-gate {
723*7c478bd9Sstevel@tonic-gate 	int bdelim;
724*7c478bd9Sstevel@tonic-gate 
725*7c478bd9Sstevel@tonic-gate sw:	switch (C) {
726*7c478bd9Sstevel@tonic-gate 	case '"':
727*7c478bd9Sstevel@tonic-gate 		SKIP;
728*7c478bd9Sstevel@tonic-gate 		return;
729*7c478bd9Sstevel@tonic-gate 	case 's':
730*7c478bd9Sstevel@tonic-gate 		if (C == '\\') {
731*7c478bd9Sstevel@tonic-gate 			backsl();
732*7c478bd9Sstevel@tonic-gate 		} else {
733*7c478bd9Sstevel@tonic-gate 			while ((C >= '0') && (c <= '9'))
734*7c478bd9Sstevel@tonic-gate 				;
735*7c478bd9Sstevel@tonic-gate 			(void) ungetc(c, infile);
736*7c478bd9Sstevel@tonic-gate 			c = '0';
737*7c478bd9Sstevel@tonic-gate 		}
738*7c478bd9Sstevel@tonic-gate 		lindx--;
739*7c478bd9Sstevel@tonic-gate 		return;
740*7c478bd9Sstevel@tonic-gate 
741*7c478bd9Sstevel@tonic-gate 	case 'f':
742*7c478bd9Sstevel@tonic-gate 	case 'n':
743*7c478bd9Sstevel@tonic-gate 	case '*':
744*7c478bd9Sstevel@tonic-gate 		if (C != '(')
745*7c478bd9Sstevel@tonic-gate 			return;
746*7c478bd9Sstevel@tonic-gate 		/* FALLTHROUGH */
747*7c478bd9Sstevel@tonic-gate 
748*7c478bd9Sstevel@tonic-gate 	case '(':
749*7c478bd9Sstevel@tonic-gate 		if (C != '\n') {
750*7c478bd9Sstevel@tonic-gate 			(void) C;
751*7c478bd9Sstevel@tonic-gate 		}
752*7c478bd9Sstevel@tonic-gate 		return;
753*7c478bd9Sstevel@tonic-gate 
754*7c478bd9Sstevel@tonic-gate 	case '$':
755*7c478bd9Sstevel@tonic-gate 		(void) C;	/* discard argument number */
756*7c478bd9Sstevel@tonic-gate 		return;
757*7c478bd9Sstevel@tonic-gate 
758*7c478bd9Sstevel@tonic-gate 	case 'b':
759*7c478bd9Sstevel@tonic-gate 	case 'x':
760*7c478bd9Sstevel@tonic-gate 	case 'v':
761*7c478bd9Sstevel@tonic-gate 	case 'h':
762*7c478bd9Sstevel@tonic-gate 	case 'w':
763*7c478bd9Sstevel@tonic-gate 	case 'o':
764*7c478bd9Sstevel@tonic-gate 	case 'l':
765*7c478bd9Sstevel@tonic-gate 	case 'L':
766*7c478bd9Sstevel@tonic-gate 		if ((bdelim = C) == '\n')
767*7c478bd9Sstevel@tonic-gate 			return;
768*7c478bd9Sstevel@tonic-gate 		while ((C != '\n') && (c != bdelim))
769*7c478bd9Sstevel@tonic-gate 			if (c == '\\')
770*7c478bd9Sstevel@tonic-gate 				backsl();
771*7c478bd9Sstevel@tonic-gate 		return;
772*7c478bd9Sstevel@tonic-gate 
773*7c478bd9Sstevel@tonic-gate 	case '\\':
774*7c478bd9Sstevel@tonic-gate 		if (inmacro)
775*7c478bd9Sstevel@tonic-gate 			goto sw;
776*7c478bd9Sstevel@tonic-gate 	default:
777*7c478bd9Sstevel@tonic-gate 		return;
778*7c478bd9Sstevel@tonic-gate 	}
779*7c478bd9Sstevel@tonic-gate }
780*7c478bd9Sstevel@tonic-gate 
781*7c478bd9Sstevel@tonic-gate 
782*7c478bd9Sstevel@tonic-gate 
783*7c478bd9Sstevel@tonic-gate 
784*7c478bd9Sstevel@tonic-gate static char *
785*7c478bd9Sstevel@tonic-gate copys(char *s)
786*7c478bd9Sstevel@tonic-gate {
787*7c478bd9Sstevel@tonic-gate 	char *t, *t0;
788*7c478bd9Sstevel@tonic-gate 
789*7c478bd9Sstevel@tonic-gate 	if ((t0 = t = calloc((unsigned)(strlen(s) + 1), sizeof (*t))) == NULL)
790*7c478bd9Sstevel@tonic-gate 		fatal_msg(gettext("Cannot allocate memory"));
791*7c478bd9Sstevel@tonic-gate 
792*7c478bd9Sstevel@tonic-gate 	while (*t++ = *s++)
793*7c478bd9Sstevel@tonic-gate 		;
794*7c478bd9Sstevel@tonic-gate 	return (t0);
795*7c478bd9Sstevel@tonic-gate }
796*7c478bd9Sstevel@tonic-gate 
797*7c478bd9Sstevel@tonic-gate static void
798*7c478bd9Sstevel@tonic-gate sce(void)
799*7c478bd9Sstevel@tonic-gate {
800*7c478bd9Sstevel@tonic-gate 	char *ap;
801*7c478bd9Sstevel@tonic-gate 	int n, i;
802*7c478bd9Sstevel@tonic-gate 	char a[10];
803*7c478bd9Sstevel@tonic-gate 
804*7c478bd9Sstevel@tonic-gate 	for (ap = a; C != '\n'; ap++) {
805*7c478bd9Sstevel@tonic-gate 		*ap = c;
806*7c478bd9Sstevel@tonic-gate 		if (ap == &a[9]) {
807*7c478bd9Sstevel@tonic-gate 			SKIP;
808*7c478bd9Sstevel@tonic-gate 			ap = a;
809*7c478bd9Sstevel@tonic-gate 			break;
810*7c478bd9Sstevel@tonic-gate 		}
811*7c478bd9Sstevel@tonic-gate 	}
812*7c478bd9Sstevel@tonic-gate 	if (ap != a) {
813*7c478bd9Sstevel@tonic-gate 		n = atoi(a);
814*7c478bd9Sstevel@tonic-gate 	} else {
815*7c478bd9Sstevel@tonic-gate 		n = 1;
816*7c478bd9Sstevel@tonic-gate 	}
817*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; ) {
818*7c478bd9Sstevel@tonic-gate 		if (C == '.') {
819*7c478bd9Sstevel@tonic-gate 			if (C == 'c') {
820*7c478bd9Sstevel@tonic-gate 				if (C == 'e') {
821*7c478bd9Sstevel@tonic-gate 					while (C == ' ')
822*7c478bd9Sstevel@tonic-gate 						;
823*7c478bd9Sstevel@tonic-gate 					if (c == '0') {
824*7c478bd9Sstevel@tonic-gate 						break;
825*7c478bd9Sstevel@tonic-gate 					} else {
826*7c478bd9Sstevel@tonic-gate 						SKIP;
827*7c478bd9Sstevel@tonic-gate 					}
828*7c478bd9Sstevel@tonic-gate 				} else {
829*7c478bd9Sstevel@tonic-gate 					SKIP;
830*7c478bd9Sstevel@tonic-gate 				}
831*7c478bd9Sstevel@tonic-gate 			} else {
832*7c478bd9Sstevel@tonic-gate 				SKIP;
833*7c478bd9Sstevel@tonic-gate 			}
834*7c478bd9Sstevel@tonic-gate 		} else {
835*7c478bd9Sstevel@tonic-gate 			SKIP;
836*7c478bd9Sstevel@tonic-gate 			i++;
837*7c478bd9Sstevel@tonic-gate 		}
838*7c478bd9Sstevel@tonic-gate 	}
839*7c478bd9Sstevel@tonic-gate }
840