GNU Octave  6.2.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-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <sstream>
31 
32 #include "file-info.h"
33 #include "file-stat.h"
34 #include "str-vec.h"
35 
36 #include "builtin-defun-decls.h"
37 #include "defaults.h"
38 #include "Cell.h"
39 #include "defun.h"
40 #include "error.h"
41 #include "errwarn.h"
42 #include "input.h"
43 #include "ovl.h"
44 #include "ov-usr-fcn.h"
45 #include "ov.h"
46 #include "pager.h"
47 #include "pt-eval.h"
48 #include "pt-jit.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.
65 static 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 (cmd_list)
77  {
79  = octave::__get_event_manager__ ("octave_user_code::~octave_user_code");
80 
82  }
83 
84  delete cmd_list;
85  delete m_file_info;
86 }
87 
88 void
90 {
92 
94 
95  if (fs && (fs.mtime () > time_parsed ()))
96  warning ("function file '%s' changed since it was parsed",
97  file_name.c_str ());
98 }
99 
100 std::string
102 {
103  if (! m_file_info)
104  get_file_info ();
105 
106  return m_file_info->get_line (line);
107 }
108 
109 std::deque<std::string>
110 octave_user_code::get_code_lines (size_t line, 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 
118 void
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 
131 std::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  { "file_name", file_name },
143  { "time_parsed", t_parsed },
144  { "time_checked", 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 
157  : octave_user_code ()
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 (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 
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 
194  const octave_value_list& args)
195 {
196  return tw.execute_user_script (*this, nargout, args);
197 }
198 
199 void
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  param_list (pl), ret_list (rl),
219  lead_comm (), trail_comm (),
220  location_line (0), location_column (0),
221  parent_name (), system_fcn_file (false),
222  num_named_args (param_list ? param_list->length () : 0),
223  subfunction (false), inline_function (false),
224  anonymous_function (false), nested_function (false),
225  class_constructor (none), class_method (none)
226 #if defined (HAVE_LLVM)
227  , jit_info (0)
228 #endif
229 {
230  if (cmd_list)
232 }
233 
235 {
236  delete param_list;
237  delete ret_list;
238  delete lead_comm;
239  delete trail_comm;
240 
241 #if defined (HAVE_LLVM)
242  delete jit_info;
243 #endif
244 }
245 
248 {
249  ret_list = t;
250 
251  return this;
252 }
253 
254 // If there is no explicit end statement at the end of the function,
255 // relocate the no_op that was generated for the end of file condition
256 // to appear on the next line after the last statement in the file, or
257 // the next line after the function keyword if there are no statements.
258 // More precisely, the new location should probably be on the next line
259 // after the end of the parameter list, but we aren't tracking that
260 // information (yet).
261 
262 void
264 {
265  if (cmd_list && ! cmd_list->empty ())
266  {
267  octave::tree_statement *last_stmt = cmd_list->back ();
268 
269  if (last_stmt && last_stmt->is_end_of_fcn_or_script ()
270  && last_stmt->is_end_of_file ())
271  {
273  next_to_last_elt = cmd_list->rbegin ();
274 
275  next_to_last_elt++;
276 
277  int new_eof_line;
278  int new_eof_col;
279 
280  if (next_to_last_elt == cmd_list->rend ())
281  {
282  new_eof_line = beginning_line ();
283  new_eof_col = beginning_column ();
284  }
285  else
286  {
287  octave::tree_statement *next_to_last_stmt = *next_to_last_elt;
288 
289  new_eof_line = next_to_last_stmt->line ();
290  new_eof_col = next_to_last_stmt->column ();
291  }
292 
293  last_stmt->set_location (new_eof_line + 1, new_eof_col);
294  }
295  }
296 }
297 
298 void
300 {
301  std::map<std::string, octave_value> fcns = subfunctions ();
302 
303  if (! fcns.empty ())
304  {
305  for (auto& nm_fnval : fcns)
306  {
307  octave_user_function *f = nm_fnval.second.user_function_value ();
308 
309  if (f)
310  f->maybe_relocate_end_internal ();
311  }
312  }
313 
315 }
316 
317 void
319 {
320  m_scope.set_parent (ps);
321 }
322 
323 std::string
325 {
326  std::ostringstream result;
327 
328  if (is_anonymous_function ())
329  result << "anonymous@" << fcn_file_name ()
330  << ':' << location_line << ':' << location_column;
331  else if (is_subfunction ())
332  result << parent_fcn_name () << '>' << name ();
333  else if (is_class_method ())
334  result << '@' << dispatch_class () << '/' << name ();
336  result << '@' << name ();
337  else if (is_inline_function ())
338  result << "inline@" << fcn_file_name ()
339  << ':' << location_line << ':' << location_column;
340  else
341  result << name ();
342 
343  return result.str ();
344 }
345 
346 void
348 {
349  if (! file_name.empty ())
350  {
351  // We really should stash the whole path to the file we found,
352  // when we looked it up, to avoid possible race conditions...
353  // FIXME
354  //
355  // We probably also don't need to get the library directory
356  // every time, but since this function is only called when the
357  // function file is parsed, it probably doesn't matter that
358  // much.
359 
360  std::string ff_name = octave::fcn_file_in_path (file_name);
361 
363  if (fcn_file_dir == ff_name.substr (0, fcn_file_dir.length ()))
364  system_fcn_file = true;
365  }
366  else
367  system_fcn_file = false;
368 }
369 
370 void
372 {
374 }
375 
376 bool
378 {
379  return (param_list && param_list->takes_varargs ());
380 }
381 
382 bool
384 {
385  return (ret_list && ret_list->takes_varargs ());
386 }
387 
388 void
390 {
392 
394 }
395 
396 void
398 {
400 }
401 
402 void
404 {
406 }
407 
408 std::map<std::string, octave_value>
410 {
411  return m_scope.subfunctions ();
412 }
413 
414 // Find definition of final subfunction in list of subfuns:
415 //
416 // sub1>sub2>...>subN
417 
419 octave_user_function::find_subfunction (const std::string& subfuns_arg) const
420 {
421  std::string subfuns = subfuns_arg;
422 
423  std::string first_fun = subfuns;
424 
425  size_t pos = subfuns.find ('>');
426 
427  if (pos == std::string::npos)
428  subfuns = "";
429  else
430  {
431  first_fun = subfuns.substr (0, pos-1);
432  subfuns = subfuns.substr (pos+1);
433  }
434 
435  octave_value ov_fcn = m_scope.find_subfunction (first_fun);
436 
437  if (subfuns.empty ())
438  return ov_fcn;
439 
440  octave_user_function *fcn = ov_fcn.user_function_value ();
441 
442  return fcn->find_subfunction (subfuns);
443 }
444 
445 bool
447 {
448  return m_scope.has_subfunctions ();
449 }
450 
451 void
452 octave_user_function::stash_subfunction_names (const std::list<std::string>& names)
453 {
455 }
456 
457 std::list<std::string>
459 {
460  return m_scope.subfunction_names ();
461 }
462 
465 {
467 
469 
470  if (n > 0)
471  retval = args.slice (num_named_args, n);
472 
473  return retval;
474 }
475 
476 // We must overload the call method so that we call the proper
477 // push_stack_frame method, which is overloaded for pointers to
478 // octave_function, octave_user_function, and octave_user_script
479 // objects.
480 
483  const octave_value_list& args)
484 {
485  tw.push_stack_frame (this);
486 
487  octave::unwind_action act ([&tw] () { tw.pop_stack_frame (); });
488 
489  return execute (tw, nargout, args);
490 }
491 
494  const octave_value_list& args)
495 {
496  return tw.execute_user_function (*this, nargout, args);
497 }
498 
499 void
501 {
502  tw.visit_octave_user_function (*this);
503 }
504 
507 {
508  assert (is_special_expr ());
509  assert (cmd_list->length () == 1);
510 
512  return stmt->expression ();
513 }
514 
515 bool
517 {
518  bool retval = false;
520  && param_list && ret_list
521  && param_list->length () > 0 && ! param_list->varargs_only ()
522  && ret_list->length () == 1 && ! ret_list->takes_varargs ())
523  {
526  retval = par1->name () == ret1->name ();
527  }
528 
529  return retval;
530 }
531 
532 std::string
534 {
535  std::string retval;
536 
537  switch (class_constructor)
538  {
539  case none:
540  retval = "none";
541  break;
542 
543  case legacy:
544  retval = "legacy";
545  break;
546 
547  case classdef:
548  retval = "classdef";
549  break;
550 
551  default:
552  retval = "unrecognized enum value";
553  break;
554  }
555 
556  return retval;
557 }
558 
559 std::string
561 {
562  std::string retval;
563 
564  switch (class_method)
565  {
566  case none:
567  retval = "none";
568  break;
569 
570  case legacy:
571  retval = "legacy";
572  break;
573 
574  case classdef:
575  retval = "classdef";
576  break;
577 
578  default:
579  retval = "unrecognized enum value";
580  break;
581  }
582 
583  return retval;
584 }
585 
588 {
589  std::map<std::string, octave_value> m
590  = {{ "user_code", octave_user_code::dump () },
591  { "line", location_line },
592  { "col", location_column },
593  { "end_line", end_location_line },
594  { "end_col", end_location_column },
595  { "parent_name", parent_name },
596  { "system_fcn_file", system_fcn_file },
597  { "num_named_args", num_named_args },
598  { "subfunction", subfunction },
599  { "inline_function", inline_function },
600  { "anonymous_function", anonymous_function },
601  { "nested_function", nested_function },
602  { "ctor_type", ctor_type_str () },
603  { "class_method", class_method }};
604 
605  return octave_value (m);
606 }
607 
608 void
610 {
612 
614 }
615 
616 void
618 {
620 
622 }
623 
624 void
626 {
627  octave::interpreter& interp
628  = octave::__get_interpreter__ ("octave_user_function::restore_warning_states");
629 
630  octave::tree_evaluator& tw = interp.get_evaluator ();
631 
632  octave_value val
634 
635  if (val.is_defined ())
636  {
637  // Fail spectacularly if SAVED_WARNING_STATES is not an
638  // octave_map (or octave_scalar_map) object.
639 
640  if (! val.isstruct ())
641  panic_impossible ();
642 
643  octave_map m = val.map_value ();
644 
645  Cell ids = m.contents ("identifier");
646  Cell states = m.contents ("state");
647 
648  for (octave_idx_type i = 0; i < m.numel (); i++)
649  Fwarning (interp, ovl (states(i), ids(i)));
650  }
651 }
652 
653 DEFMETHOD (nargin, interp, args, ,
654  doc: /* -*- texinfo -*-
655 @deftypefn {} {} nargin ()
656 @deftypefnx {} {} nargin (@var{fcn})
657 Report the number of input arguments to a function.
658 
659 Called from within a function, return the number of arguments passed to the
660 function. At the top level, return the number of command line arguments
661 passed to Octave.
662 
663 If called with the optional argument @var{fcn}---a function name or
664 handle---return the declared number of arguments that the function can
665 accept.
666 
667 If the last argument to @var{fcn} is @var{varargin} the returned value is
668 negative. For example, the function @code{union} for sets is declared as
669 
670 @example
671 @group
672 function [y, ia, ib] = union (a, b, varargin)
673 
674 and
675 
676 nargin ("union")
677 @result{} -3
678 @end group
679 @end example
680 
681 Programming 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 
692 
693  if (nargin == 1)
694  {
695  octave_value func = args(0);
696 
697  if (func.is_string ())
698  {
699  octave::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  octave::tree_parameter_list *param_list = fcn->parameter_list ();
724 
725  retval = (param_list ? param_list->length () : 0);
726  if (fcn->takes_varargs ())
727  retval = -1 - retval;
728  }
729  else
730  {
731  octave::tree_evaluator& tw = interp.get_evaluator ();
732 
734 
735  if (retval.is_undefined ())
736  retval = 0;
737  }
738 
739  return retval;
740 }
741 
742 DEFMETHOD (nargout, interp,args, ,
743  doc: /* -*- texinfo -*-
744 @deftypefn {} {} nargout ()
745 @deftypefnx {} {} nargout (@var{fcn})
746 Report the number of output arguments from a function.
747 
748 Called from within a function, return the number of values the caller
749 expects to receive. At the top level, @code{nargout} with no argument is
750 undefined and will produce an error.
751 
752 If called with the optional argument @var{fcn}---a function name or
753 handle---return the number of declared output values that the function can
754 produce.
755 
756 If the final output argument is @var{varargout} the returned value is
757 negative.
758 
759 For example,
760 
761 @example
762 f ()
763 @end example
764 
765 @noindent
766 will 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
773 will cause @code{nargout} to return 2 inside the function @code{f}.
774 
775 In the second usage,
776 
777 @example
778 nargout (@@histc) # or nargout ("histc") using a string input
779 @end example
780 
781 @noindent
782 will return 2, because @code{histc} has two outputs, whereas
783 
784 @example
785 nargout (@@imread)
786 @end example
787 
788 @noindent
789 will return -2, because @code{imread} has two outputs and the second is
790 @var{varargout}.
791 
792 Programming Note. @code{nargout} does not work for built-in functions and
793 returns -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 
803 
804  if (nargin == 1)
805  {
806  octave_value func = args(0);
807 
808  if (func.is_string ())
809  {
810  octave::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  {
823  octave_fcn_handle *fh = func.fcn_handle_value ();
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  octave::tree_parameter_list *ret_list = fcn->return_list ();
846 
847  retval = (ret_list ? 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  octave::tree_evaluator& tw = interp.get_evaluator ();
858 
860 
861  if (retval.is_undefined ())
862  retval = 0;
863  }
864 
865  return retval;
866 }
867 
868 DEFUN (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")
873 Query or set the internal flag for @code{subsasgn} method call
874 optimizations.
875 
876 If true, Octave will attempt to eliminate the redundant copying when calling
877 the @code{subsasgn} method of a user-defined class.
878 
879 When called from inside a function with the @qcode{"local"} option, the
880 variable is changed locally for the function and any subroutines it calls.
881 The original variable value is restored when exiting the function.
882 @seealso{subsasgn}
883 @end deftypefn */)
884 {
885  return SET_INTERNAL_VARIABLE (optimize_subsasgn_calls);
886 }
887 
888 static bool val_in_table (const Matrix& table, double val)
889 {
890  if (table.isempty ())
891  return false;
892 
893  octave_idx_type i = table.lookup (val, ASCENDING);
894  return (i > 0 && table(i-1) == val);
895 }
896 
897 static bool isargout1 (int nargout, const Matrix& ignored, double k)
898 {
899  if (k != octave::math::fix (k) || k <= 0)
900  error ("isargout: K must be a positive integer");
901 
902  return (k == 1 || k <= nargout) && ! val_in_table (ignored, k);
903 }
904 
905 DEFMETHOD (isargout, interp, args, ,
906  doc: /* -*- texinfo -*-
907 @deftypefn {} {} isargout (@var{k})
908 Within a function, return a logical value indicating whether the argument
909 @var{k} will be assigned to a variable on output.
910 
911 If the result is false, the argument has been ignored during the function
912 call through the use of the tilde (~) special output argument. Functions
913 can use @code{isargout} to avoid performing unnecessary calculations for
914 outputs which are unwanted.
915 
916 If @var{k} is outside the range @code{1:max (nargout)}, the function returns
917 false. @var{k} can also be an array, in which case the function works
918 element-by-element and a logical array is returned. At the top level,
919 @code{isargout} returns an error.
920 @seealso{nargout, varargout, nthargout}
921 @end deftypefn */)
922 {
923  if (args.length () != 1)
924  print_usage ();
925 
926  if (interp.at_top_level ())
927  error ("isargout: invalid call at top level");
928 
929  octave::tree_evaluator& tw = interp.get_evaluator ();
930 
931  octave_value tmp;
932 
933  int nargout1 = 0;
935  if (tmp.is_defined ())
936  nargout1 = tmp.int_value ();
937 
938  Matrix ignored;
940  if (tmp.is_defined ())
941  ignored = tmp.matrix_value ();
942 
943  if (args(0).is_scalar_type ())
944  {
945  double k = args(0).double_value ();
946 
947  return ovl (isargout1 (nargout1, ignored, k));
948  }
949  else if (args(0).isnumeric ())
950  {
951  const NDArray ka = args(0).array_value ();
952 
953  boolNDArray r (ka.dims ());
954  for (octave_idx_type i = 0; i < ka.numel (); i++)
955  r(i) = isargout1 (nargout1, ignored, ka(i));
956 
957  return ovl (r);
958  }
959  else
960  err_wrong_type_arg ("isargout", args(0));
961 
962  return ovl ();
963 }
964 
965 /*
966 %!function [x, y] = try_isargout ()
967 %! if (isargout (1))
968 %! if (isargout (2))
969 %! x = 1; y = 2;
970 %! else
971 %! x = -1;
972 %! endif
973 %! else
974 %! if (isargout (2))
975 %! y = -2;
976 %! else
977 %! error ("no outputs requested");
978 %! endif
979 %! endif
980 %!endfunction
981 %!
982 %!function [a, b] = try_isargout2 (x, y)
983 %! a = y;
984 %! b = {isargout(1), isargout(2), x};
985 %!endfunction
986 %!
987 %!test
988 %! [x, y] = try_isargout ();
989 %! assert ([x, y], [1, 2]);
990 %!
991 %!test
992 %! [x, ~] = try_isargout ();
993 %! assert (x, -1);
994 %!
995 %!test
996 %! [~, y] = try_isargout ();
997 %! assert (y, -2);
998 %!
999 %!error [~, ~] = try_isargout ()
1000 %!
1001 ## Check to see that isargout isn't sticky:
1002 %!test
1003 %! [x, y] = try_isargout ();
1004 %! assert ([x, y], [1, 2]);
1005 %!
1006 ## It should work without ():
1007 %!test
1008 %! [~, y] = try_isargout;
1009 %! assert (y, -2);
1010 %!
1011 ## It should work in function handles, anonymous functions, and cell
1012 ## arrays of handles or anonymous functions.
1013 %!test
1014 %! fh = @try_isargout;
1015 %! af = @() try_isargout;
1016 %! c = {fh, af};
1017 %! [~, y] = fh ();
1018 %! assert (y, -2);
1019 %! [~, y] = af ();
1020 %! assert (y, -2);
1021 %! [~, y] = c{1}();
1022 %! assert (y, -2);
1023 %! [~, y] = c{2}();
1024 %! assert (y, -2);
1025 %!
1026 ## Nesting, anyone?
1027 %!test
1028 %! [~, b] = try_isargout2 (try_isargout, rand);
1029 %! assert (b, {0, 1, -1});
1030 %!test
1031 %! [~, b] = try_isargout2 ({try_isargout, try_isargout}, rand);
1032 %! assert (b, {0, 1, {-1, -1}});
1033 */
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
octave_idx_type lookup(const T &value, sortmode mode=UNSORTED) const
Do a binary lookup in a sorted array.
Definition: Array.cc:2145
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:453
bool isempty(void) const
Size of the specified dimension.
Definition: Array.h:572
Definition: Cell.h:43
Definition: dMatrix.h:42
bool empty(void) const
Definition: base-list.h:50
size_t length(void) const
Definition: base-list.h:53
elt_type & front(void)
Definition: base-list.h:79
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
elt_type & back(void)
Definition: base-list.h:80
Provides threadsafe access to octave.
std::string get_line(size_t line) const
Definition: file-info.cc:40
std::deque< std::string > get_lines(size_t line, size_t num_lines) const
Definition: file-info.cc:63
tree_evaluator & get_evaluator(void)
std::map< std::string, octave_value > subfunctions(void) const
Definition: symscope.h:536
void set_user_code(octave_user_code *code)
Definition: symscope.h:617
octave_value find_subfunction(const std::string &name) const
Definition: symscope.h:519
std::list< std::string > subfunction_names(void) const
Definition: symscope.h:566
void erase_subfunctions(void)
Definition: symscope.h:543
void unlock_subfunctions(void)
Definition: symscope.h:530
void set_parent(const symbol_scope &p)
Definition: symscope.h:623
void mark_subfunctions_in_scope_as_private(const std::string &class_name)
Definition: symscope.h:549
void stash_subfunction_names(const std::list< std::string > &names)
Definition: symscope.h:560
void lock_subfunctions(void)
Definition: symscope.h:524
bool has_subfunctions(void) const
Definition: symscope.h:555
octave_value dump(void) const
Definition: symscope.h:574
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope())
Definition: symtab.cc:249
sys::time mtime(void) const
Definition: file-stat.h:131
tree_identifier * ident(void)
Definition: pt-decl.h:88
octave_value_list execute_user_script(octave_user_script &user_script, int nargout, const octave_value_list &args)
Definition: pt-eval.cc:2628
octave_value_list execute_user_function(octave_user_function &user_function, int nargout, const octave_value_list &args)
Definition: pt-eval.cc:2673
void pop_stack_frame(void)
Definition: pt-eval.cc:1860
octave_value get_auto_fcn_var(stack_frame::auto_var_type avt) const
Definition: pt-eval.cc:1594
void push_stack_frame(const symbol_scope &scope)
Definition: pt-eval.cc:1833
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:363
void visit_octave_user_function_header(octave_user_function &)
Definition: pt-pr-code.cc:328
void mark_as_script_body(void)
Definition: pt-stmt.h:175
bp_table::intmap remove_all_breakpoints(event_manager &evmgr, const std::string &file)
Definition: pt-stmt.cc:281
void mark_as_function_body(void)
Definition: pt-stmt.h:171
bool is_end_of_fcn_or_script(void) const
Definition: pt-stmt.cc:150
int column(void) const
Definition: pt-stmt.cc:125
int line(void) const
Definition: pt-stmt.cc:117
tree_expression * expression(void)
Definition: pt-stmt.h:101
bool is_end_of_file(void) const
Definition: pt-stmt.cc:167
void set_location(int l, int c)
Definition: pt-stmt.cc:133
virtual void visit_octave_user_script(octave_user_script &)
Definition: pt-walk.cc:177
virtual void visit_octave_user_function(octave_user_function &)
Definition: pt-walk.cc:185
virtual octave_user_function * user_function_value(bool silent=false)
Definition: ov-base.cc:882
virtual std::string type_name(void) const
Definition: ov-base.h:874
friend class octave_value
Definition: ov-base.h:228
bool is_anonymous(void) const
std::string dispatch_class(void) const
Definition: ov-fcn.h:151
bool is_class_method(const std::string &cname="") const
Definition: ov-fcn.h:118
bool is_class_constructor(const std::string &cname="") const
Definition: ov-fcn.h:113
virtual void mark_as_private_function(const std::string &cname="")
Definition: ov-fcn.h:158
std::string name(void) const
Definition: ov-fcn.h:214
octave_value dump(void) const
Definition: ov-usr-fcn.cc:138
std::string get_code_line(size_t line)
Definition: ov-usr-fcn.cc:101
std::string fcn_file_name(void) const
Definition: ov-usr-fcn.h:110
~octave_user_code(void)
Definition: ov-usr-fcn.cc:67
std::string file_name
Definition: ov-usr-fcn.h:135
octave::file_info * m_file_info
Definition: ov-usr-fcn.h:146
void get_file_info(void)
Definition: ov-usr-fcn.cc:89
octave::sys::time time_parsed(void) const
Definition: ov-usr-fcn.h:112
void cache_function_text(const std::string &text, const octave::sys::time &timestamp)
Definition: ov-usr-fcn.cc:119
std::deque< std::string > get_code_lines(size_t line, size_t num_lines)
Definition: ov-usr-fcn.cc:110
octave::sys::time t_parsed
Definition: ov-usr-fcn.h:138
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:132
octave::sys::time t_checked
Definition: ov-usr-fcn.h:142
octave::tree_statement_list * cmd_list
Definition: ov-usr-fcn.h:149
std::string parent_fcn_name(void) const
Definition: ov-usr-fcn.h:269
std::string parent_name
Definition: ov-usr-fcn.h:450
void restore_warning_states(void)
Definition: ov-usr-fcn.cc:625
octave::tree_parameter_list * ret_list
Definition: ov-usr-fcn.h:435
octave::tree_expression * special_expr(void)
Definition: ov-usr-fcn.cc:506
void unlock_subfunctions(void)
Definition: ov-usr-fcn.cc:403
void erase_subfunctions(void)
Definition: ov-usr-fcn.cc:371
void mark_as_system_fcn_file(void)
Definition: ov-usr-fcn.cc:347
octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-usr-fcn.cc:482
octave::comment_list * trail_comm
Definition: ov-usr-fcn.h:441
bool is_special_expr(void) const
Definition: ov-usr-fcn.h:338
octave::tree_parameter_list * return_list(void)
Definition: ov-usr-fcn.h:396
void stash_parent_fcn_scope(const octave::symbol_scope &ps)
Definition: ov-usr-fcn.cc:318
void maybe_relocate_end(void)
Definition: ov-usr-fcn.cc:299
octave_user_function * define_ret_list(octave::tree_parameter_list *t)
Definition: ov-usr-fcn.cc:247
octave_value_list all_va_args(const octave_value_list &args)
Definition: ov-usr-fcn.cc:464
void stash_subfunction_names(const std::list< std::string > &names)
Definition: ov-usr-fcn.cc:452
std::string profiler_name(void) const
Definition: ov-usr-fcn.cc:324
bool is_classdef_constructor(const std::string &cname="") const
Definition: ov-usr-fcn.h:359
bool takes_varargs(void) const
Definition: ov-usr-fcn.cc:377
octave_value_list execute(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition: ov-usr-fcn.cc:493
octave::tree_parameter_list * parameter_list(void)
Definition: ov-usr-fcn.h:394
bool takes_var_return(void) const
Definition: ov-usr-fcn.cc:383
class_method_type class_constructor
Definition: ov-usr-fcn.h:476
void mark_as_private_function(const std::string &cname="")
Definition: ov-usr-fcn.cc:389
std::list< std::string > subfunction_names(void) const
Definition: ov-usr-fcn.cc:458
int beginning_column(void) const
Definition: ov-usr-fcn.h:246
void print_code_function_header(const std::string &prefix)
Definition: ov-usr-fcn.cc:609
void accept(octave::tree_walker &tw)
Definition: ov-usr-fcn.cc:500
octave::jit_function_info * jit_info
Definition: ov-usr-fcn.h:482
bool is_inline_function(void) const
Definition: ov-usr-fcn.h:319
void print_code_function_trailer(const std::string &prefix)
Definition: ov-usr-fcn.cc:617
std::map< std::string, octave_value > subfunctions(void) const
Definition: ov-usr-fcn.cc:409
bool has_subfunctions(void) const
Definition: ov-usr-fcn.cc:446
octave::comment_list * lead_comm
Definition: ov-usr-fcn.h:438
octave_value find_subfunction(const std::string &subfuns) const
Definition: ov-usr-fcn.cc:419
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
bool is_subfunction(void) const
Definition: ov-usr-fcn.h:315
bool subsasgn_optimization_ok(void)
Definition: ov-usr-fcn.cc:516
int beginning_line(void) const
Definition: ov-usr-fcn.h:245
void lock_subfunctions(void)
Definition: ov-usr-fcn.cc:397
std::string method_type_str(void) const
Definition: ov-usr-fcn.cc:560
std::string ctor_type_str(void) const
Definition: ov-usr-fcn.cc:533
octave::tree_parameter_list * param_list
Definition: ov-usr-fcn.h:431
octave_value dump(void) const
Definition: ov-usr-fcn.cc:587
bool is_anonymous_function(void) const
Definition: ov-usr-fcn.h:323
class_method_type class_method
Definition: ov-usr-fcn.h:479
void maybe_relocate_end_internal(void)
Definition: ov-usr-fcn.cc:263
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
octave_user_function * user_function_value(bool silent=false) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:765
bool is_string(void) const
Definition: ov.h:593
bool is_defined(void) const
Definition: ov.h:551
bool is_function_handle(void) const
Definition: ov.h:721
octave_function * function_value(bool silent=false) const
bool isstruct(void) const
Definition: ov.h:605
octave_fcn_handle * fcn_handle_value(bool silent=false) const
std::string string_value(bool force=false) const
Definition: ov.h:927
octave_map map_value(void) const
bool is_undefined(void) const
Definition: ov.h:554
bool is_inline_function(void) const
Definition: ov.h:727
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:806
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:138
#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:1050
OCTAVE_EXPORT octave_value_list Fwarning(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: error.cc:1462
void error(const char *fmt,...)
Definition: error.cc:968
#define panic_impossible()
Definition: error.h:380
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
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
T * r
Definition: mx-inlines.cc:773
std::string fcn_file_dir(void)
Definition: defaults.cc:315
double fix(double x)
Definition: lo-mappers.h:118
interpreter & __get_interpreter__(const std::string &who)
event_manager & __get_event_manager__(const std::string &who)
std::string fcn_file_in_path(const std::string &name)
Definition: utils.cc:592
@ ASCENDING
Definition: oct-sort.h:95
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:180
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:888
static bool isargout1(int nargout, const Matrix &ignored, double k)
Definition: ov-usr-fcn.cc:897
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
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:313
#define SET_INTERNAL_VARIABLE(NM)
Definition: variables.h:103