Mercurial > octave
comparison libinterp/corefcn/call-stack.cc @ 31607:aac27ad79be6 stable
maint: Re-indent code after switch to using namespace macros.
* build-env.h, build-env.in.cc, Cell.h, __betainc__.cc, __eigs__.cc,
__ftp__.cc, __ichol__.cc, __ilu__.cc, __isprimelarge__.cc, __magick_read__.cc,
__pchip_deriv__.cc, amd.cc, base-text-renderer.cc, base-text-renderer.h,
besselj.cc, bitfcns.cc, bsxfun.cc, c-file-ptr-stream.h, call-stack.cc,
call-stack.h, ccolamd.cc, cellfun.cc, chol.cc, colamd.cc, dasrt.cc, data.cc,
debug.cc, defaults.cc, defaults.h, det.cc, display.cc, display.h, dlmread.cc,
dynamic-ld.cc, dynamic-ld.h, ellipj.cc, environment.cc, environment.h,
error.cc, error.h, errwarn.h, event-manager.cc, event-manager.h,
event-queue.cc, event-queue.h, fcn-info.cc, fcn-info.h, fft.cc, fft2.cc,
file-io.cc, filter.cc, find.cc, ft-text-renderer.cc, ft-text-renderer.h,
gcd.cc, gl-render.cc, gl-render.h, gl2ps-print.cc, gl2ps-print.h,
graphics-toolkit.cc, graphics-toolkit.h, graphics.cc, gsvd.cc, gtk-manager.cc,
gtk-manager.h, help.cc, help.h, hook-fcn.cc, hook-fcn.h, input.cc, input.h,
interpreter-private.cc, interpreter-private.h, interpreter.cc, interpreter.h,
inv.cc, jsondecode.cc, jsonencode.cc, latex-text-renderer.cc,
latex-text-renderer.h, load-path.cc, load-path.h, load-save.cc, load-save.h,
lookup.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, lsode.cc, lu.cc, mappers.cc,
matrix_type.cc, max.cc, mex.cc, mexproto.h, mxarray.h, mxtypes.in.h,
oct-errno.in.cc, oct-hdf5-types.cc, oct-hist.cc, oct-hist.h, oct-map.cc,
oct-map.h, oct-opengl.h, oct-prcstrm.h, oct-process.cc, oct-process.h,
oct-stdstrm.h, oct-stream.cc, oct-stream.h, oct-strstrm.h,
octave-default-image.h, ordqz.cc, ordschur.cc, pager.cc, pager.h, pinv.cc,
pow2.cc, pr-output.cc, psi.cc, qr.cc, quadcc.cc, rand.cc, regexp.cc,
settings.cc, settings.h, sighandlers.cc, sighandlers.h, sparse-xpow.cc,
sqrtm.cc, stack-frame.cc, stack-frame.h, stream-euler.cc, strfns.cc, svd.cc,
syminfo.cc, syminfo.h, symrcm.cc, symrec.cc, symrec.h, symscope.cc, symscope.h,
symtab.cc, symtab.h, sysdep.cc, sysdep.h, text-engine.cc, text-engine.h,
text-renderer.cc, text-renderer.h, time.cc, toplev.cc, typecast.cc,
url-handle-manager.cc, url-handle-manager.h, urlwrite.cc, utils.cc, utils.h,
variables.cc, variables.h, xdiv.cc, __delaunayn__.cc, __init_fltk__.cc,
__init_gnuplot__.cc, __ode15__.cc, __voronoi__.cc, audioread.cc, convhulln.cc,
gzip.cc, cdef-class.cc, cdef-class.h, cdef-fwd.h, cdef-manager.cc,
cdef-manager.h, cdef-method.cc, cdef-method.h, cdef-object.cc, cdef-object.h,
cdef-package.cc, cdef-package.h, cdef-property.cc, cdef-property.h,
cdef-utils.cc, cdef-utils.h, ov-base-diag.cc, ov-base-int.cc, ov-base-mat.cc,
ov-base-mat.h, ov-base-scalar.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc,
ov-bool-mat.h, ov-bool-sparse.cc, ov-bool.cc, ov-builtin.h, ov-cell.cc,
ov-ch-mat.cc, ov-class.cc, ov-class.h, ov-classdef.cc, ov-classdef.h,
ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-cx-sparse.cc, ov-dld-fcn.cc,
ov-dld-fcn.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn.h, ov-float.cc,
ov-flt-complex.cc, ov-flt-cx-diag.cc, ov-flt-cx-mat.cc, ov-flt-re-diag.cc,
ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h, ov-java.cc, ov-lazy-idx.cc,
ov-legacy-range.cc, ov-magic-int.cc, ov-mex-fcn.cc, ov-mex-fcn.h,
ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc,
ov-re-mat.h, ov-re-sparse.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc,
ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h, ov.cc, ov.h, ovl.h,
octave.cc, octave.h, op-b-sbm.cc, op-bm-sbm.cc, op-cs-scm.cc, op-fm-fcm.cc,
op-fs-fcm.cc, op-s-scm.cc, op-scm-cs.cc, op-scm-s.cc, op-sm-cs.cc, ops.h,
anon-fcn-validator.cc, anon-fcn-validator.h, bp-table.cc, bp-table.h,
comment-list.cc, comment-list.h, filepos.h, lex.h, oct-lvalue.cc, oct-lvalue.h,
parse.h, profiler.cc, profiler.h, pt-anon-scopes.cc, pt-anon-scopes.h,
pt-arg-list.cc, pt-arg-list.h, pt-args-block.cc, pt-args-block.h,
pt-array-list.cc, pt-array-list.h, pt-assign.cc, pt-assign.h, pt-binop.cc,
pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc,
pt-cell.h, pt-check.cc, pt-check.h, pt-classdef.cc, pt-classdef.h, pt-cmd.h,
pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h,
pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h,
pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h,
pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h,
pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-spmd.cc, pt-spmd.h,
pt-stmt.cc, pt-stmt.h, pt-tm-const.cc, pt-tm-const.h, pt-unop.cc, pt-unop.h,
pt-walk.cc, pt-walk.h, pt.cc, pt.h, token.cc, token.h, Range.cc, Range.h,
idx-vector.cc, idx-vector.h, range-fwd.h, CollocWt.cc, CollocWt.h,
aepbalance.cc, aepbalance.h, chol.cc, chol.h, gepbalance.cc, gepbalance.h,
gsvd.cc, gsvd.h, hess.cc, hess.h, lo-mappers.cc, lo-mappers.h, lo-specfun.cc,
lo-specfun.h, lu.cc, lu.h, oct-convn.cc, oct-convn.h, oct-fftw.cc, oct-fftw.h,
oct-norm.cc, oct-norm.h, oct-rand.cc, oct-rand.h, oct-spparms.cc,
oct-spparms.h, qr.cc, qr.h, qrp.cc, qrp.h, randgamma.cc, randgamma.h,
randmtzig.cc, randmtzig.h, randpoisson.cc, randpoisson.h, schur.cc, schur.h,
sparse-chol.cc, sparse-chol.h, sparse-lu.cc, sparse-lu.h, sparse-qr.cc,
sparse-qr.h, svd.cc, svd.h, child-list.cc, child-list.h, dir-ops.cc, dir-ops.h,
file-ops.cc, file-ops.h, file-stat.cc, file-stat.h, lo-sysdep.cc, lo-sysdep.h,
lo-sysinfo.cc, lo-sysinfo.h, mach-info.cc, mach-info.h, oct-env.cc, oct-env.h,
oct-group.cc, oct-group.h, oct-password.cc, oct-password.h, oct-syscalls.cc,
oct-syscalls.h, oct-time.cc, oct-time.h, oct-uname.cc, oct-uname.h,
action-container.cc, action-container.h, base-list.h, cmd-edit.cc, cmd-edit.h,
cmd-hist.cc, cmd-hist.h, f77-fcn.h, file-info.cc, file-info.h,
lo-array-errwarn.cc, lo-array-errwarn.h, lo-hash.cc, lo-hash.h, lo-ieee.h,
lo-regexp.cc, lo-regexp.h, lo-utils.cc, lo-utils.h, oct-base64.cc,
oct-base64.h, oct-glob.cc, oct-glob.h, oct-inttypes.h, oct-mutex.cc,
oct-mutex.h, oct-refcount.h, oct-shlib.cc, oct-shlib.h, oct-sparse.cc,
oct-sparse.h, oct-string.h, octave-preserve-stream-state.h, pathsearch.cc,
pathsearch.h, quit.cc, quit.h, unwind-prot.cc, unwind-prot.h, url-transfer.cc,
url-transfer.h:
Re-indent code after switch to using namespace macros.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 01 Dec 2022 18:02:15 -0800 |
parents | e88a07dec498 |
children | 597f3ee61a48 |
comparison
equal
deleted
inserted
replaced
31605:e88a07dec498 | 31607:aac27ad79be6 |
---|---|
47 #include "symscope.h" | 47 #include "symscope.h" |
48 #include "variables.h" | 48 #include "variables.h" |
49 | 49 |
50 OCTAVE_BEGIN_NAMESPACE(octave) | 50 OCTAVE_BEGIN_NAMESPACE(octave) |
51 | 51 |
52 // Use static fields for the best efficiency. | 52 // Use static fields for the best efficiency. |
53 // NOTE: C++0x will allow these two to be merged into one. | 53 // NOTE: C++0x will allow these two to be merged into one. |
54 static const char *bt_fieldnames[] = | 54 static const char *bt_fieldnames[] = |
55 { "file", "name", "line", "column", nullptr }; | 55 { "file", "name", "line", "column", nullptr }; |
56 | 56 |
57 static const octave_fields bt_fields (bt_fieldnames); | 57 static const octave_fields bt_fields (bt_fieldnames); |
58 | 58 |
59 call_stack::call_stack (tree_evaluator& evaluator) | 59 call_stack::call_stack (tree_evaluator& evaluator) |
60 : m_evaluator (evaluator), m_cs (), m_curr_frame (0), | 60 : m_evaluator (evaluator), m_cs (), m_curr_frame (0), |
61 m_max_stack_depth (1024), m_global_values () | 61 m_max_stack_depth (1024), m_global_values () |
62 { | 62 { |
63 push (symbol_scope ("top scope")); | 63 push (symbol_scope ("top scope")); |
64 } | 64 } |
65 | 65 |
66 octave_function * call_stack::current_function (bool skip_first) const | 66 octave_function *call_stack::current_function (bool skip_first) const |
67 { | 67 { |
68 if (m_cs.empty ()) | 68 if (m_cs.empty ()) |
69 error ("current_function: call stack is empty"); | 69 error ("current_function: call stack is empty"); |
70 | 70 |
71 octave_function *fcn = nullptr; | 71 octave_function *fcn = nullptr; |
72 | 72 |
73 std::size_t idx = m_curr_frame; | 73 std::size_t idx = m_curr_frame; |
74 | 74 |
75 if (idx > 0 && skip_first) | 75 if (idx > 0 && skip_first) |
76 --idx; | |
77 | |
78 while (true) | |
79 { | |
80 fcn = m_cs[idx]->function (); | |
81 | |
82 if (fcn || idx == 0) | |
83 break; | |
84 | |
76 --idx; | 85 --idx; |
77 | 86 } |
78 while (true) | 87 |
79 { | 88 return fcn; |
80 fcn = m_cs[idx]->function (); | 89 } |
81 | 90 |
82 if (fcn || idx == 0) | 91 int call_stack::current_line (void) const |
92 { | |
93 int retval = -1; | |
94 | |
95 if (! m_cs.empty ()) | |
96 { | |
97 const std::shared_ptr<stack_frame> elt = m_cs[m_curr_frame]; | |
98 retval = elt->line (); | |
99 } | |
100 | |
101 return retval; | |
102 } | |
103 | |
104 int call_stack::current_column (void) const | |
105 { | |
106 int retval = -1; | |
107 | |
108 if (! m_cs.empty ()) | |
109 { | |
110 const std::shared_ptr<stack_frame> elt = m_cs[m_curr_frame]; | |
111 retval = elt->column (); | |
112 } | |
113 | |
114 return retval; | |
115 } | |
116 | |
117 octave_user_code *call_stack::current_user_code (void) const | |
118 { | |
119 // Start at current frame. | |
120 | |
121 std::size_t xframe = find_current_user_frame (); | |
122 | |
123 if (xframe > 0) | |
124 { | |
125 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | |
126 | |
127 octave_function *f = elt->function (); | |
128 | |
129 if (f && f->is_user_code ()) | |
130 return dynamic_cast<octave_user_code *> (f); | |
131 } | |
132 | |
133 return nullptr; | |
134 } | |
135 | |
136 int call_stack::current_user_code_line (void) const | |
137 { | |
138 // Start at current frame. | |
139 | |
140 std::size_t xframe = find_current_user_frame (); | |
141 | |
142 if (xframe > 0) | |
143 { | |
144 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | |
145 | |
146 octave_function *f = elt->function (); | |
147 | |
148 if (f && f->is_user_code ()) | |
149 { | |
150 int line = elt->line (); | |
151 | |
152 if (line > 0) | |
153 return line; | |
154 } | |
155 } | |
156 | |
157 return -1; | |
158 } | |
159 | |
160 int call_stack::current_user_code_column (void) const | |
161 { | |
162 // Start at current frame. | |
163 | |
164 std::size_t xframe = find_current_user_frame (); | |
165 | |
166 if (xframe > 0) | |
167 { | |
168 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | |
169 | |
170 octave_function *f = elt->function (); | |
171 | |
172 if (f && f->is_user_code ()) | |
173 { | |
174 int column = elt->column (); | |
175 | |
176 if (column > 0) | |
177 return column; | |
178 } | |
179 } | |
180 | |
181 return -1; | |
182 } | |
183 | |
184 unwind_protect *call_stack::curr_fcn_unwind_protect_frame (void) | |
185 { | |
186 // Start at current frame. | |
187 | |
188 std::size_t xframe = find_current_user_frame (); | |
189 | |
190 if (xframe > 0) | |
191 { | |
192 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | |
193 | |
194 octave_function *f = elt->function (); | |
195 | |
196 if (f && f->is_user_code ()) | |
197 return elt->unwind_protect_frame (); | |
198 } | |
199 | |
200 return nullptr; | |
201 } | |
202 | |
203 octave_user_code *call_stack::debug_user_code (void) const | |
204 { | |
205 octave_user_code *retval = nullptr; | |
206 | |
207 // This should never happen... | |
208 if (m_curr_frame == 0) | |
209 return retval; | |
210 | |
211 std::size_t i = m_curr_frame; | |
212 | |
213 while (i != 0) | |
214 { | |
215 const std::shared_ptr<stack_frame> elt = m_cs[i--]; | |
216 | |
217 octave_function *f = elt->function (); | |
218 | |
219 if (f && f->is_user_code ()) | |
220 { | |
221 retval = dynamic_cast<octave_user_code *> (f); | |
83 break; | 222 break; |
84 | 223 } |
85 --idx; | 224 } |
86 } | 225 |
87 | 226 return retval; |
88 return fcn; | 227 } |
89 } | 228 |
90 | 229 int call_stack::debug_user_code_line (void) const |
91 int call_stack::current_line (void) const | 230 { |
92 { | 231 int retval = -1; |
93 int retval = -1; | 232 |
94 | 233 // This should never happen... |
95 if (! m_cs.empty ()) | 234 if (m_curr_frame == 0) |
96 { | |
97 const std::shared_ptr<stack_frame> elt = m_cs[m_curr_frame]; | |
98 retval = elt->line (); | |
99 } | |
100 | |
101 return retval; | 235 return retval; |
102 } | 236 |
103 | 237 std::size_t i = m_curr_frame; |
104 int call_stack::current_column (void) const | 238 |
105 { | 239 while (i != 0) |
106 int retval = -1; | 240 { |
107 | 241 const std::shared_ptr<stack_frame> elt = m_cs[i--]; |
108 if (! m_cs.empty ()) | 242 |
109 { | 243 octave_function *f = elt->function (); |
110 const std::shared_ptr<stack_frame> elt = m_cs[m_curr_frame]; | 244 |
111 retval = elt->column (); | 245 if (f && f->is_user_code ()) |
112 } | 246 { |
113 | 247 if (elt->line ()) |
248 { | |
249 retval = elt->line (); | |
250 break; | |
251 } | |
252 } | |
253 } | |
254 | |
255 return retval; | |
256 } | |
257 | |
258 int call_stack::debug_user_code_column (void) const | |
259 { | |
260 int retval = -1; | |
261 | |
262 // This should never happen... | |
263 if (m_curr_frame == 0) | |
114 return retval; | 264 return retval; |
115 } | 265 |
116 | 266 // Start looking with the caller of the calling debug function. |
117 octave_user_code * call_stack::current_user_code (void) const | 267 std::size_t i = m_curr_frame; |
118 { | 268 |
119 // Start at current frame. | 269 while (i != 0) |
120 | 270 { |
121 std::size_t xframe = find_current_user_frame (); | 271 const std::shared_ptr<stack_frame> elt = m_cs[i--]; |
122 | 272 |
123 if (xframe > 0) | 273 octave_function *f = elt->function (); |
124 { | 274 |
125 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | 275 if (f && f->is_user_code ()) |
126 | 276 { |
127 octave_function *f = elt->function (); | 277 if (elt->column ()) |
128 | 278 { |
129 if (f && f->is_user_code ()) | 279 retval = elt->column (); |
130 return dynamic_cast<octave_user_code *> (f); | 280 break; |
131 } | 281 } |
132 | 282 } |
133 return nullptr; | 283 } |
134 } | 284 |
135 | 285 return retval; |
136 int call_stack::current_user_code_line (void) const | 286 } |
137 { | 287 |
138 // Start at current frame. | 288 std::string call_stack::get_dispatch_class (void) const |
139 | 289 { |
140 std::size_t xframe = find_current_user_frame (); | 290 return m_cs[m_curr_frame]->get_dispatch_class (); |
141 | 291 } |
142 if (xframe > 0) | 292 |
143 { | 293 void call_stack::set_dispatch_class (const std::string& class_name) |
144 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | 294 { |
145 | 295 m_cs[m_curr_frame]->set_dispatch_class (class_name); |
146 octave_function *f = elt->function (); | 296 } |
147 | 297 |
148 if (f && f->is_user_code ()) | 298 bool call_stack::is_class_method_executing (std::string& dispatch_class) const |
149 { | 299 { |
150 int line = elt->line (); | 300 dispatch_class = ""; |
151 | 301 |
152 if (line > 0) | 302 octave_function *f = current_function (); |
153 return line; | 303 |
154 } | 304 bool retval = (f && f->is_class_method ()); |
155 } | 305 |
156 | 306 if (retval) |
157 return -1; | 307 dispatch_class = f->dispatch_class (); |
158 } | 308 |
159 | 309 return retval; |
160 int call_stack::current_user_code_column (void) const | 310 } |
161 { | 311 |
162 // Start at current frame. | 312 bool call_stack::is_class_constructor_executing (std::string& dispatch_class) const |
163 | 313 { |
164 std::size_t xframe = find_current_user_frame (); | 314 dispatch_class = ""; |
165 | 315 |
166 if (xframe > 0) | 316 octave_function *f = current_function (); |
167 { | 317 |
168 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | 318 bool retval = (f && f->is_class_constructor ()); |
169 | 319 |
170 octave_function *f = elt->function (); | 320 if (retval) |
171 | 321 dispatch_class = f->dispatch_class (); |
172 if (f && f->is_user_code ()) | 322 |
173 { | 323 return retval; |
174 int column = elt->column (); | 324 } |
175 | 325 |
176 if (column > 0) | 326 bool call_stack::all_scripts (void) const |
177 return column; | 327 { |
178 } | 328 bool retval = true; |
179 } | 329 |
180 | 330 auto p = m_cs.cend (); |
181 return -1; | 331 |
182 } | 332 while (p != m_cs.cbegin ()) |
183 | 333 { |
184 unwind_protect * call_stack::curr_fcn_unwind_protect_frame (void) | 334 const std::shared_ptr<stack_frame> elt = *(--p); |
185 { | 335 |
186 // Start at current frame. | 336 octave_function *f = elt->function (); |
187 | 337 |
188 std::size_t xframe = find_current_user_frame (); | 338 if (f && ! f->is_user_script ()) |
189 | 339 { |
190 if (xframe > 0) | 340 retval = false; |
191 { | 341 break; |
192 const std::shared_ptr<stack_frame> elt = m_cs[xframe]; | 342 } |
193 | 343 } |
194 octave_function *f = elt->function (); | 344 |
195 | 345 return retval; |
196 if (f && f->is_user_code ()) | 346 } |
197 return elt->unwind_protect_frame (); | 347 |
198 } | 348 void call_stack::get_new_frame_index_and_links |
199 | 349 (std::size_t& new_frame_idx, std::shared_ptr<stack_frame>& parent_link, |
200 return nullptr; | 350 std::shared_ptr<stack_frame>& static_link) const |
201 } | 351 { |
202 | 352 // FIXME: is there a better way? |
203 octave_user_code * call_stack::debug_user_code (void) const | 353 |
204 { | 354 std::size_t prev_frame_idx = m_curr_frame; |
205 octave_user_code *retval = nullptr; | 355 |
206 | 356 new_frame_idx = m_cs.size (); |
207 // This should never happen... | 357 |
208 if (m_curr_frame == 0) | 358 // m_max_stack_depth should never be less than zero. |
209 return retval; | 359 if (new_frame_idx > static_cast<std::size_t> (m_max_stack_depth)) |
210 | 360 error ("max_stack_depth exceeded"); |
211 std::size_t i = m_curr_frame; | 361 |
212 | 362 // There can't be any links to previous frames if this is the first |
213 while (i != 0) | 363 // frame on the stack. |
214 { | 364 |
215 const std::shared_ptr<stack_frame> elt = m_cs[i--]; | 365 if (new_frame_idx == 0) |
216 | 366 return; |
217 octave_function *f = elt->function (); | 367 |
218 | 368 parent_link = m_cs[prev_frame_idx]; |
219 if (f && f->is_user_code ()) | 369 |
220 { | 370 octave_function *t_fcn = parent_link->function (); |
221 retval = dynamic_cast<octave_user_code *> (f); | 371 |
372 static_link = (t_fcn | |
373 ? (t_fcn->is_user_code () | |
374 ? parent_link : parent_link->static_link ()) | |
375 : parent_link); | |
376 } | |
377 | |
378 void call_stack::push (const symbol_scope& scope) | |
379 { | |
380 std::size_t new_frame_idx; | |
381 std::shared_ptr<stack_frame> parent_link; | |
382 std::shared_ptr<stack_frame> static_link; | |
383 | |
384 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
385 | |
386 std::shared_ptr<stack_frame> | |
387 new_frame (stack_frame::create (m_evaluator, scope, new_frame_idx, | |
388 parent_link, static_link)); | |
389 | |
390 m_cs.push_back (new_frame); | |
391 | |
392 m_curr_frame = new_frame_idx; | |
393 } | |
394 | |
395 void call_stack::push (octave_user_function *fcn, | |
396 const std::shared_ptr<stack_frame>& closure_frames) | |
397 { | |
398 std::size_t new_frame_idx; | |
399 std::shared_ptr<stack_frame> parent_link; | |
400 std::shared_ptr<stack_frame> static_link; | |
401 | |
402 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
403 | |
404 std::shared_ptr<stack_frame> | |
405 new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, | |
406 parent_link, static_link, | |
407 closure_frames)); | |
408 | |
409 m_cs.push_back (new_frame); | |
410 | |
411 m_curr_frame = new_frame_idx; | |
412 } | |
413 | |
414 void call_stack::push (octave_user_function *fcn, | |
415 const stack_frame::local_vars_map& local_vars, | |
416 const std::shared_ptr<stack_frame>& closure_frames) | |
417 { | |
418 std::size_t new_frame_idx; | |
419 std::shared_ptr<stack_frame> parent_link; | |
420 std::shared_ptr<stack_frame> static_link; | |
421 | |
422 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
423 | |
424 std::shared_ptr<stack_frame> | |
425 new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, | |
426 parent_link, static_link, local_vars, | |
427 closure_frames)); | |
428 | |
429 m_cs.push_back (new_frame); | |
430 | |
431 m_curr_frame = new_frame_idx; | |
432 } | |
433 | |
434 void call_stack::push (octave_user_script *script) | |
435 { | |
436 std::size_t new_frame_idx; | |
437 std::shared_ptr<stack_frame> parent_link; | |
438 std::shared_ptr<stack_frame> static_link; | |
439 | |
440 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
441 | |
442 std::shared_ptr<stack_frame> | |
443 new_frame (stack_frame::create (m_evaluator, script, new_frame_idx, | |
444 parent_link, static_link)); | |
445 | |
446 m_cs.push_back (new_frame); | |
447 | |
448 m_curr_frame = new_frame_idx; | |
449 } | |
450 | |
451 void call_stack::push (octave_function *fcn) | |
452 { | |
453 std::size_t new_frame_idx; | |
454 std::shared_ptr<stack_frame> parent_link; | |
455 std::shared_ptr<stack_frame> static_link; | |
456 | |
457 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
458 | |
459 std::shared_ptr<stack_frame> | |
460 new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, | |
461 parent_link, static_link)); | |
462 | |
463 m_cs.push_back (new_frame); | |
464 | |
465 m_curr_frame = new_frame_idx; | |
466 } | |
467 | |
468 bool call_stack::goto_frame (std::size_t n, bool verbose) | |
469 { | |
470 bool retval = false; | |
471 | |
472 if (n < m_cs.size ()) | |
473 { | |
474 retval = true; | |
475 | |
476 m_curr_frame = n; | |
477 | |
478 if (verbose) | |
479 { | |
480 const std::shared_ptr<stack_frame> elt = m_cs[n]; | |
481 | |
482 elt->display_stopped_in_message (octave_stdout); | |
483 } | |
484 } | |
485 | |
486 return retval; | |
487 } | |
488 | |
489 std::size_t call_stack::find_current_user_frame (void) const | |
490 { | |
491 std::size_t user_frame = m_curr_frame; | |
492 | |
493 std::shared_ptr<stack_frame> frm = m_cs[user_frame]; | |
494 | |
495 if (! (frm->is_user_fcn_frame () || frm->is_user_script_frame () | |
496 || frm->is_scope_frame ())) | |
497 { | |
498 frm = frm->static_link (); | |
499 | |
500 user_frame = frm->index (); | |
501 } | |
502 | |
503 return user_frame; | |
504 } | |
505 | |
506 std::shared_ptr<stack_frame> call_stack::current_user_frame (void) const | |
507 { | |
508 std::size_t frame = find_current_user_frame (); | |
509 | |
510 return m_cs[frame]; | |
511 } | |
512 | |
513 // Go to the Nth frame (up if N is negative or down if positive) in | |
514 // the call stack that corresponds to a script, function, or scope | |
515 // beginning with the frame indexed by START. | |
516 | |
517 std::size_t call_stack::dbupdown (std::size_t start, int n, bool verbose) | |
518 { | |
519 if (start >= m_cs.size ()) | |
520 error ("invalid stack frame"); | |
521 | |
522 // Can't go up from here. | |
523 | |
524 if (start == 0 && n < 0) | |
525 { | |
526 if (verbose) | |
527 m_cs[start]->display_stopped_in_message (octave_stdout); | |
528 | |
529 return start; | |
530 } | |
531 | |
532 std::shared_ptr<stack_frame> frm = m_cs[start]; | |
533 | |
534 if (! (frm && (frm->is_user_fcn_frame () | |
535 || frm->is_user_script_frame () | |
536 || frm->is_scope_frame ()))) | |
537 error ("call_stack::dbupdown: invalid initial frame in call stack!"); | |
538 | |
539 // Use index into the call stack to begin the search. At this point | |
540 // we iterate up or down using indexing instead of static links | |
541 // because ... FIXME: it's a bit complicated, but deserves | |
542 // explanation. May be easiest with some pictures of the call stack | |
543 // for an example or two. | |
544 | |
545 std::size_t xframe = frm->index (); | |
546 | |
547 if (n == 0) | |
548 { | |
549 if (verbose) | |
550 frm->display_stopped_in_message (octave_stdout); | |
551 | |
552 return xframe; | |
553 } | |
554 | |
555 int incr = 0; | |
556 | |
557 if (n < 0) | |
558 { | |
559 incr = -1; | |
560 n = -n; | |
561 } | |
562 else if (n > 0) | |
563 incr = 1; | |
564 | |
565 std::size_t last_good_frame = 0; | |
566 | |
567 while (true) | |
568 { | |
569 frm = m_cs[xframe]; | |
570 | |
571 if (frm->is_user_fcn_frame () || frm->is_user_script_frame () | |
572 || frm->is_scope_frame ()) | |
573 { | |
574 last_good_frame = xframe; | |
575 | |
576 if (n == 0) | |
222 break; | 577 break; |
223 } | 578 |
224 } | 579 n--; |
225 | 580 } |
226 return retval; | 581 |
227 } | 582 xframe += incr; |
228 | 583 |
229 int call_stack::debug_user_code_line (void) const | 584 if (xframe == 0) |
230 { | 585 { |
231 int retval = -1; | 586 last_good_frame = 0; |
232 | |
233 // This should never happen... | |
234 if (m_curr_frame == 0) | |
235 return retval; | |
236 | |
237 std::size_t i = m_curr_frame; | |
238 | |
239 while (i != 0) | |
240 { | |
241 const std::shared_ptr<stack_frame> elt = m_cs[i--]; | |
242 | |
243 octave_function *f = elt->function (); | |
244 | |
245 if (f && f->is_user_code ()) | |
246 { | |
247 if (elt->line ()) | |
248 { | |
249 retval = elt->line (); | |
250 break; | |
251 } | |
252 } | |
253 } | |
254 | |
255 return retval; | |
256 } | |
257 | |
258 int call_stack::debug_user_code_column (void) const | |
259 { | |
260 int retval = -1; | |
261 | |
262 // This should never happen... | |
263 if (m_curr_frame == 0) | |
264 return retval; | |
265 | |
266 // Start looking with the caller of the calling debug function. | |
267 std::size_t i = m_curr_frame; | |
268 | |
269 while (i != 0) | |
270 { | |
271 const std::shared_ptr<stack_frame> elt = m_cs[i--]; | |
272 | |
273 octave_function *f = elt->function (); | |
274 | |
275 if (f && f->is_user_code ()) | |
276 { | |
277 if (elt->column ()) | |
278 { | |
279 retval = elt->column (); | |
280 break; | |
281 } | |
282 } | |
283 } | |
284 | |
285 return retval; | |
286 } | |
287 | |
288 std::string call_stack::get_dispatch_class (void) const | |
289 { | |
290 return m_cs[m_curr_frame]->get_dispatch_class (); | |
291 } | |
292 | |
293 void call_stack::set_dispatch_class (const std::string& class_name) | |
294 { | |
295 m_cs[m_curr_frame]->set_dispatch_class (class_name); | |
296 } | |
297 | |
298 bool call_stack::is_class_method_executing (std::string& dispatch_class) const | |
299 { | |
300 dispatch_class = ""; | |
301 | |
302 octave_function *f = current_function (); | |
303 | |
304 bool retval = (f && f->is_class_method ()); | |
305 | |
306 if (retval) | |
307 dispatch_class = f->dispatch_class (); | |
308 | |
309 return retval; | |
310 } | |
311 | |
312 bool call_stack::is_class_constructor_executing (std::string& dispatch_class) const | |
313 { | |
314 dispatch_class = ""; | |
315 | |
316 octave_function *f = current_function (); | |
317 | |
318 bool retval = (f && f->is_class_constructor ()); | |
319 | |
320 if (retval) | |
321 dispatch_class = f->dispatch_class (); | |
322 | |
323 return retval; | |
324 } | |
325 | |
326 bool call_stack::all_scripts (void) const | |
327 { | |
328 bool retval = true; | |
329 | |
330 auto p = m_cs.cend (); | |
331 | |
332 while (p != m_cs.cbegin ()) | |
333 { | |
334 const std::shared_ptr<stack_frame> elt = *(--p); | |
335 | |
336 octave_function *f = elt->function (); | |
337 | |
338 if (f && ! f->is_user_script ()) | |
339 { | |
340 retval = false; | |
341 break; | |
342 } | |
343 } | |
344 | |
345 return retval; | |
346 } | |
347 | |
348 void call_stack::get_new_frame_index_and_links | |
349 (std::size_t& new_frame_idx, std::shared_ptr<stack_frame>& parent_link, | |
350 std::shared_ptr<stack_frame>& static_link) const | |
351 { | |
352 // FIXME: is there a better way? | |
353 | |
354 std::size_t prev_frame_idx = m_curr_frame; | |
355 | |
356 new_frame_idx = m_cs.size (); | |
357 | |
358 // m_max_stack_depth should never be less than zero. | |
359 if (new_frame_idx > static_cast<std::size_t> (m_max_stack_depth)) | |
360 error ("max_stack_depth exceeded"); | |
361 | |
362 // There can't be any links to previous frames if this is the first | |
363 // frame on the stack. | |
364 | |
365 if (new_frame_idx == 0) | |
366 return; | |
367 | |
368 parent_link = m_cs[prev_frame_idx]; | |
369 | |
370 octave_function *t_fcn = parent_link->function (); | |
371 | |
372 static_link = (t_fcn | |
373 ? (t_fcn->is_user_code () | |
374 ? parent_link : parent_link->static_link ()) | |
375 : parent_link); | |
376 } | |
377 | |
378 void call_stack::push (const symbol_scope& scope) | |
379 { | |
380 std::size_t new_frame_idx; | |
381 std::shared_ptr<stack_frame> parent_link; | |
382 std::shared_ptr<stack_frame> static_link; | |
383 | |
384 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
385 | |
386 std::shared_ptr<stack_frame> | |
387 new_frame (stack_frame::create (m_evaluator, scope, new_frame_idx, | |
388 parent_link, static_link)); | |
389 | |
390 m_cs.push_back (new_frame); | |
391 | |
392 m_curr_frame = new_frame_idx; | |
393 } | |
394 | |
395 void call_stack::push (octave_user_function *fcn, | |
396 const std::shared_ptr<stack_frame>& closure_frames) | |
397 { | |
398 std::size_t new_frame_idx; | |
399 std::shared_ptr<stack_frame> parent_link; | |
400 std::shared_ptr<stack_frame> static_link; | |
401 | |
402 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
403 | |
404 std::shared_ptr<stack_frame> | |
405 new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, | |
406 parent_link, static_link, | |
407 closure_frames)); | |
408 | |
409 m_cs.push_back (new_frame); | |
410 | |
411 m_curr_frame = new_frame_idx; | |
412 } | |
413 | |
414 void call_stack::push (octave_user_function *fcn, | |
415 const stack_frame::local_vars_map& local_vars, | |
416 const std::shared_ptr<stack_frame>& closure_frames) | |
417 { | |
418 std::size_t new_frame_idx; | |
419 std::shared_ptr<stack_frame> parent_link; | |
420 std::shared_ptr<stack_frame> static_link; | |
421 | |
422 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
423 | |
424 std::shared_ptr<stack_frame> | |
425 new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, | |
426 parent_link, static_link, local_vars, | |
427 closure_frames)); | |
428 | |
429 m_cs.push_back (new_frame); | |
430 | |
431 m_curr_frame = new_frame_idx; | |
432 } | |
433 | |
434 void call_stack::push (octave_user_script *script) | |
435 { | |
436 std::size_t new_frame_idx; | |
437 std::shared_ptr<stack_frame> parent_link; | |
438 std::shared_ptr<stack_frame> static_link; | |
439 | |
440 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
441 | |
442 std::shared_ptr<stack_frame> | |
443 new_frame (stack_frame::create (m_evaluator, script, new_frame_idx, | |
444 parent_link, static_link)); | |
445 | |
446 m_cs.push_back (new_frame); | |
447 | |
448 m_curr_frame = new_frame_idx; | |
449 } | |
450 | |
451 void call_stack::push (octave_function *fcn) | |
452 { | |
453 std::size_t new_frame_idx; | |
454 std::shared_ptr<stack_frame> parent_link; | |
455 std::shared_ptr<stack_frame> static_link; | |
456 | |
457 get_new_frame_index_and_links (new_frame_idx, parent_link, static_link); | |
458 | |
459 std::shared_ptr<stack_frame> | |
460 new_frame (stack_frame::create (m_evaluator, fcn, new_frame_idx, | |
461 parent_link, static_link)); | |
462 | |
463 m_cs.push_back (new_frame); | |
464 | |
465 m_curr_frame = new_frame_idx; | |
466 } | |
467 | |
468 bool call_stack::goto_frame (std::size_t n, bool verbose) | |
469 { | |
470 bool retval = false; | |
471 | |
472 if (n < m_cs.size ()) | |
473 { | |
474 retval = true; | |
475 | |
476 m_curr_frame = n; | |
477 | |
478 if (verbose) | |
479 { | |
480 const std::shared_ptr<stack_frame> elt = m_cs[n]; | |
481 | |
482 elt->display_stopped_in_message (octave_stdout); | |
483 } | |
484 } | |
485 | |
486 return retval; | |
487 } | |
488 | |
489 std::size_t call_stack::find_current_user_frame (void) const | |
490 { | |
491 std::size_t user_frame = m_curr_frame; | |
492 | |
493 std::shared_ptr<stack_frame> frm = m_cs[user_frame]; | |
494 | |
495 if (! (frm->is_user_fcn_frame () || frm->is_user_script_frame () | |
496 || frm->is_scope_frame ())) | |
497 { | |
498 frm = frm->static_link (); | |
499 | |
500 user_frame = frm->index (); | |
501 } | |
502 | |
503 return user_frame; | |
504 } | |
505 | |
506 std::shared_ptr<stack_frame> call_stack::current_user_frame (void) const | |
507 { | |
508 std::size_t frame = find_current_user_frame (); | |
509 | |
510 return m_cs[frame]; | |
511 } | |
512 | |
513 // Go to the Nth frame (up if N is negative or down if positive) in | |
514 // the call stack that corresponds to a script, function, or scope | |
515 // beginning with the frame indexed by START. | |
516 | |
517 std::size_t call_stack::dbupdown (std::size_t start, int n, bool verbose) | |
518 { | |
519 if (start >= m_cs.size ()) | |
520 error ("invalid stack frame"); | |
521 | |
522 // Can't go up from here. | |
523 | |
524 if (start == 0 && n < 0) | |
525 { | |
526 if (verbose) | |
527 m_cs[start]->display_stopped_in_message (octave_stdout); | |
528 | |
529 return start; | |
530 } | |
531 | |
532 std::shared_ptr<stack_frame> frm = m_cs[start]; | |
533 | |
534 if (! (frm && (frm->is_user_fcn_frame () | |
535 || frm->is_user_script_frame () | |
536 || frm->is_scope_frame ()))) | |
537 error ("call_stack::dbupdown: invalid initial frame in call stack!"); | |
538 | |
539 // Use index into the call stack to begin the search. At this point | |
540 // we iterate up or down using indexing instead of static links | |
541 // because ... FIXME: it's a bit complicated, but deserves | |
542 // explanation. May be easiest with some pictures of the call stack | |
543 // for an example or two. | |
544 | |
545 std::size_t xframe = frm->index (); | |
546 | |
547 if (n == 0) | |
548 { | |
549 if (verbose) | |
550 frm->display_stopped_in_message (octave_stdout); | |
551 | |
552 return xframe; | |
553 } | |
554 | |
555 int incr = 0; | |
556 | |
557 if (n < 0) | |
558 { | |
559 incr = -1; | |
560 n = -n; | |
561 } | |
562 else if (n > 0) | |
563 incr = 1; | |
564 | |
565 std::size_t last_good_frame = 0; | |
566 | |
567 while (true) | |
568 { | |
569 frm = m_cs[xframe]; | |
570 | |
571 if (frm->is_user_fcn_frame () || frm->is_user_script_frame () | |
572 || frm->is_scope_frame ()) | |
573 { | |
574 last_good_frame = xframe; | |
575 | |
576 if (n == 0) | |
577 break; | |
578 | |
579 n--; | |
580 } | |
581 | |
582 xframe += incr; | |
583 | |
584 if (xframe == 0) | |
585 { | |
586 last_good_frame = 0; | |
587 break; | |
588 } | |
589 | |
590 if (xframe == m_cs.size ()) | |
591 break; | 587 break; |
592 } | 588 } |
593 | 589 |
594 if (verbose) | 590 if (xframe == m_cs.size ()) |
595 m_cs[last_good_frame]->display_stopped_in_message (octave_stdout); | 591 break; |
596 | 592 } |
597 return last_good_frame; | 593 |
598 } | 594 if (verbose) |
599 | 595 m_cs[last_good_frame]->display_stopped_in_message (octave_stdout); |
600 // Like dbupdown above but find the starting frame automatically from | 596 |
601 // the current frame. If the current frame is already a user | 597 return last_good_frame; |
602 // function, script, or scope frame, use that. Otherwise, follow | 598 } |
603 // the static link for the current frame. If that is not a user | 599 |
604 // function, script or scope frame then there is an error in the | 600 // Like dbupdown above but find the starting frame automatically from |
605 // implementation. | 601 // the current frame. If the current frame is already a user |
606 | 602 // function, script, or scope frame, use that. Otherwise, follow |
607 std::size_t call_stack::dbupdown (int n, bool verbose) | 603 // the static link for the current frame. If that is not a user |
608 { | 604 // function, script or scope frame then there is an error in the |
609 std::size_t start = find_current_user_frame (); | 605 // implementation. |
610 | 606 |
611 return dbupdown (start, n, verbose); | 607 std::size_t call_stack::dbupdown (int n, bool verbose) |
612 } | 608 { |
613 | 609 std::size_t start = find_current_user_frame (); |
614 // May be used to temporarily change the value ov m_curr_frame inside | 610 |
615 // a function like evalin. If used in a function like dbup, the new | 611 return dbupdown (start, n, verbose); |
616 // value of m_curr_frame would be wiped out when dbup returns and the | 612 } |
617 // stack frame for dbup is popped. | 613 |
618 | 614 // May be used to temporarily change the value ov m_curr_frame inside |
619 void call_stack::goto_caller_frame (void) | 615 // a function like evalin. If used in a function like dbup, the new |
620 { | 616 // value of m_curr_frame would be wiped out when dbup returns and the |
621 std::size_t start = find_current_user_frame (); | 617 // stack frame for dbup is popped. |
622 | 618 |
623 std::shared_ptr<stack_frame> caller_frame = m_cs[start]->static_link (); | 619 void call_stack::goto_caller_frame (void) |
624 | 620 { |
625 // Allow evalin ('caller', ...) to work when called from the | 621 std::size_t start = find_current_user_frame (); |
626 // top-level prompt. | 622 |
627 | 623 std::shared_ptr<stack_frame> caller_frame = m_cs[start]->static_link (); |
628 m_curr_frame = caller_frame ? caller_frame->index () : 0; | 624 |
629 } | 625 // Allow evalin ('caller', ...) to work when called from the |
630 | 626 // top-level prompt. |
631 void call_stack::goto_base_frame (void) | 627 |
632 { | 628 m_curr_frame = caller_frame ? caller_frame->index () : 0; |
633 if (m_curr_frame > 0) | 629 } |
634 m_curr_frame = 0; | 630 |
635 } | 631 void call_stack::goto_base_frame (void) |
636 | 632 { |
637 std::list<std::shared_ptr<stack_frame>> | 633 if (m_curr_frame > 0) |
638 call_stack::backtrace_frames (octave_idx_type& curr_user_frame) const | 634 m_curr_frame = 0; |
639 { | 635 } |
640 std::list<std::shared_ptr<stack_frame>> frames; | 636 |
641 | 637 std::list<std::shared_ptr<stack_frame>> |
642 // curr_frame is the index to the current frame in the overall call | 638 call_stack::backtrace_frames (octave_idx_type& curr_user_frame) const |
643 // stack, which includes any compiled function frames and scope | 639 { |
644 // frames. The curr_user_frame value we set is the index into the | 640 std::list<std::shared_ptr<stack_frame>> frames; |
645 // subset of frames returned in the octave_map object. | 641 |
646 | 642 // curr_frame is the index to the current frame in the overall call |
647 std::size_t curr_frame = find_current_user_frame (); | 643 // stack, which includes any compiled function frames and scope |
648 | 644 // frames. The curr_user_frame value we set is the index into the |
649 // Don't include top-level stack frame in the list. | 645 // subset of frames returned in the octave_map object. |
650 | 646 |
651 for (std::size_t n = m_cs.size () - 1; n > 0; n--) | 647 std::size_t curr_frame = find_current_user_frame (); |
652 { | 648 |
653 std::shared_ptr<stack_frame> frm = m_cs[n]; | 649 // Don't include top-level stack frame in the list. |
654 | 650 |
655 if (frm->is_user_script_frame () || frm->is_user_fcn_frame () | 651 for (std::size_t n = m_cs.size () - 1; n > 0; n--) |
656 || frm->is_scope_frame ()) | 652 { |
657 { | 653 std::shared_ptr<stack_frame> frm = m_cs[n]; |
658 if (frm->index () == curr_frame) | 654 |
659 curr_user_frame = frames.size (); | 655 if (frm->is_user_script_frame () || frm->is_user_fcn_frame () |
660 | 656 || frm->is_scope_frame ()) |
661 frames.push_back (frm); | 657 { |
662 } | 658 if (frm->index () == curr_frame) |
663 | 659 curr_user_frame = frames.size (); |
664 if (n == 0) | 660 |
665 break; | 661 frames.push_back (frm); |
666 } | 662 } |
667 | 663 |
668 return frames; | 664 if (n == 0) |
669 } | 665 break; |
670 | 666 } |
671 std::list<std::shared_ptr<stack_frame>> | 667 |
672 call_stack::backtrace_frames (void) const | 668 return frames; |
673 { | 669 } |
674 octave_idx_type curr_user_frame = -1; | 670 |
675 | 671 std::list<std::shared_ptr<stack_frame>> |
676 return backtrace_frames (curr_user_frame); | 672 call_stack::backtrace_frames (void) const |
677 } | 673 { |
678 | 674 octave_idx_type curr_user_frame = -1; |
679 std::list<frame_info> | 675 |
680 call_stack::backtrace_info (octave_idx_type& curr_user_frame, | 676 return backtrace_frames (curr_user_frame); |
681 bool print_subfn) const | 677 } |
682 { | 678 |
683 std::list<std::shared_ptr<stack_frame>> frames | 679 std::list<frame_info> |
684 = backtrace_frames (curr_user_frame); | 680 call_stack::backtrace_info (octave_idx_type& curr_user_frame, |
685 | 681 bool print_subfn) const |
686 std::list<frame_info> retval; | 682 { |
687 | 683 std::list<std::shared_ptr<stack_frame>> frames |
688 for (const auto& frm : frames) | 684 = backtrace_frames (curr_user_frame); |
689 { | 685 |
690 if (frm->is_user_script_frame () || frm->is_user_fcn_frame () | 686 std::list<frame_info> retval; |
691 || frm->is_scope_frame ()) | 687 |
692 { | 688 for (const auto& frm : frames) |
693 retval.push_back (frame_info (frm->fcn_file_name (), | 689 { |
694 frm->fcn_name (print_subfn), | 690 if (frm->is_user_script_frame () || frm->is_user_fcn_frame () |
695 frm->line (), frm->column ())); | 691 || frm->is_scope_frame ()) |
696 } | 692 { |
697 } | 693 retval.push_back (frame_info (frm->fcn_file_name (), |
698 | 694 frm->fcn_name (print_subfn), |
699 return retval; | 695 frm->line (), frm->column ())); |
700 } | 696 } |
701 | 697 } |
702 std::list<frame_info> call_stack::backtrace_info (void) const | 698 |
703 { | 699 return retval; |
704 octave_idx_type curr_user_frame = -1; | 700 } |
705 | 701 |
706 return backtrace_info (curr_user_frame, true); | 702 std::list<frame_info> call_stack::backtrace_info (void) const |
707 } | 703 { |
708 | 704 octave_idx_type curr_user_frame = -1; |
709 octave_map call_stack::backtrace (octave_idx_type& curr_user_frame, | 705 |
710 bool print_subfn) const | 706 return backtrace_info (curr_user_frame, true); |
711 { | 707 } |
712 std::list<std::shared_ptr<stack_frame>> frames | 708 |
713 = backtrace_frames (curr_user_frame); | 709 octave_map call_stack::backtrace (octave_idx_type& curr_user_frame, |
714 | 710 bool print_subfn) const |
715 std::size_t nframes = frames.size (); | 711 { |
716 | 712 std::list<std::shared_ptr<stack_frame>> frames |
717 octave_map retval (dim_vector (nframes, 1), bt_fields); | 713 = backtrace_frames (curr_user_frame); |
718 | 714 |
719 Cell& file = retval.contents (0); | 715 std::size_t nframes = frames.size (); |
720 Cell& name = retval.contents (1); | 716 |
721 Cell& line = retval.contents (2); | 717 octave_map retval (dim_vector (nframes, 1), bt_fields); |
722 Cell& column = retval.contents (3); | 718 |
723 | 719 Cell& file = retval.contents (0); |
724 octave_idx_type k = 0; | 720 Cell& name = retval.contents (1); |
725 | 721 Cell& line = retval.contents (2); |
726 for (const auto& frm : frames) | 722 Cell& column = retval.contents (3); |
727 { | 723 |
728 if (frm->is_user_script_frame () || frm->is_user_fcn_frame () | 724 octave_idx_type k = 0; |
729 || frm->is_scope_frame ()) | 725 |
730 { | 726 for (const auto& frm : frames) |
731 file(k) = frm->fcn_file_name (); | 727 { |
732 name(k) = frm->fcn_name (print_subfn); | 728 if (frm->is_user_script_frame () || frm->is_user_fcn_frame () |
733 line(k) = frm->line (); | 729 || frm->is_scope_frame ()) |
734 column(k) = frm->column (); | 730 { |
735 | 731 file(k) = frm->fcn_file_name (); |
736 k++; | 732 name(k) = frm->fcn_name (print_subfn); |
737 } | 733 line(k) = frm->line (); |
738 } | 734 column(k) = frm->column (); |
739 | 735 |
740 return retval; | 736 k++; |
741 } | 737 } |
742 | 738 } |
743 octave_map call_stack::backtrace (void) const | 739 |
744 { | 740 return retval; |
745 octave_idx_type curr_user_frame = -1; | 741 } |
746 | 742 |
747 return backtrace (curr_user_frame, true); | 743 octave_map call_stack::backtrace (void) const |
748 } | 744 { |
749 | 745 octave_idx_type curr_user_frame = -1; |
750 octave_map call_stack::empty_backtrace (void) const | 746 |
751 { | 747 return backtrace (curr_user_frame, true); |
752 return octave_map (dim_vector (0, 1), bt_fields); | 748 } |
753 } | 749 |
754 | 750 octave_map call_stack::empty_backtrace (void) const |
755 void call_stack::pop (void) | 751 { |
756 { | 752 return octave_map (dim_vector (0, 1), bt_fields); |
757 // Never pop top scope. | 753 } |
758 // FIXME: is it possible for this case to happen? | 754 |
759 | 755 void call_stack::pop (void) |
760 if (m_cs.size () > 1) | 756 { |
761 { | 757 // Never pop top scope. |
762 std::shared_ptr<stack_frame> elt = m_cs.back (); | 758 // FIXME: is it possible for this case to happen? |
763 | 759 |
764 std::shared_ptr<stack_frame> caller = elt->parent_link (); | 760 if (m_cs.size () > 1) |
765 | 761 { |
766 m_curr_frame = caller->index (); | 762 std::shared_ptr<stack_frame> elt = m_cs.back (); |
767 | 763 |
768 if (elt->is_closure_context ()) | 764 std::shared_ptr<stack_frame> caller = elt->parent_link (); |
769 elt->break_closure_cycles (elt); | 765 |
770 | 766 m_curr_frame = caller->index (); |
771 m_cs.pop_back (); | 767 |
772 } | 768 if (elt->is_closure_context ()) |
773 } | 769 elt->break_closure_cycles (elt); |
774 | 770 |
775 void call_stack::clear (void) | 771 m_cs.pop_back (); |
776 { | 772 } |
777 while (! m_cs.empty ()) | 773 } |
778 pop (); | 774 |
779 } | 775 void call_stack::clear (void) |
780 | 776 { |
781 symbol_info_list call_stack::all_variables (void) | 777 while (! m_cs.empty ()) |
782 { | 778 pop (); |
783 return m_cs[m_curr_frame]->all_variables (); | 779 } |
784 } | 780 |
785 | 781 symbol_info_list call_stack::all_variables (void) |
786 std::list<std::string> call_stack::global_variable_names (void) const | 782 { |
787 { | 783 return m_cs[m_curr_frame]->all_variables (); |
788 std::list<std::string> retval; | 784 } |
789 | 785 |
790 for (const auto& nm_ov : m_global_values) | 786 std::list<std::string> call_stack::global_variable_names (void) const |
791 { | 787 { |
792 if (nm_ov.second.is_defined ()) | 788 std::list<std::string> retval; |
793 retval.push_back (nm_ov.first); | 789 |
794 } | 790 for (const auto& nm_ov : m_global_values) |
795 | 791 { |
796 retval.sort (); | 792 if (nm_ov.second.is_defined ()) |
797 | 793 retval.push_back (nm_ov.first); |
798 return retval; | 794 } |
799 } | 795 |
800 | 796 retval.sort (); |
801 std::list<std::string> call_stack::top_level_variable_names (void) const | 797 |
802 { | 798 return retval; |
803 return m_cs[0]->variable_names (); | 799 } |
804 } | 800 |
805 | 801 std::list<std::string> call_stack::top_level_variable_names (void) const |
806 std::list<std::string> call_stack::variable_names (void) const | 802 { |
807 { | 803 return m_cs[0]->variable_names (); |
808 return m_cs[m_curr_frame]->variable_names (); | 804 } |
809 } | 805 |
810 | 806 std::list<std::string> call_stack::variable_names (void) const |
811 void call_stack::clear_global_variable (const std::string& name) | 807 { |
812 { | 808 return m_cs[m_curr_frame]->variable_names (); |
813 auto p = m_global_values.find (name); | 809 } |
814 | 810 |
815 if (p != m_global_values.end ()) | 811 void call_stack::clear_global_variable (const std::string& name) |
816 p->second = octave_value (); | 812 { |
817 } | 813 auto p = m_global_values.find (name); |
818 | 814 |
819 void call_stack::clear_global_variable_pattern (const std::string& pattern) | 815 if (p != m_global_values.end ()) |
820 { | 816 p->second = octave_value (); |
821 glob_match pat (pattern); | 817 } |
822 | 818 |
823 for (auto& nm_ov : m_global_values) | 819 void call_stack::clear_global_variable_pattern (const std::string& pattern) |
824 { | 820 { |
825 if (pat.match (nm_ov.first)) | 821 glob_match pat (pattern); |
826 nm_ov.second = octave_value (); | 822 |
827 } | 823 for (auto& nm_ov : m_global_values) |
828 } | 824 { |
829 | 825 if (pat.match (nm_ov.first)) |
830 void call_stack::clear_global_variable_regexp (const std::string& pattern) | 826 nm_ov.second = octave_value (); |
831 { | 827 } |
832 regexp pat (pattern); | 828 } |
833 | 829 |
834 for (auto& nm_ov : m_global_values) | 830 void call_stack::clear_global_variable_regexp (const std::string& pattern) |
835 { | 831 { |
836 if (pat.is_match (nm_ov.first)) | 832 regexp pat (pattern); |
837 nm_ov.second = octave_value (); | 833 |
838 } | 834 for (auto& nm_ov : m_global_values) |
839 } | 835 { |
840 | 836 if (pat.is_match (nm_ov.first)) |
841 void call_stack::clear_global_variables (void) | 837 nm_ov.second = octave_value (); |
842 { | 838 } |
843 for (auto& nm_ov : m_global_values) | 839 } |
844 nm_ov.second = octave_value (); | 840 |
845 } | 841 void call_stack::clear_global_variables (void) |
846 | 842 { |
847 symbol_info_list | 843 for (auto& nm_ov : m_global_values) |
848 call_stack::glob_symbol_info (const std::string& pattern) const | 844 nm_ov.second = octave_value (); |
849 { | 845 } |
850 return m_cs[m_curr_frame]->glob_symbol_info (pattern); | 846 |
851 } | 847 symbol_info_list |
852 | 848 call_stack::glob_symbol_info (const std::string& pattern) const |
853 symbol_info_list | 849 { |
854 call_stack::regexp_symbol_info (const std::string& pattern) const | 850 return m_cs[m_curr_frame]->glob_symbol_info (pattern); |
855 { | 851 } |
856 return m_cs[m_curr_frame]->regexp_symbol_info (pattern); | 852 |
857 } | 853 symbol_info_list |
858 | 854 call_stack::regexp_symbol_info (const std::string& pattern) const |
859 symbol_info_list call_stack::get_symbol_info (void) | 855 { |
860 { | 856 return m_cs[m_curr_frame]->regexp_symbol_info (pattern); |
861 return m_cs[m_curr_frame]->get_symbol_info (); | 857 } |
862 } | 858 |
863 | 859 symbol_info_list call_stack::get_symbol_info (void) |
864 symbol_info_list call_stack::top_scope_symbol_info (void) const | 860 { |
865 { | 861 return m_cs[m_curr_frame]->get_symbol_info (); |
866 return m_cs[0]->get_symbol_info (); | 862 } |
867 } | 863 |
868 | 864 symbol_info_list call_stack::top_scope_symbol_info (void) const |
869 octave_value call_stack::max_stack_depth (const octave_value_list& args, | 865 { |
870 int nargout) | 866 return m_cs[0]->get_symbol_info (); |
871 { | 867 } |
872 return set_internal_variable (m_max_stack_depth, args, nargout, | 868 |
873 "max_stack_depth", 0); | 869 octave_value call_stack::max_stack_depth (const octave_value_list& args, |
874 } | 870 int nargout) |
875 | 871 { |
876 void call_stack::make_persistent (const symbol_record& sym) | 872 return set_internal_variable (m_max_stack_depth, args, nargout, |
877 { | 873 "max_stack_depth", 0); |
878 m_cs[m_curr_frame]->make_persistent (sym); | 874 } |
879 } | 875 |
880 | 876 void call_stack::make_persistent (const symbol_record& sym) |
881 void call_stack::make_global (const symbol_record& sym) | 877 { |
882 { | 878 m_cs[m_curr_frame]->make_persistent (sym); |
883 m_cs[m_curr_frame]->make_global (sym); | 879 } |
884 } | 880 |
885 | 881 void call_stack::make_global (const symbol_record& sym) |
886 octave_value call_stack::global_varval (const std::string& name) const | 882 { |
887 { | 883 m_cs[m_curr_frame]->make_global (sym); |
888 auto p = m_global_values.find (name); | 884 } |
889 | 885 |
890 return p == m_global_values.end () ? octave_value () : p->second; | 886 octave_value call_stack::global_varval (const std::string& name) const |
891 } | 887 { |
892 | 888 auto p = m_global_values.find (name); |
893 octave_value& call_stack::global_varref (const std::string& name) | 889 |
894 { | 890 return p == m_global_values.end () ? octave_value () : p->second; |
895 return m_global_values[name]; | 891 } |
896 } | 892 |
897 | 893 octave_value& call_stack::global_varref (const std::string& name) |
898 octave_value call_stack::get_top_level_value (const std::string& name) const | 894 { |
899 { | 895 return m_global_values[name]; |
900 return m_cs[0]->varval (name); | 896 } |
901 } | 897 |
902 | 898 octave_value call_stack::get_top_level_value (const std::string& name) const |
903 void call_stack::set_top_level_value (const std::string& name, | 899 { |
904 const octave_value& value) | 900 return m_cs[0]->varval (name); |
905 { | 901 } |
906 m_cs[0]->assign (name, value); | 902 |
907 } | 903 void call_stack::set_top_level_value (const std::string& name, |
908 | 904 const octave_value& value) |
909 octave_value call_stack::do_who (int argc, const string_vector& argv, | 905 { |
910 bool return_list, bool verbose) | 906 m_cs[0]->assign (name, value); |
911 { | 907 } |
912 octave_value retval; | 908 |
913 | 909 octave_value call_stack::do_who (int argc, const string_vector& argv, |
914 std::string my_name = argv[0]; | 910 bool return_list, bool verbose) |
915 | 911 { |
916 std::string file_name; | 912 octave_value retval; |
917 | 913 |
918 bool from_file = false; | 914 std::string my_name = argv[0]; |
919 bool global_only = false; | 915 |
920 bool have_regexp = false; | 916 std::string file_name; |
921 | 917 |
922 int i = 1; | 918 bool from_file = false; |
923 while (i < argc) | 919 bool global_only = false; |
924 { | 920 bool have_regexp = false; |
925 if (argv[i] == "-file") | 921 |
926 { | 922 int i = 1; |
927 if (from_file) | 923 while (i < argc) |
928 error ("%s: -file option may only be specified once", | 924 { |
929 my_name.c_str ()); | 925 if (argv[i] == "-file") |
930 | 926 { |
931 from_file = true; | 927 if (from_file) |
932 | 928 error ("%s: -file option may only be specified once", |
933 if (i == argc - 1) | 929 my_name.c_str ()); |
934 error ("%s: -file argument must be followed by a filename", | 930 |
935 my_name.c_str ()); | 931 from_file = true; |
936 | 932 |
937 file_name = argv[++i]; | 933 if (i == argc - 1) |
938 } | 934 error ("%s: -file argument must be followed by a filename", |
939 else if (argv[i] == "-regexp") | 935 my_name.c_str ()); |
940 { | 936 |
941 have_regexp = true; | 937 file_name = argv[++i]; |
942 } | 938 } |
943 else if (argv[i] == "global") | 939 else if (argv[i] == "-regexp") |
944 global_only = true; | 940 { |
945 else if (argv[i][0] == '-') | 941 have_regexp = true; |
946 warning ("%s: unrecognized option '%s'", my_name.c_str (), | 942 } |
947 argv[i].c_str ()); | 943 else if (argv[i] == "global") |
948 else | 944 global_only = true; |
949 break; | 945 else if (argv[i][0] == '-') |
950 | 946 warning ("%s: unrecognized option '%s'", my_name.c_str (), |
951 i++; | 947 argv[i].c_str ()); |
952 } | 948 else |
953 | 949 break; |
954 int npatterns = argc - i; | 950 |
955 string_vector patterns; | 951 i++; |
956 if (npatterns > 0) | 952 } |
957 { | 953 |
958 patterns.resize (npatterns); | 954 int npatterns = argc - i; |
959 for (int j = 0; j < npatterns; j++) | 955 string_vector patterns; |
960 patterns[j] = argv[i+j]; | 956 if (npatterns > 0) |
961 } | 957 { |
962 else | 958 patterns.resize (npatterns); |
963 { | 959 for (int j = 0; j < npatterns; j++) |
964 patterns.resize (1); | 960 patterns[j] = argv[i+j]; |
965 patterns[0] = "*"; | 961 } |
966 } | 962 else |
967 | 963 { |
968 if (from_file) | 964 patterns.resize (1); |
969 { | 965 patterns[0] = "*"; |
970 // FIXME: This is an inefficient manner to implement this as the | 966 } |
971 // variables are loaded in to a temporary context and then treated. | 967 |
972 // It would be better to refactor symbol_info_list to not store the | 968 if (from_file) |
973 // symbol records and then use it in load-save.cc (do_load) to | 969 { |
974 // implement this option there so that the variables are never | 970 // FIXME: This is an inefficient manner to implement this as the |
975 // stored at all. | 971 // variables are loaded in to a temporary context and then treated. |
976 | 972 // It would be better to refactor symbol_info_list to not store the |
977 // Set up temporary scope. | 973 // symbol records and then use it in load-save.cc (do_load) to |
978 | 974 // implement this option there so that the variables are never |
979 symbol_scope tmp_scope ("$dummy_scope$"); | 975 // stored at all. |
980 | 976 |
981 push (tmp_scope); | 977 // Set up temporary scope. |
982 | 978 |
983 unwind_action restore_scope ([=] (void) { pop (); }); | 979 symbol_scope tmp_scope ("$dummy_scope$"); |
984 | 980 |
985 feval ("load", octave_value (file_name), 0); | 981 push (tmp_scope); |
986 | 982 |
987 std::string newmsg = "Variables in the file " + file_name + ":\n\n"; | 983 unwind_action restore_scope ([=] (void) { pop (); }); |
988 | 984 |
989 if (global_only) | 985 feval ("load", octave_value (file_name), 0); |
990 return do_global_who_two (patterns, have_regexp, return_list, | 986 |
991 verbose, newmsg); | 987 std::string newmsg = "Variables in the file " + file_name + ":\n\n"; |
992 else | 988 |
993 return do_who_two (patterns, have_regexp, return_list, verbose, | 989 if (global_only) |
994 newmsg); | 990 return do_global_who_two (patterns, have_regexp, return_list, |
995 } | 991 verbose, newmsg); |
996 else | 992 else |
997 { | 993 return do_who_two (patterns, have_regexp, return_list, verbose, |
998 if (global_only) | 994 newmsg); |
999 return do_global_who_two (patterns, have_regexp, return_list, | 995 } |
1000 verbose); | 996 else |
1001 else | 997 { |
1002 return do_who_two (patterns, have_regexp, return_list, verbose); | 998 if (global_only) |
1003 } | 999 return do_global_who_two (patterns, have_regexp, return_list, |
1004 } | 1000 verbose); |
1005 | 1001 else |
1006 octave_value call_stack::do_who_two (const string_vector& patterns, | 1002 return do_who_two (patterns, have_regexp, return_list, verbose); |
1007 bool have_regexp, bool return_list, | 1003 } |
1008 bool verbose, const std::string& msg) | 1004 } |
1009 { | 1005 |
1010 return m_cs[m_curr_frame]->who (patterns, have_regexp, return_list, | 1006 octave_value call_stack::do_who_two (const string_vector& patterns, |
1011 verbose, m_evaluator.whos_line_format (), | 1007 bool have_regexp, bool return_list, |
1012 msg); | 1008 bool verbose, const std::string& msg) |
1013 } | 1009 { |
1014 | 1010 return m_cs[m_curr_frame]->who (patterns, have_regexp, return_list, |
1015 octave_value call_stack::do_global_who_two (const string_vector& patterns, | 1011 verbose, m_evaluator.whos_line_format (), |
1016 bool have_regexp, | 1012 msg); |
1017 bool return_list, bool verbose, | 1013 } |
1018 const std::string& msg) | 1014 |
1019 { | 1015 octave_value call_stack::do_global_who_two (const string_vector& patterns, |
1020 symbol_info_list symbol_stats; | 1016 bool have_regexp, |
1021 std::list<std::string> symbol_names; | 1017 bool return_list, bool verbose, |
1022 | 1018 const std::string& msg) |
1023 octave_idx_type npatterns = patterns.numel (); | 1019 { |
1024 | 1020 symbol_info_list symbol_stats; |
1025 for (octave_idx_type j = 0; j < npatterns; j++) | 1021 std::list<std::string> symbol_names; |
1026 { | 1022 |
1027 std::string pattern = patterns[j]; | 1023 octave_idx_type npatterns = patterns.numel (); |
1028 | 1024 |
1029 std::list<std::string> tmp; | 1025 for (octave_idx_type j = 0; j < npatterns; j++) |
1030 | 1026 { |
1031 if (have_regexp) | 1027 std::string pattern = patterns[j]; |
1032 { | 1028 |
1033 regexp pat (pattern); | 1029 std::list<std::string> tmp; |
1034 | 1030 |
1035 for (auto& nm_ov : m_global_values) | 1031 if (have_regexp) |
1036 { | 1032 { |
1037 if (pat.is_match (nm_ov.first)) | 1033 regexp pat (pattern); |
1038 tmp.push_back (nm_ov.first); | 1034 |
1039 } | 1035 for (auto& nm_ov : m_global_values) |
1040 } | 1036 { |
1041 else | 1037 if (pat.is_match (nm_ov.first)) |
1042 { | 1038 tmp.push_back (nm_ov.first); |
1043 glob_match pat (pattern); | 1039 } |
1044 | 1040 } |
1045 for (auto& nm_ov : m_global_values) | 1041 else |
1046 { | 1042 { |
1047 if (pat.match (nm_ov.first)) | 1043 glob_match pat (pattern); |
1048 tmp.push_back (nm_ov.first); | 1044 |
1049 } | 1045 for (auto& nm_ov : m_global_values) |
1050 } | 1046 { |
1051 | 1047 if (pat.match (nm_ov.first)) |
1052 for (const auto& nm : tmp) | 1048 tmp.push_back (nm_ov.first); |
1053 { | 1049 } |
1054 octave_value value = m_global_values[nm]; | 1050 } |
1055 | 1051 |
1056 if (value.is_defined ()) | 1052 for (const auto& nm : tmp) |
1057 { | 1053 { |
1058 if (verbose) | 1054 octave_value value = m_global_values[nm]; |
1059 { | 1055 |
1060 bool is_formal = false; | 1056 if (value.is_defined ()) |
1061 bool is_global = true; | 1057 { |
1062 bool is_persistent = false; | 1058 if (verbose) |
1063 | 1059 { |
1064 symbol_info syminf (nm, value, is_formal, is_global, | 1060 bool is_formal = false; |
1065 is_persistent); | 1061 bool is_global = true; |
1066 | 1062 bool is_persistent = false; |
1067 symbol_stats.append (syminf); | 1063 |
1068 } | 1064 symbol_info syminf (nm, value, is_formal, is_global, |
1069 else | 1065 is_persistent); |
1070 symbol_names.push_back (nm); | 1066 |
1071 } | 1067 symbol_stats.append (syminf); |
1072 } | 1068 } |
1073 } | 1069 else |
1074 | 1070 symbol_names.push_back (nm); |
1075 if (return_list) | 1071 } |
1076 { | 1072 } |
1077 if (verbose) | 1073 } |
1078 { | 1074 |
1079 std::string caller_fcn_name; | 1075 if (return_list) |
1080 octave_function *caller_fcn = caller_function (); | 1076 { |
1081 if (caller_fcn) | 1077 if (verbose) |
1082 caller_fcn_name = caller_fcn->name (); | 1078 { |
1083 | 1079 std::string caller_fcn_name; |
1084 return symbol_stats.map_value (caller_fcn_name, 1); | 1080 octave_function *caller_fcn = caller_function (); |
1085 } | 1081 if (caller_fcn) |
1086 else | 1082 caller_fcn_name = caller_fcn->name (); |
1087 return Cell (string_vector (symbol_names)); | 1083 |
1088 } | 1084 return symbol_stats.map_value (caller_fcn_name, 1); |
1089 else if (! (symbol_stats.empty () && symbol_names.empty ())) | 1085 } |
1090 { | 1086 else |
1091 if (msg.empty ()) | 1087 return Cell (string_vector (symbol_names)); |
1092 octave_stdout << "Global variables:\n\n"; | 1088 } |
1093 else | 1089 else if (! (symbol_stats.empty () && symbol_names.empty ())) |
1094 octave_stdout << msg; | 1090 { |
1095 | 1091 if (msg.empty ()) |
1096 if (verbose) | 1092 octave_stdout << "Global variables:\n\n"; |
1097 symbol_stats.display (octave_stdout, | 1093 else |
1098 m_evaluator.whos_line_format ()); | 1094 octave_stdout << msg; |
1099 else | 1095 |
1100 { | 1096 if (verbose) |
1101 string_vector names (symbol_names); | 1097 symbol_stats.display (octave_stdout, |
1102 | 1098 m_evaluator.whos_line_format ()); |
1103 names.list_in_columns (octave_stdout); | 1099 else |
1104 } | 1100 { |
1105 | 1101 string_vector names (symbol_names); |
1106 octave_stdout << "\n"; | 1102 |
1107 } | 1103 names.list_in_columns (octave_stdout); |
1108 | 1104 } |
1109 return octave_value (); | 1105 |
1110 } | 1106 octave_stdout << "\n"; |
1111 | 1107 } |
1112 void call_stack::display (void) const | 1108 |
1113 { | 1109 return octave_value (); |
1114 std::ostream& os = octave_stdout; | 1110 } |
1115 | 1111 |
1116 std::size_t nframes = size (); | 1112 void call_stack::display (void) const |
1117 | 1113 { |
1118 for (std::size_t i = 0; i < nframes; i++) | 1114 std::ostream& os = octave_stdout; |
1119 { | 1115 |
1120 m_cs[i]->display (false); | 1116 std::size_t nframes = size (); |
1121 if (i < nframes - 1) | 1117 |
1122 os << std::endl; | 1118 for (std::size_t i = 0; i < nframes; i++) |
1123 } | 1119 { |
1124 } | 1120 m_cs[i]->display (false); |
1125 | 1121 if (i < nframes - 1) |
1126 void call_stack::set_auto_fcn_var (stack_frame::auto_var_type avt, | 1122 os << std::endl; |
1127 const octave_value& val) | 1123 } |
1128 { | 1124 } |
1129 m_cs[m_curr_frame]->set_auto_fcn_var (avt, val); | 1125 |
1130 } | 1126 void call_stack::set_auto_fcn_var (stack_frame::auto_var_type avt, |
1131 | 1127 const octave_value& val) |
1132 octave_value call_stack::get_auto_fcn_var (stack_frame::auto_var_type avt) const | 1128 { |
1133 { | 1129 m_cs[m_curr_frame]->set_auto_fcn_var (avt, val); |
1134 return m_cs[m_curr_frame]->get_auto_fcn_var (avt); | 1130 } |
1135 } | 1131 |
1132 octave_value call_stack::get_auto_fcn_var (stack_frame::auto_var_type avt) const | |
1133 { | |
1134 return m_cs[m_curr_frame]->get_auto_fcn_var (avt); | |
1135 } | |
1136 | 1136 |
1137 DEFMETHOD (max_stack_depth, interp, args, nargout, | 1137 DEFMETHOD (max_stack_depth, interp, args, nargout, |
1138 doc: /* -*- texinfo -*- | 1138 doc: /* -*- texinfo -*- |
1139 @deftypefn {} {@var{val} =} max_stack_depth () | 1139 @deftypefn {} {@var{val} =} max_stack_depth () |
1140 @deftypefnx {} {@var{old_val} =} max_stack_depth (@var{new_val}) | 1140 @deftypefnx {} {@var{old_val} =} max_stack_depth (@var{new_val}) |