$rLine) { if (!preg_match('/^(\t+)(?:\} )?while \(/', $rLine, $rM)) { continue; } $rChecked++; $rEnd = self::closes($rLines, $rNo, strlen($rM[1])); $rLast = $rEnd === null ? '' : trim($rLines[$rEnd - 1]); $this->assertNotSame( 'break;', $rLast, basename($rFile) . ':' . $rEnd . ": the loop's last statement is an unconditional break, so the daemon re-executes itself every pass" ); } } $this->assertGreaterThan(4, $rChecked, 'the daemon loops were not found at all'); } /** The line (0-based) of the `}` that closes a block opened at $rNo, indented with $rTabs tabs. */ private static function closes(array $rLines, int $rNo, int $rTabs): ?int { $rClose = str_repeat("\t", $rTabs) . '}'; for ($i = $rNo + 1; $i < count($rLines); $i++) { if (str_starts_with($rLines[$i], $rClose)) { return $i; } } return null; } }