From c6aa2068e2068ec68673b9b91dc7b68445c48365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Arroyo=20Calle?= Date: Fri, 9 Dec 2022 23:46:00 +0100 Subject: [PATCH 1/2] Add predicate copy_file/2 in library(files) --- build/instructions_template.rs | 4 ++++ src/lib/files.pl | 10 ++++++++-- src/machine/dispatch.rs | 8 ++++++++ src/machine/system_calls.rs | 13 +++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/build/instructions_template.rs b/build/instructions_template.rs index bc1ca703..f8cce3f4 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -262,6 +262,8 @@ enum SystemClauseType { DeleteFile, #[strum_discriminants(strum(props(Arity = "2", Name = "$rename_file")))] RenameFile, + #[strum_discriminants(strum(props(Arity = "2", Name = "$copy_file")))] + CopyFile, #[strum_discriminants(strum(props(Arity = "2", Name = "$working_directory")))] WorkingDirectory, #[strum_discriminants(strum(props(Arity = "1", Name = "$delete_directory")))] @@ -1611,6 +1613,7 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallMakeDirectoryPath(_) | &Instruction::CallDeleteFile(_) | &Instruction::CallRenameFile(_) | + &Instruction::CallCopyFile(_) | &Instruction::CallWorkingDirectory(_) | &Instruction::CallDeleteDirectory(_) | &Instruction::CallPathCanonical(_) | @@ -1825,6 +1828,7 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteMakeDirectoryPath(_) | &Instruction::ExecuteDeleteFile(_) | &Instruction::ExecuteRenameFile(_) | + &Instruction::ExecuteCopyFile(_) | &Instruction::ExecuteWorkingDirectory(_) | &Instruction::ExecuteDeleteDirectory(_) | &Instruction::ExecutePathCanonical(_) | diff --git a/src/lib/files.pl b/src/lib/files.pl index 1e856ff1..7d0afeda 100644 --- a/src/lib/files.pl +++ b/src/lib/files.pl @@ -70,8 +70,9 @@ In this library, directories and files are represented as file_exists/1, directory_exists/1, delete_file/1, - rename_file/2, - delete_directory/1, + rename_file/2, + copy_file/2, + delete_directory/1, make_directory/1, make_directory_path/1, working_directory/2, @@ -150,6 +151,11 @@ rename_file(File, Renamed) :- must_be(chars, Renamed), '$rename_file'(File, Renamed). +copy_file(File, Copied) :- + file_must_exist(File, copy_file/2), + must_be(chars, Copied), + '$copy_file'(File, Copied). + %% delete_directory(+Directory). % % Succeeds if Directory is deleted from the current system. diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index ee57a83e..1cc1d365 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -3533,6 +3533,14 @@ impl Machine { self.rename_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } + &Instruction::CallCopyFile(_) => { + self.copy_file(); + step_or_fail!(self, self.machine_st.p += 1); + } + &Instruction::ExecuteCopyFile(_) => { + self.copy_file(); + step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + } &Instruction::CallWorkingDirectory(_) => { try_or_throw!(self.machine_st, self.working_directory()); step_or_fail!(self, self.machine_st.p += 1); diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 275c0ce7..515baba6 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -1653,6 +1653,19 @@ impl Machine { self.machine_st.fail = true; } + #[inline(always)] + pub(crate) fn copy_file(&mut self) { + if let Some(file) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) { + if let Some(copied) = self.machine_st.value_to_str_like(self.machine_st.registers[2]) { + if fs::copy(file.as_str(), copied.as_str()).is_ok() { + return; + } + } + } + + self.machine_st.fail = true; + } + #[inline(always)] pub(crate) fn delete_directory(&mut self) { if let Some(dir) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) { From 5f703afed11a2c8c191a7a06f19dc8be568606bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Arroyo=20Calle?= Date: Sun, 11 Dec 2022 00:08:41 +0100 Subject: [PATCH 2/2] Rename copy_file/2 to file_copy/2 --- build/instructions_template.rs | 8 ++++---- src/lib/files.pl | 11 +++++++---- src/machine/dispatch.rs | 8 ++++---- src/machine/system_calls.rs | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/build/instructions_template.rs b/build/instructions_template.rs index f8cce3f4..ade61a9c 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -262,8 +262,8 @@ enum SystemClauseType { DeleteFile, #[strum_discriminants(strum(props(Arity = "2", Name = "$rename_file")))] RenameFile, - #[strum_discriminants(strum(props(Arity = "2", Name = "$copy_file")))] - CopyFile, + #[strum_discriminants(strum(props(Arity = "2", Name = "$file_copy")))] + FileCopy, #[strum_discriminants(strum(props(Arity = "2", Name = "$working_directory")))] WorkingDirectory, #[strum_discriminants(strum(props(Arity = "1", Name = "$delete_directory")))] @@ -1613,7 +1613,7 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallMakeDirectoryPath(_) | &Instruction::CallDeleteFile(_) | &Instruction::CallRenameFile(_) | - &Instruction::CallCopyFile(_) | + &Instruction::CallFileCopy(_) | &Instruction::CallWorkingDirectory(_) | &Instruction::CallDeleteDirectory(_) | &Instruction::CallPathCanonical(_) | @@ -1828,7 +1828,7 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::ExecuteMakeDirectoryPath(_) | &Instruction::ExecuteDeleteFile(_) | &Instruction::ExecuteRenameFile(_) | - &Instruction::ExecuteCopyFile(_) | + &Instruction::ExecuteFileCopy(_) | &Instruction::ExecuteWorkingDirectory(_) | &Instruction::ExecuteDeleteDirectory(_) | &Instruction::ExecutePathCanonical(_) | diff --git a/src/lib/files.pl b/src/lib/files.pl index 7d0afeda..e920b5bd 100644 --- a/src/lib/files.pl +++ b/src/lib/files.pl @@ -71,7 +71,7 @@ In this library, directories and files are represented as directory_exists/1, delete_file/1, rename_file/2, - copy_file/2, + file_copy/2, delete_directory/1, make_directory/1, make_directory_path/1, @@ -151,10 +151,13 @@ rename_file(File, Renamed) :- must_be(chars, Renamed), '$rename_file'(File, Renamed). -copy_file(File, Copied) :- - file_must_exist(File, copy_file/2), +%% file_copy(+File, +Copied). +% +% Succeeds if File is copied to Copied +file_copy(File, Copied) :- + file_must_exist(File, file_copy/2), must_be(chars, Copied), - '$copy_file'(File, Copied). + '$file_copy'(File, Copied). %% delete_directory(+Directory). % diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 1cc1d365..a93d9e22 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -3533,12 +3533,12 @@ impl Machine { self.rename_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCopyFile(_) => { - self.copy_file(); + &Instruction::CallFileCopy(_) => { + self.file_copy(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCopyFile(_) => { - self.copy_file(); + &Instruction::ExecuteFileCopy(_) => { + self.file_copy(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } &Instruction::CallWorkingDirectory(_) => { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 515baba6..f72cbf8a 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -1654,7 +1654,7 @@ impl Machine { } #[inline(always)] - pub(crate) fn copy_file(&mut self) { + pub(crate) fn file_copy(&mut self) { if let Some(file) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) { if let Some(copied) = self.machine_st.value_to_str_like(self.machine_st.registers[2]) { if fs::copy(file.as_str(), copied.as_str()).is_ok() {