General-purpose, custom functions that might be used in several sections, appear here
proc gregsub {re txt block} {
set res {}
while 1 {
set part [lindex [regexp -inline $re $txt] 1]
if {![string length $part]} {
append res $txt
break
}
set lst [split [regsub -- $re $txt "\0"] "\0"]
append res [lindex $lst 0] [apply $block $part]
set txt [lindex $lst 1]
}
return $res
}
proc regrange {p1 sep p2 data block} {
set on 0
set delay 0
if {![string compare $sep "..."]} {
set delay 1
}
if ![llength $p1] { ; set on 1
set p1 {$-^} ; }
foreach line $data {
switch -exact -- $sep {
{..} {
if {[regexp -- $p1 $line]} {set on 1} elseif {[regexp -- $p2 $line]} {set delay 1}
if {$on} {
apply $block $line
}
if {$delay} {
set on 0
set delay 0
}
}
{...} {
if {[regexp -- $p1 $line]} {set delay 0} elseif {[regexp -- $p2 $line]} {set on 0}
if {$on} {
apply $block $line
}
if {!$delay} {
set on 1
set delay 1
}
}
default {
error "wrong range operator $sep"
}
}
}
}
proc with-file {file block} {
set fd [open $file]
uplevel 1 [list apply $block $fd]
close $fd
}
proc read-lines {fd block} {
while {[gets $fd line] >= 0} {
uplevel 1 [list apply $block $line]
}
}
proc readlines {fd block} {
set data [read -nonewline $fd]
set variable options
set cr "\n"
if [info exist options(CR)] {
set cr $options(CR)
}
foreach line [split [regsub -all -- $cr $data "\0" ] "\0" ] {
uplevel 1 [list apply $block $line]
puts -nonewline $cr
}
}
proc argf-iter {block} {
variable options
foreach file $::argv {
with-file $file [list fd "return \[readlines \$fd {$block}\]"]
}
} |