ADDED: file_modification_time/2, obtaining a time stamp.

This addresses a remaining aspect of #511.
This commit is contained in:
Markus Triska
2020-07-16 22:56:10 +02:00
parent 0f4667d942
commit 4f386b3e5e
3 changed files with 49 additions and 13 deletions

View File

@@ -179,6 +179,7 @@ pub enum SystemClauseType {
DeleteFile, DeleteFile,
WorkingDirectory, WorkingDirectory,
PathCanonical, PathCanonical,
FileModificationTime,
DeleteAttribute, DeleteAttribute,
DeleteHeadAttribute, DeleteHeadAttribute,
DynamicModuleResolution(usize), DynamicModuleResolution(usize),
@@ -347,6 +348,7 @@ impl SystemClauseType {
&SystemClauseType::DeleteFile => clause_name!("$delete_file"), &SystemClauseType::DeleteFile => clause_name!("$delete_file"),
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"), &SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"), &SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
&SystemClauseType::FileModificationTime => clause_name!("$file_modification_time"),
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"), &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"), &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => { &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
@@ -684,6 +686,7 @@ impl SystemClauseType {
("$delete_file", 1) => Some(SystemClauseType::DeleteFile), ("$delete_file", 1) => Some(SystemClauseType::DeleteFile),
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory), ("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical), ("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
("$file_modification_time", 2) => Some(SystemClauseType::FileModificationTime),
("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), ("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
("$use_module_from_file", 1) => ("$use_module_from_file", 1) =>
Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)), Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)),

View File

@@ -53,10 +53,12 @@
delete_file/1, delete_file/1,
make_directory/1, make_directory/1,
working_directory/2, working_directory/2,
path_canonical/2]). path_canonical/2,
file_modification_time/2]).
:- use_module(library(error)). :- use_module(library(error)).
:- use_module(library(lists)). :- use_module(library(lists)).
:- use_module(library(charsio)).
list_of_chars(Cs) :- list_of_chars(Cs) :-
must_be(list, Cs), must_be(list, Cs),
@@ -119,3 +121,12 @@ path_canonical(Ps, Cs) :-
maplist(must_be(character), Ps), maplist(must_be(character), Ps),
can_be(list, Cs), can_be(list, Cs),
'$path_canonical'(Ps, Cs). '$path_canonical'(Ps, Cs).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
T is the modification time of File.
T is a time stamp, suitable for use in format_time//2 in library(time).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
file_modification_time(File, T) :-
'$file_modification_time'(File, T0),
read_term_from_chars(T0, T).

View File

@@ -943,6 +943,22 @@ impl MachineState {
} }
} }
} }
&SystemClauseType::FileModificationTime => {
let file = self.heap_pstr_iter(self[temp_v!(1)]).to_string();
if let Ok(md) = fs::metadata(file) {
if let Ok(time) = md.modified() {
let chars = self.systemtime_to_timestamp(time);
self.unify(self[temp_v!(2)], chars);
} else {
self.fail = true;
return Ok(());
}
} else {
self.fail = true;
return Ok(());
}
}
&SystemClauseType::AtEndOfExpansion => { &SystemClauseType::AtEndOfExpansion => {
if self.cp == LocalCodePtr::TopLevel(0, 0) { if self.cp == LocalCodePtr::TopLevel(0, 0) {
self.at_end_of_expansion = true; self.at_end_of_expansion = true;
@@ -3227,18 +3243,7 @@ impl MachineState {
self.unify(a1, addr); self.unify(a1, addr);
} }
&SystemClauseType::CurrentTime => { &SystemClauseType::CurrentTime => {
let system_time = SystemTime::now(); let str = self.systemtime_to_timestamp(SystemTime::now());
let datetime: DateTime<Local> = system_time.into();
let mut fstr = "[".to_string();
let specifiers = vec!["d","m","Y","y","H","M","S","b","B","a","A","w","u","U","W","j","D","x","v"];
for spec in specifiers {
fstr.push_str(&format!("'{}'=\"%{}\", ", spec, spec).to_string());
}
fstr.push_str("finis].");
let str = { let s = datetime.format(&fstr).to_string();
self.heap.put_complete_string(&s)
};
self.unify(self[temp_v!(1)], str); self.unify(self[temp_v!(1)], str);
} }
&SystemClauseType::OpDeclaration => { &SystemClauseType::OpDeclaration => {
@@ -5718,6 +5723,23 @@ impl MachineState {
return_from_clause!(self.last_call, self) return_from_clause!(self.last_call, self)
} }
pub(super)
fn systemtime_to_timestamp(
&mut self,
system_time: SystemTime
) -> Addr {
let datetime: DateTime<Local> = system_time.into();
let mut fstr = "[".to_string();
let specifiers = vec!["d","m","Y","y","H","M","S","b","B","a","A","w","u","U","W","j","D","x","v"];
for spec in specifiers {
fstr.push_str(&format!("'{}'=\"%{}\", ", spec, spec).to_string());
}
fstr.push_str("finis].");
let s = datetime.format(&fstr).to_string();
self.heap.put_complete_string(&s)
}
pub(super) pub(super)
fn string_encoding_bytes( fn string_encoding_bytes(
&mut self, &mut self,