#!/usr/bin/env python3 """Check C89 locals in bytes find and repeat helpers.""" import sys from pathlib import Path if len(sys.argv) != 2: raise SystemExit("usage: vc6-bytes-core-c89.test.py bytesobject.c") source = Path(sys.argv[1]).read_text() def function_body(signature): start = source.index(signature) body_start = source.index("\n{\n", start) + 2 body_end = source.index("\n}\n", body_start) return source[body_start:body_end] find = function_body("_PyBytes_Find(const char *haystack") if not find.lstrip().startswith("Py_ssize_t res;"): raise SystemExit("_PyBytes_Find res must be declared in its entry group") if "Py_ssize_t res =" in find: raise SystemExit("_PyBytes_Find res declaration must be separate from assignment") if "if (res == -1) {\n Py_ssize_t last_align;" not in find: raise SystemExit("_PyBytes_Find last_align must be declared at the conditional block entry") if not (find.index("res = stringlib_find(") < find.index("if (res == -1)") < find.index("last_align = len_haystack - len_needle;") < find.index("memcmp(haystack + last_align")): raise SystemExit("_PyBytes_Find search and trailing-alignment order changed") repeat = function_body("_PyBytes_Repeat(char* dest") if "else {\n Py_ssize_t copied;\n if (src != dest)" not in repeat: raise SystemExit("_PyBytes_Repeat copied must be declared at the else-block entry") if "Py_ssize_t copied =" in repeat: raise SystemExit("_PyBytes_Repeat copied declaration must be separate from assignment") if not (repeat.index("memcpy(dest, src, len_src);") < repeat.index("copied = len_src;") < repeat.index("while (copied < len_dest)")): raise SystemExit("_PyBytes_Repeat copy loop initialization order changed") print("bytes find/repeat C89 declarations and execution order: PASS")