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