dc: fix "small dc" to have standard command line API
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
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 @@
#define DATA_FMT "ll"
#endif
-
struct globals {
unsigned pointer;
unsigned base;
@@ -36,7 +35,6 @@
base = 10; \
} while (0)
-
static void check_under(void)
{
if (pointer == 0)
@@ -184,25 +182,25 @@
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 @@
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;
}