xref: /freebsd/sys/ddb/db_expr.c (revision c69cee69f9886806e57d9b08337d565b2bdf8298)
1dd3cb568SWarner Losh /*-
25b81b6b3SRodney W. Grimes  * Mach Operating System
35b81b6b3SRodney W. Grimes  * Copyright (c) 1991,1990 Carnegie Mellon University
45b81b6b3SRodney W. Grimes  * All Rights Reserved.
55b81b6b3SRodney W. Grimes  *
65b81b6b3SRodney W. Grimes  * Permission to use, copy, modify and distribute this software and its
75b81b6b3SRodney W. Grimes  * documentation is hereby granted, provided that both the copyright
85b81b6b3SRodney W. Grimes  * notice and this permission notice appear in all copies of the
95b81b6b3SRodney W. Grimes  * software, derivative works or modified versions, and any portions
105b81b6b3SRodney W. Grimes  * thereof, and that both notices appear in supporting documentation.
115b81b6b3SRodney W. Grimes  *
125b81b6b3SRodney W. Grimes  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
135b81b6b3SRodney W. Grimes  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
145b81b6b3SRodney W. Grimes  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
155b81b6b3SRodney W. Grimes  *
165b81b6b3SRodney W. Grimes  * Carnegie Mellon requests users of this software to return to
175b81b6b3SRodney W. Grimes  *
185b81b6b3SRodney W. Grimes  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
195b81b6b3SRodney W. Grimes  *  School of Computer Science
205b81b6b3SRodney W. Grimes  *  Carnegie Mellon University
215b81b6b3SRodney W. Grimes  *  Pittsburgh PA 15213-3890
225b81b6b3SRodney W. Grimes  *
235b81b6b3SRodney W. Grimes  * any improvements or extensions that they make and grant Carnegie the
245b81b6b3SRodney W. Grimes  * rights to redistribute these changes.
255b81b6b3SRodney W. Grimes  */
265b81b6b3SRodney W. Grimes /*
275b81b6b3SRodney W. Grimes  *	Author: David B. Golub, Carnegie Mellon University
285b81b6b3SRodney W. Grimes  *	Date:	7/90
295b81b6b3SRodney W. Grimes  */
30753960f7SDavid E. O'Brien 
31753960f7SDavid E. O'Brien #include <sys/cdefs.h>
32753960f7SDavid E. O'Brien __FBSDID("$FreeBSD$");
33753960f7SDavid E. O'Brien 
34f540b106SGarrett Wollman #include <sys/param.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);
46*c69cee69SPedro F. Giffuni static bool	db_logical_or_expr(db_expr_t *valuep);
47*c69cee69SPedro F. Giffuni static bool	db_logical_and_expr(db_expr_t *valuep);
48*c69cee69SPedro F. Giffuni static bool	db_logical_relation_expr(db_expr_t *valuep);
49058284fcSBruce Evans 
50cd508278SPedro F. Giffuni static bool
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)) {
605b81b6b3SRodney W. Grimes 		db_error("Symbol not found\n");
615b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
625b81b6b3SRodney W. Grimes 	    }
632b490bc7SPedro F. Giffuni 	    return (true);
645b81b6b3SRodney W. Grimes 	}
655b81b6b3SRodney W. Grimes 	if (t == tNUMBER) {
665b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_tok_number;
672b490bc7SPedro F. Giffuni 	    return (true);
685b81b6b3SRodney W. Grimes 	}
695b81b6b3SRodney W. Grimes 	if (t == tDOT) {
705b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_dot;
712b490bc7SPedro F. Giffuni 	    return (true);
725b81b6b3SRodney W. Grimes 	}
735b81b6b3SRodney W. Grimes 	if (t == tDOTDOT) {
745b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_prev;
752b490bc7SPedro F. Giffuni 	    return (true);
765b81b6b3SRodney W. Grimes 	}
775b81b6b3SRodney W. Grimes 	if (t == tPLUS) {
785b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t) db_next;
792b490bc7SPedro F. Giffuni 	    return (true);
805b81b6b3SRodney W. Grimes 	}
815b81b6b3SRodney W. Grimes 	if (t == tDITTO) {
825b81b6b3SRodney W. Grimes 	    *valuep = (db_expr_t)db_last_addr;
832b490bc7SPedro F. Giffuni 	    return (true);
845b81b6b3SRodney W. Grimes 	}
855b81b6b3SRodney W. Grimes 	if (t == tDOLLAR) {
865b81b6b3SRodney W. Grimes 	    if (!db_get_variable(valuep))
872b490bc7SPedro F. Giffuni 		return (false);
882b490bc7SPedro F. Giffuni 	    return (true);
895b81b6b3SRodney W. Grimes 	}
905b81b6b3SRodney W. Grimes 	if (t == tLPAREN) {
915b81b6b3SRodney W. Grimes 	    if (!db_expression(valuep)) {
925b81b6b3SRodney W. Grimes 		db_error("Syntax error\n");
935b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
945b81b6b3SRodney W. Grimes 	    }
955b81b6b3SRodney W. Grimes 	    t = db_read_token();
965b81b6b3SRodney W. Grimes 	    if (t != tRPAREN) {
975b81b6b3SRodney W. Grimes 		db_error("Syntax error\n");
985b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
995b81b6b3SRodney W. Grimes 	    }
1002b490bc7SPedro F. Giffuni 	    return (true);
1015b81b6b3SRodney W. Grimes 	}
1025b81b6b3SRodney W. Grimes 	db_unread_token(t);
1032b490bc7SPedro F. Giffuni 	return (false);
1045b81b6b3SRodney W. Grimes }
1055b81b6b3SRodney W. Grimes 
106cd508278SPedro F. Giffuni static bool
10719b79af1SWarner Losh db_unary(db_expr_t *valuep)
1085b81b6b3SRodney W. Grimes {
1095b81b6b3SRodney W. Grimes 	int	t;
1105b81b6b3SRodney W. Grimes 
1115b81b6b3SRodney W. Grimes 	t = db_read_token();
1125b81b6b3SRodney W. Grimes 	if (t == tMINUS) {
1135b81b6b3SRodney W. Grimes 	    if (!db_unary(valuep)) {
114*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '-');
115*c69cee69SPedro F. Giffuni 		db_error(NULL);
1165b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1175b81b6b3SRodney W. Grimes 	    }
1185b81b6b3SRodney W. Grimes 	    *valuep = -*valuep;
1192b490bc7SPedro F. Giffuni 	    return (true);
1205b81b6b3SRodney W. Grimes 	}
121*c69cee69SPedro F. Giffuni 	if (t == tEXCL) {
122*c69cee69SPedro F. Giffuni 	    if(!db_unary(valuep)) {
123*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '!');
124*c69cee69SPedro F. Giffuni 		db_error(NULL);
125*c69cee69SPedro F. Giffuni 		/* NOTREACHED  */
126*c69cee69SPedro F. Giffuni 	    }
127*c69cee69SPedro F. Giffuni 	    *valuep = (!(*valuep));
128*c69cee69SPedro F. Giffuni 	    return (true);
129*c69cee69SPedro F. Giffuni 	}
130*c69cee69SPedro F. Giffuni 	if (t == tBIT_NOT) {
131*c69cee69SPedro F. Giffuni 	    if(!db_unary(valuep)) {
132*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '~');
133*c69cee69SPedro F. Giffuni 		db_error(NULL);
134*c69cee69SPedro F. Giffuni 		/* NOTREACHED */
135*c69cee69SPedro F. Giffuni 	    }
136*c69cee69SPedro F. Giffuni 	    *valuep = (~(*valuep));
137*c69cee69SPedro F. Giffuni 	    return (true);
138*c69cee69SPedro F. Giffuni 	}
1395b81b6b3SRodney W. Grimes 	if (t == tSTAR) {
1405b81b6b3SRodney W. Grimes 	    /* indirection */
1415b81b6b3SRodney W. Grimes 	    if (!db_unary(valuep)) {
142*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '*');
143*c69cee69SPedro F. Giffuni 		db_error(NULL);
1445b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1455b81b6b3SRodney W. Grimes 	    }
146*c69cee69SPedro F. Giffuni 	    *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
147*c69cee69SPedro F. Giffuni 		false);
1482b490bc7SPedro F. Giffuni 	    return (true);
1495b81b6b3SRodney W. Grimes 	}
1505b81b6b3SRodney W. Grimes 	db_unread_token(t);
1515b81b6b3SRodney W. Grimes 	return (db_term(valuep));
1525b81b6b3SRodney W. Grimes }
1535b81b6b3SRodney W. Grimes 
154cd508278SPedro F. Giffuni static bool
15519b79af1SWarner Losh db_mult_expr(db_expr_t *valuep)
1565b81b6b3SRodney W. Grimes {
1575b81b6b3SRodney W. Grimes 	db_expr_t	lhs, rhs;
1585b81b6b3SRodney W. Grimes 	int		t;
1595b81b6b3SRodney W. Grimes 
1605b81b6b3SRodney W. Grimes 	if (!db_unary(&lhs))
1612b490bc7SPedro F. Giffuni 	    return (false);
1625b81b6b3SRodney W. Grimes 
1635b81b6b3SRodney W. Grimes 	t = db_read_token();
164*c69cee69SPedro F. Giffuni 	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
165*c69cee69SPedro F. Giffuni 	    t == tBIT_AND ) {
1665b81b6b3SRodney W. Grimes 	    if (!db_term(&rhs)) {
167*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", '!');
168*c69cee69SPedro F. Giffuni 		db_error(NULL);
1695b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
1705b81b6b3SRodney W. Grimes 	    }
171*c69cee69SPedro F. Giffuni 	    switch(t)  {
172*c69cee69SPedro F. Giffuni 		case tSTAR:
1735b81b6b3SRodney W. Grimes 		    lhs *= rhs;
174*c69cee69SPedro F. Giffuni 		    break;
175*c69cee69SPedro F. Giffuni 		case tBIT_AND:
176*c69cee69SPedro F. Giffuni 		    lhs &= rhs;
177*c69cee69SPedro F. Giffuni 		    break;
178*c69cee69SPedro F. Giffuni 		default:
1795b81b6b3SRodney W. Grimes 		    if (rhs == 0) {
1805b81b6b3SRodney W. Grimes 			db_error("Divide by 0\n");
1815b81b6b3SRodney W. Grimes 			/*NOTREACHED*/
1825b81b6b3SRodney W. Grimes 		    }
1835b81b6b3SRodney W. Grimes 		    if (t == tSLASH)
1845b81b6b3SRodney W. Grimes 			lhs /= rhs;
1855b81b6b3SRodney W. Grimes 		    else if (t == tPCT)
1865b81b6b3SRodney W. Grimes 			lhs %= rhs;
1875b81b6b3SRodney W. Grimes 		    else
188fc891c19SPedro F. Giffuni 			lhs = roundup(lhs, rhs);
1895b81b6b3SRodney W. Grimes 	    }
1905b81b6b3SRodney W. Grimes 	    t = db_read_token();
1915b81b6b3SRodney W. Grimes 	}
1925b81b6b3SRodney W. Grimes 	db_unread_token(t);
1935b81b6b3SRodney W. Grimes 	*valuep = lhs;
1942b490bc7SPedro F. Giffuni 	return (true);
1955b81b6b3SRodney W. Grimes }
1965b81b6b3SRodney W. Grimes 
197cd508278SPedro F. Giffuni static bool
19819b79af1SWarner Losh db_add_expr(db_expr_t *valuep)
1995b81b6b3SRodney W. Grimes {
2005b81b6b3SRodney W. Grimes 	db_expr_t	lhs, rhs;
2015b81b6b3SRodney W. Grimes 	int		t;
202*c69cee69SPedro F. Giffuni 	char		c;
2035b81b6b3SRodney W. Grimes 
2045b81b6b3SRodney W. Grimes 	if (!db_mult_expr(&lhs))
2052b490bc7SPedro F. Giffuni 	    return (false);
2065b81b6b3SRodney W. Grimes 
2075b81b6b3SRodney W. Grimes 	t = db_read_token();
208*c69cee69SPedro F. Giffuni 	while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
2095b81b6b3SRodney W. Grimes 	    if (!db_mult_expr(&rhs)) {
210*c69cee69SPedro F. Giffuni 		c = db_tok_string[0];
211*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%c'\n", c);
212*c69cee69SPedro F. Giffuni 		db_error(NULL);
2135b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
2145b81b6b3SRodney W. Grimes 	    }
215*c69cee69SPedro F. Giffuni 	    switch (t) {
216*c69cee69SPedro F. Giffuni 	    case tPLUS:
2175b81b6b3SRodney W. Grimes 		lhs += rhs;
218*c69cee69SPedro F. Giffuni 		break;
219*c69cee69SPedro F. Giffuni 	    case tMINUS:
2205b81b6b3SRodney W. Grimes 		lhs -= rhs;
221*c69cee69SPedro F. Giffuni 		break;
222*c69cee69SPedro F. Giffuni 	    case tBIT_OR:
223*c69cee69SPedro F. Giffuni 		lhs |= rhs;
224*c69cee69SPedro F. Giffuni 		break;
225*c69cee69SPedro F. Giffuni 	    default:
226*c69cee69SPedro F. Giffuni 		__unreachable();
227*c69cee69SPedro F. Giffuni 	    }
2285b81b6b3SRodney W. Grimes 	    t = db_read_token();
2295b81b6b3SRodney W. Grimes 	}
2305b81b6b3SRodney W. Grimes 	db_unread_token(t);
2315b81b6b3SRodney W. Grimes 	*valuep = lhs;
2322b490bc7SPedro F. Giffuni 	return (true);
2335b81b6b3SRodney W. Grimes }
2345b81b6b3SRodney W. Grimes 
235cd508278SPedro F. Giffuni static bool
23619b79af1SWarner Losh db_shift_expr(db_expr_t *valuep)
2375b81b6b3SRodney W. Grimes {
2385b81b6b3SRodney W. Grimes 	db_expr_t	lhs, rhs;
2395b81b6b3SRodney W. Grimes 	int		t;
2405b81b6b3SRodney W. Grimes 
2415b81b6b3SRodney W. Grimes 	if (!db_add_expr(&lhs))
2422b490bc7SPedro F. Giffuni 		return (false);
2435b81b6b3SRodney W. Grimes 	t = db_read_token();
2445b81b6b3SRodney W. Grimes 	while (t == tSHIFT_L || t == tSHIFT_R) {
2455b81b6b3SRodney W. Grimes 	    if (!db_add_expr(&rhs)) {
2465b81b6b3SRodney W. Grimes 		db_error("Syntax error\n");
2475b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
2485b81b6b3SRodney W. Grimes 	    }
2495b81b6b3SRodney W. Grimes 	    if (rhs < 0) {
2505b81b6b3SRodney W. Grimes 		db_error("Negative shift amount\n");
2515b81b6b3SRodney W. Grimes 		/*NOTREACHED*/
2525b81b6b3SRodney W. Grimes 	    }
2535b81b6b3SRodney W. Grimes 	    if (t == tSHIFT_L)
2545b81b6b3SRodney W. Grimes 		lhs <<= rhs;
2555b81b6b3SRodney W. Grimes 	    else {
2565b81b6b3SRodney W. Grimes 		/* Shift right is unsigned */
2575b81b6b3SRodney W. Grimes 		lhs = (unsigned) lhs >> rhs;
2585b81b6b3SRodney W. Grimes 	    }
2595b81b6b3SRodney W. Grimes 	    t = db_read_token();
2605b81b6b3SRodney W. Grimes 	}
2615b81b6b3SRodney W. Grimes 	db_unread_token(t);
2625b81b6b3SRodney W. Grimes 	*valuep = lhs;
2632b490bc7SPedro F. Giffuni 	return (true);
2645b81b6b3SRodney W. Grimes }
2655b81b6b3SRodney W. Grimes 
266*c69cee69SPedro F. Giffuni static bool
267*c69cee69SPedro F. Giffuni db_logical_relation_expr(
268*c69cee69SPedro F. Giffuni 	db_expr_t *valuep)
269*c69cee69SPedro F. Giffuni {
270*c69cee69SPedro F. Giffuni 	db_expr_t	lhs, rhs;
271*c69cee69SPedro F. Giffuni 	int		t;
272*c69cee69SPedro F. Giffuni 	char		op[3];
273*c69cee69SPedro F. Giffuni 
274*c69cee69SPedro F. Giffuni 	if (!db_shift_expr(&lhs))
275*c69cee69SPedro F. Giffuni 	    return (false);
276*c69cee69SPedro F. Giffuni 
277*c69cee69SPedro F. Giffuni 	t = db_read_token();
278*c69cee69SPedro F. Giffuni 	while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
279*c69cee69SPedro F. Giffuni 	    t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
280*c69cee69SPedro F. Giffuni 	    op[0] = db_tok_string[0];
281*c69cee69SPedro F. Giffuni 	    op[1] = db_tok_string[1];
282*c69cee69SPedro F. Giffuni 	    op[2] = 0;
283*c69cee69SPedro F. Giffuni 	    if (!db_shift_expr(&rhs)) {
284*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after \"%s\"\n", op);
285*c69cee69SPedro F. Giffuni 		db_error(NULL);
286*c69cee69SPedro F. Giffuni 		/*NOTREACHED*/
287*c69cee69SPedro F. Giffuni 	    }
288*c69cee69SPedro F. Giffuni 	    switch(t) {
289*c69cee69SPedro F. Giffuni 		case tLOG_EQ:
290*c69cee69SPedro F. Giffuni 		    lhs = (lhs == rhs);
291*c69cee69SPedro F. Giffuni 		    break;
292*c69cee69SPedro F. Giffuni 		case tLOG_NOT_EQ:
293*c69cee69SPedro F. Giffuni 		    lhs = (lhs != rhs);
294*c69cee69SPedro F. Giffuni 		    break;
295*c69cee69SPedro F. Giffuni 		case tGREATER:
296*c69cee69SPedro F. Giffuni 		    lhs = (lhs > rhs);
297*c69cee69SPedro F. Giffuni 		    break;
298*c69cee69SPedro F. Giffuni 		case tGREATER_EQ:
299*c69cee69SPedro F. Giffuni 		    lhs = (lhs >= rhs);
300*c69cee69SPedro F. Giffuni 		    break;
301*c69cee69SPedro F. Giffuni 		case tLESS:
302*c69cee69SPedro F. Giffuni 		    lhs = (lhs < rhs);
303*c69cee69SPedro F. Giffuni 		    break;
304*c69cee69SPedro F. Giffuni 		case tLESS_EQ:
305*c69cee69SPedro F. Giffuni 		    lhs = (lhs <= rhs);
306*c69cee69SPedro F. Giffuni 		    break;
307*c69cee69SPedro F. Giffuni 		default:
308*c69cee69SPedro F. Giffuni 		    __unreachable();
309*c69cee69SPedro F. Giffuni 	    }
310*c69cee69SPedro F. Giffuni 	    t = db_read_token();
311*c69cee69SPedro F. Giffuni 	}
312*c69cee69SPedro F. Giffuni 	db_unread_token(t);
313*c69cee69SPedro F. Giffuni 	*valuep = lhs;
314*c69cee69SPedro F. Giffuni 	return (true);
315*c69cee69SPedro F. Giffuni }
316*c69cee69SPedro F. Giffuni 
317*c69cee69SPedro F. Giffuni static bool
318*c69cee69SPedro F. Giffuni db_logical_and_expr(
319*c69cee69SPedro F. Giffuni 	db_expr_t *valuep)
320*c69cee69SPedro F. Giffuni {
321*c69cee69SPedro F. Giffuni 	db_expr_t	lhs, rhs;
322*c69cee69SPedro F. Giffuni 	int		t;
323*c69cee69SPedro F. Giffuni 
324*c69cee69SPedro F. Giffuni 	if (!db_logical_relation_expr(&lhs))
325*c69cee69SPedro F. Giffuni 	    return (false);
326*c69cee69SPedro F. Giffuni 
327*c69cee69SPedro F. Giffuni 	t = db_read_token();
328*c69cee69SPedro F. Giffuni 	while (t == tLOG_AND) {
329*c69cee69SPedro F. Giffuni 	    if (!db_logical_relation_expr(&rhs)) {
330*c69cee69SPedro F. Giffuni 		db_printf("Expression syntax error after '%s'\n", "&&");
331*c69cee69SPedro F. Giffuni 		db_error(NULL);
332*c69cee69SPedro F. Giffuni 		/*NOTREACHED*/
333*c69cee69SPedro F. Giffuni 	    }
334*c69cee69SPedro F. Giffuni 	    lhs = (lhs && rhs);
335*c69cee69SPedro F. Giffuni 	    t = db_read_token();
336*c69cee69SPedro F. Giffuni 	}
337*c69cee69SPedro F. Giffuni 	db_unread_token(t);
338*c69cee69SPedro F. Giffuni 	*valuep = lhs;
339*c69cee69SPedro F. Giffuni 	return (true);
340*c69cee69SPedro F. Giffuni }
341*c69cee69SPedro F. Giffuni 
342*c69cee69SPedro F. Giffuni static bool
343*c69cee69SPedro F. Giffuni db_logical_or_expr(
344*c69cee69SPedro F. Giffuni 	db_expr_t *valuep)
345*c69cee69SPedro F. Giffuni {
346*c69cee69SPedro F. Giffuni 	db_expr_t	lhs, rhs;
347*c69cee69SPedro F. Giffuni 	int		t;
348*c69cee69SPedro F. Giffuni 
349*c69cee69SPedro F. Giffuni 	if (!db_logical_and_expr(&lhs))
350*c69cee69SPedro F. Giffuni 		return(false);
351*c69cee69SPedro F. Giffuni 
352*c69cee69SPedro F. Giffuni 	t = db_read_token();
353*c69cee69SPedro F. Giffuni 	while (t == tLOG_OR) {
354*c69cee69SPedro F. Giffuni 		if (!db_logical_and_expr(&rhs)) {
355*c69cee69SPedro F. Giffuni 			db_printf("Expression syntax error after '%s'\n", "||");
356*c69cee69SPedro F. Giffuni 			db_error(NULL);
357*c69cee69SPedro F. Giffuni 			/*NOTREACHED*/
358*c69cee69SPedro F. Giffuni 		}
359*c69cee69SPedro F. Giffuni 		lhs = (lhs || rhs);
360*c69cee69SPedro F. Giffuni 		t = db_read_token();
361*c69cee69SPedro F. Giffuni 	}
362*c69cee69SPedro F. Giffuni 	db_unread_token(t);
363*c69cee69SPedro F. Giffuni 	*valuep = lhs;
364*c69cee69SPedro F. Giffuni 	return (true);
365*c69cee69SPedro F. Giffuni }
366*c69cee69SPedro F. Giffuni 
3675b81b6b3SRodney W. Grimes int
36819b79af1SWarner Losh db_expression(db_expr_t *valuep)
3695b81b6b3SRodney W. Grimes {
370*c69cee69SPedro F. Giffuni 	return (db_logical_or_expr(valuep));
3715b81b6b3SRodney W. Grimes }
372