From d0bc5fdfea72ffac3102c76760f3e55a40a430ea Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 8 Dec 2018 18:59:07 +0100 Subject: [PATCH] dc: fix "small dc" to have standard command line API Signed-off-by: Denys Vlasenko --- 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; }