Sunday, April 13, 2025

Link libraries script for MSX-2 Basic code

PowerShell Script: linklib.ps1

Script Requirements

  • The script must be named linklib.ps1.
  • Accept named parameters:
    • -FilePath: Full path to a .bas file (required)
    • -LibFolder: Optional path to a folder containing library files
    • -TargetFile: Optional output file path; if not provided, overwrite the original file
  • Process the input file line by line.
  • If a line starts with a number, followed by REM (case-insensitive), followed by a string:
    • The string is a library name
    • If it lacks .bas suffix, append it
    • Try to resolve it as a file path
    • If not found, try LibFolder + filename if LibFolder is provided
    • If still not found, terminate with an error
    • If found, replace the original line with contents of the library file
  • Use the actual script name in all output messages (using $MyInvocation.MyCommand.Name)

Script Code

<#
.SYNOPSIS
    Replaces library include lines in a .bas file with actual file content.

.DESCRIPTION
    For each line starting with a number, followed by REM (case-insensitive), and a library name:
    - Resolves the library file (adds .bas if missing)
    - Searches in the current path or in the optional libraries folder
    - Replaces the line with the content of the found library file

.PARAMETER FilePath
    The full path to the .bas file to process.

.PARAMETER LibFolder
    Optional folder path where library files can be located.

.PARAMETER TargetFile
    Optional path to write the result. If not provided, overwrites the source file.

.EXAMPLE
    .linklib.ps1 -FilePath "C:codemain.bas" -LibFolder "C:codelibs" -TargetFile "C:codelinked.bas"
#>

param (
    [Parameter(Mandatory = $true)]
    [string]$FilePath,

    [Parameter(Mandatory = $false)]
    [string]$LibFolder,

    [Parameter(Mandatory = $false)]
    [string]$TargetFile
)

$scriptName = $MyInvocation.MyCommand.Name

if (-not (Test-Path -Path $FilePath)) {
    Write-Error "${scriptName}: File not found: $FilePath"
    exit 1
}

if (-not $TargetFile) {
    $TargetFile = $FilePath
}

try {
    $lines = Get-Content -LiteralPath $FilePath
    $output = @()

    foreach ($line in $lines) {
        if ($line -match '^s*(d+)s+REMs+(.*)$') {
            $lineNumber = $matches[1]
            $libName = $matches[2].Trim()

            if (-not $libName.ToLower().EndsWith(".bas")) {
                $libName += ".bas"
            }

            $resolvedPath = $libName

            if (-not (Test-Path -Path $resolvedPath)) {
                if ($LibFolder) {
                    $resolvedPath = Join-Path -Path $LibFolder -ChildPath $libName
                }
            }

            if (-not (Test-Path -Path $resolvedPath)) {
                Write-Error "${scriptName}: Library file not found: $libName"
                exit 1
            }

            Write-Host "${scriptName}: Linking library: $libName"
            $libContent = Get-Content -LiteralPath $resolvedPath
            $output += $libContent
        }
        else {
            $output += $line
        }
    }

    Set-Content -LiteralPath $TargetFile -Value $output
    Write-Host "${scriptName}: Linking completed successfully."
    Write-Host "${scriptName}: Output written to: $TargetFile"
}
catch {
    Write-Error "${scriptName}: Error during processing - $_"
    exit 1
}