EnglishРусский  

   ..

   arr.g

   arrstr.g

   arrustr.g

   buf.g

   console.g

   fcopy.g

   ffind.g

   file.g

   hash.g

   math.g

   process.g

   search.g

   stack.g

   stdlib.g

   str.g

   stradv.g

   strfile.g

   system.g

   ustr.g

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

source\lib\stdlib\ffind.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2004-2007, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * Author: Alexey Krivonogov ( gentee )
 11 *
 12 ******************************************************************************/
 13 
 14 define <export> {
 15 /*-----------------------------------------------------------------------------
 16 * Id: findflags D
 17 * 
 18 * Summary: Flags for searching files.
 19 *
 20 -----------------------------------------------------------------------------*/
 21    FIND_DIR     = 0x0001    // Search only for directories.
 22    FIND_FILE    = 0x0002    // Search only for files.
 23    FIND_RECURSE = 0x0004    // Search in all subdirectories.
 24    
 25 /*-----------------------------------------------------------------------------
 26 * Id: fdelflags D
 27 * 
 28 * Summary: Flags for delfiles.
 29 *
 30 -----------------------------------------------------------------------------*/
 31    DELF_RO      = 0x0100    // Delete files with the attribute read-only.
 32    
 33 //-----------------------------------------------------------------------------   
 34 }
 35 
 36 /*-----------------------------------------------------------------------------
 37 * Id: tfinfo T finfo 
 38 * 
 39 * Summary: File information structure. This structure is used by 
 40            #a(getfileinfo) function and #a(ffind_opfor, foreach ) operator.
 41 *
 42 -----------------------------------------------------------------------------*/
 43 
 44 type finfo {
 45    str       fullname   // The full name of the file or directory.
 46    str       name       // The name of the file or directory.
 47    uint      attrib     // File attributes.
 48    filetime  created    // Creation time.
 49    filetime  lastwrite  // Last modification time.
 50    filetime  lastaccess // Last access time.
 51    uint      sizehi     // High size uint.
 52    uint      sizelo     // Low size uint.
 53 }
 54 
 55 //-----------------------------------------------------------------------------
 56 
 57 type fstack {
 58    finfo  info
 59    str    path
 60    uint   find
 61    uint   ok   
 62 }
 63 
 64 /*-----------------------------------------------------------------------------
 65 * Id: ffind T 
 66 * 
 67 * Summary: File search structure. This structure is used in 
 68            #a(ffind_opfor,foreach ) operator. You must not modify fields of 
 69            #i(ffind) variable. You must initialize it with #a(ffind_init) 
 70            method.
 71 *
 72 -----------------------------------------------------------------------------*/
 73 
 74 type ffind <index = finfo> {
 75    stack  deep of fstack    // Hidden data.
 76    str    initname          // Hidden data.
 77    str    wildcard          // Hidden data. 
 78    uint   flag              // Hidden data.
 79 }
 80 
 81 //-----------------------------------------------------------------------------
 82 
 83 method fstack.delete()
 84 {
 85    if this.find 
 86    {
 87       FindClose( this.find )
 88       this.find = 0
 89    }
 90 }
 91 
 92 /*-----------------------------------------------------------------------------
 93 * Id: ffind_init F2
 94 *
 95 * Summary: Initializing file search. An object of the #a(ffind) type is used to
 96            search for files and directories by mask. Before starting the 
 97            search, you should call the init method. After this it is possible 
 98            to use the initiated object in the #b(foreach) loop. The #a(tfinfo)
 99            structure will be returned for each found file.  
100 *  
101 * Params: name - The mask for searching files and directories. 
102           flag - The combination of the following flags:$$[findflags] 
103 * 
104 -----------------------------------------------------------------------------*/
105 
106 method ffind.init( str name, uint flag )
107 {
108    arr ss of fstack
109    this.deep.clear()
110    this.flag = flag
111    this.initname = name
112    this.initname.fdelslash()
113    this.wildcard.fnameext( this.initname )
114    ss.insert( 0, 1 )
115    this.deep.push()
116 }
117 
118 func  wfd2finfo( WIN32_FIND_DATA  wfd, finfo fi, str path )
119 {
120    fi.name.copy( &wfd.cFileName )
121    ( fi.fullname = path ).faddname( fi.name )
122    fi.attrib = wfd.dwFileAttributes
123    fi.lastwrite = wfd.ftLastWriteTime
124    fi.created = wfd.ftCreationTime
125    fi.lastaccess = wfd.ftLastAccessTime
126    fi.sizehi = wfd.nFileSizeHigh
127    fi.sizelo = wfd.nFileSizeLow
128 }
129 
130 operator finfo =( finfo left, finfo right )
131 {
132    left.fullname = right.fullname
133    left.name = right.name
134    left.attrib = right.attrib
135    left.lastwrite = right.lastwrite
136    left.created = right.created
137    left.lastaccess = right.lastaccess
138    left.sizehi = right.sizehi
139    left.sizelo = right.sizelo
140 
141    return left
142 }
143 
144 method finfo ffind.getinfo
145 {
146    return this.deep.top()->finfo   
147 }
148 
149 method finfo ffind.found( WIN32_FIND_DATA wfd )
150 {
151    uint  flag = this.flag
152    uint  current = this.deep.top()
153    
154    if !wfd.cFileName[0] : goto next
155    
156    label again
157    current as fstack
158 
159    current.ok = 0
160    if wfd.cFileName[0] == '.' && ( !wfd.cFileName[1] ||
161            ( wfd.cFileName[1] == '.' && !wfd.cFileName[2] ))
162    {
163       goto next
164    }  
165    if wfd.dwFileAttributes & $FILE_ATTRIBUTE_DIRECTORY 
166    {
167        if flag & $FIND_DIR : current.ok = 1
168    }
169    else : if flag & $FIND_FILE : current.ok = 1
170    
171    if current.ok
172    {     
173       //current.ok = sfwildcard( &wfd.cFileName, this.wildcard.ptr())
174       str fn
175       fn.copy(  &wfd.cFileName )
176       current.ok = fn.fwildcard( this.wildcard ) 
177    }
178 
179    if wfd.dwFileAttributes & $FILE_ATTRIBUTE_DIRECTORY &&
180       flag & $FIND_RECURSE
181    {
182       str   newfld
183       uint  find
184       
185       wfd2finfo( wfd, current.info, current.path )
186 
187       newfld = current.info.fullname
188       current as this.deep.push()
189       current as fstack
190       current.path = newfld
191       newfld.faddname( "*" )
192       
193       current.find = FindFirstFile( newfld.ptr(), wfd )
194       if current.find != $INVALID_HANDLE_VALUE 
195       {
196          goto again
197       }
198       current as this.deep.pop()
199       current as fstack
200    }
201    if current.ok 
202    {
203       wfd2finfo( wfd, current.info, current.path ) 
204       return this.getinfo()
205    }
206 
207    label next
208    if FindNextFile( current.find, wfd ) : goto again
209 
210    FindClose( current.find )
211    current.find = 0
212 
213    if *this.deep > 1 
214    {
215       current as this.deep.pop()
216       current as fstack      
217       if ( current.ok ) : this.getinfo()
218       else : goto next
219    }
220    
221    return this.getinfo()
222 }
223 
224 /*-----------------------------------------------------------------------------
225 * Id: ffind_opfor F5
226 *
227 * Summary: Foreach operator. You can use #b(foreach) operator to look over  
228            files in some directory with the specified wildcard. The #a(tfinfo)
229            structure will be returned for each found file. You must call 
230            #a(ffind_init) before using #b(foreach). #srcg[
231 |ffind fd
232 |fd.init( "c:\\*.exe", $FIND_FILE | $FIND_RECURSE )
233 |foreach finfo cur,fd
234 |{
235 |   print( "\( cur.fullname )\n" )
236 |}]
237 *  
238 * Title: foreach var,ffind
239 *
240 * Define: foreach variable,ffind {...}
241 * 
242 -----------------------------------------------------------------------------*/
243 
244 method uint ffind.next( fordata fd)
245 {
246    WIN32_FIND_DATA  wfd   
247    
248    return &this.found( wfd )
249 }
250 
251 method uint ffind.first( fordata fd )
252 {
253    WIN32_FIND_DATA  wfd
254    str              temp
255    uint             start
256    
257    start = this.deep.top()
258    start as fstack
259    if !*this.initname 
260    {
261       start.find = 0
262       return &start.info
263    }
264    ( temp = this.initname ).fdelslash()
265    
266    if this.flag & $FIND_RECURSE
267    {
268       temp.fgetdir( temp )
269       temp.faddname( "*" )
270    }
271    start.find = FindFirstFile( temp.ptr(), wfd )
272    if start.find == $INVALID_HANDLE_VALUE 
273    {
274       start.find = 0
275       return &start.info
276    }
277    start.path.fgetdir( temp )
278    return &this.found( wfd )
279 }
280 
281 method  uint  ffind.eof( fordata fd )
282 {
283    return !this.deep.top()->fstack.find
284 }
285 
286 /*-----------------------------------------------------------------------------
287 * Id: getfileinfo F
288 *
289 * Summary: Get information about a file or directory.  
290 *  
291 * Params: name - The name of a file or directory. 
292           fi - The structure #a(tfinfo) all the information will be written to. 
293 * 
294 * Return: It returns 1 if the file is found, it returns 0 otherwise.
295 *
296 -----------------------------------------------------------------------------*/
297 
298 func uint getfileinfo( str name, finfo fi )
299 {
300    ffind fd
301    
302    fd.init( name, $FIND_DIR | $FIND_FILE )
303    foreach finfo cur, fd
304    {
305       fi = cur            
306       return 1
307    }
308    
309    return 0
310 }
311 
312 /*-----------------------------------------------------------------------------
313 ** Id: delfiles F
314 *
315 * Summary: Deleting files and directories by mask. Directories are deleted
316            together with all files and subdirectories. Be really careful while
317            using this function. For example, calling
318             
319 |#srcg[delfiles( "c:\\temp", $FIND_DIR | $FIND_FILE | $FIND_RECURSE )]
320 
321            will delete all files and directories named temp on the disk N:
322            including a search in all directories. In this case temp is
323            considered a mask and since the flag $FIND_RECURSE is specified, the
324            entire disk C: will be searched. If you just need to delete the
325            directory temp with all its subdirectories and files, you should 
326            call 
327 
328 |#srcg[delfiles("c:\\temp", $FIND_DIR )]
329            Calling
330 
331 |#srcg[delfiles( "c:\\temp\\*.tmp", $FIND_FILE )]
332             will delete all files in the directory tmp leaving subdirectories. 
333 *  
334 * Params: name - The name of mask for searching. 
335           flag - Search and delete flags.$$[findflags]$$[fdelflags] 
336 * 
337 -----------------------------------------------------------------------------*/
338 
339 func  delfiles( str name, uint flag )
340 {
341    ffind fd
342    
343    fd.init( name, flag )
344    
345    foreach finfo cur, fd
346    {
347       if cur.attrib & $FILE_ATTRIBUTE_DIRECTORY
348       {
349          delfiles( cur.fullname + "\\*.*" , flag | $FIND_FILE )
350          deletedir( cur.fullname )       
351       }
352       else
353       {
354          if flag & $DELF_RO && cur.attrib & $FILE_ATTRIBUTE_READONLY
355          {
356             setattribnormal( cur.fullname )
357          }
358          deletefile( cur.fullname )
359       }   
360    }
361 }
362 
363 
Редактировать