diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-08 18:59:07 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-08 18:59:07 +0100 |
| commit | d0bc5fdfea72ffac3102c76760f3e55a40a430ea (patch) | |
| tree | 9052c70dedfdd78d1835f16d12a393b98a40ce7c | |
| parent | 23427a63fc8f7742210d329b9edd77a6e547d2cd (diff) | |
| download | busybox-w32-d0bc5fdfea72ffac3102c76760f3e55a40a430ea.tar.gz busybox-w32-d0bc5fdfea72ffac3102c76760f3e55a40a430ea.tar.bz2 busybox-w32-d0bc5fdfea72ffac3102c76760f3e55a40a430ea.zip | |
dc: fix "small dc" to have standard command line API
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | miscutils/bc.c | 3 | ||||
| -rw-r--r-- | 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 @@ | |||
| 159 | //usage: | 159 | //usage: |
| 160 | //usage:#define dc_full_usage "\n" | 160 | //usage:#define dc_full_usage "\n" |
| 161 | //usage: "\nTiny RPN calculator. Operations:" | 161 | //usage: "\nTiny RPN calculator. Operations:" |
| 162 | //usage: "\n+, -, *, /, %, ^, exp, ~, divmod, |, " | 162 | //usage: "\n+, -, *, /, %, ~, ^, |," |
| 163 | //usage: "modular exponentiation," | ||
| 164 | //usage: "\np - print top of the stack (without popping)" | 163 | //usage: "\np - print top of the stack (without popping)" |
| 165 | //usage: "\nf - print entire stack" | 164 | //usage: "\nf - print entire stack" |
| 166 | //usage: "\nk - pop the value and set the precision" | 165 | //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; | |||
| 20 | #define DATA_FMT "ll" | 20 | #define DATA_FMT "ll" |
| 21 | #endif | 21 | #endif |
| 22 | 22 | ||
| 23 | |||
| 24 | struct globals { | 23 | struct globals { |
| 25 | unsigned pointer; | 24 | unsigned pointer; |
| 26 | unsigned base; | 25 | unsigned base; |
| @@ -36,7 +35,6 @@ enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof( | |||
| 36 | base = 10; \ | 35 | base = 10; \ |
| 37 | } while (0) | 36 | } while (0) |
| 38 | 37 | ||
| 39 | |||
| 40 | static void check_under(void) | 38 | static void check_under(void) |
| 41 | { | 39 | { |
| 42 | if (pointer == 0) | 40 | if (pointer == 0) |
| @@ -184,25 +182,25 @@ struct op { | |||
| 184 | 182 | ||
| 185 | static const struct op operators[] = { | 183 | static const struct op operators[] = { |
| 186 | #if ENABLE_FEATURE_DC_LIBM | 184 | #if ENABLE_FEATURE_DC_LIBM |
| 187 | {"**", power}, | 185 | {"^", power}, |
| 188 | {"exp", power}, | 186 | // {"exp", power}, |
| 189 | {"pow", power}, | 187 | // {"pow", power}, |
| 190 | #endif | 188 | #endif |
| 191 | {"%", mod}, | 189 | {"%", mod}, |
| 192 | {"mod", mod}, | 190 | // {"mod", mod}, |
| 191 | // logic ops are not standard, remove? | ||
| 193 | {"and", and}, | 192 | {"and", and}, |
| 194 | {"or", or}, | 193 | {"or", or}, |
| 195 | {"not", not}, | 194 | {"not", not}, |
| 196 | {"eor", eor}, | ||
| 197 | {"xor", eor}, | 195 | {"xor", eor}, |
| 198 | {"+", add}, | 196 | {"+", add}, |
| 199 | {"add", add}, | 197 | // {"add", add}, |
| 200 | {"-", sub}, | 198 | {"-", sub}, |
| 201 | {"sub", sub}, | 199 | // {"sub", sub}, |
| 202 | {"*", mul}, | 200 | {"*", mul}, |
| 203 | {"mul", mul}, | 201 | // {"mul", mul}, |
| 204 | {"/", divide}, | 202 | {"/", divide}, |
| 205 | {"div", divide}, | 203 | // {"div", divide}, |
| 206 | {"p", print_no_pop}, | 204 | {"p", print_no_pop}, |
| 207 | {"f", print_stack_no_pop}, | 205 | {"f", print_stack_no_pop}, |
| 208 | {"o", set_output_base}, | 206 | {"o", set_output_base}, |
| @@ -243,24 +241,50 @@ static void stack_machine(const char *argument) | |||
| 243 | bb_error_msg_and_die("syntax error at '%s'", argument); | 241 | bb_error_msg_and_die("syntax error at '%s'", argument); |
| 244 | } | 242 | } |
| 245 | 243 | ||
| 244 | static void process_file(FILE *fp) | ||
| 245 | { | ||
| 246 | char *line; | ||
| 247 | while ((line = xmalloc_fgetline(fp)) != NULL) { | ||
| 248 | stack_machine(line); | ||
| 249 | free(line); | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 246 | int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 253 | int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 247 | int dc_main(int argc UNUSED_PARAM, char **argv) | 254 | int dc_main(int argc UNUSED_PARAM, char **argv) |
| 248 | { | 255 | { |
| 256 | bool script = 0; | ||
| 257 | |||
| 249 | INIT_G(); | 258 | INIT_G(); |
| 250 | 259 | ||
| 251 | //TODO: fix this, should take: dc -eSCRIPT -fFILE FILE | 260 | /* Run -e'SCRIPT' and -fFILE in order of appearance, then handle FILEs */ |
| 252 | argv++; | 261 | for (;;) { |
| 253 | if (!argv[0]) { | 262 | int n = getopt(argc, argv, "e:f:"); |
| 254 | /* take stuff from stdin if no args are given */ | 263 | if (n <= 0) |
| 255 | char *line; | 264 | break; |
| 256 | while ((line = xmalloc_fgetline(stdin)) != NULL) { | 265 | switch (n) { |
| 257 | stack_machine(line); | 266 | case 'e': |
| 258 | free(line); | 267 | script = 1; |
| 268 | stack_machine(optarg); | ||
| 269 | break; | ||
| 270 | case 'f': | ||
| 271 | script = 1; | ||
| 272 | process_file(xfopen_for_read(optarg)); | ||
| 273 | break; | ||
| 274 | default: | ||
| 275 | bb_show_usage(); | ||
| 259 | } | 276 | } |
| 260 | } else { | ||
| 261 | do { | ||
| 262 | stack_machine(*argv); | ||
| 263 | } while (*++argv); | ||
| 264 | } | 277 | } |
| 278 | argv += optind; | ||
| 279 | |||
| 280 | if (*argv) { | ||
| 281 | do | ||
| 282 | process_file(xfopen_for_read(*argv++)); | ||
| 283 | while (*argv); | ||
| 284 | } else if (!script) { | ||
| 285 | /* Take stuff from stdin if no args are given */ | ||
| 286 | process_file(stdin); | ||
| 287 | } | ||
| 288 | |||
| 265 | return EXIT_SUCCESS; | 289 | return EXIT_SUCCESS; |
| 266 | } | 290 | } |
