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:
|
||||||
//usage:#define dc_full_usage "\n"
|
//usage:#define dc_full_usage "\n"
|
||||||
//usage: "\nTiny RPN calculator. Operations:"
|
//usage: "\nTiny RPN calculator. Operations:"
|
||||||
//usage: "\n+, -, *, /, %, ^, exp, ~, divmod, |, "
|
//usage: "\n+, -, *, /, %, ~, ^, |,"
|
||||||
//usage: "modular exponentiation,"
|
|
||||||
//usage: "\np - print top of the stack (without popping)"
|
//usage: "\np - print top of the stack (without popping)"
|
||||||
//usage: "\nf - print entire stack"
|
//usage: "\nf - print entire stack"
|
||||||
//usage: "\nk - pop the value and set the precision"
|
//usage: "\nk - pop the value and set the precision"
|
||||||
|
@ -20,7 +20,6 @@ typedef unsigned long long data_t;
|
|||||||
#define DATA_FMT "ll"
|
#define DATA_FMT "ll"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct globals {
|
struct globals {
|
||||||
unsigned pointer;
|
unsigned pointer;
|
||||||
unsigned base;
|
unsigned base;
|
||||||
@ -36,7 +35,6 @@ enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(
|
|||||||
base = 10; \
|
base = 10; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
static void check_under(void)
|
static void check_under(void)
|
||||||
{
|
{
|
||||||
if (pointer == 0)
|
if (pointer == 0)
|
||||||
@ -184,25 +182,25 @@ struct op {
|
|||||||
|
|
||||||
static const struct op operators[] = {
|
static const struct op operators[] = {
|
||||||
#if ENABLE_FEATURE_DC_LIBM
|
#if ENABLE_FEATURE_DC_LIBM
|
||||||
{"**", power},
|
{"^", power},
|
||||||
{"exp", power},
|
// {"exp", power},
|
||||||
{"pow", power},
|
// {"pow", power},
|
||||||
#endif
|
#endif
|
||||||
{"%", mod},
|
{"%", mod},
|
||||||
{"mod", mod},
|
// {"mod", mod},
|
||||||
|
// logic ops are not standard, remove?
|
||||||
{"and", and},
|
{"and", and},
|
||||||
{"or", or},
|
{"or", or},
|
||||||
{"not", not},
|
{"not", not},
|
||||||
{"eor", eor},
|
|
||||||
{"xor", eor},
|
{"xor", eor},
|
||||||
{"+", add},
|
{"+", add},
|
||||||
{"add", add},
|
// {"add", add},
|
||||||
{"-", sub},
|
{"-", sub},
|
||||||
{"sub", sub},
|
// {"sub", sub},
|
||||||
{"*", mul},
|
{"*", mul},
|
||||||
{"mul", mul},
|
// {"mul", mul},
|
||||||
{"/", divide},
|
{"/", divide},
|
||||||
{"div", divide},
|
// {"div", divide},
|
||||||
{"p", print_no_pop},
|
{"p", print_no_pop},
|
||||||
{"f", print_stack_no_pop},
|
{"f", print_stack_no_pop},
|
||||||
{"o", set_output_base},
|
{"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);
|
bb_error_msg_and_die("syntax error at '%s'", argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
static void process_file(FILE *fp)
|
||||||
int dc_main(int argc UNUSED_PARAM, char **argv)
|
|
||||||
{
|
{
|
||||||
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;
|
char *line;
|
||||||
while ((line = xmalloc_fgetline(stdin)) != NULL) {
|
while ((line = xmalloc_fgetline(fp)) != NULL) {
|
||||||
stack_machine(line);
|
stack_machine(line);
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
do {
|
|
||||||
stack_machine(*argv);
|
int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
} while (*++argv);
|
int dc_main(int argc UNUSED_PARAM, char **argv)
|
||||||
|
{
|
||||||
|
bool script = 0;
|
||||||
|
|
||||||
|
INIT_G();
|
||||||
|
|
||||||
|
/* 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();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user