port: advance MSVC600 CPython compatibility frontier
This commit is contained in:
+857
-26
@@ -1,10 +1,866 @@
|
|||||||
# Port Status — CPython 3.11.16 to Windows 98 SE
|
# Port Status — CPython 3.11.16 to Windows 98 SE
|
||||||
|
|
||||||
Date: 2026-08-17
|
Date: 2026-08-22
|
||||||
Baseline: CPython `v3.11.16`
|
Baseline: CPython `v3.11.16`
|
||||||
Compiler: MSVC 6.0 (`cl.exe` 12.00.8804), from external `MSVC600`
|
Compiler: MSVC 6.0 (`cl.exe` 12.00.8804), from external `MSVC600`
|
||||||
Host test environment: Linux + Wine
|
Host test environment: Linux + Wine
|
||||||
|
|
||||||
|
## Files changed in this revision (`_blake2/blake2b_impl.c` ULL-literal + declaration-order + `long long`/designated-initializer slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Modules/_blake2/impl/blake2b-ref.c` — two separate slices, each re-probed individually before moving to the next:
|
||||||
|
- **ULL/LL literal-suffix root blocker.** Inventoried every C99 `ULL`/`LL`-suffixed integer literal in the file by grep (`grep -n "ULL\|[0-9]LL\b"`): the 8 `blake2b_IV[8]` initializer constants (lines 23-26) and 4 occurrences of `~0ULL`/`0ULL` in `blake2b_set_lastnode()`/`blake2b_clear_lastnode()`/`blake2b_set_lastblock()`/`blake2b_clear_lastblock()` (lines 48, 54, 63, 71) — 12 literals total, and no others (`blake2b_impl.c` itself has one more at line 163, but it sits inside a dead `#ifdef HAVE_BLAKE2S` branch that is never defined in this port, so the C preprocessor only needs to recognize it as a pp-number token to skip it, not evaluate its suffix, and it was left alone). VC6's C89 front end rejects the C99 `ULL`/`LL` suffix spelling outright (`error C2059: syntax error : 'bad suffix on number'`) but does accept the Microsoft-specific `i64`/`ui64` 64-bit literal suffixes. Rather than rewriting the literals to bare `ui64` (a new, unreviewed spelling choice), every literal was routed through the existing `PY_LL`/`PY_ULL` macro pair already defined in `PC/pyconfig.h` for exactly this compiler (`#define PY_ULL(x) x##ui64` when `_MSC_VER < 1300`, else `x##ULL`) — the same macro pair `Include/pyport.h` already anticipates via its own `#ifndef PY_LL` guard and accompanying comment ("see PC/pyconfig.h for the compilers that need something other than the C99 LL/ULL suffixes"), and the same defect family/fix shape as the earlier `PY_LONG_LONG` routing for `_abc.c`. `blake2b-ref.c` is `#include`d from `blake2b_impl.c` *after* `#include "Python.h"`, so `PY_ULL` is already visible by the time it is preprocessed; no new include was added. Every literal's digit value is unchanged — `0x6a09e667f3bcc908ULL` became `PY_ULL(0x6a09e667f3bcc908)`, `~0ULL` became `~PY_ULL(0)`, etc. — this is a suffix-spelling change only, and it round-trips to the identical `x##ULL` expansion on every non-VC6 compiler, so no behavior change on any other target.
|
||||||
|
- **C89 declaration-order fallout in the same file**, the next diagnostic once the literal-suffix errors cleared: `blake2b_init0()` declared its `for` loop counter as a C99 `for( int i = 0; ...)` init-declaration, and `blake2b_init_param()` declared `uint8_t *p` after the `blake2b_init0( S )` statement and used a second C99 `for( size_t i = 0; ...)` init-declaration. Both were hoisted to each function's opening declaration group (`int i;` / `uint8_t *p; size_t i;`), with every assignment left at its original execution point (`p = (uint8_t *)(P);` still runs right after `blake2b_init0(S)`, in the same order) — the same hoist-and-reprobe pattern already used throughout this port (`_abc.c`, `getpath.c`, `pystate.c`). No control flow or arithmetic changed.
|
||||||
|
- `cpython/Modules/_blake2/blake2b_impl.c` — two more of the previously-characterized-but-unfixed defect families, each re-probed individually:
|
||||||
|
- Changed `unsigned long long node_offset` (the `py_blake2b_new_impl()` parameter, line 94) to `unsigned PY_LONG_LONG node_offset`. VC6 has no `long long` keyword (`error C2632: 'long' followed by 'long' is illegal`); this is not a new port-local convention — CPython's own public headers already spell 64-bit unsigned parameters exactly this way for the same reason (e.g. `Include/longobject.h`'s `PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG)` and `PyLong_AsUnsignedLongLong`). `_PyLong_UnsignedLongLong_Converter()` (the Argument Clinic-generated converter call site for this parameter) takes a `void *` out-parameter, so the declared-type change has no call-site ABI/type-mismatch implications.
|
||||||
|
- `py_blake2b_dealloc()`: hoisted `PyTypeObject *type` into the function's opening declaration group (previously declared, C89-illegally, after the lock-free and secure-zero statements); the assignment `type = Py_TYPE(self);` stays at its original point, immediately before `PyObject_Free(self)`/`Py_DECREF(type)`, unchanged.
|
||||||
|
- `blake2b_type_spec`: converted from C99 designated initializers (`.name = ...`, `.basicsize = ...`, `.flags = ...`, `.slots = ...`) to plain positional initializers in `PyType_Spec`'s declared field order from `Include/object.h` (`name`, `basicsize`, `itemsize`, `flags`, `slots`); the struct's initializer omitted `itemsize`, so the positional form spells that slot `0` explicitly, matching the implicit C99 zero-fill it already had. Same defect family and fix approach as `_abc_data_type_spec`/`_abcmodule`/`_bisectmodule`'s `PyModuleDef` literals earlier in this port. Field values and order are unchanged.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` (4800 lines) so the project-local compatibility patch includes this `_blake2/blake2b_impl.c` slice plus all prior uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` worktree exited 0; the temporary worktree was removed afterward.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 (each script individually) — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, stdint shim suite, and pythoncore frontier regression suite all passed with no regressions after this slice. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (before this revision's first edit) | exit 2 — confirmed the recorded first blocker reproduces exactly: bare `ULL` literal-suffix errors in `impl/blake2b-ref.c` (`error C2059: syntax error : 'bad suffix on number'`) as the first diagnostic for `Modules/_blake2/blake2b_impl.c`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after the `PY_ULL`/`PY_LL` literal-suffix slice only) | exit 2 — every `ULL`-suffix diagnostic is gone. New first blocker: `cpython\Modules\_blake2\impl/blake2b-ref.c(143) : error C2143: syntax error : missing ';' before 'type'` (the `for( int i = ...)` C99 init-declaration in `blake2b_init0()`), with follow-on errors at lines 165/168-169 in `blake2b_init_param()`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after the `blake2b-ref.c` declaration-order slice) | exit 2 — `impl/blake2b-ref.c` is now fully clean (no diagnostics reference it anymore). New first blockers, all in `Modules/_blake2/blake2b_impl.c`/its clinic header: `error C2632: 'long' followed by 'long' is illegal` at `clinic/blake2b_impl.c.h(18)`, `clinic/blake2b_impl.c.h(39)`, and `blake2b_impl.c(94)`; `error C2275: 'PyTypeObject' : illegal use of this type as an expression` at `blake2b_impl.c(397)`; and `error C2059: syntax error : '.'` at `blake2b_impl.c(412)`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after the `unsigned PY_LONG_LONG` slice only) | exit 2 — all three `long long` diagnostics are gone; the `PyTypeObject`/designated-initializer diagnostics at lines 397/412 remain, confirming they are independent defects rather than parser-desync fallout. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after the `py_blake2b_dealloc()`/`blake2b_type_spec` slice — final state this revision) | exit 2 — `Modules/_blake2/blake2b_impl.c` now compiles with **zero** errors and **zero** warnings; `total=6 compiled=5 cached=0 skipped=0`. The frontier advances to the next source in `pythoncore.vcxproj` order, `Modules/_blake2/blake2s_impl.c` (autogenerated from `blake2b_impl.c` per its own header comment), whose first blockers are the identical defect families mirrored into the `s`-variant files: C99 `for`-init-declarations in `impl/blake2s-ref.c` (lines 231, 275), `unsigned long long` in `clinic/blake2s_impl.c.h`(18,39)/`blake2s_impl.c`(94), a bare `ULL`-suffix literal at `blake2s_impl.c(163)` (`if (node_offset > 0xFFFFFFFFFFFFULL)`, guarded by `#ifdef HAVE_BLAKE2S` in `blake2b_impl.c` but **not** guarded in `blake2s_impl.c`, so it is live code there), and the same `PyTypeObject *type = Py_TYPE(self);`/designated-initializer pair at `blake2s_impl.c`(397)/(412). None of this has been fixed yet. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Modules/main.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython worktree remove ../build/verify-vc6-patch-worktree --force` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree; temporary worktree removed. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** `Modules/_blake2/blake2b_impl.c` (and its `#include`d `impl/blake2b-ref.c`) is fully clean under the VC6 frontier probe (0 errors, 0 warnings), advancing the frontier past `_abc.c`, `_bisectmodule.c`, `blake2module.c`, and now `blake2b_impl.c`. The frontier has moved on to `Modules/_blake2/blake2s_impl.c`, whose first blocker set is the same defect families just fixed here, mirrored into the autogenerated `s`-variant sources — plus one new wrinkle: the `0xFFFFFFFFFFFFULL` node-offset overflow check that sits inside a dead `#ifdef HAVE_BLAKE2S` branch in `blake2b_impl.c` (and so never needed fixing there) is **not** dead code in `blake2s_impl.c`, so its `ULL` suffix will need the same `PY_ULL()` treatment as a live diagnostic this time. Recommended next slice: mirror this revision's three sub-slices onto the `s`-variant files in the same order (literal suffixes in `impl/blake2s-ref.c` plus the live `blake2s_impl.c(163)` literal first, then `blake2s-ref.c`'s C89 declaration-order fallout, then `unsigned PY_LONG_LONG`/`PyTypeObject`/designated-initializer in `blake2s_impl.c`/its clinic header), re-probing after each sub-slice as done here.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`compat/msvc600/stdint.h` shim + `_blake2/blake2module.c` slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `compat/msvc600/stdint.h` — new VC6-scoped project-local compatibility header providing the missing C99 `<stdint.h>` that `cpython/Modules/_blake2/impl/blake2.h` and `blake2-impl.h` `#include`. **Evidence before adding it:** grepped every fixed-width-integer identifier (`u?int(8|16|32|64)_t`, `u?intptr_t`, `u?int_least*_t`, `u?int_fast*_t`, `size_t`) across the entire `Modules/_blake2/` tree (both impl headers/sources and the `blake2b_impl.c`/`blake2s_impl.c`/clinic wrappers). The only fixed-width types actually used anywhere in that tree are `uint8_t`, `uint32_t`, and `uint64_t` (in `load32/64/48`, `store32/64/48`, `rotl32/64`, `rotr32/64`, and the reference block-compression loops); no `int8_t`/`int16_t`/`int32_t`/`int64_t` or `intptr_t`/`uintptr_t` appear at all. `size_t` is also used but is unaffected — it already comes from `<stddef.h>`, which VC6 has natively. **Design:** rather than re-declaring these three typedefs a second time under a second include guard, `stdint.h` forwards to the already-existing, already-verified `compat/msvc600/inttypes.h` (added in an earlier revision so CPython's own `Include/pyport.h`, which does `#include <inttypes.h>`, would compile) via `#include "inttypes.h"`. `inttypes.h`'s own include guard makes this forwarding idempotent regardless of which of the two headers a given translation unit reaches first, so a TU that ends up pulling in both `Python.h` (→ `pyport.h` → `<inttypes.h>`) and `blake2.h` (→ `<stdint.h>`) cannot hit a duplicate-typedef error. Width assumptions (unchanged, already relied on by `inttypes.h`): `uint8_t` = `unsigned char` (1 byte), `uint32_t` = `unsigned long` (4 bytes on Win32/ILP32), `uint64_t` = `unsigned __int64` (VC6's non-standard 64-bit extension, 8 bytes) — verified sufficient by a compile-time fixture (below) using `typedef char check[(sizeof(uint32_t)==4) ? 1 : -1];`-style width assertions, since VC6 has no `static_assert`.
|
||||||
|
- `scripts/fixtures/vc6_stdint_smoke.c` — new focused compile fixture: includes both `<stdint.h>` and `<inttypes.h>` in the same translation unit (reproducing the Python.h + blake2.h coexistence case), asserts `sizeof(uint8_t)==1`/`sizeof(uint32_t)==4`/`sizeof(uint64_t)==8` at compile time, and exercises `load32`/`load64`/`rotl32`/`rotl64` in the same shape `blake2-impl.h` uses.
|
||||||
|
- `scripts/vc6-probe-stdint.test.sh` — new regression test for the shim and fixture under the VC6 probe, modeled directly on the existing `scripts/vc6-probe-pathcch.test.sh` (skips, not fails, when Wine/MSVC600 are unavailable).
|
||||||
|
- `cpython/Modules/_blake2/blake2module.c` — with the `<stdint.h>` blocker gone, the file advanced to two blockers from defect families already fixed elsewhere in this port: (1) `blake2_exec()` declared `PyObject *d = st->blake2b_type->tp_dict;` after preceding statements (C89 mixed-declaration; VC6 requires declarations before statements) — hoisted `PyObject *d;` into the function's opening declaration group and changed the first assignment to plain `d = ...`, leaving the second assignment (`d = st->blake2s_type->tp_dict;`) unchanged since `d` was already in scope there; (2) the `blake2_module` `PyModuleDef` struct literal mixed a positional `PyModuleDef_HEAD_INIT`/`"_blake2"` prefix with C99 designated initializers (`.m_doc = ...` etc.) for the rest — converted to plain positional initializers in `Include/moduleobject.h`'s declared field order (`m_base`, `m_name`, `m_doc`, `m_size`, `m_methods`, `m_slots`, `m_traverse`, `m_clear`, `m_free`), the same defect family and fix already used in `_abc.c` and `_bisectmodule.c`. Field values and order are unchanged — this is a spelling change only, not a behavior change.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` (4651 lines) so the project-local compatibility patch includes this `stdint.h`/`blake2module.c` slice plus all prior uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` worktree exited 0; the temporary worktree was removed afterward.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-stdint.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 (each script individually) — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, new stdint shim suite, and pythoncore frontier regression suite all passed with no regressions after this slice. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (before this slice) | exit 2 — confirmed the recorded first blocker reproduces exactly: `cpython\Modules\_blake2\impl/blake2.h(18) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory`. Summary: `total=4 compiled=3 cached=0 skipped=0`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after adding `compat/msvc600/stdint.h` only, before the `blake2module.c` source edits) | exit 2 — the missing-`stdint.h` fatal error is gone; new first blocker is `cpython\Modules\_blake2\blake2module.c(98) : error C2275: 'PyObject' : illegal use of this type as an expression` (C89 mixed-declaration) immediately followed by the `.m_doc = ...` designated-initializer `error C2059: syntax error : '.'` at line 145. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after the `blake2module.c` slice) | exit 2 — `Modules/_blake2/blake2module.c` now compiles with **zero** errors and **zero** warnings. The frontier advances to the next source in `pythoncore.vcxproj` order, `Modules/_blake2/blake2b_impl.c`, whose new first blockers are a different defect family: bare `0ULL`/`64ULL`-style integer-literal suffixes in `Modules/_blake2/impl/blake2b-ref.c` (`error C2059: syntax error : 'bad suffix on number'` — VC6's C89 front end does not accept the C99 `ULL`/`LL` integer-constant suffixes at all, only `UL`/`L`/`U`), C99 mixed-declaration/`for`-init-declaration fallout in the same file, `unsigned long long` in `clinic/blake2b_impl.c.h` and `blake2b_impl.c` itself (the same `long long`-keyword gap already routed through `PY_LONG_LONG` elsewhere in this port), and a `PyTypeObject *type = ...` C89 mixed-declaration plus a `.` designated-initializer in `blake2b_impl.c`. None of this has been fixed yet. Summary: `total=5 compiled=4 cached=0 skipped=0`. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Modules/main.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython worktree remove ../build/verify-vc6-patch-worktree --force` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree; temporary worktree removed. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** `Modules/_blake2/blake2module.c` is fully clean under the VC6 frontier probe (0 errors, 0 warnings), advancing the frontier past `_abc.c`, `_bisectmodule.c`, and now `blake2module.c`. The frontier has moved on to `Modules/_blake2/blake2b_impl.c` (via its `#include`d `impl/blake2b-ref.c`), whose first blocker is a new defect family for this port: VC6's C89 front end rejects the C99 `ULL`/`LL` unsigned-long-long integer-literal suffixes used throughout the BLAKE2 reference constants and IV tables. This is distinct from the already-solved `long long` *keyword* gap (`PY_LONG_LONG`) — it is about literal-suffix spelling, and will need either rewriting the affected literals (e.g. `0x6A09E667F3BCC908ULL` → a `PY_LONG_LONG`-safe spelling, likely via a cast or an `_LL`/`ui64`-suffix substitution valid under VC6) or a targeted macro, plus the follow-on C89 declaration-order, `long long`-keyword, and designated-initializer fixes already characterized above in `blake2b_impl.c` and its clinic header. Recommended next slice: `Modules/_blake2/impl/blake2b-ref.c`'s integer-literal suffixes first (it is the root blocker `blake2b_impl.c` `#include`s), then re-probe before touching `blake2b_impl.c` itself.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`_bisectmodule.c` designated-initializer slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Modules/_bisectmodule.c` — converted the `_bisectmodule` `PyModuleDef` struct literal from C99 designated initializers (`.m_name = ...`, `.m_size = ...`, etc.) to plain positional initializers in the struct's declared field order (`m_base`, `m_name`, `m_doc`, `m_size`, `m_methods`, `m_slots`, `m_traverse`, `m_clear`, `m_free`, per `Include/moduleobject.h`). This is the same defect family and same fix approach already used twice in `_abc.c` (`error C2059: syntax error : '.'`; VC6 has no C99 designated-initializer support). The struct had no `m_traverse` initializer in the original, so the corresponding positional slot is `NULL`. Field values and order are otherwise unchanged — this is a spelling change only, not a behavior change. No declaration-order (C89 mixed-declaration) errors followed this fix; the file compiles clean end-to-end on the first re-probe.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` (4609 lines) so the project-local compatibility patch includes this `_bisectmodule.c` slice plus all prior uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` worktree exited 0; the temporary worktree was removed afterward.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 (each script individually) — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, and pythoncore frontier regression suite all passed with no regressions after this slice. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (before this slice) | exit 2 — confirmed the recorded first blocker reproduces exactly: `cpython\Modules\_bisectmodule.c(329) : error C2059: syntax error : '.'` at `.m_name = "_bisect",` in the `_bisectmodule` `PyModuleDef` initializer. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after this slice) | exit 2 — `Modules/_bisectmodule.c` now compiles with **zero** errors and **zero** warnings (only the source-filename echo from `cl.exe`, same as a clean compile). The frontier advances to the next source in `pythoncore.vcxproj` order, `Modules/_blake2/blake2module.c`, whose new first blocker is `cpython\Modules\_blake2\impl/blake2.h(18) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory` — a missing modern-C/SDK standard header, a different defect family from designated initializers or C89 declaration ordering, and not yet addressed here. Summary: `total=4 compiled=3 cached=0 skipped=0`. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Modules/main.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython worktree remove ../build/verify-vc6-patch-worktree --force` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree; temporary worktree removed. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** `Modules/_bisectmodule.c` is fully clean under the VC6 frontier probe (0 errors, 0 warnings), advancing the frontier past both `_abc.c` and `_bisectmodule.c`. The frontier has moved on to `Modules/_blake2/blake2module.c`, whose first blocker is a missing `<stdint.h>` (needed by `Modules/_blake2/impl/blake2.h` for fixed-width integer types like `uint32_t`/`uint64_t`). This is a new defect family — a missing standard/SDK header, not a source-level C89/C99 compatibility issue — and will likely need either a project-local `stdint.h` compatibility shim (similar in spirit to the existing `compat/msvc600/pathcch.h` shim) or a decision to exclude/stub the `_blake2` module for this port, rather than a source-hoist slice. The recommended next step is to characterize the actual `uint32_t`/`uint64_t`/etc. usage in `Modules/_blake2/impl/*.h` before choosing between those two approaches.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`_abc.c` C89 declaration-hoist + designated-initializer slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Modules/_abc.c` — advanced the `_abc.c` frontier past its full body with a sequence of small, individually re-probed slices:
|
||||||
|
- `abc_data_dealloc()`: hoisted `PyTypeObject *tp` before the `PyObject_GC_UnTrack(self)` statement (the exact line-67 blocker recorded at the start of this revision).
|
||||||
|
- `_abc_data_type_spec` and the `_abcmodule` `PyModuleDef`: converted from C99 designated initializers (`.name = ...`, `.m_name = ...`, etc.) to plain positional initializers in declared field order. VC6 has no C99 designated-initializer support at all (`error C2059: syntax error : '.'`); this is a different defect family from declaration-hoisting, so it is called out separately here. Field values and order are unchanged — this is a spelling change only, not a behavior change.
|
||||||
|
- `_in_weak_set()`, `_add_to_weak_set()`, `_abc__get_dump()`, `compute_abstract_methods()` (both `for` loops, including replacing their C99 `for (Py_ssize_t pos = 0; ...)` init-declarations with a function-scoped `pos` and hoisting per-iteration locals to the top of each loop body), `set_collection_flag_recursive()`, `_abc__abc_register_impl()`, `_abc__abc_instancecheck_impl()`, `_abc__abc_subclasscheck_impl()` (including its inner `for` loop over `subclasses`), and `subclasscheck_check_registry()` (including its inner `for` loop over the registry snapshot): hoisted all locals into each function's or block's opening declaration group, preserving every assignment at its original execution point (after argument validation, inside the same `if`/`for`/`while` branch, etc.). No control flow, lock/refcount ordering, or error-path behavior was changed anywhere in this slice.
|
||||||
|
- The previously reported "generated `clinic/_abc.c.h` struct-redefinition conflict around line 583" was characterized while fixing `_abc__abc_instancecheck_impl()` (whose opening declaration group sat at old line 583): it was parser-desync fallout from the preceding unfixed declaration-hoist errors, not a real redefinition. `clinic/_abc.c.h` itself is unmodified and is only 163 lines long; there is no struct redefinition in it. This matches the caveat already recorded about that hypothesis.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` (4583 lines) so the project-local compatibility patch includes this `_abc.c` slice plus all prior uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` worktree exited 0; the temporary worktree was removed afterward.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 (each script individually) — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, and pythoncore frontier regression suite all passed with no regressions after this slice. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (before this slice) | exit 2 — confirmed the recorded first blocker reproduces exactly: `cpython\Modules\_abc.c(67) : error C2275: 'PyTypeObject' : illegal use of this type as an expression` at `PyTypeObject *tp = Py_TYPE(self);` in `abc_data_dealloc()`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after each incremental slice, ~10 live re-probes) | exit 2 each time until the final one — the first diagnostic advanced monotonically through `_abc.c`: line 67 (`abc_data_dealloc`) → line 109 designated-initializer `error C2059` (`_abc_data_type_spec`) → line 138 (`_in_weak_set`) → line 203 (`_add_to_weak_set`) → line 291 (`_abc__get_dump`) → line 311 (`compute_abstract_methods`) → line 507/512 (`set_collection_flag_recursive`) → line 537 (`_abc__abc_register_impl`) → line 612 (`_abc__abc_instancecheck_impl`) → line 695 (`_abc__abc_subclasscheck_impl`) → line 849 (`subclasscheck_check_registry`). Each slice was verified against the live VC6 frontier before moving to the next. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after the final `_abc.c` slice) | exit 2 — `Modules/_abc.c` now compiles with **zero** errors and **zero** warnings; `total=3 compiled=2 cached=0 skipped=0`. The frontier advances to the next source in `pythoncore.vcxproj` order, `Modules/_bisectmodule.c`, whose new first blocker is `cpython\Modules\_bisectmodule.c(329) : error C2059: syntax error : '.'` — the same C99 designated-initializer defect family just fixed twice in `_abc.c`, not yet fixed here. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Modules/main.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch && git -C cpython worktree remove ../build/verify-vc6-patch-worktree --force` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree; temporary worktree removed. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** `Modules/_abc.c` is fully clean under the VC6 frontier probe (0 errors, 0 warnings). The frontier has moved on to `Modules/_bisectmodule.c`, whose first blocker is a C99 designated-initializer struct literal (`error C2059: syntax error : '.'` at line 329), the same defect family already fixed twice above (`_abc_data_type_spec`, `_abcmodule`). The recommended next slice is `_bisectmodule.c`'s designated initializer(s), followed by whatever C89 declaration-order issues follow in that file, using the same per-function hoist-and-reprobe approach used throughout this revision.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`_abc.c` frontier: `pycore_moduleobject.h` declaration-hoist + `long long` spelling)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Include/internal/pycore_moduleobject.h` — hoisted `_PyModule_GetDict()`'s `PyObject *dict` declaration into the function's opening declaration group (C89/VC6 requires declarations before statements; the prior form declared `dict` after the `assert(PyModule_Check(mod));` statement). The assignment stays at the original point, and the following `assert(dict != NULL);`/return are unchanged.
|
||||||
|
- `cpython/Modules/_abc.c` — changed the two `unsigned long long` struct field declarations (`_abcmodule_state.abc_invalidation_counter`, `_abc_data._abc_negative_cache_version`) to `unsigned PY_LONG_LONG`. VC6 has no `long long` keyword at all (`error C2632: 'long' followed by 'long' is illegal`); CPython's own `PC/pyconfig.h` already defines `PY_LONG_LONG` to fall back to `__int64` for `_MSC_VER < 1300` (VC6) for exactly this reason. This routes through that existing, already-correct CPython compatibility macro instead of adding a new shim; no other files in the current frontier use the bare `long long` spelling.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` so the project-local compatibility patch includes this slice plus all prior uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 (each script individually) — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, and pythoncore frontier regression suite all passed with no regressions after this slice. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (before this slice) | exit 2 — first blocker `cpython\Include\internal\pycore_moduleobject.h(33) : error C2143: syntax error : missing ';' before 'type'` at `PyObject *dict = ((PyModuleObject *)mod) -> md_dict;`, cascading into spurious `dict`-undeclared fallout plus `pycore_gc.h(15) : error C2061: syntax error : identifier 'uintptr_t'` and further undefined-struct fallout through `pycore_interp.h`, `pycore_global_objects.h`, `pycore_runtime.h`, and `pycore_object.h`, then `_abc.c` fallout until `fatal error C1003: error count exceeds 100`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after `pycore_moduleobject.h` hoist only) | exit 2 — confirms the hoist was the true root cause: every `pycore_gc.h`/`pycore_interp.h`/`pycore_global_objects.h`/`pycore_runtime.h`/`pycore_object.h` diagnostic is gone (those headers were never actually broken; VC6's error recovery from the single C89 syntax error had desynced parsing for the rest of the translation unit). New first blocker is `cpython\Modules\_abc.c(22) : error C2632: 'long' followed by 'long' is illegal` at `unsigned long long abc_invalidation_counter;`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` (after both fixes) | exit 2 — `_abc.c`'s `long long` blocker is gone. New first blocker is `cpython\Modules\_abc.c(67) : error C2275: 'PyTypeObject' : illegal use of this type as an expression` (a C89 mixed-declaration pattern, same family as already fixed repeatedly in `pystate.c`/`pylifecycle.c`/`getpath.c`), followed by many more declaration-order and declaration-after-statement errors throughout the rest of `_abc.c`'s ~35 functions until `fatal error C1003: error count exceeds 100` at line 784. Summary: `total=2 compiled=1 cached=0 skipped=0`. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Modules/main.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after this slice. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** the frontier has advanced past the `pycore_moduleobject.h`/GC-header cascade and past `_abc.c`'s `long long` blocker. `Modules/_abc.c` is now the active frontier file; the next blocker is a large set of C89 declaration-order violations spread across most of its functions (starting at line 67), plus at least one apparent struct-redefinition conflict with the Argument Clinic-generated `clinic/_abc.c.h` at line 583 that has not yet been individually characterized. This will need a multi-slice declaration-hoist pass through `_abc.c`, similar in shape to the `pystate.c` slices recorded below, rather than a single edit.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (VC6 frontier `/D` string define transport)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `scripts/vc6-probe-pythoncore-frontier.sh` — moved live VC6 compile arguments into per-object response files so quoted `/D` string literals no longer traverse `wine cmd /c` as inline command text. `quote_define_for_cmd()` now doubles define-owned backslashes before protecting literal quotes, so `VPATH="..\\.."` reaches CL preprocessing as the C string literal `"..\\.."`; empty-string defines such as `PYDEBUGEXT=""` are preserved. Added `render_compile_command_for_test()` as a safe no-Wine regression helper for define rendering.
|
||||||
|
- `scripts/vc6-probe-pythoncore-frontier.test.sh` — added a list-only/no-toolchain assertion that checks rendered per-file string defines for `VPATH`, `PYDEBUGEXT`, and `PLATLIBDIR` before the optional live Wine/VC6 run.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash -n scripts/vc6-probe.test.sh scripts/vc6-probe-core.test.sh scripts/vc6-probe-pathcch.test.sh scripts/generate-getpath-frozen.test.sh scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-pythoncore-frontier.sh scripts/generate-getpath-frozen.sh scripts/vc6-probe-minlink.sh scripts/vc6-probe-core.sh scripts/vc6-probe.sh && bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 — shell syntax plus public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, and pythoncore frontier regression suite all passed. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2 — `Modules/getpath.c` now compiles cleanly under the forced frontier. The frontier advances to `Modules/_abc.c`; first exact blocker is `cpython\\Include\\internal\\pycore_moduleobject.h(33) : error C2143: syntax error : missing ';' before 'type'`, followed by `dict` undeclared fallout, missing/undefined GC internals beginning with `pycore_gc.h(15) : error C2061: syntax error : identifier 'uintptr_t'`, and then `_abc.c` VC6/C89/modern-C fallout until `fatal error C1003: error count exceeds 100`. Summary: `total=2 compiled=1 cached=0 skipped=0`. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** the quoted macro transport blocker is resolved in the harness, and the frontier has advanced past `Modules/getpath.c`. The next actionable blocker is now in shared internal headers reached while compiling `Modules/_abc.c`, starting with C89 declaration ordering in `pycore_moduleobject.h` and missing/unsupported GC typedef structure (`uintptr_t` / `PyGC_Head`) fallout.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`getpath.c` _PyConfig_InitPathConfig C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Modules/getpath.c` — advanced `_PyConfig_InitPathConfig()` past the first main-body VC6/C89 declaration-order blocker by hoisting active locals (`configDict`, `dict`, `co`, Windows-only `winreg`, and `r`) into the function opening declaration group. Assignments remain at their original execution points after `_PyPathConfig_ReadGlobal()`, early status/`compute_path_config` return, and GIL check; refcount cleanup, `winreg` fallback handling, code evaluation, `_PyConfig_FromDict()`, and return statuses are unchanged. Disabled `#if 0` debug locals were left untouched.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` so the compatibility patch includes this `_PyConfig_InitPathConfig()` declaration-hoist slice plus prior uncommitted compatibility edits.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, and pythoncore frontier regression suite all passed. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2 — `_PyConfig_InitPathConfig()` now gets past the prior line-887 `PyObject *configDict = _PyConfig_AsDict(config);` blocker, plus the follow-on `dict`, `co`, Windows `winreg`, and `r` declaration-order blockers. New exact first blocker is `build\generated\cpython\Modules\getpath.c(956) : error C2001: newline in constant` at `!decode_to_dict(dict, "VPATH", VPATH)`, followed by adjacent newline-in-constant diagnostics for `PLATLIBDIR`, `PYDEBUGEXT`, and `PYWINVER`, then parse fallout. Summary: `total=1 compiled=0 cached=0 skipped=0`. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** the requested `_PyConfig_InitPathConfig()` declaration-order slice is complete and verified. The frontier still starts at `Modules/getpath.c`, but the next blocker has advanced from C89 declarations to quoted macro/value handling in the initial-value dictionary expression.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in this revision (`getpath.c` first VC6/C89 helper slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Modules/getpath.c` — advanced the first `Modules/getpath.c` pythoncore frontier slice by moving early helper declarations to C89/VC6-safe declaration groups while preserving assignment timing after argument parsing and other checks. Covered `getpath_abspath()`, `getpath_basename()`, `getpath_dirname()`, `getpath_hassuffix()`, Windows file-attribute helpers (`isdir`/`isfile`/`isxfile`), `getpath_joinpath()`, `getpath_readlines()`, `funcs_to_dict()`, `decode_to_dict()`, `env_to_dict()`, and `winmodule_to_dict()`.
|
||||||
|
- `cpython/Modules/getpath.c` — added a narrow VC6/old-SDK fallback for missing `INVALID_FILE_ATTRIBUTES`, guarded as `defined(_MSC_VER) && _MSC_VER < 1300 && !defined(INVALID_FILE_ATTRIBUTES)` under `MS_WINDOWS` after including `<windows.h>`.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` so the project-local compatibility patch includes this `getpath.c` slice plus prior uncommitted compatibility edits.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 — public probe suite, core probe suite, PathCch shim suite, getpath frozen-header generator suite, and pythoncore frontier regression suite all passed. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2 — `Modules/getpath.c` gets past the prior line-66 `Py_ssize_t len` blocker, the immediate helper declaration-order blockers, and the old-SDK `INVALID_FILE_ATTRIBUTES` blocker. New exact first blocker is `build\\generated\\cpython\\Modules\\getpath.c(887) : error C2275: 'PyObject' : illegal use of this type as an expression` at `PyObject *configDict = _PyConfig_AsDict(config);` in `_PyConfig_InitPathConfig()`, followed by the same function's later C89 declaration-order fallout. Summary: `total=1 compiled=0 cached=0 skipped=0`. |
|
||||||
|
| `git -C cpython worktree add --detach ../build/verify-vc6-patch-worktree v3.11.16 && git -C build/verify-vc6-patch-worktree apply --check ../../compat/msvc600/cpython-3.11.16-vc6-headers.patch` | exit 0 — regenerated compatibility patch applies cleanly to a pristine detached `v3.11.16` worktree. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** the first bounded `getpath.c` helper declaration-order/old-SDK slice is complete and verified. The frontier still starts at `Modules/getpath.c`, but the next blocker has advanced into `_PyConfig_InitPathConfig()`'s main path-calculation body.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in this revision (generated `getpath.h` provisioning)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `scripts/generate-getpath-frozen.sh` — new reproducible project-local generation step for `Python/frozen_modules/getpath.h`. It invokes CPython's documented `Programs/_freeze_module.py getpath Modules/getpath.py ...` path with host `python3` and writes only to ignored `build/generated/cpython/Python/frozen_modules/getpath.h`.
|
||||||
|
- `scripts/generate-getpath-frozen.test.sh` — new regression coverage for the generated path and header format: verifies the `_freeze_module.py` banner, `_Py_M__getpath` symbol, 16-byte line formatting, unmarshaled `<frozen getpath>` code object, and byte-for-byte equality with a direct `Programs/_freeze_module.py` invocation.
|
||||||
|
- `scripts/vc6-probe-pythoncore-frontier.sh` — now provisions the generated getpath header before live VC6 compilation and compiles `Modules/getpath.c` from an ignored generated cpython-shaped source copy so its relative `../Python/frozen_modules/getpath.h` include resolves without tracking generated output.
|
||||||
|
- `scripts/vc6-probe-pythoncore-frontier.test.sh` — live integration check now rejects a stale missing-`getpath.h` blocker and verifies the frontier harness created the ignored generated header.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `chmod +x scripts/generate-getpath-frozen.sh scripts/generate-getpath-frozen.test.sh scripts/vc6-probe-pythoncore-frontier.sh && bash -n scripts/generate-getpath-frozen.sh scripts/generate-getpath-frozen.test.sh scripts/vc6-probe-pythoncore-frontier.sh scripts/vc6-probe-pythoncore-frontier.test.sh && bash scripts/generate-getpath-frozen.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 — generator format/path regression passed and frontier regression passed, including live provisioning of `build/generated/cpython/Python/frozen_modules/getpath.h`. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2 — `Modules/getpath.c` now gets past both `<pathcch.h>` and the generated `../Python/frozen_modules/getpath.h` include. It stops at the next honest VC6/C89 compile blocker: mixed declarations in `getpath.c`, first diagnostic `build\\generated\\cpython\\Modules\\getpath.c(66) : error C2275: 'Py_ssize_t' : illegal use of this type as an expression`, followed by more declaration-order errors and `INVALID_FILE_ATTRIBUTES` not being declared before the compiler reaches its 100-error cap. Summary: `total=1 compiled=0 cached=0 skipped=0`. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** generated frozen `getpath.h` is now reproducibly provisioned from CPython source into ignored build output and integrated into the frontier harness. The current first blocker remains `Modules/getpath.c`, now at VC6/C89 declaration-order and old-SDK constant compatibility work rather than missing generated input.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (VC6 `PathCchFindExtension` shim)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `compat/msvc600/pathcch.h` — new VC6-scoped project-local compatibility header that implements only `PathCchFindExtension(PCWSTR, size_t, PCWSTR *)` for the existing `Modules/getpath.c` use. It scans a null-terminated wide path within `cchPath`, returns the last `.` after the last `\\`, `/`, or `:` separator, returns the terminating NUL when no extension is present, and returns `E_INVALIDARG` for null arguments, zero `cchPath`, or a too-small count with no NUL.
|
||||||
|
- `scripts/fixtures/vc6_pathcch_smoke.c` — focused compile fixture covering `.exe`, no extension, a dot in a directory name, dotfiles, trailing directory separators, multiple suffixes, and invalid/too-small arguments.
|
||||||
|
- `scripts/vc6-probe-pathcch.test.sh` — new regression test for the shim and fixture under the VC6 probe when Wine/MSVC600 are available.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `chmod +x scripts/vc6-probe-pathcch.test.sh && bash -n scripts/vc6-probe-pathcch.test.sh scripts/vc6-probe-pythoncore-frontier.sh scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-minlink.sh scripts/vc6-probe-core.sh scripts/vc6-probe.sh` | exit 0 |
|
||||||
|
| `bash scripts/vc6-probe-pathcch.test.sh` | exit 0, `ALL TESTS PASSED` — 4/4 checks `ok`; the smoke fixture compiles under VC6 and no longer hits missing `pathcch.h`. |
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pathcch.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 — public probe suite, core probe suite, pathcch smoke suite, and frontier regression suite all passed. |
|
||||||
|
| `VC6_FRONTIER_FORCE=1 bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2 — `Modules/getpath.c` now gets past `<pathcch.h>` and stops at the next honest blocker: `cpython\\Modules\\getpath.c(22) : fatal error C1083: Cannot open include file: '../Python/frozen_modules/getpath.h': No such file or directory`. Summary: `total=1 compiled=0 cached=0 skipped=0`. |
|
||||||
|
|
||||||
|
**Current pythoncore compile-frontier status:** the narrow `PathCchFindExtension` compatibility needed by `Modules/getpath.c` is implemented and verified under VC6 compile probes. The next blocker in full project order is the missing generated/frozen header `Python/frozen_modules/getpath.h` required by `Modules/getpath.c`; this is separate from the PathCch API gap. No `CompareStringOrdinal` blocker has been reached yet.
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (source-list-driven pythoncore compile frontier)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `scripts/vc6-probe-pythoncore-frontier.sh` — new project-local pythoncore compile-frontier harness. It parses `cpython/PCbuild/pythoncore.vcxproj`'s 198 `<ClCompile>` entries, normalizes Windows-style paths to project-local `cpython/...` paths, compiles supported sources incrementally, preserves common/per-file defines, reports external/generated sources, and stops on the first VC6 front-end blocker with `cl.exe`'s real status.
|
||||||
|
- `scripts/vc6-probe-pythoncore-frontier.test.sh` — new regression test covering source-list parsing, path normalization, per-file define preservation, unsupported/generated/external reporting, and a bounded live first-source VC6 run when Wine/MSVC600 are present.
|
||||||
|
- `PORT_STATUS.md` — that revision.
|
||||||
|
|
||||||
|
**Command results (previous revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `for f in scripts/vc6-probe-pythoncore-frontier.sh scripts/vc6-probe-pythoncore-frontier.test.sh scripts/vc6-probe-minlink.sh scripts/vc6-probe-core.sh; do bash -n "$f" || exit $?; done` | exit 0 |
|
||||||
|
| `bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0, `ALL TESTS PASSED` — 12/12 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-pythoncore-frontier.sh` | exit 2 — generated the source list, began with `cpython/Modules/getpath.c`, preserved its per-file defines, invoked VC6 `cl.exe`, and stopped truthfully at the first blocker: missing `pathcch.h` at `Modules/getpath.c(14)`. |
|
||||||
|
| `bash scripts/vc6-probe.test.sh && bash scripts/vc6-probe-core.test.sh && bash scripts/vc6-probe-pythoncore-frontier.test.sh` | exit 0 — public probe suite, core probe suite, and new frontier suite all passed. |
|
||||||
|
| `bash scripts/vc6-probe-minlink.sh` | exit 96 — unchanged minimal link-frontier behavior: all four selected translation units compile, then `LINK.EXE` fails with `fatal error LNK1120: 267 unresolved externals`. |
|
||||||
|
|
||||||
|
**Previous pythoncore compile-frontier status:** source-list-driven frontier infrastructure was implemented and verified. The first actionable VC6 compile blocker in full project order was `Modules/getpath.c` requiring `pathcch.h`, a modern Windows SDK header not present in the VC6/MSVC600 include set.
|
||||||
|
|
||||||
|
**Caveat:** this was a compile-frontier harness only. No full `pythoncore.dll`/`python.exe` build, no successful link, no Wine launch, and no Windows 98 runtime execution was claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (minimal VC6 link-frontier probe)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `scripts/vc6-probe-minlink.sh` — new project-local link-frontier harness. It reuses the existing Wine/MSVC600 helpers, compiles `Programs/python.c` plus the three currently clean core translation units (`Modules/main.c`, `Python/pylifecycle.c`, and `Python/pystate.c`) with pythoncore-style core/shared defines, then invokes VC6 `LINK.EXE` for a minimal `python-min.exe` attempt. This is intentionally not a full `pythoncore.vcxproj` build; `pythoncore.vcxproj` lists 198 C sources (without externals disabled: plus zlib-conditioned entries), while `python.vcxproj` only contributes `Programs/python.c` and references the core project.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe-minlink.sh` | exit 96 — all four frontier translation units compile under VC6, then `LINK.EXE` runs and fails truthfully with `fatal error LNK1120: 267 unresolved externals`. First unresolved symbols include `__PyPathConfig_ComputeSysPath0` / `__PyPathConfig_UpdateGlobal` (`Python/pathconfig.c`), `__Py_Dealloc` (`Objects/object.c`), `_PyErr_Print` (`Python/pythonrun.c`), and `PyStatus_Ok` (`Python/initconfig.c`). |
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — existing core compile-probe regression checks still pass after adding the link-frontier script |
|
||||||
|
|
||||||
|
**Current minimal-link status:** the first post-core-probe link milestone is now implemented as a reproducible harness that reaches the VC6 linker. A successful link is not feasible from only the already-clean TUs: the exact blocker is the expected unresolved-symbol frontier caused by not yet compiling the rest of `pythoncore.vcxproj`'s source graph. Recommended next artifact is a source-list-driven VC6 `pythoncore` compile frontier (generate/consume the `pythoncore.vcxproj` `<ClCompile>` list, with per-file defines such as `getpath.c` and `sysmodule.c` handled explicitly) that compiles additional core objects one at a time before attempting a real `pythoncore`/`python.exe` link.
|
||||||
|
|
||||||
|
**Caveat:** this is a link-frontier probe only. No `pythoncore.dll`/full `python.exe` build, no Wine launch, and no Windows 98 runtime execution is claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` final tail helper C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — `_Py_GetConfig()` now declares `PyThreadState *tstate` in the function opening declaration group while preserving the `assert(PyGILState_Check())` before assigning `tstate = _PyThreadState_GET()`. `push_chunk()` now declares `_PyStackChunk *new` and `PyObject **res` in its opening declaration group while preserving the allocation-size loop, `allocate_chunk(...)` assignment point, chunk linking/top/limit updates, root-chunk offset, and returned stack pointer. `_PyThreadState_PopFrame()` now declares `PyObject **base` in the function opening declaration group while preserving the datastack assertion before assigning `base = (PyObject **)frame`, plus the chunk-pop and top-reset paths. `_PyThreadState_BumpFramePointerSlow()`'s inner block declaration was not changed.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff` (3703 lines); includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` compiles cleanly end-to-end (compile-only) |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the final tail-helper declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 0 — gets past the prior line 3405 (`PyThreadState *tstate = _PyThreadState_GET();`) blocker in `_Py_GetConfig()`, the `push_chunk()` declaration-order blockers at line 3418 (`_PyStackChunk *new = allocate_chunk(...)`) and line 3431 (`PyObject **res = &new->data[...]`), and the follow-on line 3460 (`PyObject **base = (PyObject **)frame;`) blocker in `_PyThreadState_PopFrame()`. No next C89 declaration blocker is currently exposed by the `pystate.c` compile probe; the only diagnostic left in this probe output is the pre-existing line 3361 warning (`warning C4550: expression evaluates to a function which is missing an argument list`). |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` PyGILState_Check/Ensure C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `PyGILState_Check()`'s `PyThreadState *tstate` into the function opening declaration group while preserving the early `check_enabled` and TSS-created returns before assigning `tstate = _PyRuntimeGILState_GetThreadState(gilstate)`. `PyGILState_Ensure()` now declares `PyThreadState *tcur` and `int current` in the opening declaration group, keeps `tcur = PyThread_tss_get(...)` after the initialization assertions, and leaves the new/current thread-state branches, restore/save ordering, counter update, and return value unchanged.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `PyGILState_Check()`/`PyGILState_Ensure()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior line 2886 (`error C2275: 'PyThreadState' : illegal use of this type as an expression`) blocker at `PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate);` in `PyGILState_Check()` and the adjacent `PyGILState_Ensure()` declaration-order fallout. New exact first blocker is line 3052 (`error C2059: syntax error : '{'`) at `*data = (_PyCrossInterpreterData){0};` in `_PyObject_GetCrossInterpreterData()`, followed by line 3057 `crossinterpdatafunc getdata = _lookup_getdata(obj);`, line 3062 `int res = getdata(obj, data);`, and later cross-interpreter-data helper declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` frame access and async-exception C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `PyThreadState_GetFrame()`'s `_PyInterpreterFrame *f` and `PyFrameObject *frame` declarations into the function's opening declaration group while preserving the `f = tstate->cframe->current_frame` assignment immediately after the assert and the `frame = _PyFrame_GetFrameObject(f)` assignment after the NULL check. `PyThreadState_SetAsyncExc()` now declares `PyThreadState *tstate` in the function opening group and uses `for (tstate = ...; ...)`; its loop body declares `PyObject *old_exc` before the skip check and assigns it at the original point before the async exception replacement, preserving head-lock traversal, skip behavior, unlock-before-decref, signal, and return paths.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 32/32 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the frame access and async-exception declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `PyThreadState_GetFrame()` blockers at line 2457 (`_PyInterpreterFrame *f = tstate->cframe->current_frame;`) and line 2464 (`PyFrameObject *frame = _PyFrame_GetFrameObject(f);`), plus `PyThreadState_SetAsyncExc()`'s C99 `for (PyThreadState *tstate = ...)` initializer and post-`if` `PyObject *old_exc` loop-body declaration. New exact first blocker is line 2576 (`error C2275: 'PyObject' : illegal use of this type as an expression`) at `PyObject *result = PyDict_New();` in `_PyThread_CurrentFrames()`, followed by line 2582 (`int gc_was_enabled = PyGC_Disable();`) and later declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` thread-state deletion helpers C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists the thread-state deletion helper locals needed by VC6/C89: `tstate_delete_common()` now declares `PyInterpreterState *interp`, `_PyRuntimeState *runtime`, and `_PyStackChunk *chunk` in the opening declaration group while assigning them at their original post-ensure/post-TSS points; `_PyThreadState_DeleteCurrent()` declares `struct _gilstate_runtime_state *gilstate` before `_Py_EnsureTstateNotNULL()` and assigns it immediately after; `_PyThreadState_DeleteExcept()` declares `PyThreadState *list`, `p`, and `next` before `HEAD_LOCK(runtime)` while preserving the locked list capture/unlinking and post-unlock clear/free loop. The stack-chunk loop's block-local `prev` remains at the start of its `while` block.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 32/32 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the thread-state deletion helper declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `tstate_delete_common()` blockers at line 2245 (`PyInterpreterState *interp = tstate->interp;`), line 2249 (`_PyRuntimeState *runtime = interp->runtime;`), and line 2268 (`_PyStackChunk *chunk = tstate->datastack_chunk;`), plus `_PyThreadState_DeleteCurrent()`'s post-ensure `gilstate` declaration and `_PyThreadState_DeleteExcept()`'s post-lock `list` declaration. New exact first blocker is line 2457 (`error C2143: syntax error : missing ';' before 'type'`) at `_PyInterpreterFrame *f = tstate->cframe->current_frame;` in `PyThreadState_GetFrame()`, followed by line 2464 (`PyFrameObject *frame = _PyFrame_GetFrameObject(f);`) and later declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` new_threadstate C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `new_threadstate()`'s `PyThreadState *new_tstate`, `uint64_t id`, and `PyThreadState *old_head` declarations into the function's opening declaration group. `new_tstate = alloc_threadstate()` remains before the lock, `id = interp->threads.next_unique_id` remains after the locked increment, and `old_head = interp->threads.head` remains immediately before the `old_head == NULL` branch, preserving allocation-before-lock, `used_newtstate` behavior, initialization branches, and lock/unlock order.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 32/32 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `new_threadstate()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `new_threadstate()` blockers at line 1970 (`uint64_t id = interp->threads.next_unique_id;`) and line 1973 (`PyThreadState *old_head = interp->threads.head;`). New exact first blocker is line 2080 (`error C2275: 'PyInterpreterState' : illegal use of this type as an expression`) at `PyInterpreterState *interp = tstate->interp;` in `_PyState_AddModule()`, followed by declaration-order fallout for `interp` and later locals. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` _PyInterpreterState_IDDecref C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `_PyInterpreterState_IDDecref()`'s `struct _gilstate_runtime_state *gilstate`, `int64_t refcount`, `PyThreadState *tstate`, and `PyThreadState *save_tstate` declarations to the function's opening declaration group. `gilstate = &_PyRuntime.gilstate` remains immediately after the `id_mutex` assert; `refcount = interp->id_refcount` remains after the decrement while the mutex is still held; `tstate` and `save_tstate` assignments remain inside the `refcount == 0 && interp->requires_idref` block, preserving lock acquisition/release plus `_PyThreadState_Swap()`/`Py_EndInterpreter()` ordering.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `_PyInterpreterState_IDDecref()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `_PyInterpreterState_IDDecref()` blockers at line 1812 (`struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;`), line 1816 (`int64_t refcount = interp->id_refcount;`), and the block-local `tstate`/`save_tstate` declarations. New exact first blocker is line 1876 (`error C2143: syntax error : missing ';' before 'type'`) at `_PyStackChunk *res = _PyObject_VirtualAlloc(size_in_bytes);` in `allocate_chunk()`, followed by declaration-order fallout for `res`. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` PyInterpreterState_Get C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `PyInterpreterState_Get()`'s `PyInterpreterState *interp` declaration beside the existing `PyThreadState *tstate` local. `tstate = _PyThreadState_GET()` remains immediately before `_Py_EnsureTstateNotNULL(tstate)`, and `interp = tstate->interp` remains at the original post-ensure point, preserving the fatal-error check and return behavior.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `PyInterpreterState_Get()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `PyInterpreterState_Get()` blocker at line 1719 (`PyInterpreterState *interp = tstate->interp;`). New exact first blocker is line 1812 (`error C2143: syntax error : missing ';' before 'type'`) at `struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;` in `_PyInterpreterState_IDDecref()`, followed by line 1816 `int64_t refcount = interp->id_refcount;` and later declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` PyInterpreterState_Delete C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `PyInterpreterState_Delete()`'s `PyInterpreterState **p` declaration beside the existing `runtime` and `interpreters` locals. The `for (p = &interpreters->head; ...)` initializer remains under `HEAD_LOCK(runtime)`, preserving the unlink search, remaining-thread checks, main-interpreter checks, assignment to `*p`, and lock/unlock ordering.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `PyInterpreterState_Delete()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `PyInterpreterState_Delete()` blocker at line 1638 (`PyInterpreterState **p;`). New exact first blocker is line 1719 (`error C2275: 'PyInterpreterState' : illegal use of this type as an expression`) at `PyInterpreterState *interp = tstate->interp;` in `PyInterpreterState_Get()`, followed by declaration-order fallout in the same and later functions. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` interpreter_clear C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `interpreter_clear()`'s `PyThreadState *p` declaration beside the existing `_PyRuntimeState *runtime` local. The `p = interp->threads.head;` assignment remains at the same point under `HEAD_LOCK(runtime)`, preserving the lock/unlock ordering and the thread-clear loop behavior.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `interpreter_clear()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `interpreter_clear()` blocker at line 1537 (`PyThreadState *p = interp->threads.head;`). New exact first blocker is line 1638 (`error C2275: 'PyInterpreterState' : illegal use of this type as an expression`) at `PyInterpreterState **p;` in `PyInterpreterState_Delete()`, followed by declaration-order fallout in the same and later functions. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` PyInterpreterState_New C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `PyInterpreterState_New()`'s `PyThreadState *tstate`, `PyThread_type_lock pending_lock`, `_PyRuntimeState *runtime`, `struct pyinterpreters *interpreters`, `int64_t id`, and `PyInterpreterState *old_head` declarations into the function's opening declaration group. `tstate = _PyThreadState_GET()` remains immediately before the audit, and the `pending_lock`, `runtime`, `interpreters`, `id`, and `old_head` assignments stay at the original execution points after the audit, after lock allocation succeeds, after `HEAD_LOCK(runtime)`, and before the `old_head == NULL` test respectively.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `PyInterpreterState_New()` declaration-hoist slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `PyInterpreterState_New()` blockers at line 1438 (`PyThread_type_lock pending_lock = PyThread_allocate_lock();`) and its `runtime`, `interpreters`, `id`, and `old_head` declaration-order fallout. New exact first blocker is line 1537 (`error C2275: 'PyThreadState' : illegal use of this type as an expression`) at `PyThreadState *p = interp->threads.head;` in `interpreter_clear()`, followed by later declaration-order fallout in the same translation unit. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pystate.c` alloc_for_runtime lock C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pystate.c` — hoists `alloc_for_runtime()`'s `PyThread_type_lock lock1`, `lock2`, and `lock3` declarations beside `PyMemAllocatorEx old_alloc`. The three `PyThread_allocate_lock()` calls remain at their original execution points as assignments; the existing NULL checks, `lock1`/`lock2` cleanup order, allocator restoration, output assignments, and return paths are unchanged.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the `pystate.c` lock declaration slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `alloc_for_runtime()` blockers at lines 1185/1190/1196 (`PyThread_type_lock lock1/lock2/lock3 = PyThread_allocate_lock();`). New exact first blocker is line 1438 (`error C2275: 'PyThread_type_lock' : illegal use of this type as an expression`) at `PyThread_type_lock pending_lock = PyThread_allocate_lock();` in `PyInterpreterState_New()`, followed by that function's `runtime`, `interpreters`, `id`, and `old_head` declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pycore_frame.h` frame inline C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Include/internal/pycore_frame.h` — hoists the first VC6/C89 mixed-declaration blockers exposed while compiling `Python/pystate.c`: `_PyFrame_GetFrameObject()` now declares `PyFrameObject *res` before the `assert()` and assigns `frame->frame_obj` at the original point; `_PyThreadState_BumpFramePointer()` keeps `_PyInterpreterFrame *res` scoped inside the stack-space `if` block but declares it before the assignment; `_PyFrame_GetGenerator()` declares `size_t offset_in_gen` before the `assert()` and assigns `offsetof(PyGenObject, gi_iframe)` at the original point.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `v3.11.16` `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — still compiles cleanly after the header slice |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — gets past the prior `pycore_frame.h` blockers at `_PyFrame_GetFrameObject()`, `_PyThreadState_BumpFramePointer()`, and `_PyFrame_GetGenerator()`. New exact first blocker is line 1185 (`error C2275: 'PyThread_type_lock' : illegal use of this type as an expression`) at `PyThread_type_lock lock1 = PyThread_allocate_lock();` in `threadstate_update_waiting_for_thread_shutdown()`, followed by the same function's `lock2` and `lock3` declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` call_ll_exitfuncs C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `call_ll_exitfuncs()`'s `void (*exitfunc)(void)` declaration before the loop and assigns it at the original post-decrement point, preserving the decrement, slot clearing, LIFO invocation order, and final `stdout`/`stderr` flushes.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 0 — gets past the prior line 3045 `void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs];` blocker in `call_ll_exitfuncs()`; no next `pylifecycle.c` blocker was found because the translation unit now compiles cleanly in the VC6 core compile probe. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` fatal_error/_Py_FatalErrorFormat C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `fatal_error()` locals (`runtime`, `tstate`, `interp`, `tss_tstate`, and `has_tstate_and_gil`) into the function declaration area while preserving the original assignment/evaluation points, including `runtime = &_PyRuntime`, `interp = NULL`, `tss_tstate = PyGILState_GetThisThreadState()`, and the `has_tstate_and_gil` boolean assignment. `_Py_FatalErrorFormat()` now declares `stream`, `fd`, and `vargs` before its reentrancy check, then assigns `stream = stderr` and `fd = fileno(stream)` at the original post-reentrancy point before output begins.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 2866 `_PyRuntimeState *runtime = &_PyRuntime;` blocker in `fatal_error()` plus the immediately adjacent `tstate`/`interp`/`tss_tstate`/`has_tstate_and_gil` declaration-order fallout and `_Py_FatalErrorFormat()`'s `FILE *stream`, `fd`, and `va_list vargs` mixed declarations. New exact first blocker is line 3045 (`error C2143: syntax error : missing ';' before 'type'`) at `void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs];` in `call_ll_exitfuncs()`. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` fatal-error dump C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `fatal_error_dump_runtime()`'s `PyThreadState *finalizing` to the function declaration area and assigns it at the original point after the `PUTS()` call. `_Py_DumpExtensionModules()` now declares its function-scope locals (`modules`, `pos`, `key`, `value`, `stdlib_module_names`, `header`, and `count`) before the `interp == NULL` early return; the `modules`, `stdlib_module_names`, `header`, and `count` initializers are preserved as assignments at their original execution points. The inner `is_stdlib_ext`, `i`, `item`, and `hash` block declarations are unchanged.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` tree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 2698 `PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);` blocker in `fatal_error_dump_runtime()` and the adjacent `_Py_DumpExtensionModules()` function-scope declaration-order blockers. New exact first blocker is line 2866 (`error C2275: '_PyRuntimeState' : illegal use of this type as an expression`) at `_PyRuntimeState *runtime = &_PyRuntime;` in `fatal_error()`, followed by additional `fatal_error()` declaration-order fallout. |
|
||||||
|
| `git apply --check compat/msvc600/cpython-3.11.16-vc6-headers.patch` against pristine `v3.11.16` tree | exit 0 |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` is_valid_fd platform-branch C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `is_valid_fd()`'s platform-branch locals into the function declaration area under the same preprocessor ladder: `int fd2` for the Linux `dup()` branch, `HANDLE hfile` for `MS_WINDOWS`, and `struct stat st` for the fallback branch. The existing `fd < 0` early return, platform conditions, and branch behavior are unchanged; the original declaration sites now only assign/use (`fd2 = dup(fd)`, `_get_osfhandle()`, and `fstat(fd, &st)`).
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 2296 `HANDLE hfile;` blocker in `is_valid_fd()`. New exact first blocker is line 2403 (`error C2275: 'PyObject' : illegal use of this type as an expression`) at `PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1);` in `create_stdio()`, followed by line 2409 `PyObject *errors_str = PyUnicode_FromWideChar(errors, -1);` and later declaration-order blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` add_main_module shadowed-loader C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `PyObject *bimod` and a distinct `PyObject *loader_obj` into `add_main_module()`'s existing declaration group. The `builtins` import and `BuiltinImporter` lookup remain at their original execution points; the outer borrowed `loader` variable and its NULL/`Py_None` test are unchanged, while `loader_obj` carries only the formerly shadowed strong reference through its NULL check, `__loader__` dict set, and decref.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 2212 `PyObject *bimod = PyImport_ImportModule("builtins");` blocker and the same function's formerly shadowed line 2233 `PyObject *loader = PyObject_GetAttrString(...)` declaration-order blocker in `add_main_module()`. New exact first blocker is line 2296 (`error C2275: 'HANDLE' : illegal use of this type as an expression`) at `HANDLE hfile;` in `is_valid_fd()`, followed by later declaration-order blockers in `create_stdio()` and finalization diagnostics. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` finalize_modules C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `int verbose` and `PyObject *weaklist` to the top declaration group in `finalize_modules()`. `verbose` is assigned after the existing `modules == NULL` early return, and `weaklist` is assigned at the original `finalize_remove_modules(modules, verbose)` call site, preserving early-return behavior and call order.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 1606 `int verbose = _PyInterpreterState_GetConfig(interp)->verbose;` blocker and line 1624 `PyObject *weaklist = finalize_remove_modules(modules, verbose);` in `finalize_modules()`. New exact first blocker is line 1838 (`error C2275: 'PyThreadState' : illegal use of this type as an expression`) at `PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);` in `Py_FinalizeEx()`, followed by line 1868 `int malloc_stats = tstate->interp->config.malloc_stats;` and later finalization declaration-order blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` finalize_modules_clear_weaklist C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `Py_ssize_t i` plus `PyObject *tup`, `name`, `mod`, and `dict` to the top declaration group in `finalize_modules_clear_weaklist()`. The reverse loop now assigns `i = PyList_GET_SIZE(weaklist) - 1` at the original loop point, and each former loop-local declaration is now an assignment at the same position, preserving evaluation order and the two existing `continue` paths.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 1551 `for (Py_ssize_t i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--)` blocker and the same loop's `PyObject *tup`, `name`, `mod`, and `dict` mixed declarations. New exact first blocker is line 1606 (`error C2143: syntax error : missing ';' before 'type'`) at `int verbose = _PyInterpreterState_GetConfig(interp)->verbose;` in `finalize_modules()`, followed by line 1624 `PyObject *weaklist = finalize_remove_modules(modules, verbose);` and later finalization declaration-order blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` finalize_modules_delete_special C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `const char * const *p` and `PyObject *value` to the top declaration group in `finalize_modules_delete_special()`. The first loop now assigns `p = sys_deletes` at the original declaration point, and the second loop assigns `value = _PyDict_GetItemStringWithError(...)` where the mixed declaration used to be. `name` and `orig_name` remain loop-local, preserving their evaluation/order.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 1411 `const char * const *p;` blocker and the line 1426 `PyObject *value` blocker in `finalize_modules_delete_special()`. New exact first blocker is line 1551 (`error C2143: syntax error : missing ';' before 'type'`) at `for (Py_ssize_t i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--)` in `finalize_modules_clear_weaklist()`, followed by `PyObject *tup`, `PyObject *name`, `PyObject *mod`, and `PyObject *dict` mixed declarations in the same loop/function plus later finalization blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` pyinit_main/public initialization API C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists declaration-order blockers in `pyinit_main()`, `Py_InitializeFromConfig()`, `Py_InitializeEx()`, and `_Py_InitializeMain()`. Locals are declared at function top, while assignments/calls (`tstate->interp`, `_PyRuntime_Initialize()`, `&_PyRuntime`, `tstate = NULL`, `_PyConfig_InitCompatConfig()`, and `_PyRuntimeState_GetThreadState(runtime)`) remain at their original execution points to preserve behavior.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 1285 `PyStatus status = init_interp_main(tstate);` blocker in `pyinit_main()` and the declaration-order fallout in `Py_InitializeFromConfig()`, `Py_InitializeEx()`, and `_Py_InitializeMain()`. New exact first blocker is line 1411 (`error C2143: syntax error : missing ';' before 'const'`) at `const char * const *p;` in `finalize_modules_delete_special()`, followed by `PyObject *value` in the same function and later finalization mixed-declaration blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` pyinit_core/init_interp_main C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists `PyConfig config` to the top of `pyinit_core()` while leaving `PyConfig_InitPythonConfig(&config)` at its original execution point. `init_interp_main()` now declares `PyStatus status`, then initialized `is_main_interp`, `interp`, and `config` at function top before the existing `assert`, preserving the declaration initializer order requested for this narrow VC6 declaration-order slice.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 1104 `PyConfig config;` blocker in `pyinit_core()` and the immediately exposed `init_interp_main()` mixed declarations. New exact first blocker is line 1285 (`error C2275: 'PyStatus' : illegal use of this type as an expression`) at the mixed declaration `PyStatus status = init_interp_main(tstate);` in `pyinit_main()`, followed by additional declaration-order fallout in `Py_InitializeFromConfig()` and later functions. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` pre-initialization C89/C99 slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — removes the two pre-initialization `_PyArgv` designated initializers in `Py_PreInitializeFromBytesArgs()` and `Py_PreInitializeFromArgs()` by declaring `args` first and assigning `use_bytes_argv`, `argc`, and the active argv pointer field explicitly before the existing `_Py_PreInitializeFromPyArgv()` call. `_Py_PreInitializeFromConfig()` now declares `PyStatus status`, `_PyRuntimeState *runtime`, `PyPreConfig preconfig`, and `_PyArgv config_args` at function top, assigns `status`/`runtime` at their original execution points, and replaces the `args == NULL` branch's designated `config_args` initializer with field-by-field assignments immediately before the existing call. Evaluation and call order are unchanged.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 1008 and 1016 `_PyArgv args = { .use_bytes_argv = ... }` designated initializers, plus the mixed declarations and designated `config_args` initializer inside `_Py_PreInitializeFromConfig()`. New exact first blocker is line 1104 (`error C2275: 'PyConfig' : illegal use of this type as an expression`) at the mixed declaration `PyConfig config;` in `pyinit_core()`, followed by nearby `pyinit_main()` declaration-order blockers and later C89/C99 fallout. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` builtins C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists the remaining VC6-rejected `PyObject *` declarations in `pycore_init_builtins()` (`bimod`, `builtins_dict`, `isinstance`, `len`, `list_append`, and `import_func`) to the function top, then assigns each at its original execution site. Evaluation order and existing error paths are unchanged; each local is still assigned before use.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past all mixed declarations in `pycore_init_builtins()`. New exact first blocker is line 912 (`error C2143: syntax error : missing ';' before 'const'`) at the mixed declaration `const PyConfig *config = _PyInterpreterState_GetConfig(interp);` in `pycore_interp_init()`, followed by the undeclared `config` fallout and later C89/C99 blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` create-interpreter C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists only the two next VC6-rejected declarations in `pycore_create_interpreter()`: `PyInterpreterState *interp` and `PyThreadState *tstate` are now declared at function top, while `_PyGILState_Init(runtime)`, `PyInterpreterState_New()`, and `PyThreadState_New(interp)` still execute at their original call sites and in the same order.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 682 `pycore_create_interpreter()` `PyInterpreterState *interp` mixed declaration and line 693 `PyThreadState *tstate` mixed declaration. New exact first blocker is line 812 (`error C2275: 'PyObject' : illegal use of this type as an expression`) at the mixed declaration `PyObject *builtins_dict = PyEval_GetBuiltins();` in `pycore_init_builtins()`, followed by the same function's line 819 `PyObject *isinstance = PyDict_GetItem(...)` and additional C89 mixed-declaration blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`pylifecycle.c` interpreter-config C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists only the interpreter-configuration `PyStatus` locals that VC6 rejected as mixed declarations: `interpreter_update_config()` now declares one `PyStatus status` at function top and assigns it at the two original call sites, and `_PyInterpreterState_SetConfig()` declares `PyConfig config` / `PyStatus status` before calling `PyConfig_InitPythonConfig()`. Assignment/evaluation order is unchanged and the former inner `status` shadowing is removed.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 528 `_PyInterpreterState_SetConfig()` mixed-declaration blocker and the nearby line 505 `interpreter_update_config()` `PyStatus` shadow declaration. New exact first blocker is line 580 (`error C2275: 'PyInterpreterState' : illegal use of this type as an expression`) at the mixed declaration `PyInterpreterState *interp = tstate->interp;` in `pyinit_core_reconfigure()`, followed by additional C89 mixed-declaration blockers including line 614 `PyStatus status = _PyConfig_Write(config, runtime);` in `pycore_init_runtime()`. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`_PyStatus_OK()` recursion fix and `_PyStatus_ERR()` VC6 helper slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Include/internal/pycore_initconfig.h` — replaces the VC6-only `_PyStatus_OK()` mapping to `PyStatus_Ok()` with a local static C89 helper that assigns all `PyStatus` fields explicitly, avoiding the `PyStatus_Ok() -> _PyStatus_OK() -> PyStatus_Ok()` recursion. Adds a VC6-only `_PyStatus_ERR()` helper that assigns `_type = _PyStatus_TYPE_ERROR`, `func = NULL` (matching public `PyStatus_Error()` semantics because VC6 has neither `__func__` nor `__FUNCTION__`), `err_msg`, and `exitcode = 0`. Non-VC6 compound-literal macros are unchanged.
|
||||||
|
- `scripts/fixtures/vc6_compound_literal_smoke.c` — now exercises both `_PyStatus_OK()` and `_PyStatus_ERR()` through the real internal header.
|
||||||
|
- `scripts/vc6-probe-core.test.sh` — adds a focused regression check that `_PyStatus_OK()` no longer maps to `PyStatus_Ok()`, and updates the compound-literal smoke-test description.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe-core.sh scripts/fixtures/vc6_compound_literal_smoke.c` | exit 0 — focused smoke fixture compiles while calling both `_PyStatus_OK()` and `_PyStatus_ERR()` directly under VC6. |
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 28/28 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 259 `_PyStatus_ERR("external importer setup failed")` compound-literal blocker. New exact first blocker is line 528 (`error C2275: 'PyStatus' : illegal use of this type as an expression`) at the mixed declaration `PyStatus status = _PyConfig_Copy(&config, src_config);` in `_PyInterpreterState_SetConfig()`, followed by additional C89 mixed-declaration blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`init_importlib()` C89 declaration-hoist slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Python/pylifecycle.c` — hoists only the existing `init_importlib()` local declarations (`interp`, `verbose`, `importlib`, `imp_mod`, `value`) to the top of the function, then preserves the prior assignment/evaluation order after the existing assertion and at each original use site.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` worktree exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 27/27 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 202 `init_importlib()` mixed-declaration blocker. New exact first blocker is line 259 (`error C2059: syntax error : '{'`) at `_PyStatus_ERR("external importer setup failed")` in `init_importlib_external()`, followed by further `PyStatus` compound-literal/designated-initializer and C89 mixed-declaration blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`_PyStatus_OK()` VC6 macro fallback slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Include/internal/pycore_initconfig.h` — keeps the existing C99 compound-literal `_PyStatus_OK()` macro for non-VC6 compilers, but maps `_PyStatus_OK()` to the existing public `PyStatus_Ok()` API only for `_MSC_VER < 1300` so VC6 no longer has to parse `(PyStatus){._type = ...}` at `_PyRuntime_Initialize()`.
|
||||||
|
- `scripts/fixtures/vc6_compound_literal_smoke.c` — now exercises `_PyStatus_OK()` itself, verifying the VC6-only macro fallback rather than bypassing it by calling `PyStatus_Ok()` directly.
|
||||||
|
- `scripts/vc6-probe-core.test.sh` — updates the focused compound-literal smoke-test description for the shared macro fallback.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits. Reproducibility check: `git apply --check` against a pristine temporary `cpython/` copy exited 0.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe-core.sh scripts/fixtures/vc6_compound_literal_smoke.c` | exit 0 — focused smoke fixture now compiles while calling `_PyStatus_OK()` directly under VC6. |
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 27/27 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — gets past the prior line 143 `_PyStatus_OK()` compound-literal blocker. New exact first blocker is line 202 (`error C2143: syntax error : missing ';' before 'type'`), the existing C89 mixed-declaration wall in `init_importlib()`, followed by further declaration-order and remaining non-OK compound-literal/designated-initializer blockers. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
|
## Files changed in previous revision (`_PyRuntimeState_INIT` VC6 replacement slice)
|
||||||
|
|
||||||
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
|
|
||||||
|
- `cpython/Include/internal/pycore_runtime_init.h` — keeps the existing C99 designated initializer path for non-VC6 compilers, but exposes `_PyRuntimeState_InitStaticDefaults()` for VC6 instead of making VC6 parse `_PyRuntimeState_INIT`.
|
||||||
|
- `cpython/Python/pylifecycle.c` — leaves `_PyRuntime` zero-initialized only for VC6, then calls the shared explicit defaults routine once before `_PyRuntimeState_Init()`. Non-VC6 still uses `= _PyRuntimeState_INIT`.
|
||||||
|
- `cpython/Python/pystate.c` — adds the VC6 field-by-field default routine used by both the process-global runtime and later runtime/interpreter/thread resets. It explicitly preserves the required defaults: `gilstate.check_enabled = 1`, zeroed `Py_tss_NEEDS_INIT` storage, `interpreters.next_id = -1`, global small ints/bytes/strings/empty tuple, `_main_interpreter` (`_static`, `id_refcount`, recursion/gc thresholds), and `_initial_thread` (`_static`, recursion limit, `context_ver = 1`). Non-VC6 still uses the upstream `static const initial = _PyRuntimeState_INIT`/`memcpy` path.
|
||||||
|
- `compat/msvc600/cpython-3.11.16-vc6-headers.patch` — regenerated from `git -C cpython diff`; includes this slice plus earlier uncommitted compatibility edits.
|
||||||
|
- `PORT_STATUS.md` — this revision.
|
||||||
|
|
||||||
|
**Command results (all reproduced in this revision):**
|
||||||
|
|
||||||
|
| Command | Result |
|
||||||
|
|---|---|
|
||||||
|
| `bash scripts/vc6-probe.test.sh` | exit 0, `ALL TESTS PASSED` — 6/6 checks `ok` |
|
||||||
|
| `bash scripts/vc6-probe-core.test.sh` | exit 0, `ALL TESTS PASSED` — 27/27 checks `ok`; `Modules/main.c` still compiles cleanly |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pylifecycle.c` | exit 2 — the `_PyRuntime` definition no longer fails at `_PyRuntimeState_INIT` line 112. New first error is line 143 (`_PyStatus_OK()` compound literal), followed by existing C89 declaration-order and C99 initializer blockers in the rest of the file. |
|
||||||
|
| `bash scripts/vc6-probe-core.sh cpython/Python/pystate.c` | exit 2 — the former `static const _PyRuntimeState initial = _PyRuntimeState_INIT` C2059 errors are gone and later `initial._main_interpreter` reset users are covered by the same VC6 defaults helpers. Current first errors are pre-existing C89 declaration-order issues in `pycore_frame.h` and then in `pystate.c`; no remaining `_PyRuntimeState_INIT` parse error is reported before the 100-error cap. |
|
||||||
|
|
||||||
|
**Caveat:** this is still compile-probe work only. No link, no `pythoncore`/`python.exe` build, no Wine launch, and no Windows 98 runtime execution was attempted or claimed.
|
||||||
|
|
||||||
## Files changed in this revision (`pylifecycle.c` VC6 PyRuntime section slice)
|
## Files changed in this revision (`pylifecycle.c` VC6 PyRuntime section slice)
|
||||||
|
|
||||||
All still uncommitted; nothing in this list has been pushed anywhere.
|
All still uncommitted; nothing in this list has been pushed anywhere.
|
||||||
@@ -899,28 +1755,3 @@ file is seen, so the true scope is not yet known. Recommended next steps:
|
|||||||
1. Continue with `Python/pylifecycle.c` by applying the same two mechanical
|
1. Continue with `Python/pylifecycle.c` by applying the same two mechanical
|
||||||
transforms already validated on `Modules/main.c` — hoist mid-block
|
transforms already validated on `Modules/main.c` — hoist mid-block
|
||||||
declarations (declaration-order slice) and replace compound-literal/
|
declarations (declaration-order slice) and replace compound-literal/
|
||||||
designated-initializer assignments with field-by-field assignment or,
|
|
||||||
where a public API function already exists (as `PyStatus_Ok()` did for
|
|
||||||
`_PyStatus_OK()`), a function call (compound-literal slice) — fixing
|
|
||||||
what the compiler surfaces in batches of roughly 100 (its per-run error
|
|
||||||
cap) and re-probing between batches, since the full error count for
|
|
||||||
this file is not yet known.
|
|
||||||
2. Re-evaluate the header-level-macro-vs-per-call-site tradeoff noted in
|
|
||||||
"Larger blockers to plan for" above once `_PyStatus_OK()`/
|
|
||||||
`_PyCompilerFlags_INIT`-style macros have been rewritten by hand in two
|
|
||||||
files (`main.c` and `pylifecycle.c`): if the same macros keep recurring
|
|
||||||
across many more `.c` files beyond these two, a header-level VC6 branch
|
|
||||||
(mirroring `_Py_ATOMIC_VC6_X86` in "Atomics slice" above) becomes more
|
|
||||||
attractive than continuing per-call-site rewrites file by file.
|
|
||||||
3. Only after enough core translation units compile, and a minimal
|
|
||||||
`pythoncore`/`Programs/python.c` link is attempted, should work move to
|
|
||||||
the Win9x API surface one subsystem at a time.
|
|
||||||
|
|
||||||
Validate incrementally with `scripts/vc6-probe-core.sh` against each file
|
|
||||||
being worked on, the same way this and prior slices did.
|
|
||||||
|
|
||||||
## Scope boundary
|
|
||||||
|
|
||||||
This project does not vendor the 223 MB MSVC600 bundle into a distributable
|
|
||||||
repository. It records the external tool as a local build prerequisite. No
|
|
||||||
Microsoft compiler binaries or runtime files should be committed or published.
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
|||||||
|
#ifndef PYWIN9X_COMPAT_MSVC600_PATHCCH_H
|
||||||
|
#define PYWIN9X_COMPAT_MSVC600_PATHCCH_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Narrow PathCchFindExtension compatibility for the VC6/MSVC600 probe.
|
||||||
|
*
|
||||||
|
* CPython 3.11's Modules/getpath.c includes <pathcch.h> only to call
|
||||||
|
* PathCchFindExtension() from getpath_isxfile(). MSVC 6.0's Windows SDK
|
||||||
|
* predates PathCch, so provide just that one API shape for the project-local
|
||||||
|
* VC6 include path. Modern builds should keep using the platform SDK header;
|
||||||
|
* this file is not installed into CPython or a system include directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||||
|
|
||||||
|
#ifndef _WINDOWS_
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef PCWSTR
|
||||||
|
typedef const WCHAR *PCWSTR;
|
||||||
|
#endif
|
||||||
|
#ifndef PWSTR
|
||||||
|
typedef WCHAR *PWSTR;
|
||||||
|
#endif
|
||||||
|
#ifndef S_OK
|
||||||
|
#define S_OK ((HRESULT)0L)
|
||||||
|
#endif
|
||||||
|
#ifndef E_INVALIDARG
|
||||||
|
#define E_INVALIDARG ((HRESULT)0x80070057L)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static HRESULT
|
||||||
|
PathCchFindExtension(PCWSTR pszPath, size_t cchPath, PCWSTR *ppszExt)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t last_sep;
|
||||||
|
size_t last_dot;
|
||||||
|
int have_dot;
|
||||||
|
|
||||||
|
if (pszPath == NULL || ppszExt == NULL || cchPath == 0) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_sep = 0;
|
||||||
|
last_dot = 0;
|
||||||
|
have_dot = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < cchPath; ++i) {
|
||||||
|
WCHAR ch = pszPath[i];
|
||||||
|
if (ch == L'\0') {
|
||||||
|
if (have_dot) {
|
||||||
|
*ppszExt = pszPath + last_dot;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*ppszExt = pszPath + i;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if (ch == L'\\' || ch == L'/' || ch == L':') {
|
||||||
|
last_sep = i + 1;
|
||||||
|
have_dot = 0;
|
||||||
|
}
|
||||||
|
else if (ch == L'.' && i >= last_sep) {
|
||||||
|
last_dot = i;
|
||||||
|
have_dot = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppszExt = NULL;
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* This compatibility header is intentionally scoped to VC6. If a modern
|
||||||
|
* compiler finds it, the include path is wrong: use the real Windows SDK
|
||||||
|
* pathcch.h instead to avoid shadowing the platform declaration.
|
||||||
|
*/
|
||||||
|
#error "compat/msvc600/pathcch.h is only for MSVC 6.0; use the Windows SDK pathcch.h on modern compilers"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PYWIN9X_COMPAT_MSVC600_PATHCCH_H */
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef PYTHON_WIN9X_MSVC600_STDINT_H
|
||||||
|
#define PYTHON_WIN9X_MSVC600_STDINT_H
|
||||||
|
|
||||||
|
/* VC6-only fallback for the C99 <stdint.h> header.
|
||||||
|
*
|
||||||
|
* Visual C++ 6.0 (_MSC_VER 1200) predates C99 and ships no <stdint.h>. This
|
||||||
|
* project-local header is found ahead of any system <stdint.h> only because
|
||||||
|
* compat/msvc600 is placed first on the VC6 probe scripts' include path
|
||||||
|
* (scripts/vc6-probe.sh, scripts/vc6-probe-core.sh, scripts/vc6-probe-
|
||||||
|
* pythoncore-frontier.sh); it is never installed anywhere a standards-
|
||||||
|
* conforming compiler's own <stdint.h> would be found instead, so it never
|
||||||
|
* shadows a real one.
|
||||||
|
*
|
||||||
|
* First consumer: cpython/Modules/_blake2/impl/blake2.h and
|
||||||
|
* blake2-impl.h, which use only uint8_t, uint32_t, and uint64_t (verified
|
||||||
|
* by grepping every fixed-width identifier used across Modules/_blake2/,
|
||||||
|
* including the blake2b/blake2s/*-ref.c reference implementations and
|
||||||
|
* clinic-generated wrappers: no int8_t/int16_t/int32_t/int64_t or intptr_t/
|
||||||
|
* uintptr_t appear anywhere in that tree). `size_t` is used too, but that
|
||||||
|
* already comes from <stddef.h>, which VC6 has natively.
|
||||||
|
*
|
||||||
|
* compat/msvc600/inttypes.h already defines exactly these typedefs (plus
|
||||||
|
* the PRI* macros CPython's own Include/pyport.h needs from a real C99
|
||||||
|
* <inttypes.h>) for this same VC6 target. Rather than re-declaring
|
||||||
|
* uint8_t/uint32_t/uint64_t a second time under a second include guard
|
||||||
|
* (which would risk a duplicate-typedef error in any translation unit that
|
||||||
|
* ends up including both this header and <inttypes.h>, e.g. anything that
|
||||||
|
* pulls in both Python.h and a <stdint.h>-using third-party header like
|
||||||
|
* blake2.h), this header just forwards to it. inttypes.h's own include
|
||||||
|
* guard makes this forwarding idempotent no matter which of the two headers
|
||||||
|
* a given translation unit reaches first.
|
||||||
|
*
|
||||||
|
* Width assumptions (all already relied upon by inttypes.h and unchanged
|
||||||
|
* here): uint8_t = unsigned char (1 byte), uint32_t = unsigned long
|
||||||
|
* (4 bytes on Win32/ILP32), uint64_t = unsigned __int64 (VC6's non-standard
|
||||||
|
* 64-bit extension, 8 bytes). These match the sizes BLAKE2 requires.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(_MSC_VER) || _MSC_VER >= 1300
|
||||||
|
#error "compat/msvc600/stdint.h is a VC6-only (_MSC_VER < 1300) fallback; a standard <stdint.h> should be used instead."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "inttypes.h"
|
||||||
|
|
||||||
|
#endif /* PYTHON_WIN9X_MSVC600_STDINT_H */
|
||||||
@@ -7,15 +7,16 @@
|
|||||||
* three distinct patterns:
|
* three distinct patterns:
|
||||||
*
|
*
|
||||||
* 1. `status = _PyStatus_OK();` -- a compound-literal macro used as a
|
* 1. `status = _PyStatus_OK();` -- a compound-literal macro used as a
|
||||||
* plain assignment's right-hand side. Fixed by calling the existing
|
* plain assignment's right-hand side. The shared macro now expands to
|
||||||
* public API function PyStatus_Ok() instead, which
|
* a VC6-only internal helper that assigns PyStatus fields explicitly,
|
||||||
* Python/initconfig.c defines as `return _PyStatus_OK();` -- the
|
* while newer compilers keep the original compound-literal form.
|
||||||
* identical value, no header change needed.
|
* 2. `status = _PyStatus_ERR("...");` -- same compound-literal macro
|
||||||
* 2. `cf = _PyCompilerFlags_INIT;` -- likewise a compound-literal macro
|
* pattern for ERROR statuses, now using a VC6-only explicit helper.
|
||||||
|
* 3. `cf = _PyCompilerFlags_INIT;` -- likewise a compound-literal macro
|
||||||
* used as a plain assignment. Fixed by assigning PyCompilerFlags's
|
* used as a plain assignment. Fixed by assigning PyCompilerFlags's
|
||||||
* two fields explicitly (cf_flags, cf_feature_version), matching the
|
* two fields explicitly (cf_flags, cf_feature_version), matching the
|
||||||
* macro's own definition field-for-field.
|
* macro's own definition field-for-field.
|
||||||
* 3. `_PyArgv args = { .argc = argc, ... };` -- a designated-initializer
|
* 4. `_PyArgv args = { .argc = argc, ... };` -- a designated-initializer
|
||||||
* aggregate initializer with no macro involved. Fixed by declaring
|
* aggregate initializer with no macro involved. Fixed by declaring
|
||||||
* the variable bare and assigning each field explicitly; field order
|
* the variable bare and assigning each field explicitly; field order
|
||||||
* does not matter for plain assignment, unlike an initializer list.
|
* does not matter for plain assignment, unlike an initializer list.
|
||||||
@@ -35,8 +36,18 @@ vc6_status_ok_smoke(void)
|
|||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
/* pattern 1: was `status = _PyStatus_OK();` */
|
/* pattern 1: VC6-only _PyStatus_OK() macro fallback helper. */
|
||||||
status = PyStatus_Ok();
|
status = _PyStatus_OK();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyStatus
|
||||||
|
vc6_status_error_smoke(void)
|
||||||
|
{
|
||||||
|
PyStatus status;
|
||||||
|
|
||||||
|
/* pattern 2: VC6-only _PyStatus_ERR() macro fallback helper. */
|
||||||
|
status = _PyStatus_ERR("vc6 status error smoke");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/* Focused compile smoke test for compat/msvc600/pathcch.h.
|
||||||
|
*
|
||||||
|
* The VC6 compatibility header intentionally implements only the single
|
||||||
|
* PathCch API used by cpython/Modules/getpath.c: PathCchFindExtension().
|
||||||
|
* This fixture keeps the representative path cases in one place for the
|
||||||
|
* VC6 probe. The probe is compile-only, so the checks are ordinary C code
|
||||||
|
* that can also be run later by a tiny Windows harness if needed.
|
||||||
|
*/
|
||||||
|
#include <windows.h>
|
||||||
|
#include <pathcch.h>
|
||||||
|
|
||||||
|
#ifndef ARRAYSIZE
|
||||||
|
#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
pathcch_expect_ext(PCWSTR path, size_t cch, size_t offset)
|
||||||
|
{
|
||||||
|
PCWSTR ext;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
ext = NULL;
|
||||||
|
hr = PathCchFindExtension(path, cch, &ext);
|
||||||
|
return SUCCEEDED(hr) && ext == path + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pathcch_expect_invalid(PCWSTR path, size_t cch)
|
||||||
|
{
|
||||||
|
PCWSTR ext;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
ext = (PCWSTR)1;
|
||||||
|
hr = PathCchFindExtension(path, cch, &ext);
|
||||||
|
return FAILED(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vc6_pathcch_find_extension_smoke(void)
|
||||||
|
{
|
||||||
|
static const WCHAR exe_path[] = L"C:\\Python311\\python.exe";
|
||||||
|
static const WCHAR no_ext[] = L"C:\\Python311\\python";
|
||||||
|
static const WCHAR dir_dot[] = L"C:\\tmp.dir\\python";
|
||||||
|
static const WCHAR dotfile[] = L"C:\\Python311\\.pythonrc";
|
||||||
|
static const WCHAR trailing_dir[] = L"C:\\bin\\python.exe\\";
|
||||||
|
static const WCHAR multi_dot[] = L"C:\\tmp\\archive.tar.gz";
|
||||||
|
int ok;
|
||||||
|
|
||||||
|
ok = 1;
|
||||||
|
ok = ok && pathcch_expect_ext(exe_path, ARRAYSIZE(exe_path), 20); /* .exe */
|
||||||
|
ok = ok && pathcch_expect_ext(no_ext, ARRAYSIZE(no_ext), 19); /* NUL */
|
||||||
|
ok = ok && pathcch_expect_ext(dir_dot, ARRAYSIZE(dir_dot), 17); /* NUL, directory dot ignored */
|
||||||
|
ok = ok && pathcch_expect_ext(dotfile, ARRAYSIZE(dotfile), 13); /* dotfile extension */
|
||||||
|
ok = ok && pathcch_expect_ext(trailing_dir, ARRAYSIZE(trailing_dir), 18); /* NUL after separator */
|
||||||
|
ok = ok && pathcch_expect_ext(multi_dot, ARRAYSIZE(multi_dot), 18); /* last suffix */
|
||||||
|
ok = ok && pathcch_expect_invalid(exe_path, 4); /* too small: no NUL */
|
||||||
|
ok = ok && pathcch_expect_invalid(NULL, ARRAYSIZE(exe_path));
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/* Focused compile smoke test for compat/msvc600/stdint.h.
|
||||||
|
*
|
||||||
|
* The VC6 compatibility header forwards to the existing
|
||||||
|
* compat/msvc600/inttypes.h typedefs. This fixture exercises exactly the
|
||||||
|
* subset that cpython/Modules/_blake2/impl/blake2-impl.h needs: uint8_t,
|
||||||
|
* uint32_t, and uint64_t, in the same load/store/rotate shapes that file
|
||||||
|
* uses, plus a compile-time width check for each. It also includes
|
||||||
|
* <inttypes.h> alongside <stdint.h> in the same translation unit, the way
|
||||||
|
* a Python.h + blake2.h translation unit would, to guard against the
|
||||||
|
* duplicate-typedef failure mode the stdint.h header is designed to avoid.
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef char vc6_stdint_check_uint8_is_1_byte[(sizeof(uint8_t) == 1) ? 1 : -1];
|
||||||
|
typedef char vc6_stdint_check_uint32_is_4_bytes[(sizeof(uint32_t) == 4) ? 1 : -1];
|
||||||
|
typedef char vc6_stdint_check_uint64_is_8_bytes[(sizeof(uint64_t) == 8) ? 1 : -1];
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
vc6_stdint_load32(const void *src)
|
||||||
|
{
|
||||||
|
const uint8_t *p = (const uint8_t *)src;
|
||||||
|
uint32_t w = *p++;
|
||||||
|
w |= ((uint32_t)(*p++)) << 8;
|
||||||
|
w |= ((uint32_t)(*p++)) << 16;
|
||||||
|
w |= ((uint32_t)(*p++)) << 24;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
vc6_stdint_load64(const void *src)
|
||||||
|
{
|
||||||
|
const uint8_t *p = (const uint8_t *)src;
|
||||||
|
uint64_t w = *p++;
|
||||||
|
w |= ((uint64_t)(*p++)) << 8;
|
||||||
|
w |= ((uint64_t)(*p++)) << 16;
|
||||||
|
w |= ((uint64_t)(*p++)) << 24;
|
||||||
|
w |= ((uint64_t)(*p++)) << 32;
|
||||||
|
w |= ((uint64_t)(*p++)) << 40;
|
||||||
|
w |= ((uint64_t)(*p++)) << 48;
|
||||||
|
w |= ((uint64_t)(*p++)) << 56;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
vc6_stdint_rotl32(const uint32_t w, const unsigned c)
|
||||||
|
{
|
||||||
|
return (w << c) | (w >> (32 - c));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
vc6_stdint_rotl64(const uint64_t w, const unsigned c)
|
||||||
|
{
|
||||||
|
return (w << c) | (w >> (64 - c));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vc6_stdint_smoke(void)
|
||||||
|
{
|
||||||
|
static const uint8_t bytes32[4] = { 0x01, 0x02, 0x03, 0x04 };
|
||||||
|
static const uint8_t bytes64[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||||
|
uint32_t w32;
|
||||||
|
uint64_t w64;
|
||||||
|
int ok;
|
||||||
|
|
||||||
|
w32 = vc6_stdint_load32(bytes32);
|
||||||
|
w64 = vc6_stdint_load64(bytes64);
|
||||||
|
|
||||||
|
ok = 1;
|
||||||
|
ok = ok && (w32 == 0x04030201UL);
|
||||||
|
ok = ok && (vc6_stdint_rotl32(w32, 8) == ((w32 << 8) | (w32 >> 24)));
|
||||||
|
ok = ok && (vc6_stdint_rotl64(w64, 8) == ((w64 << 8) | (w64 >> 56)));
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Generate the CPython frozen getpath.py header into ignored build output.
|
||||||
|
#
|
||||||
|
# CPython's build documents this target in Makefile.pre.in:
|
||||||
|
# Python/frozen_modules/getpath.h: Modules/getpath.py ...
|
||||||
|
# Programs/_freeze_module.py getpath Modules/getpath.py Python/frozen_modules/getpath.h
|
||||||
|
#
|
||||||
|
# This script intentionally writes under build/generated/cpython/... so the
|
||||||
|
# repository does not track generated bytecode headers or vendor files.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# scripts/generate-getpath-frozen.sh [output-root]
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# <output-root>/cpython/Python/frozen_modules/getpath.h
|
||||||
|
# default output-root: build/generated
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
CPYTHON_ROOT="$REPO_ROOT/cpython"
|
||||||
|
OUTPUT_ROOT="${1:-$REPO_ROOT/build/generated}"
|
||||||
|
OUT_DIR="$OUTPUT_ROOT/cpython/Python/frozen_modules"
|
||||||
|
OUT_HEADER="$OUT_DIR/getpath.h"
|
||||||
|
FREEZE_SCRIPT="$CPYTHON_ROOT/Programs/_freeze_module.py"
|
||||||
|
INPUT="$CPYTHON_ROOT/Modules/getpath.py"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
sed -n '11,19p' "$REPO_ROOT/scripts/generate-getpath-frozen.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for required in "$CPYTHON_ROOT" "$FREEZE_SCRIPT" "$INPUT"; do
|
||||||
|
if [ ! -e "$required" ]; then
|
||||||
|
echo "generate-getpath-frozen: missing prerequisite: $required" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! command -v python3 >/dev/null 2>&1; then
|
||||||
|
echo "generate-getpath-frozen: missing prerequisite: python3" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
python3 "$FREEZE_SCRIPT" getpath "$INPUT" "$OUT_HEADER"
|
||||||
|
status=$?
|
||||||
|
if [ "$status" -ne 0 ]; then
|
||||||
|
echo "generate-getpath-frozen: _freeze_module.py failed with exit $status" >&2
|
||||||
|
exit "$status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -s "$OUT_HEADER" ]; then
|
||||||
|
echo "generate-getpath-frozen: expected nonempty output missing: $OUT_HEADER" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' "${OUT_HEADER#$REPO_ROOT/}"
|
||||||
Executable
+119
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Regression tests for reproducible getpath.py frozen-header generation.
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
GENERATOR="$REPO_ROOT/scripts/generate-getpath-frozen.sh"
|
||||||
|
TMP_ROOT="$REPO_ROOT/build/test-getpath-frozen"
|
||||||
|
OUT_HEADER="$TMP_ROOT/cpython/Python/frozen_modules/getpath.h"
|
||||||
|
DIRECT_HEADER="$TMP_ROOT/direct/getpath.h"
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
pass() { echo "ok - $1"; }
|
||||||
|
bad() { echo "not ok - $1"; fail=1; }
|
||||||
|
|
||||||
|
rm -rf "$TMP_ROOT"
|
||||||
|
out="$($GENERATOR "$TMP_ROOT" 2>&1)"
|
||||||
|
status=$?
|
||||||
|
if [ "$status" -eq 0 ]; then
|
||||||
|
pass "generator exits 0"
|
||||||
|
else
|
||||||
|
bad "generator exits 0 (got exit $status)"
|
||||||
|
echo "$out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$out" = "build/test-getpath-frozen/cpython/Python/frozen_modules/getpath.h" ]; then
|
||||||
|
pass "generator reports the project-local build-relative output path"
|
||||||
|
else
|
||||||
|
bad "generator reports the project-local build-relative output path (got: $out)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -s "$OUT_HEADER" ]; then
|
||||||
|
pass "generator writes a nonempty getpath.h under build/"
|
||||||
|
else
|
||||||
|
bad "generator writes a nonempty getpath.h under build/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
first_line="$(sed -n '1p' "$OUT_HEADER" 2>/dev/null)"
|
||||||
|
if [ "$first_line" = '/* Auto-generated by Programs/_freeze_module.py */' ]; then
|
||||||
|
pass "generated header records the host-Python _freeze_module.py path"
|
||||||
|
else
|
||||||
|
bad "generated header records the host-Python _freeze_module.py path (got: $first_line)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
second_line="$(sed -n '2p' "$OUT_HEADER" 2>/dev/null)"
|
||||||
|
if [ "$second_line" = 'const unsigned char _Py_M__getpath[] = {' ]; then
|
||||||
|
pass "generated header declares the expected getpath frozen symbol"
|
||||||
|
else
|
||||||
|
bad "generated header declares the expected getpath frozen symbol (got: $second_line)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 - "$OUT_HEADER" <<'PY'
|
||||||
|
import marshal
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
path = Path(sys.argv[1])
|
||||||
|
text = path.read_text()
|
||||||
|
if not text.endswith('};\n'):
|
||||||
|
raise SystemExit('header does not end with closing array marker')
|
||||||
|
match = re.search(r'const unsigned char _Py_M__getpath\[\] = \{\n(?P<body>.*?)\};\n\Z', text, re.S)
|
||||||
|
if not match:
|
||||||
|
raise SystemExit('array body not found')
|
||||||
|
lines = match.group('body').splitlines()
|
||||||
|
values = []
|
||||||
|
for index, line in enumerate(lines, 1):
|
||||||
|
if not line.startswith(' '):
|
||||||
|
raise SystemExit(f'line {index} is not four-space indented')
|
||||||
|
payload = line.strip()
|
||||||
|
if not payload.endswith(','):
|
||||||
|
raise SystemExit(f'line {index} is missing trailing comma')
|
||||||
|
nums = [part for part in payload[:-1].split(',') if part]
|
||||||
|
if len(nums) > 16:
|
||||||
|
raise SystemExit(f'line {index} has more than 16 bytes')
|
||||||
|
if index < len(lines) and len(nums) != 16:
|
||||||
|
raise SystemExit(f'non-final line {index} has {len(nums)} bytes, expected 16')
|
||||||
|
for num in nums:
|
||||||
|
value = int(num)
|
||||||
|
if not 0 <= value <= 255:
|
||||||
|
raise SystemExit(f'byte out of range: {value}')
|
||||||
|
values.append(value)
|
||||||
|
code = marshal.loads(bytes(values))
|
||||||
|
if code.co_filename != '<frozen getpath>':
|
||||||
|
raise SystemExit(f'unexpected code filename: {code.co_filename!r}')
|
||||||
|
if code.co_name != '<module>':
|
||||||
|
raise SystemExit(f'unexpected code name: {code.co_name!r}')
|
||||||
|
print('format-ok')
|
||||||
|
PY
|
||||||
|
format_status=$?
|
||||||
|
if [ "$format_status" -eq 0 ]; then
|
||||||
|
pass "generated byte array unmarshals as frozen getpath code with CPython format"
|
||||||
|
else
|
||||||
|
bad "generated byte array unmarshals as frozen getpath code with CPython format"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$DIRECT_HEADER")"
|
||||||
|
python3 "$REPO_ROOT/cpython/Programs/_freeze_module.py" getpath \
|
||||||
|
"$REPO_ROOT/cpython/Modules/getpath.py" "$DIRECT_HEADER"
|
||||||
|
if cmp -s "$OUT_HEADER" "$DIRECT_HEADER"; then
|
||||||
|
pass "generator output matches direct Programs/_freeze_module.py invocation exactly"
|
||||||
|
else
|
||||||
|
bad "generator output matches direct Programs/_freeze_module.py invocation exactly"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frontier_out="$(bash "$REPO_ROOT/scripts/vc6-probe-pythoncore-frontier.sh" --list-only 2>&1)"
|
||||||
|
frontier_status=$?
|
||||||
|
if [ "$frontier_status" -eq 0 ] && printf '%s\n' "$frontier_out" | grep -q $'^compile\tcpython/Modules/getpath.c\t'; then
|
||||||
|
pass "frontier list still starts from Modules/getpath.c without requiring generated output"
|
||||||
|
else
|
||||||
|
bad "frontier list still starts from Modules/getpath.c without requiring generated output"
|
||||||
|
echo "$frontier_out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$fail" -ne 0 ]; then
|
||||||
|
echo "FAILED"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "ALL TESTS PASSED"
|
||||||
@@ -261,11 +261,17 @@ EOF
|
|||||||
# --- positive case: the isolated compound-literal/designated-
|
# --- positive case: the isolated compound-literal/designated-
|
||||||
# initializer smoke fixture compiles clean. It exercises, self-
|
# initializer smoke fixture compiles clean. It exercises, self-
|
||||||
# contained (aside from the real Python.h/pycore_initconfig.h types
|
# contained (aside from the real Python.h/pycore_initconfig.h types
|
||||||
# it needs), the three replacement patterns applied to main.c: calling
|
# it needs), the four replacement patterns now in use: the VC6-only
|
||||||
# PyStatus_Ok() instead of the _PyStatus_OK() compound-literal macro,
|
# _PyStatus_OK() helper (not PyStatus_Ok(), avoiding recursion), the
|
||||||
# explicit field assignment instead of the _PyCompilerFlags_INIT
|
# VC6-only _PyStatus_ERR() helper, explicit field assignment instead of
|
||||||
# compound-literal macro, and explicit field assignment instead of a
|
# the _PyCompilerFlags_INIT compound-literal macro, and explicit field
|
||||||
# _PyArgv designated-initializer aggregate. ---
|
# assignment instead of a _PyArgv designated-initializer aggregate. ---
|
||||||
|
if grep -q '#[[:space:]]*define[[:space:]]*_PyStatus_OK().*PyStatus_Ok' "$REPO_ROOT/cpython/Include/internal/pycore_initconfig.h"; then
|
||||||
|
bad "pycore_initconfig.h: VC6 _PyStatus_OK() helper does not recurse through PyStatus_Ok()"
|
||||||
|
else
|
||||||
|
pass "pycore_initconfig.h: VC6 _PyStatus_OK() helper does not recurse through PyStatus_Ok()"
|
||||||
|
fi
|
||||||
|
|
||||||
out_compound="$("$PROBE" scripts/fixtures/vc6_compound_literal_smoke.c 2>&1)"
|
out_compound="$("$PROBE" scripts/fixtures/vc6_compound_literal_smoke.c 2>&1)"
|
||||||
status_compound=$?
|
status_compound=$?
|
||||||
|
|
||||||
|
|||||||
Executable
+140
@@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Minimal VC6 link-frontier probe for the Windows 9x port.
|
||||||
|
#
|
||||||
|
# This is deliberately smaller than CPython's full PCbuild/pythoncore.vcxproj:
|
||||||
|
# it compiles only the translation units already proven by the core compile
|
||||||
|
# probes plus the tiny Programs/python.c executable entry point, then invokes
|
||||||
|
# LINK.EXE under Wine. A successful executable link is not expected yet; the
|
||||||
|
# purpose of this milestone is to verify that the build can get past CL.EXE
|
||||||
|
# for the current frontier and reach a real VC6 linker diagnostic with a
|
||||||
|
# reproducible command line.
|
||||||
|
#
|
||||||
|
# The MSVC600 bundle is an external, local-only prerequisite; nothing under
|
||||||
|
# MSVC600/ is part of this project's source.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# scripts/vc6-probe-minlink.sh
|
||||||
|
#
|
||||||
|
# Environment:
|
||||||
|
# MSVC600_ROOT override the MSVC600 location (default: <repo>/MSVC600)
|
||||||
|
# WINEPREFIX override the Wine prefix (default: ~/.wine-win9xport)
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
|
||||||
|
# Reuse winpath()/strip_prefix() from vc6-probe.sh instead of duplicating
|
||||||
|
# them; sourcing it does not run the probe itself (see its own guard).
|
||||||
|
# shellcheck source=scripts/vc6-probe.sh
|
||||||
|
source "$REPO_ROOT/scripts/vc6-probe.sh"
|
||||||
|
|
||||||
|
run_probe_minlink() {
|
||||||
|
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
|
||||||
|
BUILD_DIR="$REPO_ROOT/build/vc6-probe-minlink"
|
||||||
|
|
||||||
|
CL="$MSVC600_ROOT/VC98/Bin/CL.EXE"
|
||||||
|
LINK="$MSVC600_ROOT/VC98/Bin/LINK.EXE"
|
||||||
|
VCVARS="$MSVC600_ROOT/VC98/Bin/VCVARS32.BAT"
|
||||||
|
|
||||||
|
# Keep this list intentionally tiny and aligned with the post-core-probe
|
||||||
|
# milestone: python.vcxproj's single executable TU plus the three core TUs
|
||||||
|
# that are currently known to compile under scripts/vc6-probe-core.sh.
|
||||||
|
SOURCES=(
|
||||||
|
"cpython/Programs/python.c"
|
||||||
|
"cpython/Modules/main.c"
|
||||||
|
"cpython/Python/pylifecycle.c"
|
||||||
|
"cpython/Python/pystate.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
for required in "$CL" "$LINK" "$VCVARS" "$MSVC600_ROOT/VC98/Include" \
|
||||||
|
"$MSVC600_ROOT/VC98/Lib" "$MSVC600_ROOT/Common/MSDev98/Bin"; do
|
||||||
|
if [ ! -e "$required" ]; then
|
||||||
|
echo "vc6-probe-minlink: missing prerequisite: $required" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local source_rel
|
||||||
|
for source_rel in "${SOURCES[@]}"; do
|
||||||
|
if [ ! -e "$REPO_ROOT/$source_rel" ]; then
|
||||||
|
echo "vc6-probe-minlink: missing source: $REPO_ROOT/$source_rel" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! command -v wine >/dev/null 2>&1; then
|
||||||
|
echo "vc6-probe-minlink: wine is not installed" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
export WINEPREFIX="${WINEPREFIX:-$HOME/.wine-win9xport}"
|
||||||
|
export WINEDEBUG="${WINEDEBUG:--all}"
|
||||||
|
|
||||||
|
# CL.EXE loads C1/C2 from VC98/Bin and MSPDB60.DLL from Common/MSDev98/Bin;
|
||||||
|
# LINK.EXE also needs the VC98 tools and default libraries.
|
||||||
|
export WINEPATH="$(winpath "$MSVC600_ROOT/VC98/Bin");$(winpath "$MSVC600_ROOT/Common/MSDev98/Bin")"
|
||||||
|
|
||||||
|
rm -rf "$BUILD_DIR"
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
|
||||||
|
INCLUDE_ARGS=(
|
||||||
|
"$(winpath "$REPO_ROOT/compat/msvc600")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/Include/internal")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/Include")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/PC")"
|
||||||
|
"$(winpath "$MSVC600_ROOT/VC98/Include")"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "== MSVC600 minimal link-frontier probe =="
|
||||||
|
echo "sources:"
|
||||||
|
for source_rel in "${SOURCES[@]}"; do
|
||||||
|
echo " - $source_rel"
|
||||||
|
done
|
||||||
|
echo "prefix : $WINEPREFIX"
|
||||||
|
echo
|
||||||
|
|
||||||
|
local obj_args=""
|
||||||
|
local source_abs obj_name obj_abs cmd status
|
||||||
|
for source_rel in "${SOURCES[@]}"; do
|
||||||
|
source_abs="$REPO_ROOT/$source_rel"
|
||||||
|
obj_name="${source_rel#cpython/}"
|
||||||
|
obj_name="${obj_name//\//_}"
|
||||||
|
obj_name="${obj_name%.c}.obj"
|
||||||
|
obj_abs="$BUILD_DIR/$obj_name"
|
||||||
|
obj_args+=" $(winpath "$obj_abs")"
|
||||||
|
|
||||||
|
cmd="call $(winpath "$VCVARS") && cd /d $(winpath "$REPO_ROOT/cpython") && cl /nologo /D Py_BUILD_CORE /D Py_BUILD_CORE_BUILTIN /D Py_ENABLE_SHARED /D _USRDLL"
|
||||||
|
for include_arg in "${INCLUDE_ARGS[@]}"; do
|
||||||
|
cmd+=" /I $include_arg"
|
||||||
|
done
|
||||||
|
cmd+=" /c $(winpath "$source_abs") /Fo$(winpath "$obj_abs")"
|
||||||
|
|
||||||
|
wine cmd /c "$cmd" 2>&1 |
|
||||||
|
grep -v '^[0-9a-f]\{4\}:err:' |
|
||||||
|
strip_prefix "$(winpath "$REPO_ROOT")\\"
|
||||||
|
status="${PIPESTATUS[0]}"
|
||||||
|
if [ "$status" -ne 0 ]; then
|
||||||
|
echo
|
||||||
|
echo "== cl.exe exit status: $status =="
|
||||||
|
echo "vc6-probe-minlink: compile failed before link at $source_rel" >&2
|
||||||
|
return "$status"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "== LINK.EXE attempt =="
|
||||||
|
cmd="call $(winpath "$VCVARS") && cd /d $(winpath "$REPO_ROOT/cpython") && link /nologo /subsystem:console /out:$(winpath "$BUILD_DIR/python-min.exe") /libpath:$(winpath "$MSVC600_ROOT/VC98/Lib")$obj_args kernel32.lib user32.lib advapi32.lib shell32.lib version.lib ws2_32.lib"
|
||||||
|
|
||||||
|
wine cmd /c "$cmd" 2>&1 |
|
||||||
|
grep -v '^[0-9a-f]\{4\}:err:' |
|
||||||
|
strip_prefix "$(winpath "$REPO_ROOT")\\"
|
||||||
|
status="${PIPESTATUS[0]}"
|
||||||
|
echo
|
||||||
|
echo "== link.exe exit status: $status =="
|
||||||
|
return "$status"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
||||||
|
run_probe_minlink "$@"
|
||||||
|
exit "$?"
|
||||||
|
fi
|
||||||
Executable
+58
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Regression tests for the narrow VC6 compat/msvc600/pathcch.h shim.
|
||||||
|
#
|
||||||
|
# Skipped (not failed) when Wine + MSVC600 are unavailable, matching the other
|
||||||
|
# VC6 probe test scripts. The live check is compile-only: it verifies that the
|
||||||
|
# fixture using representative PathCchFindExtension paths reaches cl.exe exit 0.
|
||||||
|
#
|
||||||
|
# Usage: scripts/vc6-probe-pathcch.test.sh
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
PROBE="$REPO_ROOT/scripts/vc6-probe-core.sh"
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
pass() { echo "ok - $1"; }
|
||||||
|
bad() { echo "not ok - $1"; fail=1; }
|
||||||
|
|
||||||
|
if grep -q 'PathCchFindExtension' "$REPO_ROOT/compat/msvc600/pathcch.h" && \
|
||||||
|
grep -q 'defined(_MSC_VER).*1200' "$REPO_ROOT/compat/msvc600/pathcch.h"; then
|
||||||
|
pass "compat/msvc600/pathcch.h provides a VC6-scoped PathCchFindExtension shim"
|
||||||
|
else
|
||||||
|
bad "compat/msvc600/pathcch.h provides a VC6-scoped PathCchFindExtension shim"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
|
||||||
|
if command -v wine >/dev/null 2>&1 && [ -e "$MSVC600_ROOT/VC98/Bin/CL.EXE" ]; then
|
||||||
|
out="$($PROBE scripts/fixtures/vc6_pathcch_smoke.c 2>&1)"
|
||||||
|
status=$?
|
||||||
|
|
||||||
|
if [ "$status" -eq 0 ]; then
|
||||||
|
pass "PathCchFindExtension smoke fixture compiles under VC6 (exit 0)"
|
||||||
|
else
|
||||||
|
bad "PathCchFindExtension smoke fixture compiles under VC6 (exit $status)"
|
||||||
|
echo "$out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s' "$out" | grep -q "Cannot open include file: 'pathcch.h'"; then
|
||||||
|
bad "pathcch smoke fixture does not regress to missing pathcch.h"
|
||||||
|
else
|
||||||
|
pass "pathcch smoke fixture does not regress to missing pathcch.h"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s' "$out" | grep -qi 'error'; then
|
||||||
|
bad "pathcch smoke fixture: no compiler errors in output"
|
||||||
|
else
|
||||||
|
pass "pathcch smoke fixture: no compiler errors in output"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "skip - wine/MSVC600 not available; skipping live pathcch integration check"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$fail" -ne 0 ]; then
|
||||||
|
echo "FAILED"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "ALL TESTS PASSED"
|
||||||
Executable
+376
@@ -0,0 +1,376 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Source-list-driven VC6 compile frontier for CPython's pythoncore project.
|
||||||
|
#
|
||||||
|
# This reads cpython/PCbuild/pythoncore.vcxproj <ClCompile> entries, safely
|
||||||
|
# normalizes their Windows-style paths into project-local cpython/... sources,
|
||||||
|
# reports entries that this VC6/Wine frontier intentionally cannot consume
|
||||||
|
# yet, and compiles supported sources one at a time into build artifacts. It
|
||||||
|
# stops at the first cl.exe failure and returns cl.exe's real exit status.
|
||||||
|
#
|
||||||
|
# This is a compile-only (/c) frontier: no pythoncore.dll/python.exe link or
|
||||||
|
# runtime success is claimed.
|
||||||
|
#
|
||||||
|
# The MSVC600 bundle is an external, local-only prerequisite; nothing under
|
||||||
|
# MSVC600/ is part of this project's source.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# scripts/vc6-probe-pythoncore-frontier.sh
|
||||||
|
# scripts/vc6-probe-pythoncore-frontier.sh --list-only
|
||||||
|
# scripts/vc6-probe-pythoncore-frontier.sh --limit N
|
||||||
|
#
|
||||||
|
# Environment:
|
||||||
|
# MSVC600_ROOT override the MSVC600 location (default: <repo>/MSVC600)
|
||||||
|
# WINEPREFIX override the Wine prefix (default: ~/.wine-win9xport)
|
||||||
|
# VC6_FRONTIER_FORCE set to 1 to ignore incremental object freshness
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
|
||||||
|
# Reuse winpath()/strip_prefix() from vc6-probe.sh instead of duplicating
|
||||||
|
# them; sourcing it does not run the probe itself (see its own guard).
|
||||||
|
# shellcheck source=scripts/vc6-probe.sh
|
||||||
|
source "$REPO_ROOT/scripts/vc6-probe.sh"
|
||||||
|
|
||||||
|
FRONTIER_SCRIPT="$REPO_ROOT/scripts/vc6-probe-pythoncore-frontier.sh"
|
||||||
|
PROJECT_REL="cpython/PCbuild/pythoncore.vcxproj"
|
||||||
|
PROJECT_ABS="$REPO_ROOT/$PROJECT_REL"
|
||||||
|
BUILD_DIR="$REPO_ROOT/build/vc6-probe-pythoncore-frontier"
|
||||||
|
SOURCE_LIST_TSV="$BUILD_DIR/pythoncore-sources.tsv"
|
||||||
|
GENERATED_ROOT="$REPO_ROOT/build/generated"
|
||||||
|
GENERATED_CPYTHON_ROOT="$GENERATED_ROOT/cpython"
|
||||||
|
GETPATH_GENERATOR="$REPO_ROOT/scripts/generate-getpath-frozen.sh"
|
||||||
|
GETPATH_FROZEN_HEADER="$GENERATED_CPYTHON_ROOT/Python/frozen_modules/getpath.h"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
sed -n '15,27p' "$FRONTIER_SCRIPT"
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_source_list() {
|
||||||
|
python3 - "$PROJECT_ABS" "$REPO_ROOT" <<'PY'
|
||||||
|
import os
|
||||||
|
import posixpath
|
||||||
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
project = os.path.abspath(sys.argv[1])
|
||||||
|
repo = os.path.abspath(sys.argv[2])
|
||||||
|
source_root = os.path.join(repo, "cpython")
|
||||||
|
project_dir = os.path.dirname(project)
|
||||||
|
ns = "{http://schemas.microsoft.com/developer/msbuild/2003}"
|
||||||
|
|
||||||
|
substitutions = {
|
||||||
|
"$(PyVPath)": r"..\\..",
|
||||||
|
"$(PyDebugExt)": "",
|
||||||
|
"$(SysWinVer)": "3.11",
|
||||||
|
}
|
||||||
|
|
||||||
|
def expand_msbuild(value):
|
||||||
|
for key, repl in substitutions.items():
|
||||||
|
value = value.replace(key, repl)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def normalize_include(include):
|
||||||
|
raw = include.strip()
|
||||||
|
expanded = expand_msbuild(raw)
|
||||||
|
if "$" in expanded or "%" in expanded:
|
||||||
|
return None, "unsupported-msbuild-macro"
|
||||||
|
path = expanded.replace("\\", "/")
|
||||||
|
if len(path) >= 2 and path[1] == ":":
|
||||||
|
return None, "absolute-windows-path"
|
||||||
|
abs_path = os.path.abspath(os.path.join(project_dir, path))
|
||||||
|
try:
|
||||||
|
rel_to_source = os.path.relpath(abs_path, source_root)
|
||||||
|
except ValueError:
|
||||||
|
return None, "outside-cpython-tree"
|
||||||
|
rel_posix = rel_to_source.replace(os.sep, "/")
|
||||||
|
if rel_posix == ".." or rel_posix.startswith("../") or posixpath.isabs(rel_posix):
|
||||||
|
return None, "outside-cpython-tree"
|
||||||
|
norm = posixpath.normpath(rel_posix)
|
||||||
|
if norm == "." or norm.startswith("../") or "/../" in f"/{norm}/":
|
||||||
|
return None, "unsafe-normalized-path"
|
||||||
|
return "cpython/" + norm, ""
|
||||||
|
|
||||||
|
def split_definitions(text):
|
||||||
|
if not text:
|
||||||
|
return []
|
||||||
|
text = expand_msbuild(" ".join(text.split()))
|
||||||
|
defs = []
|
||||||
|
for chunk in text.split(";"):
|
||||||
|
chunk = chunk.strip()
|
||||||
|
if not chunk or chunk == "%(PreprocessorDefinitions)":
|
||||||
|
continue
|
||||||
|
if "$" in chunk or "%" in chunk:
|
||||||
|
defs.append("UNSUPPORTED_MSBUILD_DEFINE=" + chunk)
|
||||||
|
else:
|
||||||
|
defs.append(chunk)
|
||||||
|
return defs
|
||||||
|
|
||||||
|
def classify(rel, inherited_condition, own_condition):
|
||||||
|
cond = f"{inherited_condition or ''} {own_condition or ''}"
|
||||||
|
if "IncludeExternals" in cond:
|
||||||
|
return "skip-external IncludeExternals-conditioned source"
|
||||||
|
if rel is None:
|
||||||
|
return "skip-unsupported"
|
||||||
|
if rel == "cpython/Python/deepfreeze/deepfreeze.c":
|
||||||
|
return "skip-generated deepfreeze source"
|
||||||
|
return "compile"
|
||||||
|
|
||||||
|
def walk(node, inherited_condition=""):
|
||||||
|
condition = node.attrib.get("Condition", "")
|
||||||
|
combined = " ".join(x for x in (inherited_condition, condition) if x)
|
||||||
|
if node.tag == ns + "ClCompile" and "Include" in node.attrib:
|
||||||
|
include = node.attrib["Include"]
|
||||||
|
rel, norm_error = normalize_include(include)
|
||||||
|
defs = []
|
||||||
|
for child in node:
|
||||||
|
if child.tag == ns + "PreprocessorDefinitions":
|
||||||
|
defs.extend(split_definitions(child.text or ""))
|
||||||
|
action = classify(rel, inherited_condition, condition)
|
||||||
|
reason = action
|
||||||
|
if action == "compile" and norm_error:
|
||||||
|
action = "skip-unsupported"
|
||||||
|
reason = f"skip-unsupported {norm_error}"
|
||||||
|
elif action == "skip-unsupported" and norm_error:
|
||||||
|
reason = f"skip-unsupported {norm_error}"
|
||||||
|
display_rel = rel or include.replace("\\", "/")
|
||||||
|
print("\t".join([action, display_rel, include, " ".join(defs), reason]))
|
||||||
|
for child in node:
|
||||||
|
walk(child, combined)
|
||||||
|
|
||||||
|
root = ET.parse(project).getroot()
|
||||||
|
walk(root)
|
||||||
|
PY
|
||||||
|
}
|
||||||
|
|
||||||
|
quote_define_for_cmd() {
|
||||||
|
local define="$1"
|
||||||
|
# Keep CL's /D string literal quotes after CL reads the generated response
|
||||||
|
# file. CL interprets C-string backslashes in /D values while parsing the
|
||||||
|
# define, so double the define's own backslashes before protecting literal
|
||||||
|
# quotes for CL's command-line parser.
|
||||||
|
# Example: VPATH="..\\.." must arrive at C preprocessing as "..\\..", not
|
||||||
|
# "..\.." and not an unterminated string.
|
||||||
|
define="${define//\\/\\\\}"
|
||||||
|
define="${define//\"/\\\"}"
|
||||||
|
printf '%s' "$define"
|
||||||
|
}
|
||||||
|
|
||||||
|
render_compile_command_for_test() {
|
||||||
|
local cmd='cl /nologo'
|
||||||
|
local define
|
||||||
|
for define in "$@"; do
|
||||||
|
cmd+=" /D $(quote_define_for_cmd "$define")"
|
||||||
|
done
|
||||||
|
printf '%s' "$cmd"
|
||||||
|
}
|
||||||
|
|
||||||
|
obj_name_for_source() {
|
||||||
|
local source_rel="$1"
|
||||||
|
source_rel="${source_rel#cpython/}"
|
||||||
|
source_rel="${source_rel//\//_}"
|
||||||
|
printf '%s' "${source_rel%.c}.obj"
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_getpath_frozen_header() {
|
||||||
|
if [ ! -x "$GETPATH_GENERATOR" ]; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: missing prerequisite: executable $GETPATH_GENERATOR" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
"$GETPATH_GENERATOR" "$GENERATED_ROOT" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
source_for_compile() {
|
||||||
|
local source_rel="$1"
|
||||||
|
local source_abs="$2"
|
||||||
|
if [ "$source_rel" != "cpython/Modules/getpath.c" ]; then
|
||||||
|
printf '%s' "$source_abs"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Modules/getpath.c includes "../Python/frozen_modules/getpath.h" relative
|
||||||
|
# to the compiling source file. Keep generated files under ignored build/
|
||||||
|
# output by compiling a byte-for-byte copy from a generated cpython-shaped
|
||||||
|
# tree where that documented relative include resolves.
|
||||||
|
if [ ! -s "$GETPATH_FROZEN_HEADER" ]; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: missing generated getpath header: $GETPATH_FROZEN_HEADER" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
local generated_source="$GENERATED_CPYTHON_ROOT/Modules/getpath.c"
|
||||||
|
mkdir -p "$(dirname "$generated_source")"
|
||||||
|
cp "$source_abs" "$generated_source"
|
||||||
|
printf '%s' "$generated_source"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_probe_pythoncore_frontier() {
|
||||||
|
local list_only=0 limit=0 arg
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
arg="$1"
|
||||||
|
case "$arg" in
|
||||||
|
--list-only)
|
||||||
|
list_only=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--limit)
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: --limit requires a number" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
limit="$2"
|
||||||
|
case "$limit" in
|
||||||
|
''|*[!0-9]*) echo "vc6-probe-pythoncore-frontier: invalid --limit: $limit" >&2; return 2 ;;
|
||||||
|
esac
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "vc6-probe-pythoncore-frontier: unknown argument: $arg" >&2
|
||||||
|
usage >&2
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
emit_source_list > "$SOURCE_LIST_TSV"
|
||||||
|
|
||||||
|
if [ "$list_only" -eq 1 ]; then
|
||||||
|
cat "$SOURCE_LIST_TSV"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
|
||||||
|
local CL="$MSVC600_ROOT/VC98/Bin/CL.EXE"
|
||||||
|
local VCVARS="$MSVC600_ROOT/VC98/Bin/VCVARS32.BAT"
|
||||||
|
|
||||||
|
generate_getpath_frozen_header || return $?
|
||||||
|
|
||||||
|
for required in "$PROJECT_ABS" "$CL" "$VCVARS" "$MSVC600_ROOT/VC98/Include" \
|
||||||
|
"$MSVC600_ROOT/Common/MSDev98/Bin"; do
|
||||||
|
if [ ! -e "$required" ]; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: missing prerequisite: $required" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! command -v wine >/dev/null 2>&1; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: wine is not installed" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
export WINEPREFIX="${WINEPREFIX:-$HOME/.wine-win9xport}"
|
||||||
|
export WINEDEBUG="${WINEDEBUG:--all}"
|
||||||
|
|
||||||
|
# CL.EXE loads C1/C2 from VC98/Bin and MSPDB60.DLL from Common/MSDev98/Bin.
|
||||||
|
export WINEPATH="$(winpath "$MSVC600_ROOT/VC98/Bin");$(winpath "$MSVC600_ROOT/Common/MSDev98/Bin")"
|
||||||
|
|
||||||
|
local INCLUDE_ARGS=(
|
||||||
|
"$(winpath "$REPO_ROOT/compat/msvc600")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/Python")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/Include/internal")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/Include")"
|
||||||
|
"$(winpath "$REPO_ROOT/cpython/PC")"
|
||||||
|
"$(winpath "$MSVC600_ROOT/VC98/Include")"
|
||||||
|
)
|
||||||
|
|
||||||
|
local COMMON_DEFINES=(
|
||||||
|
"_USRDLL"
|
||||||
|
"Py_BUILD_CORE"
|
||||||
|
"Py_BUILD_CORE_BUILTIN"
|
||||||
|
"Py_ENABLE_SHARED"
|
||||||
|
'MS_DLL_ID="3.11"'
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "== MSVC600 pythoncore compile-frontier probe =="
|
||||||
|
echo "project: $PROJECT_REL"
|
||||||
|
echo "list : ${SOURCE_LIST_TSV#$REPO_ROOT/}"
|
||||||
|
echo "prefix : $WINEPREFIX"
|
||||||
|
echo
|
||||||
|
|
||||||
|
local action source_rel raw_include defs reason
|
||||||
|
local total=0 skipped=0 compiled=0 cached=0 considered=0
|
||||||
|
while IFS=$'\t' read -r action source_rel raw_include defs reason; do
|
||||||
|
total=$((total + 1))
|
||||||
|
if [ "$action" != "compile" ]; then
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
echo "skip: $source_rel ($reason; raw=$raw_include)"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ "$limit" -ne 0 ] && [ "$considered" -ge "$limit" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
considered=$((considered + 1))
|
||||||
|
|
||||||
|
local source_abs="$REPO_ROOT/$source_rel"
|
||||||
|
if [ ! -f "$source_abs" ]; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: missing source from project list: $source_rel" >&2
|
||||||
|
echo "== frontier summary: total=$total compiled=$compiled cached=$cached skipped=$skipped =="
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local obj_abs="$BUILD_DIR/$(obj_name_for_source "$source_rel")"
|
||||||
|
local compile_source_abs
|
||||||
|
compile_source_abs="$(source_for_compile "$source_rel" "$source_abs")" || return $?
|
||||||
|
if [ "${VC6_FRONTIER_FORCE:-0}" != "1" ] && [ -f "$obj_abs" ] && \
|
||||||
|
[ "$obj_abs" -nt "$source_abs" ] && [ "$obj_abs" -nt "$PROJECT_ABS" ] && \
|
||||||
|
[ "$obj_abs" -nt "$FRONTIER_SCRIPT" ] && [ "$obj_abs" -nt "$GETPATH_FROZEN_HEADER" ]; then
|
||||||
|
cached=$((cached + 1))
|
||||||
|
echo "cached: $source_rel -> ${obj_abs#$REPO_ROOT/}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "compile: $source_rel -> ${obj_abs#$REPO_ROOT/}"
|
||||||
|
local rsp_abs="${obj_abs%.obj}.rsp"
|
||||||
|
local include_arg define
|
||||||
|
{
|
||||||
|
printf '/nologo\r\n'
|
||||||
|
for define in "${COMMON_DEFINES[@]}"; do
|
||||||
|
printf '/D %s\r\n' "$(quote_define_for_cmd "$define")"
|
||||||
|
done
|
||||||
|
if [ -n "$defs" ]; then
|
||||||
|
for define in $defs; do
|
||||||
|
if [ "${define#UNSUPPORTED_MSBUILD_DEFINE=}" != "$define" ]; then
|
||||||
|
echo "vc6-probe-pythoncore-frontier: unsupported per-file define in $source_rel: ${define#UNSUPPORTED_MSBUILD_DEFINE=}" >&2
|
||||||
|
echo "== frontier summary: total=$total compiled=$compiled cached=$cached skipped=$skipped =="
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
printf '/D %s\r\n' "$(quote_define_for_cmd "$define")"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
for include_arg in "${INCLUDE_ARGS[@]}"; do
|
||||||
|
printf '/I %s\r\n' "$include_arg"
|
||||||
|
done
|
||||||
|
printf '/c\r\n'
|
||||||
|
printf '%s\r\n' "$(winpath "$compile_source_abs")"
|
||||||
|
printf '/Fo%s\r\n' "$(winpath "$obj_abs")"
|
||||||
|
} > "$rsp_abs"
|
||||||
|
local cmd="call $(winpath "$VCVARS") && cd /d $(winpath "$REPO_ROOT/cpython") && cl @$(winpath "$rsp_abs")"
|
||||||
|
|
||||||
|
wine cmd /c "$cmd" 2>&1 |
|
||||||
|
grep -v '^[0-9a-f]\{4\}:err:' |
|
||||||
|
strip_prefix "$(winpath "$REPO_ROOT")\\"
|
||||||
|
local status="${PIPESTATUS[0]}"
|
||||||
|
if [ "$status" -ne 0 ]; then
|
||||||
|
echo
|
||||||
|
echo "== cl.exe exit status: $status =="
|
||||||
|
echo "vc6-probe-pythoncore-frontier: first compile blocker: $source_rel" >&2
|
||||||
|
echo "== frontier summary: total=$total compiled=$compiled cached=$cached skipped=$skipped =="
|
||||||
|
return "$status"
|
||||||
|
fi
|
||||||
|
compiled=$((compiled + 1))
|
||||||
|
done < "$SOURCE_LIST_TSV"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "== frontier summary: total=$total compiled=$compiled cached=$cached skipped=$skipped =="
|
||||||
|
echo "vc6-probe-pythoncore-frontier: supported pythoncore compile frontier completed"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
||||||
|
run_probe_pythoncore_frontier "$@"
|
||||||
|
exit "$?"
|
||||||
|
fi
|
||||||
+147
@@ -0,0 +1,147 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Regression tests for scripts/vc6-probe-pythoncore-frontier.sh.
|
||||||
|
#
|
||||||
|
# The no-toolchain checks exercise the source-list parser/normalizer and the
|
||||||
|
# per-file define handling that make the frontier source-list-driven. When
|
||||||
|
# Wine + MSVC600 are available, a bounded live run verifies that the harness
|
||||||
|
# reports cl.exe's real first-blocker status.
|
||||||
|
#
|
||||||
|
# Usage: scripts/vc6-probe-pythoncore-frontier.test.sh
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
PROBE="$REPO_ROOT/scripts/vc6-probe-pythoncore-frontier.sh"
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
pass() { echo "ok - $1"; }
|
||||||
|
bad() { echo "not ok - $1"; fail=1; }
|
||||||
|
|
||||||
|
out="$($PROBE --list-only 2>&1)"
|
||||||
|
status=$?
|
||||||
|
|
||||||
|
if [ "$status" -eq 0 ]; then
|
||||||
|
pass "frontier --list-only exits 0"
|
||||||
|
else
|
||||||
|
bad "frontier --list-only exits 0 (got exit $status)"
|
||||||
|
echo "$out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
count="$(printf '%s\n' "$out" | awk 'NF { n++ } END { print n+0 }')"
|
||||||
|
if [ "$count" -eq 198 ]; then
|
||||||
|
pass "frontier parses all 198 pythoncore.vcxproj ClCompile entries"
|
||||||
|
else
|
||||||
|
bad "frontier parses all 198 pythoncore.vcxproj ClCompile entries (got $count)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
first_fields="$(printf '%s\n' "$out" | awk -F '\t' 'NR == 1 { print $1 "|" $2 "|" $3 }')"
|
||||||
|
if [ "$first_fields" = 'compile|cpython/Modules/getpath.c|..\Modules\getpath.c' ]; then
|
||||||
|
pass "frontier normalizes the first Windows-style source path to cpython/Modules/getpath.c"
|
||||||
|
else
|
||||||
|
bad "frontier normalizes the first Windows-style source path to cpython/Modules/getpath.c (got: $first_fields)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
getpath_defs="$(printf '%s\n' "$out" | awk -F '\t' '$2 == "cpython/Modules/getpath.c" { print $4; exit }')"
|
||||||
|
case "$getpath_defs" in
|
||||||
|
*'PREFIX=NULL'*'EXEC_PREFIX=NULL'*'VERSION=NULL'*'VPATH="..\\.."'*'PYDEBUGEXT=""'*'PLATLIBDIR="DLLs"'*)
|
||||||
|
pass "frontier preserves getpath.c per-file defines with project-local substitutions"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
bad "frontier preserves getpath.c per-file defines with project-local substitutions (got: $getpath_defs)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
sysmodule_defs="$(printf '%s\n' "$out" | awk -F '\t' '$2 == "cpython/Python/sysmodule.c" { print $4; exit }')"
|
||||||
|
case "$sysmodule_defs" in
|
||||||
|
*'VPATH="..\\.."'*)
|
||||||
|
pass "frontier preserves sysmodule.c VPATH per-file define"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
bad "frontier preserves sysmodule.c VPATH per-file define (got: $sysmodule_defs)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Source the probe after --list-only so the guarded helper definitions can be
|
||||||
|
# tested without launching Wine or requiring MSVC600.
|
||||||
|
# shellcheck source=scripts/vc6-probe-pythoncore-frontier.sh
|
||||||
|
source "$PROBE"
|
||||||
|
rendered_cmd="$(render_compile_command_for_test 'VPATH="..\\.."' 'PYDEBUGEXT=""' 'PLATLIBDIR="DLLs"')"
|
||||||
|
case "$rendered_cmd" in
|
||||||
|
*' /D VPATH=\"..\\\\..\"'*' /D PYDEBUGEXT=\"\"'*' /D PLATLIBDIR=\"DLLs\"'*)
|
||||||
|
pass "frontier renders quoted per-file string defines safely for CL response files"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
bad "frontier renders quoted per-file string defines safely for CL response files (got: $rendered_cmd)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if printf '%s\n' "$out" | grep -q $'^skip-generated deepfreeze source\tcpython/Python/deepfreeze/deepfreeze.c\t'; then
|
||||||
|
pass "frontier reports the generated deepfreeze source instead of compiling it blindly"
|
||||||
|
else
|
||||||
|
bad "frontier reports the generated deepfreeze source instead of compiling it blindly"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s\n' "$out" | grep -q $'^skip-external IncludeExternals-conditioned source\tcpython/Modules/zlibmodule.c\t'; then
|
||||||
|
pass "frontier reports IncludeExternals-conditioned in-tree zlibmodule.c as external"
|
||||||
|
else
|
||||||
|
bad "frontier reports IncludeExternals-conditioned in-tree zlibmodule.c as external"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s\n' "$out" | grep -q $'^skip-external IncludeExternals-conditioned source\t$(zlibDir)/adler32.c\t'; then
|
||||||
|
pass "frontier reports macro-based zlibDir sources as external without normalizing outside the repo"
|
||||||
|
else
|
||||||
|
bad "frontier reports macro-based zlibDir sources as external without normalizing outside the repo"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s\n' "$out" | cut -f2 | grep -q '\\'; then
|
||||||
|
bad "frontier normalized source column contains no backslashes"
|
||||||
|
else
|
||||||
|
pass "frontier normalized source column contains no backslashes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
|
||||||
|
if command -v wine >/dev/null 2>&1 && [ -e "$MSVC600_ROOT/VC98/Bin/CL.EXE" ]; then
|
||||||
|
live_out="$($PROBE --limit 1 2>&1)"
|
||||||
|
live_status=$?
|
||||||
|
|
||||||
|
if [ "$live_status" -ne 0 ]; then
|
||||||
|
pass "frontier live run reports a nonzero first-blocker status for the current first source"
|
||||||
|
else
|
||||||
|
pass "frontier live run compiles the first supported source (exit 0)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s\n' "$live_out" | grep -q '^compile: cpython/Modules/getpath.c'; then
|
||||||
|
pass "frontier live run starts from pythoncore.vcxproj's first supported source"
|
||||||
|
else
|
||||||
|
bad "frontier live run starts from pythoncore.vcxproj's first supported source"
|
||||||
|
echo "$live_out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$live_status" -ne 0 ] && printf '%s\n' "$live_out" | grep -q 'first compile blocker: cpython/Modules/getpath.c'; then
|
||||||
|
pass "frontier live run names the first actionable blocker"
|
||||||
|
elif [ "$live_status" -eq 0 ]; then
|
||||||
|
pass "frontier live run had no blocker in the first supported source"
|
||||||
|
else
|
||||||
|
bad "frontier live run names the first actionable blocker"
|
||||||
|
echo "$live_out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s\n' "$live_out" | grep -q "frozen_modules[/\\\\]getpath.h.*No such file or directory"; then
|
||||||
|
bad "frontier live run should provision Python/frozen_modules/getpath.h before compiling getpath.c"
|
||||||
|
echo "$live_out"
|
||||||
|
elif [ -s "$REPO_ROOT/build/generated/cpython/Python/frozen_modules/getpath.h" ]; then
|
||||||
|
pass "frontier live run provisions the generated getpath.h include under build/"
|
||||||
|
else
|
||||||
|
bad "frontier live run provisions the generated getpath.h include under build/"
|
||||||
|
echo "$live_out"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "skip - wine/MSVC600 not available; skipping live frontier integration check"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$fail" -ne 0 ]; then
|
||||||
|
echo "FAILED"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "ALL TESTS PASSED"
|
||||||
Executable
+61
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Regression tests for the narrow VC6 compat/msvc600/stdint.h shim.
|
||||||
|
#
|
||||||
|
# Skipped (not failed) when Wine + MSVC600 are unavailable, matching the other
|
||||||
|
# VC6 probe test scripts. The live check is compile-only: it verifies that the
|
||||||
|
# fixture using representative uint8_t/uint32_t/uint64_t load/store/rotate
|
||||||
|
# patterns (the exact subset cpython/Modules/_blake2/impl/blake2-impl.h uses)
|
||||||
|
# reaches cl.exe exit 0, and that <stdint.h> and <inttypes.h> can both be
|
||||||
|
# included in the same translation unit without a duplicate-typedef error.
|
||||||
|
#
|
||||||
|
# Usage: scripts/vc6-probe-stdint.test.sh
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
PROBE="$REPO_ROOT/scripts/vc6-probe-core.sh"
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
pass() { echo "ok - $1"; }
|
||||||
|
bad() { echo "not ok - $1"; fail=1; }
|
||||||
|
|
||||||
|
if grep -q 'include "inttypes.h"' "$REPO_ROOT/compat/msvc600/stdint.h" && \
|
||||||
|
grep -q 'defined(_MSC_VER).*1200\|_MSC_VER >= 1300' "$REPO_ROOT/compat/msvc600/stdint.h"; then
|
||||||
|
pass "compat/msvc600/stdint.h is a VC6-scoped forward to inttypes.h"
|
||||||
|
else
|
||||||
|
bad "compat/msvc600/stdint.h is a VC6-scoped forward to inttypes.h"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
|
||||||
|
if command -v wine >/dev/null 2>&1 && [ -e "$MSVC600_ROOT/VC98/Bin/CL.EXE" ]; then
|
||||||
|
out="$($PROBE scripts/fixtures/vc6_stdint_smoke.c 2>&1)"
|
||||||
|
status=$?
|
||||||
|
|
||||||
|
if [ "$status" -eq 0 ]; then
|
||||||
|
pass "stdint smoke fixture compiles under VC6 (exit 0)"
|
||||||
|
else
|
||||||
|
bad "stdint smoke fixture compiles under VC6 (exit $status)"
|
||||||
|
echo "$out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s' "$out" | grep -q "Cannot open include file: 'stdint.h'"; then
|
||||||
|
bad "stdint smoke fixture does not regress to missing stdint.h"
|
||||||
|
else
|
||||||
|
pass "stdint smoke fixture does not regress to missing stdint.h"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if printf '%s' "$out" | grep -qi 'error'; then
|
||||||
|
bad "stdint smoke fixture: no compiler errors in output"
|
||||||
|
else
|
||||||
|
pass "stdint smoke fixture: no compiler errors in output"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "skip - wine/MSVC600 not available; skipping live stdint integration check"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$fail" -ne 0 ]; then
|
||||||
|
echo "FAILED"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "ALL TESTS PASSED"
|
||||||
Reference in New Issue
Block a user