]> Repositorios git - scryer-prolog.git/commitdiff
detect source_sink domain error in open/4 (#480)
authorMark Thom <[email protected]>
Sun, 10 May 2020 19:19:14 +0000 (13:19 -0600)
committerMark Thom <[email protected]>
Sun, 10 May 2020 19:19:14 +0000 (13:19 -0600)
src/prolog/machine/machine_errors.rs
src/prolog/machine/system_calls.rs

index 93c36a73833c224d62d94f46f4d5c3007551b076..74374e33aab2829a4082294a1cd7500feba9c072 100644 (file)
@@ -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",
         }
index ce7c7a679f09094250f479605dc2f62a8ffb1a56..9edbdacb974984a520babb5b8a6d745c662eb312 100644 (file)
@@ -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 {