3Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
4 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
6This file is part of Octave.
8Octave is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
13Octave is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18You should have received a copy of the GNU General Public License
19along with Octave; see the file COPYING. If not, see
20<http://www.gnu.org/licenses/>.
38#include "glob-match.h"
39#include "regex-match.h"
56#include "ov-usr-fcn.h"
61#include "unwind-prot.h"
65// Defines layout for the whos/who -long command
66static std::string Vwhos_line_format
67 = " %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;\n";
70clear_mex_functions (void)
72 symbol_table::clear_mex_functions ();
76clear_function (const std::string& nm)
78 symbol_table::clear_function (nm);
82clear_variable (const std::string& nm)
84 symbol_table::clear_variable (nm);
88clear_symbol (const std::string& nm)
90 symbol_table::clear_symbol (nm);
93// Attributes of variables and functions.
95// Is this octave_value a valid function?
98is_valid_function (const std::string& fcn_name,
99 const std::string& warn_for, bool warn)
101 octave_function *ans = 0;
103 if (! fcn_name.empty ())
105 octave_value val = symbol_table::find_function (fcn_name);
107 if (val.is_defined ())
108 ans = val.function_value (true);
112 error ("%s: the symbol `%s' is not valid as a function",
113 warn_for.c_str (), fcn_name.c_str ());
119is_valid_function (const octave_value& arg,
120 const std::string& warn_for, bool warn)
122 octave_function *ans = 0;
124 std::string fcn_name;
126 if (arg.is_string ())
128 fcn_name = arg.string_value ();
131 ans = is_valid_function (fcn_name, warn_for, warn);
133 error ("%s: expecting function name as argument", warn_for.c_str ());
136 error ("%s: expecting function name as argument", warn_for.c_str ());
142extract_function (const octave_value& arg, const std::string& warn_for,
143 const std::string& fname, const std::string& header,
144 const std::string& trailer)
146 octave_function *retval = 0;
148 retval = is_valid_function (arg, warn_for, 0);
152 std::string s = arg.string_value ();
154 std::string cmd = header;
156 cmd.append (trailer);
162 eval_string (cmd, true, parse_status, 0);
164 if (parse_status == 0)
166 retval = is_valid_function (fname, warn_for, 0);
170 error ("%s: `%s' is not valid as a function",
171 warn_for.c_str (), fname.c_str ());
175 warning ("%s: passing function body as a string is obsolete."
176 " Please use anonymous functions.", warn_for.c_str ());
179 error ("%s: `%s' is not valid as a function",
180 warn_for.c_str (), fname.c_str ());
183 error ("%s: expecting first argument to be a string",
191get_struct_elts (const std::string& text)
197 size_t len = text.length ();
199 while ((pos = text.find ('.', pos)) != std::string::npos)
207 string_vector retval (n);
211 for (int i = 0; i < n; i++)
213 len = text.find ('.', pos);
215 if (len != std::string::npos)
218 retval[i] = text.substr (pos, len);
220 if (len != std::string::npos)
228is_variable (const std::string& name)
234 octave_value val = symbol_table::varval (name);
236 retval = val.is_defined ();
243generate_struct_completions (const std::string& text,
244 std::string& prefix, std::string& hint)
248 size_t pos = text.rfind ('.');
250 if (pos != std::string::npos)
252 if (pos == text.length ())
255 hint = text.substr (pos+1);
257 prefix = text.substr (0, pos);
259 std::string base_name = prefix;
261 pos = base_name.find_first_of ("{(.");
263 if (pos != std::string::npos)
264 base_name = base_name.substr (0, pos);
266 if (is_variable (base_name))
270 unwind_protect frame;
272 frame.protect_var (error_state);
273 frame.protect_var (warning_state);
275 frame.protect_var (discard_error_messages);
276 frame.protect_var (discard_warning_messages);
278 discard_error_messages = true;
279 discard_warning_messages = true;
281 octave_value tmp = eval_string (prefix, true, parse_status);
285 if (tmp.is_defined () && tmp.is_map ())
286 names = tmp.map_keys ();
293// FIXME -- this will have to be much smarter to work
297looks_like_struct (const std::string& text)
299 bool retval = (! text.empty ()
301 && text.find_first_of (file_ops::dir_sep_chars ()) == std::string::npos
302 && text.find ("..") == std::string::npos
303 && text.rfind ('.') != std::string::npos);
306 symbol_record *sr = curr_sym_tab->lookup (text);
308 if (sr && ! sr->is_function ())
312 unwind_protect frame;
314 frame.protect_var (discard_error_messages);
315 frame.protect_var (error_state);
317 discard_error_messages = true;
319 octave_value tmp = eval_string (text, true, parse_status);
323 retval = (tmp.is_defined () && tmp.is_map ());
331do_isglobal (const octave_value_list& args)
333 octave_value retval = false;
335 int nargin = args.length ();
343 std::string name = args(0).string_value ();
347 error ("isglobal: expecting std::string argument");
351 return symbol_table::is_global (name);
354DEFUN (isglobal, args, ,
356@deftypefn {Built-in Function} {} isglobal (@var{name})\n\
357Return 1 if @var{name} is globally visible. Otherwise, return 0. For\n\
369 return do_isglobal (args);
372DEFUN (is_global, args, ,
374@deftypefn {Built-in Function} {} isglobal (@var{name})\n\
375This function has been deprecated. Use isglobal instead.\n\
378 return do_isglobal (args);
382safe_symbol_lookup (const std::string& symbol_name)
386 unwind_protect frame;
388 frame.protect_var (buffer_error_messages);
389 frame.protect_var (Vdebug_on_error);
390 frame.protect_var (Vdebug_on_warning);
392 buffer_error_messages++;
393 Vdebug_on_error = false;
394 Vdebug_on_warning = false;
396 retval = symbol_table::find (symbol_name);
404symbol_exist (const std::string& name, const std::string& type)
408 std::string struct_elts;
409 std::string symbol_name = name;
411 size_t pos = name.find ('.');
413 if (pos != std::string::npos && pos > 0)
415 struct_elts = name.substr (pos+1);
416 symbol_name = name.substr (0, pos);
419 // We shouldn't need to look in the global symbol table, since any
420 // name that is visible in the current scope will be in the local
423 octave_value val = safe_symbol_lookup (symbol_name);
425 if (val.is_defined ())
427 bool not_a_struct = struct_elts.empty ();
428 bool var_ok = not_a_struct /* || val.is_map_element (struct_elts) */;
432 && (type == "any" || type == "var")
433 && (val.is_constant () || val.is_object ()
434 || val.is_inline_function () || val.is_function_handle ()))
440 && (type == "any" || type == "builtin"))
442 if (not_a_struct && val.is_builtin_function ())
450 && (type == "any" || type == "file")
451 && (val.is_user_function () || val.is_dld_function ()))
453 octave_function *f = val.function_value (true);
454 std::string s = f ? f->fcn_file_name () : std::string ();
456 retval = s.empty () ? 103 : (val.is_user_function () ? 2 : 3);
460 if (! (type == "var" || type == "builtin"))
464 std::string file_name = lookup_autoload (name);
466 if (file_name.empty ())
467 file_name = load_path::find_fcn (name);
469 size_t len = file_name.length ();
473 if (type == "any" || type == "file")
475 if (len > 4 && (file_name.substr (len-4) == ".oct"
476 || file_name.substr (len-4) == ".mex"))
486 std::string file_name = file_in_path (name, "");
488 if (file_name.empty ())
491 file_stat fs (file_name);
495 if ((type == "any" || type == "file")
500 else if ((type == "any" || type == "dir")
512#define GET_IDX(LEN) \
513 static_cast<int> ((LEN-1) * static_cast<double> (rand ()) / RAND_MAX)
516unique_symbol_name (const std::string& basename)
518 static const std::string alpha
519 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
521 static size_t len = alpha.length ();
523 std::string nm = basename + alpha[GET_IDX (len)];
525 size_t pos = nm.length ();
527 if (nm.substr (0, 2) == "__")
530 while (symbol_exist (nm, "any"))
531 nm.insert (pos++, 1, alpha[GET_IDX (len)]);
538@deftypefn {Built-in Function} {} exist (@var{name}, @var{type})\n\
539Return 1 if the name exists as a variable, 2 if the name is an\n\
540absolute file name, an ordinary file in Octave's @code{path}, or (after\n\
541appending @samp{.m}) a function file in Octave's @code{path}, 3 if the\n\
542name is a @samp{.oct} or @samp{.mex} file in Octave's @code{path},\n\
5435 if the name is a built-in function, 7 if the name is a directory, or 103\n\
544if the name is a function not associated with a file (entered on\n\
547Otherwise, return 0.\n\
549This function also returns 2 if a regular file called @var{name}\n\
550exists in Octave's search path. If you want information about\n\
551other types of files, you should use some combination of the functions\n\
552@code{file_in_path} and @code{stat} instead.\n\
554If the optional argument @var{type} is supplied, check only for\n\
555symbols of the specified type. Valid types are\n\
559Check only for variables.\n\
561Check only for built-in functions.\n\
563Check only for files.\n\
565Check only for directories.\n\
569 octave_value retval = false;
571 int nargin = args.length ();
573 if (nargin == 1 || nargin == 2)
575 std::string name = args(0).string_value ();
580 = (nargin == 2) ? args(1).string_value () : std::string ("any");
583 retval = symbol_exist (name, type);
585 error ("exist: expecting second argument to be a string");
588 error ("exist: expecting first argument to be a string");
597lookup_function_handle (const std::string& nm)
599 octave_value val = symbol_table::varval (nm);
601 return val.is_function_handle () ? val : octave_value ();
605get_global_value (const std::string& nm, bool silent)
607 octave_value val = symbol_table::global_varval (nm);
609 if (val.is_undefined () && ! silent)
610 error ("get_global_value: undefined symbol `%s'", nm.c_str ());
616set_global_value (const std::string& nm, const octave_value& val)
618 symbol_table::global_varref (nm) = val;
622get_top_level_value (const std::string& nm, bool silent)
624 octave_value val = symbol_table::top_level_varval (nm);
626 if (val.is_undefined () && ! silent)
627 error ("get_top_level_value: undefined symbol `%s'", nm.c_str ());
633set_top_level_value (const std::string& nm, const octave_value& val)
635 symbol_table::top_level_varref (nm) = val;
641set_internal_variable (bool& var, const octave_value_list& args,
642 int nargout, const char *nm)
646 int nargin = args.length ();
648 if (nargout > 0 || nargin == 0)
653 bool bval = args(0).bool_value ();
658 error ("%s: expecting arg to be a logical value", nm);
667set_internal_variable (char& var, const octave_value_list& args,
668 int nargout, const char *nm)
672 int nargin = args.length ();
674 if (nargout > 0 || nargin == 0)
679 std::string sval = args(0).string_value ();
683 switch (sval.length ())
694 error ("%s: argument must be a single character", nm);
699 error ("%s: argument must be a single character", nm);
708set_internal_variable (int& var, const octave_value_list& args,
709 int nargout, const char *nm,
710 int minval, int maxval)
714 int nargin = args.length ();
716 if (nargout > 0 || nargin == 0)
721 int ival = args(0).int_value ();
726 error ("%s: expecting arg to be greater than %d", nm, minval);
727 else if (ival > maxval)
728 error ("%s: expecting arg to be less than or equal to %d",
734 error ("%s: expecting arg to be an integer value", nm);
743set_internal_variable (double& var, const octave_value_list& args,
744 int nargout, const char *nm,
745 double minval, double maxval)
749 int nargin = args.length ();
751 if (nargout > 0 || nargin == 0)
756 double dval = args(0).scalar_value ();
761 error ("%s: expecting arg to be greater than %g", minval);
762 else if (dval > maxval)
763 error ("%s: expecting arg to be less than or equal to %g", maxval);
768 error ("%s: expecting arg to be a scalar value", nm);
777set_internal_variable (std::string& var, const octave_value_list& args,
778 int nargout, const char *nm, bool empty_ok)
782 int nargin = args.length ();
784 if (nargout > 0 || nargin == 0)
789 std::string sval = args(0).string_value ();
793 if (empty_ok || ! sval.empty ())
796 error ("%s: value must not be empty", nm);
799 error ("%s: expecting arg to be a character string", nm);
812 int parameter_length;
813 int first_parameter_length;
820print_descriptor (std::ostream& os, std::list<whos_parameter> params)
822 // This method prints a line of information on a given symbol
823 std::list<whos_parameter>::iterator i = params.begin ();
824 std::ostringstream param_buf;
826 while (i != params.end ())
828 whos_parameter param = *i;
830 if (param.command != '\0')
832 // Do the actual printing
833 switch (param.modifier)
836 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
837 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
841 os << std::setiosflags (std::ios::right) << std::setw (param.parameter_length);
842 param_buf << std::setiosflags (std::ios::right) << std::setw (param.parameter_length);
846 if (param.command != 's')
848 os << std::setiosflags (std::ios::left)
849 << std::setw (param.parameter_length);
850 param_buf << std::setiosflags (std::ios::left)
851 << std::setw (param.parameter_length);
856 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
857 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
860 if (param.command == 's' && param.modifier == 'c')
864 if (param.modifier == 'c')
866 a = param.first_parameter_length - param.balance;
868 b = param.parameter_length - a - param.text . length ();
870 os << std::setiosflags (std::ios::left) << std::setw (a)
871 << "" << std::resetiosflags (std::ios::left) << param.text
872 << std::setiosflags (std::ios::left)
873 << std::setw (b) << ""
874 << std::resetiosflags (std::ios::left);
875 param_buf << std::setiosflags (std::ios::left) << std::setw (a)
876 << "" << std::resetiosflags (std::ios::left) << param.line
877 << std::setiosflags (std::ios::left)
878 << std::setw (b) << ""
879 << std::resetiosflags (std::ios::left);
885 param_buf << param.line;
887 os << std::resetiosflags (std::ios::left)
888 << std::resetiosflags (std::ios::right);
889 param_buf << std::resetiosflags (std::ios::left)
890 << std::resetiosflags (std::ios::right);
896 param_buf << param.line;
901 os << param_buf.str ();
904// FIXME -- This is a bit of a kluge. We'd like to just use val.dims()
905// and if val is an object, expect that dims will call size if it is
906// overloaded by a user-defined method. But there are currently some
907// unresolved const issues that prevent that solution from working.
910get_dims_str (const octave_value& val)
912 octave_value tmp = val;
914 Matrix sz = tmp.size ();
916 dim_vector dv (sz.numel ());
918 for (octave_idx_type i = 0; i < dv.length (); i++)
930 symbol_info (const symbol_table::symbol_record& sr,
931 const std::string& expr_str = std::string (),
932 const octave_value& expr_val = octave_value ())
933 : name (expr_str.empty () ? sr.name () : expr_str),
934 is_automatic (sr.is_automatic ()),
935 is_formal (sr.is_formal ()),
936 is_global (sr.is_global ()),
937 is_persistent (sr.is_persistent ()),
938 varval (expr_val.is_undefined () ? sr.varval () : expr_val)
941 void display_line (std::ostream& os,
942 const std::list<whos_parameter>& params) const
944 std::string dims_str = get_dims_str (varval);
946 std::list<whos_parameter>::const_iterator i = params.begin ();
948 while (i != params.end ())
950 whos_parameter param = *i;
952 if (param.command != '\0')
954 // Do the actual printing.
956 switch (param.modifier)
959 os << std::setiosflags (std::ios::left)
960 << std::setw (param.parameter_length);
964 os << std::setiosflags (std::ios::right)
965 << std::setw (param.parameter_length);
969 if (param.command == 's')
971 int front = param.first_parameter_length
972 - dims_str.find ('x');
973 int back = param.parameter_length
976 front = (front > 0) ? front : 0;
977 back = (back > 0) ? back : 0;
979 os << std::setiosflags (std::ios::left)
982 << std::resetiosflags (std::ios::left)
984 << std::setiosflags (std::ios::left)
987 << std::resetiosflags (std::ios::left);
991 os << std::setiosflags (std::ios::left)
992 << std::setw (param.parameter_length);
997 error ("whos_line_format: modifier `%c' unknown",
1000 os << std::setiosflags (std::ios::right)
1001 << std::setw (param.parameter_length);
1004 switch (param.command)
1010 tmp[0] = (is_automatic ? 'a' : ' ');
1011 tmp[1] = (is_formal ? 'f' : ' ');
1012 tmp[2] = (is_global ? 'g' : ' ');
1013 tmp[3] = (is_persistent ? 'p' : ' ');
1021 os << varval.byte_size ();
1025 os << varval.class_name ();
1029 os << varval.capacity ();
1037 if (param.modifier != 'c')
1042 os << varval.type_name ();
1046 error ("whos_line_format: command `%c' unknown",
1050 os << std::resetiosflags (std::ios::left)
1051 << std::resetiosflags (std::ios::right);
1067 octave_value varval;
1071 symbol_info_list (void) : lst () { }
1073 symbol_info_list (const symbol_info_list& sil) : lst (sil.lst) { }
1075 symbol_info_list& operator = (const symbol_info_list& sil)
1083 ~symbol_info_list (void) { }
1085 void append (const symbol_table::symbol_record& sr)
1087 lst.push_back (symbol_info (sr));
1090 void append (const symbol_table::symbol_record& sr,
1091 const std::string& expr_str,
1092 const octave_value& expr_val)
1094 lst.push_back (symbol_info (sr, expr_str, expr_val));
1097 size_t size (void) const { return lst.size (); }
1099 bool empty (void) const { return lst.empty (); }
1102 map_value (const std::string& caller_function_name, int nesting_level) const
1104 size_t len = lst.size ();
1106 Cell name_info (len, 1);
1107 Cell size_info (len, 1);
1108 Cell bytes_info (len, 1);
1109 Cell class_info (len, 1);
1110 Cell global_info (len, 1);
1111 Cell sparse_info (len, 1);
1112 Cell complex_info (len, 1);
1113 Cell nesting_info (len, 1);
1114 Cell persistent_info (len, 1);
1116 std::list<symbol_info>::const_iterator p = lst.begin ();
1118 for (size_t j = 0; j < len; j++)
1120 const symbol_info& si = *p++;
1124 ni.assign ("function", caller_function_name);
1125 ni.assign ("level", nesting_level);
1127 name_info(j) = si.name;
1128 global_info(j) = si.is_global;
1129 persistent_info(j) = si.is_persistent;
1131 octave_value val = si.varval;
1133 size_info(j) = val.size ();
1134 bytes_info(j) = val.byte_size ();
1135 class_info(j) = val.class_name ();
1136 sparse_info(j) = val.is_sparse_type ();
1137 complex_info(j) = val.is_complex_type ();
1138 nesting_info(j) = ni;
1143 info.assign ("name", name_info);
1144 info.assign ("size", size_info);
1145 info.assign ("bytes", bytes_info);
1146 info.assign ("class", class_info);
1147 info.assign ("global", global_info);
1148 info.assign ("sparse", sparse_info);
1149 info.assign ("complex", complex_info);
1150 info.assign ("nesting", nesting_info);
1151 info.assign ("persistent", persistent_info);
1156 void display (std::ostream& os)
1161 size_t elements = 0;
1163 std::list<whos_parameter> params = parse_whos_line_format ();
1165 print_descriptor (os, params);
1167 octave_stdout << "\n";
1169 for (std::list<symbol_info>::const_iterator p = lst.begin ();
1170 p != lst.end (); p++)
1172 p->display_line (os, params);
1174 octave_value val = p->varval;
1176 elements += val.capacity ();
1177 bytes += val.byte_size ();
1180 os << "\nTotal is " << elements
1181 << (elements == 1 ? " element" : " elements")
1182 << " using " << bytes << (bytes == 1 ? " byte" : " bytes")
1187 // Parse the string whos_line_format, and return a parameter list,
1188 // containing all information needed to print the given
1189 // attributtes of the symbols.
1190 std::list<whos_parameter> parse_whos_line_format (void)
1193 size_t format_len = Vwhos_line_format.length ();
1195 std::list<whos_parameter> params;
1200 std::string param_string = "abcenst";
1201 Array<int> param_length (dim_vector (param_string.length (), 1));
1202 Array<std::string> param_names (dim_vector (param_string.length (), 1));
1203 size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t;
1205 pos_a = param_string.find ('a'); // Attributes
1206 pos_b = param_string.find ('b'); // Bytes
1207 pos_c = param_string.find ('c'); // Class
1208 pos_e = param_string.find ('e'); // Elements
1209 pos_n = param_string.find ('n'); // Name
1210 pos_s = param_string.find ('s'); // Size
1211 pos_t = param_string.find ('t'); // Type
1213 param_names(pos_a) = "Attr";
1214 param_names(pos_b) = "Bytes";
1215 param_names(pos_c) = "Class";
1216 param_names(pos_e) = "Elements";
1217 param_names(pos_n) = "Name";
1218 param_names(pos_s) = "Size";
1219 param_names(pos_t) = "Type";
1221 for (size_t i = 0; i < param_string.length (); i++)
1222 param_length(i) = param_names(i) . length ();
1224 // Calculating necessary spacing for name column,
1225 // bytes column, elements column and class column
1227 for (std::list<symbol_info>::const_iterator p = lst.begin ();
1228 p != lst.end (); p++)
1230 std::stringstream ss1, ss2;
1234 param_length(pos_n) = ((str.length ()
1235 > static_cast<size_t> (param_length(pos_n)))
1236 ? str.length () : param_length(pos_n));
1238 octave_value val = p->varval;
1240 str = val.type_name ();
1241 param_length(pos_t) = ((str.length ()
1242 > static_cast<size_t> (param_length(pos_t)))
1243 ? str.length () : param_length(pos_t));
1245 elements1 = val.capacity ();
1248 param_length(pos_e) = ((str.length ()
1249 > static_cast<size_t> (param_length(pos_e)))
1250 ? str.length () : param_length(pos_e));
1252 bytes1 = val.byte_size ();
1255 param_length(pos_b) = ((str.length ()
1256 > static_cast<size_t> (param_length(pos_b)))
1257 ? str.length () : param_length (pos_b));
1261 while (static_cast<size_t> (idx) < format_len)
1263 whos_parameter param;
1264 param.command = '\0';
1266 if (Vwhos_line_format[idx] == '%')
1268 bool error_encountered = false;
1269 param.modifier = 'r';
1270 param.parameter_length = 0;
1272 int a = 0, b = -1, balance = 1;
1277 // Parse one command from whos_line_format
1278 cmd = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
1279 pos = cmd.find (';');
1280 if (pos != std::string::npos)
1281 cmd = cmd.substr (0, pos+1);
1283 error ("parameter without ; in whos_line_format");
1285 idx += cmd.length ();
1287 // FIXME -- use iostream functions instead of sscanf!
1289 if (cmd.find_first_of ("crl") != 1)
1290 items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d;",
1291 &garbage, ¶m.command, &a, &b, &balance);
1293 items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d;",
1294 &garbage, ¶m.modifier, ¶m.command,
1295 &a, &b, &balance) - 1;
1299 error ("whos_line_format: parameter structure without command in whos_line_format");
1300 error_encountered = true;
1303 // Insert data into parameter
1304 param.first_parameter_length = 0;
1305 pos = param_string.find (param.command);
1306 if (pos != std::string::npos)
1308 param.parameter_length = param_length(pos);
1309 param.text = param_names(pos);
1310 param.line.assign (param_names(pos).length (), '=');
1312 param.parameter_length = (a > param.parameter_length
1313 ? a : param.parameter_length);
1314 if (param.command == 's' && param.modifier == 'c' && b > 0)
1315 param.first_parameter_length = b;
1319 error ("whos_line_format: '%c' is not a command",
1321 error_encountered = true;
1324 if (param.command == 's')
1326 // Have to calculate space needed for printing
1327 // matrix dimensions Space needed for Size column is
1328 // hard to determine in prior, because it depends on
1329 // dimensions to be shown. That is why it is
1330 // recalculated for each Size-command int first,
1333 int first = param.first_parameter_length;
1334 int total = param.parameter_length;
1336 for (std::list<symbol_info>::const_iterator p = lst.begin ();
1337 p != lst.end (); p++)
1339 octave_value val = p->varval;
1340 std::string dims_str = get_dims_str (val);
1341 int first1 = dims_str.find ('x');
1342 int total1 = dims_str.length ();
1343 int rest1 = total1 - first1;
1344 rest = (rest1 > rest ? rest1 : rest);
1345 first = (first1 > first ? first1 : first);
1346 total = (total1 > total ? total1 : total);
1349 if (param.modifier == 'c')
1351 if (first < balance)
1352 first += balance - first;
1353 if (rest + balance < param.parameter_length)
1354 rest += param.parameter_length - rest - balance;
1356 param.parameter_length = first + rest;
1357 param.first_parameter_length = first;
1358 param.balance = balance;
1362 param.parameter_length = total;
1363 param.first_parameter_length = 0;
1366 else if (param.modifier == 'c')
1368 error ("whos_line_format: modifier 'c' not available for command '%c'",
1370 error_encountered = true;
1373 // What happens if whos_line_format contains negative numbers
1374 // at param_length positions?
1375 param.balance = (b < 0 ? 0 : param.balance);
1376 param.first_parameter_length = (b < 0 ? 0 :
1377 param.first_parameter_length);
1378 param.parameter_length = (a < 0
1380 : (param.parameter_length
1381 < param_length(pos_s)
1382 ? param_length(pos_s)
1383 : param.parameter_length));
1385 // Parameter will not be pushed into parameter list if ...
1386 if (! error_encountered)
1387 params.push_back (param);
1391 // Text string, to be printed as it is ...
1394 text = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
1395 pos = text.find ('%');
1396 if (pos != std::string::npos)
1397 text = text.substr (0, pos);
1399 // Push parameter into list ...
1400 idx += text.length ();
1402 param.line.assign (text.length(), ' ');
1403 params.push_back (param);
1411 std::list<symbol_info> lst;
1416do_who (int argc, const string_vector& argv, bool return_list,
1417 bool verbose = false, std::string msg = std::string ())
1419 octave_value retval;
1421 std::string my_name = argv[0];
1423 bool global_only = false;
1424 bool have_regexp = false;
1427 for (i = 1; i < argc; i++)
1429 if (argv[i] == "-file")
1431 // FIXME. This is an inefficient manner to implement this as the
1432 // variables are loaded in to a temporary context and then treated.
1433 // It would be better to refecat symbol_info_list to not store the
1434 // symbol records and then use it in load-save.cc (do_load) to
1435 // implement this option there so that the variables are never
1438 error ("whos: -file argument must be followed by a file name");
1441 std::string nm = argv [i + 1];
1443 unwind_protect frame;
1445 // Set up temporary scope.
1447 symbol_table::scope_id tmp_scope = symbol_table::alloc_scope ();
1448 frame.add_fcn (symbol_table::erase_scope, tmp_scope);
1450 symbol_table::set_scope (tmp_scope);
1452 octave_call_stack::push (tmp_scope, 0);
1453 frame.add_fcn (octave_call_stack::pop);
1455 frame.add_fcn (symbol_table::clear_variables);
1457 feval ("load", octave_value (nm), 0);
1461 std::string newmsg = std::string ("Variables in the file ") +
1464 retval = do_who (i, argv, return_list, verbose, newmsg);
1470 else if (argv[i] == "-regexp")
1472 else if (argv[i] == "global")
1474 else if (argv[i][0] == '-')
1475 warning ("%s: unrecognized option `%s'", my_name.c_str (),
1481 int npats = argc - i;
1485 pats.resize (npats);
1486 for (int j = 0; j < npats; j++)
1487 pats[j] = argv[i+j];
1491 pats.resize (++npats);
1495 symbol_info_list symbol_stats;
1496 std::list<std::string> symbol_names;
1498 for (int j = 0; j < npats; j++)
1500 std::string pat = pats[j];
1504 std::list<symbol_table::symbol_record> tmp = global_only
1505 ? symbol_table::regexp_global_variables (pat)
1506 : symbol_table::regexp_variables (pat);
1508 for (std::list<symbol_table::symbol_record>::const_iterator p = tmp.begin ();
1509 p != tmp.end (); p++)
1511 if (p->is_variable ())
1514 symbol_stats.append (*p);
1516 symbol_names.push_back (p->name ());
1522 size_t pos = pat.find_first_of (".({");
1524 if (pos != std::string::npos && pos > 0)
1528 // NOTE: we can only display information for
1529 // expressions based on global values if the variable is
1530 // global in the current scope because we currently have
1531 // no way of looking up the base value in the global
1532 // scope and then evaluating the arguments in the
1535 std::string base_name = pat.substr (0, pos);
1537 if (symbol_table::is_variable (base_name))
1539 symbol_table::symbol_record sr
1540 = symbol_table::find_symbol (base_name);
1542 if (! global_only || sr.is_global ())
1546 octave_value expr_val
1547 = eval_string (pat, true, parse_status);
1550 symbol_stats.append (sr, pat, expr_val);
1559 std::list<symbol_table::symbol_record> tmp = global_only
1560 ? symbol_table::glob_global_variables (pat)
1561 : symbol_table::glob_variables (pat);
1563 for (std::list<symbol_table::symbol_record>::const_iterator p = tmp.begin ();
1564 p != tmp.end (); p++)
1566 if (p->is_variable ())
1569 symbol_stats.append (*p);
1571 symbol_names.push_back (p->name ());
1582 std::string caller_function_name;
1583 octave_function *caller = octave_call_stack::caller ();
1585 caller_function_name = caller->name ();
1587 retval = symbol_stats.map_value (caller_function_name, 1);
1590 retval = Cell (string_vector (symbol_names));
1592 else if (! (symbol_stats.empty () && symbol_names.empty ()))
1594 if (msg.length () == 0)
1596 octave_stdout << "Global variables:\n\n";
1598 octave_stdout << "Variables in the current scope:\n\n";
1600 octave_stdout << msg;
1603 symbol_stats.display (octave_stdout);
1606 string_vector names (symbol_names);
1608 names.list_in_columns (octave_stdout);
1611 octave_stdout << "\n";
1617DEFUN (who, args, nargout,
1619@deftypefn {Command} {} who\n\
1620@deftypefnx {Command} {} who pattern @dots{}\n\
1621@deftypefnx {Command} {} who option pattern @dots{}\n\
1622@deftypefnx {Command} {C =} who (\"pattern\", @dots{})\n\
1623List currently defined variables matching the given patterns. Valid\n\
1624pattern syntax is the same as described for the @code{clear} command.\n\
1625If no patterns are supplied, all variables are listed.\n\
1626By default, only variables visible in the local scope are displayed.\n\
1628The following are valid options but may not be combined.\n\
1632List variables in the global scope rather than the current scope.\n\
1634The patterns are considered to be regular expressions when matching the\n\
1635variables to display. The same pattern syntax accepted by\n\
1636the @code{regexp} function is used.\n\
1638The next argument is treated as a filename. All variables found within the\n\
1639specified file are listed. No patterns are accepted when reading variables\n\
1643If called as a function, return a cell array of defined variable names\n\
1644matching the given patterns.\n\
1645@seealso{whos, regexp}\n\
1648 octave_value retval;
1652 int argc = args.length () + 1;
1654 string_vector argv = args.make_argv ("who");
1657 retval = do_who (argc, argv, nargout == 1);
1665DEFUN (whos, args, nargout,
1667@deftypefn {Command} {} whos\n\
1668@deftypefnx {Command} {} whos pattern @dots{}\n\
1669@deftypefnx {Command} {} whos option pattern @dots{}\n\
1670@deftypefnx {Command} {S =} whos (\"pattern\", @dots{})\n\
1671Provide detailed information on currently defined variables matching the\n\
1672given patterns. Options and pattern syntax are the same as for the\n\
1673@code{who} command. Extended information about each variable is\n\
1674summarized in a table with the following default entries.\n\
1678Attributes of the listed variable. Possible attributes are:\n\
1681Variable in local scope\n\
1683Variable with global scope\n\
1685Persistent variable\n\
1688The name of the variable.\n\
1690The logical size of the variable. A scalar is 1x1, a vector is 1xN or Nx1,\n\
1691a 2-D matrix is MxN.\n\
1693The amount of memory currently used to store the variable.\n\
1695The class of the variable. Examples include double, single, char, uint16,\n\
1699The table can be customized to display more or less information through\n\
1700the function @code{whos_line_format}.\n\
1702If @code{whos} is called as a function, return a struct array of defined\n\
1703variable names matching the given patterns. Fields in the structure\n\
1704describing each variable are: name, size, bytes, class, global, sparse, \n\
1705complex, nesting, persistent.\n\
1706@seealso{who, whos_line_format}\n\
1709 octave_value retval;
1713 int argc = args.length () + 1;
1715 string_vector argv = args.make_argv ("whos");
1718 retval = do_who (argc, argv, nargout == 1, true);
1726// Defining variables.
1729bind_ans (const octave_value& val, bool print)
1731 static std::string ans = "ans";
1733 if (val.is_defined ())
1735 if (val.is_cs_list ())
1737 octave_value_list lst = val.list_value ();
1739 for (octave_idx_type i = 0; i < lst.length (); i++)
1740 bind_ans (lst(i), print);
1744 symbol_table::varref (ans) = val;
1747 val.print_with_name (octave_stdout, ans);
1753bind_internal_variable (const std::string& fname, const octave_value& val)
1755 octave_value_list args;
1759 feval (fname, args, 0);
1765 octave_function *fcn = octave_call_stack::current ();
1770 error ("mlock: invalid use outside a function");
1774munlock (const std::string& nm)
1776 octave_value val = symbol_table::find_function (nm);
1778 if (val.is_defined ())
1780 octave_function *fcn = val.function_value ();
1788mislocked (const std::string& nm)
1790 bool retval = false;
1792 octave_value val = symbol_table::find_function (nm);
1794 if (val.is_defined ())
1796 octave_function *fcn = val.function_value ();
1799 retval = fcn->islocked ();
1805DEFUN (mlock, args, ,
1807@deftypefn {Built-in Function} {} mlock ()\n\
1808Lock the current function into memory so that it can't be cleared.\n\
1809@seealso{munlock, mislocked, persistent}\n\
1812 octave_value_list retval;
1814 if (args.length () == 0)
1816 octave_function *fcn = octave_call_stack::caller ();
1821 error ("mlock: invalid use outside a function");
1829DEFUN (munlock, args, ,
1831@deftypefn {Built-in Function} {} munlock (@var{fcn})\n\
1832Unlock the named function. If no function is named\n\
1833then unlock the current function.\n\
1834@seealso{mlock, mislocked, persistent}\n\
1837 octave_value_list retval;
1839 if (args.length() == 1)
1841 std::string name = args(0).string_value ();
1846 error ("munlock: expecting argument to be a function name");
1848 else if (args.length () == 0)
1850 octave_function *fcn = octave_call_stack::caller ();
1855 error ("munlock: invalid use outside a function");
1864DEFUN (mislocked, args, ,
1866@deftypefn {Built-in Function} {} mislocked (@var{fcn})\n\
1867Return true if the named function is locked. If no function is named\n\
1868then return true if the current function is locked.\n\
1869@seealso{mlock, munlock, persistent}\n\
1872 octave_value retval;
1874 if (args.length() == 1)
1876 std::string name = args(0).string_value ();
1879 retval = mislocked (name);
1881 error ("mislocked: expecting argument to be a function name");
1883 else if (args.length () == 0)
1885 octave_function *fcn = octave_call_stack::caller ();
1888 retval = fcn->islocked ();
1890 error ("mislocked: invalid use outside a function");
1898// Deleting names from the symbol tables.
1901name_matches_any_pattern (const std::string& nm, const string_vector& argv,
1902 int argc, int idx, bool have_regexp = false)
1904 bool retval = false;
1906 for (int k = idx; k < argc; k++)
1908 std::string patstr = argv[k];
1909 if (! patstr.empty ())
1913 regex_match pattern (patstr);
1915 if (pattern.match (nm))
1923 glob_match pattern (patstr);
1925 if (pattern.match (nm))
1938maybe_warn_exclusive (bool exclusive)
1941 warning ("clear: ignoring --exclusive option");
1945do_clear_functions (const string_vector& argv, int argc, int idx,
1946 bool exclusive = false)
1949 symbol_table::clear_functions ();
1954 string_vector fcns = symbol_table::user_function_names ();
1956 int fcount = fcns.length ();
1958 for (int i = 0; i < fcount; i++)
1960 std::string nm = fcns[i];
1962 if (! name_matches_any_pattern (nm, argv, argc, idx))
1963 symbol_table::clear_function (nm);
1969 symbol_table::clear_function_pattern (argv[idx++]);
1975do_clear_globals (const string_vector& argv, int argc, int idx,
1976 bool exclusive = false)
1980 string_vector gvars = symbol_table::global_variable_names ();
1982 int gcount = gvars.length ();
1984 for (int i = 0; i < gcount; i++)
1985 symbol_table::clear_global (gvars[i]);
1991 string_vector gvars = symbol_table::global_variable_names ();
1993 int gcount = gvars.length ();
1995 for (int i = 0; i < gcount; i++)
1997 std::string nm = gvars[i];
1999 if (! name_matches_any_pattern (nm, argv, argc, idx))
2000 symbol_table::clear_global (nm);
2006 symbol_table::clear_global_pattern (argv[idx++]);
2012do_clear_variables (const string_vector& argv, int argc, int idx,
2013 bool exclusive = false, bool have_regexp = false)
2016 symbol_table::clear_variables ();
2021 string_vector lvars = symbol_table::variable_names ();
2023 int lcount = lvars.length ();
2025 for (int i = 0; i < lcount; i++)
2027 std::string nm = lvars[i];
2029 if (! name_matches_any_pattern (nm, argv, argc, idx, have_regexp))
2030 symbol_table::clear_variable (nm);
2037 symbol_table::clear_variable_regexp (argv[idx++]);
2040 symbol_table::clear_variable_pattern (argv[idx++]);
2046do_clear_symbols (const string_vector& argv, int argc, int idx,
2047 bool exclusive = false)
2050 symbol_table::clear_variables ();
2055 // FIXME -- is this really what we want, or do we
2056 // somehow want to only clear the functions that are not
2057 // shadowed by local variables? It seems that would be a
2058 // bit harder to do.
2060 do_clear_variables (argv, argc, idx, exclusive);
2061 do_clear_functions (argv, argc, idx, exclusive);
2066 symbol_table::clear_symbol_pattern (argv[idx++]);
2072do_matlab_compatible_clear (const string_vector& argv, int argc, int idx)
2074 // This is supposed to be mostly Matlab compatible.
2076 for (; idx < argc; idx++)
2078 if (argv[idx] == "all"
2079 && ! symbol_table::is_local_variable ("all"))
2081 symbol_table::clear_all ();
2083 else if (argv[idx] == "functions"
2084 && ! symbol_table::is_local_variable ("functions"))
2086 do_clear_functions (argv, argc, ++idx);
2088 else if (argv[idx] == "global"
2089 && ! symbol_table::is_local_variable ("global"))
2091 do_clear_globals (argv, argc, ++idx);
2093 else if (argv[idx] == "variables"
2094 && ! symbol_table::is_local_variable ("variables"))
2096 symbol_table::clear_variables ();
2098 else if (argv[idx] == "classes"
2099 && ! symbol_table::is_local_variable ("classes"))
2101 symbol_table::clear_objects ();
2102 octave_class::clear_exemplar_map ();
2106 symbol_table::clear_symbol_pattern (argv[idx]);
2111#define CLEAR_OPTION_ERROR(cond) \
2122DEFUN (clear, args, ,
2124@deffn {Command} clear [options] pattern @dots{}\n\
2125Delete the names matching the given patterns from the symbol table. The\n\
2126pattern may contain the following special characters:\n\
2130Match any single character.\n\
2133Match zero or more characters.\n\
2135@item [ @var{list} ]\n\
2136Match the list of characters specified by @var{list}. If the first\n\
2137character is @code{!} or @code{^}, match all characters except those\n\
2138specified by @var{list}. For example, the pattern @samp{[a-zA-Z]} will\n\
2139match all lower and upper case alphabetic characters.\n\
2142For example, the command\n\
2149clears the name @code{foo} and all names that begin with the letter\n\
2150@code{b} and end with the letter @code{r}.\n\
2152If @code{clear} is called without any arguments, all user-defined\n\
2153variables (local and global) are cleared from the symbol table. If\n\
2154@code{clear} is called with at least one argument, only the visible\n\
2155names matching the arguments are cleared. For example, suppose you have\n\
2156defined a function @code{foo}, and then hidden it by performing the\n\
2157assignment @code{foo = 2}. Executing the command @kbd{clear foo} once\n\
2158will clear the variable definition and restore the definition of\n\
2159@code{foo} as a function. Executing @kbd{clear foo} a second time will\n\
2160clear the function definition.\n\
2162The following options are available in both long and short form\n\
2165Clears all local and global user-defined variables and all functions\n\
2166from the symbol table.\n\
2168@item -exclusive, -x\n\
2169Clears the variables that don't match the following pattern.\n\
2171@item -functions, -f\n\
2172Clears the function names and the built-in symbols names.\n\
2174Clears the global symbol names.\n\
2175@item -variables, -v\n\
2176Clears the local variable names.\n\
2177@item -classes, -c\n\
2178Clears the class structure table and clears all objects.\n\
2180The arguments are treated as regular expressions as any variables that\n\
2181match will be cleared.\n\
2183With the exception of @code{exclusive}, all long options can be used \n\
2184without the dash as well.\n\
2187 octave_value_list retval;
2189 int argc = args.length () + 1;
2191 string_vector argv = args.make_argv ("clear");
2197 do_clear_globals (argv, argc, 1);
2198 do_clear_variables (argv, argc, 1);
2204 bool clear_all = false;
2205 bool clear_functions = false;
2206 bool clear_globals = false;
2207 bool clear_variables = false;
2208 bool clear_objects = false;
2209 bool exclusive = false;
2210 bool have_regexp = false;
2211 bool have_dash_option = false;
2213 while (++idx < argc)
2215 if (argv[idx] == "-all" || argv[idx] == "-a")
2217 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2219 have_dash_option = true;
2222 else if (argv[idx] == "-exclusive" || argv[idx] == "-x")
2224 have_dash_option = true;
2227 else if (argv[idx] == "-functions" || argv[idx] == "-f")
2229 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2231 have_dash_option = true;
2232 clear_functions = true;
2234 else if (argv[idx] == "-global" || argv[idx] == "-g")
2236 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2238 have_dash_option = true;
2239 clear_globals = true;
2241 else if (argv[idx] == "-variables" || argv[idx] == "-v")
2243 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2245 have_dash_option = true;
2246 clear_variables = true;
2248 else if (argv[idx] == "-classes" || argv[idx] == "-c")
2250 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2252 have_dash_option = true;
2253 clear_objects = true;
2255 else if (argv[idx] == "-regexp" || argv[idx] == "-r")
2257 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2259 have_dash_option = true;
2268 if (! have_dash_option)
2270 do_matlab_compatible_clear (argv, argc, idx);
2276 maybe_warn_exclusive (exclusive);
2280 ("clear: ignoring extra arguments after -all");
2282 symbol_table::clear_all ();
2284 else if (have_regexp)
2286 do_clear_variables (argv, argc, idx, exclusive, true);
2288 else if (clear_functions)
2290 do_clear_functions (argv, argc, idx, exclusive);
2292 else if (clear_globals)
2294 do_clear_globals (argv, argc, idx, exclusive);
2296 else if (clear_variables)
2298 do_clear_variables (argv, argc, idx, exclusive);
2300 else if (clear_objects)
2302 symbol_table::clear_objects ();
2303 octave_class::clear_exemplar_map ();
2307 do_clear_symbols (argv, argc, idx, exclusive);
2317DEFUN (whos_line_format, args, nargout,
2319@deftypefn {Built-in Function} {@var{val} =} whos_line_format ()\n\
2320@deftypefnx {Built-in Function} {@var{old_val} =} whos_line_format (@var{new_val})\n\
2321Query or set the format string used by the command @code{whos}.\n\
2323A full format string is:\n\
2325@c Set example in small font to prevent overfull line\n\
2327%[modifier]<command>[:width[:left-min[:balance]]];\n\
2330The following command sequences are available:\n\
2334Prints attributes of variables (g=global, p=persistent,\n\
2335f=formal parameter, a=automatic variable).\n\
2337Prints number of bytes occupied by variables.\n\
2339Prints class names of variables.\n\
2341Prints elements held by variables.\n\
2343Prints variable names.\n\
2345Prints dimensions of variables.\n\
2347Prints type names of variables.\n\
2350Every command may also have an alignment modifier:\n\
2356Right alignment (default).\n\
2358Column-aligned (only applicable to command %s).\n\
2361The @code{width} parameter is a positive integer specifying the minimum\n\
2362number of columns used for printing. No maximum is needed as the field will\n\
2363auto-expand as required.\n\
2365The parameters @code{left-min} and @code{balance} are only available when the\n\
2366column-aligned modifier is used with the command @samp{%s}.\n\
2367@code{balance} specifies the column number within the field width which will\n\
2368be aligned between entries. Numbering starts from 0 which indicates the\n\
2369leftmost column. @code{left-min} specifies the minimum field width to the\n\
2370left of the specified balance column.\n\
2372The default format is\n\
2373@code{\" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;\\n\"}.\n\
2377 return SET_INTERNAL_VARIABLE (whos_line_format);