\        
\  

WINAPI: FindFirstFileA       KERNEL32.DLL
WINAPI: FindNextFileA        KERNEL32.DLL
WINAPI: FindClose            KERNEL32.DLL
WINAPI: SetCurrentDirectoryA KERNEL32.DLL

16 CONSTANT FILE_ATTRIBUTE_DIRECTORY

  0
  4 -- dwFileAttributes
  8 -- ftCreationTime
  8 -- ftLastAccessTime
  8 -- ftLastWriteTime
  4 -- nFileSizeHigh
  4 -- nFileSizeLow
  4 -- dwReserved0
  4 -- dwReserved1
256 -- cFileName          \ [ MAX_PATH ]
 14 -- cAlternateFileName \ [ 14 ]
CONSTANT /WIN32_FIND_DATA

: FIND-FILES ( addr u xt -- )
\ addr u -     
\ xt ( addr u -- ) -     
  >R OVER + 0 SWAP C!
  /WIN32_FIND_DATA ALLOCATE THROW >R
  R@ SWAP FindFirstFileA DUP -1 =
  IF DROP R> FREE DROP R> DROP EXIT THEN
  R@ cFileName ASCIIZ> R> ROT ROT R@ EXECUTE >R
  BEGIN
    R@ OVER FindNextFileA
  WHILE
    R@ cFileName ASCIIZ> R> ROT ROT R@ EXECUTE >R
  REPEAT
  FindClose DROP
  R> FREE DROP R> DROP
;
: FIND-FILES-RECURSE ( addr u xt -- )
\ addr u - 
\ xt ( addr u -- ) -     
  >R OVER + 0 SWAP C!
  /WIN32_FIND_DATA ALLOCATE THROW >R
  R@ SWAP FindFirstFileA DUP -1 =
  IF DROP R> FREE DROP R> DROP EXIT THEN
  R@ cFileName ASCIIZ> R> ROT ROT R@ EXECUTE >R
  BEGIN
    R@ OVER FindNextFileA
  WHILE
    R@ cFileName ASCIIZ> 2DUP S" ." COMPARE 0= >R
    S" .." COMPARE 0= R> OR
    IF ELSE
    R@  @ FILE_ATTRIBUTE_DIRECTORY AND FILE_ATTRIBUTE_DIRECTORY =
    IF R@ cFileName SetCurrentDirectoryA DROP
       R> S" *.*" R@ RECURSE >R
       S" .." DROP SetCurrentDirectoryA DROP
    ELSE R@ cFileName ASCIIZ> R> ROT ROT R@ EXECUTE >R THEN
    THEN
  REPEAT
  FindClose DROP
  R> FREE DROP R> DROP
;
: TT ." (" TYPE ." )" CR ;
: TEST S" *.*" ['] TT FIND-FILES-RECURSE ;
