From 11e6cfeb82225253fb041565f5404564db881a4c Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 17 Dec 2017 14:41:55 -0800 Subject: [PATCH] [math] Remove exception handling in builtin_math This handles errors explicitly instead of catching them. --- src/builtin_math.cpp | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/builtin_math.cpp b/src/builtin_math.cpp index ba61af8fb..e86e6039a 100644 --- a/src/builtin_math.cpp +++ b/src/builtin_math.cpp @@ -119,36 +119,40 @@ static const wchar_t *math_get_arg(int *argidx, wchar_t **argv, wcstring *storag static mu::ValueOrError moduloOperator(double v, double w) { return (int)v % std::max(1, (int)w); }; /// Evaluate math expressions. -static int evaluate_expression(wchar_t *cmd, parser_t &parser, io_streams_t &streams, +static int evaluate_expression(const wchar_t *cmd, parser_t &parser, io_streams_t &streams, math_cmd_opts_t &opts, wcstring &expression) { UNUSED(parser); - try { - mu::Parser p; - // MuParser doesn't implement the modulo operator so we add it ourselves since there are - // likely users of our old math wrapper around bc that expect it to be available. - p.DefineOprtChars(L"%"); - p.DefineOprt(L"%", moduloOperator, mu::prINFIX); - - mu::OptionalError oerr = p.SetExpr(expression); - if (oerr.has_error()) throw oerr.error(); - std::vector vs; - p.Eval(&vs); - for (const mu::ValueOrError &v : vs) { - if (v.has_error()) throw v.error(); - } - for (const mu::ValueOrError &v : vs) { - if (opts.scale == 0) { - streams.out.append_format(L"%ld\n", static_cast(*v)); - } else { - streams.out.append_format(L"%.*lf\n", opts.scale, *v); - } - } - return STATUS_CMD_OK; - } catch (mu::Parser::exception_type &e) { - streams.err.append_format(_(L"%ls: Invalid expression: %ls\n"), cmd, e.GetMsg().c_str()); + // Helper to print an error and return an error code. + auto printError = [&streams, cmd](const mu::ParserError &err) { + streams.err.append_format(_(L"%ls: Invalid expression: %ls\n"), cmd, err.GetMsg().c_str()); return STATUS_CMD_ERROR; + }; + + mu::Parser p; + // MuParser doesn't implement the modulo operator so we add it ourselves since there are + // likely users of our old math wrapper around bc that expect it to be available. + p.DefineOprtChars(L"%"); + mu::OptionalError oerr = p.DefineOprt(L"%", moduloOperator, mu::prINFIX); + assert(!oerr.has_error() && "Unexpected error defining modulo operator"); + (void)oerr; + + oerr = p.SetExpr(expression); + if (oerr.has_error()) return printError(oerr.error()); + + std::vector vs; + p.Eval(&vs); + for (const mu::ValueOrError &v : vs) { + if (v.has_error()) return printError(v.error()); } + for (const mu::ValueOrError &v : vs) { + if (opts.scale == 0) { + streams.out.append_format(L"%ld\n", static_cast(*v)); + } else { + streams.out.append_format(L"%.*lf\n", opts.scale, *v); + } + } + return STATUS_CMD_OK; } /// The math builtin evaluates math expressions.