Author: pfg
Date: Mon May 16 19:42:38 2016
New Revision: 299970
URL: https://svnweb.freebsd.org/changeset/base/299970

Log:
  Add a small set of logical operators to DDB command language.
  
  This are based on Mach3.
  Documentation is pending but has been promised.
  
  Submitted by: Dan Partelly
  Reviewed by:  adrian, jhb (older version)
  
  Differential Revision:        https://reviews.freebsd.org/D4230
  RelNotes:     yes

Modified:
  head/sys/ddb/db_examine.c
  head/sys/ddb/db_expr.c
  head/sys/ddb/db_lex.c
  head/sys/ddb/db_lex.h

Modified: head/sys/ddb/db_examine.c
==============================================================================
--- head/sys/ddb/db_examine.c   Mon May 16 19:39:05 2016        (r299969)
+++ head/sys/ddb/db_examine.c   Mon May 16 19:42:38 2016        (r299970)
@@ -225,6 +225,10 @@ db_print_cmd(db_expr_t addr, bool have_a
                else
                    db_printf("\\%03o", (int)value);
                break;
+           default:
+               db_print_format = 'x';
+               db_error("Syntax error: unsupported print modifier\n");
+               /*NOTREACHED*/
        }
        db_printf("\n");
 }

Modified: head/sys/ddb/db_expr.c
==============================================================================
--- head/sys/ddb/db_expr.c      Mon May 16 19:39:05 2016        (r299969)
+++ head/sys/ddb/db_expr.c      Mon May 16 19:42:38 2016        (r299970)
@@ -43,6 +43,9 @@ static bool   db_mult_expr(db_expr_t *valu
 static bool    db_shift_expr(db_expr_t *valuep);
 static bool    db_term(db_expr_t *valuep);
 static bool    db_unary(db_expr_t *valuep);
+static bool    db_logical_or_expr(db_expr_t *valuep);
+static bool    db_logical_and_expr(db_expr_t *valuep);
+static bool    db_logical_relation_expr(db_expr_t *valuep);
 
 static bool
 db_term(db_expr_t *valuep)
@@ -108,19 +111,40 @@ db_unary(db_expr_t *valuep)
        t = db_read_token();
        if (t == tMINUS) {
            if (!db_unary(valuep)) {
-               db_error("Syntax error\n");
+               db_printf("Expression syntax error after '%c'\n", '-');
+               db_error(NULL);
                /*NOTREACHED*/
            }
            *valuep = -*valuep;
            return (true);
        }
+       if (t == tEXCL) {
+           if(!db_unary(valuep)) {
+               db_printf("Expression syntax error after '%c'\n", '!');
+               db_error(NULL);
+               /* NOTREACHED  */
+           }
+           *valuep = (!(*valuep));
+           return (true);
+       }
+       if (t == tBIT_NOT) {
+           if(!db_unary(valuep)) {
+               db_printf("Expression syntax error after '%c'\n", '~');
+               db_error(NULL);
+               /* NOTREACHED */
+           }
+           *valuep = (~(*valuep));
+           return (true);
+       }
        if (t == tSTAR) {
            /* indirection */
            if (!db_unary(valuep)) {
-               db_error("Syntax error\n");
+               db_printf("Expression syntax error after '%c'\n", '*');
+               db_error(NULL);
                /*NOTREACHED*/
            }
-           *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *), false);
+           *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
+               false);
            return (true);
        }
        db_unread_token(t);
@@ -137,24 +161,31 @@ db_mult_expr(db_expr_t *valuep)
            return (false);
 
        t = db_read_token();
