[BACK]Return to unifdef.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / unifdef

Annotation of src/usr.bin/unifdef/unifdef.c, Revision 1.2

1.2     ! deraadt     1: /*     $OpenBSD: unifdef.c,v 1.4 1994/12/20 01:44:07 jtc Exp $ */
1.1       deraadt     2: /*     $NetBSD: unifdef.c,v 1.4 1994/12/20 01:44:07 jtc Exp $  */
                      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";
                     44: #endif /* not lint */
                     45:
                     46: #ifndef lint
                     47: #if 0
                     48: static char sccsid[] = "@(#)unifdef.c  8.1 (Berkeley) 6/6/93";
                     49: #endif
1.2     ! deraadt    50: static char rcsid[] = "$OpenBSD: unifdef.c,v 1.4 1994/12/20 01:44:07 jtc Exp $";
1.1       deraadt    51: #endif /* not lint */
                     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
                     70: FILE *input;
                     71: #ifndef YES
                     72: #define YES 1
                     73: #define NO  0
                     74: #endif/*YES */
                     75: typedef int Bool;
                     76:
                     77: char *progname BSS;
                     78: char *filename BSS;
                     79: char text BSS;          /* -t option in effect: this is a text file */
                     80: char lnblank BSS;       /* -l option in effect: blank deleted lines */
                     81: char complement BSS;    /* -c option in effect: complement the operation */
                     82:
                     83: #define MAXSYMS 100
                     84: char *symname[MAXSYMS] BSS; /* symbol name */
                     85: char true[MAXSYMS] BSS;     /* -Dsym */
                     86: char ignore[MAXSYMS] BSS;   /* -iDsym or -iUsym */
                     87: char insym[MAXSYMS] BSS;    /* state: false, inactive, true */
                     88: #define SYM_INACTIVE 0      /* symbol is currently inactive */
                     89: #define SYM_FALSE    1      /* symbol is currently false */
                     90: #define SYM_TRUE     2      /* symbol is currently true  */
                     91:
                     92: char nsyms BSS;
                     93: char incomment BSS;         /* inside C comment */
                     94:
                     95: #define QUOTE_NONE   0
                     96: #define QUOTE_SINGLE 1
                     97: #define QUOTE_DOUBLE 2
                     98: char inquote BSS;           /* inside single or double quotes */
                     99: int exitstat BSS;
                    100:
                    101: int    error __P((int, int, int));
                    102: int    findsym __P((char *));
                    103: void   flushline __P((Bool));
                    104: int    getlin __P((char *, int, FILE *, int));
                    105: void   pfile __P((void));
                    106: void   prname __P((void));
                    107: char   *skipcomment __P((char *));
                    108: char   *skipquote __P((char *, int));
                    109:
                    110: int
                    111: main (argc, argv)
                    112: int argc;
                    113: char **argv;
                    114: {
                    115:     char **curarg;
                    116:     register char *cp;
                    117:     register char *cp1;
                    118:     char ignorethis;
                    119:
                    120:     progname = argv[0][0] ? argv[0] : "unifdef";
                    121:
                    122:     for (curarg = &argv[1]; --argc > 0; curarg++) {
                    123:        if (*(cp1 = cp = *curarg) != '-')
                    124:            break;
                    125:        if (*++cp1 == 'i') {
                    126:            ignorethis = YES;
                    127:            cp1++;
                    128:        } else
                    129:            ignorethis = NO;
                    130:        if (   (   *cp1 == 'D'
                    131:                || *cp1 == 'U'
                    132:               )
                    133:            && cp1[1] != '\0'
                    134:           ) {
                    135:            register int symind;
                    136:
                    137:            if ((symind = findsym (&cp1[1])) < 0) {
                    138:                if (nsyms >= MAXSYMS) {
                    139:                    prname ();
                    140:                    fprintf (stderr, "too many symbols.\n");
                    141:                    exit (2);
                    142:                }
                    143:                symind = nsyms++;
                    144:                symname[symind] = &cp1[1];
                    145:                insym[symind] = SYM_INACTIVE;
                    146:            }
                    147:            ignore[symind] = ignorethis;
                    148:            true[symind] = *cp1 == 'D' ? YES : NO;
                    149:        } else if (ignorethis)
                    150:            goto unrec;
                    151:        else if (strcmp (&cp[1], "t") == 0)
                    152:            text = YES;
                    153:        else if (strcmp (&cp[1], "l") == 0)
                    154:            lnblank = YES;
                    155:        else if (strcmp (&cp[1], "c") == 0)
                    156:            complement = YES;
                    157:        else {
                    158:  unrec:
                    159:            prname ();
                    160:            fprintf (stderr, "unrecognized option: %s\n", cp);
                    161:            goto usage;
                    162:        }
                    163:     }
                    164:     if (nsyms == 0) {
                    165:  usage:
                    166:        fprintf (stderr, "\
                    167: Usage: %s [-l] [-t] [-c] [[-Dsym] [-Usym] [-iDsym] [-iUsym]]... [file]\n\
                    168:     At least one arg from [-D -U -iD -iU] is required\n", progname);
                    169:        exit (2);
                    170:     }
                    171:
                    172:     if (argc > 1) {
                    173:        prname ();
                    174:        fprintf (stderr, "can only do one file.\n");
                    175:     } else if (argc == 1) {
                    176:        filename = *curarg;
                    177:        if ((input = fopen (filename, "r")) != NULL) {
                    178:            pfile();
                    179:            (void) fclose (input);
                    180:        } else {
                    181:            prname ();
                    182:            fprintf (stderr, "can't open ");
                    183:            perror(*curarg);
                    184:        }
                    185:     } else {
                    186:        filename = "[stdin]";
                    187:        input = stdin;
                    188:        pfile();
                    189:     }
                    190:
                    191:     (void) fflush (stdout);
                    192:     exit (exitstat);
                    193: }
                    194:
                    195: /* types of input lines: */
                    196: typedef int Linetype;
                    197: #define LT_PLAIN       0   /* ordinary line */
                    198: #define LT_TRUE        1   /* a true  #ifdef of a symbol known to us */
                    199: #define LT_FALSE       2   /* a false #ifdef of a symbol known to us */
                    200: #define LT_OTHER       3   /* an #ifdef of a symbol not known to us */
                    201: #define LT_IF          4   /* an #ifdef of a symbol not known to us */
                    202: #define LT_ELSE        5   /* #else */
                    203: #define LT_ENDIF       6   /* #endif */
                    204: #define LT_LEOF        7   /* end of file */
                    205: Linetype checkline __P((int *));
                    206:
                    207: typedef int Reject_level;
                    208: Reject_level reject BSS;    /* 0 or 1: pass thru; 1 or 2: ignore comments */
                    209: #define REJ_NO          0
                    210: #define REJ_IGNORE      1
                    211: #define REJ_YES         2
                    212: int doif __P((int, int, Reject_level, int));
                    213:
                    214: int linenum BSS;    /* current line number */
                    215: int stqcline BSS;   /* start of current coment or quote */
                    216: char *errs[] = {
                    217: #define NO_ERR      0
                    218:                        "",
                    219: #define END_ERR     1
                    220:                        "",
                    221: #define ELSE_ERR    2
                    222:                        "Inappropriate else",
                    223: #define ENDIF_ERR   3
                    224:                        "Inappropriate endif",
                    225: #define IEOF_ERR    4
                    226:                        "Premature EOF in ifdef",
                    227: #define CEOF_ERR    5
                    228:                        "Premature EOF in comment",
                    229: #define Q1EOF_ERR   6
                    230:                        "Premature EOF in quoted character",
                    231: #define Q2EOF_ERR   7
                    232:                        "Premature EOF in quoted string"
                    233: };
                    234:
                    235: /* States for inif arg to doif */
                    236: #define IN_NONE 0
                    237: #define IN_IF   1
                    238: #define IN_ELSE 2
                    239:
                    240: void
                    241: pfile ()
                    242: {
                    243:     reject = REJ_NO;
                    244:     (void) doif (-1, IN_NONE, reject, 0);
                    245:     return;
                    246: }
                    247:
                    248: int
                    249: doif (thissym, inif, prevreject, depth)
                    250: register int thissym;   /* index of the symbol who was last ifdef'ed */
                    251: int inif;               /* YES or NO we are inside an ifdef */
                    252: Reject_level prevreject;/* previous value of reject */
                    253: int depth;              /* depth of ifdef's */
                    254: {
                    255:     register Linetype lineval;
                    256:     register Reject_level thisreject;
                    257:     int doret;          /* tmp return value of doif */
                    258:     int cursym;         /* index of the symbol returned by checkline */
                    259:     int stline;         /* line number when called this time */
                    260:
                    261:     stline = linenum;
                    262:     for (;;) {
                    263:        switch (lineval = checkline (&cursym)) {
                    264:        case LT_PLAIN:
                    265:            flushline (YES);
                    266:            break;
                    267:
                    268:        case LT_TRUE:
                    269:        case LT_FALSE:
                    270:            thisreject = reject;
                    271:            if (lineval == LT_TRUE)
                    272:                insym[cursym] = SYM_TRUE;
                    273:            else {
                    274:                if (reject != REJ_YES)
                    275:                    reject = ignore[cursym] ? REJ_IGNORE : REJ_YES;
                    276:                insym[cursym] = SYM_FALSE;
                    277:            }
                    278:            if (ignore[cursym])
                    279:                flushline (YES);
                    280:            else {
                    281:                exitstat = 1;
                    282:                flushline (NO);
                    283:            }
                    284:            if ((doret = doif (cursym, IN_IF, thisreject, depth + 1)) != NO_ERR)
                    285:                return error (doret, stline, depth);
                    286:            break;
                    287:
                    288:        case LT_IF:
                    289:        case LT_OTHER:
                    290:            flushline (YES);
                    291:            if ((doret = doif (-1, IN_IF, reject, depth + 1)) != NO_ERR)
                    292:                return error (doret, stline, depth);
                    293:            break;
                    294:
                    295:        case LT_ELSE:
                    296:            if (inif != IN_IF)
                    297:                return error (ELSE_ERR, linenum, depth);
                    298:            inif = IN_ELSE;
                    299:            if (thissym >= 0) {
                    300:                if (insym[thissym] == SYM_TRUE) {
                    301:                    reject = ignore[thissym] ? REJ_IGNORE : REJ_YES;
                    302:                    insym[thissym] = SYM_FALSE;
                    303:                } else { /* (insym[thissym] == SYM_FALSE) */
                    304:                    reject = prevreject;
                    305:                    insym[thissym] = SYM_TRUE;
                    306:                }
                    307:                if (!ignore[thissym]) {
                    308:                    flushline (NO);
                    309:                    break;
                    310:                }
                    311:            }
                    312:            flushline (YES);
                    313:            break;
                    314:
                    315:        case LT_ENDIF:
                    316:            if (inif == IN_NONE)
                    317:                return error (ENDIF_ERR, linenum, depth);
                    318:            if (thissym >= 0) {
                    319:                insym[thissym] = SYM_INACTIVE;
                    320:                reject = prevreject;
                    321:                if (!ignore[thissym]) {
                    322:                    flushline (NO);
                    323:                    return NO_ERR;
                    324:                }
                    325:            }
                    326:            flushline (YES);
                    327:            return NO_ERR;
                    328:
                    329:        case LT_LEOF: {
                    330:            int err;
                    331:            err =   incomment
                    332:                  ? CEOF_ERR
                    333:                  : inquote == QUOTE_SINGLE
                    334:                  ? Q1EOF_ERR
                    335:                  : inquote == QUOTE_DOUBLE
                    336:                  ? Q2EOF_ERR
                    337:                  : NO_ERR;
                    338:            if (inif != IN_NONE) {
                    339:                if (err != NO_ERR)
                    340:                    (void) error (err, stqcline, depth);
                    341:                return error (IEOF_ERR, stline, depth);
                    342:            } else if (err != NO_ERR)
                    343:                return error (err, stqcline, depth);
                    344:            else
                    345:                return NO_ERR;
                    346:            }
                    347:        }
                    348:     }
                    349: }
                    350:
                    351: #define endsym(c) (!isalpha (c) && !isdigit (c) && c != '_')
                    352:
                    353: #define MAXLINE 256
                    354: char tline[MAXLINE] BSS;
                    355:
                    356: Linetype
                    357: checkline (cursym)
                    358: int *cursym;    /* if LT_TRUE or LT_FALSE returned, set this to sym index */
                    359: {
                    360:     register char *cp;
                    361:     register char *symp;
                    362:     char *scp;
                    363:     Linetype retval;
                    364: #   define KWSIZE 8
                    365:     char keyword[KWSIZE];
                    366:
                    367:     linenum++;
                    368:     if (getlin (tline, sizeof tline, input, NO) == EOF)
                    369:        return LT_LEOF;
                    370:
                    371:     retval = LT_PLAIN;
                    372:     if (   *(cp = tline) != '#'
                    373:        || incomment
                    374:        || inquote == QUOTE_SINGLE
                    375:        || inquote == QUOTE_DOUBLE
                    376:        )
                    377:        goto eol;
                    378:
                    379:     cp = skipcomment (++cp);
                    380:     symp = keyword;
                    381:     while (!endsym (*cp)) {
                    382:        *symp = *cp++;
                    383:        if (++symp >= &keyword[KWSIZE])
                    384:            goto eol;
                    385:     }
                    386:     *symp = '\0';
                    387:
                    388:     if (strcmp (keyword, "ifdef") == 0) {
                    389:        retval = YES;
                    390:        goto ifdef;
                    391:     } else if (strcmp (keyword, "ifndef") == 0) {
                    392:        retval = NO;
                    393:  ifdef:
                    394:        scp = cp = skipcomment (++cp);
                    395:        if (incomment) {
                    396:            retval = LT_PLAIN;
                    397:            goto eol;
                    398:        }
                    399:        {
                    400:            int symind;
                    401:
                    402:            if ((symind = findsym (scp)) >= 0)
                    403:                retval = (retval ^ true[*cursym = symind])
                    404:                         ? LT_FALSE : LT_TRUE;
                    405:            else
                    406:                retval = LT_OTHER;
                    407:        }
                    408:     } else if (strcmp (keyword, "if") == 0)
                    409:        retval = LT_IF;
                    410:     else if (strcmp (keyword, "else") == 0)
                    411:        retval = LT_ELSE;
                    412:     else if (strcmp (keyword, "endif") == 0)
                    413:        retval = LT_ENDIF;
                    414:
                    415:  eol:
                    416:     if (!text && reject != REJ_IGNORE)
                    417:        for (; *cp; ) {
                    418:            if (incomment)
                    419:                cp = skipcomment (cp);
                    420:            else if (inquote == QUOTE_SINGLE)
                    421:                cp = skipquote (cp, QUOTE_SINGLE);
                    422:            else if (inquote == QUOTE_DOUBLE)
                    423:                cp = skipquote (cp, QUOTE_DOUBLE);
                    424:            else if (*cp == '/' && cp[1] == '*')
                    425:                cp = skipcomment (cp);
                    426:            else if (*cp == '\'')
                    427:                cp = skipquote (cp, QUOTE_SINGLE);
                    428:            else if (*cp == '"')
                    429:                cp = skipquote (cp, QUOTE_DOUBLE);
                    430:            else
                    431:                cp++;
                    432:        }
                    433:     return retval;
                    434: }
                    435:
                    436: /*
                    437:  *  Skip over comments and stop at the next charaacter
                    438:  *  position that is not whitespace.
                    439:  */
                    440: char *
                    441: skipcomment (cp)
                    442: register char *cp;
                    443: {
                    444:     if (incomment)
                    445:        goto inside;
                    446:     for (;; cp++) {
                    447:        while (*cp == ' ' || *cp == '\t')
                    448:            cp++;
                    449:        if (text)
                    450:            return cp;
                    451:        if (   cp[0] != '/'
                    452:            || cp[1] != '*'
                    453:           )
                    454:            return cp;
                    455:        cp += 2;
                    456:        if (!incomment) {
                    457:            incomment = YES;
                    458:            stqcline = linenum;
                    459:        }
                    460:  inside:
                    461:        for (;;) {
                    462:            for (; *cp != '*'; cp++)
                    463:                if (*cp == '\0')
                    464:                    return cp;
                    465:            if (*++cp == '/') {
                    466:                incomment = NO;
                    467:                break;
                    468:            }
                    469:        }
                    470:     }
                    471: }
                    472:
                    473: /*
                    474:  *  Skip over a quoted string or character and stop at the next charaacter
                    475:  *  position that is not whitespace.
                    476:  */
                    477: char *
                    478: skipquote (cp, type)
                    479: register char *cp;
                    480: register int type;
                    481: {
                    482:     register char qchar;
                    483:
                    484:     qchar = type == QUOTE_SINGLE ? '\'' : '"';
                    485:
                    486:     if (inquote == type)
                    487:        goto inside;
                    488:     for (;; cp++) {
                    489:        if (*cp != qchar)
                    490:            return cp;
                    491:        cp++;
                    492:        inquote = type;
                    493:        stqcline = linenum;
                    494:  inside:
                    495:        for (; ; cp++) {
                    496:            if (*cp == qchar)
                    497:                break;
                    498:            if (   *cp == '\0'
                    499:                || *cp == '\\' && *++cp == '\0'
                    500:               )
                    501:                return cp;
                    502:        }
                    503:        inquote = QUOTE_NONE;
                    504:     }
                    505: }
                    506:
                    507: /*
                    508:  *  findsym - look for the symbol in the symbol table.
                    509:  *            if found, return symbol table index,
                    510:  *            else return -1.
                    511:  */
                    512: int
                    513: findsym (str)
                    514: char *str;
                    515: {
                    516:     register char *cp;
                    517:     register char *symp;
                    518:     register int symind;
                    519:     register char chr;
                    520:
                    521:     for (symind = 0; symind < nsyms; ++symind) {
                    522:        if (insym[symind] == SYM_INACTIVE) {
                    523:            for ( symp = symname[symind], cp = str
                    524:                ; *symp && *cp == *symp
                    525:                ; cp++, symp++
                    526:                )
                    527:                continue;
                    528:            chr = *cp;
                    529:            if (*symp == '\0' && endsym (chr))
                    530:                return symind;
                    531:        }
                    532:     }
                    533:     return -1;
                    534: }
                    535:
                    536: /*
                    537:  *   getlin - expands tabs if asked for
                    538:  *            and (if compiled in) treats form-feed as an end-of-line
                    539:  */
                    540: int
                    541: getlin (line, maxline, inp, expandtabs)
                    542: register char *line;
                    543: int maxline;
                    544: FILE *inp;
                    545: int expandtabs;
                    546: {
                    547:     int tmp;
                    548:     register int num;
                    549:     register int chr;
                    550: #ifdef  FFSPECIAL
                    551:     static char havechar = NO;  /* have leftover char from last time */
                    552:     static char svchar BSS;
                    553: #endif/*FFSPECIAL */
                    554:
                    555:     num = 0;
                    556: #ifdef  FFSPECIAL
                    557:     if (havechar) {
                    558:        havechar = NO;
                    559:        chr = svchar;
                    560:        goto ent;
                    561:     }
                    562: #endif/*FFSPECIAL */
                    563:     while (num + 8 < maxline) {   /* leave room for tab */
                    564:        chr = getc (inp);
                    565:        if (isprint (chr)) {
                    566: #ifdef  FFSPECIAL
                    567:  ent:
                    568: #endif/*FFSPECIAL */
                    569:            *line++ = chr;
                    570:            num++;
                    571:        } else
                    572:            switch (chr) {
                    573:            case EOF:
                    574:                return EOF;
                    575:
                    576:            case '\t':
                    577:                if (expandtabs) {
                    578:                    num += tmp = 8 - (num & 7);
                    579:                    do
                    580:                        *line++ = ' ';
                    581:                    while (--tmp);
                    582:                    break;
                    583:                }
                    584:            default:
                    585:                *line++ = chr;
                    586:                num++;
                    587:                break;
                    588:
                    589:            case '\n':
                    590:                *line = '\n';
                    591:                num++;
                    592:                goto end;
                    593:
                    594: #ifdef  FFSPECIAL
                    595:            case '\f':
                    596:                if (++num == 1)
                    597:                    *line = '\f';
                    598:                else {
                    599:                    *line = '\n';
                    600:                    havechar = YES;
                    601:                    svchar = chr;
                    602:                }
                    603:                goto end;
                    604: #endif/*FFSPECIAL */
                    605:            }
                    606:     }
                    607:  end:
                    608:     *++line = '\0';
                    609:     return num;
                    610: }
                    611:
                    612: void
                    613: flushline (keep)
                    614: Bool keep;
                    615: {
                    616:     if ((keep && reject != REJ_YES) ^ complement) {
                    617:        register char *line = tline;
                    618:        register FILE *out = stdout;
                    619:        register char chr;
                    620:
                    621:        while (chr = *line++)
                    622:            putc (chr, out);
                    623:     } else if (lnblank)
                    624:        putc ('\n', stdout);
                    625:     return;
                    626: }
                    627:
                    628: void
                    629: prname ()
                    630: {
                    631:     fprintf (stderr, "%s: ", progname);
                    632:     return;
                    633: }
                    634:
                    635: int
                    636: error (err, line, depth)
                    637: int err;        /* type of error & index into error string array */
                    638: int line;       /* line number */
                    639: int depth;      /* how many ifdefs we are inside */
                    640: {
                    641:     if (err == END_ERR)
                    642:        return err;
                    643:
                    644:     prname ();
                    645:
                    646: #ifndef TESTING
                    647:     fprintf (stderr, "Error in %s line %d: %s.\n", filename, line, errs[err]);
                    648: #else/* TESTING */
                    649:     fprintf (stderr, "Error in %s line %d: %s. ", filename, line, errs[err]);
                    650:     fprintf (stderr, "ifdef depth: %d\n", depth);
                    651: #endif/*TESTING */
                    652:
                    653:     exitstat = 2;
                    654:     return depth > 1 ? IEOF_ERR : END_ERR;
                    655: }