GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
variables.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2017 John W. Eaton
4 Copyright (C) 2009-2010 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <cstdio>
29 #include <cstring>
30 
31 #include <iomanip>
32 #include <set>
33 #include <string>
34 
35 #include "file-stat.h"
36 #include "oct-env.h"
37 #include "file-ops.h"
38 #include "glob-match.h"
39 #include "lo-regexp.h"
40 #include "str-vec.h"
41 
42 #include "call-stack.h"
43 #include <defaults.h>
44 #include "Cell.h"
45 #include "defun.h"
46 #include "dirfns.h"
47 #include "error.h"
48 #include "errwarn.h"
49 #include "help.h"
50 #include "input.h"
51 #include "interpreter.h"
52 #include "lex.h"
53 #include "load-path.h"
54 #include "octave-link.h"
56 #include "oct-map.h"
57 #include "ovl.h"
58 #include "ov.h"
59 #include "ov-class.h"
60 #include "ov-usr-fcn.h"
61 #include "pager.h"
62 #include "parse.h"
63 #include "symtab.h"
64 #include "unwind-prot.h"
65 #include "utils.h"
66 #include "variables.h"
67 
68 // Defines layout for the whos/who -long command
70  = " %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;\n";
71 
72 void
74 {
76 }
77 
78 void
80 {
82 }
83 
84 void
86 {
88 }
89 
90 void
92 {
94 }
95 
96 // Attributes of variables and functions.
97 
98 // Is this octave_value a valid function?
99 
102  const std::string& warn_for, bool warn)
103 {
104  octave_function *ans = 0;
105 
106  if (! fcn_name.empty ())
107  {
109 
110  if (val.is_defined ())
111  ans = val.function_value (true);
112  }
113 
114  // FIXME: Should this be "err" and "error_for", rather than warn?
115  if (! ans && warn)
116  error ("%s: the symbol '%s' is not valid as a function",
117  warn_for.c_str (), fcn_name.c_str ());
118 
119  return ans;
120 }
121 
124  const std::string& warn_for, bool warn)
125 {
126  octave_function *ans = 0;
127 
128  std::string fcn_name;
129 
130  if (arg.is_string ())
131  {
132  fcn_name = arg.string_value ();
133 
134  ans = is_valid_function (fcn_name, warn_for, warn);
135  }
136  else if (warn)
137  // FIXME: Should this be "err" and "error_for", rather than warn?
138  error ("%s: argument must be a string containing function name",
139  warn_for.c_str ());
140 
141  return ans;
142 }
143 
145 extract_function (const octave_value& arg, const std::string& warn_for,
146  const std::string& fname, const std::string& header,
147  const std::string& trailer)
148 {
149  octave_function *retval = 0;
150 
151  retval = is_valid_function (arg, warn_for, 0);
152 
153  if (! retval)
154  {
155  std::string s = arg.xstring_value ("%s: first argument must be a string",
156  warn_for.c_str ());
157 
158  std::string cmd = header;
159  cmd.append (s);
160  cmd.append (trailer);
161 
162  int parse_status;
163 
164  eval_string (cmd, true, parse_status, 0);
165 
166  if (parse_status != 0)
167  error ("%s: '%s' is not valid as a function",
168  warn_for.c_str (), fname.c_str ());
169 
170  retval = is_valid_function (fname, warn_for, 0);
171 
172  if (! retval)
173  error ("%s: '%s' is not valid as a function",
174  warn_for.c_str (), fname.c_str ());
175 
176  warning ("%s: passing function body as a string is obsolete; please use anonymous functions",
177  warn_for.c_str ());
178  }
179 
180  return retval;
181 }
182 
185 {
186  int n = 1;
187 
188  size_t pos = 0;
189 
190  size_t len = text.length ();
191 
192  while ((pos = text.find ('.', pos)) != std::string::npos)
193  {
194  if (++pos == len)
195  break;
196 
197  n++;
198  }
199 
200  string_vector retval (n);
201 
202  pos = 0;
203 
204  for (int i = 0; i < n; i++)
205  {
206  len = text.find ('.', pos);
207 
208  if (len != std::string::npos)
209  len -= pos;
210 
211  retval[i] = text.substr (pos, len);
212 
213  if (len != std::string::npos)
214  pos += len + 1;
215  }
216 
217  return retval;
218 }
219 
220 static inline bool
222 {
223  bool retval = false;
224 
225  if (! name.empty ())
226  {
228 
229  retval = val.is_defined ();
230  }
231 
232  return retval;
233 }
234 
237  std::string& prefix, std::string& hint)
238 {
239  string_vector names;
240 
241  size_t pos = text.rfind ('.');
242  bool array = false;
243 
244  if (pos != std::string::npos)
245  {
246  if (pos == text.length ())
247  hint = "";
248  else
249  hint = text.substr (pos+1);
250 
251  prefix = text.substr (0, pos);
252 
253  if (prefix == "")
254  {
255  array = true;
256  prefix = find_indexed_expression (text);
257  }
258 
259  std::string base_name = prefix;
260 
261  pos = base_name.find_first_of ("{(. ");
262 
263  if (pos != std::string::npos)
264  base_name = base_name.substr (0, pos);
265 
266  if (is_variable (base_name))
267  {
268  int parse_status;
269 
271 
274 
275  discard_error_messages = true;
277 
278  try
279  {
280  octave_value tmp = eval_string (prefix, true, parse_status);
281 
282  frame.run ();
283 
284  if (tmp.is_defined ()
285  && (tmp.is_map () || tmp.is_java () || tmp.is_classdef_object ()))
286  names = tmp.map_keys ();
287  }
288  catch (const octave::execution_exception&)
289  {
291  }
292  }
293  }
294 
295  // Undo look-back that found the array expression,
296  // but insert an extra "." to distinguish from the non-struct case.
297  if (array)
298  prefix = ".";
299 
300  return names;
301 }
302 
303 // FIXME: this will have to be much smarter to work "correctly".
304 bool
305 looks_like_struct (const std::string& text, char prev_char)
306 {
307  bool retval = (! text.empty ()
308  && (text != "." || prev_char == ')' || prev_char == '}')
309  && text.find_first_of (octave::sys::file_ops::dir_sep_chars ()) == std::string::npos
310  && text.find ("..") == std::string::npos
311  && text.rfind ('.') != std::string::npos);
312 
313 #if 0
314  symbol_record *sr = curr_sym_tab->lookup (text);
315 
316  if (sr && ! sr->is_function ())
317  {
318  int parse_status;
319 
321 
323 
324  discard_error_messages = true;
325 
326  octave_value tmp = eval_string (text, true, parse_status);
327 
328  frame.run ();
329 
330  retval = (tmp.is_defined () && tmp.is_map ());
331  }
332 #endif
333 
334  return retval;
335 }
336 
337 static octave_value
339 {
340  if (args.length () != 1)
341  print_usage ();
342 
343  if (! args(0).is_string ())
344  error ("isglobal: NAME must be a string");
345 
346  std::string name = args(0).string_value ();
347 
348  return symbol_table::is_global (name);
349 }
350 
351 DEFUN (isglobal, args, ,
352  doc: /* -*- texinfo -*-
353 @deftypefn {} {} isglobal (@var{name})
354 Return true if @var{name} is a globally visible variable.
355 
356 For example:
357 
358 @example
359 @group
360 global x
361 isglobal ("x")
362  @result{} 1
363 @end group
364 @end example
365 @seealso{isvarname, exist}
366 @end deftypefn */)
367 {
368  return do_isglobal (args);
369 }
370 
371 /*
372 %!test
373 %! global x;
374 %! assert (isglobal ("x"), true);
375 
376 %!error isglobal ()
377 %!error isglobal ("a", "b")
378 %!error isglobal (1)
379 */
380 
381 int
383 {
384  if (octave::is_keyword (name))
385  return 0;
386 
387  bool search_any = type == "any";
388  bool search_var = type == "var";
389  bool search_dir = type == "dir";
390  bool search_file = type == "file";
391  bool search_builtin = type == "builtin";
392  bool search_class = type == "class";
393 
394  if (! (search_any || search_var || search_dir || search_file ||
395  search_builtin || search_class))
396  error ("exist: unrecognized type argument \"%s\"", type.c_str ());
397 
398  if (search_any || search_var)
399  {
401 
402  if (val.is_constant () || val.is_object ()
403  || val.is_function_handle ()
404  || val.is_anonymous_function ()
405  || val.is_inline_function ())
406  return 1;
407 
408  if (search_var)
409  return 0;
410  }
411 
412  // We shouldn't need to look in the global symbol table, since any name
413  // that is visible in the current scope will be in the local symbol table.
414 
415  // Command line function which Matlab does not support
416  if (search_any)
417  {
419 
420  if (val.is_defined ())
421  return 103;
422  }
423 
424  if (search_any || search_file || search_dir)
425  {
426  std::string file_name = lookup_autoload (name);
427 
428  if (file_name.empty ())
429  file_name = load_path::find_fcn (name);
430 
431  size_t len = file_name.length ();
432 
433  if (len > 0)
434  {
435  if (search_any || search_file)
436  {
437  if (len > 4 && (file_name.substr (len-4) == ".oct"
438  || file_name.substr (len-4) == ".mex"))
439  return 3;
440  else
441  return 2;
442  }
443  }
444 
445  file_name = file_in_path (name, "");
446 
447  if (file_name.empty ())
448  file_name = name;
449 
450  octave::sys::file_stat fs (file_name);
451 
452  if (fs)
453  {
454  if (search_any || search_file)
455  {
456  if (fs.is_dir ())
457  return 7;
458 
459  len = file_name.length ();
460 
461  if (len > 4 && (file_name.substr (len-4) == ".oct"
462  || file_name.substr (len-4) == ".mex"))
463  return 3;
464  else
465  return 2;
466  }
467  else if (search_dir && fs.is_dir ())
468  return 7;
469  }
470 
471  if (search_file || search_dir)
472  return 0;
473  }
474 
475  if (search_any || search_builtin)
476  {
478  return 5;
479 
480  if (search_builtin)
481  return 0;
482  }
483 
484  return 0;
485 }
486 
487 #define GET_IDX(LEN) \
488  static_cast<int> ((LEN-1) * static_cast<double> (rand ()) / RAND_MAX)
489 
492 {
493  static const std::string alpha
494  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
495 
496  static size_t len = alpha.length ();
497 
498  std::string nm = basename + alpha[GET_IDX (len)];
499 
500  size_t pos = nm.length ();
501 
502  if (nm.substr (0, 2) == "__")
503  nm.append ("__");
504 
505  while (symbol_exist (nm, "any"))
506  nm.insert (pos++, 1, alpha[GET_IDX (len)]);
507 
508  return nm;
509 }
510 
511 DEFUN (exist, args, ,
512  doc: /* -*- texinfo -*-
513 @deftypefn {} {@var{c} =} exist (@var{name})
514 @deftypefnx {} {@var{c} =} exist (@var{name}, @var{type})
515 Check for the existence of @var{name} as a variable, function, file,
516 directory, or class.
517 
518 The return code @var{c} is one of
519 
520 @table @asis
521 @item 1
522 @var{name} is a variable.
523 
524 @item 2
525 @var{name} is an absolute filename, an ordinary file in Octave's
526 @code{path}, or (after appending @samp{.m}) a function file in Octave's
527 @code{path}.
528 
529 @item 3
530 @var{name} is a @samp{.oct} or @samp{.mex} file in Octave's @code{path}.
531 
532 @item 5
533 @var{name} is a built-in function.
534 
535 @item 7
536 @var{name} is a directory.
537 
538 @item 103
539 @var{name} is a function not associated with a file (entered on the command
540 line).
541 
542 @item 0
543 @var{name} does not exist.
544 @end table
545 
546 If the optional argument @var{type} is supplied, check only for symbols of
547 the specified type. Valid types are
548 
549 @table @asis
550 @item @qcode{"var"}
551 Check only for variables.
552 
553 @item @qcode{"builtin"}
554 Check only for built-in functions.
555 
556 @item @qcode{"dir"}
557 Check only for directories.
558 
559 @item @qcode{"file"}
560 Check only for files and directories.
561 
562 @item @qcode{"class"}
563 Check only for classes. (Note: This option is accepted, but not currently
564 implemented)
565 @end table
566 
567 If no type is given, and there are multiple possible matches for name,
568 @code{exist} will return a code according to the following priority list:
569 variable, built-in function, oct-file, directory, file, class.
570 
571 @code{exist} returns 2 if a regular file called @var{name} is present in
572 Octave's search path. If you want information about other types of files
573 not on the search path you should use some combination of the functions
574 @code{file_in_path} and @code{stat} instead.
575 
576 Programming Note: If @var{name} is implemented by a buggy .oct/.mex file,
577 calling @var{exist} may cause Octave to crash. To maintain high
578 performance, Octave trusts .oct/.mex files instead of @nospell{sandboxing}
579 them.
580 
581 @seealso{file_in_loadpath, file_in_path, dir_in_loadpath, stat}
582 @end deftypefn */)
583 {
584  int nargin = args.length ();
585 
586  if (nargin < 1 || nargin > 2)
587  print_usage ();
588 
589  std::string name = args(0).xstring_value ("exist: NAME must be a string");
590 
591  if (nargin == 2)
592  {
593  std::string type = args(1).xstring_value ("exist: TYPE must be a string");
594 
595  if (type == "class")
596  warning ("exist: \"class\" type argument is not implemented");
597 
598  return ovl (symbol_exist (name, type));
599  }
600  else
601  return ovl (symbol_exist (name));
602 }
603 
604 /*
605 %!shared dirtmp, __var1
606 %! dirtmp = P_tmpdir ();
607 %! __var1 = 1;
608 
609 %!assert (exist ("__%Highly_unlikely_name%__"), 0)
610 %!assert (exist ("__var1"), 1)
611 %!assert (exist ("__var1", "var"), 1)
612 %!assert (exist ("__var1", "builtin"), 0)
613 %!assert (exist ("__var1", "dir"), 0)
614 %!assert (exist ("__var1", "file"), 0)
615 
616 %!test
617 %! if (isunix ())
618 %! assert (exist ("/bin/sh"), 2);
619 %! assert (exist ("/bin/sh", "file"), 2);
620 %! assert (exist ("/bin/sh", "dir"), 0);
621 %! assert (exist ("/dev/null"), 2);
622 %! assert (exist ("/dev/null", "file"), 2);
623 %! assert (exist ("/dev/null", "dir"), 0);
624 %! endif
625 
626 %!assert (exist ("print_usage"), 2)
627 %!assert (exist ("print_usage.m"), 2)
628 %!assert (exist ("print_usage", "file"), 2)
629 %!assert (exist ("print_usage", "dir"), 0)
630 
631 ## Don't search path for rooted relative filenames
632 %!assert (exist ("plot.m", "file"), 2)
633 %!assert (exist ("./plot.m", "file"), 0)
634 %!assert (exist ("./%nonexistentfile%", "file"), 0)
635 %!assert (exist ("%nonexistentfile%", "file"), 0)
636 
637 ## Don't search path for absolute filenames
638 %!test
639 %! tname = tempname (pwd ());
640 %! unwind_protect
641 %! ## open/close file to create it, equivalent of touch
642 %! fid = fopen (tname, "w");
643 %! fclose (fid);
644 %! [~, fname] = fileparts (tname);
645 %! assert (exist (fullfile (pwd (), fname), "file"), 2);
646 %! unwind_protect_cleanup
647 %! unlink (tname);
648 %! end_unwind_protect
649 %! assert (exist (fullfile (pwd (), "%nonexistentfile%"), "file"), 0);
650 
651 %!testif HAVE_CHOLMOD
652 %! assert (exist ("chol"), 3);
653 %! assert (exist ("chol.oct"), 3);
654 %! assert (exist ("chol", "file"), 3);
655 %! assert (exist ("chol", "builtin"), 0);
656 
657 %!assert (exist ("sin"), 5)
658 %!assert (exist ("sin", "builtin"), 5)
659 %!assert (exist ("sin", "file"), 0)
660 
661 %!assert (exist (dirtmp), 7)
662 %!assert (exist (dirtmp, "dir"), 7)
663 %!assert (exist (dirtmp, "file"), 7)
664 
665 %!error exist ()
666 %!error exist (1,2,3)
667 %!warning <"class" type argument is not implemented> exist ("a", "class");
668 %!error <TYPE must be a string> exist ("a", 1)
669 %!error <NAME must be a string> exist (1)
670 %!error <unrecognized type argument "foobar"> exist ("a", "foobar")
671 
672 */
673 
676 {
678 
679  return val.is_function_handle () ? val : octave_value ();
680 }
681 
683 get_global_value (const std::string& nm, bool silent)
684 {
686 
687  if (val.is_undefined () && ! silent)
688  error ("get_global_value: undefined symbol '%s'", nm.c_str ());
689 
690  return val;
691 }
692 
693 void
694 set_global_value (const std::string& nm, const octave_value& val)
695 {
696  symbol_table::global_assign (nm, val);
697 }
698 
700 get_top_level_value (const std::string& nm, bool silent)
701 {
703 
704  if (val.is_undefined () && ! silent)
705  error ("get_top_level_value: undefined symbol '%s'", nm.c_str ());
706 
707  return val;
708 }
709 
710 void
711 set_top_level_value (const std::string& nm, const octave_value& val)
712 {
714 }
715 
716 // Variable values.
717 
718 static bool
719 wants_local_change (const octave_value_list& args, int& nargin)
720 {
721  bool retval = false;
722 
723  if (nargin == 2)
724  {
725  if (! args(1).is_string () || args(1).string_value () != "local")
726  error_with_cfn ("second argument must be \"local\"");
727 
728  nargin = 1;
729  retval = true;
730  }
731 
732  return retval;
733 }
734 
735 template <typename T>
736 bool try_local_protect (T& var)
737 {
739  octave_user_function *curr_usr_fcn = 0;
740  if (curr_usr_code && curr_usr_code->is_user_function ())
741  curr_usr_fcn = dynamic_cast<octave_user_function *> (curr_usr_code);
742 
743  if (curr_usr_fcn && curr_usr_fcn->local_protect (var))
744  return true;
745  else
746  return false;
747 }
748 
750 set_internal_variable (bool& var, const octave_value_list& args,
751  int nargout, const char *nm)
752 {
754 
755  int nargin = args.length ();
756 
757  if (nargout > 0 || nargin == 0)
758  retval = var;
759 
760  if (wants_local_change (args, nargin))
761  {
762  if (! try_local_protect (var))
763  warning ("\"local\" has no effect outside a function");
764  }
765 
766  if (nargin > 1)
767  print_usage ();
768 
769  if (nargin == 1)
770  {
771  bool bval = args(0).xbool_value ("%s: argument must be a logical value", nm);
772 
773  var = bval;
774  }
775 
776  return retval;
777 }
778 
780 set_internal_variable (char& var, const octave_value_list& args,
781  int nargout, const char *nm)
782 {
784 
785  int nargin = args.length ();
786 
787  if (nargout > 0 || nargin == 0)
788  retval = var;
789 
790  if (wants_local_change (args, nargin))
791  {
792  if (! try_local_protect (var))
793  warning ("\"local\" has no effect outside a function");
794  }
795 
796  if (nargin > 1)
797  print_usage ();
798 
799  if (nargin == 1)
800  {
801  std::string sval = args(0).xstring_value ("%s: argument must be a single character", nm);
802 
803  switch (sval.length ())
804  {
805  case 1:
806  var = sval[0];
807  break;
808 
809  case 0:
810  var = '\0';
811  break;
812 
813  default:
814  error ("%s: argument must be a single character", nm);
815  break;
816  }
817  }
818 
819  return retval;
820 }
821 
823 set_internal_variable (int& var, const octave_value_list& args,
824  int nargout, const char *nm,
825  int minval, int maxval)
826 {
828 
829  int nargin = args.length ();
830 
831  if (nargout > 0 || nargin == 0)
832  retval = var;
833 
834  if (wants_local_change (args, nargin))
835  {
836  if (! try_local_protect (var))
837  warning ("\"local\" has no effect outside a function");
838  }
839 
840  if (nargin > 1)
841  print_usage ();
842 
843  if (nargin == 1)
844  {
845  int ival = args(0).xint_value ("%s: argument must be an integer value", nm);
846 
847  if (ival < minval)
848  error ("%s: arg must be greater than %d", nm, minval);
849  if (ival > maxval)
850  error ("%s: arg must be less than or equal to %d", nm, maxval);
851 
852  var = ival;
853  }
854 
855  return retval;
856 }
857 
859 set_internal_variable (double& var, const octave_value_list& args,
860  int nargout, const char *nm,
861  double minval, double maxval)
862 {
864 
865  int nargin = args.length ();
866 
867  if (nargout > 0 || nargin == 0)
868  retval = var;
869 
870  if (wants_local_change (args, nargin))
871  {
872  if (! try_local_protect (var))
873  warning ("\"local\" has no effect outside a function");
874  }
875 
876  if (nargin > 1)
877  print_usage ();
878 
879  if (nargin == 1)
880  {
881  double dval = args(0).xscalar_value ("%s: argument must be a scalar value", nm);
882 
883  if (dval < minval)
884  error ("%s: argument must be greater than %g", minval);
885  if (dval > maxval)
886  error ("%s: argument must be less than or equal to %g", maxval);
887 
888  var = dval;
889  }
890 
891  return retval;
892 }
893 
896  int nargout, const char *nm, bool empty_ok)
897 {
899 
900  int nargin = args.length ();
901 
902  if (nargout > 0 || nargin == 0)
903  retval = var;
904 
905  if (wants_local_change (args, nargin))
906  {
907  if (! try_local_protect (var))
908  warning ("\"local\" has no effect outside a function");
909  }
910 
911  if (nargin > 1)
912  print_usage ();
913 
914  if (nargin == 1)
915  {
916  std::string sval = args(0).xstring_value ("%s: first argument must be a string", nm);
917 
918  if (! empty_ok && sval.empty ())
919  error ("%s: value must not be empty", nm);
920 
921  var = sval;
922  }
923 
924  return retval;
925 }
926 
928 set_internal_variable (int& var, const octave_value_list& args,
929  int nargout, const char *nm, const char **choices)
930 {
932  int nchoices = 0;
933  while (choices[nchoices] != 0)
934  nchoices++;
935 
936  int nargin = args.length ();
937 
938  assert (var < nchoices);
939 
940  if (nargout > 0 || nargin == 0)
941  retval = choices[var];
942 
943  if (wants_local_change (args, nargin))
944  {
945  if (! try_local_protect (var))
946  warning ("\"local\" has no effect outside a function");
947  }
948 
949  if (nargin > 1)
950  print_usage ();
951 
952  if (nargin == 1)
953  {
954  std::string sval = args(0).xstring_value ("%s: first argument must be a string", nm);
955 
956  int i = 0;
957  for (; i < nchoices; i++)
958  {
959  if (sval == choices[i])
960  {
961  var = i;
962  break;
963  }
964  }
965  if (i == nchoices)
966  error ("%s: value not allowed (\"%s\")", nm, sval.c_str ());
967  }
968 
969  return retval;
970 }
971 
974  int nargout, const char *nm, const char **choices)
975 {
977  int nchoices = 0;
978  while (choices[nchoices] != 0)
979  nchoices++;
980 
981  int nargin = args.length ();
982 
983  if (nargout > 0 || nargin == 0)
984  retval = var;
985 
986  if (wants_local_change (args, nargin))
987  {
988  if (! try_local_protect (var))
989  warning ("\"local\" has no effect outside a function");
990  }
991 
992  if (nargin > 1)
993  print_usage ();
994 
995  if (nargin == 1)
996  {
997  std::string sval = args(0).xstring_value ("%s: first argument must be a string", nm);
998 
999  int i = 0;
1000  for (; i < nchoices; i++)
1001  {
1002  if (sval == choices[i])
1003  {
1004  var = sval;
1005  break;
1006  }
1007  }
1008  if (i == nchoices)
1009  error ("%s: value not allowed (\"%s\")", nm, sval.c_str ());
1010  }
1011 
1012  return retval;
1013 }
1014 
1015 struct
1016 whos_parameter
1017 {
1018  char command;
1019  char modifier;
1020  int parameter_length;
1021  int first_parameter_length;
1022  int balance;
1023  std::string text;
1024  std::string line;
1025 };
1026 
1027 static void
1028 print_descriptor (std::ostream& os, std::list<whos_parameter> params)
1029 {
1030  // This method prints a line of information on a given symbol
1031  std::list<whos_parameter>::iterator i = params.begin ();
1032  std::ostringstream param_buf;
1033 
1034  octave_preserve_stream_state stream_state (os);
1035 
1036  while (i != params.end ())
1037  {
1038  whos_parameter param = *i;
1039 
1040  if (param.command != '\0')
1041  {
1042  // Do the actual printing
1043  switch (param.modifier)
1044  {
1045  case 'l':
1046  os << std::setiosflags (std::ios::left)
1047  << std::setw (param.parameter_length);
1048  param_buf << std::setiosflags (std::ios::left)
1049  << std::setw (param.parameter_length);
1050  break;
1051 
1052  case 'r':
1053  os << std::setiosflags (std::ios::right)
1054  << std::setw (param.parameter_length);
1055  param_buf << std::setiosflags (std::ios::right)
1056  << std::setw (param.parameter_length);
1057  break;
1058 
1059  case 'c':
1060  if (param.command != 's')
1061  {
1062  os << std::setiosflags (std::ios::left)
1063  << std::setw (param.parameter_length);
1064  param_buf << std::setiosflags (std::ios::left)
1065  << std::setw (param.parameter_length);
1066  }
1067  break;
1068 
1069  default:
1070  os << std::setiosflags (std::ios::left)
1071  << std::setw (param.parameter_length);
1072  param_buf << std::setiosflags (std::ios::left)
1073  << std::setw (param.parameter_length);
1074  }
1075 
1076  if (param.command == 's' && param.modifier == 'c')
1077  {
1078  int a, b;
1079 
1080  if (param.modifier == 'c')
1081  {
1082  a = param.first_parameter_length - param.balance;
1083  a = (a < 0 ? 0 : a);
1084  b = param.parameter_length - a - param.text.length ();
1085  b = (b < 0 ? 0 : b);
1086  os << std::setiosflags (std::ios::left) << std::setw (a)
1087  << "" << std::resetiosflags (std::ios::left) << param.text
1088  << std::setiosflags (std::ios::left)
1089  << std::setw (b) << ""
1090  << std::resetiosflags (std::ios::left);
1091  param_buf << std::setiosflags (std::ios::left)
1092  << std::setw (a)
1093  << "" << std::resetiosflags (std::ios::left)
1094  << param.line
1095  << std::setiosflags (std::ios::left)
1096  << std::setw (b) << ""
1097  << std::resetiosflags (std::ios::left);
1098  }
1099  }
1100  else
1101  {
1102  os << param.text;
1103  param_buf << param.line;
1104  }
1105  os << std::resetiosflags (std::ios::left)
1106  << std::resetiosflags (std::ios::right);
1107  param_buf << std::resetiosflags (std::ios::left)
1108  << std::resetiosflags (std::ios::right);
1109  i++;
1110  }
1111  else
1112  {
1113  os << param.text;
1114  param_buf << param.line;
1115  i++;
1116  }
1117  }
1118 
1119  os << param_buf.str ();
1120 }
1121 
1122 // FIXME: This is a bit of a kluge. We'd like to just use val.dims()
1123 // and if val is an object, expect that dims will call size if it is
1124 // overloaded by a user-defined method. But there are currently some
1125 // unresolved const issues that prevent that solution from working.
1126 // This same kluge is done in symtab.cc (do_workspace_info), fix there too.
1127 
1130 {
1131  octave_value tmp = val;
1132 
1133  Matrix sz = tmp.size ();
1134 
1136 
1137  for (octave_idx_type i = 0; i < dv.ndims (); i++)
1138  dv(i) = sz(i);
1139 
1140  return dv.str ();
1141 }
1142 
1143 class
1145 {
1146 private:
1148  {
1150  const std::string& expr_str = "",
1151  const octave_value& expr_val = octave_value ())
1152  : name (expr_str.empty () ? sr.name () : expr_str),
1153  varval (expr_val.is_undefined () ? sr.varval () : expr_val),
1154  is_automatic (sr.is_automatic ()),
1155  is_complex (varval.is_complex_type ()),
1156  is_formal (sr.is_formal ()),
1157  is_global (sr.is_global ()),
1158  is_persistent (sr.is_persistent ())
1159  { }
1160 
1161  void display_line (std::ostream& os,
1162  const std::list<whos_parameter>& params) const
1163  {
1164  std::string dims_str = get_dims_str (varval);
1165 
1166  std::list<whos_parameter>::const_iterator i = params.begin ();
1167 
1168  octave_preserve_stream_state stream_state (os);
1169 
1170  while (i != params.end ())
1171  {
1172  whos_parameter param = *i;
1173 
1174  if (param.command != '\0')
1175  {
1176  // Do the actual printing.
1177 
1178  switch (param.modifier)
1179  {
1180  case 'l':
1181  os << std::setiosflags (std::ios::left)
1182  << std::setw (param.parameter_length);
1183  break;
1184 
1185  case 'r':
1186  os << std::setiosflags (std::ios::right)
1187  << std::setw (param.parameter_length);
1188  break;
1189 
1190  case 'c':
1191  if (param.command == 's')
1192  {
1193  int front = param.first_parameter_length
1194  - dims_str.find ('x');
1195  int back = param.parameter_length
1196  - dims_str.length ()
1197  - front;
1198  front = (front > 0) ? front : 0;
1199  back = (back > 0) ? back : 0;
1200 
1201  os << std::setiosflags (std::ios::left)
1202  << std::setw (front)
1203  << ""
1204  << std::resetiosflags (std::ios::left)
1205  << dims_str
1206  << std::setiosflags (std::ios::left)
1207  << std::setw (back)
1208  << ""
1209  << std::resetiosflags (std::ios::left);
1210  }
1211  else
1212  {
1213  os << std::setiosflags (std::ios::left)
1214  << std::setw (param.parameter_length);
1215  }
1216  break;
1217 
1218  default:
1219  error ("whos_line_format: modifier '%c' unknown",
1220  param.modifier);
1221 
1222  os << std::setiosflags (std::ios::right)
1223  << std::setw (param.parameter_length);
1224  }
1225 
1226  switch (param.command)
1227  {
1228  case 'a':
1229  {
1230  char tmp[6];
1231 
1232  tmp[0] = (is_automatic ? 'a' : ' ');
1233  tmp[1] = (is_complex ? 'c' : ' ');
1234  tmp[2] = (is_formal ? 'f' : ' ');
1235  tmp[3] = (is_global ? 'g' : ' ');
1236  tmp[4] = (is_persistent ? 'p' : ' ');
1237  tmp[5] = 0;
1238 
1239  os << tmp;
1240  }
1241  break;
1242 
1243  case 'b':
1244  os << varval.byte_size ();
1245  break;
1246 
1247  case 'c':
1248  os << varval.class_name ();
1249  break;
1250 
1251  case 'e':
1252  os << varval.numel ();
1253  break;
1254 
1255  case 'n':
1256  os << name;
1257  break;
1258 
1259  case 's':
1260  if (param.modifier != 'c')
1261  os << dims_str;
1262  break;
1263 
1264  case 't':
1265  os << varval.type_name ();
1266  break;
1267 
1268  default:
1269  error ("whos_line_format: command '%c' unknown",
1270  param.command);
1271  }
1272 
1273  os << std::resetiosflags (std::ios::left)
1274  << std::resetiosflags (std::ios::right);
1275  i++;
1276  }
1277  else
1278  {
1279  os << param.text;
1280  i++;
1281  }
1282  }
1283  }
1284 
1292  };
1293 
1294 public:
1295  symbol_info_list (void) : lst () { }
1296 
1297  symbol_info_list (const symbol_info_list& sil) : lst (sil.lst) { }
1298 
1299  symbol_info_list& operator = (const symbol_info_list& sil)
1300  {
1301  if (this != &sil)
1302  lst = sil.lst;
1303 
1304  return *this;
1305  }
1306 
1308 
1310  {
1311  lst.push_back (symbol_info (sr));
1312  }
1313 
1315  const std::string& expr_str,
1316  const octave_value& expr_val)
1317  {
1318  lst.push_back (symbol_info (sr, expr_str, expr_val));
1319  }
1320 
1321  size_t size (void) const { return lst.size (); }
1322 
1323  bool empty (void) const { return lst.empty (); }
1324 
1325  octave_map
1326  map_value (const std::string& caller_function_name, int nesting_level) const
1327  {
1328  size_t len = lst.size ();
1329 
1330  Cell name_info (len, 1);
1331  Cell size_info (len, 1);
1332  Cell bytes_info (len, 1);
1333  Cell class_info (len, 1);
1334  Cell global_info (len, 1);
1335  Cell sparse_info (len, 1);
1336  Cell complex_info (len, 1);
1337  Cell nesting_info (len, 1);
1338  Cell persistent_info (len, 1);
1339 
1340  std::list<symbol_info>::const_iterator p = lst.begin ();
1341 
1342  for (size_t j = 0; j < len; j++)
1343  {
1344  const symbol_info& si = *p++;
1345 
1346  octave_scalar_map ni;
1347 
1348  ni.assign ("function", caller_function_name);
1349  ni.assign ("level", nesting_level);
1350 
1351  name_info(j) = si.name;
1352  global_info(j) = si.is_global;
1353  persistent_info(j) = si.is_persistent;
1354 
1355  octave_value val = si.varval;
1356 
1357  size_info(j) = val.size ();
1358  bytes_info(j) = val.byte_size ();
1359  class_info(j) = val.class_name ();
1360  sparse_info(j) = val.is_sparse_type ();
1361  complex_info(j) = val.is_complex_type ();
1362  nesting_info(j) = ni;
1363  }
1364 
1365  octave_map info;
1366 
1367  info.assign ("name", name_info);
1368  info.assign ("size", size_info);
1369  info.assign ("bytes", bytes_info);
1370  info.assign ("class", class_info);
1371  info.assign ("global", global_info);
1372  info.assign ("sparse", sparse_info);
1373  info.assign ("complex", complex_info);
1374  info.assign ("nesting", nesting_info);
1375  info.assign ("persistent", persistent_info);
1376 
1377  return info;
1378  }
1379 
1380  void display (std::ostream& os)
1381  {
1382  if (! lst.empty ())
1383  {
1384  size_t bytes = 0;
1385  size_t elements = 0;
1386 
1387  std::list<whos_parameter> params = parse_whos_line_format ();
1388 
1389  print_descriptor (os, params);
1390 
1391  octave_stdout << "\n";
1392 
1393  for (std::list<symbol_info>::const_iterator p = lst.begin ();
1394  p != lst.end (); p++)
1395  {
1396  p->display_line (os, params);
1397 
1398  octave_value val = p->varval;
1399 
1400  elements += val.numel ();
1401  bytes += val.byte_size ();
1402  }
1403 
1404  os << "\nTotal is " << elements
1405  << (elements == 1 ? " element" : " elements")
1406  << " using " << bytes << (bytes == 1 ? " byte" : " bytes")
1407  << "\n";
1408  }
1409  }
1410 
1411  // Parse the string whos_line_format, and return a parameter list,
1412  // containing all information needed to print the given
1413  // attributes of the symbols.
1414  std::list<whos_parameter> parse_whos_line_format (void)
1415  {
1416  int idx;
1417  size_t format_len = Vwhos_line_format.length ();
1418  char garbage;
1419  std::list<whos_parameter> params;
1420 
1421  size_t bytes1;
1422  int elements1;
1423 
1424  std::string param_string = "abcenst";
1425  Array<int> param_length (dim_vector (param_string.length (), 1));
1426  Array<std::string> param_names (dim_vector (param_string.length (), 1));
1427  size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t;
1428 
1429  pos_a = param_string.find ('a'); // Attributes
1430  pos_b = param_string.find ('b'); // Bytes
1431  pos_c = param_string.find ('c'); // Class
1432  pos_e = param_string.find ('e'); // Elements
1433  pos_n = param_string.find ('n'); // Name
1434  pos_s = param_string.find ('s'); // Size
1435  pos_t = param_string.find ('t'); // Type
1436 
1437  param_names(pos_a) = "Attr";
1438  param_names(pos_b) = "Bytes";
1439  param_names(pos_c) = "Class";
1440  param_names(pos_e) = "Elements";
1441  param_names(pos_n) = "Name";
1442  param_names(pos_s) = "Size";
1443  param_names(pos_t) = "Type";
1444 
1445  for (size_t i = 0; i < param_string.length (); i++)
1446  param_length(i) = param_names(i).length ();
1447 
1448  // The attribute column needs size 5.
1449  param_length(pos_a) = 5;
1450 
1451  // Calculating necessary spacing for name column,
1452  // bytes column, elements column and class column
1453 
1454  for (std::list<symbol_info>::const_iterator p = lst.begin ();
1455  p != lst.end (); p++)
1456  {
1457  std::stringstream ss1, ss2;
1458  std::string str;
1459 
1460  str = p->name;
1461  param_length(pos_n) = ((str.length ()
1462  > static_cast<size_t> (param_length(pos_n)))
1463  ? str.length () : param_length(pos_n));
1464 
1465  octave_value val = p->varval;
1466 
1467  str = val.type_name ();
1468  param_length(pos_t) = ((str.length ()
1469  > static_cast<size_t> (param_length(pos_t)))
1470  ? str.length () : param_length(pos_t));
1471 
1472  elements1 = val.numel ();
1473  ss1 << elements1;
1474  str = ss1.str ();
1475  param_length(pos_e) = ((str.length ()
1476  > static_cast<size_t> (param_length(pos_e)))
1477  ? str.length () : param_length(pos_e));
1478 
1479  bytes1 = val.byte_size ();
1480  ss2 << bytes1;
1481  str = ss2.str ();
1482  param_length(pos_b) = ((str.length ()
1483  > static_cast<size_t> (param_length(pos_b)))
1484  ? str.length () : param_length (pos_b));
1485  }
1486 
1487  idx = 0;
1488  while (static_cast<size_t> (idx) < format_len)
1489  {
1490  whos_parameter param;
1491  param.command = '\0';
1492 
1493  if (Vwhos_line_format[idx] == '%')
1494  {
1495  bool error_encountered = false;
1496  param.modifier = 'r';
1497  param.parameter_length = 0;
1498 
1499  int a = 0;
1500  int b = -1;
1501  int balance = 1;
1502  unsigned int items;
1503  size_t pos;
1504  std::string cmd;
1505 
1506  // Parse one command from whos_line_format
1507  cmd = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
1508  pos = cmd.find (';');
1509  if (pos == std::string::npos)
1510  error ("parameter without ; in whos_line_format");
1511 
1512  cmd = cmd.substr (0, pos+1);
1513 
1514  idx += cmd.length ();
1515 
1516  // FIXME: use iostream functions instead of sscanf!
1517 
1518  if (cmd.find_first_of ("crl") != 1)
1519  items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d;",
1520  &garbage, &param.command, &a, &b, &balance);
1521  else
1522  items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d;",
1523  &garbage, &param.modifier, &param.command,
1524  &a, &b, &balance) - 1;
1525 
1526  if (items < 2)
1527  error ("whos_line_format: parameter structure without command in whos_line_format");
1528 
1529  // Insert data into parameter
1530  param.first_parameter_length = 0;
1531  pos = param_string.find (param.command);
1532  if (pos == std::string::npos)
1533  error ("whos_line_format: '%c' is not a command", param.command);
1534 
1535  param.parameter_length = param_length(pos);
1536  param.text = param_names(pos);
1537  param.line.assign (param_names(pos).length (), '=');
1538 
1539  param.parameter_length = (a > param.parameter_length
1540  ? a : param.parameter_length);
1541  if (param.command == 's' && param.modifier == 'c' && b > 0)
1542  param.first_parameter_length = b;
1543 
1544  if (param.command == 's')
1545  {
1546  // Have to calculate space needed for printing
1547  // matrix dimensions Space needed for Size column is
1548  // hard to determine in prior, because it depends on
1549  // dimensions to be shown. That is why it is
1550  // recalculated for each Size-command int first,
1551  // rest = 0, total;
1552  int rest = 0;
1553  int first = param.first_parameter_length;
1554  int total = param.parameter_length;
1555 
1556  for (std::list<symbol_info>::const_iterator p = lst.begin ();
1557  p != lst.end (); p++)
1558  {
1559  octave_value val = p->varval;
1560  std::string dims_str = get_dims_str (val);
1561  int first1 = dims_str.find ('x');
1562  int total1 = dims_str.length ();
1563  int rest1 = total1 - first1;
1564  rest = (rest1 > rest ? rest1 : rest);
1565  first = (first1 > first ? first1 : first);
1566  total = (total1 > total ? total1 : total);
1567  }
1568 
1569  if (param.modifier == 'c')
1570  {
1571  if (first < balance)
1572  first += balance - first;
1573  if (rest + balance < param.parameter_length)
1574  rest += param.parameter_length - rest - balance;
1575 
1576  param.parameter_length = first + rest;
1577  param.first_parameter_length = first;
1578  param.balance = balance;
1579  }
1580  else
1581  {
1582  param.parameter_length = total;
1583  param.first_parameter_length = 0;
1584  }
1585  }
1586  else if (param.modifier == 'c')
1587  error ("whos_line_format: modifier 'c' not available for command '%c'",
1588  param.command);
1589 
1590  // What happens if whos_line_format contains negative numbers
1591  // at param_length positions?
1592  param.balance = (b < 0 ? 0 : param.balance);
1593  param.first_parameter_length = (b < 0 ? 0 :
1594  param.first_parameter_length);
1595  param.parameter_length = (a < 0
1596  ? 0
1597  : (param.parameter_length
1598  < param_length(pos_s)
1599  ? param_length(pos_s)
1600  : param.parameter_length));
1601 
1602  // Parameter will not be pushed into parameter list if ...
1603  if (! error_encountered)
1604  params.push_back (param);
1605  }
1606  else
1607  {
1608  // Text string, to be printed as it is ...
1609  std::string text;
1610  size_t pos;
1611  text = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
1612  pos = text.find ('%');
1613  if (pos != std::string::npos)
1614  text = text.substr (0, pos);
1615 
1616  // Push parameter into list ...
1617  idx += text.length ();
1618  param.text=text;
1619  param.line.assign (text.length (), ' ');
1620  params.push_back (param);
1621  }
1622  }
1623 
1624  return params;
1625  }
1626 
1627 private:
1628  std::list<symbol_info> lst;
1629 
1630 };
1631 
1632 static octave_value
1633 do_who (int argc, const string_vector& argv, bool return_list,
1634  bool verbose = false, std::string msg = "")
1635 {
1637 
1638  std::string my_name = argv[0];
1639 
1640  bool global_only = false;
1641  bool have_regexp = false;
1642 
1643  int i;
1644  for (i = 1; i < argc; i++)
1645  {
1646  if (argv[i] == "-file")
1647  {
1648  // FIXME: This is an inefficient manner to implement this as the
1649  // variables are loaded in to a temporary context and then treated.
1650  // It would be better to refecat symbol_info_list to not store the
1651  // symbol records and then use it in load-save.cc (do_load) to
1652  // implement this option there so that the variables are never
1653  // stored at all.
1654  if (i == argc - 1)
1655  error ("whos: -file argument must be followed by a filename");
1656 
1657  std::string nm = argv[i + 1];
1658 
1660 
1661  // Set up temporary scope.
1662 
1664  frame.add_fcn (symbol_table::erase_scope, tmp_scope);
1665 
1666  symbol_table::set_scope (tmp_scope);
1667 
1668  octave_call_stack::push (tmp_scope, 0);
1670 
1672 
1673  feval ("load", octave_value (nm), 0);
1674 
1675  std::string newmsg = std::string ("Variables in the file ")
1676  + nm + ":\n\n";
1677 
1678  retval = do_who (i, argv, return_list, verbose, newmsg);
1679 
1680  return retval;
1681  }
1682  else if (argv[i] == "-regexp")
1683  have_regexp = true;
1684  else if (argv[i] == "global")
1685  global_only = true;
1686  else if (argv[i][0] == '-')
1687  warning ("%s: unrecognized option '%s'", my_name.c_str (),
1688  argv[i].c_str ());
1689  else
1690  break;
1691  }
1692 
1693  int npats = argc - i;
1694  string_vector pats;
1695  if (npats > 0)
1696  {
1697  pats.resize (npats);
1698  for (int j = 0; j < npats; j++)
1699  pats[j] = argv[i+j];
1700  }
1701  else
1702  {
1703  pats.resize (++npats);
1704  pats[0] = "*";
1705  }
1706 
1707  symbol_info_list symbol_stats;
1708  std::list<std::string> symbol_names;
1709 
1710  for (int j = 0; j < npats; j++)
1711  {
1712  std::string pat = pats[j];
1713 
1714  if (have_regexp)
1715  {
1716  std::list<symbol_table::symbol_record> tmp = global_only
1719 
1720  for (std::list<symbol_table::symbol_record>::const_iterator
1721  p = tmp.begin (); p != tmp.end (); p++)
1722  {
1723  if (p->is_variable ())
1724  {
1725  if (verbose)
1726  symbol_stats.append (*p);
1727  else
1728  symbol_names.push_back (p->name ());
1729  }
1730  }
1731  }
1732  else
1733  {
1734  size_t pos = pat.find_first_of (".({");
1735 
1736  if (pos != std::string::npos && pos > 0)
1737  {
1738  if (verbose)
1739  {
1740  // NOTE: we can only display information for
1741  // expressions based on global values if the variable is
1742  // global in the current scope because we currently have
1743  // no way of looking up the base value in the global
1744  // scope and then evaluating the arguments in the
1745  // current scope.
1746 
1747  std::string base_name = pat.substr (0, pos);
1748 
1749  if (symbol_table::is_variable (base_name))
1750  {
1752  = symbol_table::find_symbol (base_name);
1753 
1754  if (! global_only || sr.is_global ())
1755  {
1756  int parse_status;
1757 
1758  octave_value expr_val
1759  = eval_string (pat, true, parse_status);
1760 
1761  symbol_stats.append (sr, pat, expr_val);
1762  }
1763  }
1764  }
1765  }
1766  else
1767  {
1768  std::list<symbol_table::symbol_record> tmp = global_only
1771 
1772  for (std::list<symbol_table::symbol_record>::const_iterator
1773  p = tmp.begin (); p != tmp.end (); p++)
1774  {
1775  if (p->is_variable ())
1776  {
1777  if (verbose)
1778  symbol_stats.append (*p);
1779  else
1780  symbol_names.push_back (p->name ());
1781  }
1782  }
1783  }
1784  }
1785  }
1786 
1787  if (return_list)
1788  {
1789  if (verbose)
1790  {
1791  std::string caller_function_name;
1793  if (caller)
1794  caller_function_name = caller->name ();
1795 
1796  retval = symbol_stats.map_value (caller_function_name, 1);
1797  }
1798  else
1799  retval = Cell (string_vector (symbol_names));
1800  }
1801  else if (! (symbol_stats.empty () && symbol_names.empty ()))
1802  {
1803  if (msg.empty ())
1804  if (global_only)
1805  octave_stdout << "Global variables:\n\n";
1806  else
1807  octave_stdout << "Variables in the current scope:\n\n";
1808  else
1809  octave_stdout << msg;
1810 
1811  if (verbose)
1812  symbol_stats.display (octave_stdout);
1813  else
1814  {
1815  string_vector names (symbol_names);
1816 
1818  }
1819 
1820  octave_stdout << "\n";
1821  }
1822 
1823  return retval;
1824 }
1825 
1826 DEFUN (who, args, nargout,
1827  doc: /* -*- texinfo -*-
1828 @deftypefn {} {} who
1829 @deftypefnx {} {} who pattern @dots{}
1830 @deftypefnx {} {} who option pattern @dots{}
1831 @deftypefnx {} {C =} who ("pattern", @dots{})
1832 List currently defined variables matching the given patterns.
1833 
1834 Valid pattern syntax is the same as described for the @code{clear} command.
1835 If no patterns are supplied, all variables are listed.
1836 
1837 By default, only variables visible in the local scope are displayed.
1838 
1839 The following are valid options, but may not be combined.
1840 
1841 @table @code
1842 @item global
1843 List variables in the global scope rather than the current scope.
1844 
1845 @item -regexp
1846 The patterns are considered to be regular expressions when matching the
1847 variables to display. The same pattern syntax accepted by the @code{regexp}
1848 function is used.
1849 
1850 @item -file
1851 The next argument is treated as a filename. All variables found within the
1852 specified file are listed. No patterns are accepted when reading variables
1853 from a file.
1854 @end table
1855 
1856 If called as a function, return a cell array of defined variable names
1857 matching the given patterns.
1858 @seealso{whos, isglobal, isvarname, exist, regexp}
1859 @end deftypefn */)
1860 {
1861  int argc = args.length () + 1;
1862 
1863  string_vector argv = args.make_argv ("who");
1864 
1865  return do_who (argc, argv, nargout == 1);
1866 }
1867 
1868 DEFUN (whos, args, nargout,
1869  doc: /* -*- texinfo -*-
1870 @deftypefn {} {} whos
1871 @deftypefnx {} {} whos pattern @dots{}
1872 @deftypefnx {} {} whos option pattern @dots{}
1873 @deftypefnx {} {S =} whos ("pattern", @dots{})
1874 Provide detailed information on currently defined variables matching the
1875 given patterns.
1876 
1877 Options and pattern syntax are the same as for the @code{who} command.
1878 
1879 Extended information about each variable is summarized in a table with the
1880 following default entries.
1881 
1882 @table @asis
1883 @item Attr
1884 Attributes of the listed variable. Possible attributes are:
1885 
1886 @table @asis
1887 @item blank
1888 Variable in local scope
1889 
1890 @item @code{a}
1891 Automatic variable. An automatic variable is one created by the
1892 interpreter, for example @code{argn}.
1893 
1894 @item @code{c}
1895 Variable of complex type.
1896 
1897 @item @code{f}
1898 Formal parameter (function argument).
1899 
1900 @item @code{g}
1901 Variable with global scope.
1902 
1903 @item @code{p}
1904 Persistent variable.
1905 @end table
1906 
1907 @item Name
1908 The name of the variable.
1909 
1910 @item Size
1911 The logical size of the variable. A scalar is 1x1, a vector is
1912 @nospell{1xN} or @nospell{Nx1}, a 2-D matrix is @nospell{MxN}.
1913 
1914 @item Bytes
1915 The amount of memory currently used to store the variable.
1916 
1917 @item Class
1918 The class of the variable. Examples include double, single, char, uint16,
1919 cell, and struct.
1920 @end table
1921 
1922 The table can be customized to display more or less information through
1923 the function @code{whos_line_format}.
1924 
1925 If @code{whos} is called as a function, return a struct array of defined
1926 variable names matching the given patterns. Fields in the structure
1927 describing each variable are: name, size, bytes, class, global, sparse,
1928 complex, nesting, persistent.
1929 @seealso{who, whos_line_format}
1930 @end deftypefn */)
1931 {
1932  int argc = args.length () + 1;
1933 
1934  string_vector argv = args.make_argv ("whos");
1935 
1936  return do_who (argc, argv, nargout == 1, true);
1937 }
1938 
1939 // Defining variables.
1940 
1941 void
1942 bind_ans (const octave_value& val, bool print)
1943 {
1944  static std::string ans = "ans";
1945 
1946  if (val.is_defined ())
1947  {
1948  if (val.is_cs_list ())
1949  {
1950  octave_value_list lst = val.list_value ();
1951 
1952  for (octave_idx_type i = 0; i < lst.length (); i++)
1953  bind_ans (lst(i), print);
1954  }
1955  else
1956  {
1957  symbol_table::force_assign (ans, val);
1958 
1959  if (print)
1960  val.print_with_name (octave_stdout, ans);
1961  }
1962  }
1963 }
1964 
1965 void
1967 {
1969 
1970  args(0) = val;
1971 
1972  feval (fname, args, 0);
1973 }
1974 
1975 void
1976 mlock (void)
1977 {
1979 
1980  if (! fcn)
1981  error ("mlock: invalid use outside a function");
1982 
1983  fcn->lock ();
1984 }
1985 
1986 void
1987 munlock (const std::string& nm)
1988 {
1990 
1991  if (val.is_defined ())
1992  {
1993  octave_function *fcn = val.function_value ();
1994 
1995  if (fcn)
1996  fcn->unlock ();
1997  }
1998 }
1999 
2000 bool
2001 mislocked (const std::string& nm)
2002 {
2003  bool retval = false;
2004 
2006 
2007  if (val.is_defined ())
2008  {
2009  octave_function *fcn = val.function_value ();
2010 
2011  if (fcn)
2012  retval = fcn->islocked ();
2013  }
2014 
2015  return retval;
2016 }
2017 
2018 DEFUN (mlock, args, ,
2019  doc: /* -*- texinfo -*-
2020 @deftypefn {} {} mlock ()
2021 Lock the current function into memory so that it can't be cleared.
2022 @seealso{munlock, mislocked, persistent}
2023 @end deftypefn */)
2024 {
2025  if (args.length () != 0)
2026  print_usage ();
2027 
2029 
2030  if (! fcn)
2031  error ("mlock: invalid use outside a function");
2032 
2033  fcn->lock ();
2034 
2035  return ovl ();
2036 }
2037 
2038 DEFUN (munlock, args, ,
2039  doc: /* -*- texinfo -*-
2040 @deftypefn {} {} munlock ()
2041 @deftypefnx {} {} munlock (@var{fcn})
2042 Unlock the named function @var{fcn}.
2043 
2044 If no function is named then unlock the current function.
2045 @seealso{mlock, mislocked, persistent}
2046 @end deftypefn */)
2047 {
2048  int nargin = args.length ();
2049 
2050  if (nargin > 1)
2051  print_usage ();
2052 
2053  if (nargin == 1)
2054  {
2055  std::string name = args(0).xstring_value ("munlock: FCN must be a string");
2056 
2057  munlock (name);
2058  }
2059  else
2060  {
2062 
2063  if (! fcn)
2064  error ("munlock: invalid use outside a function");
2065 
2066  fcn->unlock ();
2067  }
2068 
2069  return ovl ();
2070 }
2071 
2072 DEFUN (mislocked, args, ,
2073  doc: /* -*- texinfo -*-
2074 @deftypefn {} {} mislocked ()
2075 @deftypefnx {} {} mislocked (@var{fcn})
2076 Return true if the named function @var{fcn} is locked.
2077 
2078 If no function is named then return true if the current function is locked.
2079 @seealso{mlock, munlock, persistent}
2080 @end deftypefn */)
2081 {
2082  int nargin = args.length ();
2083 
2084  if (nargin > 1)
2085  print_usage ();
2086 
2088 
2089  if (nargin == 1)
2090  {
2091  std::string name = args(0).xstring_value ("mislocked: FCN must be a string");
2092 
2093  retval = mislocked (name);
2094  }
2095  else
2096  {
2098 
2099  if (! fcn)
2100  error ("mislocked: invalid use outside a function");
2101 
2102  retval = fcn->islocked ();
2103  }
2104 
2105  return retval;
2106 }
2107 
2108 // Deleting names from the symbol tables.
2109 
2110 static inline bool
2111 name_matches_any_pattern (const std::string& nm, const string_vector& argv,
2112  int argc, int idx, bool have_regexp = false)
2113 {
2114  bool retval = false;
2115 
2116  for (int k = idx; k < argc; k++)
2117  {
2118  std::string patstr = argv[k];
2119  if (! patstr.empty ())
2120  {
2121  if (have_regexp)
2122  {
2123  if (octave::regexp::is_match (patstr, nm))
2124  {
2125  retval = true;
2126  break;
2127  }
2128  }
2129  else
2130  {
2131  glob_match pattern (patstr);
2132 
2133  if (pattern.match (nm))
2134  {
2135  retval = true;
2136  break;
2137  }
2138  }
2139  }
2140  }
2141 
2142  return retval;
2143 }
2144 
2145 static inline void
2146 maybe_warn_exclusive (bool exclusive)
2147 {
2148  if (exclusive)
2149  warning ("clear: ignoring --exclusive option");
2150 }
2151 
2152 static void
2153 do_clear_functions (const string_vector& argv, int argc, int idx,
2154  bool exclusive = false)
2155 {
2156  if (idx == argc)
2158  else
2159  {
2160  if (exclusive)
2161  {
2163 
2164  int fcount = fcns.numel ();
2165 
2166  for (int i = 0; i < fcount; i++)
2167  {
2168  std::string nm = fcns[i];
2169 
2170  if (! name_matches_any_pattern (nm, argv, argc, idx))
2172  }
2173  }
2174  else
2175  {
2176  while (idx < argc)
2178  }
2179  }
2180 }
2181 
2182 static void
2183 do_clear_globals (const string_vector& argv, int argc, int idx,
2184  bool exclusive = false)
2185 {
2186  if (idx == argc)
2187  {
2189 
2190  int gcount = gvars.numel ();
2191 
2192  for (int i = 0; i < gcount; i++)
2193  symbol_table::clear_global (gvars[i]);
2194  }
2195  else
2196  {
2197  if (exclusive)
2198  {
2200 
2201  int gcount = gvars.numel ();
2202 
2203  for (int i = 0; i < gcount; i++)
2204  {
2205  std::string nm = gvars[i];
2206 
2207  if (! name_matches_any_pattern (nm, argv, argc, idx))
2209  }
2210  }
2211  else
2212  {
2213  while (idx < argc)
2214  symbol_table::clear_global_pattern (argv[idx++]);
2215  }
2216  }
2217 }
2218 
2219 static void
2220 do_clear_variables (const string_vector& argv, int argc, int idx,
2221  bool exclusive = false, bool have_regexp = false)
2222 {
2223  if (idx == argc)
2225  else
2226  {
2227  if (exclusive)
2228  {
2230 
2231  int lcount = lvars.numel ();
2232 
2233  for (int i = 0; i < lcount; i++)
2234  {
2235  std::string nm = lvars[i];
2236 
2237  if (! name_matches_any_pattern (nm, argv, argc, idx, have_regexp))
2239  }
2240  }
2241  else
2242  {
2243  if (have_regexp)
2244  while (idx < argc)
2246  else
2247  while (idx < argc)
2249  }
2250  }
2251 }
2252 
2253 static void
2254 do_clear_symbols (const string_vector& argv, int argc, int idx,
2255  bool exclusive = false)
2256 {
2257  if (idx == argc)
2259  else
2260  {
2261  if (exclusive)
2262  {
2263  // FIXME: is this really what we want, or do we
2264  // somehow want to only clear the functions that are not
2265  // shadowed by local variables? It seems that would be a
2266  // bit harder to do.
2267 
2268  do_clear_variables (argv, argc, idx, exclusive);
2269  do_clear_functions (argv, argc, idx, exclusive);
2270  }
2271  else
2272  {
2273  while (idx < argc)
2274  symbol_table::clear_symbol_pattern (argv[idx++]);
2275  }
2276  }
2277 }
2278 
2279 static void
2280 do_matlab_compatible_clear (const string_vector& argv, int argc, int idx)
2281 {
2282  // This is supposed to be mostly Matlab compatible.
2283 
2284  for (; idx < argc; idx++)
2285  {
2286  if (argv[idx] == "all"
2287  && ! symbol_table::is_local_variable ("all"))
2288  {
2290  }
2291  else if (argv[idx] == "functions"
2292  && ! symbol_table::is_local_variable ("functions"))
2293  {
2294  do_clear_functions (argv, argc, ++idx);
2295  }
2296  else if (argv[idx] == "global"
2297  && ! symbol_table::is_local_variable ("global"))
2298  {
2299  do_clear_globals (argv, argc, ++idx);
2300  }
2301  else if (argv[idx] == "variables"
2302  && ! symbol_table::is_local_variable ("variables"))
2303  {
2305  }
2306  else if (argv[idx] == "classes"
2307  && ! symbol_table::is_local_variable ("classes"))
2308  {
2312  }
2313  else
2314  {
2316  }
2317  }
2318 }
2319 
2320 #define CLEAR_OPTION_ERROR(cond) \
2321  do \
2322  { \
2323  if (cond) \
2324  print_usage (); \
2325  } \
2326  while (0)
2327 
2328 DEFUN (clear, args, ,
2329  doc: /* -*- texinfo -*-
2330 @deftypefn {} {} clear [options] pattern @dots{}
2331 Delete the names matching the given patterns from the symbol table.
2332 
2333 The pattern may contain the following special characters:
2334 
2335 @table @code
2336 @item ?
2337 Match any single character.
2338 
2339 @item *
2340 Match zero or more characters.
2341 
2342 @item [ @var{list} ]
2343 Match the list of characters specified by @var{list}. If the first
2344 character is @code{!} or @code{^}, match all characters except those
2345 specified by @var{list}. For example, the pattern @samp{[a-zA-Z]} will
2346 match all lowercase and uppercase alphabetic characters.
2347 @end table
2348 
2349 For example, the command
2350 
2351 @example
2352 clear foo b*r
2353 @end example
2354 
2355 @noindent
2356 clears the name @code{foo} and all names that begin with the letter
2357 @code{b} and end with the letter @code{r}.
2358 
2359 If @code{clear} is called without any arguments, all user-defined
2360 variables (local and global) are cleared from the symbol table.
2361 
2362 If @code{clear} is called with at least one argument, only the visible
2363 names matching the arguments are cleared. For example, suppose you have
2364 defined a function @code{foo}, and then hidden it by performing the
2365 assignment @code{foo = 2}. Executing the command @kbd{clear foo} once
2366 will clear the variable definition and restore the definition of
2367 @code{foo} as a function. Executing @kbd{clear foo} a second time will
2368 clear the function definition.
2369 
2370 The following options are available in both long and short form
2371 
2372 @table @code
2373 @item -all, -a
2374 Clear all local and global user-defined variables and all functions from the
2375 symbol table.
2376 
2377 @item -exclusive, -x
2378 Clear the variables that don't match the following pattern.
2379 
2380 @item -functions, -f
2381 Clear the function names and the built-in symbols names.
2382 
2383 @item -global, -g
2384 Clear global symbol names.
2385 
2386 @item -variables, -v
2387 Clear local variable names.
2388 
2389 @item -classes, -c
2390 Clears the class structure table and clears all objects.
2391 
2392 @item -regexp, -r
2393 The arguments are treated as regular expressions as any variables that
2394 match will be cleared.
2395 @end table
2396 
2397 With the exception of @code{exclusive}, all long options can be used
2398 without the dash as well.
2399 @seealso{who, whos, exist}
2400 @end deftypefn */)
2401 {
2402  int argc = args.length () + 1;
2403 
2404  string_vector argv = args.make_argv ("clear");
2405 
2406  if (argc == 1)
2407  {
2408  do_clear_globals (argv, argc, true);
2409  do_clear_variables (argv, argc, true);
2410 
2412  }
2413  else
2414  {
2415  int idx = 0;
2416 
2417  bool clear_all = false;
2418  bool clear_functions = false;
2419  bool clear_globals = false;
2420  bool clear_variables = false;
2421  bool clear_objects = false;
2422  bool exclusive = false;
2423  bool have_regexp = false;
2424  bool have_dash_option = false;
2425 
2426  while (++idx < argc)
2427  {
2428  if (argv[idx] == "-all" || argv[idx] == "-a")
2429  {
2430  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2431 
2432  have_dash_option = true;
2433  clear_all = true;
2434  }
2435  else if (argv[idx] == "-exclusive" || argv[idx] == "-x")
2436  {
2437  have_dash_option = true;
2438  exclusive = true;
2439  }
2440  else if (argv[idx] == "-functions" || argv[idx] == "-f")
2441  {
2442  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2443 
2444  have_dash_option = true;
2445  clear_functions = true;
2446  }
2447  else if (argv[idx] == "-global" || argv[idx] == "-g")
2448  {
2449  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2450 
2451  have_dash_option = true;
2452  clear_globals = true;
2453  }
2454  else if (argv[idx] == "-variables" || argv[idx] == "-v")
2455  {
2456  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2457 
2458  have_dash_option = true;
2459  clear_variables = true;
2460  }
2461  else if (argv[idx] == "-classes" || argv[idx] == "-c")
2462  {
2463  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2464 
2465  have_dash_option = true;
2466  clear_objects = true;
2467  }
2468  else if (argv[idx] == "-regexp" || argv[idx] == "-r")
2469  {
2470  CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2471 
2472  have_dash_option = true;
2473  have_regexp = true;
2474  }
2475  else
2476  break;
2477  }
2478 
2479  if (idx <= argc)
2480  {
2481  if (! have_dash_option)
2482  do_matlab_compatible_clear (argv, argc, idx);
2483  else
2484  {
2485  if (clear_all)
2486  {
2487  maybe_warn_exclusive (exclusive);
2488 
2489  if (++idx < argc)
2490  warning ("clear: ignoring extra arguments after -all");
2491 
2493  }
2494  else if (have_regexp)
2495  {
2496  do_clear_variables (argv, argc, idx, exclusive, true);
2497  }
2498  else if (clear_functions)
2499  {
2500  do_clear_functions (argv, argc, idx, exclusive);
2501  }
2502  else if (clear_globals)
2503  {
2504  do_clear_globals (argv, argc, idx, exclusive);
2505  }
2506  else if (clear_variables)
2507  {
2508  do_clear_variables (argv, argc, idx, exclusive);
2509  }
2510  else if (clear_objects)
2511  {
2515  }
2516  else
2517  {
2518  do_clear_symbols (argv, argc, idx, exclusive);
2519  }
2520  }
2521 
2523  }
2524  }
2525 
2526  return ovl ();
2527 }
2528 
2529 DEFUN (whos_line_format, args, nargout,
2530  doc: /* -*- texinfo -*-
2531 @deftypefn {} {@var{val} =} whos_line_format ()
2532 @deftypefnx {} {@var{old_val} =} whos_line_format (@var{new_val})
2533 @deftypefnx {} {} whos_line_format (@var{new_val}, "local")
2534 Query or set the format string used by the command @code{whos}.
2535 
2536 A full format string is:
2537 @c Set example in small font to prevent overfull line
2538 
2539 @smallexample
2540 %[modifier]<command>[:width[:left-min[:balance]]];
2541 @end smallexample
2542 
2543 The following command sequences are available:
2544 
2545 @table @code
2546 @item %a
2547 Prints attributes of variables (g=global, p=persistent, f=formal parameter,
2548 a=automatic variable).
2549 
2550 @item %b
2551 Prints number of bytes occupied by variables.
2552 
2553 @item %c
2554 Prints class names of variables.
2555 
2556 @item %e
2557 Prints elements held by variables.
2558 
2559 @item %n
2560 Prints variable names.
2561 
2562 @item %s
2563 Prints dimensions of variables.
2564 
2565 @item %t
2566 Prints type names of variables.
2567 @end table
2568 
2569 Every command may also have an alignment modifier:
2570 
2571 @table @code
2572 @item l
2573 Left alignment.
2574 
2575 @item r
2576 Right alignment (default).
2577 
2578 @item c
2579 Column-aligned (only applicable to command %s).
2580 @end table
2581 
2582 The @code{width} parameter is a positive integer specifying the minimum
2583 number of columns used for printing. No maximum is needed as the field will
2584 auto-expand as required.
2585 
2586 The parameters @code{left-min} and @code{balance} are only available when
2587 the column-aligned modifier is used with the command @samp{%s}.
2588 @code{balance} specifies the column number within the field width which
2589 will be aligned between entries. Numbering starts from 0 which indicates
2590 the leftmost column. @code{left-min} specifies the minimum field width to
2591 the left of the specified balance column.
2592 
2593 The default format is:
2594 
2595 @qcode{" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;@xbackslashchar{}n"}
2596 
2597 When called from inside a function with the @qcode{"local"} option, the
2598 variable is changed locally for the function and any subroutines it calls.
2599 The original variable value is restored when exiting the function.
2600 @seealso{whos}
2601 @end deftypefn */)
2602 {
2603  return SET_INTERNAL_VARIABLE (whos_line_format);
2604 }
2605 
2606 static std::string Vmissing_function_hook = "__unimplemented__";
2607 
2608 DEFUN (missing_function_hook, args, nargout,
2609  doc: /* -*- texinfo -*-
2610 @deftypefn {} {@var{val} =} missing_function_hook ()
2611 @deftypefnx {} {@var{old_val} =} missing_function_hook (@var{new_val})
2612 @deftypefnx {} {} missing_function_hook (@var{new_val}, "local")
2613 Query or set the internal variable that specifies the function to call when
2614 an unknown identifier is requested.
2615 
2616 When called from inside a function with the @qcode{"local"} option, the
2617 variable is changed locally for the function and any subroutines it calls.
2618 The original variable value is restored when exiting the function.
2619 @seealso{missing_component_hook}
2620 @end deftypefn */)
2621 {
2622  return SET_INTERNAL_VARIABLE (missing_function_hook);
2623 }
2624 
2625 void maybe_missing_function_hook (const std::string& name)
2626 {
2627  // Don't do this if we're handling errors.
2628  if (buffer_error_messages == 0 && ! Vmissing_function_hook.empty ())
2629  {
2630  octave_value val = symbol_table::find_function (Vmissing_function_hook);
2631 
2632  if (val.is_defined ())
2633  {
2634  // Ensure auto-restoration.
2636  frame.protect_var (Vmissing_function_hook);
2637 
2638  // Clear the variable prior to calling the function.
2639  const std::string func_name = Vmissing_function_hook;
2640  Vmissing_function_hook.clear ();
2641 
2642  // Call.
2643  feval (func_name, octave_value (name));
2644  }
2645  }
2646 }
2647 
2648 DEFUN (__varval__, args, ,
2649  doc: /* -*- texinfo -*-
2650 @deftypefn {} {} __varval__ (@var{name})
2651 Return the value of the variable @var{name} directly from the symbol table.
2652 @end deftypefn */)
2653 {
2654  if (args.length () != 1)
2655  print_usage ();
2656 
2657  std::string name = args(0).xstring_value ("__varval__: first argument must be a variable name");
2658 
2659  return symbol_table::varval (args(0).string_value ());
2660 }
2661 
2663 
2664 DEFUN (missing_component_hook, args, nargout,
2665  doc: /* -*- texinfo -*-
2666 @deftypefn {} {@var{val} =} missing_component_hook ()
2667 @deftypefnx {} {@var{old_val} =} missing_component_hook (@var{new_val})
2668 @deftypefnx {} {} missing_component_hook (@var{new_val}, "local")
2669 Query or set the internal variable that specifies the function to call when
2670 a component of Octave is missing.
2671 
2672 This can be useful for packagers that may split the Octave installation into
2673 multiple sub-packages, for example, to provide a hint to users for how to
2674 install the missing components.
2675 
2676 When called from inside a function with the @qcode{"local"} option, the
2677 variable is changed locally for the function and any subroutines it calls.
2678 The original variable value is restored when exiting the function.
2679 
2680 The hook function is expected to be of the form
2681 
2682 @example
2683 @var{fcn} (@var{component})
2684 @end example
2685 
2686 Octave will call @var{fcn} with the name of the function that requires the
2687 component and a string describing the missing component. The hook function
2688 should return an error message to be displayed.
2689 @seealso{missing_function_hook}
2690 @end deftypefn */)
2691 {
2692  return SET_INTERNAL_VARIABLE (missing_component_hook);
2693 }
static void clear_objects(scope_id scope=xcurrent_scope)
Definition: symtab.h:1696
bool is_object(void) const
Definition: ov.h:593
OCTINTERP_API void set_top_level_value(const std::string &nm, const octave_value &val)
static int left
Definition: randmtzig.cc:185
void display_line(std::ostream &os, const std::list< whos_parameter > &params) const
Definition: variables.cc:1161
Definition: Cell.h:37
std::string str(char sep= 'x') const
Definition: dim-vector.cc:73
static void clear_functions(bool force=false)
Definition: symtab.h:1704
std::string get_dims_str(const octave_value &val)
Definition: variables.cc:1129
fname
Definition: load-save.cc:754
void lock(void)
Definition: ov-fcn.h:129
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:347
static void clear_variable_pattern(const std::string &pat, scope_id scope=xcurrent_scope)
Definition: symtab.h:1761
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
size_t size(void) const
Definition: variables.cc:1321
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
static std::string dir_sep_chars(void)
Definition: file-ops.h:85
in that an updated permutation matrix is returned Note that if var
Definition: lu.cc:606
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
int argc
Definition: load-save.cc:633
octave_idx_type length(void) const
Definition: ovl.h:96
bool is_defined(void) const
Definition: ov.h:536
static void set_scope(scope_id scope)
Definition: symtab.h:1169
bool local_protect(T &variable)
Definition: ov-usr-fcn.h:396
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup so it is best to provide a consistent set and leave this option set to zero tem it may help to set this parameter to a nonzero value it is probably best to try leaving this option set to zero first
Definition: DASSL-opts.cc:419
for large enough k
Definition: lu.cc:606
bool looks_like_struct(const std::string &text, char prev_char)
Definition: variables.cc:305
void run(size_t num)
void protect_var(T &var)
tem check only for symbols of the specified type Valid types are table asis item and there are multiple possible matches for name
Definition: variables.cc:582
static std::list< symbol_record > regexp_variables(const std::string &pattern, scope_id scope=xcurrent_scope)
Definition: symtab.h:2022
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
void error(const char *fmt,...)
Definition: error.cc:570
static void print_descriptor(std::ostream &os, std::list< whos_parameter > params)
Definition: variables.cc:1028
std::string name(void) const
Definition: ov-fcn.h:163
#define SET_INTERNAL_VARIABLE(NM)
Definition: variables.h:126
nd deftypefn *void maybe_missing_function_hook(const std::string &name)
Definition: variables.cc:2268
static octave_function * current(void)
Definition: call-stack.h:108
static scope_id alloc_scope(void)
Definition: symtab.h:1167
symbol_info_list(void)
Definition: variables.cc:1295
OCTINTERP_API std::string file_in_path(const std::string &, const std::string &)
static std::list< std::string > variable_names(scope_id scope=xcurrent_scope)
Definition: symtab.h:2146
static void clear_mex_functions(void)
Definition: symtab.h:1816
static std::string Vwhos_line_format
Definition: variables.cc:70
static bool is_variable(const std::string &name)
Definition: variables.cc:221
static octave_value do_who(int argc, const string_vector &argv, bool return_list, bool verbose=false, std::string msg="")
Definition: variables.cc:1633
to define functions rather than attempting to enter them directly on the command line The block of commands is executed as soon as you exit the editor To avoid executing any simply delete all the lines from the buffer before leaving the editor When invoked with no edit the previously executed command
Definition: oct-hist.cc:587
std::string xstring_value(const char *fmt,...) const
Definition: ov.cc:2122
s
Definition: file-io.cc:2682
static bool is_local_variable(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:2191
in this the arguments are accumulated from left to right
Definition: data.cc:393
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.cc:1276
void resize(octave_idx_type n, const std::string &rfv="")
Definition: str-vec.h:97
static octave_value varval(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context)
Definition: symtab.h:1373
static void clear_variables(void)
Definition: symtab.h:1691
bool is_function_handle(void) const
Definition: ov.h:702
octave_value arg
Definition: pr-output.cc:3440
static octave_value find_cmdline_function(const std::string &name)
Definition: symtab.h:1558
octave_function * fcn
Definition: ov-class.cc:1743
string_vector argv
Definition: load-save.cc:635
static std::string find_fcn(const std::string &fcn, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:146
std::string unique_symbol_name(const std::string &basename)
Definition: variables.cc:491
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
static symbol_record find_symbol(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1278
void clear_function(const std::string &nm)
Definition: variables.cc:79
JNIEnv void * args
Definition: ov-java.cc:67
OCTINTERP_API octave_value get_top_level_value(const std::string &nm, bool silent=false)
static octave_value global_varval(const std::string &name)
Definition: symtab.h:1406
static std::list< std::string > global_variable_names(void)
Definition: symtab.h:2126
bool verbose
Definition: load-save.cc:654
bool is_dir(void) const
Definition: file-stat.cc:57
static void clear_symbol(const std::string &name)
Definition: symtab.h:1733
int buffer_error_messages
Definition: error.cc:111
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are empty
Definition: ov-struct.cc:1688
static std::list< symbol_record > glob_variables(const std::string &pattern, scope_id scope=xcurrent_scope)
Definition: symtab.h:2014
static octave_user_code * caller_user_code(size_t nskip=0)
Definition: call-stack.h:172
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:941
static std::string basename(const std::string &s, bool strip_path=false)
Definition: mkoctfile.cc:342
std::list< symbol_info > lst
Definition: variables.cc:1628
static octave_function * caller(void)
Definition: call-stack.h:126
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:935
void add_fcn(void(*fcn)(void))
void clear_variable(const std::string &nm)
Definition: variables.cc:85
string_vector make_argv(const std::string &="") const
Definition: ovl.cc:214
bool is_sparse_type(void) const
Definition: ov.h:682
octave_idx_type numel(const octave_value_list &idx)
Definition: ov.h:411
static std::list< symbol_record > regexp_global_variables(const std::string &pattern)
Definition: symtab.h:2054
OCTINTERP_API bool mislocked(const std::string &)
std::string string_value(bool force=false) const
Definition: ov.h:908
bool is_global(void) const
Definition: symtab.h:606
void error_with_cfn(const char *fmt,...)
Definition: error.cc:600
then the function must return scalars which will be concatenated into the return array(s).If code
Definition: cellfun.cc:398
int nargin
Definition: graphics.cc:10115
bool is_string(void) const
Definition: ov.h:578
static void clear_variable_regexp(const std::string &pat, scope_id scope=xcurrent_scope)
Definition: symtab.h:1770
std::string str
Definition: hash.cc:118
string_vector get_struct_elts(const std::string &text)
Definition: variables.cc:184
static void force_assign(const std::string &name, const octave_value &value=octave_value(), scope_id scope=xcurrent_scope, context_id context=xdefault_context)
Definition: symtab.h:1355
string_vector generate_struct_completions(const std::string &text, std::string &prefix, std::string &hint)
Definition: variables.cc:236
static void global_assign(const std::string &name, const octave_value &value=octave_value())
Definition: symtab.h:1383
bool is_inline_function(void) const
Definition: ov.h:708
OCTINTERP_API octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
bool is_complex_type(void) const
Definition: ov.h:670
double tmp
Definition: data.cc:6300
octave_value retval
Definition: data.cc:6294
static void clear_global(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1715
OCTINTERP_API octave_value lookup_function_handle(const std::string &nm)
OCTINTERP_API void munlock(const std::string &)
static void push(octave_function *f, symbol_table::scope_id scope=symbol_table::current_scope(), symbol_table::context_id context=symbol_table::current_context())
Definition: call-stack.h:214
symbol_info(const symbol_table::symbol_record &sr, const std::string &expr_str="", const octave_value &expr_val=octave_value())
Definition: variables.cc:1149
string_vector map_keys(void) const
Definition: ov.h:930
OCTINTERP_API void bind_ans(const octave_value &val, bool print)
idx type
Definition: ov.cc:3129
Array< std::string > param
Definition: urlwrite.cc:343
virtual bool is_user_function(void) const
Definition: ov-base.h:461
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix="") const
Definition: str-vec.cc:195
Definition: dMatrix.h:37
sz
Definition: data.cc:5342
bool is_match(const std::string &buffer)
Definition: lo-regexp.cc:420
bool is_keyword(const std::string &s)
Definition: lex.cc:4529
std::list< whos_parameter > parse_whos_line_format(void)
Definition: variables.cc:1414
static dim_vector alloc(int n)
Definition: dim-vector.h:270
feval(ar{f}, 1) esult
Definition: oct-parse.cc:8829
bool is_classdef_object(void) const
Definition: ov.h:596
OCTINTERP_API void set_global_value(const std::string &nm, const octave_value &val)
octave_map map_value(const std::string &caller_function_name, int nesting_level) const
Definition: variables.cc:1326
static std::string Vmissing_component_hook
Definition: variables.cc:2305
octave_function * function_value(bool silent=false) const
Definition: ov.cc:1705
void unlock(void)
Definition: ov-fcn.h:135
static bool is_variable(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1478
bool is_map(void) const
Definition: ov.h:590
void warning(const char *fmt,...)
Definition: error.cc:788
static void clear_all(bool force=false)
Definition: symtab.h:1670
octave::unwind_protect frame
Definition: graphics.cc:11584
void recover_from_exception(void)
Definition: interpreter.cc:200
static std::list< std::string > user_function_names(void)
Definition: symtab.h:2109
std::string type_name(void) const
Definition: ov.h:1232
octave_idx_type length(void) const
Number of elements in the array.
Definition: Array.h:354
OCTAVE_EXPORT octave_value_list the first data row corresponds to an index of zero The a spreadsheet style form such as the file is read until end of file is reached The such as text
Definition: dlmread.cc:191
static void clear_variable(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:1724
#define octave_stdout
Definition: pager.h:146
static void clear_exemplar_map(void)
Definition: ov-class.cc:1112
static bool is_global(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:2204
~symbol_info_list(void)
Definition: variables.cc:1307
OCTINTERP_API octave_value get_global_value(const std::string &nm, bool silent=false)
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
is longer than or if then or only for unique occurrences of the complete pattern(false).The default is true.If a cell array of strings ar
Definition: strfind.cc:192
p
Definition: lu.cc:138
void assign(const std::string &k, const octave_value &val)
Definition: oct-map.h:223
bool is_cs_list(void) const
Definition: ov.h:602
bool empty(void) const
Definition: variables.cc:1323
static std::list< symbol_record > glob_global_variables(const std::string &pattern)
Definition: symtab.h:2031
symbol_info_list(const symbol_info_list &sil)
Definition: variables.cc:1297
Matrix size(void)
Definition: ov.h:408
octave_function * extract_function(const octave_value &arg, const std::string &warn_for, const std::string &fname, const std::string &header, const std::string &trailer)
Definition: variables.cc:145
void print_with_name(std::ostream &os, const std::string &name) const
Definition: ov.h:1225
bool is_anonymous_function(void) const
Definition: ov.h:705
OCTINTERP_API void bind_internal_variable(const std::string &fname, const octave_value &val)
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:301
std::string class_name(void) const
Definition: ov.h:1234
b
Definition: cellfun.cc:398
bool is_constant(void) const
Definition: ov.h:699
bool is_undefined(void) const
Definition: ov.h:539
static void clear_global_pattern(const std::string &pat, scope_id scope=xcurrent_scope)
Definition: symtab.h:1752
octave::sys::file_stat fs(filename)
std::string find_indexed_expression(const std::string &text)
Definition: input.cc:509
void append(const symbol_table::symbol_record &sr)
Definition: variables.cc:1309
void clear_symbol(const std::string &nm)
Definition: variables.cc:91
void display(std::ostream &os)
Definition: variables.cc:1380
octave_value_list list_value(void) const
Definition: ov.cc:1741
static void pop(void)
Definition: call-stack.h:313
static bool is_built_in_function_name(const std::string &name)
Definition: symtab.h:1487
static void clear_symbol_pattern(const std::string &pat)
Definition: symtab.h:1779
OCTINTERP_API octave_value_list eval_string(const std::string &, bool silent, int &parse_status, int nargout)
static octave_value do_isglobal(const octave_value_list &args)
Definition: variables.cc:338
std::string lookup_autoload(const std::string &nm)
Definition: oct-parse.cc:8219
bool is_java(void) const
Definition: ov.h:599
void clear_mex_functions(void)
Definition: variables.cc:73
octave_function * is_valid_function(const std::string &fcn_name, const std::string &warn_for, bool warn)
Definition: variables.cc:101
bool discard_warning_messages
Definition: error.cc:121
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
bool discard_error_messages
Definition: error.cc:118
static void clear(octave::dynamic_library &oct_file)
Definition: dynamic-ld.cc:230
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
#define GET_IDX(LEN)
Definition: variables.cc:487
dim_vector dv
Definition: sub2ind.cc:263
static void clear_function(const std::string &name)
Definition: symtab.h:1710
static void clear_function_pattern(const std::string &pat)
Definition: symtab.h:1741
void append(const symbol_table::symbol_record &sr, const std::string &expr_str, const octave_value &expr_val)
Definition: variables.cc:1314
bool islocked(void) const
Definition: ov-fcn.h:141
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
int symbol_exist(const std::string &name, const std::string &type)
Definition: variables.cc:382
static void erase_scope(scope_id scope)
Definition: symtab.h:1215
static void top_level_assign(const std::string &name, const octave_value &value=octave_value())
Definition: symtab.h:1414
size_t byte_size(void) const
Definition: ov.h:506
OCTINTERP_API void mlock(void)
static octave_value top_level_varval(const std::string &name)
Definition: symtab.h:1430