[BusyBox] Today's ash improvements

Aaron Lehmann aaronl at vitelus.com
Fri Aug 3 10:54:09 UTC 2001


This patch contains three distinct size optimizations:

1) is_digit() uses only one comparison now. ((c)>='0' && (c)<='9') was
replaced with ((unsigned)(c) - '0' <= 9). Neat trick, eh?

2) The 257 byte is_type table was replaced by a few simple tests.
is_special was changed from ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
to (is_digit(c)||c=='!'||c=='#'||c=='$'||c=='*'||c=='-').

3) tokendlist was changed from a 30 byte array of booleans (chars) to
a 30 bit bitmask.


As always, no guarentees. I played around interactively and ran the
test script, but who knows what could go wrong?
-------------- next part --------------
Index: ash.c
===================================================================
RCS file: /var/cvs/busybox/ash.c,v
retrieving revision 1.17
diff -u -r1.17 ash.c
--- ash.c	2001/08/02 05:02:45	1.17
+++ ash.c	2001/08/03 16:44:12
@@ -202,11 +202,11 @@
 #define CTLENDARI '\207'
 #define CTLQUOTEMARK '\210'
 
-#define is_digit(c)     ((c)>='0' && (c)<='9')
+#define is_digit(c)     ((unsigned)(c) - '0' <= 9)
 #define is_alpha(c)     (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))
 #define is_name(c)      (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))
 #define is_in_name(c)   (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))
-#define is_special(c)   ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
+#define is_special(c)   (is_digit(c)||c=='!'||c=='#'||c=='$'||c=='*'||c=='-')
 #define digit_val(c)    ((c) - '0')
 
 
@@ -973,108 +973,9 @@
       CWORD
 };
 
-/* character classification table */
-static const char is_type[257] = {
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       0,
-      0,       0,       0,       ISSPECL,
-      0,       ISSPECL, ISSPECL, 0,
-      0,       0,       0,       0,
-      ISSPECL, 0,       0,       ISSPECL,
-      0,       0,       ISDIGIT, ISDIGIT,
-      ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
-      ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
-      0,       0,       0,       0,
-      0,       ISSPECL, ISSPECL, ISUPPER,
-      ISUPPER, ISUPPER, ISUPPER, ISUPPER,
-      ISUPPER, ISUPPER, ISUPPER, ISUPPER,
-      ISUPPER, ISUPPER, ISUPPER, ISUPPER,
-      ISUPPER, ISUPPER, ISUPPER, ISUPPER,
-      ISUPPER, ISUPPER, ISUPPER, ISUPPER,
-      ISUPPER, ISUPPER, ISUPPER, ISUPPER,
-      ISUPPER, 0,       0,       0,
-      0,       ISUNDER, 0,       ISLOWER,
-      ISLOWER, ISLOWER, ISLOWER, ISLOWER,
-      ISLOWER, ISLOWER, ISLOWER, ISLOWER,
-      ISLOWER, ISLOWER, ISLOWER, ISLOWER,
-      ISLOWER, ISLOWER, ISLOWER, ISLOWER,
-      ISLOWER, ISLOWER, ISLOWER, ISLOWER,
-      ISLOWER, ISLOWER, ISLOWER, ISLOWER,
-      ISLOWER, 0,       0,       0,
-      0
-};
-
-/* Array indicating which tokens mark the end of a list */
-static const char tokendlist[] = {
-	1,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	1,
-	1,
-	1,
-	0,
-	0,
-	0,
-	0,
-	0,
-	1,
-	1,
-	1,
-	1,
-	1,
-	1,
-	0,
-	0,
-	0,
-	1,
-	0,
-	0,
-	0,
-	1,
-};
+/* Bitmask indicating which tokens mark the end of a list */
+/* Equivilent to binary 100000001110000011111100010001 */
+static const unsigned int tokendlist = 0x20383F11;
 
 static const char *const tokname[] = {
 	"end of file",
@@ -9391,7 +9292,7 @@
 	int tok;
 
 	checkkwd = 2;
-	if (nlflag == 0 && tokendlist[peektoken()])
+	if (nlflag == 0 && (tokendlist & (0x20000000 >> peektoken())))
 		return NULL;
 	n1 = NULL;
 	for (;;) {
@@ -9434,7 +9335,7 @@
 				tokpushback++;
 			}
 			checkkwd = 2;
-			if (tokendlist[peektoken()])
+			if (tokendlist & (0x20000000 >> peektoken()))
 				return n1;
 			break;
 		case TEOF:


More information about the busybox mailing list