fs.tcl 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. # -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
  2. #
  3. # $Id: fs.tcl,v 1.6 2004/03/28 02:44:57 hobbs Exp $
  4. #
  5. # File system routines to handle some file system variations
  6. # and how that interoperates with the Tix widgets (mainly HList).
  7. #
  8. # Copyright (c) 2004 ActiveState
  9. ##
  10. ## Cross-platform
  11. ##
  12. proc tixFSSep {} { return "/" }
  13. proc tixFSNormalize {path} {
  14. # possibly use tixFSTilde ?
  15. return [file normalize $path]
  16. }
  17. proc tixFSVolumes {} {
  18. return [file volumes]
  19. }
  20. proc tixFSAncestors {path} {
  21. return [file split [file normalize $path]]
  22. }
  23. # how a filename should be displayed
  24. proc tixFSDisplayFileName {path} {
  25. if {$path eq [file dirname $path]} {
  26. return $path
  27. } else {
  28. return [file tail $path]
  29. }
  30. }
  31. # dir: Make a listing of this directory
  32. # showSubDir: Want to list the subdirectories?
  33. # showFile: Want to list the non-directory files in this directory?
  34. # showPrevDir: Want to list ".." as well?
  35. # showHidden: Want to list the hidden files?
  36. #
  37. # return value: a list of files and/or subdirectories
  38. #
  39. proc tixFSListDir {dir showSubDir showFile showPrevDir \
  40. showHidden {pattern ""}} {
  41. if {$pattern eq ""} { set pattern [list "*"] }
  42. if {$::tcl_platform(platform) eq "unix"
  43. && $showHidden && $pattern eq "*"} { lappend pattern ".*" }
  44. if {[catch {eval [list glob -nocomplain -directory $dir] \
  45. $pattern} files]} {
  46. # The user has entered an invalid or unreadable directory
  47. # %% todo: prompt error, go back to last succeed directory
  48. return ""
  49. }
  50. set list ""
  51. foreach f [lsort -dictionary $files] {
  52. set tail [file tail $f]
  53. # file tail handles this automatically
  54. #if {[string match ~* $tail]} { set tail ./$tail }
  55. if {[file isdirectory $f]} {
  56. if {$tail eq "."} { continue }
  57. if {$showSubDir} {
  58. if {$tail eq ".." && !$showPrevDir} { continue }
  59. lappend list $tail
  60. }
  61. } else {
  62. if {$showFile} { lappend list $tail }
  63. }
  64. }
  65. return $list
  66. }
  67. # in: internal name
  68. # out: native name
  69. proc tixFSNativeNorm {path} {
  70. return [tixFSNative [tixFSNormalize $path]]
  71. }
  72. # tixFSDisplayName --
  73. #
  74. # Returns the name of a normalized path which is usually displayed by
  75. # the OS
  76. #
  77. proc tixFSDisplayName {path} {
  78. return [tixFSNative $path]
  79. }
  80. proc tixFSTilde {path} {
  81. # verify that paths with leading ~ are files or real users
  82. if {[string match ~* $path]} {
  83. # The following will report if the user doesn't exist
  84. if {![file isdirectory $path]} {
  85. set path ./$path
  86. } else {
  87. set path [file normalize $path]
  88. }
  89. }
  90. return $path
  91. }
  92. proc tixFSJoin {dir sub} {
  93. return [tixFSNative [file join $dir [tixFSTilde $sub]]]
  94. }
  95. proc tixFSNative {path} {
  96. return $path
  97. }
  98. if {$::tcl_platform(platform) eq "windows"} {
  99. ##
  100. ## WINDOWS
  101. ##
  102. # is an absoulte path only if it starts with a baclskash
  103. # or starts with "<drive letter>:"
  104. #
  105. # in: nativeName
  106. #
  107. proc tixFSIsAbsPath {nativeName} {
  108. set ptype [file pathtype $nativename]
  109. return [expr {$ptype eq "absolute" || $ptype eq "volumerelative"}]
  110. }
  111. # tixFSIsValid --
  112. #
  113. # Checks whether a native pathname contains invalid characters.
  114. #
  115. proc tixFSIsValid {path} {
  116. #if {$::tcl_platform(platform) eq "windows"} {set bad "\\/:*?\"<>|\0"}
  117. return 1
  118. }
  119. proc tixFSExternal {path} {
  120. # Avoid normalization on root adding unwanted volumerelative pwd
  121. if {[string match -nocase {[A-Z]:} $path]} {
  122. return $path/
  123. }
  124. return [file normalize $path]
  125. }
  126. proc tixFSInternal {path} {
  127. # Only need to watch for ^[A-Z]:/$, but this does the trick
  128. return [string trimright [file normalize $path] /]
  129. }
  130. } else {
  131. ##
  132. ## UNIX
  133. ##
  134. proc tixFSIsAbsPath {path} {
  135. return [string match {[~/]*} $path]
  136. }
  137. # tixFSIsValid --
  138. #
  139. # Checks whether a native pathname contains invalid characters.
  140. #
  141. proc tixFSIsValid {path} { return 1 }
  142. proc tixFSExternal {path} { return $path }
  143. proc tixFSInternal {path} { return $path }
  144. }