[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