diff options
author | P. J. McDermott <pj@pehjota.net> | 2016-02-21 12:12:20 (EST) |
---|---|---|
committer | P. J. McDermott <pj@pehjota.net> | 2016-02-21 12:14:23 (EST) |
commit | 506a0723291b4abc4b707a6353a840ef51f95ee8 (patch) | |
tree | 4babbc574fd99607d9cb39d5b999d79ff21e9ecd /eshtrans | |
parent | 37a60f8da15bcf6ef93c9173e3a5c6cecf9693cc (diff) | |
download | eggshell-506a0723291b4abc4b707a6353a840ef51f95ee8.zip eggshell-506a0723291b4abc4b707a6353a840ef51f95ee8.tar.gz eggshell-506a0723291b4abc4b707a6353a840ef51f95ee8.tar.bz2 |
eshtrans/frontend: Fix handling of words beginning with "\"
Diffstat (limited to 'eshtrans')
-rw-r--r-- | eshtrans/frontend/lexer.esh | 48 | ||||
-rw-r--r-- | eshtrans/main.esh | 8 |
2 files changed, 42 insertions, 14 deletions
diff --git a/eshtrans/frontend/lexer.esh b/eshtrans/frontend/lexer.esh index 0991239..d904aa0 100644 --- a/eshtrans/frontend/lexer.esh +++ b/eshtrans/frontend/lexer.esh @@ -361,14 +361,14 @@ next_word() local res= local word= - if ! res="$(scan_word false)"; then + if ! res="$(scan_word false "${prev_c}")"; then exit 1 fi ln_off=${res%%${RS}*} res="${res#*${RS}}" c="${res%%${RS}*}" res="${res#*${RS}}" - word="${prev_c}${res%%${RS}*}" + word="${res%%${RS}*}" # We must advance lineno because scan_word() was run in a subshell. lineno=$((${lineno} + ${ln_off})) @@ -396,16 +396,28 @@ next_word() scan_word() { local in_param="${1}" - shift 1 - local res= + local prev_c="${2}" + shift 2 + local lines= local word= local quoted= - local lines= + local tmp_c= + local res= local wordexp= + lines=0 word='' quoted=false - lines=0 + + # Sort of a localized ungetc(). + case "${prev_c}" in + '') ;; + *) + tmp_c="${c}" + c="${prev_c}" + ;; + esac + while :; do dbg "parsing word char '$c' at lineno $lineno" case "${c}" in @@ -436,7 +448,10 @@ scan_word() 'delimiters' fi esac - lgetc + case "${prev_c}" in + '') lgetc;; + *) c="${tmp_c}"; prev_c='';; + esac if ! res=$(scan_wordexp); then exit 1 fi @@ -460,8 +475,13 @@ scan_word() break ;; \\) + dbg 'first backslash in word' word="${word}${c}" - lgetc + case "${prev_c}" in + '') lgetc;; + *) c="${tmp_c}"; prev_c='';; + esac + dbg "next char: '$c'" case "${c}" in '') # Bash, ksh93, mksh, and zsh ignore a # backslash at the end of a file, but @@ -479,7 +499,10 @@ scan_word() \') word="${word}${c}" while :; do - lgetc + case "${prev_c}" in + '') lgetc;; + *) c="${tmp_c}"; prev_c='';; + esac word="${word}${c}" case "${c}" in '') @@ -511,7 +534,10 @@ scan_word() word="${word}${c}" ;; esac - lgetc + case "${prev_c}" in + '') lgetc;; + *) c="${tmp_c}"; prev_c='';; + esac done if ${quoted}; then @@ -673,7 +699,7 @@ scan_wordexp_param_brace() # If a modification was found if ${mod}; then # Get word. - if ! res="$(scan_word true)"; then + if ! res="$(scan_word true '')"; then exit 1 fi ln_off=${res%%${RS}*} diff --git a/eshtrans/main.esh b/eshtrans/main.esh index 1cd6e07..46edd26 100644 --- a/eshtrans/main.esh +++ b/eshtrans/main.esh @@ -98,7 +98,9 @@ main() #try 'v=foo' #try 'if &&' #try 'if true; do' -try 'foo' '#bar' -try '# foo' 'bar' -try '' 'foo' +#try 'foo' '#bar' +#try '# foo' 'bar' +#try '' 'foo' +dbg=true +try '\\ foo' } |