93 строки
2.4 KiB
Plaintext
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;
|
|
}
|