GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-usr-fcn.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2022 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 <sstream>
31
32#include "file-info.h"
33#include "file-ops.h"
34#include "file-stat.h"
35#include "str-vec.h"
36
37#include "builtin-defun-decls.h"
38#include "defaults.h"
39#include "Cell.h"
40#include "defun.h"
41#include "error.h"
42#include "errwarn.h"
43#include "input.h"
44#include "ovl.h"
45#include "ov-usr-fcn.h"
46#include "ov.h"
47#include "pager.h"
48#include "pt-eval.h"
49#include "pt-jump.h"
50#include "pt-misc.h"
51#include "pt-pr-code.h"
52#include "pt-stmt.h"
53#include "pt-walk.h"
54#include "symtab.h"
55#include "interpreter-private.h"
56#include "interpreter.h"
57#include "unwind-prot.h"
58#include "utils.h"
59#include "parse.h"
60#include "profiler.h"
61#include "variables.h"
62#include "ov-fcn-handle.h"
63
64// Whether to optimize subsasgn method calls.
65static bool Voptimize_subsasgn_calls = true;
66
68{
69 // This function is no longer valid, so remove the pointer to it from
70 // the corresponding scope.
71 // FIXME: would it be better to use shared/weak pointers for this job
72 // instead of storing a bare pointer in the scope object?
73 m_scope.set_user_code (nullptr);
74
75 // FIXME: shouldn't this happen automatically when deleting cmd_list?
76 if (m_cmd_list)
77 {
78 octave::event_manager& evmgr
79 = octave::__get_event_manager__ ("octave_user_code::~octave_user_code");
80
82 }
83
84 delete m_cmd_list;
85 delete m_file_info;
86}
87
88void
90{
92
94
95 if (fs && (fs.mtime () > time_parsed ()))
96 warning ("function file '%s' changed since it was parsed",
97 m_file_name.c_str ());
98}
99
100std::string
102{
103 if (! m_file_info)
104 get_file_info ();
105
106 return m_file_info->get_line (line);
107}
108
109std::deque<std::string>
110octave_user_code::get_code_lines (std::size_t line, std::size_t num_lines)
111{
112 if (! m_file_info)
113 get_file_info ();
114
115 return m_file_info->get_lines (line, num_lines);
116}
117
118void
120 const octave::sys::time& timestamp)
121{
122 if (m_file_info)
123 delete m_file_info;
124
125 if (timestamp > time_parsed ())
126 warning ("help text for function is newer than function");
127
128 m_file_info = new octave::file_info (text, timestamp);
129}
130
131std::map<std::string, octave_value>
133{
134 return std::map<std::string, octave_value> ();
135}
136
139{
140 std::map<std::string, octave_value> m
141 = {{ "scope_info", m_scope ? m_scope.dump () : "0x0" },
142 { "m_file_name", m_file_name },
143 { "time_parsed", m_t_parsed },
144 { "time_checked", m_t_checked }};
145
146 return octave_value (m);
147}
148
149
150// User defined scripts.
151
153 "user-defined script",
154 "user-defined script");
155
158{ }
159
161 (const std::string& fnm, const std::string& nm,
163 const std::string& ds)
164 : octave_user_code (fnm, nm, scope, cmds, ds)
165{
166 if (m_cmd_list)
168}
169
171 (const std::string& fnm, const std::string& nm,
172 const octave::symbol_scope& scope, const std::string& ds)
173 : octave_user_code (fnm, nm, scope, nullptr, ds)
174{ }
175
176// We must overload the call method so that we call the proper
177// push_stack_frame method, which is overloaded for pointers to
178// octave_function, octave_user_function, and octave_user_script
179// objects.
180
182octave_user_script::call (octave::tree_evaluator& tw, int nargout,
183 const octave_value_list& args)
184{
185 tw.push_stack_frame (this);
186
187 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
188
189 return execute (tw, nargout, args);
190}
191
193octave_user_script::execute (octave::tree_evaluator& tw, int nargout,
194 const octave_value_list& args)
195{
196 return tw.execute_user_script (*this, nargout, args);
197}
198
199void
201{
202 tw.visit_octave_user_script (*this);
203}
204
205// User defined functions.
206
208 "user-defined function",
209 "user-defined function");
210
211// Ugh. This really needs to be simplified (code/data?
212// extrinsic/intrinsic state?).
213
217 : octave_user_code ("", "", scope, cl, ""),
218 m_param_list (pl), m_ret_list (rl),
219 m_lead_comm (), m_trail_comm (),
220 m_location_line (0), m_location_column (0),
221 m_system_fcn_file (false),
222 m_num_named_args (m_param_list ? m_param_list->length () : 0),
223 m_subfunction (false), m_inline_function (false),
224 m_anonymous_function (false), m_nested_function (false),
225 m_class_constructor (none), m_class_method (none)
226{
227 if (m_cmd_list)
229}
230
232{
233 delete m_param_list;
234 delete m_ret_list;
235 delete m_lead_comm;
236 delete m_trail_comm;
237}
238
241{
242 m_ret_list = t;
243
244 return this;
245}
246
247// If there is no explicit end statement at the end of the function,
248// relocate the no_op that was generated for the end of file condition
249// to appear on the next line after the last statement in the file, or
250// the next line after the function keyword if there are no statements.
251// More precisely, the new location should probably be on the next line
252// after the end of the parameter list, but we aren't tracking that
253// information (yet).
254
255void
257{
258 if (m_cmd_list && ! m_cmd_list->empty ())
259 {
260 octave::tree_statement *last_stmt = m_cmd_list->back ();
261
262 if (last_stmt && last_stmt->is_end_of_fcn_or_script ()
263 && last_stmt->is_end_of_file ())
264 {
266 next_to_last_elt = m_cmd_list->rbegin ();
267
268 next_to_last_elt++;
269
270 int new_eof_line;
271 int new_eof_col;
272
273 if (next_to_last_elt == m_cmd_list->rend ())
274 {
275 new_eof_line = beginning_line ();
276 new_eof_col = beginning_column ();
277 }
278 else
279 {
280 octave::tree_statement *next_to_last_stmt = *next_to_last_elt;
281
282 new_eof_line = next_to_last_stmt->line ();
283 new_eof_col = next_to_last_stmt->column ();
284 }
285
286 last_stmt->set_location (new_eof_line + 1, new_eof_col);
287 }
288 }
289}
290
291void
293{
294 std::map<std::string, octave_value> fcns = subfunctions ();
295
296 if (! fcns.empty ())
297 {
298 for (auto& nm_fnval : fcns)
299 {
300 octave_user_function *f = nm_fnval.second.user_function_value ();
301
302 if (f)
303 f->maybe_relocate_end_internal ();
304 }
305 }
306
308}
309
310void
312{
313 m_scope.set_parent (ps);
314}
315
316std::string
318{
319 std::ostringstream result;
320
322 result << "anonymous@" << fcn_file_name ()
323 << ':' << m_location_line << ':' << m_location_column;
324 else if (is_subfunction ())
325 result << parent_fcn_name () << '>' << name ();
326 else if (is_class_method ())
327 result << '@' << dispatch_class () << '/' << name ();
329 result << '@' << name ();
330 else if (is_inline_function ())
331 result << "inline@" << fcn_file_name ()
332 << ':' << m_location_line << ':' << m_location_column;
333 else
334 result << name ();
335
336 return result.str ();
337}
338
339void
341{
342 if (! m_file_name.empty ())
343 {
344 // We really should stash the whole path to the file we found,
345 // when we looked it up, to avoid possible race conditions...
346 // FIXME
347 //
348 // We probably also don't need to get the library directory
349 // every time, but since this function is only called when the
350 // function file is parsed, it probably doesn't matter that
351 // much.
352
353 std::string ff_name = octave::fcn_file_in_path (m_file_name);
354
355 static const std::string canonical_fcn_file_dir
358 static const std::string fcn_file_dir
359 = canonical_fcn_file_dir.empty () ? octave::config::fcn_file_dir ()
360 : canonical_fcn_file_dir;
361
362 if (fcn_file_dir == ff_name.substr (0, fcn_file_dir.length ()))
363 m_system_fcn_file = true;
364 }
365 else
366 m_system_fcn_file = false;
367}
368
369void
371{
373}
374
375bool
377{
379}
380
381bool
383{
384 return (m_ret_list && m_ret_list->takes_varargs ());
385}
386
387void
389{
391
393}
394
395void
397{
399}
400
401void
403{
405}
406
407std::map<std::string, octave_value>
409{
410 return m_scope.subfunctions ();
411}
412
413// Find definition of final subfunction in list of subfuns:
414//
415// sub1>sub2>...>subN
416
418octave_user_function::find_subfunction (const std::string& subfuns_arg) const
419{
420 std::string subfuns = subfuns_arg;
421
422 std::string first_fun = subfuns;
423
424 std::size_t pos = subfuns.find ('>');
425
426 if (pos == std::string::npos)
427 subfuns = "";
428 else
429 {
430 first_fun = subfuns.substr (0, pos-1);
431 subfuns = subfuns.substr (pos+1);
432 }
433
434 octave_value ov_fcn = m_scope.find_subfunction (first_fun);
435
436 if (subfuns.empty ())
437 return ov_fcn;
438
440
441 return fcn->find_subfunction (subfuns);
442}
443
444bool
446{
447 return m_scope.has_subfunctions ();
448}
449
450void
451octave_user_function::stash_subfunction_names (const std::list<std::string>& names)
452{
454}
455
456std::list<std::string>
458{
459 return m_scope.subfunction_names ();
460}
461
464{
465 octave_value_list retval;
466
468
469 if (n > 0)
470 retval = args.slice (m_num_named_args, n);
471
472 return retval;
473}
474
475// We must overload the call method so that we call the proper
476// push_stack_frame method, which is overloaded for pointers to
477// octave_function, octave_user_function, and octave_user_script
478// objects.
479
481octave_user_function::call (octave::tree_evaluator& tw, int nargout,
482 const octave_value_list& args)
483{
484 tw.push_stack_frame (this);
485
486 octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
487
488 return execute (tw, nargout, args);
489}
490
492octave_user_function::execute (octave::tree_evaluator& tw, int nargout,
493 const octave_value_list& args)
494{
495 return tw.execute_user_function (*this, nargout, args);
496}
497
498void
500{
502}
503
506{
507 assert (is_special_expr ());
508 assert (m_cmd_list->length () == 1);
509
511 return stmt->expression ();
512}
513
514bool
516{
517 bool retval = false;
520 && m_param_list->length () > 0 && ! m_param_list->varargs_only ()
521 && m_ret_list->length () == 1 && ! m_ret_list->takes_varargs ())
522 {
525 retval = par1->name () == ret1->name ();
526 }
527
528 return retval;
529}
530
531std::string
533{
534 std::string retval;
535
536 switch (m_class_constructor)
537 {
538 case none:
539 retval = "none";
540 break;
541
542 case legacy:
543 retval = "legacy";
544 break;
545
546 case classdef:
547 retval = "classdef";
548 break;
549
550 default:
551 retval = "unrecognized enum value";
552 break;
553 }
554
555 return retval;
556}
557
558std::string
560{
561 std::string retval;
562
563 switch (m_class_method)
564 {
565 case none:
566 retval = "none";
567 break;
568
569 case legacy:
570 retval = "legacy";
571 break;
572
573 case classdef:
574 retval = "classdef";
575 break;
576
577 default:
578 retval = "unrecognized enum value";
579 break;
580 }
581
582 return retval;
583}
584
587{
588 std::map<std::string, octave_value> m
589 = {{ "user_code", octave_user_code::dump () },
590 { "line", m_location_line },
591 { "col", m_location_column },
592 { "end_line", m_end_location_line },
593 { "end_col", m_end_location_column },
594 { "system_fcn_file", m_system_fcn_file },
595 { "num_named_args", m_num_named_args },
596 { "subfunction", m_subfunction },
597 { "inline_function", m_inline_function },
598 { "anonymous_function", m_anonymous_function },
599 { "nested_function", m_nested_function },
600 { "ctor_type", ctor_type_str () },
601 { "class_method", m_class_method }};
602
603 return octave_value (m);
604}
605
606void
608{
610
612}
613
614void
616{
618
620}
621
622void
624{
625 octave::interpreter& interp
626 = octave::__get_interpreter__ ("octave_user_function::restore_warning_states");
627
628 octave::tree_evaluator& tw = interp.get_evaluator ();
629
630 octave_value val
631 = tw.get_auto_fcn_var (octave::stack_frame::SAVED_WARNING_STATES);
632
633 if (val.is_defined ())
634 {
635 // Fail spectacularly if SAVED_WARNING_STATES is not an
636 // octave_map (or octave_scalar_map) object.
637
638 if (! val.isstruct ())
640
641 octave_map m = val.map_value ();
642
643 Cell ids = m.contents ("identifier");
644 Cell states = m.contents ("state");
645
646 for (octave_idx_type i = 0; i < m.numel (); i++)
647 Fwarning (interp, ovl (states(i), ids(i)));
648 }
649}
650
651OCTAVE_NAMESPACE_BEGIN
652
653DEFMETHOD (nargin, interp, args, ,
654 doc: /* -*- texinfo -*-
655@deftypefn {} {} nargin ()
656@deftypefnx {} {} nargin (@var{fcn})
657Report the number of input arguments to a function.
658
659Called from within a function, return the number of arguments passed to the
660function. At the top level, return the number of command line arguments
661passed to Octave.
662
663If called with the optional argument @var{fcn}---a function name or
664handle---return the declared number of arguments that the function can
665accept.
666
667If the last argument to @var{fcn} is @var{varargin} the returned value is
668negative. For example, the function @code{union} for sets is declared as
669
670@example
671@group
672function [y, ia, ib] = union (a, b, varargin)
673
674and
675
676nargin ("union")
677@result{} -3
678@end group
679@end example
680
681Programming Note: @code{nargin} does not work on compiled functions
682(@file{.oct} files) such as built-in or dynamically loaded functions.
683@seealso{nargout, narginchk, varargin, inputname}
684@end deftypefn */)
685{
686 int nargin = args.length ();
687
688 if (nargin > 1)
689 print_usage ();
690
691 octave_value retval;
692
693 if (nargin == 1)
694 {
695 octave_value func = args(0);
696
697 if (func.is_string ())
698 {
699 symbol_table& symtab = interp.get_symbol_table ();
700
701 std::string name = func.string_value ();
702 func = symtab.find_function (name);
703 if (func.is_undefined ())
704 error ("nargin: invalid function name: %s", name.c_str ());
705 }
706
707 octave_function *fcn_val = func.function_value (true);
708 if (! fcn_val)
709 error ("nargin: FCN must be a string or function handle");
710
711 octave_user_function *fcn = fcn_val->user_function_value (true);
712
713 if (! fcn)
714 {
715 // Matlab gives up for histc, so maybe it's ok that we
716 // give up sometimes too?
717
718 std::string type = fcn_val->type_name ();
719 error ("nargin: number of input arguments unavailable for %s objects",
720 type.c_str ());
721 }
722
723 tree_parameter_list *m_param_list = fcn->parameter_list ();
724
725 retval = (m_param_list ? m_param_list->length () : 0);
726 if (fcn->takes_varargs ())
727 retval = -1 - retval;
728 }
729 else
730 {
731 tree_evaluator& tw = interp.get_evaluator ();
732
733 retval = tw.get_auto_fcn_var (stack_frame::NARGIN);
734
735 if (retval.is_undefined ())
736 retval = 0;
737 }
738
739 return retval;
740}
741
742DEFMETHOD (nargout, interp, args, ,
743 doc: /* -*- texinfo -*-
744@deftypefn {} {} nargout ()
745@deftypefnx {} {} nargout (@var{fcn})
746Report the number of output arguments from a function.
747
748Called from within a function, return the number of values the caller
749expects to receive. At the top level, @code{nargout} with no argument is
750undefined and will produce an error.
751
752If called with the optional argument @var{fcn}---a function name or
753handle---return the number of declared output values that the function can
754produce.
755
756If the final output argument is @var{varargout} the returned value is
757negative.
758
759For example,
760
761@example
762f ()
763@end example
764
765@noindent
766will cause @code{nargout} to return 0 inside the function @code{f} and
767
768@example
769[s, t] = f ()
770@end example
771
772@noindent
773will cause @code{nargout} to return 2 inside the function @code{f}.
774
775In the second usage,
776
777@example
778nargout (@@histc) # or nargout ("histc") using a string input
779@end example
780
781@noindent
782will return 2, because @code{histc} has two outputs, whereas
783
784@example
785nargout (@@imread)
786@end example
787
788@noindent
789will return -2, because @code{imread} has two outputs and the second is
790@var{varargout}.
791
792Programming Note. @code{nargout} does not work for built-in functions and
793returns -1 for all anonymous functions.
794@seealso{nargin, varargout, isargout, nthargout}
795@end deftypefn */)
796{
797 int nargin = args.length ();
798
799 if (nargin > 1)
800 print_usage ();
801
802 octave_value retval;
803
804 if (nargin == 1)
805 {
806 octave_value func = args(0);
807
808 if (func.is_string ())
809 {
810 symbol_table& symtab = interp.get_symbol_table ();
811
812 std::string name = func.string_value ();
813 func = symtab.find_function (name);
814 if (func.is_undefined ())
815 error ("nargout: invalid function name: %s", name.c_str ());
816 }
817
818 if (func.is_inline_function ())
819 return ovl (1);
820
821 if (func.is_function_handle ())
822 {
824
825 if (fh->is_anonymous ())
826 return ovl (-1);
827 }
828
829 octave_function *fcn_val = func.function_value (true);
830 if (! fcn_val)
831 error ("nargout: FCN must be a string or function handle");
832
833 octave_user_function *fcn = fcn_val->user_function_value (true);
834
835 if (! fcn)
836 {
837 // Matlab gives up for histc, so maybe it's ok that we
838 // give up sometimes too?
839
840 std::string type = fcn_val->type_name ();
841 error ("nargout: number of output arguments unavailable for %s objects",
842 type.c_str ());
843 }
844
845 tree_parameter_list *m_ret_list = fcn->return_list ();
846
847 retval = (m_ret_list ? m_ret_list->length () : 0);
848
849 if (fcn->takes_var_return ())
850 retval = -1 - retval;
851 }
852 else
853 {
854 if (interp.at_top_level ())
855 error ("nargout: invalid call at top level");
856
857 tree_evaluator& tw = interp.get_evaluator ();
858
859 retval = tw.get_auto_fcn_var (stack_frame::NARGOUT);
860
861 if (retval.is_undefined ())
862 retval = 0;
863 }
864
865 return retval;
866}
867
868DEFUN (optimize_subsasgn_calls, args, nargout,
869 doc: /* -*- texinfo -*-
870@deftypefn {} {@var{val} =} optimize_subsasgn_calls ()
871@deftypefnx {} {@var{old_val} =} optimize_subsasgn_calls (@var{new_val})
872@deftypefnx {} {} optimize_subsasgn_calls (@var{new_val}, "local")
873Query or set the internal flag for @code{subsasgn} method call
874optimizations.
875
876If true, Octave will attempt to eliminate the redundant copying when calling
877the @code{subsasgn} method of a user-defined class.
878
879When called from inside a function with the @qcode{"local"} option, the
880variable is changed locally for the function and any subroutines it calls.
881The original variable value is restored when exiting the function.
882@seealso{subsasgn}
883@end deftypefn */)
884{
885 return set_internal_variable (Voptimize_subsasgn_calls, args, nargout,
886 "optimize_subsasgn_calls");
887}
888
889static bool val_in_table (const Matrix& table, double val)
890{
891 if (table.isempty ())
892 return false;
893
894 octave_idx_type i = table.lookup (val, ASCENDING);
895 return (i > 0 && table(i-1) == val);
896}
897
898static bool isargout1 (int nargout, const Matrix& ignored, double k)
899{
900 if (k != math::fix (k) || k <= 0)
901 error ("isargout: K must be a positive integer");
902
903 return (k == 1 || k <= nargout) && ! val_in_table (ignored, k);
904}
905
906DEFMETHOD (isargout, interp, args, ,
907 doc: /* -*- texinfo -*-
908@deftypefn {} {} isargout (@var{k})
909Within a function, return a logical value indicating whether the argument
910@var{k} will be assigned to a variable on output.
911
912If the result is false, the argument has been ignored during the function
913call through the use of the tilde (~) special output argument. Functions
914can use @code{isargout} to avoid performing unnecessary calculations for
915outputs which are unwanted.
916
917If @var{k} is outside the range @code{1:max (nargout)}, the function returns
918false. @var{k} can also be an array, in which case the function works
919element-by-element and a logical array is returned. At the top level,
920@code{isargout} returns an error.
921@seealso{nargout, varargout, nthargout}
922@end deftypefn */)
923{
924 if (args.length () != 1)
925 print_usage ();
926
927 if (interp.at_top_level ())
928 error ("isargout: invalid call at top level");
929
930 tree_evaluator& tw = interp.get_evaluator ();
931
932 octave_value tmp;
933
934 int nargout1 = 0;
935 tmp = tw.get_auto_fcn_var (stack_frame::NARGOUT);
936 if (tmp.is_defined ())
937 nargout1 = tmp.int_value ();
938
939 Matrix ignored;
940 tmp = tw.get_auto_fcn_var (stack_frame::IGNORED);
941 if (tmp.is_defined ())
942 ignored = tmp.matrix_value ();
943
944 if (args(0).is_scalar_type ())
945 {
946 double k = args(0).double_value ();
947
948 return ovl (isargout1 (nargout1, ignored, k));
949 }
950 else if (args(0).isnumeric ())
951 {
952 const NDArray ka = args(0).array_value ();
953
954 boolNDArray r (ka.dims ());
955 for (octave_idx_type i = 0; i < ka.numel (); i++)
956 r(i) = isargout1 (nargout1, ignored, ka(i));
957
958 return ovl (r);
959 }
960 else
961 err_wrong_type_arg ("isargout", args(0));
962
963 return ovl ();
964}
965
966/*
967%!function [x, y] = try_isargout ()
968%! if (isargout (1))
969%! if (isargout (2))
970%! x = 1; y = 2;
971%! else
972%! x = -1;
973%! endif
974%! else
975%! if (isargout (2))
976%! y = -2;
977%! else
978%! error ("no outputs requested");
979%! endif
980%! endif
981%!endfunction
982%!
983%!function [a, b] = try_isargout2 (x, y)
984%! a = y;
985%! b = {isargout(1), isargout(2), x};
986%!endfunction
987%!
988%!test
989%! [x, y] = try_isargout ();
990%! assert ([x, y], [1, 2]);
991%!
992%!test
993%! [x, ~] = try_isargout ();
994%! assert (x, -1);
995%!
996%!test
997%! [~, y] = try_isargout ();
998%! assert (y, -2);
999%!
1000%!error [~, ~] = try_isargout ()
1001%!
1002## Check to see that isargout isn't sticky:
1003%!test
1004%! [x, y] = try_isargout ();
1005%! assert ([x, y], [1, 2]);
1006%!
1007## It should work without ():
1008%!test
1009%! [~, y] = try_isargout;
1010%! assert (y, -2);
1011%!
1012## It should work in function handles, anonymous functions, and cell
1013## arrays of handles or anonymous functions.
1014%!test
1015%! fh = @try_isargout;
1016%! af = @() try_isargout;
1017%! c = {fh, af};
1018%! [~, y] = fh ();
1019%! assert (y, -2);
1020%! [~, y] = af ();
1021%! assert (y, -2);
1022%! [~, y] = c{1}();
1023%! assert (y, -2);
1024%! [~, y] = c{2}();
1025%! assert (y, -2);
1026%!
1027## Nesting, anyone?
1028%!test
1029%! [~, b] = try_isargout2 (try_isargout, rand);
1030%! assert (b, {0, 1, -1});
1031%!test
1032%! [~, b] = try_isargout2 ({try_isargout, try_isargout}, rand);
1033%! assert (b, {0, 1, {-1, -1}});
1034*/
1035
1036OCTAVE_NAMESPACE_END
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:411
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:487
bool isempty(void) const
Size of the specified dimension.
Definition: Array.h:607
OCTARRAY_API octave_idx_type lookup(const T &value, sortmode mode=UNSORTED) const
Do a binary lookup in a sorted array.
Definition: Array.cc:2138
Definition: Cell.h:43
Definition: dMatrix.h:42
elt_type & back(void)
Definition: base-list.h:80
bool empty(void) const
Definition: base-list.h:50
elt_type & front(void)
Definition: base-list.h:79
std::size_t length(void) const
Definition: base-list.h:53
std::list< tree_statement * >::reverse_iterator reverse_iterator
Definition: base-list.h:46
reverse_iterator rend(void)
Definition: base-list.h:75
reverse_iterator rbegin(void)
Definition: base-list.h:71
OCTAVE_API std::string get_line(std::size_t line) const
Definition: file-info.cc:40
OCTAVE_API std::deque< std::string > get_lines(std::size_t line, std::size_t num_lines) const
Definition: file-info.cc:63
void set_user_code(octave_user_code *code)
Definition: symscope.h:603
octave_value find_subfunction(const std::string &name) const
Definition: symscope.h:511
void erase_subfunctions(void)
Definition: symscope.h:535
void unlock_subfunctions(void)
Definition: symscope.h:522
std::map< std::string, octave_value > subfunctions(void) const
Definition: symscope.h:528
void set_parent(const symbol_scope &p)
Definition: symscope.h:609
void mark_subfunctions_in_scope_as_private(const std::string &class_name)
Definition: symscope.h:541
std::list< std::string > subfunction_names(void) const
Definition: symscope.h:558
void stash_subfunction_names(const std::list< std::string > &names)
Definition: symscope.h:552
void lock_subfunctions(void)
Definition: symscope.h:516
bool has_subfunctions(void) const
Definition: symscope.h:547
octave_value dump(void) const
Definition: symscope.h:566
sys::time mtime(void) const
Definition: file-stat.h:131
tree_identifier * ident(void)
Definition: pt-decl.h:88
std::string name(void) const
Definition: pt-id.h:73
bool takes_varargs(void) const
Definition: pt-misc.h:85
void visit_octave_user_function_trailer(octave_user_function &)
Definition: pt-pr-code.cc:431
void visit_octave_user_function_header(octave_user_function &)
Definition: pt-pr-code.cc:396
void mark_as_script_body(void)
Definition: pt-stmt.h:175
void mark_as_function_body(void)
Definition: pt-stmt.h:171
bp_table::bp_lines remove_all_breakpoints(event_manager &evmgr, const std::string &file)
Definition: pt-stmt.cc:279
bool is_end_of_fcn_or_script(void) const
Definition: pt-stmt.cc:152
int column(void) const
Definition: pt-stmt.cc:127
int line(void) const
Definition: pt-stmt.cc:119
bool is_end_of_file(void) const
Definition: pt-stmt.cc:169
tree_expression * expression(void)
Definition: pt-stmt.h:101
void set_location(int l, int c)
Definition: pt-stmt.cc:135
virtual void visit_octave_user_script(octave_user_script &)
Definition: pt-walk.cc:267
virtual void visit_octave_user_function(octave_user_function &)
Definition: pt-walk.cc:275
virtual octave_user_function * user_function_value(bool silent=false)
Definition: ov-base.cc:944
virtual std::string type_name(void) const
Definition: ov-base.h:922
friend class octave_value
Definition: ov-base.h:256
bool is_anonymous(void) const
std::string dispatch_class(void) const
Definition: ov-fcn.h:149
bool is_class_method(const std::string &cname="") const
Definition: ov-fcn.h:116
bool is_class_constructor(const std::string &cname="") const
Definition: ov-fcn.h:111
virtual void mark_as_private_function(const std::string &cname="")
Definition: ov-fcn.h:156
std::string name(void) const
Definition: ov-fcn.h:207
const Cell & contents(const_iterator p) const
Definition: oct-map.h:331
octave_idx_type numel(void) const
Definition: oct-map.h:389
octave_value dump(void) const
Definition: ov-usr-fcn.cc:138
std::string fcn_file_name(void) const
Definition: ov-usr-fcn.h:106
std::string get_code_line(std::size_t line)
Definition: ov-usr-fcn.cc:101
std::string m_file_name
Definition: ov-usr-fcn.h:131
octave::sys::time m_t_checked
Definition: ov-usr-fcn.h:138
~octave_user_code(void)
Definition: ov-usr-fcn.cc:67
std::deque< std::string > get_code_lines(std::size_t line, std::size_t num_lines)
Definition: ov-usr-fcn.cc:110
octave::tree_statement_list * m_cmd_list
Definition: ov-usr-fcn.h:145
octave::sys::time m_t_parsed
Definition: ov-usr-fcn.h:134
octave::file_info * m_file_info
Definition: ov-usr-fcn.h:142
void get_file_info(void)
Definition: ov-usr-fcn.cc:89
octave::sys::time time_parsed(void) const
Definition: ov-usr-fcn.h:108
void cache_function_text(const std::string &text, const octave::sys::time &timestamp)
Definition: ov-usr-fcn.cc:119
virtual std::map< std::string, octave_value > subfunctions(void) const
Definition: ov-usr-fcn.cc:132
octave::symbol_scope m_scope
Definition: ov-usr-fcn.h:128
std::string parent_fcn_name(void) const
Definition: ov-usr-fcn.h:263
void restore_warning_states(void)
Definition: ov-usr-fcn.cc:623
octave::tree_expression * special_expr(void)
Definition: ov-usr-fcn.cc:505
void unlock_subfunctions(void)
Definition: ov-usr-fcn.cc:402
void erase_subfunctions(void)
Definition: ov-usr-fcn.cc:370
void mark_as_system_fcn_file(void)
Definition: ov-usr-fcn.cc:340
octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-usr-fcn.cc:481
bool is_special_expr(void) const
Definition: ov-usr-fcn.h:337
octave::comment_list * m_trail_comm
Definition: ov-usr-fcn.h:434
octave::tree_parameter_list * m_param_list
Definition: ov-usr-fcn.h:424
void stash_parent_fcn_scope(const octave::symbol_scope &ps)
Definition: ov-usr-fcn.cc:311
void maybe_relocate_end(void)
Definition: ov-usr-fcn.cc:292
octave_user_function * define_ret_list(octave::tree_parameter_list *t)
Definition: ov-usr-fcn.cc:240
octave_value_list all_va_args(const octave_value_list &args)
Definition: ov-usr-fcn.cc:463
void stash_subfunction_names(const std::list< std::string > &names)
Definition: ov-usr-fcn.cc:451
std::string profiler_name(void) const
Definition: ov-usr-fcn.cc:317
bool is_classdef_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:358
bool takes_varargs(void) const
Definition: ov-usr-fcn.cc:376
octave_value_list execute(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-usr-fcn.cc:492
bool takes_var_return(void) const
Definition: ov-usr-fcn.cc:382
void mark_as_private_function(const std::string &cname="")
Definition: ov-usr-fcn.cc:388
std::list< std::string > subfunction_names(void) const
Definition: ov-usr-fcn.cc:457
int beginning_column(void) const
Definition: ov-usr-fcn.h:242
class_method_type m_class_method
Definition: ov-usr-fcn.h:466
void print_code_function_header(const std::string &prefix)
Definition: ov-usr-fcn.cc:607
octave::tree_parameter_list * m_ret_list
Definition: ov-usr-fcn.h:428
void accept(octave::tree_walker &tw)
Definition: ov-usr-fcn.cc:499
octave::tree_parameter_list * parameter_list(void)
Definition: ov-usr-fcn.h:393
bool is_inline_function(void) const
Definition: ov-usr-fcn.h:318
void print_code_function_trailer(const std::string &prefix)
Definition: ov-usr-fcn.cc:615
std::map< std::string, octave_value > subfunctions(void) const
Definition: ov-usr-fcn.cc:408
bool has_subfunctions(void) const
Definition: ov-usr-fcn.cc:445
octave_value find_subfunction(const std::string &subfuns) const
Definition: ov-usr-fcn.cc:418
octave_user_function(const octave::symbol_scope &scope=octave::symbol_scope(), octave::tree_parameter_list *pl=nullptr, octave::tree_parameter_list *rl=nullptr, octave::tree_statement_list *cl=nullptr)
Definition: ov-usr-fcn.cc:215
class_method_type m_class_constructor
Definition: ov-usr-fcn.h:463
bool is_subfunction(void) const
Definition: ov-usr-fcn.h:314
bool subsasgn_optimization_ok(void)
Definition: ov-usr-fcn.cc:515
int beginning_line(void) const
Definition: ov-usr-fcn.h:241
octave::tree_parameter_list * return_list(void)
Definition: ov-usr-fcn.h:395
void lock_subfunctions(void)
Definition: ov-usr-fcn.cc:396
std::string method_type_str(void) const
Definition: ov-usr-fcn.cc:559
octave::comment_list * m_lead_comm
Definition: ov-usr-fcn.h:431
std::string ctor_type_str(void) const
Definition: ov-usr-fcn.cc:532
octave_value dump(void) const
Definition: ov-usr-fcn.cc:586
bool is_anonymous_function(void) const
Definition: ov-usr-fcn.h:322
void maybe_relocate_end_internal(void)
Definition: ov-usr-fcn.cc:256
void accept(octave::tree_walker &tw)
Definition: ov-usr-fcn.cc:200
octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-usr-fcn.cc:182
octave_value_list execute(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-usr-fcn.cc:193
octave_idx_type length(void) const
Definition: ovl.h:113
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
Definition: ovl.h:131
OCTINTERP_API octave_function * function_value(bool silent=false) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:857
OCTINTERP_API octave_fcn_handle * fcn_handle_value(bool silent=false) const
OCTINTERP_API octave_user_function * user_function_value(bool silent=false) const
bool is_string(void) const
Definition: ov.h:682
bool is_defined(void) const
Definition: ov.h:637
bool is_function_handle(void) const
Definition: ov.h:813
bool isstruct(void) const
Definition: ov.h:694
std::string string_value(bool force=false) const
Definition: ov.h:1019
OCTINTERP_API octave_map map_value(void) const
bool is_undefined(void) const
Definition: ov.h:640
bool is_inline_function(void) const
Definition: ov.h:819
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:898
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope())
Definition: symtab.cc:249
octave_value get_auto_fcn_var(stack_frame::auto_var_type avt) const
Definition: pt-eval.cc:2204
OCTINTERP_API void print_usage(void)
Definition: defun-int.h:72
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:111
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void warning(const char *fmt,...)
Definition: error.cc:1055
OCTAVE_EXPORT octave_value_list Fwarning(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: error.cc:1469
void error(const char *fmt,...)
Definition: error.cc:980
#define panic_impossible()
Definition: error.h:411
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:166
QString name
F77_RET_T const F77_DBLE const F77_DBLE * f
std::string fcn_file_dir(void)
Definition: defaults.cc:315
double fix(double x)
Definition: lo-mappers.h:118
std::string canonicalize_file_name(const std::string &name)
Definition: file-ops.cc:688
event_manager & __get_event_manager__(const std::string &who)
interpreter & __get_interpreter__(const std::string &who)
@ ASCENDING
Definition: oct-sort.h:97
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:222
static bool Voptimize_subsasgn_calls
Definition: ov-usr-fcn.cc:65
static bool val_in_table(const Matrix &table, double val)
Definition: ov-usr-fcn.cc:889
static bool isargout1(int nargout, const Matrix &ignored, double k)
Definition: ov-usr-fcn.cc:898
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
#define octave_stdout
Definition: pager.h:314
std::string fcn_file_in_path(const std::string &name)
Definition: utils.cc:739
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition: variables.cc:587