aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-04-11 01:33:54 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-04-11 01:34:46 +0200
commit0403bedccc17c8ea3059523e32ea615e5df4bc26 (patch)
treef7cd40adbfc0ee1ccd0bad90e319daf146ad5937 /shell/hush.c
parent89e9d5534d0e8879803ed9dbb25dff3989c31202 (diff)
downloadbusybox-w32-0403bedccc17c8ea3059523e32ea615e5df4bc26.tar.gz
busybox-w32-0403bedccc17c8ea3059523e32ea615e5df4bc26.tar.bz2
busybox-w32-0403bedccc17c8ea3059523e32ea615e5df4bc26.zip
hush: optimize parse_stream()
Since we check for '\' anyway when we determine whether we can look ahead, we can just check for *and handle* it there. function old new delta parse_stream 2751 2740 -11 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r--shell/hush.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 523fc1a31..735fbef27 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5076,6 +5076,14 @@ static struct pipe *parse_stream(char **pstring,
5076 } 5076 }
5077 nommu_addchr(&ctx.as_string, ch); 5077 nommu_addchr(&ctx.as_string, ch);
5078 5078
5079 /* Handle "'" and "\" first, as they won't play nice with
5080 * i_peek_and_eat_bkslash_nl() anyway:
5081 * echo z\\
5082 * and
5083 * echo '\
5084 * '
5085 * would break.
5086 */
5079 if (ch == '\'') { 5087 if (ch == '\'') {
5080 ctx.word.has_quoted_part = 1; 5088 ctx.word.has_quoted_part = 1;
5081 next = i_getch(input); 5089 next = i_getch(input);
@@ -5101,19 +5109,34 @@ static struct pipe *parse_stream(char **pstring,
5101 } 5109 }
5102 continue; /* get next char */ 5110 continue; /* get next char */
5103 } 5111 }
5112 if (ch == '\\') {
5113 /*nommu_addchr(&ctx.as_string, '\\'); - already done */
5114 o_addchr(&ctx.word, '\\');
5115 ch = i_getch(input);
5116 if (ch == EOF) {
5117 /* Testcase: eval 'echo Ok\' */
5104 5118
5105 next = '\0'; 5119#if 0 /* bash-4.3.43 was removing backslash, but 4.4.19 retains it, most other shells too */
5106 if (ch != '\n' && ch != '\\') { 5120 /* Remove trailing '\' from ctx.as_string */
5107 /* Not on '\': do not break the case of "echo z\\": 5121 ctx.as_string.data[--ctx.as_string.length] = '\0';
5108 * on 2nd '\', i_peek_and_eat_bkslash_nl() 5122#endif
5109 * would stop and try to read next line, 5123 continue; /* get next char */
5110 * not letting the command to execute. 5124 }
5125 /* Example: echo Hello \2>file
5126 * we need to know that word 2 is quoted
5111 */ 5127 */
5112 next = i_peek_and_eat_bkslash_nl(input); 5128 ctx.word.has_quoted_part = 1;
5129 nommu_addchr(&ctx.as_string, ch);
5130 o_addchr(&ctx.word, ch);
5131 continue; /* get next char */
5113 } 5132 }
5114 5133
5134 next = '\0';
5135 if (ch != '\n')
5136 next = i_peek_and_eat_bkslash_nl(input);
5137
5115 is_special = "{}<>;&|()#" /* special outside of "str" */ 5138 is_special = "{}<>;&|()#" /* special outside of "str" */
5116 "\\$\"" IF_HUSH_TICK("`") /* always special */ 5139 "$\"" IF_HUSH_TICK("`") /* always special */
5117 SPECIAL_VAR_SYMBOL_STR; 5140 SPECIAL_VAR_SYMBOL_STR;
5118 /* Are { and } special here? */ 5141 /* Are { and } special here? */
5119 if (ctx.command->argv /* word [word]{... - non-special */ 5142 if (ctx.command->argv /* word [word]{... - non-special */
@@ -5401,26 +5424,6 @@ static struct pipe *parse_stream(char **pstring,
5401 /* non-comment #: "echo a#b" etc */ 5424 /* non-comment #: "echo a#b" etc */
5402 o_addchr(&ctx.word, ch); 5425 o_addchr(&ctx.word, ch);
5403 continue; /* get next char */ 5426 continue; /* get next char */
5404 case '\\':
5405 /*nommu_addchr(&ctx.as_string, '\\'); - already done */
5406 o_addchr(&ctx.word, '\\');
5407 ch = i_getch(input);
5408 if (ch == EOF) {
5409 /* Testcase: eval 'echo Ok\' */
5410
5411#if 0 /* bash-4.3.43 was removing backslash, but 4.4.19 retains it, most other shells too */
5412 /* Remove trailing '\' from ctx.as_string */
5413 ctx.as_string.data[--ctx.as_string.length] = '\0';
5414#endif
5415 continue; /* get next char */
5416 }
5417 /* Example: echo Hello \2>file
5418 * we need to know that word 2 is quoted
5419 */
5420 ctx.word.has_quoted_part = 1;
5421 nommu_addchr(&ctx.as_string, ch);
5422 o_addchr(&ctx.word, ch);
5423 continue; /* get next char */
5424 case '$': 5427 case '$':
5425 if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) { 5428 if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
5426 debug_printf_parse("parse_stream parse error: " 5429 debug_printf_parse("parse_stream parse error: "