[git commit] dc: fix "small dc" to have standard command line API

Denys Vlasenko vda.linux at googlemail.com
Sat Dec 8 17:59:07 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=d0bc5fdfea72ffac3102c76760f3e55a40a430ea
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 miscutils/bc.c |  3 +--
 miscutils/dc.c | 70 +++++++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 48 insertions(+), 25 deletions(-)

diff --git a/miscutils/bc.c b/miscutils/bc.c
index 24e4b6392..e543b2b93 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 bca4778bf..17fdda8fd 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;
 }


More information about the busybox-cvs mailing list