Annotation of src/usr.bin/unifdef/unifdef.c, Revision 1.3
1.3 ! deraadt 1: /* $OpenBSD: unifdef.c,v 1.2 1996/06/26 05:42:10 deraadt Exp $ */
! 2: /* $NetBSD: unifdef.c,v 1.6 1998/10/08 01:31:59 wsanchez Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1985, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Dave Yost.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: static char copyright[] =
42: "@(#) Copyright (c) 1985, 1993\n\
43: The Regents of the University of California. All rights reserved.\n";
1.3 ! deraadt 44: #endif /* not lint */
1.1 deraadt 45:
46: #ifndef lint
47: #if 0
48: static char sccsid[] = "@(#)unifdef.c 8.1 (Berkeley) 6/6/93";
49: #endif
1.3 ! deraadt 50: static char rcsid[] = "$OpenBSD: unifdef.c,v 1.2 1996/06/26 05:42:10 deraadt Exp $";
! 51: #endif /* not lint */
1.1 deraadt 52:
53: /*
54: * unifdef - remove ifdef'ed lines
55: *
56: * Warning: will not work correctly if input contains null characters.
57: *
58: * Wishlist:
59: * provide an option which will append the name of the
60: * appropriate symbol after #else's and #endif's
61: * provide an option which will check symbols after
62: * #else's and #endif's to see that they match their
63: * corresponding #ifdef or #ifndef
64: */
65:
66: #include <stdio.h>
67: #include <ctype.h>
68:
69: #define BSS
1.3 ! deraadt 70: FILE *input;
1.1 deraadt 71: #ifndef YES
72: #define YES 1
73: #define NO 0
1.3 ! deraadt 74: #endif /* YES */
! 75: #define C_COMMENT 1
! 76: #define CXX_COMMENT 2
1.1 deraadt 77: typedef int Bool;
78:
1.3 ! deraadt 79: char *progname BSS;
! 80: char *filename BSS;
! 81: char text BSS; /* -t option in effect: this is a text file */
! 82: char lnblank BSS; /* -l option in effect: blank deleted lines */
! 83: char complement BSS; /* -c option in effect: complement the
! 84: * operation */
1.1 deraadt 85:
86: #define MAXSYMS 100
1.3 ! deraadt 87: char *symname[MAXSYMS] BSS; /* symbol name */
! 88: char true[MAXSYMS] BSS; /* -Dsym */
! 89: char ignore[MAXSYMS] BSS; /* -iDsym or -iUsym */
! 90: char insym[MAXSYMS] BSS; /* state: false, inactive, true */
! 91: #define SYM_INACTIVE 0 /* symbol is currently inactive */
! 92: #define SYM_FALSE 1 /* symbol is currently false */
! 93: #define SYM_TRUE 2 /* symbol is currently true */
1.1 deraadt 94:
95: char nsyms BSS;
1.3 ! deraadt 96: char incomment BSS; /* inside C comment */
1.1 deraadt 97:
98: #define QUOTE_NONE 0
99: #define QUOTE_SINGLE 1
100: #define QUOTE_DOUBLE 2
1.3 ! deraadt 101: char inquote BSS; /* inside single or double quotes */
1.1 deraadt 102: int exitstat BSS;
103:
1.3 ! deraadt 104: int error __P((int, int, int));
! 105: int findsym __P((char *));
! 106: void flushline __P((Bool));
! 107: int getlin __P((char *, int, FILE *, int));
! 108: void pfile __P((void));
! 109: void prname __P((void));
1.1 deraadt 110: char *skipcomment __P((char *));
111: char *skipquote __P((char *, int));
112:
113: int
1.3 ! deraadt 114: main(argc, argv)
! 115: int argc;
! 116: char **argv;
! 117: {
! 118: char **curarg;
! 119: char *cp;
! 120: char *cp1;
! 121: char ignorethis;
! 122:
! 123: progname = argv[0][0] ? argv[0] : "unifdef";
! 124:
! 125: for (curarg = &argv[1]; --argc > 0; curarg++) {
! 126: if (*(cp1 = cp = *curarg) != '-')
! 127: break;
! 128: if (*++cp1 == 'i') {
! 129: ignorethis = YES;
! 130: cp1++;
! 131: } else
! 132: ignorethis = NO;
! 133: if ((*cp1 == 'D'
! 134: || *cp1 == 'U'
! 135: )
! 136: && cp1[1] != '\0'
! 137: ) {
! 138: int symind;
! 139:
! 140: if ((symind = findsym(&cp1[1])) < 0) {
! 141: if (nsyms >= MAXSYMS) {
! 142: prname();
! 143: fprintf(stderr, "too many symbols.\n");
! 144: exit(2);
! 145: }
! 146: symind = nsyms++;
! 147: symname[symind] = &cp1[1];
! 148: insym[symind] = SYM_INACTIVE;
! 149: }
! 150: ignore[symind] = ignorethis;
! 151: true[symind] = *cp1 == 'D' ? YES : NO;
! 152: } else
! 153: if (ignorethis)
! 154: goto unrec;
! 155: else
! 156: if (strcmp(&cp[1], "t") == 0)
! 157: text = YES;
! 158: else
! 159: if (strcmp(&cp[1], "l") == 0)
! 160: lnblank = YES;
! 161: else
! 162: if (strcmp(&cp[1], "c") == 0)
! 163: complement = YES;
! 164: else {
! 165: unrec:
! 166: prname();
! 167: fprintf(stderr, "unrecognized option: %s\n", cp);
! 168: goto usage;
! 169: }
1.1 deraadt 170: }
1.3 ! deraadt 171: if (nsyms == 0) {
! 172: usage:
! 173: fprintf(stderr, "\
1.1 deraadt 174: Usage: %s [-l] [-t] [-c] [[-Dsym] [-Usym] [-iDsym] [-iUsym]]... [file]\n\
175: At least one arg from [-D -U -iD -iU] is required\n", progname);
1.3 ! deraadt 176: exit(2);
1.1 deraadt 177: }
1.3 ! deraadt 178: if (argc > 1) {
! 179: prname();
! 180: fprintf(stderr, "can only do one file.\n");
! 181: } else
! 182: if (argc == 1) {
! 183: filename = *curarg;
! 184: if ((input = fopen(filename, "r")) != NULL) {
! 185: pfile();
! 186: (void) fclose(input);
! 187: } else {
! 188: prname();
! 189: fprintf(stderr, "can't open ");
! 190: perror(*curarg);
! 191: }
! 192: } else {
! 193: filename = "[stdin]";
! 194: input = stdin;
! 195: pfile();
! 196: }
1.1 deraadt 197:
1.3 ! deraadt 198: (void) fflush(stdout);
! 199: exit(exitstat);
1.1 deraadt 200: }
201: /* types of input lines: */
202: typedef int Linetype;
1.3 ! deraadt 203: #define LT_PLAIN 0 /* ordinary line */
! 204: #define LT_TRUE 1 /* a true #ifdef of a symbol known to us */
! 205: #define LT_FALSE 2 /* a false #ifdef of a symbol known to us */
! 206: #define LT_OTHER 3 /* an #ifdef of a symbol not known to us */
! 207: #define LT_IF 4 /* an #ifdef of a symbol not known to us */
! 208: #define LT_ELSE 5 /* #else */
! 209: #define LT_ENDIF 6 /* #endif */
! 210: #define LT_LEOF 7 /* end of file */
1.1 deraadt 211: Linetype checkline __P((int *));
212:
213: typedef int Reject_level;
1.3 ! deraadt 214: Reject_level reject BSS; /* 0 or 1: pass thru; 1 or 2: ignore comments */
1.1 deraadt 215: #define REJ_NO 0
216: #define REJ_IGNORE 1
217: #define REJ_YES 2
218: int doif __P((int, int, Reject_level, int));
219:
1.3 ! deraadt 220: int linenum BSS; /* current line number */
! 221: int stqcline BSS; /* start of current coment or quote */
! 222: char *errs[] = {
1.1 deraadt 223: #define NO_ERR 0
1.3 ! deraadt 224: "",
1.1 deraadt 225: #define END_ERR 1
1.3 ! deraadt 226: "",
1.1 deraadt 227: #define ELSE_ERR 2
1.3 ! deraadt 228: "Inappropriate else",
1.1 deraadt 229: #define ENDIF_ERR 3
1.3 ! deraadt 230: "Inappropriate endif",
1.1 deraadt 231: #define IEOF_ERR 4
1.3 ! deraadt 232: "Premature EOF in ifdef",
1.1 deraadt 233: #define CEOF_ERR 5
1.3 ! deraadt 234: "Premature EOF in comment",
1.1 deraadt 235: #define Q1EOF_ERR 6
1.3 ! deraadt 236: "Premature EOF in quoted character",
1.1 deraadt 237: #define Q2EOF_ERR 7
1.3 ! deraadt 238: "Premature EOF in quoted string"
1.1 deraadt 239: };
240: /* States for inif arg to doif */
241: #define IN_NONE 0
242: #define IN_IF 1
243: #define IN_ELSE 2
244:
245: void
1.3 ! deraadt 246: pfile()
1.1 deraadt 247: {
1.3 ! deraadt 248: reject = REJ_NO;
! 249: (void) doif(-1, IN_NONE, reject, 0);
! 250: return;
1.1 deraadt 251: }
252:
253: int
1.3 ! deraadt 254: doif(thissym, inif, prevreject, depth)
! 255: int thissym; /* index of the symbol who was last ifdef'ed */
! 256: int inif; /* YES or NO we are inside an ifdef */
! 257: Reject_level prevreject;/* previous value of reject */
! 258: int depth; /* depth of ifdef's */
! 259: {
! 260: Linetype lineval;
! 261: Reject_level thisreject;
! 262: int doret; /* tmp return value of doif */
! 263: int cursym; /* index of the symbol returned by checkline */
! 264: int stline; /* line number when called this time */
! 265:
! 266: stline = linenum;
! 267: for (;;) {
! 268: switch (lineval = checkline(&cursym)) {
! 269: case LT_PLAIN:
! 270: flushline(YES);
! 271: break;
! 272:
! 273: case LT_TRUE:
! 274: case LT_FALSE:
! 275: thisreject = reject;
! 276: if (lineval == LT_TRUE)
! 277: insym[cursym] = SYM_TRUE;
! 278: else {
! 279: if (reject != REJ_YES)
! 280: reject = ignore[cursym] ? REJ_IGNORE : REJ_YES;
! 281: insym[cursym] = SYM_FALSE;
! 282: }
! 283: if (ignore[cursym])
! 284: flushline(YES);
! 285: else {
! 286: exitstat = 1;
! 287: flushline(NO);
! 288: }
! 289: if ((doret = doif(cursym, IN_IF, thisreject, depth + 1)) != NO_ERR)
! 290: return error(doret, stline, depth);
! 291: break;
! 292:
! 293: case LT_IF:
! 294: case LT_OTHER:
! 295: flushline(YES);
! 296: if ((doret = doif(-1, IN_IF, reject, depth + 1)) != NO_ERR)
! 297: return error(doret, stline, depth);
! 298: break;
! 299:
! 300: case LT_ELSE:
! 301: if (inif != IN_IF)
! 302: return error(ELSE_ERR, linenum, depth);
! 303: inif = IN_ELSE;
! 304: if (thissym >= 0) {
! 305: if (insym[thissym] == SYM_TRUE) {
! 306: reject = ignore[thissym] ? REJ_IGNORE : REJ_YES;
! 307: insym[thissym] = SYM_FALSE;
! 308: } else { /* (insym[thissym] ==
! 309: * SYM_FALSE) */
! 310: reject = prevreject;
! 311: insym[thissym] = SYM_TRUE;
! 312: }
! 313: if (!ignore[thissym]) {
! 314: flushline(NO);
! 315: break;
! 316: }
! 317: }
! 318: flushline(YES);
! 319: break;
! 320:
! 321: case LT_ENDIF:
! 322: if (inif == IN_NONE)
! 323: return error(ENDIF_ERR, linenum, depth);
! 324: if (thissym >= 0) {
! 325: insym[thissym] = SYM_INACTIVE;
! 326: reject = prevreject;
! 327: if (!ignore[thissym]) {
! 328: flushline(NO);
! 329: return NO_ERR;
! 330: }
! 331: }
! 332: flushline(YES);
! 333: return NO_ERR;
! 334:
! 335: case LT_LEOF:{
! 336: int err;
! 337: err = incomment
! 338: ? CEOF_ERR
! 339: : inquote == QUOTE_SINGLE
! 340: ? Q1EOF_ERR
! 341: : inquote == QUOTE_DOUBLE
! 342: ? Q2EOF_ERR
! 343: : NO_ERR;
! 344: if (inif != IN_NONE) {
! 345: if (err != NO_ERR)
! 346: (void) error(err, stqcline, depth);
! 347: return error(IEOF_ERR, stline, depth);
! 348: } else
! 349: if (err != NO_ERR)
! 350: return error(err, stqcline, depth);
! 351: else
! 352: return NO_ERR;
! 353: }
1.1 deraadt 354: }
355: }
356: }
357: #define endsym(c) (!isalpha (c) && !isdigit (c) && c != '_')
358:
359: #define MAXLINE 256
1.3 ! deraadt 360: char tline[MAXLINE] BSS;
1.1 deraadt 361:
362: Linetype
1.3 ! deraadt 363: checkline(cursym)
! 364: int *cursym; /* if LT_TRUE or LT_FALSE returned, set this
! 365: * to sym index */
! 366: {
! 367: char *cp;
! 368: char *symp;
! 369: char *scp;
! 370: Linetype retval;
! 371: #define KWSIZE 8
! 372: char keyword[KWSIZE];
! 373:
! 374: linenum++;
! 375: if (getlin(tline, sizeof tline, input, NO) == EOF)
! 376: return LT_LEOF;
! 377:
! 378: retval = LT_PLAIN;
! 379: if (*(cp = tline) != '#'
! 380: || incomment
! 381: || inquote == QUOTE_SINGLE
! 382: || inquote == QUOTE_DOUBLE
! 383: )
! 384: goto eol;
! 385:
! 386: cp = skipcomment(++cp);
! 387: symp = keyword;
! 388: while (!endsym(*cp)) {
! 389: *symp = *cp++;
! 390: if (++symp >= &keyword[KWSIZE])
! 391: goto eol;
1.1 deraadt 392: }
1.3 ! deraadt 393: *symp = '\0';
1.1 deraadt 394:
1.3 ! deraadt 395: if (strcmp(keyword, "ifdef") == 0) {
! 396: retval = YES;
! 397: goto ifdef;
! 398: } else
! 399: if (strcmp(keyword, "ifndef") == 0) {
! 400: retval = NO;
! 401: ifdef:
! 402: scp = cp = skipcomment(++cp);
! 403: if (incomment) {
! 404: retval = LT_PLAIN;
! 405: goto eol;
! 406: } {
! 407: int symind;
! 408:
! 409: if ((symind = findsym(scp)) >= 0)
! 410: retval = (retval ^ true[*cursym = symind])
! 411: ? LT_FALSE : LT_TRUE;
! 412: else
! 413: retval = LT_OTHER;
! 414: }
! 415: } else
! 416: if (strcmp(keyword, "if") == 0)
! 417: retval = LT_IF;
! 418: else
! 419: if (strcmp(keyword, "else") == 0)
! 420: retval = LT_ELSE;
! 421: else
! 422: if (strcmp(keyword, "endif") == 0)
! 423: retval = LT_ENDIF;
! 424:
! 425: eol:
! 426: if (!text && reject != REJ_IGNORE)
! 427: for (; *cp;) {
! 428: if (incomment)
! 429: cp = skipcomment(cp);
! 430: else
! 431: if (inquote == QUOTE_SINGLE)
! 432: cp = skipquote(cp, QUOTE_SINGLE);
! 433: else
! 434: if (inquote == QUOTE_DOUBLE)
! 435: cp = skipquote(cp, QUOTE_DOUBLE);
! 436: else
! 437: if (*cp == '/' && (cp[1] == '*' || cp[1] == '/'))
! 438: cp = skipcomment(cp);
! 439: else
! 440: if (*cp == '\'')
! 441: cp = skipquote(cp, QUOTE_SINGLE);
! 442: else
! 443: if (*cp == '"')
! 444: cp = skipquote(cp, QUOTE_DOUBLE);
! 445: else
! 446: cp++;
! 447: }
! 448: return retval;
1.1 deraadt 449: }
450: /*
451: * Skip over comments and stop at the next charaacter
452: * position that is not whitespace.
453: */
1.3 ! deraadt 454: char *
! 455: skipcomment(cp)
! 456: char *cp;
! 457: {
! 458: if (incomment)
! 459: goto inside;
! 460: for (;; cp++) {
! 461: while (*cp == ' ' || *cp == '\t')
! 462: cp++;
! 463: if (text)
! 464: return cp;
! 465: if (cp[0] != '/')
! 466: return cp;
! 467:
! 468: if (cp[1] == '*') {
! 469: if (!incomment) {
! 470: incomment = C_COMMENT;
! 471: stqcline = linenum;
! 472: }
! 473: } else if (cp[1] == '/') {
! 474: if (!incomment) {
! 475: incomment = CXX_COMMENT;
! 476: stqcline = linenum;
! 477: }
! 478: } else
! 479: return cp;
! 480:
! 481: cp += 2;
! 482: inside:
! 483: if (incomment == C_COMMENT) {
! 484: for (;;) {
! 485: for (; *cp != '*'; cp++)
! 486: if (*cp == '\0')
! 487: return cp;
! 488: if (*++cp == '/') {
! 489: incomment = NO;
! 490: break;
! 491: }
! 492: }
! 493: }
! 494: else if (incomment == CXX_COMMENT) {
! 495: for (; *cp != '\n'; cp++)
! 496: if (*cp == '\0')
! 497: return cp;
! 498: incomment = NO;
! 499: }
1.1 deraadt 500: }
501: }
502: /*
503: * Skip over a quoted string or character and stop at the next charaacter
504: * position that is not whitespace.
505: */
1.3 ! deraadt 506: char *
! 507: skipquote(cp, type)
! 508: char *cp;
! 509: int type;
! 510: {
! 511: char qchar;
! 512:
! 513: qchar = type == QUOTE_SINGLE ? '\'' : '"';
! 514:
! 515: if (inquote == type)
! 516: goto inside;
! 517: for (;; cp++) {
! 518: if (*cp != qchar)
! 519: return cp;
! 520: cp++;
! 521: inquote = type;
! 522: stqcline = linenum;
! 523: inside:
! 524: for (;; cp++) {
! 525: if (*cp == qchar)
! 526: break;
! 527: if (*cp == '\0' || (*cp == '\\' && *++cp == '\0'))
! 528: return cp;
! 529: }
! 530: inquote = QUOTE_NONE;
1.1 deraadt 531: }
532: }
533: /*
534: * findsym - look for the symbol in the symbol table.
535: * if found, return symbol table index,
536: * else return -1.
537: */
538: int
1.3 ! deraadt 539: findsym(str)
! 540: char *str;
1.1 deraadt 541: {
1.3 ! deraadt 542: char *cp;
! 543: char *symp;
! 544: int symind;
! 545: char chr;
! 546:
! 547: for (symind = 0; symind < nsyms; ++symind) {
! 548: if (insym[symind] == SYM_INACTIVE) {
! 549: for (symp = symname[symind], cp = str
! 550: ; *symp && *cp == *symp
! 551: ; cp++, symp++
! 552: )
! 553: continue;
! 554: chr = *cp;
! 555: if (*symp == '\0' && endsym(chr))
! 556: return symind;
! 557: }
1.1 deraadt 558: }
1.3 ! deraadt 559: return -1;
1.1 deraadt 560: }
561: /*
562: * getlin - expands tabs if asked for
563: * and (if compiled in) treats form-feed as an end-of-line
564: */
565: int
1.3 ! deraadt 566: getlin(line, maxline, inp, expandtabs)
! 567: char *line;
! 568: int maxline;
! 569: FILE *inp;
! 570: int expandtabs;
! 571: {
! 572: int tmp;
! 573: int num;
! 574: int chr;
1.1 deraadt 575: #ifdef FFSPECIAL
1.3 ! deraadt 576: static char havechar = NO; /* have leftover char from last time */
! 577: static char svchar BSS;
! 578: #endif /* FFSPECIAL */
1.1 deraadt 579:
1.3 ! deraadt 580: num = 0;
1.1 deraadt 581: #ifdef FFSPECIAL
1.3 ! deraadt 582: if (havechar) {
! 583: havechar = NO;
! 584: chr = svchar;
! 585: goto ent;
! 586: }
! 587: #endif /* FFSPECIAL */
! 588: while (num + 8 < maxline) { /* leave room for tab */
! 589: chr = getc(inp);
! 590: if (isprint(chr)) {
1.1 deraadt 591: #ifdef FFSPECIAL
1.3 ! deraadt 592: ent:
! 593: #endif /* FFSPECIAL */
! 594: *line++ = chr;
! 595: num++;
! 596: } else
! 597: switch (chr) {
! 598: case EOF:
! 599: return EOF;
! 600:
! 601: case '\t':
! 602: if (expandtabs) {
! 603: num += tmp = 8 - (num & 7);
! 604: do
! 605: *line++ = ' ';
! 606: while (--tmp);
! 607: break;
! 608: }
! 609: default:
! 610: *line++ = chr;
! 611: num++;
! 612: break;
! 613:
! 614: case '\n':
! 615: *line = '\n';
! 616: num++;
! 617: goto end;
1.1 deraadt 618:
619: #ifdef FFSPECIAL
1.3 ! deraadt 620: case '\f':
! 621: if (++num == 1)
! 622: *line = '\f';
! 623: else {
! 624: *line = '\n';
! 625: havechar = YES;
! 626: svchar = chr;
! 627: }
! 628: goto end;
! 629: #endif /* FFSPECIAL */
! 630: }
! 631: }
! 632: end:
! 633: *++line = '\0';
! 634: return num;
1.1 deraadt 635: }
636:
637: void
1.3 ! deraadt 638: flushline(keep)
! 639: Bool keep;
1.1 deraadt 640: {
1.3 ! deraadt 641: if ((keep && reject != REJ_YES) ^ complement) {
! 642: char *line = tline;
! 643: FILE *out = stdout;
! 644: char chr;
! 645:
! 646: while ((chr = *line++))
! 647: putc(chr, out);
! 648: } else
! 649: if (lnblank)
! 650: putc('\n', stdout);
! 651: return;
1.1 deraadt 652: }
653:
654: void
1.3 ! deraadt 655: prname()
1.1 deraadt 656: {
1.3 ! deraadt 657: fprintf(stderr, "%s: ", progname);
! 658: return;
1.1 deraadt 659: }
660:
661: int
1.3 ! deraadt 662: error(err, line, depth)
! 663: int err; /* type of error & index into error string
! 664: * array */
! 665: int line; /* line number */
! 666: int depth; /* how many ifdefs we are inside */
1.1 deraadt 667: {
1.3 ! deraadt 668: if (err == END_ERR)
! 669: return err;
1.1 deraadt 670:
1.3 ! deraadt 671: prname();
1.1 deraadt 672:
673: #ifndef TESTING
1.3 ! deraadt 674: fprintf(stderr, "Error in %s line %d: %s.\n", filename, line, errs[err]);
! 675: #else /* TESTING */
! 676: fprintf(stderr, "Error in %s line %d: %s. ", filename, line, errs[err]);
! 677: fprintf(stderr, "ifdef depth: %d\n", depth);
! 678: #endif /* TESTING */
1.1 deraadt 679:
1.3 ! deraadt 680: exitstat = 2;
! 681: return depth > 1 ? IEOF_ERR : END_ERR;
1.1 deraadt 682: }