diff options
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/dc.c | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/miscutils/dc.c b/miscutils/dc.c index 6bcfbe249..a7bd360d2 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c | |||
| @@ -196,14 +196,6 @@ struct op { | |||
| 196 | }; | 196 | }; |
| 197 | 197 | ||
| 198 | static const struct op operators[] = { | 198 | static const struct op operators[] = { |
| 199 | {"+", add}, | ||
| 200 | {"add", add}, | ||
| 201 | {"-", sub}, | ||
| 202 | {"sub", sub}, | ||
| 203 | {"*", mul}, | ||
| 204 | {"mul", mul}, | ||
| 205 | {"/", divide}, | ||
| 206 | {"div", divide}, | ||
| 207 | #if ENABLE_FEATURE_DC_LIBM | 199 | #if ENABLE_FEATURE_DC_LIBM |
| 208 | {"**", power}, | 200 | {"**", power}, |
| 209 | {"exp", power}, | 201 | {"exp", power}, |
| @@ -216,28 +208,47 @@ static const struct op operators[] = { | |||
| 216 | {"not", not}, | 208 | {"not", not}, |
| 217 | {"eor", eor}, | 209 | {"eor", eor}, |
| 218 | {"xor", eor}, | 210 | {"xor", eor}, |
| 211 | {"+", add}, | ||
| 212 | {"add", add}, | ||
| 213 | {"-", sub}, | ||
| 214 | {"sub", sub}, | ||
| 215 | {"*", mul}, | ||
| 216 | {"mul", mul}, | ||
| 217 | {"/", divide}, | ||
| 218 | {"div", divide}, | ||
| 219 | {"p", print_no_pop}, | 219 | {"p", print_no_pop}, |
| 220 | {"f", print_stack_no_pop}, | 220 | {"f", print_stack_no_pop}, |
| 221 | {"o", set_output_base}, | 221 | {"o", set_output_base}, |
| 222 | }; | 222 | }; |
| 223 | 223 | ||
| 224 | /* Feed the stack machine */ | ||
| 224 | static void stack_machine(const char *argument) | 225 | static void stack_machine(const char *argument) |
| 225 | { | 226 | { |
| 226 | char *end; | 227 | char *end; |
| 227 | double d; | 228 | double number; |
| 228 | const struct op *o; | 229 | const struct op *o; |
| 229 | 230 | ||
| 230 | d = strtod(argument, &end); | 231 | next: |
| 231 | if (end != argument && *end == '\0') { | 232 | number = strtod(argument, &end); |
| 232 | push(d); | 233 | if (end != argument) { |
| 233 | return; | 234 | argument = end; |
| 235 | push(number); | ||
| 236 | goto next; | ||
| 234 | } | 237 | } |
| 235 | 238 | ||
| 239 | /* We might have matched a digit, eventually advance the argument */ | ||
| 240 | argument = skip_whitespace(argument); | ||
| 241 | |||
| 242 | if (*argument == '\0') | ||
| 243 | return; | ||
| 244 | |||
| 236 | o = operators; | 245 | o = operators; |
| 237 | do { | 246 | do { |
| 238 | if (strcmp(o->name, argument) == 0) { | 247 | const size_t name_len = strlen(o->name); |
| 248 | if (strncmp(o->name, argument, name_len) == 0) { | ||
| 249 | argument += name_len; | ||
| 239 | o->function(); | 250 | o->function(); |
| 240 | return; | 251 | goto next; |
| 241 | } | 252 | } |
| 242 | o++; | 253 | o++; |
| 243 | } while (o != operators + ARRAY_SIZE(operators)); | 254 | } while (o != operators + ARRAY_SIZE(operators)); |
| @@ -254,25 +265,11 @@ int dc_main(int argc UNUSED_PARAM, char **argv) | |||
| 254 | if (!argv[0]) { | 265 | if (!argv[0]) { |
| 255 | /* take stuff from stdin if no args are given */ | 266 | /* take stuff from stdin if no args are given */ |
| 256 | char *line; | 267 | char *line; |
| 257 | char *cursor; | ||
| 258 | char *token; | ||
| 259 | while ((line = xmalloc_fgetline(stdin)) != NULL) { | 268 | while ((line = xmalloc_fgetline(stdin)) != NULL) { |
| 260 | cursor = line; | 269 | stack_machine(line); |
| 261 | while (1) { | ||
| 262 | token = skip_whitespace(cursor); | ||
| 263 | if (*token == '\0') | ||
| 264 | break; | ||
| 265 | cursor = skip_non_whitespace(token); | ||
| 266 | if (*cursor != '\0') | ||
| 267 | *cursor++ = '\0'; | ||
| 268 | stack_machine(token); | ||
| 269 | } | ||
| 270 | free(line); | 270 | free(line); |
| 271 | } | 271 | } |
| 272 | } else { | 272 | } else { |
| 273 | // why? it breaks "dc -2 2 + p" | ||
| 274 | //if (argv[0][0] == '-') | ||
| 275 | // bb_show_usage(); | ||
| 276 | do { | 273 | do { |
| 277 | stack_machine(*argv); | 274 | stack_machine(*argv); |
| 278 | } while (*++argv); | 275 | } while (*++argv); |
