Browse Source

tcl9 fixes

master
Julian Noble 5 months ago
parent
commit
408634fa72
  1. 2
      src/bootsupport/modules/overtype-1.6.2.tm
  2. 2
      src/bootsupport/modules/punk/ansi-0.1.1.tm
  3. 2
      src/bootsupport/modules/punk/assertion-0.1.0.tm
  4. 1
      src/bootsupport/modules/punk/mix/base-0.1.tm
  5. 9
      src/bootsupport/modules/punk/mix/templates/utility/scriptappwrappers/multishell.cmd
  6. 2
      src/bootsupport/modules/sha1-2.0.4.tm
  7. 2
      src/bootsupport/modules/textutil/adjust-0.7.3.tm
  8. 2
      src/bootsupport/modules/textutil/repeat-0.7.tm
  9. 2
      src/bootsupport/modules/textutil/split-0.8.tm
  10. 2
      src/bootsupport/modules/textutil/string-0.8.tm
  11. 2
      src/bootsupport/modules/textutil/tabify-0.7.tm
  12. 2
      src/bootsupport/modules/textutil/trim-0.7.tm
  13. 4
      src/embedded/man/files/punk/_module_sshrun-0.1.0.tm.n
  14. 4
      src/embedded/md/doc/files/punk/_module_sshrun-0.1.0.tm.md
  15. 4
      src/embedded/www/doc/files/punk/_module_sshrun-0.1.0.tm.html
  16. 4
      src/modules/argp-0.2.tm
  17. 46
      src/modules/flagfilter-0.3.tm
  18. 2
      src/modules/patternpunk-1.1.tm
  19. 5
      src/modules/punk-0.1.tm
  20. 2
      src/modules/punk/ansi-999999.0a1.0.tm
  21. 2
      src/modules/punk/assertion-999999.0a1.0.tm
  22. 1
      src/modules/punk/mix/base-0.1.tm
  23. 9
      src/modules/punk/mix/templates/utility/scriptappwrappers/multishell.cmd
  24. 14
      src/modules/punk/repl-0.1.tm
  25. 1
      src/modules/punk/winrun-999999.0a1.0.tm
  26. 5
      src/modules/shellfilter-0.1.9.tm
  27. 14
      src/punk86.vfs/lib/app-shellspy/shellspy.tcl
  28. 83
      src/scriptapps/wrapfiletofile.tcl
  29. 410
      src/vendormodules/base64-2.5.tm
  30. 306
      src/vendormodules/debug-1.0.6.tm
  31. 2
      src/vendormodules/overtype-1.6.2.tm
  32. 2
      src/vendormodules/sha1-2.0.4.tm
  33. 2
      src/vendormodules/struct/list-1.8.5.tm
  34. 2
      src/vendormodules/struct/matrix-2.1.tm
  35. 56
      src/vendormodules/term/ansi/code-0.2.tm
  36. 108
      src/vendormodules/term/ansi/code/attr-0.1.tm
  37. 272
      src/vendormodules/term/ansi/code/ctrl-0.3.tm
  38. 93
      src/vendormodules/term/ansi/code/macros-0.1.tm
  39. 2
      src/vendormodules/textutil-0.9.tm
  40. 2
      src/vendormodules/textutil/adjust-0.7.3.tm
  41. 2
      src/vendormodules/textutil/patch-0.1.tm
  42. 2
      src/vendormodules/textutil/repeat-0.7.tm
  43. 2
      src/vendormodules/textutil/split-0.8.tm
  44. 2
      src/vendormodules/textutil/string-0.8.tm
  45. 2
      src/vendormodules/textutil/tabify-0.7.tm
  46. 2
      src/vendormodules/textutil/trim-0.7.tm

2
src/bootsupport/modules/overtype-1.6.2.tm

@ -44,7 +44,7 @@
#[para] packages used by overtype
#[list_begin itemized]
package require Tcl 8.6
package require Tcl 8.6-
package require textutil
package require punk::lib ;#required for lines_as_list
package require punk::ansi ;#required to detect, split, strip and calculate lengths

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

@ -2626,7 +2626,7 @@ namespace eval punk::ansi::class {
} errM]} {
error "sha1 package unavailable"
}
return [{*}$o_cksum_command $o_string]
return [{*}$o_cksum_command [encoding convertto utf-8 $o_string]]
}
#todo - allow setting checksum algorithm and/or command

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

@ -50,7 +50,7 @@
#[para] packages used by punk::assertion
#[list_begin itemized]
package require Tcl 8.6
package require Tcl 8.6-
#*** !doctools
#[item] [package {Tcl 8.6}]

1
src/bootsupport/modules/punk/mix/base-0.1.tm

