1
1
s-lang/slsh/lib/fswalk.sl

93 строки
2.4 KiB
Plaintext

% Functions to walk the file system
% Copyright (C) 2012-2017,2018 John E. Davis
%
% This file is part of the S-Lang Library and may be distributed under the
% terms of the GNU General Public License. See the file COPYING for
% more information.
private define process_dir (w, dir, dir_st);
private define process_dir (w, dir, dir_st)
{
variable status;
if (w.dir_method != NULL)
{
status = (@w.dir_method) (dir, dir_st, __push_list (w.dir_method_args));
if (status <= 0)
return status;
}
foreach (listdir (dir))
{
variable file = ();
file = path_concat (dir, file);
variable st = (@w.stat_func)(file);
if (st == NULL)
{
() = fprintf (stderr, "Unable to stat %s: %s\n", file, errno_string (errno));
continue;
}
if (stat_is ("dir", st.st_mode))
{
status = process_dir (w, file, dir_st);
if (status < 0)
return status;
continue;
}
if (w.file_method == NULL)
continue;
status = (@w.file_method) (file, st, __push_list(w.file_method_args));
if (status <= 0)
return status;
}
return 1;
}
private define fswalk (w, start)
{
variable st = (@w.stat_func)(start);
ifnot (stat_is ("dir", st.st_mode))
{
throw InvalidParmError, "fs_walk: $start is not a directory"$;
}
() = process_dir (w, start, st);
}
define fswalk_new ()
{
if (_NARGS != 2)
usage ("\
w = fswalk_new (dirfunc, filefunc [; qualifiers]);\n\
w.walk (topdir);\n\
\n\
Qualifiers:\n\
dargs={args,...} Additional arguments to be passed to dirfunc\n\
fargs={args,...} Additional arguments to be passed to dirfunc\n\
followlinks[=0|1] Indicates whethe or not symbolic links will be followed\n\
");
variable dir_method, file_method;
(dir_method, file_method) = ();
variable dir_method_args = qualifier ("dargs", {});
variable file_method_args = qualifier ("fargs", {});
if (typeof (dir_method_args) != List_Type)
dir_method_args = {dir_method_args};
if (typeof (file_method_args) != List_Type)
file_method_args = {file_method_args};
variable followlinks
= (qualifier_exists ("followlinks") && (0 != qualifier ("followlinks")));
variable w = struct
{
walk = &fswalk,
file_method = file_method,
file_method_args = file_method_args,
dir_method = dir_method,
dir_method_args = dir_method_args,
stat_func = (followlinks ? &stat_file : &lstat_file),
};
return w;
}