import subprocess, re, sys

SITES = r"C:/Users/decid/AppData/Local/Temp/claude/C--Users-decid-Documents-projects-spt-core/43af483b-6d22-46cb-9d99-8b7713a6ff46/scratchpad/cut-4d6007ac/census_sites.txt"
SHA = "4d6007ac"
rows = [l.split("\t") for l in open(SITES, encoding="utf-8").read().splitlines()]

cache = {}
def blob(p):
    if p not in cache:
        cache[p] = subprocess.run(["git", "show", SHA + ":" + p], capture_output=True, check=True).stdout.decode("utf-8", "replace")
    return cache[p]

MACRO = re.compile(r"\b(eprintln!|println!|eprint!|print!)")
MACRO_OPEN = re.compile(r"\b(eprintln!|println!|eprint!|print!)\s*\(")
def literals(text):
    """string literals of a Rust call, walked with the same state machine as call_text
    (a regex char class here was mis-built twice; the walker is the thing already proven)."""
    out = []
    cur = None
    esc = False
    for c in text:
        if cur is None:
            if c == '"':
                cur = []
            continue
        if esc:
            cur.append(c)
            esc = False
            continue
        if c == chr(92):
            cur.append(c)
            esc = True
            continue
        if c == '"':
            out.append(''.join(cur))
            cur = None
            continue
        cur.append(c)
    return out
ESC_N = chr(92) + "n"

def call_text(src, macro_line_idx):
    lines = src.split("\n")
    text = "\n".join(lines[macro_line_idx:macro_line_idx + 60])
    m = MACRO_OPEN.search(text)
    if not m:
        return None
    i = m.end() - 1
    depth = 0
    instr = False
    esc = False
    for k in range(i, len(text)):
        c = text[k]
        if instr:
            if esc:
                esc = False
            elif c == chr(92):
                esc = True
            elif c == '"':
                instr = False
            continue
        if c == '"':
            instr = True
        elif c == "(":
            depth += 1
        elif c == ")":
            depth -= 1
            if depth == 0:
                return text[i:k + 1]
    return None

interior = []
unterminated = []
skipped = 0
for loc, tok, mac in rows:
    path, ln = loc.rsplit(":", 1)
    src = blob(path)
    lines = src.split("\n")
    j = int(ln) - 1
    start = j
    for k in range(j, max(-1, j - 5), -1):
        if MACRO.search(lines[k]):
            start = k
            break
    ct = call_text(src, start)
    if ct is None:
        skipped += 1
        continue
    lits = literals(ct)
    n = sum(l.count(ESC_N) for l in lits)
    if n:
        interior.append((loc, tok, mac, n))
    if mac in ("eprint!", "print!"):
        if not lits or not lits[-1].endswith(ESC_N):
            unterminated.append((loc, tok, mac))

# known-positive sentinel: the escaped-newline detector must find the site we
# already read by hand (firewall.rs carries the newline in the PAYLOAD, not the
# literal, so the sentinel here is a literal we verified separately).
print("rows", len(rows), "unparsed calls", skipped)
print("sites with an escaped newline INSIDE a string literal of the call:", len(interior))
for r in interior[:15]:
    print("   ", r[0], r[1], r[2], "count=", r[3])
print("non-ln macro sites whose last literal is not newline-terminated:", len(unterminated))
for r in unterminated:
    print("   ", r)
