Annotation of 43BSDReno/pgrm/dbx/scanner.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that: (1) source distributions retain this entire copyright
        !             7:  * notice and comment, and (2) distributions including binaries display
        !             8:  * the following acknowledgement:  ``This product includes software
        !             9:  * developed by the University of California, Berkeley and its contributors''
        !            10:  * in the documentation or other materials provided with the distribution
        !            11:  * and in all advertising materials mentioning features or use of this
        !            12:  * software. Neither the name of the University nor the names of its
        !            13:  * contributors may be used to endorse or promote products derived
        !            14:  * from this software without specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)scanner.c  5.3 (Berkeley) 6/1/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: /*
        !            25:  * Debugger scanner.
        !            26:  */
        !            27: 
        !            28: #include "defs.h"
        !            29: #include "scanner.h"
        !            30: #include "main.h"
        !            31: #include "keywords.h"
        !            32: #include "tree.h"
        !            33: #include "symbols.h"
        !            34: #include "names.h"
        !            35: #include "y.tab.h"
        !            36: 
        !            37: #ifndef public
        !            38: typedef int Token;
        !            39: 
        !            40: #define MAXLINESIZE 10240
        !            41: 
        !            42: #endif
        !            43: 
        !            44: public String initfile = ".dbxinit";
        !            45: 
        !            46: typedef enum { WHITE, ALPHA, NUM, OTHER } Charclass;
        !            47: 
        !            48: private Charclass class[256 + 1];
        !            49: private Charclass *lexclass = class + 1;
        !            50: 
        !            51: #define isdigit(c) (lexclass[c] == NUM)
        !            52: #define isalnum(c) (lexclass[c] == ALPHA or lexclass[c] == NUM)
        !            53: #define ishexdigit(c) ( \
        !            54:     isdigit(c) or (c >= 'a' and c <= 'f') or (c >= 'A' and c <= 'F') \
        !            55: )
        !            56: 
        !            57: public boolean chkalias;
        !            58: public char scanner_linebuf[MAXLINESIZE];
        !            59: 
        !            60: private File in;
        !            61: private char *curchar, *prevchar;
        !            62: 
        !            63: #define MAXINCLDEPTH 10
        !            64: 
        !            65: private struct {
        !            66:     File savefile;
        !            67:     Filename savefn;
        !            68:     int savelineno;
        !            69: } inclinfo[MAXINCLDEPTH];
        !            70: 
        !            71: private unsigned int curinclindex;
        !            72: 
        !            73: private Token getident();
        !            74: private Token getnum();
        !            75: private Token getstring();
        !            76: private Boolean eofinput();
        !            77: private char charcon();
        !            78: 
        !            79: private enterlexclass(class, s)
        !            80: Charclass class;
        !            81: String s;
        !            82: {
        !            83:     register char *p;
        !            84: 
        !            85:     for (p = s; *p != '\0'; p++) {
        !            86:        lexclass[*p] = class;
        !            87:     }
        !            88: }
        !            89: 
        !            90: public scanner_init()
        !            91: {
        !            92:     register Integer i;
        !            93: 
        !            94:     for (i = 0; i < 257; i++) {
        !            95:        class[i] = OTHER;
        !            96:     }
        !            97:     enterlexclass(WHITE, " \t");
        !            98:     enterlexclass(ALPHA, "abcdefghijklmnopqrstuvwxyz");
        !            99:     enterlexclass(ALPHA, "ABCDEFGHIJKLMNOPQRSTUVWXYZ_$");
        !           100:     enterlexclass(NUM, "0123456789");
        !           101:     in = stdin;
        !           102:     errfilename = nil;
        !           103:     errlineno = 0;
        !           104:     curchar = scanner_linebuf;
        !           105:     scanner_linebuf[0] = '\0';
        !           106:     chkalias = true;
        !           107: }
        !           108: 
        !           109: /*
        !           110:  * Read a single token.
        !           111:  *
        !           112:  * The input is line buffered.  Tokens cannot cross line boundaries.
        !           113:  *
        !           114:  * There are two "modes" of operation:  one as in a compiler,
        !           115:  * and one for reading shell-like syntax.  In the first mode
        !           116:  * there is the additional choice of doing alias processing.
        !           117:  */
        !           118: 
        !           119: private Boolean shellmode;
        !           120: 
        !           121: public Token yylex()
        !           122: {
        !           123:     register int c;
        !           124:     register char *p;
        !           125:     register Token t;
        !           126:     String line;
        !           127:     integer n;
        !           128: 
        !           129:     p = curchar;
        !           130:     if (*p == '\0') {
        !           131:        do {
        !           132:            if (isterm(in)) {
        !           133:                printf("(%s) ", cmdname);
        !           134:            }
        !           135:            fflush(stdout);
        !           136:            line = fgets(scanner_linebuf, MAXLINESIZE, in);
        !           137:        } while (line == nil and not eofinput());
        !           138:        if (line == nil) {
        !           139:            c = EOF;
        !           140:        } else {
        !           141:            p = scanner_linebuf;
        !           142:            while (lexclass[*p] == WHITE) {
        !           143:                p++;
        !           144:            }
        !           145:            shellmode = false;
        !           146:        }
        !           147:        chkalias = true;
        !           148:     } else {
        !           149:        while (lexclass[*p] == WHITE) {
        !           150:            p++;
        !           151:        }
        !           152:     }
        !           153:     curchar = p;
        !           154:     prevchar = curchar;
        !           155:     c = *p;
        !           156:     if (lexclass[c] == ALPHA) {
        !           157:        t = getident(chkalias);
        !           158:     } else if (lexclass[c] == NUM) {
        !           159:        if (shellmode) {
        !           160:            t = getident(chkalias);
        !           161:        } else {
        !           162:            t = getnum();
        !           163:        }
        !           164:     } else {
        !           165:        ++curchar;
        !           166:        switch (c) {
        !           167:            case '\n':
        !           168:                t = '\n';
        !           169:                if (errlineno != 0) {
        !           170:                    errlineno++;
        !           171:                }
        !           172:                break;
        !           173: 
        !           174:            case '"':
        !           175:            case '\'':
        !           176:                t = getstring(c);
        !           177:                break;
        !           178: 
        !           179:            case '.':
        !           180:                if (shellmode) {
        !           181:                    --curchar;
        !           182:                    t = getident(chkalias);
        !           183:                } else if (isdigit(*curchar)) {
        !           184:                    --curchar;
        !           185:                    t = getnum();
        !           186:                } else {
        !           187:                    t = '.';
        !           188:                }
        !           189:                break;
        !           190: 
        !           191:            case '-':
        !           192:                if (shellmode) {
        !           193:                    --curchar;
        !           194:                    t = getident(chkalias);
        !           195:                } else if (*curchar == '>') {
        !           196:                    ++curchar;
        !           197:                    t = ARROW;
        !           198:                } else {
        !           199:                    t = '-';
        !           200:                }
        !           201:                break;
        !           202: 
        !           203:            case '#':
        !           204:                if (not isterm(in)) {
        !           205:                    *p = '\0';
        !           206:                    curchar = p;
        !           207:                    t = '\n';
        !           208:                    ++errlineno;
        !           209:                } else {
        !           210:                    t = '#';
        !           211:                }
        !           212:                break;
        !           213: 
        !           214:            case '\\':
        !           215:                if (*(p+1) == '\n') {
        !           216:                    n = MAXLINESIZE - (p - &scanner_linebuf[0]);
        !           217:                    if (n > 1) {
        !           218:                        if (fgets(p, n, in) == nil) {
        !           219:                            t = 0;
        !           220:                        } else {
        !           221:                            curchar = p;
        !           222:                            t = yylex();
        !           223:                        }
        !           224:                    } else {
        !           225:                        t = '\\';
        !           226:                    }
        !           227:                } else {
        !           228:                    t = '\\';
        !           229:                }
        !           230:                break;
        !           231: 
        !           232:            case EOF:
        !           233:                t = 0;
        !           234:                break;
        !           235: 
        !           236:            default:
        !           237:                if (shellmode and index("!&*<>()[]", c) == nil) {
        !           238:                    --curchar;
        !           239:                    t = getident(chkalias);
        !           240:                } else {
        !           241:                    t = c;
        !           242:                }
        !           243:                break;
        !           244:        }
        !           245:     }
        !           246:     chkalias = false;
        !           247: #   ifdef LEXDEBUG
        !           248:        if (lexdebug) {
        !           249:            fprintf(stderr, "yylex returns ");
        !           250:            print_token(stderr, t);
        !           251:            fprintf(stderr, "\n");
        !           252:        }
        !           253: #   endif
        !           254:     return t;
        !           255: }
        !           256: 
        !           257: /*
        !           258:  * Put the given string before the current character
        !           259:  * in the current line, thus inserting it into the input stream.
        !           260:  */
        !           261: 
        !           262: public insertinput (s)
        !           263: String s;
        !           264: {
        !           265:     register char *p, *q;
        !           266:     int need, avail, shift;
        !           267: 
        !           268:     q = s;
        !           269:     need = strlen(q);
        !           270:     avail = curchar - &scanner_linebuf[0];
        !           271:     if (need <= avail) {
        !           272:        curchar = &scanner_linebuf[avail - need];
        !           273:        p = curchar;
        !           274:        while (*q != '\0') {
        !           275:            *p++ = *q++;
        !           276:        }
        !           277:     } else {
        !           278:        p = curchar;
        !           279:        while (*p != '\0') {
        !           280:            ++p;
        !           281:        }
        !           282:        shift = need - avail;
        !           283:        if (p + shift >= &scanner_linebuf[MAXLINESIZE]) {
        !           284:            error("alias expansion too large");
        !           285:        }
        !           286:        for (;;) {
        !           287:            *(p + shift) = *p;
        !           288:            if (p == curchar) {
        !           289:                break;
        !           290:            }
        !           291:            --p;
        !           292:        }
        !           293:        p = &scanner_linebuf[0];
        !           294:        while (*q != '\0') {
        !           295:            *p++ = *q++;
        !           296:        }
        !           297:        curchar = &scanner_linebuf[0];
        !           298:     }
        !           299: }
        !           300: 
        !           301: /*
        !           302:  * Get the actuals for a macro call.
        !           303:  */
        !           304: 
        !           305: private String movetochar (str, c)
        !           306: String str;
        !           307: char c;
        !           308: {
        !           309:     register char *p;
        !           310: 
        !           311:     while (*p != c) {
        !           312:        if (*p == '\0') {
        !           313:            error("missing ')' in macro call");
        !           314:        } else if (*p == ')') {
        !           315:            error("not enough parameters in macro call");
        !           316:        } else if (*p == ',') {
        !           317:            error("too many parameters in macro call");
        !           318:        }
        !           319:        ++p;
        !           320:     }
        !           321:     return p;
        !           322: }
        !           323: 
        !           324: private String *getactuals (n)
        !           325: integer n;
        !           326: {
        !           327:     String *a;
        !           328:     register char *p;
        !           329:     int i;
        !           330: 
        !           331:     a = newarr(String, n);
        !           332:     p = curchar;
        !           333:     while (*p != '(') {
        !           334:        if (lexclass[*p] != WHITE) {
        !           335:            error("missing actuals for macro");
        !           336:        }
        !           337:        ++p;
        !           338:     }
        !           339:     ++p;
        !           340:     for (i = 0; i < n - 1; i++) {
        !           341:        a[i] = p;
        !           342:        p = movetochar(p, ',');
        !           343:        *p = '\0';
        !           344:        ++p;
        !           345:     }
        !           346:     a[n-1] = p;
        !           347:     p = movetochar(p, ')');
        !           348:     *p = '\0';
        !           349:     curchar = p + 1;
        !           350:     return a;
        !           351: }
        !           352: 
        !           353: /*
        !           354:  * Do command macro expansion, assuming curchar points to the beginning
        !           355:  * of the actuals, and we are not in shell mode.
        !           356:  */
        !           357: 
        !           358: private expand (pl, str)
        !           359: List pl;
        !           360: String str;
        !           361: {
        !           362:     char buf[4096], namebuf[100];
        !           363:     register char *p, *q, *r;
        !           364:     String *actual;
        !           365:     Name n;
        !           366:     integer i;
        !           367:     boolean match;
        !           368: 
        !           369:     if (pl == nil) {
        !           370:        insertinput(str);
        !           371:     } else {
        !           372:        actual = getactuals(list_size(pl));
        !           373:        p = buf;
        !           374:        q = str;
        !           375:        while (*q != '\0') {
        !           376:            if (p >= &buf[4096]) {
        !           377:                error("alias expansion too large");
        !           378:            }
        !           379:            if (lexclass[*q] == ALPHA) {
        !           380:                r = namebuf;
        !           381:                do {
        !           382:                    *r++ = *q++;
        !           383:                } while (isalnum(*q));
        !           384:                *r = '\0';
        !           385:                i = 0;
        !           386:                match = false;
        !           387:                foreach(Name, n, pl)
        !           388:                    if (streq(ident(n), namebuf)) {
        !           389:                        match = true;
        !           390:                        break;
        !           391:                    }
        !           392:                    ++i;
        !           393:                endfor
        !           394:                if (match) {
        !           395:                    r = actual[i];
        !           396:                } else {
        !           397:                    r = namebuf;
        !           398:                }
        !           399:                while (*r != '\0') {
        !           400:                    *p++ = *r++;
        !           401:                }
        !           402:            } else {
        !           403:                *p++ = *q++;
        !           404:            }
        !           405:        }
        !           406:        *p = '\0';
        !           407:        insertinput(buf);
        !           408:     }
        !           409: }
        !           410: 
        !           411: /*
        !           412:  * Parser error handling.
        !           413:  */
        !           414: 
        !           415: public yyerror(s)
        !           416: String s;
        !           417: {
        !           418:     register char *p;
        !           419:     register integer start;
        !           420: 
        !           421:     if (streq(s, "syntax error")) {
        !           422:        beginerrmsg();
        !           423:        p = prevchar;
        !           424:        start = p - &scanner_linebuf[0];
        !           425:        if (p > &scanner_linebuf[0]) {
        !           426:            while (lexclass[*p] == WHITE and p > &scanner_linebuf[0]) {
        !           427:                --p;
        !           428:            }
        !           429:        }
        !           430:        fprintf(stderr, "%s", scanner_linebuf);
        !           431:        if (start != 0) {
        !           432:            fprintf(stderr, "%*c", start, ' ');
        !           433:        }
        !           434:        if (p == &scanner_linebuf[0]) {
        !           435:            fprintf(stderr, "^ unrecognized command");
        !           436:        } else {
        !           437:            fprintf(stderr, "^ syntax error");
        !           438:        }
        !           439:        enderrmsg();
        !           440:     } else {
        !           441:        error(s);
        !           442:     }
        !           443: }
        !           444: 
        !           445: /*
        !           446:  * Eat the current line.
        !           447:  */
        !           448: 
        !           449: public gobble ()
        !           450: {
        !           451:     curchar = scanner_linebuf;
        !           452:     scanner_linebuf[0] = '\0';
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Scan an identifier.
        !           457:  *
        !           458:  * If chkalias is true, check first to see if it's an alias.
        !           459:  * Otherwise, check to see if it's a keyword.
        !           460:  */
        !           461: 
        !           462: private Token getident (chkalias)
        !           463: boolean chkalias;
        !           464: {
        !           465:     char buf[1024];
        !           466:     register char *p, *q;
        !           467:     register Token t;
        !           468:     List pl;
        !           469:     String str;
        !           470: 
        !           471:     p = curchar;
        !           472:     q = buf;
        !           473:     if (shellmode) {
        !           474:        do {
        !           475:            *q++ = *p++;
        !           476:        } while (index(" \t\n!&<>*[]()'\"", *p) == nil);
        !           477:     } else {
        !           478:        do {
        !           479:            *q++ = *p++;
        !           480:        } while (isalnum(*p));
        !           481:     }
        !           482:     curchar = p;
        !           483:     *q = '\0';
        !           484:     yylval.y_name = identname(buf, false);
        !           485:     if (chkalias) {
        !           486:        if (findalias(yylval.y_name, &pl, &str)) {
        !           487:            expand(pl, str);
        !           488:            while (lexclass[*curchar] == WHITE) {
        !           489:                ++curchar;
        !           490:            }
        !           491:            if (pl == nil) {
        !           492:                t = getident(false);
        !           493:            } else {
        !           494:                t = getident(true);
        !           495:            }
        !           496:        } else if (shellmode) {
        !           497:            t = NAME;
        !           498:        } else {
        !           499:            t = findkeyword(yylval.y_name, NAME);
        !           500:        }
        !           501:     } else if (shellmode) {
        !           502:        t = NAME;
        !           503:     } else {
        !           504:        t = findkeyword(yylval.y_name, NAME);
        !           505:     }
        !           506:     return t;
        !           507: }
        !           508: 
        !           509: /*
        !           510:  * Scan a number.
        !           511:  */
        !           512: 
        !           513: private Token getnum()
        !           514: {
        !           515:     char buf[1024];
        !           516:     register Char *p, *q;
        !           517:     register Token t;
        !           518:     Integer base;
        !           519: 
        !           520:     p = curchar;
        !           521:     q = buf;
        !           522:     if (*p == '0') {
        !           523:        if (*(p+1) == 'x') {
        !           524:            p += 2;
        !           525:            base = 16;
        !           526:        } else if (*(p+1) == 't') {
        !           527:            base = 10;
        !           528:        } else if (varIsSet("$hexin")) {
        !           529:            base = 16;
        !           530:        } else {
        !           531:            base = 8;
        !           532:        }
        !           533:     } else if (varIsSet("$hexin")) {
        !           534:        base = 16;
        !           535:     } else if (varIsSet("$octin")) {
        !           536:        base = 8;
        !           537:     } else {
        !           538:        base = 10;
        !           539:     }
        !           540:     if (base == 16) {
        !           541:        do {
        !           542:            *q++ = *p++;
        !           543:        } while (ishexdigit(*p));
        !           544:     } else {
        !           545:        do {
        !           546:            *q++ = *p++;
        !           547:        } while (isdigit(*p));
        !           548:     }
        !           549:     if (*p == '.') {
        !           550:        do {
        !           551:            *q++ = *p++;
        !           552:        } while (isdigit(*p));
        !           553:        if (*p == 'e' or *p == 'E') {
        !           554:            p++;
        !           555:            if (*p == '+' or *p == '-' or isdigit(*p)) {
        !           556:                *q++ = 'e';
        !           557:                do {
        !           558:                    *q++ = *p++;
        !           559:                } while (isdigit(*p));
        !           560:            }
        !           561:        }
        !           562:        *q = '\0';
        !           563:        yylval.y_real = atof(buf);
        !           564:        t = REAL;
        !           565:     } else {
        !           566:        *q = '\0';
        !           567:        switch (base) {
        !           568:            case 10:
        !           569:                yylval.y_int = atol(buf);
        !           570:                break;
        !           571: 
        !           572:            case 8:
        !           573:                yylval.y_int = octal(buf);
        !           574:                break;
        !           575: 
        !           576:            case 16:
        !           577:                yylval.y_int = hex(buf);
        !           578:                break;
        !           579: 
        !           580:            default:
        !           581:                badcaseval(base);
        !           582:        }
        !           583:        t = INT;
        !           584:     }
        !           585:     curchar = p;
        !           586:     return t;
        !           587: }
        !           588: 
        !           589: /*
        !           590:  * Convert a string of octal digits to an integer.
        !           591:  */
        !           592: 
        !           593: private int octal(s)
        !           594: String s;
        !           595: {
        !           596:     register Char *p;
        !           597:     register Integer n;
        !           598: 
        !           599:     n = 0;
        !           600:     for (p = s; *p != '\0'; p++) {
        !           601:        n = 8*n + (*p - '0');
        !           602:     }
        !           603:     return n;
        !           604: }
        !           605: 
        !           606: /*
        !           607:  * Convert a string of hexadecimal digits to an integer.
        !           608:  */
        !           609: 
        !           610: private int hex(s)
        !           611: String s;
        !           612: {
        !           613:     register Char *p;
        !           614:     register Integer n;
        !           615: 
        !           616:     n = 0;
        !           617:     for (p = s; *p != '\0'; p++) {
        !           618:        n *= 16;
        !           619:        if (*p >= 'a' and *p <= 'f') {
        !           620:            n += (*p - 'a' + 10);
        !           621:        } else if (*p >= 'A' and *p <= 'F') {
        !           622:            n += (*p - 'A' + 10);
        !           623:        } else {
        !           624:            n += (*p - '0');
        !           625:        }
        !           626:     }
        !           627:     return n;
        !           628: }
        !           629: 
        !           630: /*
        !           631:  * Scan a string.
        !           632:  */
        !           633: 
        !           634: private Token getstring (quote)
        !           635: char quote;
        !           636: {
        !           637:     register char *p, *q;
        !           638:     char buf[MAXLINESIZE];
        !           639:     boolean endofstring;
        !           640:     Token t;
        !           641: 
        !           642:     p = curchar;
        !           643:     q = buf;
        !           644:     endofstring = false;
        !           645:     while (not endofstring) {
        !           646:        if (*p == '\\' and *(p+1) == '\n') {
        !           647:            if (fgets(scanner_linebuf, MAXLINESIZE, in) == nil) {
        !           648:                error("non-terminated string");
        !           649:            }
        !           650:            p = &scanner_linebuf[0] - 1;
        !           651:        } else if (*p == '\n' or *p == '\0') {
        !           652:            error("non-terminated string");
        !           653:            endofstring = true;
        !           654:        } else if (*p == quote) {
        !           655:            endofstring = true;
        !           656:        } else {
        !           657:            curchar = p;
        !           658:            *q++ = charcon(p);
        !           659:            p = curchar;
        !           660:        }
        !           661:        p++;
        !           662:     }
        !           663:     curchar = p;
        !           664:     *q = '\0';
        !           665:     if (quote == '\'' and buf[1] == '\0') {
        !           666:        yylval.y_char = buf[0];
        !           667:        t = CHAR;
        !           668:     } else {
        !           669:        yylval.y_string = strdup(buf);
        !           670:        t = STRING;
        !           671:     }
        !           672:     return t;
        !           673: }
        !           674: 
        !           675: /*
        !           676:  * Process a character constant.
        !           677:  * Watch out for backslashes.
        !           678:  */
        !           679: 
        !           680: private char charcon (s)
        !           681: String s;
        !           682: {
        !           683:     register char *p, *q;
        !           684:     char c, buf[10];
        !           685: 
        !           686:     p = s;
        !           687:     if (*p == '\\') {
        !           688:        ++p;
        !           689:        switch (*p) {
        !           690:            case '\\':
        !           691:                c = '\\';
        !           692:                break;
        !           693: 
        !           694:            case 'n':
        !           695:                c = '\n';
        !           696:                break;
        !           697: 
        !           698:            case 'r':
        !           699:                c = '\r';
        !           700:                break;
        !           701: 
        !           702:            case 't':
        !           703:                c = '\t';
        !           704:                break;
        !           705: 
        !           706:            case '\'':
        !           707:            case '"':
        !           708:                c = *p;
        !           709:                break;
        !           710: 
        !           711:            default:
        !           712:                if (isdigit(*p)) {
        !           713:                    q = buf;
        !           714:                    do {
        !           715:                        *q++ = *p++;
        !           716:                    } while (isdigit(*p));
        !           717:                    *q = '\0';
        !           718:                    c = (char) octal(buf);
        !           719:                }
        !           720:                --p;
        !           721:                break;
        !           722:        }
        !           723:        curchar = p;
        !           724:     } else {
        !           725:        c = *p;
        !           726:     }
        !           727:     return c;
        !           728: }
        !           729: 
        !           730: /*
        !           731:  * Input file management routines.
        !           732:  */
        !           733: 
        !           734: public setinput(filename)
        !           735: Filename filename;
        !           736: {
        !           737:     File f;
        !           738: 
        !           739:     f = fopen(filename, "r");
        !           740:     if (f == nil) {
        !           741:        error("can't open %s", filename);
        !           742:     } else {
        !           743:        if (curinclindex >= MAXINCLDEPTH) {
        !           744:            error("unreasonable input nesting on \"%s\"", filename);
        !           745:        }
        !           746:        inclinfo[curinclindex].savefile = in;
        !           747:        inclinfo[curinclindex].savefn = errfilename;
        !           748:        inclinfo[curinclindex].savelineno = errlineno;
        !           749:        curinclindex++;
        !           750:        in = f;
        !           751:        errfilename = filename;
        !           752:        errlineno = 1;
        !           753:     }
        !           754: }
        !           755: 
        !           756: private Boolean eofinput()
        !           757: {
        !           758:     register Boolean b;
        !           759: 
        !           760:     if (curinclindex == 0) {
        !           761:        if (isterm(in)) {
        !           762:            putchar('\n');
        !           763:            clearerr(in);
        !           764:            b = false;
        !           765:        } else {
        !           766:            b = true;
        !           767:        }
        !           768:     } else {
        !           769:        fclose(in);
        !           770:        --curinclindex;
        !           771:        in = inclinfo[curinclindex].savefile;
        !           772:        errfilename = inclinfo[curinclindex].savefn;
        !           773:        errlineno = inclinfo[curinclindex].savelineno;
        !           774:        b = false;
        !           775:     }
        !           776:     return b;
        !           777: }
        !           778: 
        !           779: /*
        !           780:  * Pop the current input.  Return whether successful.
        !           781:  */
        !           782: 
        !           783: public Boolean popinput()
        !           784: {
        !           785:     Boolean b;
        !           786: 
        !           787:     if (curinclindex == 0) {
        !           788:        b = false;
        !           789:     } else {
        !           790:        b = (Boolean) (not eofinput());
        !           791:     }
        !           792:     return b;
        !           793: }
        !           794: 
        !           795: /*
        !           796:  * Return whether we are currently reading from standard input.
        !           797:  */
        !           798: 
        !           799: public Boolean isstdin()
        !           800: {
        !           801:     return (Boolean) (in == stdin);
        !           802: }
        !           803: 
        !           804: /*
        !           805:  * Send the current line to the shell.
        !           806:  */
        !           807: 
        !           808: public shellline()
        !           809: {
        !           810:     register char *p;
        !           811: 
        !           812:     p = curchar;
        !           813:     while (*p != '\0' and (*p == '\n' or lexclass[*p] == WHITE)) {
        !           814:        ++p;
        !           815:     }
        !           816:     shell(p);
        !           817:     if (*p == '\0' and isterm(in)) {
        !           818:        putchar('\n');
        !           819:     }
        !           820:     erecover();
        !           821: }
        !           822: 
        !           823: /*
        !           824:  * Read the rest of the current line in "shell mode".
        !           825:  */
        !           826: 
        !           827: public beginshellmode()
        !           828: {
        !           829:     shellmode = true;
        !           830: }
        !           831: 
        !           832: /*
        !           833:  * Print out a token for debugging.
        !           834:  */
        !           835: 
        !           836: public print_token(f, t)
        !           837: File f;
        !           838: Token t;
        !           839: {
        !           840:     if (t == '\n') {
        !           841:        fprintf(f, "char '\\n'");
        !           842:     } else if (t == EOF) {
        !           843:        fprintf(f, "EOF");
        !           844:     } else if (t < 256) {
        !           845:        fprintf(f, "char '%c'", t);
        !           846:     } else {
        !           847:        fprintf(f, "\"%s\"", keywdstring(t));
        !           848:     }
        !           849: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.