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>
This commit is contained in:
parent
89e9d5534d
commit
0403bedccc
59
shell/hush.c
59
shell/hush.c
@ -5076,6 +5076,14 @@ static struct pipe *parse_stream(char **pstring,
|
||||
}
|
||||
nommu_addchr(&ctx.as_string, ch);
|
||||
|
||||
/* Handle "'" and "\" first, as they won't play nice with
|
||||
* i_peek_and_eat_bkslash_nl() anyway:
|
||||
* echo z\\
|
||||
* and
|
||||
* echo '\
|
||||
* '
|
||||
* would break.
|
||||
*/
|
||||
if (ch == '\'') {
|
||||
ctx.word.has_quoted_part = 1;
|
||||
next = i_getch(input);
|
||||
@ -5101,19 +5109,34 @@ static struct pipe *parse_stream(char **pstring,
|
||||
}
|
||||
continue; /* get next char */
|
||||
}
|
||||
if (ch == '\\') {
|
||||
/*nommu_addchr(&ctx.as_string, '\\'); - already done */
|
||||
o_addchr(&ctx.word, '\\');
|
||||
ch = i_getch(input);
|
||||
if (ch == EOF) {
|
||||
/* Testcase: eval 'echo Ok\' */
|
||||
|
||||
next = '\0';
|
||||
if (ch != '\n' && ch != '\\') {
|
||||
/* Not on '\': do not break the case of "echo z\\":
|
||||
* on 2nd '\', i_peek_and_eat_bkslash_nl()
|
||||
* would stop and try to read next line,
|
||||
* not letting the command to execute.
|
||||
#if 0 /* bash-4.3.43 was removing backslash, but 4.4.19 retains it, most other shells too */
|
||||
/* Remove trailing '\' from ctx.as_string */
|
||||
ctx.as_string.data[--ctx.as_string.length] = '\0';
|
||||
#endif
|
||||
continue; /* get next char */
|
||||
}
|
||||
/* Example: echo Hello \2>file
|
||||
* we need to know that word 2 is quoted
|
||||
*/
|
||||
next = i_peek_and_eat_bkslash_nl(input);
|
||||
ctx.word.has_quoted_part = 1;
|
||||
nommu_addchr(&ctx.as_string, ch);
|
||||
o_addchr(&ctx.word, ch);
|
||||
continue; /* get next char */
|
||||
}
|
||||
|
||||
next = '\0';
|
||||
if (ch != '\n')
|
||||
next = i_peek_and_eat_bkslash_nl(input);
|
||||
|
||||
is_special = "{}<>;&|()#" /* special outside of "str" */
|
||||
"\\$\"" IF_HUSH_TICK("`") /* always special */
|
||||
"$\"" IF_HUSH_TICK("`") /* always special */
|
||||
SPECIAL_VAR_SYMBOL_STR;
|
||||
/* Are { and } special here? */
|
||||
if (ctx.command->argv /* word [word]{... - non-special */
|
||||
@ -5401,26 +5424,6 @@ static struct pipe *parse_stream(char **pstring,
|
||||
/* non-comment #: "echo a#b" etc */
|
||||
o_addchr(&ctx.word, ch);
|
||||
continue; /* get next char */
|
||||
case '\\':
|
||||
/*nommu_addchr(&ctx.as_string, '\\'); - already done */
|
||||
o_addchr(&ctx.word, '\\');
|
||||
ch = i_getch(input);
|
||||
if (ch == EOF) {
|
||||
/* Testcase: eval 'echo Ok\' */
|
||||
|
||||
#if 0 /* bash-4.3.43 was removing backslash, but 4.4.19 retains it, most other shells too */
|
||||
/* Remove trailing '\' from ctx.as_string */
|
||||
ctx.as_string.data[--ctx.as_string.length] = '\0';
|
||||
#endif
|
||||
continue; /* get next char */
|
||||
}
|
||||
/* Example: echo Hello \2>file
|
||||
* we need to know that word 2 is quoted
|
||||
*/
|
||||
ctx.word.has_quoted_part = 1;
|
||||
nommu_addchr(&ctx.as_string, ch);
|
||||
o_addchr(&ctx.word, ch);
|
||||
continue; /* get next char */
|
||||
case '$':
|
||||
if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
|
||||
debug_printf_parse("parse_stream parse error: "
|
||||
|
Loading…
Reference in New Issue
Block a user