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.cpp94
1 files changed, 71 insertions, 23 deletions
diff --git a/qmake/tools/qdir.cpp b/qmake/tools/qdir.cpp
index 418ea49..5714878 100644
--- a/qmake/tools/qdir.cpp
+++ b/qmake/tools/qdir.cpp
@@ -1,76 +1,81 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QDir class 4** Implementation of QDir class
5** 5**
6** Created : 950427 6** Created : 950427
7** 7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 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 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
15** 15**
16** This file may be distributed and/or modified under the terms of the 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 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 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition 21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License 22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software. 23** Agreement provided with the Software.
24** 24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38#include "qplatformdefs.h" 38#include "qplatformdefs.h"
39#include "qdir.h" 39#include "qdir.h"
40 40
41#ifndef QT_NO_DIR 41#ifndef QT_NO_DIR
42#include <private/qdir_p.h> 42#include <private/qdir_p.h>
43#include "qfileinfo.h" 43#include "qfileinfo.h"
44#include "qregexp.h" 44#include "qregexp.h"
45#include "qstringlist.h" 45#include "qstringlist.h"
46#include <stdlib.h> 46#include <limits.h>
47#include <ctype.h>
48 47
48#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
49const bool CaseSensitiveFS = FALSE;
50#else
51const bool CaseSensitiveFS = TRUE;
52#endif
49 53
50 54
51/*! 55/*!
52 \class QDir 56 \class QDir
57 \reentrant
53 \brief The QDir class provides access to directory structures and their contents in a platform-independent way. 58 \brief The QDir class provides access to directory structures and their contents in a platform-independent way.
54 59
55 \ingroup io 60 \ingroup io
56 \mainclass 61 \mainclass
57 62
58 A QDir is used to manipulate path names, access information 63 A QDir is used to manipulate path names, access information
59 regarding paths and files, and manipulate the underlying file 64 regarding paths and files, and manipulate the underlying file
60 system. 65 system.
61 66
62 A QDir can point to a file using either a relative or an absolute 67 A QDir can point to a file using either a relative or an absolute
63 path. Absolute paths begin with the directory separator "/" 68 path. Absolute paths begin with the directory separator "/"
64 (optionally preceded by a drive specification under Windows). If 69 (optionally preceded by a drive specification under Windows). If
65 you always use "/" as a directory separator, Qt will translate 70 you always use "/" as a directory separator, Qt will translate
66 your paths to conform to the underlying operating system. Relative 71 your paths to conform to the underlying operating system. Relative
67 file names begin with a directory name or a file name and specify 72 file names begin with a directory name or a file name and specify
68 a path relative to the current directory. 73 a path relative to the current directory.
69 74
70 The "current" path refers to the application's working directory. 75 The "current" path refers to the application's working directory.
71 A QDir's own path is set and retrieved with setPath() and path(). 76 A QDir's own path is set and retrieved with setPath() and path().
72 77
73 An example of an absolute path is the string "/tmp/quartz", a 78 An example of an absolute path is the string "/tmp/quartz", a
74 relative path might look like "src/fatlib". You can use the 79 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 80 function isRelative() to check if a QDir is using a relative or an
76 absolute file path. Call convertToAbs() to convert a relative QDir 81 absolute file path. Call convertToAbs() to convert a relative QDir
@@ -209,48 +214,56 @@ QDir::QDir( const QString &path, const QString &nameFilter,
209 if ( nameFilt.isEmpty() ) 214 if ( nameFilt.isEmpty() )
210 nameFilt = QString::fromLatin1("*"); 215 nameFilt = QString::fromLatin1("*");
211 filtS = (FilterSpec)filterSpec; 216 filtS = (FilterSpec)filterSpec;
212 sortS = (SortSpec)sortSpec; 217 sortS = (SortSpec)sortSpec;
213} 218}
214 219
215/*! 220/*!
216 Constructs a QDir that is a copy of the directory \a d. 221 Constructs a QDir that is a copy of the directory \a d.
217 222
218 \sa operator=() 223 \sa operator=()
219*/ 224*/
220 225
221QDir::QDir( const QDir &d ) 226QDir::QDir( const QDir &d )
222{ 227{
223 dPath = d.dPath; 228 dPath = d.dPath;
224 fList = 0; 229 fList = 0;
225 fiList = 0; 230 fiList = 0;
226 nameFilt = d.nameFilt; 231 nameFilt = d.nameFilt;
227 dirty = TRUE; 232 dirty = TRUE;
228 allDirs = d.allDirs; 233 allDirs = d.allDirs;
229 filtS = d.filtS; 234 filtS = d.filtS;
230 sortS = d.sortS; 235 sortS = d.sortS;
231} 236}
232 237
238/*!
239 Refreshes the directory information.
240*/
241void QDir::refresh() const
242{
243 QDir* that = (QDir*) this;
244 that->dirty = TRUE;
245}
233 246
234void QDir::init() 247void QDir::init()
235{ 248{
236 fList = 0; 249 fList = 0;
237 fiList = 0; 250 fiList = 0;
238 nameFilt = QString::fromLatin1("*"); 251 nameFilt = QString::fromLatin1("*");
239 dirty = TRUE; 252 dirty = TRUE;
240 allDirs = FALSE; 253 allDirs = FALSE;
241 filtS = All; 254 filtS = All;
242 sortS = SortSpec(Name | IgnoreCase); 255 sortS = SortSpec(Name | IgnoreCase);
243} 256}
244 257
245/*! 258/*!
246 Destroys the QDir frees up its resources. 259 Destroys the QDir frees up its resources.
247*/ 260*/
248 261
249QDir::~QDir() 262QDir::~QDir()
250{ 263{
251 delete fList; 264 delete fList;
252 delete fiList; 265 delete fiList;
253} 266}
254 267
255 268
256/*! 269/*!
@@ -361,52 +374,78 @@ QString QDir::filePath( const QString &fileName,
361 return tmp; 374 return tmp;
362} 375}
363 376
364/*! 377/*!
365 Returns the absolute path name of a file in the directory. Does \e 378 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 379 not check if the file actually exists in the directory. Redundant
367 multiple separators or "." and ".." directories in \a fileName 380 multiple separators or "." and ".." directories in \a fileName
368 will not be removed (see cleanDirPath()). 381 will not be removed (see cleanDirPath()).
369 382
370 If \a acceptAbsPath is TRUE a \a fileName starting with a 383 If \a acceptAbsPath is TRUE a \a fileName starting with a
371 separator "/" will be returned without change. If \a acceptAbsPath 384 separator "/" will be returned without change. If \a acceptAbsPath
372 is FALSE an absolute path will be prepended to the fileName and 385 is FALSE an absolute path will be prepended to the fileName and
373 the resultant string returned. 386 the resultant string returned.
374 387
375 \sa filePath() 388 \sa filePath()
376*/ 389*/
377 390
378QString QDir::absFilePath( const QString &fileName, 391QString QDir::absFilePath( const QString &fileName,
379 bool acceptAbsPath ) const 392 bool acceptAbsPath ) const
380{ 393{
381 if ( acceptAbsPath && !isRelativePath( fileName ) ) 394 if ( acceptAbsPath && !isRelativePath( fileName ) )
382 return fileName; 395 return fileName;
383 396
384 QString tmp = absPath(); 397 QString tmp = absPath();
385 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && 398#ifdef Q_OS_WIN32
386 fileName[0] != '/') ) 399 if ( fileName[0].isLetter() && fileName[1] == ':' ) {
387 tmp += '/'; 400 int drv = fileName.upper()[0].latin1() - 'A' + 1;
388 tmp += fileName; 401 if ( _getdrive() != drv ) {
402 if ( qt_winunicode ) {
403 TCHAR buf[PATH_MAX];
404 ::_tgetdcwd( drv, buf, PATH_MAX );
405 tmp.setUnicodeCodes( (ushort*)buf, ::_tcslen(buf) );
406 } else {
407 char buf[PATH_MAX];
408 ::_getdcwd( drv, buf, PATH_MAX );
409 tmp = buf;
410 }
411 if ( !tmp.endsWith("\\") )
412 tmp += "\\";
413 tmp += fileName.right( fileName.length() - 2 );
414 int x;
415 for ( x = 0; x < (int) tmp.length(); x++ ) {
416 if ( tmp[x] == '\\' )
417 tmp[x] = '/';
418 }
419 }
420 } else
421#endif
422 {
423 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
424 fileName[0] != '/') )
425 tmp += '/';
426 tmp += fileName;
427 }
389 return tmp; 428 return tmp;
390} 429}
391 430
392 431
393/*! 432/*!
394 Returns \a pathName with the '/' separators converted to 433 Returns \a pathName with the '/' separators converted to
395 separators that are appropriate for the underlying operating 434 separators that are appropriate for the underlying operating
396 system. 435 system.
397 436
398 On Windows, convertSeparators("c:/winnt/system32") returns 437 On Windows, convertSeparators("c:/winnt/system32") returns
399 "c:\winnt\system32". 438 "c:\winnt\system32".
400 439
401 The returned string may be the same as the argument on some 440 The returned string may be the same as the argument on some
402 operating systems, for example on Unix. 441 operating systems, for example on Unix.
403*/ 442*/
404 443
405QString QDir::convertSeparators( const QString &pathName ) 444QString QDir::convertSeparators( const QString &pathName )
406{ 445{
407 QString n( pathName ); 446 QString n( pathName );
408#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) 447#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
409 for ( int i=0; i<(int)n.length(); i++ ) { 448 for ( int i=0; i<(int)n.length(); i++ ) {
410 if ( n[i] == '/' ) 449 if ( n[i] == '/' )
411 n[i] = '\\'; 450 n[i] = '\\';
412 } 451 }
@@ -913,64 +952,66 @@ QDir &QDir::operator=( const QDir &d )
913 952
914 Sets the directory path to be the given \a path. 953 Sets the directory path to be the given \a path.
915*/ 954*/
916 955
917QDir &QDir::operator=( const QString &path ) 956QDir &QDir::operator=( const QString &path )
918{ 957{
919 dPath = cleanDirPath( path ); 958 dPath = cleanDirPath( path );
920 dirty = TRUE; 959 dirty = TRUE;
921 return *this; 960 return *this;
922} 961}
923 962
924 963
925/*! 964/*!
926 \fn bool QDir::operator!=( const QDir &d ) const 965 \fn bool QDir::operator!=( const QDir &d ) const
927 966
928 Returns TRUE if directory \a d and this directory have different 967 Returns TRUE if directory \a d and this directory have different
929 paths or different sort or filter settings; otherwise returns 968 paths or different sort or filter settings; otherwise returns
930 FALSE. 969 FALSE.
931 970
932 Example: 971 Example:
933 \code 972 \code
934 // The current directory is "/usr/local" 973 // The current directory is "/usr/local"
935 QDir d1( "/usr/local/bin" ); 974 QDir d1( "/usr/local/bin" );
936 QDir d2( "bin" ); 975 QDir d2( "bin" );
937 if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed 976 if ( d1 != d2 )
977 qDebug( "They differ" );
938 \endcode 978 \endcode
939*/ 979*/
940 980
941/*! 981/*!
942 Returns TRUE if directory \a d and this directory have the same 982 Returns TRUE if directory \a d and this directory have the same
943 path and their sort and filter settings are the same; otherwise 983 path and their sort and filter settings are the same; otherwise
944 returns FALSE. 984 returns FALSE.
945 985
946 Example: 986 Example:
947 \code 987 \code
948 // The current directory is "/usr/local" 988 // The current directory is "/usr/local"
949 QDir d1( "/usr/local/bin" ); 989 QDir d1( "/usr/local/bin" );
950 QDir d2( "bin" ); 990 QDir d2( "bin" );
951 d2.convertToAbs(); 991 d2.convertToAbs();
952 if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed 992 if ( d1 == d2 )
993 qDebug( "They're the same" );
953 \endcode 994 \endcode
954*/ 995*/
955 996
956bool QDir::operator==( const QDir &d ) const 997bool QDir::operator==( const QDir &d ) const
957{ 998{
958 return dPath == d.dPath && 999 return dPath == d.dPath &&
959 nameFilt == d.nameFilt && 1000 nameFilt == d.nameFilt &&
960 allDirs == d.allDirs && 1001 allDirs == d.allDirs &&
961 filtS == d.filtS && 1002 filtS == d.filtS &&
962 sortS == d.sortS; 1003 sortS == d.sortS;
963} 1004}
964 1005
965 1006
966/*! 1007/*!
967 Removes the file, \a fileName. 1008 Removes the file, \a fileName.
968 1009
969 If \a acceptAbsPath is TRUE a path starting with separator "/" 1010 If \a acceptAbsPath is TRUE a path starting with separator "/"
970 will remove the file with the absolute path. If \a acceptAbsPath 1011 will remove the file with the absolute path. If \a acceptAbsPath
971 is FALSE any number of separators at the beginning of \a fileName 1012 is FALSE any number of separators at the beginning of \a fileName
972 will be removed and the resultant file name will be removed. 1013 will be removed and the resultant file name will be removed.
973 1014
974 Returns TRUE if the file is removed successfully; otherwise 1015 Returns TRUE if the file is removed successfully; otherwise
975 returns FALSE. 1016 returns FALSE.
976*/ 1017*/
@@ -1066,110 +1107,117 @@ QDir QDir::current()
1066QDir QDir::home() 1107QDir QDir::home()
1067{ 1108{
1068 return QDir( homeDirPath() ); 1109 return QDir( homeDirPath() );
1069} 1110}
1070 1111
1071/*! 1112/*!
1072 Returns the root directory. 1113 Returns the root directory.
1073 1114
1074 \sa rootDirPath() drives() 1115 \sa rootDirPath() drives()
1075*/ 1116*/
1076 1117
1077QDir QDir::root() 1118QDir QDir::root()
1078{ 1119{
1079 return QDir( rootDirPath() ); 1120 return QDir( rootDirPath() );
1080} 1121}
1081 1122
1082/*! 1123/*!
1083 \fn QString QDir::homeDirPath() 1124 \fn QString QDir::homeDirPath()
1084 1125
1085 Returns the absolute path of the user's home directory. 1126 Returns the absolute path of the user's home directory.
1086 1127
1087 \sa home() 1128 \sa home()
1088*/ 1129*/
1089 1130
1090QStringList qt_makeFilterList( const QString &filter ) 1131QValueList<QRegExp> qt_makeFilterList( const QString &filter )
1091{ 1132{
1133 QValueList<QRegExp> regExps;
1092 if ( filter.isEmpty() ) 1134 if ( filter.isEmpty() )
1093 return QStringList(); 1135 return regExps;
1094 1136
1095 QChar sep( ';' ); 1137 QChar sep( ';' );
1096 int i = filter.find( sep, 0 ); 1138 int i = filter.find( sep, 0 );
1097 if ( i == -1 && filter.find( ' ', 0 ) != -1 ) 1139 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
1098 sep = QChar( ' ' ); 1140 sep = QChar( ' ' );
1099 1141
1100 QStringList list = QStringList::split( sep, filter ); 1142 QStringList list = QStringList::split( sep, filter );
1101 QStringList::Iterator it = list.begin(); 1143 QStringList::Iterator it = list.begin();
1102 QStringList list2; 1144 while ( it != list.end() ) {
1145 regExps << QRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE );
1146 ++it;
1147 }
1148 return regExps;
1149}
1103 1150
1104 for ( ; it != list.end(); ++it ) { 1151bool qt_matchFilterList( const QValueList<QRegExp>& filters,
1105 QString s = *it; 1152 const QString &fileName )
1106 list2 << s.stripWhiteSpace(); 1153{
1154 QValueList<QRegExp>::ConstIterator rit = filters.begin();
1155 while ( rit != filters.end() ) {
1156 if ( (*rit).exactMatch(fileName) )
1157 return TRUE;
1158 ++rit;
1107 } 1159 }
1108 return list2; 1160 return FALSE;
1109} 1161}
1110 1162
1163
1111/*! 1164/*!
1112 \overload 1165 \overload
1113 1166
1114 Returns TRUE if the \a fileName matches any of the wildcard (glob) 1167 Returns TRUE if the \a fileName matches any of the wildcard (glob)
1115 patterns in the list of \a filters; otherwise returns FALSE. 1168 patterns in the list of \a filters; otherwise returns FALSE.
1116 1169
1117 (See \link qregexp.html#wildcard-matching QRegExp wildcard 1170 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1118 matching.\endlink) 1171 matching.\endlink)
1119 \sa QRegExp::match() 1172 \sa QRegExp::match()
1120*/ 1173*/
1121 1174
1122bool QDir::match( const QStringList &filters, const QString &fileName ) 1175bool QDir::match( const QStringList &filters, const QString &fileName )
1123{ 1176{
1124 QStringList::ConstIterator sit = filters.begin(); 1177 QStringList::ConstIterator sit = filters.begin();
1125 while ( sit != filters.end() ) { 1178 while ( sit != filters.end() ) {
1126#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) 1179 QRegExp rx( *sit, CaseSensitiveFS, TRUE );
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) ) 1180 if ( rx.exactMatch(fileName) )
1132 return TRUE; 1181 return TRUE;
1133 ++sit; 1182 ++sit;
1134 } 1183 }
1135 return FALSE; 1184 return FALSE;
1136} 1185}
1137 1186
1138/*! 1187/*!
1139 Returns TRUE if the \a fileName matches the wildcard (glob) 1188 Returns TRUE if the \a fileName matches the wildcard (glob)
1140 pattern \a filter; otherwise returns FALSE. The \a filter may 1189 pattern \a filter; otherwise returns FALSE. The \a filter may
1141 contain multiple patterns separated by spaces or semicolons. 1190 contain multiple patterns separated by spaces or semicolons.
1142 1191
1143 (See \link qregexp.html#wildcard-matching QRegExp wildcard 1192 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1144 matching.\endlink) 1193 matching.\endlink)
1145 \sa QRegExp::match() 1194 \sa QRegExp::match()
1146*/ 1195*/
1147 1196
1148bool QDir::match( const QString &filter, const QString &fileName ) 1197bool QDir::match( const QString &filter, const QString &fileName )
1149{ 1198{
1150 QStringList lst = qt_makeFilterList( filter ); 1199 return qt_matchFilterList( qt_makeFilterList(filter), fileName );
1151 return match( lst, fileName );
1152} 1200}
1153 1201
1154 1202
1155/*! 1203/*!
1156 Removes all multiple directory separators "/" and resolves any 1204 Removes all multiple directory separators "/" and resolves any
1157 "."s or ".."s found in the path, \a filePath. 1205 "."s or ".."s found in the path, \a filePath.
1158 1206
1159 Symbolic links are kept. This function does not return the 1207 Symbolic links are kept. This function does not return the
1160 canonical path, but rather the simplest version of the input. 1208 canonical path, but rather the simplest version of the input.
1161 For example, "./local" becomes "local", "local/../bin" becomes 1209 For example, "./local" becomes "local", "local/../bin" becomes
1162 "bin" and "/local/usr/../bin" becomes "/local/bin". 1210 "bin" and "/local/usr/../bin" becomes "/local/bin".
1163 1211
1164 \sa absPath() canonicalPath() 1212 \sa absPath() canonicalPath()
1165*/ 1213*/
1166 1214
1167QString QDir::cleanDirPath( const QString &filePath ) 1215QString QDir::cleanDirPath( const QString &filePath )
1168{ 1216{
1169 QString name = filePath; 1217 QString name = filePath;
1170 QString newPath; 1218 QString newPath;
1171 1219
1172 if ( name.isEmpty() ) 1220 if ( name.isEmpty() )
1173 return name; 1221 return name;
1174 1222
1175 slashify( name ); 1223 slashify( name );