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

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