- git_sync.ps1 nou: conversie recursiva bin->text in arbore (staging temp, incremental, orfani, RoundtripExempt, DbfList cu date, anti-dialog cfg) - vfp_filemap.ps1: mapari .pjx->.pj2 si .dbf->.db2 - txt2vcx.ps1: CacheRoot implicit = ProjectRoot (text in-arbore) + cfg anti-dialog in staging - test_roundtrip.ps1: parametrizat per proiect, restaurare din backup temp (nu git checkout) - test_git_sync.ps1 nou: incremental, orfani, esec partial, protectie binar, scutire roundtrip - CLAUDE.md: fluxul nou documentat Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
13 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
A local shared copy of FoxBin2Prg (the VFPX tool by Fernando D. Bozzo, maintained by Lutz Scheffler): a Visual FoxPro 9 program that converts VFP binary files to PRG-style text and back. Supported conversions: PJX↔PJ2, SCX↔SC2, VCX↔VC2, FRX↔FR2, LBX↔LB2, DBC↔DC2, DBF↔DB2, MNX↔MN2.
This directory is a git clone with two remotes:
origin=https://github.com/fdbozzo/foxbin2prg.git(upstream, read-only).mastertracksorigin/masterand stays a pristine mirror.romfast=git@gitea.romfast.ro:romfast/foxbin2prg.git(our fork on Gitea, SSH). Working branchromfast(default on Gitea) = upstreammaster+ the ROA additions committed (vcx2txt.ps1,PROMPT_cautare_vfp.md,CLAUDE.md,git_svn_parallel_init_prompt.md). The pre-git local state is kept on branchlocal-snapshot-v1.21.04.
Update flow (sync fork from upstream): git fetch origin → git checkout master && git merge --ff-only origin/master → git checkout romfast && git merge master → git push romfast romfast master. After any update, regenerate binaries/EXE in VFP9 with DO ReCreate_FoxBin2Prg.prg (an error about TESTS\FXUResults.db2 is expected). Text caches live outside this folder (D:\ROA\_vfp_textcache\, see below) so ReCreate never touches them; compiled binaries are kept out of git via the upstream .gitignore plus .git/info/exclude (which also still ignores any stray local _textcache*).
It serves two purposes:
- Upstream tool source (for occasional patches to FoxBin2Prg itself).
- A shared search tool for the ROA VFP projects (
D:\ROA\ROAGEST,D:\ROA\ROAIMOB,D:\ROA\ROAACNPRO, …) via the local additions below.
Local additions (ROA-specific, not part of upstream)
git_sync.ps1— the in-tree flow (primary for migrated ROA projects): folder-mode recursive over the whole project tree (incl.COMUN\), generates the.??2text next to each binary (not in an external cache) so git tracks readable text instead of binaries. Incremental, converts in a temp staging area and copies back only the text (never touches the SVN working-copy binaries), cleans up orphan.??2, continues past per-file failures and exits nonzero on any. Params:-ProjectRoot,-DbfList(tables converted to.db2with data),-RoundtripExempt,-SubDir. Run at session start and before everygit commit; do not commit while it reports failures.vcx2txt.ps1— PowerShell script that converts the VFP binaries of a project (read from its.pjx) into text under a cache folder, so the code inside.vcx/.scx/.frx/.mnx/.dbcbinaries becomes greppable. Incremental (skips up-to-date files), does not need the VFP IDE open (uses the compiledFoxBin2Prg.EXE). Search-only / non-migrated projects; migrated projects usegit_sync.ps1instead.txt2vcx.ps1— the write-back counterpart: regenerates.vcx/.scxbinaries from edited.vc2/.sc2text and copies them back into the project (see "Golden rule" below for scope/limits).-CacheRootdefaults to-ProjectRoot(in-tree flow: cache→project mapping is identity); pass a separate root only for the old external-cache flow.vfp_filemap.ps1— shared bin↔memo↔text extension map (.vcx/.vct/.vc2,.scx/.sct/.sc2,.pjx/.pjt/.pj2,.dbf/.fpt/.db2, …), dot-sourced bygit_sync.ps1,vcx2txt.ps1andtxt2vcx.ps1so the mapping stays in one place. Also hostsInvoke-FoxBin2PrgSafe(timeout +taskkill).test_roundtrip.ps1— standalone fidelity/regression test for the bin→text→bin→text roundtrip and fortxt2vcx.ps1's guard rails (staleness, COMUN, missing binary, negative/corrupt input, multi-file runs); parametrized per project. See examples below.test_git_sync.ps1— standalone tests forgit_sync.ps1on temp fixtures: incremental (up-to-date files skipped), orphan cleanup, nonzero exit on partial failure, and binaries byte-identical after any run.- Text caches (external-cache flow, non-migrated / search-only projects) live outside this folder, under
D:\ROA\_vfp_textcache\(one subfolder per project:roacnpro,roagest,roaimob) — per-project regenerable text caches. Migrated projects (ROACONT, COMUN, …) keep their.??2in-tree viagit_sync.ps1instead of a cache here. Safe to delete; never version them. They must stay outsidefoxbin2prg:ReCreate_FoxBin2Prg.prgdoes a recursivePrg2Binover the whole tool folder (get_FilesFromDirectoryrecurses into every subfolder, foxbin2prg.prg:6135) and would reconvert any.??2under it back into stray binaries. PROMPT_cautare_vfp.md— reusable prompt (Romanian) explaining how to set up this search flow in any VFP project. Read it before working on VFP code search.
Golden rule: the text cache is for searching, and — for .vcx/.scx only — for making real code edits via txt2vcx.ps1. Caveats:
- The generated text format is position-sensitive: don't reformat or reflow lines when editing; preserve the exact line layout.
- Properties/methods are emitted alphabetically sorted — a newly added property must be inserted in alphabetical order, not appended.
- Only
.vcx/.scxsupport write-back..frx/.mnx/.lbx/.pjx/.dbc/.dbfare read-only text (edit in the VFP IDE): menus still need GENMENU to produce.mpr, and the other formats are too fragile for round-trip write-back.git_sync.ps1still generates their.??2for readable diffs, but never writes them back. - Six FFC/third-party classes under
COMUN\are ingit_sync.ps1's-RoundtripExemptlist (#INCLUDEmakes the isolated roundtrip a false-negative):accessibility.vcx,oinventar.vcx,_gdiplus.vcx,_reportlistener.vcx(inCOMUN\clase\),foxcharts.vcx(COMUN\utile\foxcharts\),_webview.vcx(COMUN\utile\web\). Their text is valid (bin→text runs) but roundtrip is not guaranteed — edit them only in the IDE. - Targets under
COMUN\require-AllowComunand explicit approval — a change there affects every ROA app. - After any VFP IDE session (even one that only opened a class/form), re-run
vcx2txt.ps1to refresh the cache before editing text — otherwisetxt2vcx.ps1's staleness check will (correctly) refuse to write back over unseen IDE changes. - Encoding:
.vc2/.sc2files declareCPID="1252"in their header, but for ROAGEST at least the Romanian-diacritics bytes are actually cp1250 (0xE3=ă,0xBA=ş, etc.) — the header lies. Don't decode/re-encode the text with a codepage inferred from the header; treat it byte-preserving (read/write/copy as raw bytes, compare on bytes) and this doesn't matter in practice — it only bites if a script tries to interpret the text as a specific codepage string. - Corrupt text can trigger a modal VFP dialog, not just a nonzero exit code: if
.vc2/.sc2text is malformed,Prg2Bincan returnErrorLevel 0while producing a corrupt binary — the real error only surfaces on a subsequent bin→text pass, sometimes as a native VFP MessageBox that blocks headlessly (not suppressible via parameters/.cfg). Any automated invocation ofFoxBin2Prg.EXEmust go through theInvoke-FoxBin2PrgSafewrapper invfp_filemap.ps1(default 60s timeout +taskkillon hang) rather than calling the exe directly — and treat the fidelity check (bin→text→compare), not the exe'sErrorLevel, as the real backstop against corrupt/malformed text.
# Populate/refresh a project's text cache (incremental)
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Project 'D:\ROA\ROAGEST\roagest.pjx' -ProjectRoot 'D:\ROA\ROAGEST' -CacheRoot 'D:\ROA\_vfp_textcache\roagest'
# Include reports/menus too: -Types vcx,scx,frx,mnx
# One-off conversion of a file/folder not in the project: -Source 'path\to\lib.vcx'
# Other flags: -Force (reconvert all), -Clean (wipe cache first)
Then search the cache with Grep (e.g. PROCEDURE do_salvare), citing file:line from the cache.
Write back an edited .vc2/.sc2 (after reviewing the diff on text):
& 'D:\ROA\UTIL\foxbin2prg\txt2vcx.ps1' -TextFile 'D:\ROA\_vfp_textcache\roagest\Clase\oavize.vc2' -ProjectRoot 'D:\ROA\ROAGEST' -CacheRoot 'D:\ROA\_vfp_textcache\roagest'
# Preview only, no files touched in the project: add -DryRun
# Target under COMUN\: add -AllowComun (needs approval)
# Skip the staleness check (IDE binary is known up to date some other way): -Force
# Skip the fidelity re-check after regen (not recommended): -NoVerify
Run the regression/fidelity test suite (no Pester, standalone):
& 'D:\ROA\UTIL\foxbin2prg\test_roundtrip.ps1' -ProjectRoot 'D:\ROA\ROAGEST' -CacheRoot 'D:\ROA\_vfp_textcache\roagest' -Phase all
# Run a single phase: -Phase fidelity|edit|negative|smoke
Commands
All FoxBin2Prg commands run inside VFP 9 (or via the compiled FoxBin2Prg.EXE).
* After clone/pull: regenerate all binaries from text and compile the EXEs.
* NEVER run foxbin2prg.prg directly for this — it uses a special config.
DO ReCreate_FoxBin2Prg.prg
* Convert a single file (direction inferred from extension)
DO FOXBIN2PRG.PRG WITH "<path>\file.scx" && binary -> text (.sc2)
DO FOXBIN2PRG.PRG WITH "<path>\file.sc2" && text -> binary (.scx)
* Convert a whole directory
DO FOXBIN2PRG.PRG WITH "<path>","Bin2Prg"
DO FOXBIN2PRG.PRG WITH "<path>","Prg2Bin"
* Config templates
DO FOXBIN2PRG.PRG WITH "-c","template.cfg" && default settings
DO FOXBIN2PRG.PRG WITH "-C","config.cfg" && active settings
DO FOXBIN2PRG.PRG WITH "-t","table.dbf.cfg" && per-table template
* Interactive help / option list
DO FOXBIN2PRG.PRG WITH "?"
Tests
Unit tests live in TESTS/ and use FoxUnit (path configured in TESTS/foxunit_path.txt). Files: ut__foxbin2prg__<class>__<method>.prg (unit) and ft__foxbin2prg__<class>.prg (functional). Run them from VFP via FoxUnit; test fixtures live in TESTS/DATOS_READONLY/.
Architecture
Nearly everything is in one ~34,000-line file: foxbin2prg.prg. Key class hierarchy inside it:
c_foxbin2prg(As Session) — entry point / public API. Parameter parsing, config resolution (evaluateConfiguration), file dispatch, progress UI, error logging. Also usable as COM-ish object (CREATEOBJECT('c_foxbin2prg'),.execute(...)), which is how the.vbshelpers and SCM integrations drive it.c_conversor_base— shared conversion logic (backup handling, timestamps, comment/property parsing, exclusion blocks).c_conversor_bin_a_prgand per-type subclasses (c_conversor_vcx_a_prg,c_conversor_scx_a_prg,c_conversor_pjx_a_prg,c_conversor_dbf_a_prg, …) — binary → text.c_conversor_prg_a_binand per-type subclasses — text → binary.
CL_*model classes (CL_CLASE,CL_PROJECT,CL_DBC*,CL_DBF_*,CL_MENU*, …) — object model the text files are parsed into / generated from.CL_CFG/CL_DBF_CFG— config file handling (FOXBIN2PRG.CFGwith directory inheritance, per-table.dbf.cfg).CL_LANG— localization (EN/ES/FR/DE), auto-selected.
Supporting files: foxbin2prg_keywords.dbf/.cdx (VFP keyword table used during generation — has its own .db2 text form), props_*.txt (per-control default property lists used to suppress default values in output), Create_FoxBin2Prg.cfg (the special self-conversion config), Fb2P_Diff/ and FileName_Caps/ (companion sub-projects, built by ReCreate_FoxBin2Prg.prg), BuildProcess/ (VFPXDeployment build hooks), ThorUpdater/ (Thor/VFPX release plumbing).
Text format is position-sensitive: the generated .??2 files look like PRG/XML but are parsed line by line; structure and line layout must be preserved when editing them. Properties/methods are emitted alphabetically sorted.
Upstream contribution conventions (from .github/CONTRIBUTING.md)
If patching FoxBin2Prg itself:
- Two version constants at the top of
foxbin2prg.prg: bump only the minor part ofDC_FB2PRG_VERSION_REAL(e.g.'1.21.04'); do not changeDN_FB2PRG_VERSION(1.21) — it's written into every text file and forces mass recommits. - Add the change to the history section at the top of
foxbin2prg.prgand todocs/ChangeLog.md; update the version inREADME.md. - Style: mixed-case keywords, tab indentation, spaces around operators and after list items; do not run BeautifyX with mDots insertion.
- After changes, regenerate text with
DO Create_FoxBin2Prg.prgand compile in VFP9 SP2.
Documentation
docs/FoxBin2Prg_Internals.md— settings reference and internals (ZOrder, timestamps, class-per-file, DBF export hooks, API).docs/FoxBin2Prg_Run.md— full command-line/parameter reference.docs/FoxBin2Prg_git.md,docs/FoxBin2Prg_SCM.md— SCM integration.- Spanish docs in
Documentacion/are unmaintained.