Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/qtools/qdir_win32.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
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_)
44extern Q_UINT32 DosQueryCurrentDisk(Q_UINT32*,Q_UINT32*);
45#define NO_ERROR 0
46#endif
47
48extern QStringList qt_makeFilterList( const QString &filter );
49
50extern int qt_cmp_si_sortSpec;
51
52#if defined(Q_C_CALLBACKS)
53extern "C" {
54#endif
55
56extern int qt_cmp_si( const void *, const void * );
57
58#if defined(Q_C_CALLBACKS)
59}
60#endif
61
62static QString p_getenv( QString name )
63{
64 DWORD len = GetEnvironmentVariableW( ( LPCWSTR ) qt_winTchar ( name, TRUE ), NULL, 0 );
65 if ( len == 0 )
66 return QString::null;
67 /* ansi: we allocate too much memory, but this shouldn't be the problem here ... */
68 LPWSTR buf = (LPWSTR)new WCHAR[ len ];
69 len = GetEnvironmentVariableW ( ( LPCWSTR ) qt_winTchar ( name, TRUE ), buf, len );
70 if ( len == 0 )
71 {
72 delete[] buf;
73 return QString::null;
74 }
75 QString ret = qt_winQString ( buf );
76 delete[] buf;
77 return ret;
78}
79
80
81void QDir::slashify( QString& n )
82{
83 for ( int i=0; i<(int)n.length(); i++ )
84 {
85 if ( n[i] == '\\' )
86 n[i] = '/';
87 }
88}
89
90QString QDir::homeDirPath()
91{
92 QString d = p_getenv ( "HOME" );
93 if ( d.isNull () ) {
94 d = p_getenv ( "USERPROFILE" );
95 if ( d.isNull () ) {
96 QString homeDrive = p_getenv ( "HOMEDRIVE" );
97 QString homePath = p_getenv ( "HOMEPATH" );
98 if ( !homeDrive.isNull () && !homePath.isNull () ) {
99 d = homeDrive + homePath;
100 } else {
101 d = rootDirPath ();
102 }
103 }
104 }
105 slashify( d );
106 return d;
107}
108
109QString QDir::canonicalPath() const
110{
111 QString r;
112
113 char cur[PATH_MAX];
114 char tmp[PATH_MAX];
115 GETCWD( cur, PATH_MAX );
116 if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
117GETCWD( tmp, PATH_MAX );
118r = QFile::decodeName(tmp);
119 }
120 CHDIR( cur );
121
122 slashify( r );
123 return r;
124}
125
126bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
127{
128#if defined(__CYGWIN32_)
129 return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) == 0;
130#else
131 return _wmkdir( ( LPCWSTR ) filePath( dirName, acceptAbsPath ).ucs2() ) == 0;
132#endif
133}
134
135bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
136{
137#if defined(__CYGWIN32_)
138 return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
139#else
140 return _wrmdir( ( LPCWSTR ) filePath( dirName, acceptAbsPath ).ucs2() ) == 0;
141#endif
142}
143
144bool QDir::isReadable() const
145{
146 QString path = dPath;
147 if ( ( path[ 0 ] == '\\' ) || ( path[ 0 ] == '/' ) )
148 path = rootDirPath() + path;
149#if defined(__CYGWIN32_)
150 return ACCESS( QFile::encodeName(dPath), R_OK ) == 0;
151#else
152 return ( _waccess( (wchar_t*) path.ucs2(), R_OK ) == 0 );
153#endif
154}
155
156bool QDir::isRoot() const
157{
158 QString path = dPath;
159 slashify( path );
160 return path == rootDirPath ();
161}
162
163bool QDir::rename( const QString &name, const QString &newName,
164 bool acceptAbsPaths)
165{
166 if ( name.isEmpty() || newName.isEmpty() ) {
167#if defined(CHECK_NULL)
168qWarning( "QDir::rename: Empty or null file name(s)" );
169#endif
170return FALSE;
171 }
172 QString fn1 = filePath( name, acceptAbsPaths );
173 QString fn2 = filePath( newName, acceptAbsPaths );
174#if defined(__CYGWIN32_)
175 return ::rename( QFile::encodeName(fn1),
176 QFile::encodeName(fn2) ) == 0;
177#else
178 return MoveFileW( ( LPCWSTR ) fn1.ucs2(), ( LPCWSTR ) fn2.ucs2() ) != 0;
179#endif
180}
181
182bool QDir::setCurrent( const QString &path )
183{
184#if defined(__CYGWIN32_)
185 int r;
186 r = CHDIR( QFile::encodeName(path) );
187 return r >= 0;
188#else
189 if ( !QDir( path ).exists() )
190 return false;
191 return ( SetCurrentDirectoryW( ( LPCWSTR ) path.ucs2() ) >= 0 );
192#endif
193}
194
195QString QDir::currentDirPath()
196{
197 QString result;
198
199#if defined(__CYGWIN32_)
200
201 STATBUF st;
202 if ( STAT( ".", &st ) == 0 ) {
203char currentName[PATH_MAX];
204if ( GETCWD( currentName, PATH_MAX ) != 0 )
205 result = QFile::decodeName(currentName);
206#if defined(DEBUG)
207if ( result.isNull() )
208 qWarning( "QDir::currentDirPath: getcwd() failed" );
209#endif
210 } else {
211#if defined(DEBUG)
212qWarning( "QDir::currentDirPath: stat(\".\") failed" );
213#endif
214 }
215
216#else
217
218 DWORD size = 0;
219 WCHAR currentName[ PATH_MAX ];
220 size = ::GetCurrentDirectoryW( PATH_MAX, currentName );
221 if ( size != 0 ) {
222 if ( size > PATH_MAX ) {
223 WCHAR * newCurrentName = new WCHAR[ size ];
224 if ( ::GetCurrentDirectoryW( PATH_MAX, newCurrentName ) != 0 )
225 result = QString::fromUcs2( ( ushort* ) newCurrentName );
226 delete [] newCurrentName;
227 } else {
228 result = QString::fromUcs2( ( ushort* ) currentName );
229 }
230 }
231
232 if ( result.length() >= 2 && result[ 1 ] == ':' )
233 result[ 0 ] = result.at( 0 ).upper(); // Force uppercase drive letters.
234#endif
235 slashify( result );
236 return result;
237}
238
239QString QDir::rootDirPath()
240{
241 QString d = p_getenv ( "SystemDrive" );
242 if ( d.isNull () )
243 d = QString::fromLatin1( "c:" ); // not "c:\\" !
244 slashify ( d );
245 return d;
246}
247
248bool QDir::isRelativePath( const QString &path )
249{
250 if ( path.isEmpty() )
251 return TRUE;
252 int p = 0;
253 if ( path[ 0 ].isLetter() && path[ 1 ] == ':' )
254 p = 2; // we have checked the first 2.
255 return ( ( path[ p ] != '/' ) && ( path[ p ] != '\\' ) );
256}
257
258#undef IS_SUBDIR
259#undef IS_RDONLY
260#undef IS_ARCH
261#undef IS_HIDDEN
262#undef IS_SYSTEM
263#undef FF_GETFIRST
264#undef FF_GETNEXT
265#undef FF_ERROR
266
267#if defined(_OS_WIN32_)
268#define IS_SUBDIR FILE_ATTRIBUTE_DIRECTORY
269#define IS_RDONLY FILE_ATTRIBUTE_READONLY
270#define IS_ARCH FILE_ATTRIBUTE_ARCHIVE
271#define IS_HIDDEN FILE_ATTRIBUTE_HIDDEN
272#define IS_SYSTEM FILE_ATTRIBUTE_SYSTEM
273#define FF_GETFIRST FindFirstFile
274#define FF_GETNEXT FindNextFile
275#define FF_ERROR INVALID_HANDLE_VALUE
276#else
277#define IS_SUBDIR _A_SUBDIR
278#define IS_RDONLY _A_RDONLY
279#define IS_ARCH _A_ARCH
280#define IS_HIDDEN _A_HIDDEN
281#define IS_SYSTEM _A_SYSTEM
282#define FF_GETFIRST _findfirst
283#define FF_GETNEXT _findnext
284#define FF_ERROR -1
285#endif
286
287
288bool QDir::readDirEntries( const QString &nameFilter,
289 int filterSpec, int sortSpec )
290{
291 int i;
292 if ( !fList ) {
293fList = new QStringList;
294CHECK_PTR( fList );
295fiList = new QFileInfoList;
296CHECK_PTR( fiList );
297fiList->setAutoDelete( TRUE );
298 } else {
299fList->clear();
300fiList->clear();
301 }
302
303 QStringList filters = qt_makeFilterList( nameFilter );
304
305 bool doDirs = (filterSpec & Dirs)!= 0;
306 bool doFiles = (filterSpec & Files)!= 0;
307 bool noSymLinks = (filterSpec & NoSymLinks) != 0;
308 bool doReadable = (filterSpec & Readable)!= 0;
309 bool doWritable = (filterSpec & Writable)!= 0;
310 bool doExecable = (filterSpec & Executable) != 0;
311 bool doHidden = (filterSpec & Hidden)!= 0;
312 // show hidden files if the user asks explicitly for e.g. .*
313 if ( !doHidden && !nameFilter.isEmpty() && nameFilter[0] == '.' )
314 doHidden = TRUE;
315 bool doModified = (filterSpec & Modified) != 0;
316 bool doSystem = (filterSpec & System) != 0;
317
318 QRegExp wc( nameFilter.data(), FALSE, TRUE ); // wild card, case insensitive
319 bool first = TRUE;
320 QString p = dPath.copy();
321 int plen = p.length();
322#if defined(_OS_WIN32_)
323 HANDLE ff;
324 WIN32_FIND_DATAW finfo;
325#else
326 long ff;
327 _finddata_t finfo;
328#endif
329 QFileInfo fi;
330 if ( plen == 0 )
331 {
332#if defined(CHECK_NULL)
333 warning( "QDir::readDirEntries: No directory name specified" );
334#endif
335 return FALSE;
336 }
337 if ( p.at(plen-1) != '/' && p.at(plen-1) != '\\' )
338 p += '/';
339 p += "*.*";
340
341#if defined(__CYGWIN32_)
342 ff = FF_GETFIRST( p.data(), &finfo );
343#else
344 ff = FindFirstFileW ( ( LPCWSTR ) p.ucs2(), &finfo );
345#endif
346 if ( ff == FF_ERROR )
347 {
348#if defined(DEBUG)
349 warning( "QDir::readDirEntries: Cannot read the directory: %s",
350 (const char *)dPath );
351#endif
352 return FALSE;
353 }
354
355 while ( TRUE )
356 {
357if ( first )
358 first = FALSE;
359else
360 {
361#if defined(__CYGWIN32_)
362 if ( FF_GETNEXT(ff,&finfo) == -1 )
363break;
364#else
365 //if ( !FF_GETNEXT(ff,&finfo) )
366 //break;
367 if (!FindNextFileW(ff, &finfo ))
368 break;
369#endif
370}
371#if defined(__CYGWIN32_)
372int attrib = finfo.attrib;
373#else
374int attrib = finfo.dwFileAttributes;
375#endif
376bool isDir= (attrib & IS_SUBDIR) != 0;
377bool isFile= !isDir;
378bool isSymLink= FALSE;
379bool isReadable = TRUE;
380bool isWritable = (attrib & IS_RDONLY) == 0;
381bool isExecable = FALSE;
382bool isModified = (attrib & IS_ARCH) != 0;
383bool isHidden= (attrib & IS_HIDDEN) != 0;
384bool isSystem= (attrib & IS_SYSTEM) != 0;
385
386#if defined(__CYGWIN32_)
387const char *fname = finfo.name;
388#else
389//const char *fname = finfo.cFileName;
390 QString fname = QString::fromUcs2( ( const unsigned short* ) finfo.cFileName);
391#endif
392if ( wc.match(fname.utf8()) == -1 && !(allDirs && isDir) )
393 continue;
394
395QString name = fname;
396if ( doExecable )
397 {
398 QString ext = name.right(4).lower();
399 if ( ext == ".exe" || ext == ".com" || ext == ".bat" ||
400 ext == ".pif" || ext == ".cmd" )
401isExecable = TRUE;
402}
403
404if ( (doDirs && isDir) || (doFiles && isFile) )
405 {
406 if ( noSymLinks && isSymLink )
407continue;
408 if ( (filterSpec & RWEMask) != 0 )
409if ( (doReadable && !isReadable) ||
410 (doWritable && !isWritable) ||
411 (doExecable && !isExecable) )
412 continue;
413 if ( doModified && !isModified )
414continue;
415 if ( !doHidden && isHidden )
416continue;
417 if ( !doSystem && isSystem )
418continue;
419 fi.setFile( *this, name );
420 fiList->append( new QFileInfo( fi ) );
421}
422 }
423#if defined(__CYGWIN32_)
424 _findclose( ff );
425#else
426 FindClose( ff );
427#endif
428
429 // Sort...
430 QDirSortItem* si= new QDirSortItem[fiList->count()];
431 QFileInfo* itm;
432 i=0;
433 for (itm = fiList->first(); itm; itm = fiList->next())
434si[i++].item = itm;
435 qt_cmp_si_sortSpec = sortSpec;
436 qsort( si, i, sizeof(si[0]), qt_cmp_si );
437 // put them back in the list
438 fiList->setAutoDelete( FALSE );
439 fiList->clear();
440 int j;
441 for ( j=0; j<i; j++ ) {
442fiList->append( si[j].item );
443fList->append( si[j].item->fileName() );
444 }
445 delete [] si;
446 fiList->setAutoDelete( TRUE );
447
448 if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
449 nameFilter == nameFilt )
450dirty = FALSE;
451 else
452dirty = TRUE;
453 return TRUE;
454}
455
456const QFileInfoList * QDir::drives()
457{
458 // at most one instance of QFileInfoList is leaked, and this variable
459 // points to that list
460 static QFileInfoList * knownMemoryLeak = 0;
461
462 if ( !knownMemoryLeak ) {
463knownMemoryLeak = new QFileInfoList;
464
465#if defined(_OS_WIN32_)
466Q_UINT32 driveBits = (Q_UINT32) GetLogicalDrives() & 0x3ffffff;
467#elif defined(_OS_OS2EMX_)
468Q_UINT32 driveBits, cur;
469if (DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR)
470 exit(1);
471driveBits &= 0x3ffffff;
472#endif
473char driveName[4];
474qstrcpy( driveName, "a:/" );
475while( driveBits ) {
476 if ( driveBits & 1 )
477knownMemoryLeak->append( new QFileInfo( driveName ) );
478 driveName[0]++;
479 driveBits = driveBits >> 1;
480}
481 }
482
483 return knownMemoryLeak;
484}
485#endif //QT_NO_DIR
486

Archive Download this file

Revision: 1322