Annotation of Gnu-Mach/ddb/db_lex.c, revision 1.1.1.3

1.1.1.2   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.2   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.2   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.2   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.2   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     Author: David B. Golub, Carnegie Mellon University
                     28:  *     Date:   7/90
                     29:  */
1.1.1.3 ! root       30: 
1.1       root       31: #if MACH_KDB
                     32: 
                     33: /*
                     34:  * Lexical analyzer.
                     35:  */
1.1.1.3 ! root       36: #include <string.h>
1.1       root       37: #include <machine/db_machdep.h>
1.1.1.3 ! root       38: #include <ddb/db_command.h>
        !            39: #include <ddb/db_examine.h>
        !            40: #include <ddb/db_input.h>
1.1       root       41: #include <ddb/db_lex.h>
1.1.1.3 ! root       42: #include <ddb/db_output.h>
1.1       root       43: 
                     44: char   db_line[DB_LEX_LINE_SIZE];
                     45: char   db_last_line[DB_LEX_LINE_SIZE];
                     46: char   *db_lp, *db_endlp;
                     47: char   *db_last_lp;
                     48: int    db_look_char = 0;
                     49: db_expr_t db_look_token = 0;
                     50: 
                     51: int
                     52: db_read_line(repeat_last)
                     53:        char    *repeat_last;
                     54: {
                     55:        int     i;
                     56: 
                     57:        i = db_readline(db_line, sizeof(db_line));
                     58:        if (i == 0)
                     59:            return (0); /* EOI */
                     60:        if (repeat_last) {
                     61:            if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) {
                     62:                db_strcpy(db_line, db_last_line);
                     63:                db_printf("%s", db_line);
                     64:                i = strlen(db_line);
                     65:            } else if (db_line[0] != '\n' && db_line[0] != 0)
                     66:                db_strcpy(db_last_line, db_line);
                     67:        }
                     68:        db_lp = db_line;
                     69:        db_endlp = db_lp + i;
                     70:        db_last_lp = db_lp;
                     71:        db_look_char = 0;
                     72:        db_look_token = 0;
                     73:        return (i);
                     74: }
                     75: 
                     76: void
1.1.1.3 ! root       77: db_flush_line(void)
1.1       root       78: {
                     79:        db_lp = db_line;
                     80:        db_last_lp = db_lp;
                     81:        db_endlp = db_line;
                     82: }
                     83: 
                     84: void
                     85: db_switch_input(buffer, size)
                     86:        char *buffer;
                     87:        int  size;
                     88: {
                     89:        db_lp = buffer;
                     90:        db_last_lp = db_lp;
                     91:        db_endlp = buffer + size;
                     92:        db_look_char = 0;
                     93:        db_look_token = 0;
                     94: }
                     95: 
                     96: void
                     97: db_save_lex_context(lp)
                     98:        register struct db_lex_context *lp;
                     99: {
                    100:        lp->l_ptr = db_lp;
                    101:        lp->l_eptr = db_endlp;
                    102:        lp->l_char = db_look_char;
                    103:        lp->l_token = db_look_token;
                    104: }
                    105: 
                    106: void
                    107: db_restore_lex_context(lp)
                    108:        register struct db_lex_context *lp;
                    109: {
                    110:        db_lp = lp->l_ptr;
                    111:        db_last_lp = db_lp;
                    112:        db_endlp = lp->l_eptr;
                    113:        db_look_char = lp->l_char;
                    114:        db_look_token = lp->l_token;
                    115: }
                    116: 
                    117: int
1.1.1.3 ! root      118: db_read_char(void)
1.1       root      119: {
                    120:        int     c;
                    121: 
                    122:        if (db_look_char != 0) {
                    123:            c = db_look_char;
                    124:            db_look_char = 0;
                    125:        }
                    126:        else if (db_lp >= db_endlp)
                    127:            c = -1;
1.1.1.2   root      128:        else
1.1       root      129:            c = *db_lp++;
                    130:        return (c);
                    131: }
                    132: 
                    133: void
                    134: db_unread_char(c)
                    135:        int c;
                    136: {
                    137:        db_look_char = c;
                    138: }
                    139: 
                    140: void
                    141: db_unread_token(t)
                    142:        int     t;
                    143: {
                    144:        db_look_token = t;
                    145: }
                    146: 
                    147: int
1.1.1.3 ! root      148: db_read_token(void)
1.1       root      149: {
                    150:        int     t;
                    151: 
                    152:        if (db_look_token) {
                    153:            t = db_look_token;
                    154:            db_look_token = 0;
                    155:        }
                    156:        else {
                    157:            db_last_lp = db_lp;
                    158:            if (db_look_char)
                    159:                db_last_lp--;
                    160:            t = db_lex();
                    161:        }
                    162:        return (t);
                    163: }
                    164: 
                    165: db_expr_t      db_tok_number;
                    166: char           db_tok_string[TOK_STRING_SIZE];
                    167: db_expr_t      db_radix = 16;
                    168: 
                    169: void
