Fix for UBSan build
[platform/upstream/doxygen.git] / qtools / qdir_unix.cpp
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     (void)GETCWD( cur, PATH_MAX );
86     if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
87         (void)GETCWD( tmp, PATH_MAX );
88         r = QFile::decodeName(tmp);
89     }
90     (void)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