Compare commits

...

3 Commits

Author SHA1 Message Date
Julian Noble faa459f572 punkzip PROVENANCE.md: relative sibling-checkout convention replaces the dev-machine absolute path 3 days ago
Julian Noble 2c1dec100e CRLF hygiene ahead of the fossil catch-up: glob the vendored sdx patches, LF two strays 3 days ago
Julian Noble 03306be068 argparsingtest 1.3.0: opt, cmdline and tepam are optional, not module-level requires 3 days ago
  1. 5
      .fossil-settings/crlf-glob
  2. 68
      src/modules/argparsingtest-999999.0a1.0.tm
  3. 5
      src/modules/argparsingtest-buildversion.txt
  4. 88
      src/tests/modules/argparsingtest/testsuites/argparsingtest/argparsingtest.test
  5. 29
      src/tools/punkzip/PROVENANCE.md

5
.fossil-settings/crlf-glob

@ -3,8 +3,11 @@
#kit payloads, and vendored-tool test fixtures (vendor/payload files keep their #kit payloads, and vendored-tool test fixtures (vendor/payload files keep their
#upstream endings; the LF preference in root AGENTS.md governs authored text #upstream endings; the LF preference in root AGENTS.md governs authored text
#files, not these trees). punkzip's hamlet.txt fixture is CRLF byte-exact test #files, not these trees). punkzip's hamlet.txt fixture is CRLF byte-exact test
#data - its compression tests pin sizes against it. #data - its compression tests pin sizes against it. suite_tcl86's patches/ holds
#vendored sdx sources (Matt Newman / Jean-Claude Wippler) plus the patch file
#derived from them - upstream CRLF, kept byte-exact so the patch applies.
src/embedded/* src/embedded/*
src/vendorlib/* src/vendorlib/*
src/vfs/* src/vfs/*
src/tools/punkzip/src/fixtures/* src/tools/punkzip/src/fixtures/*
src/buildsuites/suite_tcl86/patches/*

68
src/modules/argparsingtest-999999.0a1.0.tm

@ -50,15 +50,28 @@
package require Tcl 8.6- package require Tcl 8.6-
package require punk::args package require punk::args
package require opt
package require cmdline # Every parser package this module compares is OPTIONAL, including the tcllib ones.
package require tepam # A comparison harness that cannot load at all because one of the libraries it
# compares is absent is useless on exactly the runtime you most want to measure -
# and punkshell builds do ship without tcllib. A missing library must degrade to a
# not_loaded row (see the {optional <pkg>} roster markers), never to a load failure.
# Guarded here rather than at the call sites because the guard needed differs:
# cmdline - used only INSIDE proc bodies, so the requires below are the whole story
# opt - tcl::OptProc DEFINES the wrapper procs, so each definition site is
# tepam additionally guarded by an 'is the package present' test. Those sites
# test presence rather than catching, so a genuine error in a spec still
# surfaces loudly on a runtime that does have the package.
# argp, parse_args and argparse are required further down, at their own sites.
catch {package require opt}
catch {package require cmdline}
catch {package require tepam}
#*** !doctools #*** !doctools
#[item] [package {Tcl 8.6}] #[item] [package {Tcl 8.6}]
#[item] [package {punk::args}] #[item] [package {punk::args}]
#[item] [package {opt}] #[item] [package {opt}] (optional - parser under test)
#[item] [package {cmdline}] #[item] [package {cmdline}] (optional - parser under test)
#[item] [package {tepam}] #[item] [package {tepam}] (optional - parser under test)
# #package require frobz # #package require frobz
# #*** !doctools # #*** !doctools
@ -163,13 +176,13 @@ namespace eval argparsingtest {
punkargs_by_id always punkargs_by_id always
punkargs_parsecache always punkargs_parsecache always
punkargs_validate_ansistripped always punkargs_validate_ansistripped always
opt always opt {optional opt}
cmdline_untyped always cmdline_untyped {optional cmdline}
cmdline_typed always cmdline_typed {optional cmdline}
argp {optional argp} argp {optional argp}
parse_args {optional parse_args} parse_args {optional parse_args}
argparse {optional argparse} argparse {optional argparse}
tepam always tepam {optional tepam}
} }
} }
tkstyle { tkstyle {
@ -180,8 +193,8 @@ namespace eval argparsingtest {
punkargs always punkargs always
punkargs_by_id always punkargs_by_id always
punkargs_parsecache always punkargs_parsecache always
opt always opt {optional opt}
tepam always tepam {optional tepam}
argparse {optional argparse} argparse {optional argparse}
cmdline_untyped unsupported cmdline_untyped unsupported
cmdline_typed unsupported cmdline_typed unsupported
@ -197,10 +210,10 @@ namespace eval argparsingtest {
punkargs always punkargs always
punkargs_by_id always punkargs_by_id always
punkargs_parsecache always punkargs_parsecache always
opt always opt {optional opt}
cmdline_untyped always cmdline_untyped {optional cmdline}
cmdline_typed always cmdline_typed {optional cmdline}
tepam always tepam {optional tepam}
parse_args {optional parse_args} parse_args {optional parse_args}
argparse {optional argparse} argparse {optional argparse}
argp unsupported argp unsupported
@ -214,7 +227,7 @@ namespace eval argparsingtest {
punkargs always punkargs always
punkargs_by_id always punkargs_by_id always
punkargs_parsecache always punkargs_parsecache always
opt always opt {optional opt}
argparse {optional argparse} argparse {optional argparse}
cmdline_untyped unsupported cmdline_untyped unsupported
cmdline_typed unsupported cmdline_typed unsupported
@ -1494,6 +1507,8 @@ namespace eval argparsingtest::opts {
-join -type none -multiple 1 -join -type none -multiple 1
}] }]
} }
#tcl::OptProc DEFINES this proc, so skip the definition when opt is absent - see the optional-package requires at the module top
if {![catch {package present opt}]} {
tcl::OptProc opt { tcl::OptProc opt {
{-return string "return type"} {-return string "return type"}
{-frametype \uFFEF "type of frame"} {-frametype \uFFEF "type of frame"}
@ -1513,6 +1528,7 @@ namespace eval argparsingtest::opts {
} }
return $opts return $opts
} }
}
#cmdline::getoptions is much faster than typedGetoptions #cmdline::getoptions is much faster than typedGetoptions
namespace eval argdoc { namespace eval argdoc {
@ -1736,6 +1752,8 @@ namespace eval argparsingtest::opts {
-join -type none -multiple 1 -join -type none -multiple 1
}] }]
} }
#tepam::procedure DEFINES this proc, so skip the definition when tepam is absent - see the optional-package requires at the module top
if {![catch {package present tepam}]} {
tepam::procedure {tepam} { tepam::procedure {tepam} {
-args { -args {
{-return -type string -default string} {-return -type string -default string}
@ -1753,6 +1771,7 @@ namespace eval argparsingtest::opts {
} { } {
return [dict create return $return frametype $frametype show_edge $show_edge show_seps $show_seps x $x y $y z $z 1 $1 2 $2 3 $3 join $join] return [dict create return $return frametype $frametype show_edge $show_edge show_seps $show_seps x $x y $y z $z 1 $1 2 $2 3 $3 join $join]
} }
}
#*** !doctools #*** !doctools
#[list_end] [comment {--- end definitions namespace argparsingtest::opts ---}] #[list_end] [comment {--- end definitions namespace argparsingtest::opts ---}]
@ -1967,6 +1986,8 @@ namespace eval argparsingtest::tkstyle {
-join -type none -multiple 1 -join -type none -multiple 1
}] }]
} }
#tcl::OptProc DEFINES this proc, so skip the definition when opt is absent - see the optional-package requires at the module top
if {![catch {package present opt}]} {
tcl::OptProc opt { tcl::OptProc opt {
{p1 -string "first positional argument"} {p1 -string "first positional argument"}
{p2 -string "second positional argument"} {p2 -string "second positional argument"}
@ -1990,6 +2011,7 @@ namespace eval argparsingtest::tkstyle {
} }
return [list $p1 $p2 $opts] return [list $p1 $p2 $opts]
} }
}
namespace eval argdoc { namespace eval argdoc {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@ -2015,6 +2037,8 @@ namespace eval argparsingtest::tkstyle {
-join -type none -multiple 1 -join -type none -multiple 1
}] }]
} }
#tepam::procedure DEFINES this proc, so skip the definition when tepam is absent - see the optional-package requires at the module top
if {![catch {package present tepam}]} {
tepam::procedure {tepam} { tepam::procedure {tepam} {
-named_arguments_first 0 -named_arguments_first 0
-args { -args {
@ -2035,6 +2059,7 @@ namespace eval argparsingtest::tkstyle {
} { } {
return [list $p1 $p2 [dict create return $return frametype $frametype show_edge $show_edge show_seps $show_seps x $x y $y z $z 1 $1 2 $2 3 $3 join $join]] return [list $p1 $p2 [dict create return $return frametype $frametype show_edge $show_edge show_seps $show_seps x $x y $y z $z 1 $1 2 $2 3 $3 join $join]]
} }
}
namespace eval argdoc { namespace eval argdoc {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@ -2296,6 +2321,8 @@ namespace eval argparsingtest::tclstyle {
p2 -type string -optional 0 p2 -type string -optional 0
}] }]
} }
#tcl::OptProc DEFINES this proc, so skip the definition when opt is absent - see the optional-package requires at the module top
if {![catch {package present opt}]} {
tcl::OptProc opt { tcl::OptProc opt {
{-return string "return type"} {-return string "return type"}
{-frametype \uFFEF "type of frame"} {-frametype \uFFEF "type of frame"}
@ -2319,6 +2346,7 @@ namespace eval argparsingtest::tclstyle {
} }
return [list $p1 $p2 $opts] return [list $p1 $p2 $opts]
} }
}
namespace eval argdoc { namespace eval argdoc {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@ -2439,6 +2467,8 @@ namespace eval argparsingtest::tclstyle {
p2 -type string -optional 0 p2 -type string -optional 0
}] }]
} }
#tepam::procedure DEFINES this proc, so skip the definition when tepam is absent - see the optional-package requires at the module top
if {![catch {package present tepam}]} {
tepam::procedure {tepam} { tepam::procedure {tepam} {
-args { -args {
{-return -type string -default string} {-return -type string -default string}
@ -2458,6 +2488,7 @@ namespace eval argparsingtest::tclstyle {
} { } {
return [list $p1 $p2 [dict create return $return frametype $frametype show_edge $show_edge show_seps $show_seps x $x y $y z $z 1 $1 2 $2 3 $3 join $join]] return [list $p1 $p2 [dict create return $return frametype $frametype show_edge $show_edge show_seps $show_seps x $x y $y z $z 1 $1 2 $2 3 $3 join $join]]
} }
}
namespace eval argdoc { namespace eval argdoc {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@ -2848,6 +2879,8 @@ namespace eval argparsingtest::sandwich {
p5 -type string -optional 0 p5 -type string -optional 0
}] }]
} }
#tcl::OptProc DEFINES this proc, so skip the definition when opt is absent - see the optional-package requires at the module top
if {![catch {package present opt}]} {
tcl::OptProc opt { tcl::OptProc opt {
{p1 -string "first leading positional argument"} {p1 -string "first leading positional argument"}
{p2 -string "second leading positional argument"} {p2 -string "second leading positional argument"}
@ -2874,6 +2907,7 @@ namespace eval argparsingtest::sandwich {
} }
return [list [list $p1 $p2] [list $p3 $p4 $p5] $opts] return [list [list $p1 $p2] [list $p3 $p4 $p5] $opts]
} }
}
namespace eval argdoc { namespace eval argdoc {
lappend PUNKARGS [list { lappend PUNKARGS [list {

5
src/modules/argparsingtest-buildversion.txt

@ -1,6 +1,9 @@
1.2.0 1.3.0
#First line must be a semantic version number #First line must be a semantic version number
#all other lines are ignored. #all other lines are ignored.
#1.3.0 - opt, cmdline and tepam are no longer module-level hard requires. A punkshell build without tcllib could not load the module at all ("can't find package opt"), which is useless on exactly the runtime you wanted to measure: every parser this module compares is now optional and a missing one degrades to a not_loaded row like argp/parse_args/argparse already did. Their roster entries become {optional opt} / {optional cmdline} / {optional tepam}
#1.3.0 - the guard differs by package because the dependency does: cmdline is only called inside proc bodies, so the catch-guarded require is the whole story, whereas tcl::OptProc and tepam::procedure DEFINE their wrapper procs - those 7 definition sites are additionally guarded by a 'package present' test, so the proc simply does not exist when the package is absent (and discover_parsers then never calls it). Presence test rather than catch, so a genuine spec error still raises loudly on a runtime that does have the package
#1.3.0 - regression pinned by module_loads_without_optional_parser_packages (child interp with an emptied auto_path); tests that name parsers explicitly now filter through a loaded_parsers helper
#1.2.0 - fourth calling style 'sandwich': 2 mandatory leading positionals, THEN the 10 keyed options (argvec now exercises the valueless -join flag alongside -flag value pairs), THEN 3 mandatory trailing positionals. The 2/3 split is asymmetric on purpose - an even split could be satisfied by a parser that just halves the positional block. New namespace argparsingtest::sandwich with manual_switch, punkargs, punkargs_by_id, punkargs_parsecache, opt and argparse wrappers; return contract is {{p1 p2} {p3 p4 p5} optsdict} (grouped rather than the flat {p1 p2 opts} of the other positional styles, since positionals sit on both sides of the options) #1.2.0 - fourth calling style 'sandwich': 2 mandatory leading positionals, THEN the 10 keyed options (argvec now exercises the valueless -join flag alongside -flag value pairs), THEN 3 mandatory trailing positionals. The 2/3 split is asymmetric on purpose - an even split could be satisfied by a parser that just halves the positional block. New namespace argparsingtest::sandwich with manual_switch, punkargs, punkargs_by_id, punkargs_parsecache, opt and argparse wrappers; return contract is {{p1 p2} {p3 p4 p5} optsdict} (grouped rather than the flat {p1 p2 opts} of the other positional styles, since positionals sit on both sides of the options)
#1.2.0 - sandwich style: cmdline, tepam, argp and parse_args are 'unsupported' (N/A rows) - each verified to fail on the style's argvec. cmdline is the notable one: cmdline::getoptions returns WITHOUT error having parsed nothing, leaving every option at its default and the argument list untouched #1.2.0 - sandwich style: cmdline, tepam, argp and parse_args are 'unsupported' (N/A rows) - each verified to fail on the style's argvec. cmdline is the notable one: cmdline::getoptions returns WITHOUT error having parsed nothing, leaving every option at its default and the argument list untouched
#1.2.0 - sandwich style: punk::args, opt and the manual baseline model the arrangement and reject options ahead of the leaders; argparse reaches the style only via -mixed, which permits switches anywhere and therefore parses the argvec correctly WITHOUT enforcing the arrangement (pinned by the sandwich_strictness / sandwich_argparse_is_permissive tests) #1.2.0 - sandwich style: punk::args, opt and the manual baseline model the arrangement and reject options ahead of the leaders; argparse reaches the style only via -mixed, which permits switches anywhere and therefore parses the argvec correctly WITHOUT enforcing the arrangement (pinned by the sandwich_strictness / sandwich_argparse_is_permissive tests)

88
src/tests/modules/argparsingtest/testsuites/argparsingtest/argparsingtest.test

@ -15,6 +15,20 @@ namespace eval ::testspace {
testConstraint parse_args_loaded [expr {![catch {package present parse_args}]}] testConstraint parse_args_loaded [expr {![catch {package present parse_args}]}]
testConstraint argparse_loaded [expr {![catch {package present argparse}]}] testConstraint argparse_loaded [expr {![catch {package present argparse}]}]
#added 2026-07-28 (agent) - opt, cmdline and tepam are optional too (module 1.3.0 stopped
#hard-requiring them: a comparison harness must still load on a build without tcllib), so any
#test naming parsers explicitly has to drop the ones this runtime cannot load
proc loaded_parsers {style names} {
set disco [dict get [argparsingtest::discover_parsers -style $style] $style]
set out {}
foreach n $names {
if {[dict exists $disco $n] && [dict get $disco $n] eq "loaded"} {
lappend out $n
}
}
return $out
}
#added 2026-07-18 (agent) - suite rewritten for the argparsingtest 1.0.0 restructure: #added 2026-07-18 (agent) - suite rewritten for the argparsingtest 1.0.0 restructure:
#parser procs live in per-style namespaces (opts/tkstyle/tclstyle), harness results are keyed by style #parser procs live in per-style namespaces (opts/tkstyle/tclstyle), harness results are keyed by style
#Split 2026-07-19 (G-092 - parallel-floor reduction, tests moved verbatim): this file holds #Split 2026-07-19 (G-092 - parallel-floor reduction, tests moved verbatim): this file holds
@ -91,7 +105,9 @@ namespace eval ::testspace {
if {$ok eq 1 && [dict get $r opts manual_switch] ne "loaded"} { set ok "opts manual_switch status" } if {$ok eq 1 && [dict get $r opts manual_switch] ne "loaded"} { set ok "opts manual_switch status" }
if {$ok eq 1 && [dict get $r tkstyle cmdline_typed] ne "unsupported"} { set ok "tkstyle cmdline_typed status" } if {$ok eq 1 && [dict get $r tkstyle cmdline_typed] ne "unsupported"} { set ok "tkstyle cmdline_typed status" }
if {$ok eq 1 && [dict get $r tkstyle argp] ne "unsupported"} { set ok "tkstyle argp status" } if {$ok eq 1 && [dict get $r tkstyle argp] ne "unsupported"} { set ok "tkstyle argp status" }
if {$ok eq 1 && [dict get $r tclstyle cmdline_typed] ne "loaded"} { set ok "tclstyle cmdline_typed status" } #tclstyle CAN express cmdline, so there the status tracks whether the package is installed
set expect_cmdline [expr {[catch {package present cmdline}] ? "not_loaded" : "loaded"}]
if {$ok eq 1 && [dict get $r tclstyle cmdline_typed] ne $expect_cmdline} { set ok "tclstyle cmdline_typed status" }
if {$ok eq 1 && [dict get $r tclstyle argp] ne "unsupported"} { set ok "tclstyle argp status" } if {$ok eq 1 && [dict get $r tclstyle argp] ne "unsupported"} { set ok "tclstyle argp status" }
if {$ok eq 1 && [dict exists $r opts test1_switch]} { set ok "stale test1_switch key present" } if {$ok eq 1 && [dict exists $r opts test1_switch]} { set ok "stale test1_switch key present" }
set ok set ok
@ -105,6 +121,10 @@ namespace eval ::testspace {
foreach {pkg pname styles} { foreach {pkg pname styles} {
parse_args parse_args {opts tclstyle} parse_args parse_args {opts tclstyle}
argparse argparse {opts tkstyle tclstyle sandwich} argparse argparse {opts tkstyle tclstyle sandwich}
opt opt {opts tkstyle tclstyle sandwich}
cmdline cmdline_untyped {opts tclstyle}
cmdline cmdline_typed {opts tclstyle}
tepam tepam {opts tkstyle tclstyle}
} { } {
set expected [expr {[catch {package present $pkg}] ? "not_loaded" : "loaded"}] set expected [expr {[catch {package present $pkg}] ? "not_loaded" : "loaded"}]
foreach s $styles { foreach s $styles {
@ -128,6 +148,66 @@ namespace eval ::testspace {
set ok set ok
} -result 1 } -result 1
#added 2026-07-28 (agent) - regression pin for the 1.3.0 change: the module used to hard-require
#opt, cmdline and tepam, so 'package require argparsingtest' died outright with "can't find
#package opt" on a punkshell build without tcllib - a comparison harness unloadable on exactly
#the runtime you wanted to measure. Exercised in a child interp with an emptied auto_path, which
#is where tcllib's pkgIndex-based packages come from. If a runtime provides any of the three as a
#.tm on a module path this degrades to asserting the module still loads, which is the main claim.
test module_loads_without_optional_parser_packages {Test that the module loads when opt, cmdline and tepam are unavailable} -body {
set tm_paths [tcl::tm::list]
#pin to the parent's versions - a plain require prefers a stable copy over the 999999.0a1.0 source module
set pinned ""
foreach pkg {punk::args punk::lib argparsingtest} {
if {![catch {package present $pkg} ver]} {
append pinned "package require -exact [list $pkg] [list $ver]\n"
}
}
set child [interp create]
try {
set child_tm [interp eval $child {tcl::tm::list}]
if {[llength $child_tm]} {
interp eval $child [list tcl::tm::path remove {*}$child_tm]
}
if {[llength $tm_paths]} {
interp eval $child [list tcl::tm::path add {*}$tm_paths]
}
interp eval $child [list set ::auto_path [list]]
set result [interp eval $child [string cat $pinned {
set absent {}
foreach p {opt cmdline tepam} {
if {[catch {package present $p}]} { lappend absent $p }
}
set disco [dict get [argparsingtest::discover_parsers -style opts] opts]
set statuses {}
set stillcommands {}
foreach {pname pkg} {opt opt cmdline_untyped cmdline cmdline_typed cmdline tepam tepam} {
if {$pkg in $absent} {
lappend statuses $pname [dict get $disco $pname]
}
}
#opt and tepam DEFINE their wrapper procs, so those must not exist when absent
foreach {pname pkg} {opt opt tepam tepam} {
if {$pkg in $absent && [llength [info commands ::argparsingtest::opts::$pname]]} {
lappend stillcommands $pname
}
}
list loaded [package present argparsingtest] absent $absent statuses $statuses stillcommands $stillcommands
}]]
} finally {
interp delete $child
}
set ok 1
if {[dict get $result loaded] eq ""} { set ok "child did not load argparsingtest" }
if {$ok eq 1 && [llength [dict get $result stillcommands]] } { set ok "wrapper procs defined without their package: [dict get $result stillcommands]" }
if {$ok eq 1} {
foreach {pname status} [dict get $result statuses] {
if {$status ne "not_loaded"} { set ok "$pname reported $status with its package absent" ; break }
}
}
set ok
} -result 1
#added 2026-07-26 (agent) - opts-style external wrappers agree with the hand-rolled baseline's option values #added 2026-07-26 (agent) - opts-style external wrappers agree with the hand-rolled baseline's option values
test parse_args_opts_values {Test that the parse_args opts wrapper returns the declared option values} -constraints parse_args_loaded -body { test parse_args_opts_values {Test that the parse_args opts wrapper returns the declared option values} -constraints parse_args_loaded -body {
set r [argparsingtest::opts::parse_args -return object -x hello -y world -1 1 -2 2 -3 3] set r [argparsingtest::opts::parse_args -return object -x hello -y world -1 1 -2 2 -3 3]
@ -204,7 +284,7 @@ namespace eval ::testspace {
test sandwich_strictness {Test that the modelling sandwich parsers reject options before the leaders} -body { test sandwich_strictness {Test that the modelling sandwich parsers reject options before the leaders} -body {
set badvec {-x hello -join alpha beta gamma delta epsilon} set badvec {-x hello -join alpha beta gamma delta epsilon}
set ok 1 set ok 1
foreach pname {manual_switch punkargs punkargs_by_id punkargs_parsecache opt} { foreach pname [loaded_parsers sandwich {manual_switch punkargs punkargs_by_id punkargs_parsecache opt}] {
if {![catch {argparsingtest::sandwich::$pname {*}$badvec} r]} { if {![catch {argparsingtest::sandwich::$pname {*}$badvec} r]} {
set ok "$pname accepted options-before-leaders: $r" set ok "$pname accepted options-before-leaders: $r"
break break
@ -237,7 +317,7 @@ namespace eval ::testspace {
#added 2026-07-17 (agent) #added 2026-07-17 (agent)
test first_call_library_backed {Test that first_call returns cold and warm float timings for library-backed parsers (warm-up scripts must run cleanly)} -body { test first_call_library_backed {Test that first_call returns cold and warm float timings for library-backed parsers (warm-up scripts must run cleanly)} -body {
set r [argparsingtest::first_call -style opts -parsers {punkargs punkargs_by_id opt cmdline_untyped cmdline_typed tepam}] set r [argparsingtest::first_call -style opts -parsers [loaded_parsers opts {punkargs punkargs_by_id opt cmdline_untyped cmdline_typed tepam}]]
set ok 1 set ok 1
foreach {pname sub} [dict get $r opts] { foreach {pname sub} [dict get $r opts] {
foreach mode {cold warm} { foreach mode {cold warm} {
@ -254,7 +334,7 @@ namespace eval ::testspace {
test first_call_positional_styles {Test first_call cold and warm for tkstyle, tclstyle and sandwich parsers} -body { test first_call_positional_styles {Test first_call cold and warm for tkstyle, tclstyle and sandwich parsers} -body {
set ok 1 set ok 1
foreach {s plist} {tkstyle {punkargs_by_id tepam} tclstyle {cmdline_untyped} sandwich {manual_switch punkargs_by_id opt}} { foreach {s plist} {tkstyle {punkargs_by_id tepam} tclstyle {cmdline_untyped} sandwich {manual_switch punkargs_by_id opt}} {
set r [argparsingtest::first_call -style $s -parsers $plist] set r [argparsingtest::first_call -style $s -parsers [loaded_parsers $s $plist]]
foreach {pname sub} [dict get $r $s] { foreach {pname sub} [dict get $r $s] {
foreach mode {cold warm} { foreach mode {cold warm} {
if {![dict exists $sub $mode]} { set ok "missing $mode for $s $pname" ; break } if {![dict exists $sub $mode]} { set ok "missing $mode for $s $pname" ; break }

29
src/tools/punkzip/PROVENANCE.md

@ -2,8 +2,12 @@
## Origin ## Origin
- Upstream repository: `c:/repo/jn/zig/punkzip` (git; remote - Upstream repository: punkzip (git; remote
`https://www.gitea1.intx.com.au/jn/punkzip`) `https://www.gitea1.intx.com.au/jn/punkzip`). The working checkout is expected as
a sibling of this repository, at `../zig/punkzip` relative to the punkshell repo
root. That is a layout convention, not a requirement - if no checkout is present
there, clone the remote to that location; the Vendored state commit below
identifies the exact upstream state in any clone.
- Vendored state: commit `0882f0373eb2c983142e713c814b91aa82cfcea7` (punkzip v2.3.1, - Vendored state: commit `0882f0373eb2c983142e713c814b91aa82cfcea7` (punkzip v2.3.1,
2026-07-27; upstream working tree clean at copy time) 2026-07-27; upstream working tree clean at copy time)
- Vendored: 2026-07-27 for goal G-126 (see `goals/G-126-punkzip-accelerator.md`) - Vendored: 2026-07-27 for goal G-126 (see `goals/G-126-punkzip-accelerator.md`)
@ -35,20 +39,19 @@ fork boundary stays clean and every vendored state corresponds to an upstream co
## Re-vendor procedure ## Re-vendor procedure
From a CLEAN upstream checkout (commit upstream first; a dirty copy has no committed From a CLEAN upstream checkout (commit upstream first; a dirty copy has no committed
provenance): provenance). All commands run from the punkshell repo root, with the upstream
checkout at its expected sibling location `../zig/punkzip` (see Origin):
cd c:/repo/jn/zig/punkzip git -C ../zig/punkzip status --short # must be empty
git status --short # must be empty git -C ../zig/punkzip rev-parse HEAD # record as the new Vendored state above
git rev-parse HEAD # record as the new Vendored state above
# from the punkshell repo root:
rm -rf src/tools/punkzip/src rm -rf src/tools/punkzip/src
cp c:/repo/jn/zig/punkzip/build.zig src/tools/punkzip/ cp ../zig/punkzip/build.zig src/tools/punkzip/
cp c:/repo/jn/zig/punkzip/build.zig.zon src/tools/punkzip/ cp ../zig/punkzip/build.zig.zon src/tools/punkzip/
cp c:/repo/jn/zig/punkzip/LICENSE src/tools/punkzip/ cp ../zig/punkzip/LICENSE src/tools/punkzip/
cp c:/repo/jn/zig/punkzip/LICENSE-time-dot-zig src/tools/punkzip/ cp ../zig/punkzip/LICENSE-time-dot-zig src/tools/punkzip/
cp c:/repo/jn/zig/punkzip/README.md src/tools/punkzip/ cp ../zig/punkzip/README.md src/tools/punkzip/
cp -r c:/repo/jn/zig/punkzip/src src/tools/punkzip/src cp -r ../zig/punkzip/src src/tools/punkzip/src
# verify with the pinned toolchain (zig build test must pass; the gate is the # verify with the pinned toolchain (zig build test must pass; the gate is the
# exit code - the zip suite's negative tests print EOCD warnings while passing): # exit code - the zip suite's negative tests print EOCD warnings while passing):

Loading…
Cancel
Save