dc: fix "small dc" to have standard command line API
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
23427a63fc
commit
d0bc5fdfea
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user