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;
|
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[] = {
|
static const char *const tokname_array[] = {
|
||||||
"\1end of file",
|
"end of file",
|
||||||
"\0newline",
|
"newline",
|
||||||
"\0redirection",
|
"redirection",
|
||||||
"\0word",
|
"word",
|
||||||
"\0;",
|
";",
|
||||||
"\0&",
|
"&",
|
||||||
"\0&&",
|
"&&",
|
||||||
"\0||",
|
"||",
|
||||||
"\0|",
|
"|",
|
||||||
"\0(",
|
"(",
|
||||||
"\1)",
|
")",
|
||||||
"\1;;",
|
";;",
|
||||||
"\1`",
|
"`",
|
||||||
#define KWDOFFSET 13
|
#define KWDOFFSET 13
|
||||||
/* the following are keywords */
|
/* the following are keywords */
|
||||||
"\0!",
|
"!",
|
||||||
"\0case",
|
"case",
|
||||||
"\1do",
|
"do",
|
||||||
"\1done",
|
"done",
|
||||||
"\1elif",
|
"elif",
|
||||||
"\1else",
|
"else",
|
||||||
"\1esac",
|
"esac",
|
||||||
"\1fi",
|
"fi",
|
||||||
"\0for",
|
"for",
|
||||||
#if ENABLE_ASH_BASH_COMPAT
|
#if ENABLE_ASH_BASH_COMPAT
|
||||||
"\0function",
|
"function",
|
||||||
#endif
|
#endif
|
||||||
"\0if",
|
"if",
|
||||||
"\0in",
|
"in",
|
||||||
"\1then",
|
"then",
|
||||||
"\0until",
|
"until",
|
||||||
"\0while",
|
"while",
|
||||||
"\0{",
|
"{",
|
||||||
"\1}",
|
"}",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Wrapper around strcmp for qsort/bsearch/... */
|
/* Wrapper around strcmp for qsort/bsearch/... */
|
||||||
static int
|
static int
|
||||||
pstrcmp(const void *a, const void *b)
|
pstrcmp(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return strcmp((char*) a, (*(char**) b) + 1);
|
return strcmp((char*)a, *(char**)b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *const *
|
static const char *const *
|
||||||
@ -9339,6 +9376,11 @@ static const struct builtincmd builtintab[] = {
|
|||||||
/*
|
/*
|
||||||
* Search the table of builtin commands.
|
* 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 *
|
static struct builtincmd *
|
||||||
find_builtin(const char *name)
|
find_builtin(const char *name)
|
||||||
{
|
{
|
||||||
@ -9346,7 +9388,7 @@ find_builtin(const char *name)
|
|||||||
|
|
||||||
bp = bsearch(
|
bp = bsearch(
|
||||||
name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
|
name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
|
||||||
pstrcmp
|
pstrcmp1
|
||||||
);
|
);
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
@ -10669,8 +10711,8 @@ static const char *
|
|||||||
tokname(char *buf, int tok)
|
tokname(char *buf, int tok)
|
||||||
{
|
{
|
||||||
if (tok < TSEMI)
|
if (tok < TSEMI)
|
||||||
return tokname_array[tok] + 1;
|
return tokname_array[tok];
|
||||||
sprintf(buf, "\"%s\"", tokname_array[tok] + 1);
|
sprintf(buf, "\"%s\"", tokname_array[tok]);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10727,7 +10769,7 @@ list(int nlflag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
||||||
if (nlflag == 2 && tokname_array[peektoken()][0])
|
if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
|
||||||
return n1;
|
return n1;
|
||||||
nlflag |= 2;
|
nlflag |= 2;
|
||||||
|
|
||||||
@ -11109,7 +11151,7 @@ parse_command(void)
|
|||||||
n1->nbinary.ch1 = list(0);
|
n1->nbinary.ch1 = list(0);
|
||||||
got = readtoken();
|
got = readtoken();
|
||||||
if (got != TDO) {
|
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 : ""));
|
got == TWORD ? wordtext : ""));
|
||||||
raise_error_unexpected_syntax(TDO);
|
raise_error_unexpected_syntax(TDO);
|
||||||
}
|
}
|
||||||
@ -12156,7 +12198,7 @@ readtoken(void)
|
|||||||
pp = findkwd(wordtext);
|
pp = findkwd(wordtext);
|
||||||
if (pp) {
|
if (pp) {
|
||||||
lasttoken = t = pp - tokname_array;
|
lasttoken = t = pp - tokname_array;
|
||||||
TRACE(("keyword '%s' recognized\n", tokname_array[t] + 1));
|
TRACE(("keyword '%s' recognized\n", tokname_array[t]));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12177,9 +12219,9 @@ readtoken(void)
|
|||||||
checkkwd = 0;
|
checkkwd = 0;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (!alreadyseen)
|
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
|
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
|
#endif
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user