Files
comun/docs/cautare_vcx_vct.md
2026-08-03 02:50:05 +03:00

9.5 KiB

Căutare în codul din librăriile/formele VFP (.vcx/.vct, .scx/.sct, ...)

Partajat între proiectele ROA* (companion narativ la PROMPT_cautare_vfp.md din acest folder — varianta "prompt de copiat" — acest fișier e ghidul de referință complet, cu exemple).

Căutare de cod-sursă (proceduri, metode, parametri) care nu stă în .prg, ci în interiorul binarelor VFP: librării de clase (.vcx+.vct), forme (.scx+.sct), rapoarte (.frx+.frt), meniuri (.mnx+.mnt), baze de date (.dbc+.dct).

De ce e nevoie de asta

Un .vcx e o tabelă DBF: codul metodelor stă în câmpuri memo în .vct. grep direct pe .vct găsește textul dar ca binar (octeți \0 între linii), fără numere de linie și greu de citit. Soluția: convertim binarul în reprezentarea lui TEXT (.vc2, .sc2, …) — PRG-style lizibil, metode sortate alfabetic — și căutăm în text cu grep/Grep.

Regula de aur: textul generat e doar pentru citire/căutare, CU O EXCEPȚIE: pentru .vcx/.scx se poate și edita pe text, cu write-back în binar (txt2vcx.ps1) — vezi PROMPT_cautare_vfp.md pasul 3 (ordine obligatorie, encoding, fidelity check). Pentru .frx/.mnx/.dbc nu există write-back — modificările se fac tot în IDE-ul VFP.

Unelte disponibile (verificate)

Unealtă Cale Rol Recomandare
FoxBin2Prg D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE Binar VFP ⇄ text bidirecțional (.vc2/.sc2/.fr2/.mn2/.dc2/.lb2) De folosit. Fidel, include corpul metodelor, parametri, comentarii
vcx2prg D:\ROA\UTIL\vcx2prg\x2prg.prg Doar .vcx.prg compilabil Alternativă mai veche, doar clase, necesită IDE VFP deschis
prgtovcx D:\ROA\UTIL\prgtovcx\prgtovcx.PRG Invers: .prg.vcx Nu pentru căutare (direcție opusă)

FoxBin2Prg e prima alegere: rulează din linia de comandă fără IDE deschis (EXE compilat), acoperă toate tipurile de container, text mai fidel decât vcx2prg.

Dacă FoxBin2Prg.EXE lipsește: deschide D:\ROA\UTIL\foxbin2prg\foxbin2prg.pj2 în VFP 9 și Build > Build Executable. Lângă EXE trebuie să existe filename_caps.exe și props*.txt (deja în folder).

Mod recomandat: scriptul vcx2txt.ps1

D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 copiază binarul + memo-ul într-un cache care oglindește structura proiectului (nu murdărește arborele SVN), rulează FoxBin2Prg, păstrează doar textul. Incremental (sare peste ce e deja la zi).

# DOAR fișierele proiectului curent (recomandat, rapid) -> cache text propriu
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
  -Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
  -CacheRoot 'D:\ROA\_vfp_textcache\<nume_proiect>'

# include și rapoartele (.frx) și meniurile (.mnx)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
  -Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
  -CacheRoot 'D:\ROA\_vfp_textcache\<nume_proiect>' -Types vcx,scx,frx,mnx

# conversie punctuală a unui fișier/folder (chiar dacă NU e în proiect, ex. o clasă din COMUN)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source '<RADACINA_PROIECT>\COMUN\clase\caut.vcx'

