1 """Common operations on DOS pathnames."""
8 """Normalize the case of a pathname.
9 On MS-DOS it maps the pathname to lowercase, turns slashes into
11 Other normalizations (such as optimizing '../' away) are not allowed
12 (this is done by normpath).
13 Previously, this version mapped invalid consecutive characters to a
14 single '_', but this has been removed. This functionality should
15 possibly be added as a new function."""
17 return s
.replace("/", "\\").lower()
21 """Return whether a path is absolute.
22 Trivial in Posix, harder on the Mac or MS-DOS.
23 For DOS it is absolute if it starts with a slash or backslash (current
24 volume), or if a pathname after the volume letter and colon starts with
25 a slash or backslash."""
28 return s
!= '' and s
[:1] in '/\\'
32 """Join two (or more) paths."""
38 elif path
== '' or path
[-1:] in '/\\:':
41 path
= path
+ "\\" + b
46 """Split a path into a drive specification (a drive letter followed
47 by a colon) and path specification.
48 It is always true that drivespec + pathspec == p."""
56 """Split a path into head (everything up to the last '/') and tail
57 (the rest). After the trailing '/' is stripped, the invariant
58 join(head, tail) == p holds.
59 The resulting head won't end in '/' unless it is the root."""
62 # set i to index beyond p's last slash
64 while i
and p
[i
-1] not in '/\\':
66 head
, tail
= p
[:i
], p
[i
:] # now tail has no slashes
67 # remove trailing slashes from head, unless it's all slashes
69 while head2
and head2
[-1] in '/\\':
76 """Split a path into root and extension.
77 The extension is everything starting at the first dot in the last
78 pathname component; the root is everything before that.
79 It is always true that root + ext == p."""
84 root
, ext
= root
+ ext
+ c
, ''
93 """Return the tail (basename) part of a path."""
99 """Return the head (dirname) part of a path."""
105 """Return the longest prefix of all list elements."""
110 for i
in range(len(prefix
)):
111 if prefix
[:i
+1] <> item
[:i
+1]:
118 # Get size, mtime, atime of files.
120 def getsize(filename
):
121 """Return the size of a file, reported by os.stat()."""
122 st
= os
.stat(filename
)
123 return st
[stat
.ST_SIZE
]
125 def getmtime(filename
):
126 """Return the last modification time of a file, reported by os.stat()."""
127 st
= os
.stat(filename
)
128 return st
[stat
.ST_MTIME
]
130 def getatime(filename
):
131 """Return the last access time of a file, reported by os.stat()."""
132 st
= os
.stat(filename
)
133 return st
[stat
.ST_ATIME
]
137 """Is a path a symbolic link?
138 This will always return false on systems where posix.lstat doesn't exist."""
144 """Does a path exist?
145 This is false for dangling symbolic links."""
155 """Is a path a dos directory?"""
161 return stat
.S_ISDIR(st
[stat
.ST_MODE
])
165 """Is a path a regular file?"""
171 return stat
.S_ISREG(st
[stat
.ST_MODE
])
175 """Is a path a mount point?"""
176 # XXX This degenerates in: 'is this the root?' on DOS
178 return isabs(splitdrive(path
)[1])
181 def walk(top
, func
, arg
):
182 """Directory tree walk.
183 For each directory under top (including top itself, but excluding
184 '.' and '..'), func(arg, dirname, filenames) is called, where
185 dirname is the name of the directory and filenames is the list
186 files files (and subdirectories etc.) in the directory.
187 The func may modify the filenames list, to implement a filter,
188 or to impose a different order of visiting."""
191 names
= os
.listdir(top
)
194 func(arg
, top
, names
)
195 exceptions
= ('.', '..')
197 if name
not in exceptions
:
198 name
= join(top
, name
)
200 walk(name
, func
, arg
)
203 def expanduser(path
):
204 """Expand paths beginning with '~' or '~user'.
205 '~' means $HOME; '~user' means that user's home directory.
206 If the path doesn't begin with '~', or if the user or $HOME is unknown,
207 the path is returned unchanged (leaving error reporting to whatever
208 function is called with the expanded path as argument).
209 See also module 'glob' for expansion of *, ? and [...] in pathnames.
210 (A function should also be defined to do full *sh-style environment
211 variable expansion.)"""
216 while i
< n
and path
[i
] not in '/\\':
219 if not os
.environ
.has_key('HOME'):
221 userhome
= os
.environ
['HOME']
224 return userhome
+ path
[i
:]
227 def expandvars(path
):
228 """Expand paths containing shell variable substitutions.
229 The following rules apply:
230 - no expansion within single quotes
231 - no escape character, except for '$$' which is translated into '$'
232 - ${varname} is accepted.
233 - varnames can be made out of letters, digits and the character '_'"""
234 # XXX With COMMAND.COM you can use any characters in a variable name,
235 # XXX except '^|<>='.
240 varchars
= string
.letters
+ string
.digits
+ '_-'
244 while index
< pathlen
:
246 if c
== '\'': # no expansion within single quotes
247 path
= path
[index
+ 1:]
250 index
= path
.index('\'')
251 res
= res
+ '\'' + path
[:index
+ 1]
255 elif c
== '$': # variable or '$$'
256 if path
[index
+ 1:index
+ 2] == '$':
259 elif path
[index
+ 1:index
+ 2] == '{':
260 path
= path
[index
+2:]
263 index
= path
.index('}')
265 if os
.environ
.has_key(var
):
266 res
= res
+ os
.environ
[var
]
273 c
= path
[index
:index
+ 1]
274 while c
!= '' and c
in varchars
:
277 c
= path
[index
:index
+ 1]
278 if os
.environ
.has_key(var
):
279 res
= res
+ os
.environ
[var
]
289 """Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
290 Also, components of the path are silently truncated to 8+3 notation."""
292 path
= path
.replace("/", "\\")
293 prefix
, path
= splitdrive(path
)
294 while path
[:1] == "\\":
295 prefix
= prefix
+ "\\"
297 comps
= path
.split("\\")
299 while i
< len(comps
):
302 elif comps
[i
] == '..' and i
> 0 and \
303 comps
[i
-1] not in ('', '..'):
306 elif comps
[i
] == '' and i
> 0 and comps
[i
-1] <> '':
308 elif '.' in comps
[i
]:
309 comp
= comps
[i
].split('.')
310 comps
[i
] = comp
[0][:8] + '.' + comp
[1][:3]
312 elif len(comps
[i
]) > 8:
313 comps
[i
] = comps
[i
][:8]
317 # If the path is now empty, substitute '.'
318 if not prefix
and not comps
:
320 return prefix
+ "\\".join(comps
)
325 """Return an absolute path."""
327 path
= join(os
.getcwd(), path
)
328 return normpath(path
)