The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_expr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: MIT-CMU
    3  *
    4  * Mach Operating System
    5  * Copyright (c) 1991,1990 Carnegie Mellon University
    6  * All Rights Reserved.
    7  *
    8  * Permission to use, copy, modify and distribute this software and its
    9  * documentation is hereby granted, provided that both the copyright
   10  * notice and this permission notice appear in all copies of the
   11  * software, derivative works or modified versions, and any portions
   12  * thereof, and that both notices appear in supporting documentation.
   13  *
   14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
   15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  *
   18  * Carnegie Mellon requests users of this software to return to
   19  *
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  *
   25  * any improvements or extensions that they make and grant Carnegie the
   26  * rights to redistribute these changes.
   27  */
   28 /*
   29  *      Author: David B. Golub, Carnegie Mellon University
   30  *      Date:   7/90
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 
   39 #include <ddb/ddb.h>
   40 #include <ddb/db_lex.h>
   41 #include <ddb/db_access.h>
   42 #include <ddb/db_command.h>
   43 
   44 static bool     db_add_expr(db_expr_t *valuep);
   45 static bool     db_mult_expr(db_expr_t *valuep);
   46 static bool     db_shift_expr(db_expr_t *valuep);
   47 static bool     db_term(db_expr_t *valuep);
   48 static bool     db_unary(db_expr_t *valuep);
   49 static bool     db_logical_or_expr(db_expr_t *valuep);
   50 static bool     db_logical_and_expr(db_expr_t *valuep);
   51 static bool     db_logical_relation_expr(db_expr_t *valuep);
   52 
   53 static bool
   54 db_term(db_expr_t *valuep)
   55 {
   56         int     t;
   57 
   58         t = db_read_token();
   59         if (t == tIDENT) {
   60             if (!db_value_of_name(db_tok_string, valuep) &&
   61                 !db_value_of_name_pcpu(db_tok_string, valuep) &&
   62                 !db_value_of_name_vnet(db_tok_string, valuep)) {
   63                 db_printf("Symbol '%s' not found\n", db_tok_string);
   64                 db_error(NULL);
   65                 /*NOTREACHED*/
   66             }
   67             return (true);
   68         }
   69         if (t == tNUMBER) {
   70             *valuep = (db_expr_t)db_tok_number;
   71             return (true);
   72         }
   73         if (t == tDOT) {
   74             *valuep = (db_expr_t)db_dot;
   75             return (true);
   76         }
   77         if (t == tDOTDOT) {
   78             *valuep = (db_expr_t)db_prev;
   79             return (true);
   80         }
   81         if (t == tPLUS) {
   82             *valuep = (db_expr_t) db_next;
   83             return (true);
   84         }
   85         if (t == tDITTO) {
   86             *valuep = (db_expr_t)db_last_addr;
   87             return (true);
   88         }
   89         if (t == tDOLLAR) {
   90             if (!db_get_variable(valuep))
   91                 return (false);
   92             return (true);
   93         }
   94         if (t == tLPAREN) {
   95             if (!db_expression(valuep)) {
   96                 db_printf("Expression syntax error after '%c'\n", '(');
   97                 db_error(NULL);
   98                 /*NOTREACHED*/
   99             }
  100             t = db_read_token();
  101             if (t != tRPAREN) {
  102                 db_printf("Expression syntax error -- expected '%c'\n", ')');
  103                 db_error(NULL);
  104                 /*NOTREACHED*/
  105             }
  106             return (true);
  107         }
  108         db_unread_token(t);
  109         return (false);
  110 }
  111 
  112 static bool
  113 db_unary(db_expr_t *valuep)
  114 {
  115         int     t;
  116 
  117         t = db_read_token();
  118         if (t == tMINUS) {
  119             if (!db_unary(valuep)) {
  120                 db_printf("Expression syntax error after '%c'\n", '-');
  121                 db_error(NULL);
  122                 /*NOTREACHED*/
  123             }
  124             *valuep = -*valuep;
  125             return (true);
  126         }
  127         if (t == tEXCL) {
  128             if (!db_unary(valuep)) {
  129                 db_printf("Expression syntax error after '%c'\n", '!');
  130                 db_error(NULL);
  131                 /* NOTREACHED  */
  132             }
  133             *valuep = (!(*valuep));
  134             return (true);
  135         }
  136         if (t == tBIT_NOT) {
  137             if (!db_unary(valuep)) {
  138                 db_printf("Expression syntax error after '%c'\n", '~');
  139                 db_error(NULL);
  140                 /* NOTREACHED */
  141             }
  142             *valuep = (~(*valuep));
  143             return (true);
  144         }
  145         if (t == tSTAR) {
  146             /* indirection */
  147             if (!db_unary(valuep)) {
  148                 db_printf("Expression syntax error after '%c'\n", '*');
  149                 db_error(NULL);
  150                 /*NOTREACHED*/
  151             }
  152             *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
  153                 false);
  154             return (true);
  155         }
  156         db_unread_token(t);
  157         return (db_term(valuep));
  158 }
  159 
  160 static bool
  161 db_mult_expr(db_expr_t *valuep)
  162 {
  163         db_expr_t       lhs, rhs;
  164         int             t;
  165 
  166         if (!db_unary(&lhs))
  167             return (false);
  168 
  169         t = db_read_token();
  170         while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
  171             t == tBIT_AND ) {
  172             if (!db_term(&rhs)) {
  173                 db_printf("Expression syntax error after '%c'\n",
  174                     t == tSTAR ? '*' : t == tSLASH ? '/' : t == tPCT ? '%' :
  175                     t == tHASH ? '#' : '&');
  176                 db_error(NULL);
  177                 /*NOTREACHED*/
  178             }
  179             switch(t)  {
  180                 case tSTAR:
  181                     lhs *= rhs;
  182                     break;
  183                 case tBIT_AND:
  184                     lhs &= rhs;
  185                     break;
  186                 default:
  187                     if (rhs == 0) {
  188                         db_error("Division by 0\n");
  189                         /*NOTREACHED*/
  190                     }
  191                     if (t == tSLASH)
  192                         lhs /= rhs;
  193                     else if (t == tPCT)
  194                         lhs %= rhs;
  195                     else
  196                         lhs = roundup(lhs, rhs);
  197             }
  198             t = db_read_token();
  199         }
  200         db_unread_token(t);
  201         *valuep = lhs;
  202         return (true);
  203 }
  204 
  205 static bool
  206 db_add_expr(db_expr_t *valuep)
  207 {
  208         db_expr_t       lhs, rhs;
  209         int             t;
  210 
  211         if (!db_mult_expr(&lhs))
  212             return (false);
  213 
  214         t = db_read_token();
  215         while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
  216             if (!db_mult_expr(&rhs)) {
  217                 db_printf("Expression syntax error after '%c'\n",
  218                     t == tPLUS ? '+' : t == tMINUS ? '-' : '|');
  219                 db_error(NULL);
  220                 /*NOTREACHED*/
  221             }
  222             switch (t) {
  223             case tPLUS:
  224                 lhs += rhs;
  225                 break;
  226             case tMINUS:
  227                 lhs -= rhs;
  228                 break;
  229             case tBIT_OR:
  230                 lhs |= rhs;
  231                 break;
  232             default:
  233                 __assert_unreachable();
  234             }
  235             t = db_read_token();
  236         }
  237         db_unread_token(t);
  238         *valuep = lhs;
  239         return (true);
  240 }
  241 
  242 static bool
  243 db_shift_expr(db_expr_t *valuep)
  244 {
  245         db_expr_t       lhs, rhs;
  246         int             t;
  247 
  248         if (!db_add_expr(&lhs))
  249                 return (false);
  250         t = db_read_token();
  251         while (t == tSHIFT_L || t == tSHIFT_R) {
  252             if (!db_add_expr(&rhs)) {
  253                 db_printf("Expression syntax error after '%s'\n",
  254                     t == tSHIFT_L ? "<<" : ">>");
  255                 db_error(NULL);
  256                 /*NOTREACHED*/
  257             }
  258             if (rhs < 0) {
  259                 db_printf("Negative shift amount %jd\n", (intmax_t)rhs);
  260                 db_error(NULL);
  261                 /*NOTREACHED*/
  262             }
  263             if (t == tSHIFT_L)
  264                 lhs <<= rhs;
  265             else {
  266                 /* Shift right is unsigned */
  267                 lhs = (db_addr_t)lhs >> rhs;
  268             }
  269             t = db_read_token();
  270         }
  271         db_unread_token(t);
  272         *valuep = lhs;
  273         return (true);
  274 }
  275 
  276 static bool
  277 db_logical_relation_expr(
  278         db_expr_t *valuep)
  279 {
  280         db_expr_t       lhs, rhs;
  281         int             t;
  282 
  283         if (!db_shift_expr(&lhs))
  284             return (false);
  285 
  286         t = db_read_token();
  287         while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
  288             t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
  289             if (!db_shift_expr(&rhs)) {
  290                 db_printf("Expression syntax error after '%s'\n",
  291                     t == tLOG_EQ ? "==" : t == tLOG_NOT_EQ ? "!=" :
  292                     t == tGREATER ? ">" : t == tGREATER_EQ ? ">=" :
  293                     t == tLESS ? "<" : "<=");
  294                 db_error(NULL);
  295                 /*NOTREACHED*/
  296             }
  297             switch(t) {
  298                 case tLOG_EQ:
  299                     lhs = (lhs == rhs);
  300                     break;
  301                 case tLOG_NOT_EQ:
  302                     lhs = (lhs != rhs);
  303                     break;
  304                 case tGREATER:
  305                     lhs = (lhs > rhs);
  306                     break;
  307                 case tGREATER_EQ:
  308                     lhs = (lhs >= rhs);
  309                     break;
  310                 case tLESS:
  311                     lhs = (lhs < rhs);
  312                     break;
  313                 case tLESS_EQ:
  314                     lhs = (lhs <= rhs);
  315                     break;
  316                 default:
  317                     __assert_unreachable();
  318             }
  319             t = db_read_token();
  320         }
  321         db_unread_token(t);
  322         *valuep = lhs;
  323         return (true);
  324 }
  325 
  326 static bool
  327 db_logical_and_expr(
  328         db_expr_t *valuep)
  329 {
  330         db_expr_t       lhs, rhs;
  331         int             t;
  332 
  333         if (!db_logical_relation_expr(&lhs))
  334             return (false);
  335 
  336         t = db_read_token();
  337         while (t == tLOG_AND) {
  338             if (!db_logical_relation_expr(&rhs)) {
  339                 db_printf("Expression syntax error after '%s'\n", "&&");
  340                 db_error(NULL);
  341                 /*NOTREACHED*/
  342             }
  343             lhs = (lhs && rhs);
  344             t = db_read_token();
  345         }
  346         db_unread_token(t);
  347         *valuep = lhs;
  348         return (true);
  349 }
  350 
  351 static bool
  352 db_logical_or_expr(
  353         db_expr_t *valuep)
  354 {
  355         db_expr_t       lhs, rhs;
  356         int             t;
  357 
  358         if (!db_logical_and_expr(&lhs))
  359                 return(false);
  360 
  361         t = db_read_token();
  362         while (t == tLOG_OR) {
  363                 if (!db_logical_and_expr(&rhs)) {
  364                         db_printf("Expression syntax error after '%s'\n", "||");
  365                         db_error(NULL);
  366                         /*NOTREACHED*/
  367                 }
  368                 lhs = (lhs || rhs);
  369                 t = db_read_token();
  370         }
  371         db_unread_token(t);
  372         *valuep = lhs;
  373         return (true);
  374 }
  375 
  376 int
  377 db_expression(db_expr_t *valuep)
  378 {
  379         return (db_logical_or_expr(valuep));
  380 }

Cache object: b591df30ddec81af2a4bea319d7a121c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.