Bans bare C printf-family calls inside src/ (FastLED #2773 item 1.5).
| 62 | |
| 63 | |
| 64 | class BareSnprintfChecker(FileContentChecker): |
| 65 | """Bans bare C printf-family calls inside src/ (FastLED #2773 item 1.5).""" |
| 66 | |
| 67 | def __init__(self): |
| 68 | self.violations: dict[str, list[tuple[int, str]]] = {} |
| 69 | |
| 70 | def should_process_file(self, file_path: str) -> bool: |
| 71 | # Only src/. |
| 72 | if not file_path.startswith(str(SRC_ROOT)): |
| 73 | return False |
| 74 | if not file_path.endswith((".cpp", ".h", ".hpp")): |
| 75 | return False |
| 76 | norm = file_path.replace("\\", "/") |
| 77 | # Skip the shim itself. |
| 78 | for exempt in EXEMPT_FILES: |
| 79 | if norm.endswith(exempt): |
| 80 | return False |
| 81 | # Skip third-party upstream code — we don't control these sources. |
| 82 | if "/third_party/" in norm: |
| 83 | return False |
| 84 | # Skip host-only unit-test watchdog scaffolding. These files are HOST |
| 85 | # test infrastructure (apple/posix/win) and never link into ESP32 |
| 86 | # firmware, so the binary-size argument doesn't apply. |
| 87 | if norm.endswith("/run_unit_test.hpp"): |
| 88 | return False |
| 89 | return True |
| 90 | |
| 91 | def check_file_content(self, file_content: FileContent) -> list[str]: |
| 92 | violations: list[tuple[int, str]] = [] |
| 93 | in_block_comment = False |
| 94 | |
| 95 | for line_number, line in enumerate(file_content.lines, 1): |
| 96 | stripped = line.strip() |
| 97 | |
| 98 | # Track /* ... */ blocks (single-line case handled by the slice below). |
| 99 | if in_block_comment: |
| 100 | if "*/" in line: |
| 101 | in_block_comment = False |
| 102 | continue |
| 103 | if "/*" in line and "*/" not in line: |
| 104 | in_block_comment = True |
| 105 | continue |
| 106 | |
| 107 | if stripped.startswith("//"): |
| 108 | continue |
| 109 | if _SUPPRESS in line: |
| 110 | continue |
| 111 | |
| 112 | # Strip trailing // comment so we don't match inside a comment. |
| 113 | code = line.split("//")[0] |
| 114 | if _BANNED_PATTERN.search(code): |
| 115 | violations.append((line_number, line.rstrip())) |
| 116 | |
| 117 | if violations: |
| 118 | self.violations[file_content.path] = violations |
| 119 | |
| 120 | return [] |
| 121 |
no outgoing calls
no test coverage detected