From 4f386b3e5e10b978196ea786a3e7cdbf73a41e1c Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Thu, 16 Jul 2020 22:56:10 +0200 Subject: [PATCH] ADDED: file_modification_time/2, obtaining a time stamp. This addresses a remaining aspect of #511. --- src/clause_types.rs | 3 +++ src/lib/files.pl | 13 ++++++++++- src/machine/system_calls.rs | 46 +++++++++++++++++++++++++++---------- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/clause_types.rs b/src/clause_types.rs index c4546623..97aac77a 100644 --- a/src/clause_types.rs +++ b/src/clause_types.rs @@ -179,6 +179,7 @@ pub enum SystemClauseType { DeleteFile, WorkingDirectory, PathCanonical, + FileModificationTime, DeleteAttribute, DeleteHeadAttribute, DynamicModuleResolution(usize), @@ -347,6 +348,7 @@ impl SystemClauseType { &SystemClauseType::DeleteFile => clause_name!("$delete_file"), &SystemClauseType::WorkingDirectory => clause_name!("$working_directory"), &SystemClauseType::PathCanonical => clause_name!("$path_canonical"), + &SystemClauseType::FileModificationTime => clause_name!("$file_modification_time"), &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"), &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"), &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => { @@ -684,6 +686,7 @@ impl SystemClauseType { ("$delete_file", 1) => Some(SystemClauseType::DeleteFile), ("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory), ("$path_canonical", 2) => Some(SystemClauseType::PathCanonical), + ("$file_modification_time", 2) => Some(SystemClauseType::FileModificationTime), ("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), ("$use_module_from_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)), diff --git a/src/lib/files.pl b/src/lib/files.pl index 69847b29..481ed08d 100644 --- a/src/lib/files.pl +++ b/src/lib/files.pl @@ -53,10 +53,12 @@ delete_file/1, make_directory/1, working_directory/2, - path_canonical/2]). + path_canonical/2, + file_modification_time/2]). :- use_module(library(error)). :- use_module(library(lists)). +:- use_module(library(charsio)). list_of_chars(Cs) :- must_be(list, Cs), @@ -119,3 +121,12 @@ path_canonical(Ps, Cs) :- maplist(must_be(character), Ps), can_be(list, 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). diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 2f357873..6c8ee329 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -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 => { if self.cp == LocalCodePtr::TopLevel(0, 0) { self.at_end_of_expansion = true; @@ -3227,18 +3243,7 @@ impl MachineState { self.unify(a1, addr); } &SystemClauseType::CurrentTime => { - let system_time = SystemTime::now(); - let datetime: DateTime = 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) - }; + let str = self.systemtime_to_timestamp(SystemTime::now()); self.unify(self[temp_v!(1)], str); } &SystemClauseType::OpDeclaration => { @@ -5718,6 +5723,23 @@ impl MachineState { return_from_clause!(self.last_call, self) } + pub(super) + fn systemtime_to_timestamp( + &mut self, + system_time: SystemTime + ) -> Addr { + let datetime: DateTime = 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) fn string_encoding_bytes( &mut self, -- 2.54.0