From 0142fe59202ab4c0c19939511cd71de7c17d3994 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 5 Mar 2008 19:51:12 +0000 Subject: Handle multi-line quoted variable assignments. svn path=/main/trunk/; revision=9440 --- bin/filter-bash-environment.py | 45 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'bin') 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__": -- cgit v1.2.3-1-g7c22