1.1.1.3 ! root      170: db_flush_lex(void)
1.1       root      171: {
                    172:        db_flush_line();
                    173:        db_look_char = 0;
                    174:        db_look_token = 0;
                    175: }
                    176: 
                    177: #define        DB_DISP_SKIP    40              /* number of chars to display skip */
                    178: 
                    179: void
1.1.1.3 ! root      180: db_skip_to_eol(void)
1.1       root      181: {
1.1.1.3 ! root      182:        register int skip;
        !           183:        register int t;
        !           184:        register int n;
1.1       root      185:        register char *p;
                    186: 
                    187:        t = db_read_token();
                    188:        p = db_last_lp;
                    189:        for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
                    190:            t = db_read_token();
                    191:        if (t == tSEMI_COLON)
                    192:            db_unread_token(t);
                    193:        if (skip != 0) {
                    194:            while (p < db_last_lp && (*p == ' ' || *p == '\t'))
                    195:                p++;
                    196:            db_printf("Warning: Skipped input data \"");
                    197:            for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
                    198:                db_printf("%c", *p++);
                    199:            if (n >= DB_DISP_SKIP)
                    200:                db_printf("....");
                    201:            db_printf("\"\n");
                    202:        }
                    203: }
                    204: 
                    205: int
1.1.1.3 ! root      206: db_lex(void)
1.1       root      207: {
                    208:        register char *cp;
1.1.1.3 ! root      209:        register int c;
1.1       root      210: 
                    211:        c = db_read_char();
                    212:        while (c <= ' ' || c > '~') {
                    213:            if (c == '\n' || c == -1)
                    214:                return (tEOL);
                    215:            c = db_read_char();
                    216:        }
                    217: 
                    218:        cp = db_tok_string;
                    219:        *cp++ = c;
                    220: 
                    221:        if (c >= '0' && c <= '9') {
                    222:            /* number */
                    223:            int r, digit;
                    224: 
                    225:            if (c > '0')
                    226:                r = db_radix;
                    227:            else {
                    228:                c = db_read_char();
                    229:                if (c == 'O' || c == 'o')
                    230:                    r = 8;
                    231:                else if (c == 'T' || c == 't')
                    232:                    r = 10;
                    233:                else if (c == 'X' || c == 'x')
                    234:                    r = 16;
                    235:                else {
                    236:                    cp--;
                    237:                    r = db_radix;
                    238:                    db_unread_char(c);
                    239:                }
                    240:                c = db_read_char();
                    241:                *cp++ = c;
                    242:            }
                    243:            db_tok_number = 0;
                    244:            for (;;) {
                    245:                if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
                    246:                    digit = c - '0';
                    247:                else if (r == 16 && ((c >= 'A' && c <= 'F') ||
                    248:                                     (c >= 'a' && c <= 'f'))) {
                    249:                    if (c >= 'a')
                    250:                        digit = c - 'a' + 10;
                    251:                    else
                    252:                        digit = c - 'A' + 10;
                    253:                }
                    254:                else
                    255:                    break;
                    256:                db_tok_number = db_tok_number * r + digit;
                    257:                c = db_read_char();
                    258:                if (cp < &db_tok_string[sizeof(db_tok_string)-1])
                    259:                        *cp++ = c;
                    260:            }
                    261:            cp[-1] = 0;
                    262:            if ((c >= '0' && c <= '9') ||
                    263:                (c >= 'A' && c <= 'Z') ||
                    264:                (c >= 'a' && c <= 'z') ||
                    265:                (c == '_'))
                    266:            {
1.1.1.2   root      267:                db_printf("Bad character '%c' after number %s\n",
1.1       root      268:                                c, db_tok_string);
                    269:                db_error(0);
                    270:                db_flush_lex();
                    271:                return (tEOF);
                    272:            }
                    273:            db_unread_char(c);
                    274:            return (tNUMBER);
                    275:        }
                    276:        if ((c >= 'A' && c <= 'Z') ||
                    277:            (c >= 'a' && c <= 'z') ||
                    278:            c == '_' || c == '\\' || c == ':')
                    279:        {
                    280:            /* identifier */
                    281:            if (c == '\\') {
                    282:                c = db_read_char();
                    283:                if (c == '\n' || c == -1)
                    284:                    db_error("Bad '\\' at the end of line\n");
                    285:                cp[-1] = c;
                    286:            }
                    287:            while (1) {
                    288:                c = db_read_char();
                    289:                if ((c >= 'A' && c <= 'Z') ||
                    290:                    (c >= 'a' && c <= 'z') ||
                    291:                    (c >= '0' && c <= '9') ||
                    292:                    c == '_' || c == '\\' || c == ':' || c == '.')
                    293:                {
                    294:                    if (c == '\\') {
                    295:                        c = db_read_char();
                    296:                        if (c == '\n' || c == -1)
                    297:                            db_error("Bad '\\' at the end of line\n");
                    298:                    }
                    299:                    *cp++ = c;
                    300:                    if (cp == db_tok_string+sizeof(db_tok_string)) {
                    301:                        db_error("String too long\n");
                    302:                        db_flush_lex();
                    303:                        return (tEOF);
                    304:                    }
                    305:                    continue;
                    306:                }
                    307:                else {
                    308:                    *cp = '\0';
                    309:                    break;
                    310:                }
                    311:            }
                    312:            db_unread_char(c);
                    313:            return (tIDENT);
                    314:        }
                    315: 
                    316:        *cp = 0;
                    317:        switch (c) {
                    318:            case '+':
                    319:                return (tPLUS);
                    320:            case '-':
                    321:                return (tMINUS);
                    322:            case '.':
                    323:                c = db_read_char();
                    324:                if (c == '.') {
                    325:                    *cp++ = c;
                    326:                    *cp = 0;
                    327:                    return (tDOTDOT);
                    328:                }
                    329:                db_unread_char(c);
                    330:                return (tDOT);
                    331:            case '*':
                    332:                return (tSTAR);
                    333:            case '/':
                    334:                return (tSLASH);
                    335:            case '=':
                    336:                c = db_read_char();
                    337:                if (c == '=') {
                    338:                    *cp++ = c;
                    339:                    *cp = 0;
                    340:                    return(tLOG_EQ);
                    341:                }
                    342:                db_unread_char(c);
                    343:                return (tEQ);
                    344:            case '%':
                    345:                return (tPCT);
                    346:            case '#':
                    347:                return (tHASH);
                    348:            case '(':
                    349:                return (tLPAREN);
                    350:            case ')':
                    351:                return (tRPAREN);
                    352:            case ',':
                    353:                return (tCOMMA);
                    354:            case '\'':
                    355:                return (tQUOTE);
                    356:            case '"':
                    357:                /* string */
                    358:                cp = db_tok_string;
                    359:                c = db_read_char();
                    360:                while (c != '"' && c > 0 && c != '\n') {
                    361:                    if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
                    362:                        db_error("Too long string\n");
                    363:                        db_flush_lex();
                    364:                        return (tEOF);
                    365:                    }
                    366:                    if (c == '\\') {
                    367:                        c = db_read_char();
                    368:                        switch(c) {
                    369:                        case 'n':
                    370:                            c = '\n'; break;
                    371:                        case 't':
                    372:                            c = '\t'; break;
                    373:                        case '\\':
                    374:                        case '"':
                    375:                            break;
                    376:                        default:
                    377:                            db_printf("Bad escape sequence '\\%c'\n", c);
                    378:                            db_error(0);
                    379:                            db_flush_lex();
                    380:                            return (tEOF);
                    381:                        }
                    382:                    }
                    383:                    *cp++ = c;
                    384:                    c = db_read_char();
                    385:                }
                    386:                *cp = 0;
                    387:                if (c != '"') {
                    388:                    db_error("Non terminated string constant\n");
                    389:                    db_flush_lex();
                    390:                    return (tEOF);
                    391:                }
                    392:                return (tSTRING);
                    393:            case '$':
                    394:                return (tDOLLAR);
                    395:            case '!':
                    396:                c = db_read_char();
                    397:                if (c == '=') {
                    398:                    *cp++ = c;
                    399:                    *cp = 0;
                    400:                    return(tLOG_NOT_EQ);
                    401:                }
                    402:                db_unread_char(c);
                    403:                return (tEXCL);
                    404:            case '&':
                    405:                c = db_read_char();
                    406:                if (c == '&') {
                    407:                    *cp++ = c;
                    408:                    *cp = 0;
                    409:                    return(tLOG_AND);
                    410:                }
                    411:                db_unread_char(c);
                    412:                return(tBIT_AND);
                    413:            case '|':
                    414:                c = db_read_char();
                    415:                if (c == '|') {
                    416:                    *cp++ = c;
                    417:                    *cp = 0;
                    418:                    return(tLOG_OR);
                    419:                }
                    420:                db_unread_char(c);
                    421:                return(tBIT_OR);
                    422:            case '<':
                    423:                c = db_read_char();
                    424:                *cp++ = c;
                    425:                *cp = 0;
                    426:                if (c == '<')
                    427:                    return (tSHIFT_L);
                    428:                if (c == '=')
                    429:                    return (tLESS_EQ);
                    430:                cp[-1] = 0;
                    431:                db_unread_char(c);
                    432:                return(tLESS);
                    433:                break;
                    434:            case '>':
                    435:                c = db_read_char();
                    436:                *cp++ = c;
                    437:                *cp = 0;
                    438:                if (c == '>')
                    439:                    return (tSHIFT_R);
                    440:                if (c == '=')
                    441:                    return (tGREATER_EQ);
                    442:                cp[-1] = 0;
                    443:                db_unread_char(c);
                    444:                return (tGREATER);
                    445:                break;
                    446:            case ';':
                    447:                return (tSEMI_COLON);
                    448:            case '?':
                    449:                return (tQUESTION);
                    450:            case -1:
                    451:                db_strcpy(db_tok_string, "<EOL>");
                    452:                return (tEOF);
                    453:        }
                    454:        db_printf("Bad character '%c'\n", c);
                    455:        db_flush_lex();
                    456:        return (tEOF);
                    457: }
                    458: 
1.1.1.2   root      459: #endif /* MACH_KDB */

unix.superglobalmegacorp.com

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