From: stephan b. <sg...@us...> - 2004-12-23 02:41:31
|
Update of /cvsroot/pclasses/pclasses2/src/System In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23520/src/System Added Files: PathFinder.cpp Log Message: egg --- NEW FILE: PathFinder.cpp --- // Author: stephan beal <st...@s1...> // License: Public Domain #include <iostream> #include <stdlib.h> // getenv() #if WIN32 # include <io.h> # include <stdio.h> #else # include <unistd.h> #endif #include "PathFinder.hpp" // CERR is a drop-in replacement for std::cerr, but slightly more // decorative. #ifndef CERR #define CERR std::cerr << __FILE__ << ":" << std::dec << __LINE__ << " : " #endif using std::string; using std::ostream; namespace P { namespace System { PathFinder::~PathFinder() { DTOROUT(PathFinder) << this->pathString() << std::endl; } PathFinder::PathFinder( const string & p, const string & e, const string & pathsep ) { this->pathSeparator( pathsep ); this->path( p ); this->extensions( e ); } const string & PathFinder::pathSeparator() const { return ( ( PathFinder * ) this )->pathseparator; } void PathFinder::pathSeparator( const string & sep ) { this->pathseparator = sep; } std::string PathFinder::joinList( const string_list & list, const std::string & separator ) const { std::string ret; unsigned long count = list.size(); unsigned long at = 0; string_list::const_iterator it = list.begin(); string_list::const_iterator et = list.end(); for(; it != et; ++it ) { ret += (*it); if( ++at != count ) ret += separator; } return ret; } string PathFinder::pathString() const { return this->joinList( this->paths, this->pathseparator ); } const PathFinder::string_list & PathFinder::path() const { return this->paths; } string PathFinder::extensionsString() const { return this->joinList( this->exts, this->pathseparator ); } const PathFinder::string_list & PathFinder::extensions() const { return this->exts; } size_t tokenize_to_list( const std::string & str, std::list<std::string> & li, const std::string & sep ) { // internal helper function if( str.empty() ) return 0; size_t c = 0; std::string token; std::string::size_type sz = str.size(); for( std::string::size_type i = 0; i < sz; i++ ) { if( sz-1 == i ) token += str[i]; if( str.find( sep, i ) == i || (sz-1 == i) ) { //CERR << "token="<<token<<std::endl; li.push_back( token ); token = ""; i += sep.size() - 1; continue; } token += str[i]; } return c; } size_t PathFinder::path( const string & p ) { this->paths.erase( this->paths.begin(), this->paths.end() ); return tokenize_to_list( p, this->paths, this->pathseparator ); } size_t PathFinder::path( const PathFinder::string_list & p ) { this->paths = p; return this->paths.size(); } void PathFinder::addPath( const string & p ) { tokenize_to_list( p, this->paths, this->pathseparator ); } size_t PathFinder::extensions( const string & p ) { this->exts.erase( this->exts.begin(), this->exts.end() ); return tokenize_to_list( p, this->exts, this->pathseparator ); } size_t PathFinder::extensions( const PathFinder::string_list & e ) { this->exts = e; return this->exts.size(); } void PathFinder::addExtension( const string & p ) { tokenize_to_list( p, this->exts, this->pathseparator ); } // static bool PathFinder::isAccessible( const string & path ) { #if WIN32 # define CHECKACCESS _access # define CHECKRIGHTS 0 #else # define CHECKACCESS access # define CHECKRIGHTS F_OK #endif return 0 == CHECKACCESS( path.c_str(), CHECKRIGHTS ); #undef CHECKACCESS #undef CHECKRIGHTS } string PathFinder::basename( const std::string & name ) { string::size_type slashat = name.find_last_of( PathFinder::dirSeparator() ); if ( slashat == string::npos ) return name; return name.substr( slashat + 1 ); } std::string PathFinder::dirSeparator() { #if WIN32 return std::string( "\\" ); #else return std::string( "/" ); #endif } string PathFinder::find( const string & resource, bool check_cache ) const { //static const std::string NOT_FOUND = "PathFinder::find() : no findie"; if( resource.empty() ) return resource; #define CHECKPATH(CHECKAT) \ if( ! CHECKAT.empty() && PathFinder::isAccessible( CHECKAT ) ) \ { this->hitcache[resource] = CHECKAT; return CHECKAT; } //CERR << "find( " << resource << " )" << std::endl; if( check_cache ) { std::map <std::string,std::string>::iterator mapiter; mapiter = this->hitcache.find( resource ); if( this->hitcache.end() != mapiter ) return (*mapiter).second; } CHECKPATH( resource ); string_list::const_iterator piter = this->paths.begin(); string_list::const_iterator eiter = this->exts.begin(); string path; string ext; if ( PathFinder::isAccessible( resource ) ) return resource; piter = this->paths.begin(); string checkhere; while ( piter != this->paths.end() ) { path = ( *piter ); if ( !path.empty() ) { path += PathFinder::dirSeparator(); } ++piter; checkhere = path + resource; //CERR << "find( " << resource << " ) checking " << checkhere << std::endl; CHECKPATH( checkhere ); eiter = this->exts.begin(); while ( eiter != this->exts.end() ) { ext = ( *eiter ); ++eiter; checkhere = path + resource + ext; //CERR << "find( " << resource << " ) checking " << checkhere << std::endl; CHECKPATH( checkhere ); } } //CERR << "find( "<<resource<<" ): not found :(" << std::endl; // so arguable: // this->hitcache[resource] = ""; return string(); } void PathFinder::clearCache() { this->hitcache.clear(); } // /** // bin_PathFinder is a PathFinder which uses the environment's PATH by default. // */ // class bin_PathFinder:public PathFinder // { // public: // bin_PathFinder(); // virtual ~ bin_PathFinder(); // }; // bin_PathFinder::bin_PathFinder() : PathFinder( ::getenv( "PATH" ) ) // { // this->extensions( ".sh" ); // #if CONFIG_HAVE_CYGWIN // this->extensions(".exe:.bat"); // #endif // } // bin_PathFinder::~bin_PathFinder() // { // } }} // namespaces |