mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
[math] Check for runtime errors
When number is infinite, not a number, larger than LONG_MAX or smaller than LONG_MIN, print a corresponding error and return STATUS_CMD_ERROR. This should fix the worst of the problems, by at least making them clear. Fixes #4479. Fixes #4768.
This commit is contained in:
parent
98d29b53de
commit
9fc3d1215b
2 changed files with 24 additions and 2 deletions
|
@ -17,7 +17,7 @@ The following options are available:
|
|||
|
||||
\subsection return-values Return Values
|
||||
|
||||
If the expression is successfully evaluated the return `status` is zero (success) else one.
|
||||
If the expression is successfully evaluated and doesn't over/underflow or return NaN the return `status` is zero (success) else one.
|
||||
|
||||
\subsection math-syntax
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include "tinyexpr.h"
|
||||
|
@ -145,7 +146,28 @@ static int evaluate_expression(const wchar_t *cmd, parser_t &parser, io_streams_
|
|||
double v = te_interp(narrow_str.c_str(), &error);
|
||||
|
||||
if (error.position == 0) {
|
||||
if (opts.scale == 0) {
|
||||
// Check some runtime errors after the fact.
|
||||
// TODO: Really, this should be done in tinyexpr
|
||||
// (e.g. infinite is the result of "x / 0"),
|
||||
// but that's much more work.
|
||||
if (std::isinfinite(v)) {
|
||||
streams.err.append_format(L"%ls: Error: Result is infinite\n", cmd);
|
||||
streams.err.append_format(L"'%ls'\n", expression.c_str());
|
||||
retval = STATUS_CMD_ERROR;
|
||||
} else if (std::isnan(v)) {
|
||||
streams.err.append_format(L"%ls: Error: Result is not a number\n", cmd);
|
||||
streams.err.append_format(L"'%ls'\n", expression.c_str());
|
||||
retval = STATUS_CMD_ERROR;
|
||||
} else if (v >= LONG_MAX) {
|
||||
streams.err.append_format(L"%ls: Error: Result is too large\n", cmd);
|
||||
streams.err.append_format(L"'%ls'\n", expression.c_str());
|
||||
retval = STATUS_CMD_ERROR;
|
||||
} else if (v <= LONG_MIN) {
|
||||
streams.err.append_format(L"%ls: Error: Result is too small\n", cmd);
|
||||
streams.err.append_format(L"'%ls'\n", expression.c_str());
|
||||
retval = STATUS_CMD_ERROR;
|
||||
} else if (opts.scale == 0) {
|
||||
// Normal results
|
||||
streams.out.append_format(L"%ld\n", static_cast<long>(v));
|
||||
} else {
|
||||
streams.out.append_format(L"%.*lf\n", opts.scale, v);
|
||||
|
|
Loading…
Reference in a new issue