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