Small patch for library pio
This commit is contained in:
@@ -3,5 +3,9 @@
|
|||||||
:- use_module(library(dcgs)).
|
:- use_module(library(dcgs)).
|
||||||
|
|
||||||
phrase_from_file(NT, File) :-
|
phrase_from_file(NT, File) :-
|
||||||
'$file_to_chars'(File, Chars),
|
( var(File) -> throw(error(instantiation_error, phrase_from_file/2))
|
||||||
phrase(NT, Chars).
|
; (\+ atom(File) ; File = []) ->
|
||||||
|
throw(error(domain_error(source_sink, File), phrase_from_file/2))
|
||||||
|
; '$file_to_chars'(File, Chars),
|
||||||
|
phrase(NT, Chars)
|
||||||
|
).
|
||||||
|
|||||||
@@ -1522,6 +1522,8 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
&SystemClauseType::FileToChars => {
|
&SystemClauseType::FileToChars => {
|
||||||
|
// TODO: Replace this with stream.
|
||||||
|
use std::io;
|
||||||
let a1 = self.store(self.deref(self[temp_v!(1)]));
|
let a1 = self.store(self.deref(self[temp_v!(1)]));
|
||||||
let a2 = self.store(self.deref(self[temp_v!(2)]));
|
let a2 = self.store(self.deref(self[temp_v!(2)]));
|
||||||
|
|
||||||
@@ -1542,50 +1544,64 @@ impl MachineState {
|
|||||||
let name = clause_name!("$file_to_chars");
|
let name = clause_name!("$file_to_chars");
|
||||||
let mut file = match File::open(&file_name) {
|
let mut file = match File::open(&file_name) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(_e) => {
|
Err(e) => {
|
||||||
let file_name_ = clause_name!(file_name.clone(),
|
let file_name_ = clause_name!(file_name.clone(),
|
||||||
indices.atom_tbl.clone());
|
indices.atom_tbl.clone());
|
||||||
let arity = 2;
|
let arity = 2;
|
||||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
let err = match e.kind() {
|
||||||
|
io::ErrorKind::NotFound => {
|
||||||
|
MachineError::existence_error(
|
||||||
|
h,
|
||||||
|
ExistenceError::SourceSink(
|
||||||
|
ModuleSource::File(file_name_)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
io::ErrorKind::PermissionDenied => {
|
||||||
|
let stub = MachineError::functor_stub(
|
||||||
|
name.clone(),
|
||||||
|
arity
|
||||||
|
);
|
||||||
|
let source_sink = self.store(self.deref(a1));
|
||||||
|
MachineError::permission_error(
|
||||||
|
h,
|
||||||
|
Permission::Access,
|
||||||
|
"source_sink",
|
||||||
|
source_sink
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => unreachable!() // Not nice.
|
||||||
|
};
|
||||||
|
|
||||||
let err = MachineError::existence_error(
|
|
||||||
h,
|
|
||||||
ExistenceError::SourceSink(
|
|
||||||
ModuleSource::File(file_name_)
|
|
||||||
),
|
|
||||||
);
|
|
||||||
let err = self.error_form(err, stub);
|
let err = self.error_form(err, stub);
|
||||||
|
|
||||||
self.throw_exception(err);
|
self.throw_exception(err);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut buffer = String::new();
|
let char_list = {
|
||||||
let _ = match file.read_to_string(&mut buffer) {
|
let mut buffer = String::new();
|
||||||
Ok(size) => size,
|
match file.read_to_string(&mut buffer) {
|
||||||
Err(_e) => {
|
Ok(_size) => {
|
||||||
// TODO: Distinguish the case/error.
|
let chars = buffer.chars().map(|c| Addr::Char(c));
|
||||||
let file_name_ = clause_name!(file_name.clone(),
|
Addr::HeapCell(self.heap.to_list(chars))
|
||||||
indices.atom_tbl.clone());
|
}
|
||||||
let arity = 2;
|
Err(_e) => {
|
||||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
// This case if the data isn't UTF-8 valid.
|
||||||
let h = self.heap.h();
|
let mut buffer = Vec::new();
|
||||||
|
let _ = match file.read_to_end(&mut buffer) {
|
||||||
let err = MachineError::existence_error(
|
Ok(size) => size,
|
||||||
h,
|
Err(_e) => unreachable!()
|
||||||
ExistenceError::SourceSink(
|
};
|
||||||
ModuleSource::File(file_name_)
|
let chars = buffer
|
||||||
),
|
.into_iter()
|
||||||
);
|
.map(|b| Addr::Char(b as char));
|
||||||
let err = self.error_form(err, stub);
|
Addr::HeapCell(self.heap.to_list(chars))
|
||||||
|
}
|
||||||
self.throw_exception(err);
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let chars = buffer.chars().map(|c| Addr::Char(c));
|
|
||||||
let char_list = Addr::HeapCell(self.heap.to_list(chars));
|
|
||||||
|
|
||||||
self.unify(char_list, a2);
|
self.unify(char_list, a2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user