summaryrefslogtreecommitdiff
path: root/qmake/tools/qdir.cpp
Side-by-side diff
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,100 +1,105 @@
/****************************************************************************
** $Id$
**
** Implementation of QDir class
**
** Created : 950427
**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
**
** This file is part of the tools module of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
** licenses may use this file in accordance with the Qt Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
** information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include "qplatformdefs.h"
#include "qdir.h"
#ifndef QT_NO_DIR
#include <private/qdir_p.h>
#include "qfileinfo.h"
#include "qregexp.h"
#include "qstringlist.h"
-#include <stdlib.h>
-#include <ctype.h>
+#include <limits.h>
+#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
+const bool CaseSensitiveFS = FALSE;
+#else
+const bool CaseSensitiveFS = TRUE;
+#endif
/*!
\class QDir
+ \reentrant
\brief The QDir class provides access to directory structures and their contents in a platform-independent way.
\ingroup io
\mainclass
A QDir is used to manipulate path names, access information
regarding paths and files, and manipulate the underlying file
system.
A QDir can point to a file using either a relative or an absolute
path. Absolute paths begin with the directory separator "/"
(optionally preceded by a drive specification under Windows). If
you always use "/" as a directory separator, Qt will translate
your paths to conform to the underlying operating system. Relative
file names begin with a directory name or a file name and specify
a path relative to the current directory.
The "current" path refers to the application's working directory.
A QDir's own path is set and retrieved with setPath() and path().
An example of an absolute path is the string "/tmp/quartz", a
relative path might look like "src/fatlib". You can use the
function isRelative() to check if a QDir is using a relative or an
absolute file path. Call convertToAbs() to convert a relative QDir
to an absolute one. For a simplified path use cleanDirPath(). To
obtain a path which has no symbolic links or redundant ".."
elements use canonicalPath(). The path can be set with setPath(),
and changed with cd() and cdUp().
QDir provides several static functions, for example, setCurrent()
to set the application's working directory and currentDirPath() to
retrieve the application's working directory. Access to some
common paths is provided with the static functions, current(),
home() and root() which return QDir objects or currentDirPath(),
homeDirPath() and rootDirPath() which return the path as a string.
The number of entries in a directory is returned by count().
Obtain a string list of the names of all the files and directories
in a directory with entryList(). If you prefer a list of QFileInfo
pointers use entryInfoList(). Both these functions can apply a
name filter, an attributes filter (e.g. read-only, files not
directories, etc.), and a sort order. The filters and sort may be
set with calls to setNameFilter(), setFilter() and setSorting().
They may also be specified in the entryList() and
entryInfoList()'s arguments.
Create a new directory with mkdir(), rename a directory with
rename() and remove an existing directory with rmdir(). Remove a
@@ -185,96 +190,104 @@ QDir::QDir()
Example that lists all the files in "/tmp":
\code
QDir d( "/tmp" );
for ( int i = 0; i < d.count(); i++ )
printf( "%s\n", d[i] );
\endcode
If \a path is "" or QString::null, QDir uses "." (the current
directory). If \a nameFilter is "" or QString::null, QDir uses the
name filter "*" (all files).
Note that \a path need not exist.
\sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
*/
QDir::QDir( const QString &path, const QString &nameFilter,
int sortSpec, int filterSpec )
{
init();
dPath = cleanDirPath( path );
if ( dPath.isEmpty() )
dPath = QString::fromLatin1(".");
nameFilt = nameFilter;
if ( nameFilt.isEmpty() )
nameFilt = QString::fromLatin1("*");
filtS = (FilterSpec)filterSpec;
sortS = (SortSpec)sortSpec;
}
/*!
Constructs a QDir that is a copy of the directory \a d.
\sa operator=()
*/
QDir::QDir( const QDir &d )
{
dPath = d.dPath;
fList = 0;
fiList = 0;
nameFilt = d.nameFilt;
dirty = TRUE;
allDirs = d.allDirs;
filtS = d.filtS;
sortS = d.sortS;
}
+/*!
+ Refreshes the directory information.
+*/
+void QDir::refresh() const
+{
+ QDir* that = (QDir*) this;
+ that->dirty = TRUE;
+}
void QDir::init()
{
fList = 0;
fiList = 0;
nameFilt = QString::fromLatin1("*");
dirty = TRUE;
allDirs = FALSE;
filtS = All;
sortS = SortSpec(Name | IgnoreCase);
}
/*!
Destroys the QDir frees up its resources.
*/
QDir::~QDir()
{
delete fList;
delete fiList;
}
/*!
Sets the path of the directory to \a path. The path is cleaned of
redundant ".", ".." and of multiple separators. No check is made
to ensure that a directory with this path exists.
The path can be either absolute or relative. Absolute paths begin
with the directory separator "/" (optionally preceded by a drive
specification under Windows). Relative file names begin with a
directory name or a file name and specify a path relative to the
current directory. An example of an absolute path is the string
"/tmp/quartz", a relative path might look like "src/fatlib".
\sa path(), absPath(), exists(), cleanDirPath(), dirName(),
absFilePath(), isRelative(), convertToAbs()
*/
void QDir::setPath( const QString &path )
{
dPath = cleanDirPath( path );
if ( dPath.isEmpty() )
dPath = QString::fromLatin1(".");
dirty = TRUE;
}
/*!
@@ -337,100 +350,126 @@ QString QDir::dirName() const
check if the file actually exists in the directory. If the QDir is
relative the returned path name will also be relative. Redundant
multiple separators or "." and ".." directories in \a fileName
will not be removed (see cleanDirPath()).
If \a acceptAbsPath is TRUE a \a fileName starting with a
separator "/" will be returned without change. If \a acceptAbsPath
is FALSE an absolute path will be prepended to the fileName and
the resultant string returned.
\sa absFilePath(), isRelative(), canonicalPath()
*/
QString QDir::filePath( const QString &fileName,
bool acceptAbsPath ) const
{
if ( acceptAbsPath && !isRelativePath(fileName) )
return QString(fileName);
QString tmp = dPath;
if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
fileName[0] != '/') )
tmp += '/';
tmp += fileName;
return tmp;
}
/*!
Returns the absolute path name of a file in the directory. Does \e
not check if the file actually exists in the directory. Redundant
multiple separators or "." and ".." directories in \a fileName
will not be removed (see cleanDirPath()).
If \a acceptAbsPath is TRUE a \a fileName starting with a
separator "/" will be returned without change. If \a acceptAbsPath
is FALSE an absolute path will be prepended to the fileName and
the resultant string returned.
\sa filePath()
*/
QString QDir::absFilePath( const QString &fileName,
bool acceptAbsPath ) const
{
if ( acceptAbsPath && !isRelativePath( fileName ) )
return fileName;
QString tmp = absPath();
- if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
- fileName[0] != '/') )
- tmp += '/';
- tmp += fileName;
+#ifdef Q_OS_WIN32
+ if ( fileName[0].isLetter() && fileName[1] == ':' ) {
+ int drv = fileName.upper()[0].latin1() - 'A' + 1;
+ if ( _getdrive() != drv ) {
+ if ( qt_winunicode ) {
+ TCHAR buf[PATH_MAX];
+ ::_tgetdcwd( drv, buf, PATH_MAX );
+ tmp.setUnicodeCodes( (ushort*)buf, ::_tcslen(buf) );
+ } else {
+ char buf[PATH_MAX];
+ ::_getdcwd( drv, buf, PATH_MAX );
+ tmp = buf;
+ }
+ if ( !tmp.endsWith("\\") )
+ tmp += "\\";
+ tmp += fileName.right( fileName.length() - 2 );
+ int x;
+ for ( x = 0; x < (int) tmp.length(); x++ ) {
+ if ( tmp[x] == '\\' )
+ tmp[x] = '/';
+ }
+ }
+ } else
+#endif
+ {
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ }
return tmp;
}
/*!
Returns \a pathName with the '/' separators converted to
separators that are appropriate for the underlying operating
system.
On Windows, convertSeparators("c:/winnt/system32") returns
"c:\winnt\system32".
The returned string may be the same as the argument on some
operating systems, for example on Unix.
*/
QString QDir::convertSeparators( const QString &pathName )
{
QString n( pathName );
#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
for ( int i=0; i<(int)n.length(); i++ ) {
if ( n[i] == '/' )
n[i] = '\\';
}
#elif defined(Q_OS_MAC9)
while(n.length() && n[0] == '/' ) n = n.right(n.length()-1);
for ( int i=0; i<(int)n.length(); i++ ) {
if ( n[i] == '/' )
n[i] = ':';
}
if(n.contains(':') && n.left(1) != ':')
n.prepend(':');
#endif
return n;
}
/*!
Changes the QDir's directory to \a dirName.
If \a acceptAbsPath is TRUE a path starting with separator "/"
will cause the function to change to the absolute directory. If \a
acceptAbsPath is FALSE any number of separators at the beginning
of \a dirName will be removed and the function will descend into
\a dirName.
Returns TRUE if the new directory exists and is readable;
otherwise returns FALSE. Note that the logical cd() operation is
@@ -889,112 +928,114 @@ void QDir::convertToAbs()
dPath = absPath();
}
/*!
Makes a copy of QDir \a d and assigns it to this QDir.
*/
QDir &QDir::operator=( const QDir &d )
{
dPath = d.dPath;
delete fList;
fList = 0;
delete fiList;
fiList = 0;
nameFilt = d.nameFilt;
dirty = TRUE;
allDirs = d.allDirs;
filtS = d.filtS;
sortS = d.sortS;
return *this;
}
/*!
\overload
Sets the directory path to be the given \a path.
*/
QDir &QDir::operator=( const QString &path )
{
dPath = cleanDirPath( path );
dirty = TRUE;
return *this;
}
/*!
\fn bool QDir::operator!=( const QDir &d ) const
Returns TRUE if directory \a d and this directory have different
paths or different sort or filter settings; otherwise returns
FALSE.
Example:
\code
// The current directory is "/usr/local"
QDir d1( "/usr/local/bin" );
QDir d2( "bin" );
- if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed
+ if ( d1 != d2 )
+ qDebug( "They differ" );
\endcode
*/
/*!
Returns TRUE if directory \a d and this directory have the same
path and their sort and filter settings are the same; otherwise
returns FALSE.
Example:
\code
// The current directory is "/usr/local"
QDir d1( "/usr/local/bin" );
QDir d2( "bin" );
d2.convertToAbs();
- if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed
+ if ( d1 == d2 )
+ qDebug( "They're the same" );
\endcode
*/
bool QDir::operator==( const QDir &d ) const
{
return dPath == d.dPath &&
nameFilt == d.nameFilt &&
allDirs == d.allDirs &&
filtS == d.filtS &&
sortS == d.sortS;
}
/*!
Removes the file, \a fileName.
If \a acceptAbsPath is TRUE a path starting with separator "/"
will remove the file with the absolute path. If \a acceptAbsPath
is FALSE any number of separators at the beginning of \a fileName
will be removed and the resultant file name will be removed.
Returns TRUE if the file is removed successfully; otherwise
returns FALSE.
*/
bool QDir::remove( const QString &fileName, bool acceptAbsPath )
{
if ( fileName.isEmpty() ) {
#if defined(QT_CHECK_NULL)
qWarning( "QDir::remove: Empty or null file name" );
#endif
return FALSE;
}
QString p = filePath( fileName, acceptAbsPath );
return QFile::remove( p );
}
/*!
Checks for the existence of the file \a name.
If \a acceptAbsPath is TRUE a path starting with separator "/"
will check the file with the absolute path. If \a acceptAbsPath is
FALSE any number of separators at the beginning of \a name will be
removed and the resultant file name will be checked.
Returns TRUE if the file exists; otherwise returns FALSE.
\sa QFileInfo::exists(), QFile::exists()
@@ -1042,158 +1083,165 @@ char QDir::separator()
\sa currentDirPath(), QDir::QDir()
*/
QDir QDir::current()
{
return QDir( currentDirPath() );
}
/*!
Returns the home directory.
Under Windows the \c HOME environment variable is used. If this
does not exist the \c USERPROFILE environment variable is used. If
that does not exist the path is formed by concatenating the \c
HOMEDRIVE and \c HOMEPATH environment variables. If they don't
exist the rootDirPath() is used (this uses the \c SystemDrive
environment variable). If none of these exist "C:\" is used.
Under non-Windows operating systems the \c HOME environment
variable is used if it exists, otherwise rootDirPath() is used.
\sa homeDirPath()
*/
QDir QDir::home()
{
return QDir( homeDirPath() );
}
/*!
Returns the root directory.
\sa rootDirPath() drives()
*/
QDir QDir::root()
{
return QDir( rootDirPath() );
}
/*!
\fn QString QDir::homeDirPath()
Returns the absolute path of the user's home directory.
\sa home()
*/
-QStringList qt_makeFilterList( const QString &filter )
+QValueList<QRegExp> qt_makeFilterList( const QString &filter )
{
+ QValueList<QRegExp> regExps;
if ( filter.isEmpty() )
- return QStringList();
+ return regExps;
QChar sep( ';' );
int i = filter.find( sep, 0 );
if ( i == -1 && filter.find( ' ', 0 ) != -1 )
sep = QChar( ' ' );
QStringList list = QStringList::split( sep, filter );
QStringList::Iterator it = list.begin();
- QStringList list2;
+ while ( it != list.end() ) {
+ regExps << QRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE );
+ ++it;
+ }
+ return regExps;
+}
- for ( ; it != list.end(); ++it ) {
- QString s = *it;
- list2 << s.stripWhiteSpace();
+bool qt_matchFilterList( const QValueList<QRegExp>& filters,
+ const QString &fileName )
+{
+ QValueList<QRegExp>::ConstIterator rit = filters.begin();
+ while ( rit != filters.end() ) {
+ if ( (*rit).exactMatch(fileName) )
+ return TRUE;
+ ++rit;
}
- return list2;
+ return FALSE;
}
+
/*!
\overload
Returns TRUE if the \a fileName matches any of the wildcard (glob)
patterns in the list of \a filters; otherwise returns FALSE.
(See \link qregexp.html#wildcard-matching QRegExp wildcard
matching.\endlink)
\sa QRegExp::match()
*/
bool QDir::match( const QStringList &filters, const QString &fileName )
{
QStringList::ConstIterator sit = filters.begin();
while ( sit != filters.end() ) {
-#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
- QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive..
-#else
- QRegExp rx( *sit, TRUE, TRUE ); // ..while others are.
-#endif
+ QRegExp rx( *sit, CaseSensitiveFS, TRUE );
if ( rx.exactMatch(fileName) )
return TRUE;
++sit;
}
return FALSE;
}
/*!
Returns TRUE if the \a fileName matches the wildcard (glob)
pattern \a filter; otherwise returns FALSE. The \a filter may
contain multiple patterns separated by spaces or semicolons.
(See \link qregexp.html#wildcard-matching QRegExp wildcard
matching.\endlink)
\sa QRegExp::match()
*/
bool QDir::match( const QString &filter, const QString &fileName )
{
- QStringList lst = qt_makeFilterList( filter );
- return match( lst, fileName );
+ return qt_matchFilterList( qt_makeFilterList(filter), fileName );
}
/*!
Removes all multiple directory separators "/" and resolves any
"."s or ".."s found in the path, \a filePath.
Symbolic links are kept. This function does not return the
canonical path, but rather the simplest version of the input.
For example, "./local" becomes "local", "local/../bin" becomes
"bin" and "/local/usr/../bin" becomes "/local/bin".
\sa absPath() canonicalPath()
*/
QString QDir::cleanDirPath( const QString &filePath )
{
QString name = filePath;
QString newPath;
if ( name.isEmpty() )
return name;
slashify( name );
bool addedSeparator;
if ( isRelativePath(name) ) {
addedSeparator = TRUE;
name.insert( 0, '/' );
} else {
addedSeparator = FALSE;
}
int ePos, pos, upLevel;
pos = ePos = name.length();
upLevel = 0;
int len;
while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
len = ePos - pos - 1;
if ( len == 2 && name.at(pos + 1) == '.'
&& name.at(pos + 2) == '.' ) {
upLevel++;
} else {
if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
if ( !upLevel )
newPath = QString::fromLatin1("/")