[BusyBox] tr argumnent processing

Rainer Weikusat rainer.weikusat at sncag.com
Tue Jul 26 17:12:34 UTC 2005


The busybox tr understands exactly one argument with support for
switch clustering, it does not understand the conventional '--' for
"stop with option processing" and using a single hyphen instead of an
actual option does neither result in an error message nor is the
obvious use (instead of '--' to terminate option processing)
documented. The patch below changes tr.c to accept multiple arguments,
to print a usage message whenever an undocumented or incomplete option
is encountered and to accept '--' for its "usual"
purpose. Additionally, it does away with the pointless Pascalisms in
the argument processing (one variable less), prints a usage message
when called with no arguments and corrects the verb in one of the
error messages.

Index: busybox/coreutils/tr.c
===================================================================
RCS file: /data/repo/busybox/coreutils/tr.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- busybox/coreutils/tr.c	26 Jul 2005 15:51:11 -0000	1.4
+++ busybox/coreutils/tr.c	26 Jul 2005 15:52:07 -0000	1.5
@@ -152,8 +152,7 @@
 extern int tr_main(int argc, char **argv)
 {
 	register unsigned char *ptr;
-	int output_length=0, input_length;
-	int idx = 1;
+	int output_length = 0, input_length;
 	int i;
 	RESERVE_CONFIG_BUFFER(output, BUFSIZ);
 	RESERVE_CONFIG_BUFFER(input,  BUFSIZ);
@@ -168,43 +167,55 @@
 	pinvec  = invec;
 	poutvec = outvec;
 
-	if (argc > 1 && argv[idx][0] == '-') {
-		for (ptr = (unsigned char *) &argv[idx][1]; *ptr; ptr++) {
-			switch (*ptr) {
-			case 'c':
-				com_fl = TRUE;
-				break;
-			case 'd':
-				del_fl = TRUE;
-				break;
-			case 's':
-				sq_fl = TRUE;
-				break;
-			default:
-				bb_show_usage();
-			}
-		}
-		idx++;
+	if (argc == 1) goto show_usage;
+	
+	while (--argc && **++argv == '-') {
+		ptr = *argv + 1;
+		
+		do switch (*ptr) {
+		case 'c':
+			com_fl = TRUE;
+			break;
+
+		case 'd':
+			del_fl = TRUE;
+			break;
+
+		case 's':
+			sq_fl = TRUE;
+			break;
+
+		case '-':
+			goto start_processing;
+
+		default:
+		show_usage:
+			bb_show_usage();
+		} while (*++ptr);
 	}
+
+ start_processing:
 	for (i = 0; i <= ASCII; i++) {
 		vector[i] = i;
 		invec[i] = outvec[i] = FALSE;
 	}
-
-	if (argv[idx] != NULL) {
-		input_length = expand(argv[idx++], input);
+	if (*argv) {
+		input_length = expand(*argv, input);
+		++argv;
+		
 		if (com_fl)
 			input_length = complement(input, input_length);
-		if (argv[idx] != NULL) {
-			if (*argv[idx] == '\0')
-				bb_error_msg_and_die("STRING2 cannot be empty");
-			output_length = expand(argv[idx], output);
+		if (*argv) {
+			if (!**argv)
+				bb_error_msg_and_die("STRING2 must not be empty");
+			
+			output_length = expand(*argv, output);
 			map(input, input_length, output, output_length);
 		}
 		for (i = 0; i < input_length; i++)
-			invec[(unsigned char)input[i]] = TRUE;
+			invec[(unsigned)input[i]] = TRUE;
 		for (i = 0; i < output_length; i++)
-			outvec[(unsigned char)output[i]] = TRUE;
+			outvec[(unsigned)output[i]] = TRUE;
 	}
 	convert();
 	return (0);
@@ -245,4 +256,3 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
-
Index: busybox/include/usage.h
===================================================================
RCS file: /data/repo/busybox/include/usage.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- busybox/include/usage.h	26 Jul 2005 15:51:11 -0000	1.13
+++ busybox/include/usage.h	26 Jul 2005 15:52:07 -0000	1.14
@@ -2874,7 +2874,8 @@
 	"Options:\n" \
 	"\t-c\ttake complement of STRING1\n" \
 	"\t-d\tdelete input characters coded STRING1\n" \
-	"\t-s\tsqueeze multiple output characters of STRING2 into one character"
+	"\t-s\tsqueeze multiple output characters of STRING2 into one character\n" \
+	"\t--\tterminate option processing"
 #define tr_example_usage \
 	"$ echo \"gdkkn vnqkc\" | tr [a-y] [b-z]\n" \
 	"hello world\n"



More information about the busybox mailing list