aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c3
-rw-r--r--miscutils/dc.c70
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
24struct globals { 23struct 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
40static void check_under(void) 38static void check_under(void)
41{ 39{
42 if (pointer == 0) 40 if (pointer == 0)
@@ -184,25 +182,25 @@ struct op {
184 182
185static const struct op operators[] = { 183static 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
244static 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
246int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 253int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
247int dc_main(int argc UNUSED_PARAM, char **argv) 254int 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}