164 lines
3.5 KiB
Diff
164 lines
3.5 KiB
Diff
|
Fix dc inconsistency, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=538685
|
||
|
From upstream: http://busybox.net/downloads/fixes-1.23.1/busybox-1.23.1-dc.patch
|
||
|
|
||
|
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||
|
|
||
|
--- busybox-1.23.1/miscutils/dc.c
|
||
|
+++ busybox-1.23.1-dc/miscutils/dc.c
|
||
|
@@ -196,14 +196,6 @@ struct op {
|
||
|
};
|
||
|
|
||
|
static const struct op operators[] = {
|
||
|
- {"+", add},
|
||
|
- {"add", add},
|
||
|
- {"-", sub},
|
||
|
- {"sub", sub},
|
||
|
- {"*", mul},
|
||
|
- {"mul", mul},
|
||
|
- {"/", divide},
|
||
|
- {"div", divide},
|
||
|
#if ENABLE_FEATURE_DC_LIBM
|
||
|
{"**", power},
|
||
|
{"exp", power},
|
||
|
@@ -216,28 +208,47 @@ static const struct op operators[] = {
|
||
|
{"not", not},
|
||
|
{"eor", eor},
|
||
|
{"xor", eor},
|
||
|
+ {"+", add},
|
||
|
+ {"add", add},
|
||
|
+ {"-", sub},
|
||
|
+ {"sub", sub},
|
||
|
+ {"*", mul},
|
||
|
+ {"mul", mul},
|
||
|
+ {"/", divide},
|
||
|
+ {"div", divide},
|
||
|
{"p", print_no_pop},
|
||
|
{"f", print_stack_no_pop},
|
||
|
{"o", set_output_base},
|
||
|
};
|
||
|
|
||
|
+/* Feed the stack machine */
|
||
|
static void stack_machine(const char *argument)
|
||
|
{
|
||
|
char *end;
|
||
|
- double d;
|
||
|
+ double number;
|
||
|
const struct op *o;
|
||
|
|
||
|
- d = strtod(argument, &end);
|
||
|
- if (end != argument && *end == '\0') {
|
||
|
- push(d);
|
||
|
- return;
|
||
|
+ next:
|
||
|
+ number = strtod(argument, &end);
|
||
|
+ if (end != argument) {
|
||
|
+ argument = end;
|
||
|
+ push(number);
|
||
|
+ goto next;
|
||
|
}
|
||
|
|
||
|
+ /* We might have matched a digit, eventually advance the argument */
|
||
|
+ argument = skip_whitespace(argument);
|
||
|
+
|
||
|
+ if (*argument == '\0')
|
||
|
+ return;
|
||
|
+
|
||
|
o = operators;
|
||
|
do {
|
||
|
- if (strcmp(o->name, argument) == 0) {
|
||
|
+ const size_t name_len = strlen(o->name);
|
||
|
+ if (strncmp(o->name, argument, name_len) == 0) {
|
||
|
+ argument += name_len;
|
||
|
o->function();
|
||
|
- return;
|
||
|
+ goto next;
|
||
|
}
|
||
|
o++;
|
||
|
} while (o != operators + ARRAY_SIZE(operators));
|
||
|
@@ -254,25 +265,11 @@ int dc_main(int argc UNUSED_PARAM, char
|
||
|
if (!argv[0]) {
|
||
|
/* take stuff from stdin if no args are given */
|
||
|
char *line;
|
||
|
- char *cursor;
|
||
|
- char *token;
|
||
|
while ((line = xmalloc_fgetline(stdin)) != NULL) {
|
||
|
- cursor = line;
|
||
|
- while (1) {
|
||
|
- token = skip_whitespace(cursor);
|
||
|
- if (*token == '\0')
|
||
|
- break;
|
||
|
- cursor = skip_non_whitespace(token);
|
||
|
- if (*cursor != '\0')
|
||
|
- *cursor++ = '\0';
|
||
|
- stack_machine(token);
|
||
|
- }
|
||
|
+ stack_machine(line);
|
||
|
free(line);
|
||
|
}
|
||
|
} else {
|
||
|
- // why? it breaks "dc -2 2 + p"
|
||
|
- //if (argv[0][0] == '-')
|
||
|
- // bb_show_usage();
|
||
|
do {
|
||
|
stack_machine(*argv);
|
||
|
} while (*++argv);
|
||
|
--- busybox-1.23.1/testsuite/dc.tests
|
||
|
+++ busybox-1.23.1-dc/testsuite/dc.tests
|
||
|
@@ -0,0 +1,56 @@
|
||
|
+#!/bin/sh
|
||
|
+# Copyright 2015 by Bernhard Reutner-Fischer
|
||
|
+# Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||
|
+
|
||
|
+. ./testing.sh
|
||
|
+
|
||
|
+# testing "test name" "command" "expected result" "file input" "stdin"
|
||
|
+
|
||
|
+testing "dc basic syntax (stdin, multiple args)" \
|
||
|
+ "dc" \
|
||
|
+ "30\n" \
|
||
|
+ "" "10 20+p"
|
||
|
+
|
||
|
+testing "dc basic syntax (argv, single arg)" \
|
||
|
+ "dc '10 20+p'" \
|
||
|
+ "30\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+testing "dc basic syntax (argv, multiple args)" \
|
||
|
+ "dc 10 20+p" \
|
||
|
+ "30\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+testing "dc complex with spaces (single arg)" \
|
||
|
+ "dc '8 8 * 2 2 + / p'" \
|
||
|
+ "16\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+testing "dc complex without spaces (single arg)" \
|
||
|
+ "dc '8 8*2 2+/p'" \
|
||
|
+ "16\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+testing "dc complex with spaces (multiple args)" \
|
||
|
+ "dc 8 8 \* 2 2 + / p" \
|
||
|
+ "16\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+testing "dc complex without spaces (multiple args)" \
|
||
|
+ "dc 8 8\*2 2+/p" \
|
||
|
+ "16\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+exit $FAILCOUNT
|
||
|
+
|
||
|
+# we do not support arguments
|
||
|
+testing "dc -e <exprs>" \
|
||
|
+ "dc -e '10 2+f'" \
|
||
|
+ "12\n" \
|
||
|
+ "" ""
|
||
|
+
|
||
|
+testing "dc -f <exprs-from-given-file>" \
|
||
|
+ "dc -f input" \
|
||
|
+ "12\n" \
|
||
|
+ "10 2+f" ""
|
||
|
+
|