Mercurial > octave-nkf
comparison src/variables.cc @ 7336:745a8299c2b5
[project @ 2007-12-28 20:56:55 by jwe]
author | jwe |
---|---|
date | Fri, 28 Dec 2007 20:56:58 +0000 |
parents | 97db94ae2cf0 |
children | 0fa079d04772 |
comparison
equal
deleted
inserted
replaced
7335:58f5fab3ebe5 | 7336:745a8299c2b5 |
---|---|
26 #endif | 26 #endif |
27 | 27 |
28 #include <cstdio> | 28 #include <cstdio> |
29 #include <cstring> | 29 #include <cstring> |
30 | 30 |
31 #include <iomanip> | |
31 #include <set> | 32 #include <set> |
32 #include <string> | 33 #include <string> |
33 | 34 |
34 #include "file-stat.h" | 35 #include "file-stat.h" |
35 #include "oct-env.h" | 36 #include "oct-env.h" |
61 | 62 |
62 // Should Octave always check to see if function files have changed | 63 // Should Octave always check to see if function files have changed |
63 // since they were last compiled? | 64 // since they were last compiled? |
64 static int Vignore_function_time_stamp = 1; | 65 static int Vignore_function_time_stamp = 1; |
65 | 66 |
66 // Symbol table for symbols at the top level. | 67 // Defines layout for the whos/who -long command |
67 symbol_table *top_level_sym_tab = 0; | 68 static std::string Vwhos_line_format |
68 | 69 = " %a:4; %ln:6; %cs:16:6:8:1; %rb:12; %lc:-1;\n"; |
69 // Symbol table for the current scope. | |
70 symbol_table *curr_sym_tab = 0; | |
71 | |
72 // Symbol table for the current caller scope. | |
73 symbol_table *curr_caller_sym_tab = 0; | |
74 | |
75 // Symbol table for global symbols. | |
76 symbol_table *global_sym_tab = 0; | |
77 | |
78 // Symbol table for functions and built-in symbols. | |
79 symbol_table *fbi_sym_tab = 0; | |
80 | |
81 bool | |
82 at_top_level (void) | |
83 { | |
84 return (curr_sym_tab == top_level_sym_tab); | |
85 } | |
86 | |
87 // Initialization. | |
88 | |
89 // Create the initial symbol tables and set the current scope at the | |
90 // top level. | |
91 | |
92 void | |
93 initialize_symbol_tables (void) | |
94 { | |
95 if (! fbi_sym_tab) | |
96 fbi_sym_tab = new symbol_table (2048, "FBI"); | |
97 | |
98 if (! global_sym_tab) | |
99 global_sym_tab = new symbol_table (2048, "GLOBAL"); | |
100 | |
101 if (! top_level_sym_tab) | |
102 top_level_sym_tab = new symbol_table (4096, "TOP"); | |
103 | |
104 curr_caller_sym_tab = curr_sym_tab = top_level_sym_tab; | |
105 } | |
106 | 70 |
107 void | 71 void |
108 clear_mex_functions (void) | 72 clear_mex_functions (void) |
109 { | 73 { |
110 fbi_sym_tab->clear_mex_functions (); | 74 symbol_table::clear_mex_functions (); |
75 } | |
76 | |
77 void | |
78 clear_function (const std::string& nm) | |
79 { | |
80 symbol_table::clear_function (nm); | |
81 } | |
82 | |
83 void | |
84 clear_variable (const std::string& nm) | |
85 { | |
86 symbol_table::clear_variable (nm); | |
87 } | |
88 | |
89 void | |
90 clear_symbol (const std::string& nm) | |
91 { | |
92 symbol_table::clear_symbol (nm); | |
111 } | 93 } |
112 | 94 |
113 // Attributes of variables and functions. | 95 // Attributes of variables and functions. |
114 | 96 |
115 // Is this a command-style function? | 97 // Is this a command-style function? |
116 | 98 |
117 static std::set <std::string> command_set; | 99 static std::set <std::string> command_set; |
118 | 100 |
119 static inline bool | 101 void |
120 is_marked_as_command (const std::string& s) | |
121 { | |
122 return command_set.find (s) != command_set.end (); | |
123 } | |
124 | |
125 static inline void | |
126 mark_as_command (const std::string& s) | 102 mark_as_command (const std::string& s) |
127 { | 103 { |
128 command_set.insert (s); | 104 command_set.insert (s); |
129 } | 105 } |
130 | 106 |
131 static inline void | 107 static inline void |
132 unmark_command (const std::string& s) | 108 unmark_command (const std::string& s) |
133 { | 109 { |
134 command_set.erase (s); | 110 command_set.erase (s); |
135 | |
136 symbol_record *sr = fbi_sym_tab->lookup (s); | |
137 | |
138 if (sr) | |
139 sr->unmark_command (); | |
140 } | 111 } |
141 | 112 |
142 DEFCMD (mark_as_command, args, , | 113 DEFCMD (mark_as_command, args, , |
143 "-*- texinfo -*-\n\ | 114 "-*- texinfo -*-\n\ |
144 @deftypefn {Built-in Function} {} mark_as_command (@var{name})\n\ | 115 @deftypefn {Built-in Function} {} mark_as_command (@var{name})\n\ |
146 @seealso{unmark_command, iscommand}\n\ | 117 @seealso{unmark_command, iscommand}\n\ |
147 @end deftypefn") | 118 @end deftypefn") |
148 { | 119 { |
149 octave_value_list retval; | 120 octave_value_list retval; |
150 | 121 |
151 if (at_top_level ()) | 122 if (symbol_table::at_top_level ()) |
152 { | 123 { |
153 int nargin = args.length (); | 124 int nargin = args.length (); |
154 | 125 |
155 if (nargin > 0) | 126 if (nargin > 0) |
156 { | 127 { |
180 @seealso{mark_as_command, iscommand}\n\ | 151 @seealso{mark_as_command, iscommand}\n\ |
181 @end deftypefn") | 152 @end deftypefn") |
182 { | 153 { |
183 octave_value_list retval; | 154 octave_value_list retval; |
184 | 155 |
185 if (at_top_level ()) | 156 if (symbol_table::at_top_level ()) |
186 { | 157 { |
187 int nargin = args.length (); | 158 int nargin = args.length (); |
188 | 159 |
189 if (nargin > 0) | 160 if (nargin > 0) |
190 { | 161 { |
208 } | 179 } |
209 | 180 |
210 bool | 181 bool |
211 is_command_name (const std::string& s) | 182 is_command_name (const std::string& s) |
212 { | 183 { |
213 bool retval = false; | 184 return command_set.find (s) != command_set.end (); |
214 | 185 } |
215 symbol_record *sr = fbi_sym_tab->lookup (s); | 186 |
216 | |
217 if (sr) | |
218 { | |
219 if (sr->is_command ()) | |
220 retval = true; | |
221 else if (is_marked_as_command (s)) | |
222 { | |
223 sr->mark_as_command (); | |
224 retval = true; | |
225 } | |
226 } | |
227 else | |
228 retval = is_marked_as_command (s); | |
229 | |
230 return retval; | |
231 } | |
232 | 187 |
233 DEFCMD (iscommand, args, , | 188 DEFCMD (iscommand, args, , |
234 "-*- texinfo -*-\n\ | 189 "-*- texinfo -*-\n\ |
235 @deftypefn {Built-in Function} {} iscommand (@var{name})\n\ | 190 @deftypefn {Built-in Function} {} iscommand (@var{name})\n\ |
236 Return true if @var{name} is a command style function. If @var{name}\n\ | 191 Return true if @var{name} is a command style function. If @var{name}\n\ |
272 | 227 |
273 // Is this a raw input command? | 228 // Is this a raw input command? |
274 | 229 |
275 static std::set <std::string> rawcommand_set; | 230 static std::set <std::string> rawcommand_set; |
276 | 231 |
277 bool | |
278 is_marked_as_rawcommand (const std::string& s) | |
279 { | |
280 return rawcommand_set.find (s) != rawcommand_set.end (); | |
281 } | |
282 | |
283 void | 232 void |
284 mark_as_rawcommand (const std::string& s) | 233 mark_as_rawcommand (const std::string& s) |
285 { | 234 { |
286 command_set.insert (s); | 235 command_set.insert (s); |
287 rawcommand_set.insert (s); | 236 rawcommand_set.insert (s); |
289 | 238 |
290 void | 239 void |
291 unmark_rawcommand (const std::string& s) | 240 unmark_rawcommand (const std::string& s) |
292 { | 241 { |
293 rawcommand_set.erase (s); | 242 rawcommand_set.erase (s); |
294 | |
295 symbol_record *sr = fbi_sym_tab->lookup (s); | |
296 | |
297 if (sr) | |
298 sr->unmark_rawcommand (); | |
299 } | 243 } |
300 | 244 |
301 DEFCMD (mark_as_rawcommand, args, , | 245 DEFCMD (mark_as_rawcommand, args, , |
302 "-*- texinfo -*-\n\ | 246 "-*- texinfo -*-\n\ |
303 @deftypefn {Built-in Function} {} mark_as_rawcommand (@var{name})\n\ | 247 @deftypefn {Built-in Function} {} mark_as_rawcommand (@var{name})\n\ |
312 @seealso{unmark_rawcommand, israwcommand, iscommand, mark_as_command}\n\ | 256 @seealso{unmark_rawcommand, israwcommand, iscommand, mark_as_command}\n\ |
313 @end deftypefn") | 257 @end deftypefn") |
314 { | 258 { |
315 octave_value_list retval; | 259 octave_value_list retval; |
316 | 260 |
317 if (at_top_level ()) | 261 if (symbol_table::at_top_level ()) |
318 { | 262 { |
319 int nargin = args.length (); | 263 int nargin = args.length (); |
320 | 264 |
321 if (nargin > 0) | 265 if (nargin > 0) |
322 { | 266 { |
348 @seealso{mark_as_rawcommand, israwcommand, iscommand, unmark_command}\n\ | 292 @seealso{mark_as_rawcommand, israwcommand, iscommand, unmark_command}\n\ |
349 @end deftypefn") | 293 @end deftypefn") |
350 { | 294 { |
351 octave_value_list retval; | 295 octave_value_list retval; |
352 | 296 |
353 if (at_top_level ()) | 297 if (symbol_table::at_top_level ()) |
354 { | 298 { |
355 int nargin = args.length (); | 299 int nargin = args.length (); |
356 | 300 |
357 if (nargin > 0) | 301 if (nargin > 0) |
358 { | 302 { |
376 } | 320 } |
377 | 321 |
378 bool | 322 bool |
379 is_rawcommand_name (const std::string& s) | 323 is_rawcommand_name (const std::string& s) |
380 { | 324 { |
381 bool retval = false; | 325 return rawcommand_set.find (s) != rawcommand_set.end (); |
382 | |
383 symbol_record *sr = fbi_sym_tab->lookup (s); | |
384 | |
385 if (sr) | |
386 { | |
387 if (sr->is_rawcommand ()) | |
388 retval = true; | |
389 else if (is_marked_as_rawcommand (s)) | |
390 { | |
391 sr->mark_as_rawcommand (); | |
392 retval = true; | |
393 } | |
394 } | |
395 else | |
396 retval = is_marked_as_rawcommand (s); | |
397 | |
398 return retval; | |
399 } | 326 } |
400 | 327 |
401 DEFCMD (israwcommand, args, , | 328 DEFCMD (israwcommand, args, , |
402 "-*- texinfo -*-\n\ | 329 "-*- texinfo -*-\n\ |
403 @deftypefn {Built-in Function} {} israwcommand (@var{name})\n\ | 330 @deftypefn {Built-in Function} {} israwcommand (@var{name})\n\ |
437 print_usage (); | 364 print_usage (); |
438 | 365 |
439 return retval; | 366 return retval; |
440 } | 367 } |
441 | 368 |
442 // Is this a built-in function? | |
443 | |
444 bool | |
445 is_builtin_function_name (const std::string& s) | |
446 { | |
447 symbol_record *sr = fbi_sym_tab->lookup (s); | |
448 return (sr && sr->is_builtin_function ()); | |
449 } | |
450 | |
451 // Is this a mapper function? | |
452 | |
453 bool | |
454 is_mapper_function_name (const std::string& s) | |
455 { | |
456 symbol_record *sr = fbi_sym_tab->lookup (s); | |
457 return (sr && sr->is_mapper_function ()); | |
458 } | |
459 | |
460 // Is this function globally in this scope? | |
461 | |
462 bool | |
463 is_globally_visible (const std::string& name) | |
464 { | |
465 symbol_record *sr = curr_sym_tab->lookup (name); | |
466 return (sr && sr->is_linked_to_global ()); | |
467 } | |
468 | |
469 // Is this octave_value a valid function? | 369 // Is this octave_value a valid function? |
470 | 370 |
471 octave_function * | 371 octave_function * |
472 is_valid_function (const std::string& fcn_name, | 372 is_valid_function (const std::string& fcn_name, |
473 const std::string& warn_for, bool warn) | 373 const std::string& warn_for, bool warn) |
474 { | 374 { |
475 octave_function *ans = 0; | 375 octave_function *ans = 0; |
476 | 376 |
477 symbol_record *sr = 0; | |
478 | |
479 if (! fcn_name.empty ()) | 377 if (! fcn_name.empty ()) |
480 { | 378 { |
481 sr = fbi_sym_tab->lookup (fcn_name, true); | 379 octave_value val = symbol_table::find_function (fcn_name); |
482 | 380 |
483 lookup (sr, false); | 381 if (val.is_defined ()) |
484 } | 382 ans = val.function_value (true); |
485 | 383 } |
486 if (sr) | 384 |
487 { | 385 if (! ans && warn) |
488 octave_value tmp = sr->def (); | 386 error ("%s: the symbol `%s' is not valid as a function", |
489 ans = tmp.function_value (true); | 387 warn_for.c_str (), fcn_name.c_str ()); |
490 } | |
491 | |
492 if (! sr || ! ans || ! sr->is_function ()) | |
493 { | |
494 if (warn) | |
495 error ("%s: the symbol `%s' is not valid as a function", | |
496 warn_for.c_str (), fcn_name.c_str ()); | |
497 ans = 0; | |
498 } | |
499 | 388 |
500 return ans; | 389 return ans; |
501 } | 390 } |
502 | 391 |
503 octave_function * | 392 octave_function * |
611 { | 500 { |
612 bool retval = false; | 501 bool retval = false; |
613 | 502 |
614 if (! name.empty ()) | 503 if (! name.empty ()) |
615 { | 504 { |
616 symbol_record *sr = curr_sym_tab->lookup (name); | 505 octave_value val = symbol_table::varval (name); |
617 | 506 |
618 if (! sr) | 507 retval = val.is_defined (); |
619 sr = fbi_sym_tab->lookup (name); | |
620 | |
621 retval = (sr && sr->is_variable ()); | |
622 } | 508 } |
623 | 509 |
624 return retval; | 510 return retval; |
625 } | 511 } |
626 | 512 |
731 { | 617 { |
732 error ("isglobal: expecting std::string argument"); | 618 error ("isglobal: expecting std::string argument"); |
733 return retval; | 619 return retval; |
734 } | 620 } |
735 | 621 |
736 symbol_record *sr = curr_sym_tab->lookup (name); | 622 return symbol_table::is_global (name); |
737 | |
738 retval = (sr && sr->is_linked_to_global ()); | |
739 | |
740 return retval; | |
741 } | 623 } |
742 | 624 |
743 DEFUN (isglobal, args, , | 625 DEFUN (isglobal, args, , |
744 "-*- texinfo -*-\n\ | 626 "-*- texinfo -*-\n\ |
745 @deftypefn {Built-in Function} {} isglobal (@var{name})\n\ | 627 @deftypefn {Built-in Function} {} isglobal (@var{name})\n\ |
785 | 667 |
786 // We shouldn't need to look in the global symbol table, since any | 668 // We shouldn't need to look in the global symbol table, since any |
787 // name that is visible in the current scope will be in the local | 669 // name that is visible in the current scope will be in the local |
788 // symbol table. | 670 // symbol table. |
789 | 671 |
790 symbol_record *sr = curr_sym_tab->lookup (symbol_name); | 672 octave_value_list evaluated_args; |
791 | 673 bool args_evaluated; |
792 if (! (sr && sr->is_defined ())) | 674 |
793 sr = fbi_sym_tab->lookup (symbol_name); | 675 octave_value val = symbol_table::find (symbol_name, 0, string_vector (), |
794 | 676 evaluated_args, args_evaluated); |
795 if (sr && sr->is_defined ()) | 677 |
678 if (val.is_defined ()) | |
796 { | 679 { |
797 bool not_a_struct = struct_elts.empty (); | 680 bool not_a_struct = struct_elts.empty (); |
798 bool var_ok = not_a_struct || sr->is_map_element (struct_elts); | 681 bool var_ok = not_a_struct /* || val.is_map_element (struct_elts) */; |
799 | 682 |
800 if (! retval | 683 if (! retval |
801 && var_ok | 684 && var_ok |
802 && (type == "any" || type == "var") | 685 && (type == "any" || type == "var") |
803 && sr->is_user_variable ()) | 686 && val.is_constant ()) |
804 { | 687 { |
805 retval = 1; | 688 retval = 1; |
806 } | 689 } |
807 | 690 |
808 if (! retval | 691 if (! retval |
809 && (type == "any" || type == "builtin")) | 692 && (type == "any" || type == "builtin")) |
810 { | 693 { |
811 if (not_a_struct && sr->is_builtin_function ()) | 694 if (not_a_struct && val.is_builtin_function ()) |
812 { | 695 { |
813 retval = 5; | 696 retval = 5; |
814 } | 697 } |
815 } | 698 } |
816 | 699 |
817 if (! retval | 700 if (! retval |
818 && not_a_struct | 701 && not_a_struct |
819 && (type == "any" || type == "file") | 702 && (type == "any" || type == "file") |
820 && (sr->is_user_function () || sr->is_dld_function ())) | 703 && (val.is_user_function () || val.is_dld_function ())) |
821 { | 704 { |
822 octave_value t = sr->def (); | 705 octave_function *f = val.function_value (true); |
823 octave_function *f = t.function_value (true); | |
824 std::string s = f ? f->fcn_file_name () : std::string (); | 706 std::string s = f ? f->fcn_file_name () : std::string (); |
825 | 707 |
826 retval = s.empty () ? 103 : (sr->is_user_function () ? 2 : 3); | 708 retval = s.empty () ? 103 : (val.is_user_function () ? 2 : 3); |
827 } | 709 } |
828 } | 710 } |
829 | 711 |
830 if (! (type == "var" || type == "builtin")) | 712 if (! (type == "var" || type == "builtin")) |
831 { | 713 { |
960 print_usage (); | 842 print_usage (); |
961 | 843 |
962 return retval; | 844 return retval; |
963 } | 845 } |
964 | 846 |
965 bool | |
966 fcn_out_of_date (octave_function *fcn, const std::string& ff, time_t tp) | |
967 { | |
968 bool retval = false; | |
969 | |
970 fcn->mark_fcn_file_up_to_date (octave_time ()); | |
971 | |
972 if (! (Vignore_function_time_stamp == 2 | |
973 || (Vignore_function_time_stamp && fcn->is_system_fcn_file ()))) | |
974 { | |
975 file_stat fs (ff); | |
976 | |
977 if (fs && fs.is_newer (tp)) | |
978 retval = true; | |
979 } | |
980 | |
981 return retval; | |
982 } | |
983 | |
984 // Is there a corresponding function file that is newer than the | |
985 // symbol definition? | |
986 | |
987 static bool | |
988 symbol_out_of_date (symbol_record *sr) | |
989 { | |
990 bool retval = false; | |
991 | |
992 if (sr) | |
993 { | |
994 octave_value ans = sr->def (); | |
995 | |
996 octave_function *fcn = ans.function_value (true); | |
997 | |
998 if (fcn) | |
999 { | |
1000 std::string ff = fcn->fcn_file_name (); | |
1001 | |
1002 if (! ff.empty ()) | |
1003 { | |
1004 octave_time tc = fcn->time_checked (); | |
1005 | |
1006 bool relative = fcn->is_relative (); | |
1007 | |
1008 if (tc < Vlast_prompt_time | |
1009 || (relative && tc < Vlast_chdir_time)) | |
1010 { | |
1011 octave_time ottp = fcn->time_parsed (); | |
1012 time_t tp = ottp.unix_time (); | |
1013 | |
1014 std::string nm = fcn->is_nested_function () | |
1015 ? fcn->parent_fcn_name () : fcn->name (); | |
1016 | |
1017 // FIXME -- the following code is repeated | |
1018 // in load_fcn_from_file in parse.y. | |
1019 | |
1020 int nm_len = nm.length (); | |
1021 | |
1022 std::string file; | |
1023 | |
1024 if (octave_env::absolute_pathname (nm) | |
1025 && ((nm_len > 4 && (nm.substr (nm_len-4) == ".oct" | |
1026 || nm.substr (nm_len-4) == ".mex")) | |
1027 || (nm_len > 2 && nm.substr (nm_len-4) == ".m"))) | |
1028 { | |
1029 file = nm; | |
1030 } | |
1031 else | |
1032 { | |
1033 file = lookup_autoload (nm); | |
1034 | |
1035 if (file.empty ()) | |
1036 file = load_path::find_fcn (nm); | |
1037 | |
1038 file = octave_env::make_absolute (file, octave_env::getcwd ()); | |
1039 } | |
1040 | |
1041 if (file.empty ()) | |
1042 { | |
1043 // Can't see this function now, so we should | |
1044 // clear it. | |
1045 | |
1046 sr->clear (); | |
1047 | |
1048 retval = true; | |
1049 } | |
1050 else if (same_file (file, ff)) | |
1051 { | |
1052 retval = fcn_out_of_date (fcn, ff, tp); | |
1053 } | |
1054 else | |
1055 { | |
1056 // Check the full function name. Maybe we already | |
1057 // parsed it. | |
1058 | |
1059 symbol_record *full_sr = fbi_sym_tab->lookup (file); | |
1060 | |
1061 if (full_sr) | |
1062 { | |
1063 octave_value v = full_sr->def (); | |
1064 | |
1065 if (v.is_function ()) | |
1066 { | |
1067 // OK, swap the aliases around. | |
1068 | |
1069 // FIXME -- this is a bit | |
1070 // tricky, so maybe some refactoring is | |
1071 // in order here too... | |
1072 | |
1073 symbol_record *short_sr = fbi_sym_tab->lookup (nm); | |
1074 | |
1075 if (short_sr) | |
1076 short_sr->alias (full_sr); | |
1077 | |
1078 // Make local symbol table entry point | |
1079 // to correct global function too. | |
1080 | |
1081 sr->alias (full_sr); | |
1082 | |
1083 fcn = v.function_value (); | |
1084 | |
1085 retval = fcn_out_of_date (fcn, file, tp); | |
1086 } | |
1087 else | |
1088 retval = true; | |
1089 } | |
1090 else | |
1091 retval = true; | |
1092 } | |
1093 } | |
1094 } | |
1095 } | |
1096 } | |
1097 | |
1098 return retval; | |
1099 } | |
1100 | |
1101 bool | |
1102 lookup (symbol_record *sym_rec, bool exec_script) | |
1103 { | |
1104 bool script_executed = false; | |
1105 | |
1106 if (! sym_rec->is_linked_to_global ()) | |
1107 { | |
1108 if (sym_rec->is_defined ()) | |
1109 { | |
1110 if (sym_rec->is_function () && symbol_out_of_date (sym_rec)) | |
1111 script_executed = load_fcn_from_file (sym_rec, exec_script); | |
1112 } | |
1113 else if (! sym_rec->is_formal_parameter ()) | |
1114 { | |
1115 link_to_builtin_or_function (sym_rec); | |
1116 | |
1117 if (! sym_rec->is_defined ()) | |
1118 script_executed = load_fcn_from_file (sym_rec, exec_script); | |
1119 else if (sym_rec->is_function () && symbol_out_of_date (sym_rec)) | |
1120 script_executed = load_fcn_from_file (sym_rec, exec_script); | |
1121 } | |
1122 } | |
1123 | |
1124 return script_executed; | |
1125 } | |
1126 | |
1127 // Get the symbol record for the given name that is visible in the | |
1128 // current scope. Reread any function definitions that appear to be | |
1129 // out of date. If a function is available in a file but is not | |
1130 // currently loaded, this will load it and insert the name in the | |
1131 // current symbol table. | |
1132 | |
1133 symbol_record * | |
1134 lookup_by_name (const std::string& nm, bool exec_script) | |
1135 { | |
1136 symbol_record *sym_rec = curr_sym_tab->lookup (nm, true); | |
1137 | |
1138 lookup (sym_rec, exec_script); | |
1139 | |
1140 return sym_rec; | |
1141 } | |
1142 | |
1143 octave_value | |
1144 lookup_function (const std::string& nm, const std::string& parent) | |
1145 { | |
1146 octave_value retval; | |
1147 | |
1148 symbol_record *sr = 0; | |
1149 | |
1150 if (! parent.empty ()) | |
1151 sr = fbi_sym_tab->lookup (parent + ":" + nm); | |
1152 | |
1153 if (! sr || ! sr->is_function ()) | |
1154 { | |
1155 if (curr_parent_function) | |
1156 sr = fbi_sym_tab->lookup (curr_parent_function->name () + ":" + nm); | |
1157 | |
1158 if (! sr || ! sr->is_function ()) | |
1159 sr = fbi_sym_tab->lookup (nm, true); | |
1160 | |
1161 if (sr && ! sr->is_function ()) | |
1162 load_fcn_from_file (sr, false); | |
1163 } | |
1164 | |
1165 if (sr) | |
1166 { | |
1167 octave_value v = sr->def (); | |
1168 | |
1169 if (v.is_function ()) | |
1170 retval = v; | |
1171 } | |
1172 | |
1173 return retval; | |
1174 } | |
1175 | |
1176 octave_value | |
1177 lookup_user_function (const std::string& nm) | |
1178 { | |
1179 octave_value retval; | |
1180 | |
1181 symbol_record *sr = 0; | |
1182 | |
1183 if (curr_parent_function) | |
1184 { | |
1185 std::string parent = curr_parent_function->name (); | |
1186 | |
1187 sr = fbi_sym_tab->lookup (parent + ":" + nm); | |
1188 } | |
1189 | |
1190 if (! sr || ! sr->is_user_function ()) | |
1191 { | |
1192 sr = fbi_sym_tab->lookup (nm, true); | |
1193 | |
1194 if (sr && ! sr->is_user_function ()) | |
1195 load_fcn_from_file (sr, false); | |
1196 } | |
1197 | |
1198 if (sr) | |
1199 retval = sr->def (); | |
1200 | |
1201 return retval; | |
1202 } | |
1203 | |
1204 octave_value | 847 octave_value |
1205 lookup_function_handle (const std::string& nm) | 848 lookup_function_handle (const std::string& nm) |
1206 { | 849 { |
1207 octave_value retval; | 850 octave_value val = symbol_table::varval (nm); |
1208 | 851 |
1209 symbol_record *sr = curr_sym_tab->lookup (nm, true); | 852 return val.is_function_handle () ? val : octave_value (); |
1210 | |
1211 if (sr && sr->def ().is_function_handle ()) | |
1212 retval = sr->def (); | |
1213 | |
1214 return retval; | |
1215 } | 853 } |
1216 | 854 |
1217 octave_value | 855 octave_value |
1218 get_global_value (const std::string& nm, bool silent) | 856 get_global_value (const std::string& nm, bool silent) |
1219 { | 857 { |
1220 octave_value retval; | 858 octave_value val = symbol_table::varval (nm, symbol_table::global_scope ()); |
1221 | 859 |
1222 symbol_record *sr = global_sym_tab->lookup (nm); | 860 if (val.is_undefined () && ! silent) |
1223 | 861 error ("get_global_by_name: undefined symbol `%s'", nm.c_str ()); |
1224 if (sr) | 862 |
1225 { | 863 return val; |
1226 octave_value sr_def = sr->def (); | |
1227 | |
1228 if (sr_def.is_defined ()) | |
1229 retval = sr_def; | |
1230 else if (! silent) | |
1231 error ("get_global_by_name: undefined symbol `%s'", nm.c_str ()); | |
1232 } | |
1233 else if (! silent) | |
1234 error ("get_global_by_name: unknown symbol `%s'", nm.c_str ()); | |
1235 | |
1236 return retval; | |
1237 } | 864 } |
1238 | 865 |
1239 void | 866 void |
1240 set_global_value (const std::string& nm, const octave_value& val) | 867 set_global_value (const std::string& nm, const octave_value& val) |
1241 { | 868 { |
1242 symbol_record *sr = global_sym_tab->lookup (nm, true); | 869 symbol_table::varref (nm, symbol_table::global_scope ()) = val; |
1243 | |
1244 if (sr) | |
1245 sr->define (val); | |
1246 else | |
1247 panic_impossible (); | |
1248 } | 870 } |
1249 | 871 |
1250 // Variable values. | 872 // Variable values. |
1251 | 873 |
1252 octave_value | 874 octave_value |
1413 print_usage (); | 1035 print_usage (); |
1414 | 1036 |
1415 return retval; | 1037 return retval; |
1416 } | 1038 } |
1417 | 1039 |
1418 // Global stuff and links to builtin variables and functions. | 1040 struct |
1419 | 1041 symbol_record_name_compare |
1420 // Make the definition of the symbol record sr be the same as the | 1042 { |
1421 // definition of the global variable of the same name, creating it if | 1043 bool operator () (const symbol_table::symbol_record& a, |
1422 // it doesn't already exist. | 1044 const symbol_table::symbol_record& b) |
1045 { | |
1046 std::string a_nm = a.name (); | |
1047 std::string b_nm = b.name (); | |
1048 | |
1049 return a_nm.compare (b_nm); | |
1050 } | |
1051 }; | |
1052 | |
1053 struct | |
1054 whos_parameter | |
1055 { | |
1056 char command; | |
1057 char modifier; | |
1058 int parameter_length; | |
1059 int first_parameter_length; | |
1060 int dimensions; | |
1061 int balance; | |
1062 std::string text; | |
1063 std::string line; | |
1064 }; | |
1065 | |
1066 static void | |
1067 print_descriptor (std::ostream& os, std::list<whos_parameter> params) | |
1068 { | |
1069 // This method prints a line of information on a given symbol | |
1070 std::list<whos_parameter>::iterator i = params.begin (); | |
1071 std::ostringstream param_buf; | |
1072 | |
1073 while (i != params.end ()) | |
1074 { | |
1075 whos_parameter param = *i; | |
1076 | |
1077 if (param.command != '\0') | |
1078 { | |
1079 // Do the actual printing | |
1080 switch (param.modifier) | |
1081 { | |
1082 case 'l': | |
1083 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1084 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1085 break; | |
1086 | |
1087 case 'r': | |
1088 os << std::setiosflags (std::ios::right) << std::setw (param.parameter_length); | |
1089 param_buf << std::setiosflags (std::ios::right) << std::setw (param.parameter_length); | |
1090 break; | |
1091 | |
1092 case 'c': | |
1093 if (param.command != 's') | |
1094 { | |
1095 os << std::setiosflags (std::ios::left) | |
1096 << std::setw (param.parameter_length); | |
1097 param_buf << std::setiosflags (std::ios::left) | |
1098 << std::setw (param.parameter_length); | |
1099 } | |
1100 break; | |
1101 | |
1102 default: | |
1103 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1104 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1105 } | |
1106 | |
1107 if (param.command == 's' && param.modifier == 'c') | |
1108 { | |
1109 int a, b; | |
1110 | |
1111 if (param.modifier == 'c') | |
1112 { | |
1113 a = param.first_parameter_length - param.balance; | |
1114 a = (a < 0 ? 0 : a); | |
1115 b = param.parameter_length - a - param.text . length (); | |
1116 b = (b < 0 ? 0 : b); | |
1117 os << std::setiosflags (std::ios::left) << std::setw (a) | |
1118 << "" << std::resetiosflags (std::ios::left) << param.text | |
1119 << std::setiosflags (std::ios::left) | |
1120 << std::setw (b) << "" | |
1121 << std::resetiosflags (std::ios::left); | |
1122 param_buf << std::setiosflags (std::ios::left) << std::setw (a) | |
1123 << "" << std::resetiosflags (std::ios::left) << param.line | |
1124 << std::setiosflags (std::ios::left) | |
1125 << std::setw (b) << "" | |
1126 << std::resetiosflags (std::ios::left); | |
1127 } | |
1128 } | |
1129 else | |
1130 { | |
1131 os << param.text; | |
1132 param_buf << param.line; | |
1133 } | |
1134 os << std::resetiosflags (std::ios::left) | |
1135 << std::resetiosflags (std::ios::right); | |
1136 param_buf << std::resetiosflags (std::ios::left) | |
1137 << std::resetiosflags (std::ios::right); | |
1138 i++; | |
1139 } | |
1140 else | |
1141 { | |
1142 os << param.text; | |
1143 param_buf << param.line; | |
1144 i++; | |
1145 } | |
1146 } | |
1147 | |
1148 os << param_buf.str (); | |
1149 } | |
1150 | |
1151 // Calculate how much space needs to be reserved for the first part of | |
1152 // the dimensions string. For example, | |
1153 // | |
1154 // mat is a 12x3 matrix | |
1155 // ^^ => 2 columns | |
1156 | |
1157 static int | |
1158 dimensions_string_req_first_space (const dim_vector& dims, int print_dims) | |
1159 { | |
1160 int first_param_space = 0; | |
1161 | |
1162 // Calculating dimensions. | |
1163 | |
1164 std::string dim_str = ""; | |
1165 std::stringstream ss; | |
1166 long dim = dims.length (); | |
1167 | |
1168 first_param_space = (first_param_space >= 1 ? first_param_space : 1); | |
1169 | |
1170 // Preparing dimension string. | |
1171 | |
1172 if ((dim <= print_dims || print_dims < 0) && print_dims != 0) | |
1173 { | |
1174 // Dimensions string must be printed like this: 2x3x4x2. | |
1175 | |
1176 if (dim == 0 || dim == 1) | |
1177 first_param_space = 1; // First parameter is 1. | |
1178 else | |
1179 { | |
1180 ss << dims (0); | |
1181 | |
1182 dim_str = ss.str (); | |
1183 first_param_space = dim_str.length (); | |
1184 } | |
1185 } | |
1186 else | |
1187 { | |
1188 // Printing dimension string as: a-D. | |
1189 | |
1190 ss << dim; | |
1191 | |
1192 dim_str = ss.str (); | |
1193 first_param_space = dim_str.length (); | |
1194 } | |
1195 | |
1196 return first_param_space; | |
1197 } | |
1198 | |
1199 // Make the dimensions-string. For example: mat is a 2x3 matrix. | |
1200 // ^^^ | |
1201 // | |
1202 // FIXME -- why not just use the dim_vector::str () method? | |
1203 | |
1204 std::string | |
1205 make_dimensions_string (const dim_vector& dims, int print_dims) | |
1206 { | |
1207 // Calculating dimensions. | |
1208 | |
1209 std::string dim_str = ""; | |
1210 std::stringstream ss; | |
1211 long dim = dims.length (); | |
1212 | |
1213 // Preparing dimension string. | |
1214 | |
1215 if ((dim <= print_dims || print_dims < 0) && print_dims != 0) | |
1216 { | |
1217 // Only printing the dimension string as: axbxc... | |
1218 | |
1219 if (dim == 0) | |
1220 ss << "1x1"; | |
1221 else | |
1222 { | |
1223 for (int i = 0; i < dim; i++) | |
1224 { | |
1225 if (i == 0) | |
1226 { | |
1227 if (dim == 1) | |
1228 { | |
1229 // Looks like this is not going to happen in | |
1230 // Octave, but ... | |
1231 | |
1232 ss << "1x" << dims (i); | |
1233 } | |
1234 else | |
1235 ss << dims (i); | |
1236 } | |
1237 else if (i < dim && dim != 1) | |
1238 ss << "x" << dims (i); | |
1239 } | |
1240 } | |
1241 } | |
1242 else | |
1243 { | |
1244 // Printing dimension string as: a-D. | |
1245 | |
1246 ss << dim << "-D"; | |
1247 } | |
1248 | |
1249 dim_str = ss.str (); | |
1250 | |
1251 return dim_str; | |
1252 } | |
1253 | |
1254 // Calculate how much space needs to be reserved for the | |
1255 // dimensions string. For example, | |
1256 // | |
1257 // mat is a 12x3 matrix | |
1258 // ^^^^ => 4 columns | |
1259 // | |
1260 // FIXME -- why not just use the dim_vector::str () method? | |
1261 | |
1262 static int | |
1263 dimensions_string_req_total_space (const dim_vector& dims, int print_dims) | |
1264 { | |
1265 std::string dim_str = ""; | |
1266 std::stringstream ss; | |
1267 | |
1268 ss << make_dimensions_string (dims, print_dims); | |
1269 dim_str = ss.str (); | |
1270 | |
1271 return dim_str.length (); | |
1272 } | |
1273 | |
1274 static std::list<whos_parameter> | |
1275 parse_whos_line_format (const std::list<symbol_table::symbol_record>& symbols) | |
1276 { | |
1277 // This method parses the string whos_line_format, and returns | |
1278 // a parameter list, containing all information needed to print | |
1279 // the given attributtes of the symbols | |
1280 int idx; | |
1281 size_t format_len = Vwhos_line_format.length (); | |
1282 char garbage; | |
1283 std::list<whos_parameter> params; | |
1284 | |
1285 size_t bytes1; | |
1286 int elements1; | |
1287 | |
1288 std::string param_string = "abcenst"; | |
1289 Array<int> param_length (dim_vector (param_string.length (), 1)); | |
1290 Array<std::string> param_names (dim_vector (param_string.length (), 1)); | |
1291 size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t; | |
1292 | |
1293 pos_a = param_string.find ('a'); // Attributes | |
1294 pos_b = param_string.find ('b'); // Bytes | |
1295 pos_c = param_string.find ('c'); // Class | |
1296 pos_e = param_string.find ('e'); // Elements | |
1297 pos_n = param_string.find ('n'); // Name | |
1298 pos_s = param_string.find ('s'); // Size | |
1299 pos_t = param_string.find ('t'); // Type | |
1300 | |
1301 param_names(pos_a) = "Attr"; | |
1302 param_names(pos_b) = "Bytes"; | |
1303 param_names(pos_c) = "Class"; | |
1304 param_names(pos_e) = "Elements"; | |
1305 param_names(pos_n) = "Name"; | |
1306 param_names(pos_s) = "Size"; | |
1307 param_names(pos_t) = "Type"; | |
1308 | |
1309 for (size_t i = 0; i < param_string.length (); i++) | |
1310 param_length(i) = param_names(i) . length (); | |
1311 | |
1312 // Calculating necessary spacing for name column, | |
1313 // bytes column, elements column and class column | |
1314 | |
1315 for (std::list<symbol_table::symbol_record>::const_iterator p = symbols.begin (); | |
1316 p != symbols.end (); p++) | |
1317 { | |
1318 std::stringstream ss1, ss2; | |
1319 std::string str; | |
1320 | |
1321 str = p->name (); | |
1322 param_length(pos_n) = ((str.length () | |
1323 > static_cast<size_t> (param_length(pos_n))) | |
1324 ? str.length () : param_length(pos_n)); | |
1325 | |
1326 octave_value val = p->varval (); | |
1327 | |
1328 str = val.type_name (); | |
1329 param_length(pos_t) = ((str.length () | |
1330 > static_cast<size_t> (param_length(pos_t))) | |
1331 ? str.length () : param_length(pos_t)); | |
1332 | |
1333 elements1 = val.capacity (); | |
1334 ss1 << elements1; | |
1335 str = ss1.str (); | |
1336 param_length(pos_e) = ((str.length () | |
1337 > static_cast<size_t> (param_length(pos_e))) | |
1338 ? str.length () : param_length(pos_e)); | |
1339 | |
1340 bytes1 = val.byte_size (); | |
1341 ss2 << bytes1; | |
1342 str = ss2.str (); | |
1343 param_length(pos_b) = ((str.length () | |
1344 > static_cast<size_t> (param_length(pos_b))) | |
1345 ? str.length () : param_length (pos_b)); | |
1346 } | |
1347 | |
1348 idx = 0; | |
1349 while (static_cast<size_t> (idx) < format_len) | |
1350 { | |
1351 whos_parameter param; | |
1352 param.command = '\0'; | |
1353 | |
1354 if (Vwhos_line_format[idx] == '%') | |
1355 { | |
1356 bool error_encountered = false; | |
1357 param.modifier = 'r'; | |
1358 param.parameter_length = 0; | |
1359 param.dimensions = 8; | |
1360 | |
1361 int a = 0, b = -1, c = 8, balance = 1; | |
1362 unsigned int items; | |
1363 size_t pos; | |
1364 std::string cmd; | |
1365 | |
1366 // Parse one command from whos_line_format | |
1367 cmd = Vwhos_line_format.substr (idx, Vwhos_line_format.length ()); | |
1368 pos = cmd.find (';'); | |
1369 if (pos != NPOS) | |
1370 cmd = cmd.substr (0, pos+1); | |
1371 else | |
1372 error ("parameter without ; in whos_line_format"); | |
1373 | |
1374 idx += cmd.length (); | |
1375 | |
1376 // FIXME -- use iostream functions instead of sscanf! | |
1377 | |
1378 if (cmd.find_first_of ("crl") != 1) | |
1379 items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d:%d;", | |
1380 &garbage, ¶m.command, &a, &b, &c, &balance); | |
1381 else | |
1382 items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d:%d;", | |
1383 &garbage, ¶m.modifier, ¶m.command, | |
1384 &a, &b, &c, &balance) - 1; | |
1385 | |
1386 if (items < 2) | |
1387 { | |
1388 error ("whos_line_format: parameter structure without command in whos_line_format"); | |
1389 error_encountered = true; | |
1390 } | |
1391 | |
1392 // Insert data into parameter | |
1393 param.first_parameter_length = 0; | |
1394 pos = param_string.find (param.command); | |
1395 if (pos != NPOS) | |
1396 { | |
1397 param.parameter_length = param_length(pos); | |
1398 param.text = param_names(pos); | |
1399 param.line.assign (param_names(pos).length (), '='); | |
1400 | |
1401 param.parameter_length = (a > param.parameter_length | |
1402 ? a : param.parameter_length); | |
1403 if (param.command == 's' && param.modifier == 'c' && b > 0) | |
1404 param.first_parameter_length = b; | |
1405 } | |
1406 else | |
1407 { | |
1408 error ("whos_line_format: '%c' is not a command", | |
1409 param.command); | |
1410 error_encountered = true; | |
1411 } | |
1412 | |
1413 if (param.command == 's') | |
1414 { | |
1415 // Have to calculate space needed for printing matrix dimensions | |
1416 // Space needed for Size column is hard to determine in prior, | |
1417 // because it depends on dimensions to be shown. That is why it is | |
1418 // recalculated for each Size-command | |
1419 int first, rest = 0, total; | |
1420 param.dimensions = c; | |
1421 first = param.first_parameter_length; | |
1422 total = param.parameter_length; | |
1423 | |
1424 for (std::list<symbol_table::symbol_record>::const_iterator p = symbols.begin (); | |
1425 p != symbols.end (); p++) | |
1426 { | |
1427 octave_value val = p->varval (); | |
1428 dim_vector dims = val.dims (); | |
1429 int first1 = dimensions_string_req_first_space (dims, param.dimensions); | |
1430 int total1 = dimensions_string_req_total_space (dims, param.dimensions); | |
1431 int rest1 = total1 - first1; | |
1432 rest = (rest1 > rest ? rest1 : rest); | |
1433 first = (first1 > first ? first1 : first); | |
1434 total = (total1 > total ? total1 : total); | |
1435 } | |
1436 | |
1437 if (param.modifier == 'c') | |
1438 { | |
1439 if (first < balance) | |
1440 first += balance - first; | |
1441 if (rest + balance < param.parameter_length) | |
1442 rest += param.parameter_length - rest - balance; | |
1443 | |
1444 param.parameter_length = first + rest; | |
1445 param.first_parameter_length = first; | |
1446 param.balance = balance; | |
1447 } | |
1448 else | |
1449 { | |
1450 param.parameter_length = total; | |
1451 param.first_parameter_length = 0; | |
1452 } | |
1453 } | |
1454 else if (param.modifier == 'c') | |
1455 { | |
1456 error ("whos_line_format: modifier 'c' not available for command '%c'", | |
1457 param.command); | |
1458 error_encountered = true; | |
1459 } | |
1460 | |
1461 // What happens if whos_line_format contains negative numbers | |
1462 // at param_length positions? | |
1463 param.balance = (b < 0 ? 0 : param.balance); | |
1464 param.first_parameter_length = (b < 0 ? 0 : | |
1465 param.first_parameter_length); | |
1466 param.parameter_length = (a < 0 | |
1467 ? 0 | |
1468 : (param.parameter_length | |
1469 < param_length(pos_s) | |
1470 ? param_length(pos_s) | |
1471 : param.parameter_length)); | |
1472 | |
1473 // Parameter will not be pushed into parameter list if ... | |
1474 if (! error_encountered) | |
1475 params.push_back (param); | |
1476 } | |
1477 else | |
1478 { | |
1479 // Text string, to be printed as it is ... | |
1480 std::string text; | |
1481 size_t pos; | |
1482 text = Vwhos_line_format.substr (idx, Vwhos_line_format.length ()); | |
1483 pos = text.find ('%'); | |
1484 if (pos != NPOS) | |
1485 text = text.substr (0, pos); | |
1486 | |
1487 // Push parameter into list ... | |
1488 idx += text.length (); | |
1489 param.text=text; | |
1490 param.line.assign (text.length(), ' '); | |
1491 params.push_back (param); | |
1492 } | |
1493 } | |
1494 | |
1495 return params; | |
1496 } | |
1423 | 1497 |
1424 void | 1498 void |
1425 link_to_global_variable (symbol_record *sr) | 1499 print_symbol_info_line (std::ostream& os, |
1426 { | 1500 const symbol_table::symbol_record& sr, |
1427 if (! sr->is_linked_to_global ()) | 1501 std::list<whos_parameter>& params) |
1428 { | 1502 { |
1429 sr->mark_as_linked_to_global (); | 1503 octave_value val = sr.varval (); |
1430 | 1504 dim_vector dims = val.dims (); |
1431 if (! error_state) | 1505 |
1432 { | 1506 std::list<whos_parameter>::iterator i = params.begin (); |
1433 std::string nm = sr->name (); | 1507 |
1434 | 1508 while (i != params.end ()) |
1435 symbol_record *gsr = global_sym_tab->lookup (nm, true); | 1509 { |
1436 | 1510 whos_parameter param = *i; |
1437 // Make sure this symbol is a variable. | 1511 |
1438 | 1512 if (param.command != '\0') |
1439 if (! gsr->is_user_variable ()) | 1513 { |
1440 gsr->define (octave_value ()); | 1514 // Do the actual printing. |
1441 | 1515 |
1442 sr->alias (gsr); | 1516 switch (param.modifier) |
1443 } | 1517 { |
1444 } | 1518 case 'l': |
1445 } | 1519 os << std::setiosflags (std::ios::left) |
1446 | 1520 << std::setw (param.parameter_length); |
1447 // Make the definition of the symbol record sr be the same as the | 1521 break; |
1448 // definition of the builtin variable of the same name. | 1522 |
1449 | 1523 case 'r': |
1450 // Make the definition of the symbol record sr be the same as the | 1524 os << std::setiosflags (std::ios::right) |
1451 // definition of the builtin function, or user function of the same | 1525 << std::setw (param.parameter_length); |
1452 // name, provided that the name has not been used as a formal parameter. | 1526 break; |
1453 | 1527 |
1454 void | 1528 case 'c': |
1455 link_to_builtin_or_function (symbol_record *sr) | 1529 if (param.command == 's') |
1456 { | 1530 { |
1457 std::string nm = sr->name (); | 1531 int front = param.first_parameter_length |
1458 | 1532 - dimensions_string_req_first_space (dims, param.dimensions); |
1459 symbol_record *tmp_sym = 0; | 1533 int back = param.parameter_length |
1460 | 1534 - dimensions_string_req_total_space (dims, param.dimensions) |
1461 octave_function *fcn = octave_call_stack::current (); | 1535 - front; |
1462 | 1536 front = (front > 0) ? front : 0; |
1463 std::string parent = fcn ? fcn->parent_fcn_name () : std::string (); | 1537 back = (back > 0) ? back : 0; |
1464 | 1538 |
1465 if (! parent.empty ()) | 1539 os << std::setiosflags (std::ios::left) |
1466 tmp_sym = fbi_sym_tab->lookup (parent + ":" + nm); | 1540 << std::setw (front) |
1467 | 1541 << "" |
1468 if (! tmp_sym && curr_parent_function) | 1542 << std::resetiosflags (std::ios::left) |
1469 tmp_sym = fbi_sym_tab->lookup (curr_parent_function->name () + ":" + nm); | 1543 << make_dimensions_string (dims, param.dimensions) |
1470 | 1544 << std::setiosflags (std::ios::left) |
1471 if (! tmp_sym) | 1545 << std::setw (back) |
1472 tmp_sym = fbi_sym_tab->lookup (nm); | 1546 << "" |
1473 | 1547 << std::resetiosflags (std::ios::left); |
1474 if (tmp_sym | 1548 } |
1475 && tmp_sym->is_function () | 1549 else |
1476 && ! tmp_sym->is_formal_parameter ()) | 1550 { |
1477 sr->alias (tmp_sym); | 1551 os << std::setiosflags (std::ios::left) |
1478 } | 1552 << std::setw (param.parameter_length); |
1479 | 1553 } |
1480 // Force a link to a function in the current symbol table. This is | 1554 break; |
1481 // used just after defining a function to avoid different behavior | 1555 |
1482 // depending on whether or not the function has been evaluated after | 1556 default: |
1483 // being defined. | 1557 error ("whos_line_format: modifier `%c' unknown", |
1484 // | 1558 param.modifier); |
1485 // Return without doing anything if there isn't a function with the | 1559 |
1486 // given name defined in the global symbol table. | 1560 os << std::setiosflags (std::ios::right) |
1487 | 1561 << std::setw (param.parameter_length); |
1488 void | 1562 } |
1489 force_link_to_function (const std::string& id_name) | 1563 |
1490 { | 1564 switch (param.command) |
1491 symbol_record *fsr = fbi_sym_tab->lookup (id_name, true); | 1565 { |
1492 if (fsr->is_function ()) | 1566 case 'a': |
1493 { | 1567 { |
1494 curr_sym_tab->clear (id_name); | 1568 char tmp[5]; |
1495 symbol_record *csr = curr_sym_tab->lookup (id_name, true); | 1569 |
1496 csr->alias (fsr); | 1570 tmp[0] = (sr.is_automatic () ? 'a' : ' '); |
1497 } | 1571 tmp[1] = (sr.is_formal () ? 'f' : ' '); |
1498 } | 1572 tmp[2] = (sr.is_global () ? 'g' : ' '); |
1499 | 1573 tmp[3] = (sr.is_persistent () ? 'p' : ' '); |
1500 DEFUN (document, args, , | 1574 tmp[4] = 0; |
1501 "-*- texinfo -*-\n\ | 1575 |
1502 @deftypefn {Built-in Function} {} document (@var{symbol}, @var{text})\n\ | 1576 os << tmp; |
1503 Set the documentation string for @var{symbol} to @var{text}.\n\ | 1577 } |
1504 @end deftypefn") | 1578 break; |
1579 | |
1580 case 'b': | |
1581 os << val.byte_size (); | |
1582 break; | |
1583 | |
1584 case 'c': | |
1585 os << val.class_name (); | |
1586 break; | |
1587 | |
1588 case 'e': | |
1589 os << val.capacity (); | |
1590 break; | |
1591 | |
1592 case 'n': | |
1593 os << sr.name (); | |
1594 break; | |
1595 | |
1596 case 's': | |
1597 if (param.modifier != 'c') | |
1598 os << make_dimensions_string (dims, param.dimensions); | |
1599 break; | |
1600 | |
1601 case 't': | |
1602 os << val.type_name (); | |
1603 break; | |
1604 | |
1605 default: | |
1606 error ("whos_line_format: command `%c' unknown", param.command); | |
1607 } | |
1608 | |
1609 os << std::resetiosflags (std::ios::left) | |
1610 << std::resetiosflags (std::ios::right); | |
1611 i++; | |
1612 } | |
1613 else | |
1614 { | |
1615 os << param.text; | |
1616 i++; | |
1617 } | |
1618 } | |
1619 } | |
1620 | |
1621 static octave_value | |
1622 do_who (int argc, const string_vector& argv, bool return_list, | |
1623 bool verbose = false) | |
1505 { | 1624 { |
1506 octave_value retval; | 1625 octave_value retval; |
1507 | 1626 |
1508 int nargin = args.length (); | |
1509 | |
1510 if (nargin == 2) | |
1511 { | |
1512 std::string name = args(0).string_value (); | |
1513 | |
1514 if (! error_state) | |
1515 { | |
1516 std::string help = args(1).string_value (); | |
1517 | |
1518 if (! error_state) | |
1519 { | |
1520 if (is_command_name (name) | |
1521 || is_mapper_function_name (name) | |
1522 || is_builtin_function_name (name)) | |
1523 error ("document: can't redefine help for built-in functions"); | |
1524 else | |
1525 { | |
1526 symbol_record *sym_rec = curr_sym_tab->lookup (name); | |
1527 | |
1528 if (sym_rec) | |
1529 sym_rec->document (help); | |
1530 else | |
1531 error ("document: no such symbol `%s'", name.c_str ()); | |
1532 } | |
1533 } | |
1534 } | |
1535 } | |
1536 else | |
1537 print_usage (); | |
1538 | |
1539 return retval; | |
1540 } | |
1541 | |
1542 // FIXME -- this function is duplicated in symtab.cc with the | |
1543 // name maybe_list_cmp_fcn. | |
1544 | |
1545 static int | |
1546 symbol_record_name_compare (const void *a_arg, const void *b_arg) | |
1547 { | |
1548 const symbol_record *a = *(static_cast<symbol_record *const*> (a_arg)); | |
1549 const symbol_record *b = *(static_cast<symbol_record *const*> (b_arg)); | |
1550 | |
1551 std::string a_nm = a->name (); | |
1552 std::string b_nm = b->name (); | |
1553 | |
1554 return a_nm.compare (b_nm); | |
1555 } | |
1556 | |
1557 static octave_value | |
1558 do_who (int argc, const string_vector& argv, int return_list) | |
1559 { | |
1560 octave_value retval; | |
1561 | |
1562 bool show_builtins = false; | |
1563 bool show_functions = false; | |
1564 bool show_variables = false; | |
1565 bool show_verbose = false; | |
1566 | |
1567 std::string my_name = argv[0]; | 1627 std::string my_name = argv[0]; |
1628 | |
1629 bool global_only = false; | |
1568 | 1630 |
1569 int i; | 1631 int i; |
1570 for (i = 1; i < argc; i++) | 1632 for (i = 1; i < argc; i++) |
1571 { | 1633 { |
1572 if (argv[i] == "-all" || argv[i] == "-a") | 1634 if (argv[i] == "-regexp" || argv[i] == "-file") |
1573 { | 1635 { |
1574 show_builtins = true; | 1636 error ("%s: `%s' option not implemented", my_name.c_str (), |
1575 show_functions = true; | 1637 argv[i].c_str ()); |
1576 show_variables = true; | 1638 |
1577 } | 1639 return retval; |
1578 else if (argv[i] == "-builtins" || argv[i] == "-b") | 1640 } |
1579 show_builtins = true; | 1641 else if (argv[i] == "global") |
1580 else if (argv[i] == "-functions" || argv[i] == "-f") | 1642 global_only = true; |
1581 show_functions = true; | |
1582 else if (argv[i] == "-long" || argv[i] == "-l") | |
1583 show_verbose = true; | |
1584 else if (argv[i] == "-variables" || argv[i] == "-v") | |
1585 show_variables = true; | |
1586 else if (argv[i][0] == '-') | 1643 else if (argv[i][0] == '-') |
1587 warning ("%s: unrecognized option `%s'", my_name.c_str (), | 1644 warning ("%s: unrecognized option `%s'", my_name.c_str (), |
1588 argv[i].c_str ()); | 1645 argv[i].c_str ()); |
1589 else | 1646 else |
1590 break; | 1647 break; |
1591 } | 1648 } |
1592 | 1649 |
1593 // If no options were specified to select the type of symbol to | |
1594 // display, then set defaults. | |
1595 | |
1596 if (! (show_builtins || show_functions || show_variables)) | |
1597 { | |
1598 show_functions = at_top_level (); | |
1599 show_variables = true; | |
1600 } | |
1601 | |
1602 int npats = argc - i; | 1650 int npats = argc - i; |
1603 string_vector pats (npats); | 1651 string_vector pats (npats > 0 ? npats : 1); |
1604 for (int j = 0; j < npats; j++) | 1652 if (npats > 0) |
1605 pats[j] = argv[i+j]; | 1653 { |
1606 | 1654 for (int j = 0; j < npats; j++) |
1607 // If the user specified -l and nothing else, show variables. If | 1655 pats[j] = argv[i+j]; |
1608 // evaluating this at the top level, also show functions. | 1656 } |
1609 | 1657 else |
1610 if (show_verbose && ! (show_builtins || show_functions || show_variables)) | 1658 pats[0] = "*"; |
1611 { | 1659 |
1612 show_functions = at_top_level (); | 1660 symbol_table::scope_id scope = global_only |
1613 show_variables = 1; | 1661 ? symbol_table::global_scope () : symbol_table::current_scope (); |
1614 } | 1662 |
1663 std::list<symbol_table::symbol_record> symbols | |
1664 = symbol_table::glob_variables (pats, scope); | |
1665 | |
1666 size_t symbols_len = symbols.size (); | |
1615 | 1667 |
1616 if (return_list) | 1668 if (return_list) |
1617 { | 1669 { |
1618 // FIXME -- maybe symbol_list should return a std::list | 1670 if (verbose) |
1619 // object instead of an Array. | |
1620 | |
1621 dim_vector dv (0, 0); | |
1622 | |
1623 Array<symbol_record *> s3 (dv); | |
1624 Array<symbol_record *> s4 (dv); | |
1625 Array<symbol_record *> s5 (dv); | |
1626 Array<symbol_record *> s6 (dv); | |
1627 Array<symbol_record *> s7 (dv); | |
1628 Array<symbol_record *> s8 (dv); | |
1629 | |
1630 if (show_builtins) | |
1631 { | |
1632 s3 = fbi_sym_tab->symbol_list (pats, symbol_record::BUILTIN_FUNCTION, | |
1633 SYMTAB_ALL_SCOPES); | |
1634 } | |
1635 | |
1636 if (show_functions) | |
1637 { | |
1638 s4 = fbi_sym_tab->symbol_list (pats, symbol_record::DLD_FUNCTION, | |
1639 SYMTAB_ALL_SCOPES); | |
1640 | |
1641 s5 = fbi_sym_tab->symbol_list (pats, symbol_record::USER_FUNCTION, | |
1642 SYMTAB_ALL_SCOPES); | |
1643 | |
1644 s6 = fbi_sym_tab->symbol_list (pats, symbol_record::MEX_FUNCTION, | |
1645 SYMTAB_ALL_SCOPES); | |
1646 } | |
1647 | |
1648 if (show_variables) | |
1649 { | |
1650 s7 = curr_sym_tab->symbol_list (pats, symbol_record::USER_VARIABLE, | |
1651 SYMTAB_LOCAL_SCOPE); | |
1652 | |
1653 s8 = curr_sym_tab->symbol_list (pats, symbol_record::USER_VARIABLE, | |
1654 SYMTAB_GLOBAL_SCOPE); | |
1655 } | |
1656 | |
1657 octave_idx_type s3_len = s3.length (); | |
1658 octave_idx_type s4_len = s4.length (); | |
1659 octave_idx_type s5_len = s5.length (); | |
1660 octave_idx_type s6_len = s6.length (); | |
1661 octave_idx_type s7_len = s7.length (); | |
1662 octave_idx_type s8_len = s8.length (); | |
1663 | |
1664 octave_idx_type symbols_len | |
1665 = s3_len + s4_len + s5_len + s6_len + s7_len + s8_len; | |
1666 | |
1667 Array<symbol_record *> symbols (dim_vector (symbols_len, 1)); | |
1668 | |
1669 octave_idx_type k = 0; | |
1670 | |
1671 symbols.insert (s3, k, 0); | |
1672 k += s3_len; | |
1673 symbols.insert (s4, k, 0); | |
1674 k += s4_len; | |
1675 symbols.insert (s5, k, 0); | |
1676 k += s5_len; | |
1677 symbols.insert (s6, k, 0); | |
1678 k += s6_len; | |
1679 symbols.insert (s7, k, 0); | |
1680 k += s7_len; | |
1681 symbols.insert (s8, k, 0); | |
1682 | |
1683 symbols.qsort (symbol_record_name_compare); | |
1684 | |
1685 if (show_verbose) | |
1686 { | 1671 { |
1687 Array<octave_value> name_info (symbols_len, 1); | 1672 Array<octave_value> name_info (symbols_len, 1); |
1688 Array<octave_value> size_info (symbols_len, 1); | 1673 Array<octave_value> size_info (symbols_len, 1); |
1689 Array<octave_value> bytes_info (symbols_len, 1); | 1674 Array<octave_value> bytes_info (symbols_len, 1); |
1690 Array<octave_value> class_info (symbols_len, 1); | 1675 Array<octave_value> class_info (symbols_len, 1); |
1691 Array<octave_value> global_info (symbols_len, 1); | 1676 Array<octave_value> global_info (symbols_len, 1); |
1692 Array<octave_value> sparse_info (symbols_len, 1); | 1677 Array<octave_value> sparse_info (symbols_len, 1); |
1693 Array<octave_value> complex_info (symbols_len, 1); | 1678 Array<octave_value> complex_info (symbols_len, 1); |
1694 Array<octave_value> nesting_info (symbols_len, 1); | 1679 Array<octave_value> nesting_info (symbols_len, 1); |
1695 | 1680 |
1696 for (octave_idx_type j = 0; j < symbols_len; j++) | 1681 std::list<symbol_table::symbol_record>::const_iterator p |
1697 { | 1682 = symbols.begin (); |
1698 symbol_record *sr = symbols(j); | 1683 |
1684 for (size_t j = 0; j < symbols_len; j++) | |
1685 { | |
1686 const symbol_table::symbol_record& sr = *p++; | |
1699 | 1687 |
1700 Octave_map ni; | 1688 Octave_map ni; |
1701 | 1689 |
1702 std::string caller_function_name; | 1690 std::string caller_function_name; |
1703 | 1691 |
1706 caller_function_name = caller->name (); | 1694 caller_function_name = caller->name (); |
1707 | 1695 |
1708 ni.assign ("function", caller_function_name); | 1696 ni.assign ("function", caller_function_name); |
1709 ni.assign ("level", 1); | 1697 ni.assign ("level", 1); |
1710 | 1698 |
1711 name_info(j) = sr->name (); | 1699 name_info(j) = sr.name (); |
1712 size_info(j) = sr->size (); | 1700 global_info(j) = sr.is_global (); |
1713 bytes_info(j) = sr->byte_size (); | 1701 |
1714 class_info(j) = sr->class_name (); | 1702 octave_value val = sr.varval (); |
1715 global_info(j) = sr->is_linked_to_global (); | 1703 |
1716 sparse_info(j) = sr->is_sparse_type (); | 1704 size_info(j) = val.size (); |
1717 complex_info(j) = sr->is_complex_type (); | 1705 bytes_info(j) = val.byte_size (); |
1706 class_info(j) = val.class_name (); | |
1707 sparse_info(j) = val.is_sparse_type (); | |
1708 complex_info(j) = val.is_complex_type (); | |
1718 nesting_info(j) = ni; | 1709 nesting_info(j) = ni; |
1719 } | 1710 } |
1720 | 1711 |
1721 Octave_map info; | 1712 Octave_map info; |
1722 | 1713 |
1737 | 1728 |
1738 if (symbols_len > 0) | 1729 if (symbols_len > 0) |
1739 { | 1730 { |
1740 names.resize (symbols_len); | 1731 names.resize (symbols_len); |
1741 | 1732 |
1742 for (octave_idx_type j = 0; j < symbols_len; j++) | 1733 std::list<symbol_table::symbol_record>::const_iterator p |
1743 names[j] = symbols(j)->name (); | 1734 = symbols.begin (); |
1735 | |
1736 for (size_t j = 0; j < symbols_len; j++) | |
1737 { | |
1738 names[j] = p->name (); | |
1739 p++; | |
1740 } | |
1744 } | 1741 } |
1745 | 1742 |
1746 retval = Cell (names); | 1743 retval = Cell (names); |
1747 } | 1744 } |
1748 } | 1745 } |
1749 else | 1746 else if (symbols_len > 0) |
1750 { | 1747 { |
1751 int pad_after = 0; | 1748 if (global_only) |
1752 | 1749 octave_stdout << "Global variables:\n\n"; |
1753 if (show_builtins) | 1750 else |
1754 { | 1751 octave_stdout << "Variables in the current scope:\n\n"; |
1755 pad_after += fbi_sym_tab->maybe_list | 1752 |
1756 ("*** built-in functions:", pats, octave_stdout, | 1753 if (verbose) |
1757 show_verbose, symbol_record::BUILTIN_FUNCTION, SYMTAB_ALL_SCOPES); | 1754 { |
1758 } | 1755 size_t bytes = 0; |
1759 | 1756 size_t elements = 0; |
1760 if (show_functions) | 1757 |
1761 { | 1758 std::list<whos_parameter> params; |
1762 pad_after += fbi_sym_tab->maybe_list | 1759 |
1763 ("*** dynamically linked functions:", pats, | 1760 params = parse_whos_line_format (symbols); |
1764 octave_stdout, show_verbose, symbol_record::DLD_FUNCTION, | 1761 |
1765 SYMTAB_ALL_SCOPES); | 1762 print_descriptor (octave_stdout, params); |
1766 | 1763 |
1767 pad_after += fbi_sym_tab->maybe_list | 1764 octave_stdout << "\n"; |
1768 ("*** currently compiled functions:", pats, | 1765 |
1769 octave_stdout, show_verbose, symbol_record::USER_FUNCTION, | 1766 for (std::list<symbol_table::symbol_record>::const_iterator p = symbols.begin (); |
1770 SYMTAB_ALL_SCOPES); | 1767 p != symbols.end (); p++) |
1771 | 1768 { |
1772 pad_after += fbi_sym_tab->maybe_list | 1769 print_symbol_info_line (octave_stdout, *p, params); |
1773 ("*** mex functions:", pats, | 1770 octave_value val = p->varval (); |
1774 octave_stdout, show_verbose, symbol_record::MEX_FUNCTION, | 1771 elements += val.capacity (); |
1775 SYMTAB_ALL_SCOPES); | 1772 bytes += val.byte_size (); |
1776 } | 1773 } |
1777 | 1774 |
1778 if (show_variables) | 1775 octave_stdout << "\nTotal is " << elements |
1779 { | 1776 << (elements == 1 ? " element" : " elements") |
1780 pad_after += curr_sym_tab->maybe_list | 1777 << " using " << bytes |
1781 ("*** local user variables:", pats, octave_stdout, | 1778 << (bytes == 1 ? " byte" : " bytes") << "\n"; |
1782 show_verbose, symbol_record::USER_VARIABLE, SYMTAB_LOCAL_SCOPE); | 1779 } |
1783 | 1780 else |
1784 pad_after += curr_sym_tab->maybe_list | 1781 { |
1785 ("*** globally visible user variables:", pats, | 1782 string_vector names (symbols_len); |
1786 octave_stdout, show_verbose, symbol_record::USER_VARIABLE, | 1783 |
1787 SYMTAB_GLOBAL_SCOPE); | 1784 std::list<symbol_table::symbol_record>::const_iterator p |
1788 } | 1785 = symbols.begin (); |
1789 | 1786 |
1790 if (pad_after) | 1787 for (size_t j = 0; j < symbols_len; j++) |
1791 octave_stdout << "\n"; | 1788 { |
1789 names[j] = p->name (); | |
1790 p++; | |
1791 } | |
1792 | |
1793 names.list_in_columns (octave_stdout); | |
1794 } | |
1795 | |
1796 octave_stdout << "\n"; | |
1792 } | 1797 } |
1793 | 1798 |
1794 return retval; | 1799 return retval; |
1795 } | 1800 } |
1796 | 1801 |
1838 { | 1843 { |
1839 int argc = args.length () + 1; | 1844 int argc = args.length () + 1; |
1840 | 1845 |
1841 string_vector argv = args.make_argv ("who"); | 1846 string_vector argv = args.make_argv ("who"); |
1842 | 1847 |
1843 if (error_state) | 1848 if (! error_state) |
1844 return retval; | 1849 retval = do_who (argc, argv, nargout == 1); |
1845 | |
1846 retval = do_who (argc, argv, nargout == 1); | |
1847 } | 1850 } |
1848 else | 1851 else |
1849 print_usage (); | 1852 print_usage (); |
1850 | 1853 |
1851 return retval; | 1854 return retval; |
1859 { | 1862 { |
1860 octave_value retval; | 1863 octave_value retval; |
1861 | 1864 |
1862 if (nargout < 2) | 1865 if (nargout < 2) |
1863 { | 1866 { |
1864 int nargin = args.length (); | 1867 int argc = args.length () + 1; |
1865 | 1868 |
1866 octave_value_list tmp_args; | 1869 string_vector argv = args.make_argv ("whos"); |
1867 | 1870 |
1868 for (int i = nargin; i > 0; i--) | 1871 if (! error_state) |
1869 tmp_args(i) = args(i-1); | 1872 retval = do_who (argc, argv, nargout == 1, true); |
1870 | |
1871 tmp_args(0) = "-long"; | |
1872 | |
1873 int argc = tmp_args.length () + 1; | |
1874 | |
1875 string_vector argv = tmp_args.make_argv ("whos"); | |
1876 | |
1877 if (error_state) | |
1878 return retval; | |
1879 | |
1880 retval = do_who (argc, argv, nargout == 1); | |
1881 } | 1873 } |
1882 else | 1874 else |
1883 print_usage (); | 1875 print_usage (); |
1884 | 1876 |
1885 return retval; | 1877 return retval; |
1888 // Defining variables. | 1880 // Defining variables. |
1889 | 1881 |
1890 void | 1882 void |
1891 bind_ans (const octave_value& val, bool print) | 1883 bind_ans (const octave_value& val, bool print) |
1892 { | 1884 { |
1893 symbol_record *sr = curr_sym_tab->lookup ("ans", true); | 1885 static std::string ans = "ans"; |
1894 | 1886 |
1895 if (val.is_defined ()) | 1887 if (val.is_defined ()) |
1896 { | 1888 { |
1897 sr->define (val); | 1889 symbol_table::varref (ans) = val; |
1898 | 1890 |
1899 if (print) | 1891 if (print) |
1900 val.print_with_name (octave_stdout, "ans"); | 1892 val.print_with_name (octave_stdout, ans); |
1901 } | 1893 } |
1902 } | 1894 } |
1903 | 1895 |
1904 void | 1896 void |
1905 bind_internal_variable (const std::string& fname, const octave_value& val) | 1897 bind_internal_variable (const std::string& fname, const octave_value& val) |
1910 | 1902 |
1911 feval (fname, args, 0); | 1903 feval (fname, args, 0); |
1912 } | 1904 } |
1913 | 1905 |
1914 void | 1906 void |
1915 mlock (const std::string& nm) | 1907 mlock (void) |
1916 { | 1908 { |
1917 symbol_record *sr = fbi_sym_tab->lookup (nm, true); | 1909 octave_function *fcn = octave_call_stack::caller (); |
1918 | 1910 |
1919 if (sr) | 1911 if (fcn) |
1920 sr->mark_as_static (); | 1912 fcn->lock (); |
1913 else | |
1914 error ("mlock: invalid use outside a function"); | |
1921 } | 1915 } |
1922 | 1916 |
1923 void | 1917 void |
1924 munlock (const std::string& nm) | 1918 munlock (const std::string& nm) |
1925 { | 1919 { |
1926 symbol_record *sr = fbi_sym_tab->lookup (nm); | 1920 octave_value val = symbol_table::find_function (nm); |
1927 | 1921 |
1928 if (sr && sr->is_static ()) | 1922 if (val.is_defined ()) |
1929 sr->unmark_static (); | 1923 { |
1930 else | 1924 octave_function *fcn = val.function_value (); |
1931 error ("munlock: %s is not locked", nm.c_str ()); | 1925 |
1926 if (fcn) | |
1927 fcn->unlock (); | |
1928 } | |
1932 } | 1929 } |
1933 | 1930 |
1934 bool | 1931 bool |
1935 mislocked (const std::string& nm) | 1932 mislocked (const std::string& nm) |
1936 { | 1933 { |
1937 symbol_record *sr = fbi_sym_tab->lookup (nm); | 1934 bool retval = false; |
1938 | 1935 |
1939 return (sr && sr->is_static ()); | 1936 octave_value val = symbol_table::find_function (nm); |
1937 | |
1938 if (val.is_defined ()) | |
1939 { | |
1940 octave_function *fcn = val.function_value (); | |
1941 | |
1942 if (fcn) | |
1943 retval = fcn->islocked (); | |
1944 } | |
1945 | |
1946 return retval; | |
1940 } | 1947 } |
1941 | 1948 |
1942 DEFCMD (mlock, args, , | 1949 DEFCMD (mlock, args, , |
1943 "-*- texinfo -*-\n\ | 1950 "-*- texinfo -*-\n\ |
1944 @deftypefn {Built-in Function} {} mlock (@var{name})\n\ | 1951 @deftypefn {Built-in Function} {} mlock (@var{name})\n\ |
1945 Lock the named function into memory. If no function is named\n\ | 1952 Lock the current function into memory so that it can't be cleared.\n\ |
1946 then lock in the current function.\n\ | |
1947 @seealso{munlock, mislocked, persistent}\n\ | 1953 @seealso{munlock, mislocked, persistent}\n\ |
1948 @end deftypefn") | 1954 @end deftypefn") |
1949 { | 1955 { |
1950 octave_value_list retval; | 1956 octave_value_list retval; |
1951 | 1957 |
1952 if (args.length () == 1) | 1958 if (args.length () == 0) |
1953 { | 1959 mlock (); |
1954 std::string name = args(0).string_value (); | |
1955 | |
1956 if (! error_state) | |
1957 mlock (name); | |
1958 else | |
1959 error ("mlock: expecting argument to be a function name"); | |
1960 } | |
1961 else if (args.length () == 0) | |
1962 { | |
1963 octave_user_function *fcn = octave_call_stack::caller_user_function (); | |
1964 | |
1965 if (fcn) | |
1966 mlock (fcn->name ()); | |
1967 else | |
1968 error ("mlock: invalid use outside a function"); | |
1969 } | |
1970 else | 1960 else |
1971 print_usage (); | 1961 print_usage (); |
1972 | 1962 |
1973 return retval; | 1963 return retval; |
1974 } | 1964 } |
1992 else | 1982 else |
1993 error ("munlock: expecting argument to be a function name"); | 1983 error ("munlock: expecting argument to be a function name"); |
1994 } | 1984 } |
1995 else if (args.length () == 0) | 1985 else if (args.length () == 0) |
1996 { | 1986 { |
1997 octave_user_function *fcn = octave_call_stack::caller_user_function (); | 1987 octave_function *fcn = octave_call_stack::caller (); |
1998 | 1988 |
1999 if (fcn) | 1989 if (fcn) |
2000 munlock (fcn->name ()); | 1990 fcn->unlock (); |
2001 else | 1991 else |
2002 error ("munlock: invalid use outside a function"); | 1992 error ("munlock: invalid use outside a function"); |
2003 } | 1993 } |
2004 else | 1994 else |
2005 print_usage (); | 1995 print_usage (); |
2027 else | 2017 else |
2028 error ("mislocked: expecting argument to be a function name"); | 2018 error ("mislocked: expecting argument to be a function name"); |
2029 } | 2019 } |
2030 else if (args.length () == 0) | 2020 else if (args.length () == 0) |
2031 { | 2021 { |
2032 octave_user_function *fcn = octave_call_stack::caller_user_function (); | 2022 octave_function *fcn = octave_call_stack::caller (); |
2033 | 2023 |
2034 if (fcn) | 2024 if (fcn) |
2035 retval = mislocked (fcn->name ()); | 2025 retval = fcn->islocked (); |
2036 else | 2026 else |
2037 error ("mislocked: invalid use outside a function"); | 2027 error ("mislocked: invalid use outside a function"); |
2038 } | 2028 } |
2039 else | 2029 else |
2040 print_usage (); | 2030 print_usage (); |
2067 } | 2057 } |
2068 | 2058 |
2069 return retval; | 2059 return retval; |
2070 } | 2060 } |
2071 | 2061 |
2072 static inline bool | |
2073 is_local_variable (const std::string& nm) | |
2074 { | |
2075 symbol_record *sr = curr_sym_tab->lookup (nm); | |
2076 | |
2077 return (sr && sr->is_variable ()); | |
2078 } | |
2079 | |
2080 static inline void | 2062 static inline void |
2081 maybe_warn_exclusive (bool exclusive) | 2063 maybe_warn_exclusive (bool exclusive) |
2082 { | 2064 { |
2083 if (exclusive) | 2065 if (exclusive) |
2084 warning ("clear: ignoring --exclusive option"); | 2066 warning ("clear: ignoring --exclusive option"); |
2085 } | 2067 } |
2086 | 2068 |
2087 static inline void | 2069 static void |
2088 do_clear_all (void) | |
2089 { | |
2090 curr_sym_tab->clear (); | |
2091 fbi_sym_tab->clear_functions (); | |
2092 global_sym_tab->clear (); | |
2093 } | |
2094 | |
2095 static inline void | |
2096 do_clear_functions (void) | |
2097 { | |
2098 curr_sym_tab->clear_functions (); | |
2099 fbi_sym_tab->clear_functions (); | |
2100 } | |
2101 | |
2102 static inline void | |
2103 do_clear_globals (void) | |
2104 { | |
2105 curr_sym_tab->clear_globals (); | |
2106 global_sym_tab->clear (); | |
2107 } | |
2108 | |
2109 static inline void | |
2110 do_clear_variables (void) | |
2111 { | |
2112 curr_sym_tab->clear (); | |
2113 } | |
2114 | |
2115 static inline bool | |
2116 do_clear_function (const std::string& nm) | |
2117 { | |
2118 bool b1 = curr_sym_tab->clear_function (nm); | |
2119 | |
2120 bool b2 = fbi_sym_tab->clear_function (nm); | |
2121 | |
2122 return b1 || b2; | |
2123 } | |
2124 | |
2125 static inline bool | |
2126 do_clear_global (const std::string& nm) | |
2127 { | |
2128 bool b1 = curr_sym_tab->clear_global (nm); | |
2129 | |
2130 bool b2 = global_sym_tab->clear_variable (nm); | |
2131 | |
2132 return b1 || b2; | |
2133 } | |
2134 | |
2135 static inline bool | |
2136 do_clear_variable (const std::string& nm) | |
2137 { | |
2138 return curr_sym_tab->clear_variable (nm); | |
2139 } | |
2140 | |
2141 static inline bool | |
2142 do_clear_symbol (const std::string& nm) | |
2143 { | |
2144 bool cleared = curr_sym_tab->clear_variable (nm); | |
2145 | |
2146 if (! cleared) | |
2147 cleared = do_clear_function (nm); | |
2148 | |
2149 return cleared; | |
2150 } | |
2151 | |
2152 static inline bool | |
2153 do_clear_function_pattern (const std::string& pat) | |
2154 { | |
2155 bool b1 = curr_sym_tab->clear_function_pattern (pat); | |
2156 | |
2157 bool b2 = fbi_sym_tab->clear_function_pattern (pat); | |
2158 | |
2159 return b1 || b2; | |
2160 } | |
2161 | |
2162 static inline bool | |
2163 do_clear_global_pattern (const std::string& pat) | |
2164 { | |
2165 bool b1 = curr_sym_tab->clear_global_pattern (pat); | |
2166 | |
2167 bool b2 = global_sym_tab->clear_variable_pattern (pat); | |
2168 | |
2169 return b1 || b2; | |
2170 } | |
2171 | |
2172 static inline bool | |
2173 do_clear_variable_pattern (const std::string& pat) | |
2174 { | |
2175 return curr_sym_tab->clear_variable_pattern (pat); | |
2176 } | |
2177 | |
2178 static inline bool | |
2179 do_clear_symbol_pattern (const std::string& pat) | |
2180 { | |
2181 // FIXME -- if we have a variable v1 and a function v2 and | |
2182 // someone says clear v*, we will clear the variable but not the | |
2183 // function. Is that really what should happen? (I think it is | |
2184 // what Matlab does.) | |
2185 | |
2186 bool cleared = curr_sym_tab->clear_variable_pattern (pat); | |
2187 | |
2188 if (! cleared) | |
2189 cleared = do_clear_function_pattern (pat); | |
2190 | |
2191 return cleared; | |
2192 } | |
2193 | |
2194 static inline void | |
2195 do_clear_functions (const string_vector& argv, int argc, int idx, | 2070 do_clear_functions (const string_vector& argv, int argc, int idx, |
2196 bool exclusive = false) | 2071 bool exclusive = false) |
2197 { | 2072 { |
2198 if (idx == argc) | 2073 if (idx == argc) |
2199 do_clear_functions (); | 2074 symbol_table::clear_functions (); |
2200 else | 2075 else |
2201 { | 2076 { |
2202 if (exclusive) | 2077 if (exclusive) |
2203 { | 2078 { |
2204 string_vector lfcns = curr_sym_tab->user_function_name_list (); | 2079 string_vector fcns = symbol_table::user_function_names (); |
2205 | 2080 |
2206 int lcount = lfcns.length (); | 2081 int fcount = fcns.length (); |
2207 | 2082 |
2208 for (int i = 0; i < lcount; i++) | 2083 for (int i = 0; i < fcount; i++) |
2209 { | 2084 { |
2210 std::string nm = lfcns[i]; | 2085 std::string nm = fcns[i]; |
2211 | 2086 |
2212 if (! name_matches_any_pattern (nm, argv, argc, idx)) | 2087 if (! name_matches_any_pattern (nm, argv, argc, idx)) |
2213 do_clear_function (nm); | 2088 symbol_table::clear_function (nm); |
2214 } | |
2215 | |
2216 string_vector fcns = fbi_sym_tab->user_function_name_list (); | |
2217 | |
2218 int fcount = fcns.length (); | |
2219 | |
2220 for (int i = 0; i < fcount; i++) | |
2221 { | |
2222 std::string nm = fcns[i]; | |
2223 | |
2224 if (! name_matches_any_pattern (nm, argv, argc, idx)) | |
2225 do_clear_function (nm); | |
2226 } | 2089 } |
2227 } | 2090 } |
2228 else | 2091 else |
2229 { | 2092 { |
2230 while (idx < argc) | 2093 while (idx < argc) |
2231 do_clear_function_pattern (argv[idx++]); | 2094 symbol_table::clear_function_pattern (argv[idx++]); |
2232 } | 2095 } |
2233 } | 2096 } |
2234 } | 2097 } |
2235 | 2098 |
2236 static inline void | 2099 static void |
2237 do_clear_globals (const string_vector& argv, int argc, int idx, | 2100 do_clear_globals (const string_vector& argv, int argc, int idx, |
2238 bool exclusive = false) | 2101 bool exclusive = false) |
2239 { | 2102 { |
2240 if (idx == argc) | 2103 if (idx == argc) |
2241 do_clear_globals (); | 2104 symbol_table::clear_variables(symbol_table::global_scope ()); |
2242 else | 2105 else |
2243 { | 2106 { |
2244 if (exclusive) | 2107 if (exclusive) |
2245 { | 2108 { |
2246 string_vector lvars = curr_sym_tab->global_variable_name_list (); | 2109 string_vector gvars |
2247 | 2110 = symbol_table::variable_names (symbol_table::global_scope ()); |
2248 int lcount = lvars.length (); | 2111 |
2249 | 2112 int gcount = gvars.length (); |
2250 for (int i = 0; i < lcount; i++) | 2113 |
2251 { | 2114 for (int i = 0; i < gcount; i++) |
2252 std::string nm = lvars[i]; | 2115 { |
2116 std::string nm = gvars[i]; | |
2253 | 2117 |
2254 if (! name_matches_any_pattern (nm, argv, argc, idx)) | 2118 if (! name_matches_any_pattern (nm, argv, argc, idx)) |
2255 do_clear_global (nm); | 2119 symbol_table::clear_global (nm); |
2256 } | |
2257 | |
2258 string_vector gvars = global_sym_tab->global_variable_name_list (); | |
2259 | |
2260 int gcount = gvars.length (); | |
2261 | |
2262 for (int i = 0; i < gcount; i++) | |
2263 { | |
2264 std::string nm = gvars[i]; | |
2265 | |
2266 if (! name_matches_any_pattern (nm, argv, argc, idx)) | |
2267 do_clear_global (nm); | |
2268 } | 2120 } |
2269 } | 2121 } |
2270 else | 2122 else |
2271 { | 2123 { |
2272 while (idx < argc) | 2124 while (idx < argc) |
2273 do_clear_global_pattern (argv[idx++]); | 2125 symbol_table::clear_global_pattern (argv[idx++]); |
2274 } | 2126 } |
2275 } | 2127 } |
2276 } | 2128 } |
2277 | 2129 |
2278 static inline void | 2130 static void |
2279 do_clear_variables (const string_vector& argv, int argc, int idx, | 2131 do_clear_variables (const string_vector& argv, int argc, int idx, |
2280 bool exclusive = false) | 2132 bool exclusive = false) |
2281 { | 2133 { |
2282 if (idx == argc) | 2134 if (idx == argc) |
2283 do_clear_variables (); | 2135 symbol_table::clear_variables (); |
2284 else | 2136 else |
2285 { | 2137 { |
2286 if (exclusive) | 2138 if (exclusive) |
2287 { | 2139 { |
2288 string_vector lvars = curr_sym_tab->variable_name_list (); | 2140 string_vector lvars = symbol_table::variable_names (); |
2289 | 2141 |
2290 int lcount = lvars.length (); | 2142 int lcount = lvars.length (); |
2291 | 2143 |
2292 for (int i = 0; i < lcount; i++) | 2144 for (int i = 0; i < lcount; i++) |
2293 { | 2145 { |
2294 std::string nm = lvars[i]; | 2146 std::string nm = lvars[i]; |
2295 | 2147 |
2296 if (! name_matches_any_pattern (nm, argv, argc, idx)) | 2148 if (! name_matches_any_pattern (nm, argv, argc, idx)) |
2297 do_clear_variable (nm); | 2149 symbol_table::clear_variable (nm); |
2298 } | 2150 } |
2299 } | 2151 } |
2300 else | 2152 else |
2301 { | 2153 { |
2302 while (idx < argc) | 2154 while (idx < argc) |
2303 do_clear_variable_pattern (argv[idx++]); | 2155 symbol_table::clear_variable_pattern (argv[idx++]); |
2304 } | 2156 } |
2305 } | 2157 } |
2306 } | 2158 } |
2307 | 2159 |
2308 static inline void | 2160 static void |
2309 do_clear_symbols (const string_vector& argv, int argc, int idx, | 2161 do_clear_symbols (const string_vector& argv, int argc, int idx, |
2310 bool exclusive = false) | 2162 bool exclusive = false) |
2311 { | 2163 { |
2312 if (idx == argc) | 2164 if (idx == argc) |
2313 do_clear_variables (); | 2165 symbol_table::clear_variables (); |
2314 else | 2166 else |
2315 { | 2167 { |
2316 if (exclusive) | 2168 if (exclusive) |
2317 { | 2169 { |
2318 // FIXME -- is this really what we want, or do we | 2170 // FIXME -- is this really what we want, or do we |
2324 do_clear_functions (argv, argc, idx, exclusive); | 2176 do_clear_functions (argv, argc, idx, exclusive); |
2325 } | 2177 } |
2326 else | 2178 else |
2327 { | 2179 { |
2328 while (idx < argc) | 2180 while (idx < argc) |
2329 do_clear_symbol_pattern (argv[idx++]); | 2181 symbol_table::clear_symbol_pattern (argv[idx++]); |
2330 } | 2182 } |
2331 } | 2183 } |
2332 } | 2184 } |
2333 | 2185 |
2334 static void | 2186 static void |
2336 { | 2188 { |
2337 // This is supposed to be mostly Matlab compatible. | 2189 // This is supposed to be mostly Matlab compatible. |
2338 | 2190 |
2339 for (; idx < argc; idx++) | 2191 for (; idx < argc; idx++) |
2340 { | 2192 { |
2341 if (argv[idx] == "all" && ! is_local_variable ("all")) | 2193 if (argv[idx] == "all" |
2342 { | 2194 && ! symbol_table::is_local_variable ("all")) |
2343 do_clear_all (); | 2195 { |
2344 } | 2196 symbol_table::clear_all (); |
2345 else if (argv[idx] == "functions" && ! is_local_variable ("functions")) | 2197 } |
2198 else if (argv[idx] == "functions" | |
2199 && ! symbol_table::is_local_variable ("functions")) | |
2346 { | 2200 { |
2347 do_clear_functions (argv, argc, ++idx); | 2201 do_clear_functions (argv, argc, ++idx); |
2348 } | 2202 } |
2349 else if (argv[idx] == "global" && ! is_local_variable ("global")) | 2203 else if (argv[idx] == "global" |
2204 && ! symbol_table::is_local_variable ("global")) | |
2350 { | 2205 { |
2351 do_clear_globals (argv, argc, ++idx); | 2206 do_clear_globals (argv, argc, ++idx); |
2352 } | 2207 } |
2353 else if (argv[idx] == "variables" && ! is_local_variable ("variables")) | 2208 else if (argv[idx] == "variables" |
2354 { | 2209 && ! symbol_table::is_local_variable ("variables")) |
2355 do_clear_variables (); | 2210 { |
2356 } | 2211 symbol_table::clear_variables (); |
2357 else | 2212 } |
2358 { | 2213 else |
2359 do_clear_symbol_pattern (argv[idx]); | 2214 { |
2215 symbol_table::clear_symbol_pattern (argv[idx]); | |
2360 } | 2216 } |
2361 } | 2217 } |
2362 } | 2218 } |
2363 | 2219 |
2364 #define CLEAR_OPTION_ERROR(cond) \ | 2220 #define CLEAR_OPTION_ERROR(cond) \ |
2370 return retval; \ | 2226 return retval; \ |
2371 } \ | 2227 } \ |
2372 } \ | 2228 } \ |
2373 while (0) | 2229 while (0) |
2374 | 2230 |
2375 bool | |
2376 clear_function (const std::string& nm) | |
2377 { | |
2378 return do_clear_function (nm); | |
2379 } | |
2380 | |
2381 bool | |
2382 clear_variable (const std::string& nm) | |
2383 { | |
2384 return do_clear_variable (nm); | |
2385 } | |
2386 | |
2387 bool | |
2388 clear_symbol (const std::string& nm) | |
2389 { | |
2390 return do_clear_symbol (nm); | |
2391 } | |
2392 | |
2393 DEFCMD (clear, args, , | 2231 DEFCMD (clear, args, , |
2394 "-*- texinfo -*-\n\ | 2232 "-*- texinfo -*-\n\ |
2395 @deffn {Command} clear [-x] pattern @dots{}\n\ | 2233 @deffn {Command} clear [-x] pattern @dots{}\n\ |
2396 Delete the names matching the given patterns from the symbol table. The\n\ | 2234 Delete the names matching the given patterns from the symbol table. The\n\ |
2397 pattern may contain the following special characters:\n\ | 2235 pattern may contain the following special characters:\n\ |
2441 | 2279 |
2442 if (! error_state) | 2280 if (! error_state) |
2443 { | 2281 { |
2444 if (argc == 1) | 2282 if (argc == 1) |
2445 { | 2283 { |
2446 do_clear_variables (); | 2284 symbol_table::clear_variables (); |
2447 } | 2285 } |
2448 else | 2286 else |
2449 { | 2287 { |
2450 int idx = 0; | 2288 int idx = 0; |
2451 | 2289 |
2509 | 2347 |
2510 if (++idx < argc) | 2348 if (++idx < argc) |
2511 warning | 2349 warning |
2512 ("clear: ignoring extra arguments after -all"); | 2350 ("clear: ignoring extra arguments after -all"); |
2513 | 2351 |
2514 curr_sym_tab->clear (); | 2352 symbol_table::clear_all (); |
2515 fbi_sym_tab->clear_functions (); | |
2516 global_sym_tab->clear (); | |
2517 } | 2353 } |
2518 else if (clear_functions) | 2354 else if (clear_functions) |
2519 { | 2355 { |
2520 do_clear_functions (argv, argc, idx, exclusive); | 2356 do_clear_functions (argv, argc, idx, exclusive); |
2521 } | 2357 } |
2545 Undocumented internal function.\n\ | 2381 Undocumented internal function.\n\ |
2546 @end deftypefn") | 2382 @end deftypefn") |
2547 { | 2383 { |
2548 octave_value_list retval; | 2384 octave_value_list retval; |
2549 | 2385 |
2550 int nargin = args.length (); | 2386 // FIXME -- what should this function do now? Print a summary for |
2551 | 2387 // each scope? Print the entire symbol table? Accept a scope |
2552 if (nargin == 1) | 2388 // argument? |
2553 { | |
2554 std::string arg = args(0).string_value (); | |
2555 | |
2556 if (arg == "fbi") | |
2557 fbi_sym_tab->print_info (octave_stdout); | |
2558 else if (arg == "global") | |
2559 global_sym_tab->print_info (octave_stdout); | |
2560 else if (arg == "top-level") | |
2561 top_level_sym_tab->print_info (octave_stdout); | |
2562 else | |
2563 { | |
2564 symbol_record *fsr = fbi_sym_tab->lookup (arg, true); | |
2565 | |
2566 if (fsr && fsr->is_user_function ()) | |
2567 { | |
2568 octave_value tmp = fsr->def (); | |
2569 const octave_base_value& rep = tmp.get_rep (); | |
2570 | |
2571 const octave_user_function& fcn | |
2572 = dynamic_cast<const octave_user_function&> (rep); | |
2573 | |
2574 fcn.print_symtab_info (octave_stdout); | |
2575 } | |
2576 else | |
2577 error ("no user-defined function named %s", arg.c_str ()); | |
2578 } | |
2579 } | |
2580 else if (nargin == 0) | |
2581 curr_sym_tab->print_info (octave_stdout); | |
2582 else | |
2583 print_usage (); | |
2584 | 2389 |
2585 return retval; | 2390 return retval; |
2586 } | 2391 } |
2587 | 2392 |
2588 DEFUN (__print_symbol_info__, args, , | 2393 DEFUN (__print_symbol_info__, args, , |
2591 Undocumented internal function.\n\ | 2396 Undocumented internal function.\n\ |
2592 @end deftypefn") | 2397 @end deftypefn") |
2593 { | 2398 { |
2594 octave_value_list retval; | 2399 octave_value_list retval; |
2595 | 2400 |
2596 int nargin = args.length (); | 2401 // FIXME -- what should this function do now? |
2597 | 2402 |
2598 if (nargin == 1) | 2403 return retval; |
2599 { | 2404 } |
2600 std::string symbol_name = args(0).string_value (); | 2405 |
2601 | 2406 DEFUN (whos_line_format, args, nargout, |
2602 if (! error_state) | 2407 "-*- texinfo -*-\n\ |
2603 { | 2408 @deftypefn {Built-in Function} {@var{val} =} whos_line_format ()\n\ |
2604 symbol_record *sr = curr_sym_tab->lookup (symbol_name); | 2409 @deftypefnx {Built-in Function} {@var{old_val} =} whos_line_format (@var{new_val})\n\ |
2605 | 2410 Query or set the format string used by the @code{whos}.\n\ |
2606 if (sr) | 2411 \n\ |
2607 sr->print_info (octave_stdout); | 2412 The following escape sequences may be used in the format:\n\ |
2608 else | 2413 @table @code\n\ |
2609 error ("__print_symbol_info__: symbol %s not found", | 2414 @item %a\n\ |
2610 symbol_name.c_str ()); | 2415 Prints attributes of variables (g=global, p=persistent,\n\ |
2611 } | 2416 f=formal parameter, a=automatic variable).\n\ |
2612 else | 2417 @item %b\n\ |
2613 print_usage (); | 2418 Prints number of bytes occupied by variables.\n\ |
2614 } | 2419 @item %c\n\ |
2615 else | 2420 Prints class names of variables.\n\ |
2616 print_usage (); | 2421 @item %e\n\ |
2617 | 2422 Prints elements held by variables.\n\ |
2618 return retval; | 2423 @item %n\n\ |
2619 } | 2424 Prints variable names.\n\ |
2620 | 2425 @item %s\n\ |
2621 DEFUN (ignore_function_time_stamp, args, nargout, | 2426 Prints dimensions of variables.\n\ |
2622 "-*- texinfo -*-\n\ | 2427 @item %t\n\ |
2623 @deftypefn {Built-in Function} {@var{val} =} ignore_function_time_stamp ()\n\ | 2428 Prints type names of variables.\n\ |
2624 @deftypefnx {Built-in Function} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})\n\ | 2429 @end table\n\ |
2625 Query or set the internal variable that controls whether Octave checks\n\ | 2430 \n\ |
2626 the time stamp on files each time it looks up functions defined in\n\ | 2431 Every command may also have a modifier:\n\ |
2627 function files. If the internal variable is set to @code{\"system\"},\n\ | 2432 @table @code\n\ |
2628 Octave will not automatically recompile function files in subdirectories of\n\ | 2433 @item l\n\ |
2629 @file{@var{octave-home}/lib/@var{version}} if they have changed since\n\ | 2434 Left alignment.\n\ |
2630 they were last compiled, but will recompile other function files in the\n\ | 2435 @item r\n\ |
2631 search path if they change. If set to @code{\"all\"}, Octave will not\n\ | 2436 Right alignment (this is the default).\n\ |
2632 recompile any function files unless their definitions are removed with\n\ | 2437 @item c\n\ |
2633 @code{clear}. If set to \"none\", Octave will always check time stamps\n\ | 2438 Centered (may only be applied to command %s).\n\ |
2634 on files to determine whether functions defined in function files\n\ | 2439 @end table\n\ |
2635 need to be recompiled.\n\ | 2440 \n\ |
2441 A command is composed like this:\n\ | |
2442 \n\ | |
2443 @example\n\ | |
2444 %[modifier]<command>[:size_of_parameter[:center-specific[\n\ | |
2445 :print_dims[:balance]]]];\n\ | |
2446 @end example\n\ | |
2447 \n\ | |
2448 Command and modifier is already explained. Size_of_parameter\n\ | |
2449 tells how many columns the parameter will need for printing.\n\ | |
2450 print_dims tells how many dimensions to print. If number of\n\ | |
2451 dimensions exceeds print_dims, dimensions will be printed like\n\ | |
2452 x-D.\n\ | |
2453 center-specific and print_dims may only be applied to command\n\ | |
2454 %s. A negative value for print_dims will cause Octave to print all\n\ | |
2455 dimensions whatsoever.\n\ | |
2456 balance specifies the offset for printing of the dimensions string.\n\ | |
2457 \n\ | |
2458 The default format is \" %a:4; %ln:6; %cs:16:6:8:1; %rb:12; %lc:-1;\\n\".\n\ | |
2636 @end deftypefn") | 2459 @end deftypefn") |
2637 { | 2460 { |
2638 octave_value retval; | 2461 return SET_INTERNAL_VARIABLE (whos_line_format); |
2639 | |
2640 if (nargout > 0) | |
2641 { | |
2642 switch (Vignore_function_time_stamp) | |
2643 { | |
2644 case 1: | |
2645 retval = "system"; | |
2646 break; | |
2647 | |
2648 case 2: | |
2649 retval = "all"; | |
2650 break; | |
2651 | |
2652 default: | |
2653 retval = "none"; | |
2654 break; | |
2655 } | |
2656 } | |
2657 | |
2658 int nargin = args.length (); | |
2659 | |
2660 if (nargin == 1) | |
2661 { | |
2662 std::string sval = args(0).string_value (); | |
2663 | |
2664 if (! error_state) | |
2665 { | |
2666 if (sval == "all") | |
2667 Vignore_function_time_stamp = 2; | |
2668 else if (sval == "system") | |
2669 Vignore_function_time_stamp = 1; | |
2670 else if (sval == "none") | |
2671 Vignore_function_time_stamp = 0; | |
2672 else | |
2673 error ("ignore_function_time_stamp: expecting argument to be \"all\", \"system\", or \"none\""); | |
2674 } | |
2675 else | |
2676 error ("ignore_function_time_stamp: expecting argument to be character string"); | |
2677 } | |
2678 else if (nargin > 1) | |
2679 print_usage (); | |
2680 | |
2681 return retval; | |
2682 } | 2462 } |
2683 | 2463 |
2684 /* | 2464 /* |
2685 ;;; Local Variables: *** | 2465 ;;; Local Variables: *** |
2686 ;;; mode: C++ *** | 2466 ;;; mode: C++ *** |