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

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             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.
        !            11:  * 
        !            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.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            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;
        !           124:        else 
        !           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:            {
        !           263:                db_printf("Bad character '%c' after number %s\n", 
        !           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: 
        !           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.