#!/usr/bin/env python3 """Check C89 declaration placement in immutable stringlib partitions.""" import sys from pathlib import Path if len(sys.argv) != 2: raise SystemExit("usage: vc6-stringlib-partition-c89.test.py partition.h") source = Path(sys.argv[1]).read_text() expected_orders = { "partition": ( "Py_INCREF(str_obj);", "empty = (PyObject*)STRINGLIB_GET_EMPTY();", "assert(empty != NULL);", "Py_INCREF(empty);", "PyTuple_SET_ITEM(out, 1, empty);", "Py_INCREF(empty);", "PyTuple_SET_ITEM(out, 2, empty);", ), "rpartition": ( "empty = (PyObject*)STRINGLIB_GET_EMPTY();", "assert(empty != NULL);", "Py_INCREF(empty);", "PyTuple_SET_ITEM(out, 0, empty);", "Py_INCREF(empty);", "PyTuple_SET_ITEM(out, 1, empty);", "Py_INCREF(str_obj);", "PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);", ), } for name, order in expected_orders.items(): signature = "STRINGLIB(" + name + ")(" start = source.index(signature) body_start = source.index("\n{\n", start) + 2 body_end = source.index("\n}\n", body_start) body = source[body_start:body_end] opening, no_match = body.split(" if (pos < 0)", 1) if "#if !STRINGLIB_MUTABLE\n PyObject *empty;\n#endif" not in opening: raise SystemExit(name + ": empty must be declared in the C89 entry declaration group") if body.count("PyObject *empty;") != 1 or "PyObject *empty =" in body: raise SystemExit(name + ": empty must have one separate declaration") branch_start = no_match.index("#else") branch_end = no_match.index("#endif", branch_start) branch = no_match[branch_start:branch_end] cursor = 0 for statement in order: position = branch.find(statement, cursor) if position < 0: raise SystemExit(name + ": empty reference-count / tuple insertion order changed") cursor = position + len(statement) print("stringlib partition C89 declarations and ownership order: PASS")