#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#review - and see which if any actually belong in the links key of our return
#review - and see which if any actually belong in the links key of our return
if {$skip_links} {
continue
}
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#
#
@ -1539,41 +1546,55 @@ namespace eval punk::du {
#
#
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#
#
#links are techically files too, whether they point to a file/dir or nothing.
#--------------------------------------
#review
#for consistency with tcl glob - we can't skip - it may point to a file or directory.
#--------------------------------------
if {!$entry_directory} {
if {!$entry_directory} {
#review - other attributes? will we see a link to a link here?
set entry_link_to_file 1
dict set linkdata target_type file
dict set linkdata target_type file
} else {
} else {
set entry_link_to_directory 1
dict set linkdata target_type directory
dict set linkdata target_type directory
}
}
lappend links $fullname
#review - other attributes? will we see a link to a link here?
#set ftype "l"
#this branch will never be taken as we're currently setting either entry_link_to_file or entry_link_to_directory
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
dict set linkdata reparseinfo $entry_reparse_info
dict set linkdata reparseinfo $entry_reparse_info
}
}
}
}
if {$entry_directory} {
set do_sizes $do_sizes_l
set do_times $do_times_l
}
if {$skip_dirs && ($entry_directory || $entry_link_to_directory)} {
continue
} elseif {$entry_directory} {
#consider all directories to be executable for now - as this what TCL glob does on windows.
#consider all directories to be executable for now - as this what TCL glob does on windows.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
if {$skip_dirs} {
#if {!$entry_reparse_point} {
continue
}
if {!$entry_reparse_point} {
lappend dirs $fullname
lappend dirs $fullname
#set ftype "d"
#set ftype "d"
set do_sizes $do_sizes_d
set do_sizes $do_sizes_d
set do_times $do_times_d
set do_times $do_times_d
} else {
#} else {
#other mechanisms can't immediately classify a link as file vs directory - so we don't return this info in the main dirs/files collections
# dict set linkdata target_type directory
dict set linkdata target_type directory
#}
}
}
}
if {!$entry_reparse_point && !$entry_directory} {
if {$entry_link_to_file || (!$entry_reparse_point && !$entry_directory)} {
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
if {$skip_files} {
if {$skip_files} {
continue
continue
@ -1620,9 +1641,6 @@ namespace eval punk::du {
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
]
]
}
}
#if {[dict size $linkdata]} {
# dict set linkinfo $fullname $linkdata
#}
if {[llength $linkdata]} {
if {[llength $linkdata]} {
dict set linkinfo $fullname $linkdata
dict set linkinfo $fullname $linkdata
}
}
@ -1686,14 +1704,17 @@ namespace eval punk::du {
}
}
return $vfsmounts
return $vfsmounts
}
}
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
proc file_join_one {base newtail} {
proc file_join_one {base newtail} {
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
#note base could be c: or c:/
# we need to be careful not to introduce extra slashes - file join should already do the right thing.
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results - apparently by design." level warning]
}
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
}
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results" level medium]
}
}
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
lappend d1_overrides italic bold
lappend d1_overrides italic bold
}
}
#if {$d in $vfsmounts} {
#dlink_style & dshortcut_style are for underlines - can be added with colours already set
# if {$d in $flaggedhidden} {
# #we could have a hidden dir which is also a vfs.. colour will be overridden giving no indication of 'hidden' status - REVIEW
# #(This situation encountered on windows - even though file attr showed -hidden 0 - the glob with -types hidden returned it.. possibly a tcl glob bug on windows)
# #mark it differently for now.. (todo bug report?)
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red Yellow bold]
# } else {
# set d1 [punk::ansi::a+ green Purple bold]
# }
# } else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red White bold]
# } else {
# set d1 [punk::ansi::a+ green bold]
# }
# }
#} else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red bold]
# }
#}
#dlink-style & dshortcut_style are for underlines - can be added with colours already set
#For example if we launch mintty from within punk, it will pick this up and then launch the new mintty with this shell. seems reasonable.
#some terminals launched from within punk will ignore this - but maintain the value: e.g tabby, rio
#others might ignore it but also clear or not pass it e.g wt, wezterm
#terminals that ignore it are presumably using a stored default shell from their own config.
#shell programs such as cmd.exe, powershell.exe seem to maintain the env variable if launched from within punk.
#we will respect the existing env(SHELL) if it is set
#- as that is the standard way to indicate the user's preferred shell - but if it isn't set, we'll set it to the current executable.
#This allows child processes launched from the shell to pick up on the fact they are running in a shell environment, and also allows nested shells to work correctly.
#review - what about the args the current shell was launched with?
set ::env(SHELL) [file normalize [info nameofexecutable]]
}
}
if {![info exists ::env(TERM)]} {
if {![info exists ::env(TERM)]} {
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#review - and see which if any actually belong in the links key of our return
#review - and see which if any actually belong in the links key of our return
if {$skip_links} {
continue
}
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#
#
@ -1539,41 +1546,55 @@ namespace eval punk::du {
#
#
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#
#
#links are techically files too, whether they point to a file/dir or nothing.
#--------------------------------------
#review
#for consistency with tcl glob - we can't skip - it may point to a file or directory.
#--------------------------------------
if {!$entry_directory} {
if {!$entry_directory} {
#review - other attributes? will we see a link to a link here?
set entry_link_to_file 1
dict set linkdata target_type file
dict set linkdata target_type file
} else {
} else {
set entry_link_to_directory 1
dict set linkdata target_type directory
dict set linkdata target_type directory
}
}
lappend links $fullname
#review - other attributes? will we see a link to a link here?
#set ftype "l"
#this branch will never be taken as we're currently setting either entry_link_to_file or entry_link_to_directory
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
dict set linkdata reparseinfo $entry_reparse_info
dict set linkdata reparseinfo $entry_reparse_info
}
}
}
}
if {$entry_directory} {
set do_sizes $do_sizes_l
set do_times $do_times_l
}
if {$skip_dirs && ($entry_directory || $entry_link_to_directory)} {
continue
} elseif {$entry_directory} {
#consider all directories to be executable for now - as this what TCL glob does on windows.
#consider all directories to be executable for now - as this what TCL glob does on windows.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
if {$skip_dirs} {
#if {!$entry_reparse_point} {
continue
}
if {!$entry_reparse_point} {
lappend dirs $fullname
lappend dirs $fullname
#set ftype "d"
#set ftype "d"
set do_sizes $do_sizes_d
set do_sizes $do_sizes_d
set do_times $do_times_d
set do_times $do_times_d
} else {
#} else {
#other mechanisms can't immediately classify a link as file vs directory - so we don't return this info in the main dirs/files collections
# dict set linkdata target_type directory
dict set linkdata target_type directory
#}
}
}
}
if {!$entry_reparse_point && !$entry_directory} {
if {$entry_link_to_file || (!$entry_reparse_point && !$entry_directory)} {
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
if {$skip_files} {
if {$skip_files} {
continue
continue
@ -1620,9 +1641,6 @@ namespace eval punk::du {
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
]
]
}
}
#if {[dict size $linkdata]} {
# dict set linkinfo $fullname $linkdata
#}
if {[llength $linkdata]} {
if {[llength $linkdata]} {
dict set linkinfo $fullname $linkdata
dict set linkinfo $fullname $linkdata
}
}
@ -1686,14 +1704,17 @@ namespace eval punk::du {
}
}
return $vfsmounts
return $vfsmounts
}
}
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
proc file_join_one {base newtail} {
proc file_join_one {base newtail} {
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
#note base could be c: or c:/
# we need to be careful not to introduce extra slashes - file join should already do the right thing.
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results - apparently by design." level warning]
}
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
}
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results" level medium]
}
}
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
lappend d1_overrides italic bold
lappend d1_overrides italic bold
}
}
#if {$d in $vfsmounts} {
#dlink_style & dshortcut_style are for underlines - can be added with colours already set
# if {$d in $flaggedhidden} {
# #we could have a hidden dir which is also a vfs.. colour will be overridden giving no indication of 'hidden' status - REVIEW
# #(This situation encountered on windows - even though file attr showed -hidden 0 - the glob with -types hidden returned it.. possibly a tcl glob bug on windows)
# #mark it differently for now.. (todo bug report?)
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red Yellow bold]
# } else {
# set d1 [punk::ansi::a+ green Purple bold]
# }
# } else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red White bold]
# } else {
# set d1 [punk::ansi::a+ green bold]
# }
# }
#} else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red bold]
# }
#}
#dlink-style & dshortcut_style are for underlines - can be added with colours already set
#For example if we launch mintty from within punk, it will pick this up and then launch the new mintty with this shell. seems reasonable.
#some terminals launched from within punk will ignore this - but maintain the value: e.g tabby, rio
#others might ignore it but also clear or not pass it e.g wt, wezterm
#terminals that ignore it are presumably using a stored default shell from their own config.
#shell programs such as cmd.exe, powershell.exe seem to maintain the env variable if launched from within punk.
#we will respect the existing env(SHELL) if it is set
#- as that is the standard way to indicate the user's preferred shell - but if it isn't set, we'll set it to the current executable.
#This allows child processes launched from the shell to pick up on the fact they are running in a shell environment, and also allows nested shells to work correctly.
#review - what about the args the current shell was launched with?
set ::env(SHELL) [file normalize [info nameofexecutable]]
}
}
if {![info exists ::env(TERM)]} {
if {![info exists ::env(TERM)]} {
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#review - and see which if any actually belong in the links key of our return
#review - and see which if any actually belong in the links key of our return
if {$skip_links} {
continue
}
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#
#
@ -1539,41 +1546,55 @@ namespace eval punk::du {
#
#
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#
#
#links are techically files too, whether they point to a file/dir or nothing.
#--------------------------------------
#review
#for consistency with tcl glob - we can't skip - it may point to a file or directory.
#--------------------------------------
if {!$entry_directory} {
if {!$entry_directory} {
#review - other attributes? will we see a link to a link here?
set entry_link_to_file 1
dict set linkdata target_type file
dict set linkdata target_type file
} else {
} else {
set entry_link_to_directory 1
dict set linkdata target_type directory
dict set linkdata target_type directory
}
}
lappend links $fullname
#review - other attributes? will we see a link to a link here?
#set ftype "l"
#this branch will never be taken as we're currently setting either entry_link_to_file or entry_link_to_directory
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
dict set linkdata reparseinfo $entry_reparse_info
dict set linkdata reparseinfo $entry_reparse_info
}
}
}
}
if {$entry_directory} {
set do_sizes $do_sizes_l
set do_times $do_times_l
}
if {$skip_dirs && ($entry_directory || $entry_link_to_directory)} {
continue
} elseif {$entry_directory} {
#consider all directories to be executable for now - as this what TCL glob does on windows.
#consider all directories to be executable for now - as this what TCL glob does on windows.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
if {$skip_dirs} {
#if {!$entry_reparse_point} {
continue
}
if {!$entry_reparse_point} {
lappend dirs $fullname
lappend dirs $fullname
#set ftype "d"
#set ftype "d"
set do_sizes $do_sizes_d
set do_sizes $do_sizes_d
set do_times $do_times_d
set do_times $do_times_d
} else {
#} else {
#other mechanisms can't immediately classify a link as file vs directory - so we don't return this info in the main dirs/files collections
# dict set linkdata target_type directory
dict set linkdata target_type directory
#}
}
}
}
if {!$entry_reparse_point && !$entry_directory} {
if {$entry_link_to_file || (!$entry_reparse_point && !$entry_directory)} {
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
if {$skip_files} {
if {$skip_files} {
continue
continue
@ -1620,9 +1641,6 @@ namespace eval punk::du {
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
]
]
}
}
#if {[dict size $linkdata]} {
# dict set linkinfo $fullname $linkdata
#}
if {[llength $linkdata]} {
if {[llength $linkdata]} {
dict set linkinfo $fullname $linkdata
dict set linkinfo $fullname $linkdata
}
}
@ -1686,14 +1704,17 @@ namespace eval punk::du {
}
}
return $vfsmounts
return $vfsmounts
}
}
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
proc file_join_one {base newtail} {
proc file_join_one {base newtail} {
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
#note base could be c: or c:/
# we need to be careful not to introduce extra slashes - file join should already do the right thing.
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results - apparently by design." level warning]
}
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
}
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results" level medium]
}
}
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
lappend d1_overrides italic bold
lappend d1_overrides italic bold
}
}
#if {$d in $vfsmounts} {
#dlink_style & dshortcut_style are for underlines - can be added with colours already set
# if {$d in $flaggedhidden} {
# #we could have a hidden dir which is also a vfs.. colour will be overridden giving no indication of 'hidden' status - REVIEW
# #(This situation encountered on windows - even though file attr showed -hidden 0 - the glob with -types hidden returned it.. possibly a tcl glob bug on windows)
# #mark it differently for now.. (todo bug report?)
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red Yellow bold]
# } else {
# set d1 [punk::ansi::a+ green Purple bold]
# }
# } else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red White bold]
# } else {
# set d1 [punk::ansi::a+ green bold]
# }
# }
#} else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red bold]
# }
#}
#dlink-style & dshortcut_style are for underlines - can be added with colours already set
#For example if we launch mintty from within punk, it will pick this up and then launch the new mintty with this shell. seems reasonable.
#some terminals launched from within punk will ignore this - but maintain the value: e.g tabby, rio
#others might ignore it but also clear or not pass it e.g wt, wezterm
#terminals that ignore it are presumably using a stored default shell from their own config.
#shell programs such as cmd.exe, powershell.exe seem to maintain the env variable if launched from within punk.
#we will respect the existing env(SHELL) if it is set
#- as that is the standard way to indicate the user's preferred shell - but if it isn't set, we'll set it to the current executable.
#This allows child processes launched from the shell to pick up on the fact they are running in a shell environment, and also allows nested shells to work correctly.
#review - what about the args the current shell was launched with?
set ::env(SHELL) [file normalize [info nameofexecutable]]
}
}
if {![info exists ::env(TERM)]} {
if {![info exists ::env(TERM)]} {
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#review - and see which if any actually belong in the links key of our return
#review - and see which if any actually belong in the links key of our return
if {$skip_links} {
continue
}
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#
#
@ -1539,41 +1546,55 @@ namespace eval punk::du {
#
#
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#
#
#links are techically files too, whether they point to a file/dir or nothing.
#--------------------------------------
#review
#for consistency with tcl glob - we can't skip - it may point to a file or directory.
#--------------------------------------
if {!$entry_directory} {
if {!$entry_directory} {
#review - other attributes? will we see a link to a link here?
set entry_link_to_file 1
dict set linkdata target_type file
dict set linkdata target_type file
} else {
} else {
set entry_link_to_directory 1
dict set linkdata target_type directory
dict set linkdata target_type directory
}
}
lappend links $fullname
#review - other attributes? will we see a link to a link here?
#set ftype "l"
#this branch will never be taken as we're currently setting either entry_link_to_file or entry_link_to_directory
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
dict set linkdata reparseinfo $entry_reparse_info
dict set linkdata reparseinfo $entry_reparse_info
}
}
}
}
if {$entry_directory} {
set do_sizes $do_sizes_l
set do_times $do_times_l
}
if {$skip_dirs && ($entry_directory || $entry_link_to_directory)} {
continue
} elseif {$entry_directory} {
#consider all directories to be executable for now - as this what TCL glob does on windows.
#consider all directories to be executable for now - as this what TCL glob does on windows.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
if {$skip_dirs} {
#if {!$entry_reparse_point} {
continue
}
if {!$entry_reparse_point} {
lappend dirs $fullname
lappend dirs $fullname
#set ftype "d"
#set ftype "d"
set do_sizes $do_sizes_d
set do_sizes $do_sizes_d
set do_times $do_times_d
set do_times $do_times_d
} else {
#} else {
#other mechanisms can't immediately classify a link as file vs directory - so we don't return this info in the main dirs/files collections
# dict set linkdata target_type directory
dict set linkdata target_type directory
#}
}
}
}
if {!$entry_reparse_point && !$entry_directory} {
if {$entry_link_to_file || (!$entry_reparse_point && !$entry_directory)} {
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
if {$skip_files} {
if {$skip_files} {
continue
continue
@ -1620,9 +1641,6 @@ namespace eval punk::du {
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
]
]
}
}
#if {[dict size $linkdata]} {
# dict set linkinfo $fullname $linkdata
#}
if {[llength $linkdata]} {
if {[llength $linkdata]} {
dict set linkinfo $fullname $linkdata
dict set linkinfo $fullname $linkdata
}
}
@ -1686,14 +1704,17 @@ namespace eval punk::du {
}
}
return $vfsmounts
return $vfsmounts
}
}
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
proc file_join_one {base newtail} {
proc file_join_one {base newtail} {
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
#note base could be c: or c:/
# we need to be careful not to introduce extra slashes - file join should already do the right thing.
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results - apparently by design." level warning]
}
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
}
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results" level medium]
}
}
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
lappend d1_overrides italic bold
lappend d1_overrides italic bold
}
}
#if {$d in $vfsmounts} {
#dlink_style & dshortcut_style are for underlines - can be added with colours already set
# if {$d in $flaggedhidden} {
# #we could have a hidden dir which is also a vfs.. colour will be overridden giving no indication of 'hidden' status - REVIEW
# #(This situation encountered on windows - even though file attr showed -hidden 0 - the glob with -types hidden returned it.. possibly a tcl glob bug on windows)
# #mark it differently for now.. (todo bug report?)
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red Yellow bold]
# } else {
# set d1 [punk::ansi::a+ green Purple bold]
# }
# } else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red White bold]
# } else {
# set d1 [punk::ansi::a+ green bold]
# }
# }
#} else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red bold]
# }
#}
#dlink-style & dshortcut_style are for underlines - can be added with colours already set
#For example if we launch mintty from within punk, it will pick this up and then launch the new mintty with this shell. seems reasonable.
#some terminals launched from within punk will ignore this - but maintain the value: e.g tabby, rio
#others might ignore it but also clear or not pass it e.g wt, wezterm
#terminals that ignore it are presumably using a stored default shell from their own config.
#shell programs such as cmd.exe, powershell.exe seem to maintain the env variable if launched from within punk.
#we will respect the existing env(SHELL) if it is set
#- as that is the standard way to indicate the user's preferred shell - but if it isn't set, we'll set it to the current executable.
#This allows child processes launched from the shell to pick up on the fact they are running in a shell environment, and also allows nested shells to work correctly.
#review - what about the args the current shell was launched with?
set ::env(SHELL) [file normalize [info nameofexecutable]]
}
}
if {![info exists ::env(TERM)]} {
if {![info exists ::env(TERM)]} {
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#REVIEW! windows api pattern match https://www.red-gate.com/simple-talk/blogs/the-unexpected-behaviour-of-directoryinfo-getfiles-with-three-letter-extensions is .. weird. partly due to 8.3 filenames
#review - and see which if any actually belong in the links key of our return
#review - and see which if any actually belong in the links key of our return
if {$skip_links} {
continue
}
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#One thing it could be, is a 'mounted folder' https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
#
#
@ -1539,41 +1546,55 @@ namespace eval punk::du {
#
#
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#Note also - a shortcut created in explorer with drag and drop to an existant folder is a different animal to a symlink (file with .lnk extension) even though it looks the same in explorer window.
#
#
#links are techically files too, whether they point to a file/dir or nothing.
#--------------------------------------
#review
#for consistency with tcl glob - we can't skip - it may point to a file or directory.
#--------------------------------------
if {!$entry_directory} {
if {!$entry_directory} {
#review - other attributes? will we see a link to a link here?
set entry_link_to_file 1
dict set linkdata target_type file
dict set linkdata target_type file
} else {
} else {
set entry_link_to_directory 1
dict set linkdata target_type directory
dict set linkdata target_type directory
}
}
lappend links $fullname
#review - other attributes? will we see a link to a link here?
#set ftype "l"
#this branch will never be taken as we're currently setting either entry_link_to_file or entry_link_to_directory
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
#dict set linkdata reparseinfo [dict get $attrdict -reparseinfo]
dict set linkdata reparseinfo $entry_reparse_info
dict set linkdata reparseinfo $entry_reparse_info
}
}
}
}
if {$entry_directory} {
set do_sizes $do_sizes_l
set do_times $do_times_l
}
if {$skip_dirs && ($entry_directory || $entry_link_to_directory)} {
continue
} elseif {$entry_directory} {
#consider all directories to be executable for now - as this what TCL glob does on windows.
#consider all directories to be executable for now - as this what TCL glob does on windows.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
#review - should check ACLS if 'x' type is given, as seems to be done on unix.
if {$skip_dirs} {
#if {!$entry_reparse_point} {
continue
}
if {!$entry_reparse_point} {
lappend dirs $fullname
lappend dirs $fullname
#set ftype "d"
#set ftype "d"
set do_sizes $do_sizes_d
set do_sizes $do_sizes_d
set do_times $do_times_d
set do_times $do_times_d
} else {
#} else {
#other mechanisms can't immediately classify a link as file vs directory - so we don't return this info in the main dirs/files collections
# dict set linkdata target_type directory
dict set linkdata target_type directory
#}
}
}
}
if {!$entry_reparse_point && !$entry_directory} {
if {$entry_link_to_file || (!$entry_reparse_point && !$entry_directory)} {
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
#review - is anything that isn't a reparse_point or a directory, some sort of 'file' in this context? What about the 'device' attribute? Can that occur in a directory listing of some sort?
if {$skip_files} {
if {$skip_files} {
continue
continue
@ -1620,9 +1641,6 @@ namespace eval punk::du {
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
m [twapi::large_system_time_to_secs_since_1970 [dict get $iteminfo mtime]]\
]
]
}
}
#if {[dict size $linkdata]} {
# dict set linkinfo $fullname $linkdata
#}
if {[llength $linkdata]} {
if {[llength $linkdata]} {
dict set linkinfo $fullname $linkdata
dict set linkinfo $fullname $linkdata
}
}
@ -1686,14 +1704,17 @@ namespace eval punk::du {
}
}
return $vfsmounts
return $vfsmounts
}
}
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
proc file_join_one {base newtail} {
proc file_join_one {base newtail} {
#work around the horrible tilde-expansion thing (not needed for tcl 9+)
#note base could be c: or c:/
# we need to be careful not to introduce extra slashes - file join should already do the right thing.
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results - apparently by design." level warning]
}
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
#possibly related anomaly is that a returned result with case that doesn't match that of the file in the underlying filesystem can't be normalized
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
# to the correct case without doing some sort of string manipulation on the result such as 'string range $f 0 end' to affect the internal representation.
}
return [dict create bug $bug bugref 108904173c description "glob with patterns on windows can return inconsistently cased results" level medium]
}
}
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#todo: it would be nice to test for the other portion of issue 108904173c - that on unix with a mounted case-insensitive filesystem we get other inconsistencies.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
#lappend d1_overrides underline undt-red ;#we use underlins to indicate symlinks and shortcuts, so we shouldn't use underlines here if possible.
lappend d1_overrides italic bold
lappend d1_overrides italic bold
}
}
#if {$d in $vfsmounts} {
#dlink_style & dshortcut_style are for underlines - can be added with colours already set
# if {$d in $flaggedhidden} {
# #we could have a hidden dir which is also a vfs.. colour will be overridden giving no indication of 'hidden' status - REVIEW
# #(This situation encountered on windows - even though file attr showed -hidden 0 - the glob with -types hidden returned it.. possibly a tcl glob bug on windows)
# #mark it differently for now.. (todo bug report?)
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red Yellow bold]
# } else {
# set d1 [punk::ansi::a+ green Purple bold]
# }
# } else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red White bold]
# } else {
# set d1 [punk::ansi::a+ green bold]
# }
# }
#} else {
# if {$d in $nonportable} {
# set d1 [punk::ansi::a+ red bold]
# }
#}
#dlink-style & dshortcut_style are for underlines - can be added with colours already set
#For example if we launch mintty from within punk, it will pick this up and then launch the new mintty with this shell. seems reasonable.
#some terminals launched from within punk will ignore this - but maintain the value: e.g tabby, rio
#others might ignore it but also clear or not pass it e.g wt, wezterm
#terminals that ignore it are presumably using a stored default shell from their own config.
#shell programs such as cmd.exe, powershell.exe seem to maintain the env variable if launched from within punk.
#we will respect the existing env(SHELL) if it is set
#- as that is the standard way to indicate the user's preferred shell - but if it isn't set, we'll set it to the current executable.
#This allows child processes launched from the shell to pick up on the fact they are running in a shell environment, and also allows nested shells to work correctly.
#review - what about the args the current shell was launched with?
set ::env(SHELL) [file normalize [info nameofexecutable]]
}
}
if {![info exists ::env(TERM)]} {
if {![info exists ::env(TERM)]} {
# tset -r seems to rely on env(TERM) - so this doesn't seem to work
# tset -r seems to rely on env(TERM) - so this doesn't seem to work