From a80fb22bc63e890632d704201355ce0f6eb71bb8 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Thu, 8 Dec 2005 16:56:21 +0000 Subject: [PATCH] backup --- zypp/Makefile.am | 3 +- zypp/NeedAType.h | 3 - zypp/Pathname.cc | 487 +++++++++++++++++++++++++------------------------------ zypp/Pathname.h | 182 ++++++++++++--------- 4 files changed, 328 insertions(+), 347 deletions(-) diff --git a/zypp/Makefile.am b/zypp/Makefile.am index 6afdca2..d8758e6 100644 --- a/zypp/Makefile.am +++ b/zypp/Makefile.am @@ -17,6 +17,7 @@ include_HEADERS = NeedAType.h \ Resolvable.h \ ResTraits.h \ Package.h \ + Pathname.h \ Selection.h \ Message.h \ Script.h \ @@ -47,6 +48,7 @@ lib@PACKAGE@_la_SOURCES = \ Resolvable.cc \ ResTraits.cc \ Package.cc \ + Pathname.cc \ Selection.cc \ Message.cc \ Script.cc \ @@ -55,7 +57,6 @@ lib@PACKAGE@_la_SOURCES = \ Changelog.cc \ \ ExternalProgram.cc \ - Pathname.cc \ PathInfo.cc \ Digest.cc diff --git a/zypp/NeedAType.h b/zypp/NeedAType.h index 80b0d02..85ed08c 100644 --- a/zypp/NeedAType.h +++ b/zypp/NeedAType.h @@ -68,9 +68,6 @@ namespace zypp */ typedef std::string Url; - /** Convenient handling of pathnmes. */ - typedef std::string Pathname; - /** Single line of (human readable) text. probabely sufficient as typedef. we may use it to classify the various strings and string lists within resolvable and other classes. diff --git a/zypp/Pathname.cc b/zypp/Pathname.cc index 6c0c999..7958684 100644 --- a/zypp/Pathname.cc +++ b/zypp/Pathname.cc @@ -1,292 +1,255 @@ /*---------------------------------------------------------------------\ -| ____ _ __ __ ___ | -| |__ / \ / / . \ . \ | -| / / \ V /| _/ _/ | -| / /__ | | | | | | | -| /_____||_| |_| |_| | -| | -\---------------------------------------------------------------------*/ -/** \file zypp/Pathname.cc - * - * \todo replace by Blocxx + | ____ _ __ __ ___ | + | |__ / \ / / . \ . \ | + | / / \ V /| _/ _/ | + | / /__ | | | | | | | + | /_____||_| |_| |_| | + | | + \---------------------------------------------------------------------*/ +/** \file zypp/Pathname.cc * */ - -#include - #include "zypp/Pathname.h" -using namespace std; - -namespace zypp { +using std::string; /////////////////////////////////////////////////////////////////// -// -// CLASS NAME : DirStack -// -// DESCRIPTION : -// -class DirStack { - - struct Dir { - - Dir * up; - Dir * dn; - string name; - - Dir( const string & n = "" ) { - name = n; - up = dn = 0; - } - - ~Dir() { - if ( up ) - up->dn = dn; - if ( dn ) - dn->up = up; - } - }; - - Dir * top; - Dir * bot; - - void Pop() { - if ( !top ) - return; - top = top->dn; - if ( top ) - delete top->up; - else { - delete bot; - bot = 0; - } - } - - public: +namespace zypp +{ ///////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + namespace + { ///////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : DirStack + // + /** silly helper to build Pathnames. + */ + class DirStack { + + struct Dir { + + Dir * up; + Dir * dn; + string name; + + Dir( const string & n = "" ) { + name = n; + up = dn = 0; + } + + ~Dir() { + if ( up ) + up->dn = dn; + if ( dn ) + dn->up = up; + } + }; + + Dir * top; + Dir * bot; + + void Pop() { + if ( !top ) + return; + top = top->dn; + if ( top ) + delete top->up; + else { + delete bot; + bot = 0; + } + } - DirStack() { top = bot = 0; } - ~DirStack() { - while ( bot ) - Pop(); - } + public: - void Push( const string & n ) { - if ( n.empty() || n == "." ) { // '.' or '/' only for bot - if ( bot ) - return; - } else if ( n == ".." && top ) { - if ( top->name == "" ) // "/.." ==> "/" - return; - - if ( top->name != "." && top->name != ".." ) { // "somedir/.." ==> "" - Pop(); - return; - } - // "../.." "./.." stays + DirStack() { top = bot = 0; } + ~DirStack() { + while ( bot ) + Pop(); } - Dir * d = new Dir( n ); - if ( !top ) - top = bot = d; - else { - top->up = d; - d->dn = top; - d->up = 0; - top = d; + void Push( const string & n ) { + if ( n.empty() || n == "." ) { // '.' or '/' only for bot + if ( bot ) + return; + } else if ( n == ".." && top ) { + if ( top->name == "" ) // "/.." ==> "/" + return; + + if ( top->name != "." && top->name != ".." ) { // "somedir/.." ==> "" + Pop(); + return; + } + // "../.." "./.." stays + } + + Dir * d = new Dir( n ); + if ( !top ) + top = bot = d; + else { + top->up = d; + d->dn = top; + d->up = 0; + top = d; + } } - } - string str() { - if ( !bot ) - return ""; - string ret; - for ( Dir * d = bot; d; d = d->up ) { - if ( d != bot ) - ret += "/"; - ret += d->name; + string str() { + if ( !bot ) + return ""; + string ret; + for ( Dir * d = bot; d; d = d->up ) { + if ( d != bot ) + ret += "/"; + ret += d->name; + } + if ( ret.empty() ) + return "/"; + return ret; } - if ( ret.empty() ) - return "/"; - return ret; - } -}; + }; + + ///////////////////////////////////////////////////////////////// + } // namespace + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // + // METHOD NAME : Pathname::_assign + // METHOD TYPE : void + // + void Pathname::_assign( const string & name_tv ) + { + prfx_i = 0; + name_t = name_tv; + + if ( name_t.empty() ) + return; -/////////////////////////////////////////////////////////////////// + string Tprfx; + DirStack Stack_Ci; + + char * Buf_aci = new char[name_tv.length() + 1]; + char * W_pci = Buf_aci; + const char * R_pci = name_tv.c_str(); + + // check for prefix + if ( name_t.length() >= 2 + && name_t[1] == ':' + && ( 'a' <= name_t[0] && name_t[0] <= 'z' + || 'A' <= name_t[0] && name_t[0] <= 'Z' ) ) { + Tprfx = name_t.substr( 0, 2 ); + prfx_i = 2; + R_pci += 2; + } + // rel or abs path + if ( *R_pci == '/' || *R_pci == '\\' ) { + Stack_Ci.Push( "" ); + ++R_pci; + } else { + Stack_Ci.Push( "." ); + } -/////////////////////////////////////////////////////////////////// -// -// -// METHOD NAME : Pathname::_assign -// METHOD TYPE : void -// -// DESCRIPTION : -// -void Pathname::_assign( const string & name_tv ) -{ - prfx_i = 0; - name_t = name_tv; - - if ( name_t.empty() ) - return; - - string Tprfx; - DirStack Stack_Ci; - - char * Buf_aci = new char[name_tv.length() + 1]; - char * W_pci = Buf_aci; - const char * R_pci = name_tv.c_str(); - - // check for prefix - if ( name_t.length() >= 2 - && name_t[1] == ':' - && ( 'a' <= name_t[0] && name_t[0] <= 'z' - || 'A' <= name_t[0] && name_t[0] <= 'Z' ) ) { - Tprfx = name_t.substr( 0, 2 ); - prfx_i = 2; - R_pci += 2; - } + do { + switch ( *R_pci ) { + case '/': + case '\\': + case '\0': + if ( W_pci != Buf_aci ) { + *W_pci = '\0'; + W_pci = Buf_aci; + Stack_Ci.Push( Buf_aci ); + } + break; + + default: + *W_pci++ = *R_pci; + break; + } + } while( *R_pci++ ); - // rel or abs path - if ( *R_pci == '/' || *R_pci == '\\' ) { - Stack_Ci.Push( "" ); - ++R_pci; - } else { - Stack_Ci.Push( "." ); + delete Buf_aci; + name_t = Tprfx + Stack_Ci.str(); } - do { - switch ( *R_pci ) { - case '/': - case '\\': - case '\0': - if ( W_pci != Buf_aci ) { - *W_pci = '\0'; - W_pci = Buf_aci; - Stack_Ci.Push( Buf_aci ); - } - break; - - default: - *W_pci++ = *R_pci; - break; + /////////////////////////////////////////////////////////////////// + // + // METHOD NAME : Pathname::dirname + // METHOD TYPE : Pathname + // + Pathname Pathname::dirname( const Pathname & name_tv ) + { + if ( name_tv.empty() ) + return ""; + + Pathname ret_t( name_tv ); + string::size_type idx = ret_t.name_t.find_last_of( '/' ); + + if ( idx == string::npos ) { + ret_t.name_t.erase( ret_t.prfx_i ); + ret_t.name_t += "."; + } else if ( idx == ret_t.prfx_i ) { + ret_t.name_t.erase( ret_t.prfx_i ); + ret_t.name_t += "/"; + } else { + ret_t.name_t.erase( idx ); } - } while( *R_pci++ ); - - delete Buf_aci; - name_t = Tprfx + Stack_Ci.str(); -} -/////////////////////////////////////////////////////////////////// -// -// -// METHOD NAME : Pathname::dirname -// METHOD TYPE : Pathname -// -// DESCRIPTION : -// -Pathname Pathname::dirname( const Pathname & name_tv ) -{ - if ( name_tv.empty() ) - return ""; - - Pathname ret_t( name_tv ); - string::size_type idx = ret_t.name_t.find_last_of( '/' ); - - if ( idx == string::npos ) { - ret_t.name_t.erase( ret_t.prfx_i ); - ret_t.name_t += "."; - } else if ( idx == ret_t.prfx_i ) { - ret_t.name_t.erase( ret_t.prfx_i ); - ret_t.name_t += "/"; - } else { - ret_t.name_t.erase( idx ); + return ret_t; } - return ret_t; -} + /////////////////////////////////////////////////////////////////// + // + // METHOD NAME : Pathname::basename + // METHOD TYPE : string + // + string Pathname::basename( const Pathname & name_tv ) + { + if ( name_tv.empty() ) + return ""; + + string ret_t( name_tv.asString() ); + ret_t.erase( 0, name_tv.prfx_i ); + string::size_type idx = ret_t.find_last_of( '/' ); + if ( idx != string::npos ) { + ret_t.erase( 0, idx+1 ); + } -/////////////////////////////////////////////////////////////////// -// -// -// METHOD NAME : Pathname::basename -// METHOD TYPE : string -// -// DESCRIPTION : -// -string Pathname::basename( const Pathname & name_tv ) -{ - if ( name_tv.empty() ) - return ""; - - string ret_t( name_tv.asString() ); - ret_t.erase( 0, name_tv.prfx_i ); - string::size_type idx = ret_t.find_last_of( '/' ); - if ( idx != string::npos ) { - ret_t.erase( 0, idx+1 ); + return ret_t; } - return ret_t; -} - -/////////////////////////////////////////////////////////////////// -// -// -// METHOD NAME : Pathname::cat -// METHOD TYPE : Pathname -// -// DESCRIPTION : -// -Pathname Pathname::cat( const Pathname & name_tv, const Pathname & add_tv ) -{ - if ( add_tv.empty() ) - return name_tv; - if ( name_tv.empty() ) - return add_tv; - - string ret_ti( add_tv.asString() ); - ret_ti.replace( 0, add_tv.prfx_i, "/" ); - - return name_tv.asString() + ret_ti; -} - -/////////////////////////////////////////////////////////////////// -// -// -// METHOD NAME : Pathname::Extend -// METHOD TYPE : Pathname -// -// DESCRIPTION : -// -Pathname Pathname::extend( const Pathname & l, const string & r ) -{ - return l.asString() + r; -} + /////////////////////////////////////////////////////////////////// + // + // METHOD NAME : Pathname::cat + // METHOD TYPE : Pathname + // + Pathname Pathname::cat( const Pathname & name_tv, const Pathname & add_tv ) + { + if ( add_tv.empty() ) + return name_tv; + if ( name_tv.empty() ) + return add_tv; + + string ret_ti( add_tv.asString() ); + ret_ti.replace( 0, add_tv.prfx_i, "/" ); + + return name_tv.asString() + ret_ti; + } -/////////////////////////////////////////////////////////////////// -// -// -// METHOD NAME : Pathname::equal -// METHOD TYPE : bool -// -// DESCRIPTION : -// -bool Pathname::equal( const Pathname & l, const Pathname & r ) -{ - return l.asString() == r.asString(); -} - -/****************************************************************** -** -** -** FUNCTION NAME : operator<< -** FUNCTION TYPE : inline std::ostream & -** -** DESCRIPTION : -*/ -ostream & operator<<( ostream & str, const Pathname & obj ) -{ - return str << obj.asString(); -} + /////////////////////////////////////////////////////////////////// + // + // METHOD NAME : Pathname::Extend + // METHOD TYPE : Pathname + // + Pathname Pathname::extend( const Pathname & l, const string & r ) + { + return l.asString() + r; + } + ///////////////////////////////////////////////////////////////// } // namespace zypp +/////////////////////////////////////////////////////////////////// diff --git a/zypp/Pathname.h b/zypp/Pathname.h index 5490283..0de0741 100644 --- a/zypp/Pathname.h +++ b/zypp/Pathname.h @@ -6,116 +6,136 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ -/** \file zypp/Pathname.h - * - * \todo replace by Blocxx +/** \file zypp/Pathname.h * */ - #ifndef ZYPP_PATHNAME_H #define ZYPP_PATHNAME_H #include #include -namespace zypp { - /////////////////////////////////////////////////////////////////// -// -// CLASS NAME : Pathname -// -// DESCRIPTION : -// -class Pathname { - - private: - - std::string::size_type prfx_i; - std::string name_t; - - protected: - - void _assign( const std::string & name_tv ); - +namespace zypp +{ ///////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : Pathname + // + /** Pathname. + * + * Always stores normalized paths (no inner '.' or '..' components + * and no consecutive '/'es). Concatenation automatically adds + * the path separator '/'. + * + * \todo Add support for handling extensions incl. stripping + * extensions from basename (basename("/path/foo.baa", ".baa") ==> "foo") + * \todo Review. Maybe use COW pimpl, ckeck storage. + */ + class Pathname + { public: - - virtual ~Pathname() {} - - Pathname() { - prfx_i = 0; - name_t = ""; - } - Pathname( const Pathname & path_tv ) { + /** Default ctor: an empty path. */ + Pathname() + : prfx_i( 0 ) + {} + + /** Ctor from string. */ + Pathname( const std::string & name_tv ) + { _assign( name_tv ); } + + /** Ctor from char*. */ + Pathname( const char * name_tv ) + { _assign( name_tv ? name_tv : "" ); } + + /** Assign */ + Pathname & operator=( const Pathname & path_tv ) + { prfx_i = path_tv.prfx_i; name_t = path_tv.name_t; - } - Pathname( const std::string & name_tv ) { - _assign( name_tv ); - } - Pathname( const char * name_tv ) { - _assign( name_tv ? name_tv : "" ); + return *this; } - Pathname & operator= ( const Pathname & path_tv ); - Pathname & operator+=( const Pathname & path_tv ); + /** Concatenate and assing. \see cat */ + Pathname & operator+=( const Pathname & path_tv ) + { return( *this = cat( *this, path_tv ) ); } - const std::string & asString() const { return name_t; } + /** String representation. */ + const std::string & asString() const + { return name_t; } - bool empty() const { return !name_t.size(); } + /** Test for an empty path. */ + bool empty() const { return name_t.empty(); } + /** Test for an absolute path. */ bool absolute() const { return !empty() && name_t[prfx_i] == '/'; } + /** Test for a relative path. */ bool relative() const { return !empty() && name_t[prfx_i] != '/'; } - Pathname dirname() const { return dirname( *this ); } - std::string basename() const { return basename( *this ); } - Pathname absolutename() const { return absolutename( *this ); } - Pathname relativename() const { return relativename( *this ); } - - static Pathname dirname ( const Pathname & name_tv ); - static std::string basename ( const Pathname & name_tv ); - static Pathname absolutename( const Pathname & name_tv ) { return name_tv.relative() ? cat( "/", name_tv ) : name_tv; } - static Pathname relativename( const Pathname & name_tv ) { return name_tv.absolute() ? cat( ".", name_tv ) : name_tv; } - - Pathname cat( const Pathname & r ) const { return cat( *this, r ); } + /** Return all but the last component od this path. */ + Pathname dirname() const { return dirname( *this ); } + static Pathname dirname( const Pathname & name_tv ); + + /** Return the last component of this path. */ + std::string basename() const { return basename( *this ); } + static std::string basename( const Pathname & name_tv ); + + /** Return this path, adding a leading '/' if relative. */ + Pathname absolutename() const { return absolutename( *this ); } + static Pathname absolutename( const Pathname & name_tv ) + { return name_tv.relative() ? cat( "/", name_tv ) : name_tv; } + + /** Return this path, removing a leading '/' if absolute.*/ + Pathname relativename() const { return relativename( *this ); } + static Pathname relativename( const Pathname & name_tv ) + { return name_tv.absolute() ? cat( ".", name_tv ) : name_tv; } + + /** Concatenation of pathnames. + * \code + * "foo" + "baa" ==> "foo/baa" + * "foo/" + "baa" ==> "foo/baa" + * "foo" + "/baa" ==> "foo/baa" + * "foo/" + "/baa" ==> "foo/baa" + * \endcode + */ + Pathname cat( const Pathname & r ) const { return cat( *this, r ); } static Pathname cat( const Pathname & l, const Pathname & r ); - Pathname extend( const std::string & r ) const { return extend( *this, r ); } + /** Append string \a r to the last component of the path. + * \code + * "foo/baa".extend( ".h" ) ==> "foo/baa.h" + * \endcode + */ + Pathname extend( const std::string & r ) const { return extend( *this, r ); } static Pathname extend( const Pathname & l, const std::string & r ); - bool equal( const Pathname & r ) const { return equal( *this, r ); } - static bool equal( const Pathname & l, const Pathname & r ); -}; - -/////////////////////////////////////////////////////////////////// - -inline bool operator==( const Pathname & l, const Pathname & r ) { - return Pathname::equal( l, r ); -} + private: + std::string::size_type prfx_i; + std::string name_t; -inline bool operator!=( const Pathname & l, const Pathname & r ) { - return !Pathname::equal( l, r ); -} + void _assign( const std::string & name_tv ); + }; + /////////////////////////////////////////////////////////////////// -inline Pathname operator+( const Pathname & l, const Pathname & r ) { - return Pathname::cat( l, r ); -} + /** \relates Pathname */ + inline bool operator==( const Pathname & l, const Pathname & r ) + { return l.asString() == r.asString(); } -inline Pathname & Pathname::operator=( const Pathname & path_tv ) { - if ( &path_tv != this ) { - prfx_i = path_tv.prfx_i; - name_t = path_tv.name_t; - } - return *this; -} + /** \relates Pathname */ + inline bool operator!=( const Pathname & l, const Pathname & r ) + { return l.asString() != r.asString(); } -inline Pathname & Pathname::operator+=( const Pathname & path_tv ) { - return( *this = *this + path_tv ); -} + /** \relates Pathname Concatenate two Pathname. */ + inline Pathname operator+( const Pathname & l, const Pathname & r ) + { return Pathname::cat( l, r ); } -/////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// -extern std::ostream & operator<<( std::ostream & str, const Pathname & obj ); + /** \relates Pathname Stream output */ + inline std::ostream & operator<<( std::ostream & str, const Pathname & obj ) + { return str << obj.asString(); } -/////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// } // namespace zypp - +/////////////////////////////////////////////////////////////////// #endif // ZYPP_PATHNAME_H -- 2.7.4