Browse Source

bootsupport and vendormodule minor tidy/update

master
Julian Noble 4 days ago
parent
commit
bdef7af0bb
  1. 195
      src/bootsupport/modules/oolib-0.1.tm
  2. 44
      src/bootsupport/modules/punk-0.1.tm
  3. 63
      src/bootsupport/modules/punk/char-0.1.0.tm
  4. 7
      src/bootsupport/modules/punk/mix/cli-0.3.1.tm
  5. 25
      src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm
  6. 3209
      src/bootsupport/modules/shellfilter-0.1.9.tm
  7. 99
      src/bootsupport/modules/textblock-0.1.3.tm
  8. 6
      src/bootsupport/modules/uuid-1.0.9.tm
  9. BIN
      src/bootsupport/modules/zipper-0.12.tm
  10. 3
      src/modules/#modpod-zipper-999999.0a1.0/zipper-999999.0a1.0.tm
  11. 87
      src/modules/punk/mix-0.1.tm
  12. 7
      src/modules/punk/mix/cli-999999.0a1.0.tm
  13. 44
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk-0.1.tm
  14. 63
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/char-0.1.0.tm
  15. 7
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm
  16. 25
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm
  17. 99
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.3.tm
  18. 6
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/uuid-1.0.9.tm
  19. BIN
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/zipper-0.12.tm
  20. 44
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk-0.1.tm
  21. 63
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/char-0.1.0.tm
  22. 7
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm
  23. 25
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm
  24. 99
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.3.tm
  25. 5
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/uuid-1.0.9.tm
  26. BIN
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/zipper-0.12.tm
  27. 702
      src/vendormodules/modpod-0.1.2.tm
  28. 4773
      src/vendormodules/overtype-1.6.5.tm
  29. 643
      src/vendormodules/packagetrace-0.8.tm
  30. 245
      src/vendormodules/uuid-1.0.9.tm
  31. BIN
      src/vfs/_vfscommon.vfs/modules/modpodtest-0.1.0.tm
  32. 2
      src/vfs/_vfscommon.vfs/modules/punk/char-0.1.0.tm
  33. 7
      src/vfs/_vfscommon.vfs/modules/punk/mix/cli-0.3.1.tm
  34. 245
      src/vfs/_vfscommon.vfs/modules/uuid-1.0.9.tm
  35. BIN
      src/vfs/_vfscommon.vfs/modules/zipper-0.12.tm

195
src/bootsupport/modules/oolib-0.1.tm

