Posted to tcl by schelte at Fri Jan 12 10:17:51 GMT 2024view pretty
if {[dict exists [namespace ensemble configure file -map] home]} return namespace eval file { if {[namespace parent] ne "::"} { # Replacement only for the parent namespace interp alias {} [namespace current]::file {} file } elseif {[namespace which file] ne "[namespace current]::file"} { # Move the original file command into the current namespace, so we # can still use it to implement the replacement rename file file } # Create a version of the file command that works the same as Tcl 8.7/9.0 namespace ensemble create -map { atime {filenamearg atime} attributes {filenamearg attributes} channels {file channels} copy {filenameargs copy} delete {filenameargs delete} dirname dirname executable {filenamearg executable} exists {filenamearg exists} extension {file extension} home home isdirectory {filenamearg isdirectory} isfile {filenamearg isfile} join filejoin link {filenameargs link} lstat {filestat lstat} mkdir {filenameargs mkdir} mtime {filenamearg mtime} nativename {filenamearg nativename} normalize normalize owned {filenamearg owned} pathtype pathtype readable {filenamearg readable} readlink {filenamearg readlink} rename {filenameargs rename} rootname {file rootname} separator {file separator} size {filenamearg size} split filesplit stat {filestat stat} system {filenamearg system} tail filetail tempdir tempdir tempfile {file tempfile} tildeexpand tildeexpand type {filenamearg type} volumes {file volumes} writable {filenamearg writable} } proc protect {name} { return [regsub {^~} $name {./&}] } proc pathtype {name} { if {[string index $name 0] eq "~"} { return relative } else { tailcall file pathtype $name } } proc filejoin {args} { set rc "" foreach arg $args { if {[pathtype $arg] ne "relative"} { set rc $arg } elseif {[string index $rc end] in {/ ""}} { append rc [string trimright $arg /] } else { append rc / [string trimright $arg /] } } return [regsub -all //+ $rc /] } proc normalize {name} { tailcall file normalize [filejoin [pwd] $name] } proc filenamearg {cmd file args} { tailcall file $cmd [protect $file] {*}$args } proc filenameargs {cmd args} { set opt 1 set args [lmap arg $args { if {$opt && [string index $arg 0] eq "-"} { if {$arg eq "--"} {set opt 0} set arg } else { set opt 0 protect $arg } }] tailcall file $cmd {*}$args } proc filestat {cmd name {var ""}} { if {[llength [info level 0]] > 3} { tailcall file $cmd [protect $name] $var } else { file $cmd [protect $name] stat return [array get stat] } } proc filesplit {name} { return [lmap part [file split $name] {regsub {^\./} $part {}}] } proc dirname {name} { tailcall file dirname [filejoin . $name] } proc filetail {name} { set rc [file tail [filejoin . $name]] return [regsub {^./} $rc {}] } proc home {user} { tailcall file normalize ~$user } proc tildeexpand {name} { tailcall file normalize $name } proc tempdir {{template tcl}} { close [file tempfile name] file delete $name set tmpdir [file dirname $name] while 1 { set rnd [binary format I [expr {int(rand() * 0x100000000)}]] set str [string range [binary encode base64 $rnd]] if {[string is alnum $str]} { set name [filejoin $tmpdir [string cat $template _ $str]] if {![catch {file mkdir $name}]} { file attributes $name -permissions go-rwx break } } } return $name } }
Comments
Posted by schelte at Fri Jan 12 10:26:25 GMT 2024 [text] [code]
This code can be loaded in a namespace to only update the file command for that namespace, or in the global namespace to make the file command behave like it does in Tcl 8.7/9 for the whole application.