@ -596,6 +596,7 @@ namespace eval punk::mix::base {
switch -- $opt_cksum_algorithm {
sha1 {
package require sha1
#review - any utf8 issues in tcl9?
set cksum_command [list sha1::sha1 -hex -file]
}
sha2 - sha256 {

9
src/bootsupport/modules/punk/mix/templates/utility/scriptappwrappers/multishell.cmd

@ -94,7 +94,8 @@ set -- "$@" "a=[Hide <#;Hide set;s 1 list]"; set -- : "$@";$1 = @'
)
@SET "vbsGetPrivileges=%temp%\punk_bat_elevate_%fname%.vbs"
@SET arglist=%*
@IF "%1"=="PUNK-ELEVATED" (
@SET qstrippedargs=%arglist:"=%
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (
GOTO :gotPrivileges
)
@IF !asadmin!==1 (
@ -103,7 +104,7 @@ set -- "$@" "a=[Hide <#;Hide set;s 1 list]"; set -- : "$@";$1 = @'
)
@GOTO skip_privileges
:getPrivileges
@IF '%1'=='PUNK-ELEVATED' (echo PUNK-ELEVATED & shift /1 & goto :gotPrivileges )
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (echo PUNK-ELEVATED & shift /1 & goto :gotPrivileges )
@ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
@ECHO args = "PUNK-ELEVATED " >> "%vbsGetPrivileges%"
@ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
@ -118,7 +119,7 @@ set -- "$@" "a=[Hide <#;Hide set;s 1 list]"; set -- : "$@";$1 = @'
@REM setlocal & pushd .
@PUSHD .
@cd /d %~dp0
@IF "%1"=="PUNK-ELEVATED" (
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (
@DEL "%vbsGetPrivileges%" 1>nul 2>nul
@SET arglist=%arglist:~14%
)
@ -634,7 +635,7 @@ $1 = @'
: \
@REM @ECHO exitcode: !task_exitcode!
: \
@IF "%1"=="PUNK-ELEVATED" (echo. & @cmd /k echo elevated prompt: type exit to quit)
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (echo. & @cmd /k echo elevated prompt: type exit to quit)
: \
@EXIT /B !task_exitcode!
# cmd has exited

2
src/bootsupport/modules/sha1-2.0.4.tm

@ -22,7 +22,7 @@
# -------------------------------------------------------------------------
# @mdgen EXCLUDE: sha1c.tcl
package require Tcl 8.2; # tcl minimum version
package require Tcl 8.2-; # tcl minimum version
namespace eval ::sha1 {
variable accel

2
src/bootsupport/modules/textutil/adjust-0.7.3.tm

@ -15,7 +15,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
package require textutil::repeat
package require textutil::string

2
src/bootsupport/modules/textutil/repeat-0.7.tm

@ -14,7 +14,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::repeat {}

2
src/bootsupport/modules/textutil/split-0.8.tm

@ -16,7 +16,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::split {}

2
src/bootsupport/modules/textutil/string-0.8.tm

@ -16,7 +16,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::string {}

2
src/bootsupport/modules/textutil/tabify-0.7.tm

@ -56,7 +56,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
package require textutil::repeat
namespace eval ::textutil::tabify {}

2
src/bootsupport/modules/textutil/trim-0.7.tm

@ -14,7 +14,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::trim {}

4
src/embedded/man/files/punk/_module_sshrun-0.1.0.tm.n

@ -286,7 +286,7 @@ send \fIhost\fR
.sp
send_exit \fIhost\fR
.sp
send_exit \fIhost\fR
pop_line \fIhost\fR \fIline_varname\fR
.sp
pop_all \fIhost\fR \fIoutput_varname\fR
.sp
@ -406,7 +406,7 @@ The net effect if this is that the remote host's tclsh will exit, so that the fi
.sp
to read the entire output at once (see the pop proc below)
.TP
send_exit \fIhost\fR
pop_line \fIhost\fR \fIline_varname\fR
.sp
After executing a "send", this can be used to read one line of output\&. The proc does the equivalent of
.CS

4
src/embedded/md/doc/files/punk/_module_sshrun-0.1.0.tm.md

@ -52,7 +52,7 @@ package require punk::sshrun
[push *host* *script*](#3)
[send *host*](#4)
[send\_exit *host*](#5)
[send\_exit *host*](#6)
[pop\_line *host* *line\_varname*](#6)
[pop\_all *host* *output\_varname*](#7)
[pop\_read *host* *numbytes* *output\_varname*](#8)
[hfileevent *host* *readable\_writable* *script*](#9)
@ -161,7 +161,7 @@ class definitions
to read the entire output at once \(see the pop proc below\)
- <a name='6'></a>send\_exit *host*
- <a name='6'></a>pop\_line *host* *line\_varname*
After executing a "send", this can be used to read one line of output\. The
proc does the equivalent of

4
src/embedded/www/doc/files/punk/_module_sshrun-0.1.0.tm.html

@ -145,7 +145,7 @@
<li><a href="#3">push <i class="arg">host</i> <i class="arg">script</i></a></li>
<li><a href="#4">send <i class="arg">host</i></a></li>
<li><a href="#5">send_exit <i class="arg">host</i></a></li>
<li><a href="#6">send_exit <i class="arg">host</i></a></li>
<li><a href="#6">pop_line <i class="arg">host</i> <i class="arg">line_varname</i></a></li>
<li><a href="#7">pop_all <i class="arg">host</i> <i class="arg">output_varname</i></a></li>
<li><a href="#8">pop_read <i class="arg">host</i> <i class="arg">numbytes</i> <i class="arg">output_varname</i></a></li>
<li><a href="#9">hfileevent <i class="arg">host</i> <i class="arg">readable_writable</i> <i class="arg">script</i></a></li>
@ -222,7 +222,7 @@
[read &lt;filehandle&gt;]
</pre>
<p>to read the entire output at once (see the pop proc below)</p></dd>
<dt><a name="6">send_exit <i class="arg">host</i></a></dt>
<dt><a name="6">pop_line <i class="arg">host</i> <i class="arg">line_varname</i></a></dt>
<dd><p>After executing a &quot;send&quot;, this can be used to read one line of output. The proc does the equivalent of</p>
<pre class="doctools_example">
[gets &lt;filehandle&gt; line]

4
src/modules/argp-0.2.tm

@ -225,11 +225,11 @@ proc argp::CheckValues { caller cmangled checklist } {
if { ![string is integer $low] \
&& [string compare "-" $low] != 0} {
return -code error "$caller, $key of type $Optstore(type,$key,$cmangled) has a lower value range that is not integer and not ´-´: $range"
return -code error "$caller, $key of type $Optstore(type,$key,$cmangled) has a lower value range that is not integer and not \u00b4-\u00b4: $range"
}
if { ![string is integer $high] \
&& [string compare "+" $high] != 0} {
return -code error "$caller, $key of type $Optstore(type,$key,$cmangled) has a upper value range that is not integer and not ´+´: $range"
return -code error "$caller, $key of type $Optstore(type,$key,$cmangled) has a upper value range that is not integer and not \u00b4+\u00b4: $range"
}
if {[string compare "-" $low] == 0} {
if { [string compare "+" $high] == 0 \

46
src/modules/flagfilter-0.3.tm

@ -2160,6 +2160,11 @@ namespace eval flagfilter {
set dispatchstatus "ok"
#each dispatch entry is a commandname and dict
#set dispatchrecord [lrange $dispatch 0 1]
set re_argnum {%arg([0-9^%]+)%}
set re_argtake {%argtake([0-9^%]+)%}
set re_dquotedparts {(?:(?:\"[^\"]*\")|(?:\"[^\"]*"))|(?:\S*[^ \"])} ;#for use with regexp -all -inline
#e.g {"a b" 'b x' "x cd "e f" g a} -> {"a b"} 'b x' {"x cd "} e f {" g a}
#dumb-editor rebalancing quote for above comment "
foreach {parentname dispatchrecord} $dispatch {
set commandinfo [get_command_info $parentname $command_specs]
@ -2172,6 +2177,45 @@ namespace eval flagfilter {
#support for %x% placeholders in dispatchrecord command
set command [string map [list %match% %matched%] $command] ;#alias
set command [string map [list %matched% [dict get $dispatchrecord matched]] $command]
set argnum_indices [regexp -indices -all -inline $re_argnum $command]
if {[llength $argnum_indices]} {
foreach {argx_indices x_indices} $argnum_indices {
#argx eg %arg12%
set argx [string range $command {*}$argx_indices]
set x [string range $command {*}$x_indices]
set command [string map [list $argx [lindex [dict get $dispatchrecord arguments] $x]] $command]
}
}
set argsreduced [dict get $dispatchrecord arguments]
#set rawparts [regexp -all -inline $re_dquotedparts [dict get $dispatchrecord raw]]
#review!
#how will this behave differently on unix
package require punk::winrun
set rawparts [punk::winrun::unquote_wintcl [dict get $dispatchrecord raw]]
#set argtake_indices [regexp -indices -all -inline $re_argtake $command]
set start 0
while {[regexp -start $start -indices $re_argtake $command argx_indices x_indices]} {
#argx eg %argtake12%
set argx [string range $command {*}$argx_indices]
set x [string range $command {*}$x_indices]
set argval [lindex [dict get $dispatchrecord arguments] $x]
set replacementlen [string length $argval]
set command [string map [list $argx $argval] $command]
set start [expr {[lindex $argx_indices 0] + $replacementlen}]
set argsreduced [lremove $argsreduced $x]
set rawparts [lremove $rawparts $x]
}
dict set dispatchrecord arguments $argsreduced
if {$start > 0} {
set rawreduced [join $rawparts]
dict set dispatchrecord raw $rawreduced
}
set argvals [dict get $dispatchrecord arguments]
set matched_operands [list]
set matched_opts [list]
@ -2273,7 +2317,7 @@ namespace eval flagfilter {
lappend dispatchstatuslist [list status err cmd $parentname outputlength 0 error $cmdresult]
if {!$was_dispatched_by_another} {
#this is the first (or a direct) call to check_flags - so make sure error gets raised in this proc rather than just storing the error in the data and returning
set raise_dispatch_error_instead_of_return "dispatchstatuslist:\n[join $dispatchstatuslist \n]"
set raise_dispatch_error_instead_of_return "dispatchstatuslist:\n[join $dispatchstatuslist \n] \nerrinfo:\n $::errorInfo"
dict set dispatchrecord result $dispatchresult
dict set dispatchrecord error $dispatcherror
dict set dispatch $parentname $dispatchrecord

2
src/modules/patternpunk-1.1.tm

@ -55,7 +55,7 @@ set ::punk::bannerTemplate [string trim {
set word2 [overtype::right [string repeat " " 7] [dict get $opts -right]]
set title [overtype::centre [string repeat " " 15] [dict get $opts -title]]
return [string map [list 111111111 $word1 2222222 $word2 000000000000000 $title] $punk::bannerTemplate]
return [string map [list 111111111 $word1 2222222 $word2 000000000000000 $title] $::punk::bannerTemplate]
}

5
src/modules/punk-0.1.tm

@ -100,7 +100,10 @@ namespace eval punk {
#We will use punk::assertion instead
package require punk::assertion
namespace import ::punk::assertion::assert
if {[catch {namespace import ::punk::assertion::assert} errM]} {
puts stderr "punk error importing punk::assertion::assert\n$errM"
puts stderr "punk::a* commands:[info commands ::punk::a*]"
}
punk::assertion::active on
# -- --- ---

2
src/modules/punk/ansi-999999.0a1.0.tm

@ -2626,7 +2626,7 @@ namespace eval punk::ansi::class {
} errM]} {
error "sha1 package unavailable"
}
return [{*}$o_cksum_command $o_string]
return [{*}$o_cksum_command [encoding convertto utf-8 $o_string]]
}
#todo - allow setting checksum algorithm and/or command

2
src/modules/punk/assertion-999999.0a1.0.tm

@ -50,7 +50,7 @@
#[para] packages used by punk::assertion
#[list_begin itemized]
package require Tcl 8.6
package require Tcl 8.6-
#*** !doctools
#[item] [package {Tcl 8.6}]

1
src/modules/punk/mix/base-0.1.tm

@ -596,6 +596,7 @@ namespace eval punk::mix::base {
switch -- $opt_cksum_algorithm {
sha1 {
package require sha1
#review - any utf8 issues in tcl9?
set cksum_command [list sha1::sha1 -hex -file]
}
sha2 - sha256 {

9
src/modules/punk/mix/templates/utility/scriptappwrappers/multishell.cmd

@ -94,7 +94,8 @@ set -- "$@" "a=[Hide <#;Hide set;s 1 list]"; set -- : "$@";$1 = @'
)
@SET "vbsGetPrivileges=%temp%\punk_bat_elevate_%fname%.vbs"
@SET arglist=%*
@IF "%1"=="PUNK-ELEVATED" (
@SET qstrippedargs=%arglist:"=%
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (
GOTO :gotPrivileges
)
@IF !asadmin!==1 (
@ -103,7 +104,7 @@ set -- "$@" "a=[Hide <#;Hide set;s 1 list]"; set -- : "$@";$1 = @'
)
@GOTO skip_privileges
:getPrivileges
@IF '%1'=='PUNK-ELEVATED' (echo PUNK-ELEVATED & shift /1 & goto :gotPrivileges )
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (echo PUNK-ELEVATED & shift /1 & goto :gotPrivileges )
@ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
@ECHO args = "PUNK-ELEVATED " >> "%vbsGetPrivileges%"
@ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
@ -118,7 +119,7 @@ set -- "$@" "a=[Hide <#;Hide set;s 1 list]"; set -- : "$@";$1 = @'
@REM setlocal & pushd .
@PUSHD .
@cd /d %~dp0
@IF "%1"=="PUNK-ELEVATED" (
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (
@DEL "%vbsGetPrivileges%" 1>nul 2>nul
@SET arglist=%arglist:~14%
)
@ -634,7 +635,7 @@ $1 = @'
: \
@REM @ECHO exitcode: !task_exitcode!
: \
@IF "%1"=="PUNK-ELEVATED" (echo. & @cmd /k echo elevated prompt: type exit to quit)
@IF /i "%qstrippedargs:~0,13%"=="PUNK-ELEVATED" (echo. & @cmd /k echo elevated prompt: type exit to quit)
: \
@EXIT /B !task_exitcode!
# cmd has exited

14
src/modules/punk/repl-0.1.tm

@ -685,9 +685,9 @@ proc repl::start {inchan args} {
if {$::punk::console::ansi_wanted == 2} {
if {[::punk::console::test_can_ansi]} {
set punk::console::ansi_wanted 1
set ::punk::console::ansi_wanted 1
} else {
set punk::console::ansi_wanted -1
set ::punk::console::ansi_wanted -1
}
}
set prompt_config [get_prompt_config]
@ -2133,7 +2133,7 @@ proc repl::repl_process_data {inputchan type chunk stdinlines prompt_config} {
append info "commandstr: [punk::ansi::ansistring::VIEW $commandstr]\n"
append info "last_run_info\n"
append info "length: [llength $::punk::last_run_display]\n"
append info "namespace: $punk::ns::ns_current"
append info "namespace: $::punk::ns::ns_current"
debug_repl_emit $info
} else {
proc debug_repl_emit {msg} {return}
@ -2183,9 +2183,9 @@ proc repl::repl_process_data {inputchan type chunk stdinlines prompt_config} {
#puts stderr "repl uplevel 0 '$run_command_string'"
set status [catch {
#uplevel 1 $run_command_string
#uplevel 1 {namespace eval $punk::ns::ns_current $run_command_string}
#uplevel 1 {namespace eval $::punk::ns::ns_current $run_command_string}
set weirdns 0
set parts [punk::ns::nsparts $punk::ns::ns_current]
set parts [punk::ns::nsparts $::punk::ns::ns_current]
foreach p $parts {
if {[string match :* $p] || [string match *: $p]} {
set weirdns 1
@ -2194,10 +2194,10 @@ proc repl::repl_process_data {inputchan type chunk stdinlines prompt_config} {
}
if {$weirdns} {
uplevel 1 {punk::ns::nseval $punk::ns::ns_current $run_command_string}
uplevel 1 {punk::ns::nseval $::punk::ns::ns_current $run_command_string}
} else {
#puts stderr "--> [ansistring VIEW -lf 1 -vt 1 $run_command_string] <--"
uplevel 1 {namespace inscope $punk::ns::ns_current $run_command_string}
uplevel 1 {namespace inscope $::punk::ns::ns_current $run_command_string}
}
} raw_result]
}

1
src/modules/punk/winrun-999999.0a1.0.tm

@ -254,6 +254,7 @@ namespace eval punk::winrun {
#unquote_wintcl and tclsh ::argv give 2 args, "a b c" , etc
#CommandLineToArgvW gives 4 args "a , b , c" , etc
#
#NOTE: used by flagfilter for splitting dispatchrecord raw element
proc unquote_wintcl {standard_quoted_cmdline} {
#with reference to https://daviddeley.com/autohotkey/parameters/parameters.htm post2008 ms C/C++ commandline parameter parsing algorithm (section 5.10)
set paramlist [list]

5
src/modules/shellfilter-0.1.9.tm

@ -1963,7 +1963,10 @@ namespace eval shellfilter {
set runtag "shellfilter-run"
#set tid [::shellfilter::log::open $runtag [list -syslog 127.0.0.1:514]]
set tid [::shellfilter::log::open $runtag [list -syslog ""]]
::shellfilter::log::write $runtag " commandlist:'$commandlist' len:[llength $commandlist]"
if {[catch {llength $commandlist} listlen]} {
set listlen "<not-a-tcl-list>"
}
::shellfilter::log::write $runtag " commandlist:'$commandlist' listlen:$listlen strlen:[string length $commandlist]"
#flush stdout
#flush stderr

14
src/punk86.vfs/lib/app-shellspy/shellspy.tcl

@ -645,7 +645,7 @@ namespace eval shellspy {
set scriptpath [file rootname $scriptpath][string tolower [file extension $scriptpath]]
if {![file exists $scriptpath]} {
puts stderr "Failed to find script: '$scriptpath'"
error "bad scriptpath '$scriptpath'"
error "bad scriptpath '$scriptpath' arguments: $scriptbin $scriptname $args"
}
}
@ -864,6 +864,16 @@ source [file normalize $scriptname]
for {set i 0} {$i < 25} {incr i} {
lappend commands [list tclscript [list sub word$i singleopts {any}]]
}
#%argN% and %argtakeN% can be used as well as %matched% - %argtakeN% will remove from raw and arguments elements of dispatchrecord
lappend commands [list withinterp [list match {^withinterp$} dispatch [list shellspy::do_script_process %argtake0%] dispatchtype raw dispatchglobal 1 singleopts {any} longopts {any} pairopts {any}]]
for {set i 0} {$i < 25} {incr i} {
lappend commands [list withinterp [list sub word$i singleopts {any} longopts {any} pairopts {any}]]
}
lappend commands [list runcmdfile [list match [list {.*\.cmd$} {.*\.bat$} ] dispatch [list shellspy::do_in_cmdshell %matched%] dispatchtype raw dispatchglobal 1 singleopts {any} longopts {any}]]
for {set i 0} {$i < 25} {incr i} {
lappend commands [list runcmdfile [list sub word$i singleopts {any}]]
}
lappend commands [list libscript [list match [list {lib::.*$} ] dispatch [list shellspy::do_script %matched% "no_repl"] dispatchtype raw dispatchglobal 1 singleopts {any}]]
for {set i 0} {$i < 25} {incr i} {
@ -921,7 +931,7 @@ source [file normalize $scriptname]
for {set i 0} {$i < 25} {incr i} {
lappend commands [list runcmduc [list sub word$i singleopts {any}]]
}
#cmd with bracked args () e.g with vim shellxquote set to "("
#cmd with bracketed args () e.g with vim shellxquote set to "("
lappend commands [list runcmdb [list match {^cmdb$} dispatch [list shellspy::do_in_cmdshellb] dispatchtype raw dispatchglobal 1 singleopts {any} longopts {any} pairopts {any}]]
for {set i 0} {$i < 25} {incr i} {
lappend commands [list runcmdb [list sub word$i singleopts {any} longopts {any} pairopts {any}]]

83
src/scriptapps/wrapfiletofile.tcl

@ -0,0 +1,83 @@
#A basic utility script to cat a file to another with optional string prefix and suffix
#does not interpret escapes e.g \n in arguments - review
#Used for example by zig.build or other systems to avoid problems with redirecting echo/cat etc
#2024 - zig.build.addSystemCommand doesn't seem to support pipelines
#padding
#padding
#padding
#padding
#padding
#padding
#padding
set usage "usage: interpreter scriptname -startnl 0|1 -prefix <string> -prefixnl 0|1 -suffix <string> -suffixnl 0|1 -input <filename> -inputnl 0|1 -output <filename>"
set defaults [dict create\
-startnl 0\
-crlf 0\
-prefix ""\
-prefixnl 0\
-suffix ""\
-suffixnl 0\
-input ""\
-inputnl 0\
-output \uFFEF\
]
if {"windows" eq $::tcl_platform(platform)} {
package require punk::winrun
package require twapi
set rawcmdline [twapi::get_process_commandline [pid]]
set allargs [punk::winrun::unquote_wintcl $rawcmdline]
#first 2 args are the interpreter and the script
set scriptargs [lrange $allargs 2 end]
} else {
set scriptargs $::argv
}
#puts stdout "scriptargs:$scriptargs"
if {[llength $scriptargs] % 2 != 0} {
puts stderr $usage
exit 1
}
set opts [dict merge $defaults $scriptargs]
#puts stdout "opts:$opts"
if {[dict get $opts -output] eq "\uFFEF"} {
puts stderr $usage
exit 2
}
set infile [dict get $opts -input]
set filedata ""
if {$infile ne ""} {
if {![file exists $infile]} {
puts stderr "Unable to read input file '$infile'"
exit 3
}
set fd [open $infile r]
set filedata [read $fd]
close $fd
}
set startnl ""
set prefixnl ""
set suffixnl ""
set inputnl ""
if {[dict get $opts -startnl]} {
set startnl \n
}
if {[dict get $opts -prefixnl]} {
set prefixnl \n
}
if {[dict get $opts -suffixnl]} {
set suffixnl \n
}
if {[dict get $opts -inputnl]} {
set inputnl \n
}
set data "$startnl[dict get $opts -prefix]$prefixnl$filedata$inputnl[dict get $opts -suffix]$suffixnl"
set fdout [open [dict get $opts -output] w]
if {[dict get $opts -crlf] == 0} {
chan configure $fdout -translation binary
}
puts -nonewline $fdout $data
close $fdout
catch {puts stdout ok}
exit 0

410
src/vendormodules/base64-2.5.tm

@ -0,0 +1,410 @@
# base64.tcl --
#
# Encode/Decode base64 for a string
# Stephen Uhler / Brent Welch (c) 1997 Sun Microsystems
# The decoder was done for exmh by Chris Garrigues
#
# Copyright (c) 1998-2000 by Ajuba Solutions.
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# Version 1.0 implemented Base64_Encode, Base64_Decode
# Version 2.0 uses the base64 namespace
# Version 2.1 fixes various decode bugs and adds options to encode
# Version 2.2 is much faster, Tcl8.0 compatible
# Version 2.2.1 bugfixes
# Version 2.2.2 bugfixes
# Version 2.3 bugfixes and extended to support Trf
# Version 2.4.x bugfixes
# @mdgen EXCLUDE: base64c.tcl
package require Tcl 8.2-
namespace eval ::base64 {
namespace export encode decode
}
package provide base64 2.5
if {[package vsatisfies [package require Tcl] 8.6]} {
proc ::base64::encode {args} {
binary encode base64 -maxlen 76 {*}$args
}
proc ::base64::decode {string} {
# Tcllib is strict with respect to end of input, yet lax for
# invalid characters outside of that.
regsub -all -- {[^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/]} $string {} string
binary decode base64 -strict $string
}
return
}
if {![catch {package require Trf 2.0}]} {
# Trf is available, so implement the functionality provided here
# in terms of calls to Trf for speed.
# ::base64::encode --
#
# Base64 encode a given string.
#
# Arguments:
# args ?-maxlen maxlen? ?-wrapchar wrapchar? string
#
# If maxlen is 0, the output is not wrapped.
#
# Results:
# A Base64 encoded version of $string, wrapped at $maxlen characters
# by $wrapchar.
proc ::base64::encode {args} {
# Set the default wrapchar and maximum line length to match
# the settings for MIME encoding (RFC 3548, RFC 2045). These
# are the settings used by Trf as well. Various RFCs allow for
# different wrapping characters and wraplengths, so these may
# be overridden by command line options.
set wrapchar "\n"
set maxlen 76
if { [llength $args] == 0 } {
error "wrong # args: should be \"[lindex [info level 0] 0]\
?-maxlen maxlen? ?-wrapchar wrapchar? string\""
}
set optionStrings [list "-maxlen" "-wrapchar"]
for {set i 0} {$i < [llength $args] - 1} {incr i} {
set arg [lindex $args $i]
set index [lsearch -glob $optionStrings "${arg}*"]
if { $index == -1 } {
error "unknown option \"$arg\": must be -maxlen or -wrapchar"
}
incr i
if { $i >= [llength $args] - 1 } {
error "value for \"$arg\" missing"
}
set val [lindex $args $i]
# The name of the variable to assign the value to is extracted
# from the list of known options, all of which have an
# associated variable of the same name as the option without
# a leading "-". The [string range] command is used to strip
# of the leading "-" from the name of the option.
#
# FRINK: nocheck
set [string range [lindex $optionStrings $index] 1 end] $val
}
# [string is] requires Tcl8.2; this works with 8.0 too
if {[catch {expr {$maxlen % 2}}]} {
return -code error "expected integer but got \"$maxlen\""
} elseif {$maxlen < 0} {
return -code error "expected positive integer but got \"$maxlen\""
}
set string [lindex $args end]
set result [::base64 -mode encode -- $string]
# Trf's encoder implicitly uses the settings -maxlen 76,
# -wrapchar \n for its output. We may have to reflow this for
# the settings chosen by the user. A second difference is that
# Trf closes the output with the wrap char sequence,
# always. The code here doesn't. Therefore 'trimright' is
# needed in the fast cases.
if {($maxlen == 76) && [string equal $wrapchar \n]} {
# Both maxlen and wrapchar are identical to Trf's
# settings. This is the super-fast case, because nearly
# nothing has to be done. Only thing to do is strip a
# terminating wrapchar.
set result [string trimright $result]
} elseif {$maxlen == 76} {
# wrapchar has to be different here, length is the
# same. We can use 'string map' to transform the wrap
# information.
set result [string map [list \n $wrapchar] \
[string trimright $result]]
} elseif {$maxlen == 0} {
# Have to reflow the output to no wrapping. Another fast
# case using only 'string map'. 'trimright' is not needed
# here.
set result [string map [list \n ""] $result]
} else {
# Have to reflow the output from 76 to the chosen maxlen,
# and possibly change the wrap sequence as well.
# Note: After getting rid of the old wrap sequence we
# extract the relevant segments from the string without
# modifying the string. Modification, i.e. removal of the
# processed part, means 'shifting down characters in
# memory', making the algorithm O(n^2). By avoiding the
# modification we stay in O(n).
set result [string map [list \n ""] $result]
set l [expr {[string length $result]-$maxlen}]
for {set off 0} {$off < $l} {incr off $maxlen} {
append res [string range $result $off [expr {$off+$maxlen-1}]] $wrapchar
}
append res [string range $result $off end]
set result $res
}
return $result
}
# ::base64::decode --
#
# Base64 decode a given string.
#
# Arguments:
# string The string to decode. Characters not in the base64
# alphabet are ignored (e.g., newlines)
#
# Results:
# The decoded value.
proc ::base64::decode {string} {
regsub -all {\s} $string {} string
::base64 -mode decode -- $string
}
} else {
# Without Trf use a pure tcl implementation
namespace eval base64 {
variable base64 {}
variable base64_en {}
# We create the auxiliary array base64_tmp, it will be unset later.
variable base64_tmp
variable i
set i 0
foreach char {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
a b c d e f g h i j k l m n o p q r s t u v w x y z \
0 1 2 3 4 5 6 7 8 9 + /} {
set base64_tmp($char) $i
lappend base64_en $char
incr i
}
#
# Create base64 as list: to code for instance C<->3, specify
# that [lindex $base64 67] be 3 (C is 67 in ascii); non-coded
# ascii chars get a {}. we later use the fact that lindex on a
# non-existing index returns {}, and that [expr {} < 0] is true
#
# the last ascii char is 'z'
variable char
variable len
variable val
scan z %c len
for {set i 0} {$i <= $len} {incr i} {
set char [format %c $i]
set val {}
if {[info exists base64_tmp($char)]} {
set val $base64_tmp($char)
} else {
set val {}
}
lappend base64 $val
}
# code the character "=" as -1; used to signal end of message
scan = %c i
set base64 [lreplace $base64 $i $i -1]
# remove unneeded variables
unset base64_tmp i char len val
namespace export encode decode
}
# ::base64::encode --
#
# Base64 encode a given string.
#
# Arguments:
# args ?-maxlen maxlen? ?-wrapchar wrapchar? string
#
# If maxlen is 0, the output is not wrapped.
#
# Results:
# A Base64 encoded version of $string, wrapped at $maxlen characters
# by $wrapchar.
proc ::base64::encode {args} {
set base64_en $::base64::base64_en
# Set the default wrapchar and maximum line length to match
# the settings for MIME encoding (RFC 3548, RFC 2045). These
# are the settings used by Trf as well. Various RFCs allow for
# different wrapping characters and wraplengths, so these may
# be overridden by command line options.
set wrapchar "\n"
set maxlen 76
if { [llength $args] == 0 } {
error "wrong # args: should be \"[lindex [info level 0] 0]\
?-maxlen maxlen? ?-wrapchar wrapchar? string\""
}
set optionStrings [list "-maxlen" "-wrapchar"]
for {set i 0} {$i < [llength $args] - 1} {incr i} {
set arg [lindex $args $i]
set index [lsearch -glob $optionStrings "${arg}*"]
if { $index == -1 } {
error "unknown option \"$arg\": must be -maxlen or -wrapchar"
}
incr i
if { $i >= [llength $args] - 1 } {
error "value for \"$arg\" missing"
}
set val [lindex $args $i]
# The name of the variable to assign the value to is extracted
# from the list of known options, all of which have an
# associated variable of the same name as the option without
# a leading "-". The [string range] command is used to strip
# of the leading "-" from the name of the option.
#
# FRINK: nocheck
set [string range [lindex $optionStrings $index] 1 end] $val
}
# [string is] requires Tcl8.2; this works with 8.0 too
if {[catch {expr {$maxlen % 2}}]} {
return -code error "expected integer but got \"$maxlen\""
} elseif {$maxlen < 0} {
return -code error "expected positive integer but got \"$maxlen\""
}
set string [lindex $args end]
set result {}
set state 0
set length 0
# Process the input bytes 3-by-3
binary scan $string c* X
foreach {x y z} $X {
ADD [lindex $base64_en [expr {($x >>2) & 0x3F}]]
if {$y != {}} {
ADD [lindex $base64_en [expr {(($x << 4) & 0x30) | (($y >> 4) & 0xF)}]]
if {$z != {}} {
ADD [lindex $base64_en [expr {(($y << 2) & 0x3C) | (($z >> 6) & 0x3)}]]
ADD [lindex $base64_en [expr {($z & 0x3F)}]]
} else {
set state 2
break
}
} else {
set state 1
break
}
}
if {$state == 1} {
ADD [lindex $base64_en [expr {(($x << 4) & 0x30)}]]
ADD =
ADD =
} elseif {$state == 2} {
ADD [lindex $base64_en [expr {(($y << 2) & 0x3C)}]]
ADD =
}
return $result
}
proc ::base64::ADD {x} {
# The line length check is always done before appending so
# that we don't get an extra newline if the output is a
# multiple of $maxlen chars long.
upvar 1 maxlen maxlen length length result result wrapchar wrapchar
if {$maxlen && $length >= $maxlen} {
append result $wrapchar
set length 0
}
append result $x
incr length
return
}
# ::base64::decode --
#
# Base64 decode a given string.
#
# Arguments:
# string The string to decode. Characters not in the base64
# alphabet are ignored (e.g., newlines)
#
# Results:
# The decoded value.
proc ::base64::decode {string} {
if {[string length $string] == 0} {return ""}
set base64 $::base64::base64
set output "" ; # Fix for [Bug 821126]
set nums {}
binary scan $string c* X
lappend X 61 ;# force a terminator
foreach x $X {
set bits [lindex $base64 $x]
if {$bits >= 0} {
if {[llength [lappend nums $bits]] == 4} {
foreach {v w z y} $nums break
set a [expr {($v << 2) | ($w >> 4)}]
set b [expr {(($w & 0xF) << 4) | ($z >> 2)}]
set c [expr {(($z & 0x3) << 6) | $y}]
append output [binary format ccc $a $b $c]
set nums {}
}
} elseif {$bits == -1} {
# = indicates end of data. Output whatever chars are
# left, if any.
if {![llength $nums]} break
# The encoding algorithm dictates that we can only
# have 1 or 2 padding characters. If x=={}, we must
# (*) have 12 bits of input (enough for 1 8-bit
# output). If x!={}, we have 18 bits of input (enough
# for 2 8-bit outputs).
#
# (*) If we don't then the input is broken (bug 2976290).
foreach {v w z} $nums break
# Bug 2976290
if {$w == {}} {
return -code error "Not enough data to process padding"
}
set a [expr {($v << 2) | (($w & 0x30) >> 4)}]
if {$z == {}} {
append output [binary format c $a ]
} else {
set b [expr {(($w & 0xF) << 4) | (($z & 0x3C) >> 2)}]
append output [binary format cc $a $b]
}
break
} else {
# RFC 2045 says that line breaks and other characters not part
# of the Base64 alphabet must be ignored, and that the decoder
# can optionally emit a warning or reject the message. We opt
# not to do so, but to just ignore the character.
continue
}
}
return $output
}
}
# # ## ### ##### ######## ############# #####################
return

306
src/vendormodules/debug-1.0.6.tm

@ -0,0 +1,306 @@
# Debug - a debug narrative logger.
# -- Colin McCormack / originally Wub server utilities
#
# Debugging areas of interest are represented by 'tokens' which have
# independantly settable levels of interest (an integer, higher is more detailed)
#
# Debug narrative is provided as a tcl script whose value is [subst]ed in the
# caller's scope if and only if the current level of interest matches or exceeds
# the Debug call's level of detail. This is useful, as one can place arbitrarily
# complex narrative in code without unnecessarily evaluating it.
#
# TODO: potentially different streams for different areas of interest.
# (currently only stderr is used. there is some complexity in efficient
# cross-threaded streams.)
# # ## ### ##### ######## ############# #####################
## Requisites
package require Tcl 8.5-
namespace eval ::debug {
namespace export -clear \
define on off prefix suffix header trailer \
names 2array level setting parray pdict \
nl tab hexl
namespace ensemble create -subcommands {}
}
# # ## ### ##### ######## ############# #####################
## API & Implementation
proc ::debug::noop {args} {}
proc ::debug::debug {tag message {level 1}} {
variable detail
if {$detail($tag) < $level} {
#puts stderr "$tag @@@ $detail($tag) >= $level"
return
}
variable prefix
variable suffix
variable header
variable trailer
variable fds
if {[info exists fds($tag)]} {
set fd $fds($tag)
} else {
set fd stderr
}
# Assemble the shown text from the user message and the various
# prefixes and suffices (global + per-tag).
set themessage ""
if {[info exists prefix(::)]} { append themessage $prefix(::) }
if {[info exists prefix($tag)]} { append themessage $prefix($tag) }
append themessage $message
if {[info exists suffix($tag)]} { append themessage $suffix($tag) }
if {[info exists suffix(::)]} { append themessage $suffix(::) }
# Resolve variables references and command invokations embedded
# into the message with plain text.
set code [catch {
set smessage [uplevel 1 [list ::subst -nobackslashes $themessage]]
set sheader [uplevel 1 [list ::subst -nobackslashes $header]]
set strailer [uplevel 1 [list ::subst -nobackslashes $trailer]]
} __ eo]
# And dump an internal error if that resolution failed.
if {$code} {
if {[catch {
set caller [info level -1]
}]} { set caller GLOBAL }
if {[string length $caller] >= 1000} {
set caller "[string range $caller 0 200]...[string range $caller end-200 end]"
}
foreach line [split $caller \n] {
puts -nonewline $fd "@@(DebugError from $tag ($eo): $line)"
}
return
}
# From here we have a good message to show. We only shorten it a
# bit if its a bit excessive in size.
if {[string length $smessage] > 4096} {
set head [string range $smessage 0 2048]
set tail [string range $smessage end-2048 end]
set smessage "${head}...(truncated)...$tail"
}
foreach line [split $smessage \n] {
puts $fd "$sheader$tag | $line$strailer"
}
return
}
# names - return names of debug tags
proc ::debug::names {} {
variable detail
return [lsort [array names detail]]
}
proc ::debug::2array {} {
variable detail
set result {}
foreach n [lsort [array names detail]] {
if {[interp alias {} debug.$n] ne "::debug::noop"} {
lappend result $n $detail($n)
} else {
lappend result $n -$detail($n)
}
}
return $result
}
# level - set level and fd for tag
proc ::debug::level {tag {level ""} {fd {}}} {
variable detail
# TODO: Force level >=0.
if {$level ne ""} {
set detail($tag) $level
}
if {![info exists detail($tag)]} {
set detail($tag) 1
}
variable fds
if {$fd ne {}} {
set fds($tag) $fd
}
return $detail($tag)
}
proc ::debug::header {text} { variable header $text }
proc ::debug::trailer {text} { variable trailer $text }
proc ::debug::define {tag} {
if {[interp alias {} debug.$tag] ne {}} return
off $tag
return
}
# Set a prefix/suffix to use for tag.
# The global (tag-independent) prefix/suffix is adressed through tag '::'.
# This works because colon (:) is an illegal character for user-specified tags.
proc ::debug::prefix {tag {theprefix {}}} {
variable prefix
set prefix($tag) $theprefix
if {[interp alias {} debug.$tag] ne {}} return
off $tag
return
}
proc ::debug::suffix {tag {theprefix {}}} {
variable suffix
set suffix($tag) $theprefix
if {[interp alias {} debug.$tag] ne {}} return
off $tag
return
}
# turn on debugging for tag
proc ::debug::on {tag {level ""} {fd {}}} {
variable active
set active($tag) 1
level $tag $level $fd
interp alias {} debug.$tag {} ::debug::debug $tag
return
}
# turn off debugging for tag
proc ::debug::off {tag {level ""} {fd {}}} {
variable active
set active($tag) 1
level $tag $level $fd
interp alias {} debug.$tag {} ::debug::noop
return
}
proc ::debug::setting {args} {
if {[llength $args] == 1} {
set args [lindex $args 0]
}
set fd stderr
if {[llength $args] % 2} {
set fd [lindex $args end]
set args [lrange $args 0 end-1]
}
foreach {tag level} $args {
if {$level > 0} {
level $tag $level $fd
interp alias {} debug.$tag {} ::debug::debug $tag
} else {
level $tag [expr {-$level}] $fd
interp alias {} debug.$tag {} ::debug::noop
}
}
return
}
# # ## ### ##### ######## ############# #####################
## Convenience commands.
# Format arrays and dicts as multi-line message.
# Insert newlines and tabs.
proc ::debug::nl {} { return \n }
proc ::debug::tab {} { return \t }
proc ::debug::parray {a {pattern *}} {
upvar 1 $a array
if {![array exists array]} {
error "\"$a\" isn't an array"
}
pdict [array get array] $pattern
}
proc ::debug::pdict {dict {pattern *}} {
set maxl 0
set names [lsort -dict [dict keys $dict $pattern]]
foreach name $names {
if {[string length $name] > $maxl} {
set maxl [string length $name]
}
}
set maxl [expr {$maxl + 2}]
set lines {}
foreach name $names {
set nameString [format (%s) $name]
lappend lines [format "%-*s = %s" \
$maxl $nameString \
[dict get $dict $name]]
}
return [join $lines \n]
}
proc ::debug::hexl {data {prefix {}}} {
set r {}
# Convert the data to hex and to characters.
binary scan $data H*@0a* hexa asciia
# Replace non-printing characters in the data with dots.
regsub -all -- {[^[:graph:] ]} $asciia {.} asciia
# Pad with spaces to a full multiple of 32/16.
set n [expr {[string length $hexa] % 32}]
if {$n < 32} { append hexa [string repeat { } [expr {32-$n}]] }
#puts "pad H [expr {32-$n}]"
set n [expr {[string length $asciia] % 32}]
if {$n < 16} { append asciia [string repeat { } [expr {16-$n}]] }
#puts "pad A [expr {32-$n}]"
# Reassemble formatted, in groups of 16 bytes/characters.
# The hex part is handled in groups of 32 nibbles.
set addr 0
while {[string length $hexa]} {
# Get front group of 16 bytes each.
set hex [string range $hexa 0 31]
set ascii [string range $asciia 0 15]
# Prep for next iteration
set hexa [string range $hexa 32 end]
set asciia [string range $asciia 16 end]
# Convert the hex to pairs of hex digits
regsub -all -- {..} $hex {& } hex
# Add the hex and latin-1 data to the result buffer
append r $prefix [format %04x $addr] { | } $hex { |} $ascii |\n
incr addr 16
}
# And done
return $r
}
# # ## ### ##### ######## ############# #####################
namespace eval debug {
variable detail ; # map: TAG -> level of interest
variable prefix ; # map: TAG -> message prefix to use
variable suffix ; # map: TAG -> message suffix to use
variable fds ; # map: TAG -> handle of open channel to log to.
variable header {} ; # per-line heading, subst'ed
variable trailer {} ; # per-line ending, subst'ed
# Notes:
# - The tag '::' is reserved. "prefix" and "suffix" use it to store
# the global message prefix / suffix.
# - prefix and suffix are applied per message.
# - header and trailer are per line. And should not generate multiple lines!
}
# # ## ### ##### ######## ############# #####################
## Ready
package provide debug 1.0.6
return

2
src/vendormodules/overtype-1.6.2.tm

@ -44,7 +44,7 @@
#[para] packages used by overtype
#[list_begin itemized]
package require Tcl 8.6
package require Tcl 8.6-
package require textutil
package require punk::lib ;#required for lines_as_list
package require punk::ansi ;#required to detect, split, strip and calculate lengths

2
src/vendormodules/sha1-2.0.4.tm

@ -22,7 +22,7 @@
# -------------------------------------------------------------------------
# @mdgen EXCLUDE: sha1c.tcl
package require Tcl 8.2; # tcl minimum version
package require Tcl 8.2-; # tcl minimum version
namespace eval ::sha1 {
variable accel

2
src/vendormodules/struct/list-1.8.5.tm

@ -13,7 +13,7 @@
#
#----------------------------------------------------------------------
package require Tcl 8.4
package require Tcl 8.4-
package require cmdline
namespace eval ::struct { namespace eval list {} }

2
src/vendormodules/struct/matrix-2.1.tm

@ -10,7 +10,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require Tcl 8.5
package require Tcl 8.5-
package require textutil::wcswidth ;# TermWidth, for _columnwidth and related places
namespace eval ::struct {}

56
src/vendormodules/term/ansi/code-0.2.tm

@ -0,0 +1,56 @@
# -*- tcl -*-
# ### ### ### ######### ######### #########
## Terminal packages - ANSI
## Generic commands to define commands for code sequences.
# ### ### ### ######### ######### #########
## Requirements
namespace eval ::term::ansi::code {}
# ### ### ### ######### ######### #########
## API. Escape clauses, plain and bracket
## Used by 'define'd commands.
proc ::term::ansi::code::esc {str} {return \033$str}
proc ::term::ansi::code::escb {str} {esc \[$str}
# ### ### ### ######### ######### #########
## API. Define command for named control code, or constant.
## (Simple definitions without arguments)
proc ::term::ansi::code::define {name escape code} {
proc [Qualified $name] {} [list ::term::ansi::code::$escape $code]
}
proc ::term::ansi::code::const {name code} {
proc [Qualified $name] {} [list return $code]
}
# ### ### ### ######### ######### #########
## Internal helper to construct fully-qualified names.
proc ::term::ansi::code::Qualified {name} {
if {![string match ::* $name]} {
# Get the caller's namespace; append :: if it is not the
# global namespace, for separation from the actual name.
set ns [uplevel 2 [list namespace current]]
if {$ns ne "::"} {append ns ::}
set name $ns$name
}
return $name
}
# ### ### ### ######### ######### #########
namespace eval ::term::ansi::code {
namespace export esc escb define const
}
# ### ### ### ######### ######### #########
## Ready
package provide term::ansi::code 0.2
##
# ### ### ### ######### ######### #########

108
src/vendormodules/term/ansi/code/attr-0.1.tm

@ -0,0 +1,108 @@
# -*- tcl -*-
# ### ### ### ######### ######### #########
## Terminal packages - ANSI - Attribute codes
# ### ### ### ######### ######### #########
## Requirements
package require term::ansi::code ; # Constants
namespace eval ::term::ansi::code::attr {}
# ### ### ### ######### ######### #########
## API. Symbolic names.
proc ::term::ansi::code::attr::names {} {
variable attr
return $attr
}
proc ::term::ansi::code::attr::import {{ns attr} args} {
if {![llength $args]} {set args *}
set args ::term::ansi::code::attr::[join $args " ::term::ansi::code::attr::"]
uplevel 1 [list namespace eval ${ns} [linsert $args 0 namespace import]]
return
}
# ### ### ### ######### ######### #########
## Internal - Setup
proc ::term::ansi::code::attr::DEF {name value} {
variable attr
const $name $value
lappend attr $name
namespace export $name
return
}
proc ::term::ansi::code::attr::INIT {} {
# ### ### ### ######### ######### #########
##
# Colors. Foreground <=> Text
DEF fgblack 30 ; # Black
DEF fgred 31 ; # Red
DEF fggreen 32 ; # Green
DEF fgyellow 33 ; # Yellow
DEF fgblue 34 ; # Blue
DEF fgmagenta 35 ; # Magenta
DEF fgcyan 36 ; # Cyan
DEF fgwhite 37 ; # White
DEF fgdefault 39 ; # Default (Black)
# Colors. Background.
DEF bgblack 40 ; # Black
DEF bgred 41 ; # Red
DEF bggreen 42 ; # Green
DEF bgyellow 43 ; # Yellow
DEF bgblue 44 ; # Blue
DEF bgmagenta 45 ; # Magenta
DEF bgcyan 46 ; # Cyan
DEF bgwhite 47 ; # White
DEF bgdefault 49 ; # Default (Transparent)
# Non-color attributes. Activation.
DEF bold 1 ; # Bold
DEF dim 2 ; # Dim
DEF italic 3 ; # Italics
DEF underline 4 ; # Underscore
DEF blink 5 ; # Blink
DEF revers 7 ; # Reverse
DEF hidden 8 ; # Hidden
DEF strike 9 ; # StrikeThrough
# Non-color attributes. Deactivation.
DEF nobold 22 ; # Bold
DEF nodim __ ; # Dim
DEF noitalic 23 ; # Italics
DEF nounderline 24 ; # Underscore
DEF noblink 25 ; # Blink
DEF norevers 27 ; # Reverse
DEF nohidden 28 ; # Hidden
DEF nostrike 29 ; # StrikeThrough
# Remainder
DEF reset 0 ; # Reset
##
# ### ### ### ######### ######### #########
return
}
# ### ### ### ######### ######### #########
## Data structures.
namespace eval ::term::ansi::code::attr {
namespace import ::term::ansi::code::const
variable attr {}
}
::term::ansi::code::attr::INIT
# ### ### ### ######### ######### #########
## Ready
package provide term::ansi::code::attr 0.1
##
# ### ### ### ######### ######### #########

272
src/vendormodules/term/ansi/code/ctrl-0.3.tm

@ -0,0 +1,272 @@
# -*- tcl -*-
# ### ### ### ######### ######### #########
## Terminal packages - ANSI - Control codes
## References
# [0] Google: ansi terminal control
# [1] http://vt100.net/docs/vt100-ug/chapter3.html
# [2] http://www.termsys.demon.co.uk/vtansi.htm
# [3] http://rrbrandt.dyndns.org:60000/docs/tut/redes/ansi.php
# [4] http://www.dee.ufcg.edu.br/~rrbrandt/tools/ansi.html
# [5] http://www.ecma-international.org/publications/standards/Ecma-048.htm
# ### ### ### ######### ######### #########
## Requirements
package require term::ansi::code
package require term::ansi::code::attr
namespace eval ::term::ansi::code::ctrl {}
# ### ### ### ######### ######### #########
## API. Symbolic names.
proc ::term::ansi::code::ctrl::names {} {
variable ctrl
return $ctrl
}
proc ::term::ansi::code::ctrl::import {{ns ctrl} args} {
if {![llength $args]} {set args *}
set args ::term::ansi::code::ctrl::[join $args " ::term::ansi::code::ctrl::"]
uplevel 1 [list namespace eval $ns [linsert $args 0 namespace import]]
return
}
# ### ### ### ######### ######### #########
## TODO = symbolic key codes for skd.
# ### ### ### ######### ######### #########
## Internal - Setup
proc ::term::ansi::code::ctrl::DEF {name esc value} {
variable ctrl
define $name $esc $value
lappend ctrl $name
namespace export $name
return
}
proc ::term::ansi::code::ctrl::DEFC {name arguments script} {
variable ctrl
proc $name $arguments $script
lappend ctrl $name
namespace export $name
return
}
proc ::term::ansi::code::ctrl::INIT {} {
# ### ### ### ######### ######### #########
##
# Erasing
DEF eeol escb K ; # Erase (to) End Of Line
DEF esol escb 1K ; # Erase (to) Start Of Line
DEF el escb 2K ; # Erase (current) Line
DEF ed escb J ; # Erase Down (to bottom)
DEF eu escb 1J ; # Erase Up (to top)
DEF es escb 2J ; # Erase Screen
# Scrolling
DEF sd esc D ; # Scroll Down
DEF su esc M ; # Scroll Up
# Cursor Handling
DEF ch escb H ; # Cursor Home
DEF sc escb s ; # Save Cursor
DEF rc escb u ; # Restore Cursor (Unsave)
DEF sca esc 7 ; # Save Cursor + Attributes
DEF rca esc 8 ; # Restore Cursor + Attributes
# Tabbing
DEF st esc H ; # Set Tab (@ current position)
DEF ct escb g ; # Clear Tab (@ current position)
DEF cat escb 3g ; # Clear All Tabs
# Device Introspection
DEF qdc escb c ; # Query Device Code
DEF qds escb 5n ; # Query Device Status
DEF qcp escb 6n ; # Query Cursor Position
DEF rd esc c ; # Reset Device
# Linewrap on/off
DEF elw escb 7h ; # Enable Line Wrap
DEF dlw escb 7l ; # Disable Line Wrap
# Graphics Mode (aka use alternate font on/off)
DEF eg esc F ; # Enter Graphics Mode
DEF lg esc G ; # Exit Graphics Mode
##
# ### ### ### ######### ######### #########
# ### ### ### ######### ######### #########
## Complex, parameterized codes
# Select Character Set
# Choose which char set is used for default and
# alternate font. This does not change whether
# default or alternate font are used
DEFC scs0 {tag} {esc ($tag} ; # Set default character set
DEFC scs1 {tag} {esc )$tag} ; # Set alternate character set
# tags in A : United Kingdom Set
# B : ASCII Set
# 0 : Special Graphics
# 1 : Alternate Character ROM Standard Character Set
# 2 : Alternate Character ROM Special Graphics
# Set Display Attributes
DEFC sda {args} {escb [join $args \;]m}
# Force Cursor Position (aka Go To)
DEFC fcp {r c} {escb ${r}\;${c}f}
# Cursor Up, Down, Forward, Backward
DEFC cu {{n 1}} {escb [expr {$n == 1 ? "A" : "${n}A"}]}
DEFC cd {{n 1}} {escb [expr {$n == 1 ? "B" : "${n}B"}]}
DEFC cf {{n 1}} {escb [expr {$n == 1 ? "C" : "${n}C"}]}
DEFC cb {{n 1}} {escb [expr {$n == 1 ? "D" : "${n}D"}]}
# Scroll Screen (entire display, or between rows start end, inclusive).
DEFC ss {args} {
if {[llength $args] == 0} {return [escb r]}
if {[llength $args] == 2} {foreach {s e} $args break ; return [escb ${s};${e}r]}
return -code error "wrong\#args"
}
# Set Key Definition
DEFC skd {code str} {escb $code\;\"$str\"p}
# Terminal title
DEFC title {str} {esc \]0\;$str\007}
# Switch to and from character/box graphics.
DEFC gron {} {esc (0}
DEFC groff {} {esc (B}
# Character graphics, box symbols
# - 4 corners, 4 t-junctions,
# one 4-way junction, 2 lines
DEFC tlc {} {return [gron]l[groff]} ; # Top Left Corner
DEFC trc {} {return [gron]k[groff]} ; # Top Right Corner
DEFC brc {} {return [gron]j[groff]} ; # Bottom Right Corner
DEFC blc {} {return [gron]m[groff]} ; # Bottom Left Corner
DEFC ltj {} {return [gron]t[groff]} ; # Left T Junction
DEFC ttj {} {return [gron]w[groff]} ; # Top T Junction
DEFC rtj {} {return [gron]u[groff]} ; # Right T Junction
DEFC btj {} {return [gron]v[groff]} ; # Bottom T Junction
DEFC fwj {} {return [gron]n[groff]} ; # Four-Way Junction
DEFC hl {} {return [gron]q[groff]} ; # Horizontal Line
DEFC vl {} {return [gron]x[groff]} ; # Vertical Line
# Optimize character graphics. The generator commands above create
# way to many superfluous commands shifting into and out of the
# graphics mode. The command below removes all shifts which are
# not needed. To this end it also knows which characters will look
# the same in both modes, to handle strings created outside this
# package.
DEFC groptim {string} {
variable grforw
variable grback
set offon [groff][gron]
set onoff [gron][groff]
while {![string equal $string [set new [string map \
[list $offon {} $onoff {}] [string map \
$grback [string map \
$grforw $string]]]]]} {
set string $new
}
return $string
}
##
# ### ### ### ######### ######### #########
# ### ### ### ######### ######### #########
## Higher level operations
# Clear screen <=> CursorHome + EraseDown
# Init (Fonts): Default ASCII, Alternate Graphics
# Show a block of text at a specific location.
DEFC clear {} {return [ch][ed]}
DEFC init {} {return [scs0 B][scs1 0]}
DEFC showat {r c text} {
if {![string length $text]} {return {}}
return [fcp $r $c][sca][join \
[split $text \n] \
[rca][cd][sca]][rca][cd]
}
##
# ### ### ### ######### ######### #########
# ### ### ### ######### ######### #########
## Attribute control (single attributes)
foreach a [::term::ansi::code::attr::names] {
DEF sda_$a escb [::term::ansi::code::attr::$a]m
}
##
# ### ### ### ######### ######### #########
return
}
# ### ### ### ######### ######### #########
## Data structures.
namespace eval ::term::ansi::code::ctrl {
namespace import ::term::ansi::code::define
namespace import ::term::ansi::code::esc
namespace import ::term::ansi::code::escb
variable grforw
variable grback
variable _
foreach _ {
! \" # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = >
? @ A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z [ ^
\\ ]
} {
lappend grforw \016$_ $_\016
lappend grback $_\017 \017$_
}
unset _
}
::term::ansi::code::ctrl::INIT
# ### ### ### ######### ######### #########
## Ready
package provide term::ansi::code::ctrl 0.3
##
# ### ### ### ######### ######### #########

93
src/vendormodules/term/ansi/code/macros-0.1.tm

@ -0,0 +1,93 @@
# -*- tcl -*-
# ### ### ### ######### ######### #########
## Terminal packages - ANSI - Higher level macros
# ### ### ### ######### ######### #########
## Requirements
package require textutil::repeat
package require textutil::tabify
package require term::ansi::code::ctrl
namespace eval ::term::ansi::code::macros {}
# ### ### ### ######### ######### #########
## API. Symbolic names.
proc ::term::ansi::code::macros::import {{ns macros} args} {
if {![llength $args]} {set args *}
set args ::term::ansi::code::macros::[join $args " ::term::ansi::code::macros::"]
uplevel 1 [list namespace eval ${ns} [linsert $args 0 namespace import]]
return
}
# ### ### ### ######### ######### #########
## Higher level operations
# Format a menu / framed block of text
proc ::term::ansi::code::macros::menu {menu} {
# Menu = dict (label => char)
array set _ {}
set shift 0
foreach {label c} $menu {
if {[string first $c $label] < 0} {
set shift 1
break
}
}
set max 0
foreach {label c} $menu {
set pos [string first $c $label]
if {$shift || ($pos < 0)} {
set xlabel "$c $label"
set pos 0
} else {
set xlabel $label
}
set len [string length $xlabel]
if {$len > $max} {set max $len}
set _($label) " [string replace $xlabel $pos $pos \
[cd::sda_fgred][cd::sda_bold][string index $xlabel $pos][cd::sda_reset]]"
}
append ms [cd::tlc][textutil::repeat::strRepeat [cd::hl] $max][cd::trc]\n
foreach {l c} $menu {append ms $_($l)\n}
append ms [cd::blc][textutil::repeat::strRepeat [cd::hl] $max][cd::brc]
return [cd::groptim $ms]
}
proc ::term::ansi::code::macros::frame {string} {
set lines [split [textutil::tabify::untabify2 $string] \n]
set max 0
foreach l $lines {
if {[set len [string length $l]] > $max} {set max $len}
}
append fs [cd::tlc][textutil::repeat::strRepeat [cd::hl] $max][cd::trc]\n
foreach l $lines {
append fs [cd::vl]${l}[textutil::repeat::strRepeat " " [expr {$max-[string length $l]}]][cd::vl]\n
}
append fs [cd::blc][textutil::repeat::strRepeat [cd::hl] $max][cd::brc]
return [cd::groptim $fs]
}
##
# ### ### ### ######### ######### #########
# ### ### ### ######### ######### #########
## Data structures.
namespace eval ::term::ansi::code::macros {
term::ansi::code::ctrl::import cd
namespace export menu frame
}
# ### ### ### ######### ######### #########
## Ready
package provide term::ansi::code::macros 0.1
##
# ### ### ### ######### ######### #########

2
src/vendormodules/textutil-0.9.tm

@ -16,7 +16,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil {}

2
src/vendormodules/textutil/adjust-0.7.3.tm

@ -15,7 +15,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
package require textutil::repeat
package require textutil::string

2
src/vendormodules/textutil/patch-0.1.tm

@ -7,7 +7,7 @@
# - Factored patch parsing into a helper
# - Replaced `puts` with report callback.
package require Tcl 8.5
package require Tcl 8.5-
package provide textutil::patch 0.1
# # ## ### ##### ######## ############# #####################

2
src/vendormodules/textutil/repeat-0.7.tm

@ -14,7 +14,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::repeat {}

2
src/vendormodules/textutil/split-0.8.tm

@ -16,7 +16,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::split {}

2
src/vendormodules/textutil/string-0.8.tm

@ -16,7 +16,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::string {}

2
src/vendormodules/textutil/tabify-0.7.tm

@ -56,7 +56,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
package require textutil::repeat
namespace eval ::textutil::tabify {}

2
src/vendormodules/textutil/trim-0.7.tm

@ -14,7 +14,7 @@
# ### ### ### ######### ######### #########
## Requirements
package require Tcl 8.2
package require Tcl 8.2-
namespace eval ::textutil::trim {}

Loading…
Cancel
Save