Skip to content

Commit

Permalink
[lexer] Recognize $'cstring' within "${x}", e.g. "${x%$'cstring'}".
Browse files Browse the repository at this point in the history
git-prompt.sh depends on this working correctly.
  • Loading branch information
Andy Chu committed Jan 19, 2019
1 parent deabb87 commit 052d8aa
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
7 changes: 6 additions & 1 deletion frontend/lex.py
Expand Up @@ -108,7 +108,7 @@

# In oil, I hope to have these lexer modes:
# COMMAND
# EXPRESSION (takes place of ARITH, VS_ARG_UNQ, VS_ARG_DQ)
# EXPRESSION (takes place of ARITH, VS_ArgUnquoted, VS_ArgDQ)
# SQ RAW_SQ DQ RAW_DQ
# VS -- a single state here? Or switches into expression state, because }
# is an operator
Expand Down Expand Up @@ -407,8 +407,13 @@ def IsKeyword(name):
# Kind.{LIT,IGNORED,VS,LEFT,RIGHT,Eof}
LEXER_DEF[lex_mode_e.VS_ArgDQ] = _VS_ARG_COMMON + _LEFT_SUBS + _VARS + [
R(r'[^$`/}"\0\\#%]+', Id.Lit_Chars), # matches a line at most

# Weird wart: even in double quoted state, double quotes are allowed
C('"', Id.Left_DoubleQuote),

# Another weird wart of bash/mksh: $'' is recognized but NOT ''!
C("$'", Id.Left_DollarSingleQuote),

R(r'[^\0]', Id.Lit_Other), # e.g. "$", must be last
]

Expand Down
7 changes: 7 additions & 0 deletions frontend/parse_lib.py
Expand Up @@ -147,6 +147,13 @@ def MakeParserForCommandSub(self, line_reader, lexer, eof_id):
"""To parse command sub, we want a fresh word parser state.
It's a new instance based on same lexer and arena.
TODO: We also need to know if we're in a double quoted context, in order to
parse " vs \"
Is that a lexer mode or can we save some code size?
The CommandParser starts in Outer mode. We could pass DQCommand or
DQOuter.
lex_mode_e.Command vs. lex_mode_e.DQCommand
"""
w_parser = word_parse.WordParser(self, lexer, line_reader)
c_parser = cmd_parse.CommandParser(self, w_parser, lexer, line_reader,
Expand Down
14 changes: 14 additions & 0 deletions spec/var-sub-quote.test.sh
Expand Up @@ -190,3 +190,17 @@ foo='a b c d'
argv.py "${foo%'c d'}" "${foo%'c d'}"
## stdout: ['a b c d', 'a b c d']
## BUG bash/mksh stdout: ['a b ', 'a b c d']
#### $'' allowed within VarSub arguments
# Odd behavior of bash/mksh: $'' is recognized but NOT ''!
x=abc
echo ${x%$'b'*}
echo "${x%$'b'*}" # git-prompt.sh relies on this
## STDOUT:
a
a
## END
## N-I dash STDOUT:
abc
abc
## END

0 comments on commit 052d8aa

Please sign in to comment.