59b93f1331e9585d6d3ce2dceb7c126ffd2f14e6
[profile/ivi/qtbase.git] / src / corelib / io / qdir.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformdefs.h"
43 #include "qdir.h"
44 #include "qdir_p.h"
45 #include "qabstractfileengine_p.h"
46 #include "qfsfileengine_p.h"
47 #ifndef QT_NO_DEBUG_STREAM
48 #include "qdebug.h"
49 #endif
50 #include "qdiriterator.h"
51 #include "qdatetime.h"
52 #include "qstring.h"
53 #include "qregexp.h"
54 #include "qvector.h"
55 #include "qalgorithms.h"
56 #include "qvarlengtharray.h"
57 #include "qfilesystementry_p.h"
58 #include "qfilesystemmetadata_p.h"
59 #include "qfilesystemengine_p.h"
60 #include <qstringbuilder.h>
61
62 #ifdef QT_BUILD_CORE_LIB
63 #  include "qresource.h"
64 #  include "private/qcoreglobaldata_p.h"
65 #endif
66
67 #include <stdlib.h>
68
69 QT_BEGIN_NAMESPACE
70
71 #if defined(Q_OS_WIN)
72 static QString driveSpec(const QString &path)
73 {
74     if (path.size() < 2)
75         return QString();
76     char c = path.at(0).toLatin1();
77     if (c < 'a' && c > 'z' && c < 'A' && c > 'Z')
78         return QString();
79     if (path.at(1).toLatin1() != ':')
80         return QString();
81     return path.mid(0, 2);
82 }
83 #endif
84
85 //************* QDirPrivate
86 QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, QDir::SortFlags sort_, QDir::Filters filters_)
87     : QSharedData()
88     , nameFilters(nameFilters_)
89     , sort(sort_)
90     , filters(filters_)
91     , fileListsInitialized(false)
92 {
93     setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
94
95     bool empty = nameFilters.isEmpty();
96     if (!empty) {
97         empty = true;
98         for (int i = 0; i < nameFilters.size(); ++i) {
99             if (!nameFilters.at(i).isEmpty()) {
100                 empty = false;
101                 break;
102             }
103         }
104     }
105     if (empty)
106         nameFilters = QStringList(QString::fromLatin1("*"));
107 }
108
109 QDirPrivate::QDirPrivate(const QDirPrivate &copy)
110     : QSharedData(copy)
111     , nameFilters(copy.nameFilters)
112     , sort(copy.sort)
113     , filters(copy.filters)
114     , fileListsInitialized(false)
115     , dirEntry(copy.dirEntry)
116     , metaData(copy.metaData)
117 {
118 }
119
120 bool QDirPrivate::exists() const
121 {
122     if (fileEngine.isNull()) {
123         QFileSystemEngine::fillMetaData(dirEntry, metaData,
124                 QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat
125         return metaData.exists() && metaData.isDirectory();
126     }
127     const QAbstractFileEngine::FileFlags info =
128         fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
129                                        | QAbstractFileEngine::ExistsFlag
130                                        | QAbstractFileEngine::Refresh);
131     if (!(info & QAbstractFileEngine::DirectoryType))
132         return false;
133     return info & QAbstractFileEngine::ExistsFlag;
134 }
135
136 // static
137 inline QChar QDirPrivate::getFilterSepChar(const QString &nameFilter)
138 {
139     QChar sep(QLatin1Char(';'));
140     int i = nameFilter.indexOf(sep, 0);
141     if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1)
142         sep = QChar(QLatin1Char(' '));
143     return sep;
144 }
145
146 // static
147 inline QStringList QDirPrivate::splitFilters(const QString &nameFilter, QChar sep)
148 {
149     if (sep == 0)
150         sep = getFilterSepChar(nameFilter);
151     QStringList ret = nameFilter.split(sep);
152     for (int i = 0; i < ret.count(); ++i)
153         ret[i] = ret[i].trimmed();
154     return ret;
155 }
156
157 inline void QDirPrivate::setPath(const QString &path)
158 {
159     QString p = QDir::fromNativeSeparators(path);
160     if (p.endsWith(QLatin1Char('/'))
161             && p.length() > 1
162 #if defined(Q_OS_WIN)
163         && (!(p.length() == 3 && p.at(1).unicode() == ':' && p.at(0).isLetter()))
164 #endif
165     ) {
166             p.truncate(p.length() - 1);
167     }
168
169     dirEntry = QFileSystemEntry(p, QFileSystemEntry::FromInternalPath());
170     metaData.clear();
171     initFileEngine();
172     clearFileLists();
173     absoluteDirEntry = QFileSystemEntry();
174 }
175
176 inline void QDirPrivate::clearFileLists()
177 {
178     fileListsInitialized = false;
179     files.clear();
180     fileInfos.clear();
181 }
182
183 inline void QDirPrivate::resolveAbsoluteEntry() const
184 {
185     if (!absoluteDirEntry.isEmpty() || dirEntry.isEmpty())
186         return;
187
188     QString absoluteName;
189     if (fileEngine.isNull()) {
190         if (!dirEntry.isRelative() && dirEntry.isClean()) {
191             absoluteDirEntry = dirEntry;
192             return;
193         }
194
195         absoluteName = QFileSystemEngine::absoluteName(dirEntry).filePath();
196     } else {
197         absoluteName = fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
198     }
199
200     absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(absoluteName), QFileSystemEntry::FromInternalPath());
201 }
202
203 /* For sorting */
204 struct QDirSortItem
205 {
206     mutable QString filename_cache;
207     mutable QString suffix_cache;
208     QFileInfo item;
209 };
210
211
212 class QDirSortItemComparator
213 {
214     int qt_cmp_si_sort_flags;
215 public:
216     QDirSortItemComparator(int flags) : qt_cmp_si_sort_flags(flags) {}
217     bool operator()(const QDirSortItem &, const QDirSortItem &);
218 };
219
220 bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortItem &n2)
221 {
222     const QDirSortItem* f1 = &n1;
223     const QDirSortItem* f2 = &n2;
224
225     if ((qt_cmp_si_sort_flags & QDir::DirsFirst) && (f1->item.isDir() != f2->item.isDir()))
226         return f1->item.isDir();
227     if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir()))
228         return !f1->item.isDir();
229
230     int r = 0;
231     int sortBy = (qt_cmp_si_sort_flags & QDir::SortByMask)
232                  | (qt_cmp_si_sort_flags & QDir::Type);
233
234     switch (sortBy) {
235       case QDir::Time:
236         r = f1->item.lastModified().secsTo(f2->item.lastModified());
237         break;
238       case QDir::Size:
239           r = int(qBound<qint64>(-1, f2->item.size() - f1->item.size(), 1));
240         break;
241       case QDir::Type:
242       {
243         bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase;
244
245         if (f1->suffix_cache.isNull())
246             f1->suffix_cache = ic ? f1->item.suffix().toLower()
247                                : f1->item.suffix();
248         if (f2->suffix_cache.isNull())
249             f2->suffix_cache = ic ? f2->item.suffix().toLower()
250                                : f2->item.suffix();
251
252         r = qt_cmp_si_sort_flags & QDir::LocaleAware
253             ? f1->suffix_cache.localeAwareCompare(f2->suffix_cache)
254             : f1->suffix_cache.compare(f2->suffix_cache);
255       }
256         break;
257       default:
258         ;
259     }
260
261     if (r == 0 && sortBy != QDir::Unsorted) {
262         // Still not sorted - sort by name
263         bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase;
264
265         if (f1->filename_cache.isNull())
266             f1->filename_cache = ic ? f1->item.fileName().toLower()
267                                     : f1->item.fileName();
268         if (f2->filename_cache.isNull())
269             f2->filename_cache = ic ? f2->item.fileName().toLower()
270                                     : f2->item.fileName();
271
272         r = qt_cmp_si_sort_flags & QDir::LocaleAware
273             ? f1->filename_cache.localeAwareCompare(f2->filename_cache)
274             : f1->filename_cache.compare(f2->filename_cache);
275     }
276     if (r == 0) // Enforce an order - the order the items appear in the array
277         r = (&n1) - (&n2);
278     if (qt_cmp_si_sort_flags & QDir::Reversed)
279         return r > 0;
280     return r < 0;
281 }
282
283 inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
284                                       QStringList *names, QFileInfoList *infos)
285 {
286     // names and infos are always empty lists or 0 here
287     int n = l.size();
288     if (n > 0) {
289         if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
290             if (infos)
291                 *infos = l;
292             if (names) {
293                 for (int i = 0; i < n; ++i)
294                     names->append(l.at(i).fileName());
295             }
296         } else {
297             QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]);
298             for (int i = 0; i < n; ++i)
299                 si[i].item = l.at(i);
300             qSort(si.data(), si.data() + n, QDirSortItemComparator(sort));
301             // put them back in the list(s)
302             if (infos) {
303                 for (int i = 0; i < n; ++i)
304                     infos->append(si[i].item);
305             }
306             if (names) {
307                 for (int i = 0; i < n; ++i)
308                     names->append(si[i].item.fileName());
309             }
310         }
311     }
312 }
313 inline void QDirPrivate::initFileLists(const QDir &dir) const
314 {
315     if (!fileListsInitialized) {
316         QFileInfoList l;
317         QDirIterator it(dir);
318         while (it.hasNext()) {
319             it.next();
320             l.append(it.fileInfo());
321         }
322         sortFileList(sort, l, &files, &fileInfos);
323         fileListsInitialized = true;
324     }
325 }
326
327 inline void QDirPrivate::initFileEngine()
328 {
329     fileEngine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(dirEntry, metaData));
330 }
331
332 /*!
333     \class QDir
334     \brief The QDir class provides access to directory structures and their contents.
335
336     \ingroup io
337     \ingroup shared
338     \reentrant
339
340
341     A QDir is used to manipulate path names, access information
342     regarding paths and files, and manipulate the underlying file
343     system. It can also be used to access Qt's \l{resource system}.
344
345     Qt uses "/" as a universal directory separator in the same way
346     that "/" is used as a path separator in URLs. If you always use
347     "/" as a directory separator, Qt will translate your paths to
348     conform to the underlying operating system.
349
350     A QDir can point to a file using either a relative or an absolute
351     path. Absolute paths begin with the directory separator
352     (optionally preceded by a drive specification under Windows).
353     Relative file names begin with a directory name or a file name and
354     specify a path relative to the current directory.
355
356     Examples of absolute paths:
357
358     \snippet code/src_corelib_io_qdir.cpp 0
359
360     On Windows, the second example above will be translated to
361     \c{C:\Documents and Settings} when used to access files.
362
363     Examples of relative paths:
364
365     \snippet code/src_corelib_io_qdir.cpp 1
366
367     You can use the isRelative() or isAbsolute() functions to check if
368     a QDir is using a relative or an absolute file path. Call
369     makeAbsolute() to convert a relative QDir to an absolute one.
370
371     \section1 Navigation and Directory Operations
372
373     A directory's path can be obtained with the path() function, and
374     a new path set with the setPath() function. The absolute path to
375     a directory is found by calling absolutePath().
376
377     The name of a directory is found using the dirName() function. This
378     typically returns the last element in the absolute path that specifies
379     the location of the directory. However, it can also return "." if
380     the QDir represents the current directory.
381
382     \snippet code/src_corelib_io_qdir.cpp 2
383
384     The path for a directory can also be changed with the cd() and cdUp()
385     functions, both of which operate like familiar shell commands.
386     When cd() is called with the name of an existing directory, the QDir
387     object changes directory so that it represents that directory instead.
388     The cdUp() function changes the directory of the QDir object so that
389     it refers to its parent directory; i.e. cd("..") is equivalent to
390     cdUp().
391
392     Directories can be created with mkdir(), renamed with rename(), and
393     removed with rmdir().
394
395     You can test for the presence of a directory with a given name by
396     using exists(), and the properties of a directory can be tested with
397     isReadable(), isAbsolute(), isRelative(), and isRoot().
398
399     The refresh() function re-reads the directory's data from disk.
400
401     \section1 Files and Directory Contents
402
403     Directories contain a number of entries, representing files,
404     directories, and symbolic links. The number of entries in a
405     directory is returned by count().
406     A string list of the names of all the entries in a directory can be
407     obtained with entryList(). If you need information about each
408     entry, use entryInfoList() to obtain a list of QFileInfo objects.
409
410     Paths to files and directories within a directory can be
411     constructed using filePath() and absoluteFilePath().
412     The filePath() function returns a path to the specified file
413     or directory relative to the path of the QDir object;
414     absoluteFilePath() returns an absolute path to the specified
415     file or directory. Neither of these functions checks for the
416     existence of files or directory; they only construct paths.
417
418     \snippet code/src_corelib_io_qdir.cpp 3
419
420     Files can be removed by using the remove() function. Directories
421     cannot be removed in the same way as files; use rmdir() to remove
422     them instead.
423
424     It is possible to reduce the number of entries returned by
425     entryList() and entryInfoList() by applying filters to a QDir object.
426     You can apply a name filter to specify a pattern with wildcards that
427     file names need to match, an attribute filter that selects properties
428     of entries and can distinguish between files and directories, and a
429     sort order.
430
431     Name filters are lists of strings that are passed to setNameFilters().
432     Attribute filters consist of a bitwise OR combination of Filters, and
433     these are specified when calling setFilter().
434     The sort order is specified using setSorting() with a bitwise OR
435     combination of SortFlags.
436
437     You can test to see if a filename matches a filter using the match()
438     function.
439
440     Filter and sort order flags may also be specified when calling
441     entryList() and entryInfoList() in order to override previously defined
442     behavior.
443
444     \section1 The Current Directory and Other Special Paths
445
446     Access to some common directories is provided with a number of static
447     functions that return QDir objects. There are also corresponding functions
448     for these that return strings:
449
450     \table
451     \header \li QDir      \li QString         \li Return Value
452     \row    \li current() \li currentPath()   \li The application's working directory
453     \row    \li home()    \li homePath()      \li The user's home directory
454     \row    \li root()    \li rootPath()      \li The root directory
455     \row    \li temp()    \li tempPath()      \li The system's temporary directory
456     \endtable
457
458     The setCurrent() static function can also be used to set the application's
459     working directory.
460
461     If you want to find the directory containing the application's executable,
462     see \l{QCoreApplication::applicationDirPath()}.
463
464     The drives() static function provides a list of root directories for each
465     device that contains a filing system. On Unix systems this returns a list
466     containing a single root directory "/"; on Windows the list will usually
467     contain \c{C:/}, and possibly other drive letters such as \c{D:/}, depending
468     on the configuration of the user's system.
469
470     \section1 Path Manipulation and Strings
471
472     Paths containing "." elements that reference the current directory at that
473     point in the path, ".." elements that reference the parent directory, and
474     symbolic links can be reduced to a canonical form using the canonicalPath()
475     function.
476
477     Paths can also be simplified by using cleanPath() to remove redundant "/"
478     and ".." elements.
479
480     It is sometimes necessary to be able to show a path in the native
481     representation for the user's platform. The static toNativeSeparators()
482     function returns a copy of the specified path in which each directory
483     separator is replaced by the appropriate separator for the underlying
484     operating system.
485
486     \section1 Examples
487
488     Check if a directory exists:
489
490     \snippet code/src_corelib_io_qdir.cpp 4
491
492     (We could also use the static convenience function
493     QFile::exists().)
494
495     Traversing directories and reading a file:
496
497     \snippet code/src_corelib_io_qdir.cpp 5
498
499     A program that lists all the files in the current directory
500     (excluding symbolic links), sorted by size, smallest first:
501
502     \snippet qdir-listfiles/main.cpp 0
503
504     \sa QFileInfo, QFile, QFileDialog, QCoreApplication::applicationDirPath(), {Find Files Example}
505 */
506
507 /*!
508     \internal
509 */
510 QDir::QDir(QDirPrivate &p) : d_ptr(&p)
511 {
512 }
513
514 /*!
515     Constructs a QDir pointing to the given directory \a path. If path
516     is empty the program's working directory, ("."), is used.
517
518     \sa currentPath()
519 */
520 QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(path))
521 {
522 }
523
524 /*!
525     Constructs a QDir with path \a path, that filters its entries by
526     name using \a nameFilter and by attributes using \a filters. It
527     also sorts the names using \a sort.
528
529     The default \a nameFilter is an empty string, which excludes
530     nothing; the default \a filters is \l AllEntries, which also means
531     exclude nothing. The default \a sort is \l Name | \l IgnoreCase,
532     i.e. sort by name case-insensitively.
533
534     If \a path is an empty string, QDir uses "." (the current
535     directory). If \a nameFilter is an empty string, QDir uses the
536     name filter "*" (all files).
537
538     Note that \a path need not exist.
539
540     \sa exists(), setPath(), setNameFilters(), setFilter(), setSorting()
541 */
542 QDir::QDir(const QString &path, const QString &nameFilter,
543            SortFlags sort, Filters filters)
544     : d_ptr(new QDirPrivate(path, QDir::nameFiltersFromString(nameFilter), sort, filters))
545 {
546 }
547
548 /*!
549     Constructs a QDir object that is a copy of the QDir object for
550     directory \a dir.
551
552     \sa operator=()
553 */
554 QDir::QDir(const QDir &dir)
555     : d_ptr(dir.d_ptr)
556 {
557 }
558
559 /*!
560     Destroys the QDir object frees up its resources. This has no
561     effect on the underlying directory in the file system.
562 */
563 QDir::~QDir()
564 {
565 }
566
567 /*!
568     Sets the path of the directory to \a path. The path is cleaned of
569     redundant ".", ".." and of multiple separators. No check is made
570     to see whether a directory with this path actually exists; but you
571     can check for yourself using exists().
572
573     The path can be either absolute or relative. Absolute paths begin
574     with the directory separator "/" (optionally preceded by a drive
575     specification under Windows). Relative file names begin with a
576     directory name or a file name and specify a path relative to the
577     current directory. An example of an absolute path is the string
578     "/tmp/quartz", a relative path might look like "src/fatlib".
579
580     \sa path(), absolutePath(), exists(), cleanPath(), dirName(),
581       absoluteFilePath(), isRelative(), makeAbsolute()
582 */
583 void QDir::setPath(const QString &path)
584 {
585     d_ptr->setPath(path);
586 }
587
588 /*!
589     Returns the path. This may contain symbolic links, but never
590     contains redundant ".", ".." or multiple separators.
591
592     The returned path can be either absolute or relative (see
593     setPath()).
594
595     \sa setPath(), absolutePath(), exists(), cleanPath(), dirName(),
596     absoluteFilePath(), toNativeSeparators(), makeAbsolute()
597 */
598 QString QDir::path() const
599 {
600     const QDirPrivate* d = d_ptr.constData();
601     return d->dirEntry.filePath();
602 }
603
604 /*!
605     Returns the absolute path (a path that starts with "/" or with a
606     drive specification), which may contain symbolic links, but never
607     contains redundant ".", ".." or multiple separators.
608
609     \sa setPath(), canonicalPath(), exists(), cleanPath(),
610     dirName(), absoluteFilePath()
611 */
612 QString QDir::absolutePath() const
613 {
614     const QDirPrivate* d = d_ptr.constData();
615     d->resolveAbsoluteEntry();
616     return d->absoluteDirEntry.filePath();
617 }
618
619 /*!
620     Returns the canonical path, i.e. a path without symbolic links or
621     redundant "." or ".." elements.
622
623     On systems that do not have symbolic links this function will
624     always return the same string that absolutePath() returns. If the
625     canonical path does not exist (normally due to dangling symbolic
626     links) canonicalPath() returns an empty string.
627
628     Example:
629
630     \snippet code/src_corelib_io_qdir.cpp 6
631
632     \sa path(), absolutePath(), exists(), cleanPath(), dirName(),
633         absoluteFilePath()
634 */
635 QString QDir::canonicalPath() const
636 {
637     const QDirPrivate* d = d_ptr.constData();
638     if (d->fileEngine.isNull()) {
639         QFileSystemEntry answer = QFileSystemEngine::canonicalName(d->dirEntry, d->metaData);
640         return answer.filePath();
641     }
642     return d->fileEngine->fileName(QAbstractFileEngine::CanonicalName);
643 }
644
645 /*!
646     Returns the name of the directory; this is \e not the same as the
647     path, e.g. a directory with the name "mail", might have the path
648     "/var/spool/mail". If the directory has no name (e.g. it is the
649     root directory) an empty string is returned.
650
651     No check is made to ensure that a directory with this name
652     actually exists; but see exists().
653
654     \sa path(), filePath(), absolutePath(), absoluteFilePath()
655 */
656 QString QDir::dirName() const
657 {
658     const QDirPrivate* d = d_ptr.constData();
659     return d->dirEntry.fileName();
660 }
661
662 /*!
663     Returns the path name of a file in the directory. Does \e not
664     check if the file actually exists in the directory; but see
665     exists(). If the QDir is relative the returned path name will also
666     be relative. Redundant multiple separators or "." and ".."
667     directories in \a fileName are not removed (see cleanPath()).
668
669     \sa dirName(), absoluteFilePath(), isRelative(), canonicalPath()
670 */
671 QString QDir::filePath(const QString &fileName) const
672 {
673     const QDirPrivate* d = d_ptr.constData();
674     if (isAbsolutePath(fileName))
675         return QString(fileName);
676
677     QString ret = d->dirEntry.filePath();
678     if (!fileName.isEmpty()) {
679         if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/'))
680             ret += QLatin1Char('/');
681         ret += fileName;
682     }
683     return ret;
684 }
685
686 /*!
687     Returns the absolute path name of a file in the directory. Does \e
688     not check if the file actually exists in the directory; but see
689     exists(). Redundant multiple separators or "." and ".."
690     directories in \a fileName are not removed (see cleanPath()).
691
692     \sa relativeFilePath(), filePath(), canonicalPath()
693 */
694 QString QDir::absoluteFilePath(const QString &fileName) const
695 {
696     const QDirPrivate* d = d_ptr.constData();
697     if (isAbsolutePath(fileName))
698         return fileName;
699
700     d->resolveAbsoluteEntry();
701     if (fileName.isEmpty())
702         return d->absoluteDirEntry.filePath();
703     if (!d->absoluteDirEntry.isRoot())
704         return d->absoluteDirEntry.filePath() % QLatin1Char('/') % fileName;
705     return d->absoluteDirEntry.filePath() % fileName;
706 }
707
708 /*!
709     Returns the path to \a fileName relative to the directory.
710
711     \snippet code/src_corelib_io_qdir.cpp 7
712
713     \sa absoluteFilePath(), filePath(), canonicalPath()
714 */
715 QString QDir::relativeFilePath(const QString &fileName) const
716 {
717     QString dir = cleanPath(absolutePath());
718     QString file = cleanPath(fileName);
719
720     if (isRelativePath(file) || isRelativePath(dir))
721         return file;
722
723 #ifdef Q_OS_WIN
724     QString dirDrive = driveSpec(dir);
725     QString fileDrive = driveSpec(file);
726
727     bool fileDriveMissing = false;
728     if (fileDrive.isEmpty()) {
729         fileDrive = dirDrive;
730         fileDriveMissing = true;
731     }
732
733     if (fileDrive.toLower() != dirDrive.toLower()
734         || (file.startsWith(QLatin1String("//"))
735         && !dir.startsWith(QLatin1String("//"))))
736         return file;
737
738     dir.remove(0, dirDrive.size());
739     if (!fileDriveMissing)
740         file.remove(0, fileDrive.size());
741 #endif
742
743     QString result;
744     QStringList dirElts = dir.split(QLatin1Char('/'), QString::SkipEmptyParts);
745     QStringList fileElts = file.split(QLatin1Char('/'), QString::SkipEmptyParts);
746
747     int i = 0;
748     while (i < dirElts.size() && i < fileElts.size() &&
749 #if defined(Q_OS_WIN)
750            dirElts.at(i).toLower() == fileElts.at(i).toLower())
751 #else
752            dirElts.at(i) == fileElts.at(i))
753 #endif
754         ++i;
755
756     for (int j = 0; j < dirElts.size() - i; ++j)
757         result += QLatin1String("../");
758
759     for (int j = i; j < fileElts.size(); ++j) {
760         result += fileElts.at(j);
761         if (j < fileElts.size() - 1)
762             result += QLatin1Char('/');
763     }
764
765     return result;
766 }
767
768 /*!
769     \since 4.2
770
771     Returns \a pathName with the '/' separators converted to
772     separators that are appropriate for the underlying operating
773     system.
774
775     On Windows, toNativeSeparators("c:/winnt/system32") returns
776     "c:\\winnt\\system32".
777
778     The returned string may be the same as the argument on some
779     operating systems, for example on Unix.
780
781     \sa fromNativeSeparators(), separator()
782 */
783 QString QDir::toNativeSeparators(const QString &pathName)
784 {
785 #if defined(Q_OS_WIN)
786     int i = pathName.indexOf(QLatin1Char('/'));
787     if (i != -1) {
788         QString n(pathName);
789
790         QChar * const data = n.data();
791         data[i++] = QLatin1Char('\\');
792
793         for (; i < n.length(); ++i) {
794             if (data[i] == QLatin1Char('/'))
795                 data[i] = QLatin1Char('\\');
796         }
797
798         return n;
799     }
800 #endif
801     return pathName;
802 }
803
804 /*!
805     \since 4.2
806
807     Returns \a pathName using '/' as file separator. On Windows,
808     for instance, fromNativeSeparators("\c{c:\\winnt\\system32}") returns
809     "c:/winnt/system32".
810
811     The returned string may be the same as the argument on some
812     operating systems, for example on Unix.
813
814     \sa toNativeSeparators(), separator()
815 */
816 QString QDir::fromNativeSeparators(const QString &pathName)
817 {
818 #if defined(Q_OS_WIN)
819     int i = pathName.indexOf(QLatin1Char('\\'));
820     if (i != -1) {
821         QString n(pathName);
822
823         QChar * const data = n.data();
824         data[i++] = QLatin1Char('/');
825
826         for (; i < n.length(); ++i) {
827             if (data[i] == QLatin1Char('\\'))
828                 data[i] = QLatin1Char('/');
829         }
830
831         return n;
832     }
833 #endif
834     return pathName;
835 }
836
837 /*!
838     Changes the QDir's directory to \a dirName.
839
840     Returns true if the new directory exists and is readable;
841     otherwise returns false. Note that the logical cd() operation is
842     not performed if the new directory does not exist.
843
844     Calling cd("..") is equivalent to calling cdUp().
845
846     \sa cdUp(), isReadable(), exists(), path()
847 */
848 bool QDir::cd(const QString &dirName)
849 {
850     // Don't detach just yet.
851     const QDirPrivate * const d = d_ptr.constData();
852
853     if (dirName.isEmpty() || dirName == QLatin1String("."))
854         return true;
855     QString newPath;
856     if (isAbsolutePath(dirName)) {
857         newPath = cleanPath(dirName);
858     } else {
859         if (isRoot())
860             newPath = d->dirEntry.filePath();
861         else
862             newPath = d->dirEntry.filePath() % QLatin1Char('/');
863         newPath += dirName;
864         if (dirName.indexOf(QLatin1Char('/')) >= 0
865             || dirName == QLatin1String("..")
866             || d->dirEntry.filePath() == QLatin1String(".")) {
867             newPath = cleanPath(newPath);
868 #if defined (Q_OS_UNIX)
869             //After cleanPath() if path is "/.." or starts with "/../" it means trying to cd above root.
870             if (newPath.startsWith(QLatin1String("/../")) || newPath == QLatin1String("/.."))
871 #else
872             /*
873               cleanPath() already took care of replacing '\' with '/'.
874               We can't use startsWith here because the letter of the drive is unknown.
875               After cleanPath() if path is "[A-Z]:/.." or starts with "[A-Z]:/../" it means trying to cd above root.
876              */
877
878             if (newPath.midRef(1, 4) == QLatin1String(":/..") && (newPath.length() == 5 || newPath.at(5) == QLatin1Char('/')))
879 #endif
880                 return false;
881             /*
882               If newPath starts with .., we convert it to absolute to
883               avoid infinite looping on
884
885                   QDir dir(".");
886                   while (dir.cdUp())
887                       ;
888             */
889             if (newPath.startsWith(QLatin1String(".."))) {
890                 newPath = QFileInfo(newPath).absoluteFilePath();
891             }
892         }
893     }
894
895     QScopedPointer<QDirPrivate> dir(new QDirPrivate(*d_ptr.constData()));
896     dir->setPath(newPath);
897     if (!dir->exists())
898         return false;
899
900     d_ptr = dir.take();
901     return true;
902 }
903
904 /*!
905     Changes directory by moving one directory up from the QDir's
906     current directory.
907
908     Returns true if the new directory exists and is readable;
909     otherwise returns false. Note that the logical cdUp() operation is
910     not performed if the new directory does not exist.
911
912     \sa cd(), isReadable(), exists(), path()
913 */
914 bool QDir::cdUp()
915 {
916     return cd(QString::fromLatin1(".."));
917 }
918
919 /*!
920     Returns the string list set by setNameFilters()
921 */
922 QStringList QDir::nameFilters() const
923 {
924     const QDirPrivate* d = d_ptr.constData();
925     return d->nameFilters;
926 }
927
928 /*!
929     Sets the name filters used by entryList() and entryInfoList() to the
930     list of filters specified by \a nameFilters.
931
932     Each name filter is a wildcard (globbing) filter that understands
933     \c{*} and \c{?} wildcards. (See \l{QRegExp wildcard matching}.)
934
935     For example, the following code sets three name filters on a QDir
936     to ensure that only files with extensions typically used for C++
937     source files are listed:
938
939     \snippet qdir-namefilters/main.cpp 0
940
941     \sa nameFilters(), setFilter()
942 */
943 void QDir::setNameFilters(const QStringList &nameFilters)
944 {
945     QDirPrivate* d = d_ptr.data();
946     d->initFileEngine();
947     d->clearFileLists();
948
949     d->nameFilters = nameFilters;
950 }
951
952 /*!
953     \obsolete
954
955     Use QDir::addSearchPath() with a prefix instead.
956
957     Adds \a path to the search paths searched in to find resources
958     that are not specified with an absolute path. The default search
959     path is to search only in the root (\c{:/}).
960
961     \sa {The Qt Resource System}
962 */
963 void QDir::addResourceSearchPath(const QString &path)
964 {
965 #ifdef QT_BUILD_CORE_LIB
966     QResource::addSearchPath(path);
967 #else
968     Q_UNUSED(path)
969 #endif
970 }
971
972 #ifdef QT_BUILD_CORE_LIB
973 /*!
974     \since 4.3
975
976     Sets or replaces Qt's search paths for file names with the prefix \a prefix
977     to \a searchPaths.
978
979     To specify a prefix for a file name, prepend the prefix followed by a single
980     colon (e.g., "images:undo.png", "xmldocs:books.xml"). \a prefix can only
981     contain letters or numbers (e.g., it cannot contain a colon, nor a slash).
982
983     Qt uses this search path to locate files with a known prefix. The search
984     path entries are tested in order, starting with the first entry.
985
986     \snippet code/src_corelib_io_qdir.cpp 8
987
988     File name prefix must be at least 2 characters long to avoid conflicts with
989     Windows drive letters.
990
991     Search paths may contain paths to \l{The Qt Resource System}.
992 */
993 void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths)
994 {
995     if (prefix.length() < 2) {
996         qWarning("QDir::setSearchPaths: Prefix must be longer than 1 character");
997         return;
998     }
999
1000     for (int i = 0; i < prefix.count(); ++i) {
1001         if (!prefix.at(i).isLetterOrNumber()) {
1002             qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers");
1003             return;
1004         }
1005     }
1006
1007     QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
1008     QMap<QString, QStringList> &paths = QCoreGlobalData::instance()->dirSearchPaths;
1009     if (searchPaths.isEmpty()) {
1010         paths.remove(prefix);
1011     } else {
1012         paths.insert(prefix, searchPaths);
1013     }
1014 }
1015
1016 /*!
1017     \since 4.3
1018
1019     Adds \a path to the search path for \a prefix.
1020
1021     \sa setSearchPaths()
1022 */
1023 void QDir::addSearchPath(const QString &prefix, const QString &path)
1024 {
1025     if (path.isEmpty())
1026         return;
1027
1028     QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
1029     QCoreGlobalData::instance()->dirSearchPaths[prefix] += path;
1030 }
1031
1032 /*!
1033     \since 4.3
1034
1035     Returns the search paths for \a prefix.
1036
1037     \sa setSearchPaths(), addSearchPath()
1038 */
1039 QStringList QDir::searchPaths(const QString &prefix)
1040 {
1041     QReadLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
1042     return QCoreGlobalData::instance()->dirSearchPaths.value(prefix);
1043 }
1044
1045 #endif // QT_BUILD_CORE_LIB
1046
1047 /*!
1048     Returns the value set by setFilter()
1049 */
1050 QDir::Filters QDir::filter() const
1051 {
1052     const QDirPrivate* d = d_ptr.constData();
1053     return d->filters;
1054 }
1055
1056 /*!
1057     \enum QDir::Filter
1058
1059     This enum describes the filtering options available to QDir; e.g.
1060     for entryList() and entryInfoList(). The filter value is specified
1061     by combining values from the following list using the bitwise OR
1062     operator:
1063
1064     \value Dirs    List directories that match the filters.
1065     \value AllDirs  List all directories; i.e. don't apply the filters
1066                     to directory names.
1067     \value Files   List files.
1068     \value Drives  List disk drives (ignored under Unix).
1069     \value NoSymLinks  Do not list symbolic links (ignored by operating
1070                        systems that don't support symbolic links).
1071     \value NoDotAndDotDot Do not list the special entries "." and "..".
1072     \value NoDot       Do not list the special entry ".".
1073     \value NoDotDot    Do not list the special entry "..".
1074     \value AllEntries  List directories, files, drives and symlinks (this does not list
1075                 broken symlinks unless you specify System).
1076     \value Readable    List files for which the application has read
1077                        access. The Readable value needs to be combined
1078                        with Dirs or Files.
1079     \value Writable    List files for which the application has write
1080                        access. The Writable value needs to be combined
1081                        with Dirs or Files.
1082     \value Executable  List files for which the application has
1083                        execute access. The Executable value needs to be
1084                        combined with Dirs or Files.
1085     \value Modified  Only list files that have been modified (ignored
1086                      on Unix).
1087     \value Hidden  List hidden files (on Unix, files starting with a ".").
1088     \value System  List system files (on Unix, FIFOs, sockets and
1089                    device files are included; on Windows, \c {.lnk}
1090                    files are included)
1091     \value CaseSensitive  The filter should be case sensitive.
1092
1093     \omitvalue TypeMask
1094     \omitvalue AccessMask
1095     \omitvalue PermissionMask
1096     \omitvalue NoFilter
1097
1098     Functions that use Filter enum values to filter lists of files
1099     and directories will include symbolic links to files and directories
1100     unless you set the NoSymLinks value.
1101
1102     A default constructed QDir will not filter out files based on
1103     their permissions, so entryList() and entryInfoList() will return
1104     all files that are readable, writable, executable, or any
1105     combination of the three.  This makes the default easy to write,
1106     and at the same time useful.
1107
1108     For example, setting the \c Readable, \c Writable, and \c Files
1109     flags allows all files to be listed for which the application has read
1110     access, write access or both. If the \c Dirs and \c Drives flags are
1111     also included in this combination then all drives, directories, all
1112     files that the application can read, write, or execute, and symlinks
1113     to such files/directories can be listed.
1114
1115     To retrieve the permissons for a directory, use the
1116     entryInfoList() function to get the associated QFileInfo objects
1117     and then use the QFileInfo::permissons() to obtain the permissions
1118     and ownership for each file.
1119 */
1120
1121 /*!
1122     Sets the filter used by entryList() and entryInfoList() to \a
1123     filters. The filter is used to specify the kind of files that
1124     should be returned by entryList() and entryInfoList(). See
1125     \l{QDir::Filter}.
1126
1127     \sa filter(), setNameFilters()
1128 */
1129 void QDir::setFilter(Filters filters)
1130 {
1131     QDirPrivate* d = d_ptr.data();
1132     d->initFileEngine();
1133     d->clearFileLists();
1134
1135     d->filters = filters;
1136 }
1137
1138 /*!
1139     Returns the value set by setSorting()
1140
1141     \sa setSorting(), SortFlag
1142 */
1143 QDir::SortFlags QDir::sorting() const
1144 {
1145     const QDirPrivate* d = d_ptr.constData();
1146     return d->sort;
1147 }
1148
1149 /*!
1150     \enum QDir::SortFlag
1151
1152     This enum describes the sort options available to QDir, e.g. for
1153     entryList() and entryInfoList(). The sort value is specified by
1154     OR-ing together values from the following list:
1155
1156     \value Name  Sort by name.
1157     \value Time  Sort by time (modification time).
1158     \value Size  Sort by file size.
1159     \value Type  Sort by file type (extension).
1160     \value Unsorted  Do not sort.
1161     \value NoSort Not sorted by default.
1162
1163     \value DirsFirst  Put the directories first, then the files.
1164     \value DirsLast Put the files first, then the directories.
1165     \value Reversed  Reverse the sort order.
1166     \value IgnoreCase  Sort case-insensitively.
1167     \value LocaleAware Sort items appropriately using the current locale settings.
1168
1169     \omitvalue SortByMask
1170
1171     You can only specify one of the first four.
1172
1173     If you specify both DirsFirst and Reversed, directories are
1174     still put first, but in reverse order; the files will be listed
1175     after the directories, again in reverse order.
1176 */
1177
1178 /*!
1179     Sets the sort order used by entryList() and entryInfoList().
1180
1181     The \a sort is specified by OR-ing values from the enum
1182     \l{QDir::SortFlag}.
1183
1184     \sa sorting(), SortFlag
1185 */
1186 void QDir::setSorting(SortFlags sort)
1187 {
1188     QDirPrivate* d = d_ptr.data();
1189     d->initFileEngine();
1190     d->clearFileLists();
1191
1192     d->sort = sort;
1193 }
1194
1195 /*!
1196     Returns the total number of directories and files in the directory.
1197
1198     Equivalent to entryList().count().
1199
1200     \sa operator[](), entryList()
1201 */
1202 uint QDir::count() const
1203 {
1204     const QDirPrivate* d = d_ptr.constData();
1205     d->initFileLists(*this);
1206     return d->files.count();
1207 }
1208
1209 /*!
1210     Returns the file name at position \a pos in the list of file
1211     names. Equivalent to entryList().at(index).
1212     \a pos must be a valid index position in the list (i.e., 0 <= pos < count()).
1213
1214     \sa count(), entryList()
1215 */
1216 QString QDir::operator[](int pos) const
1217 {
1218     const QDirPrivate* d = d_ptr.constData();
1219     d->initFileLists(*this);
1220     return d->files[pos];
1221 }
1222
1223 /*!
1224     \overload
1225
1226     Returns a list of the names of all the files and directories in
1227     the directory, ordered according to the name and attribute filters
1228     previously set with setNameFilters() and setFilter(), and sorted according
1229     to the flags set with setSorting().
1230
1231     The attribute filter and sorting specifications can be overridden using the
1232     \a filters and \a sort arguments.
1233
1234     Returns an empty list if the directory is unreadable, does not
1235     exist, or if nothing matches the specification.
1236
1237     \note To list symlinks that point to non existing files, \l System must be
1238      passed to the filter.
1239
1240     \sa entryInfoList(), setNameFilters(), setSorting(), setFilter()
1241 */
1242 QStringList QDir::entryList(Filters filters, SortFlags sort) const
1243 {
1244     const QDirPrivate* d = d_ptr.constData();
1245     return entryList(d->nameFilters, filters, sort);
1246 }
1247
1248
1249 /*!
1250     \overload
1251
1252     Returns a list of QFileInfo objects for all the files and directories in
1253     the directory, ordered according to the name and attribute filters
1254     previously set with setNameFilters() and setFilter(), and sorted according
1255     to the flags set with setSorting().
1256
1257     The attribute filter and sorting specifications can be overridden using the
1258     \a filters and \a sort arguments.
1259
1260     Returns an empty list if the directory is unreadable, does not
1261     exist, or if nothing matches the specification.
1262
1263     \sa entryList(), setNameFilters(), setSorting(), setFilter(), isReadable(), exists()
1264 */
1265 QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const
1266 {
1267     const QDirPrivate* d = d_ptr.constData();
1268     return entryInfoList(d->nameFilters, filters, sort);
1269 }
1270
1271 /*!
1272     Returns a list of the names of all the files and
1273     directories in the directory, ordered according to the name
1274     and attribute filters previously set with setNameFilters()
1275     and setFilter(), and sorted according to the flags set with
1276     setSorting().
1277
1278     The name filter, file attribute filter, and sorting specification
1279     can be overridden using the \a nameFilters, \a filters, and \a sort
1280     arguments.
1281
1282     Returns an empty list if the directory is unreadable, does not
1283     exist, or if nothing matches the specification.
1284
1285     \sa entryInfoList(), setNameFilters(), setSorting(), setFilter()
1286 */
1287 QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
1288                             SortFlags sort) const
1289 {
1290     const QDirPrivate* d = d_ptr.constData();
1291
1292     if (filters == NoFilter)
1293         filters = d->filters;
1294     if (sort == NoSort)
1295         sort = d->sort;
1296
1297     if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
1298         d->initFileLists(*this);
1299         return d->files;
1300     }
1301
1302     QFileInfoList l;
1303     QDirIterator it(d->dirEntry.filePath(), nameFilters, filters);
1304     while (it.hasNext()) {
1305         it.next();
1306         l.append(it.fileInfo());
1307     }
1308     QStringList ret;
1309     d->sortFileList(sort, l, &ret, 0);
1310     return ret;
1311 }
1312
1313 /*!
1314     Returns a list of QFileInfo objects for all the files and
1315     directories in the directory, ordered according to the name
1316     and attribute filters previously set with setNameFilters()
1317     and setFilter(), and sorted according to the flags set with
1318     setSorting().
1319
1320     The name filter, file attribute filter, and sorting specification
1321     can be overridden using the \a nameFilters, \a filters, and \a sort
1322     arguments.
1323
1324     Returns an empty list if the directory is unreadable, does not
1325     exist, or if nothing matches the specification.
1326
1327     \sa entryList(), setNameFilters(), setSorting(), setFilter(), isReadable(), exists()
1328 */
1329 QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filters,
1330                                   SortFlags sort) const
1331 {
1332     const QDirPrivate* d = d_ptr.constData();
1333
1334     if (filters == NoFilter)
1335         filters = d->filters;
1336     if (sort == NoSort)
1337         sort = d->sort;
1338
1339     if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
1340         d->initFileLists(*this);
1341         return d->fileInfos;
1342     }
1343
1344     QFileInfoList l;
1345     QDirIterator it(d->dirEntry.filePath(), nameFilters, filters);
1346     while (it.hasNext()) {
1347         it.next();
1348         l.append(it.fileInfo());
1349     }
1350     QFileInfoList ret;
1351     d->sortFileList(sort, l, 0, &ret);
1352     return ret;
1353 }
1354
1355 /*!
1356     Creates a sub-directory called \a dirName.
1357
1358     Returns true on success; otherwise returns false.
1359
1360     If the directory already exists when this function is called, it will return false.
1361
1362     \sa rmdir()
1363 */
1364 bool QDir::mkdir(const QString &dirName) const
1365 {
1366     const QDirPrivate* d = d_ptr.constData();
1367
1368     if (dirName.isEmpty()) {
1369         qWarning("QDir::mkdir: Empty or null file name(s)");
1370         return false;
1371     }
1372
1373     QString fn = filePath(dirName);
1374     if (d->fileEngine.isNull())
1375         return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false);
1376     return d->fileEngine->mkdir(fn, false);
1377 }
1378
1379 /*!
1380     Removes the directory specified by \a dirName.
1381
1382     The directory must be empty for rmdir() to succeed.
1383
1384     Returns true if successful; otherwise returns false.
1385
1386     \sa mkdir()
1387 */
1388 bool QDir::rmdir(const QString &dirName) const
1389 {
1390     const QDirPrivate* d = d_ptr.constData();
1391
1392     if (dirName.isEmpty()) {
1393         qWarning("QDir::rmdir: Empty or null file name(s)");
1394         return false;
1395     }
1396
1397     QString fn = filePath(dirName);
1398     if (d->fileEngine.isNull())
1399         return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), false);
1400
1401     return d->fileEngine->rmdir(fn, false);
1402 }
1403
1404 /*!
1405     Creates the directory path \a dirPath.
1406
1407     The function will create all parent directories necessary to
1408     create the directory.
1409
1410     Returns true if successful; otherwise returns false.
1411
1412     If the path already exists when this function is called, it will return true.
1413
1414     \sa rmpath()
1415 */
1416 bool QDir::mkpath(const QString &dirPath) const
1417 {
1418     const QDirPrivate* d = d_ptr.constData();
1419
1420     if (dirPath.isEmpty()) {
1421         qWarning("QDir::mkpath: Empty or null file name(s)");
1422         return false;
1423     }
1424
1425     QString fn = filePath(dirPath);
1426     if (d->fileEngine.isNull())
1427         return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), true);
1428     return d->fileEngine->mkdir(fn, true);
1429 }
1430
1431 /*!
1432     Removes the directory path \a dirPath.
1433
1434     The function will remove all parent directories in \a dirPath,
1435     provided that they are empty. This is the opposite of
1436     mkpath(dirPath).
1437
1438     Returns true if successful; otherwise returns false.
1439
1440     \sa mkpath()
1441 */
1442 bool QDir::rmpath(const QString &dirPath) const
1443 {
1444     const QDirPrivate* d = d_ptr.constData();
1445
1446     if (dirPath.isEmpty()) {
1447         qWarning("QDir::rmpath: Empty or null file name(s)");
1448         return false;
1449     }
1450
1451     QString fn = filePath(dirPath);
1452     if (d->fileEngine.isNull())
1453         return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), true);
1454     return d->fileEngine->rmdir(fn, true);
1455 }
1456
1457 /*!
1458     \since 5.0
1459     Removes the directory, including all its contents.
1460
1461     Returns true if successful, otherwise false.
1462
1463     If a file or directory cannot be removed, removeRecursively() keeps going
1464     and attempts to delete as many files and sub-directories as possible,
1465     then returns false.
1466
1467     If the directory was already removed, the method returns true
1468     (expected result already reached).
1469
1470     Note: this function is meant for removing a small application-internal
1471     directory (such as a temporary directory), but not user-visible
1472     directories. For user-visible operations, it is rather recommended
1473     to report errors more precisely to the user, to offer solutions
1474     in case of errors, to show progress during the deletion since it
1475     could take several minutes, etc.
1476 */
1477 bool QDir::removeRecursively()
1478 {
1479     if (!d_ptr->exists())
1480         return true;
1481
1482     bool success = true;
1483     const QString dirPath = path();
1484     // not empty -- we must empty it first
1485     QDirIterator di(dirPath, QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot);
1486     while (di.hasNext()) {
1487         di.next();
1488         const QFileInfo& fi = di.fileInfo();
1489         bool ok;
1490         if (fi.isDir() && !fi.isSymLink())
1491             ok = QDir(di.filePath()).removeRecursively(); // recursive
1492         else
1493             ok = QFile::remove(di.filePath());
1494         if (!ok)
1495             success = false;
1496     }
1497
1498     if (success)
1499         success = rmdir(absolutePath());
1500
1501     return success;
1502 }
1503
1504 /*!
1505     Returns true if the directory is readable \e and we can open files
1506     by name; otherwise returns false.
1507
1508     \warning A false value from this function is not a guarantee that
1509     files in the directory are not accessible.
1510
1511     \sa QFileInfo::isReadable()
1512 */
1513 bool QDir::isReadable() const
1514 {
1515     const QDirPrivate* d = d_ptr.constData();
1516
1517     if (d->fileEngine.isNull()) {
1518         if (!d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission))
1519             QFileSystemEngine::fillMetaData(d->dirEntry, d->metaData, QFileSystemMetaData::UserReadPermission);
1520
1521         return (d->metaData.permissions() & QFile::ReadUser) != 0;
1522     }
1523
1524     const QAbstractFileEngine::FileFlags info =
1525         d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
1526                                        | QAbstractFileEngine::PermsMask);
1527     if (!(info & QAbstractFileEngine::DirectoryType))
1528         return false;
1529     return info & QAbstractFileEngine::ReadUserPerm;
1530 }
1531
1532 /*!
1533     \overload
1534
1535     Returns true if the directory exists; otherwise returns false.
1536     (If a file with the same name is found this function will return false).
1537
1538     The overload of this function that accepts an argument is used to test
1539     for the presence of files and directories within a directory.
1540
1541     \sa QFileInfo::exists(), QFile::exists()
1542 */
1543 bool QDir::exists() const
1544 {
1545     return d_ptr->exists();
1546 }
1547
1548 /*!
1549     Returns true if the directory is the root directory; otherwise
1550     returns false.
1551
1552     Note: If the directory is a symbolic link to the root directory
1553     this function returns false. If you want to test for this use
1554     canonicalPath(), e.g.
1555
1556     \snippet code/src_corelib_io_qdir.cpp 9
1557
1558     \sa root(), rootPath()
1559 */
1560 bool QDir::isRoot() const
1561 {
1562     if (d_ptr->fileEngine.isNull())
1563         return d_ptr->dirEntry.isRoot();
1564     return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag;
1565 }
1566
1567 /*!
1568     \fn bool QDir::isAbsolute() const
1569
1570     Returns true if the directory's path is absolute; otherwise
1571     returns false. See isAbsolutePath().
1572
1573     \sa isRelative(), makeAbsolute(), cleanPath()
1574 */
1575
1576 /*!
1577    \fn bool QDir::isAbsolutePath(const QString &)
1578
1579     Returns true if \a path is absolute; returns false if it is
1580     relative.
1581
1582     \sa isAbsolute(), isRelativePath(), makeAbsolute(), cleanPath()
1583 */
1584
1585 /*!
1586     Returns true if the directory path is relative; otherwise returns
1587     false. (Under Unix a path is relative if it does not start with a
1588     "/").
1589
1590     \sa makeAbsolute(), isAbsolute(), isAbsolutePath(), cleanPath()
1591 */
1592 bool QDir::isRelative() const
1593 {
1594     if (d_ptr->fileEngine.isNull())
1595         return d_ptr->dirEntry.isRelative();
1596     return d_ptr->fileEngine->isRelativePath();
1597 }
1598
1599
1600 /*!
1601     Converts the directory path to an absolute path. If it is already
1602     absolute nothing happens. Returns true if the conversion
1603     succeeded; otherwise returns false.
1604
1605     \sa isAbsolute(), isAbsolutePath(), isRelative(), cleanPath()
1606 */
1607 bool QDir::makeAbsolute()
1608 {
1609     const QDirPrivate *d = d_ptr.constData();
1610     QScopedPointer<QDirPrivate> dir;
1611     if (!d->fileEngine.isNull()) {
1612         QString absolutePath = d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
1613         if (QDir::isRelativePath(absolutePath))
1614             return false;
1615
1616         dir.reset(new QDirPrivate(*d_ptr.constData()));
1617         dir->setPath(absolutePath);
1618     } else { // native FS
1619         d->resolveAbsoluteEntry();
1620         dir.reset(new QDirPrivate(*d_ptr.constData()));
1621         dir->setPath(d->absoluteDirEntry.filePath());
1622     }
1623     d_ptr = dir.take(); // actually detach
1624     return true;
1625 }
1626
1627 /*!
1628     Returns true if directory \a dir and this directory have the same
1629     path and their sort and filter settings are the same; otherwise
1630     returns false.
1631
1632     Example:
1633
1634     \snippet code/src_corelib_io_qdir.cpp 10
1635 */
1636 bool QDir::operator==(const QDir &dir) const
1637 {
1638     const QDirPrivate *d = d_ptr.constData();
1639     const QDirPrivate *other = dir.d_ptr.constData();
1640
1641     if (d == other)
1642         return true;
1643     Qt::CaseSensitivity sensitive;
1644     if (d->fileEngine.isNull() || other->fileEngine.isNull()) {
1645         if (d->fileEngine.data() != other->fileEngine.data()) // one is native, the other is a custom file-engine
1646             return false;
1647
1648         sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
1649     } else {
1650         if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive())
1651             return false;
1652         sensitive = d->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
1653     }
1654
1655     if (d->filters == other->filters
1656        && d->sort == other->sort
1657        && d->nameFilters == other->nameFilters) {
1658
1659         // Assume directories are the same if path is the same
1660         if (d->dirEntry.filePath() == other->dirEntry.filePath())
1661             return true;
1662
1663         if (exists()) {
1664             if (!dir.exists())
1665                 return false; //can't be equal if only one exists
1666             // Both exist, fallback to expensive canonical path computation
1667             return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0;
1668         } else {
1669             if (dir.exists())
1670                 return false; //can't be equal if only one exists
1671             // Neither exists, compare absolute paths rather than canonical (which would be empty strings)
1672             d->resolveAbsoluteEntry();
1673             other->resolveAbsoluteEntry();
1674             return d->absoluteDirEntry.filePath().compare(other->absoluteDirEntry.filePath(), sensitive) == 0;
1675         }
1676     }
1677     return false;
1678 }
1679
1680 /*!
1681     Makes a copy of the \a dir object and assigns it to this QDir
1682     object.
1683 */
1684 QDir &QDir::operator=(const QDir &dir)
1685 {
1686     d_ptr = dir.d_ptr;
1687     return *this;
1688 }
1689
1690 /*!
1691     \overload
1692     \obsolete
1693
1694     Sets the directory path to the given \a path.
1695
1696     Use setPath() instead.
1697 */
1698 QDir &QDir::operator=(const QString &path)
1699 {
1700     d_ptr->setPath(path);
1701     return *this;
1702 }
1703
1704 /*!
1705     \fn void QDir::swap(QDir &other)
1706     \since 5.0
1707
1708     Swaps this QDir instance with \a other. This function is very fast
1709     and never fails.
1710 */
1711
1712 /*!
1713     \fn bool QDir::operator!=(const QDir &dir) const
1714
1715     Returns true if directory \a dir and this directory have different
1716     paths or different sort or filter settings; otherwise returns
1717     false.
1718
1719     Example:
1720
1721     \snippet code/src_corelib_io_qdir.cpp 11
1722 */
1723
1724 /*!
1725     Removes the file, \a fileName.
1726
1727     Returns true if the file is removed successfully; otherwise
1728     returns false.
1729 */
1730 bool QDir::remove(const QString &fileName)
1731 {
1732     if (fileName.isEmpty()) {
1733         qWarning("QDir::remove: Empty or null file name");
1734         return false;
1735     }
1736     return QFile::remove(filePath(fileName));
1737 }
1738
1739 /*!
1740     Renames a file or directory from \a oldName to \a newName, and returns
1741     true if successful; otherwise returns false.
1742
1743     On most file systems, rename() fails only if \a oldName does not
1744     exist, or if a file with the new name already exists.
1745     However, there are also other reasons why rename() can
1746     fail. For example, on at least one file system rename() fails if
1747     \a newName points to an open file.
1748
1749     If \a oldName is a file (not a directory) that can't be renamed
1750     right away, Qt will try to copy \a oldName to \a newName and remove
1751     \a oldName.
1752
1753     \sa QFile::rename()
1754 */
1755 bool QDir::rename(const QString &oldName, const QString &newName)
1756 {
1757     if (oldName.isEmpty() || newName.isEmpty()) {
1758         qWarning("QDir::rename: Empty or null file name(s)");
1759         return false;
1760     }
1761
1762     QFile file(filePath(oldName));
1763     if (!file.exists())
1764         return false;
1765     return file.rename(filePath(newName));
1766 }
1767
1768 /*!
1769     Returns true if the file called \a name exists; otherwise returns
1770     false.
1771
1772     Unless \a name contains an absolute file path, the file name is assumed
1773     to be relative to the directory itself, so this function is typically used
1774     to check for the presence of files within a directory.
1775
1776     \sa QFileInfo::exists(), QFile::exists()
1777 */
1778 bool QDir::exists(const QString &name) const
1779 {
1780     if (name.isEmpty()) {
1781         qWarning("QDir::exists: Empty or null file name");
1782         return false;
1783     }
1784     return QFile::exists(filePath(name));
1785 }
1786
1787 /*!
1788     Returns a list of the root directories on this system.
1789
1790     On Windows this returns a list of QFileInfo objects containing "C:/",
1791     "D:/", etc. On other operating systems, it returns a list containing
1792     just one root directory (i.e. "/").
1793
1794     \sa root(), rootPath()
1795 */
1796 QFileInfoList QDir::drives()
1797 {
1798 #ifdef QT_NO_FSFILEENGINE
1799     return QFileInfoList();
1800 #else
1801     return QFSFileEngine::drives();
1802 #endif
1803 }
1804
1805 /*!
1806     Returns the native directory separator: "/" under Unix (including
1807     Mac OS X) and "\\" under Windows.
1808
1809     You do not need to use this function to build file paths. If you
1810     always use "/", Qt will translate your paths to conform to the
1811     underlying operating system. If you want to display paths to the
1812     user using their operating system's separator use
1813     toNativeSeparators().
1814 */
1815 QChar QDir::separator()
1816 {
1817 #if defined(Q_OS_WIN)
1818     return QLatin1Char('\\');
1819 #else
1820     return QLatin1Char('/');
1821 #endif
1822 }
1823
1824 /*!
1825     Sets the application's current working directory to \a path.
1826     Returns true if the directory was successfully changed; otherwise
1827     returns false.
1828
1829     \sa current(), currentPath(), home(), root(), temp()
1830 */
1831 bool QDir::setCurrent(const QString &path)
1832 {
1833     return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path));
1834 }
1835
1836 /*!
1837     \fn QDir QDir::current()
1838
1839     Returns the application's current directory.
1840
1841     The directory is constructed using the absolute path of the current directory,
1842     ensuring that its path() will be the same as its absolutePath().
1843
1844     \sa currentPath(), setCurrent(), home(), root(), temp()
1845 */
1846
1847 /*!
1848     Returns the absolute path of the application's current directory.
1849
1850     \sa current(), setCurrent(), homePath(), rootPath(), tempPath()
1851 */
1852 QString QDir::currentPath()
1853 {
1854     return QFileSystemEngine::currentPath().filePath();
1855 }
1856
1857 /*!
1858     \fn QDir QDir::home()
1859
1860     Returns the user's home directory.
1861
1862     The directory is constructed using the absolute path of the home directory,
1863     ensuring that its path() will be the same as its absolutePath().
1864
1865     See homePath() for details.
1866
1867     \sa drives(), current(), root(), temp()
1868 */
1869
1870 /*!
1871     Returns the absolute path of the user's home directory.
1872
1873     Under Windows this function will return the directory of the
1874     current user's profile. Typically, this is:
1875
1876     \snippet code/src_corelib_io_qdir.cpp 12
1877
1878     Use the toNativeSeparators() function to convert the separators to
1879     the ones that are appropriate for the underlying operating system.
1880
1881     If the directory of the current user's profile does not exist or
1882     cannot be retrieved, the following alternatives will be checked (in
1883     the given order) until an existing and available path is found:
1884
1885     \list 1
1886     \li The path specified by the \c USERPROFILE environment variable.
1887     \li The path formed by concatenating the \c HOMEDRIVE and \c HOMEPATH
1888     environment variables.
1889     \li The path specified by the \c HOME environment variable.
1890     \li The path returned by the rootPath() function (which uses the \c SystemDrive
1891     environment variable)
1892     \li  The \c{C:/} directory.
1893     \endlist
1894
1895     Under non-Windows operating systems the \c HOME environment
1896     variable is used if it exists, otherwise the path returned by the
1897     rootPath().
1898
1899     \sa home(), currentPath(), rootPath(), tempPath()
1900 */
1901 QString QDir::homePath()
1902 {
1903     return QFileSystemEngine::homePath();
1904 }
1905
1906 /*!
1907     \fn QDir QDir::temp()
1908
1909     Returns the system's temporary directory.
1910
1911     The directory is constructed using the absolute path of the temporary directory,
1912     ensuring that its path() will be the same as its absolutePath().
1913
1914     See tempPath() for details.
1915
1916     \sa drives(), current(), home(), root()
1917 */
1918
1919 /*!
1920     Returns the absolute path of the system's temporary directory.
1921
1922     On Unix/Linux systems this is the path in the \c TMPDIR environment
1923     variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is
1924     usually the path in the \c TEMP or \c TMP environment
1925     variable. Whether a directory separator is added to the end or
1926     not, depends on the operating system.
1927
1928     \sa temp(), currentPath(), homePath(), rootPath()
1929 */
1930 QString QDir::tempPath()
1931 {
1932     return QFileSystemEngine::tempPath();
1933 }
1934
1935 /*!
1936     \fn QDir QDir::root()
1937
1938     Returns the root directory.
1939
1940     The directory is constructed using the absolute path of the root directory,
1941     ensuring that its path() will be the same as its absolutePath().
1942
1943     See rootPath() for details.
1944
1945     \sa drives(), current(), home(), temp()
1946 */
1947
1948 /*!
1949     Returns the absolute path of the root directory.
1950
1951     For Unix operating systems this returns "/". For Windows file
1952     systems this normally returns "c:/".
1953
1954     \sa root(), drives(), currentPath(), homePath(), tempPath()
1955 */
1956 QString QDir::rootPath()
1957 {
1958     return QFileSystemEngine::rootPath();
1959 }
1960
1961 #ifndef QT_NO_REGEXP
1962 /*!
1963     \overload
1964
1965     Returns true if the \a fileName matches any of the wildcard (glob)
1966     patterns in the list of \a filters; otherwise returns false. The
1967     matching is case insensitive.
1968
1969     \sa {QRegExp wildcard matching}, QRegExp::exactMatch(), entryList(), entryInfoList()
1970 */
1971 bool QDir::match(const QStringList &filters, const QString &fileName)
1972 {
1973     for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) {
1974         QRegExp rx(*sit, Qt::CaseInsensitive, QRegExp::Wildcard);
1975         if (rx.exactMatch(fileName))
1976             return true;
1977     }
1978     return false;
1979 }
1980
1981 /*!
1982     Returns true if the \a fileName matches the wildcard (glob)
1983     pattern \a filter; otherwise returns false. The \a filter may
1984     contain multiple patterns separated by spaces or semicolons.
1985     The matching is case insensitive.
1986
1987     \sa {QRegExp wildcard matching}, QRegExp::exactMatch(), entryList(), entryInfoList()
1988 */
1989 bool QDir::match(const QString &filter, const QString &fileName)
1990 {
1991     return match(nameFiltersFromString(filter), fileName);
1992 }
1993 #endif // QT_NO_REGEXP
1994
1995 /*!
1996     Removes all multiple directory separators "/" and resolves any
1997     "."s or ".."s found in the path, \a path.
1998
1999     Symbolic links are kept. This function does not return the
2000     canonical path, but rather the simplest version of the input.
2001     For example, "./local" becomes "local", "local/../bin" becomes
2002     "bin" and "/local/usr/../bin" becomes "/local/bin".
2003
2004     \sa absolutePath(), canonicalPath()
2005 */
2006 QString QDir::cleanPath(const QString &path)
2007 {
2008     if (path.isEmpty())
2009         return path;
2010     QString name = path;
2011     QChar dir_separator = separator();
2012     if (dir_separator != QLatin1Char('/'))
2013        name.replace(dir_separator, QLatin1Char('/'));
2014
2015     int used = 0, levels = 0;
2016     const int len = name.length();
2017     QVarLengthArray<QChar> outVector(len);
2018     QChar *out = outVector.data();
2019
2020     const QChar *p = name.unicode();
2021     for (int i = 0, last = -1, iwrite = 0; i < len; ++i) {
2022         if (p[i] == QLatin1Char('/')) {
2023             while (i+1 < len && p[i+1] == QLatin1Char('/')) {
2024 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
2025                 if (!i)
2026                     break;
2027 #endif
2028                 i++;
2029             }
2030             bool eaten = false;
2031             if (i+1 < len && p[i+1] == QLatin1Char('.')) {
2032                 int dotcount = 1;
2033                 if (i+2 < len && p[i+2] == QLatin1Char('.'))
2034                     dotcount++;
2035                 if (i == len - dotcount - 1) {
2036                     if (dotcount == 1) {
2037                         break;
2038                     } else if (levels) {
2039                         if (last == -1) {
2040                             for (int i2 = iwrite-1; i2 >= 0; i2--) {
2041                                 if (out[i2] == QLatin1Char('/')) {
2042                                     last = i2;
2043                                     break;
2044                                 }
2045                             }
2046                         }
2047                         used -= iwrite - last - 1;
2048                         break;
2049                     }
2050                 } else if (p[i+dotcount+1] == QLatin1Char('/')) {
2051                     if (dotcount == 2 && levels) {
2052                         if (last == -1 || iwrite - last == 1) {
2053                             for (int i2 = (last == -1) ? (iwrite-1) : (last-1); i2 >= 0; i2--) {
2054                                 if (out[i2] == QLatin1Char('/')) {
2055                                     eaten = true;
2056                                     last = i2;
2057                                     break;
2058                                 }
2059                             }
2060                         } else {
2061                             eaten = true;
2062                         }
2063                         if (eaten) {
2064                             levels--;
2065                             used -= iwrite - last;
2066                             iwrite = last;
2067                             last = -1;
2068                         }
2069                     } else if (dotcount == 2 && i > 0 && p[i - 1] != QLatin1Char('.')) {
2070                         eaten = true;
2071                         used -= iwrite - qMax(0, last);
2072                         iwrite = qMax(0, last);
2073                         last = -1;
2074                         ++i;
2075                     } else if (dotcount == 1) {
2076                         eaten = true;
2077                     }
2078                     if (eaten)
2079                         i += dotcount;
2080                 } else {
2081                     levels++;
2082                 }
2083             } else if (last != -1 && iwrite - last == 1) {
2084 #if defined(Q_OS_WIN)
2085                 eaten = (iwrite > 2);
2086 #else
2087                 eaten = true;
2088 #endif
2089                 last = -1;
2090             } else if (last != -1 && i == len-1) {
2091                 eaten = true;
2092             } else {
2093                 levels++;
2094             }
2095             if (!eaten)
2096                 last = i - (i - iwrite);
2097             else
2098                 continue;
2099         } else if (!i && p[i] == QLatin1Char('.')) {
2100             int dotcount = 1;
2101             if (len >= 1 && p[1] == QLatin1Char('.'))
2102                 dotcount++;
2103             if (len >= dotcount && p[dotcount] == QLatin1Char('/')) {
2104                 if (dotcount == 1) {
2105                     i++;
2106                     while (i+1 < len-1 && p[i+1] == QLatin1Char('/'))
2107                         i++;
2108                     continue;
2109                 }
2110             }
2111         }
2112         out[iwrite++] = p[i];
2113         used++;
2114     }
2115
2116     QString ret = (used == len ? name : QString(out, used));
2117     // Strip away last slash except for root directories
2118     if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
2119 #if defined (Q_OS_WIN)
2120         if (!(ret.length() == 3 && ret.at(1) == QLatin1Char(':')))
2121 #endif
2122             ret.chop(1);
2123     }
2124
2125     return ret;
2126 }
2127
2128 /*!
2129     Returns true if \a path is relative; returns false if it is
2130     absolute.
2131
2132     \sa isRelative(), isAbsolutePath(), makeAbsolute()
2133 */
2134 bool QDir::isRelativePath(const QString &path)
2135 {
2136     return QFileInfo(path).isRelative();
2137 }
2138
2139 /*!
2140     Refreshes the directory information.
2141 */
2142 void QDir::refresh() const
2143 {
2144     QDirPrivate *d = const_cast<QDir*>(this)->d_ptr.data();
2145     d->metaData.clear();
2146     d->initFileEngine();
2147     d->clearFileLists();
2148 }
2149
2150 /*!
2151     \internal
2152 */
2153 QDirPrivate* QDir::d_func()
2154 {
2155     return d_ptr.data();
2156 }
2157
2158 /*!
2159     \internal
2160
2161     Returns a list of name filters from the given \a nameFilter. (If
2162     there is more than one filter, each pair of filters is separated
2163     by a space or by a semicolon.)
2164 */
2165 QStringList QDir::nameFiltersFromString(const QString &nameFilter)
2166 {
2167     return QDirPrivate::splitFilters(nameFilter);
2168 }
2169
2170 /*!
2171     \macro void Q_INIT_RESOURCE(name)
2172     \relates QDir
2173
2174     Initializes the resources specified by the \c .qrc file with the
2175     specified base \a name. Normally, Qt resources are loaded
2176     automatically at startup. The Q_INIT_RESOURCE() macro is
2177     necessary on some platforms for resources stored in a static
2178     library.
2179
2180     For example, if your application's resources are listed in a file
2181     called \c myapp.qrc, you can ensure that the resources are
2182     initialized at startup by adding this line to your \c main()
2183     function:
2184
2185     \snippet code/src_corelib_io_qdir.cpp 13
2186
2187     If the file name contains characters that cannot be part of a valid C++ function name
2188     (such as '-'), they have to be replaced by the underscore character ('_').
2189
2190     Note: This macro cannot be used in a namespace. It should be called from
2191     main(). If that is not possible, the following workaround can be used
2192     to init the resource \c myapp from the function \c{MyNamespace::myFunction}:
2193
2194     \snippet code/src_corelib_io_qdir.cpp 14
2195
2196     \sa Q_CLEANUP_RESOURCE(), {The Qt Resource System}
2197 */
2198
2199 /*!
2200     \since 4.1
2201     \macro void Q_CLEANUP_RESOURCE(name)
2202     \relates QDir
2203
2204     Unloads the resources specified by the \c .qrc file with the base
2205     name \a name.
2206
2207     Normally, Qt resources are unloaded automatically when the
2208     application terminates, but if the resources are located in a
2209     plugin that is being unloaded, call Q_CLEANUP_RESOURCE() to force
2210     removal of your resources.
2211
2212     Note: This macro cannot be used in a namespace. Please see the
2213     Q_INIT_RESOURCE documentation for a workaround.
2214
2215     Example:
2216
2217     \snippet code/src_corelib_io_qdir.cpp 15
2218
2219     \sa Q_INIT_RESOURCE(), {The Qt Resource System}
2220 */
2221
2222
2223 #ifndef QT_NO_DEBUG_STREAM
2224 QDebug operator<<(QDebug debug, QDir::Filters filters)
2225 {
2226     QStringList flags;
2227     if (filters == QDir::NoFilter) {
2228         flags << QLatin1String("NoFilter");
2229     } else {
2230         if (filters & QDir::Dirs) flags << QLatin1String("Dirs");
2231         if (filters & QDir::AllDirs) flags << QLatin1String("AllDirs");
2232         if (filters & QDir::Files) flags << QLatin1String("Files");
2233         if (filters & QDir::Drives) flags << QLatin1String("Drives");
2234         if (filters & QDir::NoSymLinks) flags << QLatin1String("NoSymLinks");
2235         if (filters & QDir::NoDot) flags << QLatin1String("NoDot");
2236         if (filters & QDir::NoDotDot) flags << QLatin1String("NoDotDot");
2237         if ((filters & QDir::AllEntries) == QDir::AllEntries) flags << QLatin1String("AllEntries");
2238         if (filters & QDir::Readable) flags << QLatin1String("Readable");
2239         if (filters & QDir::Writable) flags << QLatin1String("Writable");
2240         if (filters & QDir::Executable) flags << QLatin1String("Executable");
2241         if (filters & QDir::Modified) flags << QLatin1String("Modified");
2242         if (filters & QDir::Hidden) flags << QLatin1String("Hidden");
2243         if (filters & QDir::System) flags << QLatin1String("System");
2244         if (filters & QDir::CaseSensitive) flags << QLatin1String("CaseSensitive");
2245     }
2246     debug << "QDir::Filters(" << qPrintable(flags.join(QLatin1String("|"))) << ')';
2247     return debug;
2248 }
2249
2250 static QDebug operator<<(QDebug debug, QDir::SortFlags sorting)
2251 {
2252     if (sorting == QDir::NoSort) {
2253         debug << "QDir::SortFlags(NoSort)";
2254     } else {
2255         QString type;
2256         if ((sorting & 3) == QDir::Name) type = QLatin1String("Name");
2257         if ((sorting & 3) == QDir::Time) type = QLatin1String("Time");
2258         if ((sorting & 3) == QDir::Size) type = QLatin1String("Size");
2259         if ((sorting & 3) == QDir::Unsorted) type = QLatin1String("Unsorted");
2260
2261         QStringList flags;
2262         if (sorting & QDir::DirsFirst) flags << QLatin1String("DirsFirst");
2263         if (sorting & QDir::DirsLast) flags << QLatin1String("DirsLast");
2264         if (sorting & QDir::IgnoreCase) flags << QLatin1String("IgnoreCase");
2265         if (sorting & QDir::LocaleAware) flags << QLatin1String("LocaleAware");
2266         if (sorting & QDir::Type) flags << QLatin1String("Type");
2267         debug << "QDir::SortFlags(" << qPrintable(type)
2268               << '|'
2269               << qPrintable(flags.join(QLatin1String("|"))) << ')';
2270     }
2271     return debug;
2272 }
2273
2274 QDebug operator<<(QDebug debug, const QDir &dir)
2275 {
2276     debug.maybeSpace() << "QDir(" << dir.path()
2277                        << ", nameFilters = {"
2278                        << qPrintable(dir.nameFilters().join(QLatin1String(",")))
2279                        << "}, "
2280                        << dir.sorting()
2281                        << ','
2282                        << dir.filter()
2283                        << ')';
2284     return debug.space();
2285 }
2286 #endif // QT_NO_DEBUG_STREAM
2287
2288 QT_END_NAMESPACE