Fix Werrors with GCC-14.1.0
[platform/upstream/libzypp.git] / zypp / Pathname.h
1
2 /*---------------------------------------------------------------------\
3 |                          ____ _   __ __ ___                          |
4 |                         |__  / \ / / . \ . \                         |
5 |                           / / \ V /|  _/  _/                         |
6 |                          / /__ | | | | | |                           |
7 |                         /_____||_| |_| |_|                           |
8 |                                                                      |
9 \---------------------------------------------------------------------*/
10 /** \file       zypp/Pathname.h
11  *
12 */
13 #ifndef ZYPP_PATHNAME_H
14 #define ZYPP_PATHNAME_H
15
16 #include <iosfwd>
17 #include <string>
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22
23   class Url;
24
25   ///////////////////////////////////////////////////////////////////
26   namespace filesystem
27   { /////////////////////////////////////////////////////////////////
28
29     ///////////////////////////////////////////////////////////////////
30     //
31     //  CLASS NAME : Pathname
32     //
33     /** Pathname.
34      *
35      * \note For convenience Pathname is available as zypp::Pathname too.
36      *
37      * Always stores normalized paths (no inner '.' or '..' components
38      * and no consecutive '/'es). Concatenation automatically adds
39      * the path separator '/'.
40      *
41      * \todo Add support for handling extensions incl. stripping
42      * extensions from basename (basename("/path/foo.baa", ".baa") ==> "foo")
43     */
44     class Pathname
45     {
46     public:
47       /** Default ctor: an empty path. */
48       Pathname()
49       {}
50
51       /** Ctor from string. */
52       Pathname( const std::string & name_r )
53       { _assign( name_r ); }
54
55       /** Ctor from char*. */
56       Pathname( const char * name_r )
57       { _assign( name_r ? name_r : "" ); }
58
59       /** Copy Ctor */
60       Pathname( const Pathname & rhs )
61       : _name( rhs._name )
62       {}
63
64       /** Swap */
65       friend void swap( Pathname & lhs, Pathname & rhs )
66       {
67         using std::swap;
68         swap( lhs._name, rhs._name );
69       }
70
71       /** Move Ctor */
72       Pathname( Pathname && tmp )
73       : _name( std::move( tmp._name ) )
74       {}
75
76       /** Assign */
77       Pathname & operator=( Pathname rhs )
78       { swap( *this, rhs ); return *this; }
79
80       /** Concatenate and assign. \see cat */
81       Pathname & operator/=( const Pathname & path_tv )
82       { return( *this = cat( *this, path_tv ) ); }
83
84       /** Concatenate and assign. \see cat
85        * \deprecated: use /=
86       */
87       Pathname & operator+=( const Pathname & path_tv )
88       { return( *this = cat( *this, path_tv ) ); }
89
90       /** String representation. */
91       const std::string & asString() const
92       { return _name; }
93
94       /** String representation as "(root)/path" */
95       static std::string showRoot( const Pathname & root_r, const Pathname & path_r );
96
97       /** String representation as "(root)/path", unless \a root is \c "/" or empty. */
98       static std::string showRootIf( const Pathname & root_r, const Pathname & path_r );
99
100       /** Url representation using \c scheme_r schema . */
101       Url asUrl( const std::string & scheme_r ) const;
102       /** \overload using \c dir schema. */
103       Url asUrl() const;
104       /** \overload using \c dir schema. */
105       Url asDirUrl() const;
106       /** \overload using \c file schema. */
107       Url asFileUrl() const;
108
109       /** String representation. */
110       const char * c_str() const
111       { return _name.c_str(); }
112
113       /** Test for an empty path. */
114       bool empty()    const { return _name.empty(); }
115       /** Test for an absolute path. */
116       bool absolute() const { return *_name.c_str() == '/'; }
117       /** Test for a relative path. */
118       bool relative() const { return !( absolute() || empty() ); }
119
120       /** Test for "" or "/". */
121       bool emptyOrRoot() const { return( _name.empty() || _name == "/" ); }
122
123       /** Return all but the last component od this path. */
124       Pathname dirname() const { return dirname( *this ); }
125       static Pathname dirname( const Pathname & name_r );
126
127       /** Return the last component of this path. */
128       std::string basename() const { return basename( *this ); }
129       static std::string basename( const Pathname & name_r );
130
131       /** Return all of the characters in name after and including
132        * the last dot in the last element of name.  If there is no dot
133        * in the last element of name then returns the empty string.
134       */
135       std::string extension() const { return extension( *this ); }
136       static std::string extension( const Pathname & name_r );
137
138       /** Return this path, adding a leading '/' if relative. */
139       Pathname absolutename() const { return absolutename( *this ); }
140       static Pathname absolutename( const Pathname & name_r )
141       { return name_r.relative() ? cat( "/", name_r ) : name_r; }
142
143       /** Return this path, removing a leading '/' if absolute.*/
144       Pathname relativename() const { return relativename( *this ); }
145       static Pathname relativename( const Pathname & name_r )
146       { return name_r.absolute() ? cat( ".", name_r ) : name_r; }
147
148       /** Return \c path_r prefixed with \c root_r, unless it is already prefixed. */
149       static Pathname assertprefix( const Pathname & root_r, const Pathname & path_r );
150
151       /** Return \c path_r with any \c root_r dir prefix striped. */
152       static Pathname stripprefix( const Pathname & root_r, const Pathname & path_r );
153
154       /** Concatenation of pathnames.
155        * \code
156        *   "foo"  / "baa"  ==> "foo/baa"
157        *   "foo/" / "baa"  ==> "foo/baa"
158        *   "foo"  / "/baa" ==> "foo/baa"
159        *   "foo/" / "/baa" ==> "foo/baa"
160        * \endcode
161       */
162       Pathname cat( const Pathname & r ) const { return cat( *this, r ); }
163       static Pathname cat( const Pathname & l, const Pathname & r );
164
165       /** Append string \a r to the last component of the path.
166        * \code
167        *   "foo/baa".extend( ".h" ) ==> "foo/baa.h"
168        * \endcode
169       */
170       Pathname extend( const std::string & r ) const { return extend( *this, r ); }
171       static Pathname extend( const Pathname & l, const std::string & r );
172
173     private:
174       std::string _name;
175       void _assign( const std::string & name_r );
176     };
177     ///////////////////////////////////////////////////////////////////
178
179     /** \relates Pathname */
180     inline bool operator==( const Pathname & l, const Pathname & r )
181     { return l.asString() == r.asString(); }
182
183     /** \relates Pathname */
184     inline bool operator!=( const Pathname & l, const Pathname & r )
185     { return l.asString() != r.asString(); }
186
187     /** \relates Pathname Concatenate two Pathname. */
188     inline Pathname operator/( const Pathname & l, const Pathname & r )
189     { return Pathname::cat( l, r ); }
190
191     /** \relates Pathname Concatenate two Pathname.
192      * \deprecated: use /
193     */
194     inline Pathname operator+( const Pathname & l, const Pathname & r )
195     { return Pathname::cat( l, r ); }
196
197     /** \relates Pathname */
198     inline bool operator<( const Pathname & l, const Pathname & r )
199     { return l.asString() < r.asString(); }
200
201     ///////////////////////////////////////////////////////////////////
202
203     /** \relates Pathname Stream output */
204     inline std::ostream & operator<<( std::ostream & str, const Pathname & obj )
205     { return str << obj.asString(); }
206
207     /////////////////////////////////////////////////////////////////
208   } // namespace filesystem
209   ///////////////////////////////////////////////////////////////////
210
211   /** Dragged into namespace zypp. */
212   using filesystem::Pathname;
213
214   /////////////////////////////////////////////////////////////////
215 } // namespace zypp
216 ///////////////////////////////////////////////////////////////////
217 #endif // ZYPP_PATHNAME_H