Hi all,

I attach a patch for comments (the patch is not final is intended for
comments only, format for one thing is messed ) 
regarding support for !=, ==, <, >, >=, <= , ! , ~, & , | , && , ||
operators in DDB expressions.

The code was mainly pulled from Mach 3.0 kernel with a couple of bug-fixes
 I added them in my copy mainly
because I am interested in crafting conditional breakpoints later. (and
some other DDB usability enhancements).
Please share your opinions. 

Regards!
diff --git ddb/db_expr.c ddb/db_expr.c
index b9aebce..9f69f84 100644
--- ddb/db_expr.c
+++ ddb/db_expr.c
@@ -43,6 +43,9 @@ static boolean_t	db_mult_expr(db_expr_t *valuep);
 static boolean_t	db_shift_expr(db_expr_t *valuep);
 static boolean_t	db_term(db_expr_t *valuep);
 static boolean_t	db_unary(db_expr_t *valuep);
+static boolean_t db_logical_or_expr(db_expr_t *valuep);      
+static boolean_t db_logical_and_expr(db_expr_t *valuep);
+static boolean_t db_logical_relation_expr(db_expr_t *valuep);
 
 static boolean_t
 db_term(db_expr_t *valuep)
@@ -54,8 +57,8 @@ db_term(db_expr_t *valuep)
 	    if (!db_value_of_name(db_tok_string, valuep) &&
 		!db_value_of_name_pcpu(db_tok_string, valuep) &&
 		!db_value_of_name_vnet(db_tok_string, valuep)) {
-		db_error("Symbol not found\n");
-		/*NOTREACHED*/
+            db_error("Symbol not found\n");
+            /*NOTREACHED*/
 	    }
 	    return (TRUE);
 	}
@@ -81,18 +84,18 @@ db_term(db_expr_t *valuep)
 	}
 	if (t == tDOLLAR) {
 	    if (!db_get_variable(valuep))
-		return (FALSE);
+            return (FALSE);
 	    return (TRUE);
 	}
 	if (t == tLPAREN) {
 	    if (!db_expression(valuep)) {
-		db_error("Syntax error\n");
-		/*NOTREACHED*/
+            db_error("Unmatched ()s\n");
+            /*NOTREACHED*/
 	    }
 	    t = db_read_token();
 	    if (t != tRPAREN) {
-		db_error("Syntax error\n");
-		/*NOTREACHED*/
+            db_error("Syntax error\n");
+            /*NOTREACHED*/
 	    }
 	    return (TRUE);
 	}
@@ -108,19 +111,35 @@ db_unary(db_expr_t *valuep)
 	t = db_read_token();
 	if (t == tMINUS) {
 	    if (!db_unary(valuep)) {
-		db_error("Syntax error\n");
-		/*NOTREACHED*/
+            db_error("Expression syntax error after '-'\n");
+            /*NOTREACHED*/
 	    }
 	    *valuep = -*valuep;
 	    return (TRUE);
 	}
