Browse Source

vfs updates twapi,tcllib,tcllibc

master
Julian Noble 3 months ago
parent
commit
4ceb590875
  1. 385
      src/vfs/_vfscommon/modules/packageTrace-0.5.tm
  2. 4
      src/vfs/_vfscommon/modules/packagetrace-0.7.tm
  3. 643
      src/vfs/_vfscommon/modules/packagetrace-0.8.tm
  4. 39
      src/vfs/_vfscommon/modules/punk-0.1.tm
  5. 2
      src/vfs/_vfscommon/modules/punk/basictelnet-0.1.0.tm
  6. 39
      src/vfs/_vfscommon/modules/punk/console-0.1.1.tm
  7. 160
      src/vfs/_vfscommon/modules/punk/du-0.1.0.tm
  8. 171
      src/vfs/_vfscommon/modules/punk/lib-0.1.1.tm
  9. 25
      src/vfs/_vfscommon/modules/punk/mix/base-0.1.tm
  10. 7
      src/vfs/_vfscommon/modules/punk/mix/commandset/doc-0.1.0.tm
  11. 2
      src/vfs/_vfscommon/modules/punk/mix/util-0.1.0.tm
  12. 52
      src/vfs/_vfscommon/modules/punk/nav/fs-0.1.0.tm
  13. 26
      src/vfs/_vfscommon/modules/punk/packagepreference-0.1.0.tm
  14. 30
      src/vfs/_vfscommon/modules/punk/repl-0.1.tm
  15. 24
      src/vfs/_vfscommon/modules/punk/repl/codethread-0.1.0.tm
  16. 5
      src/vfs/_vfscommon/modules/punk/repo-0.1.1.tm
  17. 10
      src/vfs/_vfscommon/modules/textblock-0.1.1.tm
  18. 0
      src/vfs/critcl-3.3.1.vfs/README.md
  19. 801
      src/vfs/critcl-3.3.1.vfs/build.tcl
  20. 51
      src/vfs/critcl-3.3.1.vfs/genStubs.tcl
  21. 1944
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/critcl.tcl
  22. 2
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/pkgIndex.tcl
  23. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/runtime.tcl
  24. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/Config.in
  25. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/Makefile.in
  26. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/aclocal.m4
  27. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/configure.in
  28. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/README.txt
  29. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/install-sh
  30. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/license.terms
  31. 0
      src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/tcl.m4
  32. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-bitmap/bitmap.tcl
  33. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-bitmap/pkgIndex.tcl
  34. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/c/callback.c
  35. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/c/callback.h
  36. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/c/callback_int.h
  37. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/callback.tcl
  38. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-class/class.h
  39. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-class/class.tcl
  40. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-class/pkgIndex.tcl
  41. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/allocs/critcl_alloc.h
  42. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/asserts/critcl_assert.h
  43. 86
      src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/cutil.tcl
  44. 2
      src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/pkgIndex.tcl
  45. 170
      src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/trace/critcl_trace.h
  46. 295
      src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/trace/trace.c
  47. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-emap/emap.tcl
  48. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-emap/pkgIndex.tcl
  49. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-enum/enum.tcl
  50. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-enum/pkgIndex.tcl
  51. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-iassoc/iassoc.tcl
  52. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-iassoc/pkgIndex.tcl
  53. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-literals/literals.tcl
  54. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-literals/pkgIndex.tcl
  55. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-md5c/md5c.tcl
  56. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-md5c/md5c_c/md5.c
  57. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-md5c/md5c_c/md5.h
  58. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-platform/pkgIndex.tcl
  59. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-platform/platform.tcl
  60. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-util/pkgIndex.tcl
  61. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl-util/util.tcl
  62. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/Config
  63. 6831
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl.tcl
  64. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/cdata.c
  65. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/header.c
  66. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/pkginit.c
  67. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/pkginitend.c
  68. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/pkginittk.c
  69. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/preload.c
  70. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/storageclass.c
  71. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/stubs.c
  72. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/stubs_e.c
  73. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/X.h
  74. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xatom.h
  75. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xfuncproto.h
  76. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xlib.h
  77. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xutil.h
  78. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/cursorfont.h
  79. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/keysym.h
  80. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/keysymdef.h
  81. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/tkIntXlibDecls.h
  82. 2645
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tcl.h
  83. 4119
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tclDecls.h
  84. 144
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tclPlatDecls.h
  85. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tk.h
  86. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tkDecls.h
  87. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tkPlatDecls.h
  88. 2720
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.7/tcl.h
  89. 4498
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.7/tclDecls.h
  90. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.7/tclPlatDecls.h
  91. 2642
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl9.0/tcl.h
  92. 4334
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl9.0/tclDecls.h
  93. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl9.0/tclPlatDecls.h
  94. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tclAppInit.c
  95. 73
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tclpre9compat.h
  96. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tkstubs.c
  97. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tkstubs_noconst.c
  98. 0
      src/vfs/critcl-3.3.1.vfs/lib/critcl/license.terms
  99. 2
      src/vfs/critcl-3.3.1.vfs/lib/critcl/pkgIndex.tcl
  100. 0
      src/vfs/critcl-3.3.1.vfs/lib/critclf/Config
  101. Some files were not shown because too many files have changed in this diff Show More

385
src/vfs/_vfscommon/modules/packageTrace-0.5.tm

@ -1,385 +0,0 @@
#JMN 2005 - Public Domain
#
#WARNING: This package does 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.
package provide packageTrace [namespace eval packageTrace {
variable chan stderr
variable showpresent 1
set version 0.5
}]
proc packageTrace::help {} {
return {
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.)
set packageTrace::chan to desired output channel. (default stderr)
set packageTrace::showpresent 0 to skip <present/> output
}
}
#The preferred source of the ::overtype::<direction> functions is the 'overtype' package: http://mini.net/tcl/overtype
# - pasted here because packageTrace should have no extra dependencies.
#
namespace eval packageTrace_overtype {set version INLINE}
proc packageTrace_overtype::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 [packageTrace_overtype::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 packageTrace_overtype::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 packageTrace_overtype::right {args} {
# @d !todo - implement overflow, length checks etc
if {[llength $args] < 2} {
error {usage: ?-overflow [1|0]? undertext overtext}
}
#foreach {undertext overtext} [lrange $args end-1 end] break
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
}
}
}
#convenience function in case the sequence 'package forget packageTrace;package require packageTrace' is too unintuitive or weird.
proc ::packageTrace::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 ::packageTrace::init {} {
uplevel 1 {
set ::packageTrace::level -1
if {![llength [info commands tcl_findLibrary]]} {
eval $::auto_index(tcl_findLibrary)
}
package require commandstack
#rename tcl_findLibrary _tcl_findLibrary
set stackrecord [commandstack::rename_command tcl_findLibrary packageTrace]
set old_tcl_findLibrary [dict get $stackrecord implementation]
#set old_tcl_findLibrary [::commandstack::get_next_command package packageTrace]
proc tcl_findLibrary [info args $old_tcl_findLibrary] {
set original [::commandstack::get_next_command tcl_findLibrary packageTrace]
set marg [string repeat { } $::packageTrace::level]
puts -nonewline $::packageTrace::chan "${marg}<extra> tcl_findLibrary $basename $version $patch $initScript $enVarName $varName </extra>\n"
uplevel 1 [list $original $basename $version $patch $initScript $enVarName $varName]
}
set stackrecord [commandstack::rename_command package packageTrace]
set stored_target [dict get $stackrecord implementation]
set next_target [::commandstack::get_next_command package packageTrace]
if {$stored_target ne $next_target} {
error "(packageTrace::init) something went wrong renaming command 'package'"
}
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 { } 13] "VERSION"]
set f4 [packageTrace_overtype::left [string repeat { } 10] "LOAD-ms"]
set f5 [packageTrace_overtype::left [string repeat { } 10] "MODULE"]
puts -nonewline $::packageTrace::chan "-$f1$f1a$f2$f2a$f3$f4$f5\n"
unset f1 f1a f2 f2a f3 f4 f5
proc package {sub args} [string map [list %next% $next_target] {
set ch $::packageTrace::chan
set next [::commandstack::get_next_command package packageTrace]
if {$next ne "%next%"} {
puts stderr "(packageTrace package) DEBUG - command changed since start: %next% 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 $sub {*}$args]
#}
if {$sub eq "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 { } 13] ;#version col
set c4 [string repeat { } 10] ;#timing col
set c5 [string repeat { } 10] ;#module col
set c5a [string repeat { } 5] ;#close result tag col
foreach a $args {
if {[string range $a 0 0] ne "-"} {
#assume 1st non-dashed argument is package name
set pkg $a
set pkg_ [lrange $args [lsearch $args $a] end] ;# e.g "Tcl 8.6"
break
}
}
incr ::packageTrace::level
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 "/> "
set f3 ""
set f4 ""
set f5 ""
puts -nonewline $ch $f1$c1a$f2$f2a$f3$f4$f5\n
}
} else {
set f1 [packageTrace_overtype::left $c1 "${marg}<require"]
set f2 [packageTrace_overtype::left -overflow 1 $c2 "p= \"$pkg_\""] ;#disallow truncation!
set f2a " > "
set f3 ""
set f4 ""
set f5 ""
puts -nonewline $ch $f1$c1a$f2$f2a$f3$f4$f5\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\""]
set f4 [packageTrace_overtype::left $c4 "t= \"[lrange $t 0 1]\""]
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
set scr [$next ifneeded $pkg $ver]
if {[string range [lindex $scr 1] 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 1]"]
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$f1a$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
if {![string length $ver]} {
if {[lindex $args 0] eq "packageTrace"} {
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
} elseif {[lsearch [list vcompare vsatisfies provide ifneeded] $sub] < 0} {
set ver [$next $sub {*}$args]
#puts -nonewline $ch " -- package $sub $args\n"
} else {
set ver [$next $sub {*}$args]
#puts $ch "*** here $sub $args"
}
return $ver
}]
}
}
proc packageTrace::deinit {} {
packageTrace::disable
#namespace delete packageTrace
#package forget packageTrace
}
proc packageTrace::disable {} {
::commandstack::remove_renaming_package tcl_findLibrary packageTrace
::commandstack::remove_renaming_package 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
}
packageTrace::init

4
src/vfs/_vfscommon/modules/packagetrace-0.7.tm

@ -86,6 +86,10 @@ set packagetrace::showpresent 0 to skip <present/> output
"" { "" {
return $chan return $chan
} }
none {
set chan none
return none
}
stderr - stdout { stderr - stdout {
#note stderr stdout not necessarily in [chan names] (due to transforms etc?) but can still work #note stderr stdout not necessarily in [chan names] (due to transforms etc?) but can still work
set chan $ch set chan $ch

643
src/vfs/_vfscommon/modules/packagetrace-0.8.tm

@ -0,0 +1,643 @@
#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_requirement $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
}]

39
src/vfs/_vfscommon/modules/punk-0.1.tm

