From 7a99fa1b87f6ad91e3cf13cf3661e19ca69ffc07 Mon Sep 17 00:00:00 2001 From: "arda.aydin@ontrol.com.tr" Date: Thu, 13 Aug 2026 10:59:14 +0300 Subject: [PATCH] Track testprogram/ again, add claudeCodeChatLog.md The test pair verify.py runs against is back in the repo, so a fresh clone can run the built-in checks. Conversion output (*-sab2sax-*) stays ignored, so converting inside testprogram/ still leaves the tree clean. claudeCodeChatLog.md records how this got built: what was asked for, the decisions worth remembering (plain paths in system.properties, the port source, Java float formatting, the f4-rounded manifest default, why a sab cannot return runtime props) and what is still untested. Co-Authored-By: Claude Opus 5 --- .gitignore | 1 - README.md | 11 +- claudeCodeChatLog.md | 86 ++ testprogram/test_normal.sax | 1266 +++++++++++++++++++++++++++ testprogram/test_normal_sedonac.sab | Bin 0 -> 7852 bytes 5 files changed, 1359 insertions(+), 5 deletions(-) create mode 100644 claudeCodeChatLog.md create mode 100644 testprogram/test_normal.sax create mode 100644 testprogram/test_normal_sedonac.sab diff --git a/.gitignore b/.gitignore index 2673c48..5724b71 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ __pycache__/ *.pyc -testprogram/ *-sab2sax-*.sab *-sab2sax-*.sax diff --git a/README.md b/README.md index 56157b8..92a1e18 100644 --- a/README.md +++ b/README.md @@ -117,9 +117,8 @@ lossy on purpose — runtime prop values and formatting are not in the binary. I sedonac itself wrote, they do match.) With no file argument a chooser opens, listing `.sax` and `.sab`. Cancel it and the built-in -regression runs instead, against a `test_normal.sax` / `test_normal_sedonac.sab` pair in -`testprogram/`. That folder is **not** in the repo (gitignored) — drop the pair in yourself, -otherwise verify prints `SKIP` and exits 0: +regression runs instead, against the `test_normal.sax` / `test_normal_sedonac.sab` pair checked in +under `testprogram/`. Remove them and verify prints `SKIP` and exits 0 instead of failing: test_normal.sax -> sab vs test_normal_sedonac.sab test_normal_sedonac.sab -> sax vs test_normal.sax @@ -142,7 +141,11 @@ Exit code is 0 on pass, 1 on failure. A malformed file fails with a one-line rea config.py system.properties read/write, folder + file choosers verify.py regression check against sedonac's output, both directions system.properties sedona.home - testprogram/ local only, gitignored: test apps to run verify.py against + testprogram/ test apps verify.py runs against + claudeCodeChatLog.md how this got built, and why + +Conversion output (`*-sab2sax-*.sax`, `*-sab2sax-*.sab`) is gitignored, so converting inside +`testprogram/` leaves the repo clean. ## Format diff --git a/claudeCodeChatLog.md b/claudeCodeChatLog.md new file mode 100644 index 0000000..c73e066 --- /dev/null +++ b/claudeCodeChatLog.md @@ -0,0 +1,86 @@ +# Claude Code session log + +What was asked for, what was built, and the decisions behind it. Written 2026-08-13, covering the +work that produced `ec4019e` .. `2dcc170` (tags `v0.0.0.001`, `v0.0.0.002`). + +Starting point: `sab.py`, a pure-Python `.sax` -> `.sab` encoder taking ` +` on the command line, plus `verify.py`. + +## What was asked, in order + +1. **Sedona home into `system.properties`**, with a folder chooser on first run, and a file chooser + for the input. +2. **Plain paths, not java-escaped**, in that properties file. +3. **Timestamped output names** — `[name]-sab2sax-20260728-140609`. +4. **The reverse direction**, `.sab` -> `.sax`, direction chosen by the input's extension. +5. **A version**, shown in dialog titles. +6. **`testprogram/` out of the repo** — later reversed: the test pair is checked in again, while + conversion output (`*-sab2sax-*`) stays gitignored. +7. **A file chooser in `verify.py`** and a round-trip check on whatever is chosen. +8. **A window** with a button per direction, showing the chosen file before converting and the + output afterwards. +9. **`run.py`** as the entry point; log labels in capitals, values on their own lines. + +## What exists now + + run.py entry point: window with no arguments, CLI with them + gui.py the window: a button per direction + sab2sax.py the CLI: dispatches on the input extension + sab.py sax -> sab encoder + sax.py sab -> sax decoder + config.py system.properties, dialogs, NAME/VERSION + verify.py round trips + comparison against sedonac output + system.properties sedona.home + testprogram/ test apps verify.py runs against + +`sedona.home` lives in `system.properties`. Missing or pointing somewhere without `manifests/` and a +folder chooser opens, then the answer is written back. Output files are always written next to the +input as `-sab2sax-.`, so a run never overwrites the previous one. + +## Decisions worth remembering + +**Plain paths in `system.properties`.** Java's `Properties` (what sedonac reads it with) treats `\` +as an escape and doubles them up; we only read the file ourselves, so we write plain Windows paths. +The parser collapses `\\` to `\` and keeps every other backslash literal — both forms load, and +`C:\niagara` never becomes a newline. + +**The decoder is a port, not a guess.** `sax.py` follows `OfflineApp.decodeAppBinary` + +`encodeAppXml` and `OfflineComponent`/`OfflineLink` from +`sedonaSrcOrginal/sedona/src/sedona/offline/`. The tree is rebuilt from the +`firstChild`/`nextSibling` id chain; the XML is written the way `XWriter` does it — two-space +indent, a `` comment above every ``, `&#x..;` escaping. + +**Java float formatting.** `Value.encodeString` for a float is `java.lang.Float.toString`: shortest +digits that round-trip, always a decimal point, `E` form outside `[1e-3, 1e7)`. `sax.java_float` +reproduces it. It matches modern Java rather than the old JDK's extra-digit quirk on subnormals +(`1.4E-45` vs our `1.0E-45`) — only reachable with denormal floats. + +**The manifest default is a 32-bit float too.** A prop equal to its default is not written to the +`.sax`. Comparing a decoded `float` against a default parsed as a Python double makes `0.1` look +different from `0.1`, and every `minDelta="0.1"` gets written where sedonac omits it. Rounding the +default to `f4` first was the last diff between "close" and "identical". + +**A `.sab` cannot give back runtime props.** Only config props are in the binary. sedonac has the +same hole. That is why a `.sax` round trip compares the two *binaries*, not the two texts. + +## Verification + +- `test_normal.sax` -> sab, byte-identical to `test_normal_sedonac.sab` (7852 bytes) +- `test_normal_sedonac.sab` -> sax, byte-identical to `test_normal.sax` (61294 bytes) +- both round trips clean: `sab -> sax -> sab`, and `sax -> sab -> sax -> sab` + +A live `sedonac.exe` comparison was attempted and could not run here — it fails with `Cannot load +library: C:\Program Files\Zulu\zulu-21-jre\bin\server\jvm.dll`. `verify.check_encode(sax)` / +`check_decode(sab)` with no reference argument still do that comparison on a machine with a JRE +sedonac will start under. + +Malformed input fails with one line and exit 1, not a traceback: `comp 0 app: missing child 254`. + +## Where to pick up + +- Untested paths are unchanged from before: action overrides, `Buf`-typed props, non-ASCII strings, + and apps whose ids exceed the 256-entry lookup table. +- `verify.py` prints `SKIP` and exits 0 when `testprogram/` is empty rather than failing; the test + pair is checked in, so it normally runs. +- Version lives in `config.py` (`NAME`, `VERSION`). The window title, every dialog title and the CLI + banner all read from it. diff --git a/testprogram/test_normal.sax b/testprogram/test_normal.sax new file mode 100644 index 0000000..c25127c --- /dev/null +++ b/testprogram/test_normal.sax @@ -0,0 +1,1266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testprogram/test_normal_sedonac.sab b/testprogram/test_normal_sedonac.sab new file mode 100644 index 0000000000000000000000000000000000000000..8f5a9492baf692cdca09021919d9967991b10aea GIT binary patch literal 7852 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 literal 0 HcmV?d00001