9
9
* Biological Structures at Stanford, funded under the NIH Roadmap for *
10
10
* Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11
11
* *
12
- * Portions copyright (c) 2009-12 Stanford University and the Authors. *
13
- * Authors: Michael Sherman *
12
+ * Portions copyright (c) 2009-15 Stanford University and the Authors. *
13
+ * Authors: Michael Sherman, Carmichael Ong *
14
14
* Contributors: *
15
15
* *
16
16
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
@@ -41,7 +41,7 @@ namespace SimTK {
41
41
* of three components:
42
42
* <pre> [directory] [filename [extension]] </pre>
43
43
* where the directory may be an absolute location or relative to a
44
- * current working directory.
44
+ * current working directory or specified working directory .
45
45
*
46
46
* Several special directory names are supported here:
47
47
* - root (/)
@@ -84,6 +84,9 @@ namespace SimTK {
84
84
* a backslash; on other platforms the canonicalized name will always
85
85
* begin with a forward slash.
86
86
*
87
+ * @bug Eliminating ".." segments textually can cause them to behave incorrectly
88
+ * in the presence of symbolic links. These should probably be left in
89
+ * place with evaluation deferred.
87
90
*/
88
91
class SimTK_SimTKCOMMON_EXPORT Pathname {
89
92
public:
@@ -127,7 +130,7 @@ class SimTK_SimTKCOMMON_EXPORT Pathname {
127
130
// / in the directory are changed to the appropriate slash
128
131
// / for the currently running platform (i.e. backslash for
129
132
// / Windows and forward slash everywhere else).
130
- static void deconstructPathname ( const std::string& name ,
133
+ static void deconstructPathname ( const std::string& pathname ,
131
134
bool & dontApplySearchPath,
132
135
std::string& directory,
133
136
std::string& fileName,
@@ -146,33 +149,33 @@ class SimTK_SimTKCOMMON_EXPORT Pathname {
146
149
// / - If the swd is empty (after removing whitespace), deconstructPathname()
147
150
// / is called, and cwd is prepended if needed to make it an absolute path.
148
151
// / - Otherwise, we evaluate path relative to the swd. These steps are as follows:
149
- // / 1) If path is a root-relative path name (and on Windows this includes a drive)
150
- // / (e.g. /usr/file.ext or c:/documents/file.ext), then swd is ignored, and the
151
- // / absolute path is returned.
152
- // / 2) Preprocess the swd. This means that if the swd is of any form that denotes
153
- // / an absolute path (i.e. "C:/file.ext", "C:file.ext", "./file.ext", "/file.ext")
154
- // / we change the swd to reflect the absolute path (e.g. "./file.ext" may change
155
- // / to "/cwd/file.ext" or "C:/cwdOnC/file.ext").
156
- // / 3) Otherwise, if a path is given relative to a directory that is not the root
157
- // / (e.g. "./dir/file.ext" or "dir/file.ext"), then the swd is prepended to path.
158
- // / 4) To resolve drive ambiguities, if swd provides a drive, it is used. If not,
159
- // / then the path drive is used. If neither provides a drive, then the current
160
- // / drive is used.
152
+ // / 1. If path is an absolute path name (and on Windows this includes a drive)
153
+ // / (e.g. /usr/file.ext or c:/documents/file.ext), then swd is ignored, and the
154
+ // / absolute path is returned.
155
+ // / 2. Preprocess the swd. This means that if the swd is of any form that denotes
156
+ // / an absolute path (i.e. "C:/file.ext", "C:file.ext", "./file.ext", "/file.ext")
157
+ // / we change the swd to reflect the absolute path (e.g. "./file.ext" may change
158
+ // / to "/cwd/file.ext" or "C:/cwdOnC/file.ext").
159
+ // / 3. Otherwise, if a path is given relative to a directory that is not the root
160
+ // / (e.g. "./dir/file.ext" or "dir/file.ext"), then the swd is prepended to path.
161
+ // / 4. To resolve drive ambiguities, if swd provides a drive, it is used. If not,
162
+ // / then the path drive is used. If neither provides a drive, then the current
163
+ // / drive is used.
161
164
static void deconstructPathnameUsingSpecifiedWorkingDirectory (const std::string& swd,
162
- const std::string& path ,
165
+ const std::string& pathname ,
163
166
std::string& directory,
164
167
std::string& fileName,
165
168
std::string& extension);
166
169
167
170
// / Give back the deconstructed canonicalized absolute pathname for a given path.
168
171
// / If the path is not an absolute path, it will be made into an absolute path first
169
172
// / following the rules of deconstructPathname() (which it uses).
170
- static void deconstructAbsolutePathname (const std::string& path ,
173
+ static void deconstructAbsolutePathname (const std::string& pathname ,
171
174
std::string& directory,
172
175
std::string& fileName,
173
176
std::string& extension) {
174
177
bool dontApplySearchPath;
175
- deconstructPathname (path , dontApplySearchPath, directory, fileName, extension);
178
+ deconstructPathname (pathname , dontApplySearchPath, directory, fileName, extension);
176
179
if (!dontApplySearchPath)
177
180
directory = getCurrentWorkingDirectory () + directory;
178
181
}
@@ -210,25 +213,46 @@ class SimTK_SimTKCOMMON_EXPORT Pathname {
210
213
return absPath;
211
214
}
212
215
213
- static std::string findAbsolutePathnameUsingSpecifiedWorkingDirectory (const std::string& swd,
214
- const std::string& path) {
216
+ // / Same as getAbsolutePathname() but using a specified working directory
217
+ // / rather than the current working directory. See
218
+ // / deconstructPathnameUsingSpecifiedWorkingDirectory() for subtleties.
219
+ static std::string getAbsolutePathnameUsingSpecifiedWorkingDirectory
220
+ (const std::string& swd, const std::string& pathname) {
215
221
std::string directory, fileName, extension;
216
- deconstructPathnameUsingSpecifiedWorkingDirectory (swd, path, directory, fileName, extension);
222
+ deconstructPathnameUsingSpecifiedWorkingDirectory
223
+ (swd, pathname, directory, fileName, extension);
217
224
return directory + fileName + extension;
218
225
}
219
226
227
+ // / Same as getAbsoluteDirectoryPathname() but using a specified working
228
+ // / directory rather than the current working directory. See
229
+ // / deconstructPathnameUsingSpecifiedWorkingDirectory() for subtleties.
230
+ static std::string
231
+ getAbsoluteDirectoryPathnameUsingSpecifiedWorkingDirectory
232
+ (const std::string& swd, const std::string& dirPathname) {
233
+ std::string absPath =
234
+ getAbsolutePathnameUsingSpecifiedWorkingDirectory (swd, dirPathname);
235
+ if (!absPath.empty () && absPath[absPath.size ()-1 ] != getPathSeparatorChar ())
236
+ absPath += getPathSeparatorChar ();
237
+ return absPath;
238
+ }
239
+
220
240
// / Return true if the given pathname names a file that exists and is
221
241
// / readable.
222
- static bool fileExists (const std::string& fileName );
242
+ static bool fileExists (const std::string& pathname );
223
243
224
244
// / Get the default installation directory for this platform. This will
225
245
// / be /usr/local/ for Linux and Apple, and the value of the \%ProgramFiles\%
226
246
// / registry entry on Windows (typically c:\\Program Files\\).
227
247
static std::string getDefaultInstallDir ();
228
248
229
249
// / Append a subdirectory offset to an existing pathname (relative or absolute).
230
- // / A leading "/" in the offset is ignored, and the result ends in "/".
231
- static std::string addDirectoryOffset (const std::string& base, const std::string& offset);
250
+ // / A single slash will be inserted in between, ignoring any slash at the
251
+ // / end of `base` or start of `offset`, and the result will end with a
252
+ // / slash. All slashes in the result will be the correct ones for the
253
+ // / current platform.
254
+ static std::string addDirectoryOffset (const std::string& base,
255
+ const std::string& offset);
232
256
233
257
// / Find the installation directory for something, using the named
234
258
// / installation directory environment variable if it exists, otherwise
0 commit comments