Return the text inside the `while ( ... )` opener that begins on `lines[start_idx]`, joining continuation lines until parens balance. Returns None if the opener cannot be parsed cleanly (e.g. embedded in a macro or split awkwardly across the file).
(lines: list[str], start_idx: int)
| 2712 | # opening `(` after `while`, counting depth across multi-line conditions, and |
| 2713 | # return the inner text. Cheap, no second parse, no false multi-line miss. |
| 2714 | def _gather_while_condition(lines: list[str], start_idx: int) -> str | None: |
| 2715 | """Return the text inside the `while ( ... )` opener that begins on |
| 2716 | `lines[start_idx]`, joining continuation lines until parens balance. |
| 2717 | Returns None if the opener cannot be parsed cleanly (e.g. embedded in a |
| 2718 | macro or split awkwardly across the file).""" |
| 2719 | first = _strip_strings_and_line_comments(lines[start_idx]) |
| 2720 | m = re.search(r"\bwhile\s*\(", first) |
| 2721 | if not m: |
| 2722 | return None |
| 2723 | pos = m.end() |
| 2724 | depth = 1 |
| 2725 | pieces: list[str] = [] |
| 2726 | line_idx = start_idx |
| 2727 | cur = first[pos:] |
| 2728 | while line_idx < len(lines): |
| 2729 | for ch in cur: |
| 2730 | if ch == "(": |
| 2731 | depth += 1 |
| 2732 | elif ch == ")": |
| 2733 | depth -= 1 |
| 2734 | if depth == 0: |
| 2735 | break |
| 2736 | pieces.append(ch) |
| 2737 | if depth == 0: |
| 2738 | break |
| 2739 | line_idx += 1 |
| 2740 | if line_idx >= len(lines): |
| 2741 | return None |
| 2742 | cur = _strip_strings_and_line_comments(lines[line_idx]) |
| 2743 | pieces.append(" ") |
| 2744 | if depth != 0: |
| 2745 | return None |
| 2746 | return "".join(pieces) |
| 2747 | |
| 2748 | |
| 2749 | # Canonical bounded shapes drawn from the catalog in |
no test coverage detected