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