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>
This commit is contained in:
parent
bc1a00843f
commit
888527ccee
122
shell/ash.c
122
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",
|
||||
"function",
|
||||
#endif
|
||||
"\0if",
|
||||
"\0in",
|
||||
"\1then",
|
||||
"\0until",
|
||||
"\0while",
|
||||
"\0{",
|
||||
"\1}",
|
||||
"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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user