xref: /onnv-gate/usr/src/cmd/sgs/unifdef/common/unifdef.c (revision 0:68f95e015346)
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 /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /* Copyright (c) 1982 Regents of the University of California */
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate /*
35*0Sstevel@tonic-gate  *    unifdef - remove ifdef'ed lines
36*0Sstevel@tonic-gate  */
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate #include <stdio.h>
39*0Sstevel@tonic-gate #include <ctype.h>
40*0Sstevel@tonic-gate #include <locale.h>
41*0Sstevel@tonic-gate #define BSS
42*0Sstevel@tonic-gate FILE *input;
43*0Sstevel@tonic-gate #ifndef YES
44*0Sstevel@tonic-gate #define YES 1
45*0Sstevel@tonic-gate #define NO  0
46*0Sstevel@tonic-gate #endif
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate char *progname BSS;
49*0Sstevel@tonic-gate char *filename BSS;
50*0Sstevel@tonic-gate char text BSS;          /* -t option in effect: this is a text file */
51*0Sstevel@tonic-gate char lnblank BSS;       /* -l option in effect: blank deleted lines */
52*0Sstevel@tonic-gate char complement BSS;    /* -c option in effect: complement the operation */
53*0Sstevel@tonic-gate #define MAXSYMS 100
54*0Sstevel@tonic-gate char true[MAXSYMS] BSS;
55*0Sstevel@tonic-gate char ignore[MAXSYMS] BSS;
56*0Sstevel@tonic-gate char *sym[MAXSYMS] BSS;
57*0Sstevel@tonic-gate signed char insym[MAXSYMS] BSS;
58*0Sstevel@tonic-gate #define KWSIZE 8
59*0Sstevel@tonic-gate char buf[KWSIZE];
60*0Sstevel@tonic-gate char nsyms BSS;
61*0Sstevel@tonic-gate char incomment BSS;
62*0Sstevel@tonic-gate #define QUOTE1 0
63*0Sstevel@tonic-gate #define QUOTE2 1
64*0Sstevel@tonic-gate char inquote[2] BSS;
65*0Sstevel@tonic-gate int exitstat BSS;
66*0Sstevel@tonic-gate char *skipcomment ();
67*0Sstevel@tonic-gate char *skipquote ();
68*0Sstevel@tonic-gate char *nextsym();
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate #ifdef i386
71*0Sstevel@tonic-gate #define gettext(s) s
72*0Sstevel@tonic-gate #endif
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate main (argc, argv)
75*0Sstevel@tonic-gate int argc;
76*0Sstevel@tonic-gate char **argv;
77*0Sstevel@tonic-gate {
78*0Sstevel@tonic-gate     char **curarg;
79*0Sstevel@tonic-gate     register char *cp;
80*0Sstevel@tonic-gate     register char *cp1;
81*0Sstevel@tonic-gate     char ignorethis;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate     (void) setlocale (LC_ALL, "");
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate /* i386 doesn't handle this yet */
86*0Sstevel@tonic-gate #ifndef i386
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
89*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
90*0Sstevel@tonic-gate #endif
91*0Sstevel@tonic-gate     (void) textdomain(TEXT_DOMAIN);
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate #endif
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate     progname = argv[0][0] ? argv[0] : "unifdef";
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate     for (curarg = &argv[1]; --argc > 0; curarg++) {
98*0Sstevel@tonic-gate 	if (*(cp1 = cp = *curarg) != '-')
99*0Sstevel@tonic-gate 	    break;
100*0Sstevel@tonic-gate 	if (*++cp1 == 'i') {
101*0Sstevel@tonic-gate 	    ignorethis = YES;
102*0Sstevel@tonic-gate 	    cp1++;
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 	else
105*0Sstevel@tonic-gate 	    ignorethis = NO;
106*0Sstevel@tonic-gate 	if (   (   *cp1 == 'D'
107*0Sstevel@tonic-gate 		|| *cp1 == 'U'
108*0Sstevel@tonic-gate 	       )
109*0Sstevel@tonic-gate 	    && cp1[1] != '\0'
110*0Sstevel@tonic-gate 	   ) {
111*0Sstevel@tonic-gate 	    if (nsyms >= MAXSYMS) {
112*0Sstevel@tonic-gate 		prname ();
113*0Sstevel@tonic-gate 		fprintf (stderr, gettext("too many symbols.\n"));
114*0Sstevel@tonic-gate 		exit (2);
115*0Sstevel@tonic-gate 	    }
116*0Sstevel@tonic-gate 	    ignore[nsyms] = ignorethis;
117*0Sstevel@tonic-gate 	    true[nsyms] = *cp1 == 'D' ? YES : NO;
118*0Sstevel@tonic-gate 	    sym[nsyms++] = &cp1[1];
119*0Sstevel@tonic-gate 	}
120*0Sstevel@tonic-gate 	else if (ignorethis)
121*0Sstevel@tonic-gate 	    goto unrec;
122*0Sstevel@tonic-gate 	else if (strcmp (&cp[1], "t") == 0)
123*0Sstevel@tonic-gate 	    text = YES;
124*0Sstevel@tonic-gate 	else if (strcmp (&cp[1], "l") == 0)
125*0Sstevel@tonic-gate 	    lnblank = YES;
126*0Sstevel@tonic-gate 	else if (strcmp (&cp[1], "c") == 0)
127*0Sstevel@tonic-gate 	    complement = YES;
128*0Sstevel@tonic-gate 	else {
129*0Sstevel@tonic-gate  unrec:
130*0Sstevel@tonic-gate 	    prname ();
131*0Sstevel@tonic-gate 	    fprintf (stderr, gettext("unrecognized option: %s\n"), cp);
132*0Sstevel@tonic-gate 	    goto usage;
133*0Sstevel@tonic-gate 	}
134*0Sstevel@tonic-gate     }
135*0Sstevel@tonic-gate     if (nsyms == 0) {
136*0Sstevel@tonic-gate  usage:
137*0Sstevel@tonic-gate 	fprintf (stderr, gettext("\
138*0Sstevel@tonic-gate Usage: %s [-l] [-t] [-c] [[-Dsym] [-Usym] [-idsym] [-iusym]]... [file]\n\
139*0Sstevel@tonic-gate     At least one arg from [-D -U -id -iu] is required\n"), progname);
140*0Sstevel@tonic-gate 	exit (2);
141*0Sstevel@tonic-gate     }
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate     if (argc > 1) {
144*0Sstevel@tonic-gate 	prname ();
145*0Sstevel@tonic-gate 	fprintf (stderr, gettext("can only do one file.\n"));
146*0Sstevel@tonic-gate     }
147*0Sstevel@tonic-gate     else if (argc == 1) {
148*0Sstevel@tonic-gate 	filename = *curarg;
149*0Sstevel@tonic-gate 	if ((input = fopen (filename, "r")) != NULL) {
150*0Sstevel@tonic-gate 	    pfile();
151*0Sstevel@tonic-gate 	    fclose (input);
152*0Sstevel@tonic-gate 	}
153*0Sstevel@tonic-gate 	else {
154*0Sstevel@tonic-gate 	    prname ();
155*0Sstevel@tonic-gate 	    perror(*curarg);
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate     }
158*0Sstevel@tonic-gate     else {
159*0Sstevel@tonic-gate 	filename = "[stdin]";
160*0Sstevel@tonic-gate 	input = stdin;
161*0Sstevel@tonic-gate 	pfile();
162*0Sstevel@tonic-gate     }
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate     fflush (stdout);
165*0Sstevel@tonic-gate     exit (exitstat);
166*0Sstevel@tonic-gate 	/* NOTREACHED */
167*0Sstevel@tonic-gate }
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate /* types of input lines: */
170*0Sstevel@tonic-gate #define PLAIN       0   /* ordinary line */
171*0Sstevel@tonic-gate #define TRUE        1   /* a true  #ifdef of a symbol known to us */
172*0Sstevel@tonic-gate #define FALSE       2   /* a false #ifdef of a symbol known to us */
173*0Sstevel@tonic-gate #define OTHER       3   /* an #ifdef of a symbol not known to us */
174*0Sstevel@tonic-gate #define ELSE        4   /* #else */
175*0Sstevel@tonic-gate #define ENDIF       5   /* #endif */
176*0Sstevel@tonic-gate #define LEOF        6   /* end of file */
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate /* should be int declaration, was char */
179*0Sstevel@tonic-gate int reject BSS;    /* 0 or 1: pass thru; 1 or 2: ignore comments */
180*0Sstevel@tonic-gate int linenum BSS;    /* current line number */
181*0Sstevel@tonic-gate int stqcline BSS;   /* start of current coment or quote */
182*0Sstevel@tonic-gate char *errs[] = {
183*0Sstevel@tonic-gate #define NO_ERR      0
184*0Sstevel@tonic-gate 			"",
185*0Sstevel@tonic-gate #define END_ERR     1
186*0Sstevel@tonic-gate 			"",
187*0Sstevel@tonic-gate #define ELSE_ERR    2
188*0Sstevel@tonic-gate 			"Inappropriate else",
189*0Sstevel@tonic-gate #define ENDIF_ERR   3
190*0Sstevel@tonic-gate 			"Inappropriate endif",
191*0Sstevel@tonic-gate #define IEOF_ERR    4
192*0Sstevel@tonic-gate 			"Premature EOF in ifdef",
193*0Sstevel@tonic-gate #define CEOF_ERR    5
194*0Sstevel@tonic-gate 			"Premature EOF in comment",
195*0Sstevel@tonic-gate #define Q1EOF_ERR   6
196*0Sstevel@tonic-gate 			"Premature EOF in quoted character",
197*0Sstevel@tonic-gate #define Q2EOF_ERR   7
198*0Sstevel@tonic-gate 			"Premature EOF in quoted string"
199*0Sstevel@tonic-gate };
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate pfile ()
202*0Sstevel@tonic-gate {
203*0Sstevel@tonic-gate     reject = 0;
204*0Sstevel@tonic-gate     doif (-1, NO, reject, 0);
205*0Sstevel@tonic-gate     return;
206*0Sstevel@tonic-gate }
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate doif (thissym, inif, prevreject, depth)
209*0Sstevel@tonic-gate register int thissym;   /* index of the symbol who was last ifdef'ed */
210*0Sstevel@tonic-gate int inif;               /* YES or NO we are inside an ifdef */
211*0Sstevel@tonic-gate int prevreject;         /* previous value of reject */
212*0Sstevel@tonic-gate int depth;              /* depth of ifdef's */
213*0Sstevel@tonic-gate {
214*0Sstevel@tonic-gate     register int lineval;
215*0Sstevel@tonic-gate     register int thisreject;
216*0Sstevel@tonic-gate     int doret;          /* tmp return value of doif */
217*0Sstevel@tonic-gate     int cursym;         /* index of the symbol returned by checkline */
218*0Sstevel@tonic-gate     int stline;         /* line number when called this time */
219*0Sstevel@tonic-gate 
220*0Sstevel@tonic-gate     stline = linenum;
221*0Sstevel@tonic-gate     for (;;) {
222*0Sstevel@tonic-gate 	switch (lineval = checkline (&cursym)) {
223*0Sstevel@tonic-gate 	case PLAIN:
224*0Sstevel@tonic-gate 	    flushline (YES);
225*0Sstevel@tonic-gate 	    break;
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate 	case TRUE:
228*0Sstevel@tonic-gate 	case FALSE:
229*0Sstevel@tonic-gate 	    thisreject = reject;
230*0Sstevel@tonic-gate 	    if (lineval == TRUE)
231*0Sstevel@tonic-gate 		insym[cursym] = 1;
232*0Sstevel@tonic-gate 	    else {
233*0Sstevel@tonic-gate 		if (reject < 2)
234*0Sstevel@tonic-gate 		    reject = ignore[cursym] ? 1 : 2;
235*0Sstevel@tonic-gate 		insym[cursym] = -1;
236*0Sstevel@tonic-gate 	    }
237*0Sstevel@tonic-gate 	    if (ignore[cursym])
238*0Sstevel@tonic-gate 		flushline (YES);
239*0Sstevel@tonic-gate 	    else {
240*0Sstevel@tonic-gate 		exitstat = 0;
241*0Sstevel@tonic-gate 		flushline (NO);
242*0Sstevel@tonic-gate 	    }
243*0Sstevel@tonic-gate 	    if ((doret = doif (cursym, YES, thisreject, depth + 1)) != NO_ERR)
244*0Sstevel@tonic-gate 		return error (doret, stline, depth);
245*0Sstevel@tonic-gate     	    break;
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 	case OTHER:
248*0Sstevel@tonic-gate 	    flushline (YES);
249*0Sstevel@tonic-gate 	    if ((doret = doif (-1, YES, reject, depth + 1)) != NO_ERR)
250*0Sstevel@tonic-gate 		return error (doret, stline, depth);
251*0Sstevel@tonic-gate 	    break;
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate 	case ELSE:
254*0Sstevel@tonic-gate 	    if (inif != 1)
255*0Sstevel@tonic-gate 		return error (ELSE_ERR, linenum, depth);
256*0Sstevel@tonic-gate 	    inif = 2;
257*0Sstevel@tonic-gate 	    if (thissym >= 0) {
258*0Sstevel@tonic-gate 		if ((insym[thissym] = -insym[thissym]) < 0)
259*0Sstevel@tonic-gate 		    reject = ignore[thissym] ? 1 : 2;
260*0Sstevel@tonic-gate 		else
261*0Sstevel@tonic-gate 		    reject = prevreject;
262*0Sstevel@tonic-gate 		if (!ignore[thissym]) {
263*0Sstevel@tonic-gate 		    flushline (NO);
264*0Sstevel@tonic-gate 		    break;
265*0Sstevel@tonic-gate 		}
266*0Sstevel@tonic-gate 	    }
267*0Sstevel@tonic-gate 	    flushline (YES);
268*0Sstevel@tonic-gate 	    break;
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 	case ENDIF:
271*0Sstevel@tonic-gate 	    if (inif == 0)
272*0Sstevel@tonic-gate 		return error (ENDIF_ERR, linenum, depth);
273*0Sstevel@tonic-gate 	    if (thissym >= 0) {
274*0Sstevel@tonic-gate 		insym[thissym] = 0;
275*0Sstevel@tonic-gate 		reject = prevreject;
276*0Sstevel@tonic-gate 		if (!ignore[thissym]) {
277*0Sstevel@tonic-gate 		    flushline (NO);
278*0Sstevel@tonic-gate 		    return NO_ERR;
279*0Sstevel@tonic-gate 		}
280*0Sstevel@tonic-gate 	    }
281*0Sstevel@tonic-gate 	    flushline (YES);
282*0Sstevel@tonic-gate 	    return NO_ERR;
283*0Sstevel@tonic-gate 
284*0Sstevel@tonic-gate 	case LEOF: {
285*0Sstevel@tonic-gate 	    int err;
286*0Sstevel@tonic-gate 	    err =   incomment
287*0Sstevel@tonic-gate 		  ? CEOF_ERR
288*0Sstevel@tonic-gate 		  : inquote[QUOTE1]
289*0Sstevel@tonic-gate 		  ? Q1EOF_ERR
290*0Sstevel@tonic-gate 		  : inquote[QUOTE2]
291*0Sstevel@tonic-gate 		  ? Q2EOF_ERR
292*0Sstevel@tonic-gate 		  : NO_ERR;
293*0Sstevel@tonic-gate 	    if (inif) {
294*0Sstevel@tonic-gate 		if (err != NO_ERR)
295*0Sstevel@tonic-gate 		    error (err, stqcline, depth);
296*0Sstevel@tonic-gate 		return error (IEOF_ERR, stline, depth);
297*0Sstevel@tonic-gate 	    }
298*0Sstevel@tonic-gate 	    else if (err != NO_ERR)
299*0Sstevel@tonic-gate 		return error (err, stqcline, depth);
300*0Sstevel@tonic-gate 	    else
301*0Sstevel@tonic-gate 		return NO_ERR;
302*0Sstevel@tonic-gate 	    }
303*0Sstevel@tonic-gate 	}
304*0Sstevel@tonic-gate     }
305*0Sstevel@tonic-gate }
306*0Sstevel@tonic-gate 
307*0Sstevel@tonic-gate #define endsym(c) (!isalpha (c) && !isdigit (c) && c != '_')
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate #define MAXLINE 256
310*0Sstevel@tonic-gate char tline[MAXLINE] BSS;
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate checkline (cursym)
313*0Sstevel@tonic-gate int *cursym;
314*0Sstevel@tonic-gate {
315*0Sstevel@tonic-gate     register char *cp;
316*0Sstevel@tonic-gate     register char *symp;
317*0Sstevel@tonic-gate     register char chr;
318*0Sstevel@tonic-gate     char *scp;
319*0Sstevel@tonic-gate     int retval;
320*0Sstevel@tonic-gate     int symind;
321*0Sstevel@tonic-gate     char keyword[KWSIZE];
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate     linenum++;
324*0Sstevel@tonic-gate     if (getlin (tline, sizeof tline, input, NO) == EOF)
325*0Sstevel@tonic-gate         return LEOF;
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate     retval = PLAIN;
328*0Sstevel@tonic-gate     if (   *(cp = tline) != '#'
329*0Sstevel@tonic-gate 	|| incomment
330*0Sstevel@tonic-gate 	|| inquote[QUOTE1]
331*0Sstevel@tonic-gate 	|| inquote[QUOTE2]
332*0Sstevel@tonic-gate        )
333*0Sstevel@tonic-gate 	goto eol;
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate     cp = skipcomment (++cp);
336*0Sstevel@tonic-gate     symp = keyword;
337*0Sstevel@tonic-gate     while (!endsym (*cp)) {
338*0Sstevel@tonic-gate 	*symp = *cp++;
339*0Sstevel@tonic-gate 	if (++symp >= &keyword[KWSIZE])
340*0Sstevel@tonic-gate 	    goto eol;
341*0Sstevel@tonic-gate     }
342*0Sstevel@tonic-gate     *symp = '\0';
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate     if (strcmp (keyword, "ifdef") == 0) {
345*0Sstevel@tonic-gate 	retval = YES;
346*0Sstevel@tonic-gate 	goto ifdef;
347*0Sstevel@tonic-gate     }
348*0Sstevel@tonic-gate     else if (strcmp (keyword, "if") == 0) {
349*0Sstevel@tonic-gate 	cp = skipcomment(++cp);
350*0Sstevel@tonic-gate  	if (strcmp (nextsym(cp), "defined") == 0) {
351*0Sstevel@tonic-gate 		cp += strlen("defined") + 1;
352*0Sstevel@tonic-gate 		/* skip to identifier */
353*0Sstevel@tonic-gate 		while (endsym(*cp))
354*0Sstevel@tonic-gate 			++cp;
355*0Sstevel@tonic-gate 		retval = YES;
356*0Sstevel@tonic-gate 		goto ifdef;
357*0Sstevel@tonic-gate 	}
358*0Sstevel@tonic-gate 	else {
359*0Sstevel@tonic-gate 		retval = OTHER;
360*0Sstevel@tonic-gate 		goto eol;
361*0Sstevel@tonic-gate 	}
362*0Sstevel@tonic-gate     }
363*0Sstevel@tonic-gate     else if (strcmp (keyword, "ifndef") == 0) {
364*0Sstevel@tonic-gate 	retval = NO;
365*0Sstevel@tonic-gate  ifdef:
366*0Sstevel@tonic-gate 	scp = cp = skipcomment (cp);
367*0Sstevel@tonic-gate 	if (incomment) {
368*0Sstevel@tonic-gate 	    retval = PLAIN;
369*0Sstevel@tonic-gate 	    goto eol;
370*0Sstevel@tonic-gate 	}
371*0Sstevel@tonic-gate 	for (symind = 0; ; ) {
372*0Sstevel@tonic-gate 	    if (insym[symind] == 0) {
373*0Sstevel@tonic-gate 		for ( symp = sym[symind], cp = scp
374*0Sstevel@tonic-gate 		    ; *symp && *cp == *symp
375*0Sstevel@tonic-gate 		    ; cp++, symp++
376*0Sstevel@tonic-gate 		    )
377*0Sstevel@tonic-gate 		    {}
378*0Sstevel@tonic-gate 		chr = *cp;
379*0Sstevel@tonic-gate 		if (*symp == '\0' && endsym (chr)) {
380*0Sstevel@tonic-gate 		    *cursym = symind;
381*0Sstevel@tonic-gate 		    retval = (retval ^ true[symind]) ? FALSE : TRUE;
382*0Sstevel@tonic-gate 		    break;
383*0Sstevel@tonic-gate 		}
384*0Sstevel@tonic-gate 	    }
385*0Sstevel@tonic-gate 	    if (++symind >= nsyms) {
386*0Sstevel@tonic-gate 		retval = OTHER;
387*0Sstevel@tonic-gate 		break;
388*0Sstevel@tonic-gate 	    }
389*0Sstevel@tonic-gate 	}
390*0Sstevel@tonic-gate     }
391*0Sstevel@tonic-gate     else if (strcmp (keyword, "else") == 0)
392*0Sstevel@tonic-gate 	retval = ELSE;
393*0Sstevel@tonic-gate     else if (strcmp (keyword, "endif") == 0)
394*0Sstevel@tonic-gate 	retval = ENDIF;
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate  eol:
397*0Sstevel@tonic-gate     if (!text && !reject)
398*0Sstevel@tonic-gate 	for (; *cp; ) {
399*0Sstevel@tonic-gate 	    if (incomment)
400*0Sstevel@tonic-gate 		cp = skipcomment (cp);
401*0Sstevel@tonic-gate 	    else if (inquote[QUOTE1])
402*0Sstevel@tonic-gate 		cp = skipquote (cp, QUOTE1);
403*0Sstevel@tonic-gate 	    else if (inquote[QUOTE2])
404*0Sstevel@tonic-gate 		cp = skipquote (cp, QUOTE2);
405*0Sstevel@tonic-gate 	    else if (*cp == '/' && cp[1] == '*')
406*0Sstevel@tonic-gate 		cp = skipcomment (cp);
407*0Sstevel@tonic-gate 	    else if (*cp == '\'')
408*0Sstevel@tonic-gate 		cp = skipquote (cp, QUOTE1);
409*0Sstevel@tonic-gate 	    else if (*cp == '"')
410*0Sstevel@tonic-gate 		cp = skipquote (cp, QUOTE2);
411*0Sstevel@tonic-gate 	    else
412*0Sstevel@tonic-gate 		cp++;
413*0Sstevel@tonic-gate 	}
414*0Sstevel@tonic-gate     return retval;
415*0Sstevel@tonic-gate }
416*0Sstevel@tonic-gate 
417*0Sstevel@tonic-gate /*  Skip over comments and stop at the next character
418*0Sstevel@tonic-gate *  position that is not whitespace.
419*0Sstevel@tonic-gate */
420*0Sstevel@tonic-gate char *
421*0Sstevel@tonic-gate skipcomment (cp)
422*0Sstevel@tonic-gate register char *cp;
423*0Sstevel@tonic-gate {
424*0Sstevel@tonic-gate     if (incomment)
425*0Sstevel@tonic-gate 	goto inside;
426*0Sstevel@tonic-gate     for (;; cp++) {
427*0Sstevel@tonic-gate         while (*cp == ' ' || *cp == '\t')
428*0Sstevel@tonic-gate             cp++;
429*0Sstevel@tonic-gate 	if (text)
430*0Sstevel@tonic-gate             return cp;
431*0Sstevel@tonic-gate 	if (   cp[0] != '/'
432*0Sstevel@tonic-gate 	    || cp[1] != '*'
433*0Sstevel@tonic-gate 	   )
434*0Sstevel@tonic-gate             return cp;
435*0Sstevel@tonic-gate 	cp += 2;
436*0Sstevel@tonic-gate 	if (!incomment) {
437*0Sstevel@tonic-gate 	    incomment = YES;
438*0Sstevel@tonic-gate 	    stqcline = linenum;
439*0Sstevel@tonic-gate 	}
440*0Sstevel@tonic-gate  inside:
441*0Sstevel@tonic-gate 	for (;;) {
442*0Sstevel@tonic-gate 	    for (; *cp != '*'; cp++)
443*0Sstevel@tonic-gate 		if (*cp == '\0')
444*0Sstevel@tonic-gate 		    return cp;
445*0Sstevel@tonic-gate 	    if (*++cp == '/')
446*0Sstevel@tonic-gate 		break;
447*0Sstevel@tonic-gate 	}
448*0Sstevel@tonic-gate 	incomment = NO;
449*0Sstevel@tonic-gate     }
450*0Sstevel@tonic-gate }
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate /*  Skip over a quoted string or character and stop at the next charaacter
453*0Sstevel@tonic-gate *  position that is not whitespace.
454*0Sstevel@tonic-gate */
455*0Sstevel@tonic-gate char *
456*0Sstevel@tonic-gate skipquote (cp, type)
457*0Sstevel@tonic-gate register char *cp;
458*0Sstevel@tonic-gate register int type;
459*0Sstevel@tonic-gate {
460*0Sstevel@tonic-gate     register char qchar;
461*0Sstevel@tonic-gate 
462*0Sstevel@tonic-gate     qchar = type == QUOTE1 ? '\'' : '"';
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate     if (inquote[type])
465*0Sstevel@tonic-gate 	goto inside;
466*0Sstevel@tonic-gate     for (;; cp++) {
467*0Sstevel@tonic-gate 	if (*cp != qchar)
468*0Sstevel@tonic-gate 	    return cp;
469*0Sstevel@tonic-gate 	cp++;
470*0Sstevel@tonic-gate 	if (!inquote[type]) {
471*0Sstevel@tonic-gate 	    inquote[type] = YES;
472*0Sstevel@tonic-gate 	    stqcline = linenum;
473*0Sstevel@tonic-gate 	}
474*0Sstevel@tonic-gate  inside:
475*0Sstevel@tonic-gate 	for (; ; cp++) {
476*0Sstevel@tonic-gate 	    if (*cp == qchar)
477*0Sstevel@tonic-gate 		break;
478*0Sstevel@tonic-gate 	    if (   *cp == '\0'
479*0Sstevel@tonic-gate 		|| *cp == '\\'
480*0Sstevel@tonic-gate 		&& *++cp == '\0'
481*0Sstevel@tonic-gate 	       )
482*0Sstevel@tonic-gate 		return cp;
483*0Sstevel@tonic-gate 	}
484*0Sstevel@tonic-gate 	inquote[type] = NO;
485*0Sstevel@tonic-gate     }
486*0Sstevel@tonic-gate }
487*0Sstevel@tonic-gate 
488*0Sstevel@tonic-gate /*
489*0Sstevel@tonic-gate *   special getlin - treats form-feed as an end-of-line
490*0Sstevel@tonic-gate *                    and expands tabs if asked for
491*0Sstevel@tonic-gate *
492*0Sstevel@tonic-gate */
493*0Sstevel@tonic-gate getlin (line, maxline, inp, expandtabs)
494*0Sstevel@tonic-gate register char *line;
495*0Sstevel@tonic-gate int maxline;
496*0Sstevel@tonic-gate FILE *inp;
497*0Sstevel@tonic-gate int expandtabs;
498*0Sstevel@tonic-gate {
499*0Sstevel@tonic-gate     int tmp;
500*0Sstevel@tonic-gate     register int num;
501*0Sstevel@tonic-gate     register int chr;
502*0Sstevel@tonic-gate #ifdef FFSPECIAL
503*0Sstevel@tonic-gate     static char havechar = NO;  /* have leftover char from last time */
504*0Sstevel@tonic-gate     static char svchar BSS;
505*0Sstevel@tonic-gate #endif
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate     num = 0;
508*0Sstevel@tonic-gate #ifdef FFSPECIAL
509*0Sstevel@tonic-gate     if (havechar) {
510*0Sstevel@tonic-gate 	havechar = NO;
511*0Sstevel@tonic-gate 	chr = svchar;
512*0Sstevel@tonic-gate 	goto ent;
513*0Sstevel@tonic-gate     }
514*0Sstevel@tonic-gate #endif
515*0Sstevel@tonic-gate     while (num + 8 < maxline) {   /* leave room for tab */
516*0Sstevel@tonic-gate         chr = getc (inp);
517*0Sstevel@tonic-gate 	if (isprint (chr)) {
518*0Sstevel@tonic-gate #ifdef FFSPECIAL
519*0Sstevel@tonic-gate  ent:
520*0Sstevel@tonic-gate #endif
521*0Sstevel@tonic-gate 	    *line++ = chr;
522*0Sstevel@tonic-gate 	    num++;
523*0Sstevel@tonic-gate 	}
524*0Sstevel@tonic-gate 	else
525*0Sstevel@tonic-gate 	    switch (chr) {
526*0Sstevel@tonic-gate 	    case EOF:
527*0Sstevel@tonic-gate 		return EOF;
528*0Sstevel@tonic-gate 
529*0Sstevel@tonic-gate 	    case '\t':
530*0Sstevel@tonic-gate 		if (expandtabs) {
531*0Sstevel@tonic-gate 		    num += tmp = 8 - (num & 7);
532*0Sstevel@tonic-gate 		    do
533*0Sstevel@tonic-gate 			*line++ = ' ';
534*0Sstevel@tonic-gate 		    while (--tmp);
535*0Sstevel@tonic-gate 		    break;
536*0Sstevel@tonic-gate 		}
537*0Sstevel@tonic-gate             default:
538*0Sstevel@tonic-gate                 *line++ = chr;
539*0Sstevel@tonic-gate                 num++;
540*0Sstevel@tonic-gate 		break;
541*0Sstevel@tonic-gate 
542*0Sstevel@tonic-gate 	    case '\n':
543*0Sstevel@tonic-gate                 *line = '\n';
544*0Sstevel@tonic-gate                 num++;
545*0Sstevel@tonic-gate                 goto end;
546*0Sstevel@tonic-gate 
547*0Sstevel@tonic-gate #ifdef FFSPECIAL
548*0Sstevel@tonic-gate 	    case '\f':
549*0Sstevel@tonic-gate 		if (++num == 1)
550*0Sstevel@tonic-gate 		    *line = '\f';
551*0Sstevel@tonic-gate 		else {
552*0Sstevel@tonic-gate 		    *line = '\n';
553*0Sstevel@tonic-gate 		    havechar = YES;
554*0Sstevel@tonic-gate                     svchar = chr;
555*0Sstevel@tonic-gate                 }
556*0Sstevel@tonic-gate                 goto end;
557*0Sstevel@tonic-gate #endif
558*0Sstevel@tonic-gate 	    }
559*0Sstevel@tonic-gate     }
560*0Sstevel@tonic-gate  end:
561*0Sstevel@tonic-gate     *++line = '\0';
562*0Sstevel@tonic-gate     return num;
563*0Sstevel@tonic-gate }
564*0Sstevel@tonic-gate 
565*0Sstevel@tonic-gate flushline (keep)
566*0Sstevel@tonic-gate {
567*0Sstevel@tonic-gate     if ((keep && reject < 2) ^ complement)
568*0Sstevel@tonic-gate 	putlin (tline, stdout);
569*0Sstevel@tonic-gate     else if (lnblank)
570*0Sstevel@tonic-gate 	putlin ("\n", stdout);
571*0Sstevel@tonic-gate     return;
572*0Sstevel@tonic-gate }
573*0Sstevel@tonic-gate 
574*0Sstevel@tonic-gate /*
575*0Sstevel@tonic-gate *  putlin - for tools
576*0Sstevel@tonic-gate *
577*0Sstevel@tonic-gate */
578*0Sstevel@tonic-gate putlin (line, fio)
579*0Sstevel@tonic-gate register char *line;
580*0Sstevel@tonic-gate register FILE *fio;
581*0Sstevel@tonic-gate {
582*0Sstevel@tonic-gate     register char chr;
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate     while (chr = *line++)
585*0Sstevel@tonic-gate 	putc (chr, fio);
586*0Sstevel@tonic-gate     return;
587*0Sstevel@tonic-gate }
588*0Sstevel@tonic-gate 
589*0Sstevel@tonic-gate prname ()
590*0Sstevel@tonic-gate {
591*0Sstevel@tonic-gate     fprintf (stderr, "%s: ", progname);
592*0Sstevel@tonic-gate     return;
593*0Sstevel@tonic-gate }
594*0Sstevel@tonic-gate 
595*0Sstevel@tonic-gate 
596*0Sstevel@tonic-gate error (err, line, depth)
597*0Sstevel@tonic-gate {
598*0Sstevel@tonic-gate     if (err == END_ERR)
599*0Sstevel@tonic-gate 	return err;
600*0Sstevel@tonic-gate 
601*0Sstevel@tonic-gate     prname ();
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate #ifndef TESTING
604*0Sstevel@tonic-gate     fprintf (stderr, gettext("Error in %s line %d: %s.\n"),
605*0Sstevel@tonic-gate 	     filename, line, gettext(errs[err]));
606*0Sstevel@tonic-gate #endif
607*0Sstevel@tonic-gate 
608*0Sstevel@tonic-gate #ifdef TESTING
609*0Sstevel@tonic-gate     fprintf (stderr, gettext("Error in %s line %d: %s. "),
610*0Sstevel@tonic-gate 	     filename, line, errs[err]);
611*0Sstevel@tonic-gate     fprintf (stderr, gettext("ifdef depth: %d\n"), depth);
612*0Sstevel@tonic-gate #endif
613*0Sstevel@tonic-gate 
614*0Sstevel@tonic-gate     exitstat = 1;
615*0Sstevel@tonic-gate     return depth > 1 ? IEOF_ERR : END_ERR;
616*0Sstevel@tonic-gate }
617*0Sstevel@tonic-gate 
618*0Sstevel@tonic-gate /* return the next token in the line buffer */
619*0Sstevel@tonic-gate char *
620*0Sstevel@tonic-gate nextsym(p)
621*0Sstevel@tonic-gate char *p;
622*0Sstevel@tonic-gate {
623*0Sstevel@tonic-gate 	register char *key;
624*0Sstevel@tonic-gate 	register int i = KWSIZE;
625*0Sstevel@tonic-gate 
626*0Sstevel@tonic-gate 	key = buf;
627*0Sstevel@tonic-gate 	while (!endsym(*p) && --i)
628*0Sstevel@tonic-gate 		*key++ = *p++;
629*0Sstevel@tonic-gate 	*key = '\0';
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate 	return (buf);
632*0Sstevel@tonic-gate }
633