-       while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
+       while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
+           t == tBIT_AND ) {
            if (!db_term(&rhs)) {
-               db_error("Syntax error\n");
+               db_printf("Expression syntax error after '%c'\n", '!');
+               db_error(NULL);
                /*NOTREACHED*/
            }
-           if (t == tSTAR)
-               lhs *= rhs;
-           else {
-               if (rhs == 0) {
-                   db_error("Divide by 0\n");
-                   /*NOTREACHED*/
-               }
-               if (t == tSLASH)
-                   lhs /= rhs;
-               else if (t == tPCT)
-                   lhs %= rhs;
-               else
-                   lhs = roundup(lhs, rhs);
+           switch(t)  {
+               case tSTAR:
+                   lhs *= rhs;
+                   break;
+               case tBIT_AND:
+                   lhs &= rhs;
+                   break;
+               default:
+                   if (rhs == 0) {
+                       db_error("Divide by 0\n");
+                       /*NOTREACHED*/
+                   }
+                   if (t == tSLASH)
+                       lhs /= rhs;
+                   else if (t == tPCT)
+                       lhs %= rhs;
+                   else
+                       lhs = roundup(lhs, rhs);
            }
            t = db_read_token();
        }
@@ -168,20 +199,32 @@ db_add_expr(db_expr_t *valuep)
 {
        db_expr_t       lhs, rhs;
        int             t;
+       char            c;
 
        if (!db_mult_expr(&lhs))
            return (false);
 
        t = db_read_token();
-       while (t == tPLUS || t == tMINUS) {
+       while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
            if (!db_mult_expr(&rhs)) {
-               db_error("Syntax error\n");
+               c = db_tok_string[0];
+               db_printf("Expression syntax error after '%c'\n", c);
+               db_error(NULL);
                /*NOTREACHED*/
            }
-           if (t == tPLUS)
+           switch (t) {
+           case tPLUS:
                lhs += rhs;
-           else
+               break;
+           case tMINUS:
                lhs -= rhs;
+               break;
+           case tBIT_OR:
+               lhs |= rhs;
+               break;
+           default:
+               __unreachable();
+           }
            t = db_read_token();
        }
        db_unread_token(t);
@@ -196,8 +239,7 @@ db_shift_expr(db_expr_t *valuep)
        int             t;
 
        if (!db_add_expr(&lhs))
-           return (false);
-
+               return (false);
        t = db_read_token();
        while (t == tSHIFT_L || t == tSHIFT_R) {
            if (!db_add_expr(&rhs)) {
@@ -221,8 +263,109 @@ db_shift_expr(db_expr_t *valuep)
        return (true);
 }
 
+static bool
+db_logical_relation_expr(
+       db_expr_t *valuep)
+{
+       db_expr_t       lhs, rhs;
+       int             t;
+       char            op[3];
+
+       if (!db_shift_expr(&lhs))
+           return (false);
+
+       t = db_read_token();
+       while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
+           t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
+           op[0] = db_tok_string[0];
+           op[1] = db_tok_string[1];
+           op[2] = 0;
+           if (!db_shift_expr(&rhs)) {
+               db_printf("Expression syntax error after \"%s\"\n", op);
+               db_error(NULL);
+               /*NOTREACHED*/
+           }
+           switch(t) {
+               case tLOG_EQ:
+                   lhs = (lhs == rhs);
+                   break;
+               case tLOG_NOT_EQ:
+                   lhs = (lhs != rhs);
+                   break;
+               case tGREATER:
+                   lhs = (lhs > rhs);
+                   break;
+               case tGREATER_EQ:
+                   lhs = (lhs >= rhs);
+                   break;
+               case tLESS:
+                   lhs = (lhs < rhs);
+                   break;
+               case tLESS_EQ:
+                   lhs = (lhs <= rhs);
+                   break;
+               default:
+                   __unreachable();
+           }
+           t = db_read_token();
+       }
+       db_unread_token(t);
+       *valuep = lhs;
+       return (true);
+}
+
+static bool
+db_logical_and_expr(
+       db_expr_t *valuep)
+{
+       db_expr_t       lhs, rhs;
+       int             t;
+
+       if (!db_logical_relation_expr(&lhs))
+           return (false);
+
+       t = db_read_token();
+       while (t == tLOG_AND) {
+           if (!db_logical_relation_expr(&rhs)) {
+               db_printf("Expression syntax error after '%s'\n", "&&");
+               db_error(NULL);
+               /*NOTREACHED*/
+           }
+           lhs = (lhs && rhs);
+           t = db_read_token();
+       }
+       db_unread_token(t);
+       *valuep = lhs;
+       return (true);
+}
+
+static bool
+db_logical_or_expr(
+       db_expr_t *valuep)
+{
+       db_expr_t       lhs, rhs;
+       int             t;
+
+       if (!db_logical_and_expr(&lhs))
+               return(false);
+
+       t = db_read_token();
+       while (t == tLOG_OR) {
+               if (!db_logical_and_expr(&rhs)) {
+                       db_printf("Expression syntax error after '%s'\n", "||");
+                       db_error(NULL);
+                       /*NOTREACHED*/
+               }
+               lhs = (lhs || rhs);
+               t = db_read_token();
+       }
+       db_unread_token(t);
+       *valuep = lhs;
+       return (true);
+}
+
 int
 db_expression(db_expr_t *valuep)
 {
-       return (db_shift_expr(valuep));
+       return (db_logical_or_expr(valuep));
 }

Modified: head/sys/ddb/db_lex.c
==============================================================================
--- head/sys/ddb/db_lex.c       Mon May 16 19:39:05 2016        (r299969)
+++ head/sys/ddb/db_lex.c       Mon May 16 19:42:38 2016        (r299970)
@@ -274,6 +274,10 @@ db_lex(void)
            case '/':
                return (tSLASH);
            case '=':
+               c = db_read_char();
+               if (c == '=')
+                   return (tLOG_EQ);
+               db_unread_char(c);
                return (tEQ);
            case '%':
                return (tPCT);
@@ -290,21 +294,46 @@ db_lex(void)
            case '$':
                return (tDOLLAR);
            case '!':
+               c = db_read_char();
+               if (c == '='){
+                       return (tLOG_NOT_EQ);
+               }
+               db_unread_char(c);
                return (tEXCL);
            case ';':
                return (tSEMI);
+           case '&':
+               c = db_read_char();
+               if (c == '&')
+                   return (tLOG_AND);
+               db_unread_char(c);
+               return (tBIT_AND);
+           case '|':
+               c = db_read_char();
+               if (c == '|')
+                   return (tLOG_OR);
+               db_unread_char(c);
+               return (tBIT_OR);
            case '<':
                c = db_read_char();
                if (c == '<')
                    return (tSHIFT_L);
+               if (c == '=') 
+                   return (tLESS_EQ);
                db_unread_char(c);
-               break;
+               return (tLESS);
            case '>':
                c = db_read_char();
                if (c == '>')
                    return (tSHIFT_R);
+               if (c == '=')
+                   return (tGREATER_EQ);
                db_unread_char(c);
-               break;
+               return (tGREATER);
+           case '?':
+               return (tQUESTION);
+           case '~':
+               return (tBIT_NOT);
            case -1:
                return (tEOF);
        }

Modified: head/sys/ddb/db_lex.h
==============================================================================
--- head/sys/ddb/db_lex.h       Mon May 16 19:39:05 2016        (r299969)
+++ head/sys/ddb/db_lex.h       Mon May 16 19:42:38 2016        (r299970)
@@ -69,5 +69,18 @@ extern char  db_tok_string[TOK_STRING_SIZ
 #define        tSHIFT_R        19
 #define        tDOTDOT         20
 #define        tSEMI           21
+#define        tLOG_EQ         22
+#define        tLOG_NOT_EQ     23
+#define        tLESS           24
+#define        tLESS_EQ        25
+#define        tGREATER        26
+#define        tGREATER_EQ     27
+#define        tBIT_AND        28
+#define        tBIT_OR         29
+#define        tLOG_AND        30
+#define        tLOG_OR         31
+#define        tSTRING         32
+#define        tQUESTION       33
+#define        tBIT_NOT        34
 
 #endif /* !_DDB_DB_LEX_H_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to