xref: /freebsd/sys/ddb/db_expr.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
1dd3cb568SWarner Losh /*-
2796df753SPedro F. Giffuni  * SPDX-License-Identifier: MIT-CMU
3796df753SPedro F. Giffuni  *
45b81b6b3SRodney W. Grimes  * Mach Operating System
55b81b6b3SRodney W. Grimes  * Copyright (c) 1991,1990 Carnegie Mellon University
65b81b6b3SRodney W. Grimes  * All Rights Reserved.
75b81b6b3SRodney W. Grimes  *
85b81b6b3SRodney W. Grimes  * Permission to use, copy, modify and distribute this software and its
95b81b6b3SRodney W. Grimes  * documentation is hereby granted, provided that both the copyright
105b81b6b3SRodney W. Grimes  * notice and this permission notice appear in all copies of the
115b81b6b3SRodney W. Grimes  * software, derivative works or modified versions, and any portions
125b81b6b3SRodney W. Grimes  * thereof, and that both notices appear in supporting documentation.
135b81b6b3SRodney W. Grimes  *
145b81b6b3SRodney W. Grimes  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
155b81b6b3SRodney W. Grimes  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
165b81b6b3SRodney W. Grimes  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
175b81b6b3SRodney W. Grimes  *
185b81b6b3SRodney W. Grimes  * Carnegie Mellon requests users of this software to return to
195b81b6b3SRodney W. Grimes  *
205b81b6b3SRodney W. Grimes  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
215b81b6b3SRodney W. Grimes  *  School of Computer Science
225b81b6b3SRodney W. Grimes  *  Carnegie Mellon University
235b81b6b3SRodney W. Grimes  *  Pittsburgh PA 15213-3890
245b81b6b3SRodney W. Grimes  *
255b81b6b3SRodney W. Grimes  * any improvements or extensions that they make and grant Carnegie the
265b81b6b3SRodney W. Grimes  * rights to redistribute these changes.
275b81b6b3SRodney W. Grimes  */
285b81b6b3SRodney W. Grimes /*
295b81b6b3SRodney W. Grimes  *	Author: David B. Golub, Carnegie Mellon University
305b81b6b3SRodney W. Grimes  *	Date:	7/90
315b81b6b3SRodney W. Grimes  */
32753960f7SDavid E. O'Brien 
33f540b106SGarrett Wollman #include <sys/param.h>
34*c79cee71SKyle Evans #include <sys/systm.h>
355ccbc3ccSBruce Evans 
36f540b106SGarrett Wollman #include <ddb/ddb.h>
375b81b6b3SRodney W. Grimes #include <ddb/db_lex.h>
385b81b6b3SRodney W. Grimes #include <ddb/db_access.h>
395b81b6b3SRodney W. Grimes #include <ddb/db_command.h>
405b81b6b3SRodney W. Grimes 
41cd508278SPedro F. Giffuni static bool	db_add_expr(db_expr_t *valuep);
42cd508278SPedro F. Giffuni static bool	db_mult_expr(db_expr_t *valuep);
43cd508278SPedro F. Giffuni static bool	db_shift_expr(db_expr_t *valuep);
44cd508278SPedro F. Giffuni static bool	db_term(db_expr_t *valuep);
45cd508278SPedro F. Giffuni static bool	db_unary(db_expr_t *valuep);
46c69cee69SPedro F. Giffuni static bool	db_logical_or_expr(db_expr_t *valuep);
47c69cee69SPedro F. Giffuni static bool	db_logical_and_expr(db_expr_t *valuep);
48c69cee69SPedro F. Giffuni static bool	db_logical_relation_expr(db_expr_t *valuep);
49058284fcSBruce Evans 
50cd508278SPedro F. Giffuni static bool
db_term(db_expr_t * valuep)5119b79af1SWarner Losh db_term(db_expr_t *valuep)
525b81b6b3SRodney W. Grimes {
535b81b6b3SRodney W. Grimes 	int	t;
545b81b6b3SRodney W. Grimes 
555b81b6b3SRodney W. Grimes 	t = db_read_token();
565b81b6b3SRodney W. Grimes 	if (t == tIDENT) {
57eddfbb76SRobert Watson 	    if (!db_value_of_name(db_tok_string, valuep) &&
58eddfbb76SRobert Watson 		!db_value_of_name_pcpu(db_tok_string, valuep) &&
59eddfbb76SRobert Watson 		!db_value_of_name_vnet(db_tok_string, valuep)) {
6027a465b0SBruce Evans 		db_printf("Symbol '%s' not found\n", db_tok_string);
6127a465b0SBruce Evans 		db_error(NULL);
625b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
635b81b6b3SRodney W. Grimes 	    }
642b490bc7SPedro F. Giffuni 	    return (true);
655b81b6b3SRodney W. Grimes 	}
665b81b6b3SRodney W. Grimes 	if (t == tNUMBER) {
675b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_tok_number;
682b490bc7SPedro F. Giffuni 	    return (true);
695b81b6b3SRodney W. Grimes 	}
705b81b6b3SRodney W. Grimes 	if (t == tDOT) {
715b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_dot;
722b490bc7SPedro F. Giffuni 	    return (true);
735b81b6b3SRodney W. Grimes 	}
745b81b6b3SRodney W. Grimes 	if (t == tDOTDOT) {
755b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_prev;
762b490bc7SPedro F. Giffuni 	    return (true);
775b81b6b3SRodney W. Grimes 	}
785b81b6b3SRodney W. Grimes 	if (t == tPLUS) {
795b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t) db_next;
802b490bc7SPedro F. Giffuni 	    return (true);
815b81b6b3SRodney W. Grimes 	}
825b81b6b3SRodney W. Grimes 	if (t == tDITTO) {
835b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_last_addr;
842b490bc7SPedro F. Giffuni 	    return (true);
855b81b6b3SRodney W. Grimes 	}
865b81b6b3SRodney W. Grimes 	if (t == tDOLLAR) {
875b81b6b3SRodney W. Grimes 	    if (!db_get_variable(valuep))
882b490bc7SPedro F. Giffuni 		return (false);
892b490bc7SPedro F. Giffuni 	    return (true);
905b81b6b3SRodney W. Grimes 	}
915b81b6b3SRodney W. Grimes 	if (t == tLPAREN) {
925b81b6b3SRodney W. Grimes 	    if (!db_expression(valuep)) {
9327a465b0SBruce Evans 		db_printf("Expression syntax error after '%c'\n", '(');
9427a465b0SBruce Evans 		db_error(NULL);
955b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
965b81b6b3SRodney W. Grimes 	    }
975b81b6b3SRodney W. Grimes 	    t = db_read_token();
985b81b6b3SRodney W. Grimes 	    if (t != tRPAREN) {
9927a465b0SBruce Evans 		db_printf("Expression syntax error -- expected '%c'\n", ')');
10027a465b0SBruce Evans 		db_error(NULL);
1015b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1025b81b6b3SRodney W. Grimes 	    }
1032b490bc7SPedro F. Giffuni 	    return (true);
1045b81b6b3SRodney W. Grimes 	}
1055b81b6b3SRodney W. Grimes 	db_unread_token(t);
1062b490bc7SPedro F. Giffuni 	return (false);
1075b81b6b3SRodney W. Grimes }
1085b81b6b3SRodney W. Grimes 
109cd508278SPedro F. Giffuni static bool
db_unary(db_expr_t * valuep)11019b79af1SWarner Losh db_unary(db_expr_t *valuep)
1115b81b6b3SRodney W. Grimes {
1125b81b6b3SRodney W. Grimes 	int	t;
1135b81b6b3SRodney W. Grimes 
1145b81b6b3SRodney W. Grimes 	t = db_read_token();
1155b81b6b3SRodney W. Grimes 	if (t == tMINUS) {
1165b81b6b3SRodney W. Grimes 	    if (!db_unary(valuep)) {
117c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '-');
118c69cee69SPedro F. Giffuni 		db_error(NULL);
1195b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1205b81b6b3SRodney W. Grimes 	    }
1215b81b6b3SRodney W. Grimes 	    *valuep = -*valuep;
1222b490bc7SPedro F. Giffuni 	    return (true);
1235b81b6b3SRodney W. Grimes 	}
124c69cee69SPedro F. Giffuni 	if (t == tEXCL) {
125c69cee69SPedro F. Giffuni 	    if (!db_unary(valuep)) {
126c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '!');
127c69cee69SPedro F. Giffuni 		db_error(NULL);
128c69cee69SPedro F. Giffuni 		/* NOTREACHED  */
129c69cee69SPedro F. Giffuni 	    }
130c69cee69SPedro F. Giffuni 	    *valuep = (!(*valuep));
131c69cee69SPedro F. Giffuni 	    return (true);
132c69cee69SPedro F. Giffuni 	}
133c69cee69SPedro F. Giffuni 	if (t == tBIT_NOT) {
134c69cee69SPedro F. Giffuni 	    if (!db_unary(valuep)) {
135c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '~');
136c69cee69SPedro F. Giffuni 		db_error(NULL);
137c69cee69SPedro F. Giffuni 		/* NOTREACHED */
138c69cee69SPedro F. Giffuni 	    }
139c69cee69SPedro F. Giffuni 	    *valuep = (~(*valuep));
140c69cee69SPedro F. Giffuni 	    return (true);
141c69cee69SPedro F. Giffuni 	}
1425b81b6b3SRodney W. Grimes 	if (t == tSTAR) {
1435b81b6b3SRodney W. Grimes 	    /* indirection */
1445b81b6b3SRodney W. Grimes 	    if (!db_unary(valuep)) {
145c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '*');
146c69cee69SPedro F. Giffuni 		db_error(NULL);
1475b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1485b81b6b3SRodney W. Grimes 	    }
149c69cee69SPedro F. Giffuni 	    *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
150c69cee69SPedro F. Giffuni 		false);
1512b490bc7SPedro F. Giffuni 	    return (true);
1525b81b6b3SRodney W. Grimes 	}
1535b81b6b3SRodney W. Grimes 	db_unread_token(t);
1545b81b6b3SRodney W. Grimes 	return (db_term(valuep));
1555b81b6b3SRodney W. Grimes }
1565b81b6b3SRodney W. Grimes 
157cd508278SPedro F. Giffuni static bool
db_mult_expr(db_expr_t * valuep)15819b79af1SWarner Losh db_mult_expr(db_expr_t *valuep)
1595b81b6b3SRodney W. Grimes {
1605b81b6b3SRodney W. Grimes 	db_expr_t	lhs, rhs;
1615b81b6b3SRodney W. Grimes 	int		t;
1625b81b6b3SRodney W. Grimes 
1635b81b6b3SRodney W. Grimes 	if (!db_unary(&lhs))
1642b490bc7SPedro F. Giffuni 	    return (false);
1655b81b6b3SRodney W. Grimes 
1665b81b6b3SRodney W. Grimes 	t = db_read_token();
167c69cee69SPedro F. Giffuni 	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
168c69cee69SPedro F. Giffuni 	    t == tBIT_AND ) {
1695b81b6b3SRodney W. Grimes 	    if (!db_term(&rhs)) {
17027a465b0SBruce Evans 		db_printf("Expression syntax error after '%c'\n",
17127a465b0SBruce Evans 		    t == tSTAR ? '*' : t == tSLASH ? '/' : t == tPCT ? '%' :
17227a465b0SBruce Evans 		    t == tHASH ? '#' : '&');
173c69cee69SPedro F. Giffuni 		db_error(NULL);
1745b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1755b81b6b3SRodney W. Grimes 	    }
176c69cee69SPedro F. Giffuni 	    switch(t)  {
177c69cee69SPedro F. Giffuni 		case tSTAR:
1785b81b6b3SRodney W. Grimes 		    lhs *= rhs;
179c69cee69SPedro F. Giffuni 		    break;
180c69cee69SPedro F. Giffuni 		case tBIT_AND:
181c69cee69SPedro F. Giffuni 		    lhs &= rhs;
182c69cee69SPedro F. Giffuni 		    break;
183c69cee69SPedro F. Giffuni 		default:
1845b81b6b3SRodney W. Grimes 		    if (rhs == 0) {
18527a465b0SBruce Evans 			db_error("Division by 0\n");
1865b81b6b3SRodney W. Grimes 			/*NOTREACHED*/
1875b81b6b3SRodney W. Grimes 		    }
1885b81b6b3SRodney W. Grimes 		    if (t == tSLASH)
1895b81b6b3SRodney W. Grimes 			lhs /= rhs;
1905b81b6b3SRodney W. Grimes 		    else if (t == tPCT)
1915b81b6b3SRodney W. Grimes 			lhs %= rhs;
1925b81b6b3SRodney W. Grimes 		    else
193fc891c19SPedro F. Giffuni 			lhs = roundup(lhs, rhs);
1945b81b6b3SRodney W. Grimes 	    }
1955b81b6b3SRodney W. Grimes 	    t = db_read_token();
1965b81b6b3SRodney W. Grimes 	}
1975b81b6b3SRodney W. Grimes 	db_unread_token(t);
1985b81b6b3SRodney W. Grimes 	*valuep = lhs;
1992b490bc7SPedro F. Giffuni 	return (true);
2005b81b6b3SRodney W. Grimes }
2015b81b6b3SRodney W. Grimes 
202cd508278SPedro F. Giffuni static bool
db_add_expr(db_expr_t * valuep)20319b79af1SWarner Losh db_add_expr(db_expr_t *valuep)
2045b81b6b3SRodney W. Grimes {
2055b81b6b3SRodney W. Grimes 	db_expr_t	lhs, rhs;
2065b81b6b3SRodney W. Grimes 	int		t;
2075b81b6b3SRodney W. Grimes 
2085b81b6b3SRodney W. Grimes 	if (!db_mult_expr(&lhs))
2092b490bc7SPedro F. Giffuni 	    return (false);
2105b81b6b3SRodney W. Grimes 
2115b81b6b3SRodney W. Grimes 	t = db_read_token();
212c69cee69SPedro F. Giffuni 	while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
2135b81b6b3SRodney W. Grimes 	    if (!db_mult_expr(&rhs)) {
21427a465b0SBruce Evans 		db_printf("Expression syntax error after '%c'\n",
21527a465b0SBruce Evans 		    t == tPLUS ? '+' : t == tMINUS ? '-' : '|');
216c69cee69SPedro F. Giffuni 		db_error(NULL);
2175b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
2185b81b6b3SRodney W. Grimes 	    }
219c69cee69SPedro F. Giffuni 	    switch (t) {
220c69cee69SPedro F. Giffuni 	    case tPLUS:
2215b81b6b3SRodney W. Grimes 		lhs += rhs;
222c69cee69SPedro F. Giffuni 		break;
223c69cee69SPedro F. Giffuni 	    case tMINUS:
2245b81b6b3SRodney W. Grimes 		lhs -= rhs;
225c69cee69SPedro F. Giffuni 		break;
226c69cee69SPedro F. Giffuni 	    case tBIT_OR:
227c69cee69SPedro F. Giffuni 		lhs |= rhs;
228c69cee69SPedro F. Giffuni 		break;
229c69cee69SPedro F. Giffuni 	    default:
230*c79cee71SKyle Evans 		__assert_unreachable();
231c69cee69SPedro F. Giffuni 	    }
2325b81b6b3SRodney W. Grimes 	    t = db_read_token();
2335b81b6b3SRodney W. Grimes 	}
2345b81b6b3SRodney W. Grimes 	db_unread_token(t);
2355b81b6b3SRodney W. Grimes 	*valuep = lhs;
2362b490bc7SPedro F. Giffuni 	return (true);
2375b81b6b3SRodney W. Grimes }
2385b81b6b3SRodney W. Grimes 
239cd508278SPedro F. Giffuni static bool
db_shift_expr(db_expr_t * valuep)24019b79af1SWarner Losh db_shift_expr(db_expr_t *valuep)
2415b81b6b3SRodney W. Grimes {
2425b81b6b3SRodney W. Grimes 	db_expr_t	lhs, rhs;
2435b81b6b3SRodney W. Grimes 	int		t;
2445b81b6b3SRodney W. Grimes 
2455b81b6b3SRodney W. Grimes 	if (!db_add_expr(&lhs))
2462b490bc7SPedro F. Giffuni 		return (false);
2475b81b6b3SRodney W. Grimes 	t = db_read_token();
2485b81b6b3SRodney W. Grimes 	while (t == tSHIFT_L || t == tSHIFT_R) {
2495b81b6b3SRodney W. Grimes 	    if (!db_add_expr(&rhs)) {
25027a465b0SBruce Evans 		db_printf("Expression syntax error after '%s'\n",
25127a465b0SBruce Evans 		    t == tSHIFT_L ? "<<" : ">>");
25227a465b0SBruce Evans 		db_error(NULL);
2535b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
2545b81b6b3SRodney W. Grimes 	    }
2555b81b6b3SRodney W. Grimes 	    if (rhs < 0) {
25627a465b0SBruce Evans 		db_printf("Negative shift amount %jd\n", (intmax_t)rhs);
25727a465b0SBruce Evans 		db_error(NULL);
2585b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
2595b81b6b3SRodney W. Grimes 	    }
2605b81b6b3SRodney W. Grimes 	    if (t == tSHIFT_L)
2615b81b6b3SRodney W. Grimes 		lhs <<= rhs;
2625b81b6b3SRodney W. Grimes 	    else {
2635b81b6b3SRodney W. Grimes 		/* Shift right is unsigned */
26482b93348SBruce Evans 		lhs = (db_addr_t)lhs >> rhs;
2655b81b6b3SRodney W. Grimes 	    }
2665b81b6b3SRodney W. Grimes 	    t = db_read_token();
2675b81b6b3SRodney W. Grimes 	}
2685b81b6b3SRodney W. Grimes 	db_unread_token(t);
2695b81b6b3SRodney W. Grimes 	*valuep = lhs;
2702b490bc7SPedro F. Giffuni 	return (true);
2715b81b6b3SRodney W. Grimes }
2725b81b6b3SRodney W. Grimes 
273c69cee69SPedro F. Giffuni static bool
db_logical_relation_expr(db_expr_t * valuep)274c69cee69SPedro F. Giffuni db_logical_relation_expr(
275c69cee69SPedro F. Giffuni 	db_expr_t *valuep)
276c69cee69SPedro F. Giffuni {
277c69cee69SPedro F. Giffuni 	db_expr_t	lhs, rhs;
278c69cee69SPedro F. Giffuni 	int		t;
279c69cee69SPedro F. Giffuni 
280c69cee69SPedro F. Giffuni 	if (!db_shift_expr(&lhs))
281c69cee69SPedro F. Giffuni 	    return (false);
282c69cee69SPedro F. Giffuni 
283c69cee69SPedro F. Giffuni 	t = db_read_token();
284c69cee69SPedro F. Giffuni 	while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
285c69cee69SPedro F. Giffuni 	    t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
286c69cee69SPedro F. Giffuni 	    if (!db_shift_expr(&rhs)) {
28727a465b0SBruce Evans 		db_printf("Expression syntax error after '%s'\n",
28827a465b0SBruce Evans 		    t == tLOG_EQ ? "==" : t == tLOG_NOT_EQ ? "!=" :
28927a465b0SBruce Evans 		    t == tGREATER ? ">" : t == tGREATER_EQ ? ">=" :
29027a465b0SBruce Evans 		    t == tLESS ? "<" : "<=");
291c69cee69SPedro F. Giffuni 		db_error(NULL);
292c69cee69SPedro F. Giffuni 		/*NOTREACHED*/
293c69cee69SPedro F. Giffuni 	    }
294c69cee69SPedro F. Giffuni 	    switch(t) {
295c69cee69SPedro F. Giffuni 		case tLOG_EQ:
296c69cee69SPedro F. Giffuni 		    lhs = (lhs == rhs);
297c69cee69SPedro F. Giffuni 		    break;
298c69cee69SPedro F. Giffuni 		case tLOG_NOT_EQ:
299c69cee69SPedro F. Giffuni 		    lhs = (lhs != rhs);
300c69cee69SPedro F. Giffuni 		    break;
301c69cee69SPedro F. Giffuni 		case tGREATER:
302c69cee69SPedro F. Giffuni 		    lhs = (lhs > rhs);
303c69cee69SPedro F. Giffuni 		    break;
304c69cee69SPedro F. Giffuni 		case tGREATER_EQ:
305c69cee69SPedro F. Giffuni 		    lhs = (lhs >= rhs);
306c69cee69SPedro F. Giffuni 		    break;
307c69cee69SPedro F. Giffuni 		case tLESS:
308c69cee69SPedro F. Giffuni 		    lhs = (lhs < rhs);
309c69cee69SPedro F. Giffuni 		    break;
310c69cee69SPedro F. Giffuni 		case tLESS_EQ:
311c69cee69SPedro F. Giffuni 		    lhs = (lhs <= rhs);
312c69cee69SPedro F. Giffuni 		    break;
313c69cee69SPedro F. Giffuni 		default:
314*c79cee71SKyle Evans 		    __assert_unreachable();
315c69cee69SPedro F. Giffuni 	    }
316c69cee69SPedro F. Giffuni 	    t = db_read_token();
317c69cee69SPedro F. Giffuni 	}
318c69cee69SPedro F. Giffuni 	db_unread_token(t);
319c69cee69SPedro F. Giffuni 	*valuep = lhs;
320c69cee69SPedro F. Giffuni 	return (true);
321c69cee69SPedro F. Giffuni }
322c69cee69SPedro F. Giffuni 
323c69cee69SPedro F. Giffuni static bool
db_logical_and_expr(db_expr_t * valuep)324c69cee69SPedro F. Giffuni db_logical_and_expr(
325c69cee69SPedro F. Giffuni 	db_expr_t *valuep)
326c69cee69SPedro F. Giffuni {
327c69cee69SPedro F. Giffuni 	db_expr_t	lhs, rhs;
328c69cee69SPedro F. Giffuni 	int		t;
329c69cee69SPedro F. Giffuni 
330c69cee69SPedro F. Giffuni 	if (!db_logical_relation_expr(&lhs))
331c69cee69SPedro F. Giffuni 	    return (false);
332c69cee69SPedro F. Giffuni 
333c69cee69SPedro F. Giffuni 	t = db_read_token();
334c69cee69SPedro F. Giffuni 	while (t == tLOG_AND) {
335c69cee69SPedro F. Giffuni 	    if (!db_logical_relation_expr(&rhs)) {
336c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%s'\n", "&&");
337c69cee69SPedro F. Giffuni 		db_error(NULL);
338c69cee69SPedro F. Giffuni 		/*NOTREACHED*/
339c69cee69SPedro F. Giffuni 	    }
340c69cee69SPedro F. Giffuni 	    lhs = (lhs && rhs);
341c69cee69SPedro F. Giffuni 	    t = db_read_token();
342c69cee69SPedro F. Giffuni 	}
343c69cee69SPedro F. Giffuni 	db_unread_token(t);
344c69cee69SPedro F. Giffuni 	*valuep = lhs;
345c69cee69SPedro F. Giffuni 	return (true);
346c69cee69SPedro F. Giffuni }
347c69cee69SPedro F. Giffuni 
348c69cee69SPedro F. Giffuni static bool
db_logical_or_expr(db_expr_t * valuep)349c69cee69SPedro F. Giffuni db_logical_or_expr(
350c69cee69SPedro F. Giffuni 	db_expr_t *valuep)
351c69cee69SPedro F. Giffuni {
352c69cee69SPedro F. Giffuni 	db_expr_t	lhs, rhs;
353c69cee69SPedro F. Giffuni 	int		t;
354c69cee69SPedro F. Giffuni 
355c69cee69SPedro F. Giffuni 	if (!db_logical_and_expr(&lhs))
356c69cee69SPedro F. Giffuni 		return(false);
357c69cee69SPedro F. Giffuni 
358c69cee69SPedro F. Giffuni 	t = db_read_token();
359c69cee69SPedro F. Giffuni 	while (t == tLOG_OR) {
360c69cee69SPedro F. Giffuni 		if (!db_logical_and_expr(&rhs)) {
361c69cee69SPedro F. Giffuni 			db_printf("Expression syntax error after '%s'\n", "||");
362c69cee69SPedro F. Giffuni 			db_error(NULL);
363c69cee69SPedro F. Giffuni 			/*NOTREACHED*/
364c69cee69SPedro F. Giffuni 		}
365c69cee69SPedro F. Giffuni 		lhs = (lhs || rhs);
366c69cee69SPedro F. Giffuni 		t = db_read_token();
367c69cee69SPedro F. Giffuni 	}
368c69cee69SPedro F. Giffuni 	db_unread_token(t);
369c69cee69SPedro F. Giffuni 	*valuep = lhs;
370c69cee69SPedro F. Giffuni 	return (true);
371c69cee69SPedro F. Giffuni }
372c69cee69SPedro F. Giffuni 
3735b81b6b3SRodney W. Grimes int
db_expression(db_expr_t * valuep)37419b79af1SWarner Losh db_expression(db_expr_t *valuep)
3755b81b6b3SRodney W. Grimes {
376c69cee69SPedro F. Giffuni 	return (db_logical_or_expr(valuep));
3775b81b6b3SRodney W. Grimes }
378