riscospath.py revision 83eeef4b067b7182778581c9fdfb104492647bd4
1228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Module 'riscospath' -- common operations on RISC OS pathnames.
2228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
3228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# contributed by Andrew Clover  ( andrew@oaktree.co.uk )
4228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
5228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# The "os.path" name is an alias for this module on RISC OS systems;
6228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# on other systems (e.g. Mac, Windows), os.path provides the same
7228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# operations in a manner specific to that platform, and is an alias
8228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# to another module (e.g. macpath, ntpath).
9228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
10228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum"""
11228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van RossumInstead of importing this module directly, import os and refer to this module
12228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumas os.path.
13228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum"""
14228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
15228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
16228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Imports - make an error-generating swi object if the swi module is not
17228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# available (ie. we are not running on RISC OS Python)
18228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
19228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumimport os, stat, string
20228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
21228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumtry:
22683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    import swi
23228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumexcept ImportError:
24683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    class _swi:
25683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        def swi(*a):
26683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            raise AttributeError, 'This function only available under RISC OS'
27683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        block= swi
28683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    swi= _swi()
29228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
30228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum[_false, _true]= range(2)
31228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
32228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum_roots= ['$', '&', '%', '@', '\\']
33228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
34228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
35228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# _allowMOSFSNames
36228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# After importing riscospath, set _allowMOSFSNames true if you want the module
37228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# to understand the "-SomeFS-" notation left over from the old BBC Master MOS,
38228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# as well as the standard "SomeFS:" notation. Set this to be fully backwards
39228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# compatible but remember that "-SomeFS-" can also be a perfectly valid file
40228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# name so care must be taken when splitting and joining paths.
41228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
42228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum_allowMOSFSNames= _false
43228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
44228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
45228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum## Path manipulation, RISC OS stylee.
46228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
47228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef _split(p):
48683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
49683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  split filing system name (including special field) and drive specifier from rest
50683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  of path. This is needed by many riscospath functions.
51228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
52683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    dash= _allowMOSFSNames and p[:1]=='-'
53683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if dash:
54683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        q= string.find(p, '-', 1)+1
55683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    else:
56683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if p[:1]==':':
57683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            q= 0
58683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        else:
59683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            q= string.find(p, ':')+1 # q= index of start of non-FS portion of path
60683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    s= string.find(p, '#')
61683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if s==-1 or s>q:
62683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        s= q # find end of main FS name, not including special field
63228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum    else:
64683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        for c in p[dash:s]:
6579e75e1916c33ee8e3de4c1b6c38221f2dba315cFred Drake            if c not in string.ascii_letters:
66683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                q= 0
67683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                break # disallow invalid non-special-field characters in FS name
68683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    r= q
69683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if p[q:q+1]==':':
70683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        r= string.find(p, '.', q+1)+1
71683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if r==0:
72683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            r= len(p) # find end of drive name (if any) following FS name (if any)
73683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return (p[:q], p[q:r], p[r:])
74228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
75228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
76228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef normcase(p):
77683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
78683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Normalize the case of a pathname. This converts to lowercase as the native RISC
79683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  OS filesystems are case-insensitive. However, not all filesystems have to be,
80683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  and there's no simple way to find out what type an FS is argh.
81228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
82683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return string.lower(p)
83228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
84228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
85228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef isabs(p):
86683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
87683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Return whether a path is absolute. Under RISC OS, a file system specifier does
88683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  not make a path absolute, but a drive name or number does, and so does using the
89683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  symbol for root, URD, library, CSD or PSD. This means it is perfectly possible
90683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  to have an "absolute" URL dependent on the current working directory, and
91683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  equally you can have a "relative" URL that's on a completely different device to
92683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  the current one argh.
93228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
94683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    (fs, drive, path)= _split(p)
95683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return drive!='' or path[:1] in _roots
96228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
97228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
98228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef join(a, *p):
99683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
100683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Join path elements with the directory separator, replacing the entire path when
101683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  an absolute or FS-changing path part is found.
102228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
103683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    j= a
104683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    for b in p:
105683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        (fs, drive, path)= _split(b)
106683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if fs!='' or drive!='' or path[:1] in _roots:
107683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            j= b
108683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        else:
109683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            j= j+'.'+b
110683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return j
111228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
112228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
113228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef split(p):
114683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
115683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Split a path in head (everything up to the last '.') and tail (the rest). FS
116683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  name must still be dealt with separately since special field may contain '.'.
117228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
118683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    (fs, drive, path)= _split(p)
119683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    q= string.rfind(path, '.')
120683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if q!=-1:
121683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return (fs+drive+path[:q], path[q+1:])
122683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return ('', p)
123228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
124228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
125228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef splitext(p):
126683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
127683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Split a path in root and extension. This assumes the 'using slash for dot and
128683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  dot for slash with foreign files' convention common in RISC OS is in force.
129228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
130683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    (tail, head)= split(p)
131683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if '/' in head:
132683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        q= len(head)-string.rfind(head, '/')
133683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return (p[:-q], p[-q:])
134683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return (p, '')
135228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
136228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
137228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef splitdrive(p):
138683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
139683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Split a pathname into a drive specification (including FS name) and the rest of
140683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  the path. The terminating dot of the drive name is included in the drive
141683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  specification.
142228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
143683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    (fs, drive, path)= _split(p)
144683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return (fs+drive, p)
145228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
146228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
147228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef basename(p):
148683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
149683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Return the tail (basename) part of a path.
150228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
151683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return split(p)[1]
152228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
153228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
154228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef dirname(p):
155683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
156683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Return the head (dirname) part of a path.
157228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
158683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return split(p)[0]
159228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
160228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
161228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef commonprefix(ps):
162683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
163683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Return the longest prefix of all list elements. Purely string-based; does not
164683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  separate any path parts. Why am I in os.path?
165228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
166683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if len(ps)==0:
167683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return ''
168683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    prefix= ps[0]
169683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    for p in ps[1:]:
170683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        prefix= prefix[:len(p)]
171683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        for i in range(len(prefix)):
172683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            if prefix[i] <> p[i]:
173683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                prefix= prefix[:i]
174683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                if i==0:
175683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                    return ''
176683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                break
177683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return prefix
178228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
179228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
180228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum## File access functions. Why are we in os.path?
181228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
182228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef getsize(p):
183683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
184683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Return the size of a file, reported by os.stat().
185228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
186683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    st= os.stat(p)
187683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return st[stat.ST_SIZE]
188228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
189228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
190228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef getmtime(p):
191683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
192683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Return the last modification time of a file, reported by os.stat().
193228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
194683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    st = os.stat(p)
195683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return st[stat.ST_MTIME]
196228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
197228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumgetatime= getmtime
198228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
199228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
200228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# RISC OS-specific file access functions
201228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
202228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef exists(p):
203683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
204683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Test whether a path exists.
205228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
206683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    try:
207683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return swi.swi('OS_File', '5s;i', p)!=0
208683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    except swi.error:
209683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return 0
210228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
211228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
212228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef isdir(p):
213683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
214683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Is a path a directory? Includes image files.
215228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
216683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    try:
217683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return swi.swi('OS_File', '5s;i', p) in [2, 3]
218683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    except swi.error:
219683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return 0
220228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
221228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
222228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef isfile(p):
223683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
224683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Test whether a path is a file, including image files.
225228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
226683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    try:
227683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return swi.swi('OS_File', '5s;i', p) in [1, 3]
228683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    except swi.error:
229683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return 0
230228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
231228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
232228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef islink(p):
233683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
234683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  RISC OS has no links or mounts.
235228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
236683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return _false
237228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
238228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumismount= islink
239228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
240228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
241228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Same-file testing.
242228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
243228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# samefile works on filename comparison since there is no ST_DEV and ST_INO is
244228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# not reliably unique (esp. directories). First it has to normalise the
245228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# pathnames, which it can do 'properly' using OS_FSControl since samefile can
246228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# assume it's running on RISC OS (unlike normpath).
247228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
248228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef samefile(fa, fb):
249683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
250683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Test whether two pathnames reference the same actual file.
251228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
252683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    l= 512
253683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    b= swi.block(l)
254683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    swi.swi('OS_FSControl', 'isb..i', 37, fa, b, l)
255683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    fa= b.ctrlstring()
256683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    swi.swi('OS_FSControl', 'isb..i', 37, fb, b, l)
257683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    fb= b.ctrlstring()
258683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return fa==fb
259228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
260228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
261228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef sameopenfile(a, b):
262683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
263683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Test whether two open file objects reference the same file.
264228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
265683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return os.fstat(a)[stat.ST_INO]==os.fstat(b)[stat.ST_INO]
266228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
267228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
268228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum## Path canonicalisation
269228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
270228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# 'user directory' is taken as meaning the User Root Directory, which is in
271228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# practice never used, for anything.
272228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
273228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef expanduser(p):
274683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    (fs, drive, path)= _split(p)
275683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    l= 512
276683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    b= swi.block(l)
277683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters
278683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if path[:1]!='@':
279683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return p
280683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    if fs=='':
281683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        fsno= swi.swi('OS_Args', '00;i')
282683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        swi.swi('OS_FSControl', 'iibi', 33, fsno, b, l)
283683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        fsname= b.ctrlstring()
284228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum    else:
285683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if fs[:1]=='-':
286683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            fsname= fs[1:-1]
287683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        else:
288683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            fsname= fs[:-1]
289683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        fsname= string.split(fsname, '#', 1)[0] # remove special field from fs
290683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    x= swi.swi('OS_FSControl', 'ib2s.i;.....i', 54, b, fsname, l)
291228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum    if x<l:
292683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        urd= b.tostring(0, l-x-1)
293683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    else: # no URD! try CSD
294683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        x= swi.swi('OS_FSControl', 'ib0s.i;.....i', 54, b, fsname, l)
295683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if x<l:
296683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            urd= b.tostring(0, l-x-1)
297683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        else: # no CSD! use root
298683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            urd= '$'
299683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return fsname+':'+urd+path[1:]
300228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
301228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Environment variables are in angle brackets.
302228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
303228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef expandvars(p):
304683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
305683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Expand environment variables using OS_GSTrans.
306228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
307683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    l= 512
308683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    b= swi.block(l)
309683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return b.tostring(0, swi.swi('OS_GSTrans', 'sbi;..i', p, b, l))
310228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
311228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
312228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Return an absolute path.
313228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
314228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef abspath(p):
315683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return normpath(join(os.getcwd(), p))
316228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
317228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
31883eeef4b067b7182778581c9fdfb104492647bd4Guido van Rossum# realpath is a no-op on systems without islink support
31983eeef4b067b7182778581c9fdfb104492647bd4Guido van Rossumrealpath = abspath
32083eeef4b067b7182778581c9fdfb104492647bd4Guido van Rossum
32183eeef4b067b7182778581c9fdfb104492647bd4Guido van Rossum
322228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Normalize a path. Only special path element under RISC OS is "^" for "..".
323228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
324228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef normpath(p):
325683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
326683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  Normalize path, eliminating up-directory ^s.
327228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
328683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    (fs, drive, path)= _split(p)
329683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    rhs= ''
330683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    ups= 0
331683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    while path!='':
332683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        (path, el)= split(path)
333683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if el=='^':
334683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            ups= ups+1
335228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum        else:
336683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            if ups>0:
337683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                ups= ups-1
338683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            else:
339683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                if rhs=='':
340683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                    rhs= el
341683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                else:
342683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters                    rhs= el+'.'+rhs
343683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    while ups>0:
344683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        ups= ups-1
345683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        rhs= '^.'+rhs
346683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    return fs+drive+rhs
347228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
348228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
349228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Directory tree walk.
350228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum# Independent of host system. Why am I in os.path?
351228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum
352228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossumdef walk(top, func, arg):
353683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    """
354683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  walk(top,func,args) calls func(arg, d, files) for each directory "d" in the tree
355683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  rooted at "top" (including "top" itself). "files" is a list of all the files and
356683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters  subdirs in directory "d".
357228d80736c39e41a6b46dad211df0ba871b0c8f8Guido van Rossum  """
358683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    try:
359683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        names= os.listdir(top)
360683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    except os.error:
361683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        return
362683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    func(arg, top, names)
363683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters    for name in names:
364683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        name= join(top, name)
365683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters        if isdir(name) and not islink(name):
366683ecc7374fd5ab05b03565b0f1191419fd9ae1aTim Peters            walk(name, func, arg)
367