Include si sistemul de depanare/testare headless din Teste\ (harness UI cu capturi, verificare de sintaxa prin compilare, wrappere text<->binar) si docs\depanare_testare_flora2roa.md.
129 lines
5.7 KiB
PowerShell
129 lines
5.7 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Verificare de sintaxa prin compilare headless a fisierelor .prg din FLORA2ROA.
|
|
|
|
.DESCRIPTION
|
|
Cel mai ieftin test dupa orice editare de .prg (vezi COMUN\docs\depanare_testare_vfp.md, sect. 4).
|
|
Compileaza COPII ale fisierelor intr-un folder temporar, ca .fxp-urile si .err-urile generate
|
|
sa nu murdareasca arborele proiectului. VFP nu rezolva simboluri externe la compilare, deci
|
|
copia izolata e suficienta pentru sintaxa.
|
|
|
|
Toate fisierele se compileaza intr-o SINGURA rulare vfp9: lansarile repetate de vfp9 din
|
|
aceeasi sesiune PowerShell esueaza tacut (procesul porneste dar nu executa - vezi
|
|
COMUN\docs\testare-ui-vfp.md, capcana d).
|
|
|
|
Verdict per fisier: existenta unui <nume>.err dupa compilare. Se raporteaza si liniile mai
|
|
lungi de 250 de caractere (capcana VFP: literal/linie prea lunga = eroare de compilare sau
|
|
eroare 11 derutanta la runtime).
|
|
|
|
NU inlocuieste testul functional: prinde sintaxa, nu apeluri catre metode inexistente.
|
|
|
|
.PARAMETER Files
|
|
Fisiere .prg de verificat. Implicit toate .prg-urile din radacina proiectului si din Teste\.
|
|
|
|
.PARAMETER ProjectRoot
|
|
Radacina proiectului (implicit folderul parinte al acestui script).
|
|
|
|
.EXAMPLE
|
|
powershell -ExecutionPolicy Bypass -File Teste\verifica_sintaxa.ps1
|
|
|
|
.EXAMPLE
|
|
powershell -ExecutionPolicy Bypass -File Teste\verifica_sintaxa.ps1 -Files myutils.prg,app.prg
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string[]]$Files,
|
|
[string]$ProjectRoot,
|
|
[int]$MaxLineLen = 250,
|
|
[string]$Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe'
|
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
if (-not $ProjectRoot) { $ProjectRoot = Split-Path $PSScriptRoot -Parent }
|
|
if (-not (Test-Path $Vfp)) { throw "Nu gasesc vfp9.exe: $Vfp" }
|
|
|
|
if (-not $Files) {
|
|
$Files = @(Get-ChildItem -Path $ProjectRoot -Filter '*.prg' -File | ForEach-Object { $_.FullName })
|
|
$Files += @(Get-ChildItem -Path (Join-Path $ProjectRoot 'Teste') -Filter '*.prg' -File -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName })
|
|
}
|
|
$Files = $Files | ForEach-Object { if ([IO.Path]::IsPathRooted($_)) { $_ } else { Join-Path $ProjectRoot $_ } }
|
|
|
|
$work = Join-Path $env:TEMP ('flora2roa_syntax_' + [Guid]::NewGuid().ToString('N').Substring(0,8))
|
|
New-Item -ItemType Directory -Force -Path $work | Out-Null
|
|
|
|
# fisierele .h referite prin #INCLUDE trebuie sa fie langa copie, altfel compilarea da eroare
|
|
Get-ChildItem -Path $ProjectRoot -Filter '*.h' -File -ErrorAction SilentlyContinue |
|
|
ForEach-Object { Copy-Item $_.FullName (Join-Path $work $_.Name) -Force }
|
|
|
|
# omoara doar instantele vfp9 proprii (linia de comanda contine folderul de lucru temporar)
|
|
function Stop-VfpProprii([string]$Marker) {
|
|
Get-CimInstance Win32_Process -Filter "Name='vfp9.exe'" -ErrorAction SilentlyContinue | ForEach-Object {
|
|
if ($_.CommandLine -and $_.CommandLine.ToLower().Contains($Marker.ToLower())) {
|
|
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
# copiaza sursele + strange liniile prea lungi (analiza statica, fara VFP)
|
|
$copii = @()
|
|
$liniiLungi = @{}
|
|
foreach ($f in $Files) {
|
|
if (-not (Test-Path $f)) { Write-Warning "lipsa: $f"; continue }
|
|
$nume = [IO.Path]::GetFileName($f)
|
|
$copie = Join-Path $work $nume
|
|
Copy-Item -LiteralPath $f -Destination $copie -Force
|
|
$copii += [pscustomobject]@{ Nume = $nume; Sursa = $f; Copie = $copie }
|
|
|
|
$lungi = @()
|
|
$linii = [IO.File]::ReadAllLines($f, [Text.Encoding]::GetEncoding(1252))
|
|
for ($i = 0; $i -lt $linii.Length; $i++) {
|
|
if ($linii[$i].Length -gt $MaxLineLen) { $lungi += ('{0} (len={1})' -f ($i + 1), $linii[$i].Length) }
|
|
}
|
|
if ($lungi) { $liniiLungi[$nume] = ($lungi -join '; ') }
|
|
}
|
|
if (-not $copii) { Write-Host 'Nimic de verificat.'; return }
|
|
|
|
# un singur .prg care compileaza toate copiile (SAFETY OFF: fara dialog "overwrite?" headless)
|
|
$linii = @('SET SAFETY OFF', 'SET TALK OFF')
|
|
foreach ($c in $copii) { $linii += ('lcT = "{0}"' -f $c.Copie); $linii += 'COMPILE (lcT)' }
|
|
$linii += 'STRTOFILE("gata", "' + (Join-Path $work '_gata.txt') + '")'
|
|
$linii += 'QUIT'
|
|
$tmpPrg = Join-Path $work '_compile_all.prg'
|
|
Set-Content -Path $tmpPrg -Value (($linii -join "`r`n") + "`r`n") -Encoding ascii
|
|
|
|
# -A ignora config.fpw implicit, -T sare peste splash; ambele obligatorii headless
|
|
$p = Start-Process -FilePath $Vfp -ArgumentList @('-A', '-T', "`"$tmpPrg`"") -PassThru -WindowStyle Minimized
|
|
if (-not $p.WaitForExit(180000)) { Write-Warning 'Timeout la compilare (180s).'; try { $p.Kill() } catch {} }
|
|
Stop-VfpProprii $work
|
|
if (-not (Test-Path (Join-Path $work '_gata.txt'))) {
|
|
Write-Warning 'Compilarea nu a ajuns la final - verdictul per fisier poate fi incomplet.'
|
|
}
|
|
|
|
$rezultate = foreach ($c in $copii) {
|
|
$err = [IO.Path]::ChangeExtension($c.Copie, 'err')
|
|
$fxp = [IO.Path]::ChangeExtension($c.Copie, 'fxp')
|
|
$erori = if (Test-Path $err) { (Get-Content -Raw $err).Trim() } else { '' }
|
|
[pscustomobject]@{
|
|
Fisier = $c.Nume
|
|
Sintaxa = if ($erori) { 'ERORI' } elseif (Test-Path $fxp) { 'OK' } else { 'NECOMPILAT' }
|
|
Erori = $erori
|
|
LiniiLungi = $(if ($liniiLungi.ContainsKey($c.Nume)) { $liniiLungi[$c.Nume] } else { '' })
|
|
}
|
|
}
|
|
|
|
Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue
|
|
|
|
$rezultate | Format-Table Fisier, Sintaxa -AutoSize
|
|
foreach ($r in $rezultate | Where-Object { $_.Erori }) {
|
|
Write-Host ''
|
|
Write-Warning ("ERORI in {0}:`n{1}" -f $r.Fisier, $r.Erori)
|
|
}
|
|
foreach ($r in $rezultate | Where-Object { $_.LiniiLungi }) {
|
|
Write-Host ''
|
|
Write-Warning ("Linii peste $MaxLineLen caractere in {0}: {1}" -f $r.Fisier, $r.LiniiLungi)
|
|
}
|
|
$nrProbleme = @($rezultate | Where-Object { $_.Sintaxa -ne 'OK' }).Count
|
|
Write-Host ''
|
|
Write-Host ("Gata. Fisiere verificate: {0} Cu probleme: {1}" -f @($rezultate).Count, $nrProbleme)
|
|
exit ([int]($nrProbleme -gt 0))
|