Fix for UBSan build
[platform/upstream/doxygen.git] / qtools / qfileinfo.cpp
1 /****************************************************************************
2 ** 
3 **
4 ** Implementation of QFileInfo class
5 **
6 ** Created : 950628
7 **
8 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
9 **
10 ** This file is part of the tools module of the Qt GUI Toolkit.
11 **
12 ** This file may be distributed under the terms of the Q Public License
13 ** as defined by Trolltech AS of Norway and appearing in the file
14 ** LICENSE.QPL included in the packaging of this file.
15 **
16 ** This file may be distributed and/or modified under the terms of the
17 ** GNU General Public License version 2 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.GPL included in the
19 ** packaging of this file.
20 **
21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22 ** licenses may use this file in accordance with the Qt Commercial License
23 ** Agreement provided with the Software.
24 **
25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 **
28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29 **   information about Qt Commercial License Agreements.
30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
32 **
33 ** Contact info@trolltech.com if any conditions of this licensing are
34 ** not clear to you.
35 **
36 **********************************************************************/
37
38 #include "qglobal.h"
39
40 #include "qfileinfo.h"
41 #include "qfiledefs_p.h"
42 #include "qdatetime.h"
43 #include "qdir.h"
44
45 extern bool qt_file_access( const QString& fn, int t );
46
47 // NOT REVISED
48 /*!
49   \class QFileInfo qfileinfo.h
50   \brief The QFileInfo class provides system-independent file information.
51
52   \ingroup io
53
54   QFileInfo provides information about a file's name and position (path) in
55   the file system, its access rights and whether it is a directory or a
56   symbolic link.  Its size and last modified/read times are also available.
57
58   To speed up performance QFileInfo caches information about the file. Since
59   files can be changed by other users or programs, or even by other parts of
60   the same program there is a function that refreshes the file information;
61   refresh(). If you would rather like a QFileInfo to access the file system
62   every time you request information from it, you can call the function
63   setCaching( FALSE ).
64
65   A QFileInfo can point to a file using either a relative or an absolute
66   file path. Absolute file paths begin with the directory separator
67   ('/') or a drive specification (not applicable to UNIX).
68   Relative file names begin with a directory name or a file name and specify
69   a path relative to the current directory. An example of
70   an absolute path is the string "/tmp/quartz". A relative path might look like
71   "src/fatlib". You can use the function isRelative() to check if a QFileInfo
72   is using a relative or an absolute file path. You can call the function
73   convertToAbs() to convert a relative QFileInfo to an absolute one.
74
75   If you need to read and traverse directories, see the QDir class.
76 */
77
78
79 /*!
80   Constructs a new empty QFileInfo.
81 */
82
83 QFileInfo::QFileInfo()
84 {
85     fic   = 0;
86     cache = TRUE;
87 }
88
89 /*!
90   Constructs a new QFileInfo that gives information about the given file.
91   The string given can be an absolute or a relative file path.
92
93   \sa bool setFile(QString ), isRelative(), QDir::setCurrent(),
94   QDir::isRelativePath()
95 */
96
97 QFileInfo::QFileInfo( const QString &file )
98 {
99     fn    = file;
100     slashify( fn );
101     fic   = 0;
102     cache = TRUE;
103 }
104
105 /*!
106   Constructs a new QFileInfo that gives information about \e file.
107
108   If the file has a relative path, the QFileInfo will also have one.
109
110   \sa isRelative()
111 */
112
113 QFileInfo::QFileInfo( const QFile &file )
114 {
115     fn    = file.name();
116     slashify( fn );
117     fic   = 0;
118     cache = TRUE;
119 }
120
121 /*!
122   Constructs a new QFileInfo that gives information about the file
123   named \e fileName in the directory \e d.
124
125   If the directory has a relative path, the QFileInfo will also have one.
126
127   \sa isRelative()
128 */
129 #ifndef QT_NO_DIR
130 QFileInfo::QFileInfo( const QDir &d, const QString &fileName )
131 {
132     fn    = d.filePath( fileName );
133     slashify( fn );
134     fic   = 0;
135     cache = TRUE;
136 }
137 #endif
138 /*!
139   Constructs a new QFileInfo that is a copy of \e fi.
140 */
141
142 QFileInfo::QFileInfo( const QFileInfo &fi )
143 {
144     fn = fi.fn;
145     if ( fi.fic ) {
146         fic = new QFileInfoCache;
147         *fic = *fi.fic;
148     } else {
149         fic = 0;
150     }
151     cache = fi.cache;
152 }
153
154 /*!
155   Destructs the QFileInfo.
156 */
157
158 QFileInfo::~QFileInfo()
159 {
160     delete fic;
161 }
162
163
164 /*!
165   Makes a copy of \e fi and assigns it to this QFileInfo.
166 */
167
168 QFileInfo &QFileInfo::operator=( const QFileInfo &fi )
169 {
170     fn = fi.fn;
171     if ( !fi.fic ) {
172         delete fic;
173         fic = 0;
174     } else {
175         if ( !fic ) {
176             fic = new QFileInfoCache;
177             CHECK_PTR( fic );
178         }
179         *fic = *fi.fic;
180     }
181     cache = fi.cache;
182     return *this;
183 }
184
185
186 /*!
187   Sets the file to obtain information about.
188
189   The string given can be an absolute or a relative file path. Absolute file
190   paths begin with the directory separator (e.g. '/' under UNIX) or a drive
191   specification (not applicable to UNIX). Relative file names begin with a
192   directory name or a file name and specify a path relative to the current
193   directory.
194
195   Example:
196   \code
197     #include <qfileinfo.h>
198     #include <qdir.h>
199
200     void test()
201     {
202         QString absolute = "/liver/aorta";
203         QString relative = "liver/aorta";
204         QFileInfo fi1( absolute );
205         QFileInfo fi2( relative );
206
207         QDir::setCurrent( QDir::rootDirPath() );
208                                 // fi1 and fi2 now point to the same file
209
210         QDir::setCurrent( "/tmp" );
211                                 // fi1 now points to "/liver/aorta",
212                                 // while fi2 points to "/tmp/liver/aorta"
213     }
214   \endcode
215
216   \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
217 */
218
219 void QFileInfo::setFile( const QString &file )
220 {
221     fn = file;
222     slashify( fn );
223     delete fic;
224     fic = 0;
225 }
226
227 /*!
228   Sets the file to obtain information about.
229
230   If the file has a relative path, the QFileInfo will also have one.
231
232   \sa isRelative()
233 */
234
235 void QFileInfo::setFile( const QFile &file )
236 {
237     fn  = file.name();
238     slashify( fn );
239     delete fic;
240     fic = 0;
241 }
242
243 /*!
244   Sets the file to obtains information about to \e fileName in the
245   directory \e d.
246
247   If the directory has a relative path, the QFileInfo will also have one.
248
249   \sa isRelative()
250 */
251 #ifndef QT_NO_DIR
252 void QFileInfo::setFile( const QDir &d, const QString &fileName )
253 {
254     fn  = d.filePath( fileName );
255     slashify( fn );
256     delete fic;
257     fic = 0;
258 }
259 #endif
260
261 /*!
262   Returns TRUE if the file pointed to exists, otherwise FALSE.
263 */
264
265 bool QFileInfo::exists() const
266 {
267     return qt_file_access( fn, F_OK );
268 }
269
270 /*!
271   Refresh the information about the file, i.e. read in information from the
272   file system the next time a cached property is fetched.
273
274   \sa setCaching()
275 */
276
277 void QFileInfo::refresh() const
278 {
279     QFileInfo *that = (QFileInfo*)this;         // Mutable function
280     delete that->fic;
281     that->fic = 0;
282 }
283
284 /*!
285   \fn bool QFileInfo::caching() const
286   Returns TRUE if caching is enabled.
287   \sa setCaching(), refresh()
288 */
289
290 /*!
291   Enables caching of file information if \e enable is TRUE, or disables it
292   if \e enable is FALSE.
293
294   When caching is enabled, QFileInfo reads the file information the first
295   time
296
297   Caching is enabled by default.
298
299   \sa refresh(), caching()
300 */
301
302 void QFileInfo::setCaching( bool enable )
303 {
304     if ( cache == enable )
305         return;
306     cache = enable;
307     if ( cache ) {
308         delete fic;
309         fic = 0;
310     }
311 }
312
313
314 /*!
315   Returns the name, i.e. the file name including the path (which can be
316   absolute or relative).
317
318   \sa isRelative(), absFilePath()
319 */
320
321 QString QFileInfo::filePath() const
322 {
323     return fn;
324 }
325
326 /*!
327   Returns the base name of the file.
328
329   The base name consists of all characters in the file name up to (but not
330   including) the first '.' character.  The path is not included.
331
332   Example:
333   \code
334      QFileInfo fi( "/tmp/abdomen.lower" );
335      QString base = fi.baseName();              // base = "abdomen"
336   \endcode
337
338   \sa fileName(), extension()
339 */
340
341 QString QFileInfo::baseName() const
342 {
343     QString tmp = fileName();
344     int pos = tmp.find( '.' );
345     if ( pos == -1 )
346         return tmp;
347     else
348         return tmp.left( pos );
349 }
350
351 /*!
352   Returns the extension name of the file.
353
354   If \a complete is TRUE (the default), extension() returns the string
355   of all characters in the file name after (but not including) the
356   first '.'  character.  For a file named "archive.tar.gz" this
357   returns "tar.gz".
358
359   If \a complete is FALSE, extension() returns the string of all
360   characters in the file name after (but not including) the last '.'
361   character.  For a file named "archive.tar.gz" this returns "gz".
362
363   Example:
364   \code
365      QFileInfo fi( "lex.yy.c" );
366      QString ext = fi.extension();              // ext = "yy.c"
367      QString ext = fi.extension( FALSE );       // ext = "c"
368   \endcode
369
370   \sa fileName(), baseName()
371
372 */
373
374 QString QFileInfo::extension( bool complete ) const
375 {
376     QString s = fileName();
377     int pos = complete ? s.find( '.' ) : s.findRev( '.' );
378     if ( pos < 0 )
379         return QString::fromLatin1( "" );
380     else
381         return s.right( s.length() - pos - 1 );
382 }
383
384 /*!
385   Returns the directory path of the file.
386
387   If the QFileInfo is relative and \e absPath is FALSE, the QDir will be
388   relative, otherwise it will be absolute.
389
390   \sa dirPath(), filePath(), fileName(), isRelative()
391 */
392 #ifndef QT_NO_DIR
393 QDir QFileInfo::dir( bool absPath ) const
394 {
395     return QDir( dirPath(absPath) );
396 }
397 #endif
398
399
400 /*!
401   Returns TRUE if the file is readable.
402   \sa isWritable(), isExecutable(), permission()
403 */
404
405 bool QFileInfo::isReadable() const
406 {
407     return qt_file_access( fn, R_OK );
408 }
409
410 /*!
411   Returns TRUE if the file is writable.
412   \sa isReadable(), isExecutable(), permission()
413 */
414
415 bool QFileInfo::isWritable() const
416 {
417     return qt_file_access( fn, W_OK );
418 }
419
420 /*!
421   Returns TRUE if the file is executable.
422   \sa isReadable(), isWritable(), permission()
423 */
424
425 bool QFileInfo::isExecutable() const
426 {
427     return qt_file_access( fn, X_OK );
428 }
429
430
431 /*!
432   Returns TRUE if the file path name is relative to the current directory,
433   FALSE if the path is absolute (e.g. under UNIX a path is relative if it
434   does not start with a '/').
435
436   According to Einstein this function should always return TRUE.
437 */
438 #ifndef QT_NO_DIR
439 bool QFileInfo::isRelative() const
440 {
441     return QDir::isRelativePath( fn );
442 }
443
444 /*!
445   Converts the file path name to an absolute path.
446
447   If it is already absolute nothing is done.
448
449   \sa filePath(), isRelative()
450 */
451
452 bool QFileInfo::convertToAbs()
453 {
454     if ( isRelative() )
455         fn = absFilePath();
456     return QDir::isRelativePath( fn );
457 }
458 #endif