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 --- (limited to 'parsing/lexer.sh') 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= -- cgit v0.9.1