Browse Source

update bootsupport,vfs,project_layouts

master
Julian Noble 2 months ago
parent
commit
24d6f6e149
  1. 4
      src/bootsupport/modules/punk/ansi-0.1.1.tm
  2. 2
      src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm
  3. 2
      src/bootsupport/modules/punk/char-0.1.0.tm
  4. 2
      src/bootsupport/modules/punk/config-0.1.tm
  5. 6
      src/bootsupport/modules/punk/console-0.1.1.tm
  6. 13
      src/bootsupport/modules/punk/fileline-0.1.0.tm
  7. 30
      src/bootsupport/modules/punk/lib-0.1.1.tm
  8. 2
      src/bootsupport/modules/punkcheck-0.1.0.tm
  9. 6
      src/bootsupport/modules/textblock-0.1.3.tm
  10. BIN
      src/bootsupport/modules/zipper-0.12.tm
  11. 4
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm
  12. 2
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm
  13. 2
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/char-0.1.0.tm
  14. 2
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/config-0.1.tm
  15. 6
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm
  16. 13
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm
  17. 30
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm
  18. 2
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm
  19. 6
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.3.tm
  20. BIN
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/zipper-0.12.tm
  21. 4
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm
  22. 2
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm
  23. 2
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/char-0.1.0.tm
  24. 2
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/config-0.1.tm
  25. 6
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm
  26. 13
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm
  27. 30
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm
  28. 2
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm
  29. 6
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.3.tm
  30. BIN
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/zipper-0.12.tm
  31. 642
      src/vfs/_vfscommon.vfs/modules/picalc-0.1.0.tm
  32. 36
      src/vfs/_vfscommon.vfs/modules/punk-0.1.tm
  33. 7672
      src/vfs/_vfscommon.vfs/modules/punk-0.1.tm.txt
  34. 4
      src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm
  35. 44
      src/vfs/_vfscommon.vfs/modules/punk/basictelnet-0.1.0.tm
  36. 2
      src/vfs/_vfscommon.vfs/modules/punk/cap/handlers/templates-0.1.0.tm
  37. 2
      src/vfs/_vfscommon.vfs/modules/punk/char-0.1.0.tm
  38. 2
      src/vfs/_vfscommon.vfs/modules/punk/config-0.1.tm
  39. 6
      src/vfs/_vfscommon.vfs/modules/punk/console-0.1.1.tm
  40. 13
      src/vfs/_vfscommon.vfs/modules/punk/fileline-0.1.0.tm
  41. 31
      src/vfs/_vfscommon.vfs/modules/punk/icomm-0.1.0.tm
  42. 57
      src/vfs/_vfscommon.vfs/modules/punk/imap4-0.9.tm
  43. 1
      src/vfs/_vfscommon.vfs/modules/punk/jtest.tcl
  44. 30
      src/vfs/_vfscommon.vfs/modules/punk/lib-0.1.1.tm
  45. 25
      src/vfs/_vfscommon.vfs/modules/punk/repl-0.1.1.tm
  46. 4
      src/vfs/_vfscommon.vfs/modules/punk/sshrun-0.1.0.tm
  47. 478
      src/vfs/_vfscommon.vfs/modules/punk/timeinterval-0.1.0.tm
  48. 14
      src/vfs/_vfscommon.vfs/modules/punk/winrun-0.1.0.tm
  49. 2
      src/vfs/_vfscommon.vfs/modules/punkcheck-0.1.0.tm
  50. 11
      src/vfs/_vfscommon.vfs/modules/shellrun-0.1.1.tm
  51. 12
      src/vfs/_vfscommon.vfs/modules/shellthread-1.6.1.tm
  52. 6
      src/vfs/_vfscommon.vfs/modules/textblock-0.1.3.tm
  53. 153
      src/vfs/_vfscommon.vfs/modules/winlibreoffice-0.1.0.tm
  54. BIN
      src/vfs/_vfscommon.vfs/modules/zipper-0.12.tm

4
src/bootsupport/modules/punk/ansi-0.1.1.tm