@ -213,6 +213,13 @@ namespace eval punk {
proc objclone {obj} { proc objclone {obj} {
append obj2 $obj {} append obj2 $obj {}
} }
proc set_clone {varname obj} {
#maintenance: also punk::lib::set_clone
#e.g used by repl's codeinterp. Maintains internal rep, easier to call e.g interp eval code [list punk::set_clone varnmame $val]
append obj2 $obj {}
uplevel 1 [list set $varname $obj2]
}
interp alias "" strlen "" ::punk::strlen interp alias "" strlen "" ::punk::strlen
interp alias "" str_len "" ::punk::strlen interp alias "" str_len "" ::punk::strlen
interp alias "" objclone "" ::punk::objclone interp alias "" objclone "" ::punk::objclone
@ -2121,8 +2128,8 @@ namespace eval punk {
set level_script_complete 1 set level_script_complete 1
} }
{@V\*@*} - {@v\*@*} { {@V\*@*} - {@v\*@*} {
#dict value glob - return values #dict value glob - return values
set active_key_type "dict" set active_key_type dict
set keyglob [string range $index 4 end] set keyglob [string range $index 4 end]
append script [tstr -return string -allowcommands { append script [tstr -return string -allowcommands {
if {[catch {dict size $leveldata}]} { if {[catch {dict size $leveldata}]} {
@ -2132,7 +2139,7 @@ namespace eval punk {
if {$get_not} { if {$get_not} {
lappend INDEX_OPERATIONS globvalue-get-values-not lappend INDEX_OPERATIONS globvalue-get-values-not
append script \n [string map [list <keyglob> $keyglob] { append script \n [string map [list <keyglob> $keyglob] {
# set active_key_type "dict" index_operation: globvalue-get-values-not" # set active_key_type "dict" ;# index_operation: globvalue-get-values-not
set assigned [list] set assigned [list]
tcl::dict::for {k v} $leveldata { tcl::dict::for {k v} $leveldata {
if {![string match <keyglob> $v]} { if {![string match <keyglob> $v]} {
@ -2144,7 +2151,7 @@ namespace eval punk {
} else { } else {
lappend INDEX_OPERATIONS globvalue-get-values lappend INDEX_OPERATIONS globvalue-get-values
append script \n [string map [list <keyglob> $keyglob] { append script \n [string map [list <keyglob> $keyglob] {
# set active_key_type "dict" index_operation: globvalue-get-value # set active_key_type "dict" ;#index_operation: globvalue-get-value
set assigned [dict values $leveldata <keyglob>] set assigned [dict values $leveldata <keyglob>]
}] }]
} }
@ -2166,7 +2173,7 @@ namespace eval punk {
} else { } else {
lappend INDEX_OPERATIONS globkeyvalue-get-pairs lappend INDEX_OPERATIONS globkeyvalue-get-pairs
append script \n [string map [list <keyvalglob> $keyvalglob] { append script \n [string map [list <keyvalglob> $keyvalglob] {
# set active_key_type "dict" index_operation: globkeyvalue-get-pairs-not" # set active_key_type "dict" ;# index_operation: globkeyvalue-get-pairs-not
set assigned [dict create] set assigned [dict create]
tcl::dict::for {k v} $leveldata { tcl::dict::for {k v} $leveldata {
if {[string match <keyvalglob> $k] || [string match <keyvalglob> $v]} { if {[string match <keyvalglob> $k] || [string match <keyvalglob> $v]} {
@ -4952,17 +4959,14 @@ namespace eval punk {
} else { } else {
#tags ? #tags ?
#debug.punk.pipe {>>raw commandline: [concat $rhs $segment_members_filled]} 5 #debug.punk.pipe {>>raw commandline: [concat $rhs $segment_members_filled]} 5
if 0 { if {false} {
#set s [list uplevel 1 [concat $rhs $segment_members_filled]] #set s [list uplevel 1 [concat $rhs $segment_members_filled]]
if {![info exists pscript]} { if {![info exists pscript]} {
upvar ::_pipescript pscript upvar ::_pipescript pscript
} }
if {![info exists pscript]} { if {![info exists pscript]} {
#set pscript $s #set pscript $s
set pscript [funcl::o_of_n 1 $segment_members] set pscript [funcl::o_of_n 1 $segment_members]
} else { } else {
#set pscript [string map [list <p> $pscript] {uplevel 1 [concat $rhs $segment_members_filled [<p>]]}] #set pscript [string map [list <p> $pscript] {uplevel 1 [concat $rhs $segment_members_filled [<p>]]}]
#set snew "set pipe_$i \[uplevel 1 \[list $rhs $segment_members_filled " #set snew "set pipe_$i \[uplevel 1 \[list $rhs $segment_members_filled "
@ -4972,6 +4976,7 @@ namespace eval punk {
} }
} }
set cmdlist_result [uplevel 1 $segment_members_filled] set cmdlist_result [uplevel 1 $segment_members_filled]
#set d [_multi_bind_result $returnvarspec [punk::K $segment_members_filled [unset segment_members_filled]]] #set d [_multi_bind_result $returnvarspec [punk::K $segment_members_filled [unset segment_members_filled]]]
set d [_multi_bind_result $returnvarspec [lindex [list $cmdlist_result [unset cmdlist_result]] 0 ]] set d [_multi_bind_result $returnvarspec [lindex [list $cmdlist_result [unset cmdlist_result]] 0 ]]
@ -7321,16 +7326,22 @@ namespace eval punk {
if {$topic in [list tcl]} { if {$topic in [list tcl]} {
if {[punk::lib::system::has_script_var_bug]} { if {[punk::lib::system::has_tclbug_script_var]} {
append warningblock \n "minor warning: punk::lib::system::has_script_var_bug returned true! (string rep for list variable in script generated when script changed)" append warningblock \n "minor warning: punk::lib::system::has_tclbug_script_var returned true! (string rep for list variable in script generated when script changed)"
} }
if {[punk::lib::system::has_safeinterp_compile_bug]} { if {[punk::lib::system::has_tclbug_safeinterp_compile]} {
set indent " " set indent " "
append warningblock \n "[a+ web-red]warning: punk::lib::system::has_safeinterp_compile_bug returned true!" \n append warningblock \n "[a+ web-red]warning: punk::lib::system::has_tclbug_safeinterp returned true!" \n
append warningblock "${indent}(ensemble commands not compiled in safe interps - heavy performance impact in safe interps)" \n append warningblock "${indent}(ensemble commands not compiled in safe interps - heavy performance impact in safe interps)" \n
append warningblock "${indent}see https://core.tcl-lang.org/tcl/tktview/1095bf7f75" append warningblock "${indent}see https://core.tcl-lang.org/tcl/tktview/1095bf7f75"
append warningblock [a] append warningblock [a]
} }
if {[punk::lib::system::has_tclbug_list_quoting_emptyjoin]} {
set indent " "
append warningblock \n "[a+ web-red]warning: punk::lib::system::has_tclbug_list_quoting returned true!" \n
append warningblock "${indent}lists elements not properly quoted in some cases. e.g 'list {*}[lindex {etc #foo} 1] {*}[list]' (#foo not braced)" \n
append warningblock "${indent}see https://core.tcl-lang.org/tcl/tktview/e38dce74e2"
}
} }
set text "" set text ""

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

@ -525,7 +525,7 @@ namespace eval punk::basictelnet {
# - review # - review
#if we didn't make agreement that server would echo and we're in raw mode #if we didn't make agreement that server would echo and we're in raw mode
if {![dict get $server_option_state 1] && $::punk::console::is_raw} { if {![dict get $server_option_state 1] && [tsv::get console is_raw]} {
puts -nonewline stdout $chunk puts -nonewline stdout $chunk
} }
# -- --- --- --- # -- --- --- ---

39
src/vfs/_vfscommon/modules/punk/console-0.1.1.tm

@ -44,6 +44,7 @@
#[list_begin itemized] #[list_begin itemized]
package require Tcl 8.6- package require Tcl 8.6-
package require Thread ;#tsv required to sync is_raw
package require punk::ansi package require punk::ansi
#*** !doctools #*** !doctools
#[item] [package {Tcl 8.6-}] #[item] [package {Tcl 8.6-}]
@ -84,7 +85,12 @@ namespace eval punk::console {
variable previous_stty_state_stdin "" variable previous_stty_state_stdin ""
variable previous_stty_state_stdout "" variable previous_stty_state_stdout ""
variable previous_stty_state_stderr "" variable previous_stty_state_stderr ""
variable is_raw 0
#variable is_raw 0
if {![tsv::exists console is_raw]} {
tsv::set console is_raw 0
}
variable input_chunks_waiting variable input_chunks_waiting
if {![info exists input_chunks_waiting(stdin)]} { if {![info exists input_chunks_waiting(stdin)]} {
set input_chunks_waiting(stdin) [list] set input_chunks_waiting(stdin) [list]
@ -183,7 +189,8 @@ namespace eval punk::console {
#NOTE - the is_raw is only being set in current interp - but the channel is shared. #NOTE - the is_raw is only being set in current interp - but the channel is shared.
#this is problematic with the repl thread being separate. - must be a tsv? REVIEW #this is problematic with the repl thread being separate. - must be a tsv? REVIEW
proc enableRaw {{channel stdin}} { proc enableRaw {{channel stdin}} {
variable is_raw #variable is_raw
variable previous_stty_state_$channel variable previous_stty_state_$channel
set sttycmd [auto_execok stty] set sttycmd [auto_execok stty]
if {[set previous_stty_state_$channel] eq ""} { if {[set previous_stty_state_$channel] eq ""} {
@ -193,21 +200,21 @@ namespace eval punk::console {
} }
exec {*}$sttycmd raw -echo <@$channel exec {*}$sttycmd raw -echo <@$channel
set is_raw 1 tsv::set console is_raw 1
return [dict create previous [set previous_stty_state_$channel]] return [dict create previous [set previous_stty_state_$channel]]
} }
proc disableRaw {{channel stdin}} { proc disableRaw {{channel stdin}} {
variable is_raw #variable is_raw
variable previous_stty_state_$channel variable previous_stty_state_$channel
set sttycmd [auto_execok stty] set sttycmd [auto_execok stty]
if {[set previous_stty_state_$channel] ne ""} { if {[set previous_stty_state_$channel] ne ""} {
exec {*}$sttycmd [set previous_stty_state_$channel] exec {*}$sttycmd [set previous_stty_state_$channel]
set previous_stty_state_$channel "" set previous_stty_state_$channel ""
set is_raw 0 tsv::set console is_raw 0
return restored return restored
} }
exec {*}$sttycmd -raw echo <@$channel exec {*}$sttycmd -raw echo <@$channel
set is_raw 0 tsv::set console is_raw 0
return done return done
} }
proc enableVirtualTerminal {{channels {input output}}} { proc enableVirtualTerminal {{channels {input output}}} {
@ -249,11 +256,11 @@ namespace eval punk::console {
} }
proc mode {{raw_or_line query}} { proc mode {{raw_or_line query}} {
variable is_raw #variable is_raw
variable ansi_available variable ansi_available
set raw_or_line [string tolower $raw_or_line] set raw_or_line [string tolower $raw_or_line]
if {$raw_or_line eq "query"} { if {$raw_or_line eq "query"} {
if {$is_raw} { if {[tsv::get console is_raw]} {
return "raw" return "raw"
} else { } else {
return "line" return "line"
@ -493,7 +500,7 @@ namespace eval punk::console {
} }
proc [namespace parent]::enableRaw {{channel stdin}} { proc [namespace parent]::enableRaw {{channel stdin}} {
variable is_raw #variable is_raw
variable previous_stty_state_$channel variable previous_stty_state_$channel
if {[package provide twapi] ne ""} { if {[package provide twapi] ne ""} {
@ -506,7 +513,7 @@ namespace eval punk::console {
#set newmode [dict merge $oldmode [dict create -lineinput 0 -echoinput 0]] #set newmode [dict merge $oldmode [dict create -lineinput 0 -echoinput 0]]
set newmode [twapi::get_console_input_mode] set newmode [twapi::get_console_input_mode]
set is_raw 1 tsv::set console is_raw 1
#don't disable handler - it will detect is_raw #don't disable handler - it will detect is_raw
### twapi::set_console_control_handler {} ### twapi::set_console_control_handler {}
return [list stdin [list from $oldmode to $newmode]] return [list stdin [list from $oldmode to $newmode]]
@ -516,7 +523,7 @@ namespace eval punk::console {
} }
exec {*}$sttycmd raw -echo <@$channel exec {*}$sttycmd raw -echo <@$channel
set is_raw 1 tsv::set console is_raw 1
#review - inconsistent return dict #review - inconsistent return dict
return [dict create stdin [list from [set previous_stty_state_$channel] to "" note "fixme - to state not shown"]] return [dict create stdin [list from [set previous_stty_state_$channel] to "" note "fixme - to state not shown"]]
} else { } else {
@ -528,7 +535,7 @@ namespace eval punk::console {
#could be we were missing a step in reopening stdin and console configuration? #could be we were missing a step in reopening stdin and console configuration?
proc [namespace parent]::disableRaw {{channel stdin}} { proc [namespace parent]::disableRaw {{channel stdin}} {
variable is_raw #variable is_raw
variable previous_stty_state_$channel variable previous_stty_state_$channel
if {[package provide twapi] ne ""} { if {[package provide twapi] ne ""} {
@ -537,7 +544,7 @@ namespace eval punk::console {
# Turn on the echo and line-editing bits # Turn on the echo and line-editing bits
twapi::modify_console_input_mode $console_handle -lineinput 1 -echoinput 1 twapi::modify_console_input_mode $console_handle -lineinput 1 -echoinput 1
set newmode [twapi::get_console_input_mode] set newmode [twapi::get_console_input_mode]
set is_raw 0 tsv::set console is_raw 0
return [list stdin [list from $oldmode to $newmode]] return [list stdin [list from $oldmode to $newmode]]
} elseif {[set sttycmd [auto_execok stty]] ne ""} { } elseif {[set sttycmd [auto_execok stty]] ne ""} {
#stty can return info on windows - but doesn't seem to be able to set anything. #stty can return info on windows - but doesn't seem to be able to set anything.
@ -550,7 +557,7 @@ namespace eval punk::console {
return restored return restored
} }
exec {*}$sttycmd -raw echo <@$channel exec {*}$sttycmd -raw echo <@$channel
set is_raw 0 tsv::set console is_raw 0
#do we really want to exec stty yet again to show final 'to' state? #do we really want to exec stty yet again to show final 'to' state?
#probably not. We should work out how to read the stty result flags and set a result.. or just limit from,to to showing echo and lineedit states. #probably not. We should work out how to read the stty result flags and set a result.. or just limit from,to to showing echo and lineedit states.
return [list stdin [list from "[set previous_stty_state_$channel]" to "" note "fixme - to state not shown"]] return [list stdin [list from "[set previous_stty_state_$channel]" to "" note "fixme - to state not shown"]]
@ -634,7 +641,7 @@ namespace eval punk::console {
puts -nonewline $output $query;flush $output puts -nonewline $output $query;flush $output
#todo - test and save rawstate so we don't disableRaw if console was already raw #todo - test and save rawstate so we don't disableRaw if console was already raw
if {!$::punk::console::is_raw} { if {![tsv::get console is_raw]} {
set was_raw 0 set was_raw 0
punk::console::enableRaw punk::console::enableRaw
} else { } else {
@ -1378,7 +1385,7 @@ namespace eval punk::console {
#todo - compare speed with get_cursor_pos - work out why the big difference #todo - compare speed with get_cursor_pos - work out why the big difference
proc test_cursor_pos {} { proc test_cursor_pos {} {
if {!$::punk::console::is_raw} { if {![tsv::get console is_raw]} {
set was_raw 0 set was_raw 0
enableRaw enableRaw
} else { } else {

160
src/vfs/_vfscommon/modules/punk/du-0.1.0.tm

@ -1065,56 +1065,65 @@ namespace eval punk::du {
#note - with this design, we can't glob for all except dotfiles - this is for cross-platform consistency and efficiency (Review). #note - with this design, we can't glob for all except dotfiles - this is for cross-platform consistency and efficiency (Review).
#dotfiles aren't considered hidden on all platforms #dotfiles aren't considered hidden on all platforms
#some sort of antiglob is a possible enhancement and more consistent with the view that leading dot should be treated as any other filename character in this context. #some sort of antiglob is a possible enhancement and more consistent with the view that leading dot should be treated as any other filename character in this context.
if {$opt_glob eq "*"} { if {"windows" eq $::tcl_platform(platform)} {
#Note - glob operations seem to be faster than looped tests like 'file isdirectory' & 'file readlink' if {$opt_glob eq "*"} {
#set parent [lindex $folders $folderidx] #Note - glob operations seem to be faster than looped tests like 'file isdirectory' & 'file readlink'
set hdirs [glob -nocomplain -dir $folderpath -types {hidden d} * .*] #set parent [lindex $folders $folderidx]
#set hdirs {} set hdirs [glob -nocomplain -dir $folderpath -types {hidden d} * .*]
set dirs [glob -nocomplain -dir $folderpath -types d * .*] set dirs [glob -nocomplain -dir $folderpath -types d * .*]
set hlinks [glob -nocomplain -dir $folderpath -types {hidden l} * .*] set hlinks [glob -nocomplain -dir $folderpath -types {hidden l} * .*]
#set hlinks {} set links [glob -nocomplain -dir $folderpath -types l * .*] ;#links may have dupes - we don't care. punk::lib::struct_set_diff_unique
set links [glob -nocomplain -dir $folderpath -types l * .*] ;#links may have dupes - we don't care. struct::set difference will remove (?)
#set links [lsort -unique [concat $hlinks $links[unset links]]]
set hfiles [glob -nocomplain -dir $folderpath -types {hidden f} * .*]
#set hfiles {}
set files [glob -nocomplain -dir $folderpath -types f * .*]
#set files {}
} else {
set hdirs [glob -nocomplain -dir $folderpath -types {hidden d} $opt_glob]
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob]
set hlinks [glob -nocomplain -dir $folderpath -types {hidden l} $opt_glob] set hfiles [glob -nocomplain -dir $folderpath -types {hidden f} * .*]
set links [glob -nocomplain -dir $folderpath -types l $opt_glob] ;#links may have dupes - we don't care. struct::set difference will remove (?) set files [glob -nocomplain -dir $folderpath -types f * .*]
} else {
set hdirs [glob -nocomplain -dir $folderpath -types {hidden d} $opt_glob]
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob]
set hlinks [glob -nocomplain -dir $folderpath -types {hidden l} $opt_glob]
set links [glob -nocomplain -dir $folderpath -types l $opt_glob] ;#links may have dupes - we don't care. punk::lib::struct_set_diff_unique
set hfiles [glob -nocomplain -dir $folderpath -types {hidden f} $opt_glob]
set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
}
} else {
set hdirs {}
set hfiles {}
set hlinks {}
if {$opt_glob eq "*"} {
#Note - glob operations seem to be faster than looped tests like 'file isdirectory' & 'file readlink'
#set parent [lindex $folders $folderidx]
set dirs [glob -nocomplain -dir $folderpath -types d * .*]
set links [glob -nocomplain -dir $folderpath -types l * .*] ;#links may have dupes - we don't care. punk::lib::struct_set_diff_unique
set files [glob -nocomplain -dir $folderpath -types f * .*]
} else {
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob]
set links [glob -nocomplain -dir $folderpath -types l $opt_glob] ;#links may have dupes - we don't care. punk::lib::struct_set_diff_unique
set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
}
set hfiles [glob -nocomplain -dir $folderpath -types {hidden f} $opt_glob]
set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
} }
#note struct::set difference produces unordered result #note struct::set difference produces unordered result
#struct::set difference removes duplicates (but not always.. e.g if using tcl impl and 2nd element empty!) #struct::set difference removes duplicates (but not always.. e.g if using tcl impl and 2nd element empty!)
#relying on struct::set to remove dupes is somewhat risky. It is not well documented - and behaviour of dupes in inputs is underspecified as it appears to be intended for mathematical 'sets' #relying on struct::set to remove dupes is somewhat risky.
#It is not well documented - and behaviour of dupes in inputs is underspecified as it appears to be intended for mathematical 'sets' ie lists without dupes
#for this reason we must use the wrapper punk::lib::struct_set_diff_unique, which will use the well behaved critcl for speed if avail, but fall back to a deduping tcl version
#remove links and . .. from directories, remove links from files #remove links and . .. from directories, remove links from files
#ideally we would like to classify links by whether they point to files vs dirs - but there are enough cross-platform differences that we will have to leave it to the caller to sort out for now. #ideally we would like to classify links by whether they point to files vs dirs - but there are enough cross-platform differences that we will have to leave it to the caller to sort out for now.
#struct::set will affect order: tcl vs critcl give different ordering! #struct::set will affect order: tcl vs critcl give different ordering!
set files [struct::set difference [concat $hfiles $files[unset files]] $links] set files [punk::lib::struct_set_diff_unique [list {*}$hfiles {*}$files[unset files]] $links]
set dirs [struct::set difference [concat $hdirs $dirs[unset dirs]] [concat $links [list [file join $folderpath .] [file join $folderpath ..] ]]] set dirs [punk::lib::struct_set_diff_unique [list {*}$hdirs {*}$dirs[unset dirs] ] [list {*}$links [file join $folderpath .] [file join $folderpath ..]]]
#set links [lsort -unique [concat $links $hlinks]]
#---- #----
set mdata_lists [du_get_metadata_lists $sized_types $timed_types $files $dirs $links] set mdata_lists [du_get_metadata_lists $sized_types $timed_types $files $dirs $links]
set flaggedhidden [list {*}$hdirs {*}$hfiles {*}$hlinks]
if {"windows" eq $::tcl_platform(platform)} { #unix dotted files/folders are not 'flagged' as such - it's a convention - so the client can use the same convention to decide if something is hidden
set flaggedhidden [concat $hdirs $hfiles $hlinks] #this allows us to return less data - but more importantly - reserve flaggedhidden for systems where such a flag exists and avoid conflating the different concepts of what is hidden
} else {
#unix dotted files/folders are not 'flagged' as such - it's a convention - so the client can use the same convention to decide if something is hidden
#this allows us to return less data - but more importantly - reserve flaggedhidden for systems where such a flag exists and avoid conflating the different concepts of what is hidden
set flaggedhidden {}
}
set vfsmounts [get_vfsmounts_in_folder $folderpath] set vfsmounts [get_vfsmounts_in_folder $folderpath]
@ -1223,21 +1232,21 @@ namespace eval punk::du {
#if {[punk::mix::base::lib::path_a_above_b $folderpath "//zipfs:/"]} {} #if {[punk::mix::base::lib::path_a_above_b $folderpath "//zipfs:/"]} {}
#zipfs files also reported as links by glob - review - should we preserve this in response? #todo - hidden? not returned in attributes on windows at least.
#zipfs files also reported as links by glob - review - should we preserve this in response? (2024 unable to duplicate)
if {$opt_glob eq "*"} { if {$opt_glob eq "*"} {
set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs
#set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove
set links [list]
set files [glob -nocomplain -dir $folderpath -types f * .*] ;# also returns links to files set files [glob -nocomplain -dir $folderpath -types f * .*] ;# also returns links to files
} else { } else {
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob] set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob]
#set links [glob -nocomplain -dir $folderpath -types l $opt_glob] set links [glob -nocomplain -dir $folderpath -types l $opt_glob]
set links [list]
set files [glob -nocomplain -dir $folderpath -types f $opt_glob] set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
} }
#remove any links from our dirs and files collections #remove any links from our dirs and files collections
set dirs [struct::set difference $dirs[unset dirs] [concat $links [list [file join $folderpath .] [file join $folderpath ..] ]]] #see du_dirlisting_generic re struct::set difference issues
set files [struct::set difference $files[unset files] $links] set dirs [punk::lib::struct_set_diff_unique $dirs[unset dirs] [list {*}$links [file join $folderpath .] [file join $folderpath ..]]]
set files [punk::lib::struct_set_diff_unique $files[unset files] $links]
#nested vfs mount.. REVIEW - does anything need special handling? #nested vfs mount.. REVIEW - does anything need special handling?
@ -1300,34 +1309,63 @@ namespace eval punk::du {
} }
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- # -- --- --- --- --- --- --- --- --- --- --- --- --- ---
#at least some vfs on windows seem to support the -hidden attribute
#we are presuming glob will accept the -types hidden option for all vfs - even if it doesn't really apply REVIEW
#The extra globs aren't nice - but hopefully the vfs is reasonably performant (?)
set errors [dict create] set errors [dict create]
if {$opt_glob eq "*"} { if {"windows" eq $::tcl_platform(platform)} {
set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs if {$opt_glob eq "*"} {
#review - how are links handled in vfs? presumably if the vfs is a full implementation they should work at least within the vfs? set hdirs [glob -nocomplain -dir $folderpath -types {hidden d} * .*]
set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs
set files [glob -nocomplain -dir $folderpath -types f * .*] ;# also returns links to files #review - how are links handled in vfs? presumably if the vfs is a full implementation they should work at least within the vfs?
set hlinks [glob -nocomplain -dir $folderpath -types {hidden l} * .*]
set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove
set hfiles [glob -nocomplain -dir $folderpath -types {hidden l} * .*]
set files [glob -nocomplain -dir $folderpath -types f * .*] ;# also returns links to files
} else {
set hdirs [glob -nocomplain -dir $folderpath -types {hidden d} $opt_glob]
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob]
set hlinks [glob -nocomplain -dir $folderpath -types {hidden l} $opt_glob]
set links [glob -nocomplain -dir $folderpath -types l $opt_glob]
set hfiles [glob -nocomplain -dir $folderpath -types {hidden f} $opt_glob]
set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
}
} else { } else {
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob] #we leave it to the ui on unix to classify dotfiles as hidden
set links [glob -nocomplain -dir $folderpath -types l $opt_glob] set hdirs {}
set files [glob -nocomplain -dir $folderpath -types f $opt_glob] set hfiles {}
set hlinks {}
if {$opt_glob eq "*"} {
set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs
#review - how are links handled in vfs? presumably if the vfs is a full implementation they should work at least within the vfs?
set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove
set files [glob -nocomplain -dir $folderpath -types f * .*] ;# also returns links to files
} else {
set dirs [glob -nocomplain -dir $folderpath -types d $opt_glob]
set links [glob -nocomplain -dir $folderpath -types l $opt_glob]
set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
}
} }
#remove any links from our dirs and files collections #remove any links from our dirs and files collections
set dirs [struct::set difference $dirs[unset dirs] [concat $links [list [file join $folderpath .] [file join $folderpath ..] ]]] #see du_dirlisting_generic re struct::set difference issues
set files [struct::set difference $files[unset files] $links] set dirs [punk::lib::struct_set_diff_unique $dirs[unset dirs] [list {*}$links [file join $folderpath .] [file join $folderpath ..] ]]
set files [punk::lib::struct_set_diff_unique $files[unset files] $links]
#nested vfs mount.. REVIEW - does anything need special handling? #nested vfs mount.. REVIEW - does anything need special handling?
set vfsmounts [get_vfsmounts_in_folder $folderpath] set vfsmounts [get_vfsmounts_in_folder $folderpath]
set mdata_lists [du_get_metadata_lists $sized_types $timed_types $files $dirs $links] set mdata_lists [du_get_metadata_lists $sized_types $timed_types $files $dirs $links]
set flaggedhidden [list {*}$hdirs {*}$hfiles {*}$hlinks]
set effective_opts $opts set effective_opts $opts
dict set effective_opts -with_times $timed_types dict set effective_opts -with_times $timed_types
dict set effective_opts -with_sizes $sized_types dict set effective_opts -with_sizes $sized_types
return [list dirs $dirs vfsmounts $vfsmounts links $links files $files filesizes [dict get $mdata_lists fsizes] sizes [dict get $mdata_lists allsizes] times [dict get $mdata_lists alltimes] flaggedhidden {} flaggedsystem {} flaggedreadonly {} altname {} opts $effective_opts errors $errors] return [list dirs $dirs vfsmounts $vfsmounts links $links files $files filesizes [dict get $mdata_lists fsizes] sizes [dict get $mdata_lists allsizes] times [dict get $mdata_lists alltimes] flaggedhidden $flaggedhidden flaggedsystem {} flaggedreadonly {} altname {} opts $effective_opts errors $errors]
} }
#we can halve the number of round trips on unix-like systems, where 'hidden' always corresponds to dotted files #we can halve the number of round trips on unix-like systems, where 'hidden' always corresponds to dotted files
#but we don't classify as such anyway. (leave for UI)
proc du_dirlisting_unix {folderpath args} { proc du_dirlisting_unix {folderpath args} {
set defaults [dict create\ set defaults [dict create\
-glob *\ -glob *\
@ -1379,6 +1417,9 @@ namespace eval punk::du {
} }
#this is not consistent with standard way * works for unix folders - but it is consistent with behaviour of this facility on windows #this is not consistent with standard way * works for unix folders - but it is consistent with behaviour of this facility on windows
#we don't classify anything as 'flaggedhidden' on unix.
#it is a convention for dotfiles rather than a flag - and we'll leave the distinction for the display library
#This
if {$opt_glob eq "*"} { if {$opt_glob eq "*"} {
set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs set dirs [glob -nocomplain -dir $folderpath -types d * .*] ;# also returns links to dirs
set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove set links [glob -nocomplain -dir $folderpath -types l * .*] ;# links may have dupes - we don't care. struct::set difference will remove
@ -1389,8 +1430,9 @@ namespace eval punk::du {
set files [glob -nocomplain -dir $folderpath -types f $opt_glob] set files [glob -nocomplain -dir $folderpath -types f $opt_glob]
} }
#remove any links from our dirs and files collections #remove any links from our dirs and files collections
set dirs [struct::set difference $dirs[unset dirs] [concat $links [list [file join $folderpath .] [file join $folderpath ..] ]]] #see du_dirlisting_generic re struct::set difference issues
set files [struct::set difference $files[unset files] $links] set dirs [punk::lib::struct_set_diff_unique $dirs[unset dirs] [list {*}$links [file join $folderpath .] [file join $folderpath ..] ]]
set files [punk::lib::struct_set_diff_unique $files[unset files] $links]
set vfsmounts [get_vfsmounts_in_folder $folderpath] set vfsmounts [get_vfsmounts_in_folder $folderpath]
set mdata_lists [du_get_metadata_lists $sized_types $timed_types $files $dirs $links] set mdata_lists [du_get_metadata_lists $sized_types $timed_types $files $dirs $links]
@ -1406,7 +1448,7 @@ namespace eval punk::du {
#return fsizes,allsizes,alltimes metadata in same order as files,dirs,links lists - if specified in sized_types #return fsizes,allsizes,alltimes metadata in same order as files,dirs,links lists - if specified in sized_types
proc du_get_metadata_lists {sized_types timed_types files dirs links} { proc du_get_metadata_lists {sized_types timed_types files dirs links} {
set meta_dict [dict create] set meta_dict [dict create]
set meta_types [concat $sized_types $timed_types] set meta_types [list {*}$sized_types {*}$timed_types]
#known tcl stat keys 2023 - review #known tcl stat keys 2023 - review
set empty_stat_dict [dict create atime {} ctime {} dev {} gid {} ino {} mode {} mtime {} nlink {} size {} type {} uid {}] set empty_stat_dict [dict create atime {} ctime {} dev {} gid {} ino {} mode {} mtime {} nlink {} size {} type {} uid {}]
#make sure we call file stat only once per item #make sure we call file stat only once per item
@ -1419,6 +1461,7 @@ namespace eval punk::du {
if {![catch {file stat $path arrstat} errM]} { if {![catch {file stat $path arrstat} errM]} {
dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]]
} else { } else {
puts stderr "du_get_metadata_lists: file stat $path error: $errM"
dict lappend errors $path "file stat error: $errM" dict lappend errors $path "file stat error: $errM"
dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict]
} }
@ -1437,6 +1480,9 @@ namespace eval punk::du {
if {$ft eq "f"} { if {$ft eq "f"} {
#subst with na if empty? #subst with na if empty?
lappend fsizes [dict get $pathinfo size] lappend fsizes [dict get $pathinfo size]
if {[dict get $pathinfo size] eq ""} {
puts stderr "du_get_metadata_lists: fsize $path is empty!"
}
} }
} }
if {$ft in $timed_types} { if {$ft in $timed_types} {
@ -1446,7 +1492,7 @@ namespace eval punk::du {
#todo - fix . The list lengths will presumably match but have empty values if failed to stat #todo - fix . The list lengths will presumably match but have empty values if failed to stat
if {"f" in $sized_types} { if {"f" in $sized_types} {
if {[llength $fsizes] ne [llength $files]} { if {[llength $fsizes] ne [llength $files]} {
dict lappend errors $folderpath "failed to retrieve all file sizes" dict lappend errors general "failed to retrieve all file sizes"
} }
} }
return [dict create fsizes $fsizes allsizes $allsizes alltimes $alltimes] return [dict create fsizes $fsizes allsizes $allsizes alltimes $alltimes]

171
src/vfs/_vfscommon/modules/punk/lib-0.1.1.tm

@ -339,6 +339,144 @@ namespace eval punk::lib {
set has_twapi [expr {![catch {package require twapi}]}] set has_twapi [expr {![catch {package require twapi}]}]
} }
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
# Maintenance - This is the primary source for tm_version... functions
# - certain packages script require these but without package dependency
# - 1 punk boot script
# - 2 packagetrace module
# - These should be updated to sync with this
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
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
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
# -- --- # -- ---
#https://stackoverflow.com/questions/17631269/whats-the-best-way-to-join-two-lists #https://stackoverflow.com/questions/17631269/whats-the-best-way-to-join-two-lists
#DKF's 2013 recommendation of using list {*}$first {*}$second seems not to apply in 2024 #DKF's 2013 recommendation of using list {*}$first {*}$second seems not to apply in 2024
@ -1575,8 +1713,20 @@ namespace eval punk::lib {
lremove $fromlist {*}$doomed lremove $fromlist {*}$doomed
} }
#fix for tcl impl of struct::set::diff which doesn't dedupe
proc struct_set_diff_unique {A B} {
package require struct::set ;#require even if tcl impl - so the dependency isn't missed accidentally due to Loaded state of programmers machine.
if {[struct::set::Loaded] eq "tcl"} {
return [punk::lib::setdiff $A $B]
} else {
#use (presumably critcl) implementation for speed
return [struct::set difference $A $B]
}
}
#non-dupe preserving - for consistency in dedupe behaviour we don't shortcircuit empty B #non-dupe preserving - for consistency in dedupe behaviour we don't shortcircuit empty B
#consistent dedupe and order-maintenance of remaining items in A differentiate this from struct::set difference #consistent dedupe and order-maintenance of remaining items in A differentiate this from struct::set difference (dedupes with critcl, doesn't with tcl implementation 2024)
#also struct::set difference with critcl is faster #also struct::set difference with critcl is faster
proc setdiff {A B} { proc setdiff {A B} {
if {[llength $A] == 0} {return {}} if {[llength $A] == 0} {return {}}
@ -2387,7 +2537,7 @@ namespace eval punk::lib {
set stdin_state [fconfigure stdin] set stdin_state [fconfigure stdin]
if {[catch { if {[catch {
package require punk::console package require punk::console
set console_raw [set ::punk::console::is_raw] set console_raw [tsv::get console is_raw]
} err_console]} { } err_console]} {
#assume normal line mode #assume normal line mode
set console_raw 0 set console_raw 0
@ -3032,6 +3182,11 @@ namespace eval punk::lib {
proc objclone {obj} { proc objclone {obj} {
append obj2 $obj {} append obj2 $obj {}
} }
proc set_clone {varname obj} {
#used by repl's codeinterp. Maintains internal rep, easier to call e.g interp eval code [list punk::set_clone varnmame $val]
append obj2 $obj {}
uplevel 1 [list set $varname $obj2]
}
@ -3175,7 +3330,7 @@ tcl::namespace::eval punk::lib::system {
#[para] Internal functions that are not part of the API #[para] Internal functions that are not part of the API
#[list_begin definitions] #[list_begin definitions]
proc has_script_var_bug {} { proc has_tclbug_script_var {} {
set script {set j [list spud] ; list} set script {set j [list spud] ; list}
append script \n append script \n
uplevel #0 $script uplevel #0 $script
@ -3194,7 +3349,15 @@ tcl::namespace::eval punk::lib::system {
return false return false
} }
} }
proc has_safeinterp_compile_bug {{show 0}} {
proc has_tclbug_list_quoting_emptyjoin {} {
#https://core.tcl-lang.org/tcl/tktview/e38dce74e2
set v1 [list {*}[lindex #foo] {*}[]] ;#can return "#foo" instead of "{#foo}" under some beta 9 releases
set v2 [list #foo] ;#normal tcl list quoting for 1st element that looks like a comment -> "{#foo}"
return [expr {![string equal $v1 $v2]}] ;#if they're not equal - we have the bug.
}
proc has_tclbug_safeinterp_compile {{show 0}} {
#ensemble calls within safe interp not compiled #ensemble calls within safe interp not compiled
namespace eval [namespace current]::testcompile { namespace eval [namespace current]::testcompile {
proc ensembletest {} {string index a 0} proc ensembletest {} {string index a 0}

25
src/vfs/_vfscommon/modules/punk/mix/base-0.1.tm

@ -473,13 +473,26 @@ namespace eval punk::mix::base {
#set data [fileutil::cat -translation binary $filename] ;#no significant performance diff on windows - and doesn't handle win-illegal names #set data [fileutil::cat -translation binary $filename] ;#no significant performance diff on windows - and doesn't handle win-illegal names
zlib adler32 $data zlib adler32 $data
} }
#zlib crc vie file-slurp #zlib crc via file-slurp
proc cksum_crc_file {filename} { proc cksum_crc_file {filename} {
package require zlib package require zlib
set data [punk::mix::util::fcat -translation binary -encoding iso8859-1 $filename] set data [punk::mix::util::fcat -translation binary -encoding iso8859-1 $filename]
zlib crc $data zlib crc $data
} }
proc cksum_md5_data {data} {
if {[package vsatisfies [package present md5] 2-]} {
return [md5::md5 -hex $data]
} else {
return [md5::md5 $data]
}
}
#fallback md5 via file-slurp - shouldn't be needed if have md5 2-
proc cksum_md5_file {filename} {
set data [punk::mix::util::fcat -translation binary -encoding iso8859-1 $filename]
cksum_md5_data $data
}
#required to be able to accept relative paths #required to be able to accept relative paths
#for full cksum - using tar could reduce number of hashes to be made.. #for full cksum - using tar could reduce number of hashes to be made..
@ -624,7 +637,11 @@ namespace eval punk::mix::base {
} }
md5 { md5 {
package require md5 package require md5
set cksum_command [list md5::md5 -hex -file] if {[package vsatisfies [package present md5] 2- ] } {
set cksum_command [list md5::md5 -hex -file]
} else {
set cksum_comand [list cksum_md5_file]
}
} }
cksum { cksum {
package require cksum ;#tcllib package require cksum ;#tcllib
@ -637,7 +654,7 @@ namespace eval punk::mix::base {
set cksum_command [list cksum_adler32_file] set cksum_command [list cksum_adler32_file]
} }
sha3 - sha3-256 { sha3 - sha3-256 {
#todo - replace with something that doesn't call another process #todo - replace with something that doesn't call another process - only if tcllibc not available!
#set cksum_command [list apply {{file} {lindex [exec fossil sha3sum -256 $file] 0}}] #set cksum_command [list apply {{file} {lindex [exec fossil sha3sum -256 $file] 0}}]
set cksum_command [list $sha3_implementation 256] set cksum_command [list $sha3_implementation 256]
} }
@ -684,7 +701,7 @@ namespace eval punk::mix::base {
set sizeinfo "(file type $ftype - tarred size [punk::lib::format_number [file size $archivename]] bytes)" set sizeinfo "(file type $ftype - tarred size [punk::lib::format_number [file size $archivename]] bytes)"
} }
set tsstart [clock millis] set tsstart [clock millis]
puts -nonewline stdout "cksum_path: calculating cksum for $target $sizeinfo ... " puts -nonewline stdout "cksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... "
set cksum [{*}$cksum_command $archivename] set cksum [{*}$cksum_command $archivename]
set tsend [clock millis] set tsend [clock millis]
set ms [expr {$tsend - $tsstart}] set ms [expr {$tsend - $tsstart}]

7
src/vfs/_vfscommon/modules/punk/mix/commandset/doc-0.1.0.tm

@ -271,7 +271,12 @@ namespace eval punk::mix::commandset::doc {
#this case only came up because docgen used to path munge to long filenames - but left because we know there is a limit and renaming fixes it - even if it's ugly - but still allows doc generation. #this case only came up because docgen used to path munge to long filenames - but left because we know there is a limit and renaming fixes it - even if it's ugly - but still allows doc generation.
#review - if we're checking fname - should also test length of whole path and determine limits for tar #review - if we're checking fname - should also test length of whole path and determine limits for tar
package require md5 package require md5
set target_docname [md5::md5 -hex [encoding convertto utf-8 $fullpath]]_overlongfilename.man if {[package vsatisfies [package present md5] 2- ] } {
set md5opt "-hex"
} else {
set md5opt ""
}
set target_docname [md5::md5 {*}$md5opt [encoding convertto utf-8 $fullpath]]_overlongfilename.man
puts stderr "WARNING - overlong file name - renaming $fullpath" puts stderr "WARNING - overlong file name - renaming $fullpath"
puts stderr " to [file dirname $fullpath]/$target_docname" puts stderr " to [file dirname $fullpath]/$target_docname"
} }

2
src/vfs/_vfscommon/modules/punk/mix/util-0.1.0.tm

@ -261,6 +261,8 @@ namespace eval punk::mix::util {
return return
} }
# review punk::lib::tm_version.. functions
proc is_valid_tm_version {versionpart} { proc is_valid_tm_version {versionpart} {
#Needs to be suitable for use with Tcl's 'package vcompare' #Needs to be suitable for use with Tcl's 'package vcompare'
if {![catch [list package vcompare $versionpart $versionpart]]} { if {![catch [list package vcompare $versionpart $versionpart]]} {

52
src/vfs/_vfscommon/modules/punk/nav/fs-0.1.0.tm

@ -821,9 +821,12 @@ tcl::namespace::eval punk::nav::fs {
set match_contents $opt_tailglob set match_contents $opt_tailglob
} }
} }
puts stdout "searchbase: $searchbase searchspec:$searchspec" #puts stdout "searchbase: $searchbase searchspec:$searchspec"
set in_vfs 0
#file attr //cookit:/ returns {-vfs 1 -handle {}}
#we will treat it differently for now - use generic handler REVIEW
set in_vfs 0 ;#we use this only for a vfs which is reported to have a mountpoint by vfs::filesystem info - not all that have -vfs 1 attr like cookit.
if {[llength [package provide vfs]]} { if {[llength [package provide vfs]]} {
foreach mount [vfs::filesystem info] { foreach mount [vfs::filesystem info] {
if {[punk::mix::base::lib::path_a_atorbelow_b $location $mount]} { if {[punk::mix::base::lib::path_a_atorbelow_b $location $mount]} {
@ -849,22 +852,45 @@ tcl::namespace::eval punk::nav::fs {
set listing [punk::du::lib::du_dirlisting_tclvfs $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times] set listing [punk::du::lib::du_dirlisting_tclvfs $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times]
} else { } else {
set in_zipfs 0 set in_zipfs 0
if {[info commands ::tcl::zipfs::mount] ne ""} { set in_cookit 1
if {[string match //zipfs:/* $location]} { set in_other_pseudovol 1
set in_zipfs 1 switch -glob -- $location {
//zipfs:/* {
if {[info commands ::tcl::zipfs::mount] ne ""} {
set in_zipfs 1
}
}
//cookit:/* {
set in_cookit 1
}
default {
#handle 'other/unknown' that mounts at a volume-like path //pseudovol:/
if {[regexp {//((?:(?!:|/).)+):/.*} $location _match pseudovol]} {
#pseudovol probably more than one char long
#we don't really expect something like //c:/ , but anyway, it's not the same as c:/ and for all we know someone could use that as a volume name?
set in_other_pseudovol 1 ;#flag so we don't use twapi - hope generic can handle it (uses tcl glob)
} else {
#we could use 'file attr' here to test if {-vfs 1}
#but it's an extra filesystem hit on all normal paths too (which can be expensive on some systems)
#instead for now we'll assume any reasonable vfs should have been found by vfs::filesystem::info or mounted as a pseudovolume
}
} }
#dict for {zmount zpath} [zipfs mount] {
# if {[punk::mix::base::lib::path_a_atorbelow_b $location $zmount]} {
# set in_zipfs 1
# break
# }
#}
} }
if {$in_zipfs} { if {$in_zipfs} {
#relative vs absolute? review - cwd valid for //zipfs:/ ?? #relative vs absolute? review - cwd valid for //zipfs:/ ??
set listing [punk::du::lib::du_dirlisting_zipfs $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times] set listing [punk::du::lib::du_dirlisting_zipfs $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times]
} elseif {$in_cookit} {
#seems to be a vfs - except it mounts on a pseudo-volume path //cookit:/
#don't use twapi
#could possibly use du_dirlisting_tclvfs REVIEW
#files and folders are all returned with the -types hidden option for glob on windows
set listing [punk::du::lib::du_dirlisting_generic $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times]
} elseif {$in_other} {
set listing [punk::du::lib::du_dirlisting_generic $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times]
} else { } else {
set listing [punk::du::dirlisting $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times] set listing [punk::du::dirlisting $location -glob $match_contents {*}$next_opt_with_sizes {*}$next_opt_with_times]
} }
} }

26
src/vfs/_vfscommon/modules/punk/packagepreference-0.1.0.tm

@ -155,18 +155,26 @@ tcl::namespace::eval punk::packagepreference {
if {[lindex $args 1] eq "-exact"} { if {[lindex $args 1] eq "-exact"} {
set pkg [lindex $args 2] set pkg [lindex $args 2]
set vwant [lindex $args 3] set vwant [lindex $args 3]
if {[set ver [package provide $pkg]] ne ""} { if {[set ver [$COMMANDSTACKNEXT_ORIGINAL provide $pkg]] ne ""} {
if {$ver eq $vwant} { #although we could shortcircuit using vsatisfies to return the ver
return $vwant #we should instead pass through to COMMANDSTACKNEXT so as not to interfere with whatever it does.
} else { return [$COMMANDSTACKNEXT {*}$args]
#package already provided with a different version.. we will defer to underlying implementation to return the standard error
return [$COMMANDSTACKNEXT {*}$args] #if {$vwant eq "" || [$COMMANDSTACKNEXT vsatisfies $ver $vwant]} {
} # return $ver
#} else {
# #package already provided with a different version.. we will defer to underlying implementation to return the standard error
# return [$COMMANDSTACKNEXT {*}$args]
#}
} }
} else { } else {
set pkg [lindex $args 1] set pkg [lindex $args 1]
if {[set ver [package provide $pkg]] ne ""} { set vwant [lindex $args 2]
return $ver if {[set ver [$COMMANDSTACKNEXT_ORIGINAL provide $pkg]] ne ""} {
return [$COMMANDSTACKNEXT {*}$args]
#if {$vwant eq "" || [$COMMANDSTACKNEXT vsatisfies $ver $vwant]} {
# return $ver
#}
} }
} }
if {[regexp {[A-Z]} $pkg]} { if {[regexp {[A-Z]} $pkg]} {

30
src/vfs/_vfscommon/modules/punk/repl-0.1.tm

@ -73,6 +73,7 @@ namespace eval repl {
#variable last_unknown "" #variable last_unknown ""
tsv::set repl last_unknown "" tsv::set repl last_unknown ""
tsv::set console is_raw 0
variable output "" variable output ""
#important not to initialize - as it can be preset by cooperating package before app-punk has been package required #important not to initialize - as it can be preset by cooperating package before app-punk has been package required
#(this is an example of a deaddrop) #(this is an example of a deaddrop)
@ -149,7 +150,7 @@ proc ::punk::repl::init_signal_handlers {} {
flush stderr flush stderr
incr signal_control_c incr signal_control_c
#rputs stderr "* console_control: $args" #rputs stderr "* console_control: $args"
if {$::punk::console::is_raw} { if {[tsv::get console is_raw]} {
if {[lindex $::errorCode 0] eq "CHILDKILLED"} { if {[lindex $::errorCode 0] eq "CHILDKILLED"} {
#rputs stderr "\n|repl> ctrl-c errorCode: $::errorCode" #rputs stderr "\n|repl> ctrl-c errorCode: $::errorCode"
#avoid spurious triggers after interrupting a command.. #avoid spurious triggers after interrupting a command..
@ -615,7 +616,8 @@ proc repl::doprompt {prompt {col {green bold}}} {
flush stdout; #we are writing this prompt on stderr, but stdout could still be writing to screen flush stdout; #we are writing this prompt on stderr, but stdout could still be writing to screen
#our first char on stderr is based on the 'lastchar' of stdout which we have recorded but may not have arrived on screen. #our first char on stderr is based on the 'lastchar' of stdout which we have recorded but may not have arrived on screen.
#The issue we're trying to avoid is the (stderr)prompt arriving midway through a large stdout chunk #The issue we're trying to avoid is the (stderr)prompt arriving midway through a large stdout chunk
#REVIEW - this basic attempt to get stderr/stdout to cooperate is experimental and unlikely to achieve the desired effect #REVIEW - this basic attempt to get stderr/stdout to cooperate is experimental and unlikely to achieve the desired effect in all situations
#It the above flush does seem to help though.
#note that our 'flush stdout' tcl call does not wait if stdout is non-blocking #note that our 'flush stdout' tcl call does not wait if stdout is non-blocking
#todo - investigate if the overhead is reasonable for a special channel that accepts stdout and stderr records with a reader to send to console in chunk-sizes we know will be emitted correctly #todo - investigate if the overhead is reasonable for a special channel that accepts stdout and stderr records with a reader to send to console in chunk-sizes we know will be emitted correctly
# - reader of such channel could be ok to be blocking (on read? on write to real channels?)... except everything still needs to be interruptable by things like signals? # - reader of such channel could be ok to be blocking (on read? on write to real channels?)... except everything still needs to be interruptable by things like signals?
@ -1296,9 +1298,11 @@ proc repl::repl_handler {inputchan prompt_config} {
if {[dict get $original_input_conf -inputmode] eq "raw"} { if {[dict get $original_input_conf -inputmode] eq "raw"} {
#user or script has apparently put stdin into raw mode - update punk::console::is_raw to match #user or script has apparently put stdin into raw mode - update punk::console::is_raw to match
set rawmode 1 set rawmode 1
set ::punk::console::is_raw 1 #set ::punk::console::is_raw 1
tsv::set console is_raw 1
} else { } else {
set ::punk::console::is_raw 0 #set ::punk::console::is_raw 0
tsv::set console is_raw 0
} }
#what about enable/disable virtualTerminal ? #what about enable/disable virtualTerminal ?
#using stdin -inputmode to switch modes won't set virtualterminal input state appropriately #using stdin -inputmode to switch modes won't set virtualterminal input state appropriately
@ -1308,7 +1312,8 @@ proc repl::repl_handler {inputchan prompt_config} {
} else { } else {
#JMN FIX! #JMN FIX!
#this returns 0 in rawmode on 8.6 after repl thread changes #this returns 0 in rawmode on 8.6 after repl thread changes
set rawmode [set ::punk::console::is_raw] #set rawmode [set ::punk::console::is_raw]
set rawmode [tsv::get console is_raw]
} }
if {!$rawmode} { if {!$rawmode} {
@ -1672,7 +1677,8 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
set debugprompt [dict get $prompt_config debugprompt] set debugprompt [dict get $prompt_config debugprompt]
set rawmode [set ::punk::console::is_raw] #set rawmode [set ::punk::console::is_raw]
set rawmode [tsv::get console is_raw]
if {!$rawmode} { if {!$rawmode} {
#puts stderr "-->got [ansistring VIEW -lf 1 $stdinlines]<--" #puts stderr "-->got [ansistring VIEW -lf 1 $stdinlines]<--"
@ -2056,6 +2062,10 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
#/scriptlib/tests/listrep_bug.tcl #/scriptlib/tests/listrep_bug.tcl
#after the uplevel #0 $commandstr call #after the uplevel #0 $commandstr call
# vars within the script that were set to a list, and have no string-rep, will generate a string-rep once the script (commandstr) is unset, or set to another value # vars within the script that were set to a list, and have no string-rep, will generate a string-rep once the script (commandstr) is unset, or set to another value
#review - although the rep change is weird - what actual problem was caused aside from an unexpected shimmer?
#probably just that the repl can't then be used to debug representation issues and possibly that the performance is not ideal for list pipeline commands(?)
#now that we eval in another thread and interp - we seem to lose the list rep anyway.
#(unless we also save the script in that interp too in a run_command_cache)
global run_command_string global run_command_string
set run_command_string "$commandstr\n" ;#add anything that won't affect script. set run_command_string "$commandstr\n" ;#add anything that won't affect script.
global run_command_cache global run_command_cache
@ -2145,7 +2155,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
#----------------------------------------- #-----------------------------------------
#list/string-rep bug workaround part 2 #list/string-rep bug workaround part 2
#todo - set flag based on punk::lib::system::has_script_var_bug #todo - set flag based on punk::lib::system::has_tclbug_script_var
lappend run_command_cache $run_command_string lappend run_command_cache $run_command_string
#puts stderr "run_command_string rep: [rep $run_command_string]" #puts stderr "run_command_string rep: [rep $run_command_string]"
if {[llength $run_command_cache] > 2000} { if {[llength $run_command_cache] > 2000} {
@ -2693,8 +2703,10 @@ namespace eval repl {
#todo - add/remove shellfilter stacked ansiwrap #todo - add/remove shellfilter stacked ansiwrap
} }
proc mode args { proc mode args {
#with tsv::set console is_raw we don't need to call mode in both the replthread and the codethread
# REVIEW - call in local interp? how about if codethread is safe interp?
#interp eval code [list ::punk::console::mode {*}$args]
thread::send %replthread% [list punk::console::mode {*}$args] thread::send %replthread% [list punk::console::mode {*}$args]
interp eval code [list ::punk::console::mode {*}$args]
} }
proc cmdtype cmd { proc cmdtype cmd {
code invokehidden tcl:info:cmdtype $cmd code invokehidden tcl:info:cmdtype $cmd
@ -2825,6 +2837,7 @@ namespace eval repl {
code alias ::md5::md5 ::repl::interphelpers::md5 code alias ::md5::md5 ::repl::interphelpers::md5
code alias exit ::repl::interphelpers::quit code alias exit ::repl::interphelpers::quit
} elseif {$safe == 2} { } elseif {$safe == 2} {
#safebase
safe::interpCreate code -nested 1 safe::interpCreate code -nested 1
#safe::setLogCmd ::repl::interpextras::safe_msg ;#using setLogcmd early will show the auto_path notice - which is *verbose* #safe::setLogCmd ::repl::interpextras::safe_msg ;#using setLogcmd early will show the auto_path notice - which is *verbose*
#while it may conceivably be useful in debugging safe itself - auto_path and tcl::tm::list can be inspected to show these values in the safe interp itself anyway - so early logging is of limited utility here. #while it may conceivably be useful in debugging safe itself - auto_path and tcl::tm::list can be inspected to show these values in the safe interp itself anyway - so early logging is of limited utility here.
@ -2900,6 +2913,7 @@ namespace eval repl {
namespace eval ::codeinterp { namespace eval ::codeinterp {
variable errstack {} variable errstack {}
variable outstack {} variable outstack {}
variable run_command_cache
} }
# -- --- # -- ---

24
src/vfs/_vfscommon/modules/punk/repl/codethread-0.1.0.tm

@ -20,12 +20,12 @@
#*** !doctools #*** !doctools
#[manpage_begin shellspy_module_punk::repl::codethread 0 0.1.0] #[manpage_begin shellspy_module_punk::repl::codethread 0 0.1.0]
#[copyright "2024"] #[copyright "2024"]
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}] #[titledesc {Module repl codethread}] [comment {-- Name section and table of contents description --}]
#[moddesc {-}] [comment {-- Description at end of page heading --}] #[moddesc {codethread for repl - root interpreter}] [comment {-- Description at end of page heading --}]
#[require punk::repl::codethread] #[require punk::repl::codethread]
#[keywords module] #[keywords module repl]
#[description] #[description]
#[para] - #[para] This is part of the infrastructure required for the punk::repl to operate
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
@ -131,11 +131,14 @@ tcl::namespace::eval punk::repl::codethread {
# return "ok" # return "ok"
#} #}
variable run_command_cache
proc is_running {} { proc is_running {} {
variable running variable running
return $running return $running
} }
proc runscript {script} { proc runscript {script} {
#puts stderr "->runscript" #puts stderr "->runscript"
variable replthread_cond variable replthread_cond
variable output_stdout "" variable output_stdout ""
@ -169,9 +172,18 @@ tcl::namespace::eval punk::repl::codethread {
#set errhandle [shellfilter::stack::item_tophandle stderr] #set errhandle [shellfilter::stack::item_tophandle stderr]
#interp transfer "" $errhandle code #interp transfer "" $errhandle code
set scope [interp eval code [list set ::punk::ns::ns_current]]
set status [catch { set status [catch {
interp eval code [list tcl::namespace::inscope $scope $script] #shennanigans to keep compiled script around after call.
#otherwise when $script goes out of scope - internal rep of vars set in script changes.
#The shimmering may be no big deal(?) - but debug/analysis using tcl::unsupported::representation becomes impossible.
interp eval code [list ::punk::lib::set_clone ::codeinterp::clonescript $script] ;#like objclone
interp eval code {
lappend ::codeinterp::run_command_cache $::codeinterp::clonescript
if {[llength $::codeinterp::run_command_cache] > 2000} {
set ::codeinterp::run_command_cache [lrange $::codeinterp::run_command_cache 1750 end][unset ::codeinterp::run_command_cache]
}
tcl::namespace::inscope $::punk::ns::ns_current $::codeinterp::clonescript
}
} result] } result]

5
src/vfs/_vfscommon/modules/punk/repo-0.1.1.tm

@ -27,6 +27,11 @@
# #
# path/repo functions # path/repo functions
# #
#REVIEW punk::repo required early by punk boot script to find projectdir
#todo - split off basic find_project chain of functions to a smaller package and import as necessary here
#Then we can reduce early dependencies in punk boot
if {$::tcl_platform(platform) eq "windows"} { if {$::tcl_platform(platform) eq "windows"} {
package require punk::winpath package require punk::winpath
} else { } else {

10
src/vfs/_vfscommon/modules/textblock-0.1.1.tm

@ -5280,8 +5280,8 @@ tcl::namespace::eval textblock {
It excludes the extra top and side join elements htlj,hlbj,vllj,vlrj" It excludes the extra top and side join elements htlj,hlbj,vllj,vlrj"
*values -min 1 -max 1 *values -min 1 -max 1
frametype -help "name from the predefined frametypes:<ftlist> frametype -help "name from the predefined frametypes:<ftlist>
or an adhoc or an adhoc "
}] }]
append spec \n "frametype -help \"A predefined \"" append spec \n "frametype -help \"A predefined \""
punk::args::get_dict $spec $args punk::args::get_dict $spec $args
return return
@ -6804,7 +6804,11 @@ tcl::namespace::eval textblock {
if {$use_md5} { if {$use_md5} {
#package require md5 ;#already required at package load #package require md5 ;#already required at package load
set hash [md5::md5 -hex [encoding convertto utf-8 $hashables]] ;#need fast and unique to content - not cryptographic - review if {[package vsatisfies [package present md5] 2- ] } {
set hash [md5::md5 -hex [encoding convertto utf-8 $hashables]] ;#need fast and unique to content - not cryptographic - review
} else {
set hash [md5::md5 [encoding convertto utf-8 $hashables]]
}
} else { } else {
set hash $hashables set hash $hashables
} }

0
src/vfs/critcl.vfs/README.md → src/vfs/critcl-3.3.1.vfs/README.md

801
src/vfs/critcl-3.3.1.vfs/build.tcl

@ -0,0 +1,801 @@
#!/bin/sh
# -*- tcl -*- \
exec tclsh "$0" ${1+"$@"}
package require Tcl 8.6 9
unset -nocomplain ::errorInfo
set me [file normalize [info script]]
proc main {} {
global argv
if {![llength $argv]} { set argv help}
if {[catch {
eval _$argv
}]} usage
exit 0
}
set packages {
{app-critcl {.. critcl critcl.tcl} critcl-app}
{critcl critcl.tcl}
{critcl-bitmap bitmap.tcl}
{critcl-class class.tcl}
{critcl-cutil cutil.tcl}
{critcl-emap emap.tcl}
{critcl-enum enum.tcl}
{critcl-iassoc iassoc.tcl}
{critcl-literals literals.tcl}
{critcl-platform platform.tcl}
{critcl-util util.tcl}
{stubs_container container.tcl}
{stubs_gen_decl gen_decl.tcl}
{stubs_gen_header gen_header.tcl}
{stubs_gen_init gen_init.tcl}
{stubs_gen_lib gen_lib.tcl}
{stubs_gen_macro gen_macro.tcl}
{stubs_gen_slot gen_slot.tcl}
{stubs_genframe genframe.tcl}
{stubs_reader reader.tcl}
{stubs_writer writer.tcl}
}
proc usage {{status 1}} {
global errorInfo
if {[info exists errorInfo] && ($errorInfo ne {}) &&
![string match {invalid command name "_*"*} $errorInfo]
} {
puts stderr $::errorInfo
exit
}
global argv0
set prefix "Usage: "
foreach c [lsort -dict [info commands _*]] {
set c [string range $c 1 end]
if {[catch {
H${c}
} res]} {
puts stderr "$prefix[underlined]$argv0 $c[reset] args...\n"
} else {
puts stderr "$prefix[underlined]$argv0 $c[reset] $res\n"
}
set prefix " "
}
exit $status
}
proc underlined {} { return "\033\[4m" }
proc reset {} { return "\033\[0m" }
proc +x {path} {
catch { file attributes $path -permissions ugo+x }
return
}
proc critapp {dst} {
global tcl_platform
set app [file join $dst critcl]
if {$tcl_platform(platform) eq "windows"} {
append app .tcl
}
return $app
}
proc vfile {dir vfile} {
global me
set selfdir [file dirname $me]
eval [linsert $vfile 0 file join $selfdir lib $dir]
}
proc grep {file pattern} {
set lines [split [read [set chan [open $file r]]] \n]
close $chan
return [lsearch -all -inline -glob $lines $pattern]
}
proc version {file} {
set provisions [grep $file {*package provide*}]
#puts /$provisions/
return [lindex $provisions 0 3]
}
proc tmpdir {} {
set tmpraw "critcl.[clock clicks]"
set tmpdir $tmpraw.[pid]
file delete -force $tmpdir
file mkdir $tmpdir
file delete -force $tmpraw
puts "Assembly in: $tmpdir"
return $tmpdir
}
proc relativedir {dest here} {
# Convert dest into a relative path which is relative to `here`.
set save $dest
#puts stderr [list relativedir $dest $label]
set here [file split $here]
set dest [file split $dest]
#puts stderr [list relativedir < $here]
#puts stderr [list relativedir > $dest]
while {[string equal [lindex $dest 0] [lindex $here 0]]} {
set dest [lrange $dest 1 end]
set here [lrange $here 1 end]
if {[llength $dest] == 0} {break}
}
set ul [llength $dest]
set hl [llength $here]
if {$ul == 0} {
set dest [lindex [file split $save] end]
} else {
while {$hl > 1} {
set dest [linsert $dest 0 ..]
incr hl -1
}
set dest [eval file join $dest]
}
#puts stderr [list relativedir --> $dest]
return $dest
}
proc id {cv vv} {
upvar 1 $cv commit $vv version
set commit [exec git log -1 --pretty=format:%H]
set version [exec git describe]
puts "Commit: $commit"
puts "Version: $version"
return
}
proc savedoc {tmpdir} {
puts {Collecting the documentation ...}
file copy -force [file join embedded www] [file join $tmpdir doc]
return
}
proc pkgdirname {name version} {
return $name-$version
}
proc placedoc {tmpdir} {
file delete -force doc
file copy -force [file join $tmpdir doc] doc
return
}
proc 2website {} {
puts {Switching to gh-pages...}
exec 2>@ stderr >@ stdout git checkout gh-pages
return
}
proc reminder {commit} {
puts ""
puts "We are in branch gh-pages now, coming from $commit"
puts ""
return
}
proc shquote value {
return "\"[string map [list \\ \\\\ $ \\$ ` \\`] $value]\""
}
proc dest-dir {} {
global paths
if {![info exists paths(dest-dir)]} {
global env
if {[info exists env(DESTDIR)]} {
set paths(dest-dir) [string trimright $env(DESTDIR) /]
} else {
set paths(dest-dir) ""
}
} elseif {$paths(dest-dir) ne ""} {
set paths(dest-dir) [string trimright $paths(dest-dir) /]
}
return $paths(dest-dir)
}
proc prefix {} {
global paths
if {![info exists paths(prefix)]} {
set paths(prefix) [file dirname [file dirname [norm [info nameofexecutable]]]]
}
return $paths(prefix)
}
proc exec-prefix {} {
global paths
if {![info exists paths(exec-prefix)]} {
set paths(exec-prefix) [prefix]
}
return $paths(exec-prefix)
}
proc bin-dir {} {
global paths
if {![info exists paths(bin-dir)]} {
set paths(bin-dir) [exec-prefix]/bin
}
return $paths(bin-dir)
}
proc lib-dir {} {
global paths
if {![info exists paths(lib-dir)]} {
set paths(lib-dir) [exec-prefix]/lib
}
return $paths(lib-dir)
}
proc include-dir {} {
global paths
if {![info exists paths(include-dir)]} {
set paths(include-dir) [prefix]/include
}
return $paths(include-dir)
}
proc process-install-options {} {
upvar 1 args argv target target
while {[llength $argv]} {
set o [lindex $argv 0]
if {![string match -* $o]} break
switch -exact -- $o {
-target {
# ignore 0
set target [lindex $argv 1]
set argv [lrange $argv 2 end]
}
--dest-dir -
--prefix -
--exec-prefix -
--bin-dir -
--lib-dir -
--include-dir {
# ignore 0
set path [lindex $argv 1]
set argv [lrange $argv 2 end]
set key [string range $o 2 end]
global paths
set paths($key) [norm $path]
}
-- break
default {
puts [Hinstall]
exit 1
}
}
}
return
}
proc norm {path} {
# normalize smybolic links in the path, including the last element.
return [file dirname [file normalize [file join $path ...]]]
}
proc query {q c} {
puts -nonewline "$q ? "
flush stdout
set a [string tolower [gets stdin]]
if {($a ne "y" ) && ($a ne "yes")} {
puts "$c"
exit 1
}
}
proc thisexe {} {
return [info nameofexecutable]
}
proc wfile {path data} {
# Easier to write our own copy than requiring fileutil and then using fileutil::writeFile.
set fd [open $path w]
puts -nonewline $fd $data
close $fd
return
}
proc cat {path} {
# Easier to write our own copy than requiring fileutil and then using fileutil::cat.
set fd [open $path r]
set data [read $fd]
close $fd
return $data
}
proc Hsynopsis {} { return "\n\tGenerate a synopsis of procs and builtin types" }
proc _synopsis {} {
puts Public:
puts [exec grep -n ^proc lib/critcl/critcl.tcl \
| sed -e "s| \{$||" -e {s/:proc ::critcl::/ /} \
| grep -v { [A-Z]} \
| grep -v { at::[A-Z]} \
| sort -k 2 \
| sed -e {s/^/ /}]
puts Private:
puts [exec grep -n ^proc lib/critcl/critcl.tcl \
| sed -e "s| \{$||" -e {s/:proc ::critcl::/ /} \
| grep {[A-Z]} \
| sort -k 2 \
| sed -e {s/^/ /}]
puts "Builtin argument types:"
puts [exec grep -n { argtype} lib/critcl/critcl.tcl \
| grep -v "\\\$ntype" \
| sed -e "s| \{$||" -e {s/:[ ]*argtype/ /} \
| sort -k 2 \
| sed -e {s/^/ /}]
puts "Builtin result types:"
puts [exec grep -n { resulttype} lib/critcl/critcl.tcl \
| sed -e "s| \{$||" -e {s/:[ ]*resulttype/ /} \
| sort -k 2 \
| sed -e {s/^/ /}]
return
}
proc Hhelp {} { return "\n\tPrint this help" }
proc _help {} {
usage 0
return
}
proc Hrecipes {} { return "\n\tList all build commands, without details" }
proc _recipes {} {
set r {}
foreach c [info commands _*] {
lappend r [string range $c 1 end]
}
puts [lsort -dict $r]
return
}
proc Htest {} { return "\n\tRun the testsuite" }
proc _test {} {
global argv
set argv {} ;# clear -- tcltest shall see nothing
# Run all .test files in the test directory.
set selfdir [file dirname $::me]
foreach testsuite [lsort -dict [glob -directory [file join $selfdir test] *.test]] {
puts ""
puts "_ _ __ ___ _____ ________ _____________ _____________________ *** [file tail $testsuite] ***"
if {[catch {
exec >@ stdout 2>@ stderr [thisexe] $testsuite
}]} {
puts $::errorInfo
}
}
puts ""
puts "_ _ __ ___ _____ ________ _____________ _____________________"
puts ""
return
}
proc Hdoc {} { return "\n\t(Re)Generate the embedded documentation" }
proc _doc {} {
cd [file join [file dirname $::me] doc]
puts "Removing old documentation..."
file delete -force [file join .. embedded man]
file delete -force [file join .. embedded www]
file delete -force [file join .. embedded md]
file mkdir [file join .. embedded man]
file mkdir [file join .. embedded www]
file mkdir [file join .. embedded md]
puts "Generating man pages..."
exec 2>@ stderr >@ stdout dtplite -ext n -o [file join .. embedded man] nroff .
puts "Generating html..."
exec 2>@ stderr >@ stdout dtplite -o [file join .. embedded www] html .
puts "Generating markdown..."
exec 2>@ stderr >@ stdout dtplite -ext md -o [file join .. embedded md] markdown .
cd [file join .. embedded man]
file delete -force .idxdoc .tocdoc
cd [file join .. www]
file delete -force .idxdoc .tocdoc
cd [file join .. md]
file delete -force .idxdoc .tocdoc
return
}
proc Htextdoc {} { return "destination\n\tWrite plain text documentation to the specified directory" }
proc _textdoc {dst} {
set destination [file normalize $dst]
cd [file join [file dirname $::me] doc]
puts "Removing old text documentation at ${dst}..."
file delete -force $destination
file mkdir $destination
puts "Generating pages..."
exec 2>@ stderr >@ stdout dtplite -ext txt -o $destination text .
cd $destination
file delete -force .idxdoc .tocdoc
return
}
proc Hfigures {} { return "\n\t(Re)Generate the figures and diagrams for the documentation" }
proc _figures {} {
cd [file join [file dirname $::me] doc figures]
puts "Generating (tklib) diagrams..."
eval [linsert [glob *.dia] 0 exec 2>@ stderr >@ stdout dia convert -t -o . png]
return
}
proc Hrelease {} { return "\n\tGenerate a release from the current commit.\n\tAssumed to be properly tagged.\n\tLeaves checkout in the gh-pages branch, ready for commit+push" }
proc _release {} {
# # ## ### ##### ######## #############
# Get scratchpad to assemble the release in.
# Get version and hash of the commit to be released.
query "Have you run the tests" "Please do"
query "Have you run the examples" "Please do"
query "Have you bumped the version numbers" "Came back after doing so!"
set tmpdir [tmpdir]
id commit version
savedoc $tmpdir
# # ## ### ##### ######## #############
#puts {Generate starkit...}
#_starkit [file join $tmpdir critcl31.kit]
# # ## ### ##### ######## #############
#puts {Collecting starpack prefix...}
# which we use the existing starpack for, from the gh-pages branch
#exec 2>@ stderr >@ stdout git checkout gh-pages
#file copy [file join download critcl31.exe] [file join $tmpdir prefix.exe]
#exec 2>@ stderr >@ stdout git checkout $commit
# # ## ### ##### ######## #############
#puts {Generate starpack...}
#_starpack [file join $tmpdir prefix.exe] [file join $tmpdir critcl31.exe]
# TODO: vacuum the thing. fix permissions if so.
# # ## ### ##### ######## #############
2website
placedoc $tmpdir
#file copy -force [file join $tmpdir critcl31.kit] [file join download critcl31.kit]
#file copy -force [file join $tmpdir critcl31.exe] [file join download critcl31.exe]
set index [cat index.html]
set pattern "\\\[commit .*\\\] \\(v\[^)\]*\\)<!-- current"
set replacement "\[commit $commit\] (v$version)<!-- current"
regsub $pattern $index $replacement index
wfile index.html $index
# # ## ### ##### ######## #############
reminder $commit
# # ## ### ##### ######## #############
return
}
proc Hrelease-doc {} { return "\n\tUpdate the release documentation from the current commit.\n\tAssumed to be properly tagged.\n\tLeaves the checkout in the gh-pages branch, ready for commit+push" }
proc _release-doc {} {
# # ## ### ##### ######## #############
# Get scratchpad to assemble the release in.
# Get version and hash of the commit to be released.
set tmpdir [tmpdir]
id _ commit ; # Just for the printout, we are actually not using the data.
savedoc $tmpdir
2website
placedoc $tmpdir
reminder $commit
# # ## ### ##### ######## #############
return
}
proc Hdirs {} { return "[Ioptions]\n\tShow directory setup" }
proc _dirs args {
process-install-options
puts "destdir = [dest-dir]"
puts "prefix = [dest-dir][prefix]"
puts "exec-prefix = [dest-dir][exec-prefix]"
puts "bin-dir = [dest-dir][bin-dir]"
puts "lib-dir = [dest-dir][lib-dir]"
puts "include-dir = [dest-dir][include-dir]"
puts ""
return
}
proc Ioptions {} { return "?--dest-dir path? ?--prefix path? ?--exec-prefix path? ?--bin-dir path? ?--lib-dir path? ?--include-dir path?" }
proc Htargets {} { return "[Ioptions]\n\tShow available targets.\n\tExpects critcl app to be installed in the \"--bin-dir\" derived from the options and defaults" }
proc _targets args {
process-install-options
set dsta [dest-dir][bin-dir]
puts [join [split [exec [file join $dsta critcl] -targets]] \n]
return
}
proc Hinstall {} { return "?-target T? [Ioptions]\n\tInstall all packages, and application.\n\tDefault --prefix is \"\$(dirname \$(dirname /path/to/tclsh))\"" }
proc _install {args} {
global packages me
set target {}
process-install-options
set dsta [dest-dir][bin-dir]
set dstl [dest-dir][lib-dir]
set dsti [dest-dir][include-dir]
set selfdir [file dirname $me]
puts {Installing into:}
puts \tPackages:\t$dstl
puts \tApplication:\t$dsta
puts \tHeaders:\t$dsti
file mkdir $dsta $dsti
if {[catch {
# Create directories, might not exist.
file mkdir $dstl
file mkdir $dsta
set prefix \n
foreach item $packages {
# Package: /name/
if {[llength $item] == 3} {
foreach {dir vfile name} $item break
} elseif {[llength $item] == 1} {
set dir $item
set vfile {}
set name $item
} else {
foreach {dir vfile} $item break
set name $dir
}
if {$vfile ne {}} {
set version [version [vfile $dir $vfile]]
} else {
set version {}
}
set namevers [file join $dstl [pkgdirname $name $version]]
file copy -force [file join $selfdir lib $dir] [file join $dstl ${name}-new]
file delete -force $namevers
puts "${prefix}Installed package: $namevers"
file rename [file join $dstl ${name}-new] $namevers
set prefix {}
}
# Application: critcl
set theapp [critapp $dsta]
set reldstl [relativedir $dstl $theapp]
set c [open $theapp w]
lappend map @bs@ "\\"
lappend map @exe@ [shquote [norm [thisexe]]]
lappend map @relpath@ [file split $reldstl] ;# insert the dst path
lappend map "\t " {} ;# de-dent
lappend map "\t\t" { } ;# de-dent
puts $c [string trimleft [string map $map {
#!/bin/sh
# -*-tcl -*-
# hide next line from tcl @bs@
exec @exe@ "$0" ${1+"$@"}
# Add location of critcl packages to the package load path, if not
# yet present. Computed relative to the location of the application,
# as per the installation paths.
set libpath [file join [file dirname [info script]] @relpath@]
set libpath [file dirname [file normalize [file join $libpath ...]]]
if {[lsearch -exact $auto_path $libpath] < 0} {
set auto_path [linsert $auto_path[set auto_path {}] 0 $libpath]
}
unset libpath
package require critcl::app
critcl::app::main $argv}]]
close $c
+x $theapp
puts "${prefix}Installed application: $theapp"
# C packages - Need major Tcl version
set major [lindex [split [info patchlevel] .] 0]
# Special package: critcl_md5c
# Local MD5 hash implementation.
puts "\nInstalled C package:\tcritcl::md5c"
# It is special because it is a critcl-based package, not pure
# Tcl as everything else of critcl. Its installation makes it
# the first package which will be compiled with critcl on this
# machine. It uses the just-installed application for
# that. This is package-mode, where MD5 itself is not used, so
# there is no chicken vs. egg.
set src [file join $selfdir lib critcl-md5c md5c.tcl]
set version [version $src]
set name critcl_md5c_tcl$major
set dst [file join $dstl [pkgdirname $name $version]]
set cmd {}
lappend cmd exec >@ stdout 2>@ stderr
lappend cmd [thisexe]
lappend cmd $theapp
if {$target ne {}} {
lappend cmd -target $target
}
lappend cmd -libdir [file join $dstl tmp] -pkg $src
puts [list executing $cmd]
eval $cmd
file delete -force $dst
file rename [file join $dstl tmp md5c] $dst
file delete -force [file join $dstl tmp]
puts "${prefix}Installed package: $dst"
# Special package: critcl::callback
# C/Tcl callback utility code.
puts "\nInstalled C package:\tcritcl::callback"
# It is special because it is a critcl-based package, not pure
# Tcl as everything else of critcl. Its installation makes it
# the second package which will be compiled with critcl on this
# machine. It uses the just-installed application for
# that.
set src [file join $selfdir lib critcl-callback callback.tcl]
set version [version $src]
set name critcl_callback_tcl$major
set dst [file join $dstl [pkgdirname $name $version]]
set dsth [file join $dsti critcl_callback] ;# headers unversioned
set cmd {}
lappend cmd exec >@ stdout 2>@ stderr
lappend cmd [thisexe]
lappend cmd $theapp
if {$target ne {}} {
lappend cmd -target $target
}
set dstl_tmp [file join $dstl tmp]
lappend cmd -libdir $dstl_tmp
lappend cmd -includedir $dstl_tmp
lappend cmd -pkg $src
eval $cmd
file delete -force $dst $dsth
file rename [file join $dstl tmp callback] $dst
file rename [file join $dstl tmp critcl_callback] $dsth
file delete -force $dstl_tmp
puts "${prefix}Installed package: $dst"
puts "${prefix}Installed headers: [
file join $dsti critcl_callback]"
} msg]} {
if {![string match {*permission denied*} $msg]} {
return -code error -errorcode $::errorCode -errorinfo $::errorInfo $msg
}
puts stderr "\n$msg\n\nUse 'sudo' or some other way of running the operation under the user having access to the destination paths.\n"
exit
}
return
}
proc Huninstall {} { Hdrop }
proc _uninstall {args} { eval [linsert $args 0 _drop] }
proc Hdrop {} { return "[Ioptions]\n\tRemove packages" }
proc _drop {args} {
global packages me
process-install-options
set dsta [dest-dir][bin-dir]
set dstl [dest-dir][lib-dir]
set dsti [dest-dir][include-dir]
# C packages - Need major Tcl version
set major [lindex [split [info patchlevel] .] 0]
# Add the special packages (see install). Not special with regard
# to removal. Except for the name
lappend packages [list critcl-md5c md5c.tcl critcl_md5c_tcl$major]
lappend packages [list critcl-callback callback.tcl critcl_callback_tcl$major]
set selfdir [file dirname $me]
foreach item $packages {
# Package: /name/
if {[llength $item] == 3} {
foreach {dir vfile name} $item break
} elseif {[llength $item] == 1} {
set dir $item
set vfile {}
set name $item
} else {
foreach {dir vfile} $item break
set name $dir
}
if {$vfile ne {}} {
set version [version [vfile $dir $vfile]]
} else {
set version {}
}
set namevers [file join $dstl [pkgdirname $name $version]]
file delete -force $namevers
puts "Removed package: $namevers"
}
# Application: critcl
set theapp [critapp $dsta]
file delete $theapp
puts "Removed application: $theapp"
# Includes/Headers (critcl::callback)
set dsth [file join $dsti critcl_callback]
file delete -force $dsth
puts "Removed headers: $dsth"
return
}
proc Hstarkit {} { return "?destination? ?interpreter?\n\tGenerate a starkit\n\tdestination = path of result file, default 'critcl.kit'\n\tinterpreter = (path) name of tcl shell to use for execution, default 'tclkit'" }
proc _starkit {{dst critcl.kit} {interp tclkit}} {
package require vfs::mk4
set c [open $dst wb]
puts -nonewline $c "#!/bin/sh\n# -*- tcl -*- \\\nexec $interp \"\$0\" \$\{1+\"\$@\"\}\npackage require starkit\nstarkit::header mk4 -readonly\n\032################################################################################################################################################################"
close $c
vfs::mk4::Mount $dst /KIT
file copy -force lib /KIT
file copy -force main.tcl /KIT
vfs::unmount /KIT
+x $dst
puts "Created starkit: $dst"
return
}
proc Hstarpack {} { return "prefix ?destination?\n\tGenerate a fully-selfcontained executable, i.e. a starpack\n\tprefix = path of tclkit/basekit runtime to use\n\tdestination = path of result file, default 'critcl'" }
proc _starpack {prefix {dst critcl}} {
package require vfs::mk4
file copy -force $prefix $dst
vfs::mk4::Mount $dst /KIT
file mkdir [file join /KIT lib]
foreach d [glob -directory lib *] {
file delete -force [file join /KIT lib [file tail $d]]
file copy -force $d [file join /KIT lib]
}
file copy -force main.tcl /KIT
vfs::unmount /KIT
+x $dst
puts "Created starpack: $dst"
return
}
proc Hexamples {} { return "?args...?\n\tWithout arguments, list the examples.\n\tOtherwise run the recipe with its arguments on the examples" }
proc _examples {args} {
global me
set selfdir [file dirname $me]
set self [file tail $me]
# List examples, or run the build code on the examples, passing any arguments.
set examples [lsort -dict [glob -directory [file join $selfdir examples] */$self]]
puts ""
if {![llength $args]} {
foreach b $examples {
puts "* [file dirname $b]"
}
} else {
foreach b $examples {
puts "$b _______________________________________________"
eval [linsert $args 0 exec 2>@ stderr >@ stdout [thisexe] $b]
puts ""
puts ""
}
}
return
}
main

51
src/vfs/critcl-3.3.1.vfs/genStubs.tcl

@ -0,0 +1,51 @@
# genStubs.tcl --
#
# This script generates a set of stub files for a given
# interface.
#
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
# Copyright (c) 2011,2022 Andreas Kupries <andreas_kupries@users.sourceforge.net>
# (Conversion into package set).
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require Tcl 8.6 9
lappend auto_path [file dirname [file normalize [info script]]]/lib/stubs
lappend auto_path [file dirname [file normalize [info script]]]/lib/util84
package require stubs::container
package require stubs::reader
package require stubs::gen::init
package require stubs::gen::header
proc main {} {
global argv argv0
if {[llength $argv] < 2} {
puts stderr "usage: $argv0 outDir declFile ?declFile...?"
exit 1
}
set outDir [lindex $argv 0]
set T [stubs::container::new]
foreach file [lrange $argv 1 end] {
stubs::reader::file T $file
}
foreach name [lsort [stubs::container::interfaces $T]] {
puts "Emitting $name"
stubs::gen::header::rewrite@ $outDir $T $name
}
stubs::gen::init::rewrite@ $outDir $T
return
}
main
exit 0

1944
src/vfs/critcl-3.3.1.vfs/lib/app-critcl/critcl.tcl

File diff suppressed because it is too large Load Diff

2
src/vfs/critcl-3.3.1.vfs/lib/app-critcl/pkgIndex.tcl

@ -0,0 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6 9]} {return}
package ifneeded critcl::app 3.3.1 [list source [file join $dir critcl.tcl]]

0
src/vfs/critcl.vfs/lib/app-critcl/runtime.tcl → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/runtime.tcl

0
src/vfs/critcl.vfs/lib/app-critcl/tea/Config.in → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/Config.in

0
src/vfs/critcl.vfs/lib/app-critcl/tea/Makefile.in → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/Makefile.in

0
src/vfs/critcl.vfs/lib/app-critcl/tea/aclocal.m4 → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/aclocal.m4 vendored

0
src/vfs/critcl.vfs/lib/app-critcl/tea/configure.in → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/configure.in

0
src/vfs/critcl.vfs/lib/app-critcl/tea/tclconfig/README.txt → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/README.txt

0
src/vfs/critcl.vfs/lib/app-critcl/tea/tclconfig/install-sh → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/install-sh

0
src/vfs/critcl.vfs/lib/app-critcl/tea/tclconfig/license.terms → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/license.terms

0
src/vfs/critcl.vfs/lib/app-critcl/tea/tclconfig/tcl.m4 → src/vfs/critcl-3.3.1.vfs/lib/app-critcl/tea/tclconfig/tcl.m4

0
src/vfs/critcl.vfs/lib/critcl-bitmap/bitmap.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-bitmap/bitmap.tcl

0
src/vfs/critcl.vfs/lib/critcl-bitmap/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-bitmap/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-callback/c/callback.c → src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/c/callback.c

0
src/vfs/critcl.vfs/lib/critcl-callback/c/callback.h → src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/c/callback.h

0
src/vfs/critcl.vfs/lib/critcl-callback/c/callback_int.h → src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/c/callback_int.h

0
src/vfs/critcl.vfs/lib/critcl-callback/callback.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-callback/callback.tcl

0
src/vfs/critcl.vfs/lib/critcl-class/class.h → src/vfs/critcl-3.3.1.vfs/lib/critcl-class/class.h

0
src/vfs/critcl.vfs/lib/critcl-class/class.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-class/class.tcl

0
src/vfs/critcl.vfs/lib/critcl-class/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-class/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-cutil/allocs/critcl_alloc.h → src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/allocs/critcl_alloc.h

0
src/vfs/critcl.vfs/lib/critcl-cutil/asserts/critcl_assert.h → src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/asserts/critcl_assert.h

86
src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/cutil.tcl

@ -0,0 +1,86 @@
## -*- tcl -*-
# # ## ### ##### ######## ############# #####################
# Pragmas for MetaData Scanner.
# n/a
# CriTcl Utility Commands To Provide Common C-level utility functions.
#
# Copyright (c) 2017-2024 Andreas Kupries <andreas_kupries@users.sourceforge.net>
package provide critcl::cutil 0.5
# # ## ### ##### ######## ############# #####################
## Requirements.
package require Tcl 8.6 9 ; # Min supported version.
package require critcl 3.2
namespace eval ::critcl::cutil {}
# # ## ### ##### ######## ############# #####################
## Implementation -- API: Embed C Code
# # ## ### ##### ######## ############# #####################
proc critcl::cutil::alloc {} {
variable selfdir
critcl::cheaders -I$selfdir/allocs
critcl::include critcl_alloc.h
return
}
proc critcl::cutil::assertions {{enable 0}} {
variable selfdir
critcl::cheaders -I$selfdir/asserts
critcl::include critcl_assert.h
if {!$enable} return
critcl::cflags -DCRITCL_ASSERT
return
}
proc critcl::cutil::tracer {{enable 0}} {
variable selfdir
alloc ;# Tracer uses the allocation utilities in its implementation
critcl::cheaders -I$selfdir/trace
critcl::include critcl_trace.h
if {!$enable} return
critcl::csources $selfdir/trace/trace.c
critcl::cflags -DCRITCL_TRACER
return
}
proc critcl::cutil::tracer-config {args} {
while {[llength $args]} {
set o [lindex $args 0]
switch -exact -- $o {
-unthreaded -
-nothreads {
critcl::cflags -DCRITCL_TRACE_NOTHREADS
}
default {
return -code error \
"Unknown option $o, expected -nothreads, or -unthreaded"
}
}
}
return
}
# # ## ### ##### ######## ############# #####################
## State
namespace eval ::critcl::cutil {
variable selfdir [file dirname [file normalize [info script]]]
}
# # ## ### ##### ######## ############# #####################
## Export API
namespace eval ::critcl::cutil {
namespace export alloc assert tracer
catch { namespace ensemble create }
}
# # ## ### ##### ######## ############# #####################
## Ready
return

2
src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/pkgIndex.tcl

@ -0,0 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6 9]} {return}
package ifneeded critcl::cutil 0.5 [list source [file join $dir cutil.tcl]]

170
src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/trace/critcl_trace.h

@ -0,0 +1,170 @@
#ifndef __CRITCL_UTIL_TRACE_H
#define __CRITCL_UTIL_TRACE_H 1
/*
* Copyright (c) 2017-2024 Andreas Kupries <andreas_kupries@users.sourceforge.net>
*
* Narrative tracing support, controlled by CRITCL_TRACER
* = = == === ===== ======== ============= =====================
*
* Further control of the active logical sub-streams is done via the
* declarators
* - TRACE_ON
* - TRACE_OFF
* - TRACE_TAG_ON
* - TRACE_TAG_OFF
*
* The macros make use of the standard macros __FILE__ and __LINE__
* to identify traced locations (physically).
*
* ATTENTION: The trace facility assumes a C99 compiler to have
* access to the __func__ string which holds the name
* of the current function.
*
* NOTE: define CRITCL_TRACE_NOTHREADS if the tracer is run on a single-threaded
* process for sure. Else leave it at the new default of multi-threaded
* operation.
*
* In this mode it generates one `.trace` file per thread with active tracing.
* In single-threaded mode it writes to stdout as before.
*
* NOTE 2: The above can be done through the `critcl::tracer-config` command, i.e.
* invoke:
* critcl::tracer-config -nothreads
*/
#include <tcl.h>
/*
* Main (convenience) commands:
*
* - TRACE_FUNC :: Function entry, formatted parameters
* - TRACE_FUNC_VOID :: Function entry, no parameters
* - TRACE_RETURN :: Function exit, formatted result
* - TRACE_RETURN_VOID :: Function exit, no result
* - TRACE :: Additional trace line.
*
* The above commands are composed from the lower level commands below.
*
* Scoping
* - TRACE_PUSH_SCOPE :: Start a named scope, no output
* - TRACE_PUSH_FUNC :: Start a scope, named by the current function, no output
* - TRACE_POP :: End a scope, no output
* Tracing
* - TRACE_HEADER :: Start of trace line (location, indentation, scope)
* - TRACE_ADD :: Extend trace line, formatted information
* - TRACE_CLOSER :: End of trace line
*
* All of the tracing command also come in TRACE_TAG_ forms which take an
* additional 1st argument, the tag of the stream. The scoping commands do not
* take tags. They manage indentation without generating output on their own.
*/
#ifndef CRITCL_TRACER
/* Tracing is disabled. All macros vanish / devolve to their untraced functionality.
*/
#define TRACE_THREAD_EXIT TCL_THREAD_CREATE_RETURN
#define TRACE_PUSH_SCOPE(string)
#define TRACE_PUSH_FUNC
#define TRACE_POP
#define TRACE_ON
#define TRACE_OFF
#define TRACE_HEADER(indent)
#define TRACE_ADD(format, ...)
#define TRACE_CLOSER
#define TRACE_TAG_ON(tag)
#define TRACE_TAG_OFF(tag)
#define TRACE_TAG_HEADER(tag,indent)
#define TRACE_TAG_ADD(tag, format, ...)
#define TRACE_TAG_CLOSER(tag)
#define TRACE_FUNC(format, ...)
#define TRACE_FUNC_VOID
#define TRACE_RETURN(format,x) return (x);
#define TRACE_RETURN_VOID return;
#define TRACE(format, ...)
#define TRACE_TAG_FUNC(tag, format, ...)
#define TRACE_TAG_FUNC_VOID(tag)
#define TRACE_TAG_RETURN(tag, format, x) return (x);
#define TRACE_TAG_RETURN_VOID(tag) return;
#define TRACE_TAG(tag, format, ...)
#define TRACE_RUN(code)
#define TRACE_DO(code)
#define TRACE_TAG_DO(tag, code)
#define TRACE_TAG_VAR(tag) 0
#endif
#ifdef CRITCL_TRACER
/* Tracing is active. All macros are properly defined.
*/
#define TRACE_THREAD_EXIT TRACE ("THREAD EXIT %s", "(void)") ; TRACE_POP ; critcl_trace_thread_end() ; TCL_THREAD_CREATE_RETURN
#define TRACE_PUSH_SCOPE(string) critcl_trace_push (string)
#define TRACE_PUSH_FUNC TRACE_PUSH_SCOPE (__func__)
#define TRACE_POP critcl_trace_pop()
#define TRACE_ON TRACE_TAG_ON (THIS_FILE)
#define TRACE_OFF TRACE_TAG_OFF (THIS_FILE)
#define TRACE_HEADER(indent) TRACE_TAG_HEADER (THIS_FILE, indent)
#define TRACE_ADD(format, ...) TRACE_TAG_ADD (THIS_FILE, format, __VA_ARGS__)
#define TRACE_CLOSER TRACE_TAG_CLOSER (THIS_FILE)
#define TRACE_TAG_ON(tag) static int TRACE_TAG_VAR (tag) = 1
#define TRACE_TAG_OFF(tag) static int TRACE_TAG_VAR (tag) = 0
#define TRACE_TAG_VAR(tag) __critcl_tag_ ## tag ## _status
#define TRACE_TAG_HEADER(tag, indent) critcl_trace_header (TRACE_TAG_VAR (tag), (indent), __FILE__, __LINE__)
#define TRACE_TAG_ADD(tag, format, ...) critcl_trace_printf (TRACE_TAG_VAR (tag), format, __VA_ARGS__)
#define TRACE_TAG_CLOSER(tag) critcl_trace_closer (TRACE_TAG_VAR (tag))
/*
* Highlevel (convenience) tracing support.
*/
#define TRACE_FUNC(format, ...) TRACE_TAG_FUNC (THIS_FILE, format, __VA_ARGS__)
#define TRACE_FUNC_VOID TRACE_TAG_FUNC_VOID (THIS_FILE)
#define TRACE_RETURN(format,x) TRACE_TAG_RETURN (THIS_FILE, format, x)
#define TRACE_RETURN_VOID TRACE_TAG_RETURN_VOID (THIS_FILE)
#define TRACE(format, ...) TRACE_TAG (THIS_FILE, format, __VA_ARGS__)
#define TRACE_TAG_FUNC(tag, format, ...) TRACE_PUSH_FUNC; TRACE_TAG_HEADER (tag,1); TRACE_TAG_ADD (tag, format, __VA_ARGS__); TRACE_TAG_CLOSER (tag)
#define TRACE_TAG_FUNC_VOID(tag) TRACE_PUSH_FUNC; TRACE_TAG_HEADER (tag,1); TRACE_TAG_ADD (tag, "(%s)", "void"); TRACE_TAG_CLOSER (tag)
#define TRACE_TAG_RETURN(tag, format, x) TRACE_TAG_HEADER (tag,1); TRACE_TAG_ADD (tag, "%s", "RETURN = ") ; TRACE_TAG_ADD (tag, format, x) ; TRACE_TAG_CLOSER (tag) ; TRACE_POP ; return (x)
#define TRACE_TAG_RETURN_VOID(tag) TRACE_TAG_HEADER (tag,1); TRACE_TAG_ADD (tag, "RETURN %s", "(void)") ; TRACE_TAG_CLOSER (tag) ; TRACE_POP ; return
#define TRACE_TAG(tag, format, ...) TRACE_TAG_HEADER (tag,1); TRACE_TAG_ADD (tag, format, __VA_ARGS__) ; TRACE_TAG_CLOSER (tag)
#define TRACE_RUN(code) code
#define TRACE_DO(code) TRACE_TAG_DO (THIS_FILE, code)
#define TRACE_TAG_DO(tag, code) if (TRACE_TAG_VAR (tag)) { code ; }
/*
* Declarations for the support functions used in the macros.
*/
extern void critcl_trace_push (const char* scope);
extern void critcl_trace_pop (void);
extern void critcl_trace_header (int on, int indent, const char *filename, int line);
extern void critcl_trace_printf (int on, const char *pat, ...);
extern void critcl_trace_closer (int on);
extern void critcl_trace_thread_end (void);
/*
* Declarations for the support functions used by the
* implementation of "critcl::cproc".
*/
extern void critcl_trace_cmd_args (const char* scope, int oc, Tcl_Obj*const* ov);
extern int critcl_trace_cmd_result (int status, Tcl_Interp* ip);
#endif
#endif /* __CRITCL_UTIL_TRACE_H */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

295
src/vfs/critcl-3.3.1.vfs/lib/critcl-cutil/trace/trace.c

@ -0,0 +1,295 @@
/*
* Copyright (c) 2017-2024 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* = = == === ===== ======== ============= =====================
*/
#include <critcl_alloc.h>
#include <string.h>
#include <stdarg.h>
/*
* = = == === ===== ======== ============= =====================
*/
#ifdef CRITCL_TRACER
/* Tracking the stack of scopes,
* single-linked list,
* top to bottom.
*/
typedef struct scope_stack {
const char* scope;
struct scope_stack* down;
} scope_stack;
/*
* = = == === ===== ======== ============= =====================
* Tracing state (stack of scopes, associated indentation level)
*
* API regexp for trace output:
* (header printf* closer)*
*
* - closed == 1 :: post (closer)
* - closed == 0 :: post (header)
*
* [1] in (header) && !closed
* => starting a new line in the middle of an incomplete line
* => force closer
* [2] in (printf) && closed
* => continuing a line which was interrupted by another (see [1])
* => force header
*/
#define MSGMAX (1024*1024)
#ifdef CRITCL_TRACE_NOTHREADS
static scope_stack* top = 0;
static int level = 0;
static int closed = 1;
static char msg [MSGMAX];
#define SETUP
#define TOP top
#define LEVEL level
#define CLOSED closed
#define MSG msg
#define CHAN stdout
/* Thread end means nothing
*/
void
critcl_trace_thread_end (void) {}
#else
typedef struct ThreadSpecificData {
scope_stack* top;
int level;
int closed;
char msg [MSGMAX];
FILE* chan;
} ThreadSpecificData;
/* copied from tclInt.h */
#define TCL_TSD_INIT(keyPtr) \
(ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) /* OK tcl9 */
static Tcl_ThreadDataKey ctraceDataKey;
#define TOP tsdPtr->top
#define LEVEL tsdPtr->level
#define CLOSED tsdPtr->closed
#define MSG tsdPtr->msg
#define CHAN chan()
#define SETUP ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&ctraceDataKey)
// Very lazy channel initialization - First actual write
static FILE* chan (void) {
SETUP;
if (!tsdPtr->chan) {
sprintf (MSG, "%p.trace", Tcl_GetCurrentThread());
tsdPtr->chan = fopen (MSG, "a");
if (!tsdPtr->chan) {
Tcl_Panic ("out of files to open: %s", MSG);
}
}
return tsdPtr->chan;
}
/* Thread end marker, use it to close the trace file for the ended thread.
* This is needed to keep the number of open files under control as traced
* threads are spawned and end. Without it we will run out of file slots
* over time and break.
*
* Example: Benchmarks running a traced command with threads a few thousand
* times.
*/
void
critcl_trace_thread_end (void)
{
SETUP;
if (!tsdPtr->chan) return;
fclose (tsdPtr->chan);
tsdPtr->chan = NULL;
return;
}
#endif
/*
* = = == === ===== ======== ============= =====================
* Internals
*/
static void
indent (void)
{
int i;
SETUP;
for (i = 0; i < LEVEL; i++) { fwrite(" ", 1, 1, CHAN); }
fflush (CHAN);
}
static void
scope (void)
{
SETUP;
if (!TOP) return;
fwrite (TOP->scope, 1, strlen(TOP->scope), CHAN);
fflush (CHAN);
}
static void
separator (void)
{
SETUP;
fwrite(" | ", 1, 3, CHAN);
fflush (CHAN);
}
/*
* = = == === ===== ======== ============= =====================
* API
*/
void
critcl_trace_push (const char* scope)
{
SETUP;
scope_stack* new = ALLOC (scope_stack);
new->scope = scope;
new->down = TOP;
TOP = new;
LEVEL += 4;
}
void
critcl_trace_pop (void)
{
SETUP;
scope_stack* next = TOP->down;
LEVEL -= 4;
ckfree ((char*) TOP);
TOP = next;
}
void
critcl_trace_closer (int on)
{
if (!on) return;
SETUP;
fwrite ("\n", 1, 1, CHAN);
fflush (CHAN);
CLOSED = 1;
}
void
critcl_trace_header (int on, int ind, const char* filename, int line)
{
if (!on) return;
SETUP;
if (!CLOSED) critcl_trace_closer (1);
// location prefix
#if 0 /* varying path length breaks indenting by call level :( */
if (filename) {
fprintf (CHAN, "%s:%6d", filename, line);
fflush (CHAN);
}
#endif
// indentation, scope, separator
if (ind) { indent (); }
scope ();
separator();
CLOSED = 0;
}
void
critcl_trace_printf (int on, const char *format, ...)
{
/*
* 1MB output-buffer. We may trace large data structures. This is also a
* reason why the implementation can be compiled out entirely.
*/
int len;
va_list args;
if (!on) return;
SETUP;
if (CLOSED) critcl_trace_header (1, 1, 0, 0);
va_start (args, format);
len = vsnprintf (MSG, MSGMAX, format, args);
va_end (args);
fwrite (MSG, 1, len, CHAN);
fflush (CHAN);
}
void
critcl_trace_cmd_args (const char* scopename, int argc, Tcl_Obj*const* argv)
{
int i;
critcl_trace_push (scopename);
for (i=0; i < argc; i++) {
// No location information
indent();
scope();
separator();
critcl_trace_printf (1, "ARG [%3d] = %p (^%d:%s) '%s'\n",
i, argv[i], argv[i]->refCount,
argv[i]->typePtr ? argv[i]->typePtr->name : "<unknown>",
Tcl_GetString((Tcl_Obj*) argv[i]));
}
}
int
critcl_trace_cmd_result (int status, Tcl_Interp* ip)
{
Tcl_Obj* robj = Tcl_GetObjResult (ip);
const char* rstr = Tcl_GetString (robj);
const char* rstate;
const char* rtype;
static const char* state_str[] = {
/* 0 */ "OK",
/* 1 */ "ERROR",
/* 2 */ "RETURN",
/* 3 */ "BREAK",
/* 4 */ "CONTINUE",
};
char buf [TCL_INTEGER_SPACE];
if (status <= TCL_CONTINUE) {
rstate = state_str [status];
} else {
sprintf (buf, "%d", status);
rstate = (const char*) buf;
}
if (robj->typePtr) {
rtype = robj->typePtr->name;
} else {
rtype = "<unknown>";
}
// No location information
indent();
scope();
separator();
critcl_trace_printf (1, "RESULT = %s %p (^%d:%s) '%s'\n",
rstate, robj, robj->refCount, rtype, rstr);
critcl_trace_pop ();
return status;
}
#endif /* CRITCL_TRACER */
/*
* = = == === ===== ======== ============= =====================
*/
/*
* local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/

0
src/vfs/critcl.vfs/lib/critcl-emap/emap.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-emap/emap.tcl

0
src/vfs/critcl.vfs/lib/critcl-emap/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-emap/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-enum/enum.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-enum/enum.tcl

0
src/vfs/critcl.vfs/lib/critcl-enum/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-enum/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-iassoc/iassoc.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-iassoc/iassoc.tcl

0
src/vfs/critcl.vfs/lib/critcl-iassoc/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-iassoc/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-literals/literals.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-literals/literals.tcl

0
src/vfs/critcl.vfs/lib/critcl-literals/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-literals/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-md5c/md5c.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-md5c/md5c.tcl

0
src/vfs/critcl.vfs/lib/critcl-md5c/md5c_c/md5.c → src/vfs/critcl-3.3.1.vfs/lib/critcl-md5c/md5c_c/md5.c

0
src/vfs/critcl.vfs/lib/critcl-md5c/md5c_c/md5.h → src/vfs/critcl-3.3.1.vfs/lib/critcl-md5c/md5c_c/md5.h

0
src/vfs/critcl.vfs/lib/critcl-platform/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-platform/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-platform/platform.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-platform/platform.tcl

0
src/vfs/critcl.vfs/lib/critcl-util/pkgIndex.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-util/pkgIndex.tcl

0
src/vfs/critcl.vfs/lib/critcl-util/util.tcl → src/vfs/critcl-3.3.1.vfs/lib/critcl-util/util.tcl

0
src/vfs/critcl.vfs/lib/critcl/Config → src/vfs/critcl-3.3.1.vfs/lib/critcl/Config

6831
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl.tcl

File diff suppressed because it is too large Load Diff

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/cdata.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/cdata.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/header.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/header.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/pkginit.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/pkginit.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/pkginitend.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/pkginitend.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/pkginittk.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/pkginittk.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/preload.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/preload.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/storageclass.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/storageclass.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/stubs.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/stubs.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/stubs_e.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/stubs_e.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/X.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/X.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xatom.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xatom.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xfuncproto.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xfuncproto.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xlib.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xlib.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xutil.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/Xutil.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/cursorfont.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/cursorfont.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/keysym.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/keysym.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/keysymdef.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/keysymdef.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/X11/tkIntXlibDecls.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/X11/tkIntXlibDecls.h

2645
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tcl.h

File diff suppressed because it is too large Load Diff

4119
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tclDecls.h

File diff suppressed because it is too large Load Diff

144
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tclPlatDecls.h

@ -0,0 +1,144 @@
/*
* tclPlatDecls.h --
*
* Declarations of platform specific Tcl APIs.
*
* Copyright (c) 1998-1999 by Scriptics Corporation.
* All rights reserved.
*/
#ifndef _TCLPLATDECLS
#define _TCLPLATDECLS
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
#else
# ifdef USE_TCL_STUBS
# define TCL_STORAGE_CLASS
# else
# define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif
/*
* WARNING: This file is automatically generated by the tools/genStubs.tcl
* script. Any modifications to the function declarations below should be made
* in the generic/tcl.decls script.
*/
/*
* TCHAR is needed here for win32, so if it is not defined yet do it here.
* This way, we don't need to include <tchar.h> just for one define.
*/
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(_TCHAR_DEFINED)
# if defined(_UNICODE)
typedef wchar_t TCHAR;
# else
typedef char TCHAR;
# endif
# define _TCHAR_DEFINED
#endif
/* !BEGIN!: Do not edit below this line. */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Exported function declarations:
*/
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len,
Tcl_DString *dsPtr);
/* 1 */
EXTERN char * Tcl_WinTCharToUtf(const TCHAR *str, int len,
Tcl_DString *dsPtr);
/* Slot 2 is reserved */
/* 3 */
EXTERN void TclWinConvertError_(unsigned errCode);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 0 */
EXTERN int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp,
const char *bundleName, int hasResourceFile,
int maxPathLen, char *libraryPath);
/* 1 */
EXTERN int Tcl_MacOSXOpenVersionedBundleResources(
Tcl_Interp *interp, const char *bundleName,
const char *bundleVersion,
int hasResourceFile, int maxPathLen,
char *libraryPath);
/* 2 */
EXTERN void TclMacOSXNotifierAddRunLoopMode_(
const void *runLoopMode);
#endif /* MACOSX */
typedef struct TclPlatStubs {
int magic;
void *hooks;
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */
char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */
void (*reserved2)(void);
void (*tclWinConvertError_) (unsigned errCode); /* 3 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */
int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */
void (*tclMacOSXNotifierAddRunLoopMode_) (const void *runLoopMode); /* 2 */
#endif /* MACOSX */
} TclPlatStubs;
extern const TclPlatStubs *tclPlatStubsPtr;
#ifdef __cplusplus
}
#endif
#if defined(USE_TCL_STUBS)
/*
* Inline function declarations:
*/
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define Tcl_WinUtfToTChar \
(tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */
#define Tcl_WinTCharToUtf \
(tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */
/* Slot 2 is reserved */
#define TclWinConvertError_ \
(tclPlatStubsPtr->tclWinConvertError_) /* 3 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#define Tcl_MacOSXOpenBundleResources \
(tclPlatStubsPtr->tcl_MacOSXOpenBundleResources) /* 0 */
#define Tcl_MacOSXOpenVersionedBundleResources \
(tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */
#define TclMacOSXNotifierAddRunLoopMode_ \
(tclPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode_) /* 2 */
#endif /* MACOSX */
#endif /* defined(USE_TCL_STUBS) */
/* !END!: Do not edit above this line. */
#undef TclUnusedStubEntry
#undef TclMacOSXNotifierAddRunLoopMode_
#undef TclWinConvertError_
#ifdef MAC_OSX_TCL /* MACOSX */
#undef Tcl_MacOSXOpenBundleResources
#define Tcl_MacOSXOpenBundleResources(a,b,c,d,e) Tcl_MacOSXOpenVersionedBundleResources(a,b,NULL,c,d,e)
#endif
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TCLPLATDECLS */

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/tk.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tk.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/tkDecls.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tkDecls.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.6/tkPlatDecls.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.6/tkPlatDecls.h

2720
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.7/tcl.h

File diff suppressed because it is too large Load Diff

4498
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.7/tclDecls.h

File diff suppressed because it is too large Load Diff

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl8.7/tclPlatDecls.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl8.7/tclPlatDecls.h

2642
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl9.0/tcl.h

File diff suppressed because it is too large Load Diff

4334
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl9.0/tclDecls.h

File diff suppressed because it is too large Load Diff

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tcl9.0/tclPlatDecls.h → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tcl9.0/tclPlatDecls.h

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tclAppInit.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tclAppInit.c

73
src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tclpre9compat.h

@ -0,0 +1,73 @@
#ifndef CRITCL_TCL9_COMPAT_H
#define CRITCL_TCL9_COMPAT_H
/* Disable the macros making us believe that everything is hunky-dory on compilation, and then
* reward us with runtime crashes for being a sucker to have believed them.
*/
#define TCL_NO_DEPRECATED
#include "tcl.h"
/*
* - - -- --- ----- -------- ------------- ---------------------
* Check for support of the `Tcl_Size` typdef and associated definitions.
* It was introduced in Tcl 8.7 and 9, and we need backward compatibility
* definitions for 8.6.
*/
#ifndef TCL_SIZE_MAX
#include <limits.h>
#define TCL_SIZE_MAX INT_MAX
#ifndef Tcl_Size
typedef int Tcl_Size;
#endif
/* TIP #494 constants, for 8.6 too */
#define TCL_IO_FAILURE ((Tcl_Size)-1)
#define TCL_AUTO_LENGTH ((Tcl_Size)-1)
#define TCL_INDEX_NONE ((Tcl_Size)-1)
#define TCL_SIZE_MODIFIER ""
#define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
#define Tcl_NewSizeIntObj Tcl_NewIntObj
#else
#define Tcl_NewSizeIntObj Tcl_NewWideIntObj
#endif
#define TCL_SIZE_FMT "%" TCL_SIZE_MODIFIER "d"
/*
* - - -- --- ----- -------- ------------- ---------------------
* Critcl (3.3+) emits the command creation API using Tcl_Size by default.
* Map this to the older int-based API when compiling against Tcl 8.x or older.
*
* Further map use of `Tcl_GetBytesFromObj` to the old `Tcl_GetByteArrayFromObj`.
* This loses the interp argument, and the ability to return NULL.
*/
#if TCL_MAJOR_VERSION <= 8
#define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
#define Tcl_GetBytesFromObj(interp,obj,sizeptr) Tcl_GetByteArrayFromObj(obj,sizeptr)
#endif
/*
* - - -- --- ----- -------- ------------- ---------------------
*/
#ifndef CONST
#define CONST const
#endif
#ifndef CONST84
#define CONST84 const
#endif
#ifndef CONST86
#define CONST86 const
#endif
/*
* - - -- --- ----- -------- ------------- ---------------------
*/
#endif /* CRITCL_TCL9_COMPAT_H */

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tkstubs.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tkstubs.c

0
src/vfs/critcl.vfs/lib/critcl/critcl_c/tkstubs_noconst.c → src/vfs/critcl-3.3.1.vfs/lib/critcl/critcl_c/tkstubs_noconst.c

0
src/vfs/critcl.vfs/lib/critcl/license.terms → src/vfs/critcl-3.3.1.vfs/lib/critcl/license.terms

2
src/vfs/critcl-3.3.1.vfs/lib/critcl/pkgIndex.tcl

@ -0,0 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6 9]} {return}
package ifneeded critcl 3.3.1 [list source [file join $dir critcl.tcl]]

0
src/vfs/critcl.vfs/lib/critclf/Config → src/vfs/critcl-3.3.1.vfs/lib/critclf/Config

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save