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

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)
1.1.1.4 ! root       53:        const char      *repeat_last;
1.1       root       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
1.1.1.4 ! root       85: db_switch_input(
        !            86:        char *buffer,
        !            87:        int  size)
1.1       root       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
1.1.1.4 ! root       97: db_save_lex_context(struct db_lex_context *lp)
1.1       root       98: {
                     99:        lp->l_ptr = db_lp;
                    100:        lp->l_eptr = db_endlp;
                    101:        lp->l_char = db_look_char;
                    102:        lp->l_token = db_look_token;
                    103: }
                    104: 
                    105: void
                    106: db_restore_lex_context(lp)
1.1.1.4 ! root      107:        const struct db_lex_context *lp;
1.1       root      108: {
                    109:        db_lp = lp->l_ptr;
                    110:        db_last_lp = db_lp;
                    111:        db_endlp = lp->l_eptr;
                    112:        db_look_char = lp->l_char;
                    113:        db_look_token = lp->l_token;
                    114: }
                    115: 
                    116: int
1.1.1.3   root      117: db_read_char(void)
1.1       root      118: {
                    119:        int     c;
                    120: 
                    121:        if (db_look_char != 0) {
                    122:            c = db_look_char;
                    123:            db_look_char = 0;
                    124:        }
                    125:        else if (db_lp >= db_endlp)
                    126:            c = -1;
1.1.1.2   root      127:        else
1.1       root      128:            c = *db_lp++;
                    129:        return (c);
                    130: }
                    131: 
                    132: void
1.1.1.4 ! root      133: db_unread_char(int c)
1.1       root      134: {
                    135:        db_look_char = c;
                    136: }
                    137: 
                    138: void
1.1.1.4 ! root      139: db_unread_token(int t)
1.1       root      140: {
                    141:        db_look_token = t;
                    142: }
                    143: 
                    144: int
1.1.1.3   root      145: db_read_token(void)
1.1       root      146: {
                    147:        int     t;
                    148: 
                    149:        if (db_look_token) {
                    150:            t = db_look_token;
                    151:            db_look_token = 0;
                    152:        }
                    153:        else {
                    154:            db_last_lp = db_lp;
                    155:            if (db_look_char)
                    156:                db_last_lp--;
                    157:            t = db_lex();
                    158:        }
                    159:        return (t);
                    160: }
                    161: 
                    162: db_expr_t      db_tok_number;
                    163: char           db_tok_string[TOK_STRING_SIZE];
                    164: db_expr_t      db_radix = 16;
                    165: 
                    166: void
1.1.1.3   root      167: db_flush_lex(void)
1.1       root      168: {
                    169:        db_flush_line();
                    170:        db_look_char = 0;
                    171:        db_look_token = 0;
                    172: }
                    173: 
                    174: #define        DB_DISP_SKIP    40              /* number of chars to display skip */
                    175: 
                    176: void
1.1.1.3   root      177: db_skip_to_eol(void)
1.1       root      178: {
1.1.1.4 ! root      179:        int skip;
        !           180:        int t;
        !           181:        int n;
        !           182:        char *p;
1.1       root      183: 
                    184:        t = db_read_token();
                    185:        p = db_last_lp;
                    186:        for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
                    187:            t = db_read_token();
                    188:        if (t == tSEMI_COLON)
                    189:            db_unread_token(t);
                    190:        if (skip != 0) {
                    191:            while (p < db_last_lp && (*p == ' ' || *p == '\t'))
                    192:                p++;
                    193:            db_printf("Warning: Skipped input data \"");
                    194:            for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
                    195:                db_printf("%c", *p++);
                    196:            if (n >= DB_DISP_SKIP)
                    197:                db_printf("....");
                    198:            db_printf("\"\n");
                    199:        }
                    200: }
                    201: 
                    202: int
