reviewing project state, doing some tests.

This commit is contained in:
ed committed 2026-10-03 14:46:07 -04:00
1 parent f044c6d5eb
commit 61d53362e8
15 files changed
+530 -155

No files matched your search

-3
View File
@@ -44,6 +44,3 @@ test/c_library/gen
test/cpp_library/gen
!scripts/helpers/refactor.exe
# ai/**
.ai
+10 -2
View File
@@ -37,7 +37,11 @@ void clang_format_file( char const* path, char const* style_path )
strbuilder_append_str( & command, cf_verbose );
strbuilder_append_string( & command, style_arg );
strbuilder_append_string( & command, resolved_path );
system( command );
int command_result = system( command );
if ( command_result != 0 ) {
log_fmt( "clang-format failed with status %d\n", command_result );
process_exit( 1 );
}
}
// Will refactor a file with the given script at the provided path.
@@ -57,7 +61,11 @@ void refactor_file( char const* path, char const* refactor_script )
strbuilder_append_str( & command, txt("-num=1 ") );
strbuilder_append_fmt( & command, "-src=%s ", path );
strbuilder_append_fmt( & command,"-spec=%s ", refactor_script );
system(command);
int command_result = system( command );
if ( command_result != 0 ) {
log_fmt( "refactor failed with status %d\n", command_result );
process_exit( 1 );
}
log_fmt("\n");
}
+97 -103
View File
@@ -10,7 +10,57 @@ $vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
Import-Module $misc
$path_root = Get-ScriptRepoRoot
function stop-stage {
param([string]$stage, [int]$code_exit = 1)
Write-Host "FAILED: $stage" -ForegroundColor Red
exit $code_exit
}
function invoke-stageTool {
param(
[string]$stage,
[bool]$compiled,
[string]$executable,
[string]$path_work
)
if (-not $compiled) {
stop-stage "$stage compile/link"
}
if (-not (Test-Path -LiteralPath $executable)) {
stop-stage "$stage missing output $executable"
}
$code_exit = 1
push-location $path_work
try {
& $executable
$code_exit = $LASTEXITCODE
}
finally {
pop-location
}
if ($code_exit -ne 0) {
stop-stage "$stage run" $code_exit
}
Write-Host "PASSED: $stage"
}
if ($env:GENCPP_SOURCE_ROOT) {
$path_root = (Resolve-Path -LiteralPath $env:GENCPP_SOURCE_ROOT).Path
$probe = Join-Path $path_root "base\base.cpp"
if (-not (Test-Path -LiteralPath $probe)) {
stop-stage "GENCPP_SOURCE_ROOT is not a gencpp tree: $path_root"
}
}
else {
$path_root = Get-ScriptRepoRoot
}
Write-Host "SOURCE_ROOT: $path_root"
if ($null -eq $is_windows) {
$is_windows = [System.Environment]::OSVersion.Platform -eq 'Win32NT'
}
if ($null -eq $is_linux) {
$is_linux = [System.Environment]::OSVersion.Platform -eq 'Unix'
}
Push-Location $path_root
@@ -50,7 +100,7 @@ if ( $args ) { $args | ForEach-Object {
#endregion Arguments
#region Configuration
if ($IsWindows) {
if ($is_windows) {
# This library was really designed to only run on 64-bit systems.
# (Its a development tool after all)
& $devshell -arch amd64
@@ -81,7 +131,7 @@ $cannot_build = $cannot_build -and $c_lib_dyn -eq $false
$cannot_build = $cannot_build -and $unreal -eq $false
$cannot_build = $cannot_build -and $test -eq $false
if ( $cannot_build ) {
throw "No build target specified. One must be specified, this script will not assume one"
Stop-stage "No build target specified"
}
. $vendor_toolchain
@@ -125,18 +175,7 @@ if ( $base )
$executable = join-path $path_build "base.exe"
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_base
if ( Test-Path( $executable ) ) {
write-host "`nRunning base"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nbase completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "base" -compiled $result -executable $executable -path_work $path_base
}
if ( $segmented )
@@ -163,18 +202,7 @@ if ( $segmented )
$executable = join-path $path_build "segmented.exe"
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_segmented
if ( Test-Path( $executable ) ) {
write-host "`nRunning segmented"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nSegmented completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "segmented" -compiled $result -executable $executable -path_work $path_segmented
}
if ( $singleheader )
@@ -201,18 +229,7 @@ if ( $singleheader )
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_singleheader
if ( Test-Path( $executable ) ) {
write-host "`nRunning singleheader generator"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nSingleheader generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "singleheader" -compiled $result -executable $executable -path_work $path_singleheader
}
if ( $c_lib -or $c_lib_static -or $c_lib_dyn )
@@ -239,18 +256,7 @@ if ( $c_lib -or $c_lib_static -or $c_lib_dyn )
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_c_library
if ( Test-Path( $executable ) ) {
write-host "`nRunning c_library generator"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "c_lib" -compiled $result -executable $executable -path_work $path_c_library
}
if ( $c_lib_static )
@@ -267,6 +273,7 @@ if ( $c_lib_static )
$linker_args = @()
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_lib
if (-not $result) { Stop-stage "c_lib_static compile/link" }
}
if ( $c_lib_dyn )
@@ -285,6 +292,7 @@ if ( $c_lib_dyn )
$linker_args = @()
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_dll
if (-not $result) { Stop-stage "c_lib_dyn compile/link" }
}
if ( $unreal )
@@ -311,23 +319,27 @@ if ( $unreal )
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_unreal
if ( Test-Path( $executable ) ) {
write-host "`nRunning unreal variant generator"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`n Unreal variant generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "unreal" -compiled $result -executable $executable -path_work $path_unreal
. $refactor_unreal
}
# C Library testing
if ($test) {
$consumer_headers = @(
(Join-Path $path_c_library 'gen\gen_singleheader.h'),
(Join-Path $path_singleheader 'gen\gen.hpp')
)
$header_hashes_before = @{}
foreach ($header in $consumer_headers) {
if (-not (Test-Path -LiteralPath $header -PathType Leaf)) {
Stop-stage "test missing generated header $header"
}
$header_hashes_before[$header] = (Get-FileHash -LiteralPath $header -Algorithm SHA256).Hash
Write-Host "HEADER_SHA256_GENERATED: $($header_hashes_before[$header]) $header"
}
}
if ( $test -and $true )
{
$path_test_c = join-path $path_test c_library
@@ -350,24 +362,14 @@ if ( $test -and $true )
$compiler_args += $flag_all_c
$compiler_args += $flag_updated_cpp_macro
$compiler_args += $flag_c11
$compiler_args += "-H"
$linker_args = @(
$flag_link_win_subsystem_console
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_test_c
if ( Test-Path( $executable ) ) {
write-host "`nRunning c_library test"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "test-c11" -compiled $result -executable $executable -path_work $path_test_c
}
if ( $test -and $false )
@@ -398,30 +400,18 @@ if ( $test -and $false )
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_test_c
if ( Test-Path( $executable ) ) {
write-host "`nRunning c_library test"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
}
if ($test -and $false)
if ($test)
{
$path_test_cpp = join-path $path_test cpp_library
$path_build = join-path $path_test_cpp build
$path_gen = join-path $path_test_cpp gen
if ( -not(Test-Path($path_build) )) {
New-Item -ItemType Directory -Path $path_build
new-item -ItemType Directory -Path $path_build
}
if ( -not(Test-Path($path_gen) )) {
New-Item -ItemType Directory -Path $path_gen
new-item -ItemType Directory -Path $path_gen
}
$path_singleheader_include = join-path $path_singleheader gen
@@ -431,25 +421,29 @@ if ($test -and $false)
$compiler_args = @()
$compiler_args += ( $flag_define + 'GEN_TIME' )
$compiler_args += @("-x", "c++")
$compiler_args += "-std=c++17"
$compiler_args += ($flag_define + "GEN_BUILD_DEBUG=1")
$compiler_args += "-H"
$linker_args = @(
$flag_link_win_subsystem_console
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_test_cpp
if ( Test-Path( $executable ) ) {
write-host "`nRunning cpp_library test"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
invoke-stageTool -stage "test-cpp" -compiled $result -executable $executable -path_work $path_test_cpp
}
if ($test) {
foreach ($header in $consumer_headers) {
$hash = (Get-FileHash -LiteralPath $header -Algorithm SHA256).Hash
write-host "HEADER_SHA256_CONSUMED: $hash $header"
if ($hash -ne $header_hashes_before[$header]) {
Stop-stage "test header changed after generation $header"
}
}
}
#endregion Building
Pop-Location # $path_root
pop-location # $path_root
write-host "PASSED: build.ci.ps1"
exit 0
+1 -1
View File
@@ -1,3 +1,3 @@
cls
$build = Join-Path $PSScriptRoot 'build.ci.ps1'
& $build @args
exit $LASTEXITCODE
+22 -4
View File
@@ -3,7 +3,7 @@
import-module $target_arch
if ($IsWindows) {
if ($is_windows) {
# This HandmadeHero implementation is only designed for 64-bit systems
& $devshell -arch amd64
}
@@ -27,6 +27,12 @@ function run-archiver
{
param( $archiver, $library, $lib_args )
if (-not (Get-Command $archiver -ErrorAction SilentlyContinue)) {
Write-Host "FAILED: archiver launch $archiver" -ForegroundColor Red
return $false
}
Write-Host ("ARCHIVER_ARGV: " + ($lib_args -join " "))
write-host "`Creating library $library"
if ( $verbose ) {
write-host "Lib manager config:"
@@ -60,9 +66,15 @@ function run-compiler
{
param( $compiler, $unit, $compiler_args )
if (-not (Get-Command $compiler -ErrorAction SilentlyContinue)) {
Write-Host "FAILED: compiler launch $compiler" -ForegroundColor Red
return $false
}
if ( $analysis ) {
$compiler_args += $flag_syntax_only
}
Write-Host ("COMPILER_ARGV: " + ($compiler_args -join " "))
write-host "`Compiling $unit"
if ( $verbose ) {
@@ -97,6 +109,12 @@ function run-linker
{
param( $linker, $binary, $linker_args )
if (-not (Get-Command $linker -ErrorAction SilentlyContinue)) {
Write-Host "FAILED: linker launch $linker" -ForegroundColor Red
return $false
}
Write-Host ("LINKER_ARGV: " + ($linker_args -join " "))
write-host "`Linking $binary"
if ( $verbose ) {
write-host "Linker config:"
@@ -147,12 +165,12 @@ if ( $vendor -match "clang" )
$flag_library = '-l'
$flag_library_path = '-L'
$flag_linker = '-Wl,'
if ( $IsWindows ) {
if ( $is_windows ) {
$flag_link_dll = '/DLL'
$flag_link_mapfile = '/MAP:'
$flag_link_optimize_references = '/OPT:REF'
}
if ( $IsLinux ) {
if ( $is_linux ) {
$flag_link_mapfile = '--Map='
$flag_link_optimize_references = '--gc-sections'
}
@@ -191,7 +209,7 @@ if ( $vendor -match "clang" )
)
# https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170
if ( $IsWindows ) {
if ( $is_windows ) {
$libraries = @(
'Kernel32' # For Windows API
# 'msvcrt', # For the C Runtime (Dynamically Linked)
+267
View File
@@ -0,0 +1,267 @@
param(
[Parameter(Mandatory = $true)][Alias('MirrorRoot')][string]$path_mirror,
[ValidateSet(
"measure",
"positive",
"negative-compile",
"negative-link",
"negative-launch",
"negative-stale",
"negative-stale-header",
"negative-format",
"negative-refactor",
"negative-assert"
)]
[string]$mode = "positive",
[Alias('SourceRoot')][string]$path_source_root = "C:\projects\gencpp",
[Alias('ReuseMirror')][switch]$reuse_mirror
)
$ErrorActionPreference = "Stop"
$path_source = (Resolve-Path -LiteralPath $path_source_root).Path
$path_mirror = [System.IO.Path]::GetFullPath($path_mirror)
$path_verification_root = Join-Path $path_mirror 'test\verification'
if ($path_mirror -eq $path_source) { throw "MirrorRoot must not be the project checkout" }
$prefix_source = $path_source.TrimEnd('\') + '\'
$prefix_mirror = $path_mirror.TrimEnd('\') + '\'
if ($path_source.StartsWith($prefix_mirror, [System.StringComparison]::OrdinalIgnoreCase) -or
$path_mirror.StartsWith($prefix_source, [System.StringComparison]::OrdinalIgnoreCase)) {
throw "path_mirror and path_source_root must not overlap"
}
if ($reuse_mirror -and $mode -ne "positive") { throw "reuse_mirror is for the positive mode only" }
if ($reuse_mirror -and -not (Test-Path -LiteralPath (Join-Path $path_mirror 'base\base.cpp'))) {
throw "reuse_mirror needs an existing baseline mirror"
}
function Copy-Snapshot([string]$path_destination)
{
if (Test-Path -LiteralPath $path_destination) { Remove-Item -LiteralPath $path_destination -Recurse -Force }
New-Item -ItemType Directory -Path $path_destination | Out-Null
& robocopy $path_source $path_destination /E /NFL /NDL /NJH /NJS /XD .git
if ($LASTEXITCODE -ge 8) { throw "robocopy failed: $LASTEXITCODE" }
$global:LASTEXITCODE = 0
@(
"gen_segmented\gen",
"gen_segmented\build",
"gen_singleheader\gen",
"gen_singleheader\build",
"gen_c_library\gen",
"gen_c_library\build",
"gen_unreal_engine\gen",
"gen_unreal_engine\build",
"test\c_library\build",
"test\c_library\gen",
"test\cpp_library\build",
"test\cpp_library\gen",
"base\build"
) | ForEach-Object {
$path_item = Join-Path $path_destination $_
if (Test-Path -LiteralPath $path_item) { Remove-Item -LiteralPath $path_item -Recurse -Force }
}
}
function Copy-VerificationFixture([string]$name_fixture, [string]$path_destination) {
$path_fixture = Join-Path $path_verification_root $name_fixture
if (-not (Test-Path -LiteralPath $path_fixture -PathType Leaf)) {
throw "Missing verification fixture: $path_fixture"
}
Copy-Item -LiteralPath $path_fixture -Destination $path_destination -Force
}
function Invoke-Driver([string]$path_tree, [string[]]$list_targets) {
$path_driver = Join-Path $path_tree "scripts\build.ci.ps1"
$name_log = if ($reuse_mirror) { 'verify_driver.repeat.log' } else { 'verify_driver.log' }
$path_log = Join-Path $path_tree $name_log
$path_previous_root = $env:GENCPP_SOURCE_ROOT
$env:GENCPP_SOURCE_ROOT = $path_tree
$line_args = $list_targets -join ' '
try {
$text_output = & powershell.exe -NoProfile -Command "& '$path_driver' clang debug $line_args; exit `$LASTEXITCODE" *>&1
$code_exit = $LASTEXITCODE
}
finally {
$env:GENCPP_SOURCE_ROOT = $path_previous_root
}
$text_output | Tee-Object -FilePath $path_log | Out-Host
$script:path_last_driver_log = $path_log
$script:code_last_driver = $code_exit
return $code_exit
}
function Get-DriverLogText {
if (-not $script:path_last_driver_log) { return "" }
if (-not (Test-Path -LiteralPath $script:path_last_driver_log)) { return "" }
return Get-Content -LiteralPath $script:path_last_driver_log -Raw
}
function Assert-PositiveOutputs([string]$path_tree) {
$list_outputs = @(
'base\components\gen\ecodetypes.hpp',
'base\components\gen\eoperator.hpp',
'base\components\gen\especifier.hpp',
'base\components\gen\etoktype.hpp',
'base\components\gen\ast_inlines.hpp',
'gen_segmented\gen\gen.hpp',
'gen_segmented\gen\gen.cpp',
'gen_segmented\gen\gen.dep.hpp',
'gen_segmented\gen\gen.dep.cpp',
'gen_segmented\gen\gen.builder.hpp',
'gen_segmented\gen\gen.builder.cpp',
'gen_segmented\gen\gen.scanner.hpp',
'gen_segmented\gen\gen.scanner.cpp',
'gen_singleheader\gen\gen.hpp',
'gen_c_library\gen\gen.h',
'gen_c_library\gen\gen.c',
'gen_c_library\gen\gen.dep.h',
'gen_c_library\gen\gen.dep.c',
'gen_c_library\gen\gen_singleheader.h'
)
$list_hashes = foreach ($path_relative in $list_outputs) {
$path_output = Join-Path $path_tree $path_relative
if (-not (Test-Path -LiteralPath $path_output -PathType Leaf)) { throw "Missing output: $path_output" }
if ((Get-Item -LiteralPath $path_output).Length -eq 0) { throw "Empty output: $path_output" }
"{0} {1}" -f (Get-FileHash -LiteralPath $path_output -Algorithm SHA256).Hash, $path_relative
}
$text_log = (Get-DriverLogText).Replace('\\', '\')
foreach ($path_relative in @('gen_singleheader\gen\gen.hpp', 'gen_c_library\gen\gen_singleheader.h')) {
$path_header = Join-Path $path_tree $path_relative
if ($text_log -notmatch [regex]::Escape($path_header)) { throw "Compiler trace missing $path_header" }
}
$name_hash_file = if ($reuse_mirror) { 'verify_outputs.repeat.sha256' } else { 'verify_outputs.sha256' }
$list_hashes | Set-Content -LiteralPath (Join-Path $path_tree $name_hash_file)
Write-Host "PASSED: outputs and consumer header traces ($name_hash_file)"
}
$list_targets = @("base", "segmented", "singleheader", "c_lib", "test")
if (-not $reuse_mirror) { Copy-Snapshot $path_mirror }
if ($mode -eq "measure" -or $mode -eq "positive") {
$code_exit = Invoke-Driver $path_mirror $list_targets
if ($mode -eq "positive" -and $code_exit -ne 0) { exit $code_exit }
if ($mode -eq "positive") { Assert-PositiveOutputs $path_mirror }
exit $code_exit
}
if ($mode -eq "negative-compile") {
Copy-VerificationFixture 'failure_compile.cpp' (Join-Path $path_mirror 'base\base.cpp')
$code_exit = Invoke-Driver $path_mirror @("base")
if ($code_exit -eq 0) { throw "negative-compile returned 0" }
exit 0
}
if ($mode -eq "negative-link") {
Copy-VerificationFixture 'failure_link.cpp' (Join-Path $path_mirror 'base\base.cpp')
$code_exit = Invoke-Driver $path_mirror @("base")
$text_log = Get-DriverLogText
if ($code_exit -eq 0 -or $text_log -notmatch "Linking failed") {
throw "negative-link did not fail at the linker"
}
exit 0
}
if ($mode -eq "negative-launch") {
$path_toolchain = Join-Path $path_mirror "scripts\helpers\vendor_toolchain.ps1"
$text_toolchain = Get-Content -LiteralPath $path_toolchain -Raw
$text_patched = $text_toolchain.Replace(
"`$linker = 'lld-link'",
"`$linker = 'gencpp-missing-linker'"
)
if ($text_patched -eq $text_toolchain) { throw "negative-launch could not replace the linker path" }
Set-Content -LiteralPath $path_toolchain -Value $text_patched -NoNewline
$code_exit = Invoke-Driver $path_mirror @("base")
$text_log = Get-DriverLogText
if ($code_exit -eq 0 -or $text_log -notmatch "FAILED: linker launch gencpp-missing-linker") {
throw "negative-launch did not report a missing linker"
}
exit 0
}
if ($mode -eq "negative-stale") {
$path_stale_source = Join-Path $path_mirror "stale_marker.c"
$path_stale_executable = Join-Path $path_mirror "stale_marker.exe"
Copy-VerificationFixture 'stale_executable.c' $path_stale_source
& clang -o $path_stale_executable $path_stale_source
if ($LASTEXITCODE -ne 0) { throw "failed to compile stale marker" }
$path_base_build = Join-Path $path_mirror "base\build"
New-Item -ItemType Directory -Path $path_base_build -Force | Out-Null
Copy-Item -LiteralPath $path_stale_executable -Destination (Join-Path $path_base_build "base.exe") -Force
Copy-VerificationFixture 'failure_compile.cpp' (Join-Path $path_mirror 'base\base.cpp')
$code_exit = Invoke-Driver $path_mirror @("base")
if ($code_exit -eq 0) { throw "negative-stale returned 0" }
if ($code_exit -eq 73) { throw "negative-stale ran the stale executable" }
exit 0
}
if ($mode -eq "negative-stale-header") {
$code_exit = Invoke-Driver $path_mirror @("base", "segmented", "singleheader", "c_lib")
if ($code_exit -ne 0) { throw "negative-stale-header setup generation failed: $code_exit" }
Copy-Item -LiteralPath $script:path_last_driver_log -Destination (Join-Path $path_mirror 'verify_driver.setup.log')
$path_header = Join-Path $path_mirror 'gen_c_library\gen\gen_singleheader.h'
if (-not (Test-Path -LiteralPath $path_header)) { throw 'negative-stale-header missing setup header' }
Copy-VerificationFixture 'failure_compile.cpp' (Join-Path $path_mirror 'gen_c_library\c_library.cpp')
$code_exit = Invoke-Driver $path_mirror @('c_lib', 'test')
$text_log = Get-DriverLogText
if ($code_exit -eq 0 -or $text_log -notmatch 'FAILED: c_lib compile/link') {
throw 'negative-stale-header did not fail at c_lib'
}
if ($text_log -match 'Compiling .*test[.]c|PASSED: test-c11|PASSED: test-cpp') {
throw 'negative-stale-header consumed a prior header'
}
exit 0
}
if ($mode -eq "negative-format") {
$path_fake_tools = Join-Path $path_mirror "fake-tools"
New-Item -ItemType Directory -Path $path_fake_tools -Force | Out-Null
Copy-VerificationFixture 'failure_format.cmd' (Join-Path $path_fake_tools 'clang-format.cmd')
$path_saved = $env:PATH
$env:PATH = "$path_fake_tools;$env:PATH"
try {
$code_exit = Invoke-Driver $path_mirror @("base")
}
finally {
$env:PATH = $path_saved
}
$text_log = Get-DriverLogText
if ($code_exit -eq 0) { throw "negative-format returned 0" }
if ($text_log -notmatch "clang-format failed") { throw "negative-format log missing clang-format failed" }
exit 0
}
if ($mode -eq "negative-refactor") {
$path_fake_source = Join-Path $path_mirror 'failing_refactor.c'
$path_fake_executable = Join-Path $path_mirror 'scripts\helpers\refactor.exe'
Copy-VerificationFixture 'failure_refactor.c' $path_fake_source
& clang -o $path_fake_executable $path_fake_source
if ($LASTEXITCODE -ne 0) { throw 'negative-refactor failed to compile the stub' }
$code_exit = Invoke-Driver $path_mirror @('c_lib')
$text_log = Get-DriverLogText
if ($code_exit -eq 0 -or $text_log -notmatch 'refactor failed') {
throw 'negative-refactor did not propagate subprocess failure'
}
exit 0
}
if ($mode -eq "negative-assert") {
$path_header = Join-Path $path_mirror "gen_singleheader\gen\gen.hpp"
if (-not (Test-Path -LiteralPath $path_header)) {
$code_exit = Invoke-Driver $path_mirror $list_targets
if ($code_exit -ne 0) { throw "negative-assert setup generation failed: $code_exit" }
}
Copy-VerificationFixture 'failure_assert.cpp' (Join-Path $path_mirror 'test\cpp_library\test.cpp')
$code_exit = Invoke-Driver $path_mirror @("test")
$text_log = Get-DriverLogText
if ($code_exit -eq 0) { throw "negative-assert returned 0" }
if ($text_log -notmatch "FAIL forced assertion") { throw "negative-assert log missing forced assertion marker" }
exit 0
}
throw "unhandled mode $mode"
+14 -2
View File
@@ -1,3 +1,15 @@
# Test
# Baseline verification
The implementation here has been gutted and will be rewritten...
The implementation smoke is `verify_baseline.ps1`. It is not a parser corpus.
From the project root, in a fresh PowerShell process:
```powershell
.\scripts\verify_baseline.ps1 -Mode positive -MirrorRoot ..\gencpp-verify-positive
.\scripts\verify_baseline.ps1 -Mode positive -MirrorRoot ..\gencpp-verify-positive -ReuseMirror
```
The first command generates base component tables, segmented C++, single-header C++, and both C11 layouts.
It compiles and runs the C++17 and C11 single-header host smokes. The second command reuses the same mirror.
The verification wrapper copies them into the disposable mirror; it does not embed C or C++ source text.
+45 -24
View File
@@ -1,36 +1,57 @@
#if INTELLISENSE_DIRECTIVES
#include "../../gen_c_library/gen/gen_singleheader.h"
#endif
#define GEN_IMPLEMENTATION
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#include "gen_singleheader.h"
#define gen_iterator( Type, container, iter ) \
gen_begin_ ## Type(container); \
iter != gen_end_ ## Type(container); \
code = gen_next_ ## Type(container, iter)
gen_global gen_s32 g_failures = 0;
gen_internal void expect(int condition, gen_Str name) {
if (condition == false) { gen_log_fmt("FAIL %S\n", name); ++ g_failures; }
}
gen_internal void expect_fragments(gen_Str text, gen_Str label) {
expect(text.Ptr != 0 && text.Len > 0, label);
expect(gen_str_contains(text, gen_txt("baseline_message")), label);
expect(gen_str_contains(text, gen_txt("char")), label);
expect(gen_str_contains(text, gen_txt("const")), label);
expect(gen_str_contains(text, gen_txt("*")), label);
expect(gen_str_contains(text, gen_txt("GENCPP_BASELINE")), label);
}
gen_internal void expect_variable(gen_CodeVar var, gen_Str label) {
expect(var != 0, label); if (var == 0) return;
expect(var->Type == CT_Variable, label);
expect(gen_str_contains(var->Name, gen_txt("baseline_message")), label);
expect(var->ValueType != 0, label);
expect(var->Value != 0, label);
if (var->Value != 0) {
expect(gen_str_contains(var->Value->Content, gen_txt("GENCPP_BASELINE")), label);
}
}
int main()
{
gen_Context ctx = {0};
gen_init(& ctx);
gen_Context ctx = {0}; gen_init(&ctx);
gen_Builder src_hello = gen_builder_open("gen/hello.c");
gen_CodeVar hello_var = gen_parse_variable(code(
char const* hello_gencpp_str = "HELLO GENCPP C11 !";
));
gen_builder_print( & src_hello, hello_var );
gen_builder_write(& src_hello);
gen_CodeTypename type = gen_def_type(name(char), .specifiers = gen_def_specifiers(2, Spec_Const, Spec_Ptr) );
gen_CodeVar upfront = gen_def_variable(type, name(baseline_message),
.value = gen_untyped_str(code("\"GENCPP_BASELINE\""))
);
expect_variable(upfront, gen_txt("c11 upfront"));
expect_fragments(gen_strbuilder_to_str(gen_code_to_strbuilder(upfront)), gen_txt("c11 upfront serialized"));
gen_CodeBody body = gen_parse_file("gen/hello.c");
for (gen_Code code = gen_iterator(CodeBody, body, code)) switch (code->Type) {
case CT_Variable:
gen_CodeVar var = (gen_CodeVar) code;
gen_log_fmt("%S", var->Value);
break;
}
gen_Code untyped = gen_code_str(char const* baseline_message = "GENCPP_BASELINE"; );
expect(untyped != 0, gen_txt("c11 untyped"));
gen_deinit(& ctx);
gen_Str untyped_text = gen_strbuilder_to_str(gen_code_to_strbuilder(untyped));
expect_fragments(untyped_text, gen_txt("c11 untyped content"));
expect_variable(gen_parse_variable(untyped_text), gen_txt("c11 untyped reparsed"));
gen_CodeVar parsed = gen_parse_variable(code(char const* baseline_message = "GENCPP_BASELINE"; ));
expect_variable(parsed, gen_txt("c11 parsed"));
expect_fragments(gen_strbuilder_to_str(gen_code_to_strbuilder(parsed)), gen_txt("c11 parsed serialized"));
gen_deinit(&ctx);
if (g_failures != 0) { gen_log_fmt("c11 baseline smoke failed: %d\n", g_failures); return 1; }
gen_log_fmt("c11 baseline smoke passed\n");
return 0;
}
+44 -16
View File
@@ -3,27 +3,55 @@
#define GEN_ENFORCE_STRONG_CODE_TYPES
#include "gen.hpp"
global int g_failures = 0;
internal void expect(int condition, gen::Str name) {
if (condition == false) { gen::log_fmt("FAIL %S\n", name); ++ g_failures; }
}
internal void expect_fragments(gen::Str text, gen::Str label) {
expect(text.Ptr != nullptr && text.Len > 0, label);
expect(gen::str_contains(text, txt("baseline_message")), label);
expect(gen::str_contains(text, txt("char")), label);
expect(gen::str_contains(text, txt("const")), label);
expect(gen::str_contains(text, txt("*")), label);
expect(gen::str_contains(text, txt("GENCPP_BASELINE")), label);
}
internal void expect_variable(gen::CodeVar var, gen::Str label) {
expect(var.ast != nullptr, label); if (var.ast == nullptr) return;
expect(var->Type == gen::CT_Variable, label);
expect(gen::str_contains(var->Name, txt("baseline_message")), label);
expect(var->ValueType.ast != nullptr, label);
expect(var->Value.ast != nullptr, label);
if (var->Value.ast != nullptr) {
expect(gen::str_contains(var->Value->Content, txt("GENCPP_BASELINE")), label);
}
}
int main()
{
using namespace gen;
Context ctx = {};
gen::init( & ctx);
Context ctx = {}; init(&ctx);
Builder src_hello = builder_open("gen/hello.cpp");
CodeVar hello_var = parse_variable( code(
constexpr char const* hello_gencpp_str = "HELLO GENCPP !";
));
src_hello.print(hello_var);
src_hello.write();
Opts_def_type type_opts = {};
type_opts.specifiers = def_specifiers(args(Spec_Const, Spec_Ptr));
CodeTypename type = def_type(name(char), type_opts);
Opts_def_variable opts = {}; opts.value = untyped_str(code("\"GENCPP_BASELINE\""));
CodeVar upfront = def_variable(type, name(baseline_message), opts);
expect_variable(upfront, txt("cpp upfront"));
expect_fragments(strbuilder_to_str(code_to_strbuilder((Code)upfront)), txt("cpp upfront serialized"));
CodeBody body = parse_file("gen/hello.cpp");
for ( Code code : body ) switch (code->Type) {
case CT_Variable:
CodeVar var = cast(CodeVar, code);
log_fmt("%S", var->Value);
break;
}
Code untyped = code_str(char const* baseline_message = "GENCPP_BASELINE";); expect(untyped.ast != nullptr, txt("cpp untyped"));
Str untyped_text = strbuilder_to_str(code_to_strbuilder(untyped)); expect_fragments(untyped_text, txt("cpp untyped content"));
CodeVar parsed_untyped = parse_variable(untyped_text); expect_variable(parsed_untyped, txt("cpp untyped reparsed"));
gen::deinit(& ctx);
CodeVar parsed = parse_variable(code(char const* baseline_message = "GENCPP_BASELINE"; ));
expect_variable(parsed, txt("cpp parsed"));
expect_fragments(strbuilder_to_str(code_to_strbuilder((Code)parsed)), txt("cpp parsed serialized"));
deinit(&ctx);
if (g_failures != 0) { log_fmt("cpp baseline smoke failed: %d\n", g_failures); return 1; }
log_fmt("cpp baseline smoke passed\n");
return 0;
}
+10
View File
@@ -0,0 +1,10 @@
#define GEN_IMPLEMENTATION
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES
#include "gen.hpp"
int main()
{
gen::log_fmt("FAIL forced assertion\n");
return 1;
}
+3
View File
@@ -0,0 +1,3 @@
int main( {
return 1;
}
+2
View File
@@ -0,0 +1,2 @@
@echo off
exit /b 1
+7
View File
@@ -0,0 +1,7 @@
extern "C" void baseline_missing_link_target(void);
int main()
{
baseline_missing_link_target();
return 0;
}
+4
View File
@@ -0,0 +1,4 @@
int main(void)
{
return 1;
}
+4
View File
@@ -0,0 +1,4 @@
int main(void)
{
return 73;
}