From 3eceb647e59b1fb324ce62092edb63a458a73545 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sat, 20 Feb 2016 20:35:39 -0500 Subject: scan_wordexp_param_brace(): New function --- diff --git a/parsing/lexer.sh b/parsing/lexer.sh index ad076dc..5c3f6c5 100644 --- a/parsing/lexer.sh +++ b/parsing/lexer.sh @@ -1,7 +1,9 @@ fname= lineno= +ln_off= start= c= +wordexp= tok= tokens= @@ -327,9 +329,6 @@ scan_word() scan_wordexp() { - local wordexp= - local ln_off= - local mod= local res= local param= local word= @@ -340,115 +339,7 @@ scan_wordexp() case "${c}" in '{') # Parameter expansion brace - mod=true - lgetc - case "${c}" in - '#') - lgetc - case "${c}" in - [@*#?$!A-Za-z0-9_-]) - # String length - # expansion - if ! res="$(scan_param)" - then - exit 1 - fi - ln_off=${res%%${RS}*} - res="${res#*${RS}}" - c="${res%%${RS}*}" - res="${res#*${RS}}" - param="${res%%${RS}*}" - lineno=$((${lineno} + \ - ${ln_off})) - # Disable modifications. - mod=false - ;; - *) - # Special parameter "#" - param='#' - ;; - esac - ;; - *) - if ! res="$(scan_param)"; then - exit 1 - fi - ln_off=${res%%${RS}*} - res="${res#*${RS}}" - c="${res%%${RS}*}" - res="${res#*${RS}}" - param="${res%%${RS}*}" - lineno=$((${lineno} + ${ln_off})) - ;; - esac - wordexp="\${${param}" - if ${mod}; then - # Check for modifications - mod=false - case "${c}" in - ':') - mod=true - wordexp="${wordexp}${c}" - lgetc - case "${c}" in '-'|'='|'?'|'+') - wordexp="${wordexp}${c}" - lgetc - ;; - esac - ;; - '-'|'='|'?'|'+') - mod=true - wordexp="${wordexp}${c}" - lgetc - ;; - '%') - mod=true - wordexp="${wordexp}${c}" - lgetc - case "${c}" in '%') - wordexp="${wordexp}${c}" - lgetc - ;; - esac - ;; - '#') - mod=true - wordexp="${wordexp}${c}" - lgetc - case "${c}" in '#') - wordexp="${wordexp}${c}" - lgetc - ;; - esac - ;; - esac - fi - if ${mod}; then - # Get word. - if ! res="$(scan_word true)"; then - exit 1 - fi - ln_off=${res%%${RS}*} - res="${res#*${RS}}" - c="${res%%${RS}*}" - res="${res#*${RS}}" - word="${res%%${RS}*}" - # We must advance lineno because scan_word() was - # run in a subshell. - lineno=$((${lineno} + ${ln_off})) - wordexp="${wordexp}${word}" - dbg "param mod word: '$word'" - fi - # Check for right brace. - case "${c}" in - '}') - wordexp="${wordexp}${c}" - lgetc - ;; - *) - synerr 'Missing "}"' - ;; - esac + scan_wordexp_param_brace ;; '(') # Arithmetic expansion or command substitution @@ -496,6 +387,129 @@ scan_wordexp() return 0 } +scan_wordexp_param_brace() +{ + local mod= + local res= + local param= + + ln_off=0 + mod=true + + lgetc + case "${c}" in + '#') + lgetc + case "${c}" in + [@*#?$!A-Za-z0-9_-]) + # String length expansion + if ! res="$(scan_param)"; then + exit 1 + fi + ln_off=${res%%${RS}*} + res="${res#*${RS}}" + c="${res%%${RS}*}" + res="${res#*${RS}}" + param="${res%%${RS}*}" + lineno=$((${lineno} + ${ln_off})) + # Disable modifications. + mod=false + ;; + *) + # Special parameter "#" + param='#' + ;; + esac + ;; + *) + if ! res="$(scan_param)"; then + exit 1 + fi + ln_off=${res%%${RS}*} + res="${res#*${RS}}" + c="${res%%${RS}*}" + res="${res#*${RS}}" + param="${res%%${RS}*}" + lineno=$((${lineno} + ${ln_off})) + ;; + esac + wordexp="\${${param}" + + # If modifications are allowed + if ${mod}; then + # Check for modifications. + mod=false + case "${c}" in + ':') + mod=true + wordexp="${wordexp}${c}" + lgetc + case "${c}" in '-'|'='|'?'|'+') + wordexp="${wordexp}${c}" + lgetc + ;; + esac + ;; + '-'|'='|'?'|'+') + mod=true + wordexp="${wordexp}${c}" + lgetc + ;; + '%') + mod=true + wordexp="${wordexp}${c}" + lgetc + case "${c}" in '%') + wordexp="${wordexp}${c}" + lgetc + ;; + esac + ;; + '#') + mod=true + wordexp="${wordexp}${c}" + lgetc + case "${c}" in '#') + wordexp="${wordexp}${c}" + lgetc + ;; + esac + ;; + esac + fi + + # If a modification was found + if ${mod}; then + # Get word. + if ! res="$(scan_word true)"; then + exit 1 + fi + ln_off=${res%%${RS}*} + res="${res#*${RS}}" + c="${res%%${RS}*}" + res="${res#*${RS}}" + word="${res%%${RS}*}" + # We must advance lineno because scan_word() was run in a + # subshell. + lineno=$((${lineno} + ${ln_off})) + wordexp="${wordexp}${word}" + dbg "param mod word: '$word'" + fi + + # Check for right brace. + case "${c}" in + '}') + wordexp="${wordexp}${c}" + lgetc + ;; + *) + synerr 'Missing "}"' + ;; + esac + + return 0 +} + scan_param() { local param= diff --git a/parsing/parse.sh b/parsing/parse.sh index a71f90b..8f73b32 100644 --- a/parsing/parse.sh +++ b/parsing/parse.sh @@ -624,12 +624,12 @@ try() } #try '"foo bar" && $baz || qux' '${quux%uux quuux' -#try '"foo bar" && $baz || qux' '${quux%uux } quuux' -#try 'foo ${bar}' -#try 'foo ${#bar}' -#try 'foo ${bar#baz}' -#try 'foo ${#bar#}' -#try 'foo ${^}' +try '"foo bar" && $baz || qux' '${quux%uux } quuux' +try 'foo ${bar}' +try 'foo ${#bar}' +try 'foo ${bar#baz}' +try 'foo ${#bar#}' +try 'foo ${^}' #try 'foo `bar`' #try 'foo &&' #try '{ foo; }' @@ -643,9 +643,9 @@ try() #try 'foo(){ bar; }' #try 'case foo in bar) baz;; (qux) quux;; quux);; esac' #try 'foo bar ( baz )' -try 'foo $(bar)' -try 'foo $(bar); baz' -try 'foo $(bar)' 'baz' -try 'foo $(bar) baz' -try 'foo$(bar$(baz))qux' +#try 'foo $(bar)' +#try 'foo $(bar); baz' +#try 'foo $(bar)' 'baz' +#try 'foo $(bar) baz' +#try 'foo$(bar$(baz))qux' #try 'foo $((1 + 1))' -- cgit v0.9.1