1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Pathname.cc
14 #include "zypp/base/String.h"
15 #include "zypp/Pathname.h"
20 ///////////////////////////////////////////////////////////////////
22 { /////////////////////////////////////////////////////////////////
23 ///////////////////////////////////////////////////////////////////
25 { /////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
31 ///////////////////////////////////////////////////////////////////
33 // CLASS NAME : DirStack
35 /** silly helper to build Pathnames.
45 Dir( const string & n = "" ) {
75 DirStack() { top = bot = 0; }
81 void Push( const string & n ) {
82 if ( n.empty() || n == "." ) { // '.' or '/' only for bot
85 } else if ( n == ".." && top ) {
86 if ( top->name == "" ) // "/.." ==> "/"
89 if ( top->name != "." && top->name != ".." ) { // "somedir/.." ==> ""
93 // "../.." "./.." stays
96 Dir * d = new Dir( n );
111 for ( Dir * d = bot; d; d = d->up ) {
122 /////////////////////////////////////////////////////////////////
124 ///////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////
128 // METHOD NAME : Pathname::_assign
129 // METHOD TYPE : void
131 void Pathname::_assign( const string & name_tv )
136 if ( name_t.empty() )
142 char * Buf_aci = new char[name_tv.length() + 1];
143 char * W_pci = Buf_aci;
144 const char * R_pci = name_tv.c_str();
147 if ( name_t.length() >= 2
149 && ( ( 'a' <= name_t[0] && name_t[0] <= 'z' )
150 || ( 'A' <= name_t[0] && name_t[0] <= 'Z' ) ) ) {
151 Tprfx = name_t.substr( 0, 2 );
157 if ( *R_pci == '/' ) {
161 Stack_Ci.Push( "." );
168 if ( W_pci != Buf_aci ) {
171 Stack_Ci.Push( Buf_aci );
182 name_t = Tprfx + Stack_Ci.str();
185 ///////////////////////////////////////////////////////////////////
187 // METHOD NAME : Pathname::dirname
188 // METHOD TYPE : Pathname
190 Pathname Pathname::dirname( const Pathname & name_tv )
192 if ( name_tv.empty() )
195 Pathname ret_t( name_tv );
196 string::size_type idx = ret_t.name_t.find_last_of( '/' );
198 if ( idx == string::npos ) {
199 ret_t.name_t.erase( ret_t.prfx_i );
201 } else if ( idx == ret_t.prfx_i ) {
202 ret_t.name_t.erase( ret_t.prfx_i );
205 ret_t.name_t.erase( idx );
211 ///////////////////////////////////////////////////////////////////
213 // METHOD NAME : Pathname::basename
214 // METHOD TYPE : string
216 string Pathname::basename( const Pathname & name_tv )
218 if ( name_tv.empty() )
221 string ret_t( name_tv.asString() );
222 ret_t.erase( 0, name_tv.prfx_i );
223 string::size_type idx = ret_t.find_last_of( '/' );
224 if ( idx != string::npos ) {
225 ret_t.erase( 0, idx+1 );
231 ///////////////////////////////////////////////////////////////////
233 // METHOD NAME : Pathname::asUrl
236 Url Pathname::asUrl() const
238 Url ret( "dir:///" );
239 ret.setPathName( asString() );
243 std::string Pathname::showRoot( const Pathname & root_r, const Pathname & path_r )
245 return str::Str() << "(" << root_r << ")" << path_r;
248 std::string Pathname::showRootIf( const Pathname & root_r, const Pathname & path_r )
250 if ( root_r.empty() || root_r == "/" )
251 return path_r.asString();
252 return showRoot( root_r, path_r );
255 ///////////////////////////////////////////////////////////////////
257 // METHOD NAME : Pathname::extension
258 // METHOD TYPE : string
260 string Pathname::extension( const Pathname & name_tv )
262 if ( name_tv.empty() )
265 string base( basename( name_tv ) );
266 string::size_type pos = base.rfind( '.' );
267 if ( pos == string::npos )
269 return base.substr( pos );
272 ///////////////////////////////////////////////////////////////////
274 // METHOD NAME : Pathname::assertprefix
275 // METHOD TYPE : Pathname
277 Pathname Pathname::assertprefix( const Pathname & root_r, const Pathname & path_r )
281 || str::hasPrefix( path_r.asString(), root_r.asString() ) )
283 return root_r / path_r;
286 ///////////////////////////////////////////////////////////////////
288 // METHOD NAME : Pathname::cat
289 // METHOD TYPE : Pathname
291 Pathname Pathname::cat( const Pathname & name_tv, const Pathname & add_tv )
293 if ( add_tv.empty() )
295 if ( name_tv.empty() )
298 string ret_ti( add_tv.asString() );
299 ret_ti.replace( 0, add_tv.prfx_i, "/" );
301 return name_tv.asString() + ret_ti;
304 ///////////////////////////////////////////////////////////////////
306 // METHOD NAME : Pathname::Extend
307 // METHOD TYPE : Pathname
309 Pathname Pathname::extend( const Pathname & l, const string & r )
311 return l.asString() + r;
314 /////////////////////////////////////////////////////////////////
315 } // namespace filesystem
316 ///////////////////////////////////////////////////////////////////
317 /////////////////////////////////////////////////////////////////
319 ///////////////////////////////////////////////////////////////////