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 == '/' || *R_pci == '\\' ) {
161 Stack_Ci.Push( "." );
169 if ( W_pci != Buf_aci ) {
172 Stack_Ci.Push( Buf_aci );
183 name_t = Tprfx + Stack_Ci.str();
186 ///////////////////////////////////////////////////////////////////
188 // METHOD NAME : Pathname::dirname
189 // METHOD TYPE : Pathname
191 Pathname Pathname::dirname( const Pathname & name_tv )
193 if ( name_tv.empty() )
196 Pathname ret_t( name_tv );
197 string::size_type idx = ret_t.name_t.find_last_of( '/' );
199 if ( idx == string::npos ) {
200 ret_t.name_t.erase( ret_t.prfx_i );
202 } else if ( idx == ret_t.prfx_i ) {
203 ret_t.name_t.erase( ret_t.prfx_i );
206 ret_t.name_t.erase( idx );
212 ///////////////////////////////////////////////////////////////////
214 // METHOD NAME : Pathname::basename
215 // METHOD TYPE : string
217 string Pathname::basename( const Pathname & name_tv )
219 if ( name_tv.empty() )
222 string ret_t( name_tv.asString() );
223 ret_t.erase( 0, name_tv.prfx_i );
224 string::size_type idx = ret_t.find_last_of( '/' );
225 if ( idx != string::npos ) {
226 ret_t.erase( 0, idx+1 );
232 ///////////////////////////////////////////////////////////////////
234 // METHOD NAME : Pathname::asUrl
237 Url Pathname::asUrl() const
239 Url ret( "dir:///" );
240 ret.setPathName( asString() );
244 ///////////////////////////////////////////////////////////////////
246 // METHOD NAME : Pathname::extension
247 // METHOD TYPE : string
249 string Pathname::extension( const Pathname & name_tv )
251 if ( name_tv.empty() )
254 string base( basename( name_tv ) );
255 string::size_type pos = base.rfind( '.' );
256 if ( pos == string::npos )
258 return base.substr( pos );
261 ///////////////////////////////////////////////////////////////////
263 // METHOD NAME : Pathname::assertprefix
264 // METHOD TYPE : Pathname
266 Pathname Pathname::assertprefix( const Pathname & root_r, const Pathname & path_r )
270 || str::hasPrefix( path_r.asString(), root_r.asString() ) )
272 return root_r / path_r;
275 ///////////////////////////////////////////////////////////////////
277 // METHOD NAME : Pathname::cat
278 // METHOD TYPE : Pathname
280 Pathname Pathname::cat( const Pathname & name_tv, const Pathname & add_tv )
282 if ( add_tv.empty() )
284 if ( name_tv.empty() )
287 string ret_ti( add_tv.asString() );
288 ret_ti.replace( 0, add_tv.prfx_i, "/" );
290 return name_tv.asString() + ret_ti;
293 ///////////////////////////////////////////////////////////////////
295 // METHOD NAME : Pathname::Extend
296 // METHOD TYPE : Pathname
298 Pathname Pathname::extend( const Pathname & l, const string & r )
300 return l.asString() + r;
303 /////////////////////////////////////////////////////////////////
304 } // namespace filesystem
305 ///////////////////////////////////////////////////////////////////
306 /////////////////////////////////////////////////////////////////
308 ///////////////////////////////////////////////////////////////////