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