Annotation of 43BSDReno/pgrm/dbx/scanner.c, revision 1.1.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.