sync SVN r18041
This commit is contained in:
@@ -1,183 +1,75 @@
|
||||
# Căutare în codul din librăriile/formele VFP (`.vcx`/`.vct`, `.scx`/`.sct`, ...)
|
||||
# Cautare in codul din librariile/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`).
|
||||
Partajat intre proiectele ROA*. Cod-sursa (proceduri, metode, parametri) care **nu** sta in
|
||||
`.prg`, ci in binarele VFP: librarii 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`.
|
||||
Un `.vcx` e o tabela DBF: codul metodelor sta in campuri memo in `.vct`. `grep` direct pe `.vct`
|
||||
gaseste textul dar ca binar (octeti `\0` intre linii), fara numere de linie si greu de citit.
|
||||
Solutia: se converteste binarul in text (`.vc2`, `.sc2`, ...) si se cauta cu `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**.
|
||||
## Flux curent (proiecte migrate): in-arbore
|
||||
|
||||
## Unelte disponibile (verificate)
|
||||
Migrate: ROACONT, COMUN, ROAGEST, ROAAUTO, ROAIMOB, ROAACNPRO, ROAFACTURARE, ROACONTRACTE
|
||||
(prezenta `roa_sync.bat` in radacina proiectului = migrat).
|
||||
|
||||
| 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ă) |
|
||||
Textul `.??2` sta langa binar. La inceput de sesiune si inainte de orice `git commit`:
|
||||
|
||||
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).
|
||||
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\git_sync.ps1 -ProjectRoot <root>
|
||||
```
|
||||
|
||||
Exemplu (ROAAUTO):
|
||||
Apoi cauta direct cu `Grep` in `.??2` din arbore (`PROCEDURE do_salvare`, etc.), citand
|
||||
`fisier:linie`.
|
||||
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
## Indexul de simboluri: vfp_symbols.ps1
|
||||
|
||||
> 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:
|
||||
|
||||
```bash
|
||||
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.
|
||||
`grep`/`Grep` spune *unde* e textul, nu *in ce metoda*. Intr-un `.vc2` cu zeci de mii de linii
|
||||
(~2/3 proprietati/metadata, nu cod) si 15 clase care au fiecare `Init`/`Show`/`do_adauga`, fara
|
||||
interval e usor sa nimeresti metoda gresita.
|
||||
|
||||
```powershell
|
||||
$s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1'
|
||||
$c = @('-CacheRoot', 'D:\ROA\_vfp_textcache\<nume_proiect>', '-ProjectRoot', '<RADACINA_PROIECT>')
|
||||
$c = @('-CacheRoot', '<root>', '-ProjectRoot', '<root>')
|
||||
|
||||
# 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
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Grep '<expresie>' -CodeOnly # etichetat clasa.metoda, doar cod
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Where '<fisier>.vc2:<linie>' # cine detine linia
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Find '<nume>' # unde e DEFINIT
|
||||
powershell -ExecutionPolicy Bypass -File $s @c -Class '<nume_clasa>' # mostenire + metode
|
||||
```
|
||||
|
||||
Exemplu (ROAACNPRO — parametrii impliciți ai scriptului țintesc deja acest proiect):
|
||||
**`-Where`/`-Class` sunt OBLIGATORII inainte de o editare cu `txt2vcx.ps1`** - dau intervalul
|
||||
exact al metodei. Indexul se reconstruieste din text cand textul e mai nou: ruleaza `git_sync.ps1`
|
||||
inainte, altfel nu vede modificari facute in IDE si neconvertite.
|
||||
|
||||
```
|
||||
> 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)
|
||||
```
|
||||
Limite: nu rezolva apelurile indirecte (`EVALUATE`, `SET CLASSLIB`) - da candidati, nu
|
||||
certitudine. Clasele de baza VFP (`form`, `custom`) apar neindexate (n-au sursa in proiect).
|
||||
Copiile vechi de `.prg` din subfoldere sunt excluse implicit prin `-ExcludePrg`; da
|
||||
`-ExcludePrg ''` ca sa vezi tot.
|
||||
|
||||
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:
|
||||
|
||||
```powershell
|
||||
# .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):
|
||||
|
||||
```bash
|
||||
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
|
||||
## Corespondenta extensii binar -> text
|
||||
|
||||
| Container | Binar (+memo) | Text |
|
||||
|---|---|---|
|
||||
| Librărie clase | `.vcx` + `.vct` | `.vc2` |
|
||||
| Formă | `.scx` + `.sct` | `.sc2` |
|
||||
| Librarie clase | `.vcx` + `.vct` | `.vc2` |
|
||||
| Forma | `.scx` + `.sct` | `.sc2` |
|
||||
| Raport | `.frx` + `.frt` | `.fr2` |
|
||||
| Etichetă | `.lbx` + `.lbt` | `.lb2` |
|
||||
| Eticheta | `.lbx` + `.lbt` | `.lb2` |
|
||||
| Meniu | `.mnx` + `.mnt` | `.mn2` |
|
||||
| Bază de date | `.dbc` + `.dct` | `.dc2` |
|
||||
| Baza de date | `.dbc` + `.dct` | `.dc2` |
|
||||
|
||||
## Note
|
||||
## Proiecte NEmigrate (cache extern)
|
||||
|
||||
- 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](conventie_encoding_cp1252.md) — capcană de encoding la
|
||||
editarea `.sc2`/`.vc2` (nu doar la căutare).
|
||||
```
|
||||
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Project <pjx> -ProjectRoot <root> -CacheRoot <cache>
|
||||
```
|
||||
|
||||
`-CacheRoot` trebuie sa stea **in afara** folderului `foxbin2prg`: `ReCreate_FoxBin2Prg.prg` face
|
||||
`Prg2Bin` recursiv pe tot folderul uneltei si ar reconverti `.??2`-urile in binare parazitare.
|
||||
|
||||
## Editare si write-back
|
||||
|
||||
Vezi `flux-editare-vfp-text.md`. Regula de aur: `.frx`/`.mnx`/`.lbx`/`.pjx`/`.dbc`/`.dbf` sunt
|
||||
read-only (editare doar in IDE-ul VFP); write-back suportat doar pentru `.vcx`/`.scx`.
|
||||
|
||||
Reference in New Issue
Block a user