symbian-qemu-0.9.1-12/python-2.6.1/Lib/ntpath.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 # Module 'ntpath' -- common operations on WinNT/Win95 pathnames
       
     2 """Common pathname manipulations, WindowsNT/95 version.
       
     3 
       
     4 Instead of importing this module directly, import os and refer to this
       
     5 module as os.path.
       
     6 """
       
     7 
       
     8 import os
       
     9 import sys
       
    10 import stat
       
    11 import genericpath
       
    12 import warnings
       
    13 
       
    14 from genericpath import *
       
    15 
       
    16 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
       
    17            "basename","dirname","commonprefix","getsize","getmtime",
       
    18            "getatime","getctime", "islink","exists","lexists","isdir","isfile",
       
    19            "ismount","walk","expanduser","expandvars","normpath","abspath",
       
    20            "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
       
    21            "extsep","devnull","realpath","supports_unicode_filenames","relpath"]
       
    22 
       
    23 # strings representing various path-related bits and pieces
       
    24 curdir = '.'
       
    25 pardir = '..'
       
    26 extsep = '.'
       
    27 sep = '\\'
       
    28 pathsep = ';'
       
    29 altsep = '/'
       
    30 defpath = '.;C:\\bin'
       
    31 if 'ce' in sys.builtin_module_names:
       
    32     defpath = '\\Windows'
       
    33 elif 'os2' in sys.builtin_module_names:
       
    34     # OS/2 w/ VACPP
       
    35     altsep = '/'
       
    36 devnull = 'nul'
       
    37 
       
    38 # Normalize the case of a pathname and map slashes to backslashes.
       
    39 # Other normalizations (such as optimizing '../' away) are not done
       
    40 # (this is done by normpath).
       
    41 
       
    42 def normcase(s):
       
    43     """Normalize case of pathname.
       
    44 
       
    45     Makes all characters lowercase and all slashes into backslashes."""
       
    46     return s.replace("/", "\\").lower()
       
    47 
       
    48 
       
    49 # Return whether a path is absolute.
       
    50 # Trivial in Posix, harder on the Mac or MS-DOS.
       
    51 # For DOS it is absolute if it starts with a slash or backslash (current
       
    52 # volume), or if a pathname after the volume letter and colon / UNC resource
       
    53 # starts with a slash or backslash.
       
    54 
       
    55 def isabs(s):
       
    56     """Test whether a path is absolute"""
       
    57     s = splitdrive(s)[1]
       
    58     return s != '' and s[:1] in '/\\'
       
    59 
       
    60 
       
    61 # Join two (or more) paths.
       
    62 
       
    63 def join(a, *p):
       
    64     """Join two or more pathname components, inserting "\\" as needed.
       
    65     If any component is an absolute path, all previous path components
       
    66     will be discarded."""
       
    67     path = a
       
    68     for b in p:
       
    69         b_wins = 0  # set to 1 iff b makes path irrelevant
       
    70         if path == "":
       
    71             b_wins = 1
       
    72 
       
    73         elif isabs(b):
       
    74             # This probably wipes out path so far.  However, it's more
       
    75             # complicated if path begins with a drive letter:
       
    76             #     1. join('c:', '/a') == 'c:/a'
       
    77             #     2. join('c:/', '/a') == 'c:/a'
       
    78             # But
       
    79             #     3. join('c:/a', '/b') == '/b'
       
    80             #     4. join('c:', 'd:/') = 'd:/'
       
    81             #     5. join('c:/', 'd:/') = 'd:/'
       
    82             if path[1:2] != ":" or b[1:2] == ":":
       
    83                 # Path doesn't start with a drive letter, or cases 4 and 5.
       
    84                 b_wins = 1
       
    85 
       
    86             # Else path has a drive letter, and b doesn't but is absolute.
       
    87             elif len(path) > 3 or (len(path) == 3 and
       
    88                                    path[-1] not in "/\\"):
       
    89                 # case 3
       
    90                 b_wins = 1
       
    91 
       
    92         if b_wins:
       
    93             path = b
       
    94         else:
       
    95             # Join, and ensure there's a separator.
       
    96             assert len(path) > 0
       
    97             if path[-1] in "/\\":
       
    98                 if b and b[0] in "/\\":
       
    99                     path += b[1:]
       
   100                 else:
       
   101                     path += b
       
   102             elif path[-1] == ":":
       
   103                 path += b
       
   104             elif b:
       
   105                 if b[0] in "/\\":
       
   106                     path += b
       
   107                 else:
       
   108                     path += "\\" + b
       
   109             else:
       
   110                 # path is not empty and does not end with a backslash,
       
   111                 # but b is empty; since, e.g., split('a/') produces
       
   112                 # ('a', ''), it's best if join() adds a backslash in
       
   113                 # this case.
       
   114                 path += '\\'
       
   115 
       
   116     return path
       
   117 
       
   118 
       
   119 # Split a path in a drive specification (a drive letter followed by a
       
   120 # colon) and the path specification.
       
   121 # It is always true that drivespec + pathspec == p
       
   122 def splitdrive(p):
       
   123     """Split a pathname into drive and path specifiers. Returns a 2-tuple
       
   124 "(drive,path)";  either part may be empty"""
       
   125     if p[1:2] == ':':
       
   126         return p[0:2], p[2:]
       
   127     return '', p
       
   128 
       
   129 
       
   130 # Parse UNC paths
       
   131 def splitunc(p):
       
   132     """Split a pathname into UNC mount point and relative path specifiers.
       
   133 
       
   134     Return a 2-tuple (unc, rest); either part may be empty.
       
   135     If unc is not empty, it has the form '//host/mount' (or similar
       
   136     using backslashes).  unc+rest is always the input path.
       
   137     Paths containing drive letters never have an UNC part.
       
   138     """
       
   139     if p[1:2] == ':':
       
   140         return '', p # Drive letter present
       
   141     firstTwo = p[0:2]
       
   142     if firstTwo == '//' or firstTwo == '\\\\':
       
   143         # is a UNC path:
       
   144         # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
       
   145         # \\machine\mountpoint\directories...
       
   146         #           directory ^^^^^^^^^^^^^^^
       
   147         normp = normcase(p)
       
   148         index = normp.find('\\', 2)
       
   149         if index == -1:
       
   150             ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
       
   151             return ("", p)
       
   152         index = normp.find('\\', index + 1)
       
   153         if index == -1:
       
   154             index = len(p)
       
   155         return p[:index], p[index:]
       
   156     return '', p
       
   157 
       
   158 
       
   159 # Split a path in head (everything up to the last '/') and tail (the
       
   160 # rest).  After the trailing '/' is stripped, the invariant
       
   161 # join(head, tail) == p holds.
       
   162 # The resulting head won't end in '/' unless it is the root.
       
   163 
       
   164 def split(p):
       
   165     """Split a pathname.
       
   166 
       
   167     Return tuple (head, tail) where tail is everything after the final slash.
       
   168     Either part may be empty."""
       
   169 
       
   170     d, p = splitdrive(p)
       
   171     # set i to index beyond p's last slash
       
   172     i = len(p)
       
   173     while i and p[i-1] not in '/\\':
       
   174         i = i - 1
       
   175     head, tail = p[:i], p[i:]  # now tail has no slashes
       
   176     # remove trailing slashes from head, unless it's all slashes
       
   177     head2 = head
       
   178     while head2 and head2[-1] in '/\\':
       
   179         head2 = head2[:-1]
       
   180     head = head2 or head
       
   181     return d + head, tail
       
   182 
       
   183 
       
   184 # Split a path in root and extension.
       
   185 # The extension is everything starting at the last dot in the last
       
   186 # pathname component; the root is everything before that.
       
   187 # It is always true that root + ext == p.
       
   188 
       
   189 def splitext(p):
       
   190     return genericpath._splitext(p, sep, altsep, extsep)
       
   191 splitext.__doc__ = genericpath._splitext.__doc__
       
   192 
       
   193 
       
   194 # Return the tail (basename) part of a path.
       
   195 
       
   196 def basename(p):
       
   197     """Returns the final component of a pathname"""
       
   198     return split(p)[1]
       
   199 
       
   200 
       
   201 # Return the head (dirname) part of a path.
       
   202 
       
   203 def dirname(p):
       
   204     """Returns the directory component of a pathname"""
       
   205     return split(p)[0]
       
   206 
       
   207 # Is a path a symbolic link?
       
   208 # This will always return false on systems where posix.lstat doesn't exist.
       
   209 
       
   210 def islink(path):
       
   211     """Test for symbolic link.
       
   212     On WindowsNT/95 and OS/2 always returns false
       
   213     """
       
   214     return False
       
   215 
       
   216 # alias exists to lexists
       
   217 lexists = exists
       
   218 
       
   219 # Is a path a mount point?  Either a root (with or without drive letter)
       
   220 # or an UNC path with at most a / or \ after the mount point.
       
   221 
       
   222 def ismount(path):
       
   223     """Test whether a path is a mount point (defined as root of drive)"""
       
   224     unc, rest = splitunc(path)
       
   225     if unc:
       
   226         return rest in ("", "/", "\\")
       
   227     p = splitdrive(path)[1]
       
   228     return len(p) == 1 and p[0] in '/\\'
       
   229 
       
   230 
       
   231 # Directory tree walk.
       
   232 # For each directory under top (including top itself, but excluding
       
   233 # '.' and '..'), func(arg, dirname, filenames) is called, where
       
   234 # dirname is the name of the directory and filenames is the list
       
   235 # of files (and subdirectories etc.) in the directory.
       
   236 # The func may modify the filenames list, to implement a filter,
       
   237 # or to impose a different order of visiting.
       
   238 
       
   239 def walk(top, func, arg):
       
   240     """Directory tree walk with callback function.
       
   241 
       
   242     For each directory in the directory tree rooted at top (including top
       
   243     itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
       
   244     dirname is the name of the directory, and fnames a list of the names of
       
   245     the files and subdirectories in dirname (excluding '.' and '..').  func
       
   246     may modify the fnames list in-place (e.g. via del or slice assignment),
       
   247     and walk will only recurse into the subdirectories whose names remain in
       
   248     fnames; this can be used to implement a filter, or to impose a specific
       
   249     order of visiting.  No semantics are defined for, or required of, arg,
       
   250     beyond that arg is always passed to func.  It can be used, e.g., to pass
       
   251     a filename pattern, or a mutable object designed to accumulate
       
   252     statistics.  Passing None for arg is common."""
       
   253     warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.")
       
   254     try:
       
   255         names = os.listdir(top)
       
   256     except os.error:
       
   257         return
       
   258     func(arg, top, names)
       
   259     for name in names:
       
   260         name = join(top, name)
       
   261         if isdir(name):
       
   262             walk(name, func, arg)
       
   263 
       
   264 
       
   265 # Expand paths beginning with '~' or '~user'.
       
   266 # '~' means $HOME; '~user' means that user's home directory.
       
   267 # If the path doesn't begin with '~', or if the user or $HOME is unknown,
       
   268 # the path is returned unchanged (leaving error reporting to whatever
       
   269 # function is called with the expanded path as argument).
       
   270 # See also module 'glob' for expansion of *, ? and [...] in pathnames.
       
   271 # (A function should also be defined to do full *sh-style environment
       
   272 # variable expansion.)
       
   273 
       
   274 def expanduser(path):
       
   275     """Expand ~ and ~user constructs.
       
   276 
       
   277     If user or $HOME is unknown, do nothing."""
       
   278     if path[:1] != '~':
       
   279         return path
       
   280     i, n = 1, len(path)
       
   281     while i < n and path[i] not in '/\\':
       
   282         i = i + 1
       
   283 
       
   284     if 'HOME' in os.environ:
       
   285         userhome = os.environ['HOME']
       
   286     elif 'USERPROFILE' in os.environ:
       
   287         userhome = os.environ['USERPROFILE']
       
   288     elif not 'HOMEPATH' in os.environ:
       
   289         return path
       
   290     else:
       
   291         try:
       
   292             drive = os.environ['HOMEDRIVE']
       
   293         except KeyError:
       
   294             drive = ''
       
   295         userhome = join(drive, os.environ['HOMEPATH'])
       
   296 
       
   297     if i != 1: #~user
       
   298         userhome = join(dirname(userhome), path[1:i])
       
   299 
       
   300     return userhome + path[i:]
       
   301 
       
   302 
       
   303 # Expand paths containing shell variable substitutions.
       
   304 # The following rules apply:
       
   305 #       - no expansion within single quotes
       
   306 #       - '$$' is translated into '$'
       
   307 #       - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
       
   308 #       - ${varname} is accepted.
       
   309 #       - $varname is accepted.
       
   310 #       - %varname% is accepted.
       
   311 #       - varnames can be made out of letters, digits and the characters '_-'
       
   312 #         (though is not verifed in the ${varname} and %varname% cases)
       
   313 # XXX With COMMAND.COM you can use any characters in a variable name,
       
   314 # XXX except '^|<>='.
       
   315 
       
   316 def expandvars(path):
       
   317     """Expand shell variables of the forms $var, ${var} and %var%.
       
   318 
       
   319     Unknown variables are left unchanged."""
       
   320     if '$' not in path and '%' not in path:
       
   321         return path
       
   322     import string
       
   323     varchars = string.ascii_letters + string.digits + '_-'
       
   324     res = ''
       
   325     index = 0
       
   326     pathlen = len(path)
       
   327     while index < pathlen:
       
   328         c = path[index]
       
   329         if c == '\'':   # no expansion within single quotes
       
   330             path = path[index + 1:]
       
   331             pathlen = len(path)
       
   332             try:
       
   333                 index = path.index('\'')
       
   334                 res = res + '\'' + path[:index + 1]
       
   335             except ValueError:
       
   336                 res = res + path
       
   337                 index = pathlen - 1
       
   338         elif c == '%':  # variable or '%'
       
   339             if path[index + 1:index + 2] == '%':
       
   340                 res = res + c
       
   341                 index = index + 1
       
   342             else:
       
   343                 path = path[index+1:]
       
   344                 pathlen = len(path)
       
   345                 try:
       
   346                     index = path.index('%')
       
   347                 except ValueError:
       
   348                     res = res + '%' + path
       
   349                     index = pathlen - 1
       
   350                 else:
       
   351                     var = path[:index]
       
   352                     if var in os.environ:
       
   353                         res = res + os.environ[var]
       
   354                     else:
       
   355                         res = res + '%' + var + '%'
       
   356         elif c == '$':  # variable or '$$'
       
   357             if path[index + 1:index + 2] == '$':
       
   358                 res = res + c
       
   359                 index = index + 1
       
   360             elif path[index + 1:index + 2] == '{':
       
   361                 path = path[index+2:]
       
   362                 pathlen = len(path)
       
   363                 try:
       
   364                     index = path.index('}')
       
   365                     var = path[:index]
       
   366                     if var in os.environ:
       
   367                         res = res + os.environ[var]
       
   368                     else:
       
   369                         res = res + '${' + var + '}'
       
   370                 except ValueError:
       
   371                     res = res + '${' + path
       
   372                     index = pathlen - 1
       
   373             else:
       
   374                 var = ''
       
   375                 index = index + 1
       
   376                 c = path[index:index + 1]
       
   377                 while c != '' and c in varchars:
       
   378                     var = var + c
       
   379                     index = index + 1
       
   380                     c = path[index:index + 1]
       
   381                 if var in os.environ:
       
   382                     res = res + os.environ[var]
       
   383                 else:
       
   384                     res = res + '$' + var
       
   385                 if c != '':
       
   386                     index = index - 1
       
   387         else:
       
   388             res = res + c
       
   389         index = index + 1
       
   390     return res
       
   391 
       
   392 
       
   393 # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
       
   394 # Previously, this function also truncated pathnames to 8+3 format,
       
   395 # but as this module is called "ntpath", that's obviously wrong!
       
   396 
       
   397 def normpath(path):
       
   398     """Normalize path, eliminating double slashes, etc."""
       
   399     path = path.replace("/", "\\")
       
   400     prefix, path = splitdrive(path)
       
   401     # We need to be careful here. If the prefix is empty, and the path starts
       
   402     # with a backslash, it could either be an absolute path on the current
       
   403     # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
       
   404     # is therefore imperative NOT to collapse multiple backslashes blindly in
       
   405     # that case.
       
   406     # The code below preserves multiple backslashes when there is no drive
       
   407     # letter. This means that the invalid filename \\\a\b is preserved
       
   408     # unchanged, where a\\\b is normalised to a\b. It's not clear that there
       
   409     # is any better behaviour for such edge cases.
       
   410     if prefix == '':
       
   411         # No drive letter - preserve initial backslashes
       
   412         while path[:1] == "\\":
       
   413             prefix = prefix + "\\"
       
   414             path = path[1:]
       
   415     else:
       
   416         # We have a drive letter - collapse initial backslashes
       
   417         if path.startswith("\\"):
       
   418             prefix = prefix + "\\"
       
   419             path = path.lstrip("\\")
       
   420     comps = path.split("\\")
       
   421     i = 0
       
   422     while i < len(comps):
       
   423         if comps[i] in ('.', ''):
       
   424             del comps[i]
       
   425         elif comps[i] == '..':
       
   426             if i > 0 and comps[i-1] != '..':
       
   427                 del comps[i-1:i+1]
       
   428                 i -= 1
       
   429             elif i == 0 and prefix.endswith("\\"):
       
   430                 del comps[i]
       
   431             else:
       
   432                 i += 1
       
   433         else:
       
   434             i += 1
       
   435     # If the path is now empty, substitute '.'
       
   436     if not prefix and not comps:
       
   437         comps.append('.')
       
   438     return prefix + "\\".join(comps)
       
   439 
       
   440 
       
   441 # Return an absolute path.
       
   442 try:
       
   443     from nt import _getfullpathname
       
   444 
       
   445 except ImportError: # not running on Windows - mock up something sensible
       
   446     def abspath(path):
       
   447         """Return the absolute version of a path."""
       
   448         if not isabs(path):
       
   449             path = join(os.getcwd(), path)
       
   450         return normpath(path)
       
   451 
       
   452 else:  # use native Windows method on Windows
       
   453     def abspath(path):
       
   454         """Return the absolute version of a path."""
       
   455 
       
   456         if path: # Empty path must return current working directory.
       
   457             try:
       
   458                 path = _getfullpathname(path)
       
   459             except WindowsError:
       
   460                 pass # Bad path - return unchanged.
       
   461         else:
       
   462             path = os.getcwd()
       
   463         return normpath(path)
       
   464 
       
   465 # realpath is a no-op on systems without islink support
       
   466 realpath = abspath
       
   467 # Win9x family and earlier have no Unicode filename support.
       
   468 supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
       
   469                               sys.getwindowsversion()[3] >= 2)
       
   470 
       
   471 def relpath(path, start=curdir):
       
   472     """Return a relative version of a path"""
       
   473 
       
   474     if not path:
       
   475         raise ValueError("no path specified")
       
   476     start_list = abspath(start).split(sep)
       
   477     path_list = abspath(path).split(sep)
       
   478     if start_list[0].lower() != path_list[0].lower():
       
   479         unc_path, rest = splitunc(path)
       
   480         unc_start, rest = splitunc(start)
       
   481         if bool(unc_path) ^ bool(unc_start):
       
   482             raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
       
   483                                                                 % (path, start))
       
   484         else:
       
   485             raise ValueError("path is on drive %s, start on drive %s"
       
   486                                                 % (path_list[0], start_list[0]))
       
   487     # Work out how much of the filepath is shared by start and path.
       
   488     for i in range(min(len(start_list), len(path_list))):
       
   489         if start_list[i].lower() != path_list[i].lower():
       
   490             break
       
   491     else:
       
   492         i += 1
       
   493 
       
   494     rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
       
   495     if not rel_list:
       
   496         return curdir
       
   497     return join(*rel_list)