X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fdc.c;h=2121f7669a581e137e8b74dddb7d5840be169b47;hb=9a1c71a0f22e7113b87291f874281fb44a455aab;hp=c7b43ea0ac1efbbc665a91d84326f70cca1dc551;hpb=6d07432b2ff21f0d8537ba5fae3c402be9cb247a;p=oweals%2Fbusybox.git diff --git a/miscutils/dc.c b/miscutils/dc.c index c7b43ea0a..2121f7669 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -1,11 +1,15 @@ /* 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 -#include "busybox.h" /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ @@ -16,14 +20,14 @@ 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(void) { if (pointer == 0) - error_msg_and_die("stack underflow"); + bb_error_msg_and_die("stack underflow"); return stack[--pointer]; } @@ -44,6 +48,13 @@ static void mul(void) push(pop() * pop()); } +static void power(void) +{ + double topower = pop(); + + push(pow(pop(), topower)); +} + static void divide(void) { double divisor = pop(); @@ -51,6 +62,13 @@ static void divide(void) push(pop() / divisor); } +static void mod(void) +{ + unsigned int d = pop(); + + push((unsigned int) pop() % d); +} + static void and(void) { push((unsigned int) pop() & (unsigned int) pop()); @@ -73,7 +91,7 @@ static void not(void) static void set_output_base(void) { - base=(unsigned char)pop(); + base=(unsigned char)pop(); if ((base != 10) && (base != 16)) { fprintf(stderr, "Error: base = %d is not supported.\n", base); base=10; @@ -82,7 +100,7 @@ static void set_output_base(void) static void print_base(double print) { - if (base == 16) + if (base == 16) printf("%x\n", (unsigned int)print); else printf("%g\n", print); @@ -100,11 +118,6 @@ static void print_no_pop(void) print_base(stack[pointer-1]); } -static void print(void) -{ - print_base(pop()); -} - struct op { const char *name; void (*function) (void); @@ -119,10 +132,16 @@ 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}, @@ -135,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); @@ -154,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; @@ -183,6 +200,7 @@ static int number_of_tokens(char *buffer) return i; } +int dc_main(int argc, char **argv); int dc_main(int argc, char **argv) { /* take stuff from stdin if no args are given */ @@ -191,7 +209,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++) { @@ -203,13 +221,12 @@ int dc_main(int argc, char **argv) } } else { if (*argv[1]=='-') - show_usage(); + bb_show_usage(); while (argc >= 2) { stack_machine(argv[1]); argv++; argc--; } } - stack_machine(0); return EXIT_SUCCESS; }