summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/filter-bash-environment.py45
1 files changed, 37 insertions, 8 deletions
diff --git a/bin/filter-bash-environment.py b/bin/filter-bash-environment.py
index 39aa4059f..0db77ba5f 100755
--- a/bin/filter-bash-environment.py
+++ b/bin/filter-bash-environment.py
@@ -15,17 +15,50 @@ here_doc_re = re.compile(r'.*\s<<[-]?(\w+)$')
func_start_re = re.compile(r'^[-\w]+\s*\(\)\s*$')
func_end_re = re.compile(r'^\}$')
-var_assign_re = re.compile(r'(^|^declare\s+-\S+\s+|^export\s+)([^=\s]+)=.*$')
+var_assign_re = re.compile(r'(^|^declare\s+-\S+\s+|^export\s+)([^=\s]+)=("|\')?.*$')
+close_quote_re = re.compile(r'(\\"|"|\')\s*$')
def compile_egrep_pattern(s):
for k, v in egrep_compat_map.iteritems():
s = s.replace(k, v)
return re.compile(s)
+def have_end_quote(quote, line):
+ """
+ Check if the line has an end quote (useful for handling multi-line
+ quotes). This handles escaped double quotes that may occur at the
+ end of a line. The posix spec does not allow escaping of single
+ quotes inside of single quotes, so that case is not handled.
+ """
+ close_quote_match = close_quote_re.search(line)
+ return close_quote_match is not None and \
+ close_quote_match.group(0) == quote
+
def filter_bash_environment(pattern, file_in, file_out):
here_doc_delim = None
in_func = None
+ multi_line_quote = None
+ multi_line_quote_filter = None
for line in file_in:
+ if multi_line_quote is not None:
+ if not multi_line_quote_filter:
+ file_out.write(line)
+ if have_end_quote(multi_line_quote, line):
+ multi_line_quote = None
+ multi_line_quote_filter = None
+ continue
+ if here_doc_delim is None and in_func is None:
+ var_assign_match = var_assign_re.match(line)
+ if var_assign_match is not None:
+ quote = var_assign_match.group(3)
+ filter_this = pattern.match(var_assign_match.group(2)) \
+ is not None
+ if quote is not None and not have_end_quote(quote, line):
+ multi_line_quote = quote
+ multi_line_quote_filter = filter_this
+ if not filter_this:
+ file_out.write(line)
+ continue
if here_doc_delim is not None:
if here_doc_delim.match(line):
here_doc_delim = None
@@ -48,13 +81,9 @@ def filter_bash_environment(pattern, file_in, file_out):
if in_func is not None:
file_out.write(line)
continue
- var_assign_match = var_assign_re.match(line)
- if var_assign_match is not None:
- if pattern.match(var_assign_match.group(2)) is None:
- file_out.write(line)
- continue
- # TODO: properly handle multi-line variable assignments
- # like those which the 'export' builtin can produce.
+ # This line is not recognized as part of a variable assignment,
+ # function definition, or here document, so just allow it to
+ # pass through.
file_out.write(line)
if __name__ == "__main__":