VB6 2-nd pass compiler error on BAS module
Sharing this Claude generated tool here (to not get it lost) which finds procedures with useless On Error GoTo 0 which trip up VB6 compiler's codegen and result in linker error i.e. the binary produced is non-functional because of 2-nd pass codegen the compiler bombs out. The problem is exacerbated when line numbers are used with such extraneous On Error GoTo 0 i.e. compiling production code with Erl support for error handling might bomb on build server.
Here is the powershell script that you might want to check you projects for potential problems:
Code:
# Find-DanglingOnErrorGoto0.ps1
param(
[string]$Path
)
# Finds VB6 procedures that have `On Error GoTo 0` but do NOT have a real
# error handler (neither `On Error GoTo <label>` nor `On Error Resume Next`).
if (-not $Path) {
@"
Find-DanglingOnErrorGoto0.ps1 - Find VB6 procedures with a dangling 'On Error GoTo 0'.
Reports procedures that contain 'On Error GoTo 0' but never install a real error
handler ('On Error GoTo <label>' or 'On Error Resume Next') before it.
Usage:
.\Find-DanglingOnErrorGoto0.ps1 -Path <folder-or-file>
Parameters:
-Path Folder (searched recursively) or file to scan. Scans *.bas, *.cls,
*.frm and *.ctl files.
Example:
.\Find-DanglingOnErrorGoto0.ps1 -Path C:\Projects\MyVB6App
"@ | Write-Output
return
}
$reProcStart = '^\s*(?:(?:Public|Private|Friend|Static)\s+)*(?:Sub|Function|Property\s+(?:Get|Let|Set))\s+(\w+)'
$reProcEnd = '^\s*End\s+(?:Sub|Function|Property)\b'
$reGoto0 = '^\s*On\s+Error\s+GoTo\s+0\s*$'
$reResume = '^\s*On\s+Error\s+Resume\s+Next\b'
$reGotoLabel = '^\s*On\s+Error\s+GoTo\s+(?!0\s*$)\S+'
$files = Get-ChildItem -Path $Path -Recurse -Include *.bas, *.cls, *.frm, *.ctl -File
$results = foreach ($f in $files) {
$lines = Get-Content -LiteralPath $f.FullName
$inProc = $false
$procName = ''
$procStartLine = 0
$handlerInstalled = $false # is a handler active AT THIS POINT
$danglingLines = @() # On Error GoTo 0 with no active handler before it
for ($i = 0; $i -lt $lines.Count; $i++) {
$line = $lines[$i]
$lineNo = $i + 1
if (-not $inProc) {
$m = [regex]::Match($line, $reProcStart, 'IgnoreCase')
if ($m.Success) {
$inProc = $true
$procName = $m.Groups[1].Value
$procStartLine = $lineNo
$handlerInstalled = $false
$danglingLines = @()
}
continue
}
if ($line -imatch $reProcEnd) {
if ($danglingLines.Count -gt 0) {
[pscustomobject]@{
File = $f.FullName
Procedure = $procName
ProcLine = $procStartLine
Goto0At = ($danglingLines -join ',')
}
}
$inProc = $false
continue
}
if ($line -imatch $reResume -or $line -imatch $reGotoLabel) {
$handlerInstalled = $true # installs a handler for the rest of the procedure
} elseif ($line -imatch $reGoto0) {
# flag only if NO handler was installed anywhere earlier in the procedure;
# sticky flag, because due to branching (each GoTo 0 sits in a separate branch,
# followed by Err.Raise/Exit) the top-level handler is actually active on the path
if (-not $handlerInstalled) { $danglingLines += $lineNo }
}
}
}
$results = @($results)
if ($results.Count -gt 0) {
$results | Sort-Object File, ProcLine | Format-Table -AutoSize
"Total: $($results.Count) procedure(s) with dangling 'On Error GoTo 0'." | Write-Output
} else {
"None found." | Write-Output
}
cheers,
</wqw>
Re: VB6 2-nd pass compiler error on BAS module
Strange, I had a couple of hits in my most commonly used modules, but never had any compiler problems. And I always put line #s in before compiling.
Re: VB6 2-nd pass compiler error on BAS module
I found a couple in my project group too, but I've never had any compiler complaints from them either. Fixed them regardless, thanks for the tool @wqweto ;)