<# .SYNOPSIS Converteste in TEXT (.vc2/.sc2/.fr2/.mn2/.dc2/.lb2) librariile/formele VFP binare, ca sa poata fi cautat codul din proceduri/metode cu grep. .DESCRIPTION Implicit ("project mode"), converteste DOAR fisierele incluse in proiect (citite din .pjx), nu tot folderul COMUN (care contine multe librarii nefolosite in ROAACNPRO). Pentru fiecare fisier copiaza binarul + memo-ul (.vct/.sct/...) intr-un folder de cache care oglindeste structura proiectului (ca sa NU murdareasca arborele SVN), ruleaza FoxBin2Prg.exe acolo, si pastreaza doar fisierul TEXT. Incremental: sare peste ce e deja la zi. NU e nevoie de IDE-ul VFP deschis (se foloseste FoxBin2Prg.exe compilat). .PARAMETER Source Optional. Daca e dat, ignora proiectul si converteste exact: un fisier .vcx/.scx/... SAU un folder (recursiv). Folosit pentru conversii punctuale. .PARAMETER Project Fisierul .pjx din care se citeste lista de fisiere (implicit roaacnpro.PJX). .PARAMETER Types Ce extensii sa includa in project mode (implicit vcx,scx = cod). Ex: -Types vcx,scx,frx,mnx .PARAMETER ProjectRoot Radacina proiectului (implicit D:\ROA\ROAACNPRO). Caile din .pjx sunt relative la ea. .PARAMETER CacheRoot Unde se scrie textul (implicit D:\ROA\UTIL\foxbin2prg\_textcache). .PARAMETER Clean Sterge tot cache-ul inainte de conversie (util dupa ce s-au convertit accidental fisiere extra). .PARAMETER Force Reconverteste chiar daca textul exista si e mai nou decat sursa. .EXAMPLE # doar fisierele proiectului (recomandat, rapid) powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 .EXAMPLE # include si rapoartele si meniurile powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Types vcx,scx,frx,mnx .EXAMPLE # conversie punctuala a unei librarii (chiar daca nu e in proiect) powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source D:\ROA\ROAACNPRO\COMUN\clase\caut.vcx #> [CmdletBinding()] param( [string]$Source, [string]$Project = 'D:\ROA\ROAACNPRO\roaacnpro.PJX', [string[]]$Types = @('vcx','scx'), [string]$ProjectRoot = 'D:\ROA\ROAACNPRO', [string]$CacheRoot = 'D:\ROA\UTIL\foxbin2prg\_textcache', [switch]$Clean, [switch]$Force ) $ErrorActionPreference = 'Stop' $exe = 'D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE' if (-not (Test-Path $exe)) { throw "Nu gasesc $exe. Compileaza intai FoxBin2Prg (deschide foxbin2prg.pj2 in VFP si Build)." } # binar -> (memo, extensie text) $map = @{ '.vcx' = @('.vct', '.vc2'); '.scx' = @('.sct', '.sc2'); '.frx' = @('.frt', '.fr2') '.lbx' = @('.lbt', '.lb2'); '.mnx' = @('.mnt', '.mn2'); '.dbc' = @('.dct', '.dc2') } function Convert-One($fullPath) { $f = Get-Item -LiteralPath $fullPath $ext = $f.Extension.ToLower() if (-not $map.ContainsKey($ext)) { return 'skip' } $memoX = $map[$ext][0]; $txtX = $map[$ext][1] $memo = [IO.Path]::ChangeExtension($f.FullName, $memoX) $rel = $f.FullName if ($rel.ToLower().StartsWith($ProjectRoot.ToLower())) { $rel = $rel.Substring($ProjectRoot.Length).TrimStart('\') } else { $rel = $f.Name } $relDir = Split-Path $rel -Parent $workDir = if ($relDir) { Join-Path $CacheRoot $relDir } else { $CacheRoot } $txtOut = Join-Path $workDir ([IO.Path]::GetFileNameWithoutExtension($f.Name) + $txtX) if (-not $Force -and (Test-Path $txtOut) -and ((Get-Item $txtOut).LastWriteTime -ge $f.LastWriteTime)) { return 'uptodate' } if (-not (Test-Path $workDir)) { New-Item -ItemType Directory -Force -Path $workDir | Out-Null } $binCopy = Join-Path $workDir $f.Name Copy-Item -LiteralPath $f.FullName -Destination $binCopy -Force if (Test-Path $memo) { Copy-Item -LiteralPath $memo -Destination (Join-Path $workDir (Split-Path $memo -Leaf)) -Force } & $exe $binCopy '' '' '' '1' '0' '1' | Out-Null Remove-Item -LiteralPath $binCopy -Force -ErrorAction SilentlyContinue $memoCopy = Join-Path $workDir (Split-Path $memo -Leaf) if (Test-Path $memoCopy) { Remove-Item -LiteralPath $memoCopy -Force -ErrorAction SilentlyContinue } if (Test-Path $txtOut) { return 'ok' } else { return 'fail' } } # --- Construieste lista de fisiere --- $list = @() if (-not [string]::IsNullOrWhiteSpace($Source)) { if (Test-Path $Source -PathType Leaf) { $list = @((Get-Item -LiteralPath $Source).FullName) } elseif (Test-Path $Source -PathType Container) { $list = Get-ChildItem -LiteralPath $Source -Recurse -File | Where-Object { $map.ContainsKey($_.Extension.ToLower()) } | ForEach-Object { $_.FullName } } else { throw "Sursa nu exista: $Source" } } else { # PROJECT MODE: citeste .pjx -> pj2 si extrage fisierele if (-not (Test-Path $Project)) { throw "Nu gasesc proiectul: $Project" } $tmp = Join-Path $env:TEMP ('pjx_' + [IO.Path]::GetFileNameWithoutExtension($Project)) New-Item -ItemType Directory -Force -Path $tmp | Out-Null $pjxName = [IO.Path]::GetFileName($Project) Copy-Item -LiteralPath $Project -Destination (Join-Path $tmp $pjxName) -Force $pjt = [IO.Path]::ChangeExtension($Project, '.pjt') if (Test-Path $pjt) { Copy-Item -LiteralPath $pjt -Destination (Join-Path $tmp ([IO.Path]::GetFileName($pjt))) -Force } & $exe (Join-Path $tmp $pjxName) '' '' '' '1' '0' '1' | Out-Null $pj2 = Join-Path $tmp ([IO.Path]::GetFileNameWithoutExtension($Project) + '.pj2') if (-not (Test-Path $pj2)) { throw "Conversia .pjx a esuat: $pj2" } $extPat = ($Types | ForEach-Object { [regex]::Escape($_) }) -join '|' $rx = [regex]("(?i)\.ADD\('([^']*\.(?:$extPat))'\)") foreach ($m in $rx.Matches((Get-Content -Raw $pj2))) { $relp = $m.Groups[1].Value $abs = Join-Path $ProjectRoot $relp if (Test-Path $abs) { $list += (Get-Item -LiteralPath $abs).FullName } else { Write-Warning "lipsa: $relp" } } $list = $list | Sort-Object -Unique } if ($Clean -and (Test-Path $CacheRoot)) { Remove-Item -Recurse -Force $CacheRoot } if (-not $list) { Write-Host 'Nimic de convertit.'; return } $ok=0;$up=0;$fail=0 foreach ($p in $list) { switch (Convert-One $p) { 'ok' { $ok++; $r = $p; if ($r.ToLower().StartsWith($ProjectRoot.ToLower())) { $r = $r.Substring($ProjectRoot.Length).TrimStart('\') }; Write-Host "OK $r" } 'uptodate' { $up++ } 'fail' { $fail++; Write-Warning "ESEC $p" } } } Write-Host '' Write-Host "Gata. Convertite: $ok Sarite(la zi): $up Esuate: $fail (tipuri: $($Types -join ','))" Write-Host "Text in: $CacheRoot" Write-Host "Cauta cu: grep -rn 'expresie' `"$CacheRoot`""