aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-02 16:54:17 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-02 16:54:17 +0200
commit888527cceec2f58f1eae3acceddee928b5cb647a (patch)
treef4ef6c2a33a1391bfe4e9f408b15e0f36e8e21b4
parentbc1a00843fce8ce0ed101c4e6eb02ee79e673a00 (diff)
downloadbusybox-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>
-rw-r--r--shell/ash.c124
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};
7882typedef smallint token_id_t; 7882typedef 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 */
7885enum {
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
7885static const char *const tokname_array[] = { 7922static 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/... */
7923static int 7960static int
7924pstrcmp(const void *a, const void *b) 7961pstrcmp(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
7929static const char *const * 7966static 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 */
9379static int
9380pstrcmp1(const void *a, const void *b)
9381{
9382 return strcmp((char*)a, *(char**)b + 1);
9383}
9342static struct builtincmd * 9384static struct builtincmd *
9343find_builtin(const char *name) 9385find_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 *
10669tokname(char *buf, int tok) 10711tokname(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}