fix: compare a citation without the spacing its author chose

A recale rewrites the located tokens and leaves the sentence alone, so a
prose run keeps `a.c:228, 1439-1443` while the rendered form drops the
space. Comparing the two literally made a run that had just been written
look unwritten, pending_recale counted it, and bump_commit refused for
ever.

mariani was held back by three of them: it recaled twenty-five refs and
could never advance its pin, which is the desync the all-or-nothing rule
forbids. 67 refs, all anchored.
This commit is contained in:
Abdessamad Derraz committed 2026-09-05 10:41:58 +02:00
1 parent 02edf40d8f
commit bc7f131b6f
3 files changed
+64 -25

No files matched your search

+22 -22
View File
@@ -4,7 +4,7 @@ core_classification: community_fork
source: "https://github.com/sh95014/AppleWin"
upstream: "https://github.com/AppleWin/AppleWin"
profiled_date: "2026-08-12"
source_commit: "492b017709fd67d3aff6b1d88d9971254e7214fa"
source_commit: "51893cab7e8a3d1298734848f4fd616f2e1831fb"
upstream_commit: "75bd90d16a2e4eb16026bf615685ee2a02dfc0d6"
core_version: "1.7"
display_name: "Apple - Apple II (Mariani)"
@@ -23,41 +23,41 @@ notes: |
linked into the binary. MarianiFrame::GetResourceData maps each AppleWin
resource id to a file name, NSBundle resolves it against Contents/Resources,
and the file is read with open() then kept in a map for later requests
(MarianiFrame.cpp:156-232, AppDelegate.mm:1465-1469). LinuxFrame::GetResource
(source/frontends/mariani/MarianiFrame.cpp:156-232, source/frontends/mariani/AppDelegate.mm:1465-1469). LinuxFrame::GetResource
throws when the file it gets back does not have the size the call site asked
for (linuxframe.cpp:133-145), so each entry below carries the size the code
for (source/linux/linuxframe.cpp:133-145), so each entry below carries the size the code
demands. A name that resolves to nothing raises a "Resource not found" alert
and returns a null pointer.
Machine types offered in preferences: Apple II, II Plus, II J-Plus, //e,
enhanced //e, Pravets 82, Pravets 8M, Pravets 8A, TK3000 //e and Base64A
(PreferencesViewController.mm:191-193, 741-751). MemInitializeROM picks the
system ROM from that setting (Memory.cpp:2052-2069). Default slots are the
(source/frontends/mariani/preferences/PreferencesViewController.mm:191-193, 741-751). MemInitializeROM picks the
system ROM from that setting (source/Memory.cpp:2052-2069). Default slots are the
printer card in 1, Super Serial Card in 2, Mockingboard in 4 and Disk II in 6
(CardManager.cpp:325-334); the hard disk and mouse cards are chosen by the
(source/CardManager.cpp:325-334); the hard disk and mouse cards are chosen by the
user.
Two names in the resource map have no file in the bundle: the Resources build
phase lists 49 items and neither appears (Mariani.xcodeproj/project.pbxproj).
Hddrvr-v2.bin is requested when a save state written with hard disk card
version 4 is loaded (Harddisk.cpp:228, 1439-1443), and
version 4 is loaded (source/Harddisk.cpp:228, 1439-1443), and
Freezes_Non-autostart_F8_Rom.rom when the configuration value "The Freeze's
F8 Rom" is set on an Apple II (Memory.cpp:2163-2168, Utilities.cpp:188-189,
Common.h:94). Contents/Resources is the only directory searched, so that is
F8 Rom" is set on an Apple II (source/Memory.cpp:2163-2168, source/Utilities.cpp:188-189,
source/Common.h:94). Contents/Resources is the only directory searched, so that is
where the two belong.
The debugger comes up with the emulator, not with its window
(context.cpp:116). CmdDebugStartup preloads four symbol tables
(Debug.cpp:9492-9520), each read first from
(source/linux/context.cpp:116). CmdDebugStartup preloads four symbol tables
(source/Debugger/Debug.cpp:9488-9516), each read first from
~/Library/Application Support/<bundle id>/ and then from the bundle
(Debugger_Symbols.cpp:774, 814-817, MarianiFrame.cpp:36-37,
AppDelegate.mm:1471-1491).
(source/Debugger/Debugger_Symbols.cpp:774, 814-817, source/frontends/mariani/MarianiFrame.cpp:36-37,
source/frontends/mariani/AppDelegate.mm:1471-1491).
--rom and --f8rom install a 12k/16k and a 2k image from any path over the ROM
already loaded (argparser.cpp:197-198, programoptions.cpp:81-101,
Memory.cpp:2120-2213). AppleWin's -videorom and its hard disk firmware
already loaded (source/frontends/common2/argparser.cpp:205-206, source/frontends/common2/programoptions.cpp:82-102,
source/Memory.cpp:2120-2213). AppleWin's -videorom and its hard disk firmware
switches are unreachable here: ParseCmdLine has no caller in this tree, and
UseHdcFirmwareV1/V2 are called only from Windows/AppleWin.cpp:783-785, which
UseHdcFirmwareV1/V2 are called only from source/Windows/AppleWin.cpp:783-785, which
the Xcode project does not compile.
files:
@@ -447,7 +447,7 @@ files:
size: 13444
md5: 034527d42a96d0f39977cb85c6a8f2d8
sha1: fcfbbb25e06f58d13e762b02bfd468c834d98fc8
source_ref: "source/Debugger/Debugger_Symbols.cpp:46, 774, 814-817, source/Debugger/Debug.cpp:9499-9500"
source_ref: "source/Debugger/Debugger_Symbols.cpp:46, 774, 814-817, source/Debugger/Debug.cpp:9495-9496"
note: >
Preloaded into the Main table when the emulator starts. Read from the
support directory first, then from the bundle. Parsed as lines of address
@@ -460,7 +460,7 @@ files:
size: 15378
md5: 7253a9ba7d7ca807016f5adc0207dd7b
sha1: 496a0bd1af463fce81b362da9e4757a993e355d5
source_ref: "source/Debugger/Debugger_Symbols.cpp:47, 774, 814-817, source/Debugger/Debug.cpp:9502-9503"
source_ref: "source/Debugger/Debugger_Symbols.cpp:47, 774, 814-817, source/Debugger/Debug.cpp:9498-9499"
note: "Preloaded into the Basic table when the emulator starts."
- name: A2_DOS33.SYM2
@@ -469,7 +469,7 @@ files:
size: 2380
md5: 88bd69906b4b3109b3f31472fb4b47f4
sha1: 51cc84e2cbd9bd61d50a0931cdae0a2ef0a57d6c
source_ref: "source/Debugger/Debugger_Symbols.cpp:53, 774-806, source/Debugger/Debug.cpp:9506-9507"
source_ref: "source/Debugger/Debugger_Symbols.cpp:53, 774-806, source/Debugger/Debug.cpp:9502-9503"
note: >
Preloaded into the DOS33 table when the emulator starts. The .SYM2
extension routes it through the debugger script reader instead of the
@@ -546,7 +546,7 @@ analysis:
debugger_scripts:
- filename: DebuggerAutoRun.txt
source_ref: "source/Debugger/Debug.cpp:365, source/Debugger/Debug.cpp:9440-9473"
source_ref: "source/Debugger/Debug.cpp:365, source/Debugger/Debug.cpp:9436-9469"
note: >
Run once at the first DebugInitialize, from the current directory and
then from the support directory. Holds debugger commands written by the
@@ -556,10 +556,10 @@ analysis:
options:
- option: "--rom"
accepts: "12 KB image at $D000 or 16 KB image at $C000, any path"
source_ref: "source/frontends/common2/argparser.cpp:197, source/frontends/common2/programoptions.cpp:81-91, source/Memory.cpp:2173-2213"
source_ref: "source/frontends/common2/argparser.cpp:205, source/frontends/common2/programoptions.cpp:82-92, source/Memory.cpp:2173-2213"
- option: "--f8rom"
accepts: "2 KB image at $F800, any path"
source_ref: "source/frontends/common2/argparser.cpp:198, source/frontends/common2/programoptions.cpp:92-101, source/Memory.cpp:2139-2161"
source_ref: "source/frontends/common2/argparser.cpp:206, source/frontends/common2/programoptions.cpp:93-102, source/Memory.cpp:2139-2161"
note: >
Both are installed over the ROM already loaded from the bundle and neither
has a fixed name. AppleWin's -videorom has no equivalent: ParseCmdLine is
+14 -3
View File
@@ -2224,6 +2224,17 @@ def rebase_refs(
return applied
def _citation_key(ref: str) -> str:
"""A citation compared without the spacing the author chose.
A recale rewrites the located tokens and leaves the sentence alone, so
`a.c:228, 1439-1443` keeps its space while the rendered form drops it.
They are the same citation, and comparing them literally makes a run
that was written look unwritten, which holds the pin back for ever.
"""
return re.sub(r"\s+", "", ref)
def pending_recale(
report: ProfileReport, accept_changed: bool = False, text: str | None = None
) -> int:
@@ -2259,7 +2270,7 @@ def pending_recale(
pool: dict[tuple[str, str], int] = {}
for citation in collect_citations(document):
if citation.kind == "prose":
slot = (citation.field, citation.ref)
slot = (citation.field, _citation_key(citation.ref))
pool[slot] = pool.get(slot, 0) + 1
for entry in report.entries or []:
if entry.kind != "prose":
@@ -2280,9 +2291,9 @@ def pending_recale(
pending += 1
continue
rendered = _run_after_moves([p.part for p in entry.parts], moves)
if rendered == entry.source_ref:
if _citation_key(rendered) == _citation_key(entry.source_ref):
continue
slot = (entry.field, rendered)
slot = (entry.field, _citation_key(rendered))
if pool.get(slot, 0) > 0:
pool[slot] -= 1
continue
+28
View File
@@ -2160,6 +2160,34 @@ class TestWriteDryRun(unittest.TestCase):
self.assertEqual(self.path.read_text(), before)
class TestProseSpacingIsNotADifference(unittest.TestCase):
"""A recale keeps the author's spacing; the check has to allow for it.
_run_after_moves renders `a.c:228,1439-1443` while the writer leaves the
sentence as written, `a.c:228, 1439-1443`. Comparing the two literally
made the run look unwritten, so bump_commit refused for ever: mariani
was held back by three of them.
"""
def test_a_written_run_counts_as_written_whatever_the_spacing(self):
self.assertEqual(
profile_sync._citation_key("src/Harddisk.cpp:228, 1439-1443"),
profile_sync._citation_key("src/Harddisk.cpp:228,1439-1443"),
)
def test_different_citations_still_differ(self):
self.assertNotEqual(
profile_sync._citation_key("a.c:1, 2"),
profile_sync._citation_key("a.c:1, 3"),
)
def test_a_path_change_still_differs(self):
self.assertNotEqual(
profile_sync._citation_key("a.c:1"),
profile_sync._citation_key("src/a.c:1"),
)
class TestLargeFileCeiling(unittest.TestCase):
"""The fallback mapping bails above a ceiling, and it sits high enough.