diff options
author | MarcoFalke <falke.marco@gmail.com> | 2018-08-13 07:07:23 -0400 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2018-08-13 07:07:56 -0400 |
commit | ef86f2631e3ce5e1664e1913658fa6e807f35ff7 (patch) | |
tree | 1d86ce82e9dbc54c68d965e1d2e6dfdc5d2e86fd /test | |
parent | 2115cba9c60504ed1c0af8a56c5d90b5fd415497 (diff) | |
parent | 4441ad677a4cdc70ecac63e03edb4e236e36801e (diff) |
Merge #13939: lint: Make format string linter understand basic template parameter syntax
4441ad677a Make format string linter understand basic template parameter syntax (practicalswift)
Pull request description:
Make format string linter understand basic template parameter syntax.
Fixes issue described in https://github.com/bitcoin/bitcoin/pull/13705#issuecomment-412046126.
Thanks to @ken2812221 for reporting!
Tree-SHA512: 8fb995bc6b29d8b9926ef5969e02cf71c494e829434fcdeb4ed5fabad5ab96e86e5b8eea705e8a416927757b4fa4e58abc0fd4f483daa58c94e2c6fdcb8ee822
Diffstat (limited to 'test')
-rwxr-xr-x | test/lint/lint-format-strings.py | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/test/lint/lint-format-strings.py b/test/lint/lint-format-strings.py index c07dfe317b..60389176c9 100755 --- a/test/lint/lint-format-strings.py +++ b/test/lint/lint-format-strings.py @@ -123,6 +123,32 @@ def parse_function_call_and_arguments(function_name, function_call): ['foo(', '123', ')'] >>> parse_function_call_and_arguments("foo", 'foo("foo")') ['foo(', '"foo"', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf), err);') + ['strprintf(', '"%s (%d)",', ' std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf),', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo<wchar_t>().to_bytes(buf), err);') + ['strprintf(', '"%s (%d)",', ' foo<wchar_t>().to_bytes(buf),', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo().to_bytes(buf), err);') + ['strprintf(', '"%s (%d)",', ' foo().to_bytes(buf),', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo << 1, err);') + ['strprintf(', '"%s (%d)",', ' foo << 1,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo<bar>() >> 1, err);') + ['strprintf(', '"%s (%d)",', ' foo<bar>() >> 1,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo < 1 ? bar : foobar, err);') + ['strprintf(', '"%s (%d)",', ' foo < 1 ? bar : foobar,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo < 1, err);') + ['strprintf(', '"%s (%d)",', ' foo < 1,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo > 1 ? bar : foobar, err);') + ['strprintf(', '"%s (%d)",', ' foo > 1 ? bar : foobar,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo > 1, err);') + ['strprintf(', '"%s (%d)",', ' foo > 1,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo <= 1, err);') + ['strprintf(', '"%s (%d)",', ' foo <= 1,', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo <= bar<1, 2>(1, 2), err);') + ['strprintf(', '"%s (%d)",', ' foo <= bar<1, 2>(1, 2),', ' err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo>foo<1,2>(1,2)?bar:foobar,err)'); + ['strprintf(', '"%s (%d)",', ' foo>foo<1,2>(1,2)?bar:foobar,', 'err', ')'] + >>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo>foo<1,2>(1,2),err)'); + ['strprintf(', '"%s (%d)",', ' foo>foo<1,2>(1,2),', 'err', ')'] """ assert(type(function_name) is str and type(function_call) is str and function_name) remaining = normalize(escape(function_call)) @@ -131,9 +157,10 @@ def parse_function_call_and_arguments(function_name, function_call): parts = [expected_function_call] remaining = remaining[len(expected_function_call):] open_parentheses = 1 + open_template_arguments = 0 in_string = False parts.append("") - for char in remaining: + for i, char in enumerate(remaining): parts.append(parts.pop() + char) if char == "\"": in_string = not in_string @@ -151,6 +178,15 @@ def parse_function_call_and_arguments(function_name, function_call): parts.append(parts.pop()[:-1]) parts.append(char) break + prev_char = remaining[i - 1] if i - 1 >= 0 else None + next_char = remaining[i + 1] if i + 1 <= len(remaining) - 1 else None + if char == "<" and next_char not in [" ", "<", "="] and prev_char not in [" ", "<"]: + open_template_arguments += 1 + continue + if char == ">" and next_char not in [" ", ">", "="] and prev_char not in [" ", ">"] and open_template_arguments > 0: + open_template_arguments -= 1 + if open_template_arguments > 0: + continue if char == ",": parts.append("") return parts |