1 /****************************************************************************
4 ** Implementation of QDir class
8 ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
10 ** This file is part of the tools module of the Qt GUI Toolkit.
12 ** This file may be distributed under the terms of the Q Public License
13 ** as defined by Trolltech AS of Norway and appearing in the file
14 ** LICENSE.QPL included in the packaging of this file.
16 ** This file may be distributed and/or modified under the terms of the
17 ** GNU General Public License version 2 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.GPL included in the
19 ** packaging of this file.
21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22 ** licenses may use this file in accordance with the Qt Commercial License
23 ** Agreement provided with the Software.
25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29 ** information about Qt Commercial License Agreements.
30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
33 ** Contact info@trolltech.com if any conditions of this licensing are
36 **********************************************************************/
43 #include "qfileinfo.h"
44 #include "qfiledefs_p.h"
46 #include "qstringlist.h"
53 \brief Traverses directory structures and contents in a
54 platform-independent way.
58 A QDir can point to a file using either a relative or an absolute file
59 path. Absolute file paths begin with the directory separator ('/') or a
60 drive specification (not applicable to UNIX). Relative file names begin
61 with a directory name or a file name and specify a path relative to the
64 An example of an absolute path is the string "/tmp/quartz", a relative
65 path might look like "src/fatlib". You can use the function isRelative()
66 to check if a QDir is using a relative or an absolute file path. You can
67 call the function convertToAbs() to convert a relative QDir to an
70 The directory "example" under the current directory is checked for existence
74 QDir d( "example" ); // "./example"
76 qWarning( "Cannot find the example directory" );
79 If you always use '/' as a directory separator, Qt will translate your
80 paths to conform to the underlying operating system.
82 cd() and cdUp() can be used to navigate the directory tree. Note that the
83 logical cd and cdUp operations are not performed if the new directory does
88 QDir d = QDir::root(); // "/"
89 if ( !d.cd("tmp") ) { // "/tmp"
90 qWarning( "Cannot find the \"/tmp\" directory" );
92 QFile f( d.filePath("ex1.txt") ); // "/tmp/ex1.txt"
93 if ( !f.open(IO_ReadWrite) )
94 qWarning( "Cannot create the file %s", f.name() );
98 To read the contents of a directory you can use the entryList() and
99 entryInfoList() functions.
107 // This program scans the current directory and lists all files
108 // that are not symbolic links, sorted by size with the smallest files
112 int main( int argc, char **argv )
115 d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
116 d.setSorting( QDir::Size | QDir::Reversed );
118 const QFileInfoList *list = d.entryInfoList();
119 QFileInfoListIterator it( *list ); // create list iterator
120 QFileInfo *fi; // pointer for traversing
122 printf( " BYTES FILENAME\n" ); // print header
123 while ( (fi=it.current()) ) { // for each file...
124 printf( "%10li %s\n", fi->size(), fi->fileName().data() );
125 ++it; // goto next list element
133 Constructs a QDir pointing to the current directory.
139 dPath = QString::fromLatin1(".");
146 \arg \e path is the directory.
147 \arg \e nameFilter is the file name filter.
148 \arg \e sortSpec is the sort specification, which describes how to
149 sort the files in the directory.
150 \arg \e filterSpec is the filter specification, which describes how
151 to filter the files in the directory.
153 Most of these arguments (except \e path) have optional values.
157 // lists all files in /tmp
160 for ( int i=0; i<d.count(); i++ )
161 printf( "%s\n", d[i] );
164 If \e path is "" or null, the directory is set to "." (the current
165 directory). If \e nameFilter is "" or null, it is set to "*" (all
168 No check is made to ensure that the directory exists.
170 \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
173 QDir::QDir( const QString &path, const QString &nameFilter,
174 int sortSpec, int filterSpec )
177 dPath = cleanDirPath( path );
178 if ( dPath.isEmpty() )
179 dPath = QString::fromLatin1(".");
180 nameFilt = nameFilter;
181 if ( nameFilt.isEmpty() )
182 nameFilt = QString::fromLatin1("*");
183 filtS = (FilterSpec)filterSpec;
184 sortS = (SortSpec)sortSpec;
188 Constructs a QDir that is a copy of the given directory.
192 QDir::QDir( const QDir &d )
197 nameFilt = d.nameFilt;
209 nameFilt = QString::fromLatin1("*");
213 sortS = SortSpec(Name | IgnoreCase);
217 Destructs the QDir and cleans up.
230 Sets the path of the directory. The path is cleaned of redundant ".", ".."
231 and multiple separators. No check is made to ensure that a directory
232 with this path exists.
234 The path can be either absolute or relative. Absolute paths begin with the
235 directory separator ('/') or a drive specification (not
237 Relative file names begin with a directory name or a file name and specify
238 a path relative to the current directory. An example of
239 an absolute path is the string "/tmp/quartz", a relative path might look like
240 "src/fatlib". You can use the function isRelative() to check if a QDir
241 is using a relative or an absolute file path. You can call the function
242 convertToAbs() to convert a relative QDir to an absolute one.
244 \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
245 absFilePath(), isRelative(), convertToAbs()
248 void QDir::setPath( const QString &path )
250 dPath = cleanDirPath( path );
251 if ( dPath.isEmpty() )
252 dPath = QString::fromLatin1(".");
257 \fn QString QDir::path() const
258 Returns the path, this may contain symbolic links, but never contains
259 redundant ".", ".." or multiple separators.
261 The returned path can be either absolute or relative (see setPath()).
263 \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
264 absFilePath(), convertSeparators()
268 Returns the absolute (a path that starts with '/') path, which may
269 contain symbolic links, but never contains redundant ".", ".." or
272 \sa setPath(), canonicalPath(), exists(), cleanDirPath(), dirName(),
276 QString QDir::absPath() const
278 if ( QDir::isRelativePath(dPath) ) {
279 QString tmp = currentDirPath();
280 if ( tmp.right(1) != QString::fromLatin1("/") )
283 return cleanDirPath( tmp );
285 return cleanDirPath( dPath );
290 Returns the name of the directory, this is NOT the same as the path, e.g.
291 a directory with the name "mail", might have the path "/var/spool/mail".
292 If the directory has no name (e.g. the root directory) a null string is
295 No check is made to ensure that a directory with this name actually exists.
297 \sa path(), absPath(), absFilePath(), exists(), QString::isNull()
300 QString QDir::dirName() const
302 int pos = dPath.findRev( '/' );
305 return dPath.right( dPath.length() - pos - 1 );
309 Returns the path name of a file in the directory. Does NOT check if
310 the file actually exists in the directory. If the QDir is relative
311 the returned path name will also be relative. Redundant multiple separators
312 or "." and ".." directories in \e fileName will not be removed (see
315 If \e acceptAbsPath is TRUE a \e fileName starting with a separator
316 ('/') will be returned without change.
317 If \e acceptAbsPath is FALSE an absolute path will be appended to
320 \sa absFilePath(), isRelative(), canonicalPath()
323 QString QDir::filePath( const QString &fileName,
324 bool acceptAbsPath ) const
326 if ( acceptAbsPath && !isRelativePath(fileName) )
327 return QString(fileName);
330 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
331 fileName[0] != '/') )
338 Returns the absolute path name of a file in the directory. Does NOT check if
339 the file actually exists in the directory. Redundant multiple separators
340 or "." and ".." directories in \e fileName will NOT be removed (see
343 If \e acceptAbsPath is TRUE a \e fileName starting with a separator
344 ('/') will be returned without change.
345 if \e acceptAbsPath is FALSE an absolute path will be appended to
351 QString QDir::absFilePath( const QString &fileName,
352 bool acceptAbsPath ) const
354 if ( acceptAbsPath && !isRelativePath( fileName ) )
357 QString tmp = absPath();
358 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
359 fileName[0] != '/') )
367 Converts the '/' separators in \a pathName to system native
368 separators. Returns the translated string.
370 On Windows, convertSeparators("c:/winnt/system32") returns
373 No conversion is done on UNIX.
376 QString QDir::convertSeparators( const QString &pathName )
378 QString n( pathName );
379 #if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
380 for ( int i=0; i<(int)n.length(); i++ ) {
390 Changes directory by descending into the given directory. Returns
391 TRUE if the new directory exists and is readable. Note that the logical
392 cd operation is NOT performed if the new directory does not exist.
394 If \e acceptAbsPath is TRUE a path starting with a separator ('/')
395 will cd to the absolute directory, if \e acceptAbsPath is FALSE
396 any number of separators at the beginning of \e dirName will be removed.
400 QDir d = QDir::home(); // now points to home directory
401 if ( !d.cd("c++") ) { // now points to "c++" under home directory if OK
402 QFileInfo fi( d, "c++" );
405 qWarning( "Cannot cd into \"%s\".", (char*)d.absFilePath("c++") );
407 qWarning( "Cannot create directory \"%s\"\n"
408 "A file named \"c++\" already exists in \"%s\"",
409 (const char *)d.absFilePath("c++"),
410 (const char *)d.path() );
413 qWarning( "Creating directory \"%s\"",
414 (const char *) d.absFilePath("c++") );
415 if ( !d.mkdir( "c++" ) ) {
416 qWarning("Could not create directory \"%s\"",
417 (const char *)d.absFilePath("c++") );
424 Calling cd( ".." ) is equivalent to calling cdUp().
426 \sa cdUp(), isReadable(), exists(), path()
429 bool QDir::cd( const QString &dirName, bool acceptAbsPath )
431 if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
434 if ( acceptAbsPath && !isRelativePath(dirName) ) {
435 dPath = cleanDirPath( dirName );
440 if ( dirName.find('/') >= 0
441 || old == QString::fromLatin1(".")
442 || dirName == QString::fromLatin1("..") )
443 dPath = cleanDirPath( dPath );
446 dPath = old; // regret
454 Changes directory by moving one directory up the path followed to arrive
455 at the current directory.
457 Returns TRUE if the new directory exists and is readable. Note that the
458 logical cdUp() operation is not performed if the new directory does not
461 \sa cd(), isReadable(), exists(), path()
466 return cd( QString::fromLatin1("..") );
470 \fn QString QDir::nameFilter() const
471 Returns the string set by setNameFilter()
475 Sets the name filter used by entryList() and entryInfoList().
477 The name filter is a wildcarding filter that understands "*" and "?"
478 wildcards, You may specify several filter entries separated by a " " or a ";". If
479 you want entryList() and entryInfoList() to list all files ending with
480 ".cpp" and all files ending with ".h", you simply call
481 dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h")
483 \sa nameFilter(), setFilter()
486 void QDir::setNameFilter( const QString &nameFilter )
488 nameFilt = nameFilter;
489 if ( nameFilt.isEmpty() )
490 nameFilt = QString::fromLatin1("*");
495 \fn QDir::FilterSpec QDir::filter() const
496 Returns the value set by setFilter()
499 /*! \enum QDir::FilterSpec
501 This enum describes how QDir is to select what entries in a
502 directory to return. The filter value is specified by or-ing
503 together values from the following list: <ul>
505 <li> \c Dirs - List directories only
506 <li> \c Files - List files only
508 <li> \c Drives - List disk drives (does nothing under unix)
509 <li> \c NoSymLinks - Do not list symbolic links (where they exist)
510 <li> \c Readable - List files for which the application has read access.
511 <li> \c Writable - List files for which the application has write access.
512 <li> \c Executable - List files for which the application has execute access
513 <li> \c Modified - Only list files that have been modified (does nothing
515 <li> \c Hidden - List hidden files (on unix, files starting with a .)
516 <li> \c System - List system files (does nothing under unix)
519 If you do not set any of \c Readable, \c Writable or \c Executable,
520 QDir will set all three of them. This makes the default easy to
521 write and at the same time useful.
523 Examples: \c Readable|Writable means list all files for which the
524 application has read access, write access or both. \c Dirs|Drives
525 means list drives, directories, all files that the application can
526 read, write or execute, and also symlinks to such files/directories.
531 Sets the filter used by entryList() and entryInfoList(). The filter is used
532 to specify the kind of files that should be returned by entryList() and
535 \sa filter(), setNameFilter()
538 void QDir::setFilter( int filterSpec )
540 if ( filtS == (FilterSpec) filterSpec )
542 filtS = (FilterSpec) filterSpec;
547 \fn QDir::SortSpec QDir::sorting() const
549 Returns the value set by setSorting()
554 /*! \enum QDir::SortSpec
556 This enum describes how QDir is to sort entries in a directory when
557 it returns a list of them. The sort value is specified by or-ing
558 together values from the following list: <ul>
560 <li> \c Name - sort by name
561 <li> \c Time - sort by time (modification time)
562 <li> \c Size - sort by file size
563 <li> \c Unsorted - do not sort
565 <li> \c DirsFirst - put all directories first in the list
566 <li> \c Reversed - reverse the sort order
567 <li> \c IgnoreCase - sort case-insensitively
571 You can only specify one of the first four. If you specify both \c
572 DirsFirst and \c Reversed, directories are still put first but the
573 list is otherwise reversed.
576 // ### Unsorted+DirsFirst ? Unsorted+Reversed?
579 Sets the sorting order used by entryList() and entryInfoList().
581 The \e sortSpec is specified by or-ing values from the enum
582 SortSpec. The different values are:
586 <dt>Name<dd> Sort by name (alphabetical order).
587 <dt>Time<dd> Sort by time (most recent first).
588 <dt>Size<dd> Sort by size (largest first).
589 <dt>Unsorted<dd> Use the operating system order (UNIX does NOT sort
592 ORed with zero or more of these:
594 <dt>DirsFirst<dd> Always put directory names first.
595 <dt>Reversed<dd> Reverse sort order.
596 <dt>IgnoreCase<dd> Ignore case when sorting by name.
600 void QDir::setSorting( int sortSpec )
602 if ( sortS == (SortSpec) sortSpec )
604 sortS = (SortSpec) sortSpec;
609 \fn bool QDir::matchAllDirs() const
610 Returns the value set by setMatchAllDirs()
612 \sa setMatchAllDirs()
616 If \e enable is TRUE, all directories will be listed (even if they do not
617 match the filter or the name filter), otherwise only matched directories
620 \bug Currently, directories that do not match the filter will not be
621 included (the name filter will be ignored as expected).
626 void QDir::setMatchAllDirs( bool enable )
628 if ( (bool)allDirs == enable )
636 Returns the number of files that was found.
637 Equivalent to entryList().count().
638 \sa operator[](), entryList()
641 uint QDir::count() const
643 return entryList().count();
647 Returns the file name at position \e index in the list of found file
649 Equivalent to entryList().at(index).
651 Returns null if the \e index is out of range or if the entryList()
654 \sa count(), entryList()
657 QString QDir::operator[]( int index ) const
660 return fList && index >= 0 && index < (int)fList->count() ?
661 (*fList)[index] : QString::null;
666 This function is included to easy porting from Qt 1.x to Qt 2.0,
667 it is the same as entryList(), but encodes the filenames as 8-bit
668 strings using QFile::encodedName().
670 It is more efficient to use entryList().
672 QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
675 QStringList l = entryList(filterSpec,sortSpec);
676 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
677 r.append( QFile::encodeName(*it) );
683 This function is included to easy porting from Qt 1.x to Qt 2.0,
684 it is the same as entryList(), but encodes the filenames as 8-bit
685 strings using QFile::encodedName().
687 It is more efficient to use entryList().
689 QStrList QDir::encodedEntryList( const QString &nameFilter,
694 QStringList l = entryList(nameFilter,filterSpec,sortSpec);
695 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
696 r.append( QFile::encodeName(*it) );
704 Returns a list of the names of all files and directories in the directory
705 indicated by the setSorting(), setFilter() and setNameFilter()
708 The filter and sorting specifications can be overridden using the
709 \e filterSpec and \e sortSpec arguments.
711 Returns an empty list if the directory is unreadable or does not exist.
713 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
717 QStringList QDir::entryList( int filterSpec, int sortSpec ) const
719 if ( !dirty && filterSpec == (int)DefaultFilter &&
720 sortSpec == (int)DefaultSort )
722 return entryList( nameFilt, filterSpec, sortSpec );
726 Returns a list of the names of all files and directories in the directory
727 indicated by the setSorting(), setFilter() and setNameFilter()
730 The filter and sorting specifications can be overridden using the
731 \e nameFilter, \e filterSpec and \e sortSpec arguments.
733 Returns and empty list if the directory is unreadable or does not exist.
735 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
739 QStringList QDir::entryList( const QString &nameFilter,
740 int filterSpec, int sortSpec ) const
742 if ( filterSpec == (int)DefaultFilter )
744 if ( sortSpec == (int)DefaultSort )
746 QDir *that = (QDir*)this; // mutable function
747 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
750 return QStringList();
754 Returns a list of QFileInfo objects for all files and directories in
755 the directory pointed to using the setSorting(), setFilter() and
756 setNameFilter() specifications.
758 The filter and sorting specifications can be overridden using the
759 \e filterSpec and \e sortSpec arguments.
761 Returns 0 if the directory is unreadable or does not exist.
763 The returned pointer is a const pointer to a QFileInfoList. The list is
764 owned by the QDir object and will be reused on the next call to
765 entryInfoList() for the same QDir instance. If you want to keep the
766 entries of the list after a subsequent call to this function you will
769 \sa entryList(), setNameFilter(), setSorting(), setFilter()
772 const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
774 if ( !dirty && filterSpec == (int)DefaultFilter &&
775 sortSpec == (int)DefaultSort )
777 return entryInfoList( nameFilt, filterSpec, sortSpec );
781 Returns a list of QFileInfo objects for all files and directories in
782 the directory pointed to using the setSorting(), setFilter() and
783 setNameFilter() specifications.
785 The filter and sorting specifications can be overridden using the
786 \e nameFilter, \e filterSpec and \e sortSpec arguments.
788 Returns 0 if the directory is unreadable or does not exist.
790 The returned pointer is a const pointer to a QFileInfoList. The list is
791 owned by the QDir object and will be reused on the next call to
792 entryInfoList() for the same QDir instance. If you want to keep the
793 entries of the list after a subsequent call to this function you will
796 \sa entryList(), setNameFilter(), setSorting(), setFilter()
799 const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
800 int filterSpec, int sortSpec ) const
802 if ( filterSpec == (int)DefaultFilter )
804 if ( sortSpec == (int)DefaultSort )
806 QDir *that = (QDir*)this; // mutable function
807 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
814 Returns TRUE if the directory exists. (If a file with the same
815 name is found this function will of course return FALSE).
817 \sa QFileInfo::exists(), QFile::exists()
820 bool QDir::exists() const
822 QFileInfo fi( dPath );
823 return fi.exists() && fi.isDir();
827 Returns TRUE if the directory path is relative to the current directory,
828 FALSE if the path is absolute (e.g. under UNIX a path is relative if it
829 does not start with a '/').
831 According to Einstein this function should always return TRUE.
836 bool QDir::isRelative() const
838 return isRelativePath( dPath );
842 Converts the directory path to an absolute path. If it is already
843 absolute nothing is done.
848 void QDir::convertToAbs()
854 Makes a copy of d and assigns it to this QDir.
857 QDir &QDir::operator=( const QDir &d )
864 nameFilt = d.nameFilt;
873 Sets the directory path to be the given path.
876 QDir &QDir::operator=( const QString &path )
878 dPath = cleanDirPath( path );
885 \fn bool QDir::operator!=( const QDir &d ) const
886 Returns TRUE if the \e d and this dir have different path or
887 different sort/filter settings, otherwise FALSE.
891 Returns TRUE if the \e d and this dir have the same path and all sort
892 and filter settings are equal, otherwise FALSE.
895 bool QDir::operator==( const QDir &d ) const
897 return dPath == d.dPath &&
898 nameFilt == d.nameFilt &&
899 allDirs == d.allDirs &&
908 If \e acceptAbsPath is TRUE a path starting with a separator ('/')
909 will remove the file with the absolute path, if \e acceptAbsPath is FALSE
910 any number of separators at the beginning of \e fileName will be removed.
912 Returns TRUE if successful, otherwise FALSE.
915 bool QDir::remove( const QString &fileName, bool acceptAbsPath )
917 if ( fileName.isEmpty() ) {
918 #if defined(CHECK_NULL)
919 qWarning( "QDir::remove: Empty or null file name" );
923 QString p = filePath( fileName, acceptAbsPath );
924 return QFile::remove( p );
928 Checks for existence of a file.
930 If \e acceptAbsPaths is TRUE a path starting with a separator ('/')
931 will check the file with the absolute path, if \e acceptAbsPath is FALSE
932 any number of separators at the beginning of \e name will be removed.
934 Returns TRUE if the file exists, otherwise FALSE.
936 \sa QFileInfo::exists(), QFile::exists()
939 bool QDir::exists( const QString &name, bool acceptAbsPath )
941 if ( name.isEmpty() ) {
942 #if defined(CHECK_NULL)
943 qWarning( "QDir::exists: Empty or null file name" );
947 QString tmp = filePath( name, acceptAbsPath );
948 return QFile::exists( tmp );
952 Returns the native directory separator; '/' under UNIX and '\' under
953 MS-DOS, Windows NT and OS/2.
955 You do not need to use this function to build file paths. If you always
956 use '/', Qt will translate your paths to conform to the underlying
960 char QDir::separator()
962 #if defined(_OS_UNIX_)
964 #elif defined (_OS_FATFS_)
966 #elif defined (_OS_MAC_)
974 Returns the current directory.
975 \sa currentDirPath(), QDir::QDir()
980 return QDir( currentDirPath() );
984 Returns the home directory.
990 return QDir( homeDirPath() );
994 Returns the root directory.
995 \sa rootDirPath() drives()
1000 return QDir( rootDirPath() );
1004 \fn QString QDir::homeDirPath()
1006 Returns the absolute path for the user's home directory,
1010 QStringList qt_makeFilterList( const QString &filter )
1012 if ( filter.isEmpty() )
1013 return QStringList();
1016 int i = filter.find( sep, 0 );
1017 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
1020 QStringList lst = QStringList::split( sep, filter );
1022 QStringList::Iterator it = lst.begin();
1024 for ( ; it != lst.end(); ++it ) {
1026 lst2 << s.stripWhiteSpace();
1032 Returns TRUE if the \e fileName matches one of the wildcards in the list \e filters.
1036 bool QDir::match( const QStringList &filters, const QString &fileName )
1038 QStringList::ConstIterator sit = filters.begin();
1039 bool matched = FALSE;
1040 for ( ; sit != filters.end(); ++sit ) {
1041 QRegExp regexp( (*sit).data(), FALSE, TRUE );
1042 if ( regexp.match( fileName.data() ) != -1 ) {
1052 Returns TRUE if the \e fileName matches the wildcard \e filter.
1053 \a Filter may also contain multiple wildcards separated by spaces or
1058 bool QDir::match( const QString &filter, const QString &fileName )
1060 QStringList lst = qt_makeFilterList( filter );
1061 return match( lst, fileName );
1066 Removes all multiple directory separators ('/') and resolves
1067 any "." or ".." found in the path.
1069 Symbolic links are kept. This function does not return the
1070 canonical path, but rather the most simplified version of the input.
1071 "../stuff" becomes "stuff", "stuff/../nonsense" becomes "nonsense"
1072 and "\\stuff\\more\\..\\nonsense" becomes "\\stuff\\nonsense".
1074 \sa absPath() canonicalPath()
1077 QString QDir::cleanDirPath( const QString &filePath )
1079 QString name = filePath;
1082 if ( name.isEmpty() )
1087 bool addedSeparator;
1088 if ( isRelativePath(name) ) {
1089 addedSeparator = TRUE;
1090 name.insert( 0, '/' );
1092 addedSeparator = FALSE;
1095 int ePos, pos, upLevel;
1097 pos = ePos = name.length();
1101 while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
1102 len = ePos - pos - 1;
1103 if ( len == 2 && name.at(pos + 1) == '.'
1104 && name.at(pos + 2) == '.' ) {
1107 if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
1109 newPath = QString::fromLatin1("/")
1110 + name.mid(pos + 1, len) + newPath;
1117 if ( addedSeparator ) {
1119 newPath.insert( 0, QString::fromLatin1("/..") );
1120 if ( !newPath.isEmpty() )
1121 newPath.remove( 0, 1 );
1123 newPath = QString::fromLatin1(".");
1125 if ( newPath.isEmpty() )
1126 newPath = QString::fromLatin1("/");
1127 #if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
1128 if ( name[0] == '/' ) {
1129 if ( name[1] == '/' ) // "\\machine\x\ ..."
1130 newPath.insert( 0, '/' );
1132 newPath = name.left(2) + newPath;
1139 int qt_cmp_si_sortSpec;
1141 #if defined(Q_C_CALLBACKS)
1145 int qt_cmp_si( const void *n1, const void *n2 )
1150 QDirSortItem* f1 = (QDirSortItem*)n1;
1151 QDirSortItem* f2 = (QDirSortItem*)n2;
1153 if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
1154 if ( f1->item->isDir() != f2->item->isDir() )
1155 return f1->item->isDir() ? -1 : 1;
1158 int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
1162 r = f1->item->lastModified().secsTo(f2->item->lastModified());
1165 r = f2->item->size() - f1->item->size();
1171 if ( r == 0 && sortBy != QDir::Unsorted ) {
1172 // Still not sorted - sort by name
1173 bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
1175 if ( f1->filename_cache.isNull() )
1176 f1->filename_cache = ic ? f1->item->fileName().lower()
1177 : f1->item->fileName();
1178 if ( f2->filename_cache.isNull() )
1179 f2->filename_cache = ic ? f2->item->fileName().lower()
1180 : f2->item->fileName();
1182 r = f1->filename_cache.compare(f2->filename_cache);
1186 // Enforce an order - the order the items appear in the array
1187 r = (int)((char*)n1 - (char*)n2);
1190 if ( qt_cmp_si_sortSpec & QDir::Reversed )
1196 #if defined(Q_C_CALLBACKS)