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