File paths are collected
by the DIR_ENTRIES CALL routine. DIR_ENTRIES uses the following arguments:
-
-
-
an output parameter to fill with
the number of entries in the result array
-
an output parameter to set to 0
if all pathnames fit in the result array; or an output parameter to
set to 1 if some of the pathnames do not fit into the array
The body of DIR_ENTRIES
is almost identical to the code that is used to implement this functionality
in a DATA step; yet DIR_ENTRIES is a CALL routine that is easily reused
in several programs.
DIR_ENTRIES calls DIROPEN
to open a directory and retrieve a directory ID. The routine then
calls DNUM to retrieve the number of entries in the directory. For
each entry in the directory, DREAD is called to retrieve the name
of the entry. Now that the entry name is available, the routine calls
MOPEN to determine whether the entry is a file or a directory.
If the entry is a file,
then MOPEN returns a positive value. In this case, the full path to
the file is added to the result array. If the result array is full,
the truncation output argument is set to 1.
If the entry is a directory,
then MOPEN returns a value that is less than or equal to 0. In this
case, DIR_ENTRIES gathers the pathnames for the entries in this subdirectory.
It gathers the pathnames by recursively calling DIR_ENTRIES and passing
the subdirectory's path as the starting path. When DIR_ENTRIES
returns, the result array contains the paths of the subdirectory's
entries.
subroutine dir_entries(dir $, files[*] $, n, trunc);
outargs files, n, trunc;
length dir entry $ 256;
if trunc then return;
did = diropen(dir);
if did <= 0 then return;
dnum = dnum(did);
do i = 1 to dnum;
entry = dread(did, i);
/* If this entry is a file, then add to array */
/* Else entry is a directory, recurse. */
fid = mopen(did, entry);
entry = trim(dir) || '\' || entry;
if fid > 0 then do;
rc = fclose(fid);
if n < dim(files) then do;
trunc = 0;
n = n + 1;
files[n] = entry;
end;
else do;
trunc = 1;
call dirclose(did);
return;
end;
end;
else
call dir_entries(entry, files, n, trunc);
end;
call dirclose(did);
return;
endsub;