From fd597e6e6704e2a4bd03823400f2707c6e766dc0 Mon Sep 17 00:00:00 2001 From: Younes Aassila <47226184+younesaassila@users.noreply.github.com> Date: Sat, 2 Sep 2023 16:45:03 +0200 Subject: [PATCH 1/3] line breaker: fix var assignation with cast --- c_formatter_42/formatters/line_breaker.py | 42 ++++++++++++----------- tests/formatters/test_line_breaker.py | 17 ++++++--- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/c_formatter_42/formatters/line_breaker.py b/c_formatter_42/formatters/line_breaker.py index 9a89778..fb57fe9 100644 --- a/c_formatter_42/formatters/line_breaker.py +++ b/c_formatter_42/formatters/line_breaker.py @@ -39,6 +39,23 @@ def insert_break(line: str, column_limit: int) -> str: return line +def get_paren_depth(s: str) -> int: + paren_depth = 0 + is_surrounded_sq = False + is_surrounded_dq = False + for c in s: + if c == "'": + is_surrounded_sq = not is_surrounded_sq + elif c == '"': + is_surrounded_dq = not is_surrounded_dq + elif c == "(" and not is_surrounded_sq and not is_surrounded_dq: + paren_depth += 1 + elif c == ")" and not is_surrounded_sq and not is_surrounded_dq: + paren_depth -= 1 + + return paren_depth + + # The additional indent level increases in proportion to the corresponding parentheses depth # # Examples: @@ -59,31 +76,16 @@ def insert_break(line: str, column_limit: int) -> str: # > > * baz())) Next line should be indented with 2 tabs (paren depth is 2) # ----------------------------------------------------------------------------------- def additional_indent_level(s: str, nest_indent_level: int = 0) -> int: - paren_depth = 0 - is_surrounded_sq = False - is_surrounded_dq = False - for c in s: - if c == "'": - is_surrounded_sq = not is_surrounded_sq - elif c == '"': - is_surrounded_dq = not is_surrounded_dq - elif c == "(" and not is_surrounded_sq and not is_surrounded_dq: - paren_depth += 1 - elif c == ")" and not is_surrounded_sq and not is_surrounded_dq: - paren_depth -= 1 - - if paren_depth > 0: - return nest_indent_level + paren_depth - else: - return 1 # 1 is the default additional indent level + paren_depth = get_paren_depth(s) + return nest_indent_level + paren_depth if paren_depth > 0 else 1 def additional_nest_indent_level(line: str) -> int: # An exceptional rule for variable assignment # https://github.com/42School/norminette/blob/921b5e22d991591f385e1920f7e7ee5dcf71f3d5/norminette/rules/check_assignation_indent.py#L59 - align_pattern = r"^\s*({decl})((\.|->){decl})*\s+=\s+(.|\n)*?;$" - align_pattern = align_pattern.format(decl=helper.REGEX_DECL_NAME) - return 1 if re.match(align_pattern, line) is not None else 0 + parts = line.split("=") + is_assignation = len(parts) > 1 and get_paren_depth(parts[0]) == 0 + return 1 if is_assignation else 0 def line_length(line: str) -> int: diff --git a/tests/formatters/test_line_breaker.py b/tests/formatters/test_line_breaker.py index fe8ddb0..e4d98cb 100644 --- a/tests/formatters/test_line_breaker.py +++ b/tests/formatters/test_line_breaker.py @@ -224,13 +224,22 @@ def test_insert_line_break_basic_23(): def test_insert_line_break_basic_24(): - output = "*foo = foooooo(bar\n\t\t* baz);" - assert output == line_breaker("*foo = foooooo(bar * baz);", 18) + output = "foo = foooooo(bar\n\t\t* baz);" + assert output == line_breaker("foo = foooooo(bar * baz);", 18) def test_insert_line_break_basic_25(): - output = "foo[0] = foooooo(bar\n\t\t* baz);" - assert output == line_breaker("foo[0] = foooooo(bar * baz);", 20) + output = "foo[i] = foooooo(bar\n\t\t* baz);" + assert output == line_breaker("foo[i] = foooooo(bar * baz);", 21) + + +def test_insert_line_break_basic_26(): + input = ( + '((t_cast *)it->content)->name = get_name((t_cast *)it->content, "EXT=TXT");' + ) + output = """((t_cast *)it->content)->name = get_name((t_cast *)it->content, +\t\t\"EXT=TXT\");""" + assert output == line_breaker(input, 64) def test_insert_line_break_long_function_declaration(): From 6da7c4f38669fbab99d3b60b26f8a5d4428cabf2 Mon Sep 17 00:00:00 2001 From: Younes Aassila <47226184+younesaassila@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:31:17 +0200 Subject: [PATCH 2/3] Fix for strings with equal char --- c_formatter_42/formatters/line_breaker.py | 21 +++++++++++++++++---- tests/formatters/test_line_breaker.py | 5 +++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/c_formatter_42/formatters/line_breaker.py b/c_formatter_42/formatters/line_breaker.py index fb57fe9..adf64d6 100644 --- a/c_formatter_42/formatters/line_breaker.py +++ b/c_formatter_42/formatters/line_breaker.py @@ -44,9 +44,9 @@ def get_paren_depth(s: str) -> int: is_surrounded_sq = False is_surrounded_dq = False for c in s: - if c == "'": + if c == "'" and not is_surrounded_dq: is_surrounded_sq = not is_surrounded_sq - elif c == '"': + elif c == '"' and not is_surrounded_sq: is_surrounded_dq = not is_surrounded_dq elif c == "(" and not is_surrounded_sq and not is_surrounded_dq: paren_depth += 1 @@ -83,8 +83,21 @@ def additional_indent_level(s: str, nest_indent_level: int = 0) -> int: def additional_nest_indent_level(line: str) -> int: # An exceptional rule for variable assignment # https://github.com/42School/norminette/blob/921b5e22d991591f385e1920f7e7ee5dcf71f3d5/norminette/rules/check_assignation_indent.py#L59 - parts = line.split("=") - is_assignation = len(parts) > 1 and get_paren_depth(parts[0]) == 0 + index = 0 + is_surrounded_sq = False + is_surrounded_dq = False + for c in line: + if c == "'" and not is_surrounded_dq: + is_surrounded_sq = not is_surrounded_sq + elif c == '"' and not is_surrounded_sq: + is_surrounded_dq = not is_surrounded_dq + elif c == "=" and not is_surrounded_sq and not is_surrounded_dq: + break + index += 1 + if index == len(line): + return 0 + var_name = line[:index].strip() + is_assignation = get_paren_depth(var_name) == 0 return 1 if is_assignation else 0 diff --git a/tests/formatters/test_line_breaker.py b/tests/formatters/test_line_breaker.py index e4d98cb..5e9d791 100644 --- a/tests/formatters/test_line_breaker.py +++ b/tests/formatters/test_line_breaker.py @@ -234,6 +234,11 @@ def test_insert_line_break_basic_25(): def test_insert_line_break_basic_26(): + output = '"EXT = TXT" + foooooo(bar\n\t* baz);' + assert output == line_breaker('"EXT = TXT" + foooooo(bar * baz);', 27) + + +def test_insert_line_break_basic_27(): input = ( '((t_cast *)it->content)->name = get_name((t_cast *)it->content, "EXT=TXT");' ) From 9a57436e3b5a08b3eb523ced57143052f9f0b928 Mon Sep 17 00:00:00 2001 From: Younes Aassila <47226184+younesaassila@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:53:48 +0200 Subject: [PATCH 3/3] Improve code --- c_formatter_42/formatters/line_breaker.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/c_formatter_42/formatters/line_breaker.py b/c_formatter_42/formatters/line_breaker.py index adf64d6..bb069d6 100644 --- a/c_formatter_42/formatters/line_breaker.py +++ b/c_formatter_42/formatters/line_breaker.py @@ -83,21 +83,23 @@ def additional_indent_level(s: str, nest_indent_level: int = 0) -> int: def additional_nest_indent_level(line: str) -> int: # An exceptional rule for variable assignment # https://github.com/42School/norminette/blob/921b5e22d991591f385e1920f7e7ee5dcf71f3d5/norminette/rules/check_assignation_indent.py#L59 - index = 0 + is_assignation = False is_surrounded_sq = False is_surrounded_dq = False - for c in line: + for index, c in enumerate(line): if c == "'" and not is_surrounded_dq: is_surrounded_sq = not is_surrounded_sq elif c == '"' and not is_surrounded_sq: is_surrounded_dq = not is_surrounded_dq - elif c == "=" and not is_surrounded_sq and not is_surrounded_dq: + is_assignation = ( + c == "=" + and not is_surrounded_sq + and not is_surrounded_dq + and get_paren_depth(line[:index]) == 0 + ) + if is_assignation: break - index += 1 - if index == len(line): - return 0 - var_name = line[:index].strip() - is_assignation = get_paren_depth(var_name) == 0 + return 1 if is_assignation else 0