diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-02 16:54:17 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-02 16:54:17 +0200 |
| commit | 888527cceec2f58f1eae3acceddee928b5cb647a (patch) | |
| tree | f4ef6c2a33a1391bfe4e9f408b15e0f36e8e21b4 /shell | |
| parent | bc1a00843fce8ce0ed101c4e6eb02ee79e673a00 (diff) | |
| download | busybox-w32-888527cceec2f58f1eae3acceddee928b5cb647a.tar.gz busybox-w32-888527cceec2f58f1eae3acceddee928b5cb647a.tar.bz2 busybox-w32-888527cceec2f58f1eae3acceddee928b5cb647a.zip | |
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>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 124 |
1 files changed, 83 insertions, 41 deletions
diff --git a/shell/ash.c b/shell/ash.c index 41ae5cbd2..421639e8b 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -7881,49 +7881,86 @@ enum { | |||
| 7881 | }; | 7881 | }; |
| 7882 | typedef smallint token_id_t; | 7882 | typedef smallint token_id_t; |
| 7883 | 7883 | ||
| 7884 | /* first char is indicating which tokens mark the end of a list */ | 7884 | /* Nth bit indicates if token marks the end of a list */ |
| 7885 | enum { | ||
| 7886 | tokendlist = 0 | ||
| 7887 | /* 0 */ | (1u << TEOF) | ||
| 7888 | /* 1 */ | (0u << TNL) | ||
| 7889 | /* 2 */ | (0u << TREDIR) | ||
| 7890 | /* 3 */ | (0u << TWORD) | ||
| 7891 | /* 4 */ | (0u << TSEMI) | ||
| 7892 | /* 5 */ | (0u << TBACKGND) | ||
| 7893 | /* 6 */ | (0u << TAND) | ||
| 7894 | /* 7 */ | (0u << TOR) | ||
| 7895 | /* 8 */ | (0u << TPIPE) | ||
| 7896 | /* 9 */ | (0u << TLP) | ||
| 7897 | /* 10 */ | (1u << TRP) | ||
| 7898 | /* 11 */ | (1u << TENDCASE) | ||
| 7899 | /* 12 */ | (1u << TENDBQUOTE) | ||
| 7900 | /* 13 */ | (0u << TNOT) | ||
| 7901 | /* 14 */ | (0u << TCASE) | ||
| 7902 | /* 15 */ | (1u << TDO) | ||
| 7903 | /* 16 */ | (1u << TDONE) | ||
| 7904 | /* 17 */ | (1u << TELIF) | ||
| 7905 | /* 18 */ | (1u << TELSE) | ||
| 7906 | /* 19 */ | (1u << TESAC) | ||
| 7907 | /* 20 */ | (1u << TFI) | ||
| 7908 | /* 21 */ | (0u << TFOR) | ||
| 7909 | #if ENABLE_ASH_BASH_COMPAT | ||
| 7910 | /* 22 */ | (0u << TFUNCTION) | ||
| 7911 | #endif | ||
| 7912 | /* 23 */ | (0u << TIF) | ||
| 7913 | /* 24 */ | (0u << TIN) | ||
| 7914 | /* 25 */ | (1u << TTHEN) | ||
| 7915 | /* 26 */ | (0u << TUNTIL) | ||
| 7916 | /* 27 */ | (0u << TWHILE) | ||
| 7917 | /* 28 */ | (0u << TBEGIN) | ||
| 7918 | /* 29 */ | (1u << TEND) | ||
| 7919 | , /* thus far 29 bits used */ | ||
| 7920 | }; | ||
| 7921 | |||
| 7885 | static const char *const tokname_array[] = { | 7922 | static const char *const tokname_array[] = { |
| 7886 | "\1end of file", | 7923 | "end of file", |
| 7887 | "\0newline", | 7924 | "newline", |
| 7888 | "\0redirection", | 7925 | "redirection", |
| 7889 | "\0word", | 7926 | "word", |
| 7890 | "\0;", | 7927 | ";", |
| 7891 | "\0&", | 7928 | "&", |
| 7892 | "\0&&", | 7929 | "&&", |
| 7893 | "\0||", | 7930 | "||", |
| 7894 | "\0|", | 7931 | "|", |
| 7895 | "\0(", | 7932 | "(", |
| 7896 | "\1)", | 7933 | ")", |
| 7897 | "\1;;", | 7934 | ";;", |
| 7898 | "\1`", | 7935 | "`", |
| 7899 | #define KWDOFFSET 13 | 7936 | #define KWDOFFSET 13 |
| 7900 | /* the following are keywords */ | 7937 | /* the following are keywords */ |
| 7901 | "\0!", | 7938 | "!", |
| 7902 | "\0case", | 7939 | "case", |
| 7903 | "\1do", | 7940 | "do", |
| 7904 | "\1done", | 7941 | "done", |
| 7905 | "\1elif", | 7942 | "elif", |
| 7906 | "\1else", | 7943 | "else", |
| 7907 | "\1esac", | 7944 | "esac", |
| 7908 | "\1fi", | 7945 | "fi", |
| 7909 | "\0for", | 7946 | "for", |
| 7910 | #if ENABLE_ASH_BASH_COMPAT | 7947 | #if ENABLE_ASH_BASH_COMPAT |
| 7911 | "\0function", | 7948 | "function", |
| 7912 | #endif | 7949 | #endif |
| 7913 | "\0if", | 7950 | "if", |
| 7914 | "\0in", | 7951 | "in", |
| 7915 | "\1then", | 7952 | "then", |
| 7916 | "\0until", | 7953 | "until", |
| 7917 | "\0while", | 7954 | "while", |
| 7918 | "\0{", | 7955 | "{", |
| 7919 | "\1}", | 7956 | "}", |
| 7920 | }; | 7957 | }; |
| 7921 | 7958 | ||
| 7922 | /* Wrapper around strcmp for qsort/bsearch/... */ | 7959 | /* Wrapper around strcmp for qsort/bsearch/... */ |
| 7923 | static int | 7960 | static int |
| 7924 | pstrcmp(const void *a, const void *b) | 7961 | pstrcmp(const void *a, const void *b) |
| 7925 | { | 7962 | { |
| 7926 | return strcmp((char*) a, (*(char**) b) + 1); | 7963 | return strcmp((char*)a, *(char**)b); |
| 7927 | } | 7964 | } |
| 7928 | 7965 | ||
| 7929 | static const char *const * | 7966 | static const char *const * |
| @@ -9339,6 +9376,11 @@ static const struct builtincmd builtintab[] = { | |||
| 9339 | /* | 9376 | /* |
| 9340 | * Search the table of builtin commands. | 9377 | * Search the table of builtin commands. |
| 9341 | */ | 9378 | */ |
| 9379 | static int | ||
| 9380 | pstrcmp1(const void *a, const void *b) | ||
| 9381 | { | ||
| 9382 | return strcmp((char*)a, *(char**)b + 1); | ||
| 9383 | } | ||
| 9342 | static struct builtincmd * | 9384 | static struct builtincmd * |
| 9343 | find_builtin(const char *name) | 9385 | find_builtin(const char *name) |
| 9344 | { | 9386 | { |
| @@ -9346,7 +9388,7 @@ find_builtin(const char *name) | |||
| 9346 | 9388 | ||
| 9347 | bp = bsearch( | 9389 | bp = bsearch( |
| 9348 | name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]), | 9390 | name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]), |
| 9349 | pstrcmp | 9391 | pstrcmp1 |
| 9350 | ); | 9392 | ); |
| 9351 | return bp; | 9393 | return bp; |
| 9352 | } | 9394 | } |
| @@ -10669,8 +10711,8 @@ static const char * | |||
| 10669 | tokname(char *buf, int tok) | 10711 | tokname(char *buf, int tok) |
| 10670 | { | 10712 | { |
| 10671 | if (tok < TSEMI) | 10713 | if (tok < TSEMI) |
| 10672 | return tokname_array[tok] + 1; | 10714 | return tokname_array[tok]; |
| 10673 | sprintf(buf, "\"%s\"", tokname_array[tok] + 1); | 10715 | sprintf(buf, "\"%s\"", tokname_array[tok]); |
| 10674 | return buf; | 10716 | return buf; |
| 10675 | } | 10717 | } |
| 10676 | 10718 | ||
| @@ -10727,7 +10769,7 @@ list(int nlflag) | |||
| 10727 | } | 10769 | } |
| 10728 | 10770 | ||
| 10729 | checkkwd = CHKNL | CHKKWD | CHKALIAS; | 10771 | checkkwd = CHKNL | CHKKWD | CHKALIAS; |
| 10730 | if (nlflag == 2 && tokname_array[peektoken()][0]) | 10772 | if (nlflag == 2 && ((1 << peektoken()) & tokendlist)) |
| 10731 | return n1; | 10773 | return n1; |
| 10732 | nlflag |= 2; | 10774 | nlflag |= 2; |
| 10733 | 10775 | ||
| @@ -11109,7 +11151,7 @@ parse_command(void) | |||
| 11109 | n1->nbinary.ch1 = list(0); | 11151 | n1->nbinary.ch1 = list(0); |
| 11110 | got = readtoken(); | 11152 | got = readtoken(); |
| 11111 | if (got != TDO) { | 11153 | if (got != TDO) { |
| 11112 | TRACE(("expecting DO got '%s' %s\n", tokname_array[got] + 1, | 11154 | TRACE(("expecting DO got '%s' %s\n", tokname_array[got], |
| 11113 | got == TWORD ? wordtext : "")); | 11155 | got == TWORD ? wordtext : "")); |
| 11114 | raise_error_unexpected_syntax(TDO); | 11156 | raise_error_unexpected_syntax(TDO); |
| 11115 | } | 11157 | } |
| @@ -12156,7 +12198,7 @@ readtoken(void) | |||
| 12156 | pp = findkwd(wordtext); | 12198 | pp = findkwd(wordtext); |
| 12157 | if (pp) { | 12199 | if (pp) { |
| 12158 | lasttoken = t = pp - tokname_array; | 12200 | lasttoken = t = pp - tokname_array; |
| 12159 | TRACE(("keyword '%s' recognized\n", tokname_array[t] + 1)); | 12201 | TRACE(("keyword '%s' recognized\n", tokname_array[t])); |
| 12160 | goto out; | 12202 | goto out; |
| 12161 | } | 12203 | } |
| 12162 | } | 12204 | } |
| @@ -12177,9 +12219,9 @@ readtoken(void) | |||
| 12177 | checkkwd = 0; | 12219 | checkkwd = 0; |
| 12178 | #if DEBUG | 12220 | #if DEBUG |
| 12179 | if (!alreadyseen) | 12221 | if (!alreadyseen) |
| 12180 | TRACE(("token '%s' %s\n", tokname_array[t] + 1, t == TWORD ? wordtext : "")); | 12222 | TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : "")); |
| 12181 | else | 12223 | else |
| 12182 | TRACE(("reread token '%s' %s\n", tokname_array[t] + 1, t == TWORD ? wordtext : "")); | 12224 | TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : "")); |
| 12183 | #endif | 12225 | #endif |
| 12184 | return t; | 12226 | return t; |
| 12185 | } | 12227 | } |
