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_id_t uwp_frame = unwind_protect::begin_frame ();
272 unwind_protect::protect_var (error_state);
273 unwind_protect::protect_var (warning_state);
275 unwind_protect::protect_var (discard_error_messages);
276 unwind_protect::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);
283 unwind_protect::run_frame (uwp_frame);
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_id_t uwp_frame = unwind_protect::begin_frame ();
314 unwind_protect::protect_var (discard_error_messages);
315 unwind_protect::protect_var (error_state);
317 discard_error_messages = true;
319 octave_value tmp = eval_string (text, true, parse_status);
321 unwind_protect::run_frame (uwp_frame);
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_id_t uwp_frame = unwind_protect::begin_frame ();
388 unwind_protect::protect_var (buffer_error_messages);
389 unwind_protect::protect_var (Vdebug_on_error);
390 unwind_protect::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);
400 unwind_protect::run_frame (uwp_frame);
406symbol_exist (const std::string& name, const std::string& type)
410 std::string struct_elts;
411 std::string symbol_name = name;
413 size_t pos = name.find ('.');
415 if (pos != std::string::npos && pos > 0)
417 struct_elts = name.substr (pos+1);
418 symbol_name = name.substr (0, pos);
421 // We shouldn't need to look in the global symbol table, since any
422 // name that is visible in the current scope will be in the local
425 octave_value val = safe_symbol_lookup (symbol_name);
427 if (val.is_defined ())
429 bool not_a_struct = struct_elts.empty ();
430 bool var_ok = not_a_struct /* || val.is_map_element (struct_elts) */;
434 && (type == "any" || type == "var")
435 && (val.is_constant () || val.is_object ()
436 || val.is_inline_function () || val.is_function_handle ()))
442 && (type == "any" || type == "builtin"))
444 if (not_a_struct && val.is_builtin_function ())
452 && (type == "any" || type == "file")
453 && (val.is_user_function () || val.is_dld_function ()))
455 octave_function *f = val.function_value (true);
456 std::string s = f ? f->fcn_file_name () : std::string ();
458 retval = s.empty () ? 103 : (val.is_user_function () ? 2 : 3);
462 if (! (type == "var" || type == "builtin"))
466 std::string file_name = lookup_autoload (name);
468 if (file_name.empty ())
469 file_name = load_path::find_fcn (name);
471 size_t len = file_name.length ();
475 if (type == "any" || type == "file")
477 if (len > 4 && (file_name.substr (len-4) == ".oct"
478 || file_name.substr (len-4) == ".mex"))
488 std::string file_name = file_in_path (name, "");
490 if (file_name.empty ())
493 file_stat fs (file_name);
497 if ((type == "any" || type == "file")
502 else if ((type == "any" || type == "dir")
514#define GET_IDX(LEN) \
515 static_cast<int> ((LEN-1) * static_cast<double> (rand ()) / RAND_MAX)
518unique_symbol_name (const std::string& basename)
520 static const std::string alpha
521 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
523 static size_t len = alpha.length ();
525 std::string nm = basename + alpha[GET_IDX (len)];
527 size_t pos = nm.length ();
529 if (nm.substr (0, 2) == "__")
532 while (symbol_exist (nm, "any"))
533 nm.insert (pos++, 1, alpha[GET_IDX (len)]);
540@deftypefn {Built-in Function} {} exist (@var{name}, @var{type})\n\
541Return 1 if the name exists as a variable, 2 if the name is an\n\
542absolute file name, an ordinary file in Octave's @code{path}, or (after\n\
543appending @samp{.m}) a function file in Octave's @code{path}, 3 if the\n\
544name is a @samp{.oct} or @samp{.mex} file in Octave's @code{path},\n\
5455 if the name is a built-in function, 7 if the name is a directory, or 103\n\
546if the name is a function not associated with a file (entered on\n\
549Otherwise, return 0.\n\
551This function also returns 2 if a regular file called @var{name}\n\
552exists in Octave's search path. If you want information about\n\
553other types of files, you should use some combination of the functions\n\
554@code{file_in_path} and @code{stat} instead.\n\
556If the optional argument @var{type} is supplied, check only for\n\
557symbols of the specified type. Valid types are\n\
561Check only for variables.\n\
563Check only for built-in functions.\n\
565Check only for files.\n\
567Check only for directories.\n\
571 octave_value retval = false;
573 int nargin = args.length ();
575 if (nargin == 1 || nargin == 2)
577 std::string name = args(0).string_value ();
582 = (nargin == 2) ? args(1).string_value () : std::string ("any");
585 retval = symbol_exist (name, type);
587 error ("exist: expecting second argument to be a string");
590 error ("exist: expecting first argument to be a string");
599lookup_function_handle (const std::string& nm)
601 octave_value val = symbol_table::varval (nm);
603 return val.is_function_handle () ? val : octave_value ();
607get_global_value (const std::string& nm, bool silent)
609 octave_value val = symbol_table::global_varval (nm);
611 if (val.is_undefined () && ! silent)
612 error ("get_global_by_name: undefined symbol `%s'", nm.c_str ());
618set_global_value (const std::string& nm, const octave_value& val)
620 symbol_table::global_varref (nm) = val;
626set_internal_variable (bool& var, const octave_value_list& args,
627 int nargout, const char *nm)
631 int nargin = args.length ();
633 if (nargout > 0 || nargin == 0)
638 bool bval = args(0).bool_value ();
643 error ("%s: expecting arg to be a logical value", nm);
652set_internal_variable (char& var, const octave_value_list& args,
653 int nargout, const char *nm)
657 int nargin = args.length ();
659 if (nargout > 0 || nargin == 0)
664 std::string sval = args(0).string_value ();
668 switch (sval.length ())
679 error ("%s: argument must be a single character", nm);
684 error ("%s: argument must be a single character", nm);
693set_internal_variable (int& var, const octave_value_list& args,
694 int nargout, const char *nm,
695 int minval, int maxval)
699 int nargin = args.length ();
701 if (nargout > 0 || nargin == 0)
706 int ival = args(0).int_value ();
711 error ("%s: expecting arg to be greater than %d", nm, minval);
712 else if (ival > maxval)
713 error ("%s: expecting arg to be less than or equal to %d",
719 error ("%s: expecting arg to be an integer value", nm);
728set_internal_variable (double& var, const octave_value_list& args,
729 int nargout, const char *nm,
730 double minval, double maxval)
734 int nargin = args.length ();
736 if (nargout > 0 || nargin == 0)
741 double dval = args(0).scalar_value ();
746 error ("%s: expecting arg to be greater than %g", minval);
747 else if (dval > maxval)
748 error ("%s: expecting arg to be less than or equal to %g", maxval);
753 error ("%s: expecting arg to be a scalar value", nm);
762set_internal_variable (std::string& var, const octave_value_list& args,
763 int nargout, const char *nm, bool empty_ok)
767 int nargin = args.length ();
769 if (nargout > 0 || nargin == 0)
774 std::string sval = args(0).string_value ();
778 if (empty_ok || ! sval.empty ())
781 error ("%s: value must not be empty", nm);
784 error ("%s: expecting arg to be a character string", nm);
797 int parameter_length;
798 int first_parameter_length;
805print_descriptor (std::ostream& os, std::list<whos_parameter> params)
807 // This method prints a line of information on a given symbol
808 std::list<whos_parameter>::iterator i = params.begin ();
809 std::ostringstream param_buf;
811 while (i != params.end ())
813 whos_parameter param = *i;
815 if (param.command != '\0')
817 // Do the actual printing
818 switch (param.modifier)
821 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
822 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
826 os << std::setiosflags (std::ios::right) << std::setw (param.parameter_length);
827 param_buf << std::setiosflags (std::ios::right) << std::setw (param.parameter_length);
831 if (param.command != 's')
833 os << std::setiosflags (std::ios::left)
834 << std::setw (param.parameter_length);
835 param_buf << std::setiosflags (std::ios::left)
836 << std::setw (param.parameter_length);
841 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
842 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length);
845 if (param.command == 's' && param.modifier == 'c')
849 if (param.modifier == 'c')
851 a = param.first_parameter_length - param.balance;
853 b = param.parameter_length - a - param.text . length ();
855 os << std::setiosflags (std::ios::left) << std::setw (a)
856 << "" << std::resetiosflags (std::ios::left) << param.text
857 << std::setiosflags (std::ios::left)
858 << std::setw (b) << ""
859 << std::resetiosflags (std::ios::left);
860 param_buf << std::setiosflags (std::ios::left) << std::setw (a)
861 << "" << std::resetiosflags (std::ios::left) << param.line
862 << std::setiosflags (std::ios::left)
863 << std::setw (b) << ""
864 << std::resetiosflags (std::ios::left);
870 param_buf << param.line;
872 os << std::resetiosflags (std::ios::left)
873 << std::resetiosflags (std::ios::right);
874 param_buf << std::resetiosflags (std::ios::left)
875 << std::resetiosflags (std::ios::right);
881 param_buf << param.line;
886 os << param_buf.str ();
889// FIXME -- This is a bit of a kluge. We'd like to just use val.dims()
890// and if val is an object, expect that dims will call size if it is
891// overloaded by a user-defined method. But there are currently some
892// unresolved const issues that prevent that solution from working.
895get_dims_str (const octave_value& val)
897 octave_value tmp = val;
899 Matrix sz = tmp.size ();
901 dim_vector dv (sz.numel ());
903 for (octave_idx_type i = 0; i < dv.length (); i++)
915 symbol_info (const symbol_table::symbol_record& sr,
916 const std::string& expr_str = std::string (),
917 const octave_value& expr_val = octave_value ())
918 : name (expr_str.empty () ? sr.name () : expr_str),
919 is_automatic (sr.is_automatic ()),
920 is_formal (sr.is_formal ()),
921 is_global (sr.is_global ()),
922 is_persistent (sr.is_persistent ()),
923 varval (expr_val.is_undefined () ? sr.varval () : expr_val)
926 void display_line (std::ostream& os,
927 const std::list<whos_parameter>& params) const
929 std::string dims_str = get_dims_str (varval);
931 std::list<whos_parameter>::const_iterator i = params.begin ();
933 while (i != params.end ())
935 whos_parameter param = *i;
937 if (param.command != '\0')
939 // Do the actual printing.
941 switch (param.modifier)
944 os << std::setiosflags (std::ios::left)
945 << std::setw (param.parameter_length);
949 os << std::setiosflags (std::ios::right)
950 << std::setw (param.parameter_length);
954 if (param.command == 's')
956 int front = param.first_parameter_length
957 - dims_str.find ('x');
958 int back = param.parameter_length
961 front = (front > 0) ? front : 0;
962 back = (back > 0) ? back : 0;
964 os << std::setiosflags (std::ios::left)
967 << std::resetiosflags (std::ios::left)
969 << std::setiosflags (std::ios::left)
972 << std::resetiosflags (std::ios::left);
976 os << std::setiosflags (std::ios::left)
977 << std::setw (param.parameter_length);
982 error ("whos_line_format: modifier `%c' unknown",
985 os << std::setiosflags (std::ios::right)
986 << std::setw (param.parameter_length);
989 switch (param.command)
995 tmp[0] = (is_automatic ? 'a' : ' ');
996 tmp[1] = (is_formal ? 'f' : ' ');
997 tmp[2] = (is_global ? 'g' : ' ');
998 tmp[3] = (is_persistent ? 'p' : ' ');
1006 os << varval.byte_size ();
1010 os << varval.class_name ();
1014 os << varval.capacity ();
1022 if (param.modifier != 'c')
1027 os << varval.type_name ();
1031 error ("whos_line_format: command `%c' unknown",
1035 os << std::resetiosflags (std::ios::left)
1036 << std::resetiosflags (std::ios::right);
1052 octave_value varval;
1056 symbol_info_list (void) : lst () { }
1058 symbol_info_list (const symbol_info_list& sil) : lst (sil.lst) { }
1060 symbol_info_list& operator = (const symbol_info_list& sil)
1068 ~symbol_info_list (void) { }
1070 void append (const symbol_table::symbol_record& sr)
1072 lst.push_back (symbol_info (sr));
1075 void append (const symbol_table::symbol_record& sr,
1076 const std::string& expr_str,
1077 const octave_value& expr_val)
1079 lst.push_back (symbol_info (sr, expr_str, expr_val));
1082 size_t size (void) const { return lst.size (); }
1084 bool empty (void) const { return lst.empty (); }
1087 map_value (const std::string& caller_function_name, int nesting_level) const
1089 size_t len = lst.size ();
1091 Cell name_info (len, 1);
1092 Cell size_info (len, 1);
1093 Cell bytes_info (len, 1);
1094 Cell class_info (len, 1);
1095 Cell global_info (len, 1);
1096 Cell sparse_info (len, 1);
1097 Cell complex_info (len, 1);
1098 Cell nesting_info (len, 1);
1099 Cell persistent_info (len, 1);
1101 std::list<symbol_info>::const_iterator p = lst.begin ();
1103 for (size_t j = 0; j < len; j++)
1105 const symbol_info& si = *p++;
1109 ni.assign ("function", caller_function_name);
1110 ni.assign ("level", nesting_level);
1112 name_info(j) = si.name;
1113 global_info(j) = si.is_global;
1114 persistent_info(j) = si.is_persistent;
1116 octave_value val = si.varval;
1118 size_info(j) = val.size ();
1119 bytes_info(j) = val.byte_size ();
1120 class_info(j) = val.class_name ();
1121 sparse_info(j) = val.is_sparse_type ();
1122 complex_info(j) = val.is_complex_type ();
1123 nesting_info(j) = ni;
1128 info.assign ("name", name_info);
1129 info.assign ("size", size_info);
1130 info.assign ("bytes", bytes_info);
1131 info.assign ("class", class_info);
1132 info.assign ("global", global_info);
1133 info.assign ("sparse", sparse_info);
1134 info.assign ("complex", complex_info);
1135 info.assign ("nesting", nesting_info);
1136 info.assign ("persistent", persistent_info);
1141 void display (std::ostream& os)
1146 size_t elements = 0;
1148 std::list<whos_parameter> params = parse_whos_line_format ();
1150 print_descriptor (os, params);
1152 octave_stdout << "\n";
1154 for (std::list<symbol_info>::const_iterator p = lst.begin ();
1155 p != lst.end (); p++)
1157 p->display_line (os, params);
1159 octave_value val = p->varval;
1161 elements += val.capacity ();
1162 bytes += val.byte_size ();
1165 os << "\nTotal is " << elements
1166 << (elements == 1 ? " element" : " elements")
1167 << " using " << bytes << (bytes == 1 ? " byte" : " bytes")
1172 // Parse the string whos_line_format, and return a parameter list,
1173 // containing all information needed to print the given
1174 // attributtes of the symbols.
1175 std::list<whos_parameter> parse_whos_line_format (void)
1178 size_t format_len = Vwhos_line_format.length ();
1180 std::list<whos_parameter> params;
1185 std::string param_string = "abcenst";
1186 Array<int> param_length (dim_vector (param_string.length (), 1));
1187 Array<std::string> param_names (dim_vector (param_string.length (), 1));
1188 size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t;
1190 pos_a = param_string.find ('a'); // Attributes
1191 pos_b = param_string.find ('b'); // Bytes
1192 pos_c = param_string.find ('c'); // Class
1193 pos_e = param_string.find ('e'); // Elements
1194 pos_n = param_string.find ('n'); // Name
1195 pos_s = param_string.find ('s'); // Size
1196 pos_t = param_string.find ('t'); // Type
1198 param_names(pos_a) = "Attr";
1199 param_names(pos_b) = "Bytes";
1200 param_names(pos_c) = "Class";
1201 param_names(pos_e) = "Elements";
1202 param_names(pos_n) = "Name";
1203 param_names(pos_s) = "Size";
1204 param_names(pos_t) = "Type";
1206 for (size_t i = 0; i < param_string.length (); i++)
1207 param_length(i) = param_names(i) . length ();
1209 // Calculating necessary spacing for name column,
1210 // bytes column, elements column and class column
1212 for (std::list<symbol_info>::const_iterator p = lst.begin ();
1213 p != lst.end (); p++)
1215 std::stringstream ss1, ss2;
1219 param_length(pos_n) = ((str.length ()
1220 > static_cast<size_t> (param_length(pos_n)))
1221 ? str.length () : param_length(pos_n));
1223 octave_value val = p->varval;
1225 str = val.type_name ();
1226 param_length(pos_t) = ((str.length ()
1227 > static_cast<size_t> (param_length(pos_t)))
1228 ? str.length () : param_length(pos_t));
1230 elements1 = val.capacity ();
1233 param_length(pos_e) = ((str.length ()
1234 > static_cast<size_t> (param_length(pos_e)))
1235 ? str.length () : param_length(pos_e));
1237 bytes1 = val.byte_size ();
1240 param_length(pos_b) = ((str.length ()
1241 > static_cast<size_t> (param_length(pos_b)))
1242 ? str.length () : param_length (pos_b));
1246 while (static_cast<size_t> (idx) < format_len)
1248 whos_parameter param;
1249 param.command = '\0';
1251 if (Vwhos_line_format[idx] == '%')
1253 bool error_encountered = false;
1254 param.modifier = 'r';
1255 param.parameter_length = 0;
1257 int a = 0, b = -1, balance = 1;
1262 // Parse one command from whos_line_format
1263 cmd = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
1264 pos = cmd.find (';');
1265 if (pos != std::string::npos)
1266 cmd = cmd.substr (0, pos+1);
1268 error ("parameter without ; in whos_line_format");
1270 idx += cmd.length ();
1272 // FIXME -- use iostream functions instead of sscanf!
1274 if (cmd.find_first_of ("crl") != 1)
1275 items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d;",
1276 &garbage, ¶m.command, &a, &b, &balance);
1278 items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d;",
1279 &garbage, ¶m.modifier, ¶m.command,
1280 &a, &b, &balance) - 1;
1284 error ("whos_line_format: parameter structure without command in whos_line_format");
1285 error_encountered = true;
1288 // Insert data into parameter
1289 param.first_parameter_length = 0;
1290 pos = param_string.find (param.command);
1291 if (pos != std::string::npos)
1293 param.parameter_length = param_length(pos);
1294 param.text = param_names(pos);
1295 param.line.assign (param_names(pos).length (), '=');
1297 param.parameter_length = (a > param.parameter_length
1298 ? a : param.parameter_length);
1299 if (param.command == 's' && param.modifier == 'c' && b > 0)
1300 param.first_parameter_length = b;
1304 error ("whos_line_format: '%c' is not a command",
1306 error_encountered = true;
1309 if (param.command == 's')
1311 // Have to calculate space needed for printing
1312 // matrix dimensions Space needed for Size column is
1313 // hard to determine in prior, because it depends on
1314 // dimensions to be shown. That is why it is
1315 // recalculated for each Size-command int first,
1318 int first = param.first_parameter_length;
1319 int total = param.parameter_length;
1321 for (std::list<symbol_info>::const_iterator p = lst.begin ();
1322 p != lst.end (); p++)
1324 octave_value val = p->varval;
1325 std::string dims_str = get_dims_str (val);
1326 int first1 = dims_str.find ('x');
1327 int total1 = dims_str.length ();
1328 int rest1 = total1 - first1;
1329 rest = (rest1 > rest ? rest1 : rest);
1330 first = (first1 > first ? first1 : first);
1331 total = (total1 > total ? total1 : total);
1334 if (param.modifier == 'c')
1336 if (first < balance)
1337 first += balance - first;
1338 if (rest + balance < param.parameter_length)
1339 rest += param.parameter_length - rest - balance;
1341 param.parameter_length = first + rest;
1342 param.first_parameter_length = first;
1343 param.balance = balance;
1347 param.parameter_length = total;
1348 param.first_parameter_length = 0;
1351 else if (param.modifier == 'c')
1353 error ("whos_line_format: modifier 'c' not available for command '%c'",
1355 error_encountered = true;
1358 // What happens if whos_line_format contains negative numbers
1359 // at param_length positions?
1360 param.balance = (b < 0 ? 0 : param.balance);
1361 param.first_parameter_length = (b < 0 ? 0 :
1362 param.first_parameter_length);
1363 param.parameter_length = (a < 0
1365 : (param.parameter_length
1366 < param_length(pos_s)
1367 ? param_length(pos_s)
1368 : param.parameter_length));
1370 // Parameter will not be pushed into parameter list if ...
1371 if (! error_encountered)
1372 params.push_back (param);
1376 // Text string, to be printed as it is ...
1379 text = Vwhos_line_format.substr (idx, Vwhos_line_format.length ());
1380 pos = text.find ('%');
1381 if (pos != std::string::npos)
1382 text = text.substr (0, pos);
1384 // Push parameter into list ...
1385 idx += text.length ();
1387 param.line.assign (text.length(), ' ');
1388 params.push_back (param);
1396 std::list<symbol_info> lst;
1401do_who (int argc, const string_vector& argv, bool return_list,
1402 bool verbose = false, std::string msg = std::string ())
1404 octave_value retval;
1406 std::string my_name = argv[0];
1408 bool global_only = false;
1409 bool have_regexp = false;
1412 for (i = 1; i < argc; i++)
1414 if (argv[i] == "-file")
1416 // FIXME. This is an inefficient manner to implement this as the
1417 // variables are loaded in to a temporary context and then treated.
1418 // It would be better to refecat symbol_info_list to not store the
1419 // symbol records and then use it in load-save.cc (do_load) to
1420 // implement this option there so that the variables are never
1423 error ("whos: -file argument must be followed by a file name");
1426 std::string nm = argv [i + 1];
1428 unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame ();
1430 // Set up temporary scope.
1432 symbol_table::scope_id tmp_scope = symbol_table::alloc_scope ();
1433 unwind_protect::add_fcn (symbol_table::erase_scope, tmp_scope);
1435 symbol_table::set_scope (tmp_scope);
1437 octave_call_stack::push (tmp_scope, 0);
1438 unwind_protect::add_fcn (octave_call_stack::pop);
1440 unwind_protect::add_fcn (symbol_table::clear_variables);
1442 feval ("load", octave_value (nm), 0);
1446 std::string newmsg = std::string ("Variables in the file ") +
1449 retval = do_who (i, argv, return_list, verbose, newmsg);
1452 unwind_protect::run_frame (uwp_frame);
1457 else if (argv[i] == "-regexp")
1459 else if (argv[i] == "global")
1461 else if (argv[i][0] == '-')
1462 warning ("%s: unrecognized option `%s'", my_name.c_str (),
1468 int npats = argc - i;
1472 pats.resize (npats);
1473 for (int j = 0; j < npats; j++)
1474 pats[j] = argv[i+j];
1478 pats.resize (++npats);
1482 symbol_info_list symbol_stats;
1483 std::list<std::string> symbol_names;
1485 for (int j = 0; j < npats; j++)
1487 std::string pat = pats[j];
1491 std::list<symbol_table::symbol_record> tmp = global_only
1492 ? symbol_table::regexp_global_variables (pat)
1493 : symbol_table::regexp_variables (pat);
1495 for (std::list<symbol_table::symbol_record>::const_iterator p = tmp.begin ();
1496 p != tmp.end (); p++)
1498 if (p->is_variable ())
1501 symbol_stats.append (*p);
1503 symbol_names.push_back (p->name ());
1509 size_t pos = pat.find_first_of (".({");
1511 if (pos != std::string::npos && pos > 0)
1515 // NOTE: we can only display information for
1516 // expressions based on global values if the variable is
1517 // global in the current scope because we currently have
1518 // no way of looking up the base value in the global
1519 // scope and then evaluating the arguments in the
1522 std::string base_name = pat.substr (0, pos);
1524 if (symbol_table::is_variable (base_name))
1526 symbol_table::symbol_record sr
1527 = symbol_table::find_symbol (base_name);
1529 if (! global_only || sr.is_global ())
1533 octave_value expr_val
1534 = eval_string (pat, true, parse_status);
1537 symbol_stats.append (sr, pat, expr_val);
1546 std::list<symbol_table::symbol_record> tmp = global_only
1547 ? symbol_table::glob_global_variables (pat)
1548 : symbol_table::glob_variables (pat);
1550 for (std::list<symbol_table::symbol_record>::const_iterator p = tmp.begin ();
1551 p != tmp.end (); p++)
1553 if (p->is_variable ())
1556 symbol_stats.append (*p);
1558 symbol_names.push_back (p->name ());
1569 std::string caller_function_name;
1570 octave_function *caller = octave_call_stack::caller ();
1572 caller_function_name = caller->name ();
1574 retval = symbol_stats.map_value (caller_function_name, 1);
1577 retval = Cell (string_vector (symbol_names));
1579 else if (! (symbol_stats.empty () && symbol_names.empty ()))
1581 if (msg.length () == 0)
1583 octave_stdout << "Global variables:\n\n";
1585 octave_stdout << "Variables in the current scope:\n\n";
1587 octave_stdout << msg;
1590 symbol_stats.display (octave_stdout);
1593 string_vector names (symbol_names);
1595 names.list_in_columns (octave_stdout);
1598 octave_stdout << "\n";
1604DEFUN (who, args, nargout,
1606@deftypefn {Command} {} who\n\
1607@deftypefnx {Command} {} who pattern @dots{}\n\
1608@deftypefnx {Command} {} who option pattern @dots{}\n\
1609@deftypefnx {Command} {C =} who (\"pattern\", @dots{})\n\
1610List currently defined variables matching the given patterns. Valid\n\
1611pattern syntax is the same as described for the @code{clear} command.\n\
1612If no patterns are supplied, all variables are listed.\n\
1613By default, only variables visible in the local scope are displayed.\n\
1615The following are valid options but may not be combined.\n\
1619List variables in the global scope rather than the current scope.\n\
1621The patterns are considered to be regular expressions when matching the\n\
1622variables to display. The same pattern syntax accepted by\n\
1623the @code{regexp} function is used.\n\
1625The next argument is treated as a filename. All variables found within the\n\
1626specified file are listed. No patterns are accepted when reading variables\n\
1630If called as a function, return a cell array of defined variable names\n\
1631matching the given patterns.\n\
1632@seealso{whos, regexp}\n\
1635 octave_value retval;
1639 int argc = args.length () + 1;
1641 string_vector argv = args.make_argv ("who");
1644 retval = do_who (argc, argv, nargout == 1);
1652DEFUN (whos, args, nargout,
1654@deftypefn {Command} {} whos\n\
1655@deftypefnx {Command} {} whos pattern @dots{}\n\
1656@deftypefnx {Command} {} whos option pattern @dots{}\n\
1657@deftypefnx {Command} {S =} whos (\"pattern\", @dots{})\n\
1658Provide detailed information on currently defined variables matching the\n\
1659given patterns. Options and pattern syntax are the same as for the\n\
1660@code{who} command. Extended information about each variable is\n\
1661summarized in a table with the following default entries.\n\
1665Attributes of the listed variable. Possible attributes are:\n\
1668Variable in local scope\n\
1670Variable with global scope\n\
1672Persistent variable\n\
1675The name of the variable.\n\
1677The logical size of the variable. A scalar is 1x1, a vector is 1xN or Nx1,\n\
1678a 2-D matrix is MxN.\n\
1680The amount of memory currently used to store the variable.\n\
1682The class of the variable. Examples include double, single, char, uint16,\n\
1686The table can be customized to display more or less information through\n\
1687the function @code{whos_line_format}.\n\
1689If @code{whos} is called as a function, return a struct array of defined\n\
1690variable names matching the given patterns. Fields in the structure\n\
1691describing each variable are: name, size, bytes, class, global, sparse, \n\
1692complex, nesting, persistent.\n\
1693@seealso{who, whos_line_format}\n\
1696 octave_value retval;
1700 int argc = args.length () + 1;
1702 string_vector argv = args.make_argv ("whos");
1705 retval = do_who (argc, argv, nargout == 1, true);
1713// Defining variables.
1716bind_ans (const octave_value& val, bool print)
1718 static std::string ans = "ans";
1720 if (val.is_defined ())
1722 if (val.is_cs_list ())
1724 octave_value_list lst = val.list_value ();
1726 for (octave_idx_type i = 0; i < lst.length (); i++)
1727 bind_ans (lst(i), print);
1731 symbol_table::varref (ans) = val;
1734 val.print_with_name (octave_stdout, ans);
1740bind_internal_variable (const std::string& fname, const octave_value& val)
1742 octave_value_list args;
1746 feval (fname, args, 0);
1752 octave_function *fcn = octave_call_stack::current ();
1757 error ("mlock: invalid use outside a function");
1761munlock (const std::string& nm)
1763 octave_value val = symbol_table::find_function (nm);
1765 if (val.is_defined ())
1767 octave_function *fcn = val.function_value ();
1775mislocked (const std::string& nm)
1777 bool retval = false;
1779 octave_value val = symbol_table::find_function (nm);
1781 if (val.is_defined ())
1783 octave_function *fcn = val.function_value ();
1786 retval = fcn->islocked ();
1792DEFUN (mlock, args, ,
1794@deftypefn {Built-in Function} {} mlock ()\n\
1795Lock the current function into memory so that it can't be cleared.\n\
1796@seealso{munlock, mislocked, persistent}\n\
1799 octave_value_list retval;
1801 if (args.length () == 0)
1803 octave_function *fcn = octave_call_stack::caller ();
1808 error ("mlock: invalid use outside a function");
1816DEFUN (munlock, args, ,
1818@deftypefn {Built-in Function} {} munlock (@var{fcn})\n\
1819Unlock the named function. If no function is named\n\
1820then unlock the current function.\n\
1821@seealso{mlock, mislocked, persistent}\n\
1824 octave_value_list retval;
1826 if (args.length() == 1)
1828 std::string name = args(0).string_value ();
1833 error ("munlock: expecting argument to be a function name");
1835 else if (args.length () == 0)
1837 octave_function *fcn = octave_call_stack::caller ();
1842 error ("munlock: invalid use outside a function");
1851DEFUN (mislocked, args, ,
1853@deftypefn {Built-in Function} {} mislocked (@var{fcn})\n\
1854Return true if the named function is locked. If no function is named\n\
1855then return true if the current function is locked.\n\
1856@seealso{mlock, munlock, persistent}\n\
1859 octave_value retval;
1861 if (args.length() == 1)
1863 std::string name = args(0).string_value ();
1866 retval = mislocked (name);
1868 error ("mislocked: expecting argument to be a function name");
1870 else if (args.length () == 0)
1872 octave_function *fcn = octave_call_stack::caller ();
1875 retval = fcn->islocked ();
1877 error ("mislocked: invalid use outside a function");
1885// Deleting names from the symbol tables.
1888name_matches_any_pattern (const std::string& nm, const string_vector& argv,
1889 int argc, int idx, bool have_regexp = false)
1891 bool retval = false;
1893 for (int k = idx; k < argc; k++)
1895 std::string patstr = argv[k];
1896 if (! patstr.empty ())
1900 regex_match pattern (patstr);
1902 if (pattern.match (nm))
1910 glob_match pattern (patstr);
1912 if (pattern.match (nm))
1925maybe_warn_exclusive (bool exclusive)
1928 warning ("clear: ignoring --exclusive option");
1932do_clear_functions (const string_vector& argv, int argc, int idx,
1933 bool exclusive = false)
1936 symbol_table::clear_functions ();
1941 string_vector fcns = symbol_table::user_function_names ();
1943 int fcount = fcns.length ();
1945 for (int i = 0; i < fcount; i++)
1947 std::string nm = fcns[i];
1949 if (! name_matches_any_pattern (nm, argv, argc, idx))
1950 symbol_table::clear_function (nm);
1956 symbol_table::clear_function_pattern (argv[idx++]);
1962do_clear_globals (const string_vector& argv, int argc, int idx,
1963 bool exclusive = false)
1967 string_vector gvars = symbol_table::global_variable_names ();
1969 int gcount = gvars.length ();
1971 for (int i = 0; i < gcount; i++)
1972 symbol_table::clear_global (gvars[i]);
1978 string_vector gvars = symbol_table::global_variable_names ();
1980 int gcount = gvars.length ();
1982 for (int i = 0; i < gcount; i++)
1984 std::string nm = gvars[i];
1986 if (! name_matches_any_pattern (nm, argv, argc, idx))
1987 symbol_table::clear_global (nm);
1993 symbol_table::clear_global_pattern (argv[idx++]);
1999do_clear_variables (const string_vector& argv, int argc, int idx,
2000 bool exclusive = false, bool have_regexp = false)
2003 symbol_table::clear_variables ();
2008 string_vector lvars = symbol_table::variable_names ();
2010 int lcount = lvars.length ();
2012 for (int i = 0; i < lcount; i++)
2014 std::string nm = lvars[i];
2016 if (! name_matches_any_pattern (nm, argv, argc, idx, have_regexp))
2017 symbol_table::clear_variable (nm);
2024 symbol_table::clear_variable_regexp (argv[idx++]);
2027 symbol_table::clear_variable_pattern (argv[idx++]);
2033do_clear_symbols (const string_vector& argv, int argc, int idx,
2034 bool exclusive = false)
2037 symbol_table::clear_variables ();
2042 // FIXME -- is this really what we want, or do we
2043 // somehow want to only clear the functions that are not
2044 // shadowed by local variables? It seems that would be a
2045 // bit harder to do.
2047 do_clear_variables (argv, argc, idx, exclusive);
2048 do_clear_functions (argv, argc, idx, exclusive);
2053 symbol_table::clear_symbol_pattern (argv[idx++]);
2059do_matlab_compatible_clear (const string_vector& argv, int argc, int idx)
2061 // This is supposed to be mostly Matlab compatible.
2063 for (; idx < argc; idx++)
2065 if (argv[idx] == "all"
2066 && ! symbol_table::is_local_variable ("all"))
2068 symbol_table::clear_all ();
2070 else if (argv[idx] == "functions"
2071 && ! symbol_table::is_local_variable ("functions"))
2073 do_clear_functions (argv, argc, ++idx);
2075 else if (argv[idx] == "global"
2076 && ! symbol_table::is_local_variable ("global"))
2078 do_clear_globals (argv, argc, ++idx);
2080 else if (argv[idx] == "variables"
2081 && ! symbol_table::is_local_variable ("variables"))
2083 symbol_table::clear_variables ();
2085 else if (argv[idx] == "classes"
2086 && ! symbol_table::is_local_variable ("classes"))
2088 symbol_table::clear_objects ();
2089 octave_class::clear_exemplar_map ();
2093 symbol_table::clear_symbol_pattern (argv[idx]);
2098#define CLEAR_OPTION_ERROR(cond) \
2109DEFUN (clear, args, ,
2111@deffn {Command} clear [options] pattern @dots{}\n\
2112Delete the names matching the given patterns from the symbol table. The\n\
2113pattern may contain the following special characters:\n\
2117Match any single character.\n\
2120Match zero or more characters.\n\
2122@item [ @var{list} ]\n\
2123Match the list of characters specified by @var{list}. If the first\n\
2124character is @code{!} or @code{^}, match all characters except those\n\
2125specified by @var{list}. For example, the pattern @samp{[a-zA-Z]} will\n\
2126match all lower and upper case alphabetic characters.\n\
2129For example, the command\n\
2136clears the name @code{foo} and all names that begin with the letter\n\
2137@code{b} and end with the letter @code{r}.\n\
2139If @code{clear} is called without any arguments, all user-defined\n\
2140variables (local and global) are cleared from the symbol table. If\n\
2141@code{clear} is called with at least one argument, only the visible\n\
2142names matching the arguments are cleared. For example, suppose you have\n\
2143defined a function @code{foo}, and then hidden it by performing the\n\
2144assignment @code{foo = 2}. Executing the command @kbd{clear foo} once\n\
2145will clear the variable definition and restore the definition of\n\
2146@code{foo} as a function. Executing @kbd{clear foo} a second time will\n\
2147clear the function definition.\n\
2149The following options are available in both long and short form\n\
2152Clears all local and global user-defined variables and all functions\n\
2153from the symbol table.\n\
2155@item -exclusive, -x\n\
2156Clears the variables that don't match the following pattern.\n\
2158@item -functions, -f\n\
2159Clears the function names and the built-in symbols names.\n\
2161Clears the global symbol names.\n\
2162@item -variables, -v\n\
2163Clears the local variable names.\n\
2164@item -classes, -c\n\
2165Clears the class structure table and clears all objects.\n\
2167The arguments are treated as regular expressions as any variables that\n\
2168match will be cleared.\n\
2170With the exception of @code{exclusive}, all long options can be used \n\
2171without the dash as well.\n\
2174 octave_value_list retval;
2176 int argc = args.length () + 1;
2178 string_vector argv = args.make_argv ("clear");
2184 do_clear_globals (argv, argc, 1);
2185 do_clear_variables (argv, argc, 1);
2191 bool clear_all = false;
2192 bool clear_functions = false;
2193 bool clear_globals = false;
2194 bool clear_variables = false;
2195 bool clear_objects = false;
2196 bool exclusive = false;
2197 bool have_regexp = false;
2198 bool have_dash_option = false;
2200 while (++idx < argc)
2202 if (argv[idx] == "-all" || argv[idx] == "-a")
2204 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2206 have_dash_option = true;
2209 else if (argv[idx] == "-exclusive" || argv[idx] == "-x")
2211 have_dash_option = true;
2214 else if (argv[idx] == "-functions" || argv[idx] == "-f")
2216 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2218 have_dash_option = true;
2219 clear_functions = true;
2221 else if (argv[idx] == "-global" || argv[idx] == "-g")
2223 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2225 have_dash_option = true;
2226 clear_globals = true;
2228 else if (argv[idx] == "-variables" || argv[idx] == "-v")
2230 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2232 have_dash_option = true;
2233 clear_variables = true;
2235 else if (argv[idx] == "-classes" || argv[idx] == "-c")
2237 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2239 have_dash_option = true;
2240 clear_objects = true;
2242 else if (argv[idx] == "-regexp" || argv[idx] == "-r")
2244 CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
2246 have_dash_option = true;
2255 if (! have_dash_option)
2257 do_matlab_compatible_clear (argv, argc, idx);
2263 maybe_warn_exclusive (exclusive);
2267 ("clear: ignoring extra arguments after -all");
2269 symbol_table::clear_all ();
2271 else if (have_regexp)
2273 do_clear_variables (argv, argc, idx, exclusive, true);
2275 else if (clear_functions)
2277 do_clear_functions (argv, argc, idx, exclusive);
2279 else if (clear_globals)
2281 do_clear_globals (argv, argc, idx, exclusive);
2283 else if (clear_variables)
2285 do_clear_variables (argv, argc, idx, exclusive);
2287 else if (clear_objects)
2289 symbol_table::clear_objects ();
2290 octave_class::clear_exemplar_map ();
2294 do_clear_symbols (argv, argc, idx, exclusive);
2304DEFUN (whos_line_format, args, nargout,
2306@deftypefn {Built-in Function} {@var{val} =} whos_line_format ()\n\
2307@deftypefnx {Built-in Function} {@var{old_val} =} whos_line_format (@var{new_val})\n\
2308Query or set the format string used by the command @code{whos}.\n\
2310A full format string is:\n\
2312@c Set example in small font to prevent overfull line\n\
2314%[modifier]<command>[:width[:left-min[:balance]]];\n\
2317The following command sequences are available:\n\
2321Prints attributes of variables (g=global, p=persistent,\n\
2322f=formal parameter, a=automatic variable).\n\
2324Prints number of bytes occupied by variables.\n\
2326Prints class names of variables.\n\
2328Prints elements held by variables.\n\
2330Prints variable names.\n\
2332Prints dimensions of variables.\n\
2334Prints type names of variables.\n\
2337Every command may also have an alignment modifier:\n\
2343Right alignment (default).\n\
2345Column-aligned (only applicable to command %s).\n\
2348The @code{width} parameter is a positive integer specifying the minimum\n\
2349number of columns used for printing. No maximum is needed as the field will\n\
2350auto-expand as required.\n\
2352The parameters @code{left-min} and @code{balance} are only available when the\n\
2353column-aligned modifier is used with the command @samp{%s}.\n\
2354@code{balance} specifies the column number within the field width which will\n\
2355be aligned between entries. Numbering starts from 0 which indicates the\n\
2356leftmost column. @code{left-min} specifies the minimum field width to the\n\
2357left of the specified balance column.\n\
2359The default format is\n\
2360@code{\" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;\\n\"}.\n\
2364 return SET_INTERNAL_VARIABLE (whos_line_format);
2368;;; Local Variables: ***