From 33554a524c8fda86e8d41cc91f8e992ef09b0555 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sun, 21 Feb 2016 02:27:48 -0500 Subject: Fix handling of multiple here-documents on a line --- (limited to 'parsing') diff --git a/parsing/lexer.sh b/parsing/lexer.sh index c88c8b6..dc0b48d 100644 --- a/parsing/lexer.sh +++ b/parsing/lexer.sh @@ -4,7 +4,7 @@ ln_off= start= c= wordexp= -here_stack= +here_queue= here_awaiting_end= here_awaiting_word= tok= @@ -70,12 +70,10 @@ lgetc() next() { - case "${here_stack}" in *"${RS}"*) - if ${here_awaiting_word}; then - next_here - return - fi - esac + if ${here_awaiting_word}; then + next_here + return + fi while :; do dbg "parsing char '$c' at lineno $lineno" case "${c}" in @@ -85,15 +83,12 @@ next() return ;; "${LF}") - case "${here_stack}" in *"${RS}"*) - if ${here_awaiting_end}; then - synexp '' - else - here_awaiting_end=false - here_awaiting_word=true - fi - ;; - esac + if ${here_awaiting_end}; then + synexp '' + else + here_awaiting_end=false + here_awaiting_word=true + fi lgetc lineno=$((${lineno} + 1)) tok=T_NEWLINE @@ -193,14 +188,20 @@ next_here() local res= local wordexp= - # Pop the here-document off of the stack. - here="${here_stack##*${RS}}" + # Dequeue the here-document. + here="${here_queue%%${RS}*}" here_strip_tabs="${here%%${US}*}" here_end="${here%${US}*}" here_end="${here_end#*${US}}" here_escaped="${here##*${US}}" - here_stack="${here_stack%${RS}*}" - here_awaiting_word=false + here_queue="${here_queue#*${RS}}" + case "${here_queue}" in + *"${RS}"*) + ;; + *) + here_awaiting_word=false + ;; + esac line='' word='' @@ -276,15 +277,14 @@ next_io() case "${c}" in '-') lgetc tok=T_DLESSDASH - here_stack="${here_stack}${RS}" - here_stack="${here_stack}true" + here_queue="${here_queue}true" here_awaiting_end=true here_awaiting_word=false break ;; esac tok=T_DLESS - here_stack="${here_stack}${RS}false" + here_queue="${here_queue}false" here_awaiting_end=true here_awaiting_word=false break @@ -346,21 +346,19 @@ next_word() lineno=$((${lineno} + ${ln_off})) tok="T_WORD${US}${word}" - case "${here_stack}" in *"${RS}"*) - if ${here_awaiting_end}; then - here_stack="${here_stack}${US}${word}" - case "${word}" in - *\\*|*'"'*|*"'"*) - here_stack="${here_stack}${US}true" - ;; - *) - here_stack="${here_stack}${US}false" - ;; - esac - here_awaiting_end=false - fi - ;; - esac + if ${here_awaiting_end}; then + here_queue="${here_queue}${US}${word}" + case "${word}" in + *\\*|*'"'*|*"'"*) + here_queue="${here_queue}${US}true" + ;; + *) + here_queue="${here_queue}${US}false" + ;; + esac + here_queue="${here_queue}${RS}" + here_awaiting_end=false + fi } # @@ -400,7 +398,7 @@ scan_word() word="${word}${c}" ;; '$') - case "${here_stack}" in *"${RS}"*) + case "${here_queue}" in *"${RS}"*) if ${here_awaiting_end}; then synerr '%s %s %s %s' \ 'Word expansions' \ @@ -879,7 +877,7 @@ run_sublexer() fname="${fn}" lineno=${ln} start="${st}" - here_stack="${US}" + here_queue='' here_awaiting_end=false here_awaiting_word=false tokens='' @@ -912,7 +910,7 @@ run_lexer() fname="${fn}" lineno=1 start="${st}" - here_stack="${US}" + here_queue='' here_awaiting_end=false here_awaiting_word=false tokens='' diff --git a/parsing/parse.sh b/parsing/parse.sh index 81b8a54..cbe4dd9 100644 --- a/parsing/parse.sh +++ b/parsing/parse.sh @@ -653,7 +653,8 @@ try() #try '$((1 + (1 + 1)))' #try '$((1 + $(foo) + 1))' #try '$((1' -try 'foo <