Orb/Doxygen/qtools/qdir_win32.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2001 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  * Based on qdir_unix.cpp 
       
    17  *
       
    18  * Copyright (C) 1992-2000 Trolltech AS.
       
    19  */
       
    20 
       
    21 
       
    22 #include "qglobal.h"
       
    23 
       
    24 #include "qdir.h"
       
    25 #ifndef QT_NO_DIR
       
    26 
       
    27 
       
    28 #include "qfileinfo.h"
       
    29 #include "qfiledefs_p.h"
       
    30 #include "qregexp.h"
       
    31 #include "qstringlist.h"
       
    32 #include <stdlib.h>
       
    33 #include <ctype.h>
       
    34 #if defined(_OS_WIN32_)
       
    35 #if defined(_CC_BOOL_DEF_)
       
    36 #undef  bool
       
    37 #include <windows.h>
       
    38 #define bool int
       
    39 #else
       
    40 #include <windows.h>
       
    41 #endif
       
    42 #endif
       
    43 #if defined(_OS_OS2EMX_)
       
    44 extern Q_UINT32 DosQueryCurrentDisk(Q_UINT32*,Q_UINT32*);
       
    45 #define NO_ERROR 0
       
    46 #endif
       
    47 
       
    48 extern QStringList qt_makeFilterList( const QString &filter );
       
    49 
       
    50 extern int qt_cmp_si_sortSpec;
       
    51 
       
    52 #if defined(Q_C_CALLBACKS)
       
    53 extern "C" {
       
    54 #endif
       
    55 
       
    56 extern int qt_cmp_si( const void *, const void * );
       
    57 
       
    58 #if defined(Q_C_CALLBACKS)
       
    59 }
       
    60 #endif
       
    61 
       
    62 
       
    63 void QDir::slashify( QString& n )
       
    64 {
       
    65   for ( int i=0; i<(int)n.length(); i++ ) 
       
    66   {
       
    67      if ( n[i] == '\\' )
       
    68           n[i] = '/';
       
    69   }
       
    70 }
       
    71 
       
    72 QString QDir::homeDirPath()
       
    73 {
       
    74     QString d;
       
    75     d = QFile::decodeName(getenv("HOME"));
       
    76     slashify( d );
       
    77     if ( d.isNull() )
       
    78 	d = rootDirPath();
       
    79     return d;
       
    80 }
       
    81 
       
    82 QString QDir::canonicalPath() const
       
    83 {
       
    84     QString r;
       
    85 
       
    86     char cur[PATH_MAX];
       
    87     char tmp[PATH_MAX];
       
    88     GETCWD( cur, PATH_MAX );
       
    89     if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
       
    90 	GETCWD( tmp, PATH_MAX );
       
    91 	r = QFile::decodeName(tmp);
       
    92     }
       
    93     CHDIR( cur );
       
    94 
       
    95     slashify( r );
       
    96     return r;
       
    97 }
       
    98 
       
    99 bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
       
   100 {
       
   101 #if defined(__CYGWIN32_)
       
   102     return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) 
       
   103 	== 0;
       
   104 #else
       
   105     return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
       
   106 
       
   107 #endif
       
   108 }
       
   109 
       
   110 bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
       
   111 {
       
   112     return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
       
   113 }
       
   114 
       
   115 bool QDir::isReadable() const
       
   116 {
       
   117     return ACCESS( QFile::encodeName(dPath), R_OK ) == 0;
       
   118 }
       
   119 
       
   120 bool QDir::isRoot() const
       
   121 {
       
   122     return dPath == QString::fromLatin1("/");
       
   123 }
       
   124 
       
   125 bool QDir::rename( const QString &name, const QString &newName,
       
   126 		   bool acceptAbsPaths	)
       
   127 {
       
   128     if ( name.isEmpty() || newName.isEmpty() ) {
       
   129 #if defined(CHECK_NULL)
       
   130 	qWarning( "QDir::rename: Empty or null file name(s)" );
       
   131 #endif
       
   132 	return FALSE;
       
   133     }
       
   134     QString fn1 = filePath( name, acceptAbsPaths );
       
   135     QString fn2 = filePath( newName, acceptAbsPaths );
       
   136     return ::rename( QFile::encodeName(fn1),
       
   137 		     QFile::encodeName(fn2) ) == 0;
       
   138 }
       
   139 
       
   140 bool QDir::setCurrent( const QString &path )
       
   141 {
       
   142     int r;
       
   143     r = CHDIR( QFile::encodeName(path) );
       
   144     return r >= 0;
       
   145 }
       
   146 
       
   147 QString QDir::currentDirPath()
       
   148 {
       
   149     QString result;
       
   150 
       
   151     STATBUF st;
       
   152     if ( STAT( ".", &st ) == 0 ) {
       
   153 	char currentName[PATH_MAX];
       
   154 	if ( GETCWD( currentName, PATH_MAX ) != 0 )
       
   155 	    result = QFile::decodeName(currentName);
       
   156 #if defined(DEBUG)
       
   157 	if ( result.isNull() )
       
   158 	    qWarning( "QDir::currentDirPath: getcwd() failed" );
       
   159 #endif
       
   160     } else {
       
   161 #if defined(DEBUG)
       
   162 	qWarning( "QDir::currentDirPath: stat(\".\") failed" );
       
   163 #endif
       
   164     }
       
   165     slashify( result );
       
   166     return result;
       
   167 }
       
   168 
       
   169 QString QDir::rootDirPath()
       
   170 {
       
   171     QString d = QString::fromLatin1( "/" );
       
   172     return d;
       
   173 }
       
   174 
       
   175 bool QDir::isRelativePath( const QString &path )
       
   176 {
       
   177     int len = path.length();
       
   178     if ( len == 0 )
       
   179 	return TRUE;
       
   180     int i = 0;
       
   181     if ( isalpha(path[0]) && path[1] == ':' )           // drive, e.g. a:
       
   182         i = 2;
       
   183     return path[i] != '/' && path[i] != '\\';
       
   184 }
       
   185 
       
   186 #undef  IS_SUBDIR
       
   187 #undef  IS_RDONLY
       
   188 #undef  IS_ARCH
       
   189 #undef  IS_HIDDEN
       
   190 #undef  IS_SYSTEM
       
   191 #undef  FF_GETFIRST
       
   192 #undef  FF_GETNEXT
       
   193 #undef  FF_ERROR
       
   194 
       
   195 #if defined(_OS_WIN32_)
       
   196 #define IS_SUBDIR   FILE_ATTRIBUTE_DIRECTORY
       
   197 #define IS_RDONLY   FILE_ATTRIBUTE_READONLY
       
   198 #define IS_ARCH     FILE_ATTRIBUTE_ARCHIVE
       
   199 #define IS_HIDDEN   FILE_ATTRIBUTE_HIDDEN
       
   200 #define IS_SYSTEM   FILE_ATTRIBUTE_SYSTEM
       
   201 #define FF_GETFIRST FindFirstFile
       
   202 #define FF_GETNEXT  FindNextFile
       
   203 #define FF_ERROR    INVALID_HANDLE_VALUE
       
   204 #else
       
   205 #define IS_SUBDIR   _A_SUBDIR
       
   206 #define IS_RDONLY   _A_RDONLY
       
   207 #define IS_ARCH     _A_ARCH
       
   208 #define IS_HIDDEN   _A_HIDDEN
       
   209 #define IS_SYSTEM   _A_SYSTEM
       
   210 #define FF_GETFIRST _findfirst
       
   211 #define FF_GETNEXT  _findnext
       
   212 #define FF_ERROR    -1
       
   213 #endif
       
   214 
       
   215 
       
   216 bool QDir::readDirEntries( const QString &nameFilter,
       
   217 			   int filterSpec, int sortSpec )
       
   218 {
       
   219     int i;
       
   220     if ( !fList ) {
       
   221 	fList  = new QStringList;
       
   222 	CHECK_PTR( fList );
       
   223 	fiList = new QFileInfoList;
       
   224 	CHECK_PTR( fiList );
       
   225 	fiList->setAutoDelete( TRUE );
       
   226     } else {
       
   227 	fList->clear();
       
   228 	fiList->clear();
       
   229     }
       
   230 
       
   231     QStringList filters = qt_makeFilterList( nameFilter );
       
   232 
       
   233     bool doDirs	    = (filterSpec & Dirs)	!= 0;
       
   234     bool doFiles    = (filterSpec & Files)	!= 0;
       
   235     bool noSymLinks = (filterSpec & NoSymLinks) != 0;
       
   236     bool doReadable = (filterSpec & Readable)	!= 0;
       
   237     bool doWritable = (filterSpec & Writable)	!= 0;
       
   238     bool doExecable = (filterSpec & Executable) != 0;
       
   239     bool doHidden   = (filterSpec & Hidden)	!= 0;
       
   240     // show hidden files if the user asks explicitly for e.g. .*
       
   241     if ( !doHidden && !nameFilter.isEmpty() && nameFilter[0] == '.' )
       
   242          doHidden = TRUE;
       
   243     bool doModified = (filterSpec & Modified)   != 0;
       
   244     bool doSystem   = (filterSpec & System)     != 0;
       
   245 
       
   246     QRegExp   wc( nameFilter, FALSE, TRUE );    // wild card, case insensitive
       
   247     bool      first = TRUE;
       
   248     QString   p = dPath.copy();
       
   249     int       plen = p.length();
       
   250 #if defined(_OS_WIN32_)
       
   251     HANDLE    ff;
       
   252     WIN32_FIND_DATA finfo;
       
   253 #else
       
   254     long      ff;
       
   255     _finddata_t finfo;
       
   256 #endif
       
   257     QFileInfo fi;
       
   258     if ( plen == 0 )
       
   259     {
       
   260 #if defined(CHECK_NULL)
       
   261       warning( "QDir::readDirEntries: No directory name specified" );
       
   262 #endif
       
   263       return FALSE;
       
   264     }
       
   265     if ( p.at(plen-1) != '/' && p.at(plen-1) != '\\' )
       
   266           p += '/';
       
   267     p += "*.*";
       
   268 
       
   269     ff = FF_GETFIRST( p.data(), &finfo );
       
   270     if ( ff == FF_ERROR ) 
       
   271     {
       
   272 #if defined(DEBUG)
       
   273       warning( "QDir::readDirEntries: Cannot read the directory: %s",
       
   274                            (const char *)dPath );
       
   275 #endif
       
   276     return FALSE;
       
   277     }
       
   278     
       
   279     while ( TRUE ) 
       
   280     {
       
   281 	if ( first )
       
   282 	    first = FALSE;
       
   283 	else 
       
   284         {
       
   285 #if defined(_OS_WIN32_)
       
   286 	    if ( !FF_GETNEXT(ff,&finfo) )
       
   287 		break;
       
   288 #else
       
   289 	    if ( FF_GETNEXT(ff,&finfo) == -1 )
       
   290 		break;
       
   291 #endif
       
   292 	}
       
   293 #if defined(_OS_WIN32_)
       
   294 	int  attrib = finfo.dwFileAttributes;
       
   295 #else
       
   296 	int  attrib = finfo.attrib;
       
   297 #endif
       
   298 	bool isDir	= (attrib & IS_SUBDIR) != 0;
       
   299 	bool isFile	= !isDir;
       
   300 	bool isSymLink	= FALSE;
       
   301 	bool isReadable = TRUE;
       
   302 	bool isWritable = (attrib & IS_RDONLY) == 0;
       
   303 	bool isExecable = FALSE;
       
   304 	bool isModified = (attrib & IS_ARCH)   != 0;
       
   305 	bool isHidden	= (attrib & IS_HIDDEN) != 0;
       
   306 	bool isSystem	= (attrib & IS_SYSTEM) != 0;
       
   307 
       
   308 #if defined(_OS_WIN32_)
       
   309 	const char *fname = finfo.cFileName;
       
   310 #else
       
   311 	const char *fname = finfo.name;
       
   312 #endif
       
   313 	if ( wc.match(fname) == -1 && !(allDirs && isDir) )
       
   314 	    continue;
       
   315 
       
   316 	QString name = fname;
       
   317 	if ( doExecable ) 
       
   318         {
       
   319 	    QString ext = name.right(4).lower();
       
   320 	    if ( ext == ".exe" || ext == ".com" || ext == ".bat" ||
       
   321 		 ext == ".pif" || ext == ".cmd" )
       
   322 		isExecable = TRUE;
       
   323 	}
       
   324 
       
   325 	if  ( (doDirs && isDir) || (doFiles && isFile) ) 
       
   326         {
       
   327 	    if ( noSymLinks && isSymLink )
       
   328 		continue;
       
   329 	    if ( (filterSpec & RWEMask) != 0 )
       
   330 		if ( (doReadable && !isReadable) ||
       
   331 		     (doWritable && !isWritable) ||
       
   332 		     (doExecable && !isExecable) )
       
   333 		    continue;
       
   334 	    if ( doModified && !isModified )
       
   335 		continue;
       
   336 	    if ( !doHidden && isHidden )
       
   337 		continue;
       
   338 	    if ( !doSystem && isSystem )
       
   339 		continue;
       
   340 	    fi.setFile( *this, name );
       
   341 	    fiList->append( new QFileInfo( fi ) );
       
   342 	}
       
   343     }
       
   344 #if defined(_OS_WIN32_)
       
   345     FindClose( ff );
       
   346 #else
       
   347     _findclose( ff );
       
   348 #endif
       
   349 
       
   350     // Sort...
       
   351     QDirSortItem* si= new QDirSortItem[fiList->count()];
       
   352     QFileInfo* itm;
       
   353     i=0;
       
   354     for (itm = fiList->first(); itm; itm = fiList->next())
       
   355 	si[i++].item = itm;
       
   356     qt_cmp_si_sortSpec = sortSpec;
       
   357     qsort( si, i, sizeof(si[0]), qt_cmp_si );
       
   358     // put them back in the list
       
   359     fiList->setAutoDelete( FALSE );
       
   360     fiList->clear();
       
   361     int j;
       
   362     for ( j=0; j<i; j++ ) {
       
   363 	fiList->append( si[j].item );
       
   364 	fList->append( si[j].item->fileName() );
       
   365     }
       
   366     delete [] si;
       
   367     fiList->setAutoDelete( TRUE );
       
   368 
       
   369     if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
       
   370 	 nameFilter == nameFilt )
       
   371 	dirty = FALSE;
       
   372     else
       
   373 	dirty = TRUE;
       
   374     return TRUE;
       
   375 }
       
   376 
       
   377 const QFileInfoList * QDir::drives()
       
   378 {
       
   379     // at most one instance of QFileInfoList is leaked, and this variable
       
   380     // points to that list
       
   381     static QFileInfoList * knownMemoryLeak = 0;
       
   382 
       
   383     if ( !knownMemoryLeak ) {
       
   384 	knownMemoryLeak = new QFileInfoList;
       
   385 
       
   386 #if defined(_OS_WIN32_)
       
   387 	Q_UINT32 driveBits = (Q_UINT32) GetLogicalDrives() & 0x3ffffff;
       
   388 #elif defined(_OS_OS2EMX_)
       
   389 	Q_UINT32 driveBits, cur;
       
   390 	if (DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR)
       
   391 	    exit(1);
       
   392 	driveBits &= 0x3ffffff;
       
   393 #endif
       
   394 	char driveName[4];
       
   395 	qstrcpy( driveName, "a:/" );
       
   396 	while( driveBits ) {
       
   397 	    if ( driveBits & 1 )
       
   398 		knownMemoryLeak->append( new QFileInfo( driveName ) );
       
   399 	    driveName[0]++;
       
   400 	    driveBits = driveBits >> 1;
       
   401 	}
       
   402     }
       
   403 
       
   404     return knownMemoryLeak;
       
   405 }
       
   406 #endif //QT_NO_DIR