+	if ( t == tEXCL) {
+	    if(!db_unary(valuep)) {
+	        db_error("Expression syntax error after '!'\n");
+	        /* NOTREACHED  */
+        }
+        *valuep = (!(*valuep));
+        return (TRUE);
+    }
+    if (t == tBIT_NOT) {
+        if(!db_unary(valuep)) {
+            db_error("Expression syntax error after '~'\n");
+            /* NOTREACHED */
+        }
+        *valuep = (~(*valuep));
+        return (TRUE);
+    }
 	if (t == tSTAR) {
 	    /* indirection */
 	    if (!db_unary(valuep)) {
-		db_error("Syntax error\n");
+            db_error("Expression syntax error after '*'\n");
 		/*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,14 +156,20 @@ 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");
-		/*NOTREACHED*/
+            db_error("Syntax error\n");
+            /*NOTREACHED*/
 	    }
-	    if (t == tSTAR)
-		lhs *= rhs;
-	    else {
+	    switch(t)  {
+        case tSTAR:
+            lhs *= rhs;
+            break;
+        case tBIT_AND:
+            lhs &= rhs;
+            break;
+        default:
 		if (rhs == 0) {
 		    db_error("Divide by 0\n");
 		    /*NOTREACHED*/
@@ -168,20 +193,25 @@ 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");
-		/*NOTREACHED*/
+	        c = db_tok_string[0];
+            db_printf("Expression syntax error after '%c'\n",c);
+            db_error(NULL);
+            /*NOTREACHED*/
 	    }
 	    if (t == tPLUS)
-		lhs += rhs;
-	    else
-		lhs -= rhs;
+            lhs += rhs;
+	    else if (t == tMINUS)
+            lhs -= rhs;
+        else 
+            lhs |= rhs;
 	    t = db_read_token();
 	}
 	db_unread_token(t);
@@ -201,18 +231,18 @@ db_shift_expr(db_expr_t *valuep)
 	t = db_read_token();
 	while (t == tSHIFT_L || t == tSHIFT_R) {
 	    if (!db_add_expr(&rhs)) {
-		db_error("Syntax error\n");
-		/*NOTREACHED*/
+            db_error("Syntax error\n");
+            /*NOTREACHED*/
 	    }
 	    if (rhs < 0) {
-		db_error("Negative shift amount\n");
-		/*NOTREACHED*/
+            db_error("Negative shift amount\n");
+            /*NOTREACHED*/
 	    }
 	    if (t == tSHIFT_L)
-		lhs <<= rhs;
+            lhs <<= rhs;
 	    else {
-		/* Shift right is unsigned */
-		lhs = (unsigned) lhs >> rhs;
+            /* Shift right is unsigned */
+            lhs = (unsigned) lhs >> rhs;
 	    }
 	    t = db_read_token();
 	}
@@ -221,8 +251,105 @@ db_shift_expr(db_expr_t *valuep)
 	return (TRUE);
 }
 
+boolean_t
+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(0);
+                /*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;
+	    }
+            t = db_read_token();
+	}
+	db_unread_token(t);
+	*valuep = lhs;
+	return TRUE;
+}
+
+boolean_t
+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_error("Expression syntax error after \"&&\"\n");
+            /*NOTREACHED*/
+	    }
+	    lhs = (lhs && rhs);
+	    t = db_read_token();
+	}
+	db_unread_token(t);
+	*valuep = lhs;
+	return TRUE;
+}
+
+boolean_t
+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_error("Expression syntax error after \"||\"\n");
+            /*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));
 }
diff --git ddb/db_input.c ddb/db_input.c
index 7c35f91..03ea339 100644
--- ddb/db_input.c
+++ ddb/db_input.c
@@ -372,3 +372,4 @@ db_check_interrupt()
 		break;
 	}
 }
+
diff --git ddb/db_lex.c ddb/db_lex.c
index 54b5295..8ef8c54 100644
--- ddb/db_lex.c
+++ ddb/db_lex.c
@@ -260,51 +260,81 @@ db_lex()
 
 	switch (c) {
 	    case '+':
-		return (tPLUS);
+            return (tPLUS);
 	    case '-':
-		return (tMINUS);
+            return (tMINUS);
 	    case '.':
 		c = db_read_char();
 		if (c == '.')
 		    return (tDOTDOT);
 		db_unread_char(c);
-		return (tDOT);
+            return (tDOT);
 	    case '*':
-		return (tSTAR);
+            return (tSTAR);
 	    case '/':
-		return (tSLASH);
+            return (tSLASH);
 	    case '=':
-		return (tEQ);
+	        c = db_read_char();
+	        if (c == '=') {
+	            return (tLOG_EQ);
+            }
+            db_unread_char(c);
+	    	return (tEQ);
 	    case '%':
-		return (tPCT);
+		    return (tPCT);
 	    case '#':
-		return (tHASH);
+            return (tHASH);
 	    case '(':
-		return (tLPAREN);
+            return (tLPAREN);
 	    case ')':
-		return (tRPAREN);
+            return (tRPAREN);
 	    case ',':
-		return (tCOMMA);
+            return (tCOMMA);
 	    case '"':
-		return (tDITTO);
+            return (tDITTO);
 	    case '$':
-		return (tDOLLAR);
+            return (tDOLLAR);
 	    case '!':
-		return (tEXCL);
+	        c = db_read_char();
+	        if (c == '='){
+	                return (tLOG_NOT_EQ);
+            }
+            db_unread_char(c);
+            return (tEXCL);
 	    case ';':
-		return (tSEMI);
+            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);
-		db_unread_char(c);
-		break;
+            c = db_read_char();
+            if (c == '<')
+                return (tSHIFT_L);
+            if (c == '=') 
+                return (tLESS_EQ);
+            db_unread_char(c);
+            return (tLESS);
 	    case '>':
-		c = db_read_char();
-		if (c == '>')
-		    return (tSHIFT_R);
-		db_unread_char(c);
-		break;
+            c = db_read_char();
+            if (c == '>')
+                return (tSHIFT_R);
+            if (c == '=')
+                return (tGREATER_EQ);
+            db_unread_char(c);
+            return (tGREATER);
+        case '?':
+            return (tQUESTION);
+        case '~':
+            return (tBIT_NOT);
 	    case -1:
 		return (tEOF);
 	}
diff --git ddb/db_lex.h ddb/db_lex.h
index 0c526cd..1c6ff28 100644
--- ddb/db_lex.h
+++ ddb/db_lex.h
@@ -69,5 +69,19 @@ extern char	db_tok_string[TOK_STRING_SIZE];
 #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_ */
+
diff --git ddb/ddb.h ddb/ddb.h
index f5afcd9..f69387c 100644
--- ddb/ddb.h
+++ ddb/ddb.h
@@ -187,7 +187,7 @@ void		db_clear_watchpoints(void);
 db_addr_t	db_disasm(db_addr_t loc, boolean_t altfmt);
 				/* instruction disassembler */
 void		db_error(const char *s);
-int		db_expression(db_expr_t *valuep);
+int         db_expression(db_expr_t *valuep);
 int		db_get_variable(db_expr_t *valuep);
 void		db_iprintf(const char *,...) __printflike(1, 2);
 struct proc	*db_lookup_proc(db_expr_t addr);
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to