Skip to content

Commit 62cb201

Browse files
committed
Merge pull request simbody#372 from simbody/minor-mods-for-Pathname
Minor follow up mods to `Pathname` specified working directory additions
2 parents cef28f4 + d7a60be commit 62cb201

File tree

5 files changed

+194
-132
lines changed

5 files changed

+194
-132
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ This is not a comprehensive list of changes but rather a hand-curated collection
88

99
3.6 (in development)
1010
--------------------
11-
* Added C++11 features to the SimTK::Array_ container including std::initializer_list construction, move construction, and move assignment.
11+
* Added C++11 features to the `SimTK::Array_` container including `std::initializer_list` construction, move construction, move assignment, and `emplace` methods.
1212
* Make doxygen run silently so errors will be easier to see.
13+
* Added new methods to `Pathname` class for interpreting pathnames against a specified working directory instead
14+
of the current working directory (thanks to Carmichael Ong). See [Issue #264](https://github.com/simbody/simbody/issues/264) and [PR #307](https://github.com/simbody/simbody/pull/307).
1315
* (There are more that haven't been added yet)
1416

1517

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ Michael Sherman |@sherm1 |Lead developer; multibody dynamics
369369
Peter Eastman |@peastman |Much early Simbody development; visualizer
370370
Chris Dembia |@chrisdembia |Build, task space control, CMA optimizer, bug fixes & documentation
371371
Thomas Uchida |@tkuchida |Rigid impact theory & code; documentation
372+
Carmichael Ong |@carmichaelong|Pathname deconstruction with specified working directory
372373
Ian Stavness |@stavness |Computational geometry
373374
Andreas Scholz |@AndreasScholz|Computational geometry
374375
José Rivero |@j-rivero |Build, especially for Debian

SimTKcommon/include/SimTKcommon/internal/Pathname.h

+49-25
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
* Biological Structures at Stanford, funded under the NIH Roadmap for *
1010
* Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
1111
* *
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 *
1414
* Contributors: *
1515
* *
1616
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
@@ -41,7 +41,7 @@ namespace SimTK {
4141
* of three components:
4242
* <pre> [directory] [filename [extension]] </pre>
4343
* where the directory may be an absolute location or relative to a
44-
* current working directory.
44+
* current working directory or specified working directory.
4545
*
4646
* Several special directory names are supported here:
4747
* - root (/)
@@ -84,6 +84,9 @@ namespace SimTK {
8484
* a backslash; on other platforms the canonicalized name will always
8585
* begin with a forward slash.
8686
*
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.
8790
*/
8891
class SimTK_SimTKCOMMON_EXPORT Pathname {
8992
public:
@@ -127,7 +130,7 @@ class SimTK_SimTKCOMMON_EXPORT Pathname {
127130
/// in the directory are changed to the appropriate slash
128131
/// for the currently running platform (i.e. backslash for
129132
/// Windows and forward slash everywhere else).
130-
static void deconstructPathname( const std::string& name,
133+
static void deconstructPathname( const std::string& pathname,
131134
bool& dontApplySearchPath,
132135
std::string& directory,
133136
std::string& fileName,
@@ -146,33 +149,33 @@ class SimTK_SimTKCOMMON_EXPORT Pathname {
146149
/// - If the swd is empty (after removing whitespace), deconstructPathname()
147150
/// is called, and cwd is prepended if needed to make it an absolute path.
148151
/// - 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.
161164
static void deconstructPathnameUsingSpecifiedWorkingDirectory(const std::string& swd,
162-
const std::string& path,
165+
const std::string& pathname,
163166
std::string& directory,
164167
std::string& fileName,
165168
std::string& extension);
166169

167170
/// Give back the deconstructed canonicalized absolute pathname for a given path.
168171
/// If the path is not an absolute path, it will be made into an absolute path first
169172
/// following the rules of deconstructPathname() (which it uses).
170-
static void deconstructAbsolutePathname(const std::string& path,
173+
static void deconstructAbsolutePathname(const std::string& pathname,
171174
std::string& directory,
172175
std::string& fileName,
173176
std::string& extension) {
174177
bool dontApplySearchPath;
175-
deconstructPathname(path, dontApplySearchPath, directory, fileName, extension);
178+
deconstructPathname(pathname, dontApplySearchPath, directory, fileName, extension);
176179
if (!dontApplySearchPath)
177180
directory = getCurrentWorkingDirectory() + directory;
178181
}
@@ -210,25 +213,46 @@ class SimTK_SimTKCOMMON_EXPORT Pathname {
210213
return absPath;
211214
}
212215

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) {
215221
std::string directory, fileName, extension;
216-
deconstructPathnameUsingSpecifiedWorkingDirectory(swd, path, directory, fileName, extension);
222+
deconstructPathnameUsingSpecifiedWorkingDirectory
223+
(swd, pathname, directory, fileName, extension);
217224
return directory + fileName + extension;
218225
}
219226

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+
220240
/// Return true if the given pathname names a file that exists and is
221241
/// readable.
222-
static bool fileExists(const std::string& fileName);
242+
static bool fileExists(const std::string& pathname);
223243

224244
/// Get the default installation directory for this platform. This will
225245
/// be /usr/local/ for Linux and Apple, and the value of the \%ProgramFiles\%
226246
/// registry entry on Windows (typically c:\\Program Files\\).
227247
static std::string getDefaultInstallDir();
228248

229249
/// 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);
232256

233257
/// Find the installation directory for something, using the named
234258
/// installation directory environment variable if it exists, otherwise

0 commit comments

Comments
 (0)