From ea5771c44204075ad350646af6790c4dc57ee328 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 10 May 2020 13:19:14 -0600 Subject: [PATCH] detect source_sink domain error in open/4 (#480) --- src/prolog/machine/machine_errors.rs | 2 ++ src/prolog/machine/system_calls.rs | 42 +++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index 93c36a73..74374e33 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -539,6 +539,7 @@ pub enum DomainErrorType { IOMode, NotLessThanZero, Order, + SourceSink, Stream, StreamOrAlias, } @@ -549,6 +550,7 @@ impl DomainErrorType { DomainErrorType::IOMode => "io_mode", DomainErrorType::NotLessThanZero => "not_less_than_zero", DomainErrorType::Order => "order", + DomainErrorType::SourceSink => "source_sink", DomainErrorType::Stream => "stream", DomainErrorType::StreamOrAlias => "stream_or_alias", } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index ce7c7a67..9edbdacb 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -3090,7 +3090,47 @@ impl MachineState { self.to_stream_options(alias, eof_action, reposition, stream_type); let file_spec = - atom_from!(self, indices, self.store(self.deref(self[temp_v!(1)]))); + match self.store(self.deref(self[temp_v!(1)])) { + Addr::Con(h) if self.heap.atom_at(h) => { + match &self.heap[h] { + &HeapCellValue::Atom(ref atom, _) => { + atom.clone() + } + _ => { + unreachable!() + } + } + } + Addr::PStrLocation(h, n) => { + match &self.heap[h] { + &HeapCellValue::PartialString(_, true) => { + let mut heap_pstr_iter = + self.heap_pstr_iter(Addr::PStrLocation(h, n)); + + clause_name!( + heap_pstr_iter.to_string(), + indices.atom_tbl.clone() + ) + } + _ => { + clause_name!("") + } + } + } + _ => { + clause_name!("") + } + }; + + if file_spec.as_str().is_empty() { + let stub = MachineError::functor_stub(clause_name!("open"), 4); + let err = MachineError::domain_error( + DomainErrorType::SourceSink, + self[temp_v!(1)], + ); + + return Err(self.error_form(err, stub)); + } // 8.11.5.3l) if let Some(ref alias) = &options.alias { -- 2.54.0