1#!/usr/bin/python
2# Copyright (c) 2012 The Native Client Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6# pathtools is meant to be a drop-in replacement for "os.path"
7#
8# All pathnames passed into the driver are "normalized" to
9# a posix representation (with / as the separator). For example,
10# on Windows, C:\foo\bar.c would become /cygdrive/c/foo/bar.c
11# On all other platforms, pathnames are already in the correct form.
12#
13# This is convenient for two reasons:
14# 1) All of the tools invoked by the driver expect this type
15#    of pathname. (since on Windows, they are compiled with cygwin)
16# 2) Everywhere in the driver, we can assume / is the path separator.
17#
18# Special functions:
19#
20#   pathtools.normalize: Convert an OS-style path into a normalized path
21#   pathtools.tosys    : Convert a normalized path into an OS-style path
22#   pathtools.touser   : Convert a normalized path into a representation
23#                        suitable for presentation to the user.
24
25import os
26import platform
27import posixpath
28
29# This is only true when the driver is invoked on
30# Windows, but outside of Cygwin.
31WINDOWS_MANGLE = 'windows' in platform.system().lower()
32
33def normalize(syspath):
34  """ Convert an input path into a normalized path. """
35
36  if WINDOWS_MANGLE:
37    # Recognize paths which are already normalized.
38    # (Should only happen during recursive driver calls)
39    if '\\' not in syspath:
40      return syspath
41
42    return syspath.replace('\\', '/')
43  else:
44    return syspath
45
46# All functions below expect a normalized path as input
47
48def touser(npath):
49  """ Convert a unix-style path into a user-displayable format """
50  return tosys(npath)
51
52def tosys(npath):
53  """ Convert a normalized path into a system-style path """
54  if WINDOWS_MANGLE:
55    if npath.startswith('/cygdrive'):
56      components = npath.split('/')
57      assert(components[0] == '')
58      assert(len(components[2]) == 1)
59      drive = components[2]
60      components = components[3:]
61      return '%s:\\%s' % (drive.upper(), '\\'.join(components))
62    else:
63      # Work around for an issue that windows has opening long
64      # relative paths.  http://bugs.python.org/issue4071
65      npath = os.path.abspath(unicode(npath))
66      return npath.replace('/', '\\')
67  else:
68    return npath
69
70def join(*args):
71  return posixpath.join(*args)
72
73def exists(npath):
74  return os.path.exists(tosys(npath))
75
76def split(npath):
77  return posixpath.split(npath)
78
79def splitext(npath):
80  return posixpath.splitext(npath)
81
82def basename(npath):
83  return posixpath.basename(npath)
84
85def dirname(npath):
86  return posixpath.dirname(npath)
87
88def abspath(npath):
89  if WINDOWS_MANGLE:
90    # We always use absolute paths for (non-cygwin) windows
91    return npath
92  else:
93    return posixpath.abspath(npath)
94
95def normpath(npath):
96  return posixpath.normpath(npath)
97
98def isdir(npath):
99  return os.path.isdir(tosys(npath))
100
101def isfile(npath):
102  return os.path.isfile(tosys(npath))
103
104def getsize(npath):
105  return os.path.getsize(tosys(npath))
106