Annotation of XNU/osfmk/ddb/db_lex.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  */
        !            25: /*
        !            26:  * HISTORY
        !            27:  * 
        !            28:  * Revision 1.1.1.1  1998/09/22 21:05:48  wsanchez
        !            29:  * Import of Mac OS X kernel (~semeria)
        !            30:  *
        !            31:  * Revision 1.1.1.1  1998/03/07 02:26:09  wsanchez
        !            32:  * Import of OSF Mach kernel (~mburg)
        !            33:  *
        !            34:  * Revision 1.1.11.3  1996/01/09  19:15:49  devrcs
        !            35:  *     Change 'register foo' to 'register int foo'.
        !            36:  *     [1995/12/01  21:42:12  jfraser]
        !            37:  *
        !            38:  *     Merged '64-bit safe' changes from DEC alpha port.
        !            39:  *     [1995/11/21  18:03:11  jfraser]
        !            40:  *
        !            41:  * Revision 1.1.11.2  1995/01/06  19:10:21  devrcs
        !            42:  *     mk6 CR668 - 1.3b26 merge
        !            43:  *     * Revision 1.1.4.6  1994/05/06  18:39:20  tmt
        !            44:  *     Merged osc1.3dec/shared with osc1.3b19
        !            45:  *     Merge Alpha changes into osc1.312b source code.
        !            46:  *     String protos.
        !            47:  *     64bit cleanup.
        !            48:  *     Cleanup to quiet gcc warnings.
        !            49:  *     * End1.3merge
        !            50:  *     [1994/11/04  08:49:35  dwm]
        !            51:  * 
        !            52:  * Revision 1.1.11.1  1994/09/23  01:19:59  ezf
        !            53:  *     change marker to not FREE
        !            54:  *     [1994/09/22  21:10:14  ezf]
        !            55:  * 
        !            56:  * Revision 1.1.4.4  1993/08/11  20:37:55  elliston
        !            57:  *     Add ANSI Prototypes.  CR #9523.
        !            58:  *     [1993/08/11  03:33:26  elliston]
        !            59:  * 
        !            60:  * Revision 1.1.4.3  1993/07/27  18:27:38  elliston
        !            61:  *     Add ANSI prototypes.  CR #9523.
        !            62:  *     [1993/07/27  18:12:13  elliston]
        !            63:  * 
        !            64:  * Revision 1.1.4.2  1993/06/02  23:11:27  jeffc
        !            65:  *     Added to OSF/1 R1.3 from NMK15.0.
        !            66:  *     [1993/06/02  20:56:32  jeffc]
        !            67:  * 
        !            68:  * Revision 1.1  1992/09/30  02:01:10  robert
        !            69:  *     Initial revision
        !            70:  * 
        !            71:  * $EndLog$
        !            72:  */
        !            73: /* CMU_HIST */
        !            74: /*
        !            75:  * Revision 2.5  91/10/09  16:00:20  af
        !            76:  *      Revision 2.4.3.1  91/10/05  13:06:25  jeffreyh
        !            77:  *             Added relational operator tokens and string constant etc.
        !            78:  *             Added input switching functions for macro and conditional command.
        !            79:  *             Moved skip_to_eol() from db_command.c and added db_last_lp to print
        !            80:  *               skipped input data as a warning message.
        !            81:  *             Added last input repetition support to db_read_line.
        !            82:  *             Changed db_lex() to always set db_tok_string for error message.
        !            83:  *             [91/08/29            tak]
        !            84:  * 
        !            85:  * Revision 2.4.3.1  91/10/05  13:06:25  jeffreyh
        !            86:  *     Added relational operator tokens and string constant etc.
        !            87:  *     Added input switching functions for macro and conditional command.
        !            88:  *     Moved skip_to_eol() from db_command.c and added db_last_lp to print
        !            89:  *       skipped input data as a warning message.
        !            90:  *     Added last input repetition support to db_read_line.
        !            91:  *     Changed db_lex() to always set db_tok_string for error message.
        !            92:  *     [91/08/29            tak]
        !            93:  * 
        !            94:  * Revision 2.4  91/05/14  15:34:23  mrt
        !            95:  *     Correcting copyright
        !            96:  *
        !            97:  * Revision 2.3  91/02/05  17:06:36  mrt
        !            98:  *     Changed to new Mach copyright
        !            99:  *     [91/01/31  16:18:20  mrt]
        !           100:  * 
        !           101:  * Revision 2.2  90/08/27  21:51:10  dbg
        !           102:  *     Add 'dotdot' token.
        !           103:  *     [90/08/22            dbg]
        !           104:  * 
        !           105:  *     Allow backslash to quote any character into an identifier.
        !           106:  *     Allow colon in identifier for symbol table qualification.
        !           107:  *     [90/08/16            dbg]
        !           108:  *     Reduce lint.
        !           109:  *     [90/08/07            dbg]
        !           110:  *     Created.
        !           111:  *     [90/07/25            dbg]
        !           112:  * 
        !           113:  */
        !           114: /* CMU_ENDHIST */
        !           115: /* 
        !           116:  * Mach Operating System
        !           117:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !           118:  * All Rights Reserved.
        !           119:  * 
        !           120:  * Permission to use, copy, modify and distribute this software and its
        !           121:  * documentation is hereby granted, provided that both the copyright
        !           122:  * notice and this permission notice appear in all copies of the
        !           123:  * software, derivative works or modified versions, and any portions
        !           124:  * thereof, and that both notices appear in supporting documentation.
        !           125:  * 
        !           126:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !           127:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !           128:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !           129:  * 
        !           130:  * Carnegie Mellon requests users of this software to return to
        !           131:  * 
        !           132:  *  Software Distribution Coordinator  or  [email protected]
        !           133:  *  School of Computer Science
        !           134:  *  Carnegie Mellon University
        !           135:  *  Pittsburgh PA 15213-3890
        !           136:  * 
        !           137:  * any improvements or extensions that they make and grant Carnegie Mellon
        !           138:  * the rights to redistribute these changes.
        !           139:  */
        !           140: /*
        !           141:  */
        !           142: /*
        !           143:  *     Author: David B. Golub, Carnegie Mellon University
        !           144:  *     Date:   7/90
        !           145:  */
        !           146: /*
        !           147:  * Lexical analyzer.
        !           148:  */
        !           149: #include <string.h>                    /* For strcpy(), strncmp(), strlen() */
        !           150: #include <ddb/db_lex.h>
        !           151: #include <ddb/db_command.h>
        !           152: #include <ddb/db_input.h>
        !           153: #include <ddb/db_output.h>             /* For db_printf() */
        !           154: 
        !           155: char   db_line[DB_LEX_LINE_SIZE];
        !           156: char   db_last_line[DB_LEX_LINE_SIZE];
        !           157: char   *db_lp, *db_endlp;
        !           158: char   *db_last_lp;
        !           159: int    db_look_char = 0;
        !           160: db_expr_t db_look_token = 0;
        !           161: 
        !           162: 
        !           163: /* Prototypes for functions local to this file.  XXX -- should be static!
        !           164:  */
        !           165: void db_flush_line(void);
        !           166: void db_unread_char(int c);
        !           167: 
        !           168: 
        !           169: int
        !           170: db_read_line(char *repeat_last)
        !           171: {
        !           172:        int     i;
        !           173: 
        !           174:        i = db_readline(db_line, sizeof(db_line));
        !           175:        if (i == 0)
        !           176:            return (0); /* EOI */
        !           177:        if (repeat_last) {
        !           178:            if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) {
        !           179:                strcpy(db_line, db_last_line);
        !           180:                db_printf("%s", db_line);
        !           181:                i = strlen(db_line);
        !           182:            } else if (db_line[0] != '\n' && db_line[0] != 0)
        !           183:                strcpy(db_last_line, db_line);
        !           184:        }
        !           185:        db_lp = db_line;
        !           186:        db_endlp = db_lp + i;
        !           187:        db_last_lp = db_lp;
        !           188:        db_look_char = 0;
        !           189:        db_look_token = 0;
        !           190:        return (i);
        !           191: }
        !           192: 
        !           193: void
        !           194: db_flush_line(void)
        !           195: {
        !           196:        db_lp = db_line;
        !           197:        db_last_lp = db_lp;
        !           198:        db_endlp = db_line;
        !           199: }
        !           200: 
        !           201: void
        !           202: db_switch_input(
        !           203:        char    *buffer,
        !           204:        int     size)
        !           205: {
        !           206:        db_lp = buffer;
        !           207:        db_last_lp = db_lp;
        !           208:        db_endlp = buffer + size;
        !           209:        db_look_char = 0;
        !           210:        db_look_token = 0;
        !           211: }
        !           212: 
        !           213: void
        !           214: db_save_lex_context(register struct db_lex_context *lp)
        !           215: {
        !           216:        lp->l_ptr = db_lp;
        !           217:        lp->l_eptr = db_endlp;
        !           218:        lp->l_char = db_look_char;
        !           219:        lp->l_token = db_look_token;
        !           220: }
        !           221: 
        !           222: void
        !           223: db_restore_lex_context(register struct db_lex_context *lp)
        !           224: {
        !           225:        db_lp = lp->l_ptr;
        !           226:        db_last_lp = db_lp;
        !           227:        db_endlp = lp->l_eptr;
        !           228:        db_look_char = lp->l_char;
        !           229:        db_look_token = lp->l_token;
        !           230: }
        !           231: 
        !           232: int
        !           233: db_read_char(void)
        !           234: {
        !           235:        int     c;
        !           236: 
        !           237:        if (db_look_char != 0) {
        !           238:            c = db_look_char;
        !           239:            db_look_char = 0;
        !           240:        }
        !           241:        else if (db_lp >= db_endlp)
        !           242:            c = -1;
        !           243:        else 
        !           244:            c = *db_lp++;
        !           245:        return (c);
        !           246: }
        !           247: 
        !           248: void
        !           249: db_unread_char(int c)
        !           250: {
        !           251:        db_look_char = c;
        !           252: }
        !           253: 
        !           254: void
        !           255: db_unread_token(int t)
        !           256: {
        !           257:        db_look_token = t;
        !           258: }
        !           259: 
        !           260: int
        !           261: db_read_token(void)
        !           262: {
        !           263:        int     t;
        !           264: 
        !           265:        if (db_look_token) {
        !           266:            t = db_look_token;
        !           267:            db_look_token = 0;
        !           268:        }
        !           269:        else {
        !           270:            db_last_lp = db_lp;
        !           271:            if (db_look_char)
        !           272:                db_last_lp--;
        !           273:            t = db_lex();
        !           274:        }
        !           275:        return (t);
        !           276: }
        !           277: 
        !           278: db_expr_t db_tok_number;
        !           279: char   db_tok_string[TOK_STRING_SIZE];
        !           280: 
        !           281: db_expr_t db_radix = 16;
        !           282: 
        !           283: void
        !           284: db_flush_lex(void)
        !           285: {
        !           286:        db_flush_line();
        !           287:        db_look_char = 0;
        !           288:        db_look_token = 0;
        !           289: }
        !           290: 
        !           291: #define        DB_DISP_SKIP    40              /* number of chars to display skip */
        !           292: 
        !           293: void
        !           294: db_skip_to_eol(void)
        !           295: {
        !           296:        register int skip;
        !           297:        register int t;
        !           298:        register int n;
        !           299:        register char *p;
        !           300: 
        !           301:        t = db_read_token();
        !           302:        p = db_last_lp;
        !           303:        for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
        !           304:            t = db_read_token();
        !           305:        if (t == tSEMI_COLON)
        !           306:            db_unread_token(t);
        !           307:        if (skip != 0) {
        !           308:            while (p < db_last_lp && (*p == ' ' || *p == '\t'))
        !           309:                p++;
        !           310:            db_printf("Warning: Skipped input data \"");
        !           311:            for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
        !           312:                db_printf("%c", *p++);
        !           313:            if (n >= DB_DISP_SKIP)
        !           314:                db_printf("....");
        !           315:            db_printf("\"\n");
        !           316:        }
        !           317: }
        !           318: 
        !           319: int
        !           320: db_lex(void)
        !           321: {
        !           322:        register char *cp;
        !           323:        register int c;
        !           324: 
        !           325:        c = db_read_char();
        !           326:        while (c <= ' ' || c > '~') {
        !           327:            if (c == '\n' || c == -1)
        !           328:                return (tEOL);
        !           329:            c = db_read_char();
        !           330:        }
        !           331: 
        !           332:        cp = db_tok_string;
        !           333:        *cp++ = c;
        !           334: 
        !           335:        if (c >= '0' && c <= '9') {
        !           336:            /* number */
        !           337:            int r, digit;
        !           338: 
        !           339:            if (c > '0')
        !           340:                r = db_radix;
        !           341:            else {
        !           342:                c = db_read_char();
        !           343:                if (c == 'O' || c == 'o')
        !           344:                    r = 8;
        !           345:                else if (c == 'T' || c == 't')
        !           346:                    r = 10;
        !           347:                else if (c == 'X' || c == 'x')
        !           348:                    r = 16;
        !           349:                else {
        !           350:                    cp--;
        !           351:                    r = db_radix;
        !           352:                    db_unread_char(c);
        !           353:                }
        !           354:                c = db_read_char();
        !           355:                *cp++ = c;
        !           356:            }
        !           357:            db_tok_number = 0;
        !           358:            for (;;) {
        !           359:                if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
        !           360:                    digit = c - '0';
        !           361:                else if (r == 16 && ((c >= 'A' && c <= 'F') ||
        !           362:                                     (c >= 'a' && c <= 'f'))) {
        !           363:                    if (c >= 'a')
        !           364:                        digit = c - 'a' + 10;
        !           365:                    else
        !           366:                        digit = c - 'A' + 10;
        !           367:                }
        !           368:                else
        !           369:                    break;
        !           370:                db_tok_number = db_tok_number * r + digit;
        !           371:                c = db_read_char();
        !           372:                if (cp < &db_tok_string[sizeof(db_tok_string)-1])
        !           373:                        *cp++ = c;
        !           374:            }
        !           375:            cp[-1] = 0;
        !           376:            if ((c >= '0' && c <= '9') ||
        !           377:                (c >= 'A' && c <= 'Z') ||
        !           378:                (c >= 'a' && c <= 'z') ||
        !           379:                (c == '_'))
        !           380:            {
        !           381:                db_printf("Bad character '%c' after number %s\n", 
        !           382:                                c, db_tok_string);
        !           383:                db_error(0);
        !           384:                db_flush_lex();
        !           385:                return (tEOF);
        !           386:            }
        !           387:            db_unread_char(c);
        !           388:            return (tNUMBER);
        !           389:        }
        !           390:        if ((c >= 'A' && c <= 'Z') ||
        !           391:            (c >= 'a' && c <= 'z') ||
        !           392:            c == '_' || c == '\\' || c == ':')
        !           393:        {
        !           394:            /* identifier */
        !           395:            if (c == '\\') {
        !           396:                c = db_read_char();
        !           397:                if (c == '\n' || c == -1)
        !           398:                    db_error("Bad '\\' at the end of line\n");
        !           399:                cp[-1] = c;
        !           400:            }
        !           401:            while (1) {
        !           402:                c = db_read_char();
        !           403:                if ((c >= 'A' && c <= 'Z') ||
        !           404:                    (c >= 'a' && c <= 'z') ||
        !           405:                    (c >= '0' && c <= '9') ||
        !           406:                    c == '_' || c == '\\' || c == ':' || c == '.')
        !           407:                {
        !           408:                    if (c == '\\') {
        !           409:                        c = db_read_char();
        !           410:                        if (c == '\n' || c == -1)
        !           411:                            db_error("Bad '\\' at the end of line\n");
        !           412:                    }
        !           413:                    *cp++ = c;
        !           414:                    if (cp == db_tok_string+sizeof(db_tok_string)) {
        !           415:                        db_error("String too long\n");
        !           416:                        db_flush_lex();
        !           417:                        return (tEOF);
        !           418:                    }
        !           419:                    continue;
        !           420:                }
        !           421:                else {
        !           422:                    *cp = '\0';
        !           423:                    break;
        !           424:                }
        !           425:            }
        !           426:            db_unread_char(c);
        !           427:            return (tIDENT);
        !           428:        }
        !           429: 
        !           430:        *cp = 0;
        !           431:        switch (c) {
        !           432:            case '+':
        !           433:                return (tPLUS);
        !           434:            case '-':
        !           435:                return (tMINUS);
        !           436:            case '.':
        !           437:                c = db_read_char();
        !           438:                if (c == '.') {
        !           439:                    *cp++ = c;
        !           440:                    *cp = 0;
        !           441:                    return (tDOTDOT);
        !           442:                }
        !           443:                db_unread_char(c);
        !           444:                return (tDOT);
        !           445:            case '*':
        !           446:                return (tSTAR);
        !           447:            case '/':
        !           448:                return (tSLASH);
        !           449:            case '=':
        !           450:                c = db_read_char();
        !           451:                if (c == '=') {
        !           452:                    *cp++ = c;
        !           453:                    *cp = 0;
        !           454:                    return(tLOG_EQ);
        !           455:                }
        !           456:                db_unread_char(c);
        !           457:                return (tEQ);
        !           458:            case '%':
        !           459:                return (tPCT);
        !           460:            case '#':
        !           461:                return (tHASH);
        !           462:            case '(':
        !           463:                return (tLPAREN);
        !           464:            case ')':
        !           465:                return (tRPAREN);
        !           466:            case ',':
        !           467:                return (tCOMMA);
        !           468:            case '\'':
        !           469:                return (tQUOTE);
        !           470:            case '"':
        !           471:                /* string */
        !           472:                cp = db_tok_string;
        !           473:                c = db_read_char();
        !           474:                while (c != '"' && c > 0 && c != '\n') {
        !           475:                    if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
        !           476:                        db_error("Too long string\n");
        !           477:                        db_flush_lex();
        !           478:                        return (tEOF);
        !           479:                    }
        !           480:                    if (c == '\\') {
        !           481:                        c = db_read_char();
        !           482:                        switch(c) {
        !           483:                        case 'n':
        !           484:                            c = '\n'; break;
        !           485:                        case 't':
        !           486:                            c = '\t'; break;
        !           487:                        case '\\':
        !           488:                        case '"':
        !           489:                            break;
        !           490:                        default:
        !           491:                            db_printf("Bad escape sequence '\\%c'\n", c);
        !           492:                            db_error(0);
        !           493:                            db_flush_lex();
        !           494:                            return (tEOF);
        !           495:                        }
        !           496:                    }
        !           497:                    *cp++ = c;
        !           498:                    c = db_read_char();
        !           499:                }
        !           500:                *cp = 0;
        !           501:                if (c != '"') {
        !           502:                    db_error("Non terminated string constant\n");
        !           503:                    db_flush_lex();
        !           504:                    return (tEOF);
        !           505:                }
        !           506:                return (tSTRING);
        !           507:            case '$':
        !           508:                return (tDOLLAR);
        !           509:            case '!':
        !           510:                c = db_read_char();
        !           511:                if (c == '=') {
        !           512:                    *cp++ = c;
        !           513:                    *cp = 0;
        !           514:                    return(tLOG_NOT_EQ);
        !           515:                }
        !           516:                db_unread_char(c);
        !           517:                return (tEXCL);
        !           518:            case '&':
        !           519:                c = db_read_char();
        !           520:                if (c == '&') {
        !           521:                    *cp++ = c;
        !           522:                    *cp = 0;
        !           523:                    return(tLOG_AND);
        !           524:                }
        !           525:                db_unread_char(c);
        !           526:                return(tBIT_AND);
        !           527:            case '|':
        !           528:                c = db_read_char();
        !           529:                if (c == '|') {
        !           530:                    *cp++ = c;
        !           531:                    *cp = 0;
        !           532:                    return(tLOG_OR);
        !           533:                }
        !           534:                db_unread_char(c);
        !           535:                return(tBIT_OR);
        !           536:            case '<':
        !           537:                c = db_read_char();
        !           538:                *cp++ = c;
        !           539:                *cp = 0;
        !           540:                if (c == '<')
        !           541:                    return (tSHIFT_L);
        !           542:                if (c == '=')
        !           543:                    return (tLESS_EQ);
        !           544:                cp[-1] = 0;
        !           545:                db_unread_char(c);
        !           546:                return(tLESS);
        !           547:                break;
        !           548:            case '>':
        !           549:                c = db_read_char();
        !           550:                *cp++ = c;
        !           551:                *cp = 0;
        !           552:                if (c == '>')
        !           553:                    return (tSHIFT_R);
        !           554:                if (c == '=')
        !           555:                    return (tGREATER_EQ);
        !           556:                cp[-1] = 0;
        !           557:                db_unread_char(c);
        !           558:                return (tGREATER);
        !           559:                break;
        !           560:            case ';':
        !           561:                return (tSEMI_COLON);
        !           562:            case '?':
        !           563:                return (tQUESTION);
        !           564:            case -1:
        !           565:                strcpy(db_tok_string, "<EOL>");
        !           566:                return (tEOF);
        !           567:        }
        !           568:        db_printf("Bad character '%c'\n", c);
        !           569:        db_flush_lex();
        !           570:        return (tEOF);
        !           571: }

unix.superglobalmegacorp.com

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