@ -7569,11 +7569,11 @@ namespace eval punk::ansi::colour {
}
foreach c {R G B} {
if {$T($c) < [expr {1.0/6.0}]} {
if {$T($c) < (1.0/6.0)} {
set T($c) [expr {$P+($Q-$P)*6.0*$T($c)}]
} elseif {$T($c) < 0.5} {
set T($c) $Q
} elseif {$T($c) < [expr {2.0/3.0}]} {
} elseif {$T($c) < (2.0/3.0)} {
set T($c) [expr {$P+($Q-$P)*(2.0/3.0-$T($c))*6.0}]
} else {
set T($c) $P

2
src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm

@ -95,7 +95,7 @@ namespace eval punk::cap::handlers::templates {
} else {
set tm_exists [file exists $tmfile]
}
if {![file exists $tmfile]} {
if {!$tm_exists} {
puts stderr "punk::cap::handlers::templates::capsystem::pkg_register WARNING - unable to determine base folder for package '$pkg' which is attempting to register with punk::cap as a provider of '$capname' capability"
flush stderr
return 0

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

@ -1181,7 +1181,7 @@ tcl::namespace::eval punk::char {
}
puts "ok.. loading"
set fd [open $file r]
fconfigure $fd -translation binary
chan configure $fd -translation binary
set data [read $fd]
close $fd
set block_count 0

2
src/bootsupport/modules/punk/config-0.1.tm

@ -32,7 +32,7 @@ tcl::namespace::eval punk::config {
if {$exename ne ""} {
set exefolder [file dirname $exename]
#default file logs to logs folder at same level as exe if writable, or empty string
set log_folder [file normalize $exefolder/../logs]
set log_folder [file normalize $exefolder/../logs] ;#~2ms
#tcl::dict::set startup scriptlib $exefolder/scriptlib
#tcl::dict::set startup apps $exefolder/../../punkapps

6
src/bootsupport/modules/punk/console-0.1.1.tm

@ -777,7 +777,7 @@ namespace eval punk::console {
set extension [lindex [split $waitvar($callid) -] 1]
if {$extension eq ""} {
puts "blank extension $waitvar($callid)"
puts "->[set $waitvar($callid]<-"
puts "->[set $waitvar($callid)]<-"
}
puts stderr "get_ansi_response_payload Extending timeout by $extension"
after cancel $timeoutid($callid)
@ -814,7 +814,7 @@ namespace eval punk::console {
#it *might* be ok to restore entire state on an input channel
#(it's not always on all channels - e.g stdout has -winsize which is read-only)
#Safest to only restore what we think we've modified.
fconfigure $input -blocking [dict get $previous_input_state -blocking]
chan configure $input -blocking [dict get $previous_input_state -blocking]
@ -1947,7 +1947,7 @@ namespace eval punk::console {
set was_raw 1
}
puts -nonewline stdout \033\[6n ;flush stdout
fconfigure stdin -blocking 0
chan configure stdin -blocking 0
set info [read stdin 20] ;#
after 1
if {[string first "R" $info] <=0} {

13
src/bootsupport/modules/punk/fileline-0.1.0.tm

@ -158,7 +158,7 @@ namespace eval punk::fileline::class {
#[para] Constructor for textinfo object which represents a chunk or all of a file
#[para] datachunk should be passed with the file data including line-endings as-is for full functionality. ie use something like:
#[example_begin]
# fconfigure $fd -translation binary
# chan configure $fd -translation binary
# set chunkdata [lb]read $fd[rb]]
#or
# set chunkdata [lb]fileutil::cat <filename> -translation binary[rb]
@ -1221,8 +1221,11 @@ namespace eval punk::fileline::class {
#o_linemap
set oldsize [string length $o_chunk]
set newchunk ""
#review - what was the intention here?
puts stderr "regenerate_chunk -warning code incomplete"
dict for {idx lineinfo} $o_linemap {
set
#???
#set
}
@ -1287,7 +1290,7 @@ namespace eval punk::fileline {
if {$opt_file ne ""} {
set filename $opt_file
set fd [open $filename r]
fconfigure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
chan configure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
#Always read encoding in binary - check for bom below and/or apply chosen opt_encoding
set rawchunk [read $fd]
close $fd
@ -1360,7 +1363,7 @@ namespace eval punk::fileline {
set bomenc "binary" ;# utf-8???
set startdata 3
} elseif {$maybe_bom eq "84319533"} {
if {![dict exists [punk::char::page_names_dict gb18030]]} {
if {![dict exists [punk::char::page_names_dict gb18030] gb18030]} {
puts stderr "WARNING - no direct support for GB18030 (chinese) - falling back to cp936/gbk"
set bomenc cp936
} else {
@ -1485,7 +1488,7 @@ namespace eval punk::fileline {
proc file_boundary_display {filename startbyte endbyte chunksize args} {
set fd [open $filename r] ;#use default error if file not readable
fconfigure $fd -translation binary
chan configure $fd -translation binary
set rawfiledata [read $fd]
close $fd
set textobj [class::textinfo new $rawfiledata]

30
src/bootsupport/modules/punk/lib-0.1.1.tm

@ -477,7 +477,7 @@ namespace eval punk::lib {
set asegs [split [string map {:: \uFFFF} $abs] \uFFFF]
set acount [llength $asegs]
#puts "alias $abs acount:$acount asegs:$asegs segcount:$segcount segments: $segments"
if {[expr {$acount - 1}] == $segcount} {
if {($acount - 1) == $segcount} {
if {[lrange $asegs 0 end-1] eq $segments} {
if {[string match $glob [lindex $asegs end]]} {
#report this alias in the current namespace - even though there may be no matching command
@ -2760,7 +2760,7 @@ namespace eval punk::lib {
#[example_end]
puts stdout $question
flush stdout
set stdin_state [fconfigure stdin]
set stdin_state [chan configure stdin]
if {[catch {
package require punk::console
set console_raw [tsv::get console is_raw]
@ -2769,7 +2769,7 @@ namespace eval punk::lib {
set console_raw 0
}
try {
fconfigure stdin -blocking 1
chan configure stdin -blocking 1
if {$console_raw} {
punk::console::disableRaw
set answer [gets stdin]
@ -2778,7 +2778,7 @@ namespace eval punk::lib {
set answer [gets stdin]
}
} finally {
fconfigure stdin -blocking [tcl::dict::get $stdin_state -blocking]
chan configure stdin -blocking [tcl::dict::get $stdin_state -blocking]
}
return $answer
}
@ -3629,8 +3629,8 @@ namespace eval punk::lib {
set s2 [expr {$s2 + (($time-$average)*($time-$average) / ($iters-1))}]
}
set sigma [expr {int(sqrt($s2))}]
set average [expr int($average)]
set sigma [expr {int(sqrt($s2))}]
set average [expr {int($average)}]
return "$average +/- $sigma microseconds per iteration"
}
@ -3820,10 +3820,10 @@ namespace eval punk::lib {
# First, extract right hand part of number, up to and including decimal point
set point [string last "." $number];
if {$point >= 0} {
set PostDecimal [string range $number [expr $point + 1] end];
set PostDecimal [string range $number $point+1 end];
set PostDecimalP 1;
} else {
set point [expr [string length $number] + 1]
set point [expr {[string length $number] + 1}]
set PostDecimal "";
set PostDecimalP 0;
}
@ -3834,16 +3834,16 @@ namespace eval punk::lib {
incr ind;
}
set FirstNonSpace $ind;
set LastSpace [expr $FirstNonSpace - 1];
set LastSpace [expr {$FirstNonSpace - 1}];
set LeadingSpaces [string range $number 0 $LastSpace];
# Now extract the non-fractional part of the number, omitting leading spaces.
set MainNumber [string range $number $FirstNonSpace [expr $point -1]];
set MainNumber [string range $number $FirstNonSpace $point-1];
# Insert commas into the non-fractional part.
set Length [string length $MainNumber];
set Phase [expr $Length % $GroupSize]
set PhaseMinusOne [expr $Phase -1];
set Phase [expr {$Length % $GroupSize}]
set PhaseMinusOne [expr {$Phase -1}];
set DelimitedMain "";
#First we deal with the extra stuff.
@ -3851,7 +3851,7 @@ namespace eval punk::lib {
append DelimitedMain [string range $MainNumber 0 $PhaseMinusOne];
}
set FirstInGroup $Phase;
set LastInGroup [expr $FirstInGroup + $GroupSize -1];
set LastInGroup [expr {$FirstInGroup + $GroupSize -1}];
while {$LastInGroup < $Length} {
if {$FirstInGroup > 0} {
append DelimitedMain $delim;
@ -3958,8 +3958,12 @@ tcl::namespace::eval punk::lib::flatgrid {
}
}
tcl::namespace::eval punk::lib::test {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#todo - way to generate 'internal' docs separately?
#*** !doctools

2
src/bootsupport/modules/punkcheck-0.1.0.tm

@ -86,7 +86,7 @@ namespace eval punkcheck {
set linecount [llength [split $newtdl \n]]
#puts stdout $newtdl
set fd [open $punkcheck_file w]
fconfigure $fd -translation binary
chan configure $fd -translation binary
puts -nonewline $fd $newtdl
close $fd
return [list recordcount [llength $recordlist] linecount $linecount]

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

@ -663,7 +663,7 @@ tcl::namespace::eval textblock {
switch -- $k {
-ansibase_header - -ansibase_body - -ansiborder_header - -ansiborder-body - -ansiborder_footer {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set ansi_codes [list] ;
set ansi_codes [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -1109,7 +1109,7 @@ tcl::namespace::eval textblock {
}
-ansibase {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set col_ansibase_items [list] ;
set col_ansibase_items [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -7852,7 +7852,7 @@ tcl::namespace::eval textblock {
foreach {k v} $optlist {
set k2 [tcl::prefix::match -error "" $optnames $k]
switch -- $k2 {
-etabs - -type - -boxlimits - -boxmap - -joins
-etabs - -type - -boxlimits - -boxmap - -join
- -title - -titlealign - -subtitle - -subtitlealign - -width - -height
- -ansiborder - -ansibase
- -blockalign - -textalign - -ellipsis

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

Binary file not shown.

4
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm

@ -7569,11 +7569,11 @@ namespace eval punk::ansi::colour {
}
foreach c {R G B} {
if {$T($c) < [expr {1.0/6.0}]} {
if {$T($c) < (1.0/6.0)} {
set T($c) [expr {$P+($Q-$P)*6.0*$T($c)}]
} elseif {$T($c) < 0.5} {
set T($c) $Q
} elseif {$T($c) < [expr {2.0/3.0}]} {
} elseif {$T($c) < (2.0/3.0)} {
set T($c) [expr {$P+($Q-$P)*(2.0/3.0-$T($c))*6.0}]
} else {
set T($c) $P

2
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm

@ -95,7 +95,7 @@ namespace eval punk::cap::handlers::templates {
} else {
set tm_exists [file exists $tmfile]
}
if {![file exists $tmfile]} {
if {!$tm_exists} {
puts stderr "punk::cap::handlers::templates::capsystem::pkg_register WARNING - unable to determine base folder for package '$pkg' which is attempting to register with punk::cap as a provider of '$capname' capability"
flush stderr
return 0

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

@ -1181,7 +1181,7 @@ tcl::namespace::eval punk::char {
}
puts "ok.. loading"
set fd [open $file r]
fconfigure $fd -translation binary
chan configure $fd -translation binary
set data [read $fd]
close $fd
set block_count 0

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

@ -32,7 +32,7 @@ tcl::namespace::eval punk::config {
if {$exename ne ""} {
set exefolder [file dirname $exename]
#default file logs to logs folder at same level as exe if writable, or empty string
set log_folder [file normalize $exefolder/../logs]
set log_folder [file normalize $exefolder/../logs] ;#~2ms
#tcl::dict::set startup scriptlib $exefolder/scriptlib
#tcl::dict::set startup apps $exefolder/../../punkapps

6
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm

@ -777,7 +777,7 @@ namespace eval punk::console {
set extension [lindex [split $waitvar($callid) -] 1]
if {$extension eq ""} {
puts "blank extension $waitvar($callid)"
puts "->[set $waitvar($callid]<-"
puts "->[set $waitvar($callid)]<-"
}
puts stderr "get_ansi_response_payload Extending timeout by $extension"
after cancel $timeoutid($callid)
@ -814,7 +814,7 @@ namespace eval punk::console {
#it *might* be ok to restore entire state on an input channel
#(it's not always on all channels - e.g stdout has -winsize which is read-only)
#Safest to only restore what we think we've modified.
fconfigure $input -blocking [dict get $previous_input_state -blocking]
chan configure $input -blocking [dict get $previous_input_state -blocking]
@ -1947,7 +1947,7 @@ namespace eval punk::console {
set was_raw 1
}
puts -nonewline stdout \033\[6n ;flush stdout
fconfigure stdin -blocking 0
chan configure stdin -blocking 0
set info [read stdin 20] ;#
after 1
if {[string first "R" $info] <=0} {

13
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm

@ -158,7 +158,7 @@ namespace eval punk::fileline::class {
#[para] Constructor for textinfo object which represents a chunk or all of a file
#[para] datachunk should be passed with the file data including line-endings as-is for full functionality. ie use something like:
#[example_begin]
# fconfigure $fd -translation binary
# chan configure $fd -translation binary
# set chunkdata [lb]read $fd[rb]]
#or
# set chunkdata [lb]fileutil::cat <filename> -translation binary[rb]
@ -1221,8 +1221,11 @@ namespace eval punk::fileline::class {
#o_linemap
set oldsize [string length $o_chunk]
set newchunk ""
#review - what was the intention here?
puts stderr "regenerate_chunk -warning code incomplete"
dict for {idx lineinfo} $o_linemap {
set
#???
#set
}
@ -1287,7 +1290,7 @@ namespace eval punk::fileline {
if {$opt_file ne ""} {
set filename $opt_file
set fd [open $filename r]
fconfigure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
chan configure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
#Always read encoding in binary - check for bom below and/or apply chosen opt_encoding
set rawchunk [read $fd]
close $fd
@ -1360,7 +1363,7 @@ namespace eval punk::fileline {
set bomenc "binary" ;# utf-8???
set startdata 3
} elseif {$maybe_bom eq "84319533"} {
if {![dict exists [punk::char::page_names_dict gb18030]]} {
if {![dict exists [punk::char::page_names_dict gb18030] gb18030]} {
puts stderr "WARNING - no direct support for GB18030 (chinese) - falling back to cp936/gbk"
set bomenc cp936
} else {
@ -1485,7 +1488,7 @@ namespace eval punk::fileline {
proc file_boundary_display {filename startbyte endbyte chunksize args} {
set fd [open $filename r] ;#use default error if file not readable
fconfigure $fd -translation binary
chan configure $fd -translation binary
set rawfiledata [read $fd]
close $fd
set textobj [class::textinfo new $rawfiledata]

30
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm

@ -477,7 +477,7 @@ namespace eval punk::lib {
set asegs [split [string map {:: \uFFFF} $abs] \uFFFF]
set acount [llength $asegs]
#puts "alias $abs acount:$acount asegs:$asegs segcount:$segcount segments: $segments"
if {[expr {$acount - 1}] == $segcount} {
if {($acount - 1) == $segcount} {
if {[lrange $asegs 0 end-1] eq $segments} {
if {[string match $glob [lindex $asegs end]]} {
#report this alias in the current namespace - even though there may be no matching command
@ -2760,7 +2760,7 @@ namespace eval punk::lib {
#[example_end]
puts stdout $question
flush stdout
set stdin_state [fconfigure stdin]
set stdin_state [chan configure stdin]
if {[catch {
package require punk::console
set console_raw [tsv::get console is_raw]
@ -2769,7 +2769,7 @@ namespace eval punk::lib {
set console_raw 0
}
try {
fconfigure stdin -blocking 1
chan configure stdin -blocking 1
if {$console_raw} {
punk::console::disableRaw
set answer [gets stdin]
@ -2778,7 +2778,7 @@ namespace eval punk::lib {
set answer [gets stdin]
}
} finally {
fconfigure stdin -blocking [tcl::dict::get $stdin_state -blocking]
chan configure stdin -blocking [tcl::dict::get $stdin_state -blocking]
}
return $answer
}
@ -3629,8 +3629,8 @@ namespace eval punk::lib {
set s2 [expr {$s2 + (($time-$average)*($time-$average) / ($iters-1))}]
}
set sigma [expr {int(sqrt($s2))}]
set average [expr int($average)]
set sigma [expr {int(sqrt($s2))}]
set average [expr {int($average)}]
return "$average +/- $sigma microseconds per iteration"
}
@ -3820,10 +3820,10 @@ namespace eval punk::lib {
# First, extract right hand part of number, up to and including decimal point
set point [string last "." $number];
if {$point >= 0} {
set PostDecimal [string range $number [expr $point + 1] end];
set PostDecimal [string range $number $point+1 end];
set PostDecimalP 1;
} else {
set point [expr [string length $number] + 1]
set point [expr {[string length $number] + 1}]
set PostDecimal "";
set PostDecimalP 0;
}
@ -3834,16 +3834,16 @@ namespace eval punk::lib {
incr ind;
}
set FirstNonSpace $ind;
set LastSpace [expr $FirstNonSpace - 1];
set LastSpace [expr {$FirstNonSpace - 1}];
set LeadingSpaces [string range $number 0 $LastSpace];
# Now extract the non-fractional part of the number, omitting leading spaces.
set MainNumber [string range $number $FirstNonSpace [expr $point -1]];
set MainNumber [string range $number $FirstNonSpace $point-1];
# Insert commas into the non-fractional part.
set Length [string length $MainNumber];
set Phase [expr $Length % $GroupSize]
set PhaseMinusOne [expr $Phase -1];
set Phase [expr {$Length % $GroupSize}]
set PhaseMinusOne [expr {$Phase -1}];
set DelimitedMain "";
#First we deal with the extra stuff.
@ -3851,7 +3851,7 @@ namespace eval punk::lib {
append DelimitedMain [string range $MainNumber 0 $PhaseMinusOne];
}
set FirstInGroup $Phase;
set LastInGroup [expr $FirstInGroup + $GroupSize -1];
set LastInGroup [expr {$FirstInGroup + $GroupSize -1}];
while {$LastInGroup < $Length} {
if {$FirstInGroup > 0} {
append DelimitedMain $delim;
@ -3958,8 +3958,12 @@ tcl::namespace::eval punk::lib::flatgrid {
}
}
tcl::namespace::eval punk::lib::test {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#todo - way to generate 'internal' docs separately?
#*** !doctools

2
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm

@ -86,7 +86,7 @@ namespace eval punkcheck {
set linecount [llength [split $newtdl \n]]
#puts stdout $newtdl
set fd [open $punkcheck_file w]
fconfigure $fd -translation binary
chan configure $fd -translation binary
puts -nonewline $fd $newtdl
close $fd
return [list recordcount [llength $recordlist] linecount $linecount]

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

@ -663,7 +663,7 @@ tcl::namespace::eval textblock {
switch -- $k {
-ansibase_header - -ansibase_body - -ansiborder_header - -ansiborder-body - -ansiborder_footer {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set ansi_codes [list] ;
set ansi_codes [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -1109,7 +1109,7 @@ tcl::namespace::eval textblock {
}
-ansibase {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set col_ansibase_items [list] ;
set col_ansibase_items [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -7852,7 +7852,7 @@ tcl::namespace::eval textblock {
foreach {k v} $optlist {
set k2 [tcl::prefix::match -error "" $optnames $k]
switch -- $k2 {
-etabs - -type - -boxlimits - -boxmap - -joins
-etabs - -type - -boxlimits - -boxmap - -join
- -title - -titlealign - -subtitle - -subtitlealign - -width - -height
- -ansiborder - -ansibase
- -blockalign - -textalign - -ellipsis

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

Binary file not shown.

4
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm

@ -7569,11 +7569,11 @@ namespace eval punk::ansi::colour {
}
foreach c {R G B} {
if {$T($c) < [expr {1.0/6.0}]} {
if {$T($c) < (1.0/6.0)} {
set T($c) [expr {$P+($Q-$P)*6.0*$T($c)}]
} elseif {$T($c) < 0.5} {
set T($c) $Q
} elseif {$T($c) < [expr {2.0/3.0}]} {
} elseif {$T($c) < (2.0/3.0)} {
set T($c) [expr {$P+($Q-$P)*(2.0/3.0-$T($c))*6.0}]
} else {
set T($c) $P

2
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm

@ -95,7 +95,7 @@ namespace eval punk::cap::handlers::templates {
} else {
set tm_exists [file exists $tmfile]
}
if {![file exists $tmfile]} {
if {!$tm_exists} {
puts stderr "punk::cap::handlers::templates::capsystem::pkg_register WARNING - unable to determine base folder for package '$pkg' which is attempting to register with punk::cap as a provider of '$capname' capability"
flush stderr
return 0

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

@ -1181,7 +1181,7 @@ tcl::namespace::eval punk::char {
}
puts "ok.. loading"
set fd [open $file r]
fconfigure $fd -translation binary
chan configure $fd -translation binary
set data [read $fd]
close $fd
set block_count 0

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

@ -32,7 +32,7 @@ tcl::namespace::eval punk::config {
if {$exename ne ""} {
set exefolder [file dirname $exename]
#default file logs to logs folder at same level as exe if writable, or empty string
set log_folder [file normalize $exefolder/../logs]
set log_folder [file normalize $exefolder/../logs] ;#~2ms
#tcl::dict::set startup scriptlib $exefolder/scriptlib
#tcl::dict::set startup apps $exefolder/../../punkapps

6
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm

@ -777,7 +777,7 @@ namespace eval punk::console {
set extension [lindex [split $waitvar($callid) -] 1]
if {$extension eq ""} {
puts "blank extension $waitvar($callid)"
puts "->[set $waitvar($callid]<-"
puts "->[set $waitvar($callid)]<-"
}
puts stderr "get_ansi_response_payload Extending timeout by $extension"
after cancel $timeoutid($callid)
@ -814,7 +814,7 @@ namespace eval punk::console {
#it *might* be ok to restore entire state on an input channel
#(it's not always on all channels - e.g stdout has -winsize which is read-only)
#Safest to only restore what we think we've modified.
fconfigure $input -blocking [dict get $previous_input_state -blocking]
chan configure $input -blocking [dict get $previous_input_state -blocking]
@ -1947,7 +1947,7 @@ namespace eval punk::console {
set was_raw 1
}
puts -nonewline stdout \033\[6n ;flush stdout
fconfigure stdin -blocking 0
chan configure stdin -blocking 0
set info [read stdin 20] ;#
after 1
if {[string first "R" $info] <=0} {

13
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm

@ -158,7 +158,7 @@ namespace eval punk::fileline::class {
#[para] Constructor for textinfo object which represents a chunk or all of a file
#[para] datachunk should be passed with the file data including line-endings as-is for full functionality. ie use something like:
#[example_begin]
# fconfigure $fd -translation binary
# chan configure $fd -translation binary
# set chunkdata [lb]read $fd[rb]]
#or
# set chunkdata [lb]fileutil::cat <filename> -translation binary[rb]
@ -1221,8 +1221,11 @@ namespace eval punk::fileline::class {
#o_linemap
set oldsize [string length $o_chunk]
set newchunk ""
#review - what was the intention here?
puts stderr "regenerate_chunk -warning code incomplete"
dict for {idx lineinfo} $o_linemap {
set
#???
#set
}
@ -1287,7 +1290,7 @@ namespace eval punk::fileline {
if {$opt_file ne ""} {
set filename $opt_file
set fd [open $filename r]
fconfigure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
chan configure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
#Always read encoding in binary - check for bom below and/or apply chosen opt_encoding
set rawchunk [read $fd]
close $fd
@ -1360,7 +1363,7 @@ namespace eval punk::fileline {
set bomenc "binary" ;# utf-8???
set startdata 3
} elseif {$maybe_bom eq "84319533"} {
if {![dict exists [punk::char::page_names_dict gb18030]]} {
if {![dict exists [punk::char::page_names_dict gb18030] gb18030]} {
puts stderr "WARNING - no direct support for GB18030 (chinese) - falling back to cp936/gbk"
set bomenc cp936
} else {
@ -1485,7 +1488,7 @@ namespace eval punk::fileline {
proc file_boundary_display {filename startbyte endbyte chunksize args} {
set fd [open $filename r] ;#use default error if file not readable
fconfigure $fd -translation binary
chan configure $fd -translation binary
set rawfiledata [read $fd]
close $fd
set textobj [class::textinfo new $rawfiledata]

30
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm

@ -477,7 +477,7 @@ namespace eval punk::lib {
set asegs [split [string map {:: \uFFFF} $abs] \uFFFF]
set acount [llength $asegs]
#puts "alias $abs acount:$acount asegs:$asegs segcount:$segcount segments: $segments"
if {[expr {$acount - 1}] == $segcount} {
if {($acount - 1) == $segcount} {
if {[lrange $asegs 0 end-1] eq $segments} {
if {[string match $glob [lindex $asegs end]]} {
#report this alias in the current namespace - even though there may be no matching command
@ -2760,7 +2760,7 @@ namespace eval punk::lib {
#[example_end]
puts stdout $question
flush stdout
set stdin_state [fconfigure stdin]
set stdin_state [chan configure stdin]
if {[catch {
package require punk::console
set console_raw [tsv::get console is_raw]
@ -2769,7 +2769,7 @@ namespace eval punk::lib {
set console_raw 0
}
try {
fconfigure stdin -blocking 1
chan configure stdin -blocking 1
if {$console_raw} {
punk::console::disableRaw
set answer [gets stdin]
@ -2778,7 +2778,7 @@ namespace eval punk::lib {
set answer [gets stdin]
}
} finally {
fconfigure stdin -blocking [tcl::dict::get $stdin_state -blocking]
chan configure stdin -blocking [tcl::dict::get $stdin_state -blocking]
}
return $answer
}
@ -3629,8 +3629,8 @@ namespace eval punk::lib {
set s2 [expr {$s2 + (($time-$average)*($time-$average) / ($iters-1))}]
}
set sigma [expr {int(sqrt($s2))}]
set average [expr int($average)]
set sigma [expr {int(sqrt($s2))}]
set average [expr {int($average)}]
return "$average +/- $sigma microseconds per iteration"
}
@ -3820,10 +3820,10 @@ namespace eval punk::lib {
# First, extract right hand part of number, up to and including decimal point
set point [string last "." $number];
if {$point >= 0} {
set PostDecimal [string range $number [expr $point + 1] end];
set PostDecimal [string range $number $point+1 end];
set PostDecimalP 1;
} else {
set point [expr [string length $number] + 1]
set point [expr {[string length $number] + 1}]
set PostDecimal "";
set PostDecimalP 0;
}
@ -3834,16 +3834,16 @@ namespace eval punk::lib {
incr ind;
}
set FirstNonSpace $ind;
set LastSpace [expr $FirstNonSpace - 1];
set LastSpace [expr {$FirstNonSpace - 1}];
set LeadingSpaces [string range $number 0 $LastSpace];
# Now extract the non-fractional part of the number, omitting leading spaces.
set MainNumber [string range $number $FirstNonSpace [expr $point -1]];
set MainNumber [string range $number $FirstNonSpace $point-1];
# Insert commas into the non-fractional part.
set Length [string length $MainNumber];
set Phase [expr $Length % $GroupSize]
set PhaseMinusOne [expr $Phase -1];
set Phase [expr {$Length % $GroupSize}]
set PhaseMinusOne [expr {$Phase -1}];
set DelimitedMain "";
#First we deal with the extra stuff.
@ -3851,7 +3851,7 @@ namespace eval punk::lib {
append DelimitedMain [string range $MainNumber 0 $PhaseMinusOne];
}
set FirstInGroup $Phase;
set LastInGroup [expr $FirstInGroup + $GroupSize -1];
set LastInGroup [expr {$FirstInGroup + $GroupSize -1}];
while {$LastInGroup < $Length} {
if {$FirstInGroup > 0} {
append DelimitedMain $delim;
@ -3958,8 +3958,12 @@ tcl::namespace::eval punk::lib::flatgrid {
}
}
tcl::namespace::eval punk::lib::test {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#todo - way to generate 'internal' docs separately?
#*** !doctools

2
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm

@ -86,7 +86,7 @@ namespace eval punkcheck {
set linecount [llength [split $newtdl \n]]
#puts stdout $newtdl
set fd [open $punkcheck_file w]
fconfigure $fd -translation binary
chan configure $fd -translation binary
puts -nonewline $fd $newtdl
close $fd
return [list recordcount [llength $recordlist] linecount $linecount]

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

@ -663,7 +663,7 @@ tcl::namespace::eval textblock {
switch -- $k {
-ansibase_header - -ansibase_body - -ansiborder_header - -ansiborder-body - -ansiborder_footer {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set ansi_codes [list] ;
set ansi_codes [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -1109,7 +1109,7 @@ tcl::namespace::eval textblock {
}
-ansibase {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set col_ansibase_items [list] ;
set col_ansibase_items [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -7852,7 +7852,7 @@ tcl::namespace::eval textblock {
foreach {k v} $optlist {
set k2 [tcl::prefix::match -error "" $optnames $k]
switch -- $k2 {
-etabs - -type - -boxlimits - -boxmap - -joins
-etabs - -type - -boxlimits - -boxmap - -join
- -title - -titlealign - -subtitle - -subtitlealign - -width - -height
- -ansiborder - -ansibase
- -blockalign - -textalign - -ellipsis

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

Binary file not shown.

642
src/vfs/_vfscommon.vfs/modules/picalc-0.1.0.tm

@ -0,0 +1,642 @@
# -*- tcl -*-
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt
# module template: shellspy/src/decktemplates/vendor/punk/modules/template_module-0.0.3.tm
#
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem.
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository.
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# (C) 2025
#
# @@ Meta Begin
# Application picalc 0.1.0
# Meta platform tcl
# Meta license MIT
# @@ Meta End
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin shellspy_module_picalc 0 0.1.0]
#[copyright "2025"]
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}]
#[moddesc {-}] [comment {-- Description at end of page heading --}]
#[require picalc]
#[keywords module]
#[description]
#[para] -
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section Overview]
#[para] overview of picalc
#[subsection Concepts]
#[para] -
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Requirements
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[subsection dependencies]
#[para] packages used by picalc
#[list_begin itemized]
package require Tcl 8.6-
package require punk::lib
package require punk::args
#*** !doctools
#[item] [package {Tcl 8.6}]
#[item] [package {punk::lib}]
#[item] [package {punk::args}]
# #package require frobz
# #*** !doctools
# #[item] [package {frobz}]
#*** !doctools
#[list_end]
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section API]
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# oo::class namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#tcl::namespace::eval picalc::class {
#*** !doctools
#[subsection {Namespace picalc::class}]
#[para] class definitions
#if {[tcl::info::commands [tcl::namespace::current]::interface_sample1] eq ""} {
#*** !doctools
#[list_begin enumerated]
# oo::class create interface_sample1 {
# #*** !doctools
# #[enum] CLASS [class interface_sample1]
# #[list_begin definitions]
# method test {arg1} {
# #*** !doctools
# #[call class::interface_sample1 [method test] [arg arg1]]
# #[para] test method
# puts "test: $arg1"
# }
# #*** !doctools
# #[list_end] [comment {-- end definitions interface_sample1}]
# }
#*** !doctools
#[list_end] [comment {--- end class enumeration ---}]
#}
#}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval picalc {
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Base namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[subsection {Namespace picalc}]
#[para] Core API functions for picalc
#[list_begin definitions]
variable PUNKARGS
#proc sample1 {p1 n args} {
# #*** !doctools
# #[call [fun sample1] [arg p1] [arg n] [opt {option value...}]]
# #[para]Description of sample1
# #[para] Arguments:
# # [list_begin arguments]
# # [arg_def tring p1] A description of string argument p1.
# # [arg_def integer n] A description of integer argument n.
# # [list_end]
# return "ok"
#}
#a known value for the _test functions
variable pifrac [string map {" " ""} "1415926535 8979323846 2643383279 5028841971"]
#10k approx 2s
#20k approx 18s
#100k approx 1519s (25+minutes)
proc fast {dp} {
package require math::bigfloat
#math::bigfloat calculates using 'precision'
# --------------
#Faster for large values - but timing variable on same values!!
#After running on large values becomes - slower than calc and spigot for small values (somewhere around <1k)
catch {unset ::math::bigfloat::_pi0}
#this is due to the caching mechanism - for the purposes of comparison/testing and consistent results, we'll 'wreck' that caching here.
# --------------
set answer [math::bigfloat::tostr [math::bigfloat::pi [expr {$dp+3}]]] ;#we need to calculate with +3 precision to avoid rounding at the tail of chosen number of dp in all cases
return [string range $answer 0 end-2]
}
proc fast_test {max} {
variable pifrac
set pi 3.$pifrac
set result ""
set k 0
while {$k <= $max} {
set answer [fast $k]
set lcp [punk::lib::longestCommonPrefix [list $pi $answer]]
set lcplen [string length $lcp]
set tail [string range $answer $lcplen end]
set greenanswer [a+ green]$lcp[a]$tail
package require overtype ;#can't use 'format' for ANSI coloured strings
set col1 [string repeat " " [expr {$max + 3}]]
append result "[format %3s $k]-> [overtype::left $col1 $greenanswer]" \n
incr k
}
return $result
}
lappend PUNKARGS [list {
@id -id ::picalc::spigot
@cmd -name picalc::spigot -help\
"Return digits of pi to dp decimal places.
'classic' Rabinowitz and Wagon spigot algorithm.
https://www.cs.williams.edu/~heeringa/classes/cs135/s15/readings/spigot.pdf
relatively straight port from pascal algorithm
This algorithm for generating digits of pi uses a long list relative to the number of required digits
Performance doesn't seem to be spectacular,
(seems to be around 7-8secs for 1000 digits
93s for 10K digits)
The 'fast' (math::bigfloat based) function is much faster,
but also becomes extremely slow at a few 10's of thousands of digits.
"
@leaders -min 0 -max 0
@opts
-channel -choices {none stdout stderr} -default none -choicerestricted 0 -choicelabels {
none\
" Return as result string"
}
@values -min 0 -max 1
dp -type int -default 32 -help\
"Number of decimal places
(final digit is not rounded)"
}]
# 5K approx 25s
#10K approx 93s
proc spigot_emit {c chan countvar dp} {
upvar $countvar count
incr count
if {$chan eq "none"} {
upvar result r
append r $c ;#leave chars beyond dp to be trimmed by caller
return
} else {
if {$count > 2} {
if {$count <= $dp + 2} {
puts -nonewline $chan $c
}
} else {
if {$count == 1} {
puts -nonewline $chan 3
} else {
puts -nonewline $chan "."
}
}
}
}
proc spigot {args} {
set argd [punk::args::parse $args withid ::picalc::spigot]
lassign [dict values $argd] leaders opts values received
set dp [dict get $values dp]
set channel [dict get $opts -channel]
if {$dp < 1} {return 3}
set n [expr {$dp +2}] ;#dp +1 can get rounding errors
set len [expr {(10 * $n) / 3}]
set a [lrepeat [expr {$len+1}] 2]
set nines 0
set predigit 0
set result ""
set countvar 0
if {$channel eq "none"} {
set dpextra 2
} else {
set dpextra 2
}
for {set j 1} {$j <= $len} {incr j} {
set q 0
for {set i $len} {$i > 0} {incr i -1} {
set ai [lindex $a $i]
set x [expr {(10 * $ai) + ($q * $i)}]
lset a $i [expr {$x % (2*$i-1)}]
set q [expr {$x / (2*$i-1)}]
}
lset a 1 [expr {$q % 10}]
set q [expr {$q / 10}]
if {$q == 9} {
incr nines
} else {
if {$q == 10} {
#append result [expr {$predigit + 1}]
spigot_emit [expr {$predigit + 1}] $channel countvar $dp
if {$countvar == $dp +$dpextra} {
break
}
for {set k 1} {$k <= $nines} {incr k} {
#append result 0
spigot_emit 0 $channel countvar $dp
if {$countvar == $dp +$dpextra} {
break
}
}
if {$countvar == $dp +$dpextra} {
break
}
set predigit 0
set nines 0
} else {
#append result $predigit
spigot_emit $predigit $channel countvar $dp
if {$countvar == $dp +$dpextra} {
#+2 for leading 03
break
}
set predigit $q
if {$nines != 0} {
for {set k 1} {$k <= $nines} {incr k} {
#append result 9
spigot_emit 9 $channel countvar $dp
if {$countvar == $dp +$dpextra} {
break
}
}
if {$countvar == $dp +$dpextra} {
break
}
set nines 0
}
}
}
}
#append result $predigit
spigot_emit $predigit $channel countvar $dp
#eg result 0314159
if {$channel eq "none"} {
set result 3.[string range $result 2 $dp+1] ;#always trim to dp+1 (= $dp+2-1) - longer answer can have erroneous digits
#set result 3.[string range $result 2 end]
return $result
} else {
flush $channel
#review
return "emitted $countvar chars to channel $channel"
}
}
proc spigot_test {max} {
variable pifrac
set pi 3.$pifrac
set result ""
set k 0
while {$k <= $max} {
set answer [spigot $k]
set lcp [punk::lib::longestCommonPrefix [list $pi $answer]]
set lcplen [string length $lcp]
set tail [string range $answer $lcplen end]
set greenanswer [a+ green]$lcp[a]$tail
package require overtype ;#can't use 'format' for ANSI coloured strings
set col1 [string repeat " " [expr {$max + 3}]]
append result "[format %3s $k]-> [overtype::left $col1 $greenanswer]" \n
incr k
}
return $result
}
#def f(n):
# numerator, denominator = 1, 1
# # i/(2i + 1) = n/(2n + 1), ..., 3/7, 2/5, 1/3
# for i in range(n, 0, -1):
# # multiply by i/(2i + 1)
# numerator *= i
# denominator *= 2 * i + 1
# # add 1 (p/q -> (p + q)/q = p/q + q/q = p/q + 1)
# numerator += denominator
# return 2 * numerator, denominator
#for n in range(20):
# p, q = f(n)
# print(Fraction(p, q))
#an approx of pi that rapidly creates a fraction too big to calculate with standard Tcl doubles..
proc fraction {dp} {
if {$dp < 1} {return 3}
#determine an n big enough to give dp valid digits
set n [expr {$dp +1}]
set n [expr {(10 * $n) / 3}]
return [fraction_iteration $n]
}
# 5k approx 27s
# 10k approx 127s
proc calc {dp} {
if {$dp < 1} {return 3}
set n [expr {$dp +1}]
set n [expr {(10 * $n) / 3}]
package require math::bigfloat
lassign [fraction_iteration $n] a b
set bigfloat [math::bigfloat::div [math::bigfloat::int2float $a] [math::bigfloat::int2float $b]]
set answer [math::bigfloat::tostr $bigfloat]
#10*$d/3 == $n
#set trustdigits [expr {(3*$n)/10}] ;#??
return [string range $answer 0 $dp+1] ;#= +2-1
return $answer
}
proc calc_test {max} {
variable pifrac
set pi 3.$pifrac
set k 0
set result ""
set last_lcplen 0
set got ""
while {$k <= $max} {
set answer [calc $k]
set lcp [punk::lib::longestCommonPrefix [list $pi $answer]]
set lcplen [string length $lcp]
if {$lcplen > $last_lcplen} {
set last_lcplen $lcplen
set got [string index $lcp end]
set c red
} else {
set c yellow
}
set tail [string range $answer $lcplen end]
set greenanswer [a+ green]$lcp[a]$tail
package require overtype
set col1 [string repeat " " [expr {$max + 3}]]
append result "[overtype::left " " [a+ $c $got]] [format %3s $k]-> [overtype::left $col1 $greenanswer]" \n
incr k
}
return $result
}
proc fraction_iteration {n} {
set numerator 1; set denominator 1
for {set i $n} {$i > 0} {incr i -1} {
set numerator [expr {$numerator * $i}]
set denominator [expr {$denominator * (2 * $i + 1)}]
incr numerator $denominator
}
return [list [expr {$numerator * 2}] $denominator]
}
proc fraction_iteration_test {max} {
variable pifrac
set pi 3.$pifrac
set k 0
set result ""
set last_lcplen 0
set got ""
package require math::bigfloat
while {$k <= $max} {
set s [fraction_iteration $k]
lassign $s a b
#set answer [expr {$a / double($b)}] ;limited range
set bigfloat [math::bigfloat::div [math::bigfloat::int2float $a] [math::bigfloat::int2float $b]]
set answer [math::bigfloat::tostr $bigfloat]
set lcp [punk::lib::longestCommonPrefix [list $pi $answer]]
set lcplen [string length $lcp]
if {$lcplen > $last_lcplen} {
set last_lcplen $lcplen
set got [string index $lcp end]
set c red
} else {
set c yellow
}
set tail [string range $answer $lcplen end]
set greenanswer [a+ green]$lcp[a]$tail
#math::numtheory::gcd
#set gcd [punk::lib::gcd {*}$s]
#if {$gcd > 1} {
# set a [expr {$a/$gcd}]
# set b [expr {$b/$gcd}]
#}
set ax [string map [list $got [a+ $c]$got[a]] $a]
set bx [string map [list $got [a+ $c]$got[a]] $b]
set m [expr {$a % $b}]
set mx [string map [list $got [a+ $c]$got[a]] $m]
package require overtype
set sp40 [string repeat " " 40]
set sp60 [string repeat " " 60]
append result "[format %1s $got] [format %3s $k]-> [overtype::left $sp40 $greenanswer] [overtype::left $sp60 $ax] [overtype::left $sp60 $bx] [overtype::left $sp60 $mx]" \n
incr k
}
return $result
}
#an experiment
proc slow_approx {{m 1000}} {
set pi 0
set d [expr {1.0}]
for {set i 1} {$i <= $m} {incr i} {
set a [expr {2 * ($i % 2) - 1}]
set pi [expr {$pi + ($a * 4 / $d)}]
set d [expr {$d + 2.0}]
}
return $pi
}
#*** !doctools
#[list_end] [comment {--- end definitions namespace picalc ---}]
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Secondary API namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval picalc::lib {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
tcl::namespace::path [tcl::namespace::parent]
#*** !doctools
#[subsection {Namespace picalc::lib}]
#[para] Secondary functions that are part of the API
#[list_begin definitions]
#proc utility1 {p1 args} {
# #*** !doctools
# #[call lib::[fun utility1] [arg p1] [opt {?option value...?}]]
# #[para]Description of utility1
# return 1
#}
#*** !doctools
#[list_end] [comment {--- end definitions namespace picalc::lib ---}]
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section Internal]
#tcl::namespace::eval picalc::system {
#*** !doctools
#[subsection {Namespace picalc::system}]
#[para] Internal functions that are not part of the API
#}
# == === === === === === === === === === === === === === ===
# Sample 'about' function with punk::args documentation
# == === === === === === === === === === === === === === ===
tcl::namespace::eval picalc {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
variable PUNKARGS
variable PUNKARGS_aliases
lappend PUNKARGS [list {
@id -id "(package)picalc"
@package -name "picalc" -help\
"Package
Description"
}]
namespace eval argdoc {
#namespace for custom argument documentation
proc package_name {} {
return picalc
}
proc about_topics {} {
#info commands results are returned in an arbitrary order (like array keys)
set topic_funs [info commands [namespace current]::get_topic_*]
set about_topics [list]
foreach f $topic_funs {
set tail [namespace tail $f]
lappend about_topics [string range $tail [string length get_topic_] end]
}
#Adjust this function or 'default_topics' if a different order is required
return [lsort $about_topics]
}
proc default_topics {} {return [list Description *]}
# -------------------------------------------------------------
# get_topic_ functions add more to auto-include in about topics
# -------------------------------------------------------------
proc get_topic_Description {} {
punk::args::lib::tstr [string trim {
package picalc
experiments in calculating pi in Tcl
} \n]
}
proc get_topic_License {} {
return "MIT"
}
proc get_topic_Version {} {
return "$::picalc::version"
}
proc get_topic_Contributors {} {
set authors {<unspecified>}
set contributors ""
foreach a $authors {
append contributors $a \n
}
if {[string index $contributors end] eq "\n"} {
set contributors [string range $contributors 0 end-1]
}
return $contributors
}
proc get_topic_notes {} {
punk::args::lib::tstr -return string {
A playground for evaluating performance and testing methods to calculate
the digits pi in Tcl.
A precalculated value of enough precision for almost any
usecase is available at $::math::constants::pi after loading
the math::constants package.
Note that this package is focused on calculating the digits of pi so
there is no rounding of the final digit.
For large values of pi using the mathematical concept of 'precision'
rather than decimal places - consider math::bigfloat::pi
}
}
# -------------------------------------------------------------
}
# we re-use the argument definition from punk::args::standard_about and override some items
set overrides [dict create]
dict set overrides @id -id "::picalc::about"
dict set overrides @cmd -name "picalc::about"
dict set overrides @cmd -help [string trim [punk::args::lib::tstr {
Experiments in calculating the digits of pi
}] \n]
dict set overrides topic -choices [list {*}[picalc::argdoc::about_topics] *]
dict set overrides topic -choicerestricted 1
dict set overrides topic -default [picalc::argdoc::default_topics] ;#if -default is present 'topic' will always appear in parsed 'values' dict
set newdef [punk::args::resolved_def -antiglobs -package_about_namespace -override $overrides ::punk::args::package::standard_about *]
lappend PUNKARGS [list $newdef]
proc about {args} {
package require punk::args
#standard_about accepts additional choices for topic - but we need to normalize any abbreviations to full topic name before passing on
set argd [punk::args::parse $args withid ::picalc::about]
lassign [dict values $argd] _leaders opts values _received
punk::args::package::standard_about -package_about_namespace ::picalc::argdoc {*}$opts {*}[dict get $values topic]
}
}
# end of sample 'about' function
# == === === === === === === === === === === === === === ===
# -----------------------------------------------------------------------------
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked
# -----------------------------------------------------------------------------
# variable PUNKARGS
# variable PUNKARGS_aliases
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::picalc
}
# -----------------------------------------------------------------------------
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide picalc [tcl::namespace::eval picalc {
variable pkg picalc
variable version
set version 0.1.0
}]
return
#*** !doctools
#[manpage_end]

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

@ -1234,7 +1234,7 @@ namespace eval punk {
break
}
#leave the - from the end- as part of the offset
set offset [expr $endspec] ;#don't brace!
set offset [expr $endspec] ;#don't brace! (consider: set x --34;puts expr $j;puts expr {$j} )
if {$do_bounds_check && ($offset > 0 || abs($offset) >= $len)} {
set action ?mismatch-list-index-out-of-range
break
@ -1583,7 +1583,7 @@ namespace eval punk {
}
%# {
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%# not string length is not supported"
}
#string length - REVIEW -
@ -1595,7 +1595,7 @@ namespace eval punk {
%%# {
#experimental
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%%# not string length is not supported"
}
#string length - REVIEW -
@ -1606,7 +1606,7 @@ namespace eval punk {
}
%str {
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%str - not string-get is not supported"
}
lappend INDEX_OPERATIONS string-get
@ -1617,7 +1617,7 @@ namespace eval punk {
%sp {
#experimental
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%sp - not string-space is not supported"
}
lappend INDEX_OPERATIONS string-space
@ -1628,7 +1628,7 @@ namespace eval punk {
%empty {
#experimental
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%empty - not string-empty is not supported"
}
lappend INDEX_OPERATIONS string-empty
@ -1638,7 +1638,7 @@ namespace eval punk {
}
@words {
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%words - not list-words-from-string is not supported"
}
lappend INDEX_OPERATIONS list-words-from-string
@ -1650,7 +1650,7 @@ namespace eval punk {
#experimental - leading character based on result not input(?)
#input type is string - but output is list
set active_key_type "list"
if $get_not {
if {$get_not} {
error "!%chars - not list-chars-from-string is not supported"
}
lappend INDEX_OPERATIONS list-from_chars
@ -1662,7 +1662,7 @@ namespace eval punk {
#experimental - flatten one level of list
#join without arg - output is list
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!@join - not list-join-list is not supported"
}
lappend INDEX_OPERATIONS list-join-list
@ -1674,7 +1674,7 @@ namespace eval punk {
#experimental
#input type is list - but output is string
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%join - not string-join-list is not supported"
}
lappend INDEX_OPERATIONS string-join-list
@ -1684,7 +1684,7 @@ namespace eval punk {
}
%ansiview {
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%# not string-ansiview is not supported"
}
lappend INDEX_OPERATIONS string-ansiview
@ -1694,7 +1694,7 @@ namespace eval punk {
}
%ansiviewstyle {
set active_key_type "string"
if $get_not {
if {$get_not} {
error "!%# not string-ansiviewstyle is not supported"
}
lappend INDEX_OPERATIONS string-ansiviewstyle
@ -3690,7 +3690,8 @@ namespace eval punk {
#todo - some way to restrict mismatch info to simple "mismatch" and avoid overhead of verbose message
#e.g for within pipeswitch block where mismatches are expected and the reasons are less important than moving on quickly
set vidx 0
set mismatches [lmap m $match_state v $var_names {expr {$m == 0} ? {[list mismatch $v]} : {[list match $v]}}]
#set mismatches [lmap m $match_state v $var_names {expr {$m == 0} ? {[list mismatch $v]} : {[list match $v]}}]
set mismatches [lmap m $match_state v $var_names {expr {$m == 0 ? [list mismatch $v] : [list match $v]}}]
set var_display_names [list]
foreach v $var_names {
if {$v eq ""} {
@ -3699,7 +3700,9 @@ namespace eval punk {
lappend var_display_names $v
}
}
set mismatches_display [lmap m $match_state v $var_display_names {expr {$m == 0} ? {$v} : {[expr {$m eq "?"} ? {"?[string repeat { } [expr [string length $v] -1]]"} : {[string repeat " " [string length $v]]} ]}}]
#REVIEW 2025
#set mismatches_display [lmap m $match_state v $var_display_names {expr {$m == 0} ? {$v} : {[expr {$m eq "?"} ? {"?[string repeat { } [expr [string length $v] -1]]"} : {[string repeat " " [string length $v]]} ]}}]
set mismatches_display [lmap m $match_state v $var_display_names {expr {$m == 0 ? $v : [expr {$m eq "?" ? "?[string repeat { } [expr {[string length $v] -1}]]" : [string repeat " " [string length $v]] }]}}]
set msg "\n"
append msg "Unmatched\n"
append msg "Cannot match right hand side to pattern $multivar\n"
@ -5304,6 +5307,8 @@ namespace eval punk {
##if {$body ni $existing} {
set scr [base64::encode -maxlen 0 $cond] ;#will only be decoded if the debug is triggered
#tcllib has some double-substitution going on.. base64 seems easiest and will not impact the speed of normal execution when debug off.
#tclint-disable-next-line
proc ::unknown {args} [string map [list @c@ $cond @b@ $body @scr@ $scr] {
#---------------------------------------
if {![catch {expr {@c@}} res] && $res} {
@ -5368,6 +5373,7 @@ namespace eval punk {
#for var="val {a b c}"
#proc ::punk::val {{v {}}} {tailcall lindex $v}
#proc ::punk::val {{v {}}} {return $v} ;#2023 - approx 2x faster than the tailcall lindex version
proc ::punk::val [list [list v [purelist]]] {return $v}
#----------------
@ -7437,7 +7443,7 @@ namespace eval punk {
foreach v $known_punk {
set c1 [overtype::left $col1 $v]
if {[info exists ::env($v)]} {
set c2 [overtype::left $col2 [set ::env($v)]
set c2 [overtype::left $col2 [set ::env($v)]]
} else {
set c2 [overtype::right $col2 "(NOT SET)"]
}

7672
src/vfs/_vfscommon.vfs/modules/punk-0.1.tm.txt

File diff suppressed because it is too large Load Diff

4
src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm

@ -7569,11 +7569,11 @@ namespace eval punk::ansi::colour {
}
foreach c {R G B} {
if {$T($c) < [expr {1.0/6.0}]} {
if {$T($c) < (1.0/6.0)} {
set T($c) [expr {$P+($Q-$P)*6.0*$T($c)}]
} elseif {$T($c) < 0.5} {
set T($c) $Q
} elseif {$T($c) < [expr {2.0/3.0}]} {
} elseif {$T($c) < (2.0/3.0)} {
set T($c) [expr {$P+($Q-$P)*(2.0/3.0-$T($c))*6.0}]
} else {
set T($c) $P

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

@ -402,7 +402,7 @@ namespace eval punk::basictelnet {
set client_declined "CLI-WONT:[a+ red bold][get_client_option_declined_summary][a]"
set info $server_summary\n$client_summary\n$client_declined\n$info
#set existing_handler [fileevent stdin readable]
#set existing_handler [chan event stdin readable]
set RST "\x1b\[m"
set debug_width 80
@ -412,12 +412,12 @@ namespace eval punk::basictelnet {
#puts -nonewline [punk::ansi::cursor_off]
#use non cursorsave version - slower - but less likely to interfere with cursor operations in data
set existing_input_handler [fileevent $inputchannel readable] ;#stdin
fileevent $inputchannel readable {}
set existing_input_handler [chan event $inputchannel readable] ;#stdin
chan event $inputchannel readable {}
if {[string length $outputchannel]} {
set existing_output_handler [fileevent $outputchannel readable] ;#sock
fileevent $outputchannel readable {}
set existing_output_handler [chan event $outputchannel readable] ;#sock
chan event $outputchannel readable {}
}
if {[catch {
@ -434,9 +434,9 @@ namespace eval punk::basictelnet {
#todo - try? finally?
set writing_debug_frame 0
fileevent $inputchannel readable $existing_input_handler
chan event $inputchannel readable $existing_input_handler
if {[string length $outputchannel]} {
fileevent $outputchannel readable $existing_output_handler
chan event $outputchannel readable $existing_output_handler
}
return
}
@ -529,13 +529,13 @@ namespace eval punk::basictelnet {
#todo - allow telnet with channels other than stdin/stdout - and multiple sessions - per session option_states
reset_option_states
set sock [socket $server $port]
#fconfigure $sock -buffering none -blocking 0 -encoding binary -translation crlf -eofchar {}
#fconfigure $sock -buffering none -blocking 0 -encoding binary -translation binary -eofchar {}
fconfigure $sock -buffering none -blocking 0 -encoding iso8859-1 -translation binary -eofchar {}
fconfigure stdout -buffering none
fileevent $sock readable [list [namespace current]::fromServer $sock]
#chan configure $sock -buffering none -blocking 0 -encoding binary -translation crlf -eofchar {}
#chan configure $sock -buffering none -blocking 0 -encoding binary -translation binary -eofchar {}
chan configure $sock -buffering none -blocking 0 -encoding iso8859-1 -translation binary -eofchar {}
chan configure stdout -buffering none
chan event $sock readable [list [namespace current]::fromServer $sock]
chan configure stdin -blocking 0
fileevent stdin readable [list [namespace current]::toServer $sock]
chan event stdin readable [list [namespace current]::toServer $sock]
variable closed
vwait ::punk::basictelnet::closed($sock)
unset closed($sock)
@ -568,7 +568,7 @@ namespace eval punk::basictelnet {
set input_chunks_waiting(stdin) [lrange $input_chunks_waiting(stdin) 1 end]
}
fileevent stdin readable {}
chan event stdin readable {}
if {$nextwaiting eq ""} {
set chunk [read stdin]
} else {
@ -616,13 +616,13 @@ namespace eval punk::basictelnet {
#Re-enable channel read handler only if no waiting chunks - must process in order
##################################################################################
if {![llength $input_chunks_waiting(stdin)]} {
fileevent stdin readable [list [namespace current]::toServer $sock]
chan event stdin readable [list [namespace current]::toServer $sock]
} else {
#after idle [list [namespace current]::toServer $sock]
tailcall [namespace current]::toServer $sock
}
####################################################
#fileevent stdin readable [list [namespace current]::toServer $sock]
#chan event stdin readable [list [namespace current]::toServer $sock]
} else {
disconnect sock
}
@ -642,7 +642,7 @@ namespace eval punk::basictelnet {
variable encoding_guess
variable debug
variable fromserver_unprocessed
fileevent $sock readable {}
chan event $sock readable {}
variable in_sb
set chunksize 4096 ;#No choice of chunksize can avoid the possibility of splitting a token such as a Telnet protocol command or an ANSI sequence.
#in theory, a split ANSI sequence won't cause a problem - except if we have debug on which could emit a request on stdout (e.g get_cursor_pos)
@ -872,24 +872,24 @@ namespace eval punk::basictelnet {
#after idle [list fileevent $sock readable [list [namespace current]::fromServer $sock]]
#after idle [list chan event $sock readable [list [namespace current]::fromServer $sock]]
if {[string length $fromserver_unprocessed]} {
#review - by throwing to another loop without waiting for readable event - we could spin on same data...?
#after idle [list [namespace current]::fromServer $sock]
fileevent $sock readable [list [namespace current]::fromServer $sock]
chan event $sock readable [list [namespace current]::fromServer $sock]
} else {
fileevent $sock readable [list [namespace current]::fromServer $sock]
chan event $sock readable [list [namespace current]::fromServer $sock]
}
}
proc disconnect {sock} {
variable closed
puts stdout "local disconnect"
catch {fileevent $sock readable {}}
catch {chan event $sock readable {}}
catch {close $sock}
set closed($sock) 1
fileevent stdin readable {}
chan event stdin readable {}
}
proc write string {

2
src/vfs/_vfscommon.vfs/modules/punk/cap/handlers/templates-0.1.0.tm

@ -95,7 +95,7 @@ namespace eval punk::cap::handlers::templates {
} else {
set tm_exists [file exists $tmfile]
}
if {![file exists $tmfile]} {
if {!$tm_exists} {
puts stderr "punk::cap::handlers::templates::capsystem::pkg_register WARNING - unable to determine base folder for package '$pkg' which is attempting to register with punk::cap as a provider of '$capname' capability"
flush stderr
return 0

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

@ -1181,7 +1181,7 @@ tcl::namespace::eval punk::char {
}
puts "ok.. loading"
set fd [open $file r]
fconfigure $fd -translation binary
chan configure $fd -translation binary
set data [read $fd]
close $fd
set block_count 0

2
src/vfs/_vfscommon.vfs/modules/punk/config-0.1.tm

@ -32,7 +32,7 @@ tcl::namespace::eval punk::config {
if {$exename ne ""} {
set exefolder [file dirname $exename]
#default file logs to logs folder at same level as exe if writable, or empty string
set log_folder [file normalize $exefolder/../logs]
set log_folder [file normalize $exefolder/../logs] ;#~2ms
#tcl::dict::set startup scriptlib $exefolder/scriptlib
#tcl::dict::set startup apps $exefolder/../../punkapps

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

@ -777,7 +777,7 @@ namespace eval punk::console {
set extension [lindex [split $waitvar($callid) -] 1]
if {$extension eq ""} {
puts "blank extension $waitvar($callid)"
puts "->[set $waitvar($callid]<-"
puts "->[set $waitvar($callid)]<-"
}
puts stderr "get_ansi_response_payload Extending timeout by $extension"
after cancel $timeoutid($callid)
@ -814,7 +814,7 @@ namespace eval punk::console {
#it *might* be ok to restore entire state on an input channel
#(it's not always on all channels - e.g stdout has -winsize which is read-only)
#Safest to only restore what we think we've modified.
fconfigure $input -blocking [dict get $previous_input_state -blocking]
chan configure $input -blocking [dict get $previous_input_state -blocking]
@ -1947,7 +1947,7 @@ namespace eval punk::console {
set was_raw 1
}
puts -nonewline stdout \033\[6n ;flush stdout
fconfigure stdin -blocking 0
chan configure stdin -blocking 0
set info [read stdin 20] ;#
after 1
if {[string first "R" $info] <=0} {

13
src/vfs/_vfscommon.vfs/modules/punk/fileline-0.1.0.tm

@ -158,7 +158,7 @@ namespace eval punk::fileline::class {
#[para] Constructor for textinfo object which represents a chunk or all of a file
#[para] datachunk should be passed with the file data including line-endings as-is for full functionality. ie use something like:
#[example_begin]
# fconfigure $fd -translation binary
# chan configure $fd -translation binary
# set chunkdata [lb]read $fd[rb]]
#or
# set chunkdata [lb]fileutil::cat <filename> -translation binary[rb]
@ -1221,8 +1221,11 @@ namespace eval punk::fileline::class {
#o_linemap
set oldsize [string length $o_chunk]
set newchunk ""
#review - what was the intention here?
puts stderr "regenerate_chunk -warning code incomplete"
dict for {idx lineinfo} $o_linemap {
set
#???
#set
}
@ -1287,7 +1290,7 @@ namespace eval punk::fileline {
if {$opt_file ne ""} {
set filename $opt_file
set fd [open $filename r]
fconfigure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
chan configure $fd -translation binary -encoding $opt_translation;#should use translation binary to get actual line-endings - but we allow caller to override
#Always read encoding in binary - check for bom below and/or apply chosen opt_encoding
set rawchunk [read $fd]
close $fd
@ -1360,7 +1363,7 @@ namespace eval punk::fileline {
set bomenc "binary" ;# utf-8???
set startdata 3
} elseif {$maybe_bom eq "84319533"} {
if {![dict exists [punk::char::page_names_dict gb18030]]} {
if {![dict exists [punk::char::page_names_dict gb18030] gb18030]} {
puts stderr "WARNING - no direct support for GB18030 (chinese) - falling back to cp936/gbk"
set bomenc cp936
} else {
@ -1485,7 +1488,7 @@ namespace eval punk::fileline {
proc file_boundary_display {filename startbyte endbyte chunksize args} {
set fd [open $filename r] ;#use default error if file not readable
fconfigure $fd -translation binary
chan configure $fd -translation binary
set rawfiledata [read $fd]
close $fd
set textobj [class::textinfo new $rawfiledata]

31
src/vfs/_vfscommon.vfs/modules/punk/icomm-0.1.0.tm

@ -711,7 +711,6 @@ namespace eval ::punk::icomm {
#
# Results:
# None.
proc commConfigure {chan {force 0} args} {
variable comm
@ -876,9 +875,9 @@ namespace eval ::punk::icomm {
![string equal $encoding $comm($chan,encoding)]} {
# This should not be entered yet
set comm($chan,encoding) $encoding
fconfigure $comm($chan,socket) -encoding $encoding
chan configure $comm($chan,socket) -encoding $encoding
foreach {i sock} [array get comm $chan,peers,*] {
fconfigure $sock -encoding $encoding
chan configure $sock -encoding $encoding
}
}
@ -936,10 +935,10 @@ namespace eval ::punk::icomm {
set nport [incr comm(lastport)]
}
set comm($chan,socket) $ret
fconfigure $ret -translation lf -encoding $comm($chan,encoding)
chan configure $ret -translation lf -encoding $comm($chan,encoding)
# If port was 0, system allocated it for us
set comm($chan,port) [lindex [fconfigure $ret -sockname] 2]
set comm($chan,port) [lindex [chan configure $ret -sockname] 2]
return ""
}
@ -1090,8 +1089,8 @@ namespace eval ::punk::icomm {
# coroutines to hide the CSP and properly handle everything
# event based.
fconfigure $fid -blocking 0
fileevent $fid readable [list ::punk::icomm::commIncomingOffered $chan $fid $addr $remport]
chan configure $fid -blocking 0
chan event $fid readable [list ::punk::icomm::commIncomingOffered $chan $fid $addr $remport]
return
}
@ -1112,8 +1111,8 @@ namespace eval ::punk::icomm {
# Protocol version line has been received, disable event handling
# again.
fileevent $fid readable {}
fconfigure $fid -blocking 1
chan event $fid readable {}
chan configure $fid -blocking 1
# a list of offered proto versions is the first word of first line
# remote id is the second word of first line
@ -1144,7 +1143,7 @@ namespace eval ::punk::icomm {
if {[dict exists $chanconf -sockname]} {
# If the remote host addr isn't our local host addr,
# then add it to the remote id.
if {[string equal [lindex [fconfigure $fid -sockname] 0] $addr]} {
if {[string equal [lindex [chan configure $fid -sockname] 0] $addr]} {
set id $remid
} else {
set id [list $remid $addr]
@ -1216,8 +1215,8 @@ namespace eval ::punk::icomm {
set comm($chan,peers,$id) $fid
}
set comm($chan,fids,$fid) $id
fconfigure $fid -translation lf -encoding $comm($chan,encoding) -blocking 0
fileevent $fid readable [list ::punk::icomm::commCollect $chan $fid]
chan configure $fid -translation lf -encoding $comm($chan,encoding) -blocking 0
chan event $fid readable [list ::punk::icomm::commCollect $chan $fid]
}
# ::punk::icomm::commLostConn --
@ -1325,7 +1324,7 @@ namespace eval ::punk::icomm {
# ::punk::icomm::commCollect --
#
# Internal command. Called from the fileevent to read from fid
# Internal command. Called from the chan event to read from fid
# and append to the buffer. This continues until we get a whole
# command, which we then invoke.
#
@ -1344,9 +1343,9 @@ namespace eval ::punk::icomm {
if {[catch {read $fid} nbuf] || [eof $fid]} {
commDebug {puts stderr "<$chan> collect/lost eof $fid = [eof $fid]"}
commDebug {puts stderr "<$chan> collect/lost nbuf = <$nbuf>"}
commDebug {puts stderr "<$chan> collect/lost [fconfigure $fid]"}
commDebug {puts stderr "<$chan> collect/lost [chan configure $fid]"}
fileevent $fid readable {} ;# be safe
chan event $fid readable {} ;# be safe
commLostConn $chan $fid "target application died or connection lost"
return
}
@ -1996,7 +1995,7 @@ proc ::punk::icomm::initlocal {{tcpport 0}} {
if {[string equal macintosh $::tcl_platform(platform)]} {
::punk::icomm::comm new ::punk::icomm::comm -port 0 -local 0 -listen 1
set ::punk::icomm::comm(localhost) \
[lindex [fconfigure $::punk::icomm::comm(::punk::icomm::comm,socket) -sockname] 0]
[lindex [chan configure $::punk::icomm::comm(::punk::icomm::comm,socket) -sockname] 0]
::punk::icomm::comm config -local 1
} else {
::punk::icomm::comm new ::punk::icomm::comm -port 0 -local 1 -listen 1

57
src/vfs/_vfscommon.vfs/modules/punk/imap4-0.9.tm

@ -2744,6 +2744,61 @@ tcl::namespace::eval punk::imap4 {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval punk::imap4::admin {
tcl::namespace::export {[a-zA-Z]*} ;# Convention: export all lowercase
variable PUNKARGS
variable PUNKARGS_aliases
lappend PUNKARGS [list {
@id -id "::punk::imap4::admin::GETQUOTA"
@cmd -name "punk::imap4::::admin::GETQUOTA" -help\
"Get quota information"
@leaders -min 1 -max 1
chan
@opts
@values -min 1 -max 1
mailbox -help\
"e.g user/account.test"
}]
proc GETQUOTA {args} {
set argd [punk::args::parse $args withid ::punk::imap4::admin::GETQUOTA]
lassign [dict values $argd] leaders opts values received
set chan [dict get $leaders chan]
set mailbox [dict get $values mailbox]
punk::imap4::proto::simplecmd $chan GETQUOTA {AUTH SELECT} $mailbox
}
lappend PUNKARGS [list {
@id -id "::punk::imap4::admin::SETQUOTARESOURCE"
@cmd -name "punk::imap4::admin::SETQUOTARESOURCE" -help\
"Set quota for a resource"
@leaders -min 1 -max 1
chan
@opts
-resource -default STORAGE -help\
"This interface only allows setting of a single resource
at a time."
@values -min 2 -max 2
mailbox -help\
"e.g user/account.test"
quota -type integer -minsize 0 -help\
"Number of 1024 Byte blocks
(KB)"
}]
proc SETQUOTARESOURCE {args} {
set argd [punk::args::parse $args withid ::punk::imap4::admin::SETQUOTARESOURCE]
lassign [dict values $argd] leaders opts values received
set chan [dict get $leaders chan]
set mailbox [dict get $values mailbox]
set resource [dict get $opts -resource]
set quota [dict get $values quota]
punk::imap4::proto::simplecmd $chan SETQUOTA {AUTH SELECT} $mailbox "($resource $quota)"
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Secondary API namespace
@ -3294,7 +3349,7 @@ tcl::namespace::eval punk::imap4 {
# variable PUNKARGS_aliases
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::punk::imap4 ::punk::imap4::proto
lappend ::punk::args::register::NAMESPACES ::punk::imap4 ::punk::imap4::admin ::punk::imap4::proto
}
# -----------------------------------------------------------------------------

1
src/vfs/_vfscommon.vfs/modules/punk/jtest.tcl

@ -42,3 +42,4 @@
}
#test
set x blah

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

@ -477,7 +477,7 @@ namespace eval punk::lib {
set asegs [split [string map {:: \uFFFF} $abs] \uFFFF]
set acount [llength $asegs]
#puts "alias $abs acount:$acount asegs:$asegs segcount:$segcount segments: $segments"
if {[expr {$acount - 1}] == $segcount} {
if {($acount - 1) == $segcount} {
if {[lrange $asegs 0 end-1] eq $segments} {
if {[string match $glob [lindex $asegs end]]} {
#report this alias in the current namespace - even though there may be no matching command
@ -2760,7 +2760,7 @@ namespace eval punk::lib {
#[example_end]
puts stdout $question
flush stdout
set stdin_state [fconfigure stdin]
set stdin_state [chan configure stdin]
if {[catch {
package require punk::console
set console_raw [tsv::get console is_raw]
@ -2769,7 +2769,7 @@ namespace eval punk::lib {
set console_raw 0
}
try {
fconfigure stdin -blocking 1
chan configure stdin -blocking 1
if {$console_raw} {
punk::console::disableRaw
set answer [gets stdin]
@ -2778,7 +2778,7 @@ namespace eval punk::lib {
set answer [gets stdin]
}
} finally {
fconfigure stdin -blocking [tcl::dict::get $stdin_state -blocking]
chan configure stdin -blocking [tcl::dict::get $stdin_state -blocking]
}
return $answer
}
@ -3629,8 +3629,8 @@ namespace eval punk::lib {
set s2 [expr {$s2 + (($time-$average)*($time-$average) / ($iters-1))}]
}
set sigma [expr {int(sqrt($s2))}]
set average [expr int($average)]
set sigma [expr {int(sqrt($s2))}]
set average [expr {int($average)}]
return "$average +/- $sigma microseconds per iteration"
}
@ -3820,10 +3820,10 @@ namespace eval punk::lib {
# First, extract right hand part of number, up to and including decimal point
set point [string last "." $number];
if {$point >= 0} {
set PostDecimal [string range $number [expr $point + 1] end];
set PostDecimal [string range $number $point+1 end];
set PostDecimalP 1;
} else {
set point [expr [string length $number] + 1]
set point [expr {[string length $number] + 1}]
set PostDecimal "";
set PostDecimalP 0;
}
@ -3834,16 +3834,16 @@ namespace eval punk::lib {
incr ind;
}
set FirstNonSpace $ind;
set LastSpace [expr $FirstNonSpace - 1];
set LastSpace [expr {$FirstNonSpace - 1}];
set LeadingSpaces [string range $number 0 $LastSpace];
# Now extract the non-fractional part of the number, omitting leading spaces.
set MainNumber [string range $number $FirstNonSpace [expr $point -1]];
set MainNumber [string range $number $FirstNonSpace $point-1];
# Insert commas into the non-fractional part.
set Length [string length $MainNumber];
set Phase [expr $Length % $GroupSize]
set PhaseMinusOne [expr $Phase -1];
set Phase [expr {$Length % $GroupSize}]
set PhaseMinusOne [expr {$Phase -1}];
set DelimitedMain "";
#First we deal with the extra stuff.
@ -3851,7 +3851,7 @@ namespace eval punk::lib {
append DelimitedMain [string range $MainNumber 0 $PhaseMinusOne];
}
set FirstInGroup $Phase;
set LastInGroup [expr $FirstInGroup + $GroupSize -1];
set LastInGroup [expr {$FirstInGroup + $GroupSize -1}];
while {$LastInGroup < $Length} {
if {$FirstInGroup > 0} {
append DelimitedMain $delim;
@ -3958,8 +3958,12 @@ tcl::namespace::eval punk::lib::flatgrid {
}
}
tcl::namespace::eval punk::lib::test {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#todo - way to generate 'internal' docs separately?
#*** !doctools

25
src/vfs/_vfscommon.vfs/modules/punk/repl-0.1.1.tm

@ -127,7 +127,7 @@ namespace eval punk::repl {
puts stderr "\n*> repl background error: '$message'"
#puts stderr "*> [set ::errorInfo]"
puts stderr "*> errorinfo: [dict get $errdict -errorinfo]"
set stdinreader [fileevent stdin readable]
set stdinreader [chan event stdin readable]
if {![string length $stdinreader]} {
puts stderr "*> stdin reader inactive"
} else {
@ -420,14 +420,14 @@ proc repl::start {inchan args} {
puts stderr "-->repl::start active on $inchan $args replthread:[thread::id] codethread:$codethread"
set prompt_config [punk::repl::get_prompt_config]
doprompt "P% "
fileevent $inchan readable [list [namespace current]::repl_handler $inchan $prompt_config]
chan event $inchan readable [list [namespace current]::repl_handler $inchan $prompt_config]
set reading 1
#catch {
# set punk::console::tabwidth [punk::console::get_tabstop_apparent_width]
#}
vwait [namespace current]::done
fileevent $inchan readable {}
chan event $inchan readable {}
#puts stderr "-->start done = $::repl::done"
@ -1044,7 +1044,6 @@ namespace eval punk::repl::class {
incr i
}
}
method add_rendered_chunk {rchunk} {
#split only on lf newlines - movement codes and \b \v \r not expected
@ -1328,7 +1327,7 @@ proc repl::repl_handler {inputchan prompt_config} {
set prompt_reset_flag 0
}
fileevent $inputchan readable {}
chan event $inputchan readable {}
upvar ::punk::console::input_chunks_waiting input_chunks_waiting
#note -inputmode not available in Tcl 8.6 for chan configure!
#According to DKF - -buffering option doesn't affect input channels
@ -1543,14 +1542,14 @@ proc repl::repl_handler {inputchan prompt_config} {
#Re-enable channel read handler only if no waiting chunks - must process in order
##################################################################################
if {![llength $input_chunks_waiting($inputchan)]} {
fileevent $inputchan readable [list ::repl::repl_handler $inputchan $prompt_config]
chan event $inputchan readable [list ::repl::repl_handler $inputchan $prompt_config]
} else {
after idle [list ::repl::repl_handler $inputchan $prompt_config]
}
####################################################
} else {
#repl_handler_checkchannel $inputchan
fileevent $inputchan readable {}
chan event $inputchan readable {}
set reading 0
thread::send -async $::repl::codethread {set ::punk::repl::codethread::running 0}
if {$::tcl_interactive} {
@ -1758,7 +1757,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
# #review
# rputs stderr "->0byte read stdin"
# if {[chan eof $inputchan]} {
# fileevent $inputchan readable {}
# chan event $inputchan readable {}
# set reading 0
# #set running 0
# if {$::tcl_interactive} {
@ -1974,7 +1973,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
rputs stderr "-------------"
rputs stderr "$::errorInfo"
rputs stderr "-------------"
set stdinreader [fileevent $inputchan readable]
set stdinreader [chan event $inputchan readable]
if {![string length $stdinreader]} {
rputs stderr "*> $inputchan reader inactive"
} else {
@ -2186,7 +2185,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
#chan configure stdout -buffering none
#JMN
fileevent $inputchan readable {}
chan event $inputchan readable {}
set reading 0
#don't let unknown use 'args' to convert commandstr to list
#===============================================================================
@ -2530,7 +2529,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
#append commandstr \n
if {$::punk::repl::signal_control_c} {
set ::punk::repl::signal_control_c 0
fileevent $inputchan readable {}
chan event $inputchan readable {}
rputs stderr "* console_control: control-c"
flush stderr
set c [a yellow bold]
@ -2579,7 +2578,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
}
#fileevent $inputchan readable [list repl::repl_handler $inputchan $prompt_config]
#chan event $inputchan readable [list repl::repl_handler $inputchan $prompt_config]
#catch {puts stderr "zend--->[rep $::arglej]"}
@ -2591,7 +2590,7 @@ proc repl::repl_process_data {inputchan chunktype chunk stdinlines prompt_config
rputs stderr "-------------"
rputs stderr "$::errorInfo"
rputs stderr "-------------"
set stdinreader [fileevent $inputchan readable]
set stdinreader [chan event $inputchan readable]
if {![string length $stdinreader]} {
rputs stderr "*> $inputchan reader inactive"
} else {

4
src/vfs/_vfscommon.vfs/modules/punk/sshrun-0.1.0.tm

@ -306,7 +306,7 @@ namespace eval punk::sshrun {
# }]
variable ssh;
system::_verify_connection $host;
fileevent $ssh($host,F) $readable_writable $script;
chan event $ssh($host,F) $readable_writable $script;
}
proc hfconfigure {host args} {
@ -314,7 +314,7 @@ namespace eval punk::sshrun {
# [call hconfigure [arg host] [arg args]]
variable ssh;
system::_verify_connection $host;
eval fconfigure $ssh($host,F) $args;
eval chan configure $ssh($host,F) $args;
}
proc rexec {host script output_varname} {

478
src/vfs/_vfscommon.vfs/modules/punk/timeinterval-0.1.0.tm

@ -16,7 +16,7 @@
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Requirements
##e.g package require frobz
package require punk::args
@ -27,40 +27,65 @@
#
namespace eval punk::timeinterval {
proc clock_scan_interval { seconds delta units } {
# clock_scan_interval formats $seconds to a string for processing by clock scan
# then returns new timestamp in seconds
set stamp [clock format $seconds -format "%Y%m%dT%H%M%S"]
if { $delta < 0 } {
append stamp " - " [expr { abs( $delta ) } ] " " $units
} else {
append stamp " + " $delta " " $units
}
return [clock scan $stamp]
}
#The free-form 'clock scan' is deprecated. It worked in 8.4 to 8.6/8.7 (and earlier?) - but doesn't work in tcl9
#proc clock_scan_interval { seconds delta units } {
# # clock_scan_interval formats $seconds to a string for processing by clock scan
# # then returns new timestamp in seconds
# set stamp [clock format $seconds -format "%Y%m%dT%H%M%S"]
# if { $delta < 0 } {
# append stamp " - " [expr { abs( $delta ) } ] " " $units
# } else {
# append stamp " + " $delta " " $units
# }
# return [clock scan $stamp]
#}
#proc clock_scan_interval { seconds delta units } {
# #8.6+
# clock add $seconds $delta $units
#}
namespace export difference
#wrap in dict
proc difference {s1 s2} {
lassign [interval_ymdhs $s1 $s2] Y M D h m s
return [dict create years $Y months $M days $D hours $h minutes $m seconds $s]
}
proc interval_ymdhs { s1 s2 } {
# interval_ymdhs calculates the interval of time between
# the earliest date and the last date
# by starting to count at the earliest date.
lappend PUNKARGS [list {
@id -id "::punk::timeinterval::difference"
@cmd -name "punk::timeinterval::difference" -help\
"difference calculates the interval of time between
the earliest date and the last date
by starting to count at the earliest date.
It returns a dictionary with keys:
years months days hours minutes seconds"
@opts
-maxunit -default years -choices {years months days hours minutes seconds} -help\
"If maxunit is specified, the resulting dict will still contain all keys,
but keys for larger units will be zero.
e.g when -maxunit is months, years will be zero but months could be
something like 36.
"
-timezone -default "" -help\
"If unspecified, the timezone will be the
current time zone on the system"
@values -min 2 -max 2
s1
s2
}]
proc difference {args} {
set argd [punk::args::parse $args withid ::punk::timeinterval::difference]
lassign [dict values $argd] leaders opts values received
set maxunit [dict get $opts -maxunit]
set timezone [dict get $opts -timezone]
set s1 [dict get $values s1]
set s2 [dict get $values s2]
# This proc has audit features. It will automatically
# attempt to correct and report any discrepancies it finds.
# if s1 and s2 aren't in seconds, convert to seconds.
if { ![string is integer -strict $s1] } {
set s1 [clock scan $s1]
set s1 [clock scan $s1 -timezone $timezone]
}
if { ![string is integer -strict $s2] } {
set s2 [clock scan $s2]
set s2 [clock scan $s2 -timezone $timezone]
}
# postgreSQL intervals determine month length based on earliest date in interval calculations.
@ -77,69 +102,87 @@ namespace eval punk::timeinterval {
# Calculate years from s1_p0 to s2
set y_count 0
set s1_p0 $s1
set s2_y_check $s1_p0
while { $s2_y_check <= $s2 } {
set s1_p1 $s2_y_check
set y $y_count
incr y_count
set s2_y_check [clock_scan_interval $s1_p0 $y_count years]
}
# interval s1_p0 to s1_p1 counted in y years
if {$maxunit eq "years"} {
set s2_y_check $s1_p0
while { $s2_y_check <= $s2 } {
set s1_p1 $s2_y_check
set y $y_count
incr y_count
set s2_y_check [clock add $s1_p0 $y_count years -timezone $timezone]
}
# interval s1_p0 to s1_p1 counted in y years
# is the base offset incremented one too much?
set s2_y_check [clock_scan_interval $s1 $y years]
if { $s2_y_check > $s2 } {
set y [expr { $y - 1 } ]
set s2_y_check [clock_scan_interval $s1 $y years]
}
# increment s1 (s1_p0) forward y years to s1_p1
if { $y == 0 } {
set s1_p1 $s1
# is the base offset incremented one too much?
set s2_y_check [clock add $s1 $y years -timezone $timezone]
if { $s2_y_check > $s2 } {
set y [expr { $y - 1 } ]
set s2_y_check [clock add $s1 $y years -timezone $timezone]
}
# increment s1 (s1_p0) forward y years to s1_p1
if { $y == 0 } {
set s1_p1 $s1
} else {
set s1_p1 [clock add $s1 $y years -timezone $timezone]
}
} else {
set s1_p1 [clock_scan_interval $s1 $y years]
set y 0
set s1_p1 $s1
}
# interval s1 to s1_p1 counted in y years
# Calculate months from s1_p1 to s2
set m_count 0
set s2_m_check $s1_p1
while { $s2_m_check <= $s2 } {
set s1_p2 $s2_m_check
set m $m_count
incr m_count
set s2_m_check [clock_scan_interval $s1_p1 $m_count months]
set s1_p2 $s1_p1 ;#?
set m 0
if {$maxunit in {years months}} {
while { $s2_m_check <= $s2 } {
set s1_p2 $s2_m_check
set m $m_count
incr m_count
set s2_m_check [clock add $s1_p1 $m_count months -timezone $timezone]
}
}
# interval s1_p1 to s1_p2 counted in m months
# Calculate interval s1_p2 to s2 in days
# day_in_sec [expr { 60 * 60 * 24 } ]
# 86400
# Since length of month is not relative, use math.
# Clip any fractional part.
set d [expr { int( ( $s2 - $s1_p2 ) / 86400. ) } ]
# Ideally, this should always be true, but daylight savings..
# so, go backward one day and make hourly steps for last day.
if { $d > 0 } {
incr d -1
set d 0
set s1_p3 $s1_p2
if {$maxunit in {years months days}} {
# Calculate interval s1_p2 to s2 in days
# day_in_sec [expr { 60 * 60 * 24 } ]
# 86400
# Since length of month is not relative, use math.
# Clip any fractional part.
set d [expr { int( ( $s2 - $s1_p2 ) / 86400. ) } ]
# Ideally, this should always be true, but daylight savings..
# so, go backward one day and make hourly steps for last day.
if { $d > 0 } {
incr d -1
}
# Move interval from s1_p2 to s1_p3
set s1_p3 [clock add $s1_p2 $d days -timezone $timezone]
}
# Move interval from s1_p2 to s1_p3
set s1_p3 [clock_scan_interval $s1_p2 $d days]
# s1_p3 is less than a day from s2
# Calculate interval s1_p3 to s2 in hours
# hour_in_sec [expr { 60 * 60 } ]
# 3600
set h [expr { int( ( $s2 - $s1_p3 ) / 3600. ) } ]
# Move interval from s1_p3 to s1_p4
set s1_p4 [clock_scan_interval $s1_p3 $h hours]
# s1_p4 is less than an hour from s2
set h 0
set s1_p4 $s1_p3
if {$maxunit in {years months days hours}} {
# Calculate interval s1_p3 to s2 in hours
# hour_in_sec [expr { 60 * 60 } ]
# 3600
set h [expr { int( ( $s2 - $s1_p3 ) / 3600. ) } ]
# Move interval from s1_p3 to s1_p4
set s1_p4 [clock add $s1_p3 $h hours -timezone $timezone]
# s1_p4 is less than an hour from s2
}
# Sometimes h = 24, yet is already included as a day!
# For example, this case:
# interval_ymdhs 20010410T000000 19570613T000000
# difference 20010410T000000 19570613T000000
# from Age() example in PostgreSQL documentation:
# http://www.postgresql.org/docs/9.1/static/functions-datetime.html
# psql test=# select age(timestamp '2001-04-10', timestamp '1957-06-13');
@ -148,7 +191,7 @@ namespace eval punk::timeinterval {
# 43 years 9 mons 27 days
# (1 row)
# According to LibreCalc, the difference is 16007 days
#puts "s2=s1+16007days? [clock format [clock_scan_interval $s1 16007 days] -format %Y%m%dT%H%M%S]"
#puts "s2=s1+16007days? [clock format [clock add $s1 16007 days] -format %Y%m%dT%H%M%S]"
# ^ this calc is consistent with 16007 days
# So, let's ignore the Postgresql irregularity for now.
# Here's more background:
@ -156,133 +199,143 @@ namespace eval punk::timeinterval {
# http://www.postgresql.org/message-id/200707060844.l668i89w097496@wwwmaster.postgresql.org
# So, Postgres had a bug..
# Sanity check: if over 24 or 48 hours, push it up to a day unit
set h_in_days [expr { int( $h / 24. ) } ]
if { $h >= 1 } {
# adjust hours to less than a day
set h [expr { $h - ( 24 * $h_in_days ) } ]
incr d $h_in_days
set h_correction_p 1
} else {
set h_correction_p 0
if {$maxunit in {years months days}} {
# Sanity check: if over 24 or 48 hours, push it up to a day unit
set h_in_days [expr { int( $h / 24. ) } ]
if { $h >= 1 } {
# adjust hours to less than a day
set h [expr { $h - ( 24 * $h_in_days ) } ]
incr d $h_in_days
set h_correction_p 1
} else {
set h_correction_p 0
}
}
# Calculate interval s1_p4 to s2 in minutes
# minute_in_sec [expr { 60 } ]
# 60
set mm [expr { int( ( $s2 - $s1_p4 ) / 60. ) } ]
# Move interval from s1_p4 to s1_p5
set s1_p5 [clock_scan_interval $s1_p4 $mm minutes]
# Sanity check: if 60 minutes, push it up to an hour unit
if { $mm >= 60 } {
# adjust 60 minutes to 1 hour
# puts "interval_ymdhs: debug info mm - 60, h + 1"
set mm [expr { $mm - 60 } ]
incr h
set mm_correction_p 1
} else {
set mm_correction_p 0
set mm 0
set s1_p5 $s1_p4
if {$maxunit in {years months days hours minutes}} {
# Calculate interval s1_p4 to s2 in minutes
# minute_in_sec [expr { 60 } ]
# 60
set mm [expr { int( ( $s2 - $s1_p4 ) / 60. ) } ]
# Move interval from s1_p4 to s1_p5
set s1_p5 [clock add $s1_p4 $mm minutes -timezone $timezone]
}
if {$maxunit in {years months days hours}} {
# Sanity check: if 60 minutes, push it up to an hour unit
if { $mm >= 60 } {
# adjust 60 minutes to 1 hour
# puts "difference: debug info mm - 60, h + 1"
set mm [expr { $mm - 60 } ]
incr h
set mm_correction_p 1
} else {
set mm_correction_p 0
}
}
# Calculate interval s1_p5 to s2 in seconds
set s [expr { int( $s2 - $s1_p5 ) } ]
# Sanity check: if 60 seconds, push it up to one minute unit
if { $s >= 60 } {
# adjust 60 minutes to 1 hour
set s [expr { $s - 60 } ]
incr mm
set s_correction_p 1
} else {
set s_correction_p 0
if {$maxunit in {years months days hours minutes}} {
# Sanity check: if 60 seconds, push it up to one minute unit
if { $s >= 60 } {
# adjust 60 minutes to 1 hour
set s [expr { $s - 60 } ]
incr mm
set s_correction_p 1
} else {
set s_correction_p 0
}
}
set return_list [list $y $m $d $h $mm $s]
#set return_list [list $y $m $d $h $mm $s]
set return_list [dict create years $y months $m days $d hours $h minutes $mm seconds $s]
# test results by adding difference to s1 to get s2:
set i 0
set s1_test [clock format $s1 -format "%Y%m%dT%H%M%S"]
set signs_inconsistent_p 0
foreach unit {years months days hours minutes seconds} {
set t_term [lindex $return_list $i]
if { $t_term != 0 } {
set diffterms [list]
dict for {unit t_term} $return_list {
if {$t_term != 0} {
if { $t_term > 0 } {
append s1_test " + $t_term $unit"
lappend diffterms +$t_term $unit
} else {
append s1_test " - [expr { abs( $t_term ) } ] $unit"
lappend diffterms -[expr { abs( $t_term ) }] $unit
set signs_inconsistent_p 1
}
}
incr i
}
set s2_test [clock scan $s1_test]
# puts "test s2 '$s2_test' from: '$s1_test'"
set counter 0
#set s2_test [clock scan $s1_test]
set s2_test [clock add $s1 {*}$diffterms -timezone $timezone]
# puts "test s2 '$s2_test' from: '$s1_test'"
set counter 0
while { $s2 ne $s2_test && $counter < 30 } {
set s2_diff [expr { $s2_test - $s2 } ]
puts "\ninterval_ymdhs: debug s1 $s1 s2 $s2 y $y m $m d $d h $h s $s s2_diff $s2_diff"
puts "difference: debug s1 $s1 s2 $s2 y $y m $m d $d h $h s $s s2_diff $s2_diff"
set absdiff [expr {abs($s2_diff)}]
if { $absdiff > 86399 } {
if { $s2_diff > 0 } {
incr d -1
puts "interval_ymdhs: debug, audit adjustment. decreasing 1 day to $d"
puts "difference: debug, audit adjustment. decreasing 1 day to $d"
} else {
incr d
puts "interval_ymdhs: debug, audit adjustment. increasing 1 day to $d"
puts "difference: debug, audit adjustment. increasing 1 day to $d"
}
} elseif { $absdiff > 3599 } {
if { $s2_diff > 0 } {
incr h -1
puts "interval_ymdhs: debug, audit adjustment. decreasing 1 hour to $h"
puts "difference: debug, audit adjustment. decreasing 1 hour to $h"
} else {
incr h
puts "interval_ymdhs: debug, audit adjustment. increasing 1 hour to $h"
puts "difference: debug, audit adjustment. increasing 1 hour to $h"
}
} elseif { $absdiff > 59 } {
if { $s2_diff > 0 } {
incr mm -1
puts "interval_ymdhs: debug, audit adjustment. decreasing 1 minute to $mm"
puts "difference: debug, audit adjustment. decreasing 1 minute to $mm"
} else {
incr mm
puts "interval_ymdhs: debug, audit adjustment. increasing 1 minute to $mm"
puts "difference: debug, audit adjustment. increasing 1 minute to $mm"
}
} elseif { $absdiff > 0 } {
if { $s2_diff > 0 } {
incr s -1
puts "interval_ymdhs: debug, audit adjustment. decreasing 1 second to $s"
puts "difference: debug, audit adjustment. decreasing 1 second to $s"
} else {
incr s
puts "interval_ymdhs: debug, audit adjustment. increasing 1 second to $s"
puts "difference: debug, audit adjustment. increasing 1 second to $s"
}
}
set return_list [list $y $m $d $h $mm $s]
set return_list [dict create years $y months $m days $d hours $h minutes $mm seconds $s]
# set return_list [list [expr { abs($y) } ] [expr { abs($m) } ] [expr { abs($d) } ] [expr { abs($h) } ] [expr { abs($mm) } ] [expr { abs($s) } ]]
# test results by adding difference to s1 to get s2:
set i 0
set s1_test [clock format $s1 -format "%Y%m%dT%H%M%S"]
foreach unit {years months days hours minutes seconds} {
set t_term [lindex $return_list $i]
set diffterms [list]
dict for {unit t_term} $return_list {
if { $t_term != 0 } {
if { $t_term > 0 } {
append s1_test " + $t_term $unit"
lappend diffterms +$t_term $unit
} else {
append s1_test " - [expr { abs( $t_term ) } ] $unit"
lappend diffterms -[expr { abs( $t_term ) }] $unit
}
}
incr i
}
set s2_test [clock scan $s1_test]
set s2_test [clock add $s1 {*}$diffterms -timezone $timezone]
incr counter
}
if { ( $counter > 0 || $signs_inconsistent_p ) && ( $h_correction_p || $mm_correction_p || $s_correction_p ) } {
# puts "interval_ymdhs: Corrections in the main calculation were applied: h ${h_correction_p}, mm ${mm_correction_p}, s ${s_correction_p}"
}
#if { ( $counter > 0 || $signs_inconsistent_p ) && ( $h_correction_p || $mm_correction_p || $s_correction_p ) } {
# puts "difference: Corrections in the main calculation were applied: h ${h_correction_p}, mm ${mm_correction_p}, s ${s_correction_p}"
#}
if { $signs_inconsistent_p } {
puts "\ninterval_ymdhs: signs inconsistent y $y m $m d $d h $h mm $mm s $s"
puts "\punk::timeinterval::difference - signs inconsistent y $y m $m d $d h $h mm $mm s $s"
}
if { $s2 eq $s2_test } {
return $return_list
@ -290,23 +343,19 @@ namespace eval punk::timeinterval {
set s2_diff [expr { $s2_test - $s2 } ]
puts "debug s1 $s1 s1_p1 $s1_p1 s1_p2 $s1_p2 s1_p3 $s1_p3 s1_p4 $s1_p4"
puts "debug y $y m $m d $d h $h mm $mm s $s"
puts "interval_ymdhs error: s2 is '$s2' but s2_test is '$s2_test' a difference of ${s2_diff} from s1 '$s1_test'."
# error "result audit fails" "error: s2 is $s2 but s2_test is '$s2_test' a difference of ${s2_diff} from: '$s1_test'."
puts "punk::timeinterval::difference - error: s2 is '$s2' but s2_test is '$s2_test' a difference of ${s2_diff} from s1 '$s1_test'."
error "punk::timeinterval::difference result audit fail" "error: s2 is $s2 but s2_test is '$s2_test' a difference of ${s2_diff} from: '$s1_test'."
}
}
proc interval_ymdhs_w_units { t1 t2 } {
# interval_ymdhs_w_units
# returns interval_ymdhs values with units
set v_list [interval_ymdhs $t2 $t1]
set i 0
set a ""
foreach f {years months days hours minutes seconds} {
append a "[lindex $v_list $i] $f \n"
incr i
}
return $a
}
}
tcl::namespace::eval punk::timeinterval::experimental {
#The interval_remains.. functions were part of the original code from the wiki
#Updated to use clock add etc - but the result seems to be off by one for the value of days - review
#The original purpose of these functions isn't clearly understood - perhaps it was just a different
#mechanism to calculate the interval as a crosscheck?
proc interval_remains_ymdhs { s1 s2 } {
@ -342,7 +391,7 @@ namespace eval punk::timeinterval {
set s1_p1 $s2_y_check
set y $y_count
incr y_count -1
set s2_y_check [clock_scan_interval $s1_p0 $y_count years]
set s2_y_check [clock add $s1_p0 $y_count years]
}
# interval s1_p0 to s1_p1 counted in y years
@ -354,7 +403,7 @@ namespace eval punk::timeinterval {
set s1_p2 $s2_m_check
set m $m_count
incr m_count -1
set s2_m_check [clock_scan_interval $s1_p1 $m_count months]
set s2_m_check [clock add $s1_p1 $m_count months]
}
# interval s1_p1 to s1_p2 counted in m months
@ -371,7 +420,7 @@ namespace eval punk::timeinterval {
}
# Move interval from s1_p2 to s1_p3
set s1_p3 [clock_scan_interval $s1_p2 $d days]
set s1_p3 [clock add $s1_p2 $d days]
# s1_p3 is less than a day from s2
@ -380,7 +429,7 @@ namespace eval punk::timeinterval {
# 3600
set h [expr { int( ceil( ( $s2 - $s1_p3 ) / 3600. ) ) } ]
# Move interval from s1_p3 to s1_p4
set s1_p4 [clock_scan_interval $s1_p3 $h hours]
set s1_p4 [clock add $s1_p3 $h hours]
# s1_p4 is less than an hour from s2
# Sanity check: if over 24 or 48 hours, push it up to a day unit
@ -399,7 +448,7 @@ namespace eval punk::timeinterval {
# 60
set mm [expr { int( ceil( ( $s2 - $s1_p4 ) / 60. ) ) } ]
# Move interval from s1_p4 to s1_p5
set s1_p5 [clock_scan_interval $s1_p4 $mm minutes]
set s1_p5 [clock add $s1_p4 $mm minutes]
# Sanity check: if 60 minutes, push it up to an hour unit
if { $mm <= -60 } {
@ -430,21 +479,25 @@ namespace eval punk::timeinterval {
# test results by adding difference to s1 to get s2:
set i 0
set s1_test [clock format $s1 -format "%Y%m%dT%H%M%S"]
#set s1_test [clock format $s1 -format "%Y%m%dT%H%M%S"]
set signs_inconsistent_p 0
set diffterms [list]
foreach unit {years months days hours minutes seconds} {
set t_term [lindex $return_list $i]
if { $t_term != 0 } {
if { $t_term > 0 } {
append s1_test " + $t_term $unit"
#append s1_test " + $t_term $unit"
lappend diffterms +$t_term $unit
set signs_inconsistent_p 1
} else {
append s1_test " - [expr { abs( $t_term ) } ] $unit"
#append s1_test " - [expr { abs( $t_term ) } ] $unit"
lappend diffterms -[expr { abs( $t_term ) } ] $unit
}
}
incr i
}
set s2_test [clock scan $s1_test]
#set s2_test [clock scan $s1_test]
set s2_test [clock add $s1 {*}$diffterms]
set counter 0
while { $s2 ne $s2_test && $counter < 3 } {
@ -490,19 +543,23 @@ namespace eval punk::timeinterval {
# test results by adding difference to s1 to get s2:
set i 0
set s1_test [clock format $s1 -format "%Y%m%dT%H%M%S"]
#set s1_test [clock format $s1 -format "%Y%m%dT%H%M%S"]
set diffterms [list]
foreach unit {years months days hours minutes seconds} {
set t_term [lindex $return_list $i]
if { $t_term != 0 } {
if { $t_term > 0 } {
append s1_test " + $t_term $unit"
#append s1_test " + $t_term $unit"
lappend diffterms +$t_term $unit
} else {
append s1_test " - [expr { abs( $t_term ) } ] $unit"
#append s1_test " - [expr { abs( $t_term ) } ] $unit"
lappend diffterms -[expr { abs( $t_term ) } ] $unit
}
}
incr i
}
set s2_test [clock scan $s1_test]
#set s2_test [clock scan $s1_test]
set s2_test [clock add $s1 {*}$diffterms]
incr counter
}
if { ( $counter > 0 || $signs_inconsistent_p ) && ( $h_correction_p || $mm_correction_p || $s_correction_p ) } {
@ -523,10 +580,11 @@ namespace eval punk::timeinterval {
}
proc interval_remains_ymdhs_w_units { t1 t2 } {
# interval_remains_ymdhs_w_units
# returns interval_remains_ymdhs values with units
set v_list [interval_ymdhs $t2 $t1]
set v_list [interval_remains_ymdhs $t2 $t1]
set i 0
set a ""
foreach f {years months days hours minutes seconds} {
@ -541,9 +599,105 @@ namespace eval punk::timeinterval {
# == === === === === === === === === === === === === === ===
# Sample 'about' function with punk::args documentation
# == === === === === === === === === === === === === === ===
tcl::namespace::eval punk::timeinterval {
tcl::namespace::export {[a-zA-Z]*} ;# Convention: export all lowercase
variable PUNKARGS
variable PUNKARGS_aliases
lappend PUNKARGS [list {
@id -id "(package)punk::timeinterval"
@package -name "punk::timeinterval" -help\
"time interval from wiki"
}]
namespace eval argdoc {
#namespace for custom argument documentation
proc package_name {} {
return punk::timeinterval
}
proc about_topics {} {
#info commands results are returned in an arbitrary order (like array keys)
set topic_funs [info commands [namespace current]::get_topic_*]
set about_topics [list]
foreach f $topic_funs {
set tail [namespace tail $f]
lappend about_topics [string range $tail [string length get_topic_] end]
}
#Adjust this function or 'default_topics' if a different order is required
return [lsort $about_topics]
}
proc default_topics {} {return [list Description *]}
# -------------------------------------------------------------
# get_topic_ functions add more to auto-include in about topics
# -------------------------------------------------------------
proc get_topic_Description {} {
punk::args::lib::tstr [string trim {
package punk::timeinterval
basic time interval calculations
} \n]
}
proc get_topic_License {} {
return "X11"
}
proc get_topic_Version {} {
return "$::punk::timeinterval::version"
}
proc get_topic_Contributors {} {
set authors {{various "https://wiki.tcl-lang.org/page/Measuring+time+intervals+%28between+two+timestamps%29+with+months+etc"} {Julian Noble <julian@precisium.com.au>}}
set contributors ""
foreach a $authors {
append contributors $a \n
}
if {[string index $contributors end] eq "\n"} {
set contributors [string range $contributors 0 end-1]
}
return $contributors
}
proc get_topic_notes {} {
punk::args::lib::tstr -return string {
X11 license - is MIT with additional clause regarding use of contributor names.
}
}
# -------------------------------------------------------------
}
# we re-use the argument definition from punk::args::standard_about and override some items
set overrides [dict create]
dict set overrides @id -id "::punk::timeinterval::about"
dict set overrides @cmd -name "punk::timeinterval::about"
dict set overrides @cmd -help [string trim [punk::args::lib::tstr {
About punk::timeinterval
}] \n]
dict set overrides topic -choices [list {*}[punk::timeinterval::argdoc::about_topics] *]
dict set overrides topic -choicerestricted 1
dict set overrides topic -default [punk::timeinterval::argdoc::default_topics] ;#if -default is present 'topic' will always appear in parsed 'values' dict
set newdef [punk::args::resolved_def -antiglobs -package_about_namespace -override $overrides ::punk::args::package::standard_about *]
lappend PUNKARGS [list $newdef]
proc about {args} {
package require punk::args
#standard_about accepts additional choices for topic - but we need to normalize any abbreviations to full topic name before passing on
set argd [punk::args::parse $args withid ::punk::timeinterval::about]
lassign [dict values $argd] _leaders opts values _received
punk::args::package::standard_about -package_about_namespace ::punk::timeinterval::argdoc {*}$opts {*}[dict get $values topic]
}
}
# end of sample 'about' function
# == === === === === === === === === === === === === === ===
# -----------------------------------------------------------------------------
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked
# -----------------------------------------------------------------------------
# variable PUNKARGS
# variable PUNKARGS_aliases
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::punk::timeinterval
}

14
src/vfs/_vfscommon.vfs/modules/punk/winrun-0.1.0.tm

@ -37,7 +37,7 @@ namespace eval punk::winrun {
}
proc readchild_handler {chan hpid} {
#fileevent $chan readable {}
#chan event $chan readable {}
set data [read $chan 4096]
while {![chan blocked $chan] && ![eof $chan]} {
append data [read $chan 4096]
@ -46,19 +46,19 @@ namespace eval punk::winrun {
flush stdout
if {![eof $chan]} {
puts stdout "not eof $chan [fconfigure $chan] chan blocked:[chan blocked $chan]"
#fileevent $chan readable [list punk::winrun::readchild_handler $chan $hpid]
#chan event $chan readable [list punk::winrun::readchild_handler $chan $hpid]
} else {
#puts "eof: waiting exit process"
set punk::winrun::waitresult [twapi::wait_on_handle $hpid -wait -1]
}
}
proc readchilderr_handler {chan} {
fileevent $chan readable {}
chan event $chan readable {}
set data [read $chan]
puts stderr "err: $data"
flush stderr
if {![eof $chan]} {
fileevent $chan readable [list punk::winrun::readchild_handler $chan]
chan event $chan readable [list punk::winrun::readchild_handler $chan]
}
}
@ -81,7 +81,7 @@ namespace eval punk::winrun {
#after 1000
chan configure $readout -blocking 0
fileevent $readout readable [list readchild_handler $readout $hpid]
chan event $readout readable [list readchild_handler $readout $hpid]
puts stdout "input: [chan configure $writein]"
puts $writein "puts stdout blah;"
flush $writein
@ -106,8 +106,8 @@ namespace eval punk::winrun {
if {$waitresult eq "timeout"} {
puts stderr "tw_run: timeout waiting for process"
}
fileevent $readout readable {}
fileevent $readerr readable {}
chan event $readout readable {}
chan event $readerr readable {}
set code [twapi::get_process_exit_code $hpid]
twapi::close_handle $htid

2
src/vfs/_vfscommon.vfs/modules/punkcheck-0.1.0.tm

@ -86,7 +86,7 @@ namespace eval punkcheck {
set linecount [llength [split $newtdl \n]]
#puts stdout $newtdl
set fd [open $punkcheck_file w]
fconfigure $fd -translation binary
chan configure $fd -translation binary
puts -nonewline $fd $newtdl
close $fd
return [list recordcount [llength $recordlist] linecount $linecount]

11
src/vfs/_vfscommon.vfs/modules/shellrun-0.1.1.tm

@ -283,7 +283,8 @@ namespace eval shellrun {
#exitcode not part of return value for runout - colourcode appropriately
set n $RST
set c ""
if [dict exists $exitinfo exitcode] {
if {[dict exists $exitinfo exitcode]} {
set code [dict get $exitinfo exitcode]
if {$code == 0} {
set c [a+ green]
@ -291,7 +292,7 @@ namespace eval shellrun {
set c [a+ white bold]
}
lappend chunklist [list "info" "$c$exitinfo$n"]
} elseif [dict exists $exitinfo error] {
} elseif {[dict exists $exitinfo error]} {
set c [a+ yellow bold]
lappend chunklist [list "info" "${c}error [dict get $exitinfo error]$n"]
lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"]
@ -398,17 +399,15 @@ namespace eval shellrun {
set n [a]
set c ""
if [dict exists $exitinfo exitcode] {
if {[dict exists $exitinfo exitcode]} {
set code [dict get $exitinfo exitcode]
if {$code == 0} {
set c [a+ green]
} else {
set c [a+ white bold]
}
lappend chunklist [list "info" "$c$exitinfo$n"]
} elseif [dict exists $exitinfo error] {
} elseif {[dict exists $exitinfo error]} {
set c [a+ yellow bold]
lappend chunklist [list "info" "error [dict get $exitinfo error]"]
lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"]

12
src/vfs/_vfscommon.vfs/modules/shellthread-1.6.1.tm

@ -209,10 +209,10 @@ namespace eval shellthread::worker {
variable sysloghost_port
variable sock
if {[string length $sysloghost_port]} {
if {[catch {fconfigure $sock} state]} {
if {[catch {chan configure $sock} state]} {
set sock [udp_open]
fconfigure $sock -buffering none -translation binary
fconfigure $sock -remote $sysloghost_port
chan configure $sock -buffering none -translation binary
chan configure $sock -remote $sysloghost_port
}
}
}
@ -220,7 +220,7 @@ namespace eval shellthread::worker {
variable sock
catch {close $sock}
_initsock
return [fconfigure $sock]
return [chan configure $sock]
}
proc send_info {client_tid ts_sent source msg} {
@ -436,7 +436,7 @@ namespace eval shellthread::manager {
# todo - some protection mechanism for case where target is a file to stop creation of multiple worker threads writing to same file.
# Even if we use open fd,close fd wrapped around writes.. it is probably undesirable to have multiple threads with same target
# On the other hand socket targets such as UDP can happily be written to by multiple threads.
# For now the mechanism is that a call to new_worker (rename to open_worker?) will join the same thread if a sourcetag matches..
# For now the mechanism is that a call to new_worker (rename to open_worker?) will join the same thread if a sourcetag matches.
# but, as sourcetags can get removed(unsubbed via leave_worker) this doesn't guarantee two threads with same -file settings won't fight.
# Also.. the settingsdict is ignored when joining with a tag that exists.. this is problematic.. e.g logrotation where previous file still being written by existing worker
# todo - rename 'sourcetag' concept to 'targettag' ?? the concept is a mixture of both.. it is somewhat analagous to a syslog 'facility'
@ -751,7 +751,7 @@ namespace eval shellthread::manager {
set ts_end_list [dict get $workers $source ts_end_list] ;#ts_end_list is just a list of timestamps of closing calls for this source - only one is needed to close, but they may all come in a flurry.
if {[llength $ts_end_list]} {
set last_end_ts [lindex $ts_end_list end]
if {[expr {(($tsnow - $last_end_ts) / 1000) >= $timeout}]} {
if {(($tsnow - $last_end_ts) / 1000) >= $timeout} {
lappend ts_end_list $ts_now
dict set workers $source ts_end_list $ts_end_list
} else {

6
src/vfs/_vfscommon.vfs/modules/textblock-0.1.3.tm

@ -663,7 +663,7 @@ tcl::namespace::eval textblock {
switch -- $k {
-ansibase_header - -ansibase_body - -ansiborder_header - -ansiborder-body - -ansiborder_footer {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set ansi_codes [list] ;
set ansi_codes [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -1109,7 +1109,7 @@ tcl::namespace::eval textblock {
}
-ansibase {
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]"
set col_ansibase_items [list] ;
set col_ansibase_items [list]
foreach {pt code} $parts {
if {$pt ne ""} {
#we don't expect plaintext in an ansibase
@ -7852,7 +7852,7 @@ tcl::namespace::eval textblock {
foreach {k v} $optlist {
set k2 [tcl::prefix::match -error "" $optnames $k]
switch -- $k2 {
-etabs - -type - -boxlimits - -boxmap - -joins
-etabs - -type - -boxlimits - -boxmap - -join
- -title - -titlealign - -subtitle - -subtitlealign - -width - -height
- -ansiborder - -ansibase
- -blockalign - -textalign - -ellipsis

153
src/vfs/_vfscommon.vfs/modules/winlibreoffice-0.1.0.tm

@ -28,13 +28,14 @@ if {"windows" eq $::tcl_platform(platform)} {
puts stderr "Minimal functionality - only some utils may work"
}
} else {
puts stderr "Package requires twapi. No current equivalent on non-windows platform. Try tcluno http://sf.net/projets/tcluno "
puts stderr "Package requires twapi. No current equivalent on non-windows platform. Try tcluno http://sf.net/projets/tcluno"
puts stderr "Minimal functionality - only some utils may work"
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
namespace eval winlibreoffice {
namespace export from_libre_date to_libre_date
#---
#todo: investigate tcluno package http://sf.net/projects/tcluno
#CPlusPlus - platforms?
@ -212,31 +213,133 @@ namespace eval winlibreoffice {
#ULTRABOLD 175.0
#BLACK 200.0
lappend PUNKARGS [list {
@id -id ::winlibreoffice::to_libre_date
@cmd -name winlibreoffice::to_libre_date -help\
"Return an internal Libre Office date/time floating point
number representing the number of days between 1899-12-30
and the supplied time.
e.g
% to_libre_date 2025-02-28T060000
45716.25
% to_libre_date 2025-01-01T060101
45658.250706018516
"
@opts
-timezone -default "" -help\
"If unspecified, the timezone will be the
current time zone on the system"
@values -min 1 -max 1
time -type string -help\
"A unix timestamp as output by 'clock seconds'
or a text timestamp such as 2025-01-03T000000
parseable by 'clock scan'"
}]
proc to_libre_date {args} {
package require punk::args
set argd [punk::args::parse $args withid ::winlibreoffice::to_libre_date]
lassign [dict values $argd] leaders opts values received
set tz [dict get $opts -timezone]
set time [dict get $values time]
if {![string is integer -strict $time]} {
set ts [clock scan $time -timezone $tz]
} else {
set ts $time
}
#a hack
#return libreoffice date in days since 1899..
proc date_from_clockseconds_approx {cs} {
variable datebase
set tbase [clock scan $datebase]
set tbase [clock scan $datebase -timezone $tz]
package require punk::timeinterval
set diff [punk::timeinterval::difference $tbase $cs]
set info [punk::timeinterval::difference -maxunit days -timezone $tz $tbase $ts]
lassign [dict values $info] _Y _m days h m s
set Y [dict get $diff years]
set M [dict get $diff months]
set D [dict get $diff days]
set yeardays [expr 365.25 * $Y]
set monthdays [expr 30.437 * $M]
return [expr {$days + ((($h *3600) + ($m * 60) + $s)/86400.0)}]
}
lappend PUNKARGS [list {
@id -id ::winlibreoffice::from_libre_date
@cmd -name winlibreoffice::from_libre_date -help\
"Convert an internal Libre Office date floating point value
representing the number of days since 1899-12-30 to a format
understood by Tcl such as 'clock seconds', 'clock milliseconds'
as specified in the -format option.
"
@opts
-format -default "clockseconds" -choices {clockseconds clockmillis ISO8601} -choicerestricted 0 -help\
"Aside from the special values listed -format accepts a format string
as accepted by the Tcl 'clock format' command's -format option."
-timezone -default "" -help\
"If unspecified, the timezone will be the
current time zone on the system"
@values -min 1 -max 1
libredatetime -type float -help\
"Floating point number representing the number of
days since 1899-12-30."
}]
#review - we don't expect sci notation for any float values here
#but we could easily get them.. e.g 0.000000001 * 86400.0 => 8.64e-5
#todo - clockmicros ?
proc from_libre_date {args} {
package require punk::args
set argd [punk::args::parse $args withid ::winlibreoffice::from_libre_date]
lassign [dict values $argd] leaders opts values received
set format [dict get $opts -format]
set tz [dict get $opts -timezone]
set libredatetime [dict get $values libredatetime]
variable datebase
set tbase [clock scan $datebase -timezone $tz]
set intdays [expr {int($libredatetime)}]
set fracdays [lindex [split $libredatetime .] 1]
if {$fracdays ne ""} {
set fracdays "0.$fracdays"
set floatsecs [expr {$fracdays * 86400.0}] ;#assuming not a leap-second day
if {$format eq "clockmillis"} {
set wholesecs [expr {int($floatsecs)}]
set msfrac [lindex [split $floatsecs .] 1]
if {$msfrac ne ""} {
set msfrac "0.$msfrac" ;#could also be something like 0.64e-5 which should still work
set ms [expr {round(1000 * $msfrac)}]
if {$ms == 1000} {
set ms 0
incr wholesecs
}
} else {
set ms 0
}
} else {
set wholesecs [expr {round($floatsecs)}]
set ms 0
}
} else {
set wholesecs 0
set ms 0
}
#yes.. this is horrible.. just a test really - but gets in the ballpark.
return [expr int($yeardays + $monthdays + $D)]
set cs [clock add $tbase +$intdays days +$wholesecs seconds -timezone $tz]
switch -- $format {
clockseconds {
return $cs
}
clockmillis {
return [expr {($cs * 1000) + $ms}]
}
ISO8601 {
set format "%Y%m%dT%H%M%S"
}
}
return [clock format $cs -format $format]
}
#time is represented on a scale of 0 to 1 6:00am = 0.25 (24/4)
#time is represented on a scale of 0 to 1 6:00am = 0.25 (24/4)
proc date_from_clockseconds {cs} {
puts stderr "unimplemented"
#return libreoffice date as a floating point number of days since 1899.. (1899-12-30)
proc to_libre_date_from_clockseconds_gmt {cs} {
return [expr {($cs/86400.0) + 25569}]
}
#see also: https://wiki.tcl-lang.org/page/Tcom+examples+for+Microsoft+Outlook
@ -265,13 +368,15 @@ namespace eval winlibreoffice {
# -----------------------------------------------------------------------------
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked
# -----------------------------------------------------------------------------
# variable PUNKARGS
# variable PUNKARGS_aliases
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::winlibreoffice
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++

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

Binary file not shown.
Loading…
Cancel
Save