Results 1 to 3 of 3

Thread: VB6 2-nd pass compiler error on BAS module

  1. #1

    Thread Starter
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,167

    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>

  2. #2
    Hyperactive Member
    Join Date
    Jan 2018
    Posts
    339

    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.

  3. #3
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,892

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width