GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
variables.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2024 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 <cstdio>
31 #include <cstring>
32 
33 #include <iomanip>
34 #include <list>
35 #include <set>
36 #include <string>
37 
38 #include "file-stat.h"
39 #include "oct-env.h"
40 #include "file-ops.h"
41 #include "glob-match.h"
42 #include "lo-regexp.h"
43 #include "str-vec.h"
44 
45 #include "Cell.h"
46 #include "defun.h"
47 #include "error.h"
48 #include "errwarn.h"
49 #include "event-manager.h"
50 #include "help.h"
51 #include "input.h"
52 #include "interpreter-private.h"
53 #include "interpreter.h"
54 #include "lex.h"
55 #include "load-path.h"
57 #include "oct-map.h"
58 #include "ovl.h"
59 #include "ov.h"
60 #include "ov-class.h"
61 #include "ov-usr-fcn.h"
62 #include "pager.h"
63 #include "pt-eval.h"
64 #include "syminfo.h"
65 #include "symtab.h"
66 #include "sysdep.h"
67 #include "unwind-prot.h"
68 #include "utils.h"
69 #include "variables.h"
70 
71 // Attributes of variables and functions.
72 
73 // Is this octave_value a valid function?
74 
76 is_valid_function (const std::string& fcn_name,
77  const std::string& warn_for, bool warn)
78 {
79  octave_function *ans = nullptr;
80 
81  if (! fcn_name.empty ())
82  {
83  octave::symbol_table& symtab = octave::__get_symbol_table__ ();
84 
85  octave_value val = symtab.find_function (fcn_name);
86 
87  if (val.is_defined ())
88  ans = val.function_value (true);
89  }
90 
91  // FIXME: Should this be "err" and "error_for", rather than warn?
92  if (! ans && warn)
93  error ("%s: the symbol '%s' is not valid as a function",
94  warn_for.c_str (), fcn_name.c_str ());
95 
96  return ans;
97 }
98 
101  const std::string& warn_for, bool warn)
102 {
103  octave_function *ans = nullptr;
104 
105  std::string fcn_name;
106 
107  if (arg.is_string ())
108  {
109  fcn_name = arg.string_value ();
110 
111  ans = is_valid_function (fcn_name, warn_for, warn);
112  }
113  else if (warn)
114  // FIXME: Should this be "err" and "error_for", rather than warn?
115  error ("%s: argument must be a string containing function name",
116  warn_for.c_str ());
117 
118  return ans;
119 }
120 
122 
123 DEFMETHOD (isglobal, interp, args, ,
124  doc: /* -*- texinfo -*-
125 @deftypefn {} {@var{tf} =} isglobal (@var{name})
126 Return true if @var{name} is a globally visible variable.
127 
128 For example:
129 
130 @example
131 @group
132 global x
133 isglobal ("x")
134  @result{} 1
135 @end group
136 @end example
137 @seealso{isvarname, exist}
138 @end deftypefn */)
139 {
140  if (args.length () != 1)
141  print_usage ();
142 
143  std::string name = args(0).xstring_value ("isglobal: NAME must be a string");
144 
145  return ovl (interp.isglobal (name));
146 }
147 
148 /*
149 %!test
150 %! global x;
151 %! assert (isglobal ("x"), true);
152 %! clear -global x; # cleanup after test
153 
154 %!error isglobal ()
155 %!error isglobal ("a", "b")
156 %!error isglobal (1)
157 */
158 
159 static int
160 symbol_exist (interpreter& interp, const std::string& name,
161  const std::string& type = "any")
162 {
163  if (iskeyword (name))
164  return 0;
165 
166  bool search_any = type == "any";
167  bool search_var = type == "var";
168  bool search_dir = type == "dir";
169  bool search_file = type == "file";
170  bool search_builtin = type == "builtin";
171  bool search_class = type == "class";
172 
173  if (! (search_any || search_var || search_dir || search_file
174  || search_builtin || search_class))
175  error (R"(exist: unrecognized type argument "%s")", type.c_str ());
176 
177  if (search_any || search_var)
178  {
179  octave_value val = interp.varval (name);
180 
181  if (val.is_constant () || val.isobject ()
182  || val.is_function_handle ()
183  || val.is_anonymous_function ()
184  || val.is_inline_function ())
185  return 1;
186 
187  if (search_var)
188  return 0;
189  }
190 
191  symbol_table& symtab = interp.get_symbol_table ();
192 
193  // We shouldn't need to look in the global symbol table, since any name
194  // that is visible in the current scope will be in the local symbol table.
195 
196  if (search_any || search_file || search_dir || search_class)
197  {
198  bool have_fcn_ext = false;
199 
200  std::string xname = name;
201  std::string ext;
202 
203  std::size_t pos = name.rfind ('.');
204 
205  if (pos != std::string::npos)
206  {
207  ext = name.substr (pos+1);
208 
209  if (ext == "m" || ext == "oct" || ext == "mex")
210  {
211  xname = name.substr (0, pos);
212  have_fcn_ext = true;
213  }
214  }
215 
216  std::string file_name;
217 
218  if (search_any || search_file || search_class)
219  {
220  load_path& lp = interp.get_load_path ();
221 
222  // Look for class constructor first
223  file_name = lp.find_method (xname, xname);
224 
225  if (have_fcn_ext && ! file_name.empty ())
226  {
227  // Verify extension of file_name found matches ext of name.
228  pos = file_name.rfind ('.');
229 
230  if (pos != std::string::npos)
231  {
232  std::string fext = file_name.substr (pos+1);
233 
234  if (ext != fext)
235  file_name = "";
236  }
237  }
238 
239  if (search_any && file_name.empty ())
240  {
241  // Command line function which Matlab does not support
242  octave_value val = symtab.find_cmdline_function (xname);
243 
244  if (val.is_defined ())
245  return 103;
246  }
247 
248  // Autoloads can only have simple names without extensions.
249  if (! have_fcn_ext && file_name.empty ())
250  {
251  tree_evaluator& tw = interp.get_evaluator ();
252 
253  file_name = tw.lookup_autoload (name);
254  }
255 
256  // If nothing found, look for function using original name.
257  if (file_name.empty ())
258  file_name = lp.find_fcn (name);
259  }
260 
261  std::size_t len = file_name.length ();
262 
263  if (len > 0 && (search_any || search_file || search_class))
264  {
265  if (search_any || search_file)
266  {
267  if (len > 4 && (file_name.substr (len-4) == ".oct"
268  || file_name.substr (len-4) == ".mex"))
269  return 3;
270  }
271 
272  if (search_class)
273  {
274  octave_value oval = symtab.find_function (name);
275  if (oval.is_defined () && oval.is_classdef_meta ())
276  return 8;
277  else
278  return 0;
279  }
280 
281  return 2;
282  }
283 
284  // Nothing found in symbol table, try searching in path
285  file_name = file_in_path (name, "");
286 
287  if (file_name.empty ())
288  file_name = name;
289 
290  // "stat" doesn't work on UNC shares and drive letters.
291  if ((search_any || search_file) && drive_or_unc_share (file_name))
292  return 7;
293 
294  sys::file_stat fs (file_name);
295 
296  if (fs)
297  {
298  if (search_any || search_file)
299  {
300  if (fs.is_dir ())
301  return 7;
302 
303  len = file_name.length ();
304 
305  if (len > 4 && (file_name.substr (len-4) == ".oct"
306  || file_name.substr (len-4) == ".mex"))
307  return 3;
308  else
309  return 2;
310  }
311  else if (search_dir && fs.is_dir ())
312  return 7;
313  }
314 
315  if (search_file || search_dir)
316  return 0;
317  }
318 
319  if ((search_any || search_builtin)
320  && symtab.is_built_in_function_name (name))
321  return 5;
322 
323  return 0;
324 }
325 
326 int
327 symbol_exist (const std::string& name, const std::string& type)
328 {
329  octave::interpreter& interp = octave::__get_interpreter__ ();
330 
331  return octave::symbol_exist (interp, name, type);
332 }
333 
334 
335 #define GET_IDX(LEN) \
336  static_cast<int> (((LEN)-1) * static_cast<double> (rand ()) / RAND_MAX)
337 
338 std::string
339 unique_symbol_name (const std::string& basename)
340 {
341  static const std::string alpha
342  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
343 
344  static std::size_t len = alpha.length ();
345 
346  std::string nm = basename + alpha[GET_IDX (len)];
347 
348  std::size_t pos = nm.length ();
349 
350  if (nm.substr (0, 2) == "__")
351  nm.append ("__");
352 
353  octave::interpreter& interp = octave::__get_interpreter__ ();
354 
355  while (symbol_exist (interp, nm, "any"))
356  nm.insert (pos++, 1, alpha[GET_IDX (len)]);
357 
358  return nm;
359 }
360 
361 DEFMETHOD (exist, interp, args, ,
362  doc: /* -*- texinfo -*-
363 @deftypefn {} {@var{c} =} exist (@var{name})
364 @deftypefnx {} {@var{c} =} exist (@var{name}, @var{type})
365 Check for the existence of @var{name} as a variable, function, file, directory,
366 or class.
367 
368 The return code @var{c} is one of
369 
370 @table @asis
371 @item 1
372 @var{name} is a variable.
373 
374 @item 2
375 @var{name} is an absolute filename, an ordinary file in Octave's @code{path},
376 or (after appending @samp{.m}) a function file in Octave's @code{path}.
377 
378 @item 3
379 @var{name} is a @samp{.oct} or @samp{.mex} file in Octave's @code{path}.
380 
381 @item 5
382 @var{name} is a built-in function.
383 
384 @item 7
385 @var{name} is a directory.
386 
387 @item 8
388 @var{name} is a classdef class.
389 
390 @item 103
391 @var{name} is a function not associated with a file (entered on the command
392 line).
393 
394 @item 0
395 @var{name} does not exist.
396 @end table
397 
398 If the optional argument @var{type} is supplied, check only for symbols of the
399 specified type. Valid types are
400 
401 @table @asis
402 @item @qcode{"var"}
403 Check only for variables.
404 
405 @item @qcode{"builtin"}
406 Check only for built-in functions.
407 
408 @item @qcode{"dir"}
409 Check only for directories.
410 
411 @item @qcode{"file"}
412 Check only for files and directories.
413 
414 @item @qcode{"class"}
415 Check only for classdef classes.
416 @end table
417 
418 If no type is given, and there are multiple possible matches for name,
419 @code{exist} will return a code according to the following priority list:
420 variable, built-in function, oct-file, directory, file, class.
421 
422 @code{exist} returns 2 if a regular file called @var{name} is present in
423 Octave's search path. For information about other types of files not on the
424 search path use some combination of the functions @code{file_in_path} and
425 @code{stat} instead.
426 
427 Programming Note: If @var{name} is implemented by a buggy .oct/.mex file,
428 calling @var{exist} may cause Octave to crash. To maintain high performance,
429 Octave trusts .oct/.mex files instead of @nospell{sandboxing} them.
430 
431 @seealso{file_in_loadpath, file_in_path, dir_in_loadpath, stat}
432 @end deftypefn */)
433 {
434  int nargin = args.length ();
435 
436  if (nargin < 1 || nargin > 2)
437  print_usage ();
438 
439  // For compatibility with undocumented Matlab behavior, return 0 if
440  // there is an empty built-in object as the only argument.
441  if (args(0).builtin_type () != btyp_unknown && args(0).isempty ())
442  return ovl (0);
443 
444  // Also for compatibility, return 0 if the second argument is an empty
445  // built-in object.
446  if (nargin == 2 && args(1).builtin_type () != btyp_unknown
447  && args(1).isempty ())
448  return ovl (0);
449 
450  std::string name = args(0).xstring_value ("exist: NAME must be a string");
451 
452  if (nargin == 2)
453  {
454  std::string type
455  = args(1).xstring_value ("exist: TYPE must be a string");
456 
457  return ovl (symbol_exist (interp, name, type));
458  }
459  else
460  return ovl (symbol_exist (interp, name));
461 }
462 
463 /*
464 %!shared dirtmp, __var1
465 %! dirtmp = P_tmpdir ();
466 %! __var1 = 1;
467 
468 %!assert (exist ("__%Highly_unlikely_name%__"), 0)
469 %!assert (exist ("__var1"), 1)
470 %!assert (exist ("__var1", "var"), 1)
471 %!assert (exist ("__var1", "builtin"), 0)
472 %!assert (exist ("__var1", "dir"), 0)
473 %!assert (exist ("__var1", "file"), 0)
474 %!assert (exist ("__var1", "class"), 0)
475 
476 %!testif ; isunix ()
477 %! assert (exist ("/bin/sh"), 2);
478 %! assert (exist ("/bin/sh", "file"), 2);
479 %! assert (exist ("/bin/sh", "dir"), 0);
480 %! assert (exist ("/dev/null"), 2);
481 %! assert (exist ("/dev/null", "file"), 2);
482 %! assert (exist ("/dev/null", "dir"), 0);
483 
484 %!assert (exist ("print_usage"), 2)
485 %!assert (exist ("print_usage.m"), 2)
486 %!assert (exist ("print_usage", "file"), 2)
487 %!assert (exist ("print_usage", "dir"), 0)
488 
489 ## Don't search path for rooted relative filenames
490 %!assert (exist ("plot.m", "file"), 2)
491 %!assert (exist ("./plot.m", "file"), 0)
492 %!assert (exist ("./%nonexistentfile%", "file"), 0)
493 %!assert (exist ("%nonexistentfile%", "file"), 0)
494 
495 ## Don't search path for absolute filenames
496 %!test
497 %! tname = tempname ();
498 %! unwind_protect
499 %! ## open/close file to create it, equivalent of touch
500 %! fid = fopen (tname, "w");
501 %! fclose (fid);
502 %! [~, fname] = fileparts (tname);
503 %! assert (exist (fullfile (tempdir (), fname), "file"), 2);
504 %! unwind_protect_cleanup
505 %! unlink (tname);
506 %! end_unwind_protect
507 %! assert (exist (fullfile (pwd (), "%nonexistentfile%"), "file"), 0);
508 
509 %!assert (exist ("fftw"), 3)
510 %!assert (exist ("fftw.oct"), 3)
511 %!assert (exist ("fftw", "file"), 3)
512 %!assert (exist ("fftw", "builtin"), 0)
513 
514 %!assert (exist ("ftp"), 2)
515 %!assert (exist ("ftp.m"), 2)
516 %!assert (exist ("@ftp/ftp"), 2)
517 %!assert (exist ("@ftp/ftp.m"), 2)
518 %!assert (exist ("ftp", "class"), 0)
519 
520 %!assert (exist ("inputParser"), 2)
521 %!assert (exist ("inputParser.m"), 2)
522 %!assert (exist ("inputParser", "class"), 8)
523 
524 %!assert (exist ("sin"), 5)
525 %!assert (exist ("sin", "builtin"), 5)
526 %!assert (exist ("sin", "file"), 0)
527 
528 %!assert (exist (dirtmp), 7)
529 %!assert (exist (dirtmp, "dir"), 7)
530 %!assert (exist (dirtmp, "file"), 7)
531 
532 %!error exist ()
533 %!error exist (1,2,3)
534 %!error <TYPE must be a string> exist ("a", 1)
535 %!error <NAME must be a string> exist (1)
536 %!error <unrecognized type argument "foobar"> exist ("a", "foobar")
537 
538 */
539 
540 // Variable values.
541 
542 static bool
543 wants_local_change (const octave_value_list& args, int& nargin)
544 {
545  bool retval = false;
546 
547  if (nargin == 2)
548  {
549  if (! args(1).is_string () || args(1).string_value () != "local")
550  error_with_cfn (R"(second argument must be "local")");
551 
552  nargin = 1;
553  retval = true;
554  }
555 
556  return retval;
557 }
558 
559 static octave::unwind_protect *
560 curr_fcn_unwind_protect_frame ()
561 {
562  octave::tree_evaluator& tw = octave::__get_evaluator__ ();
563 
564  return tw.curr_fcn_unwind_protect_frame ();
565 }
566 
567 template <typename T>
568 static bool
569 try_local_protect (T& var)
570 {
571  octave::unwind_protect *frame = curr_fcn_unwind_protect_frame ();
572 
573  if (frame)
574  {
575  frame->protect_var (var);
576  return true;
577  }
578  else
579  return false;
580 }
581 
583 set_internal_variable (bool& var, const octave_value_list& args,
584  int nargout, const char *nm)
585 {
586  octave_value retval;
587 
588  int nargin = args.length ();
589 
590  if (nargout > 0 || nargin == 0)
591  retval = var;
592 
593  if (wants_local_change (args, nargin))
594  {
595  if (! try_local_protect (var))
596  warning (R"("local" has no effect outside a function)");
597  }
598 
599  if (nargin > 1)
600  print_usage ();
601 
602  if (nargin == 1)
603  {
604  bool bval = args(0).xbool_value ("%s: argument must be a logical value", nm);
605 
606  var = bval;
607  }
608 
609  return retval;
610 }
611 
613 set_internal_variable (char& var, const octave_value_list& args,
614  int nargout, const char *nm)
615 {
616  octave_value retval;
617 
618  int nargin = args.length ();
619 
620  if (nargout > 0 || nargin == 0)
621  retval = var;
622 
623  if (wants_local_change (args, nargin))
624  {
625  if (! try_local_protect (var))
626  warning (R"("local" has no effect outside a function)");
627  }
628 
629  if (nargin > 1)
630  print_usage ();
631 
632  if (nargin == 1)
633  {
634  std::string sval = args(0).xstring_value ("%s: argument must be a single character", nm);
635 
636  switch (sval.length ())
637  {
638  case 1:
639  var = sval[0];
640  break;
641 
642  case 0:
643  var = '\0';
644  break;
645 
646  default:
647  error ("%s: argument must be a single character", nm);
648  break;
649  }
650  }
651 
652  return retval;
653 }
654 
657  int nargout, const char *nm,
658  int minval, int maxval)
659 {
660  octave_value retval;
661 
662  int nargin = args.length ();
663 
664  if (nargout > 0 || nargin == 0)
665  retval = var;
666 
667  if (wants_local_change (args, nargin))
668  {
669  if (! try_local_protect (var))
670  warning (R"("local" has no effect outside a function)");
671  }
672 
673  if (nargin > 1)
674  print_usage ();
675 
676  if (nargin == 1)
677  {
678  int ival = args(0).xint_value ("%s: argument must be an integer value", nm);
679 
680  if (ival < minval)
681  error ("%s: arg must be greater than %d", nm, minval);
682  if (ival > maxval)
683  error ("%s: arg must be less than or equal to %d", nm, maxval);
684 
685  var = ival;
686  }
687 
688  return retval;
689 }
690 
692 set_internal_variable (double& var, const octave_value_list& args,
693  int nargout, const char *nm,
694  double minval, double maxval)
695 {
696  octave_value retval;
697 
698  int nargin = args.length ();
699 
700  if (nargout > 0 || nargin == 0)
701  retval = var;
702 
703  if (wants_local_change (args, nargin))
704  {
705  if (! try_local_protect (var))
706  warning (R"("local" has no effect outside a function)");
707  }
708 
709  if (nargin > 1)
710  print_usage ();
711 
712  if (nargin == 1)
713  {
714  double dval = args(0).xscalar_value ("%s: argument must be a scalar value", nm);
715 
716  if (dval < minval)
717  error ("%s: argument must be greater than %g", nm, minval);
718  if (dval > maxval)
719  error ("%s: argument must be less than or equal to %g", nm, maxval);
720 
721  var = dval;
722  }
723 
724  return retval;
725 }
726 
728 set_internal_variable (std::string& var, const octave_value_list& args,
729  int nargout, const char *nm, bool empty_ok)
730 {
731  octave_value retval;
732 
733  int nargin = args.length ();
734 
735  if (nargout > 0 || nargin == 0)
736  retval = var;
737 
738  if (wants_local_change (args, nargin))
739  {
740  if (! try_local_protect (var))
741  warning (R"("local" has no effect outside a function)");
742  }
743 
744  if (nargin > 1)
745  print_usage ();
746 
747  if (nargin == 1)
748  {
749  std::string sval = args(0).xstring_value ("%s: first argument must be a string", nm);
750 
751  if (! empty_ok && sval.empty ())
752  error ("%s: value must not be empty", nm);
753 
754  var = sval;
755  }
756 
757  return retval;
758 }
759 
762  int nargout, const char *nm, const char **choices)
763 {
764  octave_value retval;
765  int nchoices = 0;
766  while (choices[nchoices] != nullptr)
767  nchoices++;
768 
769  int nargin = args.length ();
770 
771  error_unless (var < nchoices);
772 
773  if (nargout > 0 || nargin == 0)
774  retval = choices[var];
775 
776  if (wants_local_change (args, nargin))
777  {
778  if (! try_local_protect (var))
779  warning (R"("local" has no effect outside a function)");
780  }
781 
782  if (nargin > 1)
783  print_usage ();
784 
785  if (nargin == 1)
786  {
787  std::string sval = args(0).xstring_value ("%s: first argument must be a string", nm);
788 
789  int i = 0;
790  for (; i < nchoices; i++)
791  {
792  if (sval == choices[i])
793  {
794  var = i;
795  break;
796  }
797  }
798  if (i == nchoices)
799  error (R"(%s: value not allowed ("%s"))", nm, sval.c_str ());
800  }
801 
802  return retval;
803 }
804 
806 set_internal_variable (std::string& var, const octave_value_list& args,
807  int nargout, const char *nm, const char **choices)
808 {
809  octave_value retval;
810  int nchoices = 0;
811  while (choices[nchoices] != nullptr)
812  nchoices++;
813 
814  int nargin = args.length ();
815 
816  if (nargout > 0 || nargin == 0)
817  retval = var;
818 
819  if (wants_local_change (args, nargin))
820  {
821  if (! try_local_protect (var))
822  warning (R"("local" has no effect outside a function)");
823  }
824 
825  if (nargin > 1)
826  print_usage ();
827 
828  if (nargin == 1)
829  {
830  std::string sval = args(0).xstring_value ("%s: first argument must be a string", nm);
831 
832  int i = 0;
833  for (; i < nchoices; i++)
834  {
835  if (sval == choices[i])
836  {
837  var = sval;
838  break;
839  }
840  }
841  if (i == nchoices)
842  error (R"(%s: value not allowed ("%s"))", nm, sval.c_str ());
843  }
844 
845  return retval;
846 }
847 
848 // NOTE: Calling Fmlock directly (without an associated stack frame)
849 // will probably not do what you expect because it will lock the calling
850 // function. You should use interpreter::mlock directly if you want to
851 // lock a .oct function. For .mex, you would normally use mexLock.
852 //
853 // FIXME: with the current implementation, calling "builtin ('mlock')"
854 // will also not do what you expect. Is there any reasonable way to fix
855 // that?
856 
857 DEFMETHOD (mlock, interp, args, ,
858  doc: /* -*- texinfo -*-
859 @deftypefn {} {} mlock ()
860 Lock the current function into memory so that it can't be removed with
861 @code{clear}.
862 @seealso{munlock, mislocked, persistent, clear}
863 @end deftypefn */)
864 {
865  if (args.length () != 0)
866  print_usage ();
867 
868  interp.mlock (true);
869 
870  return ovl ();
871 }
872 
873 DEFMETHOD (munlock, interp, args, ,
874  doc: /* -*- texinfo -*-
875 @deftypefn {} {} munlock ()
876 @deftypefnx {} {} munlock (@var{fcn})
877 Unlock the named function @var{fcn} so that it may be removed from memory with
878 @code{clear}.
879 
880 If no function is named then unlock the current function.
881 @seealso{mlock, mislocked, persistent, clear}
882 @end deftypefn */)
883 {
884  int nargin = args.length ();
885 
886  if (nargin > 1)
887  print_usage ();
888 
889  if (nargin == 1)
890  {
891  std::string name
892  = args(0).xstring_value ("munlock: FCN must be a string");
893 
894  interp.munlock (name);
895  }
896  else
897  interp.munlock (true);
898 
899  return ovl ();
900 }
901 
902 DEFMETHOD (mislocked, interp, args, ,
903  doc: /* -*- texinfo -*-
904 @deftypefn {} {@var{tf} =} mislocked ()
905 @deftypefnx {} {@var{tf} =} mislocked (@var{fcn})
906 Return true if the named function @var{fcn} is locked in memory.
907 
908 If no function is named then return true if the current function is locked.
909 @seealso{mlock, munlock, persistent, clear}
910 @end deftypefn */)
911 {
912  int nargin = args.length ();
913 
914  if (nargin > 1)
915  print_usage ();
916 
917  if (nargin == 1)
918  {
919  std::string name
920  = args(0).xstring_value ("mislocked: FCN must be a string");
921 
922  return ovl (interp.mislocked (name));
923  }
924  else
925  return ovl (interp.mislocked (true));
926 }
927 
928 // Deleting names from the symbol tables.
929 
930 static inline bool
931 name_matches_any_pattern (const std::string& nm, const string_vector& argv,
932  int argc, int idx, bool have_regexp = false)
933 {
934  bool retval = false;
935 
936  for (int k = idx; k < argc; k++)
937  {
938  std::string patstr = argv[k];
939  if (! patstr.empty ())
940  {
941  if (have_regexp)
942  {
943  if (regexp::is_match (patstr, nm))
944  {
945  retval = true;
946  break;
947  }
948  }
949  else
950  {
951  symbol_match pattern (patstr);
952 
953  if (pattern.match (nm))
954  {
955  retval = true;
956  break;
957  }
958  }
959  }
960  }
961 
962  return retval;
963 }
964 
965 static inline void
966 maybe_warn_exclusive (bool exclusive)
967 {
968  if (exclusive)
969  warning ("clear: ignoring --exclusive option");
970 }
971 
972 static void
973 do_clear_functions (interpreter& interp,
974  const string_vector& argv, int argc, int idx,
975  bool exclusive = false)
976 {
977  if (idx == argc)
978  interp.clear_functions ();
979  else
980  {
981  if (exclusive)
982  {
983  std::list<std::string> fcns = interp.user_function_names ();
984 
985  for (const auto& name : fcns)
986  {
987  if (! name_matches_any_pattern (name, argv, argc, idx))
988  interp.clear_function (name);
989  }
990  }
991  else
992  {
993  while (idx < argc)
994  interp.clear_function_pattern (argv[idx++]);
995  }
996  }
997 }
998 
999 static void
1000 do_clear_globals (interpreter& interp,
1001  const string_vector& argv, int argc, int idx,
1002  bool exclusive = false)
1003 {
1004  if (idx == argc)
1005  {
1006  std::list<std::string> gvars = interp.global_variable_names ();
1007 
1008  for (const auto& name : gvars)
1009  {
1010  interp.clear_variable (name);
1011  interp.clear_global_variable (name);
1012  }
1013  }
1014  else
1015  {
1016  if (exclusive)
1017  {
1018  std::list<std::string> gvars = interp.global_variable_names ();
1019 
1020  for (const auto& name : gvars)
1021  {
1022  if (! name_matches_any_pattern (name, argv, argc, idx))
1023  {
1024  interp.clear_variable (name);
1025  interp.clear_global_variable (name);
1026  }
1027  }
1028  }
1029  else
1030  {
1031  while (idx < argc)
1032  {
1033  std::string pattern = argv[idx++];
1034 
1035  interp.clear_variable_pattern (pattern);
1036  interp.clear_global_variable_pattern (pattern);
1037  }
1038  }
1039  }
1040 }
1041 
1042 static void
1043 do_clear_variables (interpreter& interp,
1044  const string_vector& argv, int argc, int idx,
1045  bool exclusive = false, bool have_regexp = false)
1046 {
1047  if (idx == argc)
1048  interp.clear_variables ();
1049  else
1050  {
1051  if (exclusive)
1052  {
1053  std::list<std::string> lvars = interp.variable_names ();
1054 
1055  for (const auto& name : lvars)
1056  {
1057  if (! name_matches_any_pattern (name, argv, argc, idx,
1058  have_regexp))
1059  interp.clear_variable (name);
1060  }
1061  }
1062  else
1063  {
1064  if (have_regexp)
1065  while (idx < argc)
1066  interp.clear_variable_regexp (argv[idx++]);
1067  else
1068  while (idx < argc)
1069  interp.clear_variable_pattern (argv[idx++]);
1070  }
1071  }
1072 }
1073 
1074 static void
1075 do_clear_symbols (interpreter& interp,
1076  const string_vector& argv, int argc, int idx,
1077  bool exclusive = false)
1078 {
1079  if (idx == argc)
1080  {
1081  interp.clear_variables ();
1082  }
1083  else
1084  {
1085  if (exclusive)
1086  {
1087  // FIXME: is this really what we want, or do we
1088  // somehow want to only clear the functions that are not
1089  // shadowed by local variables? It seems that would be a
1090  // bit harder to do.
1091 
1092  do_clear_variables (interp, argv, argc, idx, exclusive);
1093  do_clear_functions (interp, argv, argc, idx, exclusive);
1094  }
1095  else
1096  {
1097  while (idx < argc)
1098  interp.clear_symbol_pattern (argv[idx++]);
1099  }
1100  }
1101 }
1102 
1103 static void
1104 do_matlab_compatible_clear (interpreter& interp,
1105  const string_vector& argv, int argc, int idx)
1106 {
1107  // This is supposed to be mostly Matlab compatible.
1108 
1109  for (; idx < argc; idx++)
1110  {
1111  if (argv[idx] == "all" && ! interp.is_local_variable ("all"))
1112  {
1113  interp.clear_all ();
1114  }
1115  else if (argv[idx] == "functions"
1116  && ! interp.is_local_variable ("functions"))
1117  {
1118  do_clear_functions (interp, argv, argc, ++idx);
1119  }
1120  else if (argv[idx] == "global"
1121  && ! interp.is_local_variable ("global"))
1122  {
1123  do_clear_globals (interp, argv, argc, ++idx);
1124  }
1125  else if (argv[idx] == "variables"
1126  && ! interp.is_local_variable ("variables"))
1127  {
1128  interp.clear_variables ();
1129  }
1130  else if (argv[idx] == "classes"
1131  && ! interp.is_local_variable ("classes"))
1132  {
1133  interp.clear_objects ();
1135  interp.clear_all ();
1136  }
1137  else
1138  {
1139  interp.clear_symbol_pattern (argv[idx]);
1140  }
1141  }
1142 }
1143 
1144 DEFMETHOD (clear, interp, args, ,
1145  doc: /* -*- texinfo -*-
1146 @deftypefn {} {} clear
1147 @deftypefnx {} {} clear @var{pattern} @dots{}
1148 @deftypefnx {} {} clear @var{options} @var{pattern} @dots{}
1149 Delete the names matching the given @var{pattern}s thereby freeing memory.
1150 
1151 The @var{pattern} may contain the following special characters:
1152 
1153 @table @code
1154 @item ?
1155 Match any single character.
1156 
1157 @item *
1158 Match zero or more characters.
1159 
1160 @item [ @var{list} ]
1161 Match the list of characters specified by @var{list}. If the first character
1162 is @code{!} or @code{^}, match all characters except those specified by
1163 @var{list}. For example, the pattern @code{[a-zA-Z]} will match all lowercase
1164 and uppercase alphabetic characters. On Windows, square brackets are matched
1165 literally and are not used to group characters.
1166 @end table
1167 
1168 For example, the command
1169 
1170 @example
1171 clear foo b*r
1172 @end example
1173 
1174 @noindent
1175 clears the name @code{foo} and all names that begin with the letter @samp{b}
1176 and end with the letter @samp{r}.
1177 
1178 If @code{clear} is called without any arguments, all user-defined variables
1179 are cleared from the current workspace (i.e., local variables). Any global
1180 variables present will no longer be visible in the current workspace, but they
1181 will continue to exist in the global workspace. Functions are unaffected by
1182 this form of @code{clear}.
1183 
1184 The following options are available in both long and short form
1185 
1186 @table @code
1187 @item all, -all, -a
1188 Clear all local and global user-defined variables, and all functions from the
1189 symbol table.
1190 
1191 @item -exclusive, -x
1192 Clear variables that do @strong{not} match the following pattern.
1193 
1194 @item functions, -functions, -f
1195 Clear function names from the function symbol table. Persistent variables
1196 will be re-initialized to their default value unless the function has been
1197 locked in memory with @code{mlock}.
1198 
1199 @item global, -global, -g
1200 Clear global variable names.
1201 
1202 @item variables, -variables, -v
1203 Clear local variable names.
1204 
1205 @item classes, -classes, -c
1206 Clear the class structure table and all objects.
1207 
1208 @item -regexp, -r
1209 The @var{pattern} arguments are treated as regular expressions and any matches
1210 will be cleared.
1211 @end table
1212 
1213 With the exception of @option{-exclusive} and @option{-regexp}, all long
1214 options can be used without the dash as well. Note that, aside from
1215 @option{-exclusive}, only one other option may appear. All options must
1216 appear before any patterns.
1217 
1218 Programming Notes: The command @code{clear @var{name}} only clears the variable
1219 @var{name} when both a variable and a (shadowed) function named @var{name}
1220 are currently defined. For example, suppose you have defined a function
1221 @code{foo}, and then hidden it by performing the assignment @code{foo = 2}.
1222 Executing the command @code{clear foo} once will clear the variable
1223 definition and restore the definition of @code{foo} as a function.
1224 Executing @code{clear foo} a second time will clear the function definition.
1225 
1226 When a local variable name, which is linked to a global variable, is cleared
1227 only the local copy of the variable is removed. The global copy is untouched
1228 and can be restored with @code{global @var{global_varname}}. Conversely,
1229 @code{clear -g @var{global_varname}} will remove both the local and global
1230 variables.
1231 
1232 @seealso{clearvars, who, whos, exist, mlock}
1233 @end deftypefn */)
1234 {
1235  int argc = args.length () + 1;
1236 
1237  string_vector argv = args.make_argv ("clear");
1238 
1239  if (argc == 1)
1240  {
1241  do_clear_variables (interp, argv, argc, true);
1242 
1243  event_manager& evmgr = interp.get_event_manager ();
1244 
1245  evmgr.clear_workspace ();
1246  }
1247  else
1248  {
1249  int idx = 0;
1250 
1251  bool clear_all = false;
1252  bool clear_functions = false;
1253  bool clear_globals = false;
1254  bool clear_variables = false;
1255  bool clear_objects = false;
1256  bool exclusive = false;
1257  bool have_regexp = false;
1258  bool have_dash_option = false;
1259 
1260  while (++idx < argc)
1261  {
1262  if (argv[idx] == "-all" || argv[idx] == "-a")
1263  {
1264  if (have_dash_option)
1265  print_usage ();
1266 
1267  have_dash_option = true;
1268  clear_all = true;
1269  }
1270  else if (argv[idx] == "-exclusive" || argv[idx] == "-x")
1271  {
1272  exclusive = true;
1273  }
1274  else if (argv[idx] == "-functions" || argv[idx] == "-f")
1275  {
1276  if (have_dash_option)
1277  print_usage ();
1278 
1279  have_dash_option = true;
1280  clear_functions = true;
1281  }
1282  else if (argv[idx] == "-global" || argv[idx] == "-g")
1283  {
1284  if (have_dash_option)
1285  print_usage ();
1286 
1287  have_dash_option = true;
1288  clear_globals = true;
1289  }
1290  else if (argv[idx] == "-variables" || argv[idx] == "-v")
1291  {
1292  if (have_dash_option)
1293  print_usage ();
1294 
1295  have_dash_option = true;
1296  clear_variables = true;
1297  }
1298  else if (argv[idx] == "-classes" || argv[idx] == "-c")
1299  {
1300  if (have_dash_option)
1301  print_usage ();
1302 
1303  have_dash_option = true;
1304  clear_objects = true;
1305  }
1306  else if (argv[idx] == "-regexp" || argv[idx] == "-r")
1307  {
1308  if (have_dash_option)
1309  print_usage ();
1310 
1311  have_dash_option = true;
1312  have_regexp = true;
1313  }
1314  else
1315  break;
1316  }
1317 
1318  if (idx <= argc)
1319  {
1320  if (! have_dash_option && ! exclusive)
1321  do_matlab_compatible_clear (interp, argv, argc, idx);
1322  else
1323  {
1324  if (clear_all)
1325  {
1326  maybe_warn_exclusive (exclusive);
1327 
1328  if (++idx < argc)
1329  warning ("clear: ignoring extra arguments after -all");
1330 
1331  interp.clear_all ();
1332  }
1333  else if (have_regexp)
1334  {
1335  do_clear_variables (interp, argv, argc, idx, exclusive, true);
1336  }
1337  else if (clear_functions)
1338  {
1339  do_clear_functions (interp, argv, argc, idx, exclusive);
1340  }
1341  else if (clear_globals)
1342  {
1343  do_clear_globals (interp, argv, argc, idx, exclusive);
1344  }
1345  else if (clear_variables)
1346  {
1347  do_clear_variables (interp, argv, argc, idx, exclusive);
1348  }
1349  else if (clear_objects)
1350  {
1351  interp.clear_objects ();
1353  interp.clear_all ();
1354  }
1355  else
1356  {
1357  do_clear_symbols (interp, argv, argc, idx, exclusive);
1358  }
1359  }
1360  }
1361  }
1362 
1363  return ovl ();
1364 }
1365 
1366 /*
1367 ## This test must be wrapped in its own function or the 'clear' command will
1368 ## break the %!test environment.
1369 %!function __test_clear_no_args__ ()
1370 %! global x;
1371 %! x = 3;
1372 %! clear
1373 %! assert (! exist ("x", "var")); # x is not in the current workspace anymore
1374 %! global x; # but still lives in the global workspace
1375 %! assert (exist ("x", "var"));
1376 %!endfunction
1377 
1378 %!test
1379 %! unwind_protect
1380 %! __test_clear_no_args__ ();
1381 %! unwind_protect_cleanup
1382 %! clear -g x
1383 %! end_unwind_protect
1384 
1385 ## Test that multiple options cannot be given
1386 %!error clear -f -g
1387 */
1388 
1389 static std::string Vmissing_function_hook = "__unimplemented__";
1390 
1391 DEFUN (missing_function_hook, args, nargout,
1392  doc: /* -*- texinfo -*-
1393 @deftypefn {} {@var{val} =} missing_function_hook ()
1394 @deftypefnx {} {@var{old_val} =} missing_function_hook (@var{new_val})
1395 @deftypefnx {} {@var{old_val} =} missing_function_hook (@var{new_val}, "local")
1396 Query or set the internal variable that specifies the function to call
1397 to provide extra information when an unknown identifier is referenced.
1398 
1399 When called from inside a function with the @qcode{"local"} option, the
1400 variable is changed locally for the function and any subroutines it calls.
1401 The original variable value is restored when exiting the function.
1402 @seealso{missing_component_hook}
1403 @end deftypefn */)
1404 {
1405  return set_internal_variable (Vmissing_function_hook, args, nargout,
1406  "missing_function_hook");
1407 }
1408 
1409 std::string
1410 maybe_missing_function_hook (const std::string& name)
1411 {
1412  octave::interpreter& interp = octave::__get_interpreter__ ();
1413 
1414  // Don't do this if we're handling errors.
1415  if (Vmissing_function_hook.empty ())
1416  return "";
1417 
1418  octave::symbol_table& symtab = interp.get_symbol_table ();
1419 
1420  octave_value val = symtab.find_function (Vmissing_function_hook);
1421 
1422  if (val.is_defined ())
1423  {
1424  // Ensure auto-restoration.
1425  octave::unwind_protect_var<std::string>
1426  restore_var (Vmissing_function_hook);
1427 
1428  // Clear the variable prior to calling the function.
1429  const std::string fcn_name = Vmissing_function_hook;
1430  Vmissing_function_hook.clear ();
1431 
1432  // Call.
1433  octave_value_list tmp = interp.feval (fcn_name, octave_value (name), 1);
1434 
1435  if (tmp.length () == 1 && tmp(0).is_string ())
1436  return tmp(0).string_value ();
1437  }
1438 
1439  return "";
1440 }
1441 
1442 DEFMETHOD (__varval__, interp, args, ,
1443  doc: /* -*- texinfo -*-
1444 @deftypefn {} {@var{value} =} __varval__ (@var{name})
1445 Return the value of the variable @var{name} directly from the symbol table.
1446 
1447 If @var{name} does not exist then nothing is returned, not even an empty matrix
1448 (@code{[]}), since there would be no way to distinguish between a variable
1449 not found in the symbol table and a variable who's value was @code{[]}.
1450 
1451 A standard usage pattern is to code a @code{try}/@code{catch} block around a
1452 call to @code{__varval__}.
1453 
1454 Example Code
1455 
1456 @example
1457 @group
1458 try
1459  @var{val} = __varval__ (@var{name});
1460 catch
1461  ## No variable @var{name} found in symbol table
1462  @var{val} = NA; # Substitute Not Available (NA)
1463  error ("@var{name} not found"); # or, throw an error.
1464 end_try_catch
1465 @end group
1466 @end example
1467 
1468 Programming Note: The magic @var{name} @qcode{".argn."} will retrieve the text
1469 of input arguments to a function and is used by @code{inputname} internally.
1470 @seealso{inputname}
1471 @end deftypefn */)
1472 {
1473  if (args.length () != 1)
1474  print_usage ();
1475 
1476  std::string name = args(0).xstring_value ("__varval__: NAME must be a string");
1477 
1478  // We need this kluge to implement inputname in a .m file.
1479  if (name == ".argn.")
1480  {
1481  tree_evaluator& tw = interp.get_evaluator ();
1482 
1484  }
1485 
1486  return interp.varval (name);
1487 }
1488 
1489 static std::string Vmissing_component_hook;
1490 
1491 DEFUN (missing_component_hook, args, nargout,
1492  doc: /* -*- texinfo -*-
1493 @deftypefn {} {@var{val} =} missing_component_hook ()
1494 @deftypefnx {} {@var{old_val} =} missing_component_hook (@var{new_val})
1495 @deftypefnx {} {@var{old_val} =} missing_component_hook (@var{new_val}, "local")
1496 Query or set the internal variable that specifies the function to call when
1497 a component of Octave is missing.
1498 
1499 This can be useful for packagers that may split the Octave installation into
1500 multiple sub-packages, for example, to provide a hint to users for how to
1501 install the missing components.
1502 
1503 When called from inside a function with the @qcode{"local"} option, the
1504 variable is changed locally for the function and any subroutines it calls.
1505 The original variable value is restored when exiting the function.
1506 
1507 The hook function is expected to be of the form
1508 
1509 @example
1510 @var{fcn} (@var{component})
1511 @end example
1512 
1513 Octave will call @var{fcn} with the name of the function that requires the
1514 component and a string describing the missing component. The hook function
1515 should return an error message to be displayed.
1516 @seealso{missing_function_hook}
1517 @end deftypefn */)
1518 {
1519  return set_internal_variable (Vmissing_component_hook, args, nargout,
1520  "missing_component_hook");
1521 }
1522 
1523 OCTAVE_END_NAMESPACE(octave)
Provides threadsafe access to octave.
void clear_workspace()
octave_value varval(const std::string &name) const
void clear_variable(const std::string &name)
void clear_objects()
void mlock(bool skip_first=false) const
std::list< std::string > variable_names()
event_manager & get_event_manager()
Definition: interpreter.h:328
symbol_table & get_symbol_table()
Definition: interpreter.h:298
void clear_symbol_pattern(const std::string &pat)
void clear_global_variable(const std::string &name)
std::list< std::string > user_function_names()
void clear_global_variable_pattern(const std::string &pattern)
void clear_variables()
void clear_variable_regexp(const std::string &pattern)
bool mislocked(bool skip_first=false) const
tree_evaluator & get_evaluator()
std::list< std::string > global_variable_names()
void clear_variable_pattern(const std::string &pattern)
load_path & get_load_path()
Definition: interpreter.h:283
void clear_function_pattern(const std::string &pat)
bool is_local_variable(const std::string &name) const
void munlock(bool skip_first=false) const
void clear_function(const std::string &name)
void clear_all(bool force=false)
void clear_functions(bool force=false)
std::string find_fcn(const std::string &fcn, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:109
std::string find_method(const std::string &class_name, const std::string &meth, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:77
static void clear_exemplar_map()
Definition: ov-class.cc:1124
string_vector make_argv(const std::string &="") const
Definition: ovl.cc:227
octave_idx_type length() const
Definition: ovl.h:113
bool is_function_handle() const
Definition: ov.h:768
bool is_inline_function() const
Definition: ov.h:774
bool is_classdef_meta() const
Definition: ov.h:652
bool is_string() const
Definition: ov.h:637
bool is_constant() const
Definition: ov.h:765
bool is_defined() const
Definition: ov.h:592
octave_function * function_value(bool silent=false) const
std::string string_value(bool force=false) const
Definition: ov.h:974
bool is_anonymous_function() const
Definition: ov.h:771
bool isobject() const
Definition: ov.h:664
bool is_match(const std::string &buffer) const
Definition: lo-regexp.cc:584
bool is_built_in_function_name(const std::string &name)
Definition: symtab.cc:69
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope::invalid())
Definition: symtab.cc:254
octave_value find_cmdline_function(const std::string &name)
Definition: symtab.cc:316
octave_value get_auto_fcn_var(stack_frame::auto_var_type avt) const
Definition: pt-eval.cc:2213
std::string lookup_autoload(const std::string &nm) const
Definition: pt-eval.cc:4653
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
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:1063
void error_with_cfn(const char *fmt,...)
Definition: error.cc:1018
void() error(const char *fmt,...)
Definition: error.cc:988
#define error_unless(cond)
Definition: error.h:530
interpreter & __get_interpreter__()
tree_evaluator & __get_evaluator__()
symbol_table & __get_symbol_table__()
bool iskeyword(const std::string &s)
Definition: lex.cc:1335
octave_value set_internal_variable(std::string &var, const octave_value_list &args, int nargout, const char *nm, const char **choices)
Definition: variables.cc:806
@ btyp_unknown
Definition: ov-base.h:101
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
bool drive_or_unc_share(const std::string &)
std::string file_in_path(const std::string &, const std::string &)
#define GET_IDX(LEN)
Definition: variables.cc:335
octave_function * is_valid_function(const std::string &fcn_name, const std::string &warn_for, bool warn)
Definition: variables.cc:76
int symbol_exist(const std::string &name, const std::string &type="any")
std::string maybe_missing_function_hook(const std::string &name)
std::string unique_symbol_name(const std::string &basename)
F77_RET_T len
Definition: xerbla.cc:61