summaryrefslogtreecommitdiff
path: root/qmake/tools/qdir.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qdir.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qdir.cpp1294
1 files changed, 1294 insertions, 0 deletions
diff --git a/qmake/tools/qdir.cpp b/qmake/tools/qdir.cpp
new file mode 100644
index 0000000..418ea49
--- a/dev/null
+++ b/qmake/tools/qdir.cpp
@@ -0,0 +1,1294 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QDir class
5**
6** Created : 950427
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include "qdir.h"
40
41#ifndef QT_NO_DIR
42#include <private/qdir_p.h>
43#include "qfileinfo.h"
44#include "qregexp.h"
45#include "qstringlist.h"
46#include <stdlib.h>
47#include <ctype.h>
48
49
50
51/*!
52 \class QDir
53 \brief The QDir class provides access to directory structures and their contents in a platform-independent way.
54
55 \ingroup io
56 \mainclass
57
58 A QDir is used to manipulate path names, access information
59 regarding paths and files, and manipulate the underlying file
60 system.
61
62 A QDir can point to a file using either a relative or an absolute
63 path. Absolute paths begin with the directory separator "/"
64 (optionally preceded by a drive specification under Windows). If
65 you always use "/" as a directory separator, Qt will translate
66 your paths to conform to the underlying operating system. Relative
67 file names begin with a directory name or a file name and specify
68 a path relative to the current directory.
69
70 The "current" path refers to the application's working directory.
71 A QDir's own path is set and retrieved with setPath() and path().
72
73 An example of an absolute path is the string "/tmp/quartz", a
74 relative path might look like "src/fatlib". You can use the
75 function isRelative() to check if a QDir is using a relative or an
76 absolute file path. Call convertToAbs() to convert a relative QDir
77 to an absolute one. For a simplified path use cleanDirPath(). To
78 obtain a path which has no symbolic links or redundant ".."
79 elements use canonicalPath(). The path can be set with setPath(),
80 and changed with cd() and cdUp().
81
82 QDir provides several static functions, for example, setCurrent()
83 to set the application's working directory and currentDirPath() to
84 retrieve the application's working directory. Access to some
85 common paths is provided with the static functions, current(),
86 home() and root() which return QDir objects or currentDirPath(),
87 homeDirPath() and rootDirPath() which return the path as a string.
88
89 The number of entries in a directory is returned by count().
90 Obtain a string list of the names of all the files and directories
91 in a directory with entryList(). If you prefer a list of QFileInfo
92 pointers use entryInfoList(). Both these functions can apply a
93 name filter, an attributes filter (e.g. read-only, files not
94 directories, etc.), and a sort order. The filters and sort may be
95 set with calls to setNameFilter(), setFilter() and setSorting().
96 They may also be specified in the entryList() and
97 entryInfoList()'s arguments.
98
99 Create a new directory with mkdir(), rename a directory with
100 rename() and remove an existing directory with rmdir(). Remove a
101 file with remove(). You can interrogate a directory with exists(),
102 isReadable() and isRoot().
103
104 To get a path with a filename use filePath(), and to get a
105 directory name use dirName(); neither of these functions checks
106 for the existence of the file or directory.
107
108 The list of root directories is provided by drives(); on Unix
109 systems this returns a list containing one root directory, "/"; on
110 Windows the list will usually contain "C:/", and possibly "D:/",
111 etc.
112
113 If you need the path in a form suitable for the underlying
114 operating system use convertSeparators().
115
116 Examples:
117
118 See if a directory exists.
119 \code
120 QDir d( "example" ); // "./example"
121 if ( !d.exists() )
122 qWarning( "Cannot find the example directory" );
123 \endcode
124
125 Traversing directories and reading a file.
126 \code
127 QDir d = QDir::root(); // "/"
128 if ( !d.cd("tmp") ) { // "/tmp"
129 qWarning( "Cannot find the \"/tmp\" directory" );
130 } else {
131 QFile f( d.filePath("ex1.txt") );// "/tmp/ex1.txt"
132 if ( !f.open(IO_ReadWrite) )
133 qWarning( "Cannot create the file %s", f.name() );
134 }
135 \endcode
136
137 A program that lists all the files in the current directory
138 (excluding symbolic links), sorted by size, smallest first:
139 \code
140 #include <stdio.h>
141 #include <qdir.h>
142
143 int main( int argc, char **argv )
144 {
145 QDir d;
146 d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
147 d.setSorting( QDir::Size | QDir::Reversed );
148
149 const QFileInfoList *list = d.entryInfoList();
150 QFileInfoListIterator it( *list );
151 QFileInfo *fi;
152
153 printf( " Bytes Filename\n" );
154 while ( (fi = it.current()) != 0 ) {
155 printf( "%10li %s\n", fi->size(), fi->fileName().latin1() );
156 ++it;
157 }
158 return 0;
159 }
160 \endcode
161*/
162
163/*!
164 Constructs a QDir pointing to the current directory.
165
166 \sa currentDirPath()
167*/
168
169QDir::QDir()
170{
171 dPath = QString::fromLatin1(".");
172 init();
173}
174
175/*!
176 Constructs a QDir with path \a path, that filters its entries by
177 name using \a nameFilter and by attributes using \a filterSpec. It
178 also sorts the names using \a sortSpec.
179
180 The default \a nameFilter is an empty string, which excludes
181 nothing; the default \a filterSpec is \c All, which also means
182 exclude nothing. The default \a sortSpec is \c Name|IgnoreCase,
183 i.e. sort by name case-insensitively.
184
185 Example that lists all the files in "/tmp":
186 \code
187 QDir d( "/tmp" );
188 for ( int i = 0; i < d.count(); i++ )
189 printf( "%s\n", d[i] );
190 \endcode
191
192 If \a path is "" or QString::null, QDir uses "." (the current
193 directory). If \a nameFilter is "" or QString::null, QDir uses the
194 name filter "*" (all files).
195
196 Note that \a path need not exist.
197
198 \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
199*/
200
201QDir::QDir( const QString &path, const QString &nameFilter,
202 int sortSpec, int filterSpec )
203{
204 init();
205 dPath = cleanDirPath( path );
206 if ( dPath.isEmpty() )
207 dPath = QString::fromLatin1(".");
208 nameFilt = nameFilter;
209 if ( nameFilt.isEmpty() )
210 nameFilt = QString::fromLatin1("*");
211 filtS = (FilterSpec)filterSpec;
212 sortS = (SortSpec)sortSpec;
213}
214
215/*!
216 Constructs a QDir that is a copy of the directory \a d.
217
218 \sa operator=()
219*/
220
221QDir::QDir( const QDir &d )
222{
223 dPath = d.dPath;
224 fList = 0;
225 fiList = 0;
226 nameFilt = d.nameFilt;
227 dirty = TRUE;
228 allDirs = d.allDirs;
229 filtS = d.filtS;
230 sortS = d.sortS;
231}
232
233
234void QDir::init()
235{
236 fList = 0;
237 fiList = 0;
238 nameFilt = QString::fromLatin1("*");
239 dirty = TRUE;
240 allDirs = FALSE;
241 filtS = All;
242 sortS = SortSpec(Name | IgnoreCase);
243}
244
245/*!
246 Destroys the QDir frees up its resources.
247*/
248
249QDir::~QDir()
250{
251 delete fList;
252 delete fiList;
253}
254
255
256/*!
257 Sets the path of the directory to \a path. The path is cleaned of
258 redundant ".", ".." and of multiple separators. No check is made
259 to ensure that a directory with this path exists.
260
261 The path can be either absolute or relative. Absolute paths begin
262 with the directory separator "/" (optionally preceded by a drive
263 specification under Windows). Relative file names begin with a
264 directory name or a file name and specify a path relative to the
265 current directory. An example of an absolute path is the string
266 "/tmp/quartz", a relative path might look like "src/fatlib".
267
268 \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
269 absFilePath(), isRelative(), convertToAbs()
270*/
271
272void QDir::setPath( const QString &path )
273{
274 dPath = cleanDirPath( path );
275 if ( dPath.isEmpty() )
276 dPath = QString::fromLatin1(".");
277 dirty = TRUE;
278}
279
280/*!
281 \fn QString QDir::path() const
282
283 Returns the path, this may contain symbolic links, but never
284 contains redundant ".", ".." or multiple separators.
285
286 The returned path can be either absolute or relative (see
287 setPath()).
288
289 \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
290 absFilePath(), convertSeparators()
291*/
292
293/*!
294 Returns the absolute path (a path that starts with "/" or with a
295 drive specification), which may contain symbolic links, but never
296 contains redundant ".", ".." or multiple separators.
297
298 \sa setPath(), canonicalPath(), exists(), cleanDirPath(),
299 dirName(), absFilePath()
300*/
301
302QString QDir::absPath() const
303{
304 if ( QDir::isRelativePath(dPath) ) {
305 QString tmp = currentDirPath();
306 if ( tmp.right(1) != QString::fromLatin1("/") )
307 tmp += '/';
308 tmp += dPath;
309 return cleanDirPath( tmp );
310 } else {
311 return cleanDirPath( dPath );
312 }
313}
314
315/*!
316 Returns the name of the directory; this is \e not the same as the
317 path, e.g. a directory with the name "mail", might have the path
318 "/var/spool/mail". If the directory has no name (e.g. it is the
319 root directory) QString::null is returned.
320
321 No check is made to ensure that a directory with this name
322 actually exists.
323
324 \sa path(), absPath(), absFilePath(), exists(), QString::isNull()
325*/
326
327QString QDir::dirName() const
328{
329 int pos = dPath.findRev( '/' );
330 if ( pos == -1 )
331 return dPath;
332 return dPath.right( dPath.length() - pos - 1 );
333}
334
335/*!
336 Returns the path name of a file in the directory. Does \e not
337 check if the file actually exists in the directory. If the QDir is
338 relative the returned path name will also be relative. Redundant
339 multiple separators or "." and ".." directories in \a fileName
340 will not be removed (see cleanDirPath()).
341
342 If \a acceptAbsPath is TRUE a \a fileName starting with a
343 separator "/" will be returned without change. If \a acceptAbsPath
344 is FALSE an absolute path will be prepended to the fileName and
345 the resultant string returned.
346
347 \sa absFilePath(), isRelative(), canonicalPath()
348*/
349
350QString QDir::filePath( const QString &fileName,
351 bool acceptAbsPath ) const
352{
353 if ( acceptAbsPath && !isRelativePath(fileName) )
354 return QString(fileName);
355
356 QString tmp = dPath;
357 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
358 fileName[0] != '/') )
359 tmp += '/';
360 tmp += fileName;
361 return tmp;
362}
363
364/*!
365 Returns the absolute path name of a file in the directory. Does \e
366 not check if the file actually exists in the directory. Redundant
367 multiple separators or "." and ".." directories in \a fileName
368 will not be removed (see cleanDirPath()).
369
370 If \a acceptAbsPath is TRUE a \a fileName starting with a
371 separator "/" will be returned without change. If \a acceptAbsPath
372 is FALSE an absolute path will be prepended to the fileName and
373 the resultant string returned.
374
375 \sa filePath()
376*/
377
378QString QDir::absFilePath( const QString &fileName,
379 bool acceptAbsPath ) const
380{
381 if ( acceptAbsPath && !isRelativePath( fileName ) )
382 return fileName;
383
384 QString tmp = absPath();
385 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
386 fileName[0] != '/') )
387 tmp += '/';
388 tmp += fileName;
389 return tmp;
390}
391
392
393/*!
394 Returns \a pathName with the '/' separators converted to
395 separators that are appropriate for the underlying operating
396 system.
397
398 On Windows, convertSeparators("c:/winnt/system32") returns
399 "c:\winnt\system32".
400
401 The returned string may be the same as the argument on some
402 operating systems, for example on Unix.
403*/
404
405QString QDir::convertSeparators( const QString &pathName )
406{
407 QString n( pathName );
408#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
409 for ( int i=0; i<(int)n.length(); i++ ) {
410 if ( n[i] == '/' )
411 n[i] = '\\';
412 }
413#elif defined(Q_OS_MAC9)
414 while(n.length() && n[0] == '/' ) n = n.right(n.length()-1);
415 for ( int i=0; i<(int)n.length(); i++ ) {
416 if ( n[i] == '/' )
417 n[i] = ':';
418 }
419 if(n.contains(':') && n.left(1) != ':')
420 n.prepend(':');
421#endif
422 return n;
423}
424
425
426/*!
427 Changes the QDir's directory to \a dirName.
428
429 If \a acceptAbsPath is TRUE a path starting with separator "/"
430 will cause the function to change to the absolute directory. If \a
431 acceptAbsPath is FALSE any number of separators at the beginning
432 of \a dirName will be removed and the function will descend into
433 \a dirName.
434
435 Returns TRUE if the new directory exists and is readable;
436 otherwise returns FALSE. Note that the logical cd() operation is
437 not performed if the new directory does not exist.
438
439 Calling cd( ".." ) is equivalent to calling cdUp().
440
441 \sa cdUp(), isReadable(), exists(), path()
442*/
443
444bool QDir::cd( const QString &dirName, bool acceptAbsPath )
445{
446 if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
447 return TRUE;
448 QString old = dPath;
449 if ( acceptAbsPath && !isRelativePath(dirName) ) {
450 dPath = cleanDirPath( dirName );
451 } else {
452 if ( !isRoot() ) {
453 dPath += '/';
454 } else if ( dirName == ".." ) {
455 dPath = old;
456 return FALSE;
457 }
458 dPath += dirName;
459 if ( dirName.find('/') >= 0
460 || old == QString::fromLatin1(".")
461 || dirName == QString::fromLatin1("..") )
462 dPath = cleanDirPath( dPath );
463 }
464 if ( !exists() ) {
465 dPath = old; // regret
466 return FALSE;
467 }
468 dirty = TRUE;
469 return TRUE;
470}
471
472/*!
473 Changes directory by moving one directory up from the QDir's
474 current directory.
475
476 Returns TRUE if the new directory exists and is readable;
477 otherwise returns FALSE. Note that the logical cdUp() operation is
478 not performed if the new directory does not exist.
479
480 \sa cd(), isReadable(), exists(), path()
481*/
482
483bool QDir::cdUp()
484{
485 return cd( QString::fromLatin1("..") );
486}
487
488/*!
489 \fn QString QDir::nameFilter() const
490
491 Returns the string set by setNameFilter()
492*/
493
494/*!
495 Sets the name filter used by entryList() and entryInfoList() to \a
496 nameFilter.
497
498 The \a nameFilter is a wildcard (globbing) filter that understands
499 "*" and "?" wildcards. (See \link qregexp.html#wildcard-matching
500 QRegExp wildcard matching\endlink.) You may specify several filter
501 entries all separated by a single space " " or by a semi-colon
502 ";".
503
504 For example, if you want entryList() and entryInfoList() to list
505 all files ending with either ".cpp" or ".h", you would use either
506 dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h").
507
508 \sa nameFilter(), setFilter()
509*/
510
511void QDir::setNameFilter( const QString &nameFilter )
512{
513 nameFilt = nameFilter;
514 if ( nameFilt.isEmpty() )
515 nameFilt = QString::fromLatin1("*");
516 dirty = TRUE;
517}
518
519/*!
520 \fn QDir::FilterSpec QDir::filter() const
521
522 Returns the value set by setFilter()
523*/
524
525/*!
526 \enum QDir::FilterSpec
527
528 This enum describes the filtering options available to QDir, e.g.
529 for entryList() and entryInfoList(). The filter value is specified
530 by OR-ing together values from the following list:
531
532 \value Dirs List directories only.
533 \value Files List files only.
534 \value Drives List disk drives (ignored under Unix).
535 \value NoSymLinks Do not list symbolic links (ignored by operating
536 systems that don't support symbolic links).
537 \value All List directories, files, drives and symlinks (this does not list
538 broken symlinks unless you specify System).
539 \value TypeMask A mask for the the Dirs, Files, Drives and
540 NoSymLinks flags.
541 \value Readable List files for which the application has read access.
542 \value Writable List files for which the application has write access.
543 \value Executable List files for which the application has execute
544 access. Executables needs to be combined with Dirs or Files.
545 \value RWEMask A mask for the Readable, Writable and Executable flags.
546 \value Modified Only list files that have been modified (ignored
547 under Unix).
548 \value Hidden List hidden files (on Unix, files starting with a .).
549 \value System List system files (on Unix, FIFOs, sockets and
550 device files)
551 \value AccessMask A mask for the Readable, Writable, Executable
552 Modified, Hidden and System flags
553 \value DefaultFilter Internal flag.
554
555 If you do not set any of \c Readable, \c Writable or \c
556 Executable, QDir will set all three of them. This makes the
557 default easy to write and at the same time useful.
558
559 Examples: \c Readable|Writable means list all files for which the
560 application has read access, write access or both. \c Dirs|Drives
561 means list drives, directories, all files that the application can
562 read, write or execute, and also symlinks to such
563 files/directories.
564*/
565
566
567/*!
568 Sets the filter used by entryList() and entryInfoList() to \a
569 filterSpec. The filter is used to specify the kind of files that
570 should be returned by entryList() and entryInfoList(). See
571 \l{QDir::FilterSpec}.
572
573 \sa filter(), setNameFilter()
574*/
575
576void QDir::setFilter( int filterSpec )
577{
578 if ( filtS == (FilterSpec) filterSpec )
579 return;
580 filtS = (FilterSpec) filterSpec;
581 dirty = TRUE;
582}
583
584/*!
585 \fn QDir::SortSpec QDir::sorting() const
586
587 Returns the value set by setSorting()
588
589 \sa setSorting() SortSpec
590*/
591
592/*!
593 \enum QDir::SortSpec
594
595 This enum describes the sort options available to QDir, e.g. for
596 entryList() and entryInfoList(). The sort value is specified by
597 OR-ing together values from the following list:
598
599 \value Name Sort by name.
600 \value Time Sort by time (modification time).
601 \value Size Sort by file size.
602 \value Unsorted Do not sort.
603 \value SortByMask A mask for Name, Time and Size.
604
605 \value DirsFirst Put the directories first, then the files.
606 \value Reversed Reverse the sort order.
607 \value IgnoreCase Sort case-insensitively.
608 \value DefaultSort Internal flag.
609
610 You can only specify one of the first four.
611
612 If you specify both \c DirsFirst and \c Reversed, directories are
613 still put first, but in reverse order; the files will be listed
614 after the directories, again in reverse order.
615*/
616
617// ### Unsorted+DirsFirst ? Unsorted+Reversed?
618
619/*!
620 Sets the sort order used by entryList() and entryInfoList().
621
622 The \a sortSpec is specified by OR-ing values from the enum
623 \l{QDir::SortSpec}.
624
625 \sa sorting() SortSpec
626*/
627
628void QDir::setSorting( int sortSpec )
629{
630 if ( sortS == (SortSpec) sortSpec )
631 return;
632 sortS = (SortSpec) sortSpec;
633 dirty = TRUE;
634}
635
636/*!
637 \fn bool QDir::matchAllDirs() const
638
639 Returns the value set by setMatchAllDirs()
640
641 \sa setMatchAllDirs()
642*/
643
644/*!
645 If \a enable is TRUE then all directories are included (e.g. in
646 entryList()), and the nameFilter() is only applied to the files.
647 If \a enable is FALSE then the nameFilter() is applied to both
648 directories and files.
649
650 \sa matchAllDirs()
651*/
652
653void QDir::setMatchAllDirs( bool enable )
654{
655 if ( (bool)allDirs == enable )
656 return;
657 allDirs = enable;
658 dirty = TRUE;
659}
660
661
662/*!
663 Returns the total number of directories and files that were found.
664
665 Equivalent to entryList().count().
666
667 \sa operator[](), entryList()
668*/
669
670uint QDir::count() const
671{
672 return (uint)entryList().count();
673}
674
675/*!
676 Returns the file name at position \a index in the list of file
677 names. Equivalent to entryList().at(index).
678
679 Returns a QString::null if the \a index is out of range or if the
680 entryList() function failed.
681
682 \sa count(), entryList()
683*/
684
685QString QDir::operator[]( int index ) const
686{
687 entryList();
688 return fList && index >= 0 && index < (int)fList->count() ?
689 (*fList)[index] : QString::null;
690}
691
692
693/*!
694 \obsolete
695 This function is included to easy porting from Qt 1.x to Qt 2.0,
696 it is the same as entryList(), but encodes the filenames as 8-bit
697 strings using QFile::encodedName().
698
699 It is more efficient to use entryList().
700*/
701QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
702{
703 QStrList r;
704 QStringList l = entryList(filterSpec,sortSpec);
705 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
706 r.append( QFile::encodeName(*it) );
707 }
708 return r;
709}
710
711/*!
712 \obsolete
713 \overload
714 This function is included to easy porting from Qt 1.x to Qt 2.0,
715 it is the same as entryList(), but encodes the filenames as 8-bit
716 strings using QFile::encodedName().
717
718 It is more efficient to use entryList().
719*/
720QStrList QDir::encodedEntryList( const QString &nameFilter,
721 int filterSpec,
722 int sortSpec ) const
723{
724 QStrList r;
725 QStringList l = entryList(nameFilter,filterSpec,sortSpec);
726 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
727 r.append( QFile::encodeName(*it) );
728 }
729 return r;
730}
731
732
733
734/*!
735 \overload
736
737 Returns a list of the names of all the files and directories in
738 the directory, ordered in accordance with setSorting() and
739 filtered in accordance with setFilter() and setNameFilter().
740
741 The filter and sorting specifications can be overridden using the
742 \a filterSpec and \a sortSpec arguments.
743
744 Returns an empty list if the directory is unreadable or does not
745 exist.
746
747 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter()
748*/
749
750QStringList QDir::entryList( int filterSpec, int sortSpec ) const
751{
752 if ( !dirty && filterSpec == (int)DefaultFilter &&
753 sortSpec == (int)DefaultSort )
754 return *fList;
755 return entryList( nameFilt, filterSpec, sortSpec );
756}
757
758/*!
759 Returns a list of the names of all the files and directories in
760 the directory, ordered in accordance with setSorting() and
761 filtered in accordance with setFilter() and setNameFilter().
762
763 The filter and sorting specifications can be overridden using the
764 \a nameFilter, \a filterSpec and \a sortSpec arguments.
765
766 Returns an empty list if the directory is unreadable or does not
767 exist.
768
769 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter()
770*/
771
772QStringList QDir::entryList( const QString &nameFilter,
773 int filterSpec, int sortSpec ) const
774{
775 if ( filterSpec == (int)DefaultFilter )
776 filterSpec = filtS;
777 if ( sortSpec == (int)DefaultSort )
778 sortSpec = sortS;
779 QDir *that = (QDir*)this; // mutable function
780 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) ) {
781 if ( that->fList )
782 return *that->fList;
783 }
784 return QStringList();
785}
786
787/*!
788 \overload
789
790 Returns a list of QFileInfo objects for all the files and
791 directories in the directory, ordered in accordance with
792 setSorting() and filtered in accordance with setFilter() and
793 setNameFilter().
794
795 The filter and sorting specifications can be overridden using the
796 \a filterSpec and \a sortSpec arguments.
797
798 Returns 0 if the directory is unreadable or does not exist.
799
800 The returned pointer is a const pointer to a QFileInfoList. The
801 list is owned by the QDir object and will be reused on the next
802 call to entryInfoList() for the same QDir instance. If you want to
803 keep the entries of the list after a subsequent call to this
804 function you must copy them.
805
806 \sa entryList(), setNameFilter(), setSorting(), setFilter()
807*/
808
809const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
810{
811 if ( !dirty && filterSpec == (int)DefaultFilter &&
812 sortSpec == (int)DefaultSort )
813 return fiList;
814 return entryInfoList( nameFilt, filterSpec, sortSpec );
815}
816
817/*!
818 Returns a list of QFileInfo objects for all the files and
819 directories in the directory, ordered in accordance with
820 setSorting() and filtered in accordance with setFilter() and
821 setNameFilter().
822
823 The filter and sorting specifications can be overridden using the
824 \a nameFilter, \a filterSpec and \a sortSpec arguments.
825
826 Returns 0 if the directory is unreadable or does not exist.
827
828 The returned pointer is a const pointer to a QFileInfoList. The
829 list is owned by the QDir object and will be reused on the next
830 call to entryInfoList() for the same QDir instance. If you want to
831 keep the entries of the list after a subsequent call to this
832 function you must copy them.
833
834 \sa entryList(), setNameFilter(), setSorting(), setFilter()
835*/
836
837const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
838 int filterSpec, int sortSpec ) const
839{
840 if ( filterSpec == (int)DefaultFilter )
841 filterSpec = filtS;
842 if ( sortSpec == (int)DefaultSort )
843 sortSpec = sortS;
844 QDir *that = (QDir*)this; // mutable function
845 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
846 return that->fiList;
847 else
848 return 0;
849}
850
851/*!
852 \overload
853
854 Returns TRUE if the \e directory exists; otherwise returns FALSE.
855 (If a file with the same name is found this function will return
856 FALSE).
857
858 \sa QFileInfo::exists(), QFile::exists()
859*/
860
861bool QDir::exists() const
862{
863 QFileInfo fi( dPath );
864 return fi.exists() && fi.isDir();
865}
866
867/*!
868 Returns TRUE if the directory path is relative to the current
869 directory and returns FALSE if the path is absolute (e.g. under
870 UNIX a path is relative if it does not start with a "/").
871
872 \sa convertToAbs()
873*/
874
875bool QDir::isRelative() const
876{
877 return isRelativePath( dPath );
878}
879
880/*!
881 Converts the directory path to an absolute path. If it is already
882 absolute nothing is done.
883
884 \sa isRelative()
885*/
886
887void QDir::convertToAbs()
888{
889 dPath = absPath();
890}
891
892/*!
893 Makes a copy of QDir \a d and assigns it to this QDir.
894*/
895
896QDir &QDir::operator=( const QDir &d )
897{
898 dPath = d.dPath;
899 delete fList;
900 fList = 0;
901 delete fiList;
902 fiList = 0;
903 nameFilt = d.nameFilt;
904 dirty = TRUE;
905 allDirs = d.allDirs;
906 filtS = d.filtS;
907 sortS = d.sortS;
908 return *this;
909}
910
911/*!
912 \overload
913
914 Sets the directory path to be the given \a path.
915*/
916
917QDir &QDir::operator=( const QString &path )
918{
919 dPath = cleanDirPath( path );
920 dirty = TRUE;
921 return *this;
922}
923
924
925/*!
926 \fn bool QDir::operator!=( const QDir &d ) const
927
928 Returns TRUE if directory \a d and this directory have different
929 paths or different sort or filter settings; otherwise returns
930 FALSE.
931
932 Example:
933 \code
934 // The current directory is "/usr/local"
935 QDir d1( "/usr/local/bin" );
936 QDir d2( "bin" );
937 if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed
938 \endcode
939*/
940
941/*!
942 Returns TRUE if directory \a d and this directory have the same
943 path and their sort and filter settings are the same; otherwise
944 returns FALSE.
945
946 Example:
947 \code
948 // The current directory is "/usr/local"
949 QDir d1( "/usr/local/bin" );
950 QDir d2( "bin" );
951 d2.convertToAbs();
952 if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed
953 \endcode
954*/
955
956bool QDir::operator==( const QDir &d ) const
957{
958 return dPath == d.dPath &&
959 nameFilt == d.nameFilt &&
960 allDirs == d.allDirs &&
961 filtS == d.filtS &&
962 sortS == d.sortS;
963}
964
965
966/*!
967 Removes the file, \a fileName.
968
969 If \a acceptAbsPath is TRUE a path starting with separator "/"
970 will remove the file with the absolute path. If \a acceptAbsPath
971 is FALSE any number of separators at the beginning of \a fileName
972 will be removed and the resultant file name will be removed.
973
974 Returns TRUE if the file is removed successfully; otherwise
975 returns FALSE.
976*/
977
978bool QDir::remove( const QString &fileName, bool acceptAbsPath )
979{
980 if ( fileName.isEmpty() ) {
981#if defined(QT_CHECK_NULL)
982 qWarning( "QDir::remove: Empty or null file name" );
983#endif
984 return FALSE;
985 }
986 QString p = filePath( fileName, acceptAbsPath );
987 return QFile::remove( p );
988}
989
990/*!
991 Checks for the existence of the file \a name.
992
993 If \a acceptAbsPath is TRUE a path starting with separator "/"
994 will check the file with the absolute path. If \a acceptAbsPath is
995 FALSE any number of separators at the beginning of \a name will be
996 removed and the resultant file name will be checked.
997
998 Returns TRUE if the file exists; otherwise returns FALSE.
999
1000 \sa QFileInfo::exists(), QFile::exists()
1001*/
1002
1003bool QDir::exists( const QString &name, bool acceptAbsPath ) //### const in 4.0
1004{
1005 if ( name.isEmpty() ) {
1006#if defined(QT_CHECK_NULL)
1007 qWarning( "QDir::exists: Empty or null file name" );
1008#endif
1009 return FALSE;
1010 }
1011 QString tmp = filePath( name, acceptAbsPath );
1012 return QFile::exists( tmp );
1013}
1014
1015/*!
1016 Returns the native directory separator; "/" under UNIX (including
1017 Mac OS X) and "\" under Windows.
1018
1019 You do not need to use this function to build file paths. If you
1020 always use "/", Qt will translate your paths to conform to the
1021 underlying operating system.
1022*/
1023
1024char QDir::separator()
1025{
1026#if defined(Q_OS_UNIX)
1027 return '/';
1028#elif defined (Q_FS_FAT) || defined(Q_WS_WIN)
1029 return '\\';
1030#elif defined (Q_OS_MAC)
1031 return ':';
1032#else
1033 return '/';
1034#endif
1035}
1036
1037/*!
1038 Returns the application's current directory.
1039
1040 Use path() to access a QDir object's path.
1041
1042 \sa currentDirPath(), QDir::QDir()
1043*/
1044
1045QDir QDir::current()
1046{
1047 return QDir( currentDirPath() );
1048}
1049
1050/*!
1051 Returns the home directory.
1052
1053 Under Windows the \c HOME environment variable is used. If this
1054 does not exist the \c USERPROFILE environment variable is used. If
1055 that does not exist the path is formed by concatenating the \c
1056 HOMEDRIVE and \c HOMEPATH environment variables. If they don't
1057 exist the rootDirPath() is used (this uses the \c SystemDrive
1058 environment variable). If none of these exist "C:\" is used.
1059
1060 Under non-Windows operating systems the \c HOME environment
1061 variable is used if it exists, otherwise rootDirPath() is used.
1062
1063 \sa homeDirPath()
1064*/
1065
1066QDir QDir::home()
1067{
1068 return QDir( homeDirPath() );
1069}
1070
1071/*!
1072 Returns the root directory.
1073
1074 \sa rootDirPath() drives()
1075*/
1076
1077QDir QDir::root()
1078{
1079 return QDir( rootDirPath() );
1080}
1081
1082/*!
1083 \fn QString QDir::homeDirPath()
1084
1085 Returns the absolute path of the user's home directory.
1086
1087 \sa home()
1088*/
1089
1090QStringList qt_makeFilterList( const QString &filter )
1091{
1092 if ( filter.isEmpty() )
1093 return QStringList();
1094
1095 QChar sep( ';' );
1096 int i = filter.find( sep, 0 );
1097 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
1098 sep = QChar( ' ' );
1099
1100 QStringList list = QStringList::split( sep, filter );
1101 QStringList::Iterator it = list.begin();
1102 QStringList list2;
1103
1104 for ( ; it != list.end(); ++it ) {
1105 QString s = *it;
1106 list2 << s.stripWhiteSpace();
1107 }
1108 return list2;
1109}
1110
1111/*!
1112 \overload
1113
1114 Returns TRUE if the \a fileName matches any of the wildcard (glob)
1115 patterns in the list of \a filters; otherwise returns FALSE.
1116
1117 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1118 matching.\endlink)
1119 \sa QRegExp::match()
1120*/
1121
1122bool QDir::match( const QStringList &filters, const QString &fileName )
1123{
1124 QStringList::ConstIterator sit = filters.begin();
1125 while ( sit != filters.end() ) {
1126#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
1127 QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive..
1128#else
1129 QRegExp rx( *sit, TRUE, TRUE ); // ..while others are.
1130#endif
1131 if ( rx.exactMatch(fileName) )
1132 return TRUE;
1133 ++sit;
1134 }
1135 return FALSE;
1136}
1137
1138/*!
1139 Returns TRUE if the \a fileName matches the wildcard (glob)
1140 pattern \a filter; otherwise returns FALSE. The \a filter may
1141 contain multiple patterns separated by spaces or semicolons.
1142
1143 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1144 matching.\endlink)
1145 \sa QRegExp::match()
1146*/
1147
1148bool QDir::match( const QString &filter, const QString &fileName )
1149{
1150 QStringList lst = qt_makeFilterList( filter );
1151 return match( lst, fileName );
1152}
1153
1154
1155/*!
1156 Removes all multiple directory separators "/" and resolves any
1157 "."s or ".."s found in the path, \a filePath.
1158
1159 Symbolic links are kept. This function does not return the
1160 canonical path, but rather the simplest version of the input.
1161 For example, "./local" becomes "local", "local/../bin" becomes
1162 "bin" and "/local/usr/../bin" becomes "/local/bin".
1163
1164 \sa absPath() canonicalPath()
1165*/
1166
1167QString QDir::cleanDirPath( const QString &filePath )
1168{
1169 QString name = filePath;
1170 QString newPath;
1171
1172 if ( name.isEmpty() )
1173 return name;
1174
1175 slashify( name );
1176
1177 bool addedSeparator;
1178 if ( isRelativePath(name) ) {
1179 addedSeparator = TRUE;
1180 name.insert( 0, '/' );
1181 } else {
1182 addedSeparator = FALSE;
1183 }
1184
1185 int ePos, pos, upLevel;
1186
1187 pos = ePos = name.length();
1188 upLevel = 0;
1189 int len;
1190
1191 while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
1192 len = ePos - pos - 1;
1193 if ( len == 2 && name.at(pos + 1) == '.'
1194 && name.at(pos + 2) == '.' ) {
1195 upLevel++;
1196 } else {
1197 if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
1198 if ( !upLevel )
1199 newPath = QString::fromLatin1("/")
1200 + name.mid(pos + 1, len) + newPath;
1201 else
1202 upLevel--;
1203 }
1204 }
1205 ePos = pos;
1206 }
1207 if ( addedSeparator ) {
1208 while ( upLevel-- )
1209 newPath.insert( 0, QString::fromLatin1("/..") );
1210 if ( !newPath.isEmpty() )
1211 newPath.remove( 0, 1 );
1212 else
1213 newPath = QString::fromLatin1(".");
1214 } else {
1215 if ( newPath.isEmpty() )
1216 newPath = QString::fromLatin1("/");
1217#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
1218 if ( name[0] == '/' ) {
1219 if ( name[1] == '/' ) // "\\machine\x\ ..."
1220 newPath.insert( 0, '/' );
1221 } else {
1222 newPath = name.left(2) + newPath;
1223 }
1224#endif
1225 }
1226 return newPath;
1227}
1228
1229int qt_cmp_si_sortSpec;
1230
1231#if defined(Q_C_CALLBACKS)
1232extern "C" {
1233#endif
1234
1235#ifdef Q_OS_TEMP
1236int __cdecl qt_cmp_si( const void *n1, const void *n2 )
1237#else
1238int qt_cmp_si( const void *n1, const void *n2 )
1239#endif
1240{
1241 if ( !n1 || !n2 )
1242 return 0;
1243
1244 QDirSortItem* f1 = (QDirSortItem*)n1;
1245 QDirSortItem* f2 = (QDirSortItem*)n2;
1246
1247 if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
1248 if ( f1->item->isDir() != f2->item->isDir() )
1249 return f1->item->isDir() ? -1 : 1;
1250
1251 int r = 0;
1252 int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
1253
1254 switch ( sortBy ) {
1255 case QDir::Time:
1256 r = f1->item->lastModified().secsTo(f2->item->lastModified());
1257 break;
1258 case QDir::Size:
1259 r = f2->item->size() - f1->item->size();
1260 break;
1261 default:
1262 ;
1263 }
1264
1265 if ( r == 0 && sortBy != QDir::Unsorted ) {
1266 // Still not sorted - sort by name
1267 bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
1268
1269 if ( f1->filename_cache.isNull() )
1270 f1->filename_cache = ic ? f1->item->fileName().lower()
1271 : f1->item->fileName();
1272 if ( f2->filename_cache.isNull() )
1273 f2->filename_cache = ic ? f2->item->fileName().lower()
1274 : f2->item->fileName();
1275
1276 r = f1->filename_cache.compare(f2->filename_cache);
1277 }
1278
1279 if ( r == 0 ) {
1280 // Enforce an order - the order the items appear in the array
1281 r = (char*)n1 - (char*)n2;
1282 }
1283
1284 if ( qt_cmp_si_sortSpec & QDir::Reversed )
1285 return -r;
1286 else
1287 return r;
1288}
1289
1290#if defined(Q_C_CALLBACKS)
1291}
1292#endif
1293
1294#endif // QT_NO_DIR