
read_directory(+Directory, +Pattern, -SubdirList, -FileList)

   Unifies SubdirList with a list of subdirectories and FileList with a list
of matching files in the specified directory.



Arguments
   Directory           Atom or String
   Pattern             Atom or String
   SubdirList          Free variable or (maybe partial) list of strings
   FileList            Free variable or (maybe partial) list of strings

Type
   Operating System

Description
   read_directory/4 scans the directory specified by Directory.  It
   collects the names of the subdirectories in SubdirList and the names of
   the files matching Pattern in FileList.  SubdirList and FileList are
   lists of strings.  Pattern is a string containing a filename
   specification similar to the usual UNIX convention.  The metacharacters
   recognised are:  * matches an arbitrary sequence of characters, ?
   matches any single character, [] matches one of the characters inside
   the brackets unless the first one is a ^ in which case it matches any
   character but those inside the brackets.


   Filenames beginning with a dot are not suppressed by default, but the
   directories "." and ".." are omitted from SubdirList.




Modes and Determinism
   read_directory(+, +, -, -) is det

Exceptions
     4 --- Directory or Pattern is not instantiated.
     5 --- Directory or Pattern is neither atom nor string.
     5 --- SubdirList or FileList are instantiated, but not to lists.
   170 --- An error occurred trying to access Directory.

Examples
   
   Success:
   [eclipse]: read_directory("/usr/john", "*", Dirlist, Filelist).
   Dirlist = ["subdir1", "subdir2"]
   Filelist = ["one.c", "two.c", "three.pl", "four.pl"]
   yes.
   [eclipse]: read_directory(., "[^t]*.pl", Dirlist, Filelist).
   Dirlist = ["subdir1", "subdir2"]
   Filelist = ["four.pl"]
   yes.
   Fail:
   [eclipse]: read_directory(".", "*.c", _, ["one.c"]).
   no.
   Error:
   read_directory(_, "*", Dirs, Files).          (error 4)
   read_directory([46], "*", Dirs, Files).       (error 5)
   read_directory(".", _, Dirs, Files).          (error 4)
   read_directory(".", 3, Dirs, Files).          (error 5)
   read_directory(".", "*.pl", Dirs, file).      (error 5)
   read_directory("/private", "*", _, Files).    (error 170)


    % EXAMPLE: find_tree(+Root, +Pattern, -ListOfRelativeFiles)
    % Recursively find all files matching Pattern below the directory
    % or list of directories Roots.

    find_tree(Root, Pattern, AllFiles) :- (atom(Root);string(Root)), !,
	    find_dir(Root, "", "", Pattern, AllFiles, []).
    find_tree(Roots, Pattern, AllFiles) :-
	    find_tree(Roots, Pattern, AllFiles, []).

    find_tree([], _Pattern, AllFiles, AllFiles).
    find_tree([Root|Roots], Pattern, AllFiles, AllFiles0) :-
	    find_dir(Root, "", "", Pattern, AllFiles, AllFiles1),
	    find_tree(Roots, Pattern, AllFiles1, AllFiles0).

    find_dir(_, _, [], _, AllFiles, AllFiles) :- !.
    find_dir(Root, RelPath, [Dir|Dirs], Pattern, AllFiles, AllFiles0) :- !,
	    find_dir(Root, RelPath, Dir, Pattern, AllFiles, AllFiles1),
	    find_dir(Root, RelPath, Dirs, Pattern, AllFiles1, AllFiles0).
    find_dir(Root, RelPath, Dir, Pattern, AllFiles, AllFiles0) :-
	    ( RelPath=="" -> RelDir=Dir
	    ; concat_string([RelPath,/,Dir], RelDir) ),
	    ( RelDir=="" -> AbsDir=Root
	    ; concat_string([Root,/,RelDir], AbsDir) ),
	    read_directory(AbsDir, Pattern, SubDirs, Files),
	    find_files(Root, RelDir, Files, AllFiles, AllFiles1),
	    find_dir(Root, RelDir, SubDirs, Pattern, AllFiles1, AllFiles0).

    find_files(_, _, [], AbsFiles, AbsFiles).
    find_files(Root, RelDir, [File|Files], [AbsFile|AbsFiles], AbsFiles0) :-
	    ( RelDir=="" -> concat_string([Root,/,File], AbsFile)
	    ; concat_string([Root,/,RelDir,/,File], AbsFile) ),
	    find_files(Root, RelDir, Files, AbsFiles, AbsFiles0).


See Also
   cd / 1, getcwd / 1, get_flag / 2, pathname / 4, existing_file / 4, exists / 1, mkdir / 1
