Merge pull request #606 from triska/files

ADDED: library(files), for reasoning about files and directories.
This commit is contained in:
Mark Thom
2020-06-30 13:34:39 -03:00
committed by GitHub
5 changed files with 167 additions and 4 deletions

View File

@@ -575,7 +575,7 @@ impl DomainErrorType {
// from 7.12.2 f) of 13211-1:1995
#[derive(Debug, Clone, Copy)]
pub enum RepFlag {
// Character,
Character,
CharacterCode,
InCharacterCode,
MaxArity,
@@ -586,7 +586,7 @@ pub enum RepFlag {
impl RepFlag {
pub fn as_str(self) -> &'static str {
match self {
// RepFlag::Character => "character",
RepFlag::Character => "character",
RepFlag::CharacterCode => "character_code",
RepFlag::InCharacterCode => "in_character_code",
RepFlag::MaxArity => "max_arity",

View File

@@ -23,11 +23,11 @@ use crate::indexmap::IndexSet;
use crate::ref_thread_local::RefThreadLocal;
use std::cmp;
use std::fs;
use std::collections::BTreeSet;
use std::convert::TryFrom;
use std::io::{ErrorKind, Read, Write};
use std::iter::{once, FromIterator};
use std::fs::{OpenOptions};
use std::net::{TcpListener, TcpStream};
use std::ops::Sub;
use std::rc::Rc;
@@ -822,6 +822,63 @@ impl MachineState {
}
}
}
&SystemClauseType::DirectoryFiles => {
let dir = self.heap_pstr_iter(self[temp_v!(1)]).to_string();
let path = std::path::Path::new(&dir);
let mut files = Vec::new();
if let Ok(entries) = fs::read_dir(path) {
for entry in entries {
if let Ok(entry) = entry {
match entry.file_name().into_string() {
Ok(name) => { files.push(self.heap.put_complete_string(&name)); }
_ => {
let stub = MachineError::functor_stub(clause_name!("directory_files"), 2);
let err = MachineError::representation_error(RepFlag::Character);
let err = self.error_form(err, stub);
return Err(err);
}
}
}
}
}
let files_list = Addr::HeapCell(self.heap.to_list(files.into_iter()));
self.unify(self[temp_v!(2)], files_list);
}
&SystemClauseType::FileSize => {
let file = self.heap_pstr_iter(self[temp_v!(1)]).to_string();
let len = Integer::from(fs::metadata(&file).unwrap().len());
let len = self.heap.to_unifiable(HeapCellValue::Integer(Rc::new(len)));
self.unify(self[temp_v!(2)], len);
}
&SystemClauseType::FileExists => {
let file = self.heap_pstr_iter(self[temp_v!(1)]).to_string();
if !std::path::Path::new(&file).exists() || !fs::metadata(&file).unwrap().is_file() {
self.fail = true;
return Ok(());
}
}
&SystemClauseType::DirectoryExists => {
let directory = self.heap_pstr_iter(self[temp_v!(1)]).to_string();
if !std::path::Path::new(&directory).exists() || !fs::metadata(&directory).unwrap().is_dir() {
self.fail = true;
return Ok(());
}
}
&SystemClauseType::MakeDirectory => {
let directory = self.heap_pstr_iter(self[temp_v!(1)]).to_string();
match fs::create_dir(directory) {
Ok(_) => { }
_ => { self.fail = true;
return Ok(());
}
}
}
&SystemClauseType::AtEndOfExpansion => {
if self.cp == LocalCodePtr::TopLevel(0, 0) {
self.at_end_of_expansion = true;
@@ -3256,7 +3313,7 @@ impl MachineState {
let mode =
atom_from!(self, indices, self.store(self.deref(self[temp_v!(2)])));
let mut open_options = OpenOptions::new();
let mut open_options = fs::OpenOptions::new();
let (is_input_file, in_append_mode) =
match mode.as_str() {