PLearn 0.1
|
#include <PPath.h>
Public Member Functions | |
PPath (const string &path_="") | |
Constructs a PPath from a string (which can be a serialized PPath). | |
PPath (const char *path) | |
PPath | absolute (bool add_protocol=false) const |
Returns an absolute path in the form appropriate for the OS. | |
string | canonical () const |
Returns a PPath in the canonical (serialized form). | |
string | errorDisplay () const |
Return the string that should be displayed in an error message. | |
string | protocol () const |
PPath | addProtocol () const |
Return either a copy of this PPath if it has an explicit protocol, or a copy with an explicit FILE_PROTOCOL (the default) otherwise. | |
PPath | removeProtocol () const |
Return a copy of this PPath without its explicit protocol. | |
void | removeTrailingSlash () |
Remove the current trailing slash if there is one and it is not a root directory. | |
void | parseUrlParameters (PPath &base_path, map< string, string > ¶meters) const |
Parse a PPath url-like parameters. | |
bool | isAbsPath () const |
Return true iff this is an absolute path. | |
bool | isFilePath () const |
bool | isHttpPath () const |
bool | isFtpPath () const |
bool | isEmpty () const |
Return true iff this is an empty path, i.e. | |
bool | isRoot () const |
Return true iff this is an (absolute) root directory. | |
PPath | operator/ (const char *other) const |
Path concatenation. | |
PPath & | operator/= (const char *other) |
PPath | operator/ (const PPath &other) const |
PPath & | operator/= (const PPath &other) |
bool | operator== (const char *other) const |
The operator '==' returns true iff the two paths represent the same file or directory. | |
bool | operator== (const string &other) const |
bool | operator== (const PPath &other) const |
bool | operator!= (const char *other) const |
The operator '!=' is defined as the contrary of '=='. | |
bool | operator!= (const string &other) const |
bool | operator!= (const PPath &other) const |
PPath | up () const |
PPath | dirname () const |
PPath | basename () const |
string | hostname () const |
string | extension (bool with_dot=false) const |
PPath | no_extension () const |
PPath | drive () const |
< bool startsWith(const char& c) const; bool endsWith (const char& c) const; bool startsWith(const string& s) const; bool endsWith (const string& s) const; | |
Static Public Member Functions | |
static PPath | home () |
static PPath | getcwd () |
static PPath | getenv (const string &var, const PPath &default_="") |
static bool | addMetaprotocolBinding (const string &metaprotocol, const PPath &metapath, bool force=true) |
static void | setCanonicalInErrors (bool canonical) |
static const string & | _slash () |
System-dependent slash string. | |
static char | _slash_char () |
System-dependent slash character. | |
Protected Member Functions | |
void | resolveSlashChars () |
void | resolveDots () |
Remove extra dots from the path. | |
void | resolveSingleDots () |
Remove only extra single dots from the path. | |
void | resolveDoubleDots () |
Remove only extra double dots from the path (assume there are no extra single dots, i.e. | |
void | expandMetaprotocols () |
void | parseProtocol () |
bool | isabs () const |
Returns whether a path is absolute. | |
Static Protected Member Functions | |
static string | forbidden_chars () |
static const map< string, PPath > & | metaprotocolToMetapath () |
static string | expandEnvVariables (const string &path) |
Protected Attributes | |
string | _protocol |
Static Private Attributes | |
static bool | canonical_in_errors = false |
Whether or not to display the canonical path in errorDisplay(). |
This class is meant to manage paths homogeneously under any OS and to ease path manipulations.
This class inherits from string (www.sgi.com/tech/stl/basic_string.html), hence PPath instances behave pretty much like strings and offer all public string method you may like to use to inspect paths (find, replace, substr, ...). The main difference is that PPath offers methods and redefine operators so that path manipulations are intuitive and that concerns regarding OS differences may be forgotten. The PPath instances may also represent http or ftp file path.
Absolute and canonic path ==========================
The two major methods are absolute() and canonical(). The first one, absolute(), returns an absolute path that is in a suitable form for opening under the current OS. The second one, canonical(), returns the serialization format that we adopted for paths in PLearn. This canonical form looks like:
METAPROTOCOL:foo/bar
where METAPROTOCOL is a kind of define whose value is parsed out of the PPath config file (found in ${PLEARN_CONFIGS}/ppath.config or in ${HOME}/.plearn/ppath.config if the PLEARN_CONFIG environment variable is not defined). The rest of the path is relative to the expanded value of the metaprocol. For instance,
HOME:foo/bar
maps to /home/dorionc/foo/bar for me, while it could map to /u/bengioy/foo/bar for Yoshua and to R:\foo\bar for some Windows user. Note that the canonical form of a path ALWAYS USES slash chars ('/') while the absolute() representation uses the appropriate slash ('/') or backslash ('\'). Hence, you should never care for windows' ugly '\' and always use slash char '/' (this pretty much deprecates the usage of stringutils' slash slash_char global variables):
Under DOS the following is true. PPath("C:/foo/bar") == "C:\foo\bar"
Also note that . and .. directories are elegantly resolved by PPath so that /home/dorionc/./foo/bar and /home/dorionc/foo/bar resolve to the same representation (HOME:foo/bar).
Examples: All the following asserts are true. PPath('./foo/bar') == 'foo/bar'
PPath('foo/./bar') == 'foo/bar'
PPath('foo/../bar') == 'bar'
PPath('./foo/bar/../bar/../../foo/./bar') == 'foo/bar'
PPath('././foo/bar') / PPath('../bar/../../foo/./bar') == 'foo/bar'
Note that here the '==' operator returns true iff the two paths point to the same ressource, in particular the final slash is ignored (except for a root directory). Finally, relative paths like "foo/bar" are considered to be relative to the current working directory of the process.
Protocols =========
In the examples above, paths are assumed to target a file (or directory) on disk. This can be made explicit by adding the protocol "file:", e.g. "file:/foo/bar". The protocols available are: file: <- on disk ftp: <- on a ftp server http: <- on a http server If a protocol is used, the path MUST be absolute. Also, a protocol cannot be used with a metaprotocol: "file:HOME:foo" is invalid, but you could define HOME to be "file:/home/login" and use "HOME:foo".
What more? ===========
Among other useful methods defined by PPath, the operator/(const PPath&) is probably the most useful. Its usage will get your code rid of the stringutils' inelegant 'append_slash'.
Examples: All the following asserts are true. PPath('') == ''
PPath('foo/bar') / '' == 'foo/bar/'
PPath('foo/bar') / 'file.cc' == 'foo/bar/file.cc'
PPath('foo/bar/') / 'file.cc' == 'foo/bar/file.cc'
And note that given those... PPath foo = "foo", bar = "bar/";
... both the following prints "foo/bar/toto". One must admit the second looks nicer ;) cout << append_slash( append_slash( append_slash(foo)+bar ) ) + "toto" << endl; cout << foo / bar / "toto" << endl;
Moreover, a PPath can be split into two parts: its 'dirname' and its 'basename' (accessible respectively through the dirname() and basename() methods). The semantic of this distinction is that a PPath points to a ressource, 'basename', which can be found in the 'dirname' directory. Thus 'basename' is the part of the PPath following the last '/' (or its platform-dependent counterpart). For instance "foo/bar/file" has a 'dirname' part equal to "foo/bar" and a 'basename' part equal to "file". See help on these methods for more details and examples.
Finally, note that PPath also provide some useful static methods like PPath::home, PPath::getenv (with a default value!) and PPath::getcwd.
PLearn::PPath::PPath | ( | const string & | path_ = "" | ) |
Constructs a PPath from a string (which can be a serialized PPath).
Definition at line 390 of file PPath.cc.
References expandEnvVariables(), expandMetaprotocols(), i, parseProtocol(), PLWARNING, resolveDots(), resolveSlashChars(), and PLearn::startsWith().
Referenced by absolute(), addProtocol(), basename(), dirname(), drive(), operator/(), operator==(), PPath(), removeProtocol(), and resolveDoubleDots().
: _protocol("") { // MODULE_LOG << "PPath(const string& path_ = " << path_ << ")" << endl; // Empty path. if ( path_.empty() ) return; const string* the_path = &path_; #if defined(__CYGWIN__) || defined(_MINGW_) #ifdef __CYGWIN__ char buf[3000]; #endif string new_path; // This is a hack to try to get the right DOS path from Cygwin. // Because Cygwin has its own translation rules, not necessarily compatible // with the PPath ones, we ask it to translate the path iff it starts with // a UNIX '/' character. TODO We will need a better home-made function // to translate paths safely. if (startsWith(*the_path, '/')) { #if defined(__CYGWIN__) cygwin_conv_to_win32_path(the_path->c_str(), buf); new_path = string(buf); #elif defined(_MINGW_) // We need to convert the path by ourselves. if (!startsWith(*the_path, "/cygdrive/")) { PLWARNING("Path '%s' is expected to start with '/cygdrive/'", the_path->c_str()); new_path = *the_path; } else { // Remove '/cygdrive'. new_path = the_path->substr(9); // Copy drive letter from second to first position. new_path[0] = new_path[1]; // Add ':' after drive letter. new_path[1] = ':'; // Replace '/' by '\'. for (string::size_type i = 0; i < new_path.size(); i++) if (new_path[i] == '/') new_path[i] = '\\'; } #endif the_path = &new_path; } #endif // The path_ argument may contain environment variables that must be // expanded prior to any other processing. string internal = expandEnvVariables( *the_path ); // The PPath internal string is set here string::operator= ( internal ); resolveSlashChars ( ); expandMetaprotocols ( ); resolveDots ( ); parseProtocol ( ); // pout << "Creating PPath from '" << *the_path << "' --> '" << string(*this) // << "'" << endl; }
PLearn::PPath::PPath | ( | const char * | path | ) |
const string & PLearn::PPath::_slash | ( | ) | [static] |
System-dependent slash string.
Definition at line 137 of file PPath.cc.
Referenced by isRoot(), resolveDoubleDots(), and resolveSingleDots().
{ static string s = "/"; return s; }
char PLearn::PPath::_slash_char | ( | ) | [static] |
System-dependent slash character.
Definition at line 143 of file PPath.cc.
Referenced by basename(), canonical(), dirname(), isabs(), operator/=(), removeTrailingSlash(), resolveDoubleDots(), resolveSingleDots(), and resolveSlashChars().
{ return '/'; }
Returns an absolute path in the form appropriate for the OS.
The returned path never ends with a slash unless it is a root directory.
Definition at line 708 of file PPath.cc.
References _protocol, addProtocol(), FILE_PROTOCOL, getcwd(), isAbsPath(), isEmpty(), PLASSERT, PLERROR, PPath(), protocol(), removeProtocol(), and removeTrailingSlash().
Referenced by PLearn::addFileAndDateVariables(), PLearn::PLearner::build_(), PLearn::GaussianProcessRegressor::build_(), PLearn::FileVMatrix::build_(), PLearn::canonical(), PLearn::chdir(), PLearn::cp(), errorDisplay(), PLearn::filesize64(), PLearn::force_mkdir(), PLearn::force_mkdir_for_file(), PLearn::force_rmdir(), PLearn::VMatrix::getSavedFieldInfos(), PLearn::HelpCommand::helpAboutPyPLearnScript(), PLearn::isdir(), PLearn::isemptyFile(), PLearn::isfile(), PLearn::VMatrix::isUpToDate(), PLearn::loadAscii(), PLearn::lsdir(), PLearn::makeFileNameValid(), PLearn::matlabSave(), PLearn::mtime(), PLearn::mv(), PLearn::newFilename(), PLearn::openFile(), PLearn::FileVMatrix::openfile(), PLearn::FilteredVMatrix::openIndex(), operator==(), PLearn::pathexists(), PLearn::readFileAndMacroProcess(), PLearn::removeReferenceToFile(), PLearn::rm(), PLearn::PLearner::setExperimentDirectory(), PLearn::Learner::setExperimentDirectory(), PLearn::HyperCommand::setExperimentDirectory(), PLearn::CompareLearner::setExperimentDirectory(), PLearn::VMatrix::setMetaDataDir(), PLearn::touch(), PLearn::LearnerCommand::train(), PLearn::LocallyPrecomputedVMatrix::~LocallyPrecomputedVMatrix(), and PLearn::TemporaryDiskVMatrix::~TemporaryDiskVMatrix().
{ if (!add_protocol && protocol() != FILE_PROTOCOL) PLERROR("In PPath::absolute - The absolute() method is only meant for " "the FILE_PROTOCOL protocol when 'add_protocol' is false"); PPath abspath; // An empty path remains empty when converted to absolute. if ( isEmpty() || isAbsPath() ) abspath = PPath( *this ); // This is necessarily a file protocol (because other protocols require // an absolute path). // ===> we concatenate the current working directory of the process. else { PLASSERT( _protocol.empty() ); abspath = PPath::getcwd() / *this; } // Remove useless trailing slash. abspath.removeTrailingSlash(); // Add / remove protocol if required. Note that we cannot add a protocol to // an empty PPath (as an empty PPath is considered relative). if (add_protocol && !abspath.isEmpty()) abspath = abspath.addProtocol(); else // There can be a protocol in abspath only if there is one in *this. if (!_protocol.empty()) abspath = abspath.removeProtocol(); return abspath; }
bool PLearn::PPath::addMetaprotocolBinding | ( | const string & | metaprotocol, |
const PPath & | metapath, | ||
bool | force = true |
||
) | [static] |
Add a new metaprotocol-to-metapath binding. Return 'true' iff the given metaprotocol was not already binded. If 'force' is set to true, the binding will be made even if the given metaprotocol was already binded. Otherwise, the existing metaprotocol will be preserved.
Definition at line 316 of file PPath.cc.
References PLearn::metaprotocol_to_metapath().
{ const map<string, PPath>& bindings = metaprotocolToMetapath(); bool already_here = bindings.find(metaprotocol) != bindings.end(); if (!already_here || force) metaprotocol_to_metapath()[metaprotocol] = metapath; return !already_here; }
PPath PLearn::PPath::addProtocol | ( | ) | const |
Return either a copy of this PPath if it has an explicit protocol, or a copy with an explicit FILE_PROTOCOL (the default) otherwise.
Definition at line 847 of file PPath.cc.
References _protocol, errorDisplay(), FILE_PROTOCOL, isAbsPath(), PLERROR, and PPath().
Referenced by absolute(), and PLearn::canonical().
{ if ( _protocol.empty()) { if (!isAbsPath()) // Ugly single-line error message to ensure tests pass. PLERROR("In PPath::addProtocol - A protocol can only be added to an absolute path, and '%s' is relative", errorDisplay().c_str()); return ( PPath(string(FILE_PROTOCOL) + ':' + string(*this)) ); } return PPath( *this ); }
PPath PLearn::PPath::basename | ( | ) | const |
Returns the final component of a pathname (which will be "" if it ends with a slash). The basename never contains a slash.
It is always true that
path.dirname() / path.basename() == path
PPath::basename examples:
PPath("").basename() // "" PPath("foo.cc").basename() // "foo.cc" PPath("/").basename() // "" PPath(".").basename() // "." PPath("./").basename() // "" PPath("foo/bar").basename() // "bar" PPath("foo/bar/").basename() // "" PPath("foo/bar/hi.cc").basename() // "hi.cc"
Definition at line 962 of file PPath.cc.
References _slash_char(), and PPath().
Referenced by PLearn::addFileAndDateVariables(), extension(), PLearn::getDataSet(), hostname(), PLearn::makeFileNameValid(), PLearn::readFileAndMacroProcess(), and PLearn::unitTest().
{ size_t slash_pos = rfind(_slash_char()); if ( slash_pos == npos ) return PPath(*this); return substr(slash_pos+1); }
string PLearn::PPath::canonical | ( | ) | const |
Returns a PPath in the canonical (serialized form).
It is a string because it needs to be converted to a system-dependent version before it can be used directly as a PPath.
Definition at line 746 of file PPath.cc.
References _slash_char(), PLearn::endl(), PLearn::endsWith(), EXTREME_LOG, isEmpty(), metaprotocolToMetapath(), PLearn::plhead(), PPATH_SLASH, and PLearn::startsWith().
Referenced by PLearn::addReferenceToFile(), PLearn::canonical(), errorDisplay(), PLearn::ScoreLayerVariable::getMolecule(), PLearn::ScoreLayerVariable::getMoleculeTemplate(), PLearn::HelpSystem::helpOnClassHTML(), PLearn::nReferencesToFile(), PLearn::operator<<(), and PLearn::removeReferenceToFile().
{ // An empty path does not need to be modified. if (isEmpty()) return *this; // We have to replace any special path by its canonic equivalent. // Note that the protocol is kept. This means in particular that // if ppath = "/foo/bar" and the metaprotocol FOO maps to "file:/foo", // then the canonical form of ppath will still be "/foo/bar", and not // "FOO:bar" (we may want to change this behavior in the future). string canonic_path = *this; EXTREME_LOG << plhead("canonic_path: "+canonic_path) << endl; map<string, PPath>::const_iterator it = metaprotocolToMetapath().begin(); map<string, PPath>::const_iterator end = metaprotocolToMetapath().end(); string metaprotocol; string metapath; // Used to store the longest metapath found so far. while ( it != end ) { const string& candidate = it->second; if ( candidate.length() < metapath.length() ) { // The candidate is shorter, we are not interested. EXTREME_LOG << "Shorter:\n\t" << it->first << " -> " << candidate.c_str() << endl; ++it; continue; } if ( !startsWith(canonic_path, candidate) ) { // No match. EXTREME_LOG << "No match:\n\t" << it->first << " -> " << candidate.c_str() << endl; ++it; continue; } size_t endpath = candidate.length(); // The current candidate is only a subtring of the canonic path. // Ex: // /home/dorionc/hey // in // /home/dorionc/heyYou. // Note that if the canonic path is a root directory, it may end // with a slash, in which case this cannot happen. if ( endpath != canonic_path.length() && canonic_path[endpath] != _slash_char() && !endsWith(candidate, _slash_char()) ) { EXTREME_LOG << "Substring:\n\t" << it->first << " -> " << it->second.c_str() << endl; ++it; continue; } // The current candidate is indeed a subpath of canonic_path. metaprotocol = it->first; metapath = candidate; EXTREME_LOG << "Kept:\n\t" << it->first << " -> " << candidate.c_str() << endl; ++it; // We iterate to find the longest matching candidate. } // If any metapath was found, it must be replaced by its metaprotocol // equivalent. if ( metaprotocol.length() > 0 ) { canonic_path.replace( 0, metapath.length(), metaprotocol+':' ); // Remove the slash just after the ':' if there is something following. size_t after_colon = metaprotocol.size() + 1; if (canonic_path.size() > after_colon + 1 && canonic_path[after_colon] == _slash_char()) canonic_path.erase(after_colon, 1); } // If necessary, convert slash characters to the canonical slash. if (_slash_char() != PPATH_SLASH) { size_t slash_pos = 0; while ((slash_pos = canonic_path.find(_slash_char(), slash_pos)) != npos) canonic_path[slash_pos] = PPATH_SLASH; } return canonic_path; }
PPath PLearn::PPath::dirname | ( | ) | const |
Returns a PPath that points to the directory component of the PPath. Contrary to the up() method, the final slash is important, and the PPath may point either to a file or to a directory ressource. The returned PPath will never end with a slash, unless it is a root directory.
It is always true that
path.dirname() / path.basename() == path
PPath::dirname examples:
PPath("").dirname() // "" PPath("foo.cc").dirname() // "." PPath(".").dirname() // "." PPath("./").dirname() // "." PPath("/").dirname() // "/" PPath("/foo.cc").dirname() // "/" PPath("foo/bar").dirname() // "foo" PPath("foo/bar/").dirname() // "foo/bar" PPath("foo/bar/hi.cc").dirname() // "foo/bar"
Definition at line 942 of file PPath.cc.
References _protocol, _slash_char(), isEmpty(), isRoot(), PPath(), and removeTrailingSlash().
Referenced by PLearn::addFileAndDateVariables(), PLearn::force_mkdir_for_file(), PLearn::getDataSet(), PLearn::makeFileNameValid(), PLearn::openFile(), and PLearn::readFileAndMacroProcess().
{ if (isEmpty() || isRoot()) return PPath(*this); size_t slash_pos = rfind(_slash_char()); if ( slash_pos == npos ){ if (_protocol.empty()) return "."; else return _protocol + ":."; } PPath result = substr(0, slash_pos + 1); // Remove trailing slash if it is not a root directory. result.removeTrailingSlash(); return result; }
PPath PLearn::PPath::drive | ( | ) | const |
< bool startsWith(const char& c) const; bool endsWith (const char& c) const; bool startsWith(const string& s) const; bool endsWith (const string& s) const;
Migrated from fileutils.{h,cc}
Returns a ppath shorter than 256 character and exempt of any of the following chars: "*?'\"${}[]@ ,()" --- replaced by underscores. Returns the drive specification of a path (a drive letter followed by a colon) under dos. Under posix, always returns "".
Definition at line 1089 of file PPath.cc.
References PPath().
Referenced by isRoot().
{ return PPath(""); }
string PLearn::PPath::errorDisplay | ( | ) | const |
Return the string that should be displayed in an error message.
It will be either the absolute or canonical string, depending on the value of the global PPath boolean 'canonical_in_errors' (the default being to display the absolute path).
Definition at line 836 of file PPath.cc.
References absolute(), canonical(), and canonical_in_errors.
Referenced by addProtocol(), metaprotocolToMetapath(), resolveDoubleDots(), PLearn::PTest::run(), and up().
{ if (PPath::canonical_in_errors) return this->canonical(); else return this->absolute(); }
string PLearn::PPath::expandEnvVariables | ( | const string & | path | ) | [static, protected] |
Within PPath(const string& path_) ctor, the path_ argument may contain environment variables that must be expanded prior to any other processing. This method MUST NOT return a path since it would lead to an infinite loop of ctors.
Definition at line 330 of file PPath.cc.
References getenv(), and PLERROR.
Referenced by PPath().
{ string expanded = path; size_t begvar = expanded.find( "${" ); size_t endvar = expanded.find( "}" ); while ( begvar != npos && endvar != npos ) { size_t start = begvar+2; size_t len = endvar - start; string envvar = expanded.substr(start, len); PPath envpath = PPath::getenv(envvar); if ( envpath == "" ) PLERROR( "Unknown environment variable %s in %s.", envvar.c_str(), path.c_str() ); expanded.replace(begvar, len+3, envpath); // Look for other environment variables begvar = expanded.find( "${" ); endvar = expanded.find( "}" ); } // This method MUST NOT return a path since it would lead to an infinite // loop of ctors. return expanded; }
void PLearn::PPath::expandMetaprotocols | ( | ) | [protected] |
Used in operator= (and therefore in the ctor) to transform recognized metaprotocol contained in the path, if any.
Definition at line 489 of file PPath.cc.
References PLearn::find(), getenv(), isEmpty(), and metaprotocolToMetapath().
Referenced by PPath().
{ size_t endmeta = find(':'); if ( endmeta != npos ) { string meta = substr(0, endmeta); map<string, PPath>::const_iterator it = metaprotocolToMetapath().find(meta); PPath metapath; if ( it != metaprotocolToMetapath().end() ) metapath = it->second; else metapath = getenv(meta); if ( !metapath.isEmpty() ) { string after_colon = endmeta == length()-1 ? "" : substr(endmeta+1); *this = metapath / after_colon; } } }
string PLearn::PPath::extension | ( | bool | with_dot = false | ) | const |
Return the extension of basename() (or an empty string if it has no extension). The dot may or may not be included, depending on the value of the 'with_dot' parameter.
Definition at line 994 of file PPath.cc.
References basename().
Referenced by PLearn::addFileAndDateVariables(), PLearn::getDataSet(), PLearn::makeFileNameValid(), no_extension(), PLearn::VMatrix::resolveFieldInfoLink(), PLearn::RunObject::run(), and PLearn::RunCommand::run().
{ PPath base = basename(); size_t begext = base.rfind('.'); if ( begext == npos || // Not found. begext == base.length()-1 ) // Filename ending with a dot. return ""; return with_dot ? base.substr(begext) : base.substr(begext+1); }
string PLearn::PPath::forbidden_chars | ( | ) | [static, protected] |
OS dependent list of forbidden chars.
POSIX SETTINGS: "\\" Even if the posix standard allows backslashes in file paths, PLearn users should never use those since PLearn aims at full and easy portability.
Other chars may be forbidden soon.
DOS SETTINGS: "" None for now; coming soon.
Definition at line 132 of file PPath.cc.
Referenced by resolveSlashChars().
{ return "\\"; }
PPath PLearn::PPath::getcwd | ( | ) | [static] |
Definition at line 211 of file PPath.cc.
References PLERROR, and SYS_GETCWD.
Referenced by absolute(), and PLearn::readFileAndMacroProcess().
{ // TODO Use a NSPR function when there is one: // https://bugzilla.mozilla.org/show_bug.cgi?id=280953 char buf[2000]; if (!SYS_GETCWD(buf, 2000)) // Error while reading the current directory. One should probably use a // larger buffer, but it is even easier to crash. PLERROR("In PPath::getcwd - Could not obtain the current working " "directory, a larger buffer may be necessary"); return PPath(buf); }
Definition at line 227 of file PPath.cc.
Referenced by PLearn::addFileAndDateVariables(), expandEnvVariables(), expandMetaprotocols(), home(), and metaprotocolToMetapath().
{ char* env_var = PR_GetEnv(var.c_str()); if ( env_var ) return PPath( env_var ); return default_; }
PPath PLearn::PPath::home | ( | ) | [static] |
Definition at line 196 of file PPath.cc.
References getenv(), and PL_DEFAULT_HOME.
Referenced by metaprotocolToMetapath().
{ // Supply a default value so PLearn does not crash. // when $HOME isn't defined. #ifdef WIN32 #define PL_DEFAULT_HOME PPath("C:\\") #else #define PL_DEFAULT_HOME PPath("/") #endif return PPath::getenv("HOME", PL_DEFAULT_HOME); }
string PLearn::PPath::hostname | ( | ) | const |
Return the hostname of a PPath representing an url. Although this method is meant to be called on a PPath with a HTTP or FTP protocol, it may also be used with other protocols.
PPath::hostname example:
PPath("http://foo.com/bar/hi").hostname() // "foo.com"
Definition at line 973 of file PPath.cc.
References basename(), i, isAbsPath(), isRoot(), PLERROR, removeTrailingSlash(), and up().
Referenced by PLearn::openUrl().
{ if (!isAbsPath()) PLERROR("In PPath::hostname - Can only be used with an absolute path"); if (isRoot()) PLERROR("In PPath::hostname - The path cannot be a root directory"); int i = 0; PPath paths[2]; paths[0] = *this; paths[1] = paths[0].up(); while (!paths[1 - i].isRoot()) { i = 1 - i; paths[1 - i] = paths[i].up(); } paths[i].removeTrailingSlash(); return paths[i].basename(); }
bool PLearn::PPath::isabs | ( | ) | const [protected] |
Returns whether a path is absolute.
Trivial in Posix, harder on the Mac or MS-DOS. For DOS it is absolute if it starts with a slash or backslash (current volume), or if a pathname after the volume letter and colon starts with a slash or backslash.
It is protected because one should use isAbsPath().
Definition at line 1094 of file PPath.cc.
References _protocol, _slash_char(), FILE_PROTOCOL, isFtpPath(), isHttpPath(), and PLearn::startsWith().
{ return startsWith(c_str(), _slash_char()) || isHttpPath() || isFtpPath() || _protocol == FILE_PROTOCOL; }
bool PLearn::PPath::isAbsPath | ( | ) | const [inline] |
Return true iff this is an absolute path.
Definition at line 337 of file PPath.h.
Referenced by absolute(), addProtocol(), PLearn::canonical(), hostname(), isRoot(), operator/=(), and parseProtocol().
{ return isabs(); }
bool PLearn::PPath::isEmpty | ( | ) | const [inline] |
Return true iff this is an empty path, i.e.
it is equal to "" after its protocol has been removed.
Definition at line 344 of file PPath.h.
Referenced by absolute(), PLearn::addReferenceToFile(), PLearn::HyperLearner::auto_save(), PLearn::VMatrix::build_(), PLearn::SelectColumnsVMatrix::build_(), PLearn::RunObject::build_(), PLearn::RBMTrainer::build_(), PLearn::LIBSVMSparseVMatrix::build_(), PLearn::FileVMatrix::build_(), PLearn::CompactFileVMatrix::build_(), PLearn::AutoVMatrix::build_(), canonical(), PLearn::PyPLearnScript::close(), dirname(), expandMetaprotocols(), PLearn::force_mkdir(), PLearn::ScoreLayerVariable::getMolecule(), PLearn::ScoreLayerVariable::getMoleculeTemplate(), PLearn::VMatrix::getPrecomputedStatsFromFile(), PLearn::HyperOptimize::getResultsMat(), PLearn::nReferencesToFile(), operator/=(), operator==(), PLearn::HyperOptimize::optimize(), parseProtocol(), PLearn::removeReferenceToFile(), removeTrailingSlash(), PLearn::RBMTrainer::run(), PLearn::PTest::run(), PLearn::GeodesicDistanceKernel::setDataForKernelMatrix(), PLearn::EmbeddedLearner::setExperimentDirectory(), PLearn::ChainedLearners::setExperimentDirectory(), PLearn::BestAveragingPLearner::setExperimentDirectory(), PLearn::VMatrix::setMetaDataDir(), PLearn::NNet::train(), PLearn::HyperLearner::train(), up(), and PLearn::VMatrix::updateMtime().
{ return removeProtocol().empty(); }
bool PLearn::PPath::isFilePath | ( | ) | const [inline] |
Definition at line 338 of file PPath.h.
References FILE_PROTOCOL.
Referenced by PLearn::canonical().
{ return protocol() == FILE_PROTOCOL; }
bool PLearn::PPath::isFtpPath | ( | ) | const [inline] |
Definition at line 340 of file PPath.h.
References FTP_PROTOCOL.
Referenced by PLearn::canonical(), and isabs().
{ return _protocol == FTP_PROTOCOL; }
bool PLearn::PPath::isHttpPath | ( | ) | const [inline] |
Definition at line 339 of file PPath.h.
References HTTP_PROTOCOL.
Referenced by PLearn::canonical(), and isabs().
{ return _protocol == HTTP_PROTOCOL; }
bool PLearn::PPath::isRoot | ( | ) | const |
Return true iff this is an (absolute) root directory.
Definition at line 1105 of file PPath.cc.
References _slash(), drive(), isAbsPath(), and removeProtocol().
Referenced by dirname(), PLearn::force_mkdir(), hostname(), removeTrailingSlash(), resolveDoubleDots(), resolveSingleDots(), and up().
{ if (!isAbsPath()) return false; PPath no_prot = removeProtocol(); string drv = no_prot.drive(); return string(no_prot) == drv + _slash(); }
const map< string, PPath > & PLearn::PPath::metaprotocolToMetapath | ( | ) | [static, protected] |
Builds a static metaprotocol-to-metapath map once and returns it at each call.
Definition at line 247 of file PPath.cc.
References errorDisplay(), getenv(), PLearn::PStream::good(), home(), PLearn::isfile(), PLearn::metaprotocol_to_metapath(), PLearn::openFile(), PLearn::PStream::plearn_ascii, PLERROR, and PLWARNING.
Referenced by canonical(), and expandMetaprotocols().
{ static bool mappings; if ( !mappings ) { // Avoiding infinite loop. mappings = true; PPath plearn_configs = PPath::getenv( "PLEARN_CONFIGS", PPath::home() / ".plearn" ); PPath config_file_path = plearn_configs / "ppath.config"; if (isfile(config_file_path)) { PStream ppath_config = openFile(config_file_path, PStream::plearn_ascii); string next_metaprotocol; PPath next_metapath; while (ppath_config.good()) { ppath_config >> next_metaprotocol >> next_metapath; if (next_metaprotocol.empty()){ if (ppath_config.good()) PLERROR("In PPath::metaprotocolToMetapath - Error while parsing PPath config file (%s): read " "a blank line before reaching the end of the file", config_file_path.errorDisplay().c_str()); else // Nothing left to read. break; } // Make sure we managed to read the metapath associated with the metaprotocol. if (next_metapath.empty()) PLERROR("In PPath::metaprotocolToMetapath - Error in PPath config file (%s): could not read the " "path associated with '%s'", config_file_path.errorDisplay().c_str(), next_metaprotocol.c_str()); // For the sake of simplicity, we do not allow a metapath to end with // a slash unless it is a root directory. next_metapath.removeTrailingSlash(); if (!addMetaprotocolBinding(next_metaprotocol, next_metapath)) PLWARNING("In PPath::metaprotocolToMetapath - Metaprotocol" " '%s' is being redefined, please check your " "ppath.config (%s)", next_metaprotocol.c_str(), config_file_path.errorDisplay().c_str()); } } else { if (PR_GetEnv("HOME")) { // Default PPath settings. Defined only if the HOME environment // variable exists. metaprotocol_to_metapath()["HOME"] = "${HOME}"; metaprotocol_to_metapath()["PLEARNDIR"] = "HOME:PLearn"; metaprotocol_to_metapath()["PLEARN_LIBDIR"] = "PLEARNDIR:external_libs"; } } } return metaprotocol_to_metapath(); }
PPath PLearn::PPath::no_extension | ( | ) | const |
Return a copy of the path, but without its extension (as computed by the extension() method).
Definition at line 1007 of file PPath.cc.
References std::copy(), and extension().
Referenced by PLearn::addFileAndDateVariables(), PLearn::makeFileNameValid(), and PLearn::RunObject::run().
{ size_t ext_size = extension().size(); string copy(*this); if (ext_size > 0) copy.resize(size() - ext_size - 1); // Remove the extension and the dot. return copy; }
bool PLearn::PPath::operator!= | ( | const char * | other | ) | const [inline] |
The operator '!=' is defined as the contrary of '=='.
Definition at line 370 of file PPath.h.
References PLearn::operator==().
{ return !(operator==(string(other))); }
bool PLearn::PPath::operator!= | ( | const string & | other | ) | const [inline] |
Definition at line 371 of file PPath.h.
References PLearn::operator==().
{ return !(operator==(other)); }
Definition at line 372 of file PPath.h.
References PLearn::operator==().
{ return !(operator==(other)); }
PPath PLearn::PPath::operator/ | ( | const char * | other | ) | const [inline] |
PPath& PLearn::PPath::operator/= | ( | const char * | other | ) | [inline] |
Definition at line 355 of file PPath.h.
References operator/=().
Referenced by operator/=().
{ return operator/=(PPath(other)); }
Definition at line 882 of file PPath.cc.
References _slash_char(), PLearn::endsWith(), isAbsPath(), isEmpty(), PLearn::operator+=(), PLERROR, and resolveDots().
{ // MODULE_LOG << this->c_str() << " /= " << other << endl; if (other.isAbsPath()) PLERROR("In PPath::operator/= - The concatenated path (%s) cannot be absolute", other.c_str()); // Add a slash if needed. // Note that 'other' cannot start with a slash, otherwise it would be an // absolute directory. if ( !isEmpty () && !endsWith (*this, _slash_char()) ) string::operator+=(_slash_char()); string::operator+=(other); resolveDots ( ); return *this; }
bool PLearn::PPath::operator== | ( | const char * | other | ) | const [inline] |
The operator '==' returns true iff the two paths represent the same file or directory.
The final slash is systematically ignored. For instance: "/foo/bar" == "/foo/bar/" "/foo/bar/.." == "/foo" "bar" == "/foo/bar" if the current working directory is "/foo" This is done by comparing this->absolute() to other.absolute().
Definition at line 365 of file PPath.h.
References operator==().
Referenced by operator==().
{ return operator==(string(other)); }
bool PLearn::PPath::operator== | ( | const string & | other | ) | const |
Definition at line 904 of file PPath.cc.
References isEmpty(), operator==(), and PPath().
{ // MODULE_LOG << this->c_str() << " == " << other << " (string)"<< endl; if ( other.empty() ) return isEmpty(); if ( isEmpty() ) return false; // since 'other' is not return operator==( PPath(other) ); }
Definition at line 914 of file PPath.cc.
References absolute().
{ // MODULE_LOG << this->c_str() << " == " << other << " (PPath)"<< endl; // If they are stricly equal there is no need to go further. // Otherwise they must point to the same absolute file or directory. // Note that the absolute() method already removes the trailing slash. return ( !strcmp(c_str(), other.c_str()) || !strcmp(absolute(true).c_str(), other.absolute(true).c_str())); }
void PLearn::PPath::parseProtocol | ( | ) | [protected] |
Used in operator= (and therefore in the ctor) to assign the _protocol member.
Definition at line 665 of file PPath.cc.
References _protocol, FILE_PROTOCOL, PLearn::find(), FTP_PROTOCOL, HTTP_PROTOCOL, isAbsPath(), isEmpty(), PLERROR, and removeProtocol().
Referenced by PPath().
{ size_t endpr = find(':'); // No specified protocol if ( endpr == npos ) { // Even if the default protocol is considered to be the file protocol, // the _protocol member keeps the exact protocol value in the // string. The protocol() method, however, returns FILE_PROTOCOL if the // protocol was not specified. _protocol = ""; } // The substring preceeding the ':' delimiter COULD be the protocol. else { _protocol = substr(0, endpr); if ( _protocol == FILE_PROTOCOL || _protocol == HTTP_PROTOCOL || _protocol == FTP_PROTOCOL ) { // Make sure we do not define a protocol for a relative path. PPath check_filepath_validity = removeProtocol(); if ( !check_filepath_validity.isEmpty() && !check_filepath_validity.isAbsPath() ) PLERROR("A PPath should not specify a protocol " "for a relative path (in %s).", c_str()); } // Nothing prevents a file from containing a ':' char. Under dos, for // instance, a letter preceeding ':' represents the drive. Hence, if // we do not recognize the protocol, we assume the ':' was part of // the file name. else _protocol = ""; } }
void PLearn::PPath::parseUrlParameters | ( | PPath & | base_path, |
map< string, string > & | parameters | ||
) | const |
Parse a PPath url-like parameters.
For instance, if the PPath is protocol:/path?param1=value1¶m2=value2¶m3=value3 then after calling this method, 'base_path' will be equal to protocol:/path, and the 'parameters' map will be such that parameters["paramX"] = "valueX". Note that existing mappings in 'parameters' are not removed (unless they are overwritten by the PPath parameters).
Definition at line 1118 of file PPath.cc.
References PLERROR, PLearn::split(), and PLearn::split_on_first().
{ size_t pos = rfind('?'); if (pos == string::npos) { base_path = *this; return; } size_t check = rfind('?', pos - 1); if (check != string::npos) PLERROR("In PPath::parseUrlParameters - There can be only one '?' in a PPath"); base_path = substr(0, pos); string rest = substr(pos + 1); vector<string> pairs = PLearn::split(rest, '&'); string equal = "="; string name, value; vector<string>::const_iterator it = pairs.begin(); for (; it != pairs.end(); it++) { PLearn::split_on_first(*it, equal, name, value); if (!name.empty()) { if (value.empty()) PLERROR("In PPath::parseUrlParameters - The parameter %s has no value", name.c_str()); parameters[name] = value; } else if (!value.empty()) PLERROR("In PPath::parseUrlParameters - The value %s has no parameter name", value.c_str()); } }
string PLearn::PPath::protocol | ( | ) | const [inline] |
Even if the default protocol is considered to be the file protocol, the _protocol member keeps the exact protocol value in the string. This is to be able to quickly know whether there is a protocol in the actual string or not. The protocol() method, however, returns FILE_PROTOCOL if the protocol was not specified.
Definition at line 317 of file PPath.h.
References FILE_PROTOCOL.
Referenced by absolute(), and PLearn::canonical().
{ return _protocol.empty() ? FILE_PROTOCOL : _protocol; }
PPath PLearn::PPath::removeProtocol | ( | ) | const |
Return a copy of this PPath without its explicit protocol.
Definition at line 861 of file PPath.cc.
References _protocol, and PPath().
Referenced by absolute(), isRoot(), and parseProtocol().
{ if ( _protocol.length()==0 ) return PPath(*this); PPath no_protocol; // Avoid a call to the PPath constructor from a string. no_protocol.assign(substr(_protocol.length()+1)); return no_protocol; }
void PLearn::PPath::removeTrailingSlash | ( | ) |
Remove the current trailing slash if there is one and it is not a root directory.
Definition at line 1150 of file PPath.cc.
References _slash_char(), isEmpty(), and isRoot().
Referenced by absolute(), dirname(), PLearn::DiskVMatrix::DiskVMatrix(), and hostname().
{ if (isEmpty() || (*this)[length() - 1] != _slash_char() || isRoot()) return; resize(length() - 1); }
void PLearn::PPath::resolveDots | ( | ) | [protected] |
Remove extra dots from the path.
Definition at line 648 of file PPath.cc.
References _protocol, resolveDoubleDots(), and resolveSingleDots().
Referenced by operator/=(), and PPath().
{ // First remove temporarily the protocol. if (!_protocol.empty()) replace(0, _protocol.size() + 1, ""); resolveSingleDots(); resolveDoubleDots(); // Put back the protocol. if (!_protocol.empty()) insert(0, _protocol + ":"); }
void PLearn::PPath::resolveDoubleDots | ( | ) | [protected] |
Remove only extra double dots from the path (assume there are no extra single dots, i.e.
in general that resolveSingleDots() was called first). Also assume there is no explicit protocol in the path.
Definition at line 571 of file PPath.cc.
References _slash(), _slash_char(), errorDisplay(), PLearn::find(), isRoot(), PLERROR, PPath(), and resolveSingleDots().
Referenced by resolveDots().
{ static string sdd; static bool initialized = false; if (!initialized) { initialized = true; sdd = _slash() + ".."; // Posix: "/.." DOS: "\.." } // Examples with double dots. // "/.." -> PLERROR // "/../foo" -> PLERROR // "../foo" -> "../foo" // "foo/.." -> "." // "foo/../" -> "./" // "/foo/.." -> "/" // "/foo/../" -> "/" // "foo/../bar" -> "./bar" (call resolveSingleDots() after) // "/foo/../bar" -> "/bar" // "/..foo" -> "/..foo" // "foo../" -> "foo../" // "../../../foo"-> "../../../foo" // "foo/../../.."-> "foo/../../.." // We only care about "/.." when it is followed by a slash or it ends the path. // The path made of the substring until the '/' must not be a root directory. size_t pos_sdd = find(sdd); size_t next; while (pos_sdd != npos) { if (pos_sdd + 3 < size() && operator[](pos_sdd + 3) != _slash_char()) { // Something like "/..foo", that we ignore. next = pos_sdd + 4; } else { // Look for the slash just before. size_t pos_previous_slash = pos_sdd == 0 ? npos : rfind(_slash_char(), pos_sdd - 1); if (pos_previous_slash == npos) { // We need to make sure we are not trying to go up on a root // directory. if (PPath(substr(0, pos_sdd + 1)).isRoot()) // Long single-line error message to ensure tests pass. PLERROR("In PPath::resolveDots - '%s' is invalid", errorDisplay().c_str()); if ( (pos_sdd == 2 && substr(0,2) == "..") || (pos_sdd == 1 && operator[](0) == '.')) // We are in the case "../.." or "./.." next = pos_sdd + 3; else { // We are in the case "foo/.." replace(0, pos_sdd + 3, "."); next = 1; } } else { // There was a slash: "/xxx/..". If "xxx" == "..", we do nothing, // otherwise we get rid of it. if (substr(pos_previous_slash+1, 2) == "..") next = pos_sdd + 3; else { // We must be careful with the special case "/foo/..", where we // need to ensure we keep a final slash. if ( pos_sdd + 3 == size() // Ends with "/.." && ( pos_previous_slash == 0 || rfind(_slash_char(), pos_previous_slash-1) == npos) // "xxx/foo/.." && PPath(substr(0, pos_previous_slash+1)).isRoot()) // "xxx/" is root replace(pos_previous_slash + 1, pos_sdd-pos_previous_slash+2, ""); else replace(pos_previous_slash, pos_sdd-pos_previous_slash+3, ""); next = pos_previous_slash; } } } pos_sdd = find(sdd, next); } // At this point, we may have introduced an extra single dot ("./xxx"). resolveSingleDots(); }
void PLearn::PPath::resolveSingleDots | ( | ) | [protected] |
Remove only extra single dots from the path.
Assume there is no explicit protocol in the path.
Definition at line 514 of file PPath.cc.
References _slash(), _slash_char(), PLearn::find(), and isRoot().
Referenced by resolveDots(), and resolveDoubleDots().
{ static string ds, sd; static bool initialized = false; if (!initialized) { initialized = true; ds = "." + _slash(); // Posix: "./" DOS: ".\" sd = _slash() + "."; // Posix: "/." DOS: "\." } // Examples with single dots. // ./foo -> foo // ./ -> ./ // . -> . // /. -> / // /./ -> / // /./foo -> /foo // foo/. -> foo // foo/./ -> foo/ // foo/./bar -> foo/bar // foo/.bar -> foo/.bar // First deal with "/.": // - when it is followed by a slash, remove it // - when it ends the path, remove the dot, and remove the slash unless // the resulting directory is a root directory size_t pos_sd = find(sd); size_t next; while (pos_sd != npos) { if (pos_sd + 2 < size()) { if (operator[](pos_sd + 2) == _slash_char()) { // It is followed by a slash. replace(pos_sd, 2, ""); // Remove '/.' next = pos_sd; } else next = pos_sd + 2; // We ignore this one (e.g. "/.plearn"). } else { // It ends the path. resize(size() - 1); // Remove '.' if (!isRoot()) resize(size() - 1); // Remove '/' next = size(); // We reached the end. } pos_sd = find(sd, next); } // Now deals with "./". Because we have removed the "/." before, we cannot // have "/./" nor "./.". Thus the only case we have to consider is when it // starts the path (and this can happen only once), in which case we remove // it iff there is something that follows. size_t pos_ds = find(ds); if (pos_ds == 0 && pos_ds + 2 < size()) replace(0, 2, ""); }
void PLearn::PPath::resolveSlashChars | ( | ) | [protected] |
Replace any slash character (canonical '/' or '_slash_char') by the '_slash_char' character, removing duplicated slashes.
Definition at line 453 of file PPath.cc.
References _slash_char(), PLearn::find(), forbidden_chars(), PLERROR, and PPATH_SLASH.
Referenced by PPath().
{ size_t plen = length(); string resolved; resolved.reserve( plen ); bool last_is_slash = false; for ( size_t ch = 0; ch < plen; ch++ ) { char char_ch = operator[](ch); if ( forbidden_chars().find(char_ch) != npos ) PLERROR( "PPath '%s' cannot contain character '%c' (or any of \"%s\").", c_str(), char_ch, forbidden_chars().c_str() ); // Convert the canonic representation '/' to the appropriate // representation given the system (see slash_char instanciation in // PPath.cc). Multiple slash chars are removed. if ( char_ch == PPATH_SLASH || char_ch == _slash_char() ) { if( !last_is_slash ) { // Prevents duplicated slash characters. resolved += _slash_char(); last_is_slash = true; } } else { resolved += char_ch; last_is_slash = false; } } string::operator=(resolved); }
void PLearn::PPath::setCanonicalInErrors | ( | bool | canonical | ) | [static] |
Decide whether or not to display canonical paths in error messages. The default behavior is to display absolute paths, but canonical paths might sometimes be preferred (e.g. in testing, for cross-platform compatibility, or for debug purpose).
Definition at line 365 of file PPath.cc.
References PLearn::canonical(), and canonical_in_errors.
PPath PLearn::PPath::up | ( | ) | const |
Return a PPath pointing to the parent directory of the PPath, assuming the PPath represents a directory: you should never call this method on a PPath pointing to a file, but instead use file_path.dirname().up(). The final '/' in the PPath is ignored.
If there is no parent directory, throws a PLERROR.
PPath::up examples:
PPath("/").up() // PLERROR PPath("").up() // PLERROR PPath("/foo").up() // "/" PPath("foo").up() // "." PPath(".").up() // ".." PPath("foo/bar").up() // "foo" PPath("foo/bar/").up() // "foo" PPath("foo/bar/hi.cc").up() // "foo/bar", but never do this
Definition at line 928 of file PPath.cc.
References errorDisplay(), isEmpty(), isRoot(), and PLERROR.
Referenced by PLearn::force_mkdir(), and hostname().
{ if (isEmpty() || isRoot()) // Note that the following line has more than 80 characters, but it is // the simplest way to avoid issues in tests, as the line number of // this error is displayed, and it may be ambiguous if it spans // multiple lines. PLERROR("In PPath::up - Cannot go up on directory '%s'", errorDisplay().c_str()); return *this / ".."; }
string PLearn::PPath::_protocol [protected] |
Even if the default protocol is considered to be the file protocol, the _protocol member keeps the exact protocol value in the string. The protocol() method, however, returns FILE_PROTOCOL if the protocol was not specified.
Definition at line 279 of file PPath.h.
Referenced by absolute(), addProtocol(), dirname(), isabs(), parseProtocol(), removeProtocol(), and resolveDots().
bool PLearn::PPath::canonical_in_errors = false [static, private] |
Whether or not to display the canonical path in errorDisplay().
Default value is 'false', and it can be modified through the setCanonicalInErrors(..) function.
Definition at line 510 of file PPath.h.
Referenced by errorDisplay(), and setCanonicalInErrors().