From 8f0b6e2117cd2f3f81ca8572dea4f243ce831610 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Mon, 28 Jan 2019 11:12:18 +0100 Subject: mpick: add ternary (conditional) operator --- mpick.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'mpick.c') diff --git a/mpick.c b/mpick.c index c4a4207..f9da79d 100644 --- a/mpick.c +++ b/mpick.c @@ -46,6 +46,7 @@ enum op { EXPR_OR = 1, EXPR_AND, + EXPR_COND, EXPR_NOT, EXPR_LT, EXPR_LE, @@ -115,7 +116,7 @@ struct expr { int64_t num; regex_t *regex; enum var var; - } a, b; + } a, b, c; int extra; }; @@ -263,7 +264,7 @@ parse_op() } static struct expr *parse_cmp(); -static struct expr *parse_or(); +static struct expr *parse_cond(); static struct expr * parse_inner() @@ -285,7 +286,7 @@ parse_inner() not->a.expr = e; return not; } else if (token("(")) { - struct expr *e = parse_or(); + struct expr *e = parse_cond(); if (token(")")) return e; parse_error("missing ) at '%.15s'", pos); @@ -723,10 +724,33 @@ parse_or() } static struct expr * -parse_expr(char *s) +parse_cond() +{ + struct expr *e1 = parse_or(); + + if (token("?")) { + struct expr *e2 = parse_or(); + if (token(":")) { + struct expr *e3 = parse_cond(); + struct expr *r = mkexpr(EXPR_COND); + r->a.expr = e1; + r->b.expr = e2; + r->c.expr = e3; + + return r; + } else { + parse_error("expected : at '%.15s'", pos); + } + } + + return e1; +} + +static struct expr * +parse_expr() { pos = s; - struct expr *e = parse_or(); + struct expr *e = parse_cond(); if (*pos) parse_error("trailing garbage at '%.15s'", pos); return e; @@ -942,6 +966,10 @@ eval(struct expr *e, struct mailinfo *m) return eval(e->a.expr, m) || eval(e->b.expr, m); case EXPR_AND: return eval(e->a.expr, m) && eval(e->b.expr, m); + case EXPR_COND: + return eval(e->a.expr, m) + ? eval(e->b.expr, m) + : eval(e->c.expr, m); case EXPR_NOT: return !eval(e->a.expr, m); return 1; -- cgit 1.4.1