X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fdc.c;h=7b6405754bcf6398d534a17219e2cc59e4b154d6;hb=98ee06d3d46aa7f89c204681c7075b53300a6a6e;hp=122673a95a59d389edaf30d1438f7a020ff2d08f;hpb=dd19c6990496023fe23fefef8f1798740f7d39c6;p=oweals%2Fbusybox.git diff --git a/miscutils/dc.c b/miscutils/dc.c index 122673a95..7b6405754 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -1,8 +1,13 @@ /* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + #include "busybox.h" #include #include #include +#include #include #include @@ -10,73 +15,112 @@ static double stack[100]; static unsigned int pointer; +static unsigned char base; static void push(double a) { if (pointer >= (sizeof(stack) / sizeof(*stack))) - error_msg_and_die("stack overflow"); + bb_error_msg_and_die("stack overflow"); stack[pointer++] = a; } -static double pop() +static double pop(void) { if (pointer == 0) - error_msg_and_die("stack underflow"); + bb_error_msg_and_die("stack underflow"); return stack[--pointer]; } -static void add() +static void add(void) { push(pop() + pop()); } -static void sub() +static void sub(void) { double subtrahend = pop(); push(pop() - subtrahend); } -static void mul() +static void mul(void) { push(pop() * pop()); } -static void divide() +static void power(void) +{ + double topower = pop(); + + push(pow(pop(), topower)); +} + +static void divide(void) { double divisor = pop(); push(pop() / divisor); } -static void and() +static void mod(void) +{ + unsigned int d = pop(); + + push((unsigned int) pop() % d); +} + +static void and(void) { push((unsigned int) pop() & (unsigned int) pop()); } -static void or() +static void or(void) { push((unsigned int) pop() | (unsigned int) pop()); } -static void eor() +static void eor(void) { push((unsigned int) pop() ^ (unsigned int) pop()); } -static void not() +static void not(void) { push(~(unsigned int) pop()); } -static void print() +static void set_output_base(void) { - printf("%g\n", pop()); + base=(unsigned char)pop(); + if ((base != 10) && (base != 16)) { + fprintf(stderr, "Error: base = %d is not supported.\n", base); + base=10; + } +} + +static void print_base(double print) +{ + if (base == 16) + printf("%x\n", (unsigned int)print); + else + printf("%g\n", print); +} + +static void print_stack_no_pop(void) +{ + unsigned int i=pointer; + while (i) + print_base(stack[--i]); +} + +static void print_no_pop(void) +{ + print_base(stack[pointer-1]); } struct op { const char *name; - void (*function) (); + void (*function) (void); }; static const struct op operators[] = { @@ -88,10 +132,19 @@ static const struct op operators[] = { {"mul", mul}, {"/", divide}, {"div", divide}, + {"**", power}, + {"exp", power}, + {"pow", power}, + {"%", mod}, + {"mod", mod}, {"and", and}, {"or", or}, {"not", not}, {"eor", eor}, + {"xor", eor}, + {"p", print_no_pop}, + {"f", print_stack_no_pop}, + {"o", set_output_base}, {0, 0} }; @@ -101,10 +154,8 @@ static void stack_machine(const char *argument) double d; const struct op *o = operators; - if (argument == 0) { - print(); + if (argument == 0) return; - } d = strtod(argument, &endPointer); @@ -120,21 +171,21 @@ static void stack_machine(const char *argument) } o++; } - error_msg_and_die("%s: syntax error.", argument); + bb_error_msg_and_die("%s: syntax error", argument); } /* return pointer to next token in buffer and set *buffer to one char - * past the end of the above mentioned token + * past the end of the above mentioned token */ static char *get_token(char **buffer) { - char *start = NULL; - char *current = *buffer; + char *start = NULL; + char *current; - while (isspace(*current)) { current++; } + current = skip_whitespace(*buffer); if (*current != 0) { start = current; - while (!isspace(*current) && current != 0) { current++; } + while (!isspace(*current) && *current != 0) { current++; } *buffer = current; } return start; @@ -157,7 +208,7 @@ int dc_main(int argc, char **argv) char *line = NULL; char *cursor = NULL; char *token = NULL; - while ((line = get_line_from_file(stdin))) { + while ((line = xmalloc_getline(stdin))) { cursor = line; len = number_of_tokens(line); for (i = 0; i < len; i++) { @@ -169,13 +220,12 @@ int dc_main(int argc, char **argv) } } else { if (*argv[1]=='-') - usage(dc_usage); + bb_show_usage(); while (argc >= 2) { stack_machine(argv[1]); argv++; argc--; } } - stack_machine(0); return EXIT_SUCCESS; }