0029252: Coding rules - eliminate GCC compiler warnings -Wformat-overflow
[occt.git] / src / OSD / OSD_FileIterator.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _WIN32
16
17
18 #include <OSD_File.hxx>
19 #include <OSD_FileIterator.hxx>
20 #include <OSD_OSDError.hxx>
21 #include <OSD_Path.hxx>
22 #include <OSD_WhoAmI.hxx>
23 #include <TCollection_AsciiString.hxx>
24
25 #include <dirent.h>
26 #include <stdio.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 # define NAMLEN(dirent) strlen((dirent)->d_name)
30 # ifdef VMS
31 extern char *vmsify PARAMS ((char *name, int type));
32 # endif
33
34 /* In GNU systems, <dirent.h> defines this macro for us.  */
35 #ifdef _D_NAMLEN
36 # undef NAMLEN
37 # define NAMLEN(d) _D_NAMLEN(d)
38 #endif
39
40 #if (defined (POSIX) || defined (VMS) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__)
41 /* Posix does not require that the d_ino field be present, and some
42    systems do not provide it. */
43 # define REAL_DIR_ENTRY(dp) 1
44 # define FAKE_DIR_ENTRY(dp)
45 #else
46 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
47 # define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1)
48 #endif /* POSIX */
49
50 //const OSD_WhoAmI Iam = OSD_WFileIterator;
51
52
53 OSD_FileIterator::OSD_FileIterator()
54 : myFlag(false),
55   myDescr(0),
56   myEntry(0),
57   myInit(0)
58 {
59 }
60
61 OSD_FileIterator::OSD_FileIterator(const OSD_Path& where,
62                                    const TCollection_AsciiString& Mask)
63 : myFlag(false),
64   myDescr(0),
65   myEntry(0),
66   myInit(0)
67 {
68  Initialize(where, Mask) ;
69 }
70
71 // For Windows NT compatibility
72 void OSD_FileIterator :: Destroy () {}
73
74 void OSD_FileIterator::Initialize(const OSD_Path& where,
75                                    const TCollection_AsciiString& Mask){
76  myFlag = Standard_False;
77  where.SystemName(myPlace);
78  if (myPlace.Length()==0) myPlace = ".";
79  myMask = Mask;
80  if (myDescr) {
81    closedir((DIR *)myDescr) ;
82    myDescr = NULL ;
83  }
84  myInit = 1 ;
85 }
86
87 // Is there another file entry ?
88
89 Standard_Boolean OSD_FileIterator::More(){
90  if (myInit) {
91    myInit = 0 ;
92    myDescr = (Standard_Address) opendir(myPlace.ToCString()); 
93    if (myDescr) {            // LD : Si repertoire inaccessible retourner False
94      myFlag = Standard_True;
95      myInit = 0 ;
96      Next();          // Now find first entry
97    }
98  }
99  return myFlag;
100 }
101
102 // Private :  See if file name matches with a mask (like "*.c")
103
104 static int strcmp_joker(const char *Mask,const char *Name)
105 {
106   const char *p, *s ;
107
108   for(p = Mask,s = Name ; *p && *p != '*' ; p++,s++)
109     if (*p != *s) return 0 ;
110
111   if (!*p) return !(*s) ;
112   while (*p == '*') p++ ;
113   if (!*p) return 1 ;
114   for (;*s; s++)
115     if (strcmp_joker(p,s)) return 1 ;
116   return 0 ;
117 }
118
119 #if 0
120     // LD : ancienne version.
121
122 #define TRUE  1
123 #define FALSE 0
124 #define NO_MASK '*'
125
126 static int strcmp_joker(char *fileMask,char *fileName)
127 {
128     char *sauve_fileMask,*sauve_fileName;
129     int compare_result;
130     int beginning = 1;   // 0 if first character is a joker, otherwise 1
131
132     while (*fileName) {        // Test end of AsciiString
133
134      if (*fileMask == NO_MASK) {
135       beginning = 0;
136
137       while(*fileMask == NO_MASK) fileMask++;
138
139       if (*fileMask) {
140        while(*fileName && 
141              *fileName != *fileMask) 
142         fileName++;
143
144        sauve_fileMask = fileMask;  // Save strings
145        sauve_fileName = fileName;
146       }
147       else return(0);   // fileMask ends with a joker
148
149      }
150      else { // Compare two characters
151       compare_result = *fileMask++ - *fileName++;
152
153       if (compare_result != 0) 
154        if (beginning) 
155         return (compare_result); /* 1ere chaine pas de joker au debut */
156        else {  // Look ahead for same string
157         fileMask = sauve_fileMask;
158         fileName = ++sauve_fileName;
159         while(*fileName && 
160               *fileName != *fileMask)
161          fileName++;
162         sauve_fileName = fileName;
163        }
164
165     }    
166
167    }    
168
169    while(*fileMask == NO_MASK) fileMask++;
170    return(*fileMask - *fileName);
171 }
172 #endif
173
174 // Find next file entry in current directory
175
176 void OSD_FileIterator::Next(){
177 int again = 1;
178 struct stat stat_buf;
179  myFlag = false;   // Initialize to nothing found
180
181  do {
182     myEntry = readdir((DIR *)myDescr);
183
184     if (!myEntry){   // No file found
185      myEntry = NULL;              // Keep pointer clean
186      myFlag = Standard_False;   // No more files/directory
187      closedir((DIR *)myDescr) ;       // so close directory
188      myDescr = NULL;
189      again = 0;
190     }
191     else {
192      if (!strcmp(((struct dirent *)myEntry)->d_name,".")) continue;
193      if (!strcmp(((struct dirent *)myEntry)->d_name,"..")) continue;
194
195      // Is it a file ?
196      const TCollection_AsciiString aFullName = myPlace + "/" + ((struct dirent* )myEntry)->d_name;
197      stat(aFullName.ToCString(), &stat_buf);
198      if (S_ISREG(stat_buf.st_mode))   // LD : Ensure me it's a regular file
199       if (strcmp_joker(myMask.ToCString(), ((struct dirent *)myEntry)->d_name)){
200                                                          // Does it follow mask ?
201        myFlag = Standard_True;
202        again = 0;
203       }
204     }
205
206  } while (again);
207
208 }
209
210 // Get Name of selected file
211
212 OSD_File OSD_FileIterator::Values(){
213 OSD_Path thisvalue;
214 TCollection_AsciiString Name;
215 TCollection_AsciiString Ext;
216 Standard_Integer position;
217
218  if (myEntry) Name = ((struct dirent *)myEntry)->d_name ;
219
220  position = Name.Search(".");
221
222  if (position != -1){
223   Ext = Name;
224   Ext.Remove(1,position-1);
225   Name.Remove( position,Ext.Length());
226  }
227
228  thisvalue.SetValues("", "", "", "", "", Name,Ext); 
229  TheIterator.SetPath (thisvalue);
230
231  return (TheIterator);
232 }
233
234
235 void OSD_FileIterator::Reset(){
236  myError.Reset();
237 }
238
239 Standard_Boolean OSD_FileIterator::Failed()const{
240  return( myError.Failed());
241 }
242
243 void OSD_FileIterator::Perror() {
244  myError.Perror();
245 }
246
247
248 Standard_Integer OSD_FileIterator::Error()const{
249  return( myError.Error());
250 }
251
252 #else
253
254 //------------------------------------------------------------------------
255 //-------------------  Windows NT sources for OSD_FileIterator -----------
256 //------------------------------------------------------------------------
257
258 #include <windows.h>
259
260
261 #include <OSD_File.hxx>
262 #include <OSD_FileIterator.hxx>
263 #include <OSD_OSDError.hxx>
264 #include <OSD_Path.hxx>
265 #include <TCollection_AsciiString.hxx>
266 #include <TCollection_ExtendedString.hxx>
267
268 #define _FD (  ( PWIN32_FIND_DATAW )myData  )
269
270 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
271
272 OSD_FileIterator :: OSD_FileIterator (
273                      const OSD_Path&                where,
274                      const TCollection_AsciiString& Mask
275                     ) {
276
277  myFlag   = Standard_False;
278  myHandle = INVALID_HANDLE_VALUE;
279
280  where.SystemName ( myPlace );
281
282  if (  myPlace.Length () == 0  ) myPlace = ".";
283
284  myMask = Mask;
285  myData = NULL;
286
287 }  // end constructor
288
289 void OSD_FileIterator :: Destroy () {
290
291  if ( myData != NULL ) HeapFree (  GetProcessHeap (), 0, myData  );
292
293  if (  myHandle != INVALID_HANDLE_VALUE  )
294
295   FindClose (  ( HANDLE )myHandle  );
296
297 }  // end  OSD_DirectoryIterator :: Destroy
298
299 Standard_Boolean OSD_FileIterator :: More () {
300
301  if (  myHandle == INVALID_HANDLE_VALUE  ) {
302  
303   TCollection_AsciiString wc = myPlace + "/" + myMask;
304
305   myData = HeapAlloc (
306             GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS, sizeof ( WIN32_FIND_DATAW )
307            );
308
309   // make wchar_t string from UTF-8
310   TCollection_ExtendedString wcW(wc);
311   myHandle = FindFirstFileExW (wcW.ToWideString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
312
313   if (  myHandle == INVALID_HANDLE_VALUE  )
314   
315    _osd_wnt_set_error ( myError, OSD_WDirectoryIterator );
316   
317   else {
318   
319    myFlag      = Standard_True;
320    myFirstCall = Standard_True;
321
322    Next ();
323
324   }  // end else
325   
326  } else if ( !myFlag ) {
327  
328   FindClose (  ( HANDLE )myHandle  );
329   myHandle = INVALID_HANDLE_VALUE;
330  
331  }  // end if
332
333  return myFlag;
334
335 }  // end OSD_FileIterator :: More
336
337 void OSD_FileIterator :: Next () {
338
339  if ( ! myFirstCall || ( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) {
340  
341   do {
342   
343    if (   !FindNextFileW (  ( HANDLE )myHandle, _FD  )   ) {
344    
345     myFlag = Standard_False;
346
347     break;
348    
349    }  // end if
350   
351   } while (  ( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )  );
352  
353  }  // end if
354  
355  myFirstCall = Standard_False;
356
357 }  // end OSD_FileIterator :: Next
358
359 OSD_File OSD_FileIterator :: Values () {
360
361  // make UTF-8 string
362  TCollection_AsciiString aFileName
363    (TCollection_ExtendedString( (Standard_ExtString) _FD -> cFileName) );
364  TheIterator.SetPath (   OSD_Path ( aFileName  )   );
365
366  return TheIterator;
367
368 }  // end OSD_FileIterator :: Values
369
370 Standard_Boolean OSD_FileIterator :: Failed () const {
371
372  return myError.Failed ();
373
374 }  // end OSD_FileIterator :: Failed
375
376 void OSD_FileIterator :: Reset () {
377
378  myError.Reset ();
379
380 }  // end OSD_FileIterator :: Reset
381
382 void OSD_FileIterator :: Perror () {
383
384  myError.Perror ();
385
386 }  // end OSD_FileIterator :: Perror
387
388 Standard_Integer OSD_FileIterator :: Error () const {
389
390  return myError.Error ();
391
392 }  // end  OSD_FileIterator :: Error
393
394 // For compatibility with UNIX version
395 OSD_FileIterator::OSD_FileIterator() {}
396
397 void OSD_FileIterator::Initialize(
398                        const OSD_Path&,
399                        const TCollection_AsciiString&){}
400  
401 #endif