@ -1,195 +0,0 @@
#JMN - api should be kept in sync with package patternlib where possible
#
package provide oolib [namespace eval oolib {
variable version
set version 0.1
}]
namespace eval oolib {
oo::class create collection {
variable o_data ;#dict
variable o_alias
constructor {} {
set o_data [dict create]
}
method info {} {
return [dict info $o_data]
}
method count {} {
return [dict size $o_data]
}
method isEmpty {} {
expr {[dict size $o_data] == 0}
}
method names {{globOrIdx {}}} {
if {[llength $globOrIdx]} {
if {[string is integer -strict $globOrIdx]} {
if {$idx < 0} {
set idx "end-[expr {abs($idx + 1)}]"
}
if {[catch {lindex [dict keys $o_data] $idx} result]} {
error "[self object] no such index : '$idx'"
} else {
return $result
}
} else {
#glob
return [lsearch -glob -all -inline [dict keys $o_data] $globOrIdx]
}
} else {
return [dict keys $o_data]
}
}
#like names but without globbing
method keys {} {
dict keys $o_data
}
method key {{posn 0}} {
if {$posn < 0} {
set posn "end-[expr {abs($posn + 1)}]"
}
if {[catch {lindex [dict keys $o_data] $posn} result]} {
error "[self object] no such index : '$posn'"
} else {
return $result
}
}
method hasKey {key} {
dict exists $o_data $key
}
method get {} {
return $o_data
}
method items {} {
return [dict values $o_data]
}
method item {key} {
if {[string is integer -strict $key]} {
if {$key > 0} {
set valposn [expr {(2*$key) +1}]
return [lindex $o_data $valposn]
} else {
set key "end-[expr {abs($key + 1)}]"
return [lindex [dict keys $o_data] $key]
}
}
if {[dict exists $o_data $key]} {
return [dict get $o_data $key]
}
}
#inverse lookup
method itemKeys {value} {
set value_indices [lsearch -all [dict values $o_data] $value]
set keylist [list]
foreach i $value_indices {
set idx [expr {(($i + 1) *2) -2}]
lappend keylist [lindex $o_data $idx]
}
return $keylist
}
method search {value args} {
set matches [lsearch {*}$args [dict values $o_data] $value]
if {"-inline" in $args} {
return $matches
} else {
set keylist [list]
foreach i $matches {
set idx [expr {(($i + 1) *2) -2}]
lappend keylist [lindex $o_data $idx]
}
return $keylist
}
}
#review - see patternlib. Is the intention for aliases to be configurable independent of whether the target exists?
method alias {newAlias existingKeyOrAlias} {
if {[string is integer -strict $newAlias]} {
error "[self object] collection key alias cannot be integer"
}
if {[string length $existingKeyOrAlias]} {
set o_alias($newAlias) $existingKeyOrAlias
} else {
unset o_alias($newAlias)
}
}
method aliases {{key ""}} {
if {[string length $key]} {
set result [list]
foreach {n v} [array get o_alias] {
if {$v eq $key} {
lappend result $n $v
}
}
return $result
} else {
return [array get o_alias]
}
}
#if the supplied index is an alias, return the underlying key; else return the index supplied.
method realKey {idx} {
if {[catch {set o_alias($idx)} key]} {
return $idx
} else {
return $key
}
}
method add {value key} {
if {[string is integer -strict $key]} {
error "[self object] collection key must not be an integer. Use another structure if integer keys required"
}
if {[dict exists $o_data $key]} {
error "[self object] col_processors object error: key '$key' already exists in collection"
}
dict set o_data $key $value
return [expr {[dict size $o_data] - 1}] ;#return index of item
}
method remove {idx {endRange ""}} {
if {[string length $endRange]} {
error "[self object] collection error: ranged removal not yet implemented.. remove one item at a time"
}
if {[string is integer -strict $idx]} {
if {$idx < 0} {
set idx "end-[expr {abs($idx+1)}]"
}
set key [lindex [dict keys $o_data] $idx]
set posn $idx
} else {
set key $idx
set posn [lsearch -exact [dict keys $o_data] $key]
if {$posn < 0} {
error "[self object] no such index: '$idx' in this collection"
}
}
dict unset o_data $key
return
}
method clear {} {
set o_data [dict create]
return
}
method reverse {} {
set dictnew [dict create]
foreach k [lreverse [dict keys $o_data]] {
dict set dictnew $k [dict get $o_data $k]
}
set o_data $dictnew
return
}
#review - cmd as list vs cmd as script?
method map {cmd} {
set seed [list]
dict for {k v} $o_data {
lappend seed [uplevel #0 [list {*}$cmd $v]]
}
return $seed
}
method objectmap {cmd} {
set seed [list]
dict for {k v} $o_data {
lappend seed [uplevel #0 [list $v {*}$cmd]]
}
return $seed
}
}
}

44
src/bootsupport/modules/punk-0.1.tm

@ -8259,9 +8259,29 @@ namespace eval punk {
interp alias {} d/~ {} punk::nav::fs::d/~
interp alias "" x/ "" punk::nav::fs::x/
variable pshell_path ""
# ----------------------------------------
set pshell_path [auto_execok pwsh] ;#Still not installed by default on win10 11?
if {$pshell_path eq ""} {
#fallback to powershell 5
#set pshell_path [auto_execok powershell]
set pshell_path powershell ;#temp
} else {
set pshell_path pwsh ;#temp
}
#todo - review run commands and handling of paths with spaces
# ----------------------------------------
if {$::tcl_platform(platform) eq "windows"} {
if {$pshell_path eq ""} {
set has_powershell 0
} else {
#todo - review powershell detection on non-windows platforms
set has_powershell 1
}
if {$::tcl_platform(platform) eq "windows"} {
interp alias {} dl {} dir /q
interp alias {} dw {} dir /W/D
} else {
@ -8269,8 +8289,6 @@ namespace eval punk {
#interp alias {} dl {}
interp alias {} dl {} puts stderr "not implemented"
interp alias {} dw {} puts stderr "not implemented"
#todo - powershell detection on other platforms
set has_powershell 0
}
#todo - distinguish non-preinstalled pwsh (powershell core) from powershell which is available by default
@ -8279,13 +8297,19 @@ namespace eval punk {
# powershell runspaces e.g $rs=[RunspaceFactory]::CreateRunspace()
# $ps = [Powershell]::Create()
interp alias {} pse {} exec >@stdout pwsh -nolo -nop -c
interp alias {} psx {} runx -n pwsh -nop -nolo -c
interp alias {} psr {} run -n pwsh -nop -nolo -c
interp alias {} psout {} runout -n pwsh -nop -nolo -c
interp alias {} pserr {} runerr -n pwsh -nop -nolo -c
interp alias {} psls {} shellrun::runconsole pwsh -nop -nolo -c ls
interp alias {} psps {} shellrun::runconsole pwsh -nop -nolo -c ps
interp alias {} pse {} exec >@stdout {*}$pshell_path -nolo -nop -c
interp alias {} psx {} runx -n {*}$pshell_path -nop -nolo -c
interp alias {} psr {} run -n {*}$pshell_path -nop -nolo -c
interp alias {} psout {} runout -n {*}$pshell_path -nop -nolo -c
interp alias {} pserr {} runerr -n {*}$pshell_path -nop -nolo -c
#interp alias {} psls {} shellrun::runconsole $pshell_path -nop -nolo -c ls
#interp alias {} psls {} shellrun::runconsole {*}$pshell_path -nop -nolo -c {ls | Select-Object Mode, @{Name='Owner';Expression={(Get-Acl $_.FullName).Owner}}, LastWriteTime, Length, Name | Format-Table}
proc psls args {
variable pshell_path
shellrun::runconsole {*}$pshell_path -nop -nolo -c {*}[string map [list %a% $args] {{ls %a% | Select-Object Mode, @{Name='Owner';Expression={(Get-Acl $_.FullName).Owner}}, LastWriteTime, Length, Name | Format-Table}}]
}
interp alias {} psls {} punk::psls
interp alias {} psps {} shellrun::runconsole {*}$pshell_path -nop -nolo -c ps
} else {
set ps_missing "powershell missing (powershell is MIT licensed open source and can be installed on windows and most unix-like platforms)"
interp alias {} pse {} puts stderr $ps_missing

63
src/bootsupport/modules/punk/char-0.1.0.tm

@ -2761,6 +2761,69 @@ tcl::namespace::eval punk::char {
}
tcl::namespace::eval punk::char::lib {
variable num_superscript
#digits and a small set of related symbols
set num_superscript [list\
i \u2071\
0 \u2070\
1 \u00B9\
2 \u00B2\
3 \u00B3\
4 \u2074\
5 \u2075\
6 \u2076\
7 \u2077\
8 \u2078\
9 \u2079\
+ \u207A\
- \u207B\
= \u207C\
( \u207D\
) \u207E\
n \u207F\
]
variable num_supersub_re
set num_supersub_re {^[0-9in+\-\(\)\=]+$}
proc superscript_number {n} {
if {$n eq ""} {return ""}
variable num_superscript
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to superscript. valid chars: [dict keys $num_superscript]"
}
return [string map $num_superscript $n]
}
set num_subscript [list\
i \u1D62\
0 \u2080\
1 \u2081\
2 \u2082\
3 \u2083\
4 \u2084\
5 \u2085\
6 \u2086\
7 \u2087\
8 \u2088\
9 \u2089\
+ \u208A\
- \u208B\
= \u208C\
( \u208D\
) \u208E\
n \u2099\
]
proc subscript_number {n} {
if {$n eq ""} {return ""}
variable num_subscript
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to subcript. valid chars: [dict keys $num_subscript]"
}
return [string map $num_subscript $n]
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++

7
src/bootsupport/modules/punk/mix/cli-0.3.1.tm

@ -759,7 +759,7 @@ namespace eval punk::mix::cli {
}
} else {
puts -nonewline stderr "P"
puts -nonewline stderr "Z"
set did_skip 1
#set file_record [punkcheck::installfile_skipped_install $basedir $file_record]
$build_event targetset_end SKIPPED
@ -791,7 +791,7 @@ namespace eval punk::mix::cli {
$event targetset_end OK -note "zip modpod"
}
} else {
puts -nonewline stderr "p"
puts -nonewline stderr "z"
set did_skip 1
if {$is_interesting} {
puts stderr "$modulefile [$event targetset_source_changes]"
@ -802,7 +802,8 @@ namespace eval punk::mix::cli {
}
tarjar {
#basename may still contain #tarjar-
#to be obsoleted - update modpod to (optionally) use vfs::tar
#to be obsoleted - update modpod to (optionally) use vfs::tar ?
}
file {
set m $modpath

25
src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm

@ -257,6 +257,24 @@ namespace eval punk::mix::commandset::scriptwrap {
set target_labels_found [dict create]
set possible_target_labels_found [dict create]
set warning_target_labels_found [dict create]
#todo - allow analysis of colon-less call. May need to check list of internal commands - but what about external ones?
#set searchregexex [list {(.*\s+|^)(@*call\s*:*)(\S.*)} {(.*\s+|^)(@*CALL\s*:*)(\S.*)} {(.*\s+|^)(@*goto\s*:*)(\S.*)} {(.*\s+|^)(@*GOTO\s*:*)(\S.*)}]
#order of regex testing is important - test more specific entries with colon/comment before we test whitespace only version of goto/call
set searchregexes [list {(.*\s+|^)(@*call\s*:)(\S.*)} {(.*\s+|^)(@*CALL\s*:)(\S.*)} {(.*\s+|^)(@*goto\s*:)(\S.*)} {(.*\s*|.*\s+|^)(@*GOTO\s*:)(\S.*)}]
lappend searchregexes {(.*\|\|.*)(@*GOTO\s*:)(\S.*)} ;#review
lappend searchregexes {(.*\s+|^)(@*goto\s+%=.*=%\s*:)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*goto\s+%=.*=%\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*goto\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+%=.*=%\s*:)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+%=.*=%\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+)(\S.*)}
#review
#todo - better callsite analysis. There can be data between @GOTO or @CALL and : other than just whitespace
#e.g for @goto %= possible comment=% :mylabe%%l etc
for {set callingline_index 0} {$callingline_index < $line_count} {incr callingline_index} {
set callingline_info [$objFile lineinfo $callingline_index]
set callingline_payload [dict get $callingline_info payload]
@ -273,17 +291,14 @@ namespace eval punk::mix::commandset::scriptwrap {
}
default {
#todo - better callsite analysis. There can be data between @GOTO or @CALL and : other than just whitespace!
#todo - allow analysis of colon-less call. May need to check list of internal commands - but what about external ones?
#foreach search_regex [list {(.*\s+|^)(@*call\s*:*)(\S.*)} {(.*\s+|^)(@*CALL\s*:*)(\S.*)} {(.*\s+|^)(@*goto\s*:*)(\S.*)} {(.*\s+|^)(@*GOTO\s*:*)(\S.*)}] {}
foreach search_regex [list {(.*\s+|^)(@*call\s*:)(\S.*)} {(.*\s+|^)(@*CALL\s*:)(\S.*)} {(.*\s+|^)(@*goto\s*:)(\S.*)} {(.*\s*|.*\s+|^)(@*GOTO\s*:)(\S.*)} {(.*\|\|.*)(@*GOTO\s*:)(\S.*)}] {
foreach search_regex $searchregexes {
if {[regexp $search_regex $callingline_payload _m precall call labelplus]} {
#todo further checks to see if it's actually a batch script line
# - - - - work out what cmd.exe considers start of 512B boundaries when scanning from a callsite
#callposn affected by newlines?
#set callposn [expr {$file_offset + [string length $callingline_payload]}] ;#take callposn as end of line .. review - multiline statements?
set callposn [expr {$file_offset + $callingline_len}]
set callposn [expr {$file_offset + $callingline_len -1}]
#Note there are anomalies around target labels in bracketed sections such as IF blocks
#this is bad practice - as it can lead to unbalanced braces - but batch files can still work under cmd.exe with them in some cases

3209
src/bootsupport/modules/shellfilter-0.1.9.tm

File diff suppressed because it is too large Load Diff

99
src/bootsupport/modules/textblock-0.1.3.tm

@ -4206,7 +4206,7 @@ tcl::namespace::eval textblock {
}
#examples ptable.com
set elements [list\
set elements_layout [list\
1 H "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" He\
2 Li Be "" "" "" "" "" "" "" "" "" "" B C N O F Ne\
3 Na Mg "" "" "" "" "" "" "" "" "" "" Al Si P S Cl Ar\
@ -4218,6 +4218,76 @@ tcl::namespace::eval textblock {
"" "" "" 6 La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu\
"" "" "" 7 Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr\
]
#generate list of elements ordered by atomic number from the layout table (0 based - so atomic number is +1)
#create a lookup dict from symbol to atomic number at same time
set elements [list]
set e_atomic [dict create]
set e_group [dict create]
set e_period [dict create]
set atomic 0 ;#first, H, will be 1
set period 0
set group 0
foreach e $elements_layout {
if {[string trim $e] eq ""} {
switch -- $period {
6a {
set period "6c"
set atomic 71 ;#next is Hf=72
}
7a {
set period "7c"
set atomic 103 ;#next is Rf=104
}
}
if {$group == 18} {
#handle rows of blanks
set group 0
} else {
incr group
}
continue
}
if {[string is digit -strict $e]} {
if {$period in {0 1 2 3 4}} {
set period $e
} else {
switch -- $period {
5 {
set period 6a
}
6c {
set period 7a
}
6b {
set period 7b
set atomic 88 ;#next is Ac=89
}
7c {
set period 6b
set atomic 56 ;#next is La=57
}
}
}
incr group
continue
}
incr atomic
lappend elements $e
dict set e_atomic $e $atomic
dict set e_group $e $group
dict set e_period $e [string index $period 0]
if {$group == 18} {
set group 0 ;#false group 0 for first column of period numbers
} else {
incr group
}
}
#test no screwup above
if {[dict get $e_atomic Og] ne "118" || [dict get $e_atomic Lr] ne "103"} {
error "textblock::periodic programming error Og->[dict get $e_atomic Og] Lr->[dict get $e_atomic Lr] should be Og->118 Lr->103"
}
set type_colours [list]
@ -4297,20 +4367,35 @@ tcl::namespace::eval textblock {
tcl::dict::set ecat $e $val
}
set elements1 [list]
set elements_layout_coloured [list]
set RST [a+]
foreach e $elements {
if {[tcl::dict::get $opts -compact]} {
foreach e $elements_layout {
if {[tcl::dict::exists $ecat $e]} {
set ansi [tcl::dict::get $ecat $e ansi]
#lappend elements1 [textblock::pad $ansi$e -width 2 -which right]
#lappend elements_layout_coloured [textblock::pad $ansi$e -width 2 -which right]
#no need to pad here - table column_configure -textalign default of left will do the work of padding right anyway
lappend elements1 $ansi$e
lappend elements_layout_coloured $ansi$e
} else {
lappend elements1 $e
lappend elements_layout_coloured $e
}
}
} else {
foreach e $elements_layout {
if {[tcl::dict::exists $ecat $e]} {
set ansi [tcl::dict::get $ecat $e ansi]
#the atomic number should be a superscript as is the norm
#use subscript on line above
set a [punk::char::lib::subscript_number [tcl::dict::get $e_atomic $e]]
lappend elements_layout_coloured "$ansi$a\n $e "
} else {
lappend elements_layout_coloured $e
}
}
}
set t [list_as_table -columns 19 -return tableobject $elements1]
set t [list_as_table -columns 19 -return tableobject $elements_layout_coloured]
#(defaults to show_hseps 0)
#todo - keep simple table with symbols as base - map symbols to descriptions etc for more verbose table options

6
src/vendormodules/uuid-1.0.7.tm → src/bootsupport/modules/uuid-1.0.9.tm

@ -11,7 +11,7 @@
# Usage: uuid::uuid generate
# uuid::uuid equal $idA $idB
package require Tcl 8.5
package require Tcl 8.5 9
namespace eval uuid {
variable accel
@ -47,7 +47,7 @@ proc ::uuid::generate_tcl_machinfo {} {
# If we have /dev/urandom just stream 128 bits from that
###
if {[file exists /dev/urandom]} {
set fin [open /dev/urandom r]
set fin [open /dev/urandom rb]
binary scan [read $fin 128] H* machinfo
close $fin
} elseif {[catch {package require nettool}]} {
@ -236,7 +236,7 @@ namespace eval ::uuid {
unset e
}
package provide uuid 1.0.7
package provide uuid 1.0.9
# -------------------------------------------------------------------------
# Local variables:

BIN
src/bootsupport/modules/zipper-0.12.tm

Binary file not shown.

3
src/modules/#modpod-zipper-999999.0a1.0/zipper-999999.0a1.0.tm

@ -178,7 +178,8 @@ if {[info exists argv0] && [string match zipper-* [file tail $argv0]]} {
if {[file isfile $f]} {
regsub {^\./} $f {} f
set fd [open $f]
chan configure $fd -translation binary -encoding binary
#chan configure $fd -translation binary -encoding binary
chan configure $fd -translation binary -encoding iso8859-1
zipper::addentry $f [read $fd] [file mtime $f]
close $fd
} elseif {[file isdir $f]} {

87
src/modules/punk/mix-0.1.tm

@ -1,87 +0,0 @@
namespace eval punk::mix {
package require punk::lib
package require punk::mix_custom
proc runcli {args} {
if {![llength $args]} {
tailcall punk::mix::clicommands help
} else {
tailcall punk::mix::clicommands {*}$args
}
}
}
namespace eval punk::mix::clicommands {
namespace export help new
namespace ensemble create
namespace ensemble configure [namespace current] -unknown punk::mix::clicommands::_unknown
proc set_alias {cmdname} {
uplevel #0 [list interp alias {} $cmdname {} punk::mix::runcli]
}
proc _unknown {ns args} {
puts stderr "arglen:[llength $args]"
puts stdout "_unknown '$ns' '$args'"
list punk::mix::clicommands::help {*}$args
}
proc new {name} {
set curdir [pwd]
if {[file exists $curdir/$name]} {
error "Unable to create new project at $curdir/$name - file/folder already exists"
}
set base $curdir/$name
file mkdir $base
file mkdir $base/src
file mkdir $base/modules
}
}
punk::ensemble::extend punk::mix::clicommands punk::mix_custom
namespace eval punk::mix::clicommands {
proc help {args} {
#' **%ensemblecommand% help** *args*
#'
#' Help for ensemble commands in the command line interface
#'
#'
#' Arguments:
#'
#' * args - first word of args is the helptopic requested - usually a command name
#' - calling help with no arguments will list available commands
#'
#' Returns: help text (text)
#'
#' Examples:
#'
#' ```
#' %ensemblecommand% help <commandname>
#' ```
#'
#'
set commands [namespace export]
set helpstr ""
append helpstr "commands:\n"
foreach cmd $commands {
append helpstr " $cmd"
}
return $helpstr
}
}
package provide punk::mix [namespace eval punk::mix {
variable version
set version 0.1
}]

7
src/modules/punk/mix/cli-999999.0a1.0.tm

@ -759,7 +759,7 @@ namespace eval punk::mix::cli {
}
} else {
puts -nonewline stderr "P"
puts -nonewline stderr "Z"
set did_skip 1
#set file_record [punkcheck::installfile_skipped_install $basedir $file_record]
$build_event targetset_end SKIPPED
@ -791,7 +791,7 @@ namespace eval punk::mix::cli {
$event targetset_end OK -note "zip modpod"
}
} else {
puts -nonewline stderr "p"
puts -nonewline stderr "z"
set did_skip 1
if {$is_interesting} {
puts stderr "$modulefile [$event targetset_source_changes]"
@ -802,7 +802,8 @@ namespace eval punk::mix::cli {
}
tarjar {
#basename may still contain #tarjar-
#to be obsoleted - update modpod to (optionally) use vfs::tar
#to be obsoleted - update modpod to (optionally) use vfs::tar ?
}
file {
set m $modpath

44
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk-0.1.tm

@ -8259,9 +8259,29 @@ namespace eval punk {
interp alias {} d/~ {} punk::nav::fs::d/~
interp alias "" x/ "" punk::nav::fs::x/
variable pshell_path ""
# ----------------------------------------
set pshell_path [auto_execok pwsh] ;#Still not installed by default on win10 11?
if {$pshell_path eq ""} {
#fallback to powershell 5
#set pshell_path [auto_execok powershell]
set pshell_path powershell ;#temp
} else {
set pshell_path pwsh ;#temp
}
#todo - review run commands and handling of paths with spaces
# ----------------------------------------
if {$::tcl_platform(platform) eq "windows"} {
if {$pshell_path eq ""} {
set has_powershell 0
} else {
#todo - review powershell detection on non-windows platforms
set has_powershell 1
}
if {$::tcl_platform(platform) eq "windows"} {
interp alias {} dl {} dir /q
interp alias {} dw {} dir /W/D
} else {
@ -8269,8 +8289,6 @@ namespace eval punk {
#interp alias {} dl {}
interp alias {} dl {} puts stderr "not implemented"
interp alias {} dw {} puts stderr "not implemented"
#todo - powershell detection on other platforms
set has_powershell 0
}
#todo - distinguish non-preinstalled pwsh (powershell core) from powershell which is available by default
@ -8279,13 +8297,19 @@ namespace eval punk {
# powershell runspaces e.g $rs=[RunspaceFactory]::CreateRunspace()
# $ps = [Powershell]::Create()
interp alias {} pse {} exec >@stdout pwsh -nolo -nop -c
interp alias {} psx {} runx -n pwsh -nop -nolo -c
interp alias {} psr {} run -n pwsh -nop -nolo -c
interp alias {} psout {} runout -n pwsh -nop -nolo -c
interp alias {} pserr {} runerr -n pwsh -nop -nolo -c
interp alias {} psls {} shellrun::runconsole pwsh -nop -nolo -c ls
interp alias {} psps {} shellrun::runconsole pwsh -nop -nolo -c ps
interp alias {} pse {} exec >@stdout {*}$pshell_path -nolo -nop -c
interp alias {} psx {} runx -n {*}$pshell_path -nop -nolo -c
interp alias {} psr {} run -n {*}$pshell_path -nop -nolo -c
interp alias {} psout {} runout -n {*}$pshell_path -nop -nolo -c
interp alias {} pserr {} runerr -n {*}$pshell_path -nop -nolo -c
#interp alias {} psls {} shellrun::runconsole $pshell_path -nop -nolo -c ls
#interp alias {} psls {} shellrun::runconsole {*}$pshell_path -nop -nolo -c {ls | Select-Object Mode, @{Name='Owner';Expression={(Get-Acl $_.FullName).Owner}}, LastWriteTime, Length, Name | Format-Table}
proc psls args {
variable pshell_path
shellrun::runconsole {*}$pshell_path -nop -nolo -c {*}[string map [list %a% $args] {{ls %a% | Select-Object Mode, @{Name='Owner';Expression={(Get-Acl $_.FullName).Owner}}, LastWriteTime, Length, Name | Format-Table}}]
}
interp alias {} psls {} punk::psls
interp alias {} psps {} shellrun::runconsole {*}$pshell_path -nop -nolo -c ps
} else {
set ps_missing "powershell missing (powershell is MIT licensed open source and can be installed on windows and most unix-like platforms)"
interp alias {} pse {} puts stderr $ps_missing

63
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/char-0.1.0.tm

@ -2761,6 +2761,69 @@ tcl::namespace::eval punk::char {
}
tcl::namespace::eval punk::char::lib {
variable num_superscript
#digits and a small set of related symbols
set num_superscript [list\
i \u2071\
0 \u2070\
1 \u00B9\
2 \u00B2\
3 \u00B3\
4 \u2074\
5 \u2075\
6 \u2076\
7 \u2077\
8 \u2078\
9 \u2079\
+ \u207A\
- \u207B\
= \u207C\
( \u207D\
) \u207E\
n \u207F\
]
variable num_supersub_re
set num_supersub_re {^[0-9in+\-\(\)\=]+$}
proc superscript_number {n} {
if {$n eq ""} {return ""}
variable num_superscript
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to superscript. valid chars: [dict keys $num_superscript]"
}
return [string map $num_superscript $n]
}
set num_subscript [list\
i \u1D62\
0 \u2080\
1 \u2081\
2 \u2082\
3 \u2083\
4 \u2084\
5 \u2085\
6 \u2086\
7 \u2087\
8 \u2088\
9 \u2089\
+ \u208A\
- \u208B\
= \u208C\
( \u208D\
) \u208E\
n \u2099\
]
proc subscript_number {n} {
if {$n eq ""} {return ""}
variable num_subscript
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to subcript. valid chars: [dict keys $num_subscript]"
}
return [string map $num_subscript $n]
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++

7
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm

@ -759,7 +759,7 @@ namespace eval punk::mix::cli {
}
} else {
puts -nonewline stderr "P"
puts -nonewline stderr "Z"
set did_skip 1
#set file_record [punkcheck::installfile_skipped_install $basedir $file_record]
$build_event targetset_end SKIPPED
@ -791,7 +791,7 @@ namespace eval punk::mix::cli {
$event targetset_end OK -note "zip modpod"
}
} else {
puts -nonewline stderr "p"
puts -nonewline stderr "z"
set did_skip 1
if {$is_interesting} {
puts stderr "$modulefile [$event targetset_source_changes]"
@ -802,7 +802,8 @@ namespace eval punk::mix::cli {
}
tarjar {
#basename may still contain #tarjar-
#to be obsoleted - update modpod to (optionally) use vfs::tar
#to be obsoleted - update modpod to (optionally) use vfs::tar ?
}
file {
set m $modpath

25
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm

@ -257,6 +257,24 @@ namespace eval punk::mix::commandset::scriptwrap {
set target_labels_found [dict create]
set possible_target_labels_found [dict create]
set warning_target_labels_found [dict create]
#todo - allow analysis of colon-less call. May need to check list of internal commands - but what about external ones?
#set searchregexex [list {(.*\s+|^)(@*call\s*:*)(\S.*)} {(.*\s+|^)(@*CALL\s*:*)(\S.*)} {(.*\s+|^)(@*goto\s*:*)(\S.*)} {(.*\s+|^)(@*GOTO\s*:*)(\S.*)}]
#order of regex testing is important - test more specific entries with colon/comment before we test whitespace only version of goto/call
set searchregexes [list {(.*\s+|^)(@*call\s*:)(\S.*)} {(.*\s+|^)(@*CALL\s*:)(\S.*)} {(.*\s+|^)(@*goto\s*:)(\S.*)} {(.*\s*|.*\s+|^)(@*GOTO\s*:)(\S.*)}]
lappend searchregexes {(.*\|\|.*)(@*GOTO\s*:)(\S.*)} ;#review
lappend searchregexes {(.*\s+|^)(@*goto\s+%=.*=%\s*:)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*goto\s+%=.*=%\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*goto\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+%=.*=%\s*:)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+%=.*=%\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+)(\S.*)}
#review
#todo - better callsite analysis. There can be data between @GOTO or @CALL and : other than just whitespace
#e.g for @goto %= possible comment=% :mylabe%%l etc
for {set callingline_index 0} {$callingline_index < $line_count} {incr callingline_index} {
set callingline_info [$objFile lineinfo $callingline_index]
set callingline_payload [dict get $callingline_info payload]
@ -273,17 +291,14 @@ namespace eval punk::mix::commandset::scriptwrap {
}
default {
#todo - better callsite analysis. There can be data between @GOTO or @CALL and : other than just whitespace!
#todo - allow analysis of colon-less call. May need to check list of internal commands - but what about external ones?
#foreach search_regex [list {(.*\s+|^)(@*call\s*:*)(\S.*)} {(.*\s+|^)(@*CALL\s*:*)(\S.*)} {(.*\s+|^)(@*goto\s*:*)(\S.*)} {(.*\s+|^)(@*GOTO\s*:*)(\S.*)}] {}
foreach search_regex [list {(.*\s+|^)(@*call\s*:)(\S.*)} {(.*\s+|^)(@*CALL\s*:)(\S.*)} {(.*\s+|^)(@*goto\s*:)(\S.*)} {(.*\s*|.*\s+|^)(@*GOTO\s*:)(\S.*)} {(.*\|\|.*)(@*GOTO\s*:)(\S.*)}] {
foreach search_regex $searchregexes {
if {[regexp $search_regex $callingline_payload _m precall call labelplus]} {
#todo further checks to see if it's actually a batch script line
# - - - - work out what cmd.exe considers start of 512B boundaries when scanning from a callsite
#callposn affected by newlines?
#set callposn [expr {$file_offset + [string length $callingline_payload]}] ;#take callposn as end of line .. review - multiline statements?
set callposn [expr {$file_offset + $callingline_len}]
set callposn [expr {$file_offset + $callingline_len -1}]
#Note there are anomalies around target labels in bracketed sections such as IF blocks
#this is bad practice - as it can lead to unbalanced braces - but batch files can still work under cmd.exe with them in some cases

99
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.3.tm

@ -4206,7 +4206,7 @@ tcl::namespace::eval textblock {
}
#examples ptable.com
set elements [list\
set elements_layout [list\
1 H "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" He\
2 Li Be "" "" "" "" "" "" "" "" "" "" B C N O F Ne\
3 Na Mg "" "" "" "" "" "" "" "" "" "" Al Si P S Cl Ar\
@ -4218,6 +4218,76 @@ tcl::namespace::eval textblock {
"" "" "" 6 La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu\
"" "" "" 7 Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr\
]
#generate list of elements ordered by atomic number from the layout table (0 based - so atomic number is +1)
#create a lookup dict from symbol to atomic number at same time
set elements [list]
set e_atomic [dict create]
set e_group [dict create]
set e_period [dict create]
set atomic 0 ;#first, H, will be 1
set period 0
set group 0
foreach e $elements_layout {
if {[string trim $e] eq ""} {
switch -- $period {
6a {
set period "6c"
set atomic 71 ;#next is Hf=72
}
7a {
set period "7c"
set atomic 103 ;#next is Rf=104
}
}
if {$group == 18} {
#handle rows of blanks
set group 0
} else {
incr group
}
continue
}
if {[string is digit -strict $e]} {
if {$period in {0 1 2 3 4}} {
set period $e
} else {
switch -- $period {
5 {
set period 6a
}
6c {
set period 7a
}
6b {
set period 7b
set atomic 88 ;#next is Ac=89
}
7c {
set period 6b
set atomic 56 ;#next is La=57
}
}
}
incr group
continue
}
incr atomic
lappend elements $e
dict set e_atomic $e $atomic
dict set e_group $e $group
dict set e_period $e [string index $period 0]
if {$group == 18} {
set group 0 ;#false group 0 for first column of period numbers
} else {
incr group
}
}
#test no screwup above
if {[dict get $e_atomic Og] ne "118" || [dict get $e_atomic Lr] ne "103"} {
error "textblock::periodic programming error Og->[dict get $e_atomic Og] Lr->[dict get $e_atomic Lr] should be Og->118 Lr->103"
}
set type_colours [list]
@ -4297,20 +4367,35 @@ tcl::namespace::eval textblock {
tcl::dict::set ecat $e $val
}
set elements1 [list]
set elements_layout_coloured [list]
set RST [a+]
foreach e $elements {
if {[tcl::dict::get $opts -compact]} {
foreach e $elements_layout {
if {[tcl::dict::exists $ecat $e]} {
set ansi [tcl::dict::get $ecat $e ansi]
#lappend elements1 [textblock::pad $ansi$e -width 2 -which right]
#lappend elements_layout_coloured [textblock::pad $ansi$e -width 2 -which right]
#no need to pad here - table column_configure -textalign default of left will do the work of padding right anyway
lappend elements1 $ansi$e
lappend elements_layout_coloured $ansi$e
} else {
lappend elements1 $e
lappend elements_layout_coloured $e
}
}
} else {
foreach e $elements_layout {
if {[tcl::dict::exists $ecat $e]} {
set ansi [tcl::dict::get $ecat $e ansi]
#the atomic number should be a superscript as is the norm
#use subscript on line above
set a [punk::char::lib::subscript_number [tcl::dict::get $e_atomic $e]]
lappend elements_layout_coloured "$ansi$a\n $e "
} else {
lappend elements_layout_coloured $e
}
}
}
set t [list_as_table -columns 19 -return tableobject $elements1]
set t [list_as_table -columns 19 -return tableobject $elements_layout_coloured]
#(defaults to show_hseps 0)
#todo - keep simple table with symbols as base - map symbols to descriptions etc for more verbose table options

6
src/bootsupport/modules/uuid-1.0.7.tm → src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/uuid-1.0.9.tm

@ -11,7 +11,7 @@
# Usage: uuid::uuid generate
# uuid::uuid equal $idA $idB
package require Tcl 8.5
package require Tcl 8.5 9
namespace eval uuid {
variable accel
@ -47,7 +47,7 @@ proc ::uuid::generate_tcl_machinfo {} {
# If we have /dev/urandom just stream 128 bits from that
###
if {[file exists /dev/urandom]} {
set fin [open /dev/urandom r]
set fin [open /dev/urandom rb]
binary scan [read $fin 128] H* machinfo
close $fin
} elseif {[catch {package require nettool}]} {
@ -236,7 +236,7 @@ namespace eval ::uuid {
unset e
}
package provide uuid 1.0.7
package provide uuid 1.0.9
# -------------------------------------------------------------------------
# Local variables:

BIN
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/zipper-0.12.tm

Binary file not shown.

44
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk-0.1.tm

@ -8259,9 +8259,29 @@ namespace eval punk {
interp alias {} d/~ {} punk::nav::fs::d/~
interp alias "" x/ "" punk::nav::fs::x/
variable pshell_path ""
# ----------------------------------------
set pshell_path [auto_execok pwsh] ;#Still not installed by default on win10 11?
if {$pshell_path eq ""} {
#fallback to powershell 5
#set pshell_path [auto_execok powershell]
set pshell_path powershell ;#temp
} else {
set pshell_path pwsh ;#temp
}
#todo - review run commands and handling of paths with spaces
# ----------------------------------------
if {$::tcl_platform(platform) eq "windows"} {
if {$pshell_path eq ""} {
set has_powershell 0
} else {
#todo - review powershell detection on non-windows platforms
set has_powershell 1
}
if {$::tcl_platform(platform) eq "windows"} {
interp alias {} dl {} dir /q
interp alias {} dw {} dir /W/D
} else {
@ -8269,8 +8289,6 @@ namespace eval punk {
#interp alias {} dl {}
interp alias {} dl {} puts stderr "not implemented"
interp alias {} dw {} puts stderr "not implemented"
#todo - powershell detection on other platforms
set has_powershell 0
}
#todo - distinguish non-preinstalled pwsh (powershell core) from powershell which is available by default
@ -8279,13 +8297,19 @@ namespace eval punk {
# powershell runspaces e.g $rs=[RunspaceFactory]::CreateRunspace()
# $ps = [Powershell]::Create()
interp alias {} pse {} exec >@stdout pwsh -nolo -nop -c
interp alias {} psx {} runx -n pwsh -nop -nolo -c
interp alias {} psr {} run -n pwsh -nop -nolo -c
interp alias {} psout {} runout -n pwsh -nop -nolo -c
interp alias {} pserr {} runerr -n pwsh -nop -nolo -c
interp alias {} psls {} shellrun::runconsole pwsh -nop -nolo -c ls
interp alias {} psps {} shellrun::runconsole pwsh -nop -nolo -c ps
interp alias {} pse {} exec >@stdout {*}$pshell_path -nolo -nop -c
interp alias {} psx {} runx -n {*}$pshell_path -nop -nolo -c
interp alias {} psr {} run -n {*}$pshell_path -nop -nolo -c
interp alias {} psout {} runout -n {*}$pshell_path -nop -nolo -c
interp alias {} pserr {} runerr -n {*}$pshell_path -nop -nolo -c
#interp alias {} psls {} shellrun::runconsole $pshell_path -nop -nolo -c ls
#interp alias {} psls {} shellrun::runconsole {*}$pshell_path -nop -nolo -c {ls | Select-Object Mode, @{Name='Owner';Expression={(Get-Acl $_.FullName).Owner}}, LastWriteTime, Length, Name | Format-Table}
proc psls args {
variable pshell_path
shellrun::runconsole {*}$pshell_path -nop -nolo -c {*}[string map [list %a% $args] {{ls %a% | Select-Object Mode, @{Name='Owner';Expression={(Get-Acl $_.FullName).Owner}}, LastWriteTime, Length, Name | Format-Table}}]
}
interp alias {} psls {} punk::psls
interp alias {} psps {} shellrun::runconsole {*}$pshell_path -nop -nolo -c ps
} else {
set ps_missing "powershell missing (powershell is MIT licensed open source and can be installed on windows and most unix-like platforms)"
interp alias {} pse {} puts stderr $ps_missing

63
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/char-0.1.0.tm

@ -2761,6 +2761,69 @@ tcl::namespace::eval punk::char {
}
tcl::namespace::eval punk::char::lib {
variable num_superscript
#digits and a small set of related symbols
set num_superscript [list\
i \u2071\
0 \u2070\
1 \u00B9\
2 \u00B2\
3 \u00B3\
4 \u2074\
5 \u2075\
6 \u2076\
7 \u2077\
8 \u2078\
9 \u2079\
+ \u207A\
- \u207B\
= \u207C\
( \u207D\
) \u207E\
n \u207F\
]
variable num_supersub_re
set num_supersub_re {^[0-9in+\-\(\)\=]+$}
proc superscript_number {n} {
if {$n eq ""} {return ""}
variable num_superscript
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to superscript. valid chars: [dict keys $num_superscript]"
}
return [string map $num_superscript $n]
}
set num_subscript [list\
i \u1D62\
0 \u2080\
1 \u2081\
2 \u2082\
3 \u2083\
4 \u2084\
5 \u2085\
6 \u2086\
7 \u2087\
8 \u2088\
9 \u2089\
+ \u208A\
- \u208B\
= \u208C\
( \u208D\
) \u208E\
n \u2099\
]
proc subscript_number {n} {
if {$n eq ""} {return ""}
variable num_subscript
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to subcript. valid chars: [dict keys $num_subscript]"
}
return [string map $num_subscript $n]
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++

7
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm

@ -759,7 +759,7 @@ namespace eval punk::mix::cli {
}
} else {
puts -nonewline stderr "P"
puts -nonewline stderr "Z"
set did_skip 1
#set file_record [punkcheck::installfile_skipped_install $basedir $file_record]
$build_event targetset_end SKIPPED
@ -791,7 +791,7 @@ namespace eval punk::mix::cli {
$event targetset_end OK -note "zip modpod"
}
} else {
puts -nonewline stderr "p"
puts -nonewline stderr "z"
set did_skip 1
if {$is_interesting} {
puts stderr "$modulefile [$event targetset_source_changes]"
@ -802,7 +802,8 @@ namespace eval punk::mix::cli {
}
tarjar {
#basename may still contain #tarjar-
#to be obsoleted - update modpod to (optionally) use vfs::tar
#to be obsoleted - update modpod to (optionally) use vfs::tar ?
}
file {
set m $modpath

25
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm

@ -257,6 +257,24 @@ namespace eval punk::mix::commandset::scriptwrap {
set target_labels_found [dict create]
set possible_target_labels_found [dict create]
set warning_target_labels_found [dict create]
#todo - allow analysis of colon-less call. May need to check list of internal commands - but what about external ones?
#set searchregexex [list {(.*\s+|^)(@*call\s*:*)(\S.*)} {(.*\s+|^)(@*CALL\s*:*)(\S.*)} {(.*\s+|^)(@*goto\s*:*)(\S.*)} {(.*\s+|^)(@*GOTO\s*:*)(\S.*)}]
#order of regex testing is important - test more specific entries with colon/comment before we test whitespace only version of goto/call
set searchregexes [list {(.*\s+|^)(@*call\s*:)(\S.*)} {(.*\s+|^)(@*CALL\s*:)(\S.*)} {(.*\s+|^)(@*goto\s*:)(\S.*)} {(.*\s*|.*\s+|^)(@*GOTO\s*:)(\S.*)}]
lappend searchregexes {(.*\|\|.*)(@*GOTO\s*:)(\S.*)} ;#review
lappend searchregexes {(.*\s+|^)(@*goto\s+%=.*=%\s*:)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*goto\s+%=.*=%\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*goto\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+%=.*=%\s*:)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+%=.*=%\s+)(\S.*)}
lappend searchregexes {(.*\s+|^)(@*GOTO\s+)(\S.*)}
#review
#todo - better callsite analysis. There can be data between @GOTO or @CALL and : other than just whitespace
#e.g for @goto %= possible comment=% :mylabe%%l etc
for {set callingline_index 0} {$callingline_index < $line_count} {incr callingline_index} {
set callingline_info [$objFile lineinfo $callingline_index]
set callingline_payload [dict get $callingline_info payload]
@ -273,17 +291,14 @@ namespace eval punk::mix::commandset::scriptwrap {
}
default {
#todo - better callsite analysis. There can be data between @GOTO or @CALL and : other than just whitespace!
#todo - allow analysis of colon-less call. May need to check list of internal commands - but what about external ones?
#foreach search_regex [list {(.*\s+|^)(@*call\s*:*)(\S.*)} {(.*\s+|^)(@*CALL\s*:*)(\S.*)} {(.*\s+|^)(@*goto\s*:*)(\S.*)} {(.*\s+|^)(@*GOTO\s*:*)(\S.*)}] {}
foreach search_regex [list {(.*\s+|^)(@*call\s*:)(\S.*)} {(.*\s+|^)(@*CALL\s*:)(\S.*)} {(.*\s+|^)(@*goto\s*:)(\S.*)} {(.*\s*|.*\s+|^)(@*GOTO\s*:)(\S.*)} {(.*\|\|.*)(@*GOTO\s*:)(\S.*)}] {
foreach search_regex $searchregexes {
if {[regexp $search_regex $callingline_payload _m precall call labelplus]} {
#todo further checks to see if it's actually a batch script line
# - - - - work out what cmd.exe considers start of 512B boundaries when scanning from a callsite
#callposn affected by newlines?
#set callposn [expr {$file_offset + [string length $callingline_payload]}] ;#take callposn as end of line .. review - multiline statements?
set callposn [expr {$file_offset + $callingline_len}]
set callposn [expr {$file_offset + $callingline_len -1}]
#Note there are anomalies around target labels in bracketed sections such as IF blocks
#this is bad practice - as it can lead to unbalanced braces - but batch files can still work under cmd.exe with them in some cases

99
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.3.tm

@ -4206,7 +4206,7 @@ tcl::namespace::eval textblock {
}
#examples ptable.com
set elements [list\
set elements_layout [list\
1 H "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" He\
2 Li Be "" "" "" "" "" "" "" "" "" "" B C N O F Ne\
3 Na Mg "" "" "" "" "" "" "" "" "" "" Al Si P S Cl Ar\
@ -4218,6 +4218,76 @@ tcl::namespace::eval textblock {
"" "" "" 6 La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu\
"" "" "" 7 Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr\
]
#generate list of elements ordered by atomic number from the layout table (0 based - so atomic number is +1)
#create a lookup dict from symbol to atomic number at same time
set elements [list]
set e_atomic [dict create]
set e_group [dict create]
set e_period [dict create]
set atomic 0 ;#first, H, will be 1
set period 0
set group 0
foreach e $elements_layout {
if {[string trim $e] eq ""} {
switch -- $period {
6a {
set period "6c"
set atomic 71 ;#next is Hf=72
}
7a {
set period "7c"
set atomic 103 ;#next is Rf=104
}
}
if {$group == 18} {
#handle rows of blanks
set group 0
} else {
incr group
}
continue
}
if {[string is digit -strict $e]} {
if {$period in {0 1 2 3 4}} {
set period $e
} else {
switch -- $period {
5 {
set period 6a
}
6c {
set period 7a
}
6b {
set period 7b
set atomic 88 ;#next is Ac=89
}
7c {
set period 6b
set atomic 56 ;#next is La=57
}
}
}
incr group
continue
}
incr atomic
lappend elements $e
dict set e_atomic $e $atomic
dict set e_group $e $group
dict set e_period $e [string index $period 0]
if {$group == 18} {
set group 0 ;#false group 0 for first column of period numbers
} else {
incr group
}
}
#test no screwup above
if {[dict get $e_atomic Og] ne "118" || [dict get $e_atomic Lr] ne "103"} {
error "textblock::periodic programming error Og->[dict get $e_atomic Og] Lr->[dict get $e_atomic Lr] should be Og->118 Lr->103"
}
set type_colours [list]
@ -4297,20 +4367,35 @@ tcl::namespace::eval textblock {
tcl::dict::set ecat $e $val
}
set elements1 [list]
set elements_layout_coloured [list]
set RST [a+]
foreach e $elements {
if {[tcl::dict::get $opts -compact]} {
foreach e $elements_layout {
if {[tcl::dict::exists $ecat $e]} {
set ansi [tcl::dict::get $ecat $e ansi]
#lappend elements1 [textblock::pad $ansi$e -width 2 -which right]
#lappend elements_layout_coloured [textblock::pad $ansi$e -width 2 -which right]
#no need to pad here - table column_configure -textalign default of left will do the work of padding right anyway
lappend elements1 $ansi$e
lappend elements_layout_coloured $ansi$e
} else {
lappend elements1 $e
lappend elements_layout_coloured $e
}
}
} else {
foreach e $elements_layout {
if {[tcl::dict::exists $ecat $e]} {
set ansi [tcl::dict::get $ecat $e ansi]
#the atomic number should be a superscript as is the norm
#use subscript on line above
set a [punk::char::lib::subscript_number [tcl::dict::get $e_atomic $e]]
lappend elements_layout_coloured "$ansi$a\n $e "
} else {
lappend elements_layout_coloured $e
}
}
}
set t [list_as_table -columns 19 -return tableobject $elements1]
set t [list_as_table -columns 19 -return tableobject $elements_layout_coloured]
#(defaults to show_hseps 0)
#todo - keep simple table with symbols as base - map symbols to descriptions etc for more verbose table options

5
src/bootsupport/modules/uuid-1.0.8.tm → src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/uuid-1.0.9.tm

@ -47,8 +47,7 @@ proc ::uuid::generate_tcl_machinfo {} {
# If we have /dev/urandom just stream 128 bits from that
###
if {[file exists /dev/urandom]} {
set fin [open /dev/urandom r]
fconfigure $fin -encoding binary
set fin [open /dev/urandom rb]
binary scan [read $fin 128] H* machinfo
close $fin
} elseif {[catch {package require nettool}]} {
@ -237,7 +236,7 @@ namespace eval ::uuid {
unset e
}
package provide uuid 1.0.8
package provide uuid 1.0.9
# -------------------------------------------------------------------------
# Local variables:

BIN
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/zipper-0.12.tm

Binary file not shown.

702
src/vendormodules/modpod-0.1.2.tm

@ -1,702 +0,0 @@
# -*- tcl -*-
# Maintenance Instruction: leave the 999999.xxx.x as is and use 'pmix make' or src/make.tcl to update from <pkg>-buildversion.txt
#
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem.
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository.
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# (C) 2024
#
# @@ Meta Begin
# Application modpod 0.1.2
# Meta platform tcl
# Meta license <unspecified>
# @@ Meta End
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin modpod_module_modpod 0 0.1.2]
#[copyright "2024"]
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}]
#[moddesc {-}] [comment {-- Description at end of page heading --}]
#[require modpod]
#[keywords module]
#[description]
#[para] -
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section Overview]
#[para] overview of modpod
#[subsection Concepts]
#[para] -
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Requirements
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[subsection dependencies]
#[para] packages used by modpod
#[list_begin itemized]
package require Tcl 8.6-
package require struct::set ;#review
package require punk::lib
package require punk::args
#*** !doctools
#[item] [package {Tcl 8.6-}]
# #package require frobz
# #*** !doctools
# #[item] [package {frobz}]
#*** !doctools
#[list_end]
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section API]
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# oo::class namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
namespace eval modpod::class {
#*** !doctools
#[subsection {Namespace modpod::class}]
#[para] class definitions
if {[info commands [namespace current]::interface_sample1] eq ""} {
#*** !doctools
#[list_begin enumerated]
# oo::class create interface_sample1 {
# #*** !doctools
# #[enum] CLASS [class interface_sample1]
# #[list_begin definitions]
# method test {arg1} {
# #*** !doctools
# #[call class::interface_sample1 [method test] [arg arg1]]
# #[para] test method
# puts "test: $arg1"
# }
# #*** !doctools
# #[list_end] [comment {-- end definitions interface_sample1}]
# }
#*** !doctools
#[list_end] [comment {--- end class enumeration ---}]
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Base namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
namespace eval modpod {
namespace export {[a-z]*}; # Convention: export all lowercase
variable connected
if {![info exists connected(to)]} {
set connected(to) list
}
variable modpodscript
set modpodscript [info script]
if {[string tolower [file extension $modpodscript]] eq ".tcl"} {
set connected(self) [file dirname $modpodscript]
} else {
#expecting a .tm
set connected(self) $modpodscript
}
variable loadables [info sharedlibextension]
variable sourceables {.tcl .tk} ;# .tm ?
#*** !doctools
#[subsection {Namespace modpod}]
#[para] Core API functions for modpod
#[list_begin definitions]
#proc sample1 {p1 args} {
# #*** !doctools
# #[call [fun sample1] [arg p1] [opt {?option value...?}]]
# #[para]Description of sample1
# return "ok"
#}
#old tar connect mechanism - review - not needed?
proc connect {args} {
puts stderr "modpod::connect--->>$args"
set argd [punk::args::get_dict {
@id -id ::modpod::connect
-type -default ""
@values -min 1 -max 1
path -type string -minsize 1 -help "path to .tm file or toplevel .tcl script within #modpod-<pkg>-<ver> folder (unwrapped modpod)"
} $args]
catch {
punk::lib::showdict $argd ;#heavy dependencies
}
set opt_path [dict get $argd values path]
variable connected
set original_connectpath $opt_path
set modpodpath [modpod::system::normalize $opt_path] ;#
if {$modpodpath in $connected(to)} {
return [dict create ok ALREADY_CONNECTED]
}
lappend connected(to) $modpodpath
set connected(connectpath,$opt_path) $original_connectpath
set is_sourced [expr {[file normalize $modpodpath] eq [file normalize [info script]]}]
set connected(location,$modpodpath) [file dirname $modpodpath]
set connected(startdata,$modpodpath) -1
set connected(type,$modpodpath) [dict get $argd opts -type]
set connected(fh,$modpodpath) ""
if {[string range [file tail $modpodpath] 0 7] eq "#modpod-"} {
set connected(type,$modpodpath) "unwrapped"
lassign [::split [file tail [file dirname $modpodpath]] -] connected(package,$modpodpath) connected(version,$modpodpath)
set this_pkg_tm_folder [file dirname [file dirname $modpodpath]]
} else {
#connect to .tm but may still be unwrapped version available
lassign [::split [file rootname [file tail $modpodath]] -] connected(package,$modpodpath) connected(version,$modpodpath)
set this_pkg_tm_folder [file dirname $modpodpath]
if {$connected(type,$modpodpath) ne "unwrapped"} {
#Not directly connected to unwrapped version - but may still be redirected there
set unwrappedFolder [file join $connected(location,$modpodpath) #modpod-$connected(package,$modpodpath)-$connected(version,$modpodpath)]
if {[file exists $unwrappedFolder]} {
#folder with exact version-match must exist for redirect to 'unwrapped'
set con(type,$modpodpath) "modpod-redirecting"
}
}
}
set unwrapped_tm_file [file join $this_pkg_tm_folder] "[set connected(package,$modpodpath)]-[set connected(version,$modpodpath)].tm"
set connected(tmfile,$modpodpath)
set tail_segments [list]
set lcase_tmfile_segments [string tolower [file split $this_pkg_tm_folder]]
set lcase_modulepaths [string tolower [tcl::tm::list]]
foreach lc_mpath $lcase_modulepaths {
set mpath_segments [file split $lc_mpath]
if {[llength [struct::set intersect $lcase_tmfile_segments $mpath_segments]] == [llength $mpath_segments]} {
set tail_segments [lrange [file split $this_pkg_tm_folder] [llength $mpath_segments] end]
break
}
}
if {[llength $tail_segments]} {
set connected(fullpackage,$modpodpath) [join [concat $tail_segments [set connected(package,$modpodpath)]] ::] ;#full name of package as used in package require
} else {
set connected(fullpackage,$modpodpath) [set connected(package,$modpodpath)]
}
switch -exact -- $connected(type,$modpodpath) {
"modpod-redirecting" {
#redirect to the unwrapped version
set loadscript_name [file join $unwrappedFolder #modpod-loadscript-$con(package,$modpod).tcl]
}
"unwrapped" {
if {[info commands ::thread::id] ne ""} {
set from [pid],[thread::id]
} else {
set from [pid]
}
#::modpod::Puts stderr "$from-> Package $connected(package,$modpodpath)-$connected(version,$modpodpath) is using unwrapped version: $modpodpath"
return [list ok ""]
}
default {
#autodetect .tm - zip/tar ?
#todo - use vfs ?
#connect to tarball - start at 1st header
set connected(startdata,$modpodpath) 0
set fh [open $modpodpath r]
set connected(fh,$modpodpath) $fh
fconfigure $fh -encoding iso8859-1 -translation binary -eofchar {}
if {$connected(startdata,$modpodpath) >= 0} {
#verify we have a valid tar header
if {![catch {::modpod::system::tar::readHeader [red $fh 512]}]} {
seek $fh $connected(startdata,$modpodpath) start
return [list ok $fh]
} else {
#error "cannot verify tar header"
}
}
lpop connected(to) end
set connected(startdata,$modpodpath) -1
unset connected(fh,$modpodpath)
catch {close $fh}
return [dict create err {Does not appear to be a valid modpod}]
}
}
}
proc disconnect {{modpod ""}} {
variable connected
if {![llength $connected(to)]} {
return 0
}
if {$modpod eq ""} {
puts stderr "modpod::disconnect WARNING: modpod not explicitly specified. Disconnecting last connected: [lindex $connected(to) end]"
set modpod [lindex $connected(to) end]
}
if {[set posn [lsearch $connected(to) $modpod]] == -1} {
puts stderr "modpod::disconnect WARNING: disconnect called when not connected: $modpod"
return 0
}
if {[string length $connected(fh,$modpod)]} {
close $connected(fh,$modpod)
}
array unset connected *,$modpod
set connected(to) [lreplace $connected(to) $posn $posn]
return 1
}
proc get {args} {
set argd [punk::args::get_dict {
-from -default "" -help "path to pod"
*values -min 1 -max 1
filename
} $args]
set frompod [dict get $argd opts -from]
set filename [dict get $argd values filename]
variable connected
#//review
set modpod [::modpod::system::connect_if_not $frompod]
set fh $connected(fh,$modpod)
if {$connected(type,$modpod) eq "unwrapped"} {
#for unwrapped connection - $connected(location) already points to the #modpod-pkg-ver folder
if {[string range $filename 0 0 eq "/"]} {
#absolute path (?)
set path [file join $connected(location,$modpod) .. [string trim $filename /]]
} else {
#relative path - use #modpod-xxx as base
set path [file join $connected(location,$modpod) $filename]
}
set fd [open $path r]
#utf-8?
#fconfigure $fd -encoding iso8859-1 -translation binary
return [list ok [lindex [list [read $fd] [close $fd]] 0]]
} else {
#read from vfs
puts stderr "get $filename from wrapped pod '$frompod' not implemented"
}
}
#*** !doctools
#[list_end] [comment {--- end definitions namespace modpod ---}]
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Secondary API namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
namespace eval modpod::lib {
namespace export {[a-z]*}; # Convention: export all lowercase
namespace path [namespace parent]
#*** !doctools
#[subsection {Namespace modpod::lib}]
#[para] Secondary functions that are part of the API
#[list_begin definitions]
#proc utility1 {p1 args} {
# #*** !doctools
# #[call lib::[fun utility1] [arg p1] [opt {?option value...?}]]
# #[para]Description of utility1
# return 1
#}
proc is_valid_tm_version {versionpart} {
#Needs to be suitable for use with Tcl's 'package vcompare'
if {![catch [list package vcompare $versionparts $versionparts]]} {
return 1
} else {
return 0
}
}
#zipfile is a pure zip at this point - ie no script/exe header
proc make_zip_modpod {args} {
set argd [punk::args::get_dict {
@id -id ::modpod::lib::make_zip_modpod
-offsettype -default "archive" -choices {archive file} -help\
"Whether zip offsets are relative to start of file or start of zip-data within the file.
'archive' relative offsets are easier to work with (for writing/updating) in tools such as 7zip,peazip,
but other tools may be easier with 'file' relative offsets. (e.g info-zip,pkzip)
info-zip's 'zip -A' can sometimes convert archive-relative to file-relative.
-offsettype archive is equivalent to plain 'cat prefixfile zipfile > modulefile'"
@values -min 2 -max 2
zipfile -type path -minsize 1 -help "path to plain zip file with subfolder #modpod-packagename-version containing .tm, data files and/or binaries"
outfile -type path -minsize 1 -help "path to output file. Name should be of the form packagename-version.tm"
} $args]
set zipfile [dict get $argd values zipfile]
set outfile [dict get $argd values outfile]
set opt_offsettype [dict get $argd opts -offsettype]
set mount_stub [string map [list %offsettype% $opt_offsettype] {
#zip file with Tcl loader prepended. Requires either builtin zipfs, or vfs::zip to mount while zipped.
#Alternatively unzip so that extracted #modpod-package-version folder is in same folder as .tm file.
#generated using: modpod::lib::make_zip_modpod -offsettype %offsettype% <zipfile> <tmfile>
if {[catch {file normalize [info script]} modfile]} {
error "modpod zip stub error. Unable to determine module path. (possible safe interp restrictions?)"
}
if {$modfile eq "" || ![file exists $modfile]} {
error "modpod zip stub error. Unable to determine module path"
}
set moddir [file dirname $modfile]
set mod_and_ver [file rootname [file tail $modfile]]
lassign [split $mod_and_ver -] moduletail version
if {[file exists $moddir/#modpod-$mod_and_ver]} {
source $moddir/#modpod-$mod_and_ver/$mod_and_ver.tm
} else {
#determine module namespace so we can mount appropriately
proc intersect {A B} {
if {[llength $A] == 0} {return {}}
if {[llength $B] == 0} {return {}}
if {[llength $B] > [llength $A]} {
set res $A
set A $B
set B $res
}
set res {}
foreach x $A {set ($x) {}}
foreach x $B {
if {[info exists ($x)]} {
lappend res $x
}
}
return $res
}
set lcase_tmfile_segments [string tolower [file split $moddir]]
set lcase_modulepaths [string tolower [tcl::tm::list]]
foreach lc_mpath $lcase_modulepaths {
set mpath_segments [file split $lc_mpath]
if {[llength [intersect $lcase_tmfile_segments $mpath_segments]] == [llength $mpath_segments]} {
set tail_segments [lrange [file split $moddir] [llength $mpath_segments] end] ;#use properly cased tail
break
}
}
if {[llength $tail_segments]} {
set fullpackage [join [concat $tail_segments $moduletail] ::] ;#full name of package as used in package require
set mount_at #modpod/[file join {*}$tail_segments]/#mounted-modpod-$mod_and_ver
} else {
set fullpackage $moduletail
set mount_at #modpod/#mounted-modpod-$mod_and_ver
}
if {[info commands tcl::zipfs::mount] ne ""} {
#argument order changed to be consistent with vfs::zip::Mount etc
#early versions: zipfs::Mount mountpoint zipname
#since 2023-09: zipfs::Mount zipname mountpoint
#don't use 'file exists' when testing mountpoints. (some versions at least give massive delays on windows platform for non-existance)
#This is presumably related to // being interpreted as a network path
set mountpoints [dict keys [tcl::zipfs::mount]]
if {"//zipfs:/$mount_at" ni $mountpoints} {
#despite API change tcl::zipfs package version was unfortunately not updated - so we don't know argument order without trying it
if {[catch {
#tcl::zipfs::mount $modfile //zipfs:/#mounted-modpod-$mod_and_ver ;#extremely slow if this is a wrong guess (artifact of aforementioned file exists issue ?)
#puts "tcl::zipfs::mount $modfile $mount_at"
tcl::zipfs::mount $modfile $mount_at
} errM]} {
#try old api
if {![catch {tcl::zipfs::mount //zipfs:/$mount_at $modfile}]} {
puts stderr "modpod stub>>> tcl::zipfs::mount <file> <mountpoint> failed.\nbut old api: tcl::zipfs::mount <mountpoint> <file> succeeded\n tcl::zipfs::mount //zipfs://$mount_at $modfile"
puts stderr "Consider upgrading tcl runtime to one with fixed zipfs API"
}
}
if {![file exists //zipfs:/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm]} {
puts stderr "modpod stub>>> mount at //zipfs:/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm failed\n zipfs mounts: [zipfs mount]"
#tcl::zipfs::unmount //zipfs:/$mount_at
error "Unable to find $mod_and_ver.tm in $modfile for module $fullpackage"
}
}
# #modpod-$mod_and_ver subdirectory always present in the archive so it can be conveniently extracted and run in that form
source //zipfs:/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm
} else {
#fallback to slower vfs::zip
#NB. We don't create the intermediate dirs - but the mount still works
if {![file exists $moddir/$mount_at]} {
if {[catch {package require vfs::zip} errM]} {
set msg "Unable to load vfs::zip package to mount module $mod_and_ver (and zipfs not available either)"
append msg \n "If neither zipfs or vfs::zip are available - the module can still be loaded by manually unzipping the file $modfile in place."
append msg \n "The unzipped data will all be contained in a folder named #modpod-$mod_and_ver in the same parent folder as $modfile"
error $msg
} else {
set fd [vfs::zip::Mount $modfile $moddir/$mount_at]
if {![file exists $moddir/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm]} {
vfs::zip::Unmount $fd $moddir/$mount_at
error "Unable to find $mod_and_ver.tm in $modfile for module $fullpackage"
}
}
}
source $moddir/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm
}
}
#zipped data follows
}]
#todo - test if supplied zipfile has #modpod-loadcript.tcl or some other script/executable before even creating?
append mount_stub \x1A
modpod::system::make_mountable_zip $zipfile $outfile $mount_stub $opt_offsettype
}
#*** !doctools
#[list_end] [comment {--- end definitions namespace modpod::lib ---}]
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section Internal]
namespace eval modpod::system {
#*** !doctools
#[subsection {Namespace modpod::system}]
#[para] Internal functions that are not part of the API
#deflate,store only supported
#zipfile here is plain zip - no script/exe prefix part.
proc make_mountable_zip {zipfile outfile mount_stub {offsettype "archive"}} {
set inzip [open $zipfile r]
fconfigure $inzip -encoding iso8859-1 -translation binary
set out [open $outfile w+]
fconfigure $out -encoding iso8859-1 -translation binary
puts -nonewline $out $mount_stub
set stuboffset [tell $out]
lappend report "stub size: $stuboffset"
fcopy $inzip $out
close $inzip
set size [tell $out]
lappend report "tmfile : [file tail $outfile]"
lappend report "output size : $size"
lappend report "offsettype : $offsettype"
if {$offsettype eq "file"} {
#make zip offsets relative to start of whole file including prepended script.
#same offset structure as Tcl's 'zipfs mkimg' as at 2024-10
#not editable by 7z,nanazip,peazip
#we aren't adding any new files/folders so we can edit the offsets in place
#Now seek in $out to find the end of directory signature:
#The structure itself is 24 bytes Long, followed by a maximum of 64Kbytes text
if {$size < 65559} {
set tailsearch_start 0
} else {
set tailsearch_start [expr {$size - 65559}]
}
seek $out $tailsearch_start
set data [read $out]
#EOCD - End of Central Directory record
#PK\5\6
set start_of_end [string last "\x50\x4b\x05\x06" $data]
#set start_of_end [expr {$start_of_end + $seek}]
#incr start_of_end $seek
set filerelative_eocd_posn [expr {$start_of_end + $tailsearch_start}]
lappend report "kitfile-relative START-OF-EOCD: $filerelative_eocd_posn"
seek $out $filerelative_eocd_posn
set end_of_ctrl_dir [read $out]
binary scan $end_of_ctrl_dir issssiis eocd(signature) eocd(disknbr) eocd(ctrldirdisk) \
eocd(numondisk) eocd(totalnum) eocd(dirsize) eocd(diroffset) eocd(comment_len)
lappend report "End of central directory: [array get eocd]"
seek $out [expr {$filerelative_eocd_posn+16}]
#adjust offset of start of central directory by the length of our sfx stub
puts -nonewline $out [binary format i [expr {$eocd(diroffset) + $stuboffset}]]
flush $out
seek $out $filerelative_eocd_posn
set end_of_ctrl_dir [read $out]
binary scan $end_of_ctrl_dir issssiis eocd(signature) eocd(disknbr) eocd(ctrldirdisk) \
eocd(numondisk) eocd(totalnum) eocd(dirsize) eocd(diroffset) eocd(comment_len)
# 0x06054b50 - end of central dir signature
puts stderr "$end_of_ctrl_dir"
puts stderr "comment_len: $eocd(comment_len)"
puts stderr "eocd sig: $eocd(signature) [punk::lib::dec2hex $eocd(signature)]"
lappend report "New dir offset: $eocd(diroffset)"
lappend report "Adjusting $eocd(totalnum) zip file items."
catch {
punk::lib::showdict -roottype list -chan stderr $report ;#heavy dependencies
}
seek $out $eocd(diroffset)
for {set i 0} {$i <$eocd(totalnum)} {incr i} {
set current_file [tell $out]
set fileheader [read $out 46]
puts --------------
puts [ansistring VIEW -lf 1 $fileheader]
puts --------------
#binary scan $fileheader is2sss2ii2s3ssii x(sig) x(version) x(flags) x(method) \
# x(date) x(crc32) x(sizes) x(lengths) x(diskno) x(iattr) x(eattr) x(offset)
binary scan $fileheader ic4sss2ii2s3ssii x(sig) x(version) x(flags) x(method) \
x(date) x(crc32) x(sizes) x(lengths) x(diskno) x(iattr) x(eattr) x(offset)
set ::last_header $fileheader
puts "sig: $x(sig) (hex: [punk::lib::dec2hex $x(sig)])"
puts "ver: $x(version)"
puts "method: $x(method)"
#PK\1\2
#33639248 dec = 0x02014b50 - central directory file header signature
if { $x(sig) != 33639248 } {
error "modpod::system::make_mountable_zip Bad file header signature at item $i: dec:$x(sig) hex:[punk::lib::dec2hex $x(sig)]"
}
foreach size $x(lengths) var {filename extrafield comment} {
if { $size > 0 } {
set x($var) [read $out $size]
} else {
set x($var) ""
}
}
set next_file [tell $out]
lappend report "file $i: $x(offset) $x(sizes) $x(filename)"
seek $out [expr {$current_file+42}]
puts -nonewline $out [binary format i [expr {$x(offset)+$stuboffset}]]
#verify:
flush $out
seek $out $current_file
set fileheader [read $out 46]
lappend report "old $x(offset) + $stuboffset"
binary scan $fileheader is2sss2ii2s3ssii x(sig) x(version) x(flags) x(method) \
x(date) x(crc32) x(sizes) x(lengths) x(diskno) x(iattr) x(eattr) x(offset)
lappend report "new $x(offset)"
seek $out $next_file
}
}
close $out
#pdict/showdict reuire punk & textlib - ie lots of dependencies
#don't fall over just because of that
catch {
punk::lib::showdict -roottype list -chan stderr $report
}
#puts [join $report \n]
return
}
proc connect_if_not {{podpath ""}} {
upvar ::modpod::connected connected
set podpath [::modpod::system::normalize $podpath]
set docon 0
if {![llength $connected(to)]} {
if {![string length $podpath]} {
error "modpod::system::connect_if_not - Not connected to a modpod file, and no podpath specified"
} else {
set docon 1
}
} else {
if {![string length $podpath]} {
set podpath [lindex $connected(to) end]
puts stderr "modpod::system::connect_if_not WARNING: using last connected modpod:$podpath for operation\n -podpath not explicitly specified during operation: [info level -1]"
} else {
if {$podpath ni $connected(to)} {
set docon 1
}
}
}
if {$docon} {
if {[lindex [modpod::connect $podpath]] 0] ne "ok"} {
error "modpod::system::connect_if_not error. file $podpath does not seem to be a valid modpod"
} else {
return $podpath
}
}
#we were already connected
return $podpath
}
proc myversion {} {
upvar ::modpod::connected connected
set script [info script]
if {![string length $script]} {
error "No result from \[info script\] - modpod::system::myversion should only be called from within a loading modpod"
}
set fname [file tail [file rootname [file normalize $script]]]
set scriptdir [file dirname $script]
if {![string match "#modpod-*" $fname]} {
lassign [lrange [split $fname -] end-1 end] _pkgname version
} else {
lassign [scan [file tail [file rootname $script]] {#modpod-loadscript-%[a-z]-%s}] _pkgname version
if {![string length $version]} {
#try again on the name of the containing folder
lassign [scan [file tail $scriptdir] {#modpod-%[a-z]-%s}] _pkgname version
#todo - proper walk up the directory tree
if {![string length $version]} {
#try again on the grandparent folder (this is a standard depth for sourced .tcl files in a modpod)
lassign [scan [file tail [file dirname $scriptdir]] {#modpod-%[a-z]-%s}] _pkgname version
}
}
}
#tarjar::Log debug "'myversion' determined version for [info script]: $version"
return $version
}
proc myname {} {
upvar ::modpod::connected connected
set script [info script]
if {![string length $script]} {
error "No result from \[info script\] - modpod::system::myname should only be called from within a loading modpod"
}
return $connected(fullpackage,$script)
}
proc myfullname {} {
upvar ::modpod::connected connected
set script [info script]
#set script [::tarjar::normalize $script]
set script [file normalize $script]
if {![string length $script]} {
error "No result from \[info script\] - modpod::system::myfullname should only be called from within a loading tarjar"
}
return $::tarjar::connected(fullpackage,$script)
}
proc normalize {path} {
#newer versions of Tcl don't do tilde sub
#Tcl's 'file normalize' seems to do some unfortunate tilde substitution on windows.. (at least for relative paths)
# we take the assumption here that if Tcl's tilde substitution is required - it should be done before the path is provided to this function.
set matilda "<_tarjar_tilde_placeholder_>" ;#token that is *unlikely* to occur in the wild, and is somewhat self describing in case it somehow ..escapes..
set path [string map [list ~ $matilda] $path] ;#give our tildes to matilda to look after
set path [file normalize $path]
#set path [string tolower $path] ;#must do this after file normalize
return [string map [list $matilda ~] $path] ;#get our tildes back.
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide modpod [namespace eval modpod {
variable pkg modpod
variable version
set version 0.1.2
}]
return
#*** !doctools
#[manpage_end]

4773
src/vendormodules/overtype-1.6.5.tm

File diff suppressed because it is too large Load Diff

643
src/vendormodules/packagetrace-0.8.tm

@ -1,643 +0,0 @@
#JMN 2005 - Public Domain
#
#REVIEW: This package may not robustly output xml. More testing & development required.
#
#NOTE: the 'x' attribute on the 'info' tag may have its value truncated.
#It is a human-readable indicator only and should not be used to cross-reference to the corresponding 'require' tag using the 'p' attribute.
#Use the fact that the corresponding 'info' tag directly follows its 'require' tag.
#changes
#2021-09-17
# - added variable ::packagetrace::showpresent with default 1
# setting this to 0 will hide the <present/> tags which sometimes make the output too verbose.
# - changed t from an integer number of milliseconds to show fractional millis by using ([clock microseconds]-$t0)/1000.0 in the expr.
namespace eval packagetrace::class {
if {[info commands [namespace current]::tracer] eq ""} {
oo::class create tracer {
method get {} {
}
method test {} {
return tracertest
}
}
}
}
namespace eval packagetrace {
variable tracerlist [list]
variable chan stderr
variable showpresent 1
variable output ""
proc help {} {
return {
REVIEW - documentation inaccurate
Enable package tracing using 'package require packagetrace'
Disable package tracing using 'package forget packagetrace; package require packagetrace'
(This 2nd 'package require packagetrace' will raise an error. This is deliberate.)
use packagetrace::channel <chan> to desired output channel or none. (default stderr)
set packagetrace::showpresent 0 to skip <present/> output
}
}
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
# Maintenance - tm_version... functions - primary source is punk::lib module
# - these should be synced with code from latest punk::lib
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
proc tm_version_isvalid {versionpart} {
#Needs to be suitable for use with Tcl's 'package vcompare'
if {![catch [list package vcompare $versionpart $versionpart]]} {
return 1
} else {
return 0
}
}
proc tm_version_major {version} {
if {![tm_version_isvalid $version]} {
error "Invalid version '$version' is not a proper Tcl module version number"
}
set firstpart [lindex [split $version .] 0]
#check for a/b in first segment
if {[string is integer -strict $firstpart]} {
return $firstpart
}
if {[string first a $firstpart] > 0} {
return [lindex [split $firstpart a] 0]
}
if {[string first b $firstpart] > 0} {
return [lindex [split $firstpart b] 0]
}
error "tm_version_major unable to determine major version from version number '$version'"
}
proc tm_version_canonical {ver} {
#accepts a single valid version only - not a bounded or unbounded spec
if {![tm_version_isvalid $ver]} {
error "tm_version_canonical version '$ver' is not valid for a package version"
}
set parts [split $ver .]
set newparts [list]
foreach o $parts {
set trimmed [string trimleft $o 0]
set firstnonzero [string index $trimmed 0]
switch -exact -- $firstnonzero {
"" {
lappend newparts 0
}
a - b {
#e.g 000bnnnn -> bnnnnn
set tailtrimmed [string trimleft [string range $trimmed 1 end] 0]
if {$tailtrimmed eq ""} {
set tailtrimmed 0
}
lappend newparts 0$firstnonzero$tailtrimmed
}
default {
#digit
if {[string is integer -strict $trimmed]} {
#e.g 0100 -> 100
lappend newparts $trimmed
} else {
#e.g 0100b003 -> 100b003 (still need to process tail)
if {[set apos [string first a $trimmed]] > 0} {
set lhs [string range $trimmed 0 $apos-1] ;#assert lhs non-empty and only digits or wouldn't be in this branch
set rhs [string range $trimmed $apos+1 end] ;#assert rhs non-empty and only digits
set rhs [string trimleft $rhs 0]
if {$rhs eq ""} {
set rhs 0
}
lappend newparts ${lhs}a${rhs}
} elseif {[set bpos [string first b $trimmed]] > 0} {
set lhs [string range $trimmed 0 $bpos-1] ;#assert lhs non-empty and only digits or wouldn't be in this branch
set rhs [string range $trimmed $bpos+1 end] ;#assert rhs non-empty and only digits
set rhs [string trimleft $rhs 0]
if {$rhs eq ""} {
set rhs 0
}
lappend newparts ${lhs}b${rhs}
} else {
#assert - shouldn't get here trimmed val should have been empty, an int or contained an a or b
error "tm_version_canonical error - trimfail - unexpected"
}
}
}
}
}
return [join $newparts .]
}
proc tm_version_required_canonical {versionspec} {
#also trim leading zero from any dottedpart?
#Tcl *allows* leading zeros in any of the dotted parts - but they are not significant.
#e.g 1.01 is equivalent to 1.1 and 01.001
#also 1b3 == 1b0003
if {[string trim $versionspec] eq ""} {return ""} ;#unspecified = any version
set errmsg "tm_version_required_canonical - invalid version specification"
if {[string first - $versionspec] < 0} {
#no dash
#looks like a minbounded version (ie a single version with no dash) convert to min-max form
set from $versionspec
if {![tm_version_isvalid $from]} {
error "$errmsg '$versionpec'"
}
if {![catch {tm_version_major $from} majorv]} {
set from [tm_version_canonical $from]
return "${from}-[expr {$majorv +1}]"
} else {
error "$errmsg '$versionspec'"
}
} else {
# min- or min-max
#validation and canonicalisation (strip leading zeroes from each segment, including either side of a or b)
set parts [split $versionspec -] ;#we expect only 2 parts
lassign $parts from to
if {![tm_version_isvalid $from]} {
error "$errmsg '$versionspec'"
}
set from [tm_version_canonical $from]
if {[llength $parts] == 2} {
if {$to ne ""} {
if {![tm_version_isvalid $to]} {
error "$errmsg '$versionspec'"
}
set to [tm_version_canonical $to]
return $from-$to
} else {
return $from-
}
} else {
error "$errmsg '$versionspec'"
}
error "tm_version_required_canonical should have already returned a canonicalised versionspec - or produced an error with reason before this point"
}
}
# end tm_version... functions
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
#convenience function in case the sequence 'package forget packagetrace;package require packagetrace' is too unintuitive or weird.
#REVIEW
proc unload {} {
package forget packagetrace
if {[catch {package require packagetrace}]} {
return 1 ;#yes - we get an error if we unloaded successfully
} else {
error "packagetrace was not unloaded"
}
}
proc emit {str} {
variable chan
variable output
append output $str
if {$chan ne "none"} {
puts -nonewline $chan $str
}
return
}
proc get {{as raw}} {
variable output
switch -- [string tolower $as] {
asxml {
if {[package provide tdom] eq ""} {
set previous_output $output
package require tdom
set output $previous_output
}
set d [dom parse $output]
return [$d asXML]
}
aslist {
if {[package provide tdom] eq ""} {
set previous_output $output
package require tdom
set output $previous_output
}
set d [dom parse $output]
return [$d asList]
}
default {
return $output
}
}
}
proc channel {{ch ""}} {
variable chan
switch -exact -- $ch {
"" {
return $chan
}
none {
set chan none
return none
}
stderr - stdout {
#note stderr stdout not necessarily in [chan names] (due to transforms etc?) but can still work
set chan $ch
return $ch
}
default {
if {$ch in [chan names]} {
set chan $ch
return $ch
} else {
error "chan '$ch' not in \[chan names\]: [chan names]"
}
}
}
}
proc init {} {
uplevel 1 {
set ::packagetrace::level -1
if {![llength [info commands tcl_findLibrary]]} {
tcl::namespace::eval :: $::auto_index(tcl_findLibrary)
}
package require commandstack
set targetcommand [namespace which tcl_findLibrary] ;# normalize to presumably ::tcl_findLibrary
set stackrecord [commandstack::rename_command -renamer packagetrace $targetcommand [info args $targetcommand] {
set marg [string repeat { } $::packagetrace::level]
packagetrace::emit "${marg}<extra> tcl_findLibrary $basename $version $patch $initScript $enVarName $varName </extra>\n"
uplevel 1 [list $COMMANDSTACKNEXT $basename $version $patch $initScript $enVarName $varName]
}]
if {[dict get $stackrecord implementation] ne ""} {
set old_tcl_findLibrary [dict get $stackrecord implementation]
puts stderr "packagetrace::init renamed $targetcommand to $old_tcl_findLibrary and is providing an override"
} else {
puts stderr "packagetrace::init failed to rename $targetcommand"
}
set package_command [namespace which package]
set stackrecord [commandstack::rename_command -renamer packagetrace $package_command {subcommand args} {
set tracerlist $::packagetrace::tracerlist
set tracer [lindex $tracerlist end]
if {$tracer eq ""} {
}
set ch $::packagetrace::chan
set next $COMMANDSTACKNEXT
if {$next ne "$COMMANDSTACKNEXT_ORIGINAL"} {
puts stderr "(packagetrace package) DEBUG - command changed since start: $COMMANDSTACKNEXT_ORIGINAL is now $next"
}
#cache $ch instead of using upvar,
#because namespace may be deleted during call.
#!todo - optionally silence Tcl & Tk requires to reduce output?
#if {[lindex $args 0] eq "Tcl"} {
# return [$next $subcommand {*}$args]
#}
switch -exact -- [tcl::prefix::match {files forget ifneeded names prefer present provide require unknown vcompare versions vsatisfies} $subcommand] {
require {
#columns
set c1 [string repeat { } 30] ;#tree col
set c1a " "
set c2 [string repeat { } 20] ;#package name col
set c2a " " ;# close require/present tags
set c3 [string repeat { } 18] ;#version col - must handle v= "999999.0a1.0" without truncation
set c4 [string repeat { } 12] ;#timing col 5 chars of punct leaving remainder for value.
set c5 [string repeat { } 10] ;#module col
set c5a [string repeat { } 3] ;#close result tag col
#we assume 'package require' API sticks to solo option flags like -exact and is relatively stable.
set argidx 0
set is_exact 0
foreach a $args {
if {[string range $a 0 0] ne "-"} {
#assume 1st non-dashed argument is package name
set pkg $a
set v_requirements [lrange $args $argidx+1 end]
#normalize
if {$is_exact} {
set req [lindex $v_requirements 0] ;#only one is allowed for -exact
set v_requirements $req-$req ;#translate to v-v normalised equiv of -exact
} else {
set reqs [list]
foreach req $v_requirements {
lappend reqs [::packagetrace::tm_version_required_canonical $v_requirement] ;#empty remains empty, v -> v-<majorv+1>, leading zeros stripped from all segments.
}
set v_requirements $reqs ;#each normalised
}
set pkg_ [lrange $args $argidx end] ;# raw e.g "Tcl 8.6" or "Tcl 8.5 9"
break
} else {
if {$a eq "-exact"} {
set is_exact 1
}
}
incr argidx
}
incr ::packagetrace::level
if {$::packagetrace::level == 0} {
set packagetrace::output ""
}
set marg [string repeat { } $::packagetrace::level]
set margnext [string repeat { } [expr {$::packagetrace::level + 1}]]
if {![catch {set ver [$next present {*}$args]}]} {
if {$::packagetrace::showpresent} {
#already loaded..
set f1 [packagetrace::overtype::left $c1 "${marg}<present"]
set f2 [packagetrace::overtype::left -overflow 1 $c2 "p= \"$pkg_\""] ;#disallow truncation!
set f2a $c2a
set f3 [packagetrace::overtype::left $c3 "v= \"$ver\""]
set f4 $c4
set f5 $c5
set f5a "/> "
#puts -nonewline $ch $f1$c1a$f2$f2a$f3$f4$f5\n
packagetrace::emit $f1$c1a$f2$f2a$f3$f4$f5$f5a\n
}
} else {
set f1 [packagetrace::overtype::left $c1 "${marg}<require"]
set f2 [packagetrace::overtype::left -overflow 1 $c2 "p= \"$pkg_\""] ;#disallow truncation!
set f2a $c2a
set f3 $c3
set f4 $c4
set f5 $c5
set f5a " > "
#puts -nonewline $ch $f1$c1a$f2$f2a$f3$f4$f5\n
packagetrace::emit $f1$c1a$f2$f2a$f3$f4$f5$f5a\n
set errMsg ""
#set t0 [clock clicks -milliseconds]
set t0 [clock microseconds]
if {[catch {set ver [$next require {*}$args]} errMsg]} {
set ver ""
#
#NOTE error must be raised at some point - see below
}
#set t [expr {[clock clicks -millisec]-$t0}]
set t [expr {([clock microseconds]-$t0)/1000.0}]
#jmn
set f1 [packagetrace::overtype::left $c1 "${margnext}<info "]
#set f1a "<info "
set f1a ""
set f2 [packagetrace::overtype::left -ellipsis 1 [string range $c2 0 end-1] "x= \"$args"]
if {[string length [string trimright $f2]] <= [expr [string length $c2]-1]} {
#right-trimmed value shorter than field.. therefore we need to close attribute
set f2 [packagetrace::overtype::left $c2 [string trimright $f2]\"]
}
#we use the attributename x because this is not necessarily the same as p! may be truncated.
set f3 [packagetrace::overtype::left $c3 "v= \"$ver\""]
#truncate time to c4 width - possibly losing some precision. If truncated - add closing double quote.
set f4 [packagetrace::overtype::left -overflow 1 $c4 "t= \"[lrange $t 0 1]\""]
if {[string length [string trimright $f4]] > [expr {[string length $c4]}]} {
set f4 "[packagetrace::overtype::left [string range $c4 0 end-1] [string trimright $f4]]\""
}
if {[string length $ver]} {
set num ""
foreach c [split $ver ""] {
if {[string is digit $c] || $c eq "."} {
append num $c
} else {
break
}
}
set ver $num
#review - scr not guaranteed to be valid tcl list - should parse properly?
set scr [$next ifneeded $pkg $ver]
if {[string range $scr end-2 end] ne ".tm"} {
set f5 $c5
} else {
#!todo - optionally output module path instead of boolean?
#set f5 [packagetrace::overtype::left -ellipsis 1 -ellipsistext ... [string range $c5 0 end-1] "tm= \"[lindex $scr end]"]
set f5 [packagetrace::overtype::left -ellipsis 1 -ellipsistext ... [string range $c5 0 end-1] "tm= \"1"]
if {[string length [string trimright $f5]] <= [expr [string length $c5]-1]} {
set f5 [packagetrace::overtype::left $c5 [string trimright $f5]\"]
}
}
} else {
set f5 $c5
}
set f5a [packagetrace::overtype::left $c5a "/>"] ;#end of <info
#puts -nonewline $ch "$f1$c1a$f2$c2a$f3$f4 $f5$f5a\n"
packagetrace::emit "$f1$c1a$f2$c2a$f3$f4 $f5$f5a\n"
set f1 [packagetrace::overtype::left $c1 "${marg}</require>"]
set f1a ""
set f2 ""
set c2a ""
set f3 ""
set f4 ""
set f5 ""
set f5a ""
#puts -nonewline $ch $f1$f1a$f2$c2a$f3$f4$f5$f5a\n
packagetrace::emit $f1$f1a$f2$c2a$f3$f4$f5$f5a\n
if {![string length $ver]} {
if {[lindex $args 0] eq "packagetrace"} {
#REVIEW - what is going on here?
namespace delete ::packagetrace::overtype
}
#we must raise an error if original 'package require' would have
incr ::packagetrace::level -1
error $errMsg
}
}
incr ::packagetrace::level -1
return $ver
}
vcompare - vsatisifies - provide - ifneeded {
set result [$next $subcommand {*}$args]
#puts -nonewline $ch " -- package $subcommand $args\n"
return $result
}
default {
set result [$next $subcommand {*}$args]
#puts $ch "*** here $subcommand $args"
return $result
}
}
}]
if {[set stored_target [dict get $stackrecord implementation]] ne ""} {
puts stderr "packagetrace::init renamed $package_command to $stored_target and is providing an override"
set f1 [string repeat { } 30]
#set f1a " "
set f1a ""
set f2 [packagetrace::overtype::left [string repeat { } 20] "PACKAGE"]
set f2a " "
set f3 [packagetrace::overtype::left [string repeat { } 15] "VERSION"]
set f4 [packagetrace::overtype::left [string repeat { } 12] "LOAD-ms"]
set f5 [packagetrace::overtype::left [string repeat { } 10] "MODULE"]
#puts -nonewline $::packagetrace::chan "-$f1$f1a$f2$f2a$f3$f4$f5\n"
#packagetrace::emit "-$f1$f1a$f2$f2a$f3$f4$f5\n"
puts -nonewline stderr "-$f1$f1a$f2$f2a$f3$f4$f5\n"
unset f1 f1a f2 f2a f3 f4 f5
} else {
puts stderr "packagetrace::init failed to rename $package_command"
}
}
}
}
#The preferred source of the ::overtype::<direction> functions is the 'overtype' package
# - pasted here because packagetrace should have no extra dependencies.
# - overtype package has better support for ansi and supports wide chars
namespace eval packagetrace::overtype {set version INLINE}
namespace eval packagetrace::overtype {
proc left {args} {
# @c overtype starting at left (overstrike)
# @c can/should we use something like this?: 'format "%-*s" $len $overtext
if {[llength $args] < 2} {
error {usage: ?-overflow [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext}
}
foreach {undertext overtext} [lrange $args end-1 end] break
set opt(-ellipsis) 0
set opt(-ellipsistext) {...}
set opt(-overflow) 0
array set opt [lrange $args 0 end-2]
set len [string length $undertext]
set overlen [string length $overtext]
set diff [expr {$overlen - $len}]
if {$diff > 0} {
if {$opt(-overflow)} {
return $overtext
} else {
if {$opt(-ellipsis)} {
return [right [string range $overtext 0 [expr {$len -1}]] $opt(-ellipsistext)]
} else {
return [string range $overtext 0 [expr {$len -1}]]
}
}
} else {
return "$overtext[string range $undertext $overlen end]"
}
}
proc centre {args} {
if {[llength $args] < 2} {
error {usage: ?-bias [left|right]? ?-overflow [1|0]? undertext overtext}
}
foreach {undertext overtext} [lrange $args end-1 end] break
set opt(-bias) left
set opt(-overflow) 0
array set opt [lrange $args 0 end-2]
set olen [string length $overtext]
set ulen [string length $undertext]
set diff [expr {$ulen - $olen}]
if {$diff > 0} {
set half [expr {round(int($diff / 2))}]
if {[string match right $opt(-bias)]} {
if {[expr {2 * $half}] < $diff} {
incr half
}
}
set rhs [expr {$diff - $half - 1}]
set lhs [expr {$half - 1}]
set a [string range $undertext 0 $lhs]
set b $overtext
set c [string range $undertext end-$rhs end]
return $a$b$c
} else {
if {$diff < 0} {
if {$opt(-overflow)} {
return $overtext
} else {
return [string range $overtext 0 [expr {$ulen - 1}]]
}
} else {
return $overtext
}
}
}
proc right {args} {
if {[llength $args] < 2} {
error {usage: ?-overflow [1|0]? undertext overtext}
}
lassign [lrange $args end-1 end] undertext overtext
set opt(-overflow) 0
array set opt [lrange $args 0 end-2]
set olen [string length $overtext]
set ulen [string length $undertext]
if {$opt(-overflow)} {
return [string range $undertext 0 end-$olen]$overtext
} else {
if {$olen > $ulen} {
set diff [expr {$olen - $ulen}]
return [string range $undertext 0 end-$olen][string range $overtext 0 end-$diff]
} else {
return [string range $undertext 0 end-$olen]$overtext
}
}
}
}
proc packagetrace::deinit {} {
packagetrace::disable
#namespace delete packagetrace
#package forget packagetrace
}
proc packagetrace::disable {} {
::commandstack::remove_rename {::tcl_findLibrary packagetrace}
::commandstack::remove_rename {::package packagetrace}
}
proc packagetrace::enable {} {
#init doesn't clear state - so this is effectively an alias
tailcall packagetrace::init
}
#clear state - reset to defaults
proc packagetrace::clear {} {
variable chan
set chan stderr
variable showpresent
set showpresent 1
}
package provide packagetrace [namespace eval packagetrace {
set version 0.8
}]

245
src/vendormodules/uuid-1.0.9.tm

@ -0,0 +1,245 @@
# uuid.tcl - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
#
# UUIDs are 128 bit values that attempt to be unique in time and space.
#
# Reference:
# http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
#
# uuid: scheme:
# http://www.globecom.net/ietf/draft/draft-kindel-uuid-uri-00.html
#
# Usage: uuid::uuid generate
# uuid::uuid equal $idA $idB
package require Tcl 8.5 9
namespace eval uuid {
variable accel
array set accel {critcl 0}
namespace export uuid
variable uid
if {![info exists uid]} {
set uid 1
}
proc K {a b} {set a}
}
###
# Optimization
# Caches machine info after the first pass
###
proc ::uuid::generate_tcl_machinfo {} {
variable machinfo
if {[info exists machinfo]} {
return $machinfo
}
lappend machinfo [clock seconds]; # timestamp
lappend machinfo [clock clicks]; # system incrementing counter
lappend machinfo [info hostname]; # spatial unique id (poor)
lappend machinfo [pid]; # additional entropy
lappend machinfo [array get ::tcl_platform]
###
# If we have /dev/urandom just stream 128 bits from that
###
if {[file exists /dev/urandom]} {
set fin [open /dev/urandom rb]
binary scan [read $fin 128] H* machinfo
close $fin
} elseif {[catch {package require nettool}]} {
# More spatial information -- better than hostname.
# bug 1150714: opening a server socket may raise a warning messagebox
# with WinXP firewall, using ipconfig will return all IP addresses
# including ipv6 ones if available. ipconfig is OK on win98+
if {[string equal $::tcl_platform(platform) "windows"]} {
catch {exec ipconfig} config
lappend machinfo $config
} else {
catch {
set s [socket -server void -myaddr [info hostname] 0]
K [fconfigure $s -sockname] [close $s]
} r
lappend machinfo $r
}
if {[package provide Tk] != {}} {
lappend machinfo [winfo pointerxy .]
lappend machinfo [winfo id .]
}
} else {
###
# If the nettool package works on this platform
# use the stream of hardware ids from it
###
lappend machinfo {*}[::nettool::hwid_list]
}
return $machinfo
}
# Generates a binary UUID as per the draft spec. We generate a pseudo-random
# type uuid (type 4). See section 3.4
#
proc ::uuid::generate_tcl {} {
package require md5 2
variable uid
set tok [md5::MD5Init]
md5::MD5Update $tok [incr uid]; # package incrementing counter
foreach string [generate_tcl_machinfo] {
md5::MD5Update $tok $string
}
set r [md5::MD5Final $tok]
binary scan $r c* r
# 3.4: set uuid versioning fields
lset r 8 [expr {([lindex $r 8] & 0x3F) | 0x80}]
lset r 6 [expr {([lindex $r 6] & 0x0F) | 0x40}]
return [binary format c* $r]
}
if {[string equal $tcl_platform(platform) "windows"]
&& [package provide critcl] != {}} {
namespace eval uuid {
critcl::ccode {
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <ole2.h>
typedef long (__stdcall *LPFNUUIDCREATE)(UUID *);
typedef const unsigned char cu_char;
}
critcl::cproc generate_c {Tcl_Interp* interp} ok {
HRESULT hr = S_OK;
int r = TCL_OK;
UUID uuid = {0};
HMODULE hLib;
LPFNUUIDCREATE lpfnUuidCreate = NULL;
hLib = LoadLibraryA(("rpcrt4.dll"));
if (hLib)
lpfnUuidCreate = (LPFNUUIDCREATE)
GetProcAddress(hLib, "UuidCreate");
if (lpfnUuidCreate) {
Tcl_Obj *obj;
lpfnUuidCreate(&uuid);
obj = Tcl_NewByteArrayObj((cu_char *)&uuid, sizeof(uuid));
Tcl_SetObjResult(interp, obj);
} else {
Tcl_SetResult(interp, "error: failed to create a guid",
TCL_STATIC);
r = TCL_ERROR;
}
return r;
}
}
}
# Convert a binary uuid into its string representation.
#
proc ::uuid::tostring {uuid} {
binary scan $uuid H* s
foreach {a b} {0 7 8 11 12 15 16 19 20 end} {
append r [string range $s $a $b] -
}
return [string tolower [string trimright $r -]]
}
# Convert a string representation of a uuid into its binary format.
#
proc ::uuid::fromstring {uuid} {
return [binary format H* [string map {- {}} $uuid]]
}
# Compare two uuids for equality.
#
proc ::uuid::equal {left right} {
set l [fromstring $left]
set r [fromstring $right]
return [string equal $l $r]
}
# Call our generate uuid implementation
proc ::uuid::generate {} {
variable accel
if {$accel(critcl)} {
return [generate_c]
} else {
return [generate_tcl]
}
}
# uuid generate -> string rep of a new uuid
# uuid equal uuid1 uuid2
#
proc uuid::uuid {cmd args} {
switch -exact -- $cmd {
generate {
if {[llength $args] != 0} {
return -code error "wrong # args:\
should be \"uuid generate\""
}
return [tostring [generate]]
}
equal {
if {[llength $args] != 2} {
return -code error "wrong \# args:\
should be \"uuid equal uuid1 uuid2\""
}
return [eval [linsert $args 0 equal]]
}
default {
return -code error "bad option \"$cmd\":\
must be generate or equal"
}
}
}
# -------------------------------------------------------------------------
# LoadAccelerator --
#
# This package can make use of a number of compiled extensions to
# accelerate the digest computation. This procedure manages the
# use of these extensions within the package. During normal usage
# this should not be called, but the test package manipulates the
# list of enabled accelerators.
#
proc ::uuid::LoadAccelerator {name} {
variable accel
set r 0
switch -exact -- $name {
critcl {
if {![catch {package require tcllibc}]} {
set r [expr {[info commands ::uuid::generate_c] != {}}]
}
}
default {
return -code error "invalid accelerator package:\
must be one of [join [array names accel] {, }]"
}
}
set accel($name) $r
}
# -------------------------------------------------------------------------
# Try and load a compiled extension to help.
namespace eval ::uuid {
variable e {}
foreach e {critcl} {
if {[LoadAccelerator $e]} break
}
unset e
}
package provide uuid 1.0.9
# -------------------------------------------------------------------------
# Local variables:
# mode: tcl
# indent-tabs-mode: nil
# End:

BIN
src/vfs/_vfscommon.vfs/modules/modpodtest-0.1.0.tm

Binary file not shown.

2
src/vfs/_vfscommon.vfs/modules/punk/char-0.1.0.tm

@ -2788,7 +2788,7 @@ tcl::namespace::eval punk::char::lib {
proc superscript_number {n} {
if {$n eq ""} {return ""}
variable num_superscript
variable num_super_re
variable num_supersub_re
if {![regexp $num_supersub_re $n]} {
error "Cannot convert string '$n' to superscript. valid chars: [dict keys $num_superscript]"
}

7
src/vfs/_vfscommon.vfs/modules/punk/mix/cli-0.3.1.tm

@ -759,7 +759,7 @@ namespace eval punk::mix::cli {
}
} else {
puts -nonewline stderr "P"
puts -nonewline stderr "Z"
set did_skip 1
#set file_record [punkcheck::installfile_skipped_install $basedir $file_record]
$build_event targetset_end SKIPPED
@ -791,7 +791,7 @@ namespace eval punk::mix::cli {
$event targetset_end OK -note "zip modpod"
}
} else {
puts -nonewline stderr "p"
puts -nonewline stderr "z"
set did_skip 1
if {$is_interesting} {
puts stderr "$modulefile [$event targetset_source_changes]"
@ -802,7 +802,8 @@ namespace eval punk::mix::cli {
}
tarjar {
#basename may still contain #tarjar-
#to be obsoleted - update modpod to (optionally) use vfs::tar
#to be obsoleted - update modpod to (optionally) use vfs::tar ?
}
file {
set m $modpath

245
src/vfs/_vfscommon.vfs/modules/uuid-1.0.9.tm

@ -0,0 +1,245 @@
# uuid.tcl - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
#
# UUIDs are 128 bit values that attempt to be unique in time and space.
#
# Reference:
# http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
#
# uuid: scheme:
# http://www.globecom.net/ietf/draft/draft-kindel-uuid-uri-00.html
#
# Usage: uuid::uuid generate
# uuid::uuid equal $idA $idB
package require Tcl 8.5 9
namespace eval uuid {
variable accel
array set accel {critcl 0}
namespace export uuid
variable uid
if {![info exists uid]} {
set uid 1
}
proc K {a b} {set a}
}
###
# Optimization
# Caches machine info after the first pass
###
proc ::uuid::generate_tcl_machinfo {} {
variable machinfo
if {[info exists machinfo]} {
return $machinfo
}
lappend machinfo [clock seconds]; # timestamp
lappend machinfo [clock clicks]; # system incrementing counter
lappend machinfo [info hostname]; # spatial unique id (poor)
lappend machinfo [pid]; # additional entropy
lappend machinfo [array get ::tcl_platform]
###
# If we have /dev/urandom just stream 128 bits from that
###
if {[file exists /dev/urandom]} {
set fin [open /dev/urandom rb]
binary scan [read $fin 128] H* machinfo
close $fin
} elseif {[catch {package require nettool}]} {
# More spatial information -- better than hostname.
# bug 1150714: opening a server socket may raise a warning messagebox
# with WinXP firewall, using ipconfig will return all IP addresses
# including ipv6 ones if available. ipconfig is OK on win98+
if {[string equal $::tcl_platform(platform) "windows"]} {
catch {exec ipconfig} config
lappend machinfo $config
} else {
catch {
set s [socket -server void -myaddr [info hostname] 0]
K [fconfigure $s -sockname] [close $s]
} r
lappend machinfo $r
}
if {[package provide Tk] != {}} {
lappend machinfo [winfo pointerxy .]
lappend machinfo [winfo id .]
}
} else {
###
# If the nettool package works on this platform
# use the stream of hardware ids from it
###
lappend machinfo {*}[::nettool::hwid_list]
}
return $machinfo
}
# Generates a binary UUID as per the draft spec. We generate a pseudo-random
# type uuid (type 4). See section 3.4
#
proc ::uuid::generate_tcl {} {
package require md5 2
variable uid
set tok [md5::MD5Init]
md5::MD5Update $tok [incr uid]; # package incrementing counter
foreach string [generate_tcl_machinfo] {
md5::MD5Update $tok $string
}
set r [md5::MD5Final $tok]
binary scan $r c* r
# 3.4: set uuid versioning fields
lset r 8 [expr {([lindex $r 8] & 0x3F) | 0x80}]
lset r 6 [expr {([lindex $r 6] & 0x0F) | 0x40}]
return [binary format c* $r]
}
if {[string equal $tcl_platform(platform) "windows"]
&& [package provide critcl] != {}} {
namespace eval uuid {
critcl::ccode {
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <ole2.h>
typedef long (__stdcall *LPFNUUIDCREATE)(UUID *);
typedef const unsigned char cu_char;
}
critcl::cproc generate_c {Tcl_Interp* interp} ok {
HRESULT hr = S_OK;
int r = TCL_OK;
UUID uuid = {0};
HMODULE hLib;
LPFNUUIDCREATE lpfnUuidCreate = NULL;
hLib = LoadLibraryA(("rpcrt4.dll"));
if (hLib)
lpfnUuidCreate = (LPFNUUIDCREATE)
GetProcAddress(hLib, "UuidCreate");
if (lpfnUuidCreate) {
Tcl_Obj *obj;
lpfnUuidCreate(&uuid);
obj = Tcl_NewByteArrayObj((cu_char *)&uuid, sizeof(uuid));
Tcl_SetObjResult(interp, obj);
} else {
Tcl_SetResult(interp, "error: failed to create a guid",
TCL_STATIC);
r = TCL_ERROR;
}
return r;
}
}
}
# Convert a binary uuid into its string representation.
#
proc ::uuid::tostring {uuid} {
binary scan $uuid H* s
foreach {a b} {0 7 8 11 12 15 16 19 20 end} {
append r [string range $s $a $b] -
}
return [string tolower [string trimright $r -]]
}
# Convert a string representation of a uuid into its binary format.
#
proc ::uuid::fromstring {uuid} {
return [binary format H* [string map {- {}} $uuid]]
}
# Compare two uuids for equality.
#
proc ::uuid::equal {left right} {
set l [fromstring $left]
set r [fromstring $right]
return [string equal $l $r]
}
# Call our generate uuid implementation
proc ::uuid::generate {} {
variable accel
if {$accel(critcl)} {
return [generate_c]
} else {
return [generate_tcl]
}
}
# uuid generate -> string rep of a new uuid
# uuid equal uuid1 uuid2
#
proc uuid::uuid {cmd args} {
switch -exact -- $cmd {
generate {
if {[llength $args] != 0} {
return -code error "wrong # args:\
should be \"uuid generate\""
}
return [tostring [generate]]
}
equal {
if {[llength $args] != 2} {
return -code error "wrong \# args:\
should be \"uuid equal uuid1 uuid2\""
}
return [eval [linsert $args 0 equal]]
}
default {
return -code error "bad option \"$cmd\":\
must be generate or equal"
}
}
}
# -------------------------------------------------------------------------
# LoadAccelerator --
#
# This package can make use of a number of compiled extensions to
# accelerate the digest computation. This procedure manages the
# use of these extensions within the package. During normal usage
# this should not be called, but the test package manipulates the
# list of enabled accelerators.
#
proc ::uuid::LoadAccelerator {name} {
variable accel
set r 0
switch -exact -- $name {
critcl {
if {![catch {package require tcllibc}]} {
set r [expr {[info commands ::uuid::generate_c] != {}}]
}
}
default {
return -code error "invalid accelerator package:\
must be one of [join [array names accel] {, }]"
}
}
set accel($name) $r
}
# -------------------------------------------------------------------------
# Try and load a compiled extension to help.
namespace eval ::uuid {
variable e {}
foreach e {critcl} {
if {[LoadAccelerator $e]} break
}
unset e
}
package provide uuid 1.0.9
# -------------------------------------------------------------------------
# Local variables:
# mode: tcl
# indent-tabs-mode: nil
# End:

BIN
src/vfs/_vfscommon.vfs/modules/zipper-0.12.tm

Binary file not shown.
Loading…
Cancel
Save