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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 * 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