55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Compile the exact PickleBuffer buffer table as C89 and check both slots."""
|
|
|
|
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 PyBufferProcs picklebuf_as_buffer = \{.*?\n\};", source, re.S)
|
|
assert match, "picklebuf_as_buffer initializer not found"
|
|
header = (source_path.parent.parent / "Include/cpython/object.h").read_text()
|
|
layout = re.search(r"typedef struct \{([^{}]*)\} PyBufferProcs;", header, re.S)
|
|
assert layout, "PyBufferProcs layout not found"
|
|
body = re.sub(r"/\*.*?\*/", "", layout.group(1), flags=re.S)
|
|
assert re.findall(r"\b(bf_\w+)\s*;", body) == ["bf_getbuffer", "bf_releasebuffer"]
|
|
harness = r'''
|
|
#include <assert.h>
|
|
typedef struct { int unused; } PyObject;
|
|
typedef struct { int unused; } Py_buffer;
|
|
typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
|
|
typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
|
|
static int picklebuf_getbuf(PyObject *self, Py_buffer *view, int flags)
|
|
{
|
|
(void)self; (void)view; return flags;
|
|
}
|
|
static void picklebuf_releasebuf(PyObject *self, Py_buffer *view)
|
|
{
|
|
(void)self; (void)view;
|
|
}
|
|
'''
|
|
harness += "typedef struct {" + body + "} PyBufferProcs;\n"
|
|
harness += match.group(0)
|
|
harness += r'''
|
|
int main(void)
|
|
{
|
|
assert(picklebuf_as_buffer.bf_getbuffer == (getbufferproc)picklebuf_getbuf);
|
|
assert(picklebuf_as_buffer.bf_releasebuffer == (releasebufferproc)picklebuf_releasebuf);
|
|
return 0;
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix="vc6-picklebuf-buffer-") 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("picklebuf_as_buffer C89 compile and both semantic field mappings: PASS")
|