Modula-2 home

  Home  
  Tutorial  
  Win32 API  
  Reference  
  Projects  
  Source code  
  Links  
Shows printer-friendly 
version in new window  

 

Recursively walk through a directory tree

For Stony Brook Modula-2

By Frank Schoonjans (frank.schoonjans@ugent.be)

 

The folllowing example illustrates how we can recursively walk through a directory tree.

Our main procedure DoDirWalk takes a procedure (of type HandleFileProcedure) as its last parameter. The latter procedure will do something of interest with all files found. In our example, we only list path, file and file size.

MODULE dirwalk;

(* illustrates how to walk through a directory tree recursively
   For Stony Brook M2
   Frank Schoonjans 2004 *)

FROM SYSTEM    IMPORT FUNC;

IMPORT Conversions,FileFunc,Strings,Terminal;

TYPE
     HandleFileProcedure    = PROCEDURE(ARRAY OF CHAR, ARRAY OF CHAR, CARDINAL);

(* ******************************************************************************* *)

PROCEDURE HandleFile(path,file : ARRAY OF CHAR; filesize : CARDINAL);
VAR str : ARRAY [0..63] OF CHAR;
BEGIN
    Terminal.WriteString(path);
    Terminal.WriteString(file);
    Terminal.WriteString("   [");
    FUNC Conversions.CardToStr(filesize,str);
    Terminal.WriteString(str);
    Terminal.WriteString("]");
    Terminal.WriteLn;
END HandleFile;

(* ******************************************************************************* *)

PROCEDURE DoDirWalk(Path,mask : ARRAY OF CHAR; dosubdirs: BOOLEAN;
                    doproc: HandleFileProcedure);

    PROCEDURE DoSubDirWalk(path,subdir : ARRAY OF CHAR);
    VAR entry      : FileFunc.SearchEntry;
        searchname : FileFunc.FileSpecString;
    BEGIN
        Strings.Append(subdir,path);
        IF subdir[0]#00C THEN
           Strings.Append(FileFunc.PathSepChar,path);
        END;
        Strings.Concat(path,mask,searchname);
        IF FileFunc.FindFirst(searchname,FileFunc.StdAttributes,
                              FileFunc.FileAttributeSet{FileFunc.NormalFile},entry)
        THEN
           REPEAT
                doproc(path,entry.name,entry.size);
           UNTIL NOT FileFunc.FindNext(entry);
           FileFunc.FindClose(entry);
        END;
        IF dosubdirs
        THEN Strings.Concat(path,"*",searchname);
             IF FileFunc.FindFirst(searchname,FileFunc.StdAttributes,
                                   FileFunc.FileAttributeSet{FileFunc.Directory},entry)
             THEN
                REPEAT
                     IF entry.name[0]#"." THEN
                        DoSubDirWalk(path,entry.name);
                     END;
                UNTIL NOT FileFunc.FindNext(entry);
                FileFunc.FindClose(entry);
             END;
        END;
    END DoSubDirWalk;

VAR
    mpath : FileFunc.FileSpecString;
BEGIN
    Strings.Assign(Path,mpath); (* provide enough storage space for path *)
    DoSubDirWalk(mpath,"");
END DoDirWalk;


BEGIN
    DoDirWalk("C:\temp\","*.*",TRUE,HandleFile);
    Terminal.WriteString("Press any key to continue ... ");
    FUNC Terminal.ReadChar();
END dirwalk.