xref: /titanic_50/usr/src/cmd/sgs/unifdef/common/unifdef.c (revision 9fb1159054bb89619213a7b2be87ea3bca25fcce)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*9fb11590Smike_s  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /* Copyright (c) 1982 Regents of the University of California */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  *    unifdef - remove ifdef'ed lines
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <ctype.h>
407c478bd9Sstevel@tonic-gate #include <locale.h>
41*9fb11590Smike_s #include <string.h>
42*9fb11590Smike_s #include <stdlib.h>
43*9fb11590Smike_s #include <unistd.h>
44*9fb11590Smike_s 
457c478bd9Sstevel@tonic-gate FILE *input;
467c478bd9Sstevel@tonic-gate #ifndef YES
477c478bd9Sstevel@tonic-gate #define	YES 1
487c478bd9Sstevel@tonic-gate #define	NO  0
497c478bd9Sstevel@tonic-gate #endif
507c478bd9Sstevel@tonic-gate 
51*9fb11590Smike_s char *progname;
52*9fb11590Smike_s char *filename;
53*9fb11590Smike_s char text;		/* -t option in effect: this is a text file */
54*9fb11590Smike_s char lnblank;		/* -l option in effect: blank deleted lines */
55*9fb11590Smike_s char complement;	/* -c option in effect: complement the operation */
567c478bd9Sstevel@tonic-gate #define	MAXSYMS 100
57*9fb11590Smike_s char true[MAXSYMS];
58*9fb11590Smike_s char ignore[MAXSYMS];
59*9fb11590Smike_s char *sym[MAXSYMS];
60*9fb11590Smike_s signed char insym[MAXSYMS];
617c478bd9Sstevel@tonic-gate #define	KWSIZE 8
627c478bd9Sstevel@tonic-gate char buf[KWSIZE];
63*9fb11590Smike_s char nsyms;
64*9fb11590Smike_s char incomment;
657c478bd9Sstevel@tonic-gate #define	QUOTE1 0
667c478bd9Sstevel@tonic-gate #define	QUOTE2 1
67*9fb11590Smike_s char inquote[2];
68*9fb11590Smike_s int exitstat;
697c478bd9Sstevel@tonic-gate 
70*9fb11590Smike_s static char *skipcomment(char *cp);
71*9fb11590Smike_s static char *skipquote(char *cp, int type);
72*9fb11590Smike_s static char *nextsym(char *p);
73*9fb11590Smike_s static int doif(int thissym, int inif, int prevreject, int depth);
74*9fb11590Smike_s static void pfile(void);
75*9fb11590Smike_s static int getlin(char *line, int maxline, FILE *inp, int expandtabs);
76*9fb11590Smike_s static void prname(void);
77*9fb11590Smike_s static void flushline(int keep);
78*9fb11590Smike_s static int checkline(int *cursym);
79*9fb11590Smike_s static int error(int err, int line, int depth);
80*9fb11590Smike_s static void putlin(char *line, FILE *fio);
817c478bd9Sstevel@tonic-gate 
82*9fb11590Smike_s static void
usage(void)83*9fb11590Smike_s usage(void)
84*9fb11590Smike_s {
85*9fb11590Smike_s 	(void) fprintf(stderr, gettext(
86*9fb11590Smike_s 	    "Usage: %s [-l] [-t] [-c] [[-Dsym] [-Usym] [-idsym] "
87*9fb11590Smike_s 	    "[-iusym]]... [file]\n"
88*9fb11590Smike_s 	    "    At least one arg from [-D -U -id -iu] is required\n"),
89*9fb11590Smike_s 	    progname);
90*9fb11590Smike_s 	exit(2);
91*9fb11590Smike_s }
92*9fb11590Smike_s 
93*9fb11590Smike_s int
main(int argc,char ** argv)94*9fb11590Smike_s main(int argc, char **argv)
957c478bd9Sstevel@tonic-gate {
967c478bd9Sstevel@tonic-gate 	char **curarg;
97*9fb11590Smike_s 	char *cp;
98*9fb11590Smike_s 	char *cp1;
997c478bd9Sstevel@tonic-gate 	char ignorethis;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1047c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
1057c478bd9Sstevel@tonic-gate #endif
1067c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	progname = argv[0][0] ? argv[0] : "unifdef";
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	for (curarg = &argv[1]; --argc > 0; curarg++) {
1117c478bd9Sstevel@tonic-gate 		if (*(cp1 = cp = *curarg) != '-')
1127c478bd9Sstevel@tonic-gate 			break;
1137c478bd9Sstevel@tonic-gate 		if (*++cp1 == 'i') {
1147c478bd9Sstevel@tonic-gate 			ignorethis = YES;
1157c478bd9Sstevel@tonic-gate 			cp1++;
116*9fb11590Smike_s 		} else
1177c478bd9Sstevel@tonic-gate 			ignorethis = NO;
118*9fb11590Smike_s 		if ((*cp1 == 'D' || *cp1 == 'U') &&
119*9fb11590Smike_s 		    cp1[1] != '\0') {
1207c478bd9Sstevel@tonic-gate 			if (nsyms >= MAXSYMS) {
1217c478bd9Sstevel@tonic-gate 				prname();
122*9fb11590Smike_s 				(void) fprintf(stderr,
123*9fb11590Smike_s 				    gettext("too many symbols.\n"));
1247c478bd9Sstevel@tonic-gate 				exit(2);
1257c478bd9Sstevel@tonic-gate 			}
1267c478bd9Sstevel@tonic-gate 			ignore[nsyms] = ignorethis;
1277c478bd9Sstevel@tonic-gate 			true[nsyms] = *cp1 == 'D' ? YES : NO;
1287c478bd9Sstevel@tonic-gate 			sym[nsyms++] = &cp1[1];
129*9fb11590Smike_s 		} else if (ignorethis)
1307c478bd9Sstevel@tonic-gate 			goto unrec;
1317c478bd9Sstevel@tonic-gate 		else if (strcmp(&cp[1], "t") == 0)
1327c478bd9Sstevel@tonic-gate 			text = YES;
1337c478bd9Sstevel@tonic-gate 		else if (strcmp(&cp[1], "l") == 0)
1347c478bd9Sstevel@tonic-gate 			lnblank = YES;
1357c478bd9Sstevel@tonic-gate 		else if (strcmp(&cp[1], "c") == 0)
1367c478bd9Sstevel@tonic-gate 			complement = YES;
1377c478bd9Sstevel@tonic-gate 		else {
1387c478bd9Sstevel@tonic-gate unrec:
1397c478bd9Sstevel@tonic-gate 			prname();
140*9fb11590Smike_s 			(void) fprintf(stderr,
141*9fb11590Smike_s 			    gettext("unrecognized option: %s\n"), cp);
142*9fb11590Smike_s 			usage();
1437c478bd9Sstevel@tonic-gate 		}
1447c478bd9Sstevel@tonic-gate 	}
1457c478bd9Sstevel@tonic-gate 	if (nsyms == 0) {
146*9fb11590Smike_s 		usage();
1477c478bd9Sstevel@tonic-gate 	}
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	if (argc > 1) {
1507c478bd9Sstevel@tonic-gate 		prname();
151*9fb11590Smike_s 		(void) fprintf(stderr, gettext("can only do one file.\n"));
152*9fb11590Smike_s 	} else if (argc == 1) {
1537c478bd9Sstevel@tonic-gate 		filename = *curarg;
1547c478bd9Sstevel@tonic-gate 		if ((input = fopen(filename, "r")) != NULL) {
1557c478bd9Sstevel@tonic-gate 			pfile();
156*9fb11590Smike_s 			(void) fclose(input);
157*9fb11590Smike_s 		} else {
1587c478bd9Sstevel@tonic-gate 			prname();
1597c478bd9Sstevel@tonic-gate 			perror(*curarg);
1607c478bd9Sstevel@tonic-gate 		}
161*9fb11590Smike_s 	} else {
1627c478bd9Sstevel@tonic-gate 		filename = "[stdin]";
1637c478bd9Sstevel@tonic-gate 		input = stdin;
1647c478bd9Sstevel@tonic-gate 		pfile();
1657c478bd9Sstevel@tonic-gate 	}
1667c478bd9Sstevel@tonic-gate 
167*9fb11590Smike_s 	(void) fflush(stdout);
168*9fb11590Smike_s 	return (exitstat);
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate /* types of input lines: */
1727c478bd9Sstevel@tonic-gate #define	PLAIN	0   /* ordinary line */
1737c478bd9Sstevel@tonic-gate #define	TRUE	1   /* a true  #ifdef of a symbol known to us */
1747c478bd9Sstevel@tonic-gate #define	FALSE	2   /* a false #ifdef of a symbol known to us */
1757c478bd9Sstevel@tonic-gate #define	OTHER	3   /* an #ifdef of a symbol not known to us */
1767c478bd9Sstevel@tonic-gate #define	ELSE	4   /* #else */
1777c478bd9Sstevel@tonic-gate #define	ENDIF	5   /* #endif */
1787c478bd9Sstevel@tonic-gate #define	LEOF	6   /* end of file */
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /* should be int declaration, was char */
181*9fb11590Smike_s int reject;    /* 0 or 1: pass thru; 1 or 2: ignore comments */
182*9fb11590Smike_s int linenum;    /* current line number */
183*9fb11590Smike_s int stqcline;   /* start of current comment or quote */
184*9fb11590Smike_s 
1857c478bd9Sstevel@tonic-gate char *errs[] = {
1867c478bd9Sstevel@tonic-gate #define	NO_ERR		0
1877c478bd9Sstevel@tonic-gate 			"",
1887c478bd9Sstevel@tonic-gate #define	END_ERR		1
1897c478bd9Sstevel@tonic-gate 			"",
1907c478bd9Sstevel@tonic-gate #define	ELSE_ERR	2
1917c478bd9Sstevel@tonic-gate 			"Inappropriate else",
1927c478bd9Sstevel@tonic-gate #define	ENDIF_ERR	3
1937c478bd9Sstevel@tonic-gate 			"Inappropriate endif",
1947c478bd9Sstevel@tonic-gate #define	IEOF_ERR	4
1957c478bd9Sstevel@tonic-gate 			"Premature EOF in ifdef",
1967c478bd9Sstevel@tonic-gate #define	CEOF_ERR	5
1977c478bd9Sstevel@tonic-gate 			"Premature EOF in comment",
1987c478bd9Sstevel@tonic-gate #define	Q1EOF_ERR	6
1997c478bd9Sstevel@tonic-gate 			"Premature EOF in quoted character",
2007c478bd9Sstevel@tonic-gate #define	Q2EOF_ERR	7
2017c478bd9Sstevel@tonic-gate 			"Premature EOF in quoted string"
2027c478bd9Sstevel@tonic-gate };
2037c478bd9Sstevel@tonic-gate 
204*9fb11590Smike_s static void
pfile(void)205*9fb11590Smike_s pfile(void)
2067c478bd9Sstevel@tonic-gate {
2077c478bd9Sstevel@tonic-gate 	reject = 0;
208*9fb11590Smike_s 	(void) doif(-1, NO, reject, 0);
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate 
211*9fb11590Smike_s static int
doif(int thissym,int inif,int prevreject,int depth)212*9fb11590Smike_s doif(
213*9fb11590Smike_s     int thissym,	/* index of the symbol who was last ifdef'ed */
214*9fb11590Smike_s     int inif,		/* YES or NO we are inside an ifdef */
215*9fb11590Smike_s     int prevreject,	/* previous value of reject */
216*9fb11590Smike_s     int depth		/* depth of ifdef's */
217*9fb11590Smike_s )
2187c478bd9Sstevel@tonic-gate {
219*9fb11590Smike_s 	int lineval;
220*9fb11590Smike_s 	int thisreject;
2217c478bd9Sstevel@tonic-gate 	int doret;	/* tmp return value of doif */
2227c478bd9Sstevel@tonic-gate 	int cursym;	/* index of the symbol returned by checkline */
2237c478bd9Sstevel@tonic-gate 	int stline;	/* line number when called this time */
224*9fb11590Smike_s 	int err;
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	stline = linenum;
2277c478bd9Sstevel@tonic-gate 	for (;;) {
2287c478bd9Sstevel@tonic-gate 		switch (lineval = checkline(&cursym)) {
2297c478bd9Sstevel@tonic-gate 		case PLAIN:
2307c478bd9Sstevel@tonic-gate 			flushline(YES);
2317c478bd9Sstevel@tonic-gate 			break;
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 		case TRUE:
2347c478bd9Sstevel@tonic-gate 		case FALSE:
2357c478bd9Sstevel@tonic-gate 			thisreject = reject;
2367c478bd9Sstevel@tonic-gate 			if (lineval == TRUE)
2377c478bd9Sstevel@tonic-gate 				insym[cursym] = 1;
2387c478bd9Sstevel@tonic-gate 			else {
2397c478bd9Sstevel@tonic-gate 				if (reject < 2)
2407c478bd9Sstevel@tonic-gate 					reject = ignore[cursym] ? 1 : 2;
2417c478bd9Sstevel@tonic-gate 				insym[cursym] = -1;
2427c478bd9Sstevel@tonic-gate 			}
2437c478bd9Sstevel@tonic-gate 			if (ignore[cursym])
2447c478bd9Sstevel@tonic-gate 				flushline(YES);
2457c478bd9Sstevel@tonic-gate 			else {
2467c478bd9Sstevel@tonic-gate 				exitstat = 0;
2477c478bd9Sstevel@tonic-gate 				flushline(NO);
2487c478bd9Sstevel@tonic-gate 			}
249*9fb11590Smike_s 			if ((doret = doif(cursym, YES,
250*9fb11590Smike_s 			    thisreject, depth + 1)) != NO_ERR)
251*9fb11590Smike_s 				return (error(doret, stline, depth));
2527c478bd9Sstevel@tonic-gate 			break;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 		case OTHER:
2557c478bd9Sstevel@tonic-gate 			flushline(YES);
256*9fb11590Smike_s 			if ((doret = doif(-1, YES,
257*9fb11590Smike_s 			    reject, depth + 1)) != NO_ERR)
258*9fb11590Smike_s 				return (error(doret, stline, depth));
2597c478bd9Sstevel@tonic-gate 			break;
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 		case ELSE:
2627c478bd9Sstevel@tonic-gate 			if (inif != 1)
263*9fb11590Smike_s 				return (error(ELSE_ERR, linenum, depth));
2647c478bd9Sstevel@tonic-gate 			inif = 2;
2657c478bd9Sstevel@tonic-gate 			if (thissym >= 0) {
2667c478bd9Sstevel@tonic-gate 				if ((insym[thissym] = -insym[thissym]) < 0)
2677c478bd9Sstevel@tonic-gate 					reject = ignore[thissym] ? 1 : 2;
2687c478bd9Sstevel@tonic-gate 				else
2697c478bd9Sstevel@tonic-gate 					reject = prevreject;
2707c478bd9Sstevel@tonic-gate 				if (!ignore[thissym]) {
2717c478bd9Sstevel@tonic-gate 					flushline(NO);
2727c478bd9Sstevel@tonic-gate 					break;
2737c478bd9Sstevel@tonic-gate 				}
2747c478bd9Sstevel@tonic-gate 			}
2757c478bd9Sstevel@tonic-gate 			flushline(YES);
2767c478bd9Sstevel@tonic-gate 			break;
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 		case ENDIF:
2797c478bd9Sstevel@tonic-gate 			if (inif == 0)
280*9fb11590Smike_s 				return (error(ENDIF_ERR, linenum, depth));
2817c478bd9Sstevel@tonic-gate 			if (thissym >= 0) {
2827c478bd9Sstevel@tonic-gate 				insym[thissym] = 0;
2837c478bd9Sstevel@tonic-gate 				reject = prevreject;
2847c478bd9Sstevel@tonic-gate 				if (!ignore[thissym]) {
2857c478bd9Sstevel@tonic-gate 					flushline(NO);
286*9fb11590Smike_s 					return (NO_ERR);
2877c478bd9Sstevel@tonic-gate 				}
2887c478bd9Sstevel@tonic-gate 			}
2897c478bd9Sstevel@tonic-gate 			flushline(YES);
290*9fb11590Smike_s 			return (NO_ERR);
2917c478bd9Sstevel@tonic-gate 
292*9fb11590Smike_s 		case LEOF:
2937c478bd9Sstevel@tonic-gate 			err = incomment
2947c478bd9Sstevel@tonic-gate 			    ? CEOF_ERR
2957c478bd9Sstevel@tonic-gate 			    : inquote[QUOTE1]
2967c478bd9Sstevel@tonic-gate 			    ? Q1EOF_ERR
2977c478bd9Sstevel@tonic-gate 			    : inquote[QUOTE2]
2987c478bd9Sstevel@tonic-gate 			    ? Q2EOF_ERR
2997c478bd9Sstevel@tonic-gate 			    : NO_ERR;
3007c478bd9Sstevel@tonic-gate 			if (inif) {
3017c478bd9Sstevel@tonic-gate 				if (err != NO_ERR)
302*9fb11590Smike_s 					(void) error(err, stqcline, depth);
303*9fb11590Smike_s 				return (error(IEOF_ERR, stline, depth));
304*9fb11590Smike_s 			} else if (err != NO_ERR)
305*9fb11590Smike_s 				return (error(err, stqcline, depth));
3067c478bd9Sstevel@tonic-gate 			else
307*9fb11590Smike_s 				return (NO_ERR);
3087c478bd9Sstevel@tonic-gate 		}
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate #define	endsym(c) (!isalpha(c) && !isdigit(c) && c != '_')
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate #define	MAXLINE 256
315*9fb11590Smike_s char tline[MAXLINE];
3167c478bd9Sstevel@tonic-gate 
317*9fb11590Smike_s static int
checkline(int * cursym)318*9fb11590Smike_s checkline(int *cursym)
3197c478bd9Sstevel@tonic-gate {
320*9fb11590Smike_s 	char *cp;
321*9fb11590Smike_s 	char *symp;
322*9fb11590Smike_s 	char chr;
3237c478bd9Sstevel@tonic-gate 	char *scp;
3247c478bd9Sstevel@tonic-gate 	int retval;
3257c478bd9Sstevel@tonic-gate 	int symind;
3267c478bd9Sstevel@tonic-gate 	char keyword[KWSIZE];
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	linenum++;
329*9fb11590Smike_s 	if (getlin(tline, sizeof (tline), input, NO) == EOF)
330*9fb11590Smike_s 		return (LEOF);
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	retval = PLAIN;
333*9fb11590Smike_s 	if (*(cp = tline) != '#' || incomment ||
334*9fb11590Smike_s 	    inquote[QUOTE1] || inquote[QUOTE2])
3357c478bd9Sstevel@tonic-gate 		goto eol;
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	cp = skipcomment(++cp);
3387c478bd9Sstevel@tonic-gate 	symp = keyword;
3397c478bd9Sstevel@tonic-gate 	while (!endsym (*cp)) {
3407c478bd9Sstevel@tonic-gate 		*symp = *cp++;
3417c478bd9Sstevel@tonic-gate 		if (++symp >= &keyword[KWSIZE])
3427c478bd9Sstevel@tonic-gate 			goto eol;
3437c478bd9Sstevel@tonic-gate 	}
3447c478bd9Sstevel@tonic-gate 	*symp = '\0';
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	if (strcmp(keyword, "ifdef") == 0) {
3477c478bd9Sstevel@tonic-gate 		retval = YES;
3487c478bd9Sstevel@tonic-gate 		goto ifdef;
349*9fb11590Smike_s 	} else if (strcmp(keyword, "if") == 0) {
3507c478bd9Sstevel@tonic-gate 		cp = skipcomment(++cp);
3517c478bd9Sstevel@tonic-gate 		if (strcmp(nextsym(cp), "defined") == 0) {
3527c478bd9Sstevel@tonic-gate 			cp += strlen("defined") + 1;
3537c478bd9Sstevel@tonic-gate 			/* skip to identifier */
3547c478bd9Sstevel@tonic-gate 			while (endsym(*cp))
3557c478bd9Sstevel@tonic-gate 				++cp;
3567c478bd9Sstevel@tonic-gate 			retval = YES;
3577c478bd9Sstevel@tonic-gate 			goto ifdef;
358*9fb11590Smike_s 		} else {
3597c478bd9Sstevel@tonic-gate 			retval = OTHER;
3607c478bd9Sstevel@tonic-gate 			goto eol;
3617c478bd9Sstevel@tonic-gate 		}
362*9fb11590Smike_s 	} else if (strcmp(keyword, "ifndef") == 0) {
3637c478bd9Sstevel@tonic-gate 		retval = NO;
3647c478bd9Sstevel@tonic-gate ifdef:
3657c478bd9Sstevel@tonic-gate 		scp = cp = skipcomment(cp);
3667c478bd9Sstevel@tonic-gate 		if (incomment) {
3677c478bd9Sstevel@tonic-gate 			retval = PLAIN;
3687c478bd9Sstevel@tonic-gate 			goto eol;
3697c478bd9Sstevel@tonic-gate 		}
370*9fb11590Smike_s 		symind = 0;
371*9fb11590Smike_s 		for (;;) {
3727c478bd9Sstevel@tonic-gate 			if (insym[symind] == 0) {
373*9fb11590Smike_s 				for (symp = sym[symind], cp = scp;
374*9fb11590Smike_s 				*symp && *cp == *symp; cp++, symp++) {
375*9fb11590Smike_s 					/* NULL */
376*9fb11590Smike_s 				}
3777c478bd9Sstevel@tonic-gate 				chr = *cp;
3787c478bd9Sstevel@tonic-gate 				if (*symp == '\0' && endsym(chr)) {
3797c478bd9Sstevel@tonic-gate 					*cursym = symind;
380*9fb11590Smike_s 					retval = (retval ^ true[symind]) ?
381*9fb11590Smike_s 					    FALSE : TRUE;
3827c478bd9Sstevel@tonic-gate 					break;
3837c478bd9Sstevel@tonic-gate 				}
3847c478bd9Sstevel@tonic-gate 			}
3857c478bd9Sstevel@tonic-gate 			if (++symind >= nsyms) {
3867c478bd9Sstevel@tonic-gate 				retval = OTHER;
3877c478bd9Sstevel@tonic-gate 				break;
3887c478bd9Sstevel@tonic-gate 			}
3897c478bd9Sstevel@tonic-gate 		}
390*9fb11590Smike_s 	} else if (strcmp(keyword, "else") == 0)
3917c478bd9Sstevel@tonic-gate 		retval = ELSE;
3927c478bd9Sstevel@tonic-gate 	else if (strcmp(keyword, "endif") == 0)
3937c478bd9Sstevel@tonic-gate 		retval = ENDIF;
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate eol:
3967c478bd9Sstevel@tonic-gate 	if (!text && !reject)
397*9fb11590Smike_s 		while (*cp) {
3987c478bd9Sstevel@tonic-gate 			if (incomment)
3997c478bd9Sstevel@tonic-gate 				cp = skipcomment(cp);
4007c478bd9Sstevel@tonic-gate 			else if (inquote[QUOTE1])
4017c478bd9Sstevel@tonic-gate 				cp = skipquote(cp, QUOTE1);
4027c478bd9Sstevel@tonic-gate 			else if (inquote[QUOTE2])
4037c478bd9Sstevel@tonic-gate 				cp = skipquote(cp, QUOTE2);
4047c478bd9Sstevel@tonic-gate 			else if (*cp == '/' && cp[1] == '*')
4057c478bd9Sstevel@tonic-gate 				cp = skipcomment(cp);
4067c478bd9Sstevel@tonic-gate 			else if (*cp == '\'')
4077c478bd9Sstevel@tonic-gate 				cp = skipquote(cp, QUOTE1);
4087c478bd9Sstevel@tonic-gate 			else if (*cp == '"')
4097c478bd9Sstevel@tonic-gate 				cp = skipquote(cp, QUOTE2);
4107c478bd9Sstevel@tonic-gate 			else
4117c478bd9Sstevel@tonic-gate 				cp++;
4127c478bd9Sstevel@tonic-gate 		}
413*9fb11590Smike_s 	return (retval);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate 
416*9fb11590Smike_s /*
417*9fb11590Smike_s  * Skip over comments and stop at the next character
4187c478bd9Sstevel@tonic-gate  *  position that is not whitespace.
4197c478bd9Sstevel@tonic-gate  */
420*9fb11590Smike_s static char *
skipcomment(char * cp)421*9fb11590Smike_s skipcomment(char *cp)
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate 	if (incomment)
4247c478bd9Sstevel@tonic-gate 		goto inside;
425*9fb11590Smike_s 	for (;;) {
4267c478bd9Sstevel@tonic-gate 		while (*cp == ' ' || *cp == '\t')
4277c478bd9Sstevel@tonic-gate 			cp++;
4287c478bd9Sstevel@tonic-gate 		if (text)
429*9fb11590Smike_s 			return (cp);
430*9fb11590Smike_s 		if (cp[0] != '/' || cp[1] != '*')
431*9fb11590Smike_s 			return (cp);
4327c478bd9Sstevel@tonic-gate 		cp += 2;
4337c478bd9Sstevel@tonic-gate 		if (!incomment) {
4347c478bd9Sstevel@tonic-gate 			incomment = YES;
4357c478bd9Sstevel@tonic-gate 			stqcline = linenum;
4367c478bd9Sstevel@tonic-gate 		}
4377c478bd9Sstevel@tonic-gate inside:
4387c478bd9Sstevel@tonic-gate 		for (;;) {
4397c478bd9Sstevel@tonic-gate 			for (; *cp != '*'; cp++)
4407c478bd9Sstevel@tonic-gate 				if (*cp == '\0')
441*9fb11590Smike_s 					return (cp);
4427c478bd9Sstevel@tonic-gate 			if (*++cp == '/')
4437c478bd9Sstevel@tonic-gate 				break;
4447c478bd9Sstevel@tonic-gate 		}
4457c478bd9Sstevel@tonic-gate 		incomment = NO;
446*9fb11590Smike_s 		cp++;
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate 
450*9fb11590Smike_s /*
451*9fb11590Smike_s  * Skip over a quoted string or character and stop at the next charaacter
4527c478bd9Sstevel@tonic-gate  *  position that is not whitespace.
4537c478bd9Sstevel@tonic-gate  */
454*9fb11590Smike_s static char *
skipquote(char * cp,int type)455*9fb11590Smike_s skipquote(char *cp, int type)
4567c478bd9Sstevel@tonic-gate {
457*9fb11590Smike_s 	char qchar;
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 	qchar = type == QUOTE1 ? '\'' : '"';
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	if (inquote[type])
4627c478bd9Sstevel@tonic-gate 		goto inside;
463*9fb11590Smike_s 	for (;;) {
4647c478bd9Sstevel@tonic-gate 		if (*cp != qchar)
465*9fb11590Smike_s 			return (cp);
4667c478bd9Sstevel@tonic-gate 		cp++;
4677c478bd9Sstevel@tonic-gate 		if (!inquote[type]) {
4687c478bd9Sstevel@tonic-gate 			inquote[type] = YES;
4697c478bd9Sstevel@tonic-gate 			stqcline = linenum;
4707c478bd9Sstevel@tonic-gate 		}
4717c478bd9Sstevel@tonic-gate inside:
4727c478bd9Sstevel@tonic-gate 		for (; ; cp++) {
4737c478bd9Sstevel@tonic-gate 			if (*cp == qchar)
4747c478bd9Sstevel@tonic-gate 				break;
475*9fb11590Smike_s 			if (*cp == '\0' || *cp == '\\' && *++cp == '\0')
476*9fb11590Smike_s 				return (cp);
4777c478bd9Sstevel@tonic-gate 		}
4787c478bd9Sstevel@tonic-gate 		inquote[type] = NO;
479*9fb11590Smike_s 		cp++;
4807c478bd9Sstevel@tonic-gate 	}
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate /*
4847c478bd9Sstevel@tonic-gate  *   special getlin - treats form-feed as an end-of-line
4857c478bd9Sstevel@tonic-gate  *                    and expands tabs if asked for
4867c478bd9Sstevel@tonic-gate  */
487*9fb11590Smike_s static int
getlin(char * line,int maxline,FILE * inp,int expandtabs)488*9fb11590Smike_s getlin(char *line, int maxline, FILE *inp, int expandtabs)
4897c478bd9Sstevel@tonic-gate {
4907c478bd9Sstevel@tonic-gate 	int tmp;
491*9fb11590Smike_s 	int num;
492*9fb11590Smike_s 	int chr;
4937c478bd9Sstevel@tonic-gate #ifdef FFSPECIAL
4947c478bd9Sstevel@tonic-gate 	static char havechar = NO;  /* have leftover char from last time */
495*9fb11590Smike_s 	static char svchar;
4967c478bd9Sstevel@tonic-gate #endif
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	num = 0;
4997c478bd9Sstevel@tonic-gate #ifdef FFSPECIAL
5007c478bd9Sstevel@tonic-gate 	if (havechar) {
5017c478bd9Sstevel@tonic-gate 		havechar = NO;
5027c478bd9Sstevel@tonic-gate 		chr = svchar;
5037c478bd9Sstevel@tonic-gate 		goto ent;
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate #endif
5067c478bd9Sstevel@tonic-gate 	while (num + 8 < maxline) {   /* leave room for tab */
5077c478bd9Sstevel@tonic-gate 		chr = getc(inp);
5087c478bd9Sstevel@tonic-gate 		if (isprint(chr)) {
5097c478bd9Sstevel@tonic-gate #ifdef FFSPECIAL
5107c478bd9Sstevel@tonic-gate ent:
5117c478bd9Sstevel@tonic-gate #endif
5127c478bd9Sstevel@tonic-gate 			*line++ = chr;
5137c478bd9Sstevel@tonic-gate 			num++;
514*9fb11590Smike_s 		} else
5157c478bd9Sstevel@tonic-gate 			switch (chr) {
5167c478bd9Sstevel@tonic-gate 			case EOF:
517*9fb11590Smike_s 				return (EOF);
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 			case '\t':
5207c478bd9Sstevel@tonic-gate 				if (expandtabs) {
5217c478bd9Sstevel@tonic-gate 					num += tmp = 8 - (num & 7);
5227c478bd9Sstevel@tonic-gate 					do
5237c478bd9Sstevel@tonic-gate 						*line++ = ' ';
5247c478bd9Sstevel@tonic-gate 					while (--tmp);
5257c478bd9Sstevel@tonic-gate 					break;
5267c478bd9Sstevel@tonic-gate 				}
5277c478bd9Sstevel@tonic-gate 			default:
5287c478bd9Sstevel@tonic-gate 				*line++ = chr;
5297c478bd9Sstevel@tonic-gate 				num++;
5307c478bd9Sstevel@tonic-gate 				break;
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 			case '\n':
5337c478bd9Sstevel@tonic-gate 				*line = '\n';
5347c478bd9Sstevel@tonic-gate 				num++;
5357c478bd9Sstevel@tonic-gate 				goto end;
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate #ifdef FFSPECIAL
5387c478bd9Sstevel@tonic-gate 			case '\f':
5397c478bd9Sstevel@tonic-gate 				if (++num == 1)
5407c478bd9Sstevel@tonic-gate 					*line = '\f';
5417c478bd9Sstevel@tonic-gate 				else {
5427c478bd9Sstevel@tonic-gate 					*line = '\n';
5437c478bd9Sstevel@tonic-gate 					havechar = YES;
5447c478bd9Sstevel@tonic-gate 					svchar = chr;
5457c478bd9Sstevel@tonic-gate 				}
5467c478bd9Sstevel@tonic-gate 				goto end;
5477c478bd9Sstevel@tonic-gate #endif
5487c478bd9Sstevel@tonic-gate 			}
5497c478bd9Sstevel@tonic-gate 	}
5507c478bd9Sstevel@tonic-gate end:
5517c478bd9Sstevel@tonic-gate 	*++line = '\0';
552*9fb11590Smike_s 	return (num);
5537c478bd9Sstevel@tonic-gate }
5547c478bd9Sstevel@tonic-gate 
555*9fb11590Smike_s static void
flushline(int keep)556*9fb11590Smike_s flushline(int keep)
5577c478bd9Sstevel@tonic-gate {
5587c478bd9Sstevel@tonic-gate 	if ((keep && reject < 2) ^ complement)
5597c478bd9Sstevel@tonic-gate 		putlin(tline, stdout);
5607c478bd9Sstevel@tonic-gate 	else if (lnblank)
5617c478bd9Sstevel@tonic-gate 		putlin("\n", stdout);
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate /*
5657c478bd9Sstevel@tonic-gate  *  putlin - for tools
5667c478bd9Sstevel@tonic-gate  */
567*9fb11590Smike_s static void
putlin(char * line,FILE * fio)568*9fb11590Smike_s putlin(char *line, FILE *fio)
5697c478bd9Sstevel@tonic-gate {
570*9fb11590Smike_s 	char chr;
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	while (chr = *line++)
573*9fb11590Smike_s 		(void) putc(chr, fio);
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate 
576*9fb11590Smike_s static void
prname(void)577*9fb11590Smike_s prname(void)
5787c478bd9Sstevel@tonic-gate {
579*9fb11590Smike_s 	(void) fprintf(stderr, "%s: ", progname);
5807c478bd9Sstevel@tonic-gate }
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 
583*9fb11590Smike_s static int
error(int err,int line,int depth)584*9fb11590Smike_s error(int err, int line, int depth)
5857c478bd9Sstevel@tonic-gate {
5867c478bd9Sstevel@tonic-gate 	if (err == END_ERR)
587*9fb11590Smike_s 		return (err);
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate 	prname();
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate #ifndef TESTING
592*9fb11590Smike_s 	(void) fprintf(stderr, gettext("Error in %s line %d: %s.\n"),
5937c478bd9Sstevel@tonic-gate 	    filename, line, gettext(errs[err]));
5947c478bd9Sstevel@tonic-gate #endif
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate #ifdef TESTING
597*9fb11590Smike_s 	(void) fprintf(stderr, gettext("Error in %s line %d: %s. "),
5987c478bd9Sstevel@tonic-gate 	    filename, line, errs[err]);
599*9fb11590Smike_s 	(void) fprintf(stderr, gettext("ifdef depth: %d\n"), depth);
6007c478bd9Sstevel@tonic-gate #endif
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	exitstat = 1;
603*9fb11590Smike_s 	return (depth > 1 ? IEOF_ERR : END_ERR);
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate /* return the next token in the line buffer */
6077c478bd9Sstevel@tonic-gate char *
nextsym(char * p)608*9fb11590Smike_s nextsym(char *p)
6097c478bd9Sstevel@tonic-gate {
610*9fb11590Smike_s 	char *key;
611*9fb11590Smike_s 	int i = KWSIZE;
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate 	key = buf;
6147c478bd9Sstevel@tonic-gate 	while (!endsym(*p) && --i)
6157c478bd9Sstevel@tonic-gate 		*key++ = *p++;
6167c478bd9Sstevel@tonic-gate 	*key = '\0';
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 	return (buf);
6197c478bd9Sstevel@tonic-gate }
620