summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2016-10-02 16:54:17 +0200
committerDenys Vlasenko2016-10-02 16:54:17 +0200
commit888527cceec2f58f1eae3acceddee928b5cb647a (patch)
treef4ef6c2a33a1391bfe4e9f408b15e0f36e8e21b4
parentbc1a00843fce8ce0ed101c4e6eb02ee79e673a00 (diff)
downloadbusybox-888527cceec2f58f1eae3acceddee928b5cb647a.zip
busybox-888527cceec2f58f1eae3acceddee928b5cb647a.tar.gz
ash: undo "tokname hack"
dash has tokendlist[] array to decide which tokens end lists. We store it as first byte of each tokname_array[i]. Switch to bit array, name it like dash (tokendlist), drop special 1st byte of tokname_array[i]. This brings us closer to dash, and shrinks the binary, because many more string aliasing opportunities are now open: function old new delta pstrcmp1 - 16 +16 readtoken1 2852 2858 +6 list 326 327 +1 pstrcmp 16 15 -1 tokname 45 42 -3 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/2 up/down: 23/-4) Total: 19 bytes text data bss dec hex filename 943556 916 14292 958764 ea12c busybox_old 943463 916 14292 958671 ea0cf busybox_unstripped ^^^^^^^ note this! Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c124
1 files changed, 83 insertions, 41 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 41ae5cb..421639e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -7881,49 +7881,86 @@ enum {
};
typedef smallint token_id_t;
-/* first char is indicating which tokens mark the end of a list */
+/* Nth bit indicates if token marks the end of a list */
+enum {
+ tokendlist = 0
+ /* 0 */ | (1u << TEOF)
+ /* 1 */ | (0u << TNL)
+ /* 2 */ | (0u << TREDIR)
+ /* 3 */ | (0u << TWORD)
+ /* 4 */ | (0u << TSEMI)
+ /* 5 */ | (0u << TBACKGND)
+ /* 6 */ | (0u << TAND)
+ /* 7 */ | (0u << TOR)
+ /* 8 */ | (0u << TPIPE)
+ /* 9 */ | (0u << TLP)
+ /* 10 */ | (1u << TRP)
+ /* 11 */ | (1u << TENDCASE)
+ /* 12 */ | (1u << TENDBQUOTE)
+ /* 13 */ | (0u << TNOT)
+ /* 14 */ | (0u << TCASE)
+ /* 15 */ | (1u << TDO)
+ /* 16 */ | (1u << TDONE)
+ /* 17 */ | (1u << TELIF)
+ /* 18 */ | (1u << TELSE)
+ /* 19 */ | (1u << TESAC)
+ /* 20 */ | (1u << TFI)
+ /* 21 */ | (0u << TFOR)
+#if ENABLE_ASH_BASH_COMPAT
+ /* 22 */ | (0u << TFUNCTION)
+#endif
+ /* 23 */ | (0u << TIF)
+ /* 24 */ | (0u << TIN)
+ /* 25 */ | (1u << TTHEN)
+ /* 26 */ | (0u << TUNTIL)
+ /* 27 */ | (0u << TWHILE)
+ /* 28 */ | (0u << TBEGIN)
+ /* 29 */ | (1u << TEND)
+ , /* thus far 29 bits used */
+};
+
static const char *const tokname_array[] = {
- "\1end of file",
- "\0newline",
- "\0redirection",
- "\0word",
- "\0;",
- "\0&",
- "\0&&",
- "\0||",
- "\0|",
- "\0(",
- "\1)",
- "\1;;",
- "\1`",
+ "end of file",
+ "newline",
+ "redirection",
+ "word",
+ ";",
+ "&",
+ "&&",
+ "||",
+ "|",
+ "(",
+ ")",
+ ";;",
+ "`",
#define KWDOFFSET 13
/* the following are keywords */
- "\0!",
- "\0case",
- "\1do",
- "\1done",
- "\1elif",
- "\1else",
- "\1esac",
- "\1fi",
- "\0for",
+ "!",
+ "case",
+ "do",
+ "done",
+ "elif",
+ "else",
+ "esac",
+ "fi",
+ "for",
#if ENABLE_ASH_BASH_COMPAT
- "\0function",
-#endif
- "\0if",
- "\0in",
- "\1then",
- "\0until",
- "\0while",
- "\0{",
- "\1}",
+ "function",
+#endif
+ "if",
+ "in",
+ "then",
+ "until",
+ "while",
+ "{",
+ "}",
};
/* Wrapper around strcmp for qsort/bsearch/... */
static int
pstrcmp(const void *a, const void *b)
{
- return strcmp((char*) a, (*(char**) b) + 1);
+ return strcmp((char*)a, *(char**)b);
}
static const char *const *
@@ -9339,6 +9376,11 @@ static const struct builtincmd builtintab[] = {
/*
* Search the table of builtin commands.
*/
+static int
+pstrcmp1(const void *a, const void *b)
+{
+ return strcmp((char*)a, *(char**)b + 1);
+}
static struct builtincmd *
find_builtin(const char *name)
{
@@ -9346,7 +9388,7 @@ find_builtin(const char *name)
bp = bsearch(
name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
- pstrcmp
+ pstrcmp1
);
return bp;
}
@@ -10669,8 +10711,8 @@ static const char *
tokname(char *buf, int tok)
{
if (tok < TSEMI)
- return tokname_array[tok] + 1;
- sprintf(buf, "\"%s\"", tokname_array[tok] + 1);
+ return tokname_array[tok];
+ sprintf(buf, "\"%s\"", tokname_array[tok]);
return buf;
}
@@ -10727,7 +10769,7 @@ list(int nlflag)
}
checkkwd = CHKNL | CHKKWD | CHKALIAS;
- if (nlflag == 2 && tokname_array[peektoken()][0])
+ if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
return n1;
nlflag |= 2;
@@ -11109,7 +11151,7 @@ parse_command(void)
n1->nbinary.ch1 = list(0);
got = readtoken();
if (got != TDO) {
- TRACE(("expecting DO got '%s' %s\n", tokname_array[got] + 1,
+ TRACE(("expecting DO got '%s' %s\n", tokname_array[got],
got == TWORD ? wordtext : ""));
raise_error_unexpected_syntax(TDO);
}
@@ -12156,7 +12198,7 @@ readtoken(void)
pp = findkwd(wordtext);
if (pp) {
lasttoken = t = pp - tokname_array;
- TRACE(("keyword '%s' recognized\n", tokname_array[t] + 1));
+ TRACE(("keyword '%s' recognized\n", tokname_array[t]));
goto out;
}
}
@@ -12177,9 +12219,9 @@ readtoken(void)
checkkwd = 0;
#if DEBUG
if (!alreadyseen)
- TRACE(("token '%s' %s\n", tokname_array[t] + 1, t == TWORD ? wordtext : ""));
+ TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
else
- TRACE(("reread token '%s' %s\n", tokname_array[t] + 1, t == TWORD ? wordtext : ""));
+ TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
#endif
return t;
}