## dir.pkg
## Author: Matthias Blume (blume@cs.princeton.edu)
# Compiled by:
#
src/lib/std/standard.lib# Compare to:
#
src/lib/src/dir-tree.pkgstipulate
package lms = list_mergesort; # list_mergesort is from
src/lib/src/list-mergesort.pkg package psx = posixlib; # posixlib is from
src/lib/std/src/psx/posixlib.pkgherein
package dir
: Dir # Dir is from
src/lib/src/dir.api {
fun is_file filename
=
psx::stat::is_file
(psx::stat filename)
except
_ = FALSE;
fun is_directory name
=
psx::stat::is_directory
(psx::stat name)
except
_ = FALSE;
exists = is_directory;
fun is_something name
=
{ (psx::stat name);
TRUE; # Something exists by that name.
}
except
_ = FALSE;
fun is_dot_initial name
=
string::get_byte_as_char (name, 0) == '.';
# Return an alphabetically sorted list of directory entries,
# e.g. [ "bar", "foo", "zot" ], skipping "." and "..",
# returning those satisfying 'is_foo':
#
fun foo_names { directory_name: String,
is_foo: String -> Bool, # This will be either is_file or is_directory.
allow_dot_initial_names: Bool
}
=
file_list
where
#
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
#
THE name =>
#
# Ignore everything but vanilla files:
#
if (name == ".") loop results;
elif (name == "..") loop results;
elif (not allow_dot_initial_names and is_dot_initial name) loop results;
elif (is_foo (directory_name + "/" + name)) loop (name ! results);
else loop results;
fi;
esac;
end;
};
#
#
end;
# Return an alphabetically sorted list of files in directory,
# e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
#
fun file_names (directory_name: String)
=
foo_names { directory_name, is_foo => is_file, allow_dot_initial_names => FALSE };
# Return an alphabetically sorted list of subdirectories in directory,
# e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
#
fun directory_names (directory_name: String)
=
foo_names { directory_name, is_foo => is_directory, allow_dot_initial_names => FALSE };
# Return an alphabetically sorted list of files in directory,
# e.g. [ "bar", "foo", "zot" ], including those starting with a dot:
#
fun file_names' (directory_name: String)
=
foo_names { directory_name, is_foo => is_file, allow_dot_initial_names => TRUE };
# Return an alphabetically sorted list of subdirectories in directory,
# e.g. [ "bar", "foo", "zot" ], skipping only "." and "..":
#
fun directory_names' (directory_name: String)
=
foo_names { directory_name, is_foo => is_directory, allow_dot_initial_names => TRUE };
# Return an alphabetically sorted list of directory entries,
# e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
#
fun entry_names (directory_name: String)
=
{
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
#
THE filename =>
#
# Ignore names starting with a dot:
#
if (string::length_in_bytes filename > 0
and string::get_byte_as_char (filename, 0) == '.')
#
loop results;
else
loop (filename ! results);
fi;
esac;
end;
};
file_list;
};
# Return an alphabetically sorted list of directory entries,
# e.g. [ ".bashrc", "bar", "foo", "zot" ], skipping "." and "..":
#
fun entry_names' (directory_name: String)
=
{
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
#
THE filename =>
#
# Ignore "." and "..":
#
if (filename == "."
or filename == "..")
#
loop results;
else
loop (filename ! results);
fi;
esac;
end;
};
file_list;
};
# Return an alphabetically sorted list of directory entries,
# e.g. [ ".", ".." ".bashrc", "bar", "foo", "zot" ], including "." and "..":
#
fun entry_names'' (directory_name: String)
=
{
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
THE filename => loop (filename ! results);
esac;
end;
};
file_list;
};
# Same as foo_names, but returning absolute paths ("/foo/bar/zot"):
#
fun foos arg
=
{ cwd = winix__premicrothread::file::current_directory (); # Get current directory, so we can return full pathnames.
#
result = foo_names arg;
map' result (\\ name = cwd + "/" + name);
};
# Return an alphabetically sorted list of files in directory
# e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], skipping those starting with a dot:
#
fun files (directory_name: String)
=
foos { directory_name, is_foo => is_file, allow_dot_initial_names => FALSE };
# Return an alphabetically sorted list of directories in directory
# e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], skipping those starting with a dot:
#
fun directories (directory_name: String)
=
foos { directory_name, is_foo => is_directory, allow_dot_initial_names => FALSE };
# Return an alphabetically sorted list of files in directory
# e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], allowing dot-initial names:
#
fun files' (directory_name: String)
=
foos { directory_name, is_foo => is_file, allow_dot_initial_names => TRUE };
# Return an alphabetically sorted list of directories in directory
# e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], allowing dot-initial names other than "." and ".."
#
fun directories' (directory_name: String)
=
foos { directory_name, is_foo => is_directory, allow_dot_initial_names => TRUE };
# Return an alphabetically sorted list of directory entries,
# e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
#
fun entries (directory_name: String)
=
{
# Get current directory, so we can
# print out full pathnames:
cwd = winix__premicrothread::file::current_directory ();
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
#
THE filename =>
#
# Ignore names starting with a dot:
#
if (string::length_in_bytes filename > 0
and string::get_byte_as_char (filename, 0) == '.')
#
loop results;
else
loop (cwd + "/" + filename ! results);
fi;
esac;
end;
};
file_list;
};
# Return an alphabetically sorted list of directory entries,
# e.g. [ ".bashrc", "bar", "foo", "zot" ], skipping "." and "..":
#
fun entries' (directory_name: String)
=
{
# Get current directory, so we can
# print out full pathnames:
cwd = winix__premicrothread::file::current_directory ();
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
#
THE filename =>
#
# Ignore "." and "..":
#
if (filename == "."
or filename == "..")
#
loop results;
else
loop (cwd + "/" + filename ! results);
fi;
esac;
end;
};
file_list;
};
# Return an alphabetically sorted list of directory entries,
# e.g. [ ".", ".." ".bashrc", "bar", "foo", "zot" ], including "." and "..":
#
fun entries'' (directory_name: String)
=
{
# Get current directory, so we can
# print out full pathnames:
cwd = winix__premicrothread::file::current_directory ();
# Collect everything in directory
# as a list of strings:
#
file_list
=
safely::do
{
open_it => {. psx::open_directory_stream directory_name; },
close_it => psx::close_directory_stream,
cleanup => \\ _ = ()
}
{. loop []
where
fun loop results
=
case (psx::read_directory_entry #directory_stream)
#
NULL => lms::sort_list string::(>) results;
THE filename => loop (cwd + "/" + filename ! results);
esac;
end;
};
file_list;
};
# # 'root_directory' (usually build7.seed-libraries)
# # is the directory containing our seed-library
# # freezefiles. In general it will contain one
# # subdirectory for each independent package it
# # contains. (In practice, we have now reduced
# # that to one subdirectory named ROOT.)
# #
# # We now set up the anchor dictionary with
# # one anchor per subdirectory, the anchor
# # name being the subdirectory name.
# #
# print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'/AAA: root_directory = " + root_directory + " cwd= " + (psx::current_directory()) + "\n");
# {
# # Read the boot-directory directory-stream,
# # consing up a list of all its contents:
# #
# fun list_dir directory_stream
# =
#
# # Collect everything in boot_dir
# # as a list of strings:
# #
# file_list
# =
# safely::do
# {
# open_it => {. psx::open_directory_stream root_directory; },
# close_it => psx::close_directory_stream,
# cleanup => \\ _ = ()
# }
# loop []
# where
# fun loop l
# =
# case (psx::read_directory_entry directory_stream)
# NULL => l;
### THE x => loop (x ! l);
# THE x =>
# { print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'/loop: found " + root_directory + " entry " + x + "\n");
# loop (x ! l);
# };
# esac;
# end;
#
# fun is_directory x
# =
# psx::is_directory x
# except
# _ = FALSE;
#
#
# # Filter the contents of boot_dir,
# # ignoring everything but subdirectories:
# #
# fun sub_dir x
# =
# { d = p::cat (root_directory, x);
#
# if is_directory d
# then THE (x, d);
# else NULL; fi;
# };
#
# # Generate a list of (directory_name, directory_path)
# # pairs, which we shall momentarily treat as a list of
# # (anchor, definition) pairs:
# #
# pair_list
# =
# list::map_partial_fn
# sub_dir
# file_list;
#
# print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries': pair_list #1s = " + (string::join " " (map #1 pair_list)) + "\n");
# print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries': pair_list #2s = " + (string::join " " (map #2 pair_list)) + "\n");
# fun set_anchor (anchor, definition)
# =
# { print ("src/app/makelib/main/makelib-g.pkg/II: calling ad::set_anchor to set " + anchor + " to " + definition + "\n");
# print ("src/app/makelib/stuff/makelib-g.pkg: cwd = " + (psx::current_directory()) + "\n");
# ad::set_anchor (anchor_dictionary, anchor, THE definition);
# };
#
# apply set_anchor pair_list;
# };
};
end;
## Copyright (c) 1999, 2000 by Lucent Bell Laboratories
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.