diff options
author | pfg <pfg@FreeBSD.org> | 2016-05-16 19:42:38 +0000 |
---|---|---|
committer | pfg <pfg@FreeBSD.org> | 2016-05-16 19:42:38 +0000 |
commit | 4743a67b216c8aba38ca3ae7f25e135225723f06 (patch) | |
tree | 2cb025abdcf68645e5c507928e638d0cba7af4f9 /sys/ddb/db_expr.c | |
parent | 1b15abb8fd6d585adf0aaa204a88a017a2b8e287 (diff) | |
download | FreeBSD-src-4743a67b216c8aba38ca3ae7f25e135225723f06.zip FreeBSD-src-4743a67b216c8aba38ca3ae7f25e135225723f06.tar.gz |
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
Diffstat (limited to 'sys/ddb/db_expr.c')
-rw-r--r-- | sys/ddb/db_expr.c | 193 |
1 files changed, 168 insertions, 25 deletions
diff --git a/sys/ddb/db_expr.c b/sys/ddb/db_expr.c index 8588676..db17f36 100644 --- a/sys/ddb/db_expr.c +++ b/sys/ddb/db_expr.c @@ -43,6 +43,9 @@ static bool db_mult_expr(db_expr_t *valuep); 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)); } |