+ added dc (aka the function formerly known as math)
+ did all the housekeeping that this change requires.
This commit is contained in:
		| @@ -86,6 +86,8 @@ | |||||||
| 	* Fixed grep "Line too long" problem -- John Beppu | 	* Fixed grep "Line too long" problem -- John Beppu | ||||||
| 	* Fixed 'grep -q -i B some_file' so it works | 	* Fixed 'grep -q -i B some_file' so it works | ||||||
| 	* math takes input from stdin if no args are given.  -- John Beppu | 	* math takes input from stdin if no args are given.  -- John Beppu | ||||||
|  | 	* math was renamed to dc.  Although it deviates from dc's behaviour, | ||||||
|  | 	    this will probably be remedied in the future.  -- John Beppu | ||||||
|  |  | ||||||
|  |  | ||||||
| 	 -Erik Andersen | 	 -Erik Andersen | ||||||
|   | |||||||
| @@ -72,6 +72,9 @@ const struct BB_applet applets[] = { | |||||||
| #ifdef BB_DATE | #ifdef BB_DATE | ||||||
| 	{"date", date_main, _BB_DIR_BIN}, | 	{"date", date_main, _BB_DIR_BIN}, | ||||||
| #endif | #endif | ||||||
|  | #ifdef BB_DC | ||||||
|  | 	{"dc", dc_main, _BB_DIR_USR_BIN}, | ||||||
|  | #endif | ||||||
| #ifdef BB_DD | #ifdef BB_DD | ||||||
| 	{"dd", dd_main, _BB_DIR_BIN}, | 	{"dd", dd_main, _BB_DIR_BIN}, | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -72,6 +72,9 @@ const struct BB_applet applets[] = { | |||||||
| #ifdef BB_DATE | #ifdef BB_DATE | ||||||
| 	{"date", date_main, _BB_DIR_BIN}, | 	{"date", date_main, _BB_DIR_BIN}, | ||||||
| #endif | #endif | ||||||
|  | #ifdef BB_DC | ||||||
|  | 	{"dc", dc_main, _BB_DIR_USR_BIN}, | ||||||
|  | #endif | ||||||
| #ifdef BB_DD | #ifdef BB_DD | ||||||
| 	{"dd", dd_main, _BB_DIR_BIN}, | 	{"dd", dd_main, _BB_DIR_BIN}, | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ | |||||||
| #define BB_CP_MV | #define BB_CP_MV | ||||||
| #define BB_CUT | #define BB_CUT | ||||||
| #define BB_DATE | #define BB_DATE | ||||||
|  | #define BB_DC | ||||||
| #define BB_DD | #define BB_DD | ||||||
| #define BB_DEALLOCVT | #define BB_DEALLOCVT | ||||||
| #define BB_DF | #define BB_DF | ||||||
| @@ -54,7 +55,6 @@ | |||||||
| #define BB_LS | #define BB_LS | ||||||
| #define BB_LSMOD | #define BB_LSMOD | ||||||
| #define BB_MAKEDEVS | #define BB_MAKEDEVS | ||||||
| #define BB_MATH |  | ||||||
| //#define BB_MD5SUM | //#define BB_MD5SUM | ||||||
| #define BB_MKDIR | #define BB_MKDIR | ||||||
| #define BB_MKFIFO | #define BB_MKFIFO | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| 
 | 
 | ||||||
| /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ | /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ | ||||||
| 
 | 
 | ||||||
| static const char math_usage[] = "math expression ...\n" | static const char dc_usage[] = "math expression ...\n" | ||||||
| #ifndef BB_FEATURE_TRIVIAL_HELP | #ifndef BB_FEATURE_TRIVIAL_HELP | ||||||
| 		"\nThis is a Tiny RPN calculator that understands the\n" | 		"\nThis is a Tiny RPN calculator that understands the\n" | ||||||
| 		"following operations: +, -, /, *, and, or, not, eor.\n" | 		"following operations: +, -, /, *, and, or, not, eor.\n" | ||||||
| @@ -162,7 +162,7 @@ static int number_of_tokens(char *buffer) | |||||||
| 	return i; | 	return i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int math_main(int argc, char **argv) | int dc_main(int argc, char **argv) | ||||||
| { | { | ||||||
| 	/* take stuff from stdin if no args are given */ | 	/* take stuff from stdin if no args are given */ | ||||||
| 	if (argc <= 1) { | 	if (argc <= 1) { | ||||||
| @@ -182,7 +182,7 @@ int math_main(int argc, char **argv) | |||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if (*argv[1]=='-') | 		if (*argv[1]=='-') | ||||||
| 			usage(math_usage); | 			usage(dc_usage); | ||||||
| 		while (argc >= 2) { | 		while (argc >= 2) { | ||||||
| 			stack_machine(argv[1]); | 			stack_machine(argv[1]); | ||||||
| 			argv++; | 			argv++; | ||||||
| @@ -313,6 +313,32 @@ Example: | |||||||
|  |  | ||||||
| ------------------------------- | ------------------------------- | ||||||
|  |  | ||||||
|  | =item dc | ||||||
|  |  | ||||||
|  | Usage: dc expression ... | ||||||
|  |  | ||||||
|  | This is a Tiny RPN calculator that understands the | ||||||
|  | following operations: +, -, /, *, and, or, not, eor. | ||||||
|  | If no arguments are given, dc will process input from STDIN. | ||||||
|  |  | ||||||
|  | The behaviour of BusyBox/dc deviates (just a little ;-) from | ||||||
|  | GNU/dc, but this will be remedied in the future. | ||||||
|  |  | ||||||
|  | Example: | ||||||
|  |  | ||||||
|  | 	$ dc 2 2 + | ||||||
|  | 	4 | ||||||
|  | 	$ dc 8 8 \* 2 2 + / | ||||||
|  | 	16 | ||||||
|  | 	$ dc 0 1 and | ||||||
|  | 	0 | ||||||
|  | 	$ dc 0 1 or | ||||||
|  | 	1 | ||||||
|  | 	$ echo 72 9 div 8 mul | dc | ||||||
|  | 	64 | ||||||
|  |  | ||||||
|  | ------------------------------- | ||||||
|  |  | ||||||
| =item dd | =item dd | ||||||
|  |  | ||||||
| Usage: dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n] | Usage: dd [if=name] [of=name] [bs=n] [count=n] [skip=n] [seek=n] | ||||||
| @@ -1012,29 +1038,6 @@ Example: | |||||||
|  |  | ||||||
| ------------------------------- | ------------------------------- | ||||||
|  |  | ||||||
| =item math |  | ||||||
|  |  | ||||||
| Usage: math expression ... |  | ||||||
|  |  | ||||||
| This is a Tiny RPN calculator that understands the |  | ||||||
| following operations: +, -, /, *, and, or, not, eor. |  | ||||||
| If no arguments are given, math will process input from STDIN. |  | ||||||
|  |  | ||||||
| Example: |  | ||||||
|  |  | ||||||
| 	$ math 2 2 + |  | ||||||
| 	4 |  | ||||||
| 	$ math 8 8 \* 2 2 + / |  | ||||||
| 	16 |  | ||||||
| 	$ math 0 1 and |  | ||||||
| 	0 |  | ||||||
| 	$ math 0 1 or |  | ||||||
| 	1 |  | ||||||
| 	$ echo 72 9 / | math |  | ||||||
| 	8 |  | ||||||
|  |  | ||||||
| ------------------------------- |  | ||||||
|  |  | ||||||
| =item md5sum | =item md5sum | ||||||
|  |  | ||||||
| Usage: md5sum [OPTION] [file ...] | Usage: md5sum [OPTION] [file ...] | ||||||
| @@ -2021,4 +2024,4 @@ Enrique Zanardi <ezanardi@ull.es> | |||||||
|  |  | ||||||
| =cut | =cut | ||||||
|  |  | ||||||
| # $Id: busybox.pod,v 1.43 2000/06/20 00:11:07 proski Exp $ | # $Id: busybox.pod,v 1.44 2000/06/21 19:06:16 beppu Exp $ | ||||||
|   | |||||||
| @@ -113,6 +113,7 @@ extern int clear_main(int argc, char** argv); | |||||||
| extern int cp_mv_main(int argc, char** argv); | extern int cp_mv_main(int argc, char** argv); | ||||||
| extern int cut_main(int argc, char** argv); | extern int cut_main(int argc, char** argv); | ||||||
| extern int date_main(int argc, char** argv); | extern int date_main(int argc, char** argv); | ||||||
|  | extern int dc_main(int argc, char** argv); | ||||||
| extern int dd_main(int argc, char** argv); | extern int dd_main(int argc, char** argv); | ||||||
| extern int dirname_main(int argc, char** argv); | extern int dirname_main(int argc, char** argv); | ||||||
| extern int deallocvt_main(int argc, char** argv); | extern int deallocvt_main(int argc, char** argv); | ||||||
|   | |||||||
							
								
								
									
										194
									
								
								miscutils/dc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								miscutils/dc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | |||||||
|  | /* vi: set sw=4 ts=4: */ | ||||||
|  | #include "internal.h" | ||||||
|  | #include <ctype.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <math.h> | ||||||
|  |  | ||||||
|  | /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ | ||||||
|  |  | ||||||
|  | static const char dc_usage[] = "math expression ...\n" | ||||||
|  | #ifndef BB_FEATURE_TRIVIAL_HELP | ||||||
|  | 		"\nThis is a Tiny RPN calculator that understands the\n" | ||||||
|  | 		"following operations: +, -, /, *, and, or, not, eor.\n" | ||||||
|  | 		"i.e. 'math 2 2 add' -> 4, and 'math 8 8 \\* 2 2 + /' -> 16\n" | ||||||
|  | #endif | ||||||
|  | 		; | ||||||
|  |  | ||||||
|  | static double stack[100]; | ||||||
|  | static unsigned int pointer; | ||||||
|  |  | ||||||
|  | static void push(double a) | ||||||
|  | { | ||||||
|  | 	if (pointer >= (sizeof(stack) / sizeof(*stack))) { | ||||||
|  | 		fprintf(stderr, "math: stack overflow\n"); | ||||||
|  | 		exit(-1); | ||||||
|  | 	} else | ||||||
|  | 		stack[pointer++] = a; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static double pop() | ||||||
|  | { | ||||||
|  | 	if (pointer == 0) { | ||||||
|  | 		fprintf(stderr, "math: stack underflow\n"); | ||||||
|  | 		exit(-1); | ||||||
|  | 	} | ||||||
|  | 	return stack[--pointer]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void add() | ||||||
|  | { | ||||||
|  | 	push(pop() + pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void sub() | ||||||
|  | { | ||||||
|  | 	double subtrahend = pop(); | ||||||
|  |  | ||||||
|  | 	push(pop() - subtrahend); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void mul() | ||||||
|  | { | ||||||
|  | 	push(pop() * pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void divide() | ||||||
|  | { | ||||||
|  | 	double divisor = pop(); | ||||||
|  |  | ||||||
|  | 	push(pop() / divisor); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void and() | ||||||
|  | { | ||||||
|  | 	push((unsigned int) pop() & (unsigned int) pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void or() | ||||||
|  | { | ||||||
|  | 	push((unsigned int) pop() | (unsigned int) pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void eor() | ||||||
|  | { | ||||||
|  | 	push((unsigned int) pop() ^ (unsigned int) pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void not() | ||||||
|  | { | ||||||
|  | 	push(~(unsigned int) pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void print() | ||||||
|  | { | ||||||
|  | 	printf("%g\n", pop()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct op { | ||||||
|  | 	const char *name; | ||||||
|  | 	void (*function) (); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const struct op operators[] = { | ||||||
|  | 	{"+",   add}, | ||||||
|  | 	{"add", add}, | ||||||
|  | 	{"-",   sub}, | ||||||
|  | 	{"sub", sub}, | ||||||
|  | 	{"*",   mul}, | ||||||
|  | 	{"mul", mul}, | ||||||
|  | 	{"/",   divide}, | ||||||
|  | 	{"div", divide}, | ||||||
|  | 	{"and", and}, | ||||||
|  | 	{"or",  or}, | ||||||
|  | 	{"not", not}, | ||||||
|  | 	{"eor", eor}, | ||||||
|  | 	{0,     0} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void stack_machine(const char *argument) | ||||||
|  | { | ||||||
|  | 	char *endPointer = 0; | ||||||
|  | 	double d; | ||||||
|  | 	const struct op *o = operators; | ||||||
|  |  | ||||||
|  | 	if (argument == 0) { | ||||||
|  | 		print(); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	d = strtod(argument, &endPointer); | ||||||
|  |  | ||||||
|  | 	if (endPointer != argument) { | ||||||
|  | 		push(d); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	while (o->name != 0) { | ||||||
|  | 		if (strcmp(o->name, argument) == 0) { | ||||||
|  | 			(*(o->function)) (); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		o++; | ||||||
|  | 	} | ||||||
|  | 	fprintf(stderr, "math: %s: syntax error.\n", argument); | ||||||
|  | 	exit(-1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* return pointer to next token in buffer and set *buffer to one char | ||||||
|  |  * past the end of the above mentioned token  | ||||||
|  |  */ | ||||||
|  | static char *get_token(char **buffer) | ||||||
|  | { | ||||||
|  | 	char *start   = NULL; | ||||||
|  | 	char *current = *buffer; | ||||||
|  |  | ||||||
|  | 	while (isspace(*current)) { current++; } | ||||||
|  | 	if (*current != 0) { | ||||||
|  | 		start = current; | ||||||
|  | 		while (!isspace(*current) && current != 0) { current++; } | ||||||
|  | 		*buffer = current; | ||||||
|  | 	} | ||||||
|  | 	return start; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* In Perl one might say, scalar m|\s*(\S+)\s*|g */ | ||||||
|  | static int number_of_tokens(char *buffer) | ||||||
|  | { | ||||||
|  | 	int   i = 0; | ||||||
|  | 	char *b = buffer; | ||||||
|  | 	while (get_token(&b)) { i++; } | ||||||
|  | 	return i; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int dc_main(int argc, char **argv) | ||||||
|  | { | ||||||
|  | 	/* take stuff from stdin if no args are given */ | ||||||
|  | 	if (argc <= 1) { | ||||||
|  | 		int i, len; | ||||||
|  | 		char *line   = NULL; | ||||||
|  | 		char *cursor = NULL; | ||||||
|  | 		char *token  = NULL; | ||||||
|  | 		while ((line = cstring_lineFromFile(stdin))) { | ||||||
|  | 			cursor = line; | ||||||
|  | 			len = number_of_tokens(line); | ||||||
|  | 			for (i = 0; i < len; i++) { | ||||||
|  | 				token = get_token(&cursor); | ||||||
|  | 				*cursor++ = 0; | ||||||
|  | 				stack_machine(token); | ||||||
|  | 			} | ||||||
|  | 			free(line); | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if (*argv[1]=='-') | ||||||
|  | 			usage(dc_usage); | ||||||
|  | 		while (argc >= 2) { | ||||||
|  | 			stack_machine(argv[1]); | ||||||
|  | 			argv++; | ||||||
|  | 			argc--; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	stack_machine(0); | ||||||
|  | 	return( TRUE); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user