]> Repositorios git - scryer-prolog.git/commitdiff
Add predicate copy_file/2 in library(files)
authorAdrián Arroyo Calle <[email protected]>
Fri, 9 Dec 2022 22:46:00 +0000 (23:46 +0100)
committerAdrián Arroyo Calle <[email protected]>
Sat, 10 Dec 2022 23:06:56 +0000 (00:06 +0100)
build/instructions_template.rs
src/lib/files.pl
src/machine/dispatch.rs
src/machine/system_calls.rs

index bc1ca7030b4f3dc5d4a5ea1307f3f2c88d0a89ef..f8cce3f43ca64b3a637e65d84efd5becbfdf8dfe 100644 (file)
@@ -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(_) |
index 1e856ff1ce2a38b25513a05d7084508a7a945d2d..7d0afeda067b994a86c4c5cc7f91be793820f036 100644 (file)
@@ -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.
index ee57a83ef86def43da17e4d73075a281a236097d..1cc1d3657628168af73e3fc7294f341c55c82997 100644 (file)
@@ -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);
index 275c0ce79ccd3998548bf5e8974221c7eff6c701..515baba62dcf074643e867ea507f0c7214d1ba9c 100644 (file)
@@ -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]) {