Annotation of XNU/osfmk/ddb/db_lex.c, revision 1.1.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.