1.1.1.3   root      203: db_lex(void)
1.1       root      204: {
1.1.1.4 ! root      205:        char *cp;
        !           206:        int c;
1.1       root      207: 
                    208:        c = db_read_char();
                    209:        while (c <= ' ' || c > '~') {
                    210:            if (c == '\n' || c == -1)
                    211:                return (tEOL);
                    212:            c = db_read_char();
                    213:        }
                    214: 
                    215:        cp = db_tok_string;
                    216:        *cp++ = c;
                    217: 
                    218:        if (c >= '0' && c <= '9') {
                    219:            /* number */
                    220:            int r, digit;
                    221: 
                    222:            if (c > '0')
                    223:                r = db_radix;
                    224:            else {
                    225:                c = db_read_char();
                    226:                if (c == 'O' || c == 'o')
                    227:                    r = 8;
                    228:                else if (c == 'T' || c == 't')
                    229:                    r = 10;
                    230:                else if (c == 'X' || c == 'x')
                    231:                    r = 16;
                    232:                else {
                    233:                    cp--;
                    234:                    r = db_radix;
                    235:                    db_unread_char(c);
                    236:                }
                    237:                c = db_read_char();
                    238:                *cp++ = c;
                    239:            }
                    240:            db_tok_number = 0;
                    241:            for (;;) {
                    242:                if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
                    243:                    digit = c - '0';
                    244:                else if (r == 16 && ((c >= 'A' && c <= 'F') ||
                    245:                                     (c >= 'a' && c <= 'f'))) {
                    246:                    if (c >= 'a')
                    247:                        digit = c - 'a' + 10;
                    248:                    else
                    249:                        digit = c - 'A' + 10;
                    250:                }
                    251:                else
                    252:                    break;
                    253:                db_tok_number = db_tok_number * r + digit;
                    254:                c = db_read_char();
                    255:                if (cp < &db_tok_string[sizeof(db_tok_string)-1])
                    256:                        *cp++ = c;
                    257:            }
                    258:            cp[-1] = 0;
                    259:            if ((c >= '0' && c <= '9') ||
                    260:                (c >= 'A' && c <= 'Z') ||
                    261:                (c >= 'a' && c <= 'z') ||
                    262:                (c == '_'))
                    263:            {
1.1.1.2   root      264:                db_printf("Bad character '%c' after number %s\n",
1.1       root      265:                                c, db_tok_string);
                    266:                db_error(0);
                    267:                db_flush_lex();
                    268:                return (tEOF);
                    269:            }
                    270:            db_unread_char(c);
                    271:            return (tNUMBER);
                    272:        }
                    273:        if ((c >= 'A' && c <= 'Z') ||
                    274:            (c >= 'a' && c <= 'z') ||
                    275:            c == '_' || c == '\\' || c == ':')
                    276:        {
                    277:            /* identifier */
                    278:            if (c == '\\') {
                    279:                c = db_read_char();
                    280:                if (c == '\n' || c == -1)
                    281:                    db_error("Bad '\\' at the end of line\n");
                    282:                cp[-1] = c;
                    283:            }
                    284:            while (1) {
                    285:                c = db_read_char();
                    286:                if ((c >= 'A' && c <= 'Z') ||
                    287:                    (c >= 'a' && c <= 'z') ||
                    288:                    (c >= '0' && c <= '9') ||
                    289:                    c == '_' || c == '\\' || c == ':' || c == '.')
                    290:                {
                    291:                    if (c == '\\') {
                    292:                        c = db_read_char();
                    293:                        if (c == '\n' || c == -1)
                    294:                            db_error("Bad '\\' at the end of line\n");
                    295:                    }
                    296:                    *cp++ = c;
                    297:                    if (cp == db_tok_string+sizeof(db_tok_string)) {
                    298:                        db_error("String too long\n");
                    299:                        db_flush_lex();
                    300:                        return (tEOF);
                    301:                    }
                    302:                    continue;
                    303:                }
                    304:                else {
                    305:                    *cp = '\0';
                    306:                    break;
                    307:                }
                    308:            }
                    309:            db_unread_char(c);
                    310:            return (tIDENT);
                    311:        }
                    312: 
                    313:        *cp = 0;
                    314:        switch (c) {
                    315:            case '+':
                    316:                return (tPLUS);
                    317:            case '-':
                    318:                return (tMINUS);
                    319:            case '.':
                    320:                c = db_read_char();
                    321:                if (c == '.') {
                    322:                    *cp++ = c;
                    323:                    *cp = 0;
                    324:                    return (tDOTDOT);
                    325:                }
                    326:                db_unread_char(c);
                    327:                return (tDOT);
                    328:            case '*':
                    329:                return (tSTAR);
                    330:            case '/':
                    331:                return (tSLASH);
                    332:            case '=':
                    333:                c = db_read_char();
                    334:                if (c == '=') {
                    335:                    *cp++ = c;
                    336:                    *cp = 0;
                    337:                    return(tLOG_EQ);
                    338:                }
                    339:                db_unread_char(c);
                    340:                return (tEQ);
                    341:            case '%':
                    342:                return (tPCT);
                    343:            case '#':
                    344:                return (tHASH);
                    345:            case '(':
                    346:                return (tLPAREN);
                    347:            case ')':
                    348:                return (tRPAREN);
                    349:            case ',':
                    350:                return (tCOMMA);
                    351:            case '\'':
                    352:                return (tQUOTE);
                    353:            case '"':
                    354:                /* string */
                    355:                cp = db_tok_string;
                    356:                c = db_read_char();
                    357:                while (c != '"' && c > 0 && c != '\n') {
                    358:                    if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
                    359:                        db_error("Too long string\n");
                    360:                        db_flush_lex();
                    361:                        return (tEOF);
                    362:                    }
                    363:                    if (c == '\\') {
                    364:                        c = db_read_char();
                    365:                        switch(c) {
                    366:                        case 'n':
                    367:                            c = '\n'; break;
                    368:                        case 't':
                    369:                            c = '\t'; break;
                    370:                        case '\\':
                    371:                        case '"':
                    372:                            break;
                    373:                        default:
                    374:                            db_printf("Bad escape sequence '\\%c'\n", c);
                    375:                            db_error(0);
                    376:                            db_flush_lex();
                    377:                            return (tEOF);
                    378:                        }
                    379:                    }
                    380:                    *cp++ = c;
                    381:                    c = db_read_char();
                    382:                }
                    383:                *cp = 0;
                    384:                if (c != '"') {
                    385:                    db_error("Non terminated string constant\n");
                    386:                    db_flush_lex();
                    387:                    return (tEOF);
                    388:                }
                    389:                return (tSTRING);
                    390:            case '$':
                    391:                return (tDOLLAR);
                    392:            case '!':
                    393:                c = db_read_char();
                    394:                if (c == '=') {
                    395:                    *cp++ = c;
                    396:                    *cp = 0;
                    397:                    return(tLOG_NOT_EQ);
                    398:                }
                    399:                db_unread_char(c);
                    400:                return (tEXCL);
                    401:            case '&':
                    402:                c = db_read_char();
                    403:                if (c == '&') {
                    404:                    *cp++ = c;
                    405:                    *cp = 0;
                    406:                    return(tLOG_AND);
                    407:                }
                    408:                db_unread_char(c);
                    409:                return(tBIT_AND);
                    410:            case '|':
                    411:                c = db_read_char();
                    412:                if (c == '|') {
                    413:                    *cp++ = c;
                    414:                    *cp = 0;
                    415:                    return(tLOG_OR);
                    416:                }
                    417:                db_unread_char(c);
                    418:                return(tBIT_OR);
                    419:            case '<':
                    420:                c = db_read_char();
                    421:                *cp++ = c;
                    422:                *cp = 0;
                    423:                if (c == '<')
                    424:                    return (tSHIFT_L);
                    425:                if (c == '=')
                    426:                    return (tLESS_EQ);
                    427:                cp[-1] = 0;
                    428:                db_unread_char(c);
                    429:                return(tLESS);
                    430:                break;
                    431:            case '>':
                    432:                c = db_read_char();
                    433:                *cp++ = c;
                    434:                *cp = 0;
                    435:                if (c == '>')
                    436:                    return (tSHIFT_R);
                    437:                if (c == '=')
                    438:                    return (tGREATER_EQ);
                    439:                cp[-1] = 0;
                    440:                db_unread_char(c);
                    441:                return (tGREATER);
                    442:                break;
                    443:            case ';':
                    444:                return (tSEMI_COLON);
                    445:            case '?':
                    446:                return (tQUESTION);
                    447:            case -1:
                    448:                db_strcpy(db_tok_string, "<EOL>");
                    449:                return (tEOF);
                    450:        }
                    451:        db_printf("Bad character '%c'\n", c);
                    452:        db_flush_lex();
                    453:        return (tEOF);
                    454: }
                    455: 
1.1.1.2   root      456: #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.