From: Adrián Arroyo Calle Date: Thu, 8 Dec 2022 22:41:28 +0000 (+0100) Subject: Compatible Doclog docs for library(files) X-Git-Tag: v0.9.2~254^2 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=21d6220f3ff61cf8e4fcbf18ce06e02d0d12b99f;p=scryer-prolog.git Compatible Doclog docs for library(files) --- diff --git a/src/lib/files.pl b/src/lib/files.pl index ef73e851..1e856ff1 100644 --- a/src/lib/files.pl +++ b/src/lib/files.pl @@ -1,3 +1,22 @@ +/** Predicates for reasoning about files and directories. + +In this library, directories and files are represented as +*lists of characters*. This is an ideal representation: + +* Lists of characters can be conveniently reasoned about with DCGs + and built-in Prolog predicates from library(lists). This alone + is already a very compelling argument to use them. +* Other Scryer libraries such as library(http/http_open) also already + use lists of characters to represent paths. +* File names are mostly ephemeral, so it is good for efficiency + that they can quickly allocated transiently on the heap, leaving the + atom table mostly unaffected. Indexing is almost never needed + for file names. If needed, it should be added to the engine. +* The previous point is also good for security, since the system + leaves little trace of which files were even accessed. +* Scryer Prolog represents lists of characters extremely compactly. +*/ + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written 2020, 2022 by Markus Triska (triska@metalevel.at) Part of Scryer Prolog. @@ -67,41 +86,74 @@ :- use_module(library(charsio)). :- use_module(library(dcgs)). +%% directory_files(+Directory, -Files). +% +% Returns the list of files *and* directories available at a specific +% directory in the current system. + directory_files(Directory, Files) :- must_be(chars, Directory), can_be(list, Files), '$directory_files'(Directory, Files). +%% file_size(+File, -Size). +% +% Returns the size (in bytes) of a file. The file must exist. + file_size(File, Size) :- file_must_exist(File, file_size/2), can_be(integer, Size), '$file_size'(File, Size). +%% file_exists(+File). +% +% Succeeds if File is a file that exists in the current system. file_exists(File) :- must_be(chars, File), '$file_exists'(File). +%% directory_exists(+Directory). +% +% Succeeds if Directory is a directory that exists in the current system. directory_exists(Directory) :- must_be(chars, Directory), '$directory_exists'(Directory). +%% make_directory(+Directory). +% +% Succeeds if it creates a new directory named Directory in the current system. +% If you want to create a nested directory, use make\_directory\_path/1. make_directory(Directory) :- must_be(chars, Directory), '$make_directory'(Directory). +%% make_directory_path(+Directory). +% +% Similar to make\_directory/1 but recursively creates directories if they're missing. +% Equivalent to mkdir -p in Unix. make_directory_path(Directory) :- must_be(chars, Directory), '$make_directory_path'(Directory). +%% delete_file(+File). +% +% Succeeds if deletes File from the current system. delete_file(File) :- file_must_exist(File, delete_file/1), '$delete_file'(File). +%% rename_file(+File, +Renamed). +% +% Succeeds if File is renamed to Renamed rename_file(File, Renamed) :- file_must_exist(File, rename_file/2), must_be(chars, Renamed), '$rename_file'(File, Renamed). +%% delete_directory(+Directory). +% +% Succeeds if Directory is deleted from the current system. +% Directory must be empty. delete_directory(Directory) :- directory_must_exist(Directory, delete_directory/1), must_be(chars, Directory), @@ -117,31 +169,31 @@ directory_must_exist(Directory, Context) :- ; throw(error(existence_error(directory, Directory), Context)) ). -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dir0 is the current working directory, and the working directory - is changed to Dir. +%% workind_directory(Dir0, Dir). +% +% Dir0 is the current working directory, and the working directory +% is changed to Dir. - Use working_directory(Ds, Ds) to determine the current working directory, - and leave it as is. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +% Use `working\_directory(Ds, Ds)` to determine the current working directory, +% and leave it as is. working_directory(Dir0, Dir) :- can_be(list, Dir0), can_be(list, Dir), '$working_directory'(Dir0, Dir). -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True iff Cs is the canonical, absolute path of Ps. - - All intermediate components are normalized, and all symbolic links - are resolved. - - The predicate fails in the following situations, though not - necessarily *only* in these cases: - - 1. Ps is a path that does not exist. - 2. A non-final component in Ps is not a directory. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +%% path_canonical(Ps, Cs). +% +% True iff Cs is the canonical, absolute path of Ps. +% +% All intermediate components are normalized, and all symbolic links +% are resolved. +% +% The predicate fails in the following situations, though not +% necessarily *only* in these cases: +% +% 1. Ps is a path that does not exist. +% 2. A non-final component in Ps is not a directory. path_canonical(Ps, Cs) :- must_be(chars, Ps), @@ -155,12 +207,27 @@ path_canonical(Ps, Cs) :- For two time stamps A and B, if A precedes B, then A @< B holds. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +%% file_modification_time(+File, -T). +% +% For a file File that must exist, it returns a time stamp T with the modification time +% +% T is a time stamp compatible with library(time). file_modification_time(File, T) :- file_time_(File, modification, T). +%% file_access_time(+File, -T). +% +% For a file File that must exist, it returns a time stamp T with the access time +% +% T is a time stamp compatible with library(time). file_access_time(File, T) :- file_time_(File, access, T). +%% file_creation_time(+File, -T). +% +% For a file File that must exist, it returns a time stamp T with the creation time +% +% T is a time stamp compatible with library(time). file_creation_time(File, T) :- file_time_(File, creation, T). @@ -170,29 +237,27 @@ file_time_(File, Which, T) :- read_from_chars(T0, T). -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - path_segments(Ps, Segments): True iff Segments are the segments of Ps. - - Segments is the list of components of the path Ps that are - separated by the platform-specific directory separator. Each - segment is a list of characters. - - At least one of the arguments must be instantiated. - - Examples: - - ?- path_segments("/hello/there", Segments). - Segments = [[],"hello","there"]. - - ?- path_segments(Path, ["hello","there"]). - Path = "hello/there". - - - To obtain the platform-specific directory separator, you can use: - - ?- path_segments(Separator, ["",""]). - Separator = "/". -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +%% path_segments(Ps, Segments). +% +% True iff Segments are the segments of Ps. +% +% Segments is the list of components of the path Ps that are +% separated by the platform-specific directory separator. Each +% segment is a list of characters. +% +% At least one of the arguments must be instantiated. +% +% Examples: +% +% ?- path_segments("/hello/there", Segments). +% Segments = [[],"hello","there"]. +% ?- path_segments(Path, ["hello","there"]). +% Path = "hello/there". +% +% To obtain the platform-specific directory separator, you can use: +% +% ?- path_segments(Separator, ["",""]). +% Separator = "/". path_segments(Path, Segments) :- '$directory_separator'(Sep),