From 4119d9fc7cb15444b78f5f6e49f38139ebf5b545 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Fri, 30 Aug 2024 12:30:41 +1000 Subject: [PATCH] housekeeping - bootsupport, vfs deletion, project_layouts --- .../modules/include_modules.config | 1 + src/bootsupport/modules/overtype-1.6.5.tm | 1024 +++++++------ src/bootsupport/modules/punk/ansi-0.1.1.tm | 11 +- src/bootsupport/modules/punk/console-0.1.1.tm | 10 +- src/bootsupport/modules/punk/zip-0.1.0.tm | 632 ++++++++ src/bootsupport/modules/textblock-0.1.1.tm | 24 +- .../modules/include_modules.config | 1 + .../src/bootsupport/modules/logger-0.9.5.tm | 1297 +++++++++++++++++ .../src/bootsupport/modules/overtype-1.6.5.tm | 1024 +++++++------ .../bootsupport/modules/punk/ansi-0.1.1.tm | 11 +- .../bootsupport/modules/punk/console-0.1.1.tm | 10 +- .../src/bootsupport/modules/punk/zip-0.1.0.tm | 632 ++++++++ .../bootsupport/modules/textblock-0.1.1.tm | 24 +- .../modules/include_modules.config | 1 + .../src/bootsupport/modules/logger-0.9.5.tm | 1297 +++++++++++++++++ .../src/bootsupport/modules/overtype-1.6.5.tm | 1024 +++++++------ .../bootsupport/modules/punk/ansi-0.1.1.tm | 11 +- .../bootsupport/modules/punk/console-0.1.1.tm | 10 +- .../src/bootsupport/modules/punk/zip-0.1.0.tm | 632 ++++++++ .../bootsupport/modules/textblock-0.1.1.tm | 24 +- src/scriptapps/fetchruntime.ps1 | 2 +- .../lib_tcl8/zint-2.13.0/licence.txt | 14 - .../lib_tcl8/zint-2.13.0/pkgIndex.tcl | 2 - .../lib_tcl8/zint-2.13.0/readme.txt | 27 - .../lib_tcl8/zint-2.13.0/zint.dll | Bin 622592 -> 0 bytes 25 files changed, 6333 insertions(+), 1412 deletions(-) create mode 100644 src/bootsupport/modules/punk/zip-0.1.0.tm create mode 100644 src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/logger-0.9.5.tm create mode 100644 src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm create mode 100644 src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/logger-0.9.5.tm create mode 100644 src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm delete mode 100644 src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/licence.txt delete mode 100644 src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/pkgIndex.tcl delete mode 100644 src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/readme.txt delete mode 100644 src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/zint.dll diff --git a/src/bootsupport/modules/include_modules.config b/src/bootsupport/modules/include_modules.config index 490025b..75a091d 100644 --- a/src/bootsupport/modules/include_modules.config +++ b/src/bootsupport/modules/include_modules.config @@ -57,6 +57,7 @@ set bootsupport_modules [list\ modules punk::path\ modules punk::repo\ modules punk::tdl\ + modules punk::zip\ modules punk::winpath\ modules textblock\ modules oolib\ diff --git a/src/bootsupport/modules/overtype-1.6.5.tm b/src/bootsupport/modules/overtype-1.6.5.tm index f7e4c1a..38ce71c 100644 --- a/src/bootsupport/modules/overtype-1.6.5.tm +++ b/src/bootsupport/modules/overtype-1.6.5.tm @@ -165,16 +165,17 @@ tcl::namespace::eval overtype::priv { #could return larger than renderwidth proc _get_row_append_column {row} { + #obsolete? upvar outputlines outputlines set idx [expr {$row -1}] if {$row <= 1 || $row > [llength $outputlines]} { return 1 } else { - upvar opt_overflow opt_overflow + upvar opt_expand_right expand_right upvar renderwidth renderwidth set existinglen [punk::ansi::printing_length [lindex $outputlines $idx]] set endpos [expr {$existinglen +1}] - if {$opt_overflow} { + if {$expand_right} { return $endpos } else { if {$endpos > $renderwidth} { @@ -204,14 +205,14 @@ tcl::namespace::eval overtype { proc renderspace {args} { #*** !doctools #[call [fun overtype::renderspace] [arg args] ] - #[para] usage: ?-transparent [lb]0|1[rb]? ?-overflow [lb]1|0[rb]? ?-ellipsis [lb]1|0[rb]? ?-ellipsistext ...? undertext overtext + #[para] usage: ?-transparent [lb]0|1[rb]? ?-expand_right [lb]1|0[rb]? ?-ellipsis [lb]1|0[rb]? ?-ellipsistext ...? undertext overtext # @c overtype starting at left (overstrike) # @c can/should we use something like this?: 'format "%-*s" $len $overtext variable default_ellipsis_horizontal if {[llength $args] < 2} { - error {usage: ?-width ? ?-startcolumn ? ?-transparent [0|1|]? ?-overflow [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext} + error {usage: ?-width ? ?-startcolumn ? ?-transparent [0|1|]? ?-expand_right [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext} } set optargs [lrange $args 0 end-2] if {[llength $optargs] % 2 == 0} { @@ -228,30 +229,46 @@ tcl::namespace::eval overtype { } } set opts [tcl::dict::create\ - -bias ignored\ - -width \uFFEF\ - -height \uFFEF\ + -bias ignored\ + -width \uFFEF\ + -height \uFFEF\ -startcolumn 1\ - -wrap 0\ - -ellipsis 0\ + -wrap 0\ + -ellipsis 0\ -ellipsistext $default_ellipsis_horizontal\ -ellipsiswhitespace 0\ - -overflow 0\ - -appendlines 1\ - -transparent 0\ - -exposed1 \uFFFD\ - -exposed2 \uFFFD\ - -experimental 0\ - -looplimit \uFFEF\ - -crm_mode 0\ - -reverse_mode 0\ + -expand_right 0\ + -appendlines 1\ + -transparent 0\ + -exposed1 \uFFFD\ + -exposed2 \uFFFD\ + -experimental 0\ + -cp437 1\ + -looplimit \uFFEF\ + -crm_mode 0\ + -reverse_mode 0\ + -insert_mode 0\ + -console {stdin stdout stderr}\ ] + #expand_right is perhaps consistent with the idea of the page_size being allowed to grow horizontally.. + # it does not necessarily mean the viewport grows. (which further implies need for horizontal scrolling) + # - it does need to be within some concept of terminal width - as columns must be addressable by ansi sequences. + # - This implies the -width option value must grow if it is tied to the concept of renderspace terminal width! REVIEW. + # - further implication is that if expand_right grows the virtual renderspace terminal width - + # then some sort of reflow/rerender needs to be done for preceeding lines? + # possibly not - as expand_right is distinct from a normal terminal-width change event, + # expand_right being primarily to support other operations such as textblock::table + + #todo - viewport width/height as separate concept to terminal width/height? #-ellipsis args not used if -wrap is true foreach {k v} $argsflags { switch -- $k { - -looplimit - -width - -height - -startcolumn - -bias - -wrap - -ellipsis - -ellipsistext - -ellipsiswhitespace - -overflow - -appendlines + -looplimit - -width - -height - -startcolumn - -bias - -wrap - -ellipsis - -ellipsistext - -ellipsiswhitespace - -transparent - -exposed1 - -exposed2 - -experimental - - -reverse_mode - -crm_mode { + - -expand_right - -appendlines + - -reverse_mode - -crm_mode - -insert_mode + - -cp437 + - -console { tcl::dict::set opts $k $v } default { @@ -261,7 +278,8 @@ tcl::namespace::eval overtype { } #set opts [tcl::dict::merge $defaults $argsflags] # -- --- --- --- --- --- - set opt_overflow [tcl::dict::get $opts -overflow] + #review - expand_left for RTL text? + set opt_expand_right [tcl::dict::get $opts -expand_right] ##### # review -wrap should map onto DECAWM terminal mode - the wrap 2 idea may not fit in with this?. set opt_wrap [tcl::dict::get $opts -wrap] ;#wrap 1 is hard wrap cutting word at exact column, or 1 column early for 2w-glyph, wrap 2 is for language-based word-wrap algorithm (todo) @@ -279,23 +297,31 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- set opt_crm_mode [tcl::dict::get $opts -crm_mode] set opt_reverse_mode [tcl::dict::get $opts -reverse_mode] + set opt_insert_mode [tcl::dict::get $opts -insert_mode] + # -- --- --- --- --- --- + set opt_cp437 [tcl::dict::get $opts -cp437] + + + #initial state for renderspace 'terminal' reset + set initial_state [dict create\ + -width $opt_width\ + -height $opt_height\ + -crm_mode $opt_crm_mode\ + -reverse_mode $opt_reverse_mode\ + -insert_mode $opt_insert_mode\ + -cp437 $opt_cp437\ + ] # ---------------------------- # -experimental dev flag to set flags etc # ---------------------------- set data_mode 0 - set test_mode 1 set info_mode 0 set edit_mode 0 set opt_experimental [tcl::dict::get $opts -experimental] foreach o $opt_experimental { switch -- $o { - test_mode { - set test_mode 1 - set info_mode 1 - } old_mode { - set test_mode 0 set info_mode 1 } data_mode { @@ -309,11 +335,10 @@ tcl::namespace::eval overtype { } } } - set test_mode 1 ;#try to eliminate # ---------------------------- #modes - set insert_mode 0 ;#can be toggled by insert key or ansi IRM sequence ESC [ 4 h|l + set insert_mode $opt_insert_mode ;#can be toggled by insert key or ansi IRM sequence ESC [ 4 h|l set autowrap_mode $opt_wrap set reverse_mode $opt_reverse_mode set crm_mode $opt_crm_mode @@ -377,49 +402,45 @@ tcl::namespace::eval overtype { set looplimit [expr {[tcl::string::length $overblock] + 10}] } - if {!$test_mode} { - set inputchunks [split $overblock \n] - } else { - set scheme 3 - switch -- $scheme { - 0 { - #one big chunk - set inputchunks [list $overblock] + set scheme 3 + switch -- $scheme { + 0 { + #one big chunk + set inputchunks [list $overblock] + } + 1 { + set inputchunks [punk::ansi::ta::split_codes $overblock] + } + 2 { + + #split into lines if possible first - then into plaintext/ansi-sequence chunks ? + set inputchunks [list ""] ;#put an empty plaintext split in for starters + set i 1 + set lines [split $overblock \n] + foreach ln $lines { + if {$i < [llength $lines]} { + append ln \n + } + set sequence_split [punk::ansi::ta::split_codes_single $ln] ;#use split_codes Not split_codes_single? + set lastpt [lindex $inputchunks end] + lset inputchunks end [tcl::string::cat $lastpt [lindex $sequence_split 0]] + lappend inputchunks {*}[lrange $sequence_split 1 end] + incr i } - 1 { - set inputchunks [punk::ansi::ta::split_codes $overblock] + } + 3 { + #it turns out line based chunks are faster than the above.. probably because some of those end up doing the regex splitting twice + set lflines [list] + set inputchunks [split $overblock \n] + foreach ln $inputchunks { + append ln \n + lappend lflines $ln } - 2 { - - #split into lines if possible first - then into plaintext/ansi-sequence chunks ? - set inputchunks [list ""] ;#put an empty plaintext split in for starters - set i 1 - set lines [split $overblock \n] - foreach ln $lines { - if {$i < [llength $lines]} { - append ln \n - } - set sequence_split [punk::ansi::ta::split_codes_single $ln] ;#use split_codes Not split_codes_single? - set lastpt [lindex $inputchunks end] - lset inputchunks end [tcl::string::cat $lastpt [lindex $sequence_split 0]] - lappend inputchunks {*}[lrange $sequence_split 1 end] - incr i - } + if {[llength $lflines]} { + lset lflines end [tcl::string::range [lindex $lflines end] 0 end-1] } - 3 { - #it turns out line based chunks are faster than the above.. probably because some of those end up doing the regex splitting twice - set lflines [list] - set inputchunks [split $overblock \n] - foreach ln $inputchunks { - append ln \n - lappend lflines $ln - } - if {[llength $lflines]} { - lset lflines end [tcl::string::range [lindex $lflines end] 0 end-1] - } - set inputchunks $lflines[unset lflines] + set inputchunks $lflines[unset lflines] - } } } @@ -441,11 +462,11 @@ tcl::namespace::eval overtype { #underlines are not necessarily processed in order - depending on cursor-moves applied from overtext set row 1 - if {$data_mode} { - set col [_get_row_append_column $row] - } else { + #if {$data_mode} { + # set col [_get_row_append_column $row] + #} else { set col $opt_startcolumn - } + #} set instruction_stats [tcl::dict::create] @@ -473,33 +494,27 @@ tcl::namespace::eval overtype { } #review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary - #but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l - set LASTCALL [list -info 1\ - -insert_mode $insert_mode\ - -crm_mode $crm_mode\ - -autowrap_mode $autowrap_mode\ - -reverse_mode $reverse_mode\ - -transparent $opt_transparent\ - -width $renderwidth\ - -exposed1 $opt_exposed1\ - -exposed2 $opt_exposed2\ - -overflow $opt_overflow -cursor_column $col -cursor_row $row $undertext $overtext] - set rinfo [renderline -experimental $opt_experimental\ + set renderargs [list -experimental $opt_experimental\ + -cp437 $opt_cp437\ -info 1\ -crm_mode $crm_mode\ -insert_mode $insert_mode\ -autowrap_mode $autowrap_mode\ - -reverse_mode $reverse_mode\ + -reverse_mode $reverse_mode\ -cursor_restore_attributes $cursor_saved_attributes\ -transparent $opt_transparent\ -width $renderwidth\ -exposed1 $opt_exposed1\ -exposed2 $opt_exposed2\ - -overflow $opt_overflow\ + -expand_right $opt_expand_right\ -cursor_column $col\ -cursor_row $row\ $undertext\ $overtext\ - ] + ] + set LASTCALL $renderargs + set rinfo [renderline {*}$renderargs] + set instruction [tcl::dict::get $rinfo instruction] set insert_mode [tcl::dict::get $rinfo insert_mode] set autowrap_mode [tcl::dict::get $rinfo autowrap_mode] ;# @@ -523,6 +538,7 @@ tcl::namespace::eval overtype { #lset replay_codes_overlay [expr $overidx+1] [tcl::dict::get $rinfo replay_codes_overlay] set replay_codes_overlay [tcl::dict::get $rinfo replay_codes_overlay] if {0 && $reverse_mode} { + #test branch - todo - prune puts stderr "---->[ansistring VIEW $replay_codes_overlay] rendered: $rendered" #review #JMN3 @@ -579,29 +595,17 @@ tcl::namespace::eval overtype { #keeping separate branches for debugging - review and merge as appropriate when stable tcl::dict::incr instruction_stats $instruction switch -- $instruction { - {} { - if {$test_mode == 0} { - incr row - if {$data_mode} { - set col [_get_row_append_column $row] - if {$col > $renderwidth} { + reset { + #reset the 'renderspace terminal' (not underlying terminal) + set row 1 + set col 1 - } - } else { - set col 1 - } - } else { - #lf included in data - set row $post_render_row - set col $post_render_col - #set col 1 - #if {$post_render_row != $renderedrow} { - # set col 1 - #} else { - # set col $post_render_col - #} - } + } + {} { + #lf included in data + set row $post_render_row + set col $post_render_col } up { @@ -704,7 +708,14 @@ tcl::namespace::eval overtype { puts stdout ">>>[a+ red bold]overflow_right during restore_cursor[a]" - set sub_info [overtype::renderline -info 1 -width $renderwidth -insert_mode $insert_mode -autowrap_mode $autowrap_mode -overflow [tcl::dict::get $opts -overflow] "" $overflow_right] + set sub_info [overtype::renderline -info 1\ + -width $renderwidth\ + -insert_mode $insert_mode\ + -autowrap_mode $autowrap_mode\ + -expand_right [tcl::dict::get $opts -opt_expand_right]\ + ""\ + $overflow_right\ + ] set foldline [tcl::dict::get $sub_info result] set insert_mode [tcl::dict::get $sub_info insert_mode] ;#probably not needed..? set autowrap_mode [tcl::dict::get $sub_info autowrap_mode] ;#nor this.. @@ -735,7 +746,7 @@ tcl::namespace::eval overtype { #overflow + unapplied? } lf_start { - #raw newlines - must be test_mode + #raw newlines # ---------------------- #test with fruit.ans #test - treating as newline below... @@ -751,48 +762,58 @@ tcl::namespace::eval overtype { } lf_mid { - if 0 { - #set rhswidth [punk::ansi::printing_length $overflow_right] - #only show debug when we have overflow? - set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -nul 1 -lf 1 -vt 1 $rendered]] - set lhs [textblock::frame -title "rendered $visualwidth cols" -subtitle "row-$renderedrow" $lhs] - - set rhs "" - if {$overflow_right ne ""} { - set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -nul 1 -lf 1 -vt 1 $overflow_right]] - set rhs [textblock::frame -title overflow_right $rhs] - } - puts [textblock::join $lhs " $post_render_col " $rhs] - } - - if {!$test_mode} { - #rendered - append rendered $overflow_right - #set replay_codes_overlay "" + set edit_mode 0 + if {$edit_mode} { + set inputchunks [linsert $inputchunks 0 $overflow_right$unapplied] set overflow_right "" - - - set row $renderedrow - + set unapplied "" + set row $post_render_row + #set col $post_render_col set col $opt_startcolumn - incr row - #only add newline if we're at the bottom if {$row > [llength $outputlines]} { lappend outputlines {*}[lrepeat 1 ""] } } else { - set edit_mode 0 - if {$edit_mode} { - set inputchunks [linsert $inputchunks 0 $overflow_right$unapplied] - set overflow_right "" - set unapplied "" + if 1 { + if {$overflow_right ne ""} { + if {$opt_expand_right} { + append rendered $overflow_right + set overflow_right "" + } else { + set overflow_width [punk::ansi::printing_length $overflow_right] + if {$visualwidth + $overflow_width <= $renderwidth} { + append rendered $overflow_right + set overflow_right "" + } else { + if {$visualwidth < $renderwidth} { + set graphemes [punk::char::grapheme_split $overflow_width] + set add "" + set addlen $visualwidth + set remaining_overflow $graphemes + foreach g $graphemes { + set w [overtype::grapheme_width_cached] + if {$addlen + $w <= $renderwidth} { + append add $g + incr addlen $w + lpop remaining_overflow + } else { + break + } + } + append rendered $add + set overflow_right [join $remaining_overflow ""] + } + } + } + } set row $post_render_row - #set col $post_render_col set col $opt_startcolumn if {$row > [llength $outputlines]} { lappend outputlines {*}[lrepeat 1 ""] } } else { + #old version - known to work with various ansi graphics - e.g fruit.ans + # - but fails to limit lines to renderwidth when expand_right == 0 append rendered $overflow_right set overflow_right "" set row $post_render_row @@ -851,38 +872,28 @@ tcl::namespace::eval overtype { set row $post_render_row set col $post_render_col if {$insert_lines_below == 1} { - if {$test_mode == 0} { - set row $renderedrow - set outputlines [linsert $outputlines [expr {$renderedrow }] {*}[lrepeat $insert_lines_below ""]] ;#note - linsert can add to end too - incr row $insert_lines_below - set col $opt_startcolumn - } else { - #set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $rendered]] - #set lhs [textblock::frame -title rendered -subtitle "row-$renderedrow" $lhs] - #set rhs "" - #if {$overflow_right ne ""} { - # set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $overflow_right]] - # set rhs [textblock::frame -title overflow_right $rhs] - #} - #puts [textblock::join $lhs $rhs] - - #rendered - append rendered $overflow_right - # - - - set overflow_right "" - set row $renderedrow - #only add newline if we're at the bottom - if {$row > [llength $outputlines]} { - lappend outputlines {*}[lrepeat $insert_lines_below ""] - } - incr row $insert_lines_below - set col $opt_startcolumn + #set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $rendered]] + #set lhs [textblock::frame -title rendered -subtitle "row-$renderedrow" $lhs] + #set rhs "" + #if {$overflow_right ne ""} { + # set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $overflow_right]] + # set rhs [textblock::frame -title overflow_right $rhs] + #} + #puts [textblock::join $lhs $rhs] + #rendered + append rendered $overflow_right + # + set overflow_right "" + set row $renderedrow + #only add newline if we're at the bottom + if {$row > [llength $outputlines]} { + lappend outputlines {*}[lrepeat $insert_lines_below ""] } + incr row $insert_lines_below + set col $opt_startcolumn } } else { set row $post_render_row @@ -974,7 +985,6 @@ tcl::namespace::eval overtype { incr row set col $opt_startcolumn ;#whether wrap or not - next data is at column 1 ?? } else { - #this works for test_mode (which should become the default) - but could give a bad result otherwise - review - add tests fix. set col $post_render_col #set unapplied "" ;#this seems wrong? #set unapplied [tcl::string::range $unapplied 1 end] @@ -1052,7 +1062,7 @@ tcl::namespace::eval overtype { } - if {!$opt_overflow && !$autowrap_mode} { + if {!$opt_expand_right && !$autowrap_mode} { #not allowed to overflow column or wrap therefore we get overflow data to truncate if {[tcl::dict::get $opts -ellipsis]} { set show_ellipsis 1 @@ -1130,7 +1140,6 @@ tcl::namespace::eval overtype { set debugmsg "" append debugmsg "${Y}${sep_header}${RST}" \n append debugmsg "looplimit $looplimit reached\n" - append debugmsg "test_mode:$test_mode\n" append debugmsg "data_mode:$data_mode\n" append debugmsg "opt_appendlines:$opt_appendlines\n" append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n" @@ -1433,7 +1442,7 @@ tcl::namespace::eval overtype { #padded overtext #lappend outputlines [renderline -insert_mode 0 -transparent $opt_transparent -startcolumn [expr {$left_exposed + 1}] $undertext $overtext] #Note - we still need overflow here - as although the overtext is short - it may oveflow due to the startoffset - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -overflow $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -expand_right $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] lappend outputlines [tcl::dict::get $rinfo result] } set replay_codes [tcl::dict::get $rinfo replay_codes] @@ -1584,7 +1593,7 @@ tcl::namespace::eval overtype { set overflowlength [expr {$overtext_datalen - $renderwidth}] if {$overflowlength > 0} { #raw overtext wider than undertext column - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -exposed1 $opt_exposed1 -exposed2 $opt_exposed2 -overflow $opt_overflow -startcolumn [expr {1 + $startoffset}] $undertext $overtext] + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -exposed1 $opt_exposed1 -exposed2 $opt_exposed2 -expand_right $opt_overflow -startcolumn [expr {1 + $startoffset}] $undertext $overtext] set replay_codes [tcl::dict::get $rinfo replay_codes] set rendered [tcl::dict::get $rinfo result] set overflow_right [tcl::dict::get $rinfo overflow_right] @@ -1632,8 +1641,8 @@ tcl::namespace::eval overtype { } else { #padded overtext #lappend outputlines [renderline -insert_mode 0 -transparent $opt_transparent -startcolumn [expr {$left_exposed + 1}] $undertext $overtext] - #Note - we still need overflow here - as although the overtext is short - it may oveflow due to the startoffset - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -overflow $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] + #Note - we still need expand_right here - as although the overtext is short - it may oveflow due to the startoffset + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -expand_right $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] #puts stderr "--> [ansistring VIEW -lf 1 -nul 1 $rinfo] <--" set overflow_right [tcl::dict::get $rinfo overflow_right] set unapplied [tcl::dict::get $rinfo unapplied] @@ -1655,7 +1664,8 @@ tcl::namespace::eval overtype { #-returnextra enables returning of overflow and length #review - use punk::ansi::ta::detect to short-circuit processing and do simpler string calcs as an optimisation? #review - DECSWL/DECDWL double width line codes - very difficult/impossible to align and compose with other elements - #(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char) + #(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char? + # This would probably be impractical to support for different fonts) #todo - review transparency issues with single/double width characters #bidi - need a base direction and concept of directional runs for RTL vs LTR - may be best handled at another layer? proc renderline {args} { @@ -1677,8 +1687,10 @@ tcl::namespace::eval overtype { #[para] The main 3 are the result, overflow_right, and unapplied. #[para] Renderline handles cursor movements from either keystrokes or ANSI sequences but for a full system the aforementioned loop will need to be in place to manage the set of lines under manipulation. + #puts stderr "renderline '$args'" + if {[llength $args] < 2} { - error {usage: ?-info 0|1? ?-startcolumn ? ?-cursor_column ? ?-cursor_row |""? ?-transparent [0|1|]? ?-overflow [1|0]? undertext overtext} + error {usage: ?-info 0|1? ?-startcolumn ? ?-cursor_column ? ?-cursor_row |""? ?-transparent [0|1|]? ?-expand_right [1|0]? undertext overtext} } lassign [lrange $args end-1 end] under over if {[string first \n $under] >= 0} { @@ -1692,7 +1704,7 @@ tcl::namespace::eval overtype { set opts [tcl::dict::create\ -etabs 0\ -width \uFFEF\ - -overflow 0\ + -expand_right 0\ -transparent 0\ -startcolumn 1\ -cursor_column 1\ @@ -1713,13 +1725,13 @@ tcl::namespace::eval overtype { #cursor_row, when numeric will allow detection of certain row moves that are still within our row - allowing us to avoid an early return #An empty string for cursor_row tells us we have no info about our own row context, and to return with an unapplied string if any row move occurs - #exposed1 and exposed2 for first and second col of underying 2wide char which is truncated by transparency or overflow + #exposed1 and exposed2 for first and second col of underying 2wide char which is truncated by transparency, currsor movements to 2nd charcol, or overflow/expand_right #todo - return info about such grapheme 'cuts' in -info structure and/or create option to raise an error set argsflags [lrange $args 0 end-2] tcl::dict::for {k v} $argsflags { switch -- $k { - -experimental - -cp437 - -width - -overflow - -transparent - -startcolumn - -cursor_column - -cursor_row + -experimental - -cp437 - -width - -expand_right - -transparent - -startcolumn - -cursor_column - -cursor_row - -crm_mode - -insert_mode - -autowrap_mode - -reverse_mode - -info - -exposed1 - -exposed2 - -cursor_restore_attributes { tcl::dict::set opts $k $v @@ -1732,7 +1744,7 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- --- --- --- --- --- --- set opt_width [tcl::dict::get $opts -width] set opt_etabs [tcl::dict::get $opts -etabs] - set opt_overflow [tcl::dict::get $opts -overflow] + set opt_expand_right [tcl::dict::get $opts -expand_right] set opt_colstart [tcl::dict::get $opts -startcolumn] ;#lhs limit for overlay - an offset to cursor_column - first visible column is 1. 0 or < 0 are before the start of the underlay set opt_colcursor [tcl::dict::get $opts -cursor_column];#start cursor column relative to overlay set opt_row_context [tcl::dict::get $opts -cursor_row] @@ -1752,17 +1764,7 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- --- --- --- --- --- --- set temp_cursor_saved [tcl::dict::get $opts -cursor_restore_attributes] - set test_mode 0 set cp437_glyphs [tcl::dict::get $opts -cp437] - foreach e [tcl::dict::get $opts -experimental] { - switch -- $e { - test_mode { - set test_mode 1 - set cp437_glyphs 1 - } - } - } - set test_mode 1 ;#try to elminate set cp437_map [tcl::dict::create] if {$cp437_glyphs} { set cp437_map [set ::punk::ansi::cp437_map] @@ -1852,7 +1854,7 @@ tcl::namespace::eval overtype { set u_codestack [list] #u_gx_stack probably isn't really a stack - I don't know if g0 g1 can stack or not - for now we support only g0 anyway set u_gx_stack [list] ;#separate stack for g0 (g1 g2 g3?) graphics on and off (DEC special graphics) - #set pt_underchars "" ;#for string_columns length calculation for overflow 0 truncation + #set pt_underchars "" ;#for string_columns length calculation for expand_right 0 truncation set remainder [list] ;#for returnextra foreach {pt code} $undermap { #pt = plain text @@ -1996,47 +1998,25 @@ tcl::namespace::eval overtype { #consider also if there are other codes that should be stacked..? } - if {!$test_mode} { - #fill columns to width with spaces, and carry over stacks - we will have to keep track of where the underlying data ends manually - TODO - #Specifying a width is suitable for terminal-like applications and text-blocks - if {$opt_width ne "\uFFEF"} { - if {[llength $understacks]} { - set cs $u_codestack - set gs $u_gx_stack - } else { - set cs [list] - set gs [list] - } - if {[llength $undercols]< $opt_width} { - set diff [expr {$opt_width- [llength $undercols]}] - if {$diff > 0} { - lappend undercols {*}[lrepeat $diff " "] - lappend understacks {*}[lrepeat $diff $cs] - lappend understacks_gx {*}[lrepeat $diff $gs] - } - } + #NULL empty cell indicator + if {$opt_width ne "\uFFEF"} { + if {[llength $understacks]} { + set cs $u_codestack + set gs $u_gx_stack + } else { + set cs [list] + set gs [list] } - } else { - #NULL empty cell indicator - if {$opt_width ne "\uFFEF"} { - if {[llength $understacks]} { - set cs $u_codestack - set gs $u_gx_stack - } else { - set cs [list] - set gs [list] - } - if {[llength $undercols]< $opt_width} { - set diff [expr {$opt_width- [llength $undercols]}] - if {$diff > 0} { - lappend undercols {*}[lrepeat $diff "\u0000"] - lappend understacks {*}[lrepeat $diff $cs] - lappend understacks_gx {*}[lrepeat $diff $gs] - } + if {[llength $undercols]< $opt_width} { + set diff [expr {$opt_width- [llength $undercols]}] + if {$diff > 0} { + lappend undercols {*}[lrepeat $diff "\u0000"] + lappend understacks {*}[lrepeat $diff $cs] + lappend understacks_gx {*}[lrepeat $diff $gs] } } - } + if {$opt_width ne "\uFFEF"} { set renderwidth $opt_width } else { @@ -2127,8 +2107,10 @@ tcl::namespace::eval overtype { lappend overlay_grapheme_control_stacks $o_codestack } } else { + set tsbegin [clock micros] foreach grapheme_original [punk::char::grapheme_split $pt] { set pt_crm [ansistring VIEW -nul 1 -lf 2 -vt 2 -ff 2 $grapheme_original] + #puts stderr "ptlen [string length $pt] graphemelen[string length $grapheme_original] pt_crmlen[string length $pt_crm] $pt_crm" foreach grapheme [punk::char::grapheme_split $pt_crm] { if {$grapheme eq "\n"} { lappend overlay_grapheme_control_stacks $o_codestack @@ -2142,6 +2124,8 @@ tcl::namespace::eval overtype { } } } + set elapsed [expr {[clock micros] - $tsbegin}] + puts stderr "ptlen [string length $pt] elapsedus:$elapsed" } #only stack SGR (graphics rendition) codes - not title sets, cursor moves etc @@ -2259,11 +2243,12 @@ tcl::namespace::eval overtype { # -- --- --- #we need to initialise overflow_idx before any potential row-movements - as they need to perform a loop break and force in_excess to 1 - if {$opt_overflow} { - #somewhat counterintuitively - overflow true means we can have lines as long as we want, but either way there can be excess data that needs to be thrown back to the calling loop. + if {$opt_expand_right} { + #expand_right true means we can have lines as long as we want, but either way there can be excess data that needs to be thrown back to the calling loop. + #we currently only support horizontal expansion to the right (review regarding RTL text!) set overflow_idx -1 } else { - #overflow zero - we can't grow beyond our column width - so we get ellipsis or truncation + #expand_right zero - we can't grow beyond our column width - so we get ellipsis or truncation if {$opt_width ne "\uFFEF"} { set overflow_idx [expr {$opt_width}] } else { @@ -2304,7 +2289,7 @@ tcl::namespace::eval overtype { #movements only occur within the overlay range. #an underlay is however not necessary.. e.g - #renderline -overflow 1 "" data + #renderline -expand_right 1 "" data #set re_mode {\x1b\[\?([0-9]*)(h|l)} ;#e.g DECAWM #set re_col_move {\x1b\[([0-9]*)(C|D|G)$} @@ -2331,7 +2316,7 @@ tcl::namespace::eval overtype { g { set ch $item #crm_mode affects both graphic and control - if {$crm_mode} { + if {0 && $crm_mode} { set chars [ansistring VIEW -nul 1 -lf 2 -vt 2 -ff 2 $ch] set chars [string map [list \n "\x1b\[00001E"] $chars] if {[llength [split $chars ""]] > 1} { @@ -2376,7 +2361,7 @@ tcl::namespace::eval overtype { #linefeed after final column #puts "---c at overflow_idx=$overflow_idx" incr cursor_row - set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to opt_overflow = 1|2 + set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to expand_right = 1 set instruction lf_overflow ;#only special treatment is to give it it's own instruction in case caller needs to handle differently priv::render_unapplied $overlay_grapheme_control_list $gci break @@ -2384,7 +2369,10 @@ tcl::namespace::eval overtype { #linefeed occurred in middle or at end of text #puts "---mid-or-end-text-linefeed idx:$idx overflow_idx:$overflow_idx" incr cursor_row - set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to opt_overflow = 1|2 + if {$idx == -1 || $overflow_idx > $idx} { + #don't set overflow_idx higher if it's already set lower and we're adding graphemes to overflow + set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to expand_right = 1 + } set instruction lf_mid priv::render_unapplied $overlay_grapheme_control_list $gci break @@ -2466,23 +2454,35 @@ tcl::namespace::eval overtype { #tab of some length dependent on tabstops/elastic tabstop settings? } } elseif {$idx >= $overflow_idx} { - #jmn? - set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci-1]] - #set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] - #don't incr idx beyond the overflow_idx - #idx_over already incremented - decrement so current overlay grapheme stacks go to unapplied - incr idx_over -1 - #priv::render_unapplied $overlay_grapheme_control_list [expr {$gci-1}] ;#back one index here too - priv::render_this_unapplied $overlay_grapheme_control_list $gci ;# - set instruction overflow - break + #REVIEW + set next_gc [lindex $overlay_grapheme_control_list $gci+1] ;#next grapheme or control + lassign $next_gc next_type next_item + if {$autowrap_mode || $next_type ne "g"} { + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci-1]] + #set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + #don't incr idx beyond the overflow_idx + #idx_over already incremented - decrement so current overlay grapheme stacks go to unapplied + incr idx_over -1 + #priv::render_unapplied $overlay_grapheme_control_list [expr {$gci-1}] ;#back one index here too + priv::render_this_unapplied $overlay_grapheme_control_list $gci ;# + set instruction overflow + break + } else { + #no point throwing back to caller for each grapheme that is overflowing + #without this branch - renderline would be called with overtext reducing only by one grapheme per call + #processing a potentially long overtext each time (ie - very slow) + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + #JMN4 + + } } } else { #review. - #This corresponds to opt_overflow being true (at least until overflow_idx is in some cases forced to a value when throwing back to calling loop) + #overflow_idx = -1 + #This corresponds to expand_right being true (at least until overflow_idx is in some cases forced to a value when throwing back to calling loop) } - if {($do_transparency && [regexp $opt_transparent $ch])} { + if {($do_transparency && [regexp $opt_transparent $ch])} { #pre opt_colstart is effectively transparent (we have applied padding of required number of columns to left of overlay) if {$idx > [llength $outcols]-1} { lappend outcols " " @@ -2621,7 +2621,7 @@ tcl::namespace::eval overtype { } incr idx } - if {($cursor_column < [llength $outcols]) || $overflow_idx == -1 || $test_mode} { + if {($cursor_column < [llength $outcols]) || $overflow_idx == -1} { incr cursor_column } } elseif {$uwidth > 1} { @@ -2655,12 +2655,6 @@ tcl::namespace::eval overtype { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx incr cursor_column - if {$overflow_idx !=-1 && !$test_mode} { - #overflow - if {$cursor_column > [llength $outcols]} { - set cursor_column [llength $outcols] - } - } } } } @@ -2704,6 +2698,7 @@ tcl::namespace::eval overtype { set leadernorm [tcl::string::range [tcl::string::map [list\ \x1b\[< 1006\ \x1b\[ 7CSI\ + \x1bP 7DCS\ \x9b 8CSI\ \x1b\] 7OSC\ \x9d 8OSC\ @@ -2720,6 +2715,11 @@ tcl::namespace::eval overtype { 7CSI - 7OSC { set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 2 end]] } + 7DCS { + #ESC P + #Device Control String https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Controls-beginning-with-ESC:ESC-F.C74 + set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 2 end]] + } 7ESC { set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 1 end]] } @@ -2812,7 +2812,7 @@ tcl::namespace::eval overtype { if {$overflow_idx == -1} { incr max } - if {$test_mode && $cursor_column == $max+1} { + if {$cursor_column == $max+1} { #move_forward while in overflow incr cursor_column -1 } @@ -2829,7 +2829,7 @@ tcl::namespace::eval overtype { } #horizontal movement beyond line extent needs to wrap - throw back to caller - #we may have both overflow_rightand unapplied data + #we may have both overflow_right and unapplied data #(can have overflow_right if we were in insert_mode and processed chars prior to this movement) #leave row as is - caller will need to determine how many rows the column-movement has consumed incr cursor_column $num ;#give our caller the necessary info as columns from start of row @@ -2844,7 +2844,8 @@ tcl::namespace::eval overtype { } } } else { - if {!$opt_overflow || ($cursor_column + $num) <= [llength $outcols+1]} { + #review - dead branch + if {!$expand_right || ($cursor_column + $num) <= [llength $outcols+1]} { incr idx $num incr cursor_column $num } else { @@ -3052,55 +3053,99 @@ tcl::namespace::eval overtype { } } J { - puts stderr "overtype::renderline ED - ERASE IN DISPLAY (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - if {$param eq ""} {set param 0} - switch -exact -- $param { - 0 { - #clear from cursor to end of screen - } - 1 { - #clear from cursor to beginning of screen - } - 2 { - #clear entire screen - #ansi.sys - move cursor to upper left REVIEW - set cursor_row 1 - set cursor_column 1 - set idx [expr {$cursor_column -1}] - set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] - incr idx_over - priv::render_unapplied $overlay_grapheme_control_list $gci - set instruction move - break - } - 3 { - #clear entire screen. presumably cursor doesn't move - otherwise it would be same as 2J ? - + set modegroup [tcl::string::index $codenorm 4] ;#e.g ? + switch -exact -- $modegroup { + ? { + #CSI ? Pn J - selective erase + puts stderr "overtype::renderline ED - SELECTIVE ERASE IN DISPLAY (UNIMPLEMENTED) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" } default { + puts stderr "overtype::renderline ED - ERASE IN DISPLAY (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of screen + } + 1 { + #clear from cursor to beginning of screen + } + 2 { + #clear entire screen + #ansi.sys - move cursor to upper left REVIEW + set cursor_row 1 + set cursor_column 1 + set idx [expr {$cursor_column -1}] + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + incr idx_over + priv::render_unapplied $overlay_grapheme_control_list $gci + set instruction move + break + } + 3 { + #clear entire screen. presumably cursor doesn't move - otherwise it would be same as 2J ? + + } + default { + } + } + } } - } K { - puts stderr "overtype::renderline EL - ERASE IN LINE (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - if {$param eq ""} {set param 0} - switch -exact -- $param { - 0 { - #clear from cursor to end of line - } - 1 { - #clear from cursor to beginning of line + #see DECECM regarding background colour + set modegroup [tcl::string::index $codenorm 4] ;#e.g ? + switch -exact -- $modegroup { + ? { + puts stderr "overtype::renderline DECSEL - SELECTIVE ERASE IN LINE (UNIMPLEMENTED) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + set param [string range $param 1 end] ;#chop qmark + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of line - depending on DECSCA + } + 1 { + #clear from cursor to beginning of line - depending on DECSCA + + } + 2 { + #clear entire line - depending on DECSCA + } + default { + puts stderr "overtype::renderline DECSEL - SELECTIVE ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } - } - 2 { - #clear entire line } default { - puts stderr "overtype::renderline EL - ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + puts stderr "overtype::renderline EL - ERASE IN LINE (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of line + } + 1 { + #clear from cursor to beginning of line + + } + 2 { + #clear entire line + } + default { + puts stderr "overtype::renderline EL - ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } } } } + L { + puts stderr "overtype::renderline IL - Insert Line - not implemented [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + M { + #CSI Pn M - DL - Delete Line + puts stderr "overtype::renderline DL - Delete Line - not implemented [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + + } X { puts stderr "overtype::renderline X ECH ERASE CHARACTER - $param" #ECH - erase character @@ -3108,6 +3153,36 @@ tcl::namespace::eval overtype { priv::render_erasechar $idx $param #cursor position doesn't change. } + q { + set code_secondlast [tcl::string::index $codenorm end-1] + switch -exact -- $code_secondlast { + {"} { + #DECSCA - Select Character Protection Attribute + #(for use with selective erase: DECSED and DECSEL) + set param [tcl::string::range $codenorm 4 end-2] + if {$param eq ""} {set param 0} + #TODO - store like SGR in stacks - replays? + switch -exact -- $param { + 0 - 2 { + #canerase + puts stderr "overtype::renderline - DECSCA canerase not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + 1 { + #cannoterase + puts stderr "overtype::renderline - DECSCA cannoterase not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + default { + puts stderr "overtype::renderline DECSCA param '$param' not understood [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } + + } + default { + puts stderr "overtype::renderline - CSI ... q not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } + + } r { #$re_decstbm #https://www.vt100.net/docs/vt510-rm/DECSTBM.html @@ -3279,72 +3354,97 @@ tcl::namespace::eval overtype { set instruction restore_cursor break } + "{" { + + puts stderr "renderline warning - CSI.. - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + "}" { + set code_secondlast [tcl::string::index $codenorm end-1] + switch -exact -- $code_secondlast { + ' { + puts stderr "renderline warning - DECIC - Insert Column - CSI...' - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + default { + puts stderr "renderline warning - CSI.. - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + } + } ~ { - #$re_vt_sequence - lassign [split $param {;}] key mod - - #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ - # - #e.g esc \[2~ insert esc \[2;2~ shift-insert - #mod - subtract 1, and then use bitmask - #shift = 1, (left)Alt = 2, control=4, meta=8 (meta seems to do nothing on many terminals on windows? Intercepted by windows?) - #puts stderr "vt key:$key mod:$mod code:[ansistring VIEW $code]" - if {$key eq "1"} { - #home - } elseif {$key eq "2"} { - #Insert - if {$mod eq ""} { - #no modifier key - set insert_mode [expr {!$insert_mode}] - #rather than set the cursor - we return the insert mode state so the caller can decide + set code_secondlast [tcl::string::index $codenorm end-1] ;#used for e.g CSI x '~ + switch -exact -- $code_secondlast { + ' { + #DECDC - editing sequence - Delete Column + puts stderr "renderline warning - DECDC - unimplemented" } - } elseif {$key eq "3"} { - #Delete - presumably this shifts other chars in the line, with empty cells coming in from the end - switch -- $mod { - "" { - priv::render_delchar $idx - } - "5" { - #ctrl-del - delete to end of word (pwsh) - possibly word on next line if current line empty(?) + default { + #$re_vt_sequence + lassign [split $param {;}] key mod + + #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ + # + #e.g esc \[2~ insert esc \[2;2~ shift-insert + #mod - subtract 1, and then use bitmask + #shift = 1, (left)Alt = 2, control=4, meta=8 (meta seems to do nothing on many terminals on windows? Intercepted by windows?) + #puts stderr "vt key:$key mod:$mod code:[ansistring VIEW $code]" + if {$key eq "1"} { + #home + } elseif {$key eq "2"} { + #Insert + if {$mod eq ""} { + #no modifier key + set insert_mode [expr {!$insert_mode}] + #rather than set the cursor - we return the insert mode state so the caller can decide + } + } elseif {$key eq "3"} { + #Delete - presumably this shifts other chars in the line, with empty cells coming in from the end + switch -- $mod { + "" { + priv::render_delchar $idx + } + "5" { + #ctrl-del - delete to end of word (pwsh) - possibly word on next line if current line empty(?) + } + } + } elseif {$key eq "4"} { + #End + } elseif {$key eq "5"} { + #pgup + } elseif {$key eq "6"} { + #pgDn + } elseif {$key eq "7"} { + #Home + #?? + set idx [expr {$opt_colstart -1}] + set cursor_column 1 + } elseif {$key eq "8"} { + #End + } elseif {$key eq "11"} { + #F1 - or ESCOP or e.g shift F1 ESC\[1;2P + } elseif {$key eq "12"} { + #F2 - or ESCOQ + } elseif {$key eq "13"} { + #F3 - or ESCOR + } elseif {$key eq "14"} { + #F4 - or ESCOS + } elseif {$key eq "15"} { + #F5 or shift F5 ESC\[15;2~ + } elseif {$key eq "17"} { + #F6 + } elseif {$key eq "18"} { + #F7 + } elseif {$key eq "19"} { + #F8 + } elseif {$key eq "20"} { + #F9 + } elseif {$key eq "21"} { + #F10 + } elseif {$key eq "23"} { + #F11 + } elseif {$key eq "24"} { + #F12 } + } - } elseif {$key eq "4"} { - #End - } elseif {$key eq "5"} { - #pgup - } elseif {$key eq "6"} { - #pgDn - } elseif {$key eq "7"} { - #Home - #?? - set idx [expr {$opt_colstart -1}] - set cursor_column 1 - } elseif {$key eq "8"} { - #End - } elseif {$key eq "11"} { - #F1 - or ESCOP or e.g shift F1 ESC\[1;2P - } elseif {$key eq "12"} { - #F2 - or ESCOQ - } elseif {$key eq "13"} { - #F3 - or ESCOR - } elseif {$key eq "14"} { - #F4 - or ESCOS - } elseif {$key eq "15"} { - #F5 or shift F5 ESC\[15;2~ - } elseif {$key eq "17"} { - #F6 - } elseif {$key eq "18"} { - #F7 - } elseif {$key eq "19"} { - #F8 - } elseif {$key eq "20"} { - #F9 - } elseif {$key eq "21"} { - #F10 - } elseif {$key eq "23"} { - #F11 - } elseif {$key eq "24"} { - #F12 } } @@ -3358,51 +3458,72 @@ tcl::namespace::eval overtype { set modegroup [tcl::string::index $codenorm 4] ;#e.g ? = switch -exact -- $modegroup { ? { - set num [tcl::string::range $codenorm 5 end-1] ;#param between ? and h|l - switch -- $num { - 5 { - #DECSNM - reverse video - #How we simulate this to render within a block of text is an open question. - #track all SGR stacks and constantly flip based on the current SGR reverse state? - #It is the job of the calling loop to do this - so at this stage we'll just set the states - - if {$code_end eq "h"} { - #set (enable) - set reverse_mode 1 - } else { - #reset (disable) - set reverse_mode 0 + set smparams [tcl::string::range $codenorm 5 end-1] ;#params between ? and h|l + #one or more modes can be set + set smparam_list [split $smparams {;}] + foreach num $smparam_list { + switch -- $num { + "" { + #ignore empties e.g extra/trailing semicolon in params } - - } - 7 { - #DECAWM autowrap - if {$code_end eq "h"} { - #set (enable) - set autowrap_mode 1 - if {$opt_width ne "\uFFEF"} { - set overflow_idx $opt_width + 5 { + #DECSNM - reverse video + #How we simulate this to render within a block of text is an open question. + #track all SGR stacks and constantly flip based on the current SGR reverse state? + #It is the job of the calling loop to do this - so at this stage we'll just set the states + + if {$code_end eq "h"} { + #set (enable) + set reverse_mode 1 } else { - #review - this is also the cursor position when adding a char at end of line? - set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + #reset (disable) + set reverse_mode 0 } - #review - can idx ever be beyond overflow_idx limit when we change e.g with a width setting and cursor movements? presume not - but sanity check for now. - if {$idx >= $overflow_idx} { - puts stderr "renderline error - idx '$idx' >= overflow_idx '$overflow_idx' - unexpected" + + } + 7 { + #DECAWM autowrap + if {$code_end eq "h"} { + #set (enable) + set autowrap_mode 1 + if {$opt_width ne "\uFFEF"} { + set overflow_idx $opt_width + } else { + #review - this is also the cursor position when adding a char at end of line? + set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + } + #review - can idx ever be beyond overflow_idx limit when we change e.g with a width setting and cursor movements? + # presume not usually - but sanity check with warning for now. + if {$idx >= $overflow_idx} { + puts stderr "renderline warning - idx '$idx' >= overflow_idx '$overflow_idx' - unexpected" + } + } else { + #reset (disable) + set autowrap_mode 0 + #REVIEW! + set overflow_idx -1 } - } else { - #reset (disable) - set autowrap_mode 0 - set overflow_idx -1 } - } - 25 { - if {$code_end eq "h"} { - #visible cursor + 25 { + if {$code_end eq "h"} { + #visible cursor - } else { - #invisible cursor + } else { + #invisible cursor + } + } + 117 { + #DECECM - Erase Color Mode + #https://invisible-island.net/ncurses/ncurses.faq.html + #The Erase color selection controls the background color used when text is erased or new + #text is scrolled on to the screen. Screen background causes newly erased areas or + #scrolled text to be written using color index zero, the screen background. This is VT + #and DECterm compatible. Text background causes erased areas or scrolled text to be + #written using the current text background color. This is PC console compatible and is + #the factory default. + + #see also: https://unix.stackexchange.com/questions/251726/clear-to-end-of-line-uses-the-wrong-background-color-in-screen } } } @@ -3422,8 +3543,21 @@ tcl::namespace::eval overtype { # #use ansistring VIEW -nul 1 -lf 2 -ff 2 -vt 2 #https://vt100.net/docs/vt510-rm/CRM.html + #NOTE - vt100 CRM always does auto-wrap at right margin. + #disabling auto-wrap in set-up or by sequence is disabled. + #We should default to turning off auto-wrap when crm_mode enabled.. but + #displaying truncated (on rhs) crm can still be very useful - and we have optimisation in overflow to avoid excess renderline calls (per grapheme) + #we therefore could reasonably put in an exception to allow auto_wrap to be disabled after crm_mode is engaged, + #although this would be potentially an annoying difference to some.. REVIEW if {$code_end eq "h"} { set crm_mode 1 + set autowrap_mode 1 + if {$opt_width ne "\uFFEF"} { + set overflow_idx $opt_width + } else { + #review - this is also the cursor position when adding a char at end of line? + set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + } } else { set crm_mode 0 } @@ -3431,8 +3565,10 @@ tcl::namespace::eval overtype { 4 { #IRM - Insert/Replace Mode if {$code_end eq "h"} { + #CSI 4 h set insert_mode 1 } else { + #CSI 4 l #replace mode set insert_mode 0 } @@ -3480,25 +3616,49 @@ tcl::namespace::eval overtype { } } 7ESC { + # #re_other_single {\x1b(D|M|E)$} #also PM \x1b^...(ST) switch -- [tcl::string::index $codenorm 4] { + c { + #RIS - reset terminal to initial state - where 'terminal' in this case is the renderspace - not the underlying terminal! + puts stderr "renderline reset" + priv::render_unapplied $overlay_grapheme_control_list $gci + set instruction reset + break + } D { #\x84 #index (IND) #vt102-docs: "Moves cursor down one line in same column. If cursor is at bottom margin, screen performs a scroll-up" - puts stderr "ESC D not fully implemented" + puts stderr "renderline ESC D not fully implemented" incr cursor_row priv::render_unapplied $overlay_grapheme_control_list $gci set instruction down #retain cursor_column break } + E { + #\x85 + #review - is behaviour different to lf? + #todo - possibly(?) same logic as handling above. i.e return instruction depends on where column_cursor is at the time we get NEL + #leave implementation until logic for is set in stone... still under review + #It's arguable NEL is a pure cursor movement as opposed to the semantic meaning of crlf or lf in a file. + # + #Next Line (NEL) "Move the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up" + puts stderr "overtype::renderline ESC E unimplemented" + + } + H { + #\x88 + #Tab Set + puts stderr "overtype::renderline ESC H tab set unimplemented" + } M { #\x8D #Reverse Index (RI) #vt102-docs: "Moves cursor up one line in same column. If cursor is at top margin, screen performs a scroll-down" - puts stderr "ESC M not fully implemented" + puts stderr "overtype::renderline ESC M not fully implemented" set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] #move up @@ -3512,17 +3672,39 @@ tcl::namespace::eval overtype { #retain cursor_column break } - E { - #\x85 - #review - is behaviour different to lf? - #todo - possibly(?) same logic as handling above. i.e return instruction depends on where column_cursor is at the time we get NEL - #leave implementation until logic for is set in stone... still under review - #It's arguable NEL is a pure cursor movement as opposed to the semantic meaning of crlf or lf in a file. - # - #Next Line (NEL) "Move the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up" - puts stderr "ESC E unimplemented" + N { + #\x8e - affects next character only + puts stderr "overtype::renderline single shift select G2 command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + O { + #\x8f - affects next character only + puts stderr "overtype::renderline single shift select G3 command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + P { + #\x90 + #DCS - shouldn't get here - handled in 7DCS branch + #similarly \] OSC (\x9d) and \\ (\x9c) ST + } + V { + #\x96 } + W { + #\x97 + } + X { + #\x98 + #SOS + if {[string index $code end] eq "\007"} { + set sos_content [string range $code 2 end-1] ;#ST is \007 + } else { + set sos_content [string range $code 2 end-2] ;#ST is \x1b\\ + } + #return in some useful form to the caller + #TODO! + lappend sos_list [list string $sos_content row $cursor_row column $cursor_column] + puts stderr "overtype::renderline ESCX SOS UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } ^ { #puts stderr "renderline PM" #Privacy Message. @@ -3550,24 +3732,6 @@ tcl::namespace::eval overtype { #lappend to a dict element in the result for application-specific processing lappend pm_list $pm_content } - N - O { - puts stderr "overtype::renderline single shift command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } - P { - puts stderr "overtype::renderline DEVICE CONTROL STRING command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } - X { - #SOS - if {[string index $code end] eq "\007"} { - set sos_content [string range $code 2 end-1] ;#ST is \007 - } else { - set sos_content [string range $code 2 end-2] ;#ST is \x1b\\ - } - #return in some useful form to the caller - #TODO! - lappend sos_list [list string $sos_content row $cursor_row column $cursor_column] - puts stderr "overtype::renderline ESCX SOS UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } _ { #APC Application Program Command #just warn for now.. @@ -3578,6 +3742,14 @@ tcl::namespace::eval overtype { } } + } + 7DCS { + puts stderr "overtype::renderline DCS - DEVICE CONTROL STRING command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + # + + } + 7OSC - 8OSC { + } default { } @@ -3593,7 +3765,7 @@ tcl::namespace::eval overtype { } #-------- - if {$opt_overflow == 0} { + if {$opt_expand_right == 0} { #need to truncate to the width of the original undertext #review - string_width vs printing_length here. undertext requirement to be already rendered therefore punk::char::string_width ok? #set num_under_columns [punk::char::string_width $pt_underchars] ;#plaintext underchars @@ -3774,13 +3946,14 @@ tcl::namespace::eval overtype { cursor_saved_attributes $cursor_saved_attributes\ cursor_column $cursor_column\ cursor_row $cursor_row\ - opt_overflow $opt_overflow\ + expand_right $opt_expand_right\ replay_codes $replay_codes\ replay_codes_underlay $replay_codes_underlay\ replay_codes_overlay $replay_codes_overlay\ pm_list $pm_list\ ] if {$opt_returnextra == 1} { + #puts stderr "renderline: $result" return $result } else { #human/debug - map special chars to visual glyphs @@ -3805,6 +3978,7 @@ tcl::namespace::eval overtype { return $result } } else { + #puts stderr "renderline returning: result $outstring instruction $instruction unapplied $unapplied overflow_right $overflow_right" return $outstring } #return [join $out ""] diff --git a/src/bootsupport/modules/punk/ansi-0.1.1.tm b/src/bootsupport/modules/punk/ansi-0.1.1.tm index 7a2f944..267e680 100644 --- a/src/bootsupport/modules/punk/ansi-0.1.1.tm +++ b/src/bootsupport/modules/punk/ansi-0.1.1.tm @@ -106,7 +106,7 @@ tcl::namespace::eval punk::ansi::class { #overflow is a different concept - perhaps not particularly congruent with the idea of the textblock as a mini terminal emulator. #overflow effectively auto-expands the block(terminal?) width #overflow and wrap both being true won't make sense unless we implement a max_overflow concept - set o_rendered [overtype::renderspace -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] + set o_rendered [overtype::renderspace -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] if {$cksum eq "not-done"} { #if dimensions changed - the checksum won't have been done set o_rendered_what [$o_ansistringobj checksum] @@ -129,7 +129,7 @@ tcl::namespace::eval punk::ansi::class { set o_dimensions $dimensions - set rendered [overtype::renderspace -experimental {test_mode} -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] + set rendered [overtype::renderspace -cp437 1 -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] return $rendered } method render_to_input_line {args} { @@ -176,7 +176,7 @@ tcl::namespace::eval punk::ansi::class { if {$opt_minus ne "0"} { set chunk [tcl::string::range $chunk 0 end-$opt_minus] } - set rendered [overtype::renderspace -experimental {test_mode} -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" $chunk] + set rendered [overtype::renderspace -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" $chunk] set marker "" for {set i 1} {$i <= $w} {incr i} { if {$i % 10 == 0} { @@ -514,11 +514,8 @@ tcl::namespace::eval punk::ansi { set encnames [encoding names] set encoding "" set dimensions "" - set test_mode 0 foreach a $args { - if {$a eq "test_mode"} { - set test_mode 1 - } elseif {$a in $encnames} { + if {$a in $encnames} { set encoding $a } else { if {[regexp {[0-9]+(?:x|X)[0-9]+} $a]} { diff --git a/src/bootsupport/modules/punk/console-0.1.1.tm b/src/bootsupport/modules/punk/console-0.1.1.tm index 6368aea..4dd7bd6 100644 --- a/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/bootsupport/modules/punk/console-0.1.1.tm @@ -1021,8 +1021,8 @@ namespace eval punk::console { #It's known this isn't always the case - but things like textutil::untabify2 take only a single value #on some systems test_char_width is a similar speed to get_tabstop_apparent_width - but on some test_char_width is much slower #we will use test_char_width as a fallback - proc get_tabstop_apparent_width {} { - set tslist [get_tabstops] + proc get_tabstop_apparent_width {{inoutchannels {stdin stdout}}} { + set tslist [get_tabstops $inoutchannels] if {![llength $tslist]} { #either terminal failed to report - or none set. set testw [test_char_width \t] @@ -1199,7 +1199,7 @@ namespace eval punk::console { } if {!$emit} { - puts -nonewline stdout \033\[2K\033\[1G ;#2K erase line 1G cursor at col1 + puts -nonewline stdout \033\[2K\033\[1G ;#2K erase line, 1G cursor at col1 } set response "" if {[catch { @@ -1429,12 +1429,12 @@ namespace eval punk::console { proc cursor_save {} { #*** !doctools #[call [fun cursor_save]] - puts -nonewline \x1b\[s + puts -nonewline stdout \x1b\[s } proc cursor_restore {} { #*** !doctools #[call [fun cursor_restore]] - puts -nonewline \x1b\[u + puts -nonewline stdout \x1b\[u } #DEC equivalents of cursor_save/cursor_restore - perhaps more widely supported? proc cursor_save_dec {} { diff --git a/src/bootsupport/modules/punk/zip-0.1.0.tm b/src/bootsupport/modules/punk/zip-0.1.0.tm new file mode 100644 index 0000000..628419f --- /dev/null +++ b/src/bootsupport/modules/punk/zip-0.1.0.tm @@ -0,0 +1,632 @@ +# -*- tcl -*- +# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'pmix make' or bin/punkmake to update from -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) 2024 JMN +# (C) 2009 Path Thoyts +# +# @@ Meta Begin +# Application punk::zip 0.1.0 +# Meta platform tcl +# Meta license +# @@ Meta End + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# doctools header +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[manpage_begin shellspy_module_punk::zip 0 0.1.0] +#[copyright "2024"] +#[titledesc {Module API}] [comment {-- Name section and table of contents description --}] +#[moddesc {-}] [comment {-- Description at end of page heading --}] +#[require punk::zip] +#[keywords module] +#[description] +#[para] - + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section Overview] +#[para] overview of punk::zip +#[subsection Concepts] +#[para] - + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Requirements +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[subsection dependencies] +#[para] packages used by punk::zip +#[list_begin itemized] + +package require Tcl 8.6- +package require punk::args +#*** !doctools +#[item] [package {Tcl 8.6}] +#[item] [package {punk::args}] + +#*** !doctools +#[list_end] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section API] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# oo::class namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#tcl::namespace::eval punk::zip::class { + #*** !doctools + #[subsection {Namespace punk::zip::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 ---}] + #} +#} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# Base namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +tcl::namespace::eval punk::zip { + tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase + #variable xyz + + #*** !doctools + #[subsection {Namespace punk::zip}] + #[para] Core API functions for punk::zip + #[list_begin definitions] + + proc Path_a_atorbelow_b {path_a path_b} { + return [expr {[StripPath $path_b $path_a] ne $path_a}] + } + proc Path_a_at_b {path_a path_b} { + return [expr {[StripPath $path_a $path_b] eq "." }] + } + + proc Path_strip_alreadynormalized_prefixdepth {path prefix} { + if {$prefix eq ""} { + return $path + } + set pathparts [file split $path] + set prefixparts [file split $prefix] + if {[llength $prefixparts] >= [llength $pathparts]} { + return "" + } + return [file join \ + {*}[lrange \ + $pathparts \ + [llength $prefixparts] \ + end]] + } + + #StripPath - borrowed from tcllib fileutil + # ::fileutil::stripPath -- + # + # If the specified path references/is a path in prefix (or prefix itself) it + # is made relative to prefix. Otherwise it is left unchanged. + # In the case of it being prefix itself the result is the string '.'. + # + # Arguments: + # prefix prefix to strip from the path. + # path path to modify + # + # Results: + # path The (possibly) modified path. + + if {[string equal $::tcl_platform(platform) windows]} { + # Windows. While paths are stored with letter-case preserved al + # comparisons have to be done case-insensitive. For reference see + # SF Tcllib Bug 2499641. + + proc StripPath {prefix path} { + # [file split] is used to generate a canonical form for both + # paths, for easy comparison, and also one which is easy to modify + # using list commands. + + set prefix [file split $prefix] + set npath [file split $path] + + if {[string equal -nocase $prefix $npath]} { + return "." + } + + if {[string match -nocase "${prefix} *" $npath]} { + set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] + } + return $path + } + } else { + proc StripPath {prefix path} { + # [file split] is used to generate a canonical form for both + # paths, for easy comparison, and also one which is easy to modify + # using list commands. + + set prefix [file split $prefix] + set npath [file split $path] + + if {[string equal $prefix $npath]} { + return "." + } + + if {[string match "${prefix} *" $npath]} { + set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] + } + return $path + } + } + + proc Timet_to_dos {time_t} { + #*** !doctools + #[call [fun Timet_to_dos] [arg time_t]] + #[para] convert a unix timestamp into a DOS timestamp for ZIP times. + #[example { + # DOS timestamps are 32 bits split into bit regions as follows: + # 24 16 8 0 + # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + # |Y|Y|Y|Y|Y|Y|Y|m| |m|m|m|d|d|d|d|d| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s| + # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + #}] + set s [clock format $time_t -format {%Y %m %e %k %M %S}] + scan $s {%d %d %d %d %d %d} year month day hour min sec + expr {(($year-1980) << 25) | ($month << 21) | ($day << 16) + | ($hour << 11) | ($min << 5) | ($sec >> 1)} + } + + proc walk {args} { + #*** !doctools + #[call [fun walk] [arg ?options?] [arg base]] + #[para] Walk a directory tree rooted at base + #[para] the -excludes list can be a set of glob expressions to match against files and avoid + #[para] e.g + #[example { + # punk::zip::walk -exclude {CVS/* *~.#*} library + #}] + + set argd [punk::args::get_dict { + *proc -name punk::zip::walk + -excludes -default "" -help "list of glob expressions to match against files and exclude" + -subpath -default "" + *values -min 1 -max -1 + base + fileglobs -default {*} -multiple 1 + } $args] + set base [dict get $argd values base] + set fileglobs [dict get $argd values fileglobs] + set subpath [dict get $argd opts -subpath] + set excludes [dict get $argd opts -excludes] + + + set imatch [list] + foreach fg $fileglobs { + lappend imatch [file join $subpath $fg] + } + + set result {} + #set imatch [file join $subpath $match] + set files [glob -nocomplain -tails -types f -directory $base -- {*}$imatch] + foreach file $files { + set excluded 0 + foreach glob $excludes { + if {[string match $glob $file]} { + set excluded 1 + break + } + } + if {!$excluded} {lappend result $file} + } + foreach dir [glob -nocomplain -tails -types d -directory $base -- [file join $subpath *]] { + set subdir [walk -subpath $dir -excludes $excludes $base {*}$fileglobs] + if {[llength $subdir]>0} { + set result [concat $result $dir $subdir] + } + } + return $result + } + + # Mkzipfile -- + # + # FIX ME: should handle the current offset for non-seekable channels + # + proc Mkzipfile {zipchan base path {comment ""}} { + #*** !doctools + #[call [fun Mkzipfile] [arg zipchan] [arg base] [arg path] [arg ?comment?]] + #[para] Add a single file to a zip archive + #[para] The zipchan channel should already be open and binary. + #[para] You can provide a -comment for the file. + #[para] The return value is the central directory record that will need to be used when finalizing the zip archive. + + set fullpath [file join $base $path] + set mtime [Timet_to_dos [file mtime $fullpath]] + set utfpath [encoding convertto utf-8 $path] + set utfcomment [encoding convertto utf-8 $comment] + set flags [expr {(1<<11)}] ;# utf-8 comment and path + set method 0 ;# store 0, deflate 8 + set attr 0 ;# text or binary (default binary) + set version 20 ;# minumum version req'd to extract + set extra "" + set crc 0 + set size 0 + set csize 0 + set data "" + set seekable [expr {[tell $zipchan] != -1}] + if {[file isdirectory $fullpath]} { + set attrex 0x41ff0010 ;# 0o040777 (drwxrwxrwx) + #set attrex 0x40000010 + } elseif {[file executable $fullpath]} { + set attrex 0x81ff0080 ;# 0o100777 (-rwxrwxrwx) + } else { + set attrex 0x81b60020 ;# 0o100666 (-rw-rw-rw-) + if {[file extension $fullpath] in {".tcl" ".txt" ".c"}} { + set attr 1 ;# text + } + } + + if {[file isfile $fullpath]} { + set size [file size $fullpath] + if {!$seekable} {set flags [expr {$flags | (1 << 3)}]} + } + + + set offset [tell $zipchan] + set local [binary format a4sssiiiiss PK\03\04 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]] + append local $utfpath $extra + puts -nonewline $zipchan $local + + if {[file isfile $fullpath]} { + # If the file is under 2MB then zip in one chunk, otherwize we use + # streaming to avoid requiring excess memory. This helps to prevent + # storing re-compressed data that may be larger than the source when + # handling PNG or JPEG or nested ZIP files. + if {$size < 0x00200000} { + set fin [open $fullpath rb] + set data [read $fin] + set crc [zlib crc32 $data] + set cdata [zlib deflate $data] + if {[string length $cdata] < $size} { + set method 8 + set data $cdata + } + close $fin + set csize [string length $data] + puts -nonewline $zipchan $data + } else { + set method 8 + set fin [open $fullpath rb] + set zlib [zlib stream deflate] + while {![eof $fin]} { + set data [read $fin 4096] + set crc [zlib crc32 $data $crc] + $zlib put $data + if {[string length [set zdata [$zlib get]]]} { + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + } + } + close $fin + $zlib finalize + set zdata [$zlib get] + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + $zlib close + } + + if {$seekable} { + # update the header if the output is seekable + set local [binary format a4sssiiii PK\03\04 \ + $version $flags $method $mtime $crc $csize $size] + set current [tell $zipchan] + seek $zipchan $offset + puts -nonewline $zipchan $local + seek $zipchan $current + } else { + # Write a data descriptor record + set ddesc [binary format a4iii PK\7\8 $crc $csize $size] + puts -nonewline $zipchan $ddesc + } + } + + #PK\x01\x02 Cdentral directory file header + #set v1 0x0317 ;#upper byte 03 -> UNIX lower byte 23 -> 2.3 + set v1 0x0017 ;#upper byte 00 -> MS_DOS and OS/2 (FAT/VFAT/FAT32 file systems) + + set hdr [binary format a4ssssiiiisssssii PK\01\02 $v1 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]\ + [string length $utfcomment] 0 $attr $attrex $offset] + append hdr $utfpath $extra $utfcomment + return $hdr + } + # zip::mkzip -- + # + # eg: zip my.zip -directory Subdir -runtime unzipsfx.exe *.txt + # + proc mkzip {args} { + #*** !doctools + #[call [fun mkzip] [arg ?options?] [arg filename]] + #[para] Create a zip archive in 'filename' + #[para] If a file already exists, an error will be raised. + set argd [punk::args::get_dict { + *proc -name punk::zip::mkzip -help "Create a zip archive in 'filename'" + *opts + -return -default "pretty" -choices {pretty list none} -help "mkzip can return a list of the files and folders added to the archive + the option -return pretty is the default and uses the punk::lib pdict/plist system + to return a formatted list for the terminal + " + -zipkit -default 0 -type none -help "" + -runtime -default "" -help "specify a prefix file + e.g punk::zip::mkzip -runtime unzipsfx.exe -directory subdir output.zip + will create a self-extracting zip archive from the subdir/ folder. + " + -comment -default "" -help "An optional comment for the archive" + -directory -default "" -help "The new zip archive will scan for contents within this folder or current directory if not provided" + -base -default "" -help "The new zip archive will be rooted in this directory if provided + it must be a parent of -directory" + -exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"} + *values -min 1 -max -1 + filename -default "" -help "name of zipfile to create" + globs -default {*} -multiple 1 -help "list of glob patterns to match. + Only directories with matching files will be included in the archive" + } $args] + + set filename [dict get $argd values filename] + if {$filename eq ""} { + error "mkzip filename cannot be empty string" + } + if {[regexp {[?*]} $filename]} { + #catch a likely error where filename is omitted and first glob pattern is misinterpreted as zipfile name + error "mkzip filename should not contain glob characters ? *" + } + if {[file exists $filename]} { + error "mkzip filename:$filename already exists" + } + dict for {k v} [dict get $argd opts] { + switch -- $k { + -comment { + dict set argd opts $k [encoding convertto utf-8 $v] + } + -directory - -base { + dict set argd opts $k [file normalize $v] + } + } + } + + array set opts [dict get $argd opts] + + + if {$opts(-directory) ne ""} { + if {$opts(-base) ne ""} { + #-base and -directory have been normalized already + if {![Path_a_atorbelow_b $opts(-directory) $opts(-base)]} { + error "punk::zip::mkzip -base $opts(-base) must be above -directory $opts(-directory)" + } + set base $opts(-base) + set relpath [Path_strip_alreadynormalized_prefixdepth $opts(-directory) $opts(-base)] + } else { + set base $opts(-directory) + set relpath "" + } + set paths [walk -exclude $opts(-exclude) -subpath $relpath -- $base {*}[dict get $argd values globs]] + + set norm_filename [file normalize $filename] + set norm_dir [file normalize $opts(-directory)] ;#we only care if filename below -directory (which is where we start scanning) + if {[Path_a_atorbelow_b $norm_filename $norm_dir]} { + #check that we aren't adding the zipfile to itself + #REVIEW - now that we open zipfile after scanning - this isn't really a concern! + #keep for now in case we can add an -update or a -force facility (or in case we modify to add to zip as we scan for members?) + #In the case of -force - we may want to delay replacement of original until scan is done? + + #try to avoid looping on all paths and performing (somewhat) expensive file normalizations on each + #1st step is to check the patterns and see if our zipfile is already excluded - in which case we need not check the paths + set self_globs_match 0 + foreach g [dict get $argd values globs] { + if {[string match $g [file tail $filename]]} { + set self_globs_match 1 + break + } + } + if {$self_globs_match} { + #still dangerous + set self_excluded 0 + foreach e $opts(-exclude) { + if {[string match $e [file tail $filename]]} { + set self_excluded 1 + break + } + } + if {!$self_excluded} { + #still dangerous - likely to be in resultset - check each path + #puts stderr "zip file $filename is below directory $opts(-directory)" + set self_is_matched 0 + set i 0 + foreach p $paths { + set norm_p [file normalize [file join $opts(-directory) $p]] + if {[Path_a_at_b $norm_filename $norm_p]} { + set self_is_matched 1 + break + } + incr i + } + if {$self_is_matched} { + puts stderr "WARNING - zipfile being created '$filename' was matched. Excluding this file. Relocate the zip, or use -exclude patterns to avoid this message" + set paths [lremove $paths $i] + } + } + } + } + } else { + set paths [list] + set dir [pwd] + if {$opts(-base) ne ""} { + if {![Path_a_atorbelow_b $dir $opts(-base)]} { + error "punk::zip::mkzip -base $opts(-base) must be above current directory" + } + set relpath [Path_strip_alreadynormalized_prefixdepth [file normalize $dir] [file normalize $opts(-base)]] + } else { + set relpath "" + } + set base $opts(-base) + + set matches [glob -nocomplain -type f -- {*}[dict get $argd values globs]] + foreach m $matches { + if {$m eq $filename} { + #puts stderr "--> excluding $filename" + continue + } + set isok 1 + foreach e [concat $opts(-exclude) $filename] { + if {[string match $e $m]} { + set isok 0 + break + } + } + if {$isok} { + lappend paths [file join $relpath $m] + } + } + } + + if {![llength $paths]} { + return "" + } + + set zf [open $filename wb] + if {$opts(-runtime) ne ""} { + set rt [open $opts(-runtime) rb] + fcopy $rt $zf + close $rt + } elseif {$opts(-zipkit)} { + set zkd "#!/usr/bin/env tclkit\n\# This is a zip-based Tcl Module\n" + append zkd "package require vfs::zip\n" + append zkd "vfs::zip::Mount \[info script\] \[info script\]\n" + append zkd "if {\[file exists \[file join \[info script\] main.tcl\]\]} {\n" + append zkd " source \[file join \[info script\] main.tcl\]\n" + append zkd "}\n" + append zkd \x1A + puts -nonewline $zf $zkd + } + set count 0 + set cd "" + + set members [list] + foreach path $paths { + #puts $path + lappend members $path + append cd [Mkzipfile $zf $base $path] ;#path already includes relpath + incr count + } + set cdoffset [tell $zf] + set endrec [binary format a4ssssiis PK\05\06 0 0 \ + $count $count [string length $cd] $cdoffset\ + [string length $opts(-comment)]] + append endrec $opts(-comment) + puts -nonewline $zf $cd + puts -nonewline $zf $endrec + close $zf + + set result "" + switch -exact -- $opts(-return) { + list { + set result $members + } + pretty { + if {[info commands showlist] ne ""} { + set result [plist -channel none members] + } else { + set result $members + } + } + none { + set result "" + } + } + return $result + } + + + #*** !doctools + #[list_end] [comment {--- end definitions namespace punk::zip ---}] +} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# Secondary API namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +tcl::namespace::eval punk::zip::lib { + tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase + tcl::namespace::path [tcl::namespace::parent] + #*** !doctools + #[subsection {Namespace punk::zip::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 punk::zip::lib ---}] +} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[section Internal] +#tcl::namespace::eval punk::zip::system { + #*** !doctools + #[subsection {Namespace punk::zip::system}] + #[para] Internal functions that are not part of the API + + + +#} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Ready +package provide punk::zip [tcl::namespace::eval punk::zip { + variable pkg punk::zip + variable version + set version 0.1.0 +}] +return + +#*** !doctools +#[manpage_end] + diff --git a/src/bootsupport/modules/textblock-0.1.1.tm b/src/bootsupport/modules/textblock-0.1.1.tm index 5d127a3..88fdc3f 100644 --- a/src/bootsupport/modules/textblock-0.1.1.tm +++ b/src/bootsupport/modules/textblock-0.1.1.tm @@ -1933,13 +1933,6 @@ tcl::namespace::eval textblock { set hval $ansibase_header$header ;#no reset set rowh [my header_height $hrow] - #set h_lines [lrepeat $rowh $hcell_line_blank] - #set hcell_blank [join $h_lines \n] - #set hval_lines [split $hval \n] - #set hval_lines [lrange $hval_lines 0 $rowh-1] - #set hval_block [join $hval_lines \n] - #set headercell [overtype::left -experimental test_mode $ansibase_header$hcell_blank$RST $hval_block] - if {$hrow == 0} { set hlims $header_boxlimits_toprow set rowpos "top" @@ -2146,7 +2139,7 @@ tcl::namespace::eval textblock { #puts $hblock #puts "==>hval:'$hval'[a]" #puts "==>hval:'[ansistring VIEW $hval]'" - #set spanned_frame [overtype::renderspace -experimental test_mode -transparent 1 $spanned_frame $hblock] + #set spanned_frame [overtype::renderspace -transparent 1 $spanned_frame $hblock] #spanned values default left - todo make configurable @@ -3504,11 +3497,11 @@ tcl::namespace::eval textblock { set height [textblock::height $table] ;#only need to get height once at start } else { set nextcol [textblock::join -- [textblock::block $padwidth $height $TSUB] $nextcol] - set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent $TSUB $table[unset table] $nextcol] + set table [overtype::renderspace -expand_right 1 -transparent $TSUB $table[unset table] $nextcol] #JMN #set nextcol [textblock::join -- [textblock::block $padwidth $height "\uFFFF"] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent \uFFFF $table $nextcol] + #set table [overtype::renderspace -expand_right 1 -transparent \uFFFF $table $nextcol] } incr padwidth $bodywidth incr colposn @@ -3609,14 +3602,7 @@ tcl::namespace::eval textblock { set table $nextcol set height [textblock::height $table] ;#only need to get height once at start } else { - set table [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -overflow 1 -experimental test_mode -transparent $TSUB $table $nextcol] - - #set nextcol [textblock::join -- [textblock::block $padwidth $height $TSUB] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent $TSUB $table[unset table] $nextcol] - #JMN - - #set nextcol [textblock::join -- [textblock::block $padwidth $height "\uFFFF"] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent \uFFFF $table $nextcol] + set table [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $table $nextcol] } incr padwidth $bodywidth incr colposn @@ -3726,7 +3712,7 @@ tcl::namespace::eval textblock { lappend body_blocks $nextcol_body } else { if {$headerheight > 0} { - set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -overflow 1 -experimental test_mode -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]] + set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]] } lappend body_blocks $nextcol_body #set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body] diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/include_modules.config b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/include_modules.config index 490025b..75a091d 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/include_modules.config +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/include_modules.config @@ -57,6 +57,7 @@ set bootsupport_modules [list\ modules punk::path\ modules punk::repo\ modules punk::tdl\ + modules punk::zip\ modules punk::winpath\ modules textblock\ modules oolib\ diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/logger-0.9.5.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/logger-0.9.5.tm new file mode 100644 index 0000000..739e1c9 --- /dev/null +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/logger-0.9.5.tm @@ -0,0 +1,1297 @@ +# logger.tcl -- +# +# Tcl implementation of a general logging facility. +# +# Copyright (c) 2003 by David N. Welton +# Copyright (c) 2004-2011 by Michael Schlenker +# Copyright (c) 2006,2015 by Andreas Kupries +# +# See the file license.terms. + +# The logger package provides an 'object oriented' log facility that +# lets you have trees of services, that inherit from one another. +# This is accomplished through the use of Tcl namespaces. + + +package require Tcl 8.5 9 +package provide logger 0.9.5 + +namespace eval ::logger { + namespace eval tree {} + namespace export init enable disable services servicecmd import + + # The active services. + variable services {} + + # The log 'levels'. + variable levels [list debug info notice warn error critical alert emergency] + + # The default global log level used for new logging services + variable enabled "debug" + + # Tcl return codes (in numeric order) + variable RETURN_CODES [list "ok" "error" "return" "break" "continue"] +} + +# Try to load msgcat and fall back to format if it fails +if {[catch {package require msgcat}]} { + interp alias {} ::logger::mc {} ::format +} else { + namespace eval ::logger { + namespace import ::msgcat::mc + } +} + +# ::logger::_nsExists -- +# +# Workaround for missing namespace exists in Tcl 8.2 and 8.3. +# + +if {[package vcompare [package provide Tcl] 8.4] < 0} { + proc ::logger::_nsExists {ns} { + expr {![catch {namespace parent $ns}]} + } +} else { + proc ::logger::_nsExists {ns} { + namespace exists $ns + } +} + +# ::logger::_cmdPrefixExists -- +# +# Utility function to check if a given callback prefix exists, +# this should catch all oddities in prefix names, including spaces, +# glob patterns, non normalized namespaces etc. +# +# Arguments: +# prefix - The command prefix to check +# +# Results: +# 1 or 0 for yes or no +# +proc ::logger::_cmdPrefixExists {prefix} { + set cmd [lindex $prefix 0] + set full [namespace eval :: namespace which [list $cmd]] + if {[string equal $full ""]} {return 0} else {return 1} + # normalize namespaces + set ns [namespace qualifiers $cmd] + set cmd ${ns}::[namespace tail $cmd] + set matches [::info commands ${ns}::*] + if {[lsearch -exact $matches $cmd] != -1} {return 1} + return 0 +} + +# ::logger::walk -- +# +# Walk namespaces, starting in 'start', and evaluate 'code' in +# them. +# +# Arguments: +# start - namespace to start in. +# code - code to execute in namespaces walked. +# +# Side Effects: +# Side effects of code executed. +# +# Results: +# None. + +proc ::logger::walk { start code } { + set children [namespace children $start] + foreach c $children { + logger::walk $c $code + namespace eval $c $code + } +} + +proc ::logger::init {service} { + variable levels + variable services + variable enabled + + if {[string length [string trim $service {:}]] == 0} { + return -code error \ + -errorcode [list LOGGER EMPTY_SERVICENAME] \ + [::logger::mc "Service name invalid. May not consist only of : or be empty"] + } + # We create a 'tree' namespace to house all the services, so + # they are in a 'safe' namespace sandbox, and won't overwrite + # any commands. + namespace eval tree::${service} { + variable service + variable levels + variable oldname + variable enabled + } + + lappend services $service + + set [namespace current]::tree::${service}::service $service + set [namespace current]::tree::${service}::levels $levels + set [namespace current]::tree::${service}::oldname $service + set [namespace current]::tree::${service}::enabled $enabled + + namespace eval tree::${service} { + # Callback to use when the service in question is shut down. + variable delcallback [namespace current]::no-op + + # Callback when the loglevel is changed + variable levelchangecallback [namespace current]::no-op + + # State variable to decide when to call levelcallback + variable inSetLevel 0 + + # The currently configured levelcommands + variable lvlcmds + array set lvlcmds {} + + # List of procedures registered via the trace command + variable traceList "" + + # Flag indicating whether or not tracing is currently enabled + variable tracingEnabled 0 + + # We use this to disable a service completely. In Tcl 8.4 + # or greater, by using this, disabled log calls are a + # no-op! + + proc no-op args {} + + proc stdoutcmd {level text} { + variable service + puts "\[[clock format [clock seconds]]\] \[$service\] \[$level\] \'$text\'" + } + + proc stderrcmd {level text} { + variable service + puts stderr "\[[clock format [clock seconds]]\] \[$service\] \[$level\] \'$text\'" + } + + + # setlevel -- + # + # This command differs from enable and disable in that + # it disables all the levels below that selected, and + # then enables all levels above it, which enable/disable + # do not do. + # + # Arguments: + # lv - the level, as defined in $levels. + # + # Side Effects: + # Runs disable for the level, and then enable, in order + # to ensure that all levels are set correctly. + # + # Results: + # None. + + + proc setlevel {lv} { + variable inSetLevel 1 + set oldlvl [currentloglevel] + + # do not allow enable and disable to do recursion + if {[catch { + disable $lv 0 + set newlvl [enable $lv 0] + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } + # do the recursion here + logger::walk [namespace current] [list setlevel $lv] + + set inSetLevel 0 + lvlchangewrapper $oldlvl $newlvl + return + } + + # enable -- + # + # Enable a particular 'level', and above, for the + # service, and its 'children'. + # + # Arguments: + # lv - the level, as defined in $levels. + # + # Side Effects: + # Enables logging for the particular level, and all + # above it (those more important). It also walks + # through all services that are 'children' and enables + # them at the same level or above. + # + # Results: + # None. + + proc enable {lv {recursion 1}} { + variable levels + set lvnum [lsearch -exact $levels $lv] + if { $lvnum == -1 } { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + + variable enabled + set newlevel $enabled + set elnum [lsearch -exact $levels $enabled] + if {($elnum == -1) || ($elnum > $lvnum)} { + set newlevel $lv + } + + variable service + while { $lvnum < [llength $levels] } { + interp alias {} [namespace current]::[lindex $levels $lvnum] \ + {} [namespace current]::[lindex $levels $lvnum]cmd + incr lvnum + } + + if {$recursion} { + logger::walk [namespace current] [list enable $lv] + } + lvlchangewrapper $enabled $newlevel + set enabled $newlevel + } + + # disable -- + # + # Disable a particular 'level', and below, for the + # service, and its 'children'. + # + # Arguments: + # lv - the level, as defined in $levels. + # + # Side Effects: + # Disables logging for the particular level, and all + # below it (those less important). It also walks + # through all services that are 'children' and disables + # them at the same level or below. + # + # Results: + # None. + + proc disable {lv {recursion 1}} { + variable levels + set lvnum [lsearch -exact $levels $lv] + if { $lvnum == -1 } { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + + variable enabled + set newlevel $enabled + set elnum [lsearch -exact $levels $enabled] + if {($elnum > -1) && ($elnum <= $lvnum)} { + if {$lvnum+1 >= [llength $levels]} { + set newlevel "none" + } else { + set newlevel [lindex $levels [expr {$lvnum+1}]] + } + } + + while { $lvnum >= 0 } { + + interp alias {} [namespace current]::[lindex $levels $lvnum] {} \ + [namespace current]::no-op + incr lvnum -1 + } + if {$recursion} { + logger::walk [namespace current] [list disable $lv] + } + lvlchangewrapper $enabled $newlevel + set enabled $newlevel + } + + # currentloglevel -- + # + # Get the currently enabled log level for this service. + # + # Arguments: + # none + # + # Side Effects: + # none + # + # Results: + # current log level + # + + proc currentloglevel {} { + variable enabled + return $enabled + } + + # lvlchangeproc -- + # + # Set or introspect a callback for when the logger instance + # changes its loglevel. + # + # Arguments: + # cmd - the Tcl command to call, it is called with two parameters, old and new log level. + # or none for introspection + # + # Side Effects: + # None. + # + # Results: + # If no arguments are given return the current callback cmd. + + proc lvlchangeproc {args} { + variable levelchangecallback + + switch -exact -- [llength [::info level 0]] { + 1 {return $levelchangecallback} + 2 { + if {[::logger::_cmdPrefixExists [lindex $args 0]]} { + set levelchangecallback [lindex $args 0] + } else { + return -code error \ + -errorcode [list LOGGER INVALID_CMD] \ + [::logger::mc "Invalid cmd '%s' - does not exist" [lindex $args 0]] + } + } + default { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "Wrong # of arguments. Usage: \${log}::lvlchangeproc ?cmd?"] + } + } + } + + proc lvlchangewrapper {old new} { + variable inSetLevel + + # we are called after disable and enable are finished + if {$inSetLevel} {return} + + # no action if level does not change + if {[string equal $old $new]} {return} + + variable levelchangecallback + # no action if levelchangecallback isn't a valid command + if {[::logger::_cmdPrefixExists $levelchangecallback]} { + catch { + uplevel \#0 [linsert $levelchangecallback end $old $new] + } + } + } + + # logproc -- + # + # Command used to create a procedure that is executed to + # perform the logging. This could write to disk, out to + # the network, or something else. + # If two arguments are given, use an existing command. + # If three arguments are given, create a proc. + # + # Arguments: + # lv - the level to log, which must be one of $levels. + # args - either zero, one or two arguments. + # if zero this returns the current command registered + # if one, this is a cmd name that is called for this level + # if two, these are an argument and proc body + # + # Side Effects: + # Creates a logging command to take care of the details + # of logging an event. + # + # Results: + # If called with zero length args, returns the name of the currently + # configured logging procedure. + # + # + + proc logproc {lv args} { + variable levels + variable lvlcmds + + set lvnum [lsearch -exact $levels $lv] + if { ($lvnum == -1) && ($lv != "trace") } { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + switch -exact -- [llength $args] { + 0 { + return $lvlcmds($lv) + } + 1 { + set cmd [lindex $args 0] + if {[string equal "[namespace current]::${lv}cmd" $cmd]} {return} + if {[llength [::info commands $cmd]]} { + proc ${lv}cmd args [format { + uplevel 1 [list %s [expr {[llength $args]==1 ? [lindex $args end] : $args}]] + } $cmd] + } else { + return -code error \ + -errorcode [list LOGGER INVALID_CMD] \ + [::logger::mc "Invalid cmd '%s' - does not exist" $cmd] + } + set lvlcmds($lv) $cmd + } + 2 { + foreach {arg body} $args {break} + proc ${lv}cmd args [format {\ + _setservicename args + set val [%s [expr {[llength $args]==1 ? [lindex $args end] : $args}]] + _restoreservice + set val} ${lv}customcmd] + proc ${lv}customcmd $arg $body + set lvlcmds($lv) [namespace current]::${lv}customcmd + } + default { + return -code error \ + -errorcode [list LOGGER WRONG_USAGE] \ + [::logger::mc \ + "Usage: \${log}::logproc level ?cmd?\nor \${log}::logproc level argname body" ] + } + } + } + + + # delproc -- + # + # Set or introspect a callback for when the logger instance + # is deleted. + # + # Arguments: + # cmd - the Tcl command to call. + # or none for introspection + # + # Side Effects: + # None. + # + # Results: + # If no arguments are given return the current callback cmd. + + proc delproc {args} { + variable delcallback + + switch -exact -- [llength [::info level 0]] { + 1 {return $delcallback} + 2 { if {[::logger::_cmdPrefixExists [lindex $args 0]]} { + set delcallback [lindex $args 0] + } else { + return -code error \ + -errorcode [list LOGGER INVALID_CMD] \ + [::logger::mc "Invalid cmd '%s' - does not exist" [lindex $args 0]] + } + } + default { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "Wrong # of arguments. Usage: \${log}::delproc ?cmd?"] + } + } + } + + + # delete -- + # + # Delete the namespace and its children. + + proc delete {} { + variable delcallback + variable service + + logger::walk [namespace current] delete + if {[::logger::_cmdPrefixExists $delcallback]} { + uplevel \#0 [lrange $delcallback 0 end] + } + # clean up the global services list + set idx [lsearch -exact [logger::services] $service] + if {$idx !=-1} { + set ::logger::services [lreplace [logger::services] $idx $idx] + } + + namespace delete [namespace current] + + } + + # services -- + # + # Return all child services + + proc services {} { + variable service + + set children [list] + foreach srv [logger::services] { + if {[string match "${service}::*" $srv]} { + lappend children $srv + } + } + return $children + } + + # servicename -- + # + # Return the name of the service + + proc servicename {} { + variable service + return $service + } + + proc _setservicename {argname} { + variable service + variable oldname + upvar 1 $argname arg + if {[llength $arg] <= 1} { + return + } + + set count -1 + set newname "" + while {[string equal [lindex $arg [expr {$count+1}]] "-_logger::service"]} { + incr count 2 + set newname [lindex $arg $count] + } + if {[string equal $newname ""]} { + return + } + set oldname $service + set service $newname + # Pop off "-_logger::service " from argument list + set arg [lreplace $arg 0 $count] + } + + proc _restoreservice {} { + variable service + variable oldname + set service $oldname + return + } + + proc trace { action args } { + variable service + + # Allow other boolean values (true, false, yes, no, 0, 1) to be used + # as synonymns for "on" and "off". + + if {[string is boolean $action]} { + set xaction [expr {($action && 1) ? "on" : "off"}] + } else { + set xaction $action + } + + # Check for required arguments for actions/subcommands and dispatch + # to the appropriate procedure. + + switch -- $xaction { + "status" { + return [uplevel 1 [list logger::_trace_status $service $args]] + } + "on" { + if {[llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace on\""] + } + return [logger::_trace_on $service] + } + "off" { + if {[llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace off\""] + } + return [logger::_trace_off $service] + } + "add" { + if {![llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace add ?-ns? ...\""] + } + return [uplevel 1 [list ::logger::_trace_add $service $args]] + } + "remove" { + if {![llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace remove ?-ns? ...\""] + } + return [uplevel 1 [list ::logger::_trace_remove $service $args]] + } + + default { + return -code error \ + -errorcode [list LOGGER INVALID_ARG] \ + [::logger::mc "Invalid action \"%s\": must be status, add, remove,\ + on, or off" $action] + } + } + } + + # Walk the parent service namespaces to see first, if they + # exist, and if any are enabled, and then, as a + # consequence, enable this one + # too. + + enable $enabled + variable parent [namespace parent] + while {[string compare $parent "::logger::tree"]} { + # If the 'enabled' variable doesn't exist, create the + # whole thing. + if { ! [::info exists ${parent}::enabled] } { + logger::init [string range $parent 16 end] + } + set enabled [set ${parent}::enabled] + enable $enabled + set parent [namespace parent $parent] + } + } + + # Now create the commands for different levels. + + namespace eval tree::${service} { + set parent [namespace parent] + + # We 'inherit' the commands from the parents. This + # means that, if you want to share the same methods with + # children, they should be instantiated after the parent's + # methods have been defined. + + variable lvl ; # prevent creative writing to the global scope + if {[string compare $parent "::logger::tree"]} { + foreach lvl [::logger::levels] { + # OPTIMIZE: do not allow multiple aliases in the hierarchy + # they can always be replaced by more efficient + # direct aliases to the target procs. + interp alias {} [namespace current]::${lvl}cmd \ + {} ${parent}::${lvl}cmd -_logger::service $service + } + # inherit the starting loglevel of the parent service + setlevel [${parent}::currentloglevel] + } else { + foreach lvl [concat [::logger::levels] "trace"] { + proc ${lvl}cmd args [format {\ + _setservicename args + set val [stdoutcmd %s [expr {[llength $args]==1 ? [lindex $args end] : $args}]] + _restoreservice + set val } $lvl] + + set lvlcmds($lvl) [namespace current]::${lvl}cmd + } + setlevel $::logger::enabled + } + unset lvl ; # drop the temp iteration variable + } + + return ::logger::tree::${service} +} + +# ::logger::services -- +# +# Returns a list of all active services. +# +# Arguments: +# None. +# +# Side Effects: +# None. +# +# Results: +# List of active services. + +proc ::logger::services {} { + variable services + return $services +} + +# ::logger::enable -- +# +# Global enable for a certain level. NOTE - this implementation +# isn't terribly effective at the moment, because it might hit +# children before their parents, who will then walk down the +# tree attempting to disable the children again. +# +# Arguments: +# lv - level above which to enable logging. +# +# Side Effects: +# Enables logging in a given level, and all higher levels. +# +# Results: +# None. + +proc ::logger::enable {lv} { + variable services + if {[catch { + foreach sv $services { + ::logger::tree::${sv}::enable $lv + } + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } +} + +proc ::logger::disable {lv} { + variable services + if {[catch { + foreach sv $services { + ::logger::tree::${sv}::disable $lv + } + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } +} + +proc ::logger::setlevel {lv} { + variable services + variable enabled + variable levels + if {[lsearch -exact $levels $lv] == -1} { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + set enabled $lv + if {[catch { + foreach sv $services { + ::logger::tree::${sv}::setlevel $lv + } + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } +} + +# ::logger::levels -- +# +# Introspect the available log levels. Provided so a caller does +# not need to know implementation details or code the list +# himself. +# +# Arguments: +# None. +# +# Side Effects: +# None. +# +# Results: +# levels - The list of valid log levels accepted by enable and disable + +proc ::logger::levels {} { + variable levels + return $levels +} + +# ::logger::servicecmd -- +# +# Get the command token for a given service name. +# +# Arguments: +# service - name of the service. +# +# Side Effects: +# none +# +# Results: +# log - namespace token for this service + +proc ::logger::servicecmd {service} { + variable services + if {[lsearch -exact $services $service] == -1} { + return -code error \ + -errorcode [list LOGGER NO_SUCH_SERVICE] \ + [::logger::mc "Service \"%s\" does not exist." $service] + } + return "::logger::tree::${service}" +} + +# ::logger::import -- +# +# Import the logging commands. +# +# Arguments: +# service - name of the service. +# +# Side Effects: +# creates aliases in the target namespace +# +# Results: +# none + +proc ::logger::import {args} { + variable services + + if {[llength $args] == 0 || [llength $args] > 7} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc \ + "Wrong # of arguments: \"logger::import ?-all?\ + ?-force?\ + ?-prefix prefix? ?-namespace namespace? service\""] + } + + # process options + # + set import_all 0 + set force 0 + set prefix "" + set ns [uplevel 1 namespace current] + while {[llength $args] > 1} { + set opt [lindex $args 0] + set args [lrange $args 1 end] + switch -exact -- $opt { + -all { set import_all 1} + -prefix { set prefix [lindex $args 0] + set args [lrange $args 1 end] + } + -namespace { + set ns [lindex $args 0] + set args [lrange $args 1 end] + } + -force { + set force 1 + } + default { + return -code error \ + -errorcode [list LOGGER UNKNOWN_ARG] \ + [::logger::mc \ + "Unknown argument: \"%s\" :\nUsage:\ + \"logger::import ?-all? ?-force?\ + ?-prefix prefix? ?-namespace namespace? service\"" $opt] + } + } + } + + # + # build the list of commands to import + # + + set cmds [logger::levels] + lappend cmds "trace" + if {$import_all} { + lappend cmds setlevel enable disable logproc delproc services + lappend cmds servicename currentloglevel delete + } + + # + # check the service argument + # + + set service [lindex $args 0] + if {[lsearch -exact $services $service] == -1} { + return -code error \ + -errorcode [list LOGGER NO_SUCH_SERVICE] \ + [::logger::mc "Service \"%s\" does not exist." $service] + } + + # + # setup the namespace for the import + # + + set sourcens [logger::servicecmd $service] + set localns [uplevel 1 namespace current] + + if {[string match ::* $ns]} { + set importns $ns + } else { + set importns ${localns}::$ns + } + + # fake namespace exists for Tcl 8.2 - 8.3 + if {![_nsExists $importns]} { + namespace eval $importns {} + } + + + # + # prepare the import + # + + set imports "" + foreach cmd $cmds { + set cmdname ${importns}::${prefix}$cmd + set collision [llength [info commands $cmdname]] + if {$collision && !$force} { + return -code error \ + -errorcode [list LOGGER IMPORT_NAME_EXISTS] \ + [::logger::mc "can't import command \"%s\": already exists" $cmdname] + } + lappend imports ${importns}::${prefix}$cmd ${sourcens}::${cmd} + } + + # + # and execute the aliasing after checking all is well + # + + foreach {target source} $imports { + proc $target {args} "uplevel 1 \[linsert \$args 0 $source \]" + } +} + +# ::logger::initNamespace -- +# +# Creates a logger for the specified namespace and makes the log +# commands available to said namespace as well. Allows the initial +# setting of a default log level. +# +# Arguments: +# ns - Namespace to initialize, is also the service name, modulo a ::-prefix +# level - Initial log level, optional, defaults to 'warn'. +# +# Side Effects: +# creates aliases in the target namespace +# +# Results: +# none + +proc ::logger::initNamespace {ns {level {}}} { + set service [string trimleft $ns :] + if {$level == ""} { + # No user-specified level. Figure something out. + # - If the parent service exists then the 'logger::init' + # below will automatically inherit its level. Good enough. + # - Without a parent service go and use a default level of 'warn'. + set parent [string trimleft [namespace qualifiers $service] :] + set hasparent [expr {($parent != {}) && [_nsExists ::logger::tree::${parent}]}] + if {!$hasparent} { + set level warn + } + } + + namespace eval $ns [list ::logger::init $service] + namespace eval $ns [list ::logger::import -force -all -namespace log $service] + if {$level != ""} { + namespace eval $ns [list log::setlevel $level] + } + return +} + +# This procedure handles the "logger::trace status" command. Given no +# arguments, returns a list of all procedures that have been registered +# via "logger::trace add". Given one or more procedure names, it will +# return 1 if all were registered, or 0 if any were not. + +proc ::logger::_trace_status { service procList } { + upvar #0 ::logger::tree::${service}::traceList traceList + + # If no procedure names were given, just return the registered list + + if {![llength $procList]} { + return $traceList + } + + # Get caller's namespace for qualifying unqualified procedure names + + set caller_ns [uplevel 1 namespace current] + set caller_ns [string trimright $caller_ns ":"] + + # Search for any specified proc names that are *not* registered + + foreach procName $procList { + # Make sure the procedure namespace is qualified + + if {![string match "::*" $procName]} { + set procName ${caller_ns}::$procName + } + + # Check if the procedure has been registered for tracing + + if {[lsearch -exact $traceList $procName] == -1} { + return 0 + } + } + + return 1 +} + +# This procedure handles the "logger::trace on" command. If tracing +# is turned off, it will enable Tcl trace handlers for all of the procedures +# registered via "logger::trace add". Does nothing if tracing is already +# turned on. + +proc ::logger::_trace_on { service } { + set tcl_version [package provide Tcl] + + if {[package vcompare $tcl_version "8.4"] < 0} { + return -code error \ + -errorcode [list LOGGER TRACE_NOT_AVAILABLE] \ + [::logger::mc "execution tracing is not available in Tcl %s" $tcl_version] + } + + namespace eval ::logger::tree::${service} { + if {!$tracingEnabled} { + set tracingEnabled 1 + ::logger::_enable_traces $service $traceList + } + } + + return 1 +} + +# This procedure handles the "logger::trace off" command. If tracing +# is turned on, it will disable Tcl trace handlers for all of the procedures +# registered via "logger::trace add", leaving them in the list so they +# tracing on all of them can be enabled again with "logger::trace on". +# Does nothing if tracing is already turned off. + +proc ::logger::_trace_off { service } { + namespace eval ::logger::tree::${service} { + if {$tracingEnabled} { + ::logger::_disable_traces $service $traceList + set tracingEnabled 0 + } + } + + return 1 +} + +# This procedure is used by the logger::trace add and remove commands to +# process the arguments in a common fashion. If the -ns switch is given +# first, this procedure will return a list of all existing procedures in +# all of the namespaces given in remaining arguments. Otherwise, each +# argument is taken to be either a pattern for a glob-style search of +# procedure names or, failing that, a namespace, in which case this +# procedure returns a list of all the procedures matching the given +# pattern (or all in the named namespace, if no procedures match). + +proc ::logger::_trace_get_proclist { inputList } { + set procList "" + + if {[string equal [lindex $inputList 0] "-ns"]} { + # Verify that at least one target namespace was supplied + + set inputList [lrange $inputList 1 end] + if {![llength $inputList]} { + return -code error \ + -errorcode [list LOGGER TARGET_MISSING] \ + [::logger::mc "Must specify at least one namespace target"] + } + + # Rebuild the argument list to contain namespace procedures + + foreach namespace $inputList { + # Don't allow tracing of the logger (or child) namespaces + + if {![string match "::logger::*" $namespace]} { + set nsProcList [::info procs ${namespace}::*] + set procList [concat $procList $nsProcList] + } + } + } else { + # Search for procs or namespaces matching each of the specified + # patterns. + + foreach pattern $inputList { + set matches [uplevel 1 ::info proc $pattern] + + if {![llength $matches]} { + if {[uplevel 1 namespace exists $pattern]} { + set matches [::info procs ${pattern}::*] + } + + # Matched procs will be qualified due to above pattern + + set procList [concat $procList $matches] + } elseif {[string match "::*" $pattern]} { + # Patterns were pre-qualified - add them directly + + set procList [concat $procList $matches] + } else { + # Qualify each proc with the namespace it was in + + set ns [uplevel 1 namespace current] + if {$ns == "::"} { + set ns "" + } + foreach proc $matches { + lappend procList ${ns}::$proc + } + } + } + } + + return $procList +} + +# This procedure handles the "logger::trace add" command. If the tracing +# feature is enabled, it will enable the Tcl entry and leave trace handlers +# for each procedure specified that isn't already being traced. Each +# procedure is added to the list of procedures that the logger trace feature +# should log when tracing is enabled. + +proc ::logger::_trace_add { service procList } { + upvar #0 ::logger::tree::${service}::traceList traceList + + # Handle -ns switch and glob search patterns for procedure names + + set procList [uplevel 1 [list logger::_trace_get_proclist $procList]] + + # Enable tracing for each procedure that has not previously been + # specified via logger::trace add. If tracing is off, this will just + # store the name of the procedure for later when tracing is turned on. + + foreach procName $procList { + if {[lsearch -exact $traceList $procName] == -1} { + lappend traceList $procName + ::logger::_enable_traces $service [list $procName] + } + } +} + +# This procedure handles the "logger::trace remove" command. If the tracing +# feature is enabled, it will remove the Tcl entry and leave trace handlers +# for each procedure specified. Each procedure is removed from the list +# of procedures that the logger trace feature should log when tracing is +# enabled. + +proc ::logger::_trace_remove { service procList } { + upvar #0 ::logger::tree::${service}::traceList traceList + + # Handle -ns switch and glob search patterns for procedure names + + set procList [uplevel 1 [list logger::_trace_get_proclist $procList]] + + # Disable tracing for each proc that previously had been specified + # via logger::trace add. If tracing is off, this will just + # remove the name of the procedure from the trace list so that it + # will be excluded when tracing is turned on. + + foreach procName $procList { + set index [lsearch -exact $traceList $procName] + if {$index != -1} { + set traceList [lreplace $traceList $index $index] + ::logger::_disable_traces $service [list $procName] + } + } +} + +# This procedure enables Tcl trace handlers for all procedures specified. +# It is used both to enable Tcl's tracing for a single procedure when +# removed via "logger::trace add", as well as to enable all traces +# via "logger::trace on". + +proc ::logger::_enable_traces { service procList } { + upvar #0 ::logger::tree::${service}::tracingEnabled tracingEnabled + + if {$tracingEnabled} { + foreach procName $procList { + ::trace add execution $procName enter \ + [list ::logger::_trace_enter $service] + ::trace add execution $procName leave \ + [list ::logger::_trace_leave $service] + } + } +} + +# This procedure disables Tcl trace handlers for all procedures specified. +# It is used both to disable Tcl's tracing for a single procedure when +# removed via "logger::trace remove", as well as to disable all traces +# via "logger::trace off". + +proc ::logger::_disable_traces { service procList } { + upvar #0 ::logger::tree::${service}::tracingEnabled tracingEnabled + + if {$tracingEnabled} { + foreach procName $procList { + ::trace remove execution $procName enter \ + [list ::logger::_trace_enter $service] + ::trace remove execution $procName leave \ + [list ::logger::_trace_leave $service] + } + } +} + +######################################################################## +# Trace Handlers +######################################################################## + +# This procedure is invoked upon entry into a procedure being traced +# via "logger::trace add" when tracing is enabled via "logger::trace on" +# to log information about how the procedure was called. + +proc ::logger::_trace_enter { service cmd op } { + # Parse the command + set procName [uplevel 1 namespace origin [lindex $cmd 0]] + set args [lrange $cmd 1 end] + + # Display the message prefix + set callerLvl [expr {[::info level] - 1}] + set calledLvl [::info level] + + lappend message "proc" $procName + lappend message "level" $calledLvl + lappend message "script" [uplevel ::info script] + + # Display the caller information + set caller "" + if {$callerLvl >= 1} { + # Display the name of the caller proc w/prepended namespace + catch { + set callerProcName [lindex [::info level $callerLvl] 0] + set caller [uplevel 2 namespace origin $callerProcName] + } + } + + lappend message "caller" $caller + + # Display the argument names and values + set argSpec [uplevel 1 ::info args $procName] + set argList "" + if {[llength $argSpec]} { + foreach argName $argSpec { + lappend argList $argName + + if {$argName == "args"} { + lappend argList $args + break + } else { + lappend argList [lindex $args 0] + set args [lrange $args 1 end] + } + } + } + + lappend message "procargs" $argList + set message [list $op $message] + + ::logger::tree::${service}::tracecmd $message +} + +# This procedure is invoked upon leaving into a procedure being traced +# via "logger::trace add" when tracing is enabled via "logger::trace on" +# to log information about the result of the procedure call. + +proc ::logger::_trace_leave { service cmd status rc op } { + variable RETURN_CODES + + # Parse the command + set procName [uplevel 1 namespace origin [lindex $cmd 0]] + + # Gather the caller information + set callerLvl [expr {[::info level] - 1}] + set calledLvl [::info level] + + lappend message "proc" $procName "level" $calledLvl + lappend message "script" [uplevel ::info script] + + # Get the name of the proc being returned to w/prepended namespace + set caller "" + catch { + set callerProcName [lindex [::info level $callerLvl] 0] + set caller [uplevel 2 namespace origin $callerProcName] + } + + lappend message "caller" $caller + + # Convert the return code from numeric to verbal + + if {$status < [llength $RETURN_CODES]} { + set status [lindex $RETURN_CODES $status] + } + + lappend message "status" $status + lappend message "result" $rc + + # Display the leave message + + set message [list $op $message] + ::logger::tree::${service}::tracecmd $message + + return 1 +} + diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.6.5.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.6.5.tm index f7e4c1a..38ce71c 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.6.5.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.6.5.tm @@ -165,16 +165,17 @@ tcl::namespace::eval overtype::priv { #could return larger than renderwidth proc _get_row_append_column {row} { + #obsolete? upvar outputlines outputlines set idx [expr {$row -1}] if {$row <= 1 || $row > [llength $outputlines]} { return 1 } else { - upvar opt_overflow opt_overflow + upvar opt_expand_right expand_right upvar renderwidth renderwidth set existinglen [punk::ansi::printing_length [lindex $outputlines $idx]] set endpos [expr {$existinglen +1}] - if {$opt_overflow} { + if {$expand_right} { return $endpos } else { if {$endpos > $renderwidth} { @@ -204,14 +205,14 @@ tcl::namespace::eval overtype { proc renderspace {args} { #*** !doctools #[call [fun overtype::renderspace] [arg args] ] - #[para] usage: ?-transparent [lb]0|1[rb]? ?-overflow [lb]1|0[rb]? ?-ellipsis [lb]1|0[rb]? ?-ellipsistext ...? undertext overtext + #[para] usage: ?-transparent [lb]0|1[rb]? ?-expand_right [lb]1|0[rb]? ?-ellipsis [lb]1|0[rb]? ?-ellipsistext ...? undertext overtext # @c overtype starting at left (overstrike) # @c can/should we use something like this?: 'format "%-*s" $len $overtext variable default_ellipsis_horizontal if {[llength $args] < 2} { - error {usage: ?-width ? ?-startcolumn ? ?-transparent [0|1|]? ?-overflow [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext} + error {usage: ?-width ? ?-startcolumn ? ?-transparent [0|1|]? ?-expand_right [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext} } set optargs [lrange $args 0 end-2] if {[llength $optargs] % 2 == 0} { @@ -228,30 +229,46 @@ tcl::namespace::eval overtype { } } set opts [tcl::dict::create\ - -bias ignored\ - -width \uFFEF\ - -height \uFFEF\ + -bias ignored\ + -width \uFFEF\ + -height \uFFEF\ -startcolumn 1\ - -wrap 0\ - -ellipsis 0\ + -wrap 0\ + -ellipsis 0\ -ellipsistext $default_ellipsis_horizontal\ -ellipsiswhitespace 0\ - -overflow 0\ - -appendlines 1\ - -transparent 0\ - -exposed1 \uFFFD\ - -exposed2 \uFFFD\ - -experimental 0\ - -looplimit \uFFEF\ - -crm_mode 0\ - -reverse_mode 0\ + -expand_right 0\ + -appendlines 1\ + -transparent 0\ + -exposed1 \uFFFD\ + -exposed2 \uFFFD\ + -experimental 0\ + -cp437 1\ + -looplimit \uFFEF\ + -crm_mode 0\ + -reverse_mode 0\ + -insert_mode 0\ + -console {stdin stdout stderr}\ ] + #expand_right is perhaps consistent with the idea of the page_size being allowed to grow horizontally.. + # it does not necessarily mean the viewport grows. (which further implies need for horizontal scrolling) + # - it does need to be within some concept of terminal width - as columns must be addressable by ansi sequences. + # - This implies the -width option value must grow if it is tied to the concept of renderspace terminal width! REVIEW. + # - further implication is that if expand_right grows the virtual renderspace terminal width - + # then some sort of reflow/rerender needs to be done for preceeding lines? + # possibly not - as expand_right is distinct from a normal terminal-width change event, + # expand_right being primarily to support other operations such as textblock::table + + #todo - viewport width/height as separate concept to terminal width/height? #-ellipsis args not used if -wrap is true foreach {k v} $argsflags { switch -- $k { - -looplimit - -width - -height - -startcolumn - -bias - -wrap - -ellipsis - -ellipsistext - -ellipsiswhitespace - -overflow - -appendlines + -looplimit - -width - -height - -startcolumn - -bias - -wrap - -ellipsis - -ellipsistext - -ellipsiswhitespace - -transparent - -exposed1 - -exposed2 - -experimental - - -reverse_mode - -crm_mode { + - -expand_right - -appendlines + - -reverse_mode - -crm_mode - -insert_mode + - -cp437 + - -console { tcl::dict::set opts $k $v } default { @@ -261,7 +278,8 @@ tcl::namespace::eval overtype { } #set opts [tcl::dict::merge $defaults $argsflags] # -- --- --- --- --- --- - set opt_overflow [tcl::dict::get $opts -overflow] + #review - expand_left for RTL text? + set opt_expand_right [tcl::dict::get $opts -expand_right] ##### # review -wrap should map onto DECAWM terminal mode - the wrap 2 idea may not fit in with this?. set opt_wrap [tcl::dict::get $opts -wrap] ;#wrap 1 is hard wrap cutting word at exact column, or 1 column early for 2w-glyph, wrap 2 is for language-based word-wrap algorithm (todo) @@ -279,23 +297,31 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- set opt_crm_mode [tcl::dict::get $opts -crm_mode] set opt_reverse_mode [tcl::dict::get $opts -reverse_mode] + set opt_insert_mode [tcl::dict::get $opts -insert_mode] + # -- --- --- --- --- --- + set opt_cp437 [tcl::dict::get $opts -cp437] + + + #initial state for renderspace 'terminal' reset + set initial_state [dict create\ + -width $opt_width\ + -height $opt_height\ + -crm_mode $opt_crm_mode\ + -reverse_mode $opt_reverse_mode\ + -insert_mode $opt_insert_mode\ + -cp437 $opt_cp437\ + ] # ---------------------------- # -experimental dev flag to set flags etc # ---------------------------- set data_mode 0 - set test_mode 1 set info_mode 0 set edit_mode 0 set opt_experimental [tcl::dict::get $opts -experimental] foreach o $opt_experimental { switch -- $o { - test_mode { - set test_mode 1 - set info_mode 1 - } old_mode { - set test_mode 0 set info_mode 1 } data_mode { @@ -309,11 +335,10 @@ tcl::namespace::eval overtype { } } } - set test_mode 1 ;#try to eliminate # ---------------------------- #modes - set insert_mode 0 ;#can be toggled by insert key or ansi IRM sequence ESC [ 4 h|l + set insert_mode $opt_insert_mode ;#can be toggled by insert key or ansi IRM sequence ESC [ 4 h|l set autowrap_mode $opt_wrap set reverse_mode $opt_reverse_mode set crm_mode $opt_crm_mode @@ -377,49 +402,45 @@ tcl::namespace::eval overtype { set looplimit [expr {[tcl::string::length $overblock] + 10}] } - if {!$test_mode} { - set inputchunks [split $overblock \n] - } else { - set scheme 3 - switch -- $scheme { - 0 { - #one big chunk - set inputchunks [list $overblock] + set scheme 3 + switch -- $scheme { + 0 { + #one big chunk + set inputchunks [list $overblock] + } + 1 { + set inputchunks [punk::ansi::ta::split_codes $overblock] + } + 2 { + + #split into lines if possible first - then into plaintext/ansi-sequence chunks ? + set inputchunks [list ""] ;#put an empty plaintext split in for starters + set i 1 + set lines [split $overblock \n] + foreach ln $lines { + if {$i < [llength $lines]} { + append ln \n + } + set sequence_split [punk::ansi::ta::split_codes_single $ln] ;#use split_codes Not split_codes_single? + set lastpt [lindex $inputchunks end] + lset inputchunks end [tcl::string::cat $lastpt [lindex $sequence_split 0]] + lappend inputchunks {*}[lrange $sequence_split 1 end] + incr i } - 1 { - set inputchunks [punk::ansi::ta::split_codes $overblock] + } + 3 { + #it turns out line based chunks are faster than the above.. probably because some of those end up doing the regex splitting twice + set lflines [list] + set inputchunks [split $overblock \n] + foreach ln $inputchunks { + append ln \n + lappend lflines $ln } - 2 { - - #split into lines if possible first - then into plaintext/ansi-sequence chunks ? - set inputchunks [list ""] ;#put an empty plaintext split in for starters - set i 1 - set lines [split $overblock \n] - foreach ln $lines { - if {$i < [llength $lines]} { - append ln \n - } - set sequence_split [punk::ansi::ta::split_codes_single $ln] ;#use split_codes Not split_codes_single? - set lastpt [lindex $inputchunks end] - lset inputchunks end [tcl::string::cat $lastpt [lindex $sequence_split 0]] - lappend inputchunks {*}[lrange $sequence_split 1 end] - incr i - } + if {[llength $lflines]} { + lset lflines end [tcl::string::range [lindex $lflines end] 0 end-1] } - 3 { - #it turns out line based chunks are faster than the above.. probably because some of those end up doing the regex splitting twice - set lflines [list] - set inputchunks [split $overblock \n] - foreach ln $inputchunks { - append ln \n - lappend lflines $ln - } - if {[llength $lflines]} { - lset lflines end [tcl::string::range [lindex $lflines end] 0 end-1] - } - set inputchunks $lflines[unset lflines] + set inputchunks $lflines[unset lflines] - } } } @@ -441,11 +462,11 @@ tcl::namespace::eval overtype { #underlines are not necessarily processed in order - depending on cursor-moves applied from overtext set row 1 - if {$data_mode} { - set col [_get_row_append_column $row] - } else { + #if {$data_mode} { + # set col [_get_row_append_column $row] + #} else { set col $opt_startcolumn - } + #} set instruction_stats [tcl::dict::create] @@ -473,33 +494,27 @@ tcl::namespace::eval overtype { } #review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary - #but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l - set LASTCALL [list -info 1\ - -insert_mode $insert_mode\ - -crm_mode $crm_mode\ - -autowrap_mode $autowrap_mode\ - -reverse_mode $reverse_mode\ - -transparent $opt_transparent\ - -width $renderwidth\ - -exposed1 $opt_exposed1\ - -exposed2 $opt_exposed2\ - -overflow $opt_overflow -cursor_column $col -cursor_row $row $undertext $overtext] - set rinfo [renderline -experimental $opt_experimental\ + set renderargs [list -experimental $opt_experimental\ + -cp437 $opt_cp437\ -info 1\ -crm_mode $crm_mode\ -insert_mode $insert_mode\ -autowrap_mode $autowrap_mode\ - -reverse_mode $reverse_mode\ + -reverse_mode $reverse_mode\ -cursor_restore_attributes $cursor_saved_attributes\ -transparent $opt_transparent\ -width $renderwidth\ -exposed1 $opt_exposed1\ -exposed2 $opt_exposed2\ - -overflow $opt_overflow\ + -expand_right $opt_expand_right\ -cursor_column $col\ -cursor_row $row\ $undertext\ $overtext\ - ] + ] + set LASTCALL $renderargs + set rinfo [renderline {*}$renderargs] + set instruction [tcl::dict::get $rinfo instruction] set insert_mode [tcl::dict::get $rinfo insert_mode] set autowrap_mode [tcl::dict::get $rinfo autowrap_mode] ;# @@ -523,6 +538,7 @@ tcl::namespace::eval overtype { #lset replay_codes_overlay [expr $overidx+1] [tcl::dict::get $rinfo replay_codes_overlay] set replay_codes_overlay [tcl::dict::get $rinfo replay_codes_overlay] if {0 && $reverse_mode} { + #test branch - todo - prune puts stderr "---->[ansistring VIEW $replay_codes_overlay] rendered: $rendered" #review #JMN3 @@ -579,29 +595,17 @@ tcl::namespace::eval overtype { #keeping separate branches for debugging - review and merge as appropriate when stable tcl::dict::incr instruction_stats $instruction switch -- $instruction { - {} { - if {$test_mode == 0} { - incr row - if {$data_mode} { - set col [_get_row_append_column $row] - if {$col > $renderwidth} { + reset { + #reset the 'renderspace terminal' (not underlying terminal) + set row 1 + set col 1 - } - } else { - set col 1 - } - } else { - #lf included in data - set row $post_render_row - set col $post_render_col - #set col 1 - #if {$post_render_row != $renderedrow} { - # set col 1 - #} else { - # set col $post_render_col - #} - } + } + {} { + #lf included in data + set row $post_render_row + set col $post_render_col } up { @@ -704,7 +708,14 @@ tcl::namespace::eval overtype { puts stdout ">>>[a+ red bold]overflow_right during restore_cursor[a]" - set sub_info [overtype::renderline -info 1 -width $renderwidth -insert_mode $insert_mode -autowrap_mode $autowrap_mode -overflow [tcl::dict::get $opts -overflow] "" $overflow_right] + set sub_info [overtype::renderline -info 1\ + -width $renderwidth\ + -insert_mode $insert_mode\ + -autowrap_mode $autowrap_mode\ + -expand_right [tcl::dict::get $opts -opt_expand_right]\ + ""\ + $overflow_right\ + ] set foldline [tcl::dict::get $sub_info result] set insert_mode [tcl::dict::get $sub_info insert_mode] ;#probably not needed..? set autowrap_mode [tcl::dict::get $sub_info autowrap_mode] ;#nor this.. @@ -735,7 +746,7 @@ tcl::namespace::eval overtype { #overflow + unapplied? } lf_start { - #raw newlines - must be test_mode + #raw newlines # ---------------------- #test with fruit.ans #test - treating as newline below... @@ -751,48 +762,58 @@ tcl::namespace::eval overtype { } lf_mid { - if 0 { - #set rhswidth [punk::ansi::printing_length $overflow_right] - #only show debug when we have overflow? - set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -nul 1 -lf 1 -vt 1 $rendered]] - set lhs [textblock::frame -title "rendered $visualwidth cols" -subtitle "row-$renderedrow" $lhs] - - set rhs "" - if {$overflow_right ne ""} { - set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -nul 1 -lf 1 -vt 1 $overflow_right]] - set rhs [textblock::frame -title overflow_right $rhs] - } - puts [textblock::join $lhs " $post_render_col " $rhs] - } - - if {!$test_mode} { - #rendered - append rendered $overflow_right - #set replay_codes_overlay "" + set edit_mode 0 + if {$edit_mode} { + set inputchunks [linsert $inputchunks 0 $overflow_right$unapplied] set overflow_right "" - - - set row $renderedrow - + set unapplied "" + set row $post_render_row + #set col $post_render_col set col $opt_startcolumn - incr row - #only add newline if we're at the bottom if {$row > [llength $outputlines]} { lappend outputlines {*}[lrepeat 1 ""] } } else { - set edit_mode 0 - if {$edit_mode} { - set inputchunks [linsert $inputchunks 0 $overflow_right$unapplied] - set overflow_right "" - set unapplied "" + if 1 { + if {$overflow_right ne ""} { + if {$opt_expand_right} { + append rendered $overflow_right + set overflow_right "" + } else { + set overflow_width [punk::ansi::printing_length $overflow_right] + if {$visualwidth + $overflow_width <= $renderwidth} { + append rendered $overflow_right + set overflow_right "" + } else { + if {$visualwidth < $renderwidth} { + set graphemes [punk::char::grapheme_split $overflow_width] + set add "" + set addlen $visualwidth + set remaining_overflow $graphemes + foreach g $graphemes { + set w [overtype::grapheme_width_cached] + if {$addlen + $w <= $renderwidth} { + append add $g + incr addlen $w + lpop remaining_overflow + } else { + break + } + } + append rendered $add + set overflow_right [join $remaining_overflow ""] + } + } + } + } set row $post_render_row - #set col $post_render_col set col $opt_startcolumn if {$row > [llength $outputlines]} { lappend outputlines {*}[lrepeat 1 ""] } } else { + #old version - known to work with various ansi graphics - e.g fruit.ans + # - but fails to limit lines to renderwidth when expand_right == 0 append rendered $overflow_right set overflow_right "" set row $post_render_row @@ -851,38 +872,28 @@ tcl::namespace::eval overtype { set row $post_render_row set col $post_render_col if {$insert_lines_below == 1} { - if {$test_mode == 0} { - set row $renderedrow - set outputlines [linsert $outputlines [expr {$renderedrow }] {*}[lrepeat $insert_lines_below ""]] ;#note - linsert can add to end too - incr row $insert_lines_below - set col $opt_startcolumn - } else { - #set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $rendered]] - #set lhs [textblock::frame -title rendered -subtitle "row-$renderedrow" $lhs] - #set rhs "" - #if {$overflow_right ne ""} { - # set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $overflow_right]] - # set rhs [textblock::frame -title overflow_right $rhs] - #} - #puts [textblock::join $lhs $rhs] - - #rendered - append rendered $overflow_right - # - - - set overflow_right "" - set row $renderedrow - #only add newline if we're at the bottom - if {$row > [llength $outputlines]} { - lappend outputlines {*}[lrepeat $insert_lines_below ""] - } - incr row $insert_lines_below - set col $opt_startcolumn + #set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $rendered]] + #set lhs [textblock::frame -title rendered -subtitle "row-$renderedrow" $lhs] + #set rhs "" + #if {$overflow_right ne ""} { + # set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $overflow_right]] + # set rhs [textblock::frame -title overflow_right $rhs] + #} + #puts [textblock::join $lhs $rhs] + #rendered + append rendered $overflow_right + # + set overflow_right "" + set row $renderedrow + #only add newline if we're at the bottom + if {$row > [llength $outputlines]} { + lappend outputlines {*}[lrepeat $insert_lines_below ""] } + incr row $insert_lines_below + set col $opt_startcolumn } } else { set row $post_render_row @@ -974,7 +985,6 @@ tcl::namespace::eval overtype { incr row set col $opt_startcolumn ;#whether wrap or not - next data is at column 1 ?? } else { - #this works for test_mode (which should become the default) - but could give a bad result otherwise - review - add tests fix. set col $post_render_col #set unapplied "" ;#this seems wrong? #set unapplied [tcl::string::range $unapplied 1 end] @@ -1052,7 +1062,7 @@ tcl::namespace::eval overtype { } - if {!$opt_overflow && !$autowrap_mode} { + if {!$opt_expand_right && !$autowrap_mode} { #not allowed to overflow column or wrap therefore we get overflow data to truncate if {[tcl::dict::get $opts -ellipsis]} { set show_ellipsis 1 @@ -1130,7 +1140,6 @@ tcl::namespace::eval overtype { set debugmsg "" append debugmsg "${Y}${sep_header}${RST}" \n append debugmsg "looplimit $looplimit reached\n" - append debugmsg "test_mode:$test_mode\n" append debugmsg "data_mode:$data_mode\n" append debugmsg "opt_appendlines:$opt_appendlines\n" append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n" @@ -1433,7 +1442,7 @@ tcl::namespace::eval overtype { #padded overtext #lappend outputlines [renderline -insert_mode 0 -transparent $opt_transparent -startcolumn [expr {$left_exposed + 1}] $undertext $overtext] #Note - we still need overflow here - as although the overtext is short - it may oveflow due to the startoffset - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -overflow $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -expand_right $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] lappend outputlines [tcl::dict::get $rinfo result] } set replay_codes [tcl::dict::get $rinfo replay_codes] @@ -1584,7 +1593,7 @@ tcl::namespace::eval overtype { set overflowlength [expr {$overtext_datalen - $renderwidth}] if {$overflowlength > 0} { #raw overtext wider than undertext column - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -exposed1 $opt_exposed1 -exposed2 $opt_exposed2 -overflow $opt_overflow -startcolumn [expr {1 + $startoffset}] $undertext $overtext] + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -exposed1 $opt_exposed1 -exposed2 $opt_exposed2 -expand_right $opt_overflow -startcolumn [expr {1 + $startoffset}] $undertext $overtext] set replay_codes [tcl::dict::get $rinfo replay_codes] set rendered [tcl::dict::get $rinfo result] set overflow_right [tcl::dict::get $rinfo overflow_right] @@ -1632,8 +1641,8 @@ tcl::namespace::eval overtype { } else { #padded overtext #lappend outputlines [renderline -insert_mode 0 -transparent $opt_transparent -startcolumn [expr {$left_exposed + 1}] $undertext $overtext] - #Note - we still need overflow here - as although the overtext is short - it may oveflow due to the startoffset - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -overflow $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] + #Note - we still need expand_right here - as although the overtext is short - it may oveflow due to the startoffset + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -expand_right $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] #puts stderr "--> [ansistring VIEW -lf 1 -nul 1 $rinfo] <--" set overflow_right [tcl::dict::get $rinfo overflow_right] set unapplied [tcl::dict::get $rinfo unapplied] @@ -1655,7 +1664,8 @@ tcl::namespace::eval overtype { #-returnextra enables returning of overflow and length #review - use punk::ansi::ta::detect to short-circuit processing and do simpler string calcs as an optimisation? #review - DECSWL/DECDWL double width line codes - very difficult/impossible to align and compose with other elements - #(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char) + #(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char? + # This would probably be impractical to support for different fonts) #todo - review transparency issues with single/double width characters #bidi - need a base direction and concept of directional runs for RTL vs LTR - may be best handled at another layer? proc renderline {args} { @@ -1677,8 +1687,10 @@ tcl::namespace::eval overtype { #[para] The main 3 are the result, overflow_right, and unapplied. #[para] Renderline handles cursor movements from either keystrokes or ANSI sequences but for a full system the aforementioned loop will need to be in place to manage the set of lines under manipulation. + #puts stderr "renderline '$args'" + if {[llength $args] < 2} { - error {usage: ?-info 0|1? ?-startcolumn ? ?-cursor_column ? ?-cursor_row |""? ?-transparent [0|1|]? ?-overflow [1|0]? undertext overtext} + error {usage: ?-info 0|1? ?-startcolumn ? ?-cursor_column ? ?-cursor_row |""? ?-transparent [0|1|]? ?-expand_right [1|0]? undertext overtext} } lassign [lrange $args end-1 end] under over if {[string first \n $under] >= 0} { @@ -1692,7 +1704,7 @@ tcl::namespace::eval overtype { set opts [tcl::dict::create\ -etabs 0\ -width \uFFEF\ - -overflow 0\ + -expand_right 0\ -transparent 0\ -startcolumn 1\ -cursor_column 1\ @@ -1713,13 +1725,13 @@ tcl::namespace::eval overtype { #cursor_row, when numeric will allow detection of certain row moves that are still within our row - allowing us to avoid an early return #An empty string for cursor_row tells us we have no info about our own row context, and to return with an unapplied string if any row move occurs - #exposed1 and exposed2 for first and second col of underying 2wide char which is truncated by transparency or overflow + #exposed1 and exposed2 for first and second col of underying 2wide char which is truncated by transparency, currsor movements to 2nd charcol, or overflow/expand_right #todo - return info about such grapheme 'cuts' in -info structure and/or create option to raise an error set argsflags [lrange $args 0 end-2] tcl::dict::for {k v} $argsflags { switch -- $k { - -experimental - -cp437 - -width - -overflow - -transparent - -startcolumn - -cursor_column - -cursor_row + -experimental - -cp437 - -width - -expand_right - -transparent - -startcolumn - -cursor_column - -cursor_row - -crm_mode - -insert_mode - -autowrap_mode - -reverse_mode - -info - -exposed1 - -exposed2 - -cursor_restore_attributes { tcl::dict::set opts $k $v @@ -1732,7 +1744,7 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- --- --- --- --- --- --- set opt_width [tcl::dict::get $opts -width] set opt_etabs [tcl::dict::get $opts -etabs] - set opt_overflow [tcl::dict::get $opts -overflow] + set opt_expand_right [tcl::dict::get $opts -expand_right] set opt_colstart [tcl::dict::get $opts -startcolumn] ;#lhs limit for overlay - an offset to cursor_column - first visible column is 1. 0 or < 0 are before the start of the underlay set opt_colcursor [tcl::dict::get $opts -cursor_column];#start cursor column relative to overlay set opt_row_context [tcl::dict::get $opts -cursor_row] @@ -1752,17 +1764,7 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- --- --- --- --- --- --- set temp_cursor_saved [tcl::dict::get $opts -cursor_restore_attributes] - set test_mode 0 set cp437_glyphs [tcl::dict::get $opts -cp437] - foreach e [tcl::dict::get $opts -experimental] { - switch -- $e { - test_mode { - set test_mode 1 - set cp437_glyphs 1 - } - } - } - set test_mode 1 ;#try to elminate set cp437_map [tcl::dict::create] if {$cp437_glyphs} { set cp437_map [set ::punk::ansi::cp437_map] @@ -1852,7 +1854,7 @@ tcl::namespace::eval overtype { set u_codestack [list] #u_gx_stack probably isn't really a stack - I don't know if g0 g1 can stack or not - for now we support only g0 anyway set u_gx_stack [list] ;#separate stack for g0 (g1 g2 g3?) graphics on and off (DEC special graphics) - #set pt_underchars "" ;#for string_columns length calculation for overflow 0 truncation + #set pt_underchars "" ;#for string_columns length calculation for expand_right 0 truncation set remainder [list] ;#for returnextra foreach {pt code} $undermap { #pt = plain text @@ -1996,47 +1998,25 @@ tcl::namespace::eval overtype { #consider also if there are other codes that should be stacked..? } - if {!$test_mode} { - #fill columns to width with spaces, and carry over stacks - we will have to keep track of where the underlying data ends manually - TODO - #Specifying a width is suitable for terminal-like applications and text-blocks - if {$opt_width ne "\uFFEF"} { - if {[llength $understacks]} { - set cs $u_codestack - set gs $u_gx_stack - } else { - set cs [list] - set gs [list] - } - if {[llength $undercols]< $opt_width} { - set diff [expr {$opt_width- [llength $undercols]}] - if {$diff > 0} { - lappend undercols {*}[lrepeat $diff " "] - lappend understacks {*}[lrepeat $diff $cs] - lappend understacks_gx {*}[lrepeat $diff $gs] - } - } + #NULL empty cell indicator + if {$opt_width ne "\uFFEF"} { + if {[llength $understacks]} { + set cs $u_codestack + set gs $u_gx_stack + } else { + set cs [list] + set gs [list] } - } else { - #NULL empty cell indicator - if {$opt_width ne "\uFFEF"} { - if {[llength $understacks]} { - set cs $u_codestack - set gs $u_gx_stack - } else { - set cs [list] - set gs [list] - } - if {[llength $undercols]< $opt_width} { - set diff [expr {$opt_width- [llength $undercols]}] - if {$diff > 0} { - lappend undercols {*}[lrepeat $diff "\u0000"] - lappend understacks {*}[lrepeat $diff $cs] - lappend understacks_gx {*}[lrepeat $diff $gs] - } + if {[llength $undercols]< $opt_width} { + set diff [expr {$opt_width- [llength $undercols]}] + if {$diff > 0} { + lappend undercols {*}[lrepeat $diff "\u0000"] + lappend understacks {*}[lrepeat $diff $cs] + lappend understacks_gx {*}[lrepeat $diff $gs] } } - } + if {$opt_width ne "\uFFEF"} { set renderwidth $opt_width } else { @@ -2127,8 +2107,10 @@ tcl::namespace::eval overtype { lappend overlay_grapheme_control_stacks $o_codestack } } else { + set tsbegin [clock micros] foreach grapheme_original [punk::char::grapheme_split $pt] { set pt_crm [ansistring VIEW -nul 1 -lf 2 -vt 2 -ff 2 $grapheme_original] + #puts stderr "ptlen [string length $pt] graphemelen[string length $grapheme_original] pt_crmlen[string length $pt_crm] $pt_crm" foreach grapheme [punk::char::grapheme_split $pt_crm] { if {$grapheme eq "\n"} { lappend overlay_grapheme_control_stacks $o_codestack @@ -2142,6 +2124,8 @@ tcl::namespace::eval overtype { } } } + set elapsed [expr {[clock micros] - $tsbegin}] + puts stderr "ptlen [string length $pt] elapsedus:$elapsed" } #only stack SGR (graphics rendition) codes - not title sets, cursor moves etc @@ -2259,11 +2243,12 @@ tcl::namespace::eval overtype { # -- --- --- #we need to initialise overflow_idx before any potential row-movements - as they need to perform a loop break and force in_excess to 1 - if {$opt_overflow} { - #somewhat counterintuitively - overflow true means we can have lines as long as we want, but either way there can be excess data that needs to be thrown back to the calling loop. + if {$opt_expand_right} { + #expand_right true means we can have lines as long as we want, but either way there can be excess data that needs to be thrown back to the calling loop. + #we currently only support horizontal expansion to the right (review regarding RTL text!) set overflow_idx -1 } else { - #overflow zero - we can't grow beyond our column width - so we get ellipsis or truncation + #expand_right zero - we can't grow beyond our column width - so we get ellipsis or truncation if {$opt_width ne "\uFFEF"} { set overflow_idx [expr {$opt_width}] } else { @@ -2304,7 +2289,7 @@ tcl::namespace::eval overtype { #movements only occur within the overlay range. #an underlay is however not necessary.. e.g - #renderline -overflow 1 "" data + #renderline -expand_right 1 "" data #set re_mode {\x1b\[\?([0-9]*)(h|l)} ;#e.g DECAWM #set re_col_move {\x1b\[([0-9]*)(C|D|G)$} @@ -2331,7 +2316,7 @@ tcl::namespace::eval overtype { g { set ch $item #crm_mode affects both graphic and control - if {$crm_mode} { + if {0 && $crm_mode} { set chars [ansistring VIEW -nul 1 -lf 2 -vt 2 -ff 2 $ch] set chars [string map [list \n "\x1b\[00001E"] $chars] if {[llength [split $chars ""]] > 1} { @@ -2376,7 +2361,7 @@ tcl::namespace::eval overtype { #linefeed after final column #puts "---c at overflow_idx=$overflow_idx" incr cursor_row - set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to opt_overflow = 1|2 + set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to expand_right = 1 set instruction lf_overflow ;#only special treatment is to give it it's own instruction in case caller needs to handle differently priv::render_unapplied $overlay_grapheme_control_list $gci break @@ -2384,7 +2369,10 @@ tcl::namespace::eval overtype { #linefeed occurred in middle or at end of text #puts "---mid-or-end-text-linefeed idx:$idx overflow_idx:$overflow_idx" incr cursor_row - set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to opt_overflow = 1|2 + if {$idx == -1 || $overflow_idx > $idx} { + #don't set overflow_idx higher if it's already set lower and we're adding graphemes to overflow + set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to expand_right = 1 + } set instruction lf_mid priv::render_unapplied $overlay_grapheme_control_list $gci break @@ -2466,23 +2454,35 @@ tcl::namespace::eval overtype { #tab of some length dependent on tabstops/elastic tabstop settings? } } elseif {$idx >= $overflow_idx} { - #jmn? - set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci-1]] - #set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] - #don't incr idx beyond the overflow_idx - #idx_over already incremented - decrement so current overlay grapheme stacks go to unapplied - incr idx_over -1 - #priv::render_unapplied $overlay_grapheme_control_list [expr {$gci-1}] ;#back one index here too - priv::render_this_unapplied $overlay_grapheme_control_list $gci ;# - set instruction overflow - break + #REVIEW + set next_gc [lindex $overlay_grapheme_control_list $gci+1] ;#next grapheme or control + lassign $next_gc next_type next_item + if {$autowrap_mode || $next_type ne "g"} { + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci-1]] + #set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + #don't incr idx beyond the overflow_idx + #idx_over already incremented - decrement so current overlay grapheme stacks go to unapplied + incr idx_over -1 + #priv::render_unapplied $overlay_grapheme_control_list [expr {$gci-1}] ;#back one index here too + priv::render_this_unapplied $overlay_grapheme_control_list $gci ;# + set instruction overflow + break + } else { + #no point throwing back to caller for each grapheme that is overflowing + #without this branch - renderline would be called with overtext reducing only by one grapheme per call + #processing a potentially long overtext each time (ie - very slow) + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + #JMN4 + + } } } else { #review. - #This corresponds to opt_overflow being true (at least until overflow_idx is in some cases forced to a value when throwing back to calling loop) + #overflow_idx = -1 + #This corresponds to expand_right being true (at least until overflow_idx is in some cases forced to a value when throwing back to calling loop) } - if {($do_transparency && [regexp $opt_transparent $ch])} { + if {($do_transparency && [regexp $opt_transparent $ch])} { #pre opt_colstart is effectively transparent (we have applied padding of required number of columns to left of overlay) if {$idx > [llength $outcols]-1} { lappend outcols " " @@ -2621,7 +2621,7 @@ tcl::namespace::eval overtype { } incr idx } - if {($cursor_column < [llength $outcols]) || $overflow_idx == -1 || $test_mode} { + if {($cursor_column < [llength $outcols]) || $overflow_idx == -1} { incr cursor_column } } elseif {$uwidth > 1} { @@ -2655,12 +2655,6 @@ tcl::namespace::eval overtype { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx incr cursor_column - if {$overflow_idx !=-1 && !$test_mode} { - #overflow - if {$cursor_column > [llength $outcols]} { - set cursor_column [llength $outcols] - } - } } } } @@ -2704,6 +2698,7 @@ tcl::namespace::eval overtype { set leadernorm [tcl::string::range [tcl::string::map [list\ \x1b\[< 1006\ \x1b\[ 7CSI\ + \x1bP 7DCS\ \x9b 8CSI\ \x1b\] 7OSC\ \x9d 8OSC\ @@ -2720,6 +2715,11 @@ tcl::namespace::eval overtype { 7CSI - 7OSC { set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 2 end]] } + 7DCS { + #ESC P + #Device Control String https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Controls-beginning-with-ESC:ESC-F.C74 + set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 2 end]] + } 7ESC { set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 1 end]] } @@ -2812,7 +2812,7 @@ tcl::namespace::eval overtype { if {$overflow_idx == -1} { incr max } - if {$test_mode && $cursor_column == $max+1} { + if {$cursor_column == $max+1} { #move_forward while in overflow incr cursor_column -1 } @@ -2829,7 +2829,7 @@ tcl::namespace::eval overtype { } #horizontal movement beyond line extent needs to wrap - throw back to caller - #we may have both overflow_rightand unapplied data + #we may have both overflow_right and unapplied data #(can have overflow_right if we were in insert_mode and processed chars prior to this movement) #leave row as is - caller will need to determine how many rows the column-movement has consumed incr cursor_column $num ;#give our caller the necessary info as columns from start of row @@ -2844,7 +2844,8 @@ tcl::namespace::eval overtype { } } } else { - if {!$opt_overflow || ($cursor_column + $num) <= [llength $outcols+1]} { + #review - dead branch + if {!$expand_right || ($cursor_column + $num) <= [llength $outcols+1]} { incr idx $num incr cursor_column $num } else { @@ -3052,55 +3053,99 @@ tcl::namespace::eval overtype { } } J { - puts stderr "overtype::renderline ED - ERASE IN DISPLAY (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - if {$param eq ""} {set param 0} - switch -exact -- $param { - 0 { - #clear from cursor to end of screen - } - 1 { - #clear from cursor to beginning of screen - } - 2 { - #clear entire screen - #ansi.sys - move cursor to upper left REVIEW - set cursor_row 1 - set cursor_column 1 - set idx [expr {$cursor_column -1}] - set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] - incr idx_over - priv::render_unapplied $overlay_grapheme_control_list $gci - set instruction move - break - } - 3 { - #clear entire screen. presumably cursor doesn't move - otherwise it would be same as 2J ? - + set modegroup [tcl::string::index $codenorm 4] ;#e.g ? + switch -exact -- $modegroup { + ? { + #CSI ? Pn J - selective erase + puts stderr "overtype::renderline ED - SELECTIVE ERASE IN DISPLAY (UNIMPLEMENTED) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" } default { + puts stderr "overtype::renderline ED - ERASE IN DISPLAY (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of screen + } + 1 { + #clear from cursor to beginning of screen + } + 2 { + #clear entire screen + #ansi.sys - move cursor to upper left REVIEW + set cursor_row 1 + set cursor_column 1 + set idx [expr {$cursor_column -1}] + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + incr idx_over + priv::render_unapplied $overlay_grapheme_control_list $gci + set instruction move + break + } + 3 { + #clear entire screen. presumably cursor doesn't move - otherwise it would be same as 2J ? + + } + default { + } + } + } } - } K { - puts stderr "overtype::renderline EL - ERASE IN LINE (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - if {$param eq ""} {set param 0} - switch -exact -- $param { - 0 { - #clear from cursor to end of line - } - 1 { - #clear from cursor to beginning of line + #see DECECM regarding background colour + set modegroup [tcl::string::index $codenorm 4] ;#e.g ? + switch -exact -- $modegroup { + ? { + puts stderr "overtype::renderline DECSEL - SELECTIVE ERASE IN LINE (UNIMPLEMENTED) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + set param [string range $param 1 end] ;#chop qmark + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of line - depending on DECSCA + } + 1 { + #clear from cursor to beginning of line - depending on DECSCA + + } + 2 { + #clear entire line - depending on DECSCA + } + default { + puts stderr "overtype::renderline DECSEL - SELECTIVE ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } - } - 2 { - #clear entire line } default { - puts stderr "overtype::renderline EL - ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + puts stderr "overtype::renderline EL - ERASE IN LINE (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of line + } + 1 { + #clear from cursor to beginning of line + + } + 2 { + #clear entire line + } + default { + puts stderr "overtype::renderline EL - ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } } } } + L { + puts stderr "overtype::renderline IL - Insert Line - not implemented [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + M { + #CSI Pn M - DL - Delete Line + puts stderr "overtype::renderline DL - Delete Line - not implemented [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + + } X { puts stderr "overtype::renderline X ECH ERASE CHARACTER - $param" #ECH - erase character @@ -3108,6 +3153,36 @@ tcl::namespace::eval overtype { priv::render_erasechar $idx $param #cursor position doesn't change. } + q { + set code_secondlast [tcl::string::index $codenorm end-1] + switch -exact -- $code_secondlast { + {"} { + #DECSCA - Select Character Protection Attribute + #(for use with selective erase: DECSED and DECSEL) + set param [tcl::string::range $codenorm 4 end-2] + if {$param eq ""} {set param 0} + #TODO - store like SGR in stacks - replays? + switch -exact -- $param { + 0 - 2 { + #canerase + puts stderr "overtype::renderline - DECSCA canerase not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + 1 { + #cannoterase + puts stderr "overtype::renderline - DECSCA cannoterase not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + default { + puts stderr "overtype::renderline DECSCA param '$param' not understood [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } + + } + default { + puts stderr "overtype::renderline - CSI ... q not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } + + } r { #$re_decstbm #https://www.vt100.net/docs/vt510-rm/DECSTBM.html @@ -3279,72 +3354,97 @@ tcl::namespace::eval overtype { set instruction restore_cursor break } + "{" { + + puts stderr "renderline warning - CSI.. - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + "}" { + set code_secondlast [tcl::string::index $codenorm end-1] + switch -exact -- $code_secondlast { + ' { + puts stderr "renderline warning - DECIC - Insert Column - CSI...' - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + default { + puts stderr "renderline warning - CSI.. - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + } + } ~ { - #$re_vt_sequence - lassign [split $param {;}] key mod - - #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ - # - #e.g esc \[2~ insert esc \[2;2~ shift-insert - #mod - subtract 1, and then use bitmask - #shift = 1, (left)Alt = 2, control=4, meta=8 (meta seems to do nothing on many terminals on windows? Intercepted by windows?) - #puts stderr "vt key:$key mod:$mod code:[ansistring VIEW $code]" - if {$key eq "1"} { - #home - } elseif {$key eq "2"} { - #Insert - if {$mod eq ""} { - #no modifier key - set insert_mode [expr {!$insert_mode}] - #rather than set the cursor - we return the insert mode state so the caller can decide + set code_secondlast [tcl::string::index $codenorm end-1] ;#used for e.g CSI x '~ + switch -exact -- $code_secondlast { + ' { + #DECDC - editing sequence - Delete Column + puts stderr "renderline warning - DECDC - unimplemented" } - } elseif {$key eq "3"} { - #Delete - presumably this shifts other chars in the line, with empty cells coming in from the end - switch -- $mod { - "" { - priv::render_delchar $idx - } - "5" { - #ctrl-del - delete to end of word (pwsh) - possibly word on next line if current line empty(?) + default { + #$re_vt_sequence + lassign [split $param {;}] key mod + + #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ + # + #e.g esc \[2~ insert esc \[2;2~ shift-insert + #mod - subtract 1, and then use bitmask + #shift = 1, (left)Alt = 2, control=4, meta=8 (meta seems to do nothing on many terminals on windows? Intercepted by windows?) + #puts stderr "vt key:$key mod:$mod code:[ansistring VIEW $code]" + if {$key eq "1"} { + #home + } elseif {$key eq "2"} { + #Insert + if {$mod eq ""} { + #no modifier key + set insert_mode [expr {!$insert_mode}] + #rather than set the cursor - we return the insert mode state so the caller can decide + } + } elseif {$key eq "3"} { + #Delete - presumably this shifts other chars in the line, with empty cells coming in from the end + switch -- $mod { + "" { + priv::render_delchar $idx + } + "5" { + #ctrl-del - delete to end of word (pwsh) - possibly word on next line if current line empty(?) + } + } + } elseif {$key eq "4"} { + #End + } elseif {$key eq "5"} { + #pgup + } elseif {$key eq "6"} { + #pgDn + } elseif {$key eq "7"} { + #Home + #?? + set idx [expr {$opt_colstart -1}] + set cursor_column 1 + } elseif {$key eq "8"} { + #End + } elseif {$key eq "11"} { + #F1 - or ESCOP or e.g shift F1 ESC\[1;2P + } elseif {$key eq "12"} { + #F2 - or ESCOQ + } elseif {$key eq "13"} { + #F3 - or ESCOR + } elseif {$key eq "14"} { + #F4 - or ESCOS + } elseif {$key eq "15"} { + #F5 or shift F5 ESC\[15;2~ + } elseif {$key eq "17"} { + #F6 + } elseif {$key eq "18"} { + #F7 + } elseif {$key eq "19"} { + #F8 + } elseif {$key eq "20"} { + #F9 + } elseif {$key eq "21"} { + #F10 + } elseif {$key eq "23"} { + #F11 + } elseif {$key eq "24"} { + #F12 } + } - } elseif {$key eq "4"} { - #End - } elseif {$key eq "5"} { - #pgup - } elseif {$key eq "6"} { - #pgDn - } elseif {$key eq "7"} { - #Home - #?? - set idx [expr {$opt_colstart -1}] - set cursor_column 1 - } elseif {$key eq "8"} { - #End - } elseif {$key eq "11"} { - #F1 - or ESCOP or e.g shift F1 ESC\[1;2P - } elseif {$key eq "12"} { - #F2 - or ESCOQ - } elseif {$key eq "13"} { - #F3 - or ESCOR - } elseif {$key eq "14"} { - #F4 - or ESCOS - } elseif {$key eq "15"} { - #F5 or shift F5 ESC\[15;2~ - } elseif {$key eq "17"} { - #F6 - } elseif {$key eq "18"} { - #F7 - } elseif {$key eq "19"} { - #F8 - } elseif {$key eq "20"} { - #F9 - } elseif {$key eq "21"} { - #F10 - } elseif {$key eq "23"} { - #F11 - } elseif {$key eq "24"} { - #F12 } } @@ -3358,51 +3458,72 @@ tcl::namespace::eval overtype { set modegroup [tcl::string::index $codenorm 4] ;#e.g ? = switch -exact -- $modegroup { ? { - set num [tcl::string::range $codenorm 5 end-1] ;#param between ? and h|l - switch -- $num { - 5 { - #DECSNM - reverse video - #How we simulate this to render within a block of text is an open question. - #track all SGR stacks and constantly flip based on the current SGR reverse state? - #It is the job of the calling loop to do this - so at this stage we'll just set the states - - if {$code_end eq "h"} { - #set (enable) - set reverse_mode 1 - } else { - #reset (disable) - set reverse_mode 0 + set smparams [tcl::string::range $codenorm 5 end-1] ;#params between ? and h|l + #one or more modes can be set + set smparam_list [split $smparams {;}] + foreach num $smparam_list { + switch -- $num { + "" { + #ignore empties e.g extra/trailing semicolon in params } - - } - 7 { - #DECAWM autowrap - if {$code_end eq "h"} { - #set (enable) - set autowrap_mode 1 - if {$opt_width ne "\uFFEF"} { - set overflow_idx $opt_width + 5 { + #DECSNM - reverse video + #How we simulate this to render within a block of text is an open question. + #track all SGR stacks and constantly flip based on the current SGR reverse state? + #It is the job of the calling loop to do this - so at this stage we'll just set the states + + if {$code_end eq "h"} { + #set (enable) + set reverse_mode 1 } else { - #review - this is also the cursor position when adding a char at end of line? - set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + #reset (disable) + set reverse_mode 0 } - #review - can idx ever be beyond overflow_idx limit when we change e.g with a width setting and cursor movements? presume not - but sanity check for now. - if {$idx >= $overflow_idx} { - puts stderr "renderline error - idx '$idx' >= overflow_idx '$overflow_idx' - unexpected" + + } + 7 { + #DECAWM autowrap + if {$code_end eq "h"} { + #set (enable) + set autowrap_mode 1 + if {$opt_width ne "\uFFEF"} { + set overflow_idx $opt_width + } else { + #review - this is also the cursor position when adding a char at end of line? + set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + } + #review - can idx ever be beyond overflow_idx limit when we change e.g with a width setting and cursor movements? + # presume not usually - but sanity check with warning for now. + if {$idx >= $overflow_idx} { + puts stderr "renderline warning - idx '$idx' >= overflow_idx '$overflow_idx' - unexpected" + } + } else { + #reset (disable) + set autowrap_mode 0 + #REVIEW! + set overflow_idx -1 } - } else { - #reset (disable) - set autowrap_mode 0 - set overflow_idx -1 } - } - 25 { - if {$code_end eq "h"} { - #visible cursor + 25 { + if {$code_end eq "h"} { + #visible cursor - } else { - #invisible cursor + } else { + #invisible cursor + } + } + 117 { + #DECECM - Erase Color Mode + #https://invisible-island.net/ncurses/ncurses.faq.html + #The Erase color selection controls the background color used when text is erased or new + #text is scrolled on to the screen. Screen background causes newly erased areas or + #scrolled text to be written using color index zero, the screen background. This is VT + #and DECterm compatible. Text background causes erased areas or scrolled text to be + #written using the current text background color. This is PC console compatible and is + #the factory default. + + #see also: https://unix.stackexchange.com/questions/251726/clear-to-end-of-line-uses-the-wrong-background-color-in-screen } } } @@ -3422,8 +3543,21 @@ tcl::namespace::eval overtype { # #use ansistring VIEW -nul 1 -lf 2 -ff 2 -vt 2 #https://vt100.net/docs/vt510-rm/CRM.html + #NOTE - vt100 CRM always does auto-wrap at right margin. + #disabling auto-wrap in set-up or by sequence is disabled. + #We should default to turning off auto-wrap when crm_mode enabled.. but + #displaying truncated (on rhs) crm can still be very useful - and we have optimisation in overflow to avoid excess renderline calls (per grapheme) + #we therefore could reasonably put in an exception to allow auto_wrap to be disabled after crm_mode is engaged, + #although this would be potentially an annoying difference to some.. REVIEW if {$code_end eq "h"} { set crm_mode 1 + set autowrap_mode 1 + if {$opt_width ne "\uFFEF"} { + set overflow_idx $opt_width + } else { + #review - this is also the cursor position when adding a char at end of line? + set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + } } else { set crm_mode 0 } @@ -3431,8 +3565,10 @@ tcl::namespace::eval overtype { 4 { #IRM - Insert/Replace Mode if {$code_end eq "h"} { + #CSI 4 h set insert_mode 1 } else { + #CSI 4 l #replace mode set insert_mode 0 } @@ -3480,25 +3616,49 @@ tcl::namespace::eval overtype { } } 7ESC { + # #re_other_single {\x1b(D|M|E)$} #also PM \x1b^...(ST) switch -- [tcl::string::index $codenorm 4] { + c { + #RIS - reset terminal to initial state - where 'terminal' in this case is the renderspace - not the underlying terminal! + puts stderr "renderline reset" + priv::render_unapplied $overlay_grapheme_control_list $gci + set instruction reset + break + } D { #\x84 #index (IND) #vt102-docs: "Moves cursor down one line in same column. If cursor is at bottom margin, screen performs a scroll-up" - puts stderr "ESC D not fully implemented" + puts stderr "renderline ESC D not fully implemented" incr cursor_row priv::render_unapplied $overlay_grapheme_control_list $gci set instruction down #retain cursor_column break } + E { + #\x85 + #review - is behaviour different to lf? + #todo - possibly(?) same logic as handling above. i.e return instruction depends on where column_cursor is at the time we get NEL + #leave implementation until logic for is set in stone... still under review + #It's arguable NEL is a pure cursor movement as opposed to the semantic meaning of crlf or lf in a file. + # + #Next Line (NEL) "Move the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up" + puts stderr "overtype::renderline ESC E unimplemented" + + } + H { + #\x88 + #Tab Set + puts stderr "overtype::renderline ESC H tab set unimplemented" + } M { #\x8D #Reverse Index (RI) #vt102-docs: "Moves cursor up one line in same column. If cursor is at top margin, screen performs a scroll-down" - puts stderr "ESC M not fully implemented" + puts stderr "overtype::renderline ESC M not fully implemented" set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] #move up @@ -3512,17 +3672,39 @@ tcl::namespace::eval overtype { #retain cursor_column break } - E { - #\x85 - #review - is behaviour different to lf? - #todo - possibly(?) same logic as handling above. i.e return instruction depends on where column_cursor is at the time we get NEL - #leave implementation until logic for is set in stone... still under review - #It's arguable NEL is a pure cursor movement as opposed to the semantic meaning of crlf or lf in a file. - # - #Next Line (NEL) "Move the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up" - puts stderr "ESC E unimplemented" + N { + #\x8e - affects next character only + puts stderr "overtype::renderline single shift select G2 command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + O { + #\x8f - affects next character only + puts stderr "overtype::renderline single shift select G3 command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + P { + #\x90 + #DCS - shouldn't get here - handled in 7DCS branch + #similarly \] OSC (\x9d) and \\ (\x9c) ST + } + V { + #\x96 } + W { + #\x97 + } + X { + #\x98 + #SOS + if {[string index $code end] eq "\007"} { + set sos_content [string range $code 2 end-1] ;#ST is \007 + } else { + set sos_content [string range $code 2 end-2] ;#ST is \x1b\\ + } + #return in some useful form to the caller + #TODO! + lappend sos_list [list string $sos_content row $cursor_row column $cursor_column] + puts stderr "overtype::renderline ESCX SOS UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } ^ { #puts stderr "renderline PM" #Privacy Message. @@ -3550,24 +3732,6 @@ tcl::namespace::eval overtype { #lappend to a dict element in the result for application-specific processing lappend pm_list $pm_content } - N - O { - puts stderr "overtype::renderline single shift command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } - P { - puts stderr "overtype::renderline DEVICE CONTROL STRING command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } - X { - #SOS - if {[string index $code end] eq "\007"} { - set sos_content [string range $code 2 end-1] ;#ST is \007 - } else { - set sos_content [string range $code 2 end-2] ;#ST is \x1b\\ - } - #return in some useful form to the caller - #TODO! - lappend sos_list [list string $sos_content row $cursor_row column $cursor_column] - puts stderr "overtype::renderline ESCX SOS UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } _ { #APC Application Program Command #just warn for now.. @@ -3578,6 +3742,14 @@ tcl::namespace::eval overtype { } } + } + 7DCS { + puts stderr "overtype::renderline DCS - DEVICE CONTROL STRING command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + # + + } + 7OSC - 8OSC { + } default { } @@ -3593,7 +3765,7 @@ tcl::namespace::eval overtype { } #-------- - if {$opt_overflow == 0} { + if {$opt_expand_right == 0} { #need to truncate to the width of the original undertext #review - string_width vs printing_length here. undertext requirement to be already rendered therefore punk::char::string_width ok? #set num_under_columns [punk::char::string_width $pt_underchars] ;#plaintext underchars @@ -3774,13 +3946,14 @@ tcl::namespace::eval overtype { cursor_saved_attributes $cursor_saved_attributes\ cursor_column $cursor_column\ cursor_row $cursor_row\ - opt_overflow $opt_overflow\ + expand_right $opt_expand_right\ replay_codes $replay_codes\ replay_codes_underlay $replay_codes_underlay\ replay_codes_overlay $replay_codes_overlay\ pm_list $pm_list\ ] if {$opt_returnextra == 1} { + #puts stderr "renderline: $result" return $result } else { #human/debug - map special chars to visual glyphs @@ -3805,6 +3978,7 @@ tcl::namespace::eval overtype { return $result } } else { + #puts stderr "renderline returning: result $outstring instruction $instruction unapplied $unapplied overflow_right $overflow_right" return $outstring } #return [join $out ""] diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm index 7a2f944..267e680 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm @@ -106,7 +106,7 @@ tcl::namespace::eval punk::ansi::class { #overflow is a different concept - perhaps not particularly congruent with the idea of the textblock as a mini terminal emulator. #overflow effectively auto-expands the block(terminal?) width #overflow and wrap both being true won't make sense unless we implement a max_overflow concept - set o_rendered [overtype::renderspace -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] + set o_rendered [overtype::renderspace -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] if {$cksum eq "not-done"} { #if dimensions changed - the checksum won't have been done set o_rendered_what [$o_ansistringobj checksum] @@ -129,7 +129,7 @@ tcl::namespace::eval punk::ansi::class { set o_dimensions $dimensions - set rendered [overtype::renderspace -experimental {test_mode} -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] + set rendered [overtype::renderspace -cp437 1 -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] return $rendered } method render_to_input_line {args} { @@ -176,7 +176,7 @@ tcl::namespace::eval punk::ansi::class { if {$opt_minus ne "0"} { set chunk [tcl::string::range $chunk 0 end-$opt_minus] } - set rendered [overtype::renderspace -experimental {test_mode} -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" $chunk] + set rendered [overtype::renderspace -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" $chunk] set marker "" for {set i 1} {$i <= $w} {incr i} { if {$i % 10 == 0} { @@ -514,11 +514,8 @@ tcl::namespace::eval punk::ansi { set encnames [encoding names] set encoding "" set dimensions "" - set test_mode 0 foreach a $args { - if {$a eq "test_mode"} { - set test_mode 1 - } elseif {$a in $encnames} { + if {$a in $encnames} { set encoding $a } else { if {[regexp {[0-9]+(?:x|X)[0-9]+} $a]} { diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm index 6368aea..4dd7bd6 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm @@ -1021,8 +1021,8 @@ namespace eval punk::console { #It's known this isn't always the case - but things like textutil::untabify2 take only a single value #on some systems test_char_width is a similar speed to get_tabstop_apparent_width - but on some test_char_width is much slower #we will use test_char_width as a fallback - proc get_tabstop_apparent_width {} { - set tslist [get_tabstops] + proc get_tabstop_apparent_width {{inoutchannels {stdin stdout}}} { + set tslist [get_tabstops $inoutchannels] if {![llength $tslist]} { #either terminal failed to report - or none set. set testw [test_char_width \t] @@ -1199,7 +1199,7 @@ namespace eval punk::console { } if {!$emit} { - puts -nonewline stdout \033\[2K\033\[1G ;#2K erase line 1G cursor at col1 + puts -nonewline stdout \033\[2K\033\[1G ;#2K erase line, 1G cursor at col1 } set response "" if {[catch { @@ -1429,12 +1429,12 @@ namespace eval punk::console { proc cursor_save {} { #*** !doctools #[call [fun cursor_save]] - puts -nonewline \x1b\[s + puts -nonewline stdout \x1b\[s } proc cursor_restore {} { #*** !doctools #[call [fun cursor_restore]] - puts -nonewline \x1b\[u + puts -nonewline stdout \x1b\[u } #DEC equivalents of cursor_save/cursor_restore - perhaps more widely supported? proc cursor_save_dec {} { diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm new file mode 100644 index 0000000..628419f --- /dev/null +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm @@ -0,0 +1,632 @@ +# -*- tcl -*- +# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'pmix make' or bin/punkmake to update from -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) 2024 JMN +# (C) 2009 Path Thoyts +# +# @@ Meta Begin +# Application punk::zip 0.1.0 +# Meta platform tcl +# Meta license +# @@ Meta End + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# doctools header +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[manpage_begin shellspy_module_punk::zip 0 0.1.0] +#[copyright "2024"] +#[titledesc {Module API}] [comment {-- Name section and table of contents description --}] +#[moddesc {-}] [comment {-- Description at end of page heading --}] +#[require punk::zip] +#[keywords module] +#[description] +#[para] - + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section Overview] +#[para] overview of punk::zip +#[subsection Concepts] +#[para] - + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Requirements +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[subsection dependencies] +#[para] packages used by punk::zip +#[list_begin itemized] + +package require Tcl 8.6- +package require punk::args +#*** !doctools +#[item] [package {Tcl 8.6}] +#[item] [package {punk::args}] + +#*** !doctools +#[list_end] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section API] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# oo::class namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#tcl::namespace::eval punk::zip::class { + #*** !doctools + #[subsection {Namespace punk::zip::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 ---}] + #} +#} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# Base namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +tcl::namespace::eval punk::zip { + tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase + #variable xyz + + #*** !doctools + #[subsection {Namespace punk::zip}] + #[para] Core API functions for punk::zip + #[list_begin definitions] + + proc Path_a_atorbelow_b {path_a path_b} { + return [expr {[StripPath $path_b $path_a] ne $path_a}] + } + proc Path_a_at_b {path_a path_b} { + return [expr {[StripPath $path_a $path_b] eq "." }] + } + + proc Path_strip_alreadynormalized_prefixdepth {path prefix} { + if {$prefix eq ""} { + return $path + } + set pathparts [file split $path] + set prefixparts [file split $prefix] + if {[llength $prefixparts] >= [llength $pathparts]} { + return "" + } + return [file join \ + {*}[lrange \ + $pathparts \ + [llength $prefixparts] \ + end]] + } + + #StripPath - borrowed from tcllib fileutil + # ::fileutil::stripPath -- + # + # If the specified path references/is a path in prefix (or prefix itself) it + # is made relative to prefix. Otherwise it is left unchanged. + # In the case of it being prefix itself the result is the string '.'. + # + # Arguments: + # prefix prefix to strip from the path. + # path path to modify + # + # Results: + # path The (possibly) modified path. + + if {[string equal $::tcl_platform(platform) windows]} { + # Windows. While paths are stored with letter-case preserved al + # comparisons have to be done case-insensitive. For reference see + # SF Tcllib Bug 2499641. + + proc StripPath {prefix path} { + # [file split] is used to generate a canonical form for both + # paths, for easy comparison, and also one which is easy to modify + # using list commands. + + set prefix [file split $prefix] + set npath [file split $path] + + if {[string equal -nocase $prefix $npath]} { + return "." + } + + if {[string match -nocase "${prefix} *" $npath]} { + set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] + } + return $path + } + } else { + proc StripPath {prefix path} { + # [file split] is used to generate a canonical form for both + # paths, for easy comparison, and also one which is easy to modify + # using list commands. + + set prefix [file split $prefix] + set npath [file split $path] + + if {[string equal $prefix $npath]} { + return "." + } + + if {[string match "${prefix} *" $npath]} { + set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] + } + return $path + } + } + + proc Timet_to_dos {time_t} { + #*** !doctools + #[call [fun Timet_to_dos] [arg time_t]] + #[para] convert a unix timestamp into a DOS timestamp for ZIP times. + #[example { + # DOS timestamps are 32 bits split into bit regions as follows: + # 24 16 8 0 + # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + # |Y|Y|Y|Y|Y|Y|Y|m| |m|m|m|d|d|d|d|d| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s| + # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + #}] + set s [clock format $time_t -format {%Y %m %e %k %M %S}] + scan $s {%d %d %d %d %d %d} year month day hour min sec + expr {(($year-1980) << 25) | ($month << 21) | ($day << 16) + | ($hour << 11) | ($min << 5) | ($sec >> 1)} + } + + proc walk {args} { + #*** !doctools + #[call [fun walk] [arg ?options?] [arg base]] + #[para] Walk a directory tree rooted at base + #[para] the -excludes list can be a set of glob expressions to match against files and avoid + #[para] e.g + #[example { + # punk::zip::walk -exclude {CVS/* *~.#*} library + #}] + + set argd [punk::args::get_dict { + *proc -name punk::zip::walk + -excludes -default "" -help "list of glob expressions to match against files and exclude" + -subpath -default "" + *values -min 1 -max -1 + base + fileglobs -default {*} -multiple 1 + } $args] + set base [dict get $argd values base] + set fileglobs [dict get $argd values fileglobs] + set subpath [dict get $argd opts -subpath] + set excludes [dict get $argd opts -excludes] + + + set imatch [list] + foreach fg $fileglobs { + lappend imatch [file join $subpath $fg] + } + + set result {} + #set imatch [file join $subpath $match] + set files [glob -nocomplain -tails -types f -directory $base -- {*}$imatch] + foreach file $files { + set excluded 0 + foreach glob $excludes { + if {[string match $glob $file]} { + set excluded 1 + break + } + } + if {!$excluded} {lappend result $file} + } + foreach dir [glob -nocomplain -tails -types d -directory $base -- [file join $subpath *]] { + set subdir [walk -subpath $dir -excludes $excludes $base {*}$fileglobs] + if {[llength $subdir]>0} { + set result [concat $result $dir $subdir] + } + } + return $result + } + + # Mkzipfile -- + # + # FIX ME: should handle the current offset for non-seekable channels + # + proc Mkzipfile {zipchan base path {comment ""}} { + #*** !doctools + #[call [fun Mkzipfile] [arg zipchan] [arg base] [arg path] [arg ?comment?]] + #[para] Add a single file to a zip archive + #[para] The zipchan channel should already be open and binary. + #[para] You can provide a -comment for the file. + #[para] The return value is the central directory record that will need to be used when finalizing the zip archive. + + set fullpath [file join $base $path] + set mtime [Timet_to_dos [file mtime $fullpath]] + set utfpath [encoding convertto utf-8 $path] + set utfcomment [encoding convertto utf-8 $comment] + set flags [expr {(1<<11)}] ;# utf-8 comment and path + set method 0 ;# store 0, deflate 8 + set attr 0 ;# text or binary (default binary) + set version 20 ;# minumum version req'd to extract + set extra "" + set crc 0 + set size 0 + set csize 0 + set data "" + set seekable [expr {[tell $zipchan] != -1}] + if {[file isdirectory $fullpath]} { + set attrex 0x41ff0010 ;# 0o040777 (drwxrwxrwx) + #set attrex 0x40000010 + } elseif {[file executable $fullpath]} { + set attrex 0x81ff0080 ;# 0o100777 (-rwxrwxrwx) + } else { + set attrex 0x81b60020 ;# 0o100666 (-rw-rw-rw-) + if {[file extension $fullpath] in {".tcl" ".txt" ".c"}} { + set attr 1 ;# text + } + } + + if {[file isfile $fullpath]} { + set size [file size $fullpath] + if {!$seekable} {set flags [expr {$flags | (1 << 3)}]} + } + + + set offset [tell $zipchan] + set local [binary format a4sssiiiiss PK\03\04 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]] + append local $utfpath $extra + puts -nonewline $zipchan $local + + if {[file isfile $fullpath]} { + # If the file is under 2MB then zip in one chunk, otherwize we use + # streaming to avoid requiring excess memory. This helps to prevent + # storing re-compressed data that may be larger than the source when + # handling PNG or JPEG or nested ZIP files. + if {$size < 0x00200000} { + set fin [open $fullpath rb] + set data [read $fin] + set crc [zlib crc32 $data] + set cdata [zlib deflate $data] + if {[string length $cdata] < $size} { + set method 8 + set data $cdata + } + close $fin + set csize [string length $data] + puts -nonewline $zipchan $data + } else { + set method 8 + set fin [open $fullpath rb] + set zlib [zlib stream deflate] + while {![eof $fin]} { + set data [read $fin 4096] + set crc [zlib crc32 $data $crc] + $zlib put $data + if {[string length [set zdata [$zlib get]]]} { + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + } + } + close $fin + $zlib finalize + set zdata [$zlib get] + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + $zlib close + } + + if {$seekable} { + # update the header if the output is seekable + set local [binary format a4sssiiii PK\03\04 \ + $version $flags $method $mtime $crc $csize $size] + set current [tell $zipchan] + seek $zipchan $offset + puts -nonewline $zipchan $local + seek $zipchan $current + } else { + # Write a data descriptor record + set ddesc [binary format a4iii PK\7\8 $crc $csize $size] + puts -nonewline $zipchan $ddesc + } + } + + #PK\x01\x02 Cdentral directory file header + #set v1 0x0317 ;#upper byte 03 -> UNIX lower byte 23 -> 2.3 + set v1 0x0017 ;#upper byte 00 -> MS_DOS and OS/2 (FAT/VFAT/FAT32 file systems) + + set hdr [binary format a4ssssiiiisssssii PK\01\02 $v1 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]\ + [string length $utfcomment] 0 $attr $attrex $offset] + append hdr $utfpath $extra $utfcomment + return $hdr + } + # zip::mkzip -- + # + # eg: zip my.zip -directory Subdir -runtime unzipsfx.exe *.txt + # + proc mkzip {args} { + #*** !doctools + #[call [fun mkzip] [arg ?options?] [arg filename]] + #[para] Create a zip archive in 'filename' + #[para] If a file already exists, an error will be raised. + set argd [punk::args::get_dict { + *proc -name punk::zip::mkzip -help "Create a zip archive in 'filename'" + *opts + -return -default "pretty" -choices {pretty list none} -help "mkzip can return a list of the files and folders added to the archive + the option -return pretty is the default and uses the punk::lib pdict/plist system + to return a formatted list for the terminal + " + -zipkit -default 0 -type none -help "" + -runtime -default "" -help "specify a prefix file + e.g punk::zip::mkzip -runtime unzipsfx.exe -directory subdir output.zip + will create a self-extracting zip archive from the subdir/ folder. + " + -comment -default "" -help "An optional comment for the archive" + -directory -default "" -help "The new zip archive will scan for contents within this folder or current directory if not provided" + -base -default "" -help "The new zip archive will be rooted in this directory if provided + it must be a parent of -directory" + -exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"} + *values -min 1 -max -1 + filename -default "" -help "name of zipfile to create" + globs -default {*} -multiple 1 -help "list of glob patterns to match. + Only directories with matching files will be included in the archive" + } $args] + + set filename [dict get $argd values filename] + if {$filename eq ""} { + error "mkzip filename cannot be empty string" + } + if {[regexp {[?*]} $filename]} { + #catch a likely error where filename is omitted and first glob pattern is misinterpreted as zipfile name + error "mkzip filename should not contain glob characters ? *" + } + if {[file exists $filename]} { + error "mkzip filename:$filename already exists" + } + dict for {k v} [dict get $argd opts] { + switch -- $k { + -comment { + dict set argd opts $k [encoding convertto utf-8 $v] + } + -directory - -base { + dict set argd opts $k [file normalize $v] + } + } + } + + array set opts [dict get $argd opts] + + + if {$opts(-directory) ne ""} { + if {$opts(-base) ne ""} { + #-base and -directory have been normalized already + if {![Path_a_atorbelow_b $opts(-directory) $opts(-base)]} { + error "punk::zip::mkzip -base $opts(-base) must be above -directory $opts(-directory)" + } + set base $opts(-base) + set relpath [Path_strip_alreadynormalized_prefixdepth $opts(-directory) $opts(-base)] + } else { + set base $opts(-directory) + set relpath "" + } + set paths [walk -exclude $opts(-exclude) -subpath $relpath -- $base {*}[dict get $argd values globs]] + + set norm_filename [file normalize $filename] + set norm_dir [file normalize $opts(-directory)] ;#we only care if filename below -directory (which is where we start scanning) + if {[Path_a_atorbelow_b $norm_filename $norm_dir]} { + #check that we aren't adding the zipfile to itself + #REVIEW - now that we open zipfile after scanning - this isn't really a concern! + #keep for now in case we can add an -update or a -force facility (or in case we modify to add to zip as we scan for members?) + #In the case of -force - we may want to delay replacement of original until scan is done? + + #try to avoid looping on all paths and performing (somewhat) expensive file normalizations on each + #1st step is to check the patterns and see if our zipfile is already excluded - in which case we need not check the paths + set self_globs_match 0 + foreach g [dict get $argd values globs] { + if {[string match $g [file tail $filename]]} { + set self_globs_match 1 + break + } + } + if {$self_globs_match} { + #still dangerous + set self_excluded 0 + foreach e $opts(-exclude) { + if {[string match $e [file tail $filename]]} { + set self_excluded 1 + break + } + } + if {!$self_excluded} { + #still dangerous - likely to be in resultset - check each path + #puts stderr "zip file $filename is below directory $opts(-directory)" + set self_is_matched 0 + set i 0 + foreach p $paths { + set norm_p [file normalize [file join $opts(-directory) $p]] + if {[Path_a_at_b $norm_filename $norm_p]} { + set self_is_matched 1 + break + } + incr i + } + if {$self_is_matched} { + puts stderr "WARNING - zipfile being created '$filename' was matched. Excluding this file. Relocate the zip, or use -exclude patterns to avoid this message" + set paths [lremove $paths $i] + } + } + } + } + } else { + set paths [list] + set dir [pwd] + if {$opts(-base) ne ""} { + if {![Path_a_atorbelow_b $dir $opts(-base)]} { + error "punk::zip::mkzip -base $opts(-base) must be above current directory" + } + set relpath [Path_strip_alreadynormalized_prefixdepth [file normalize $dir] [file normalize $opts(-base)]] + } else { + set relpath "" + } + set base $opts(-base) + + set matches [glob -nocomplain -type f -- {*}[dict get $argd values globs]] + foreach m $matches { + if {$m eq $filename} { + #puts stderr "--> excluding $filename" + continue + } + set isok 1 + foreach e [concat $opts(-exclude) $filename] { + if {[string match $e $m]} { + set isok 0 + break + } + } + if {$isok} { + lappend paths [file join $relpath $m] + } + } + } + + if {![llength $paths]} { + return "" + } + + set zf [open $filename wb] + if {$opts(-runtime) ne ""} { + set rt [open $opts(-runtime) rb] + fcopy $rt $zf + close $rt + } elseif {$opts(-zipkit)} { + set zkd "#!/usr/bin/env tclkit\n\# This is a zip-based Tcl Module\n" + append zkd "package require vfs::zip\n" + append zkd "vfs::zip::Mount \[info script\] \[info script\]\n" + append zkd "if {\[file exists \[file join \[info script\] main.tcl\]\]} {\n" + append zkd " source \[file join \[info script\] main.tcl\]\n" + append zkd "}\n" + append zkd \x1A + puts -nonewline $zf $zkd + } + set count 0 + set cd "" + + set members [list] + foreach path $paths { + #puts $path + lappend members $path + append cd [Mkzipfile $zf $base $path] ;#path already includes relpath + incr count + } + set cdoffset [tell $zf] + set endrec [binary format a4ssssiis PK\05\06 0 0 \ + $count $count [string length $cd] $cdoffset\ + [string length $opts(-comment)]] + append endrec $opts(-comment) + puts -nonewline $zf $cd + puts -nonewline $zf $endrec + close $zf + + set result "" + switch -exact -- $opts(-return) { + list { + set result $members + } + pretty { + if {[info commands showlist] ne ""} { + set result [plist -channel none members] + } else { + set result $members + } + } + none { + set result "" + } + } + return $result + } + + + #*** !doctools + #[list_end] [comment {--- end definitions namespace punk::zip ---}] +} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# Secondary API namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +tcl::namespace::eval punk::zip::lib { + tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase + tcl::namespace::path [tcl::namespace::parent] + #*** !doctools + #[subsection {Namespace punk::zip::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 punk::zip::lib ---}] +} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[section Internal] +#tcl::namespace::eval punk::zip::system { + #*** !doctools + #[subsection {Namespace punk::zip::system}] + #[para] Internal functions that are not part of the API + + + +#} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Ready +package provide punk::zip [tcl::namespace::eval punk::zip { + variable pkg punk::zip + variable version + set version 0.1.0 +}] +return + +#*** !doctools +#[manpage_end] + diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.1.tm index 5d127a3..88fdc3f 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.1.tm @@ -1933,13 +1933,6 @@ tcl::namespace::eval textblock { set hval $ansibase_header$header ;#no reset set rowh [my header_height $hrow] - #set h_lines [lrepeat $rowh $hcell_line_blank] - #set hcell_blank [join $h_lines \n] - #set hval_lines [split $hval \n] - #set hval_lines [lrange $hval_lines 0 $rowh-1] - #set hval_block [join $hval_lines \n] - #set headercell [overtype::left -experimental test_mode $ansibase_header$hcell_blank$RST $hval_block] - if {$hrow == 0} { set hlims $header_boxlimits_toprow set rowpos "top" @@ -2146,7 +2139,7 @@ tcl::namespace::eval textblock { #puts $hblock #puts "==>hval:'$hval'[a]" #puts "==>hval:'[ansistring VIEW $hval]'" - #set spanned_frame [overtype::renderspace -experimental test_mode -transparent 1 $spanned_frame $hblock] + #set spanned_frame [overtype::renderspace -transparent 1 $spanned_frame $hblock] #spanned values default left - todo make configurable @@ -3504,11 +3497,11 @@ tcl::namespace::eval textblock { set height [textblock::height $table] ;#only need to get height once at start } else { set nextcol [textblock::join -- [textblock::block $padwidth $height $TSUB] $nextcol] - set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent $TSUB $table[unset table] $nextcol] + set table [overtype::renderspace -expand_right 1 -transparent $TSUB $table[unset table] $nextcol] #JMN #set nextcol [textblock::join -- [textblock::block $padwidth $height "\uFFFF"] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent \uFFFF $table $nextcol] + #set table [overtype::renderspace -expand_right 1 -transparent \uFFFF $table $nextcol] } incr padwidth $bodywidth incr colposn @@ -3609,14 +3602,7 @@ tcl::namespace::eval textblock { set table $nextcol set height [textblock::height $table] ;#only need to get height once at start } else { - set table [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -overflow 1 -experimental test_mode -transparent $TSUB $table $nextcol] - - #set nextcol [textblock::join -- [textblock::block $padwidth $height $TSUB] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent $TSUB $table[unset table] $nextcol] - #JMN - - #set nextcol [textblock::join -- [textblock::block $padwidth $height "\uFFFF"] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent \uFFFF $table $nextcol] + set table [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $table $nextcol] } incr padwidth $bodywidth incr colposn @@ -3726,7 +3712,7 @@ tcl::namespace::eval textblock { lappend body_blocks $nextcol_body } else { if {$headerheight > 0} { - set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -overflow 1 -experimental test_mode -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]] + set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]] } lappend body_blocks $nextcol_body #set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body] diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/include_modules.config b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/include_modules.config index 490025b..75a091d 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/include_modules.config +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/include_modules.config @@ -57,6 +57,7 @@ set bootsupport_modules [list\ modules punk::path\ modules punk::repo\ modules punk::tdl\ + modules punk::zip\ modules punk::winpath\ modules textblock\ modules oolib\ diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/logger-0.9.5.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/logger-0.9.5.tm new file mode 100644 index 0000000..739e1c9 --- /dev/null +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/logger-0.9.5.tm @@ -0,0 +1,1297 @@ +# logger.tcl -- +# +# Tcl implementation of a general logging facility. +# +# Copyright (c) 2003 by David N. Welton +# Copyright (c) 2004-2011 by Michael Schlenker +# Copyright (c) 2006,2015 by Andreas Kupries +# +# See the file license.terms. + +# The logger package provides an 'object oriented' log facility that +# lets you have trees of services, that inherit from one another. +# This is accomplished through the use of Tcl namespaces. + + +package require Tcl 8.5 9 +package provide logger 0.9.5 + +namespace eval ::logger { + namespace eval tree {} + namespace export init enable disable services servicecmd import + + # The active services. + variable services {} + + # The log 'levels'. + variable levels [list debug info notice warn error critical alert emergency] + + # The default global log level used for new logging services + variable enabled "debug" + + # Tcl return codes (in numeric order) + variable RETURN_CODES [list "ok" "error" "return" "break" "continue"] +} + +# Try to load msgcat and fall back to format if it fails +if {[catch {package require msgcat}]} { + interp alias {} ::logger::mc {} ::format +} else { + namespace eval ::logger { + namespace import ::msgcat::mc + } +} + +# ::logger::_nsExists -- +# +# Workaround for missing namespace exists in Tcl 8.2 and 8.3. +# + +if {[package vcompare [package provide Tcl] 8.4] < 0} { + proc ::logger::_nsExists {ns} { + expr {![catch {namespace parent $ns}]} + } +} else { + proc ::logger::_nsExists {ns} { + namespace exists $ns + } +} + +# ::logger::_cmdPrefixExists -- +# +# Utility function to check if a given callback prefix exists, +# this should catch all oddities in prefix names, including spaces, +# glob patterns, non normalized namespaces etc. +# +# Arguments: +# prefix - The command prefix to check +# +# Results: +# 1 or 0 for yes or no +# +proc ::logger::_cmdPrefixExists {prefix} { + set cmd [lindex $prefix 0] + set full [namespace eval :: namespace which [list $cmd]] + if {[string equal $full ""]} {return 0} else {return 1} + # normalize namespaces + set ns [namespace qualifiers $cmd] + set cmd ${ns}::[namespace tail $cmd] + set matches [::info commands ${ns}::*] + if {[lsearch -exact $matches $cmd] != -1} {return 1} + return 0 +} + +# ::logger::walk -- +# +# Walk namespaces, starting in 'start', and evaluate 'code' in +# them. +# +# Arguments: +# start - namespace to start in. +# code - code to execute in namespaces walked. +# +# Side Effects: +# Side effects of code executed. +# +# Results: +# None. + +proc ::logger::walk { start code } { + set children [namespace children $start] + foreach c $children { + logger::walk $c $code + namespace eval $c $code + } +} + +proc ::logger::init {service} { + variable levels + variable services + variable enabled + + if {[string length [string trim $service {:}]] == 0} { + return -code error \ + -errorcode [list LOGGER EMPTY_SERVICENAME] \ + [::logger::mc "Service name invalid. May not consist only of : or be empty"] + } + # We create a 'tree' namespace to house all the services, so + # they are in a 'safe' namespace sandbox, and won't overwrite + # any commands. + namespace eval tree::${service} { + variable service + variable levels + variable oldname + variable enabled + } + + lappend services $service + + set [namespace current]::tree::${service}::service $service + set [namespace current]::tree::${service}::levels $levels + set [namespace current]::tree::${service}::oldname $service + set [namespace current]::tree::${service}::enabled $enabled + + namespace eval tree::${service} { + # Callback to use when the service in question is shut down. + variable delcallback [namespace current]::no-op + + # Callback when the loglevel is changed + variable levelchangecallback [namespace current]::no-op + + # State variable to decide when to call levelcallback + variable inSetLevel 0 + + # The currently configured levelcommands + variable lvlcmds + array set lvlcmds {} + + # List of procedures registered via the trace command + variable traceList "" + + # Flag indicating whether or not tracing is currently enabled + variable tracingEnabled 0 + + # We use this to disable a service completely. In Tcl 8.4 + # or greater, by using this, disabled log calls are a + # no-op! + + proc no-op args {} + + proc stdoutcmd {level text} { + variable service + puts "\[[clock format [clock seconds]]\] \[$service\] \[$level\] \'$text\'" + } + + proc stderrcmd {level text} { + variable service + puts stderr "\[[clock format [clock seconds]]\] \[$service\] \[$level\] \'$text\'" + } + + + # setlevel -- + # + # This command differs from enable and disable in that + # it disables all the levels below that selected, and + # then enables all levels above it, which enable/disable + # do not do. + # + # Arguments: + # lv - the level, as defined in $levels. + # + # Side Effects: + # Runs disable for the level, and then enable, in order + # to ensure that all levels are set correctly. + # + # Results: + # None. + + + proc setlevel {lv} { + variable inSetLevel 1 + set oldlvl [currentloglevel] + + # do not allow enable and disable to do recursion + if {[catch { + disable $lv 0 + set newlvl [enable $lv 0] + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } + # do the recursion here + logger::walk [namespace current] [list setlevel $lv] + + set inSetLevel 0 + lvlchangewrapper $oldlvl $newlvl + return + } + + # enable -- + # + # Enable a particular 'level', and above, for the + # service, and its 'children'. + # + # Arguments: + # lv - the level, as defined in $levels. + # + # Side Effects: + # Enables logging for the particular level, and all + # above it (those more important). It also walks + # through all services that are 'children' and enables + # them at the same level or above. + # + # Results: + # None. + + proc enable {lv {recursion 1}} { + variable levels + set lvnum [lsearch -exact $levels $lv] + if { $lvnum == -1 } { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + + variable enabled + set newlevel $enabled + set elnum [lsearch -exact $levels $enabled] + if {($elnum == -1) || ($elnum > $lvnum)} { + set newlevel $lv + } + + variable service + while { $lvnum < [llength $levels] } { + interp alias {} [namespace current]::[lindex $levels $lvnum] \ + {} [namespace current]::[lindex $levels $lvnum]cmd + incr lvnum + } + + if {$recursion} { + logger::walk [namespace current] [list enable $lv] + } + lvlchangewrapper $enabled $newlevel + set enabled $newlevel + } + + # disable -- + # + # Disable a particular 'level', and below, for the + # service, and its 'children'. + # + # Arguments: + # lv - the level, as defined in $levels. + # + # Side Effects: + # Disables logging for the particular level, and all + # below it (those less important). It also walks + # through all services that are 'children' and disables + # them at the same level or below. + # + # Results: + # None. + + proc disable {lv {recursion 1}} { + variable levels + set lvnum [lsearch -exact $levels $lv] + if { $lvnum == -1 } { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + + variable enabled + set newlevel $enabled + set elnum [lsearch -exact $levels $enabled] + if {($elnum > -1) && ($elnum <= $lvnum)} { + if {$lvnum+1 >= [llength $levels]} { + set newlevel "none" + } else { + set newlevel [lindex $levels [expr {$lvnum+1}]] + } + } + + while { $lvnum >= 0 } { + + interp alias {} [namespace current]::[lindex $levels $lvnum] {} \ + [namespace current]::no-op + incr lvnum -1 + } + if {$recursion} { + logger::walk [namespace current] [list disable $lv] + } + lvlchangewrapper $enabled $newlevel + set enabled $newlevel + } + + # currentloglevel -- + # + # Get the currently enabled log level for this service. + # + # Arguments: + # none + # + # Side Effects: + # none + # + # Results: + # current log level + # + + proc currentloglevel {} { + variable enabled + return $enabled + } + + # lvlchangeproc -- + # + # Set or introspect a callback for when the logger instance + # changes its loglevel. + # + # Arguments: + # cmd - the Tcl command to call, it is called with two parameters, old and new log level. + # or none for introspection + # + # Side Effects: + # None. + # + # Results: + # If no arguments are given return the current callback cmd. + + proc lvlchangeproc {args} { + variable levelchangecallback + + switch -exact -- [llength [::info level 0]] { + 1 {return $levelchangecallback} + 2 { + if {[::logger::_cmdPrefixExists [lindex $args 0]]} { + set levelchangecallback [lindex $args 0] + } else { + return -code error \ + -errorcode [list LOGGER INVALID_CMD] \ + [::logger::mc "Invalid cmd '%s' - does not exist" [lindex $args 0]] + } + } + default { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "Wrong # of arguments. Usage: \${log}::lvlchangeproc ?cmd?"] + } + } + } + + proc lvlchangewrapper {old new} { + variable inSetLevel + + # we are called after disable and enable are finished + if {$inSetLevel} {return} + + # no action if level does not change + if {[string equal $old $new]} {return} + + variable levelchangecallback + # no action if levelchangecallback isn't a valid command + if {[::logger::_cmdPrefixExists $levelchangecallback]} { + catch { + uplevel \#0 [linsert $levelchangecallback end $old $new] + } + } + } + + # logproc -- + # + # Command used to create a procedure that is executed to + # perform the logging. This could write to disk, out to + # the network, or something else. + # If two arguments are given, use an existing command. + # If three arguments are given, create a proc. + # + # Arguments: + # lv - the level to log, which must be one of $levels. + # args - either zero, one or two arguments. + # if zero this returns the current command registered + # if one, this is a cmd name that is called for this level + # if two, these are an argument and proc body + # + # Side Effects: + # Creates a logging command to take care of the details + # of logging an event. + # + # Results: + # If called with zero length args, returns the name of the currently + # configured logging procedure. + # + # + + proc logproc {lv args} { + variable levels + variable lvlcmds + + set lvnum [lsearch -exact $levels $lv] + if { ($lvnum == -1) && ($lv != "trace") } { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + switch -exact -- [llength $args] { + 0 { + return $lvlcmds($lv) + } + 1 { + set cmd [lindex $args 0] + if {[string equal "[namespace current]::${lv}cmd" $cmd]} {return} + if {[llength [::info commands $cmd]]} { + proc ${lv}cmd args [format { + uplevel 1 [list %s [expr {[llength $args]==1 ? [lindex $args end] : $args}]] + } $cmd] + } else { + return -code error \ + -errorcode [list LOGGER INVALID_CMD] \ + [::logger::mc "Invalid cmd '%s' - does not exist" $cmd] + } + set lvlcmds($lv) $cmd + } + 2 { + foreach {arg body} $args {break} + proc ${lv}cmd args [format {\ + _setservicename args + set val [%s [expr {[llength $args]==1 ? [lindex $args end] : $args}]] + _restoreservice + set val} ${lv}customcmd] + proc ${lv}customcmd $arg $body + set lvlcmds($lv) [namespace current]::${lv}customcmd + } + default { + return -code error \ + -errorcode [list LOGGER WRONG_USAGE] \ + [::logger::mc \ + "Usage: \${log}::logproc level ?cmd?\nor \${log}::logproc level argname body" ] + } + } + } + + + # delproc -- + # + # Set or introspect a callback for when the logger instance + # is deleted. + # + # Arguments: + # cmd - the Tcl command to call. + # or none for introspection + # + # Side Effects: + # None. + # + # Results: + # If no arguments are given return the current callback cmd. + + proc delproc {args} { + variable delcallback + + switch -exact -- [llength [::info level 0]] { + 1 {return $delcallback} + 2 { if {[::logger::_cmdPrefixExists [lindex $args 0]]} { + set delcallback [lindex $args 0] + } else { + return -code error \ + -errorcode [list LOGGER INVALID_CMD] \ + [::logger::mc "Invalid cmd '%s' - does not exist" [lindex $args 0]] + } + } + default { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "Wrong # of arguments. Usage: \${log}::delproc ?cmd?"] + } + } + } + + + # delete -- + # + # Delete the namespace and its children. + + proc delete {} { + variable delcallback + variable service + + logger::walk [namespace current] delete + if {[::logger::_cmdPrefixExists $delcallback]} { + uplevel \#0 [lrange $delcallback 0 end] + } + # clean up the global services list + set idx [lsearch -exact [logger::services] $service] + if {$idx !=-1} { + set ::logger::services [lreplace [logger::services] $idx $idx] + } + + namespace delete [namespace current] + + } + + # services -- + # + # Return all child services + + proc services {} { + variable service + + set children [list] + foreach srv [logger::services] { + if {[string match "${service}::*" $srv]} { + lappend children $srv + } + } + return $children + } + + # servicename -- + # + # Return the name of the service + + proc servicename {} { + variable service + return $service + } + + proc _setservicename {argname} { + variable service + variable oldname + upvar 1 $argname arg + if {[llength $arg] <= 1} { + return + } + + set count -1 + set newname "" + while {[string equal [lindex $arg [expr {$count+1}]] "-_logger::service"]} { + incr count 2 + set newname [lindex $arg $count] + } + if {[string equal $newname ""]} { + return + } + set oldname $service + set service $newname + # Pop off "-_logger::service " from argument list + set arg [lreplace $arg 0 $count] + } + + proc _restoreservice {} { + variable service + variable oldname + set service $oldname + return + } + + proc trace { action args } { + variable service + + # Allow other boolean values (true, false, yes, no, 0, 1) to be used + # as synonymns for "on" and "off". + + if {[string is boolean $action]} { + set xaction [expr {($action && 1) ? "on" : "off"}] + } else { + set xaction $action + } + + # Check for required arguments for actions/subcommands and dispatch + # to the appropriate procedure. + + switch -- $xaction { + "status" { + return [uplevel 1 [list logger::_trace_status $service $args]] + } + "on" { + if {[llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace on\""] + } + return [logger::_trace_on $service] + } + "off" { + if {[llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace off\""] + } + return [logger::_trace_off $service] + } + "add" { + if {![llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace add ?-ns? ...\""] + } + return [uplevel 1 [list ::logger::_trace_add $service $args]] + } + "remove" { + if {![llength $args]} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc "wrong # args: should be \"trace remove ?-ns? ...\""] + } + return [uplevel 1 [list ::logger::_trace_remove $service $args]] + } + + default { + return -code error \ + -errorcode [list LOGGER INVALID_ARG] \ + [::logger::mc "Invalid action \"%s\": must be status, add, remove,\ + on, or off" $action] + } + } + } + + # Walk the parent service namespaces to see first, if they + # exist, and if any are enabled, and then, as a + # consequence, enable this one + # too. + + enable $enabled + variable parent [namespace parent] + while {[string compare $parent "::logger::tree"]} { + # If the 'enabled' variable doesn't exist, create the + # whole thing. + if { ! [::info exists ${parent}::enabled] } { + logger::init [string range $parent 16 end] + } + set enabled [set ${parent}::enabled] + enable $enabled + set parent [namespace parent $parent] + } + } + + # Now create the commands for different levels. + + namespace eval tree::${service} { + set parent [namespace parent] + + # We 'inherit' the commands from the parents. This + # means that, if you want to share the same methods with + # children, they should be instantiated after the parent's + # methods have been defined. + + variable lvl ; # prevent creative writing to the global scope + if {[string compare $parent "::logger::tree"]} { + foreach lvl [::logger::levels] { + # OPTIMIZE: do not allow multiple aliases in the hierarchy + # they can always be replaced by more efficient + # direct aliases to the target procs. + interp alias {} [namespace current]::${lvl}cmd \ + {} ${parent}::${lvl}cmd -_logger::service $service + } + # inherit the starting loglevel of the parent service + setlevel [${parent}::currentloglevel] + } else { + foreach lvl [concat [::logger::levels] "trace"] { + proc ${lvl}cmd args [format {\ + _setservicename args + set val [stdoutcmd %s [expr {[llength $args]==1 ? [lindex $args end] : $args}]] + _restoreservice + set val } $lvl] + + set lvlcmds($lvl) [namespace current]::${lvl}cmd + } + setlevel $::logger::enabled + } + unset lvl ; # drop the temp iteration variable + } + + return ::logger::tree::${service} +} + +# ::logger::services -- +# +# Returns a list of all active services. +# +# Arguments: +# None. +# +# Side Effects: +# None. +# +# Results: +# List of active services. + +proc ::logger::services {} { + variable services + return $services +} + +# ::logger::enable -- +# +# Global enable for a certain level. NOTE - this implementation +# isn't terribly effective at the moment, because it might hit +# children before their parents, who will then walk down the +# tree attempting to disable the children again. +# +# Arguments: +# lv - level above which to enable logging. +# +# Side Effects: +# Enables logging in a given level, and all higher levels. +# +# Results: +# None. + +proc ::logger::enable {lv} { + variable services + if {[catch { + foreach sv $services { + ::logger::tree::${sv}::enable $lv + } + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } +} + +proc ::logger::disable {lv} { + variable services + if {[catch { + foreach sv $services { + ::logger::tree::${sv}::disable $lv + } + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } +} + +proc ::logger::setlevel {lv} { + variable services + variable enabled + variable levels + if {[lsearch -exact $levels $lv] == -1} { + return -code error \ + -errorcode [list LOGGER INVALID_LEVEL] \ + [::logger::mc "Invalid level '%s' - levels are %s" $lv $levels] + } + set enabled $lv + if {[catch { + foreach sv $services { + ::logger::tree::${sv}::setlevel $lv + } + } msg] == 1} { + return -code error -errorcode $::errorCode $msg + } +} + +# ::logger::levels -- +# +# Introspect the available log levels. Provided so a caller does +# not need to know implementation details or code the list +# himself. +# +# Arguments: +# None. +# +# Side Effects: +# None. +# +# Results: +# levels - The list of valid log levels accepted by enable and disable + +proc ::logger::levels {} { + variable levels + return $levels +} + +# ::logger::servicecmd -- +# +# Get the command token for a given service name. +# +# Arguments: +# service - name of the service. +# +# Side Effects: +# none +# +# Results: +# log - namespace token for this service + +proc ::logger::servicecmd {service} { + variable services + if {[lsearch -exact $services $service] == -1} { + return -code error \ + -errorcode [list LOGGER NO_SUCH_SERVICE] \ + [::logger::mc "Service \"%s\" does not exist." $service] + } + return "::logger::tree::${service}" +} + +# ::logger::import -- +# +# Import the logging commands. +# +# Arguments: +# service - name of the service. +# +# Side Effects: +# creates aliases in the target namespace +# +# Results: +# none + +proc ::logger::import {args} { + variable services + + if {[llength $args] == 0 || [llength $args] > 7} { + return -code error \ + -errorcode [list LOGGER WRONG_NUM_ARGS] \ + [::logger::mc \ + "Wrong # of arguments: \"logger::import ?-all?\ + ?-force?\ + ?-prefix prefix? ?-namespace namespace? service\""] + } + + # process options + # + set import_all 0 + set force 0 + set prefix "" + set ns [uplevel 1 namespace current] + while {[llength $args] > 1} { + set opt [lindex $args 0] + set args [lrange $args 1 end] + switch -exact -- $opt { + -all { set import_all 1} + -prefix { set prefix [lindex $args 0] + set args [lrange $args 1 end] + } + -namespace { + set ns [lindex $args 0] + set args [lrange $args 1 end] + } + -force { + set force 1 + } + default { + return -code error \ + -errorcode [list LOGGER UNKNOWN_ARG] \ + [::logger::mc \ + "Unknown argument: \"%s\" :\nUsage:\ + \"logger::import ?-all? ?-force?\ + ?-prefix prefix? ?-namespace namespace? service\"" $opt] + } + } + } + + # + # build the list of commands to import + # + + set cmds [logger::levels] + lappend cmds "trace" + if {$import_all} { + lappend cmds setlevel enable disable logproc delproc services + lappend cmds servicename currentloglevel delete + } + + # + # check the service argument + # + + set service [lindex $args 0] + if {[lsearch -exact $services $service] == -1} { + return -code error \ + -errorcode [list LOGGER NO_SUCH_SERVICE] \ + [::logger::mc "Service \"%s\" does not exist." $service] + } + + # + # setup the namespace for the import + # + + set sourcens [logger::servicecmd $service] + set localns [uplevel 1 namespace current] + + if {[string match ::* $ns]} { + set importns $ns + } else { + set importns ${localns}::$ns + } + + # fake namespace exists for Tcl 8.2 - 8.3 + if {![_nsExists $importns]} { + namespace eval $importns {} + } + + + # + # prepare the import + # + + set imports "" + foreach cmd $cmds { + set cmdname ${importns}::${prefix}$cmd + set collision [llength [info commands $cmdname]] + if {$collision && !$force} { + return -code error \ + -errorcode [list LOGGER IMPORT_NAME_EXISTS] \ + [::logger::mc "can't import command \"%s\": already exists" $cmdname] + } + lappend imports ${importns}::${prefix}$cmd ${sourcens}::${cmd} + } + + # + # and execute the aliasing after checking all is well + # + + foreach {target source} $imports { + proc $target {args} "uplevel 1 \[linsert \$args 0 $source \]" + } +} + +# ::logger::initNamespace -- +# +# Creates a logger for the specified namespace and makes the log +# commands available to said namespace as well. Allows the initial +# setting of a default log level. +# +# Arguments: +# ns - Namespace to initialize, is also the service name, modulo a ::-prefix +# level - Initial log level, optional, defaults to 'warn'. +# +# Side Effects: +# creates aliases in the target namespace +# +# Results: +# none + +proc ::logger::initNamespace {ns {level {}}} { + set service [string trimleft $ns :] + if {$level == ""} { + # No user-specified level. Figure something out. + # - If the parent service exists then the 'logger::init' + # below will automatically inherit its level. Good enough. + # - Without a parent service go and use a default level of 'warn'. + set parent [string trimleft [namespace qualifiers $service] :] + set hasparent [expr {($parent != {}) && [_nsExists ::logger::tree::${parent}]}] + if {!$hasparent} { + set level warn + } + } + + namespace eval $ns [list ::logger::init $service] + namespace eval $ns [list ::logger::import -force -all -namespace log $service] + if {$level != ""} { + namespace eval $ns [list log::setlevel $level] + } + return +} + +# This procedure handles the "logger::trace status" command. Given no +# arguments, returns a list of all procedures that have been registered +# via "logger::trace add". Given one or more procedure names, it will +# return 1 if all were registered, or 0 if any were not. + +proc ::logger::_trace_status { service procList } { + upvar #0 ::logger::tree::${service}::traceList traceList + + # If no procedure names were given, just return the registered list + + if {![llength $procList]} { + return $traceList + } + + # Get caller's namespace for qualifying unqualified procedure names + + set caller_ns [uplevel 1 namespace current] + set caller_ns [string trimright $caller_ns ":"] + + # Search for any specified proc names that are *not* registered + + foreach procName $procList { + # Make sure the procedure namespace is qualified + + if {![string match "::*" $procName]} { + set procName ${caller_ns}::$procName + } + + # Check if the procedure has been registered for tracing + + if {[lsearch -exact $traceList $procName] == -1} { + return 0 + } + } + + return 1 +} + +# This procedure handles the "logger::trace on" command. If tracing +# is turned off, it will enable Tcl trace handlers for all of the procedures +# registered via "logger::trace add". Does nothing if tracing is already +# turned on. + +proc ::logger::_trace_on { service } { + set tcl_version [package provide Tcl] + + if {[package vcompare $tcl_version "8.4"] < 0} { + return -code error \ + -errorcode [list LOGGER TRACE_NOT_AVAILABLE] \ + [::logger::mc "execution tracing is not available in Tcl %s" $tcl_version] + } + + namespace eval ::logger::tree::${service} { + if {!$tracingEnabled} { + set tracingEnabled 1 + ::logger::_enable_traces $service $traceList + } + } + + return 1 +} + +# This procedure handles the "logger::trace off" command. If tracing +# is turned on, it will disable Tcl trace handlers for all of the procedures +# registered via "logger::trace add", leaving them in the list so they +# tracing on all of them can be enabled again with "logger::trace on". +# Does nothing if tracing is already turned off. + +proc ::logger::_trace_off { service } { + namespace eval ::logger::tree::${service} { + if {$tracingEnabled} { + ::logger::_disable_traces $service $traceList + set tracingEnabled 0 + } + } + + return 1 +} + +# This procedure is used by the logger::trace add and remove commands to +# process the arguments in a common fashion. If the -ns switch is given +# first, this procedure will return a list of all existing procedures in +# all of the namespaces given in remaining arguments. Otherwise, each +# argument is taken to be either a pattern for a glob-style search of +# procedure names or, failing that, a namespace, in which case this +# procedure returns a list of all the procedures matching the given +# pattern (or all in the named namespace, if no procedures match). + +proc ::logger::_trace_get_proclist { inputList } { + set procList "" + + if {[string equal [lindex $inputList 0] "-ns"]} { + # Verify that at least one target namespace was supplied + + set inputList [lrange $inputList 1 end] + if {![llength $inputList]} { + return -code error \ + -errorcode [list LOGGER TARGET_MISSING] \ + [::logger::mc "Must specify at least one namespace target"] + } + + # Rebuild the argument list to contain namespace procedures + + foreach namespace $inputList { + # Don't allow tracing of the logger (or child) namespaces + + if {![string match "::logger::*" $namespace]} { + set nsProcList [::info procs ${namespace}::*] + set procList [concat $procList $nsProcList] + } + } + } else { + # Search for procs or namespaces matching each of the specified + # patterns. + + foreach pattern $inputList { + set matches [uplevel 1 ::info proc $pattern] + + if {![llength $matches]} { + if {[uplevel 1 namespace exists $pattern]} { + set matches [::info procs ${pattern}::*] + } + + # Matched procs will be qualified due to above pattern + + set procList [concat $procList $matches] + } elseif {[string match "::*" $pattern]} { + # Patterns were pre-qualified - add them directly + + set procList [concat $procList $matches] + } else { + # Qualify each proc with the namespace it was in + + set ns [uplevel 1 namespace current] + if {$ns == "::"} { + set ns "" + } + foreach proc $matches { + lappend procList ${ns}::$proc + } + } + } + } + + return $procList +} + +# This procedure handles the "logger::trace add" command. If the tracing +# feature is enabled, it will enable the Tcl entry and leave trace handlers +# for each procedure specified that isn't already being traced. Each +# procedure is added to the list of procedures that the logger trace feature +# should log when tracing is enabled. + +proc ::logger::_trace_add { service procList } { + upvar #0 ::logger::tree::${service}::traceList traceList + + # Handle -ns switch and glob search patterns for procedure names + + set procList [uplevel 1 [list logger::_trace_get_proclist $procList]] + + # Enable tracing for each procedure that has not previously been + # specified via logger::trace add. If tracing is off, this will just + # store the name of the procedure for later when tracing is turned on. + + foreach procName $procList { + if {[lsearch -exact $traceList $procName] == -1} { + lappend traceList $procName + ::logger::_enable_traces $service [list $procName] + } + } +} + +# This procedure handles the "logger::trace remove" command. If the tracing +# feature is enabled, it will remove the Tcl entry and leave trace handlers +# for each procedure specified. Each procedure is removed from the list +# of procedures that the logger trace feature should log when tracing is +# enabled. + +proc ::logger::_trace_remove { service procList } { + upvar #0 ::logger::tree::${service}::traceList traceList + + # Handle -ns switch and glob search patterns for procedure names + + set procList [uplevel 1 [list logger::_trace_get_proclist $procList]] + + # Disable tracing for each proc that previously had been specified + # via logger::trace add. If tracing is off, this will just + # remove the name of the procedure from the trace list so that it + # will be excluded when tracing is turned on. + + foreach procName $procList { + set index [lsearch -exact $traceList $procName] + if {$index != -1} { + set traceList [lreplace $traceList $index $index] + ::logger::_disable_traces $service [list $procName] + } + } +} + +# This procedure enables Tcl trace handlers for all procedures specified. +# It is used both to enable Tcl's tracing for a single procedure when +# removed via "logger::trace add", as well as to enable all traces +# via "logger::trace on". + +proc ::logger::_enable_traces { service procList } { + upvar #0 ::logger::tree::${service}::tracingEnabled tracingEnabled + + if {$tracingEnabled} { + foreach procName $procList { + ::trace add execution $procName enter \ + [list ::logger::_trace_enter $service] + ::trace add execution $procName leave \ + [list ::logger::_trace_leave $service] + } + } +} + +# This procedure disables Tcl trace handlers for all procedures specified. +# It is used both to disable Tcl's tracing for a single procedure when +# removed via "logger::trace remove", as well as to disable all traces +# via "logger::trace off". + +proc ::logger::_disable_traces { service procList } { + upvar #0 ::logger::tree::${service}::tracingEnabled tracingEnabled + + if {$tracingEnabled} { + foreach procName $procList { + ::trace remove execution $procName enter \ + [list ::logger::_trace_enter $service] + ::trace remove execution $procName leave \ + [list ::logger::_trace_leave $service] + } + } +} + +######################################################################## +# Trace Handlers +######################################################################## + +# This procedure is invoked upon entry into a procedure being traced +# via "logger::trace add" when tracing is enabled via "logger::trace on" +# to log information about how the procedure was called. + +proc ::logger::_trace_enter { service cmd op } { + # Parse the command + set procName [uplevel 1 namespace origin [lindex $cmd 0]] + set args [lrange $cmd 1 end] + + # Display the message prefix + set callerLvl [expr {[::info level] - 1}] + set calledLvl [::info level] + + lappend message "proc" $procName + lappend message "level" $calledLvl + lappend message "script" [uplevel ::info script] + + # Display the caller information + set caller "" + if {$callerLvl >= 1} { + # Display the name of the caller proc w/prepended namespace + catch { + set callerProcName [lindex [::info level $callerLvl] 0] + set caller [uplevel 2 namespace origin $callerProcName] + } + } + + lappend message "caller" $caller + + # Display the argument names and values + set argSpec [uplevel 1 ::info args $procName] + set argList "" + if {[llength $argSpec]} { + foreach argName $argSpec { + lappend argList $argName + + if {$argName == "args"} { + lappend argList $args + break + } else { + lappend argList [lindex $args 0] + set args [lrange $args 1 end] + } + } + } + + lappend message "procargs" $argList + set message [list $op $message] + + ::logger::tree::${service}::tracecmd $message +} + +# This procedure is invoked upon leaving into a procedure being traced +# via "logger::trace add" when tracing is enabled via "logger::trace on" +# to log information about the result of the procedure call. + +proc ::logger::_trace_leave { service cmd status rc op } { + variable RETURN_CODES + + # Parse the command + set procName [uplevel 1 namespace origin [lindex $cmd 0]] + + # Gather the caller information + set callerLvl [expr {[::info level] - 1}] + set calledLvl [::info level] + + lappend message "proc" $procName "level" $calledLvl + lappend message "script" [uplevel ::info script] + + # Get the name of the proc being returned to w/prepended namespace + set caller "" + catch { + set callerProcName [lindex [::info level $callerLvl] 0] + set caller [uplevel 2 namespace origin $callerProcName] + } + + lappend message "caller" $caller + + # Convert the return code from numeric to verbal + + if {$status < [llength $RETURN_CODES]} { + set status [lindex $RETURN_CODES $status] + } + + lappend message "status" $status + lappend message "result" $rc + + # Display the leave message + + set message [list $op $message] + ::logger::tree::${service}::tracecmd $message + + return 1 +} + diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.6.5.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.6.5.tm index f7e4c1a..38ce71c 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.6.5.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.6.5.tm @@ -165,16 +165,17 @@ tcl::namespace::eval overtype::priv { #could return larger than renderwidth proc _get_row_append_column {row} { + #obsolete? upvar outputlines outputlines set idx [expr {$row -1}] if {$row <= 1 || $row > [llength $outputlines]} { return 1 } else { - upvar opt_overflow opt_overflow + upvar opt_expand_right expand_right upvar renderwidth renderwidth set existinglen [punk::ansi::printing_length [lindex $outputlines $idx]] set endpos [expr {$existinglen +1}] - if {$opt_overflow} { + if {$expand_right} { return $endpos } else { if {$endpos > $renderwidth} { @@ -204,14 +205,14 @@ tcl::namespace::eval overtype { proc renderspace {args} { #*** !doctools #[call [fun overtype::renderspace] [arg args] ] - #[para] usage: ?-transparent [lb]0|1[rb]? ?-overflow [lb]1|0[rb]? ?-ellipsis [lb]1|0[rb]? ?-ellipsistext ...? undertext overtext + #[para] usage: ?-transparent [lb]0|1[rb]? ?-expand_right [lb]1|0[rb]? ?-ellipsis [lb]1|0[rb]? ?-ellipsistext ...? undertext overtext # @c overtype starting at left (overstrike) # @c can/should we use something like this?: 'format "%-*s" $len $overtext variable default_ellipsis_horizontal if {[llength $args] < 2} { - error {usage: ?-width ? ?-startcolumn ? ?-transparent [0|1|]? ?-overflow [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext} + error {usage: ?-width ? ?-startcolumn ? ?-transparent [0|1|]? ?-expand_right [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext} } set optargs [lrange $args 0 end-2] if {[llength $optargs] % 2 == 0} { @@ -228,30 +229,46 @@ tcl::namespace::eval overtype { } } set opts [tcl::dict::create\ - -bias ignored\ - -width \uFFEF\ - -height \uFFEF\ + -bias ignored\ + -width \uFFEF\ + -height \uFFEF\ -startcolumn 1\ - -wrap 0\ - -ellipsis 0\ + -wrap 0\ + -ellipsis 0\ -ellipsistext $default_ellipsis_horizontal\ -ellipsiswhitespace 0\ - -overflow 0\ - -appendlines 1\ - -transparent 0\ - -exposed1 \uFFFD\ - -exposed2 \uFFFD\ - -experimental 0\ - -looplimit \uFFEF\ - -crm_mode 0\ - -reverse_mode 0\ + -expand_right 0\ + -appendlines 1\ + -transparent 0\ + -exposed1 \uFFFD\ + -exposed2 \uFFFD\ + -experimental 0\ + -cp437 1\ + -looplimit \uFFEF\ + -crm_mode 0\ + -reverse_mode 0\ + -insert_mode 0\ + -console {stdin stdout stderr}\ ] + #expand_right is perhaps consistent with the idea of the page_size being allowed to grow horizontally.. + # it does not necessarily mean the viewport grows. (which further implies need for horizontal scrolling) + # - it does need to be within some concept of terminal width - as columns must be addressable by ansi sequences. + # - This implies the -width option value must grow if it is tied to the concept of renderspace terminal width! REVIEW. + # - further implication is that if expand_right grows the virtual renderspace terminal width - + # then some sort of reflow/rerender needs to be done for preceeding lines? + # possibly not - as expand_right is distinct from a normal terminal-width change event, + # expand_right being primarily to support other operations such as textblock::table + + #todo - viewport width/height as separate concept to terminal width/height? #-ellipsis args not used if -wrap is true foreach {k v} $argsflags { switch -- $k { - -looplimit - -width - -height - -startcolumn - -bias - -wrap - -ellipsis - -ellipsistext - -ellipsiswhitespace - -overflow - -appendlines + -looplimit - -width - -height - -startcolumn - -bias - -wrap - -ellipsis - -ellipsistext - -ellipsiswhitespace - -transparent - -exposed1 - -exposed2 - -experimental - - -reverse_mode - -crm_mode { + - -expand_right - -appendlines + - -reverse_mode - -crm_mode - -insert_mode + - -cp437 + - -console { tcl::dict::set opts $k $v } default { @@ -261,7 +278,8 @@ tcl::namespace::eval overtype { } #set opts [tcl::dict::merge $defaults $argsflags] # -- --- --- --- --- --- - set opt_overflow [tcl::dict::get $opts -overflow] + #review - expand_left for RTL text? + set opt_expand_right [tcl::dict::get $opts -expand_right] ##### # review -wrap should map onto DECAWM terminal mode - the wrap 2 idea may not fit in with this?. set opt_wrap [tcl::dict::get $opts -wrap] ;#wrap 1 is hard wrap cutting word at exact column, or 1 column early for 2w-glyph, wrap 2 is for language-based word-wrap algorithm (todo) @@ -279,23 +297,31 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- set opt_crm_mode [tcl::dict::get $opts -crm_mode] set opt_reverse_mode [tcl::dict::get $opts -reverse_mode] + set opt_insert_mode [tcl::dict::get $opts -insert_mode] + # -- --- --- --- --- --- + set opt_cp437 [tcl::dict::get $opts -cp437] + + + #initial state for renderspace 'terminal' reset + set initial_state [dict create\ + -width $opt_width\ + -height $opt_height\ + -crm_mode $opt_crm_mode\ + -reverse_mode $opt_reverse_mode\ + -insert_mode $opt_insert_mode\ + -cp437 $opt_cp437\ + ] # ---------------------------- # -experimental dev flag to set flags etc # ---------------------------- set data_mode 0 - set test_mode 1 set info_mode 0 set edit_mode 0 set opt_experimental [tcl::dict::get $opts -experimental] foreach o $opt_experimental { switch -- $o { - test_mode { - set test_mode 1 - set info_mode 1 - } old_mode { - set test_mode 0 set info_mode 1 } data_mode { @@ -309,11 +335,10 @@ tcl::namespace::eval overtype { } } } - set test_mode 1 ;#try to eliminate # ---------------------------- #modes - set insert_mode 0 ;#can be toggled by insert key or ansi IRM sequence ESC [ 4 h|l + set insert_mode $opt_insert_mode ;#can be toggled by insert key or ansi IRM sequence ESC [ 4 h|l set autowrap_mode $opt_wrap set reverse_mode $opt_reverse_mode set crm_mode $opt_crm_mode @@ -377,49 +402,45 @@ tcl::namespace::eval overtype { set looplimit [expr {[tcl::string::length $overblock] + 10}] } - if {!$test_mode} { - set inputchunks [split $overblock \n] - } else { - set scheme 3 - switch -- $scheme { - 0 { - #one big chunk - set inputchunks [list $overblock] + set scheme 3 + switch -- $scheme { + 0 { + #one big chunk + set inputchunks [list $overblock] + } + 1 { + set inputchunks [punk::ansi::ta::split_codes $overblock] + } + 2 { + + #split into lines if possible first - then into plaintext/ansi-sequence chunks ? + set inputchunks [list ""] ;#put an empty plaintext split in for starters + set i 1 + set lines [split $overblock \n] + foreach ln $lines { + if {$i < [llength $lines]} { + append ln \n + } + set sequence_split [punk::ansi::ta::split_codes_single $ln] ;#use split_codes Not split_codes_single? + set lastpt [lindex $inputchunks end] + lset inputchunks end [tcl::string::cat $lastpt [lindex $sequence_split 0]] + lappend inputchunks {*}[lrange $sequence_split 1 end] + incr i } - 1 { - set inputchunks [punk::ansi::ta::split_codes $overblock] + } + 3 { + #it turns out line based chunks are faster than the above.. probably because some of those end up doing the regex splitting twice + set lflines [list] + set inputchunks [split $overblock \n] + foreach ln $inputchunks { + append ln \n + lappend lflines $ln } - 2 { - - #split into lines if possible first - then into plaintext/ansi-sequence chunks ? - set inputchunks [list ""] ;#put an empty plaintext split in for starters - set i 1 - set lines [split $overblock \n] - foreach ln $lines { - if {$i < [llength $lines]} { - append ln \n - } - set sequence_split [punk::ansi::ta::split_codes_single $ln] ;#use split_codes Not split_codes_single? - set lastpt [lindex $inputchunks end] - lset inputchunks end [tcl::string::cat $lastpt [lindex $sequence_split 0]] - lappend inputchunks {*}[lrange $sequence_split 1 end] - incr i - } + if {[llength $lflines]} { + lset lflines end [tcl::string::range [lindex $lflines end] 0 end-1] } - 3 { - #it turns out line based chunks are faster than the above.. probably because some of those end up doing the regex splitting twice - set lflines [list] - set inputchunks [split $overblock \n] - foreach ln $inputchunks { - append ln \n - lappend lflines $ln - } - if {[llength $lflines]} { - lset lflines end [tcl::string::range [lindex $lflines end] 0 end-1] - } - set inputchunks $lflines[unset lflines] + set inputchunks $lflines[unset lflines] - } } } @@ -441,11 +462,11 @@ tcl::namespace::eval overtype { #underlines are not necessarily processed in order - depending on cursor-moves applied from overtext set row 1 - if {$data_mode} { - set col [_get_row_append_column $row] - } else { + #if {$data_mode} { + # set col [_get_row_append_column $row] + #} else { set col $opt_startcolumn - } + #} set instruction_stats [tcl::dict::create] @@ -473,33 +494,27 @@ tcl::namespace::eval overtype { } #review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary - #but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l - set LASTCALL [list -info 1\ - -insert_mode $insert_mode\ - -crm_mode $crm_mode\ - -autowrap_mode $autowrap_mode\ - -reverse_mode $reverse_mode\ - -transparent $opt_transparent\ - -width $renderwidth\ - -exposed1 $opt_exposed1\ - -exposed2 $opt_exposed2\ - -overflow $opt_overflow -cursor_column $col -cursor_row $row $undertext $overtext] - set rinfo [renderline -experimental $opt_experimental\ + set renderargs [list -experimental $opt_experimental\ + -cp437 $opt_cp437\ -info 1\ -crm_mode $crm_mode\ -insert_mode $insert_mode\ -autowrap_mode $autowrap_mode\ - -reverse_mode $reverse_mode\ + -reverse_mode $reverse_mode\ -cursor_restore_attributes $cursor_saved_attributes\ -transparent $opt_transparent\ -width $renderwidth\ -exposed1 $opt_exposed1\ -exposed2 $opt_exposed2\ - -overflow $opt_overflow\ + -expand_right $opt_expand_right\ -cursor_column $col\ -cursor_row $row\ $undertext\ $overtext\ - ] + ] + set LASTCALL $renderargs + set rinfo [renderline {*}$renderargs] + set instruction [tcl::dict::get $rinfo instruction] set insert_mode [tcl::dict::get $rinfo insert_mode] set autowrap_mode [tcl::dict::get $rinfo autowrap_mode] ;# @@ -523,6 +538,7 @@ tcl::namespace::eval overtype { #lset replay_codes_overlay [expr $overidx+1] [tcl::dict::get $rinfo replay_codes_overlay] set replay_codes_overlay [tcl::dict::get $rinfo replay_codes_overlay] if {0 && $reverse_mode} { + #test branch - todo - prune puts stderr "---->[ansistring VIEW $replay_codes_overlay] rendered: $rendered" #review #JMN3 @@ -579,29 +595,17 @@ tcl::namespace::eval overtype { #keeping separate branches for debugging - review and merge as appropriate when stable tcl::dict::incr instruction_stats $instruction switch -- $instruction { - {} { - if {$test_mode == 0} { - incr row - if {$data_mode} { - set col [_get_row_append_column $row] - if {$col > $renderwidth} { + reset { + #reset the 'renderspace terminal' (not underlying terminal) + set row 1 + set col 1 - } - } else { - set col 1 - } - } else { - #lf included in data - set row $post_render_row - set col $post_render_col - #set col 1 - #if {$post_render_row != $renderedrow} { - # set col 1 - #} else { - # set col $post_render_col - #} - } + } + {} { + #lf included in data + set row $post_render_row + set col $post_render_col } up { @@ -704,7 +708,14 @@ tcl::namespace::eval overtype { puts stdout ">>>[a+ red bold]overflow_right during restore_cursor[a]" - set sub_info [overtype::renderline -info 1 -width $renderwidth -insert_mode $insert_mode -autowrap_mode $autowrap_mode -overflow [tcl::dict::get $opts -overflow] "" $overflow_right] + set sub_info [overtype::renderline -info 1\ + -width $renderwidth\ + -insert_mode $insert_mode\ + -autowrap_mode $autowrap_mode\ + -expand_right [tcl::dict::get $opts -opt_expand_right]\ + ""\ + $overflow_right\ + ] set foldline [tcl::dict::get $sub_info result] set insert_mode [tcl::dict::get $sub_info insert_mode] ;#probably not needed..? set autowrap_mode [tcl::dict::get $sub_info autowrap_mode] ;#nor this.. @@ -735,7 +746,7 @@ tcl::namespace::eval overtype { #overflow + unapplied? } lf_start { - #raw newlines - must be test_mode + #raw newlines # ---------------------- #test with fruit.ans #test - treating as newline below... @@ -751,48 +762,58 @@ tcl::namespace::eval overtype { } lf_mid { - if 0 { - #set rhswidth [punk::ansi::printing_length $overflow_right] - #only show debug when we have overflow? - set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -nul 1 -lf 1 -vt 1 $rendered]] - set lhs [textblock::frame -title "rendered $visualwidth cols" -subtitle "row-$renderedrow" $lhs] - - set rhs "" - if {$overflow_right ne ""} { - set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -nul 1 -lf 1 -vt 1 $overflow_right]] - set rhs [textblock::frame -title overflow_right $rhs] - } - puts [textblock::join $lhs " $post_render_col " $rhs] - } - - if {!$test_mode} { - #rendered - append rendered $overflow_right - #set replay_codes_overlay "" + set edit_mode 0 + if {$edit_mode} { + set inputchunks [linsert $inputchunks 0 $overflow_right$unapplied] set overflow_right "" - - - set row $renderedrow - + set unapplied "" + set row $post_render_row + #set col $post_render_col set col $opt_startcolumn - incr row - #only add newline if we're at the bottom if {$row > [llength $outputlines]} { lappend outputlines {*}[lrepeat 1 ""] } } else { - set edit_mode 0 - if {$edit_mode} { - set inputchunks [linsert $inputchunks 0 $overflow_right$unapplied] - set overflow_right "" - set unapplied "" + if 1 { + if {$overflow_right ne ""} { + if {$opt_expand_right} { + append rendered $overflow_right + set overflow_right "" + } else { + set overflow_width [punk::ansi::printing_length $overflow_right] + if {$visualwidth + $overflow_width <= $renderwidth} { + append rendered $overflow_right + set overflow_right "" + } else { + if {$visualwidth < $renderwidth} { + set graphemes [punk::char::grapheme_split $overflow_width] + set add "" + set addlen $visualwidth + set remaining_overflow $graphemes + foreach g $graphemes { + set w [overtype::grapheme_width_cached] + if {$addlen + $w <= $renderwidth} { + append add $g + incr addlen $w + lpop remaining_overflow + } else { + break + } + } + append rendered $add + set overflow_right [join $remaining_overflow ""] + } + } + } + } set row $post_render_row - #set col $post_render_col set col $opt_startcolumn if {$row > [llength $outputlines]} { lappend outputlines {*}[lrepeat 1 ""] } } else { + #old version - known to work with various ansi graphics - e.g fruit.ans + # - but fails to limit lines to renderwidth when expand_right == 0 append rendered $overflow_right set overflow_right "" set row $post_render_row @@ -851,38 +872,28 @@ tcl::namespace::eval overtype { set row $post_render_row set col $post_render_col if {$insert_lines_below == 1} { - if {$test_mode == 0} { - set row $renderedrow - set outputlines [linsert $outputlines [expr {$renderedrow }] {*}[lrepeat $insert_lines_below ""]] ;#note - linsert can add to end too - incr row $insert_lines_below - set col $opt_startcolumn - } else { - #set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $rendered]] - #set lhs [textblock::frame -title rendered -subtitle "row-$renderedrow" $lhs] - #set rhs "" - #if {$overflow_right ne ""} { - # set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $overflow_right]] - # set rhs [textblock::frame -title overflow_right $rhs] - #} - #puts [textblock::join $lhs $rhs] - - #rendered - append rendered $overflow_right - # - - - set overflow_right "" - set row $renderedrow - #only add newline if we're at the bottom - if {$row > [llength $outputlines]} { - lappend outputlines {*}[lrepeat $insert_lines_below ""] - } - incr row $insert_lines_below - set col $opt_startcolumn + #set lhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $rendered]] + #set lhs [textblock::frame -title rendered -subtitle "row-$renderedrow" $lhs] + #set rhs "" + #if {$overflow_right ne ""} { + # set rhs [overtype::left -width 40 -wrap 1 "" [ansistring VIEWSTYLE -lf 1 -vt 1 $overflow_right]] + # set rhs [textblock::frame -title overflow_right $rhs] + #} + #puts [textblock::join $lhs $rhs] + #rendered + append rendered $overflow_right + # + set overflow_right "" + set row $renderedrow + #only add newline if we're at the bottom + if {$row > [llength $outputlines]} { + lappend outputlines {*}[lrepeat $insert_lines_below ""] } + incr row $insert_lines_below + set col $opt_startcolumn } } else { set row $post_render_row @@ -974,7 +985,6 @@ tcl::namespace::eval overtype { incr row set col $opt_startcolumn ;#whether wrap or not - next data is at column 1 ?? } else { - #this works for test_mode (which should become the default) - but could give a bad result otherwise - review - add tests fix. set col $post_render_col #set unapplied "" ;#this seems wrong? #set unapplied [tcl::string::range $unapplied 1 end] @@ -1052,7 +1062,7 @@ tcl::namespace::eval overtype { } - if {!$opt_overflow && !$autowrap_mode} { + if {!$opt_expand_right && !$autowrap_mode} { #not allowed to overflow column or wrap therefore we get overflow data to truncate if {[tcl::dict::get $opts -ellipsis]} { set show_ellipsis 1 @@ -1130,7 +1140,6 @@ tcl::namespace::eval overtype { set debugmsg "" append debugmsg "${Y}${sep_header}${RST}" \n append debugmsg "looplimit $looplimit reached\n" - append debugmsg "test_mode:$test_mode\n" append debugmsg "data_mode:$data_mode\n" append debugmsg "opt_appendlines:$opt_appendlines\n" append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n" @@ -1433,7 +1442,7 @@ tcl::namespace::eval overtype { #padded overtext #lappend outputlines [renderline -insert_mode 0 -transparent $opt_transparent -startcolumn [expr {$left_exposed + 1}] $undertext $overtext] #Note - we still need overflow here - as although the overtext is short - it may oveflow due to the startoffset - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -overflow $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -expand_right $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] lappend outputlines [tcl::dict::get $rinfo result] } set replay_codes [tcl::dict::get $rinfo replay_codes] @@ -1584,7 +1593,7 @@ tcl::namespace::eval overtype { set overflowlength [expr {$overtext_datalen - $renderwidth}] if {$overflowlength > 0} { #raw overtext wider than undertext column - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -exposed1 $opt_exposed1 -exposed2 $opt_exposed2 -overflow $opt_overflow -startcolumn [expr {1 + $startoffset}] $undertext $overtext] + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -exposed1 $opt_exposed1 -exposed2 $opt_exposed2 -expand_right $opt_overflow -startcolumn [expr {1 + $startoffset}] $undertext $overtext] set replay_codes [tcl::dict::get $rinfo replay_codes] set rendered [tcl::dict::get $rinfo result] set overflow_right [tcl::dict::get $rinfo overflow_right] @@ -1632,8 +1641,8 @@ tcl::namespace::eval overtype { } else { #padded overtext #lappend outputlines [renderline -insert_mode 0 -transparent $opt_transparent -startcolumn [expr {$left_exposed + 1}] $undertext $overtext] - #Note - we still need overflow here - as although the overtext is short - it may oveflow due to the startoffset - set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -overflow $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] + #Note - we still need expand_right here - as although the overtext is short - it may oveflow due to the startoffset + set rinfo [renderline -info 1 -insert_mode 0 -transparent $opt_transparent -expand_right $opt_overflow -startcolumn [expr {$left_exposed + 1 + $startoffset}] $undertext $overtext] #puts stderr "--> [ansistring VIEW -lf 1 -nul 1 $rinfo] <--" set overflow_right [tcl::dict::get $rinfo overflow_right] set unapplied [tcl::dict::get $rinfo unapplied] @@ -1655,7 +1664,8 @@ tcl::namespace::eval overtype { #-returnextra enables returning of overflow and length #review - use punk::ansi::ta::detect to short-circuit processing and do simpler string calcs as an optimisation? #review - DECSWL/DECDWL double width line codes - very difficult/impossible to align and compose with other elements - #(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char) + #(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char? + # This would probably be impractical to support for different fonts) #todo - review transparency issues with single/double width characters #bidi - need a base direction and concept of directional runs for RTL vs LTR - may be best handled at another layer? proc renderline {args} { @@ -1677,8 +1687,10 @@ tcl::namespace::eval overtype { #[para] The main 3 are the result, overflow_right, and unapplied. #[para] Renderline handles cursor movements from either keystrokes or ANSI sequences but for a full system the aforementioned loop will need to be in place to manage the set of lines under manipulation. + #puts stderr "renderline '$args'" + if {[llength $args] < 2} { - error {usage: ?-info 0|1? ?-startcolumn ? ?-cursor_column ? ?-cursor_row |""? ?-transparent [0|1|]? ?-overflow [1|0]? undertext overtext} + error {usage: ?-info 0|1? ?-startcolumn ? ?-cursor_column ? ?-cursor_row |""? ?-transparent [0|1|]? ?-expand_right [1|0]? undertext overtext} } lassign [lrange $args end-1 end] under over if {[string first \n $under] >= 0} { @@ -1692,7 +1704,7 @@ tcl::namespace::eval overtype { set opts [tcl::dict::create\ -etabs 0\ -width \uFFEF\ - -overflow 0\ + -expand_right 0\ -transparent 0\ -startcolumn 1\ -cursor_column 1\ @@ -1713,13 +1725,13 @@ tcl::namespace::eval overtype { #cursor_row, when numeric will allow detection of certain row moves that are still within our row - allowing us to avoid an early return #An empty string for cursor_row tells us we have no info about our own row context, and to return with an unapplied string if any row move occurs - #exposed1 and exposed2 for first and second col of underying 2wide char which is truncated by transparency or overflow + #exposed1 and exposed2 for first and second col of underying 2wide char which is truncated by transparency, currsor movements to 2nd charcol, or overflow/expand_right #todo - return info about such grapheme 'cuts' in -info structure and/or create option to raise an error set argsflags [lrange $args 0 end-2] tcl::dict::for {k v} $argsflags { switch -- $k { - -experimental - -cp437 - -width - -overflow - -transparent - -startcolumn - -cursor_column - -cursor_row + -experimental - -cp437 - -width - -expand_right - -transparent - -startcolumn - -cursor_column - -cursor_row - -crm_mode - -insert_mode - -autowrap_mode - -reverse_mode - -info - -exposed1 - -exposed2 - -cursor_restore_attributes { tcl::dict::set opts $k $v @@ -1732,7 +1744,7 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- --- --- --- --- --- --- set opt_width [tcl::dict::get $opts -width] set opt_etabs [tcl::dict::get $opts -etabs] - set opt_overflow [tcl::dict::get $opts -overflow] + set opt_expand_right [tcl::dict::get $opts -expand_right] set opt_colstart [tcl::dict::get $opts -startcolumn] ;#lhs limit for overlay - an offset to cursor_column - first visible column is 1. 0 or < 0 are before the start of the underlay set opt_colcursor [tcl::dict::get $opts -cursor_column];#start cursor column relative to overlay set opt_row_context [tcl::dict::get $opts -cursor_row] @@ -1752,17 +1764,7 @@ tcl::namespace::eval overtype { # -- --- --- --- --- --- --- --- --- --- --- --- set temp_cursor_saved [tcl::dict::get $opts -cursor_restore_attributes] - set test_mode 0 set cp437_glyphs [tcl::dict::get $opts -cp437] - foreach e [tcl::dict::get $opts -experimental] { - switch -- $e { - test_mode { - set test_mode 1 - set cp437_glyphs 1 - } - } - } - set test_mode 1 ;#try to elminate set cp437_map [tcl::dict::create] if {$cp437_glyphs} { set cp437_map [set ::punk::ansi::cp437_map] @@ -1852,7 +1854,7 @@ tcl::namespace::eval overtype { set u_codestack [list] #u_gx_stack probably isn't really a stack - I don't know if g0 g1 can stack or not - for now we support only g0 anyway set u_gx_stack [list] ;#separate stack for g0 (g1 g2 g3?) graphics on and off (DEC special graphics) - #set pt_underchars "" ;#for string_columns length calculation for overflow 0 truncation + #set pt_underchars "" ;#for string_columns length calculation for expand_right 0 truncation set remainder [list] ;#for returnextra foreach {pt code} $undermap { #pt = plain text @@ -1996,47 +1998,25 @@ tcl::namespace::eval overtype { #consider also if there are other codes that should be stacked..? } - if {!$test_mode} { - #fill columns to width with spaces, and carry over stacks - we will have to keep track of where the underlying data ends manually - TODO - #Specifying a width is suitable for terminal-like applications and text-blocks - if {$opt_width ne "\uFFEF"} { - if {[llength $understacks]} { - set cs $u_codestack - set gs $u_gx_stack - } else { - set cs [list] - set gs [list] - } - if {[llength $undercols]< $opt_width} { - set diff [expr {$opt_width- [llength $undercols]}] - if {$diff > 0} { - lappend undercols {*}[lrepeat $diff " "] - lappend understacks {*}[lrepeat $diff $cs] - lappend understacks_gx {*}[lrepeat $diff $gs] - } - } + #NULL empty cell indicator + if {$opt_width ne "\uFFEF"} { + if {[llength $understacks]} { + set cs $u_codestack + set gs $u_gx_stack + } else { + set cs [list] + set gs [list] } - } else { - #NULL empty cell indicator - if {$opt_width ne "\uFFEF"} { - if {[llength $understacks]} { - set cs $u_codestack - set gs $u_gx_stack - } else { - set cs [list] - set gs [list] - } - if {[llength $undercols]< $opt_width} { - set diff [expr {$opt_width- [llength $undercols]}] - if {$diff > 0} { - lappend undercols {*}[lrepeat $diff "\u0000"] - lappend understacks {*}[lrepeat $diff $cs] - lappend understacks_gx {*}[lrepeat $diff $gs] - } + if {[llength $undercols]< $opt_width} { + set diff [expr {$opt_width- [llength $undercols]}] + if {$diff > 0} { + lappend undercols {*}[lrepeat $diff "\u0000"] + lappend understacks {*}[lrepeat $diff $cs] + lappend understacks_gx {*}[lrepeat $diff $gs] } } - } + if {$opt_width ne "\uFFEF"} { set renderwidth $opt_width } else { @@ -2127,8 +2107,10 @@ tcl::namespace::eval overtype { lappend overlay_grapheme_control_stacks $o_codestack } } else { + set tsbegin [clock micros] foreach grapheme_original [punk::char::grapheme_split $pt] { set pt_crm [ansistring VIEW -nul 1 -lf 2 -vt 2 -ff 2 $grapheme_original] + #puts stderr "ptlen [string length $pt] graphemelen[string length $grapheme_original] pt_crmlen[string length $pt_crm] $pt_crm" foreach grapheme [punk::char::grapheme_split $pt_crm] { if {$grapheme eq "\n"} { lappend overlay_grapheme_control_stacks $o_codestack @@ -2142,6 +2124,8 @@ tcl::namespace::eval overtype { } } } + set elapsed [expr {[clock micros] - $tsbegin}] + puts stderr "ptlen [string length $pt] elapsedus:$elapsed" } #only stack SGR (graphics rendition) codes - not title sets, cursor moves etc @@ -2259,11 +2243,12 @@ tcl::namespace::eval overtype { # -- --- --- #we need to initialise overflow_idx before any potential row-movements - as they need to perform a loop break and force in_excess to 1 - if {$opt_overflow} { - #somewhat counterintuitively - overflow true means we can have lines as long as we want, but either way there can be excess data that needs to be thrown back to the calling loop. + if {$opt_expand_right} { + #expand_right true means we can have lines as long as we want, but either way there can be excess data that needs to be thrown back to the calling loop. + #we currently only support horizontal expansion to the right (review regarding RTL text!) set overflow_idx -1 } else { - #overflow zero - we can't grow beyond our column width - so we get ellipsis or truncation + #expand_right zero - we can't grow beyond our column width - so we get ellipsis or truncation if {$opt_width ne "\uFFEF"} { set overflow_idx [expr {$opt_width}] } else { @@ -2304,7 +2289,7 @@ tcl::namespace::eval overtype { #movements only occur within the overlay range. #an underlay is however not necessary.. e.g - #renderline -overflow 1 "" data + #renderline -expand_right 1 "" data #set re_mode {\x1b\[\?([0-9]*)(h|l)} ;#e.g DECAWM #set re_col_move {\x1b\[([0-9]*)(C|D|G)$} @@ -2331,7 +2316,7 @@ tcl::namespace::eval overtype { g { set ch $item #crm_mode affects both graphic and control - if {$crm_mode} { + if {0 && $crm_mode} { set chars [ansistring VIEW -nul 1 -lf 2 -vt 2 -ff 2 $ch] set chars [string map [list \n "\x1b\[00001E"] $chars] if {[llength [split $chars ""]] > 1} { @@ -2376,7 +2361,7 @@ tcl::namespace::eval overtype { #linefeed after final column #puts "---c at overflow_idx=$overflow_idx" incr cursor_row - set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to opt_overflow = 1|2 + set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to expand_right = 1 set instruction lf_overflow ;#only special treatment is to give it it's own instruction in case caller needs to handle differently priv::render_unapplied $overlay_grapheme_control_list $gci break @@ -2384,7 +2369,10 @@ tcl::namespace::eval overtype { #linefeed occurred in middle or at end of text #puts "---mid-or-end-text-linefeed idx:$idx overflow_idx:$overflow_idx" incr cursor_row - set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to opt_overflow = 1|2 + if {$idx == -1 || $overflow_idx > $idx} { + #don't set overflow_idx higher if it's already set lower and we're adding graphemes to overflow + set overflow_idx $idx ;#override overflow_idx even if it was set to -1 due to expand_right = 1 + } set instruction lf_mid priv::render_unapplied $overlay_grapheme_control_list $gci break @@ -2466,23 +2454,35 @@ tcl::namespace::eval overtype { #tab of some length dependent on tabstops/elastic tabstop settings? } } elseif {$idx >= $overflow_idx} { - #jmn? - set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci-1]] - #set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] - #don't incr idx beyond the overflow_idx - #idx_over already incremented - decrement so current overlay grapheme stacks go to unapplied - incr idx_over -1 - #priv::render_unapplied $overlay_grapheme_control_list [expr {$gci-1}] ;#back one index here too - priv::render_this_unapplied $overlay_grapheme_control_list $gci ;# - set instruction overflow - break + #REVIEW + set next_gc [lindex $overlay_grapheme_control_list $gci+1] ;#next grapheme or control + lassign $next_gc next_type next_item + if {$autowrap_mode || $next_type ne "g"} { + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci-1]] + #set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + #don't incr idx beyond the overflow_idx + #idx_over already incremented - decrement so current overlay grapheme stacks go to unapplied + incr idx_over -1 + #priv::render_unapplied $overlay_grapheme_control_list [expr {$gci-1}] ;#back one index here too + priv::render_this_unapplied $overlay_grapheme_control_list $gci ;# + set instruction overflow + break + } else { + #no point throwing back to caller for each grapheme that is overflowing + #without this branch - renderline would be called with overtext reducing only by one grapheme per call + #processing a potentially long overtext each time (ie - very slow) + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + #JMN4 + + } } } else { #review. - #This corresponds to opt_overflow being true (at least until overflow_idx is in some cases forced to a value when throwing back to calling loop) + #overflow_idx = -1 + #This corresponds to expand_right being true (at least until overflow_idx is in some cases forced to a value when throwing back to calling loop) } - if {($do_transparency && [regexp $opt_transparent $ch])} { + if {($do_transparency && [regexp $opt_transparent $ch])} { #pre opt_colstart is effectively transparent (we have applied padding of required number of columns to left of overlay) if {$idx > [llength $outcols]-1} { lappend outcols " " @@ -2621,7 +2621,7 @@ tcl::namespace::eval overtype { } incr idx } - if {($cursor_column < [llength $outcols]) || $overflow_idx == -1 || $test_mode} { + if {($cursor_column < [llength $outcols]) || $overflow_idx == -1} { incr cursor_column } } elseif {$uwidth > 1} { @@ -2655,12 +2655,6 @@ tcl::namespace::eval overtype { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx incr cursor_column - if {$overflow_idx !=-1 && !$test_mode} { - #overflow - if {$cursor_column > [llength $outcols]} { - set cursor_column [llength $outcols] - } - } } } } @@ -2704,6 +2698,7 @@ tcl::namespace::eval overtype { set leadernorm [tcl::string::range [tcl::string::map [list\ \x1b\[< 1006\ \x1b\[ 7CSI\ + \x1bP 7DCS\ \x9b 8CSI\ \x1b\] 7OSC\ \x9d 8OSC\ @@ -2720,6 +2715,11 @@ tcl::namespace::eval overtype { 7CSI - 7OSC { set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 2 end]] } + 7DCS { + #ESC P + #Device Control String https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Controls-beginning-with-ESC:ESC-F.C74 + set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 2 end]] + } 7ESC { set codenorm [tcl::string::cat $leadernorm [tcl::string::range $code 1 end]] } @@ -2812,7 +2812,7 @@ tcl::namespace::eval overtype { if {$overflow_idx == -1} { incr max } - if {$test_mode && $cursor_column == $max+1} { + if {$cursor_column == $max+1} { #move_forward while in overflow incr cursor_column -1 } @@ -2829,7 +2829,7 @@ tcl::namespace::eval overtype { } #horizontal movement beyond line extent needs to wrap - throw back to caller - #we may have both overflow_rightand unapplied data + #we may have both overflow_right and unapplied data #(can have overflow_right if we were in insert_mode and processed chars prior to this movement) #leave row as is - caller will need to determine how many rows the column-movement has consumed incr cursor_column $num ;#give our caller the necessary info as columns from start of row @@ -2844,7 +2844,8 @@ tcl::namespace::eval overtype { } } } else { - if {!$opt_overflow || ($cursor_column + $num) <= [llength $outcols+1]} { + #review - dead branch + if {!$expand_right || ($cursor_column + $num) <= [llength $outcols+1]} { incr idx $num incr cursor_column $num } else { @@ -3052,55 +3053,99 @@ tcl::namespace::eval overtype { } } J { - puts stderr "overtype::renderline ED - ERASE IN DISPLAY (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - if {$param eq ""} {set param 0} - switch -exact -- $param { - 0 { - #clear from cursor to end of screen - } - 1 { - #clear from cursor to beginning of screen - } - 2 { - #clear entire screen - #ansi.sys - move cursor to upper left REVIEW - set cursor_row 1 - set cursor_column 1 - set idx [expr {$cursor_column -1}] - set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] - incr idx_over - priv::render_unapplied $overlay_grapheme_control_list $gci - set instruction move - break - } - 3 { - #clear entire screen. presumably cursor doesn't move - otherwise it would be same as 2J ? - + set modegroup [tcl::string::index $codenorm 4] ;#e.g ? + switch -exact -- $modegroup { + ? { + #CSI ? Pn J - selective erase + puts stderr "overtype::renderline ED - SELECTIVE ERASE IN DISPLAY (UNIMPLEMENTED) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" } default { + puts stderr "overtype::renderline ED - ERASE IN DISPLAY (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of screen + } + 1 { + #clear from cursor to beginning of screen + } + 2 { + #clear entire screen + #ansi.sys - move cursor to upper left REVIEW + set cursor_row 1 + set cursor_column 1 + set idx [expr {$cursor_column -1}] + set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] + incr idx_over + priv::render_unapplied $overlay_grapheme_control_list $gci + set instruction move + break + } + 3 { + #clear entire screen. presumably cursor doesn't move - otherwise it would be same as 2J ? + + } + default { + } + } + } } - } K { - puts stderr "overtype::renderline EL - ERASE IN LINE (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - if {$param eq ""} {set param 0} - switch -exact -- $param { - 0 { - #clear from cursor to end of line - } - 1 { - #clear from cursor to beginning of line + #see DECECM regarding background colour + set modegroup [tcl::string::index $codenorm 4] ;#e.g ? + switch -exact -- $modegroup { + ? { + puts stderr "overtype::renderline DECSEL - SELECTIVE ERASE IN LINE (UNIMPLEMENTED) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + set param [string range $param 1 end] ;#chop qmark + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of line - depending on DECSCA + } + 1 { + #clear from cursor to beginning of line - depending on DECSCA + + } + 2 { + #clear entire line - depending on DECSCA + } + default { + puts stderr "overtype::renderline DECSEL - SELECTIVE ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } - } - 2 { - #clear entire line } default { - puts stderr "overtype::renderline EL - ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + puts stderr "overtype::renderline EL - ERASE IN LINE (TESTING) [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + if {$param eq ""} {set param 0} + switch -exact -- $param { + 0 { + #clear from cursor to end of line + } + 1 { + #clear from cursor to beginning of line + + } + 2 { + #clear entire line + } + default { + puts stderr "overtype::renderline EL - ERASE IN LINE PARAM '$param' unrecognised [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } } } } + L { + puts stderr "overtype::renderline IL - Insert Line - not implemented [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + M { + #CSI Pn M - DL - Delete Line + puts stderr "overtype::renderline DL - Delete Line - not implemented [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + + } X { puts stderr "overtype::renderline X ECH ERASE CHARACTER - $param" #ECH - erase character @@ -3108,6 +3153,36 @@ tcl::namespace::eval overtype { priv::render_erasechar $idx $param #cursor position doesn't change. } + q { + set code_secondlast [tcl::string::index $codenorm end-1] + switch -exact -- $code_secondlast { + {"} { + #DECSCA - Select Character Protection Attribute + #(for use with selective erase: DECSED and DECSEL) + set param [tcl::string::range $codenorm 4 end-2] + if {$param eq ""} {set param 0} + #TODO - store like SGR in stacks - replays? + switch -exact -- $param { + 0 - 2 { + #canerase + puts stderr "overtype::renderline - DECSCA canerase not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + 1 { + #cannoterase + puts stderr "overtype::renderline - DECSCA cannoterase not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + default { + puts stderr "overtype::renderline DECSCA param '$param' not understood [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } + + } + default { + puts stderr "overtype::renderline - CSI ... q not implemented - [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + } + + } r { #$re_decstbm #https://www.vt100.net/docs/vt510-rm/DECSTBM.html @@ -3279,72 +3354,97 @@ tcl::namespace::eval overtype { set instruction restore_cursor break } + "{" { + + puts stderr "renderline warning - CSI.. - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + "}" { + set code_secondlast [tcl::string::index $codenorm end-1] + switch -exact -- $code_secondlast { + ' { + puts stderr "renderline warning - DECIC - Insert Column - CSI...' - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + default { + puts stderr "renderline warning - CSI.. - unimplemented [ansistring VIEW -lf 1 -nul 1 $code]" + } + } + } ~ { - #$re_vt_sequence - lassign [split $param {;}] key mod - - #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ - # - #e.g esc \[2~ insert esc \[2;2~ shift-insert - #mod - subtract 1, and then use bitmask - #shift = 1, (left)Alt = 2, control=4, meta=8 (meta seems to do nothing on many terminals on windows? Intercepted by windows?) - #puts stderr "vt key:$key mod:$mod code:[ansistring VIEW $code]" - if {$key eq "1"} { - #home - } elseif {$key eq "2"} { - #Insert - if {$mod eq ""} { - #no modifier key - set insert_mode [expr {!$insert_mode}] - #rather than set the cursor - we return the insert mode state so the caller can decide + set code_secondlast [tcl::string::index $codenorm end-1] ;#used for e.g CSI x '~ + switch -exact -- $code_secondlast { + ' { + #DECDC - editing sequence - Delete Column + puts stderr "renderline warning - DECDC - unimplemented" } - } elseif {$key eq "3"} { - #Delete - presumably this shifts other chars in the line, with empty cells coming in from the end - switch -- $mod { - "" { - priv::render_delchar $idx - } - "5" { - #ctrl-del - delete to end of word (pwsh) - possibly word on next line if current line empty(?) + default { + #$re_vt_sequence + lassign [split $param {;}] key mod + + #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ + # + #e.g esc \[2~ insert esc \[2;2~ shift-insert + #mod - subtract 1, and then use bitmask + #shift = 1, (left)Alt = 2, control=4, meta=8 (meta seems to do nothing on many terminals on windows? Intercepted by windows?) + #puts stderr "vt key:$key mod:$mod code:[ansistring VIEW $code]" + if {$key eq "1"} { + #home + } elseif {$key eq "2"} { + #Insert + if {$mod eq ""} { + #no modifier key + set insert_mode [expr {!$insert_mode}] + #rather than set the cursor - we return the insert mode state so the caller can decide + } + } elseif {$key eq "3"} { + #Delete - presumably this shifts other chars in the line, with empty cells coming in from the end + switch -- $mod { + "" { + priv::render_delchar $idx + } + "5" { + #ctrl-del - delete to end of word (pwsh) - possibly word on next line if current line empty(?) + } + } + } elseif {$key eq "4"} { + #End + } elseif {$key eq "5"} { + #pgup + } elseif {$key eq "6"} { + #pgDn + } elseif {$key eq "7"} { + #Home + #?? + set idx [expr {$opt_colstart -1}] + set cursor_column 1 + } elseif {$key eq "8"} { + #End + } elseif {$key eq "11"} { + #F1 - or ESCOP or e.g shift F1 ESC\[1;2P + } elseif {$key eq "12"} { + #F2 - or ESCOQ + } elseif {$key eq "13"} { + #F3 - or ESCOR + } elseif {$key eq "14"} { + #F4 - or ESCOS + } elseif {$key eq "15"} { + #F5 or shift F5 ESC\[15;2~ + } elseif {$key eq "17"} { + #F6 + } elseif {$key eq "18"} { + #F7 + } elseif {$key eq "19"} { + #F8 + } elseif {$key eq "20"} { + #F9 + } elseif {$key eq "21"} { + #F10 + } elseif {$key eq "23"} { + #F11 + } elseif {$key eq "24"} { + #F12 } + } - } elseif {$key eq "4"} { - #End - } elseif {$key eq "5"} { - #pgup - } elseif {$key eq "6"} { - #pgDn - } elseif {$key eq "7"} { - #Home - #?? - set idx [expr {$opt_colstart -1}] - set cursor_column 1 - } elseif {$key eq "8"} { - #End - } elseif {$key eq "11"} { - #F1 - or ESCOP or e.g shift F1 ESC\[1;2P - } elseif {$key eq "12"} { - #F2 - or ESCOQ - } elseif {$key eq "13"} { - #F3 - or ESCOR - } elseif {$key eq "14"} { - #F4 - or ESCOS - } elseif {$key eq "15"} { - #F5 or shift F5 ESC\[15;2~ - } elseif {$key eq "17"} { - #F6 - } elseif {$key eq "18"} { - #F7 - } elseif {$key eq "19"} { - #F8 - } elseif {$key eq "20"} { - #F9 - } elseif {$key eq "21"} { - #F10 - } elseif {$key eq "23"} { - #F11 - } elseif {$key eq "24"} { - #F12 } } @@ -3358,51 +3458,72 @@ tcl::namespace::eval overtype { set modegroup [tcl::string::index $codenorm 4] ;#e.g ? = switch -exact -- $modegroup { ? { - set num [tcl::string::range $codenorm 5 end-1] ;#param between ? and h|l - switch -- $num { - 5 { - #DECSNM - reverse video - #How we simulate this to render within a block of text is an open question. - #track all SGR stacks and constantly flip based on the current SGR reverse state? - #It is the job of the calling loop to do this - so at this stage we'll just set the states - - if {$code_end eq "h"} { - #set (enable) - set reverse_mode 1 - } else { - #reset (disable) - set reverse_mode 0 + set smparams [tcl::string::range $codenorm 5 end-1] ;#params between ? and h|l + #one or more modes can be set + set smparam_list [split $smparams {;}] + foreach num $smparam_list { + switch -- $num { + "" { + #ignore empties e.g extra/trailing semicolon in params } - - } - 7 { - #DECAWM autowrap - if {$code_end eq "h"} { - #set (enable) - set autowrap_mode 1 - if {$opt_width ne "\uFFEF"} { - set overflow_idx $opt_width + 5 { + #DECSNM - reverse video + #How we simulate this to render within a block of text is an open question. + #track all SGR stacks and constantly flip based on the current SGR reverse state? + #It is the job of the calling loop to do this - so at this stage we'll just set the states + + if {$code_end eq "h"} { + #set (enable) + set reverse_mode 1 } else { - #review - this is also the cursor position when adding a char at end of line? - set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + #reset (disable) + set reverse_mode 0 } - #review - can idx ever be beyond overflow_idx limit when we change e.g with a width setting and cursor movements? presume not - but sanity check for now. - if {$idx >= $overflow_idx} { - puts stderr "renderline error - idx '$idx' >= overflow_idx '$overflow_idx' - unexpected" + + } + 7 { + #DECAWM autowrap + if {$code_end eq "h"} { + #set (enable) + set autowrap_mode 1 + if {$opt_width ne "\uFFEF"} { + set overflow_idx $opt_width + } else { + #review - this is also the cursor position when adding a char at end of line? + set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + } + #review - can idx ever be beyond overflow_idx limit when we change e.g with a width setting and cursor movements? + # presume not usually - but sanity check with warning for now. + if {$idx >= $overflow_idx} { + puts stderr "renderline warning - idx '$idx' >= overflow_idx '$overflow_idx' - unexpected" + } + } else { + #reset (disable) + set autowrap_mode 0 + #REVIEW! + set overflow_idx -1 } - } else { - #reset (disable) - set autowrap_mode 0 - set overflow_idx -1 } - } - 25 { - if {$code_end eq "h"} { - #visible cursor + 25 { + if {$code_end eq "h"} { + #visible cursor - } else { - #invisible cursor + } else { + #invisible cursor + } + } + 117 { + #DECECM - Erase Color Mode + #https://invisible-island.net/ncurses/ncurses.faq.html + #The Erase color selection controls the background color used when text is erased or new + #text is scrolled on to the screen. Screen background causes newly erased areas or + #scrolled text to be written using color index zero, the screen background. This is VT + #and DECterm compatible. Text background causes erased areas or scrolled text to be + #written using the current text background color. This is PC console compatible and is + #the factory default. + + #see also: https://unix.stackexchange.com/questions/251726/clear-to-end-of-line-uses-the-wrong-background-color-in-screen } } } @@ -3422,8 +3543,21 @@ tcl::namespace::eval overtype { # #use ansistring VIEW -nul 1 -lf 2 -ff 2 -vt 2 #https://vt100.net/docs/vt510-rm/CRM.html + #NOTE - vt100 CRM always does auto-wrap at right margin. + #disabling auto-wrap in set-up or by sequence is disabled. + #We should default to turning off auto-wrap when crm_mode enabled.. but + #displaying truncated (on rhs) crm can still be very useful - and we have optimisation in overflow to avoid excess renderline calls (per grapheme) + #we therefore could reasonably put in an exception to allow auto_wrap to be disabled after crm_mode is engaged, + #although this would be potentially an annoying difference to some.. REVIEW if {$code_end eq "h"} { set crm_mode 1 + set autowrap_mode 1 + if {$opt_width ne "\uFFEF"} { + set overflow_idx $opt_width + } else { + #review - this is also the cursor position when adding a char at end of line? + set overflow_idx [expr {[llength $undercols]}] ;#index at which we would be *in* overflow a row move may still override it + } } else { set crm_mode 0 } @@ -3431,8 +3565,10 @@ tcl::namespace::eval overtype { 4 { #IRM - Insert/Replace Mode if {$code_end eq "h"} { + #CSI 4 h set insert_mode 1 } else { + #CSI 4 l #replace mode set insert_mode 0 } @@ -3480,25 +3616,49 @@ tcl::namespace::eval overtype { } } 7ESC { + # #re_other_single {\x1b(D|M|E)$} #also PM \x1b^...(ST) switch -- [tcl::string::index $codenorm 4] { + c { + #RIS - reset terminal to initial state - where 'terminal' in this case is the renderspace - not the underlying terminal! + puts stderr "renderline reset" + priv::render_unapplied $overlay_grapheme_control_list $gci + set instruction reset + break + } D { #\x84 #index (IND) #vt102-docs: "Moves cursor down one line in same column. If cursor is at bottom margin, screen performs a scroll-up" - puts stderr "ESC D not fully implemented" + puts stderr "renderline ESC D not fully implemented" incr cursor_row priv::render_unapplied $overlay_grapheme_control_list $gci set instruction down #retain cursor_column break } + E { + #\x85 + #review - is behaviour different to lf? + #todo - possibly(?) same logic as handling above. i.e return instruction depends on where column_cursor is at the time we get NEL + #leave implementation until logic for is set in stone... still under review + #It's arguable NEL is a pure cursor movement as opposed to the semantic meaning of crlf or lf in a file. + # + #Next Line (NEL) "Move the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up" + puts stderr "overtype::renderline ESC E unimplemented" + + } + H { + #\x88 + #Tab Set + puts stderr "overtype::renderline ESC H tab set unimplemented" + } M { #\x8D #Reverse Index (RI) #vt102-docs: "Moves cursor up one line in same column. If cursor is at top margin, screen performs a scroll-down" - puts stderr "ESC M not fully implemented" + puts stderr "overtype::renderline ESC M not fully implemented" set replay_codes_overlay [punk::ansi::codetype::sgr_merge_list {*}[lindex $overlay_grapheme_control_stacks $gci]] #move up @@ -3512,17 +3672,39 @@ tcl::namespace::eval overtype { #retain cursor_column break } - E { - #\x85 - #review - is behaviour different to lf? - #todo - possibly(?) same logic as handling above. i.e return instruction depends on where column_cursor is at the time we get NEL - #leave implementation until logic for is set in stone... still under review - #It's arguable NEL is a pure cursor movement as opposed to the semantic meaning of crlf or lf in a file. - # - #Next Line (NEL) "Move the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up" - puts stderr "ESC E unimplemented" + N { + #\x8e - affects next character only + puts stderr "overtype::renderline single shift select G2 command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + O { + #\x8f - affects next character only + puts stderr "overtype::renderline single shift select G3 command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } + P { + #\x90 + #DCS - shouldn't get here - handled in 7DCS branch + #similarly \] OSC (\x9d) and \\ (\x9c) ST + } + V { + #\x96 } + W { + #\x97 + } + X { + #\x98 + #SOS + if {[string index $code end] eq "\007"} { + set sos_content [string range $code 2 end-1] ;#ST is \007 + } else { + set sos_content [string range $code 2 end-2] ;#ST is \x1b\\ + } + #return in some useful form to the caller + #TODO! + lappend sos_list [list string $sos_content row $cursor_row column $cursor_column] + puts stderr "overtype::renderline ESCX SOS UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + } ^ { #puts stderr "renderline PM" #Privacy Message. @@ -3550,24 +3732,6 @@ tcl::namespace::eval overtype { #lappend to a dict element in the result for application-specific processing lappend pm_list $pm_content } - N - O { - puts stderr "overtype::renderline single shift command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } - P { - puts stderr "overtype::renderline DEVICE CONTROL STRING command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } - X { - #SOS - if {[string index $code end] eq "\007"} { - set sos_content [string range $code 2 end-1] ;#ST is \007 - } else { - set sos_content [string range $code 2 end-2] ;#ST is \x1b\\ - } - #return in some useful form to the caller - #TODO! - lappend sos_list [list string $sos_content row $cursor_row column $cursor_column] - puts stderr "overtype::renderline ESCX SOS UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" - } _ { #APC Application Program Command #just warn for now.. @@ -3578,6 +3742,14 @@ tcl::namespace::eval overtype { } } + } + 7DCS { + puts stderr "overtype::renderline DCS - DEVICE CONTROL STRING command UNIMPLEMENTED. code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code]" + # + + } + 7OSC - 8OSC { + } default { } @@ -3593,7 +3765,7 @@ tcl::namespace::eval overtype { } #-------- - if {$opt_overflow == 0} { + if {$opt_expand_right == 0} { #need to truncate to the width of the original undertext #review - string_width vs printing_length here. undertext requirement to be already rendered therefore punk::char::string_width ok? #set num_under_columns [punk::char::string_width $pt_underchars] ;#plaintext underchars @@ -3774,13 +3946,14 @@ tcl::namespace::eval overtype { cursor_saved_attributes $cursor_saved_attributes\ cursor_column $cursor_column\ cursor_row $cursor_row\ - opt_overflow $opt_overflow\ + expand_right $opt_expand_right\ replay_codes $replay_codes\ replay_codes_underlay $replay_codes_underlay\ replay_codes_overlay $replay_codes_overlay\ pm_list $pm_list\ ] if {$opt_returnextra == 1} { + #puts stderr "renderline: $result" return $result } else { #human/debug - map special chars to visual glyphs @@ -3805,6 +3978,7 @@ tcl::namespace::eval overtype { return $result } } else { + #puts stderr "renderline returning: result $outstring instruction $instruction unapplied $unapplied overflow_right $overflow_right" return $outstring } #return [join $out ""] diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm index 7a2f944..267e680 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm @@ -106,7 +106,7 @@ tcl::namespace::eval punk::ansi::class { #overflow is a different concept - perhaps not particularly congruent with the idea of the textblock as a mini terminal emulator. #overflow effectively auto-expands the block(terminal?) width #overflow and wrap both being true won't make sense unless we implement a max_overflow concept - set o_rendered [overtype::renderspace -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] + set o_rendered [overtype::renderspace -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] if {$cksum eq "not-done"} { #if dimensions changed - the checksum won't have been done set o_rendered_what [$o_ansistringobj checksum] @@ -129,7 +129,7 @@ tcl::namespace::eval punk::ansi::class { set o_dimensions $dimensions - set rendered [overtype::renderspace -experimental {test_mode} -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] + set rendered [overtype::renderspace -cp437 1 -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" [$o_ansistringobj get]] return $rendered } method render_to_input_line {args} { @@ -176,7 +176,7 @@ tcl::namespace::eval punk::ansi::class { if {$opt_minus ne "0"} { set chunk [tcl::string::range $chunk 0 end-$opt_minus] } - set rendered [overtype::renderspace -experimental {test_mode} -overflow 0 -wrap 1 -width $w -height $h -appendlines 1 "" $chunk] + set rendered [overtype::renderspace -expand_right 0 -wrap 1 -width $w -height $h -appendlines 1 "" $chunk] set marker "" for {set i 1} {$i <= $w} {incr i} { if {$i % 10 == 0} { @@ -514,11 +514,8 @@ tcl::namespace::eval punk::ansi { set encnames [encoding names] set encoding "" set dimensions "" - set test_mode 0 foreach a $args { - if {$a eq "test_mode"} { - set test_mode 1 - } elseif {$a in $encnames} { + if {$a in $encnames} { set encoding $a } else { if {[regexp {[0-9]+(?:x|X)[0-9]+} $a]} { diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm index 6368aea..4dd7bd6 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm @@ -1021,8 +1021,8 @@ namespace eval punk::console { #It's known this isn't always the case - but things like textutil::untabify2 take only a single value #on some systems test_char_width is a similar speed to get_tabstop_apparent_width - but on some test_char_width is much slower #we will use test_char_width as a fallback - proc get_tabstop_apparent_width {} { - set tslist [get_tabstops] + proc get_tabstop_apparent_width {{inoutchannels {stdin stdout}}} { + set tslist [get_tabstops $inoutchannels] if {![llength $tslist]} { #either terminal failed to report - or none set. set testw [test_char_width \t] @@ -1199,7 +1199,7 @@ namespace eval punk::console { } if {!$emit} { - puts -nonewline stdout \033\[2K\033\[1G ;#2K erase line 1G cursor at col1 + puts -nonewline stdout \033\[2K\033\[1G ;#2K erase line, 1G cursor at col1 } set response "" if {[catch { @@ -1429,12 +1429,12 @@ namespace eval punk::console { proc cursor_save {} { #*** !doctools #[call [fun cursor_save]] - puts -nonewline \x1b\[s + puts -nonewline stdout \x1b\[s } proc cursor_restore {} { #*** !doctools #[call [fun cursor_restore]] - puts -nonewline \x1b\[u + puts -nonewline stdout \x1b\[u } #DEC equivalents of cursor_save/cursor_restore - perhaps more widely supported? proc cursor_save_dec {} { diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm new file mode 100644 index 0000000..628419f --- /dev/null +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/zip-0.1.0.tm @@ -0,0 +1,632 @@ +# -*- tcl -*- +# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'pmix make' or bin/punkmake to update from -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) 2024 JMN +# (C) 2009 Path Thoyts +# +# @@ Meta Begin +# Application punk::zip 0.1.0 +# Meta platform tcl +# Meta license +# @@ Meta End + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# doctools header +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[manpage_begin shellspy_module_punk::zip 0 0.1.0] +#[copyright "2024"] +#[titledesc {Module API}] [comment {-- Name section and table of contents description --}] +#[moddesc {-}] [comment {-- Description at end of page heading --}] +#[require punk::zip] +#[keywords module] +#[description] +#[para] - + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section Overview] +#[para] overview of punk::zip +#[subsection Concepts] +#[para] - + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Requirements +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[subsection dependencies] +#[para] packages used by punk::zip +#[list_begin itemized] + +package require Tcl 8.6- +package require punk::args +#*** !doctools +#[item] [package {Tcl 8.6}] +#[item] [package {punk::args}] + +#*** !doctools +#[list_end] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +#*** !doctools +#[section API] + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# oo::class namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#tcl::namespace::eval punk::zip::class { + #*** !doctools + #[subsection {Namespace punk::zip::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 ---}] + #} +#} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# Base namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +tcl::namespace::eval punk::zip { + tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase + #variable xyz + + #*** !doctools + #[subsection {Namespace punk::zip}] + #[para] Core API functions for punk::zip + #[list_begin definitions] + + proc Path_a_atorbelow_b {path_a path_b} { + return [expr {[StripPath $path_b $path_a] ne $path_a}] + } + proc Path_a_at_b {path_a path_b} { + return [expr {[StripPath $path_a $path_b] eq "." }] + } + + proc Path_strip_alreadynormalized_prefixdepth {path prefix} { + if {$prefix eq ""} { + return $path + } + set pathparts [file split $path] + set prefixparts [file split $prefix] + if {[llength $prefixparts] >= [llength $pathparts]} { + return "" + } + return [file join \ + {*}[lrange \ + $pathparts \ + [llength $prefixparts] \ + end]] + } + + #StripPath - borrowed from tcllib fileutil + # ::fileutil::stripPath -- + # + # If the specified path references/is a path in prefix (or prefix itself) it + # is made relative to prefix. Otherwise it is left unchanged. + # In the case of it being prefix itself the result is the string '.'. + # + # Arguments: + # prefix prefix to strip from the path. + # path path to modify + # + # Results: + # path The (possibly) modified path. + + if {[string equal $::tcl_platform(platform) windows]} { + # Windows. While paths are stored with letter-case preserved al + # comparisons have to be done case-insensitive. For reference see + # SF Tcllib Bug 2499641. + + proc StripPath {prefix path} { + # [file split] is used to generate a canonical form for both + # paths, for easy comparison, and also one which is easy to modify + # using list commands. + + set prefix [file split $prefix] + set npath [file split $path] + + if {[string equal -nocase $prefix $npath]} { + return "." + } + + if {[string match -nocase "${prefix} *" $npath]} { + set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] + } + return $path + } + } else { + proc StripPath {prefix path} { + # [file split] is used to generate a canonical form for both + # paths, for easy comparison, and also one which is easy to modify + # using list commands. + + set prefix [file split $prefix] + set npath [file split $path] + + if {[string equal $prefix $npath]} { + return "." + } + + if {[string match "${prefix} *" $npath]} { + set path [eval [linsert [lrange $npath [llength $prefix] end] 0 file join ]] + } + return $path + } + } + + proc Timet_to_dos {time_t} { + #*** !doctools + #[call [fun Timet_to_dos] [arg time_t]] + #[para] convert a unix timestamp into a DOS timestamp for ZIP times. + #[example { + # DOS timestamps are 32 bits split into bit regions as follows: + # 24 16 8 0 + # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + # |Y|Y|Y|Y|Y|Y|Y|m| |m|m|m|d|d|d|d|d| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s| + # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + #}] + set s [clock format $time_t -format {%Y %m %e %k %M %S}] + scan $s {%d %d %d %d %d %d} year month day hour min sec + expr {(($year-1980) << 25) | ($month << 21) | ($day << 16) + | ($hour << 11) | ($min << 5) | ($sec >> 1)} + } + + proc walk {args} { + #*** !doctools + #[call [fun walk] [arg ?options?] [arg base]] + #[para] Walk a directory tree rooted at base + #[para] the -excludes list can be a set of glob expressions to match against files and avoid + #[para] e.g + #[example { + # punk::zip::walk -exclude {CVS/* *~.#*} library + #}] + + set argd [punk::args::get_dict { + *proc -name punk::zip::walk + -excludes -default "" -help "list of glob expressions to match against files and exclude" + -subpath -default "" + *values -min 1 -max -1 + base + fileglobs -default {*} -multiple 1 + } $args] + set base [dict get $argd values base] + set fileglobs [dict get $argd values fileglobs] + set subpath [dict get $argd opts -subpath] + set excludes [dict get $argd opts -excludes] + + + set imatch [list] + foreach fg $fileglobs { + lappend imatch [file join $subpath $fg] + } + + set result {} + #set imatch [file join $subpath $match] + set files [glob -nocomplain -tails -types f -directory $base -- {*}$imatch] + foreach file $files { + set excluded 0 + foreach glob $excludes { + if {[string match $glob $file]} { + set excluded 1 + break + } + } + if {!$excluded} {lappend result $file} + } + foreach dir [glob -nocomplain -tails -types d -directory $base -- [file join $subpath *]] { + set subdir [walk -subpath $dir -excludes $excludes $base {*}$fileglobs] + if {[llength $subdir]>0} { + set result [concat $result $dir $subdir] + } + } + return $result + } + + # Mkzipfile -- + # + # FIX ME: should handle the current offset for non-seekable channels + # + proc Mkzipfile {zipchan base path {comment ""}} { + #*** !doctools + #[call [fun Mkzipfile] [arg zipchan] [arg base] [arg path] [arg ?comment?]] + #[para] Add a single file to a zip archive + #[para] The zipchan channel should already be open and binary. + #[para] You can provide a -comment for the file. + #[para] The return value is the central directory record that will need to be used when finalizing the zip archive. + + set fullpath [file join $base $path] + set mtime [Timet_to_dos [file mtime $fullpath]] + set utfpath [encoding convertto utf-8 $path] + set utfcomment [encoding convertto utf-8 $comment] + set flags [expr {(1<<11)}] ;# utf-8 comment and path + set method 0 ;# store 0, deflate 8 + set attr 0 ;# text or binary (default binary) + set version 20 ;# minumum version req'd to extract + set extra "" + set crc 0 + set size 0 + set csize 0 + set data "" + set seekable [expr {[tell $zipchan] != -1}] + if {[file isdirectory $fullpath]} { + set attrex 0x41ff0010 ;# 0o040777 (drwxrwxrwx) + #set attrex 0x40000010 + } elseif {[file executable $fullpath]} { + set attrex 0x81ff0080 ;# 0o100777 (-rwxrwxrwx) + } else { + set attrex 0x81b60020 ;# 0o100666 (-rw-rw-rw-) + if {[file extension $fullpath] in {".tcl" ".txt" ".c"}} { + set attr 1 ;# text + } + } + + if {[file isfile $fullpath]} { + set size [file size $fullpath] + if {!$seekable} {set flags [expr {$flags | (1 << 3)}]} + } + + + set offset [tell $zipchan] + set local [binary format a4sssiiiiss PK\03\04 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]] + append local $utfpath $extra + puts -nonewline $zipchan $local + + if {[file isfile $fullpath]} { + # If the file is under 2MB then zip in one chunk, otherwize we use + # streaming to avoid requiring excess memory. This helps to prevent + # storing re-compressed data that may be larger than the source when + # handling PNG or JPEG or nested ZIP files. + if {$size < 0x00200000} { + set fin [open $fullpath rb] + set data [read $fin] + set crc [zlib crc32 $data] + set cdata [zlib deflate $data] + if {[string length $cdata] < $size} { + set method 8 + set data $cdata + } + close $fin + set csize [string length $data] + puts -nonewline $zipchan $data + } else { + set method 8 + set fin [open $fullpath rb] + set zlib [zlib stream deflate] + while {![eof $fin]} { + set data [read $fin 4096] + set crc [zlib crc32 $data $crc] + $zlib put $data + if {[string length [set zdata [$zlib get]]]} { + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + } + } + close $fin + $zlib finalize + set zdata [$zlib get] + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + $zlib close + } + + if {$seekable} { + # update the header if the output is seekable + set local [binary format a4sssiiii PK\03\04 \ + $version $flags $method $mtime $crc $csize $size] + set current [tell $zipchan] + seek $zipchan $offset + puts -nonewline $zipchan $local + seek $zipchan $current + } else { + # Write a data descriptor record + set ddesc [binary format a4iii PK\7\8 $crc $csize $size] + puts -nonewline $zipchan $ddesc + } + } + + #PK\x01\x02 Cdentral directory file header + #set v1 0x0317 ;#upper byte 03 -> UNIX lower byte 23 -> 2.3 + set v1 0x0017 ;#upper byte 00 -> MS_DOS and OS/2 (FAT/VFAT/FAT32 file systems) + + set hdr [binary format a4ssssiiiisssssii PK\01\02 $v1 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]\ + [string length $utfcomment] 0 $attr $attrex $offset] + append hdr $utfpath $extra $utfcomment + return $hdr + } + # zip::mkzip -- + # + # eg: zip my.zip -directory Subdir -runtime unzipsfx.exe *.txt + # + proc mkzip {args} { + #*** !doctools + #[call [fun mkzip] [arg ?options?] [arg filename]] + #[para] Create a zip archive in 'filename' + #[para] If a file already exists, an error will be raised. + set argd [punk::args::get_dict { + *proc -name punk::zip::mkzip -help "Create a zip archive in 'filename'" + *opts + -return -default "pretty" -choices {pretty list none} -help "mkzip can return a list of the files and folders added to the archive + the option -return pretty is the default and uses the punk::lib pdict/plist system + to return a formatted list for the terminal + " + -zipkit -default 0 -type none -help "" + -runtime -default "" -help "specify a prefix file + e.g punk::zip::mkzip -runtime unzipsfx.exe -directory subdir output.zip + will create a self-extracting zip archive from the subdir/ folder. + " + -comment -default "" -help "An optional comment for the archive" + -directory -default "" -help "The new zip archive will scan for contents within this folder or current directory if not provided" + -base -default "" -help "The new zip archive will be rooted in this directory if provided + it must be a parent of -directory" + -exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"} + *values -min 1 -max -1 + filename -default "" -help "name of zipfile to create" + globs -default {*} -multiple 1 -help "list of glob patterns to match. + Only directories with matching files will be included in the archive" + } $args] + + set filename [dict get $argd values filename] + if {$filename eq ""} { + error "mkzip filename cannot be empty string" + } + if {[regexp {[?*]} $filename]} { + #catch a likely error where filename is omitted and first glob pattern is misinterpreted as zipfile name + error "mkzip filename should not contain glob characters ? *" + } + if {[file exists $filename]} { + error "mkzip filename:$filename already exists" + } + dict for {k v} [dict get $argd opts] { + switch -- $k { + -comment { + dict set argd opts $k [encoding convertto utf-8 $v] + } + -directory - -base { + dict set argd opts $k [file normalize $v] + } + } + } + + array set opts [dict get $argd opts] + + + if {$opts(-directory) ne ""} { + if {$opts(-base) ne ""} { + #-base and -directory have been normalized already + if {![Path_a_atorbelow_b $opts(-directory) $opts(-base)]} { + error "punk::zip::mkzip -base $opts(-base) must be above -directory $opts(-directory)" + } + set base $opts(-base) + set relpath [Path_strip_alreadynormalized_prefixdepth $opts(-directory) $opts(-base)] + } else { + set base $opts(-directory) + set relpath "" + } + set paths [walk -exclude $opts(-exclude) -subpath $relpath -- $base {*}[dict get $argd values globs]] + + set norm_filename [file normalize $filename] + set norm_dir [file normalize $opts(-directory)] ;#we only care if filename below -directory (which is where we start scanning) + if {[Path_a_atorbelow_b $norm_filename $norm_dir]} { + #check that we aren't adding the zipfile to itself + #REVIEW - now that we open zipfile after scanning - this isn't really a concern! + #keep for now in case we can add an -update or a -force facility (or in case we modify to add to zip as we scan for members?) + #In the case of -force - we may want to delay replacement of original until scan is done? + + #try to avoid looping on all paths and performing (somewhat) expensive file normalizations on each + #1st step is to check the patterns and see if our zipfile is already excluded - in which case we need not check the paths + set self_globs_match 0 + foreach g [dict get $argd values globs] { + if {[string match $g [file tail $filename]]} { + set self_globs_match 1 + break + } + } + if {$self_globs_match} { + #still dangerous + set self_excluded 0 + foreach e $opts(-exclude) { + if {[string match $e [file tail $filename]]} { + set self_excluded 1 + break + } + } + if {!$self_excluded} { + #still dangerous - likely to be in resultset - check each path + #puts stderr "zip file $filename is below directory $opts(-directory)" + set self_is_matched 0 + set i 0 + foreach p $paths { + set norm_p [file normalize [file join $opts(-directory) $p]] + if {[Path_a_at_b $norm_filename $norm_p]} { + set self_is_matched 1 + break + } + incr i + } + if {$self_is_matched} { + puts stderr "WARNING - zipfile being created '$filename' was matched. Excluding this file. Relocate the zip, or use -exclude patterns to avoid this message" + set paths [lremove $paths $i] + } + } + } + } + } else { + set paths [list] + set dir [pwd] + if {$opts(-base) ne ""} { + if {![Path_a_atorbelow_b $dir $opts(-base)]} { + error "punk::zip::mkzip -base $opts(-base) must be above current directory" + } + set relpath [Path_strip_alreadynormalized_prefixdepth [file normalize $dir] [file normalize $opts(-base)]] + } else { + set relpath "" + } + set base $opts(-base) + + set matches [glob -nocomplain -type f -- {*}[dict get $argd values globs]] + foreach m $matches { + if {$m eq $filename} { + #puts stderr "--> excluding $filename" + continue + } + set isok 1 + foreach e [concat $opts(-exclude) $filename] { + if {[string match $e $m]} { + set isok 0 + break + } + } + if {$isok} { + lappend paths [file join $relpath $m] + } + } + } + + if {![llength $paths]} { + return "" + } + + set zf [open $filename wb] + if {$opts(-runtime) ne ""} { + set rt [open $opts(-runtime) rb] + fcopy $rt $zf + close $rt + } elseif {$opts(-zipkit)} { + set zkd "#!/usr/bin/env tclkit\n\# This is a zip-based Tcl Module\n" + append zkd "package require vfs::zip\n" + append zkd "vfs::zip::Mount \[info script\] \[info script\]\n" + append zkd "if {\[file exists \[file join \[info script\] main.tcl\]\]} {\n" + append zkd " source \[file join \[info script\] main.tcl\]\n" + append zkd "}\n" + append zkd \x1A + puts -nonewline $zf $zkd + } + set count 0 + set cd "" + + set members [list] + foreach path $paths { + #puts $path + lappend members $path + append cd [Mkzipfile $zf $base $path] ;#path already includes relpath + incr count + } + set cdoffset [tell $zf] + set endrec [binary format a4ssssiis PK\05\06 0 0 \ + $count $count [string length $cd] $cdoffset\ + [string length $opts(-comment)]] + append endrec $opts(-comment) + puts -nonewline $zf $cd + puts -nonewline $zf $endrec + close $zf + + set result "" + switch -exact -- $opts(-return) { + list { + set result $members + } + pretty { + if {[info commands showlist] ne ""} { + set result [plist -channel none members] + } else { + set result $members + } + } + none { + set result "" + } + } + return $result + } + + + #*** !doctools + #[list_end] [comment {--- end definitions namespace punk::zip ---}] +} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +# Secondary API namespace +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +tcl::namespace::eval punk::zip::lib { + tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase + tcl::namespace::path [tcl::namespace::parent] + #*** !doctools + #[subsection {Namespace punk::zip::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 punk::zip::lib ---}] +} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ + + + +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +#*** !doctools +#[section Internal] +#tcl::namespace::eval punk::zip::system { + #*** !doctools + #[subsection {Namespace punk::zip::system}] + #[para] Internal functions that are not part of the API + + + +#} +# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +## Ready +package provide punk::zip [tcl::namespace::eval punk::zip { + variable pkg punk::zip + variable version + set version 0.1.0 +}] +return + +#*** !doctools +#[manpage_end] + diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.1.tm index 5d127a3..88fdc3f 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.1.tm @@ -1933,13 +1933,6 @@ tcl::namespace::eval textblock { set hval $ansibase_header$header ;#no reset set rowh [my header_height $hrow] - #set h_lines [lrepeat $rowh $hcell_line_blank] - #set hcell_blank [join $h_lines \n] - #set hval_lines [split $hval \n] - #set hval_lines [lrange $hval_lines 0 $rowh-1] - #set hval_block [join $hval_lines \n] - #set headercell [overtype::left -experimental test_mode $ansibase_header$hcell_blank$RST $hval_block] - if {$hrow == 0} { set hlims $header_boxlimits_toprow set rowpos "top" @@ -2146,7 +2139,7 @@ tcl::namespace::eval textblock { #puts $hblock #puts "==>hval:'$hval'[a]" #puts "==>hval:'[ansistring VIEW $hval]'" - #set spanned_frame [overtype::renderspace -experimental test_mode -transparent 1 $spanned_frame $hblock] + #set spanned_frame [overtype::renderspace -transparent 1 $spanned_frame $hblock] #spanned values default left - todo make configurable @@ -3504,11 +3497,11 @@ tcl::namespace::eval textblock { set height [textblock::height $table] ;#only need to get height once at start } else { set nextcol [textblock::join -- [textblock::block $padwidth $height $TSUB] $nextcol] - set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent $TSUB $table[unset table] $nextcol] + set table [overtype::renderspace -expand_right 1 -transparent $TSUB $table[unset table] $nextcol] #JMN #set nextcol [textblock::join -- [textblock::block $padwidth $height "\uFFFF"] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent \uFFFF $table $nextcol] + #set table [overtype::renderspace -expand_right 1 -transparent \uFFFF $table $nextcol] } incr padwidth $bodywidth incr colposn @@ -3609,14 +3602,7 @@ tcl::namespace::eval textblock { set table $nextcol set height [textblock::height $table] ;#only need to get height once at start } else { - set table [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -overflow 1 -experimental test_mode -transparent $TSUB $table $nextcol] - - #set nextcol [textblock::join -- [textblock::block $padwidth $height $TSUB] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent $TSUB $table[unset table] $nextcol] - #JMN - - #set nextcol [textblock::join -- [textblock::block $padwidth $height "\uFFFF"] $nextcol] - #set table [overtype::renderspace -overflow 1 -experimental test_mode -transparent \uFFFF $table $nextcol] + set table [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $table $nextcol] } incr padwidth $bodywidth incr colposn @@ -3726,7 +3712,7 @@ tcl::namespace::eval textblock { lappend body_blocks $nextcol_body } else { if {$headerheight > 0} { - set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -overflow 1 -experimental test_mode -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]] + set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]] } lappend body_blocks $nextcol_body #set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body] diff --git a/src/scriptapps/fetchruntime.ps1 b/src/scriptapps/fetchruntime.ps1 index e6771f0..67dc537 100644 --- a/src/scriptapps/fetchruntime.ps1 +++ b/src/scriptapps/fetchruntime.ps1 @@ -1,5 +1,5 @@ $url = "https://www.gitea1.intx.com.au/jn/punkbin/raw/branch/master/win64/tclkit86bi.exe" -$output = "$(join-path $PSScriptRoot "..\src\runtime\tclkit86bi.exe")" +$output = "$(join-path $PSScriptRoot "..\runtime\tclkit86bi.exe")" #padding diff --git a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/licence.txt b/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/licence.txt deleted file mode 100644 index 795e883..0000000 --- a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/licence.txt +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2023 Robin Stuart -All rights reserved. - -Redistribution and use in source and binary forms are permitted -provided that the above copyright notice and this paragraph are -duplicated in all such forms and that any documentation, -advertising materials, and other materials related to such -distribution and use acknowledge that the software was developed -by the . The name of the - may not be used to endorse or promote products derived -from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/pkgIndex.tcl b/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/pkgIndex.tcl deleted file mode 100644 index e4c9a07..0000000 --- a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/pkgIndex.tcl +++ /dev/null @@ -1,2 +0,0 @@ -package ifneeded zint 2.13.0\ - [list load [file join $dir zint[info sharedlibextension]]] diff --git a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/readme.txt b/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/readme.txt deleted file mode 100644 index 50ede10..0000000 --- a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/readme.txt +++ /dev/null @@ -1,27 +0,0 @@ - zint tcl binding readme - ----------------------- - 2014-06-30 - (C) Harald Oehlmann - harald.oehlmann@users.sourceforge.net - -What: tcl binding for zint bar code generator library - -Build: -The header files of a TCL and Tk build are required for the build. - -- MS-VC6 project file "zint_tcl.dsp" may be opened by the GUI. - (will need to add your version of tcl/tk libs to LINK32, e.g. - "tcl85.lib" and "tk85.lib") -- Linux/Unix build is provided by the configure script. - Thanks to Christian Werner for that. - -Usage: - -load zint.dll -zint help - -Most options are identical to the command line tool. -Details may be found in the zint manual. - -Demo: -The demo folder contains a visual demo program. diff --git a/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/zint.dll b/src/vfs/punk8win.vfs/lib_tcl8/zint-2.13.0/zint.dll deleted file mode 100644 index fe3578aff2567f59e3d9446c1147d10164590f46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 622592 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

CcD&-rfP-yqM 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͖i^3mmc&PBXI5ujDUh} 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

XeyX0a6*K~vs2#?kyaK|%BK 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 {;joeaiiML~gq_`|(y&}M8XJr*DJ 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