61
# "else", and "fi" in if-then-else likewise must not end with "&&", thus
62
# receives similar treatment.
63
#
64
+# Swallowing here-docs with arbitrary tags requires a bit of finesse. When a
65
+# line such as "cat <<EOF >out" is seen, the here-doc tag is moved to the front
66
+# of the line enclosed in angle brackets as a sentinel, giving "<EOF>cat >out".
67
+# As each subsequent line is read, it is appended to the target line and a
68
+# (whitespace-loose) back-reference match /^<(.*)>\n\1$/ is attempted to see if
69
+# the content inside "<...>" matches the entirety of the newly-read line. For
70
+# instance, if the next line read is "some data", when concatenated with the
71
+# target line, it becomes "<EOF>cat >out\nsome data", and a match is attempted
72
+# to see if "EOF" matches "some data". Since it doesn't, the next line is
73
+# attempted. When a line consisting of only "EOF" (and possible whitespace) is
74
+# encountered, it is appended to the target line giving "<EOF>cat >out\nEOF",
75
+# in which case the "EOF" inside "<...>" does match the text following the
76
+# newline, thus the closing here-doc tag has been found. The closing tag line
77
+# and the "<...>" prefix on the target line are then discarded, leaving just
78
+# the target line "cat >out".
79
+#
80
# To facilitate regression testing (and manual debugging), a ">" annotation is
81
# applied to the line containing ")" which closes a subshell, ">>" to a line
82
# closing a nested subshell, and ">>>" to a line closing both at once. This
94
95
# here-doc -- swallow it to avoid false hits within its body (but keep the
96
# command to which it was attached)
81
-/<<[ ]*[-\\]*EOF[ ]*/ {
82
- s/[ ]*<<[ ]*[-\\]*EOF//
83
- h
97
+/<<[ ]*[-\\]*[A-Za-z0-9_]/ {
98
+ s/^\(.*\)<<[ ]*[-\\]*\([A-Za-z0-9_][A-Za-z0-9_]*\)/<\2>\1<</
99
+ s/[ ]*<<//
100
:hereslurp
101
N
86
- s/.*\n//
87
- /^[ ]*EOF[ ]*$/!bhereslurp
88
- x
102
+ /^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
103
+ s/\n.*$//
104
+ bhereslurp
105
+ }
106
+ s/^<[^>]*>//
107
+ s/\n.*$//
108
}
109
110
# one-liner "(...) &&"
158
/"[^'"]*'[^'"]*"/!bsqstring
159
}
160
# here-doc -- swallow it
142
-/<<[ ]*[-\\]*EOF/bheredoc
143
-/<<[ ]*[-\\]*EOT/bheredoc
144
-/<<[ ]*[-\\]*INPUT_END/bheredoc
161
+/<<[ ]*[-\\]*[A-Za-z0-9_]/bheredoc
162
# comment or empty line -- discard since final non-comment, non-empty line
163
# before closing ")", "done", "elsif", "else", or "fi" will need to be
164
# re-visited to drop "suspect" marking since final line of those constructs
266
bcheckchain
267
268
# found here-doc -- swallow it to avoid false hits within its body (but keep
252
-# the command to which it was attached); take care to handle here-docs nested
253
-# within here-docs by only recognizing closing tag matching outer here-doc
254
-# opening tag
269
+# the command to which it was attached)
270
:heredoc
256
-/EOF/{ s/[ ]*<<[ ]*[-\\]*EOF//; s/^/EOF/; }
257
-/EOT/{ s/[ ]*<<[ ]*[-\\]*EOT//; s/^/EOT/; }
258
-/INPUT_END/{ s/[ ]*<<[ ]*[-\\]*INPUT_END//; s/^/INPUT_END/; }
271
+s/^\(.*\)<<[ ]*[-\\]*\([A-Za-z0-9_][A-Za-z0-9_]*\)/<\2>\1<</
272
+s/[ ]*<<//
273
:hereslurpsub
274
N
261
-/^EOF.*\n[ ]*EOF[ ]*$/bhereclose
262
-/^EOT.*\n[ ]*EOT[ ]*$/bhereclose
263
-/^INPUT_END.*\n[ ]*INPUT_END[ ]*$/bhereclose
264
-bhereslurpsub
265
-:hereclose
266
-s/^EOF//
267
-s/^EOT//
268
-s/^INPUT_END//
275
+/^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
276
+ s/\n.*$//
277
+ bhereslurpsub
278
+}
279
+s/^<[^>]*>//
280
s/\n.*$//
281
bcheckchain
282