1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2002-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if defined (HAVE_CONFIG_H) 27 # include "config.h" 28 #endif 29 30 #include <cstring> 31 32 #include <ostream> 33 #include <sstream> 34 #include <new> 35 36 #include "quit.h" 37 38 sig_atomic_t octave_interrupt_state = 0; 39 40 // DEPRECATED in Octave 6. 41 // This variable should never have been public. 42 sig_atomic_t octave_exception_state = 0; 43 // Use this variable internally until the functions that use it can be 44 // removed. 45 static sig_atomic_t internal_exception_state; 46 47 volatile sig_atomic_t octave_signal_caught = 0; 48 49 void (*octave_signal_hook) (void) = nullptr; 50 void (*octave_interrupt_hook) (void) = nullptr; 51 52 // DEPRECATED in Octave 6. 53 void (*octave_bad_alloc_hook) (void) = nullptr; 54 55 // The octave_exception enum values were DEPRECATED in Octave 6. 56 // Use these values internally until the functions that use them can be 57 // removed. 58 enum octave_internal_exception 59 { 60 octave_internal_no_exception = 0, 61 octave_internal_exec_exception = 1, 62 octave_internal_alloc_exception = 3, 63 octave_internal_quit_exception = 4 64 }; 65 66 namespace octave 67 { stack_trace(void) const68 std::string execution_exception::stack_trace (void) const 69 { 70 std::size_t nframes = m_stack_info.size (); 71 72 if (nframes == 0) 73 return std::string (); 74 75 std::ostringstream buf; 76 77 buf << "error: called from\n"; 78 79 for (const auto& frm : m_stack_info) 80 { 81 buf << " " << frm.fcn_name (); 82 83 int line = frm.line (); 84 85 if (line > 0) 86 { 87 buf << " at line " << line; 88 89 int column = frm.column (); 90 91 if (column > 0) 92 buf << " column " << column; 93 } 94 95 buf << "\n"; 96 } 97 98 return buf.str (); 99 } 100 display(std::ostream & os) const101 void execution_exception::display (std::ostream& os) const 102 { 103 if (! m_message.empty ()) 104 { 105 os << m_err_type << ": " << m_message; 106 107 if (m_message.back () != '\n') 108 { 109 os << "\n"; 110 111 std::string st = stack_trace (); 112 113 if (! st.empty ()) 114 os << st; 115 } 116 } 117 } 118 } 119 120 void octave_handle_signal(void)121octave_handle_signal (void) 122 { 123 if (octave_signal_hook) 124 octave_signal_hook (); 125 126 if (octave_interrupt_state > 0) 127 { 128 octave_interrupt_state = -1; 129 130 throw octave::interrupt_exception (); 131 } 132 } 133 134 // DEPRECATED in Octave 6 135 void octave_throw_interrupt_exception(void)136octave_throw_interrupt_exception (void) 137 { 138 if (octave_interrupt_hook) 139 octave_interrupt_hook (); 140 141 throw octave::interrupt_exception (); 142 } 143 144 // DEPRECATED in Octave 6 145 void octave_throw_execution_exception(void)146octave_throw_execution_exception (void) 147 { 148 // FIXME: would a hook function be useful here? 149 150 internal_exception_state = octave_internal_exec_exception; 151 152 throw octave::execution_exception (); 153 } 154 155 // DEPRECATED in Octave 6 156 void octave_throw_bad_alloc(void)157octave_throw_bad_alloc (void) 158 { 159 internal_exception_state = octave_internal_alloc_exception; 160 161 throw std::bad_alloc (); 162 } 163 164 // DEPRECATED in Octave 6 165 void octave_rethrow_exception(void)166octave_rethrow_exception (void) 167 { 168 if (octave_interrupt_state) 169 { 170 octave_interrupt_state = -1; 171 172 throw octave::interrupt_exception (); 173 } 174 else 175 { 176 switch (internal_exception_state) 177 { 178 case octave_internal_exec_exception: 179 throw octave::execution_exception (); 180 break; 181 182 case octave_internal_alloc_exception: 183 throw std::bad_alloc (); 184 break; 185 186 default: 187 break; 188 } 189 } 190 } 191