# rebuild curat (șterge cache-ul întâi) / forțează reconversia
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
  -Project '<RADACINA_PROIECT>\<proiect>.pjx' -ProjectRoot '<RADACINA_PROIECT>' `
  -CacheRoot 'D:\ROA\_vfp_textcache\<nume_proiect>' -Clean

Exemplu (ROAAUTO):

powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 `
  -Project D:\ROA\ROAAUTO\roaauto.pjx -ProjectRoot D:\ROA\ROAAUTO `
  -CacheRoot D:\ROA\_vfp_textcache\roaauto

Cache-ul trebuie să stea în afara folderului D:\ROA\UTIL\foxbin2prg: ReCreate_FoxBin2Prg.prg face Prg2Bin recursiv pe tot folderul uneltei și ar reconverti .??2-urile din cache în binare rătăcite.

Rezultatul ajunge în cache, cu aceeași structură de directoare ca proiectul (ex.: roaauto\Clase\odevize.vc2, roaauto\comun\clase\_frm_base.vc2). Apoi:

grep -rn "PROCEDURE do_calcul_tarife" "D:\ROA\_vfp_textcache\<nume_proiect>"
grep -rln "factura_salvare" "D:\ROA\_vfp_textcache\<nume_proiect>"   # ce clase ating subiectul

Flux tipic: rulează scriptul o dată (populează cache-ul), apoi caută cu Grep în cache. La sesiuni următoare rescrie doar ce s-a schimbat (incremental). Pentru o librărie din COMUN\ care nu e în proiect, convertește-o punctual cu -Source.

Indexul de simboluri: vfp_symbols.ps1

grep spune unde e textul, nu în ce metodă. Într-un .vc2 asta contează: fișierele au uzual zeci de mii de linii, din care ~2/3 sunt proprietăți și metadata (nu cod), iar antetul clasei poate fi cu mii de linii deasupra potrivirii. D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1 reține intervalul de linii al fiecărei clase/metode/proceduri — din cache-ul text și din .prg-urile proiectului — și etichetează rezultatele.

$s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1'
$c = @('-CacheRoot', 'D:\ROA\_vfp_textcache\<nume_proiect>', '-ProjectRoot', '<RADACINA_PROIECT>')

# căutare etichetată cu clasa.metoda; -CodeOnly taie potrivirile din metadata/proprietăți
powershell -ExecutionPolicy Bypass -File $s @c -Grep '<expresie>' -CodeOnly
powershell -ExecutionPolicy Bypass -File $s @c -Where '<fisier>.vc2:<linie>'   # cine deține linia
powershell -ExecutionPolicy Bypass -File $s @c -Find '<nume>'                  # unde e DEFINIT
powershell -ExecutionPolicy Bypass -File $s @c -Class '<nume_clasa>'           # moștenire + metode

Exemplu (ROAACNPRO — parametrii impliciți ai scriptului țintesc deja acest proiect):

> vfp_symbols.ps1 -Grep 'calcul_cheiaj' -CodeOnly
clase\oacnpro.vc2:14937: [frm_tranzit.do_executa]  llSucces = calcul_cheiaj(m.lcVyeIds)
> vfp_symbols.ps1 -Class oApp
oApp (roaacnpro.prg:88) -> RoaApp (roa.prg:1) -> Custom (clasă de bază VFP)

Când merită în locul unui grep direct:

  • înainte de o editare cu txt2vcx.ps1-Where/-Class dau intervalul exact al metodei. Într-un .vc2 cu 15 clase, Init, Show, do_adauga, do_executa2 există în aproape fiecare; fără interval e ușor să nimerești metoda cu același nume din altă clasă;
  • rezultate multe-CodeOnly arată doar codul (pe goExecutor în ROAACNPRO: 1401 potriviri de cod din 1505, restul metadata);
  • „definit sau doar apelat?"-Find dă doar definiția, grep dă tot;
  • moștenire-Class arată lanțul cu fișier:linie, deci se vede dacă o metodă e suprascrisă local sau vine din COMUN.

Indexul (_symbols.tsv, în rădăcina cache-ului) se reconstruiește singur când cache-ul e mai nou (~4 s pentru ~200 de fișiere); e regenerabil, se poate șterge oricând. Rulează întâi vcx2txt.ps1: indexul e derivat din cache, deci nu poate ști de modificări făcute în IDE și neconvertite.

Limite: nu rezolvă apelurile indirecte (EVALUATE, SET CLASSLIB) — dă candidații, nu certitudinea. Clasele de bază VFP (form, custom) apar ca neindexate: normal, n-au sursă în proiect. Copiile vechi de .prg din subfoldere (ex. COMUN\programe\roa\) sunt excluse implicit prin -ExcludePrg; dă -ExcludePrg '' ca să vezi tot.

Alternativă manuală (fără script)

FoxBin2Prg scrie textul lângă sursă. Ca să nu murdărești folderul de clase al proiectului, copiază perechea binar+memo într-un folder temporar și convertește acolo:

# .vcx -> .vc2 (cType gol = extensia decide direcția BIN2PRG)
Copy-Item D:\ROA\<proiect>\Clase\odevize.vcx, D:\ROA\<proiect>\Clase\odevize.vct D:\tmp\
& 'D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE' 'D:\tmp\odevize.vcx' '' '' '' '1' '0' '1'
# => D:\tmp\odevize.vc2

Poziții parametri: fișier, cType, cTextName, lGenText, cDontShowErrors=1, cDebug=0, cDontShowProgress=1. Lasă cType gol — extensia (.vcx) determină direcția. (Nu da explicit "BIN2PRG" pentru un singur fișier: în acel mod EXE-ul așteaptă un director.)

Detalii complete de parametri: D:\ROA\UTIL\foxbin2prg\docs\FoxBin2Prg_Run.md.

Soluție rapidă „murdară" (un singur fișier, fără conversie)

Pentru „există metoda X undeva în librărie?", grep merge direct pe .vct (îl vede ca binar, dar găsește potrivirile):

grep -c "PROCEDURE" "D:\ROA\<proiect>\Clase\odevize.VCT"
grep -a -o "PROCEDURE [a-zA-Z0-9_]*" "D:\ROA\<proiect>\Clase\odevize.VCT"

Bun pentru „da/nu" și nume de metode; pentru corp/context, folosește conversia în text.

Corespondență extensii binar → text

Container Binar (+memo) Text
Librărie clase .vcx + .vct .vc2
Formă .scx + .sct .sc2
Raport .frx + .frt .fr2
Etichetă .lbx + .lbt .lb2
Meniu .mnx + .mnt .mn2
Bază de date .dbc + .dct .dc2

Note

  • Codul aplicației stă mai ales în Clase\*.vcx; multe .vcx-uri sunt în COMUN\ (framework partajat între toate aplicațiile ROA — vezi CLAUDE.md per proiect).
  • Cache-ul text e regenerabil, în afara arborelui SVN/git al proiectului — poate fi șters oricând.
  • Conversia nu necesită IDE-ul VFP deschis (folosește EXE-ul compilat).
  • Vezi și conventie_encoding_cp1252.md — capcană de encoding la editarea .sc2/.vc2 (nu doar la căutare).