port: advance VC6 typeobject frontier and preserve regression coverage
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Compile the exact range number table as C89 and check every named slot."""
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
source_path = Path(sys.argv[1])
|
||||
source = source_path.read_text()
|
||||
match = re.search(r"static PyNumberMethods range_as_number = \{.*?\n\};", source, re.S)
|
||||
assert match, "range_as_number initializer not found"
|
||||
header = (source_path.parent.parent / "Include/cpython/object.h").read_text()
|
||||
layout = re.search(r"typedef struct \{([^{}]*)\} PyNumberMethods;", header, re.S)
|
||||
assert layout, "PyNumberMethods layout not found"
|
||||
# Use the actual header's order and types; check slots by name, not position.
|
||||
body = re.sub(r"/\*.*?\*/", "", layout.group(1), flags=re.S)
|
||||
fields = re.findall(r"\b(nb_\w+)\s*;", body)
|
||||
assert len(fields) == 36 and len(set(fields)) == 36
|
||||
assert len(body.split(";")) == len(fields) + 1, "unparsed header field"
|
||||
harness = r'''
|
||||
#include <assert.h>
|
||||
typedef struct { int value; } PyObject;
|
||||
typedef PyObject *(*binaryfunc)(PyObject *, PyObject *);
|
||||
typedef PyObject *(*ternaryfunc)(PyObject *, PyObject *, PyObject *);
|
||||
typedef PyObject *(*unaryfunc)(PyObject *);
|
||||
typedef int (*inquiry)(PyObject *);
|
||||
static int range_bool(PyObject *self) { (void)self; return 1; }
|
||||
'''
|
||||
harness += "typedef struct {" + body + "} PyNumberMethods;\n"
|
||||
harness += match.group(0) + "\nint main(void) {\n"
|
||||
for field in fields:
|
||||
expected = {"nb_bool": "(inquiry)range_bool"}.get(field, "0")
|
||||
harness += f" assert(range_as_number.{field} == {expected});\n"
|
||||
harness += " return 0;\n}\n"
|
||||
with tempfile.TemporaryDirectory(prefix="vc6-rangeobject-number-") as directory:
|
||||
path = Path(directory)
|
||||
(path / "test.c").write_text(harness)
|
||||
result = subprocess.run([
|
||||
"cc", "-std=c89", "-pedantic-errors", "-Wall", "-Wextra", "-Werror",
|
||||
str(path / "test.c"), "-o", str(path / "test"),
|
||||
])
|
||||
if result.returncode:
|
||||
sys.exit(result.returncode)
|
||||
subprocess.run([str(path / "test")], check=True)
|
||||
print("range_as_number C89 compile and all 36 semantic field mappings: PASS")
|
||||
Reference in New Issue
Block a user