GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
call-stack.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if ! defined (octave_call_stack_h)
24 #define octave_call_stack_h 1
25 
26 #include "octave-config.h"
27 
28 #include <deque>
29 #include <string>
30 
31 class octave_function;
32 class octave_map;
33 class octave_user_code;
34 class octave_user_script;
35 class octave_value;
36 class octave_value_list;
37 
38 #include "symscope.h"
39 
40 namespace octave
41 {
42  class interpreter;
43 
44  class
45  OCTINTERP_API
47  {
48  public:
49 
51  {
52  public:
53 
54  friend class call_stack;
55 
57  const symbol_scope& scope = symbol_scope (),
58  symbol_record::context_id context = 0, size_t prev = 0)
59  : m_fcn (fcn), m_line (-1), m_column (-1), m_scope (scope),
60  m_context (context), m_prev (prev)
61  { }
62 
63  stack_frame (const stack_frame& elt)
64  : m_fcn (elt.m_fcn), m_line (elt.m_line), m_column (elt.m_column),
65  m_scope (elt.m_scope), m_context (elt.m_context), m_prev (elt.m_prev)
66  { }
67 
68  int line (void) const { return m_line; }
69 
70  int column (void) const { return m_column; }
71 
72  std::string fcn_file_name (void) const;
73 
74  std::string fcn_name (bool print_subfn = true) const;
75 
76  bool operator == (const stack_frame& rhs) const;
77 
78  private:
79 
81  int m_line;
82  int m_column;
85  size_t m_prev;
86  };
87 
88  typedef std::deque<stack_frame>::iterator iterator;
89  typedef std::deque<stack_frame>::const_iterator const_iterator;
90 
91  typedef std::deque<stack_frame>::reverse_iterator reverse_iterator;
92  typedef std::deque<stack_frame>::const_reverse_iterator const_reverse_iterator;
93 
94  call_stack (interpreter& interp);
95 
96  // Current function (top of stack).
97  octave_function * current (void) const
98  {
99  octave_function *retval = nullptr;
100 
101  if (! cs.empty ())
102  {
103  const stack_frame& elt = cs[curr_frame];
104  retval = elt.m_fcn;
105  }
106 
107  return retval;
108  }
109 
110  // Current line in current function.
111  int current_line (void) const;
112 
113  // Current column in current function.
114  int current_column (void) const;
115 
116  // Caller function, may be built-in.
117 
118  octave_function * caller (void) const
119  {
120  return curr_frame > 1 ? cs[curr_frame-1].m_fcn : cs[0].m_fcn;
121  }
122 
123  size_t current_frame (void) const { return curr_frame; }
124 
125  size_t size (void) const { return cs.size (); }
126 
127  size_t num_user_code_frames (octave_idx_type& curr_user_frame) const;
128 
130  {
131  return (curr_frame > 0 && curr_frame < cs.size ()
132  ? cs[curr_frame].m_scope : symbol_scope ());
133  }
134 
136  {
137  return (curr_frame > 0 && curr_frame < cs.size ()
138  ? cs[curr_frame].m_context : 0);
139  }
140 
141  // Function at location N on the call stack (N == 0 is current), may
142  // be built-in.
144  {
145  octave_function *retval = nullptr;
146 
147  if (cs.size () > n)
148  {
149  stack_frame& elt = cs[n];
150  retval = elt.m_fcn;
151  }
152 
153  return retval;
154  }
155 
156  // User code caller.
157  octave_user_code * caller_user_code (size_t nskip = 0) const;
158 
159  // Line in user code caller.
160  int caller_user_code_line (void) const;
161 
162  // Column in user code caller.
163  int caller_user_code_column (void) const;
164 
165  // Current function that we are debugging.
166  octave_user_code * debug_user_code (void) const;
167 
168  // Line number in current function that we are debugging.
169  int debug_user_code_line (void) const;
170 
171  // Column number in current function that we are debugging.
172  int debug_user_code_column (void) const;
173 
174  // Return TRUE if all elements on the call stack are scripts.
175  bool all_scripts (void) const;
176 
177  void push (octave_function *fcn);
178  void push (octave_function *fcn, const symbol_scope& scope,
180 
181  void push (void)
182  {
183  push (nullptr);
184  }
185 
187  {
188  push (nullptr, scope, context);
189  }
190 
191  void set_location (int l, int c)
192  {
193  if (! cs.empty ())
194  {
195  stack_frame& elt = cs.back ();
196 
197  elt.m_line = l;
198  elt.m_column = c;
199  }
200  }
201 
202  void set_line (int l)
203  {
204  if (! cs.empty ())
205  {
206  stack_frame& elt = cs.back ();
207 
208  elt.m_line = l;
209  }
210  }
211 
212  void set_column (int c)
213  {
214  if (! cs.empty ())
215  {
216  stack_frame& elt = cs.back ();
217 
218  elt.m_column = c;
219  }
220  }
221 
222  bool goto_frame (size_t n = 0, bool verbose = false);
223 
224  void restore_frame (size_t n)
225  {
226  goto_frame (n);
227  }
228 
229  bool goto_frame_relative (int n, bool verbose = false);
230 
231  void goto_caller_frame (void);
232 
233  void goto_base_frame (void);
234 
235  std::list<call_stack::stack_frame>
236  backtrace_frames (size_t nskip, octave_idx_type& curr_user_frame) const;
237 
238  std::list<call_stack::stack_frame>
239  backtrace_frames (size_t nskip = 0) const
240  {
241  octave_idx_type curr_user_frame = -1;
242 
243  return backtrace_frames (nskip, curr_user_frame);
244  }
245 
246  octave_map backtrace (size_t nskip, octave_idx_type& curr_user_frame,
247  bool print_subfn = true) const;
248 
249  octave_map backtrace (size_t nskip = 0);
250 
251  octave_map empty_backtrace (void) const;
252 
253  void pop (void);
254 
255  void clear (void) { cs.clear (); }
256 
257  octave_value max_stack_depth (const octave_value_list& args, int nargout);
258 
259  private:
260 
261  // The current call stack.
262  std::deque<stack_frame> cs;
263 
264  size_t curr_frame;
265 
267 
269  };
270 }
271 
272 #if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS)
273 
274 OCTAVE_DEPRECATED (4.4, "use 'octave::call_stack' instead")
275 typedef octave::call_stack octave_call_stack;
276 
277 #endif
278 
279 #endif
symbol_record::context_id current_context(void) const
Definition: call-stack.h:135
void set_location(int l, int c)
Definition: call-stack.h:191
octave_function * element(size_t n)
Definition: call-stack.h:143
stack_frame(octave_function *fcn=nullptr, const symbol_scope &scope=symbol_scope(), symbol_record::context_id context=0, size_t prev=0)
Definition: call-stack.h:56
void clear(void)
Definition: call-stack.h:255
std::deque< stack_frame >::const_reverse_iterator const_reverse_iterator
Definition: call-stack.h:92
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:79
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
void push(void)
Definition: call-stack.h:181
octave_function * fcn
Definition: ov-class.cc:1754
octave::call_stack & cs
Definition: ov-class.cc:1752
std::deque< stack_frame >::iterator iterator
Definition: call-stack.h:88
bool verbose
Definition: load-save.cc:667
stack_frame(const stack_frame &elt)
Definition: call-stack.h:63
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:997
std::list< call_stack::stack_frame > backtrace_frames(size_t nskip=0) const
Definition: call-stack.h:239
octave_function * caller(void) const
Definition: call-stack.h:118
void push(const symbol_scope &scope, symbol_record::context_id context)
Definition: call-stack.h:186
std::deque< stack_frame >::const_iterator const_iterator
Definition: call-stack.h:89
octave_value retval
Definition: data.cc:6246
bool operator==(const dim_vector &a, const dim_vector &b)
Definition: dim-vector.h:550
symbol_scope current_scope(void) const
Definition: call-stack.h:129
void set_line(int l)
Definition: call-stack.h:202
octave_function * current(void) const
Definition: call-stack.h:97
void set_column(int c)
Definition: call-stack.h:212
std::deque< stack_frame > cs
Definition: call-stack.h:262
void restore_frame(size_t n)
Definition: call-stack.h:224
symbol_record::context_id m_context
Definition: call-stack.h:84
std::deque< stack_frame >::reverse_iterator reverse_iterator
Definition: call-stack.h:91
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
size_t current_frame(void) const
Definition: call-stack.h:123
interpreter & m_interpreter
Definition: call-stack.h:268
size_t size(void) const
Definition: call-stack.h:125