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