Annotation of XNU/osfmk/ddb/db_expr.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.2.19.1  1997/03/27  18:46:35  barbou
        !            35:  *     ri-osc CR1561: make operators "logical and", "logical or"
        !            36:  *     lex correctly.
        !            37:  *     [1995/09/20  15:26:38  bolinger]
        !            38:  *     [97/02/25            barbou]
        !            39:  *
        !            40:  * Revision 1.2.10.2  1995/01/06  19:10:13  devrcs
        !            41:  *     mk6 CR668 - 1.3b26 merge
        !            42:  *     * Revision 1.2.3.5  1994/05/06  18:39:16  tmt
        !            43:  *     Merged osc1.3dec/shared with osc1.3b19
        !            44:  *     Merge Alpha changes into osc1.312b source code.
        !            45:  *     64bit cleanup.
        !            46:  *     * End1.3merge
        !            47:  *     [1994/11/04  08:49:27  dwm]
        !            48:  * 
        !            49:  * Revision 1.2.10.1  1994/09/23  01:19:06  ezf
        !            50:  *     change marker to not FREE
        !            51:  *     [1994/09/22  21:09:53  ezf]
        !            52:  * 
        !            53:  * Revision 1.2.3.3  1993/07/27  18:27:15  elliston
        !            54:  *     Add ANSI prototypes.  CR #9523.
        !            55:  *     [1993/07/27  18:11:36  elliston]
        !            56:  * 
        !            57:  * Revision 1.2.3.2  1993/06/09  02:20:06  gm
        !            58:  *     Added to OSF/1 R1.3 from NMK15.0.
        !            59:  *     [1993/06/02  20:56:16  jeffc]
        !            60:  * 
        !            61:  * Revision 1.2  1993/04/19  16:02:09  devrcs
        !            62:  *     Allow unprefixed (0x) hexadecimal constants starting by a letter:
        !            63:  *     unknown symbols are tentatively interpreted as hexadecimal constants,
        !            64:  *     and ambiguities are reported.
        !            65:  *     [93/03/24            barbou]
        !            66:  * 
        !            67:  *     Changes from mk78:
        !            68:  *     Removed unused variable from db_unary().
        !            69:  *     [92/05/16            jfriedl]
        !            70:  *     [93/02/02            bruel]
        !            71:  * 
        !            72:  *     Added string format arguments [[email protected]]
        !            73:  *     [92/12/03            bernadat]
        !            74:  * 
        !            75:  * Revision 1.1  1992/09/30  02:01:04  robert
        !            76:  *     Initial revision
        !            77:  * 
        !            78:  * $EndLog$
        !            79:  */
        !            80: /* CMU_HIST */
        !            81: /*
        !            82:  * Revision 2.5  91/10/09  15:59:46  af
        !            83:  *      Revision 2.4.3.1  91/10/05  13:06:04  jeffreyh
        !            84:  *             Added relational expression etc. to support condition expression.
        !            85:  *             Supported modifier after indirect expression to specify size,
        !            86:  *               sign extention and non current task space indirection.
        !            87:  *             Changed error messages to print more information.
        !            88:  *             [91/08/29            tak]
        !            89:  * 
        !            90:  * Revision 2.4.3.1  91/10/05  13:06:04  jeffreyh
        !            91:  *     Added relational expression etc. to support condition expression.
        !            92:  *     Supported modifier after indirect expression to specify size,
        !            93:  *       sign extention and non current task space indirection.
        !            94:  *     Changed error messages to print more information.
        !            95:  *     [91/08/29            tak]
        !            96:  * 
        !            97:  * Revision 2.4  91/05/14  15:33:45  mrt
        !            98:  *     Correcting copyright
        !            99:  * 
        !           100:  * Revision 2.3  91/02/05  17:06:25  mrt
        !           101:  *     Changed to new Mach copyright
        !           102:  *     [91/01/31  16:17:46  mrt]
        !           103:  * 
        !           104:  * Revision 2.2  90/08/27  21:50:57  dbg
        !           105:  *     Use '..' instead of '$$' for db_prev.
        !           106:  *     Use '+' for db_next.
        !           107:  *     [90/08/22            dbg]
        !           108:  * 
        !           109:  *     Allow repeated unary operators.
        !           110:  *     [90/08/20            dbg]
        !           111:  * 
        !           112:  *     Reflected back rename of db_symbol_value->db_value_of_name
        !           113:  *     [90/08/20            af]
        !           114:  *     Reduce lint.
        !           115:  *     [90/08/07            dbg]
        !           116:  *     Created.
        !           117:  *     [90/07/25            dbg]
        !           118:  * 
        !           119:  */
        !           120: /* CMU_ENDHIST */
        !           121: /* 
        !           122:  * Mach Operating System
        !           123:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !           124:  * All Rights Reserved.
        !           125:  * 
        !           126:  * Permission to use, copy, modify and distribute this software and its
        !           127:  * documentation is hereby granted, provided that both the copyright
        !           128:  * notice and this permission notice appear in all copies of the
        !           129:  * software, derivative works or modified versions, and any portions
        !           130:  * thereof, and that both notices appear in supporting documentation.
        !           131:  * 
        !           132:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !           133:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !           134:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !           135:  * 
        !           136:  * Carnegie Mellon requests users of this software to return to
        !           137:  * 
        !           138:  *  Software Distribution Coordinator  or  [email protected]
        !           139:  *  School of Computer Science
        !           140:  *  Carnegie Mellon University
        !           141:  *  Pittsburgh PA 15213-3890
        !           142:  * 
        !           143:  * any improvements or extensions that they make and grant Carnegie Mellon
        !           144:  * the rights to redistribute these changes.
        !           145:  */
        !           146: /*
        !           147:  */
        !           148: /*
        !           149:  *     Author: David B. Golub, Carnegie Mellon University
        !           150:  *     Date:   7/90
        !           151:  */
        !           152: 
        !           153: #include <mach/boolean.h>
        !           154: #include <machine/db_machdep.h>
        !           155: #include <ddb/db_access.h>
        !           156: #include <ddb/db_command.h>
        !           157: #include <ddb/db_expr.h>
        !           158: #include <ddb/db_lex.h>
        !           159: #include <ddb/db_output.h>             /* For db_printf() */
        !           160: #include <ddb/db_sym.h>
        !           161: #include <ddb/db_variables.h>
        !           162: #include <kern/task.h>
        !           163: 
        !           164: 
        !           165: 
        !           166: /* Prototypes for functions local to this file.  XXX -- should be static!
        !           167:  */
        !           168: boolean_t db_term(db_expr_t *valuep);
        !           169: boolean_t db_unary(db_expr_t *valuep);
        !           170: boolean_t db_mult_expr(db_expr_t *valuep);
        !           171: boolean_t db_add_expr(db_expr_t *valuep);
        !           172: boolean_t db_shift_expr(db_expr_t *valuep);
        !           173: boolean_t db_logical_relation_expr(db_expr_t *valuep);
        !           174: boolean_t db_logical_and_expr(db_expr_t *valuep);
        !           175: boolean_t db_logical_or_expr(db_expr_t *valuep);
        !           176: 
        !           177: 
        !           178: /* try to interpret unknown symbols as hexadecimal constants */
        !           179: int db_allow_unprefixed_hexa = 1;
        !           180: 
        !           181: boolean_t
        !           182: db_term(db_expr_t *valuep)
        !           183: {
        !           184:        int     t;
        !           185:        boolean_t valid_symbol = FALSE;
        !           186:        boolean_t valid_hexa = FALSE;
        !           187: 
        !           188:        switch(t = db_read_token()) {
        !           189:        case tIDENT:
        !           190:            if (db_value_of_name(db_tok_string, valuep)) {
        !           191:                valid_symbol = TRUE;
        !           192:            }
        !           193:            if (db_allow_unprefixed_hexa && db_radix == 16 &&
        !           194:                db_tok_string) {
        !           195:                char *cp;
        !           196:                int value;
        !           197:                    
        !           198:                value = 0;
        !           199:                valid_hexa = TRUE;
        !           200:                for (cp = db_tok_string; *cp; cp++) {
        !           201:                    if (*cp >= 'a' && *cp <= 'f') {
        !           202:                        value = value * 16 + 10 + (*cp - 'a');
        !           203:                    } else if (*cp >= 'A' && *cp <= 'F') {
        !           204:                        value = value * 16 + 10 + (*cp - 'A');
        !           205:                    } else if (*cp >= '0' && *cp <= '9') {
        !           206:                        value = value * 16 + (*cp - '0');
        !           207:                    } else {
        !           208:                        valid_hexa = FALSE;
        !           209:                        break;
        !           210:                    }
        !           211:                }
        !           212:                if (valid_hexa) {
        !           213:                    if (valid_symbol) {
        !           214:                        db_printf("Ambiguous constant %x used as a symbol\n",
        !           215:                                  value);
        !           216:                    } else {
        !           217:                        *valuep = (db_expr_t)value;
        !           218:                    }   
        !           219:                }
        !           220:            }
        !           221:            if (!valid_symbol && !valid_hexa) {
        !           222:                db_printf("Symbol \"%s\" not found\n", db_tok_string);
        !           223:                db_error(0);
        !           224:                /*NOTREACHED*/
        !           225:            }
        !           226:            return (TRUE);
        !           227:        case tNUMBER:
        !           228:            *valuep = /*(db_expr_t)*/db_tok_number;
        !           229:            return (TRUE);
        !           230:        case tDOT:
        !           231:            *valuep = (db_expr_t)db_dot;
        !           232:            return (TRUE);
        !           233:        case tDOTDOT:
        !           234:            *valuep = (db_expr_t)db_prev;
        !           235:            return (TRUE);
        !           236:        case tPLUS:
        !           237:            *valuep = (db_expr_t) db_next;
        !           238:            return (TRUE);
        !           239:        case tQUOTE:
        !           240:            *valuep = (db_expr_t)db_last_addr;
        !           241:            return (TRUE);
        !           242:        case tDOLLAR:
        !           243:            if (!db_get_variable(valuep))
        !           244:                return (FALSE);
        !           245:            return (TRUE);
        !           246:        case tLPAREN:
        !           247:            if (!db_expression(valuep)) {
        !           248:                db_error("Unmached ()s\n");
        !           249:                /*NOTREACHED*/
        !           250:            }
        !           251:            t = db_read_token();
        !           252:            if (t != tRPAREN) {
        !           253:                db_printf("')' expected at \"%s...\"\n", db_tok_string);
        !           254:                db_error(0);
        !           255:                /*NOTREACHED*/
        !           256:            }
        !           257:            return (TRUE);
        !           258:        case tSTRING:
        !           259:            {
        !           260:                    static db_tok_offset = 0;
        !           261:                    char *sp, *cp;
        !           262: 
        !           263:                    sp = (char *)db_tok_string + db_tok_offset;
        !           264:                    *valuep = *(int *)sp;
        !           265:                    for (cp = sp;
        !           266:                         *cp && cp < sp + sizeof (int);
        !           267:                         cp++);
        !           268:                    if (cp == sp + sizeof (int) && *cp) {
        !           269:                            db_tok_offset += sizeof (int);
        !           270:                            db_unread_token(t);
        !           271:                    } else {
        !           272:                            db_tok_offset = 0;
        !           273:                    }
        !           274:                    return (TRUE);
        !           275:            }
        !           276:        default:
        !           277:            db_unread_token(t);
        !           278:            return (FALSE);
        !           279:        }
        !           280: }
        !           281: 
        !           282: int
        !           283: db_size_option(
        !           284:        char            *modif,
        !           285:        boolean_t       *u_option,
        !           286:        boolean_t       *t_option)
        !           287: {
        !           288:        register  char *p;
        !           289:        int       size = sizeof(int);
        !           290: 
        !           291:        *u_option = FALSE;
        !           292:        *t_option = FALSE;
        !           293:        for (p = modif; *p; p++) {
        !           294:            switch(*p) {
        !           295:            case 'b':
        !           296:                size = sizeof(char);
        !           297:                break;
        !           298:            case 'h':
        !           299:                size = sizeof(short);
        !           300:                break;
        !           301:            case 'l':
        !           302:                size = sizeof(long);
        !           303:                break;
        !           304:            case 'u':
        !           305:                *u_option = TRUE;
        !           306:                break;
        !           307:            case 't':
        !           308:                *t_option = TRUE;
        !           309:                break;
        !           310:            }
        !           311:        }
        !           312:        return(size);
        !           313: }
        !           314: 
        !           315: boolean_t
        !           316: db_unary(db_expr_t *valuep)
        !           317: {
        !           318:        int       t;
        !           319:        int       size;
        !           320:        boolean_t u_opt, t_opt;
        !           321:        task_t    task;
        !           322:        extern    task_t db_default_task;
        !           323: 
        !           324:        t = db_read_token();
        !           325:        if (t == tMINUS) {
        !           326:            if (!db_unary(valuep)) {
        !           327:                db_error("Expression syntax error after '-'\n");
        !           328:                /*NOTREACHED*/
        !           329:            }
        !           330:            *valuep = -*valuep;
        !           331:            return (TRUE);
        !           332:        }
        !           333:        if (t == tSTAR) {
        !           334:            /* indirection */
        !           335:            if (!db_unary(valuep)) {
        !           336:                db_error("Expression syntax error after '*'\n");
        !           337:                /*NOTREACHED*/
        !           338:            }
        !           339:            task = TASK_NULL;
        !           340:            size = sizeof(db_addr_t);
        !           341:            u_opt = FALSE;
        !           342:            t = db_read_token();
        !           343:            if (t == tIDENT && db_tok_string[0] == ':') {
        !           344:                size = db_size_option(&db_tok_string[1], &u_opt, &t_opt);
        !           345:                if (t_opt)
        !           346:                    task = db_default_task;
        !           347:            } else
        !           348:                db_unread_token(t);
        !           349:            *valuep = db_get_task_value((db_addr_t)*valuep, size, !u_opt, task);
        !           350:            return (TRUE);
        !           351:        }
        !           352:        if (t == tEXCL) {
        !           353:            if (!db_unary(valuep)) {
        !           354:                db_error("Expression syntax error after '!'\n");
        !           355:                /*NOTREACHED*/
        !           356:            }
        !           357:            *valuep = (!(*valuep));
        !           358:            return (TRUE);
        !           359:        }
        !           360:        db_unread_token(t);
        !           361:        return (db_term(valuep));
        !           362: }
        !           363: 
        !           364: boolean_t
        !           365: db_mult_expr(db_expr_t *valuep)
        !           366: {
        !           367:        db_expr_t       lhs, rhs;
        !           368:        int             t;
        !           369:        char            c;
        !           370: 
        !           371:        if (!db_unary(&lhs))
        !           372:            return (FALSE);
        !           373: 
        !           374:        t = db_read_token();
        !           375:        while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH
        !           376:                || t == tBIT_AND) {
        !           377:            c = db_tok_string[0];
        !           378:            if (!db_term(&rhs)) {
        !           379:                db_printf("Expression syntax error after '%c'\n", c);
        !           380:                db_error(0);
        !           381:                /*NOTREACHED*/
        !           382:            }
        !           383:            switch(t) {
        !           384:            case tSTAR:
        !           385:                lhs *= rhs;
        !           386:                break;
        !           387:            case tBIT_AND:
        !           388:                lhs &= rhs;
        !           389:                break;
        !           390:            default:
        !           391:                if (rhs == 0) {
        !           392:                    db_error("Divide by 0\n");
        !           393:                    /*NOTREACHED*/
        !           394:                }
        !           395:                if (t == tSLASH)
        !           396:                    lhs /= rhs;
        !           397:                else if (t == tPCT)
        !           398:                    lhs %= rhs;
        !           399:                else
        !           400:                    lhs = ((lhs+rhs-1)/rhs)*rhs;
        !           401:            }
        !           402:            t = db_read_token();
        !           403:        }
        !           404:        db_unread_token(t);
        !           405:        *valuep = lhs;
        !           406:        return (TRUE);
        !           407: }
        !           408: 
        !           409: boolean_t
        !           410: db_add_expr(db_expr_t *valuep)
        !           411: {
        !           412:        db_expr_t       lhs, rhs;
        !           413:        int             t;
        !           414:        char            c;
        !           415: 
        !           416:        if (!db_mult_expr(&lhs))
        !           417:            return (FALSE);
        !           418: 
        !           419:        t = db_read_token();
        !           420:        while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
        !           421:            c = db_tok_string[0];
        !           422:            if (!db_mult_expr(&rhs)) {
        !           423:                db_printf("Expression syntax error after '%c'\n", c);
        !           424:                db_error(0);
        !           425:                /*NOTREACHED*/
        !           426:            }
        !           427:            if (t == tPLUS)
        !           428:                lhs += rhs;
        !           429:            else if (t == tMINUS)
        !           430:                lhs -= rhs;
        !           431:            else
        !           432:                lhs |= rhs;
        !           433:            t = db_read_token();
        !           434:        }
        !           435:        db_unread_token(t);
        !           436:        *valuep = lhs;
        !           437:        return (TRUE);
        !           438: }
        !           439: 
        !           440: boolean_t
        !           441: db_shift_expr(db_expr_t *valuep)
        !           442: {
        !           443:        db_expr_t       lhs, rhs;
        !           444:        int             t;
        !           445: 
        !           446:        if (!db_add_expr(&lhs))
        !           447:            return (FALSE);
        !           448: 
        !           449:        t = db_read_token();
        !           450:        while (t == tSHIFT_L || t == tSHIFT_R) {
        !           451:            if (!db_add_expr(&rhs)) {
        !           452:                db_printf("Expression syntax error after \"%s\"\n",
        !           453:                        (t == tSHIFT_L)? "<<": ">>");
        !           454:                db_error(0);
        !           455:                /*NOTREACHED*/
        !           456:            }
        !           457:            if (rhs < 0) {
        !           458:                db_error("Negative shift amount\n");
        !           459:                /*NOTREACHED*/
        !           460:            }
        !           461:            if (t == tSHIFT_L)
        !           462:                lhs <<= rhs;
        !           463:            else {
        !           464:                /* Shift right is unsigned */
        !           465:                lhs = (natural_t) lhs >> rhs;
        !           466:            }
        !           467:            t = db_read_token();
        !           468:        }
        !           469:        db_unread_token(t);
        !           470:        *valuep = lhs;
        !           471:        return (TRUE);
        !           472: }
        !           473: 
        !           474: boolean_t
        !           475: db_logical_relation_expr(db_expr_t *valuep)
        !           476: {
        !           477:        db_expr_t       lhs, rhs;
        !           478:        int             t;
        !           479:        char            op[3];
        !           480: 
        !           481:        if (!db_shift_expr(&lhs))
        !           482:            return(FALSE);
        !           483: 
        !           484:        t = db_read_token();
        !           485:        while (t == tLOG_EQ || t == tLOG_NOT_EQ
        !           486:                || t == tGREATER || t == tGREATER_EQ
        !           487:                || t == tLESS || t == tLESS_EQ) {
        !           488:            op[0] = db_tok_string[0];
        !           489:            op[1] = db_tok_string[1];
        !           490:            op[2] = 0;
        !           491:            if (!db_shift_expr(&rhs)) {
        !           492:                db_printf("Expression syntax error after \"%s\"\n", op);
        !           493:                db_error(0);
        !           494:                /*NOTREACHED*/
        !           495:            }
        !           496:            switch(t) {
        !           497:            case tLOG_EQ:
        !           498:                lhs = (lhs == rhs);
        !           499:                break;
        !           500:            case tLOG_NOT_EQ:
        !           501:                lhs = (lhs != rhs);
        !           502:                break;
        !           503:            case tGREATER:
        !           504:                lhs = (lhs > rhs);
        !           505:                break;
        !           506:            case tGREATER_EQ:
        !           507:                lhs = (lhs >= rhs);
        !           508:                break;
        !           509:            case tLESS:
        !           510:                lhs = (lhs < rhs);
        !           511:                break;
        !           512:            case tLESS_EQ:
        !           513:                lhs = (lhs <= rhs);
        !           514:                break;
        !           515:            }
        !           516:            t = db_read_token();
        !           517:        }
        !           518:        db_unread_token(t);
        !           519:        *valuep = lhs;
        !           520:        return (TRUE);
        !           521: }
        !           522: 
        !           523: boolean_t
        !           524: db_logical_and_expr(db_expr_t *valuep)
        !           525: {
        !           526:        db_expr_t       lhs, rhs;
        !           527:        int             t;
        !           528: 
        !           529:        if (!db_logical_relation_expr(&lhs))
        !           530:            return(FALSE);
        !           531: 
        !           532:        t = db_read_token();
        !           533:        while (t == tLOG_AND) {
        !           534:            if (!db_logical_relation_expr(&rhs)) {
        !           535:                db_error("Expression syntax error after \"&&\"\n");
        !           536:                /*NOTREACHED*/
        !           537:            }
        !           538:            lhs = (lhs && rhs);
        !           539:            t = db_read_token();
        !           540:        }
        !           541:        db_unread_token(t);
        !           542:        *valuep = lhs;
        !           543:        return (TRUE);
        !           544: }
        !           545: 
        !           546: boolean_t
        !           547: db_logical_or_expr(db_expr_t *valuep)
        !           548: {
        !           549:        db_expr_t       lhs, rhs;
        !           550:        int             t;
        !           551: 
        !           552:        if (!db_logical_and_expr(&lhs))
        !           553:            return(FALSE);
        !           554: 
        !           555:        t = db_read_token();
        !           556:        while (t == tLOG_OR) {
        !           557:            if (!db_logical_and_expr(&rhs)) {
        !           558:                db_error("Expression syntax error after \"||\"\n");
        !           559:                /*NOTREACHED*/
        !           560:            }
        !           561:            lhs = (lhs || rhs);
        !           562:            t = db_read_token();
        !           563:        }
        !           564:        db_unread_token(t);
        !           565:        *valuep = lhs;
        !           566:        return (TRUE);
        !           567: }
        !           568: 
        !           569: int
        !           570: db_expression(db_expr_t *valuep)
        !           571: {
        !           572:        return (db_logical_or_expr(valuep));
        !           573: }

unix.superglobalmegacorp.com

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