GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
symtab.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2017 John W. Eaton
4 Copyright (C) 2009 VZLU Prague, a.s.
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <sstream>
29 
30 #include "file-ops.h"
31 #include "file-stat.h"
32 #include "oct-env.h"
33 #include "oct-time.h"
34 #include "singleton-cleanup.h"
35 
36 #include "debug.h"
37 #include "defun.h"
38 #include "dirfns.h"
39 #include "input.h"
40 #include "load-path.h"
41 #include "ov-classdef.h"
42 #include "ov-fcn.h"
43 #include "ov-usr-fcn.h"
44 #include "pager.h"
45 #include "parse.h"
46 #include "pt-arg-list.h"
47 #include "pt-pr-code.h"
48 #include "symtab.h"
49 #include "unwind-prot.h"
50 #include "utils.h"
51 
53 
55 
57 
58 std::map<symbol_table::scope_id, symbol_table*> symbol_table::all_instances;
59 
60 std::map<std::string, octave_value> symbol_table::global_table;
61 
62 std::map<std::string, symbol_table::fcn_info> symbol_table::fcn_table;
63 
64 std::map<std::string, std::set<std::string> >
66 
67 std::map<std::string, std::list<std::string> > symbol_table::parent_map;
68 
71 
73 
75 
76 // Should Octave always check to see if function files have changed
77 // since they were last compiled?
79 
80 void
82 {
83  instance = new scope_id_cache ();
84 
86 }
87 
90 {
92 
93  // FIXME: If active_context () == -1, then it does not make much
94  // sense to use this symbol_record. This means an attempt at accessing
95  // a variable from a function that has not been called yet is
96  // happening. This should be cleared up when an implementing closures.
97 
98  return fcn && fcn->active_context () != static_cast<context_id> (-1)
99  ? fcn->active_context () : xcurrent_context;
100 }
101 
102 void
104  (std::ostream& os, const std::string& prefix) const
105 {
106  octave_value val = varval ();
107 
108  os << prefix << name;
109 
110  if (val.is_defined ())
111  {
112  os << " ["
113  << (is_local () ? "l" : "")
114  << (is_automatic () ? "a" : "")
115  << (is_formal () ? "f" : "")
116  << (is_hidden () ? "h" : "")
117  << (is_inherited () ? "i" : "")
118  << (is_global () ? "g" : "")
119  << (is_persistent () ? "p" : "")
120  << "] ";
121  val.dump (os);
122  }
123 
124  os << "\n";
125 }
126 
129 {
131 
132  if (is_global ())
133  retval = symbol_table::global_varval (name ());
134  else
135  {
136  retval = varval ();
137 
138  if (retval.is_undefined ())
139  {
140  // Use cached fcn_info pointer if possible.
141  if (rep->finfo)
142  retval = rep->finfo->find (args);
143  else
144  {
145  retval = symbol_table::find_function (name (), args);
146 
147  if (retval.is_defined ())
148  rep->finfo = get_fcn_info (name ());
149  }
150  }
151  }
152 
153  return retval;
154 }
155 
157 
158 static void
161 {
162  size_t pos = name.rfind ('.');
163 
164  fname.clear ();
165  pname.clear ();
166 
167  if (pos != std::string::npos)
168  {
169  fname = name.substr (pos + 1);
170  pname = name.substr (0, pos);
171  }
172  else
173  fname = name;
174 }
175 
176 // Check the load path to see if file that defined this is still
177 // visible. If the file is no longer visible, then erase the
178 // definition and move on. If the file is visible, then we also
179 // need to check to see whether the file has changed since the
180 // function was loaded/parsed. However, this check should only
181 // happen once per prompt (for files found from relative path
182 // elements, we also check if the working directory has changed
183 // since the last time the function was loaded/parsed).
184 //
185 // FIXME: perhaps this should be done for all loaded functions when
186 // the prompt is printed or the directory has changed, and then we
187 // would not check for it when finding symbol definitions.
188 
189 static inline bool
190 load_out_of_date_fcn (const std::string& ff, const std::string& dir_name,
191  octave_value& function,
192  const std::string& dispatch_type = "",
193  const std::string& package_name = "")
194 {
195  bool retval = false;
196 
197  octave_function *fcn = load_fcn_from_file (ff, dir_name, dispatch_type,
198  package_name);
199 
200  if (fcn)
201  {
202  retval = true;
203 
204  function = octave_value (fcn);
205  }
206  else
207  function = octave_value ();
208 
209  return retval;
210 }
211 
212 bool
214  const std::string& dispatch_type,
215  bool check_relative)
216 {
217  bool retval = false;
218 
219  octave_function *fcn = function.function_value (true);
220 
221  if (fcn)
222  {
223  // FIXME: we need to handle subfunctions properly here.
224 
225  if (! fcn->is_subfunction ())
226  {
227  std::string ff = fcn->fcn_file_name ();
228 
229  if (! ff.empty ())
230  {
231  octave::sys::time tc = fcn->time_checked ();
232 
233  bool relative = check_relative && fcn->is_relative ();
234 
235  if (tc <= Vlast_prompt_time
236  || (relative && tc < Vlast_chdir_time))
237  {
238  bool clear_breakpoints = false;
239  std::string nm = fcn->name ();
240  std::string pack = fcn->package_name ();
241  std::string canonical_nm = fcn->canonical_name ();
242 
243  bool is_same_file = false;
244 
246  std::string dir_name;
247 
248  if (check_relative)
249  {
250  int nm_len = nm.length ();
251 
253  && ((nm_len > 4
254  && (nm.substr (nm_len-4) == ".oct"
255  || nm.substr (nm_len-4) == ".mex"))
256  || (nm_len > 2
257  && nm.substr (nm_len-2) == ".m")))
258  file = nm;
259  else
260  {
261  // We don't want to make this an absolute name,
262  // because load_fcn_file looks at the name to
263  // decide whether it came from a relative lookup.
264 
265  if (! dispatch_type.empty ())
266  {
267  file = load_path::find_method (dispatch_type, nm,
268  dir_name, pack);
269 
270  if (file.empty ())
271  {
272  std::string s_name;
273  std::string s_pack;
274 
275  const std::list<std::string>& plist
276  = symbol_table::parent_classes (dispatch_type);
277  std::list<std::string>::const_iterator it
278  = plist.begin ();
279 
280  while (it != plist.end ())
281  {
282  split_name_with_package (*it, s_name,
283  s_pack);
284 
285  file = load_path::find_method (*it, nm,
286  dir_name,
287  s_pack);
288  if (! file.empty ())
289  {
290  pack = s_pack;
291  break;
292  }
293 
294  it++;
295  }
296  }
297  }
298 
299  // Maybe it's an autoload?
300  if (file.empty ())
301  file = lookup_autoload (nm);
302 
303  if (file.empty ())
304  file = load_path::find_fcn (nm, dir_name, pack);
305  }
306 
307  if (! file.empty ())
308  is_same_file = same_file (file, ff);
309  }
310  else
311  {
312  is_same_file = true;
313  file = ff;
314  }
315 
316  if (file.empty ())
317  {
318  // Can't see this function from current
319  // directory, so we should clear it.
320 
321  function = octave_value ();
322 
323  clear_breakpoints = true;
324  }
325  else if (is_same_file)
326  {
327  // Same file. If it is out of date, then reload it.
328 
329  octave::sys::time ottp = fcn->time_parsed ();
330  time_t tp = ottp.unix_time ();
331 
333 
334  if (! (Vignore_function_time_stamp == 2
335  || (Vignore_function_time_stamp
336  && fcn->is_system_fcn_file ())))
337  {
339 
340  if (fs)
341  {
342  if (fs.is_newer (tp))
343  {
344  retval = load_out_of_date_fcn (ff, dir_name,
345  function,
346  dispatch_type,
347  pack);
348 
349  clear_breakpoints = true;
350  }
351  }
352  else
353  {
354  function = octave_value ();
355 
356  clear_breakpoints = true;
357  }
358  }
359  }
360  else
361  {
362  // Not the same file, so load the new file in
363  // place of the old.
364 
365  retval = load_out_of_date_fcn (file, dir_name, function,
366  dispatch_type, pack);
367 
368  clear_breakpoints = true;
369  }
370 
371  // If the function has been replaced then clear any
372  // breakpoints associated with it
373  if (clear_breakpoints)
375  true);
376  }
377  }
378  }
379  }
380 
381  return retval;
382 }
383 
386  (const std::string& dir_name)
387 {
389 
390  std::string file_name = load_path::find_private_fcn (dir_name, name);
391 
392  if (! file_name.empty ())
393  {
394  octave_function *fcn = load_fcn_from_file (file_name, dir_name);
395 
396  if (fcn)
397  {
399 
400  size_t pos = dir_name.find_last_of (octave::sys::file_ops::dir_sep_chars ());
401 
402  if (pos != std::string::npos)
403  {
404  std::string tmp = dir_name.substr (pos+1);
405 
406  if (tmp[0] == '@')
407  class_name = tmp.substr (1);
408  }
409 
410  fcn->mark_as_private_function (class_name);
411 
412  retval = octave_value (fcn);
413 
414  private_functions[dir_name] = retval;
415  }
416  }
417 
418  return retval;
419 }
420 
423 {
425 
426  std::string dir_name;
427 
428  std::string file_name = load_path::find_method (name, name, dir_name,
429  package_name);
430 
431  if (! file_name.empty ())
432  {
433  octave_function *fcn = load_fcn_from_file (file_name, dir_name, name,
434  package_name);
435 
436  if (fcn)
437  {
438  retval = octave_value (fcn);
439 
440  class_constructors[name] = retval;
441  class_methods[name] = retval;
442  }
443  }
444  else
445  {
446  // Classdef constructors can be defined anywhere in the path, not
447  // necessarily in @-folders. Look for a normal function and load it.
448  // If the loaded function is a classdef constructor, store it as such
449  // and restore function_on_path to its previous value.
450 
451  octave_value old_function_on_path = function_on_path;
452 
453  octave_value maybe_cdef_ctor = find_user_function ();
454 
455  if (maybe_cdef_ctor.is_defined ())
456  {
457  octave_function *fcn = maybe_cdef_ctor.function_value (true);
458 
459  if (fcn && fcn->is_classdef_constructor ())
460  {
461  retval = maybe_cdef_ctor;
462 
463  class_constructors[name] = retval;
464  class_methods[name] = retval;
465 
466  function_on_path = old_function_on_path;
467  }
468  }
469  }
470 
471  return retval;
472 }
473 
476  (const std::string& dispatch_type)
477 {
479 
480  if (full_name () == dispatch_type)
481  retval = load_class_constructor ();
482  else
483  {
485  dispatch_type);
486 
487  if (cm)
488  retval = octave_value (cm);
489 
490  if (! retval.is_defined ())
491  {
492  std::string dir_name;
493 
494  std::string file_name = load_path::find_method (dispatch_type, name,
495  dir_name);
496 
497  if (! file_name.empty ())
498  {
499  octave_function *fcn = load_fcn_from_file (file_name, dir_name,
500  dispatch_type);
501 
502  if (fcn)
503  {
504  retval = octave_value (fcn);
505 
506  class_methods[dispatch_type] = retval;
507  }
508  }
509 
510  if (retval.is_undefined ())
511  {
512  // Search parent classes
513 
514  const std::list<std::string>& plist =
515  parent_classes (dispatch_type);
516 
517  std::list<std::string>::const_iterator it = plist.begin ();
518 
519  while (it != plist.end ())
520  {
521  retval = find_method (*it);
522 
523  if (retval.is_defined ())
524  {
525  class_methods[dispatch_type] = retval;
526  break;
527  }
528 
529  it++;
530  }
531  }
532  }
533  }
534 
535  return retval;
536 }
537 
538 void
541 {
542  scope_val_iterator p = subfunctions.find (scope);
543 
544  if (p != subfunctions.end ())
545  {
546  octave_function *fcn = p->second.function_value ();
547 
548  if (fcn)
549  fcn->mark_as_private_function (class_name);
550  }
551 }
552 
553 void
555 {
556  if (dispatch_map.empty ())
557  os << "dispatch: " << name << " is not overloaded" << std::endl;
558  else
559  {
560  os << "Overloaded function " << name << ":\n\n";
561 
562  for (dispatch_map_const_iterator p = dispatch_map.begin ();
563  p != dispatch_map.end (); p++)
564  os << " " << name << " (" << p->first << ", ...) -> "
565  << p->second << " (" << p->first << ", ...)\n";
566 
567  os << std::endl;
568  }
569 }
570 
573 {
575 
576  if (! dispatch_map.empty ())
577  {
578  retval = "Overloaded function:\n\n";
579 
580  for (dispatch_map_const_iterator p = dispatch_map.begin ();
581  p != dispatch_map.end (); p++)
582  retval += " " + p->second + " (" + p->first + ", ...)\n\n";
583  }
584 
585  return retval;
586 }
587 
588 // :-) JWE, can you parse this? Returns a 2D array with second dimension equal
589 // to btyp_num_types (static constant). Only the leftmost dimension can be
590 // variable in C/C++. Typedefs are boring.
591 
593 {
594  static builtin_type_t sup_table[btyp_num_types][btyp_num_types];
595  for (int i = 0; i < btyp_num_types; i++)
596  for (int j = 0; j < btyp_num_types; j++)
597  {
598  builtin_type_t ityp = static_cast<builtin_type_t> (i);
599  builtin_type_t jtyp = static_cast<builtin_type_t> (j);
600  // FIXME: Is this really right?
601  bool use_j =
602  (jtyp == btyp_func_handle || ityp == btyp_bool
603  || (btyp_isarray (ityp)
604  && (! btyp_isarray (jtyp)
605  || (btyp_isinteger (jtyp) && ! btyp_isinteger (ityp))
606  || ((ityp == btyp_double || ityp == btyp_complex
607  || ityp == btyp_char)
608  && (jtyp == btyp_float
609  || jtyp == btyp_float_complex)))));
610 
611  sup_table[i][j] = use_j ? jtyp : ityp;
612  }
613 
614  return sup_table;
615 }
616 
620 {
621  static builtin_type_t (*sup_table)[btyp_num_types] = build_sup_table ();
622  std::string dispatch_type;
623 
624  int n = args.length ();
625 
626  if (n > 0)
627  {
628  int i = 0;
629  builtin_type = args(0).builtin_type ();
630  if (builtin_type != btyp_unknown)
631  {
632  for (i = 1; i < n; i++)
633  {
634  builtin_type_t bti = args(i).builtin_type ();
635  if (bti != btyp_unknown)
636  builtin_type = sup_table[builtin_type][bti];
637  else
638  {
639  builtin_type = btyp_unknown;
640  break;
641  }
642  }
643  }
644 
645  if (builtin_type == btyp_unknown)
646  {
647  // There's a non-builtin class in the argument list.
648  dispatch_type = args(i).class_name ();
649 
650  for (int j = i+1; j < n; j++)
651  {
652  octave_value arg = args(j);
653 
654  if (arg.builtin_type () == btyp_unknown)
655  {
656  std::string cname = arg.class_name ();
657 
658  // Only switch to type of ARG if it is marked superior
659  // to the current DISPATCH_TYPE.
660  if (! symbol_table::is_superiorto (dispatch_type, cname)
661  && symbol_table::is_superiorto (cname, dispatch_type))
662  dispatch_type = cname;
663  }
664  }
665  }
666  else
667  dispatch_type = btyp_class_name[builtin_type];
668  }
669  else
670  builtin_type = btyp_unknown;
671 
672  return dispatch_type;
673 }
674 
677 {
679  return get_dispatch_type (args, builtin_type);
680 }
681 
682 // Find the definition of NAME according to the following precedence
683 // list:
684 //
685 // variable
686 // subfunction
687 // private function
688 // class method
689 // class constructor
690 // legacy dispatch
691 // command-line function
692 // autoload function
693 // function on the path
694 // built-in function
695 //
696 // Matlab documentation states that constructors have higher precedence
697 // than methods, but that does not seem to be the case.
698 
701  bool local_funcs)
702 {
703  octave_value retval = xfind (args, local_funcs);
704 
705  if (retval.is_undefined ())
706  {
707  // It is possible that the user created a file on the fly since
708  // the last prompt or chdir, so try updating the load path and
709  // searching again.
710 
712 
713  retval = xfind (args, local_funcs);
714  }
715 
716  return retval;
717 }
718 
721  bool local_funcs)
722 {
723  if (local_funcs)
724  {
725  // Subfunction. I think it only makes sense to check for
726  // subfunctions if we are currently executing a function defined
727  // from a .m file.
728 
730 
731  for (scope_id scope = xcurrent_scope; scope >= 0;)
732  {
733  scope_val_iterator r = subfunctions.find (scope);
734  if (r != subfunctions.end ())
735  {
736  // FIXME: out-of-date check here.
737 
738  return r->second;
739  }
740 
741  octave_user_function *scope_curr_fcn = get_curr_fcn (scope);
742  if (scope_curr_fcn)
743  scope = scope_curr_fcn->parent_fcn_scope ();
744  else
745  scope = -1;
746  }
747 
748  // Private function.
749 
750  if (current_fcn)
751  {
752  std::string dir_name = current_fcn->dir_name ();
753 
754  if (! dir_name.empty ())
755  {
756  str_val_iterator q = private_functions.find (dir_name);
757 
758  if (q == private_functions.end ())
759  {
760  octave_value val = load_private_function (dir_name);
761 
762  if (val.is_defined ())
763  return val;
764  }
765  else
766  {
767  octave_value& fval = q->second;
768 
769  if (fval.is_defined ())
770  out_of_date_check (fval, "", false);
771 
772  if (fval.is_defined ())
773  return fval;
774  else
775  {
776  octave_value val = load_private_function (dir_name);
777 
778  if (val.is_defined ())
779  return val;
780  }
781  }
782  }
783  }
784  }
785 
786  // Class methods.
787 
788  if (! args.empty ())
789  {
790  std::string dispatch_type = get_dispatch_type (args);
791 
792  octave_value fcn = find_method (dispatch_type);
793 
794  if (fcn.is_defined ())
795  return fcn;
796  }
797 
798  // Class constructors. The class name and function name are the same.
799 
800  str_val_iterator q = class_constructors.find (name);
801 
802  if (q == class_constructors.end ())
803  {
804  octave_value val = load_class_constructor ();
805 
806  if (val.is_defined ())
807  return val;
808  }
809  else
810  {
811  octave_value& fval = q->second;
812 
813  if (fval.is_defined ())
814  out_of_date_check (fval, name);
815 
816  if (fval.is_defined ())
817  return fval;
818  else
819  {
820  octave_value val = load_class_constructor ();
821 
822  if (val.is_defined ())
823  return val;
824  }
825  }
826 
827  // Legacy dispatch.
828 
829  if (! args.empty () && ! dispatch_map.empty ())
830  {
831  std::string dispatch_type = args(0).type_name ();
832 
834 
835  dispatch_map_iterator p = dispatch_map.find (dispatch_type);
836 
837  if (p == dispatch_map.end ())
838  p = dispatch_map.find ("any");
839 
840  if (p != dispatch_map.end ())
841  {
842  fname = p->second;
843 
845  = symbol_table::find_function (fname, args);
846 
847  if (fcn.is_defined ())
848  return fcn;
849  }
850  }
851 
852  // Command-line function.
853 
854  if (cmdline_function.is_defined ())
855  return cmdline_function;
856 
857  // Autoload?
858 
860 
861  if (fcn.is_defined ())
862  return fcn;
863 
864  // Function on the path.
865 
866  fcn = find_user_function ();
867 
868  if (fcn.is_defined ())
869  return fcn;
870 
871  // Package
872 
873  fcn = find_package ();
874 
875  if (fcn.is_defined ())
876  return fcn;
877 
878  // Built-in function (might be undefined).
879 
880  return built_in_function;
881 }
882 
883 // Find the definition of NAME according to the following precedence
884 // list:
885 //
886 // built-in function
887 // function on the path
888 // autoload function
889 // command-line function
890 // private function
891 // subfunction
892 
893 // This function is used to implement the "builtin" function, which
894 // searches for "built-in" functions. In Matlab, "builtin" only
895 // returns functions that are actually built-in to the interpreter.
896 // But since the list of built-in functions is different in Octave and
897 // Matlab, we also search up the precedence list until we find
898 // something that matches. Note that we are only searching by name,
899 // so class methods, constructors, and legacy dispatch functions are
900 // skipped.
901 
904 {
905  octave_value retval = x_builtin_find ();
906 
907  if (! retval.is_defined ())
908  {
909  // It is possible that the user created a file on the fly since
910  // the last prompt or chdir, so try updating the load path and
911  // searching again.
912 
914 
915  retval = x_builtin_find ();
916  }
917 
918  return retval;
919 }
920 
923 {
924  // Built-in function.
925  if (built_in_function.is_defined ())
926  return built_in_function;
927 
928  // Function on the path.
929 
931 
932  if (fcn.is_defined ())
933  return fcn;
934 
935  // Autoload?
936 
937  fcn = find_autoload ();
938 
939  if (fcn.is_defined ())
940  return fcn;
941 
942  // Command-line function.
943 
944  if (cmdline_function.is_defined ())
945  return cmdline_function;
946 
947  // Private function.
948 
950 
951  if (current_fcn)
952  {
953  std::string dir_name = current_fcn->dir_name ();
954 
955  if (! dir_name.empty ())
956  {
957  str_val_iterator q = private_functions.find (dir_name);
958 
959  if (q == private_functions.end ())
960  {
961  octave_value val = load_private_function (dir_name);
962 
963  if (val.is_defined ())
964  return val;
965  }
966  else
967  {
968  octave_value& fval = q->second;
969 
970  if (fval.is_defined ())
971  out_of_date_check (fval);
972 
973  if (fval.is_defined ())
974  return fval;
975  else
976  {
977  octave_value val = load_private_function (dir_name);
978 
979  if (val.is_defined ())
980  return val;
981  }
982  }
983  }
984  }
985 
986  // Subfunction. I think it only makes sense to check for
987  // subfunctions if we are currently executing a function defined
988  // from a .m file.
989 
990  for (scope_id scope = xcurrent_scope; scope >= 0;)
991  {
992  scope_val_iterator r = subfunctions.find (scope);
993  if (r != subfunctions.end ())
994  {
995  // FIXME: out-of-date check here.
996 
997  return r->second;
998  }
999 
1000  octave_user_function *scope_curr_fcn = get_curr_fcn (scope);
1001  if (scope_curr_fcn)
1002  scope = scope_curr_fcn->parent_fcn_scope ();
1003  else
1004  scope = -1;
1005  }
1006 
1007  return octave_value ();
1008 }
1009 
1012  (const std::string& dispatch_type)
1013 {
1015 
1016  str_val_iterator q = class_methods.find (dispatch_type);
1017 
1018  if (q == class_methods.end ())
1019  {
1020  octave_value val = load_class_method (dispatch_type);
1021 
1022  if (val.is_defined ())
1023  return val;
1024  }
1025  else
1026  {
1027  octave_value& fval = q->second;
1028 
1029  if (fval.is_defined ())
1030  out_of_date_check (fval, dispatch_type);
1031 
1032  if (fval.is_defined ())
1033  return fval;
1034  else
1035  {
1036  octave_value val = load_class_method (dispatch_type);
1037 
1038  if (val.is_defined ())
1039  return val;
1040  }
1041  }
1042 
1043  return retval;
1044 }
1045 
1048 {
1049  // Autoloaded function.
1050 
1051  if (autoload_function.is_defined ())
1052  out_of_date_check (autoload_function);
1053 
1054  if (! autoload_function.is_defined ())
1055  {
1056  std::string file_name = lookup_autoload (name);
1057 
1058  if (! file_name.empty ())
1059  {
1060  size_t pos = file_name.find_last_of (octave::sys::file_ops::dir_sep_chars ());
1061 
1062  std::string dir_name = file_name.substr (0, pos);
1063 
1064  octave_function *fcn = load_fcn_from_file (file_name, dir_name, "",
1065  "", name, true);
1066 
1067  if (fcn)
1068  autoload_function = octave_value (fcn);
1069  }
1070  }
1071 
1072  return autoload_function;
1073 }
1074 
1077 {
1078  // Function on the path.
1079 
1080  if (function_on_path.is_defined ())
1081  out_of_date_check (function_on_path);
1082 
1083  if (function_on_path.is_undefined ())
1084  {
1085  std::string dir_name;
1086 
1087  std::string file_name = load_path::find_fcn (name, dir_name,
1088  package_name);
1089 
1090  if (! file_name.empty ())
1091  {
1092  octave_function *fcn = load_fcn_from_file (file_name, dir_name, "",
1093  package_name);
1094 
1095  if (fcn)
1096  function_on_path = octave_value (fcn);
1097  }
1098  }
1099 
1100  return function_on_path;
1101 }
1102 
1105 {
1106  // FIXME: implement correct way to check out of date package
1107  //if (package.is_defined ())
1108  // out_of_date_check (package);
1109 
1110  if (package.is_undefined ())
1111  {
1112  octave_function * fcn =
1113  cdef_manager::find_package_symbol (full_name ());
1114 
1115  if (fcn)
1116  package = octave_value (fcn);
1117  }
1118 
1119  return package;
1120 }
1121 
1122 // Insert INF_CLASS in the set of class names that are considered
1123 // inferior to SUP_CLASS. Return FALSE if INF_CLASS is currently
1124 // marked as superior to SUP_CLASS.
1125 
1126 bool
1128  const std::string& inf_class)
1129 {
1130  if (is_superiorto (inf_class, sup_class))
1131  return false;
1132 
1133  // If sup_class doesn't have an entry in the precedence table,
1134  // this will automatically create it, and associate to it a
1135  // singleton set {inf_class} of inferior classes.
1136  class_precedence_table[sup_class].insert (inf_class);
1137 
1138  return true;
1139 }
1140 
1141 // Has class A been marked as superior to class B? Also returns
1142 // TRUE if B has been marked as inferior to A, since we only keep
1143 // one table, and convert inferiorto information to a superiorto
1144 // relationship. Two calls are required to determine whether there
1145 // is no relationship between two classes:
1146 //
1147 // if (symbol_table::is_superiorto (a, b))
1148 // // A is superior to B, or B has been marked inferior to A.
1149 // else if (symbol_table::is_superiorto (b, a))
1150 // // B is superior to A, or A has been marked inferior to B.
1151 // else
1152 // // No relation.
1153 
1154 bool
1156 {
1158  // If a has no entry in the precedence table, return false
1159  if (p == class_precedence_table.end ())
1160  return false;
1161 
1162  const std::set<std::string>& inferior_classes = p->second;
1163  std::set<std::string>::const_iterator q = inferior_classes.find (b);
1164  return (q != inferior_classes.end ());
1165 }
1166 
1167 static std::string
1169 {
1170  const octave_function *f = fcn.function_value ();
1171 
1172  return f ? f->fcn_file_name () : "";
1173 }
1174 
1175 void
1177  const std::string& prefix) const
1178 {
1179  os << prefix << full_name ()
1180  << " ["
1181  << (cmdline_function.is_defined () ? "c" : "")
1182  << (built_in_function.is_defined () ? "b" : "")
1183  << (package.is_defined () ? "p" : "")
1184  << "]\n";
1185 
1186  std::string tprefix = prefix + " ";
1187 
1188  if (autoload_function.is_defined ())
1189  os << tprefix << "autoload: "
1190  << fcn_file_name (autoload_function) << "\n";
1191 
1192  if (function_on_path.is_defined ())
1193  os << tprefix << "function from path: "
1194  << fcn_file_name (function_on_path) << "\n";
1195 
1196  if (! subfunctions.empty ())
1197  {
1198  for (scope_val_const_iterator p = subfunctions.begin ();
1199  p != subfunctions.end (); p++)
1200  os << tprefix << "subfunction: " << fcn_file_name (p->second)
1201  << " [" << p->first << "]\n";
1202  }
1203 
1204  if (! private_functions.empty ())
1205  {
1206  for (str_val_const_iterator p = private_functions.begin ();
1207  p != private_functions.end (); p++)
1208  os << tprefix << "private: " << fcn_file_name (p->second)
1209  << " [" << p->first << "]\n";
1210  }
1211 
1212  if (! class_constructors.empty ())
1213  {
1214  for (str_val_const_iterator p = class_constructors.begin ();
1215  p != class_constructors.end (); p++)
1216  os << tprefix << "constructor: " << fcn_file_name (p->second)
1217  << " [" << p->first << "]\n";
1218  }
1219 
1220  if (! class_methods.empty ())
1221  {
1222  for (str_val_const_iterator p = class_methods.begin ();
1223  p != class_methods.end (); p++)
1224  os << tprefix << "method: " << fcn_file_name (p->second)
1225  << " [" << p->first << "]\n";
1226  }
1227 
1228  if (! dispatch_map.empty ())
1229  {
1230  for (dispatch_map_const_iterator p = dispatch_map.begin ();
1231  p != dispatch_map.end (); p++)
1232  os << tprefix << "dispatch: " << fcn_file_name (p->second)
1233  << " [" << p->first << "]\n";
1234  }
1235 }
1236 
1237 void
1239  const octave_value& fcn,
1240  scope_id parent_scope)
1241 {
1242  install_subfunction (name, fcn, parent_scope);
1243 
1244  // Stash the nest_parent for resolving variables after parsing is done.
1245  octave_function *fv = fcn.function_value ();
1246 
1247  symbol_table *fcn_table_loc = get_instance (fv->scope ());
1248 
1249  symbol_table *parent_table = get_instance (parent_scope);
1250 
1251  parent_table->add_nest_child (*fcn_table_loc);
1252 }
1253 
1256  const octave_value_list& args,
1257  bool skip_variables,
1258  bool local_funcs)
1259 {
1261 
1262  return inst
1263  ? inst->do_find (name, args, skip_variables, local_funcs)
1264  : octave_value ();
1265 }
1266 
1269 {
1271 
1272  return inst ? inst->do_builtin_find (name) : octave_value ();
1273 }
1274 
1277  const octave_value_list& args,
1278  bool local_funcs)
1279 {
1281 
1282  if (! name.empty () && name[0] == '@')
1283  {
1284  // Look for a class specific function.
1285  std::string dispatch_type =
1286  name.substr (1, name.find_first_of (octave::sys::file_ops::dir_sep_str ()) - 1);
1287 
1289  size_t pos = name.find_last_of (octave::sys::file_ops::dir_sep_str ());
1290  if (pos != std::string::npos)
1291  method = name.substr (pos + 1);
1292 
1293  retval = find_method (method, dispatch_type);
1294  }
1295  else
1296  {
1297  size_t pos = name.find_first_of (Vfilemarker);
1298 
1299  if (pos == std::string::npos)
1300  retval = find (name, args, true, local_funcs);
1301  else
1302  {
1303  std::string fcn_scope = name.substr (0, pos);
1304  scope_id stored_scope = xcurrent_scope;
1306  octave_value parent = find_function (name.substr (0, pos),
1307  octave_value_list (), false);
1308 
1309  if (parent.is_defined ())
1310  {
1311  octave_function *parent_fcn = parent.function_value ();
1312 
1313  if (parent_fcn)
1314  {
1315  xcurrent_scope = parent_fcn->scope ();
1316 
1317  if (xcurrent_scope > 1)
1318  retval = find_function (name.substr (pos + 1), args);
1319  }
1320  }
1321 
1322  xcurrent_scope = stored_scope;
1323  }
1324  }
1325 
1326  return retval;
1327 }
1328 
1329 // look for @class/method>subfunction
1332  const std::string& dispatch_type)
1333 {
1334  octave_value fcn;
1335 
1336  std::string full_name = "@" + dispatch_type +
1338  size_t pos = full_name.find_first_of (Vfilemarker);
1339 
1340  if (pos != std::string::npos)
1341  {
1342  std::string fcn_scope = full_name.substr (0, pos);
1343  scope_id stored_scope = xcurrent_scope;
1345  octave_value parent = find_function (full_name.substr (0, pos),
1346  octave_value_list (), false);
1347  if (parent.is_defined ())
1348  {
1349  octave_function *parent_fcn = parent.function_value ();
1350 
1351  if (parent_fcn)
1352  {
1353  xcurrent_scope = parent_fcn->scope ();
1354 
1355  if (xcurrent_scope > 1)
1356  fcn = find_function (full_name.substr (pos + 1),
1357  octave_value_list ());
1358  }
1359  }
1360 
1361  xcurrent_scope = stored_scope;
1362  }
1363 
1364  return fcn;
1365 }
1366 
1367 void
1368 symbol_table::dump (std::ostream& os, scope_id scope)
1369 {
1370  if (scope == xglobal_scope)
1371  dump_global (os);
1372  else
1373  {
1374  symbol_table *inst = get_instance (scope, false);
1375 
1376  if (inst)
1377  {
1378  os << "*** dumping symbol table scope " << scope
1379  << " (" << inst->table_name << ")\n\n";
1380 
1381  std::map<std::string, octave_value> sfuns
1383 
1384  if (! sfuns.empty ())
1385  {
1386  os << " subfunctions defined in this scope:\n";
1387 
1388  for (std::map<std::string,
1389  octave_value>::const_iterator p = sfuns.begin ();
1390  p != sfuns.end (); p++)
1391  os << " " << p->first << "\n";
1392 
1393  os << "\n";
1394  }
1395 
1396  inst->do_dump (os);
1397  }
1398  }
1399 }
1400 
1401 void
1402 symbol_table::dump_global (std::ostream& os)
1403 {
1404  if (! global_table.empty ())
1405  {
1406  os << "*** dumping global symbol table\n\n";
1407 
1408  for (global_table_const_iterator p = global_table.begin ();
1409  p != global_table.end (); p++)
1410  {
1411  std::string nm = p->first;
1412  octave_value val = p->second;
1413 
1414  os << " " << nm << " ";
1415  val.dump (os);
1416  os << "\n";
1417  }
1418  }
1419 }
1420 
1421 void
1423 {
1424  if (! fcn_table.empty ())
1425  {
1426  os << "*** dumping globally visible functions from symbol table\n"
1427  << " (c=commandline, b=built-in)\n\n";
1428 
1429  for (fcn_table_const_iterator p = fcn_table.begin ();
1430  p != fcn_table.end (); p++)
1431  p->second.dump (os, " ");
1432 
1433  os << "\n";
1434  }
1435 }
1436 
1437 void
1439  const std::string& dir_name)
1440 {
1441  // FIXME: is this the best way to do this? Maybe it would be
1442  // better if we had a map from scope to list of subfunctions
1443  // stored with the function. Do we?
1444 
1445  for (fcn_table_const_iterator p = fcn_table.begin ();
1446  p != fcn_table.end (); p++)
1447  {
1448  std::pair<std::string, octave_value> tmp
1449  = p->second.subfunction_defined_in_scope (scope);
1450 
1451  std::string nm = tmp.first;
1452 
1453  if (! nm.empty ())
1454  {
1455  octave_value& fcn = tmp.second;
1456 
1458 
1459  if (f)
1460  f->stash_dir_name (dir_name);
1461  }
1462  }
1463 }
1464 
1467  const octave_value_list& args,
1468  bool skip_variables,
1469  bool local_funcs)
1470 {
1472 
1473  // Variable.
1474 
1475  if (! skip_variables)
1476  {
1477  table_iterator p = table.find (name);
1478 
1479  if (p != table.end ())
1480  {
1481  symbol_record sr = p->second;
1482 
1483  if (sr.is_global ())
1484  return symbol_table::global_varval (name);
1485  else
1486  {
1487  octave_value val = sr.varval ();
1488 
1489  if (val.is_defined ())
1490  return val;
1491  }
1492  }
1493  }
1494 
1495  fcn_table_iterator p = fcn_table.find (name);
1496 
1497  if (p != fcn_table.end ())
1498  return p->second.find (args, local_funcs);
1499  else
1500  {
1501  fcn_info finfo (name);
1502 
1503  octave_value fcn = finfo.find (args, local_funcs);
1504 
1505  if (fcn.is_defined ())
1506  fcn_table[name] = finfo;
1507 
1508  return fcn;
1509  }
1510 
1511  return retval;
1512 }
1513 
1516 {
1518 
1519  fcn_table_iterator p = fcn_table.find (name);
1520 
1521  if (p != fcn_table.end ())
1522  return p->second.builtin_find ();
1523  else
1524  {
1525  fcn_info finfo (name);
1526 
1527  octave_value fcn = finfo.builtin_find ();
1528 
1529  if (fcn.is_defined ())
1530  fcn_table[name] = finfo;
1531 
1532  return fcn;
1533  }
1534 
1535  return retval;
1536 }
1537 
1538 std::list<workspace_element>
1540 {
1541  std::list<workspace_element> retval;
1542 
1543  for (table_const_iterator p = table.begin (); p != table.end (); p++)
1544  {
1545  std::string nm = p->first;
1546  symbol_record sr = p->second;
1547 
1548  if (! sr.is_hidden ())
1549  {
1550  octave_value val = sr.varval ();
1551 
1552  if (val.is_defined ())
1553  {
1554  // FIXME: fix size for objects, see kluge in variables.cc
1555  //dim_vector dv = val.dims ();
1556  octave_value tmp = val;
1557  Matrix sz = tmp.size ();
1559  for (octave_idx_type i = 0; i < dv.ndims (); i++)
1560  dv(i) = sz(i);
1561 
1562  char storage = ' ';
1563  if (sr.is_global ())
1564  storage = 'g';
1565  else if (sr.is_persistent ())
1566  storage = 'p';
1567  else if (sr.is_automatic ())
1568  storage = 'a';
1569  else if (sr.is_formal ())
1570  storage = 'f';
1571  else if (sr.is_hidden ())
1572  storage = 'h';
1573  else if (sr.is_inherited ())
1574  storage = 'i';
1575 
1576  std::ostringstream buf;
1577  val.short_disp (buf);
1578  std::string short_disp_str = buf.str ();
1579 
1580  workspace_element elt (storage, nm, val.class_name (),
1581  short_disp_str, dv.str (),
1582  val.is_complex_type ());
1583 
1584  retval.push_back (elt);
1585  }
1586  }
1587  }
1588 
1589  return retval;
1590 }
1591 
1592 void
1593 symbol_table::do_dump (std::ostream& os)
1594 {
1595  if (! persistent_table.empty ())
1596  {
1597  os << " persistent variables in this scope:\n\n";
1598 
1600  p != persistent_table.end (); p++)
1601  {
1602  std::string nm = p->first;
1603  octave_value val = p->second;
1604 
1605  os << " " << nm << " ";
1606  val.dump (os);
1607  os << "\n";
1608  }
1609 
1610  os << "\n";
1611  }
1612 
1613  if (! table.empty ())
1614  {
1615  os << " other symbols in this scope (l=local; a=auto; f=formal\n"
1616  << " h=hidden; i=inherited; g=global; p=persistent)\n\n";
1617 
1618  for (table_const_iterator p = table.begin (); p != table.end (); p++)
1619  p->second.dump (os, " ");
1620 
1621  os << "\n";
1622  }
1623 }
1624 
1626 {
1627  clear_all (true);
1628 
1629  // Delete all possibly remaining scopes.
1630  for (all_instances_iterator iter = all_instances.begin ();
1631  iter != all_instances.end (); iter++)
1632  {
1633  // First zero the table entry to avoid possible duplicate delete.
1634  symbol_table *inst = iter->second;
1635  iter->second = 0;
1636 
1637  // Now delete the scope. Note that there may be side effects, such as
1638  // deleting other scopes.
1639  delete inst;
1640  }
1641 
1642  global_table.clear ();
1643  fcn_table.clear ();
1644  class_precedence_table.clear ();
1645  parent_map.clear ();
1646  all_instances.clear ();
1647 }
1648 
1649 void
1651 {
1652  if (nest_parent || nest_children.size ())
1654 
1655  if (nest_parent)
1656  {
1657  // fix bad symbol_records
1658  for (table_iterator ti = table.begin (); ti != table.end (); ++ti)
1659  {
1660  symbol_record &ours = ti->second;
1661  symbol_record parents;
1662  if (! ours.is_formal ()
1663  && nest_parent->look_nonlocal (ti->first, parents))
1664  {
1665  if (ours.is_global () || ours.is_persistent ())
1666  error ("global and persistent may only be used in the topmost level in which a nested variable is used");
1667 
1668  if (! ours.is_formal ())
1669  {
1670  ours.invalidate ();
1671  ti->second = parents;
1672  }
1673  }
1674  else
1675  ours.set_curr_fcn (curr_fcn);
1676  }
1677  }
1678  else if (nest_children.size ())
1679  {
1680  static_workspace = true;
1681  for (table_iterator ti = table.begin (); ti != table.end (); ++ti)
1682  ti->second.set_curr_fcn (curr_fcn);
1683  }
1684 
1685  for (std::vector<symbol_table*>::iterator iter = nest_children.begin ();
1686  iter != nest_children.end (); ++iter)
1687  (*iter)->do_update_nest ();
1688 }
1689 
1690 DEFUN (ignore_function_time_stamp, args, nargout,
1691  doc: /* -*- texinfo -*-
1692 @deftypefn {} {@var{val} =} ignore_function_time_stamp ()
1693 @deftypefnx {} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})
1694 Query or set the internal variable that controls whether Octave checks
1695 the time stamp on files each time it looks up functions defined in
1696 function files.
1697 
1698 If the internal variable is set to @qcode{"system"}, Octave will not
1699 automatically recompile function files in subdirectories of
1700 @file{@var{octave-home}/lib/@var{version}} if they have changed since they were last compiled, but will recompile other function files in the search path if they change.
1701 
1702 If set to @qcode{"all"}, Octave will not recompile any function files
1703 unless their definitions are removed with @code{clear}.
1704 
1705 If set to @qcode{"none"}, Octave will always check time stamps on files to
1706 determine whether functions defined in function files need to recompiled.
1707 @end deftypefn */)
1708 {
1709  int nargin = args.length ();
1710 
1711  if (nargin > 1)
1712  print_usage ();
1713 
1715 
1716  if (nargout > 0 || nargin == 0)
1717  {
1718  switch (Vignore_function_time_stamp)
1719  {
1720  case 1:
1721  retval = "system";
1722  break;
1723 
1724  case 2:
1725  retval = "all";
1726  break;
1727 
1728  default:
1729  retval = "none";
1730  break;
1731  }
1732  }
1733 
1734  if (nargin == 1)
1735  {
1736  std::string sval = args(0).xstring_value ("ignore_function_time_stamp: first argument must be a string");
1737 
1738  if (sval == "all")
1739  Vignore_function_time_stamp = 2;
1740  else if (sval == "system")
1741  Vignore_function_time_stamp = 1;
1742  else if (sval == "none")
1743  Vignore_function_time_stamp = 0;
1744  else
1745  error ("ignore_function_time_stamp: argument must be one of \"all\", \"system\", or \"none\"");
1746  }
1747 
1748  return retval;
1749 }
1750 
1751 /*
1752 %!shared old_state
1753 %! old_state = ignore_function_time_stamp ();
1754 %!test
1755 %! state = ignore_function_time_stamp ("all");
1756 %! assert (state, old_state);
1757 %! assert (ignore_function_time_stamp (), "all");
1758 %! state = ignore_function_time_stamp ("system");
1759 %! assert (state, "all");
1760 %! assert (ignore_function_time_stamp (), "system");
1761 %! ignore_function_time_stamp (old_state);
1762 
1763 ## Test input validation
1764 %!error (ignore_function_time_stamp ("all", "all"))
1765 %!error (ignore_function_time_stamp ("UNKNOWN_VALUE"))
1766 %!error (ignore_function_time_stamp (42))
1767 */
1768 
1770  doc: /* -*- texinfo -*-
1771 @deftypefn {} {[@var{scope}, @var{context}]} __current_scope__ ()
1772 Return the current scope and context as integers.
1773 @seealso{__dump_symtab_info__}
1774 @end deftypefn */)
1775 {
1777 }
1778 
1779 DEFUN (__dump_symtab_info__, args, ,
1780  doc: /* -*- texinfo -*-
1781 @deftypefn {} {} __dump_symtab_info__ ()
1782 @deftypefnx {} {} __dump_symtab_info__ (@var{scope})
1783 @deftypefnx {} {} __dump_symtab_info__ ("scopes")
1784 @deftypefnx {} {} __dump_symtab_info__ ("functions")
1785 Undocumented internal function.
1786 @seealso{__current_scope__}
1787 @end deftypefn */)
1788 {
1789  int nargin = args.length ();
1790 
1791  if (nargin > 1)
1792  print_usage ();
1793 
1795 
1796  if (nargin == 0)
1797  {
1799 
1801 
1802  std::list<symbol_table::scope_id> lst = symbol_table::scopes ();
1803 
1804  for (std::list<symbol_table::scope_id>::const_iterator p = lst.begin ();
1805  p != lst.end (); p++)
1807  }
1808  else
1809  {
1810  octave_value arg = args(0);
1811 
1812  if (arg.is_string ())
1813  {
1814  std::string s_arg = arg.string_value ();
1815 
1816  if (s_arg == "scopes")
1817  {
1818  std::list<symbol_table::scope_id> lst = symbol_table::scopes ();
1819 
1820  RowVector v (lst.size ());
1821 
1822  octave_idx_type k = 0;
1823 
1824  for (std::list<symbol_table::scope_id>::const_iterator
1825  p = lst.begin (); p != lst.end (); p++)
1826  v.xelem (k++) = *p;
1827 
1828  retval = v;
1829  }
1830  else if (s_arg == "functions")
1831  {
1833  }
1834  else
1835  error ("__dump_symtab_info__: string argument must be \"functions\" or \"scopes\"");
1836  }
1837  else
1838  {
1839  int s = arg.xint_value ("__dump_symtab_info__: first argument must be string or scope id");
1840 
1842  }
1843  }
1844 
1845  return retval;
1846 }
1847 
1848 DEFUN (__get_cmdline_fcn_txt__, args, ,
1849  doc: /* -*- texinfo -*-
1850 @deftypefn {} {} __get_cmdline_fcn_txt__ (@var{name})
1851 Undocumented internal function.
1852 @end deftypefn */)
1853 {
1854  if (args.length () != 1)
1855  print_usage ();
1856 
1857  std::string name = args(0).xstring_value ("__get_cmd_line_function_text__: first argument must be function name");
1858 
1860 
1862 
1864 
1865  if (f)
1866  {
1867  std::ostringstream buf;
1868 
1869  tree_print_code tpc (buf);
1870 
1871  f->accept (tpc);
1872 
1873  retval = ovl (buf.str ());
1874  }
1875 
1876  return retval;
1877 }
1878 
1879 // FIXME: should we have functions like this in Octave?
1880 //
1881 // DEFUN (set_variable, args, , "set_variable (NAME, VALUE)")
1882 // {
1883 // if (args.length () != 2)
1884 // print_usage ();
1885 //
1886 // std::string name = args(0).xstring_value ("set_variable: variable NAME must be a string");
1887 //
1888 // symbol_table::assign (name, args(1));
1889 //
1890 // return ovl ();
1891 // }
1892 //
1893 // DEFUN (variable_value, args, , "VALUE = variable_value (NAME)")
1894 // {
1895 // if (args.length () != 1)
1896 // print_usage ();
1897 //
1898 // octave_value retval;
1899 //
1900 // std::string name = args(0).xstring_value ("variable_value: variable NAME must be a string");
1901 //
1902 // retval = symbol_table::varval (name);
1903 //
1904 // if (retval.is_undefined ())
1905 // error ("variable_value: '%s' is not a variable in the current scope",
1906 // name.c_str ());
1907 //
1908 // return retval;
1909 // }
1910 
1911 /*
1912 bug #34497: 'clear -f' does not work for command line functions
1913 
1914 This test relies on bar being a core function that is implemented in an m-file.
1915 If the first assert fails, this is no longer the case and the tests need to be
1916 updated to use some other function.
1917 
1918 %!assert <34497> (! strcmp (which ("bar"), ""))
1919 
1920 %!function x = bar ()
1921 %! x = 5;
1922 %!endfunction
1923 %!test
1924 %! assert (bar == 5);
1925 %! assert (strcmp (which ("bar"), ""));
1926 %! clear -f bar;
1927 %! assert (! strcmp (which ("bar"), ""));
1928 
1929 %!function x = bar ()
1930 %! x = 5;
1931 %!endfunction
1932 %!test
1933 %! assert (bar == 5);
1934 %! assert (strcmp (which ("bar"), ""));
1935 %! clear bar;
1936 %! assert (! strcmp (which ("bar"), ""));
1937 */
void short_disp(std::ostream &os) const
Definition: ov.h:1228
octave_value find_user_function(void)
Definition: symtab.cc:1076
dispatch_map_type::iterator dispatch_map_iterator
Definition: symtab.h:747
static std::string dir_sep_str(void)
Definition: file-ops.h:80
virtual bool is_classdef_constructor(const std::string &="") const
Definition: ov-fcn.h:91
static void install_subfunction(const std::string &name, const octave_value &fcn, scope_id scope)
Definition: symtab.h:1590
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:120
time_t unix_time(void) const
Definition: oct-time.h:95
bool is_relative(void) const
Definition: ov-fcn.h:161
bool same_file(const std::string &f, const std::string &g)
Definition: utils.cc:130
octave_user_function * curr_fcn
Definition: symtab.h:2387
std::string help_for_dispatch(void) const
Definition: symtab.cc:572
std::string str(char sep= 'x') const
Definition: dim-vector.cc:73
octave_function * load_fcn_from_file(const std::string &file_name, const std::string &dir_name, const std::string &dispatch_type, const std::string &package_name, const std::string &fcn_name, bool autoload)
Definition: oct-parse.cc:8260
std::list< workspace_element > do_workspace_info(void) const
Definition: symtab.cc:1539
fname
Definition: load-save.cc:754
void dump(std::ostream &os, const std::string &prefix) const
Definition: symtab.cc:104
octave_value load_private_function(const std::string &dir_name)
Definition: symtab.cc:386
symbol_table * nest_parent
Definition: symtab.h:2384
std::map< std::string, octave_value >::const_iterator global_table_const_iterator
Definition: symtab.h:2351
static octave_value find_method(const std::string &name, const std::string &dispatch_type)
Definition: symtab.h:1495
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
static void create_instance(void)
Definition: symtab.cc:81
void do_update_nest(void)
Definition: symtab.cc:1650
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
static std::string dir_sep_chars(void)
Definition: file-ops.h:85
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
static symbol_table * get_instance(scope_id scope, bool create=true)
Definition: symtab.h:2441
octave_idx_type length(void) const
Definition: ovl.h:96
OCTINTERP_API context_id active_context(void) const
Definition: symtab.cc:89
bool out_of_date_check(octave_value &function, const std::string &dispatch_type, bool check_relative)
Definition: symtab.cc:213
int xint_value(const char *fmt,...) const
Definition: ov.cc:2047
bool is_defined(void) const
Definition: ov.h:536
bool is_automatic(void) const
Definition: symtab.h:604
static std::map< std::string, fcn_info > fcn_table
Definition: symtab.h:2406
bool look_nonlocal(const std::string &name, symbol_record &result)
Definition: symtab.h:2932
for large enough k
Definition: lu.cc:606
void mark_subfunction_in_scope_as_private(scope_id scope, const std::string &class_name)
Definition: symtab.cc:540
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
void error(const char *fmt,...)
Definition: error.cc:570
std::string table_name
Definition: symtab.h:2375
std::string name(void) const
Definition: ov-fcn.h:163
octave_value find(const octave_value_list &args=octave_value_list()) const
Definition: symtab.cc:128
octave_value varval(context_id context=xdefault_context) const
Definition: symtab.h:570
bool btyp_isarray(builtin_type_t btyp)
Definition: ov-base.h:99
octave_value find(const octave_value_list &args, bool local_funcs)
Definition: symtab.cc:700
bool static_workspace
Definition: symtab.h:2390
static void cleanup_instance(void)
Definition: symtab.h:115
virtual octave::sys::time time_checked(void) const
Definition: ov-fcn.h:82
octave::sys::time Vlast_prompt_time
Definition: input.cc:96
static bool load_out_of_date_fcn(const std::string &ff, const std::string &dir_name, octave_value &function, const std::string &dispatch_type="", const std::string &package_name="")
Definition: symtab.cc:190
static std::map< std::string, octave_value > global_table
Definition: symtab.h:2393
static std::string find_method(const std::string &class_name, const std::string &meth, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:99
static void stash_dir_name_for_subfunctions(scope_id scope, const std::string &dir_name)
Definition: symtab.cc:1438
bool is_newer(const octave::sys::time &time) const
Definition: file-stat.h:149
s
Definition: file-io.cc:2682
std::map< scope_id, octave_value >::iterator scope_val_iterator
Definition: symtab.h:740
static octave_value dummy_octave_value
Definition: symtab.h:52
builtin_type_t
Definition: ov-base.h:61
void stash_dir_name(const std::string &dir)
Definition: ov-fcn.h:127
static octave_function * find_method_symbol(const std::string &method_name, const std::string &class_name)
Definition: ov-classdef.h:1542
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.cc:1276
static void dump(std::ostream &os, scope_id scope=xcurrent_scope)
Definition: symtab.cc:1368
static std::string find_private_fcn(const std::string &dir, const std::string &fcn, const std::string &pack_name="")
Definition: load-path.h:161
symbol_table::context_id active_context() const
Definition: ov-usr-fcn.h:187
bool is_formal(void) const
Definition: symtab.h:605
static octave_value varval(const std::string &name, scope_id scope=xcurrent_scope, context_id context=xdefault_context)
Definition: symtab.h:1373
virtual octave::sys::time time_parsed(void) const
Definition: ov-fcn.h:79
symbol_table::scope_id parent_fcn_scope(void) const
Definition: ov-usr-fcn.h:247
octave_value arg
Definition: pr-output.cc:3440
static octave_value find_cmdline_function(const std::string &name)
Definition: symtab.h:1558
octave_function * fcn
Definition: ov-class.cc:1743
octave_base_value * rep
Definition: ov.h:1437
virtual symbol_table::scope_id scope(void)
Definition: ov-fcn.h:77
static std::string find_fcn(const std::string &fcn, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:146
static void split_name_with_package(const std::string &name, std::string &fname, std::string &pname)
Definition: symtab.cc:159
std::map< std::string, symbol_record >::iterator table_iterator
Definition: symtab.h:2348
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
static context_id current_context(void)
Definition: symtab.h:1165
JNIEnv void * args
Definition: ov-java.cc:67
octave_value load_class_method(const std::string &dispatch_type)
Definition: symtab.cc:476
dispatch_map_type::const_iterator dispatch_map_const_iterator
Definition: symtab.h:746
static octave_value global_varval(const std::string &name)
Definition: symtab.h:1406
std::map< std::string, fcn_info >::iterator fcn_table_iterator
Definition: symtab.h:2368
static scope_id_cache * instance
Definition: symtab.h:113
static context_id xcurrent_context
Definition: symtab.h:2430
static std::map< std::string, std::list< std::string > > parent_map
Definition: symtab.h:2418
OCTAVE_EXPORT octave_value_list any number nd example oindent prints the prompt xample Pick a any number!nd example oindent and waits for the user to enter a value The string entered by the user is evaluated as an so it may be a literal a variable name
Definition: input.cc:871
static std::string fcn_file_name(const octave_value &fcn)
Definition: symtab.cc:1168
void dump(std::ostream &os) const
Definition: ov.h:1338
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:941
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:935
std::map< std::string, octave_value >::const_iterator str_val_const_iterator
Definition: symtab.h:743
bool is_persistent(void) const
Definition: symtab.h:609
static octave_value find_submethod(const std::string &name, const std::string &dispatch_type)
Definition: symtab.cc:1331
std::map< std::string, octave_value >::const_iterator persistent_table_const_iterator
Definition: symtab.h:2356
std::string string_value(bool force=false) const
Definition: ov.h:908
bool is_global(void) const
Definition: symtab.h:606
static void add(fptr f)
octave_value do_builtin_find(const std::string &name)
Definition: symtab.cc:1515
std::string btyp_class_name[btyp_num_types]
Definition: ov-base.cc:84
int nargin
Definition: graphics.cc:10115
void mark_as_nested_function(void)
Definition: ov-usr-fcn.h:328
bool is_string(void) const
Definition: ov.h:578
octave_user_function * user_function_value(bool silent=false) const
Definition: ov.cc:1711
std::string package_name(void) const
Definition: ov-fcn.h:107
static int Vignore_function_time_stamp
Definition: symtab.cc:78
static bool absolute_pathname(const std::string &s)
Definition: oct-env.cc:108
bool is_complex_type(void) const
Definition: ov.h:670
static void cleanup(void)
Definition: symtab.cc:1625
double tmp
Definition: data.cc:6300
virtual void mark_as_private_function(const std::string &cname="")
Definition: ov-fcn.h:110
std::map< std::string, symbol_record > table
Definition: symtab.h:2378
static octave_function * find_package_symbol(const std::string &pack_name)
Definition: ov-classdef.h:1562
octave_value x_builtin_find(void)
Definition: symtab.cc:922
static intmap remove_all_breakpoints_in_file(const std::string &fname, bool silent=false)
Definition: debug.h:94
octave_value builtin_find(void)
Definition: symtab.h:1023
Definition: dMatrix.h:37
sz
Definition: data.cc:5342
static std::list< std::string > parent_classes(const std::string &dispatch_type)
Definition: symtab.h:2291
octave_value find_method(const std::string &dispatch_type)
Definition: symtab.cc:1012
static symbol_record dummy_symbol_record
Definition: symtab.h:657
static dim_vector alloc(int n)
Definition: dim-vector.h:270
static scope_id xcurrent_scope
Definition: symtab.h:2428
bool btyp_isinteger(builtin_type_t btyp)
Definition: ov-base.h:93
static octave_value find_autoload(const std::string &name)
Definition: symtab.h:1537
static octave_user_function * get_curr_fcn(scope_id scope=xcurrent_scope)
Definition: symtab.h:2316
std::string pname
Definition: graphics.cc:11207
static builtin_type_t(* build_sup_table(void))[btyp_num_types]
Definition: symtab.cc:592
octave::sys::time Vlast_chdir_time
Definition: dirfns.cc:68
std::string canonical_name(void) const
Definition: ov-fcn.h:165
static std::map< scope_id, symbol_table * > all_instances
Definition: symtab.h:2402
static std::map< std::string, std::set< std::string > > class_precedence_table
Definition: symtab.h:2410
octave_value xfind(const octave_value_list &args, bool local_funcs)
Definition: symtab.cc:720
octave_function * function_value(bool silent=false) const
Definition: ov.cc:1705
static bool set_class_relationship(const std::string &sup_class, const std::string &inf_class)
Definition: symtab.cc:1127
static void dump_global(std::ostream &os)
Definition: symtab.cc:1402
std::string dir_name(void) const
Definition: ov-fcn.h:125
std::map< scope_id, symbol_table * >::iterator all_instances_iterator
Definition: symtab.h:2363
static void clear_all(bool force=false)
Definition: symtab.h:1670
virtual bool is_system_fcn_file(void) const
Definition: ov-fcn.h:62
virtual std::string fcn_file_name(void) const
Definition: ov-fcn.h:64
std::map< std::string, symbol_record >::const_iterator table_const_iterator
Definition: symtab.h:2346
bool empty(void) const
Definition: ovl.h:98
#define octave_stdout
Definition: pager.h:146
std::map< std::string, octave_value >::iterator str_val_iterator
Definition: symtab.h:744
void dump(std::ostream &os, const std::string &prefix) const
Definition: symtab.cc:1176
static bool is_global(const std::string &name, scope_id scope=xcurrent_scope)
Definition: symtab.h:2204
static symbol_table * instance
Definition: symtab.h:2399
static void update(void)
Definition: load-path.h:88
static const scope_id xtop_scope
Definition: symtab.h:2426
char Vfilemarker
Definition: input.cc:124
virtual void mark_fcn_file_up_to_date(const octave::sys::time &)
Definition: ov-fcn.h:75
virtual bool is_subfunction(void) const
Definition: ov-fcn.h:85
static bool is_superiorto(const std::string &a, const std::string &b)
Definition: symtab.cc:1155
static std::list< scope_id > scopes(void)
Definition: symtab.h:1272
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
static void dump_functions(std::ostream &os)
Definition: symtab.cc:1422
__current_scope__() Return the current scope and context as integers.eealso
Definition: symtab.cc:1774
std::map< std::string, octave_value > persistent_table
Definition: symtab.h:2396
octave_map map(dims)
std::string get_dispatch_type(const octave_value_list &args, builtin_type_t &builtin_type)
Definition: symtab.cc:618
std::string method
Definition: urlwrite.cc:342
Matrix size(void)
Definition: ov.h:408
static const scope_id xglobal_scope
Definition: symtab.h:2425
octave_value builtin_find(void)
Definition: symtab.cc:903
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:301
std::string class_name(void) const
Definition: ov.h:1234
b
Definition: cellfun.cc:398
bool is_undefined(void) const
Definition: ov.h:539
octave::sys::file_stat fs(filename)
static octave_value builtin_find(const std::string &name)
Definition: symtab.cc:1268
std::map< std::string, std::set< std::string > >::const_iterator class_precedence_table_const_iterator
Definition: symtab.h:2413
void set_curr_fcn(octave_user_function *fcn)
Definition: symtab.h:642
static fcn_info * get_fcn_info(const std::string &name)
Definition: symtab.h:2554
octave_value do_find(const std::string &name, const octave_value_list &args, bool skip_variables, bool local_funcs)
Definition: symtab.cc:1466
octave_value find_autoload(void)
Definition: symtab.cc:1047
std::string lookup_autoload(const std::string &nm)
Definition: oct-parse.cc:8219
virtual octave_function * function_value(bool silent=false)
Definition: ov-base.cc:912
static void install_nestfunction(const std::string &name, const octave_value &fcn, scope_id parent_scope)
Definition: symtab.cc:1238
size_t context_id
Definition: symtab.h:55
bool is_inherited(void) const
Definition: symtab.h:608
std::vector< symbol_table * > nest_children
Definition: symtab.h:2381
std::map< std::string, fcn_info >::const_iterator fcn_table_const_iterator
Definition: symtab.h:2366
void do_dump(std::ostream &os)
Definition: symtab.cc:1593
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
static octave_value find_user_function(const std::string &name)
Definition: symtab.h:1550
static std::map< std::string, octave_value > subfunctions_defined_in_scope(scope_id scope=xcurrent_scope)
Definition: symtab.h:2254
octave_value retval
Definition: symtab.cc:1714
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
builtin_type_t builtin_type(void) const
Definition: ov.h:619
dim_vector dv
Definition: sub2ind.cc:263
octave_value find(const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.h:1017
octave_value find_package(void)
Definition: symtab.cc:1104
void print_dispatch(std::ostream &os) const
Definition: symtab.cc:554
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
octave_value load_class_constructor(void)
Definition: symtab.cc:422
std::map< scope_id, octave_value >::const_iterator scope_val_const_iterator
Definition: symtab.h:739
bool is_hidden(void) const
Definition: symtab.h:607
static scope_id current_scope(void)
Definition: symtab.h:1163
void accept(tree_walker &tw)
Definition: ov-usr-fcn.cc:646
static octave_value find(const std::string &name, const octave_value_list &args=octave_value_list(), bool skip_variables=false, bool local_funcs=true)
Definition: symtab.cc:1255
octave_value_list fval
Definition: ov-struct.cc:2060