+ 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 -q -i B some_file' so it works | ||||
| 	* 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 | ||||
|   | ||||
| @@ -72,6 +72,9 @@ const struct BB_applet applets[] = { | ||||
| #ifdef BB_DATE | ||||
| 	{"date", date_main, _BB_DIR_BIN}, | ||||
| #endif | ||||
| #ifdef BB_DC | ||||
| 	{"dc", dc_main, _BB_DIR_USR_BIN}, | ||||
| #endif | ||||
| #ifdef BB_DD | ||||
| 	{"dd", dd_main, _BB_DIR_BIN}, | ||||
| #endif | ||||
|   | ||||
| @@ -72,6 +72,9 @@ const struct BB_applet applets[] = { | ||||
| #ifdef BB_DATE | ||||
| 	{"date", date_main, _BB_DIR_BIN}, | ||||
| #endif | ||||
| #ifdef BB_DC | ||||
| 	{"dc", dc_main, _BB_DIR_USR_BIN}, | ||||
| #endif | ||||
| #ifdef BB_DD | ||||
| 	{"dd", dd_main, _BB_DIR_BIN}, | ||||
| #endif | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| #define BB_CP_MV | ||||
| #define BB_CUT | ||||
| #define BB_DATE | ||||
| #define BB_DC | ||||
| #define BB_DD | ||||
| #define BB_DEALLOCVT | ||||
| #define BB_DF | ||||
| @@ -54,7 +55,6 @@ | ||||
| #define BB_LS | ||||
| #define BB_LSMOD | ||||
| #define BB_MAKEDEVS | ||||
| #define BB_MATH | ||||
| //#define BB_MD5SUM | ||||
| #define BB_MKDIR | ||||
| #define BB_MKFIFO | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| 
 | ||||
| /* 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 | ||||
| 		"\nThis is a Tiny RPN calculator that understands the\n" | ||||
| 		"following operations: +, -, /, *, and, or, not, eor.\n" | ||||
| @@ -162,7 +162,7 @@ static int number_of_tokens(char *buffer) | ||||
| 	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 */ | ||||
| 	if (argc <= 1) { | ||||
| @@ -182,7 +182,7 @@ int math_main(int argc, char **argv) | ||||
| 		} | ||||
| 	} else { | ||||
| 		if (*argv[1]=='-') | ||||
| 			usage(math_usage); | ||||
| 			usage(dc_usage); | ||||
| 		while (argc >= 2) { | ||||
| 			stack_machine(argv[1]); | ||||
| 			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 | ||||
|  | ||||
| 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 | ||||
|  | ||||
| Usage: md5sum [OPTION] [file ...] | ||||
| @@ -2021,4 +2024,4 @@ Enrique Zanardi <ezanardi@ull.es> | ||||
|  | ||||
| =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 cut_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 dirname_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