[PATCH] dc: support GNU dc options (-e/--expression -f/--file)

wdlkmpx wdlkmpx at gmail.com
Wed Apr 4 22:18:58 UTC 2018


keep the current behavior but also take arguments: -e and -f
to make it compatible with GNU dc.

dc expr = dc -e expr = dc --expression=expr
---
 miscutils/dc.c | 46 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/miscutils/dc.c b/miscutils/dc.c
index b922a7184..42771f125 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -22,7 +22,8 @@
 //kbuild:lib-$(CONFIG_DC) += dc.o
 
 //usage:#define dc_trivial_usage
-//usage:       "EXPRESSION..."
+//usage:       "[-e] EXPRESSION\n"
+//usage:       "or:    dc  -f  FILE"
 //usage:
 //usage:#define dc_full_usage "\n\n"
 //usage:       "Tiny RPN calculator. Operations:\n"
@@ -287,8 +288,7 @@ int dc_main(int argc UNUSED_PARAM, char **argv)
 {
 	INIT_G();
 
-	argv++;
-	if (!argv[0]) {
+	if (argc < 2) {
 		/* take stuff from stdin if no args are given */
 		char *line;
 		while ((line = xmalloc_fgetline(stdin)) != NULL) {
@@ -296,9 +296,43 @@ int dc_main(int argc UNUSED_PARAM, char **argv)
 			free(line);
 		}
 	} else {
-		do {
-			stack_machine(*argv);
-		} while (*++argv);
+
+		unsigned opts;
+		char *file_str, *exp_str = NULL;
+		enum {
+			OPT_EXPRESSION  = (1 << 0),
+			OPT_FILE = (1 << 1),
+		};
+
+#if ENABLE_LONG_OPTS
+		static const char dc_longopts[] ALIGN1 =
+			/* name             has_arg             short */
+			"expression\0"      Required_argument   "e"
+			"file\0"            Required_argument   "f";
+		opts = getopt32long(argv, "e:f:" "\0", dc_longopts, &exp_str, &file_str);
+#else
+		opts = getopt32(argv, "e:f:" "\0", &exp_str, &file_str);
+#endif
+		argv += optind;
+
+		if (!(opts & OPT_FILE)) {
+			if (exp_str) { // -e
+				stack_machine(exp_str);
+			} else { // no opts
+				do {
+					stack_machine(*argv);
+				} while (*++argv);
+			}
+		} else { // -f
+			char *line;
+			FILE *cmdfile;
+			cmdfile = xfopen_stdin(file_str);
+			while ((line = xmalloc_fgetline(cmdfile)) != NULL) {
+				stack_machine(line);
+				free(line);
+			}
+			fclose_if_not_stdin(cmdfile);
+		}
 	}
 	return EXIT_SUCCESS;
 }
-- 
2.11.0



More information about the busybox mailing list