|
1 /**************************************************************************** |
|
2 ** |
|
3 ** |
|
4 ** Implementation of QDirclass |
|
5 ** |
|
6 ** Created : 950628 |
|
7 ** |
|
8 ** Copyright (C) 1992-2000 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 for Unix/X11 or for Qt/Embedded may use this file in accordance |
|
23 ** with the Qt Commercial License 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 "qglobal.h" |
|
39 |
|
40 #include "qdir.h" |
|
41 #ifndef QT_NO_DIR |
|
42 |
|
43 #include "qfileinfo.h" |
|
44 #include "qfiledefs_p.h" |
|
45 #include "qregexp.h" |
|
46 #include "qstringlist.h" |
|
47 #include <stdlib.h> |
|
48 #include <ctype.h> |
|
49 |
|
50 extern QStringList qt_makeFilterList( const QString &filter ); |
|
51 |
|
52 extern int qt_cmp_si_sortSpec; |
|
53 |
|
54 #if defined(Q_C_CALLBACKS) |
|
55 extern "C" { |
|
56 #endif |
|
57 |
|
58 extern int qt_cmp_si( const void *, const void * ); |
|
59 |
|
60 #if defined(Q_C_CALLBACKS) |
|
61 } |
|
62 #endif |
|
63 |
|
64 |
|
65 void QDir::slashify( QString& ) |
|
66 { |
|
67 } |
|
68 |
|
69 QString QDir::homeDirPath() |
|
70 { |
|
71 QString d; |
|
72 d = QFile::decodeName(getenv("HOME")); |
|
73 slashify( d ); |
|
74 if ( d.isNull() ) |
|
75 d = rootDirPath(); |
|
76 return d; |
|
77 } |
|
78 |
|
79 QString QDir::canonicalPath() const |
|
80 { |
|
81 QString r; |
|
82 |
|
83 char cur[PATH_MAX]; |
|
84 char tmp[PATH_MAX]; |
|
85 GETCWD( cur, PATH_MAX ); |
|
86 if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) { |
|
87 GETCWD( tmp, PATH_MAX ); |
|
88 r = QFile::decodeName(tmp); |
|
89 } |
|
90 CHDIR( cur ); |
|
91 |
|
92 slashify( r ); |
|
93 return r; |
|
94 } |
|
95 |
|
96 bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const |
|
97 { |
|
98 return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) |
|
99 == 0; |
|
100 } |
|
101 |
|
102 bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const |
|
103 { |
|
104 return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0; |
|
105 } |
|
106 |
|
107 bool QDir::isReadable() const |
|
108 { |
|
109 return ACCESS( QFile::encodeName(dPath), R_OK | X_OK ) == 0; |
|
110 } |
|
111 |
|
112 bool QDir::isRoot() const |
|
113 { |
|
114 return dPath == QString::fromLatin1("/"); |
|
115 } |
|
116 |
|
117 bool QDir::rename( const QString &name, const QString &newName, |
|
118 bool acceptAbsPaths ) |
|
119 { |
|
120 if ( name.isEmpty() || newName.isEmpty() ) { |
|
121 #if defined(CHECK_NULL) |
|
122 qWarning( "QDir::rename: Empty or null file name(s)" ); |
|
123 #endif |
|
124 return FALSE; |
|
125 } |
|
126 QString fn1 = filePath( name, acceptAbsPaths ); |
|
127 QString fn2 = filePath( newName, acceptAbsPaths ); |
|
128 return ::rename( QFile::encodeName(fn1), |
|
129 QFile::encodeName(fn2) ) == 0; |
|
130 } |
|
131 |
|
132 bool QDir::setCurrent( const QString &path ) |
|
133 { |
|
134 int r; |
|
135 r = CHDIR( QFile::encodeName(path) ); |
|
136 return r >= 0; |
|
137 } |
|
138 |
|
139 QString QDir::currentDirPath() |
|
140 { |
|
141 QString result; |
|
142 |
|
143 STATBUF st; |
|
144 if ( STAT( ".", &st ) == 0 ) { |
|
145 char currentName[PATH_MAX]; |
|
146 if ( GETCWD( currentName, PATH_MAX ) != 0 ) |
|
147 result = QFile::decodeName(currentName); |
|
148 #if defined(DEBUG) |
|
149 if ( result.isNull() ) |
|
150 qWarning( "QDir::currentDirPath: getcwd() failed" ); |
|
151 #endif |
|
152 } else { |
|
153 #if defined(DEBUG) |
|
154 qWarning( "QDir::currentDirPath: stat(\".\") failed" ); |
|
155 #endif |
|
156 } |
|
157 slashify( result ); |
|
158 return result; |
|
159 } |
|
160 |
|
161 QString QDir::rootDirPath() |
|
162 { |
|
163 QString d = QString::fromLatin1( "/" ); |
|
164 return d; |
|
165 } |
|
166 |
|
167 bool QDir::isRelativePath( const QString &path ) |
|
168 { |
|
169 int len = path.length(); |
|
170 if ( len == 0 ) |
|
171 return TRUE; |
|
172 return path[0] != '/'; |
|
173 } |
|
174 |
|
175 bool QDir::readDirEntries( const QString &nameFilter, |
|
176 int filterSpec, int sortSpec ) |
|
177 { |
|
178 int i; |
|
179 if ( !fList ) { |
|
180 fList = new QStringList; |
|
181 CHECK_PTR( fList ); |
|
182 fiList = new QFileInfoList; |
|
183 CHECK_PTR( fiList ); |
|
184 fiList->setAutoDelete( TRUE ); |
|
185 } else { |
|
186 fList->clear(); |
|
187 fiList->clear(); |
|
188 } |
|
189 |
|
190 QStringList filters = qt_makeFilterList( nameFilter ); |
|
191 |
|
192 bool doDirs = (filterSpec & Dirs) != 0; |
|
193 bool doFiles = (filterSpec & Files) != 0; |
|
194 bool noSymLinks = (filterSpec & NoSymLinks) != 0; |
|
195 bool doReadable = (filterSpec & Readable) != 0; |
|
196 bool doWritable = (filterSpec & Writable) != 0; |
|
197 bool doExecable = (filterSpec & Executable) != 0; |
|
198 bool doHidden = (filterSpec & Hidden) != 0; |
|
199 |
|
200 #if defined(_OS_OS2EMX_) |
|
201 //QRegExp wc( nameFilter, FALSE, TRUE ); // wild card, case insensitive |
|
202 #else |
|
203 //QRegExp wc( nameFilter, TRUE, TRUE ); // wild card, case sensitive |
|
204 #endif |
|
205 QFileInfo fi; |
|
206 DIR *dir; |
|
207 dirent *file; |
|
208 |
|
209 dir = opendir( QFile::encodeName(dPath) ); |
|
210 if ( !dir ) { |
|
211 #if defined(CHECK_NULL) |
|
212 qWarning( "QDir::readDirEntries: Cannot read the directory: %s", |
|
213 QFile::encodeName(dPath).data() ); |
|
214 #endif |
|
215 return FALSE; |
|
216 } |
|
217 |
|
218 while ( (file = readdir(dir)) ) { |
|
219 QString fn = QFile::decodeName(file->d_name); |
|
220 fi.setFile( *this, fn ); |
|
221 if ( !match( filters, fn ) && !(allDirs && fi.isDir()) ) |
|
222 continue; |
|
223 if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ) { |
|
224 if ( noSymLinks && fi.isSymLink() ) |
|
225 continue; |
|
226 if ( (filterSpec & RWEMask) != 0 ) |
|
227 if ( (doReadable && !fi.isReadable()) || |
|
228 (doWritable && !fi.isWritable()) || |
|
229 (doExecable && !fi.isExecutable()) ) |
|
230 continue; |
|
231 if ( !doHidden && fn[0] == '.' && |
|
232 fn != QString::fromLatin1(".") |
|
233 && fn != QString::fromLatin1("..") ) |
|
234 continue; |
|
235 fiList->append( new QFileInfo( fi ) ); |
|
236 } |
|
237 } |
|
238 if ( closedir(dir) != 0 ) { |
|
239 #if defined(CHECK_NULL) |
|
240 qWarning( "QDir::readDirEntries: Cannot close the directory: %s", |
|
241 dPath.local8Bit().data() ); |
|
242 #endif |
|
243 } |
|
244 |
|
245 // Sort... |
|
246 if(fiList->count()) { |
|
247 QDirSortItem* si= new QDirSortItem[fiList->count()]; |
|
248 QFileInfo* itm; |
|
249 i=0; |
|
250 for (itm = fiList->first(); itm; itm = fiList->next()) |
|
251 si[i++].item = itm; |
|
252 qt_cmp_si_sortSpec = sortSpec; |
|
253 qsort( si, i, sizeof(si[0]), qt_cmp_si ); |
|
254 // put them back in the list |
|
255 fiList->setAutoDelete( FALSE ); |
|
256 fiList->clear(); |
|
257 int j; |
|
258 for ( j=0; j<i; j++ ) { |
|
259 fiList->append( si[j].item ); |
|
260 fList->append( si[j].item->fileName() ); |
|
261 } |
|
262 delete [] si; |
|
263 fiList->setAutoDelete( TRUE ); |
|
264 } |
|
265 |
|
266 if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS && |
|
267 nameFilter == nameFilt ) |
|
268 dirty = FALSE; |
|
269 else |
|
270 dirty = TRUE; |
|
271 return TRUE; |
|
272 } |
|
273 |
|
274 const QFileInfoList * QDir::drives() |
|
275 { |
|
276 // at most one instance of QFileInfoList is leaked, and this variable |
|
277 // points to that list |
|
278 static QFileInfoList * knownMemoryLeak = 0; |
|
279 |
|
280 if ( !knownMemoryLeak ) { |
|
281 knownMemoryLeak = new QFileInfoList; |
|
282 // non-win32 versions both use just one root directory |
|
283 knownMemoryLeak->append( new QFileInfo( rootDirPath() ) ); |
|
284 } |
|
285 |
|
286 return knownMemoryLeak; |
|
287 } |
|
288 #endif //QT_NO_DIR |