summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2018-12-08 18:59:07 +0100
committerDenys Vlasenko2018-12-08 18:59:07 +0100
commitd0bc5fdfea72ffac3102c76760f3e55a40a430ea (patch)
tree9052c70dedfdd78d1835f16d12a393b98a40ce7c
parent23427a63fc8f7742210d329b9edd77a6e547d2cd (diff)
downloadbusybox-d0bc5fdfea72ffac3102c76760f3e55a40a430ea.zip
busybox-d0bc5fdfea72ffac3102c76760f3e55a40a430ea.tar.gz
dc: fix "small dc" to have standard command line API
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c3
-rw-r--r--miscutils/dc.c70
2 files changed, 48 insertions, 25 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 24e4b63..e543b2b 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -159,8 +159,7 @@
//usage:
//usage:#define dc_full_usage "\n"
//usage: "\nTiny RPN calculator. Operations:"
-//usage: "\n+, -, *, /, %, ^, exp, ~, divmod, |, "
-//usage: "modular exponentiation,"
+//usage: "\n+, -, *, /, %, ~, ^, |,"
//usage: "\np - print top of the stack (without popping)"
//usage: "\nf - print entire stack"
//usage: "\nk - pop the value and set the precision"
diff --git a/miscutils/dc.c b/miscutils/dc.c
index bca4778..17fdda8 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -20,7 +20,6 @@ typedef unsigned long long data_t;
#define DATA_FMT "ll"
#endif
-
struct globals {
unsigned pointer;
unsigned base;
@@ -36,7 +35,6 @@ enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(
base = 10; \
} while (0)
-
static void check_under(void)
{
if (pointer == 0)
@@ -184,25 +182,25 @@ struct op {
static const struct op operators[] = {
#if ENABLE_FEATURE_DC_LIBM
- {"**", power},
- {"exp", power},
- {"pow", power},
+ {"^", power},
+// {"exp", power},
+// {"pow", power},
#endif
{"%", mod},
- {"mod", mod},
+// {"mod", mod},
+ // logic ops are not standard, remove?
{"and", and},
{"or", or},
{"not", not},
- {"eor", eor},
{"xor", eor},
{"+", add},
- {"add", add},
+// {"add", add},
{"-", sub},
- {"sub", sub},
+// {"sub", sub},
{"*", mul},
- {"mul", mul},
+// {"mul", mul},
{"/", divide},
- {"div", divide},
+// {"div", divide},
{"p", print_no_pop},
{"f", print_stack_no_pop},
{"o", set_output_base},
@@ -243,24 +241,50 @@ static void stack_machine(const char *argument)
bb_error_msg_and_die("syntax error at '%s'", argument);
}
+static void process_file(FILE *fp)
+{
+ char *line;
+ while ((line = xmalloc_fgetline(fp)) != NULL) {
+ stack_machine(line);
+ free(line);
+ }
+}
+
int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int dc_main(int argc UNUSED_PARAM, char **argv)
{
+ bool script = 0;
+
INIT_G();
-//TODO: fix this, should take: dc -eSCRIPT -fFILE FILE
- argv++;
- if (!argv[0]) {
- /* take stuff from stdin if no args are given */
- char *line;
- while ((line = xmalloc_fgetline(stdin)) != NULL) {
- stack_machine(line);
- free(line);
+ /* Run -e'SCRIPT' and -fFILE in order of appearance, then handle FILEs */
+ for (;;) {
+ int n = getopt(argc, argv, "e:f:");
+ if (n <= 0)
+ break;
+ switch (n) {
+ case 'e':
+ script = 1;
+ stack_machine(optarg);
+ break;
+ case 'f':
+ script = 1;
+ process_file(xfopen_for_read(optarg));
+ break;
+ default:
+ bb_show_usage();
}
- } else {
- do {
- stack_machine(*argv);
- } while (*++argv);
}
+ argv += optind;
+
+ if (*argv) {
+ do
+ process_file(xfopen_for_read(*argv++));
+ while (*argv);
+ } else if (!script) {
+ /* Take stuff from stdin if no args are given */
+ process_file(stdin);
+ }
+
return EXIT_SUCCESS;
}