diff options
author | John Beppu <beppu@lbox.org> | 2000-06-21 19:06:16 +0000 |
---|---|---|
committer | John Beppu <beppu@lbox.org> | 2000-06-21 19:06:16 +0000 |
commit | 0021679b0dc5767e0c023b28b36eeb1476dc2364 (patch) | |
tree | 04ff8031a2151a0f95040bbc4bdf2f616d68a540 | |
parent | b405dfa54df117201d93dcb7d24e9e9873737da6 (diff) | |
download | busybox-w32-0021679b0dc5767e0c023b28b36eeb1476dc2364.tar.gz busybox-w32-0021679b0dc5767e0c023b28b36eeb1476dc2364.tar.bz2 busybox-w32-0021679b0dc5767e0c023b28b36eeb1476dc2364.zip |
+ added dc (aka the function formerly known as math)
+ did all the housekeeping that this change requires.
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | applets/busybox.c | 3 | ||||
-rw-r--r-- | busybox.c | 3 | ||||
-rw-r--r-- | busybox.def.h | 2 | ||||
-rw-r--r-- | dc.c (renamed from math.c) | 6 | ||||
-rw-r--r-- | docs/busybox.pod | 51 | ||||
-rw-r--r-- | internal.h | 1 | ||||
-rw-r--r-- | miscutils/dc.c | 194 |
8 files changed, 234 insertions, 28 deletions
@@ -86,6 +86,8 @@ | |||
86 | * Fixed grep "Line too long" problem -- John Beppu | 86 | * Fixed grep "Line too long" problem -- John Beppu |
87 | * Fixed 'grep -q -i B some_file' so it works | 87 | * Fixed 'grep -q -i B some_file' so it works |
88 | * math takes input from stdin if no args are given. -- John Beppu | 88 | * math takes input from stdin if no args are given. -- John Beppu |
89 | * math was renamed to dc. Although it deviates from dc's behaviour, | ||
90 | this will probably be remedied in the future. -- John Beppu | ||
89 | 91 | ||
90 | 92 | ||
91 | -Erik Andersen | 93 | -Erik Andersen |
diff --git a/applets/busybox.c b/applets/busybox.c index 191dee13f..221ef2a65 100644 --- a/applets/busybox.c +++ b/applets/busybox.c | |||
@@ -72,6 +72,9 @@ const struct BB_applet applets[] = { | |||
72 | #ifdef BB_DATE | 72 | #ifdef BB_DATE |
73 | {"date", date_main, _BB_DIR_BIN}, | 73 | {"date", date_main, _BB_DIR_BIN}, |
74 | #endif | 74 | #endif |
75 | #ifdef BB_DC | ||
76 | {"dc", dc_main, _BB_DIR_USR_BIN}, | ||
77 | #endif | ||
75 | #ifdef BB_DD | 78 | #ifdef BB_DD |
76 | {"dd", dd_main, _BB_DIR_BIN}, | 79 | {"dd", dd_main, _BB_DIR_BIN}, |
77 | #endif | 80 | #endif |
@@ -72,6 +72,9 @@ const struct BB_applet applets[] = { | |||
72 | #ifdef BB_DATE | 72 | #ifdef BB_DATE |
73 | {"date", date_main, _BB_DIR_BIN}, | 73 | {"date", date_main, _BB_DIR_BIN}, |
74 | #endif | 74 | #endif |
75 | #ifdef BB_DC | ||
76 | {"dc", dc_main, _BB_DIR_USR_BIN}, | ||
77 | #endif | ||
75 | #ifdef BB_DD | 78 | #ifdef BB_DD |
76 | {"dd", dd_main, _BB_DIR_BIN}, | 79 | {"dd", dd_main, _BB_DIR_BIN}, |
77 | #endif | 80 | #endif |
diff --git a/busybox.def.h b/busybox.def.h index d7756a498..89172ea98 100644 --- a/busybox.def.h +++ b/busybox.def.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define BB_CP_MV | 17 | #define BB_CP_MV |
18 | #define BB_CUT | 18 | #define BB_CUT |
19 | #define BB_DATE | 19 | #define BB_DATE |
20 | #define BB_DC | ||
20 | #define BB_DD | 21 | #define BB_DD |
21 | #define BB_DEALLOCVT | 22 | #define BB_DEALLOCVT |
22 | #define BB_DF | 23 | #define BB_DF |
@@ -54,7 +55,6 @@ | |||
54 | #define BB_LS | 55 | #define BB_LS |
55 | #define BB_LSMOD | 56 | #define BB_LSMOD |
56 | #define BB_MAKEDEVS | 57 | #define BB_MAKEDEVS |
57 | #define BB_MATH | ||
58 | //#define BB_MD5SUM | 58 | //#define BB_MD5SUM |
59 | #define BB_MKDIR | 59 | #define BB_MKDIR |
60 | #define BB_MKFIFO | 60 | #define BB_MKFIFO |
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ | 9 | /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ |
10 | 10 | ||
11 | static const char math_usage[] = "math expression ...\n" | 11 | static const char dc_usage[] = "math expression ...\n" |
12 | #ifndef BB_FEATURE_TRIVIAL_HELP | 12 | #ifndef BB_FEATURE_TRIVIAL_HELP |
13 | "\nThis is a Tiny RPN calculator that understands the\n" | 13 | "\nThis is a Tiny RPN calculator that understands the\n" |
14 | "following operations: +, -, /, *, and, or, not, eor.\n" | 14 | "following operations: +, -, /, *, and, or, not, eor.\n" |
@@ -162,7 +162,7 @@ static int number_of_tokens(char *buffer) | |||
162 | return i; | 162 | return i; |
163 | } | 163 | } |
164 | 164 | ||
165 | int math_main(int argc, char **argv) | 165 | int dc_main(int argc, char **argv) |
166 | { | 166 | { |
167 | /* take stuff from stdin if no args are given */ | 167 | /* take stuff from stdin if no args are given */ |
168 | if (argc <= 1) { | 168 | if (argc <= 1) { |
@@ -182,7 +182,7 @@ int math_main(int argc, char **argv) | |||
182 | } | 182 | } |
183 | } else { | 183 | } else { |
184 | if (*argv[1]=='-') | 184 | if (*argv[1]=='-') |
185 | usage(math_usage); | 185 | usage(dc_usage); |
186 | while (argc >= 2) { | 186 | while (argc >= 2) { |
187 | stack_machine(argv[1]); | 187 | stack_machine(argv[1]); |
188 | argv++; | 188 | argv++; |
diff --git a/docs/busybox.pod b/docs/busybox.pod index 8b1b7155f..75763d33f 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod | |||
@@ -313,6 +313,32 @@ Example: | |||
313 | 313 | ||
314 | ------------------------------- | 314 | ------------------------------- |
315 | 315 | ||
316 | =item dc | ||
317 | |||
318 | Usage: dc expression ... | ||
319 | |||
320 | This is a Tiny RPN calculator that understands the | ||
321 | following operations: +, -, /, *, and, or, not, eor. | ||
322 | If no arguments are given, dc will process input from STDIN. | ||
323 | |||
324 | The behaviour of BusyBox/dc deviates (just a little ;-) from | ||
325 | GNU/dc, but this will be remedied in the future. | ||
326 | |||
327 | Example: | ||
328 | |||
329 | $ dc 2 2 + | ||
330 | 4 | ||
331 | $ dc 8 8 \* 2 2 + / | ||
332 | 16 | ||
333 | $ dc 0 1 and | ||
334 | 0 | ||
335 | $ dc 0 1 or | ||
336 | 1 | ||
337 | $ echo 72 9 div 8 mul | dc | ||
338 | 64 | ||
339 | |||
340 | ------------------------------- | ||
341 | |||
316 | =item dd | 342 | =item dd |
317 | 343 | ||
318 | Usage: dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n] | 344 | Usage: dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n] |
@@ -1012,29 +1038,6 @@ Example: | |||
1012 | 1038 | ||
1013 | ------------------------------- | 1039 | ------------------------------- |
1014 | 1040 | ||
1015 | =item math | ||
1016 | |||
1017 | Usage: math expression ... | ||
1018 | |||
1019 | This is a Tiny RPN calculator that understands the | ||
1020 | following operations: +, -, /, *, and, or, not, eor. | ||
1021 | If no arguments are given, math will process input from STDIN. | ||
1022 | |||
1023 | Example: | ||
1024 | |||
1025 | $ math 2 2 + | ||
1026 | 4 | ||
1027 | $ math 8 8 \* 2 2 + / | ||
1028 | 16 | ||
1029 | $ math 0 1 and | ||
1030 | 0 | ||
1031 | $ math 0 1 or | ||
1032 | 1 | ||
1033 | $ echo 72 9 / | math | ||
1034 | 8 | ||
1035 | |||
1036 | ------------------------------- | ||
1037 | |||
1038 | =item md5sum | 1041 | =item md5sum |
1039 | 1042 | ||
1040 | Usage: md5sum [OPTION] [file ...] | 1043 | Usage: md5sum [OPTION] [file ...] |
@@ -2021,4 +2024,4 @@ Enrique Zanardi <ezanardi@ull.es> | |||
2021 | 2024 | ||
2022 | =cut | 2025 | =cut |
2023 | 2026 | ||
2024 | # $Id: busybox.pod,v 1.43 2000/06/20 00:11:07 proski Exp $ | 2027 | # $Id: busybox.pod,v 1.44 2000/06/21 19:06:16 beppu Exp $ |
diff --git a/internal.h b/internal.h index 50bb17a10..58f68f59b 100644 --- a/internal.h +++ b/internal.h | |||
@@ -113,6 +113,7 @@ extern int clear_main(int argc, char** argv); | |||
113 | extern int cp_mv_main(int argc, char** argv); | 113 | extern int cp_mv_main(int argc, char** argv); |
114 | extern int cut_main(int argc, char** argv); | 114 | extern int cut_main(int argc, char** argv); |
115 | extern int date_main(int argc, char** argv); | 115 | extern int date_main(int argc, char** argv); |
116 | extern int dc_main(int argc, char** argv); | ||
116 | extern int dd_main(int argc, char** argv); | 117 | extern int dd_main(int argc, char** argv); |
117 | extern int dirname_main(int argc, char** argv); | 118 | extern int dirname_main(int argc, char** argv); |
118 | extern int deallocvt_main(int argc, char** argv); | 119 | extern int deallocvt_main(int argc, char** argv); |
diff --git a/miscutils/dc.c b/miscutils/dc.c new file mode 100644 index 000000000..37c7731d2 --- /dev/null +++ b/miscutils/dc.c | |||
@@ -0,0 +1,194 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | #include "internal.h" | ||
3 | #include <ctype.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <unistd.h> | ||
7 | #include <math.h> | ||
8 | |||
9 | /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ | ||
10 | |||
11 | static const char dc_usage[] = "math expression ...\n" | ||
12 | #ifndef BB_FEATURE_TRIVIAL_HELP | ||
13 | "\nThis is a Tiny RPN calculator that understands the\n" | ||
14 | "following operations: +, -, /, *, and, or, not, eor.\n" | ||
15 | "i.e. 'math 2 2 add' -> 4, and 'math 8 8 \\* 2 2 + /' -> 16\n" | ||
16 | #endif | ||
17 | ; | ||
18 | |||
19 | static double stack[100]; | ||
20 | static unsigned int pointer; | ||
21 | |||
22 | static void push(double a) | ||
23 | { | ||
24 | if (pointer >= (sizeof(stack) / sizeof(*stack))) { | ||
25 | fprintf(stderr, "math: stack overflow\n"); | ||
26 | exit(-1); | ||
27 | } else | ||
28 | stack[pointer++] = a; | ||
29 | } | ||
30 | |||
31 | static double pop() | ||
32 | { | ||
33 | if (pointer == 0) { | ||
34 | fprintf(stderr, "math: stack underflow\n"); | ||
35 | exit(-1); | ||
36 | } | ||
37 | return stack[--pointer]; | ||
38 | } | ||
39 | |||
40 | static void add() | ||
41 | { | ||
42 | push(pop() + pop()); | ||
43 | } | ||
44 | |||
45 | static void sub() | ||
46 | { | ||
47 | double subtrahend = pop(); | ||
48 | |||
49 | push(pop() - subtrahend); | ||
50 | } | ||
51 | |||
52 | static void mul() | ||
53 | { | ||
54 | push(pop() * pop()); | ||
55 | } | ||
56 | |||
57 | static void divide() | ||
58 | { | ||
59 | double divisor = pop(); | ||
60 | |||
61 | push(pop() / divisor); | ||
62 | } | ||
63 | |||
64 | static void and() | ||
65 | { | ||
66 | push((unsigned int) pop() & (unsigned int) pop()); | ||
67 | } | ||
68 | |||
69 | static void or() | ||
70 | { | ||
71 | push((unsigned int) pop() | (unsigned int) pop()); | ||
72 | } | ||
73 | |||
74 | static void eor() | ||
75 | { | ||
76 | push((unsigned int) pop() ^ (unsigned int) pop()); | ||
77 | } | ||
78 | |||
79 | static void not() | ||
80 | { | ||
81 | push(~(unsigned int) pop()); | ||
82 | } | ||
83 | |||
84 | static void print() | ||
85 | { | ||
86 | printf("%g\n", pop()); | ||
87 | } | ||
88 | |||
89 | struct op { | ||
90 | const char *name; | ||
91 | void (*function) (); | ||
92 | }; | ||
93 | |||
94 | static const struct op operators[] = { | ||
95 | {"+", add}, | ||
96 | {"add", add}, | ||
97 | {"-", sub}, | ||
98 | {"sub", sub}, | ||
99 | {"*", mul}, | ||
100 | {"mul", mul}, | ||
101 | {"/", divide}, | ||
102 | {"div", divide}, | ||
103 | {"and", and}, | ||
104 | {"or", or}, | ||
105 | {"not", not}, | ||
106 | {"eor", eor}, | ||
107 | {0, 0} | ||
108 | }; | ||
109 | |||
110 | static void stack_machine(const char *argument) | ||
111 | { | ||
112 | char *endPointer = 0; | ||
113 | double d; | ||
114 | const struct op *o = operators; | ||
115 | |||
116 | if (argument == 0) { | ||
117 | print(); | ||
118 | return; | ||
119 | } | ||
120 | |||
121 | d = strtod(argument, &endPointer); | ||
122 | |||
123 | if (endPointer != argument) { | ||
124 | push(d); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | while (o->name != 0) { | ||
129 | if (strcmp(o->name, argument) == 0) { | ||
130 | (*(o->function)) (); | ||
131 | return; | ||
132 | } | ||
133 | o++; | ||
134 | } | ||
135 | fprintf(stderr, "math: %s: syntax error.\n", argument); | ||
136 | exit(-1); | ||
137 | } | ||
138 | |||
139 | /* return pointer to next token in buffer and set *buffer to one char | ||
140 | * past the end of the above mentioned token | ||
141 | */ | ||
142 | static char *get_token(char **buffer) | ||
143 | { | ||
144 | char *start = NULL; | ||
145 | char *current = *buffer; | ||
146 | |||
147 | while (isspace(*current)) { current++; } | ||
148 | if (*current != 0) { | ||
149 | start = current; | ||
150 | while (!isspace(*current) && current != 0) { current++; } | ||
151 | *buffer = current; | ||
152 | } | ||
153 | return start; | ||
154 | } | ||
155 | |||
156 | /* In Perl one might say, scalar m|\s*(\S+)\s*|g */ | ||
157 | static int number_of_tokens(char *buffer) | ||
158 | { | ||
159 | int i = 0; | ||
160 | char *b = buffer; | ||
161 | while (get_token(&b)) { i++; } | ||
162 | return i; | ||
163 | } | ||
164 | |||
165 | int dc_main(int argc, char **argv) | ||
166 | { | ||
167 | /* take stuff from stdin if no args are given */ | ||
168 | if (argc <= 1) { | ||
169 | int i, len; | ||
170 | char *line = NULL; | ||
171 | char *cursor = NULL; | ||
172 | char *token = NULL; | ||
173 | while ((line = cstring_lineFromFile(stdin))) { | ||
174 | cursor = line; | ||
175 | len = number_of_tokens(line); | ||
176 | for (i = 0; i < len; i++) { | ||
177 | token = get_token(&cursor); | ||
178 | *cursor++ = 0; | ||
179 | stack_machine(token); | ||
180 | } | ||
181 | free(line); | ||
182 | } | ||
183 | } else { | ||
184 | if (*argv[1]=='-') | ||
185 | usage(dc_usage); | ||
186 | while (argc >= 2) { | ||
187 | stack_machine(argv[1]); | ||
188 | argv++; | ||
189 | argc--; | ||
190 | } | ||
191 | } | ||
192 | stack_machine(0); | ||
193 | return( TRUE); | ||
194 | } | ||