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
load-path.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2006-2015 John W. Eaton
4 Copyright (C) 2010 VZLU Prague
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 <algorithm>
29 
30 #include "dir-ops.h"
31 #include "file-ops.h"
32 #include "file-stat.h"
33 #include "oct-env.h"
34 #include "pathsearch.h"
35 #include "singleton-cleanup.h"
36 
37 #include "defaults.h"
38 #include "defun.h"
39 #include "input.h"
40 #include "load-path.h"
41 #include "ov-usr-fcn.h"
42 #include "pager.h"
43 #include "parse.h"
44 #include "toplev.h"
45 #include "unwind-prot.h"
46 #include "utils.h"
47 
52 std::string load_path::sys_path;
54 
55 void
57 {
58  file_stat fs (dir_name);
59 
60  if (fs)
61  {
62  if (is_relative)
63  {
64  try
65  {
66  std::string abs_name = octave_env::make_absolute (dir_name);
67 
68  abs_dir_cache_iterator p = abs_dir_cache.find (abs_name);
69 
70  if (p != abs_dir_cache.end ())
71  {
72  // The directory is in the cache of all directories
73  // we have visited (indexed by its absolute name).
74  // If it is out of date, initialize it. Otherwise,
75  // copy the info from the cache. By doing that, we
76  // avoid unnecessary calls to stat that can slow
77  // things down tremendously for large directories.
78 
79  const dir_info& di = p->second;
80 
81  if (fs.mtime () + fs.time_resolution ()
83  initialize ();
84  else
85  *this = di;
86  }
87  else
88  {
89  // We haven't seen this directory before.
90 
91  initialize ();
92  }
93  }
94  catch (octave_execution_exception)
95  {
96  // Skip updating if we don't know where we are, but
97  // don't treat it as an error.
98 
99  error_state = 0;
100  }
101  }
102  else if (fs.mtime () + fs.time_resolution () > dir_time_last_checked)
103  initialize ();
104  }
105  else
106  {
107  std::string msg = fs.error ();
108  warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ());
109  }
110 }
111 
112 bool
113 load_path::dir_info::is_package (const std::string& name) const
114 {
115  size_t pos = name.find ('.');
116 
117  if (pos == std::string::npos)
118  return package_dir_map.find (name) != package_dir_map.end ();
119  else
120  {
121  std::string name_head = name.substr (0, pos);
122  std::string name_tail = name.substr (pos + 1);
123 
124  const_package_dir_map_iterator it = package_dir_map.find (name_head);
125 
126  if (it != package_dir_map.end ())
127  return it->second.is_package (name_tail);
128  else
129  return false;
130  }
131 }
132 
133 void
135 {
136  is_relative = ! octave_env::absolute_pathname (dir_name);
137 
138  dir_time_last_checked = octave_time (static_cast<time_t> (0));
139 
140  file_stat fs (dir_name);
141 
142  if (fs)
143  {
144  method_file_map.clear ();
145  package_dir_map.clear ();
146 
147  dir_mtime = fs.mtime ();
148  dir_time_last_checked = octave_time ();
149 
150  get_file_list (dir_name);
151 
152  try
153  {
154  std::string abs_name = octave_env::make_absolute (dir_name);
155 
156  // FIXME: nothing is ever removed from this cache of
157  // directory information, so there could be some resource
158  // problems. Perhaps it should be pruned from time to time.
159 
160  abs_dir_cache[abs_name] = *this;
161  }
162  catch (octave_execution_exception)
163  {
164  // Skip updating if we don't know where we are.
165  }
166  }
167  else
168  {
169  std::string msg = fs.error ();
170  warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ());
171  }
172 }
173 
174 void
176 {
177  dir_entry dir (d);
178 
179  if (dir)
180  {
181  string_vector flist = dir.read ();
182 
183  octave_idx_type len = flist.length ();
184 
185  all_files.resize (len);
186  fcn_files.resize (len);
187 
188  octave_idx_type all_files_count = 0;
189  octave_idx_type fcn_files_count = 0;
190 
191  for (octave_idx_type i = 0; i < len; i++)
192  {
193  std::string fname = flist[i];
194 
195  std::string full_name = file_ops::concat (d, fname);
196 
197  file_stat fs (full_name);
198 
199  if (fs)
200  {
201  if (fs.is_dir ())
202  {
203  if (fname == "private")
204  get_private_file_map (full_name);
205  else if (fname[0] == '@')
206  get_method_file_map (full_name, fname.substr (1));
207  else if (fname[0] == '+')
208  get_package_dir (full_name, fname.substr (1));
209  }
210  else
211  {
212  all_files[all_files_count++] = fname;
213 
214  size_t pos = fname.rfind ('.');
215 
216  if (pos != std::string::npos)
217  {
218  std::string ext = fname.substr (pos);
219 
220  if (ext == ".m" || ext == ".oct" || ext == ".mex")
221  {
222  std::string base = fname.substr (0, pos);
223 
224  if (valid_identifier (base))
225  fcn_files[fcn_files_count++] = fname;
226  }
227  }
228  }
229  }
230  }
231 
232  all_files.resize (all_files_count);
233  fcn_files.resize (fcn_files_count);
234  }
235  else
236  {
237  std::string msg = dir.error ();
238  warning ("load_path: %s: %s", d.c_str (), msg.c_str ());
239  }
240 }
241 
243 get_fcn_files (const std::string& d)
244 {
246 
247  dir_entry dir (d);
248 
249  if (dir)
250  {
251  string_vector flist = dir.read ();
252 
253  octave_idx_type len = flist.length ();
254 
255  for (octave_idx_type i = 0; i < len; i++)
256  {
257  std::string fname = flist[i];
258 
259  std::string ext;
260  std::string base = fname;
261 
262  size_t pos = fname.rfind ('.');
263 
264  if (pos != std::string::npos)
265  {
266  base = fname.substr (0, pos);
267  ext = fname.substr (pos);
268 
269  if (valid_identifier (base))
270  {
271  int t = 0;
272 
273  if (ext == ".m")
274  t = load_path::M_FILE;
275  else if (ext == ".oct")
277  else if (ext == ".mex")
279 
280  retval[base] |= t;
281  }
282  }
283  }
284  }
285  else
286  {
287  std::string msg = dir.error ();
288  warning ("load_path: %s: %s", d.c_str (), msg.c_str ());
289  }
290 
291  return retval;
292 }
293 
294 void
296 {
297  private_file_map = get_fcn_files (d);
298 }
299 
300 void
302  const std::string& class_name)
303 {
304  method_file_map[class_name].method_file_map = get_fcn_files (d);
305 
306  std::string pd = file_ops::concat (d, "private");
307 
308  file_stat fs (pd);
309 
310  if (fs && fs.is_dir ())
311  method_file_map[class_name].private_file_map = get_fcn_files (pd);
312 }
313 
314 void
316  const std::string& package_name)
317 {
318  package_dir_map[package_name] = dir_info (d);
319 }
320 
321 bool
323 {
324  bool retval = true;
325 
326  if (! instance)
327  {
328  instance = new load_path ();
329 
330  if (instance)
332  }
333 
334  if (! instance)
335  {
336  ::error ("unable to create load path object!");
337 
338  retval = false;
339  }
340 
341  return retval;
342 }
343 
344 // FIXME: maybe we should also maintain a map to speed up this method of access.
345 
347 load_path::find_dir_info (const std::string& dir_arg) const
348 {
349  std::string dir = file_ops::tilde_expand (dir_arg);
350 
352 
353  while (retval != dir_info_list.end ())
354  {
355  if (retval->dir_name == dir)
356  break;
357 
358  retval++;
359  }
360 
361  return retval;
362 }
363 
365 load_path::find_dir_info (const std::string& dir_arg)
366 {
367  std::string dir = file_ops::tilde_expand (dir_arg);
368 
369  dir_info_list_iterator retval = dir_info_list.begin ();
370 
371  while (retval != dir_info_list.end ())
372  {
373  if (retval->dir_name == dir)
374  break;
375 
376  retval++;
377  }
378 
379  return retval;
380 }
381 
382 bool
383 load_path::contains (const std::string& dir) const
384 {
385  return find_dir_info (dir) != dir_info_list.end ();
386 }
387 
388 bool
389 load_path::do_contains_canonical (const std::string& dir) const
390 {
391  bool retval = false;
392 
394  i != dir_info_list.end ();
395  i++)
396  {
397  if (same_file (dir, i->dir_name))
398  {
399  retval = true;
400  break;
401  }
402  }
403 
404  return retval;
405 }
406 
407 void
408 load_path::loader::move_fcn_map (const std::string& dir_name,
409  const string_vector& fcn_files, bool at_end)
410 {
411  octave_idx_type len = fcn_files.length ();
412 
413  for (octave_idx_type k = 0; k < len; k++)
414  {
415  std::string fname = fcn_files[k];
416 
417  std::string ext;
418  std::string base = fname;
419 
420  size_t pos = fname.rfind ('.');
421 
422  if (pos != std::string::npos)
423  {
424  base = fname.substr (0, pos);
425  ext = fname.substr (pos);
426  }
427 
428  file_info_list_type& file_info_list = fcn_map[base];
429 
430  if (file_info_list.size () == 1)
431  continue;
432  else
433  {
434  for (file_info_list_iterator p = file_info_list.begin ();
435  p != file_info_list.end ();
436  p++)
437  {
438  if (p->dir_name == dir_name)
439  {
440  file_info fi = *p;
441 
442  file_info_list.erase (p);
443 
444  if (at_end)
445  file_info_list.push_back (fi);
446  else
447  file_info_list.push_front (fi);
448 
449  break;
450  }
451  }
452  }
453  }
454 }
455 
456 void
457 load_path::loader::move_method_map (const std::string& dir_name, bool at_end)
458 {
459  for (method_map_iterator i = method_map.begin ();
460  i != method_map.end ();
461  i++)
462  {
463  std::string class_name = i->first;
464 
465  fcn_map_type& fm = i->second;
466 
467  std::string full_dir_name
468  = file_ops::concat (dir_name, "@" + class_name);
469 
470  for (fcn_map_iterator q = fm.begin (); q != fm.end (); q++)
471  {
472  file_info_list_type& file_info_list = q->second;
473 
474  if (file_info_list.size () == 1)
475  continue;
476  else
477  {
478  for (file_info_list_iterator p = file_info_list.begin ();
479  p != file_info_list.end (); p++)
480  {
481  if (p->dir_name == full_dir_name)
482  {
483  file_info fi = *p;
484 
485  file_info_list.erase (p);
486 
487  if (at_end)
488  file_info_list.push_back (fi);
489  else
490  file_info_list.push_front (fi);
491 
492  break;
493  }
494  }
495  }
496  }
497  }
498 }
499 
500 void
502 {
503  if (dir_info_list.size () > 1)
504  {
505  dir_info di = *i;
506 
507  dir_info_list.erase (i);
508 
509  if (at_end)
510  dir_info_list.push_back (di);
511  else
512  dir_info_list.push_front (di);
513 
514  move (di, at_end);
515  }
516 }
517 
518 void
519 load_path::move (const dir_info& di, bool at_end, const std::string& pname)
520 {
521  loader& l = get_loader (pname);
522 
523  l.move (di, at_end);
524 
525  dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
526 
527  for (dir_info::const_package_dir_map_iterator p = package_dir_map.begin ();
528  p != package_dir_map.end (); ++p)
529  {
530  std::string full_name = p->first;
531 
532  if (! pname.empty ())
533  full_name = pname + "." + full_name;
534 
535  move (p->second, at_end, full_name);
536  }
537 }
538 
539 void
540 load_path::loader::move (const dir_info& di, bool at_end)
541 {
542  std::string dir_name = di.dir_name;
543 
544  std::list<std::string>::iterator s =
545  std::find (dir_list.begin (), dir_list.end (), dir_name);
546 
547  if (s != dir_list.end ())
548  {
549  dir_list.erase (s);
550 
551  if (at_end)
552  dir_list.push_back (dir_name);
553  else
554  dir_list.push_front (dir_name);
555  }
556 
557  move_fcn_map (dir_name, di.fcn_files, at_end);
558 
559  // No need to move elements of private function map.
560 
561  move_method_map (dir_name, at_end);
562 }
563 
564 static void
565 maybe_add_path_elts (std::string& path, const std::string& dir)
566 {
567  std::string tpath = genpath (dir);
568 
569  if (! tpath.empty ())
570  {
571  if (path.empty ())
572  path = tpath;
573  else
574  path += dir_path::path_sep_str () + tpath;
575  }
576 }
577 
578 void
580 {
581  sys_path = "";
582 
583  if (set_initial_path)
584  {
594  }
595 
596  std::string tpath = load_path::command_line_path;
597 
598  if (tpath.empty ())
599  tpath = octave_env::getenv ("OCTAVE_PATH");
600 
601  std::string xpath;
602 
603  if (! tpath.empty ())
604  {
605  xpath = tpath;
606 
607  if (! sys_path.empty ())
608  xpath += dir_path::path_sep_str () + sys_path;
609  }
610  else
611  xpath = sys_path;
612 
613  do_set (xpath, false, true);
614 }
615 
616 void
618 {
619  dir_info_list.clear ();
620 
622 
623  loader_map.clear ();
624 }
625 
626 static std::list<std::string>
627 split_path (const std::string& p)
628 {
629  std::list<std::string> retval;
630 
631  size_t beg = 0;
632  size_t end = p.find (dir_path::path_sep_char ());
633 
634  size_t len = p.length ();
635 
636  while (end != std::string::npos)
637  {
638  std::string elt = p.substr (beg, end-beg);
639 
640  if (! elt.empty ())
641  retval.push_back (elt);
642 
643  beg = end + 1;
644 
645  if (beg == len)
646  break;
647 
648  end = p.find (dir_path::path_sep_char (), beg);
649  }
650 
651  std::string elt = p.substr (beg);
652 
653  if (! elt.empty ())
654  retval.push_back (elt);
655 
656  return retval;
657 }
658 
659 void
660 load_path::do_set (const std::string& p, bool warn, bool is_init)
661 {
662  // Use a list when we need to preserve order.
663  std::list<std::string> elts = split_path (p);
664 
665  // Use a set when we need to search and order is not important.
666  std::set<std::string> elts_set (elts.begin (), elts.end ());
667 
668  if (is_init)
669  init_dirs = elts_set;
670  else
671  {
672  for (std::set<std::string>::const_iterator it = init_dirs.begin ();
673  it != init_dirs.end (); it++)
674  {
675  if (elts_set.find (*it) == elts_set.end ())
676  {
677  warning_with_id ("Octave:remove-init-dir",
678  "default load path altered. Some built-in functions may not be found. Try restoredefaultpath() to recover it.");
679  break;
680  }
681  }
682  }
683 
684  // Temporarily disable add hook.
685 
686  unwind_protect frame;
687  frame.protect_var (add_hook);
688 
689  add_hook = 0;
690 
691  do_clear ();
692 
693  for (std::list<std::string>::const_iterator i = elts.begin ();
694  i != elts.end (); i++)
695  do_append (*i, warn);
696 
697  // Restore add hook and execute for all newly added directories.
698  frame.run_first ();
699 
700  for (dir_info_list_iterator i = dir_info_list.begin ();
701  i != dir_info_list.end ();
702  i++)
703  {
704  if (add_hook)
705  add_hook (i->dir_name);
706  }
707 
708  // Always prepend current directory.
709  do_prepend (".", warn);
710 }
711 
712 void
713 load_path::do_append (const std::string& dir, bool warn)
714 {
715  if (! dir.empty ())
716  do_add (dir, true, warn);
717 }
718 
719 void
720 load_path::do_prepend (const std::string& dir, bool warn)
721 {
722  if (! dir.empty ())
723  do_add (dir, false, warn);
724 }
725 
726 // Strip trailing directory separators.
727 
728 static std::string
729 strip_trailing_separators (const std::string& dir_arg)
730 {
731  std::string dir = dir_arg;
732 
733  size_t k = dir.length ();
734 
735  while (k > 1 && file_ops::is_dir_sep (dir[k-1]))
736  k--;
737 
738  if (k < dir.length ())
739  dir.resize (k);
740 
741  return dir;
742 }
743 
744 void
745 load_path::do_add (const std::string& dir_arg, bool at_end, bool warn)
746 {
747  size_t len = dir_arg.length ();
748 
749  if (len > 1 && dir_arg.substr (len-2) == "//")
750  warning_with_id ("Octave:recursive-path-search",
751  "trailing '//' is no longer special in search path elements");
752 
753  std::string dir = file_ops::tilde_expand (dir_arg);
754 
755  dir = strip_trailing_separators (dir);
756 
758 
759  if (i != dir_info_list.end ())
760  do_move (i, at_end);
761  else
762  {
763  file_stat fs (dir);
764 
765  if (fs)
766  {
767  if (fs.is_dir ())
768  {
769  dir_info di (dir);
770 
771  if (! error_state)
772  {
773  if (at_end)
774  dir_info_list.push_back (di);
775  else
776  dir_info_list.push_front (di);
777 
778  add (di, at_end);
779 
780  if (add_hook)
781  add_hook (dir);
782  }
783  }
784  else if (warn)
785  warning ("addpath: %s: not a directory", dir_arg.c_str ());
786  }
787  else if (warn)
788  {
789  std::string msg = fs.error ();
790  warning ("addpath: %s: %s", dir_arg.c_str (), msg.c_str ());
791  }
792  }
793 
794  // FIXME: is there a better way to do this?
795 
796  i = find_dir_info (".");
797 
798  if (i != dir_info_list.end ())
799  do_move (i, false);
800 }
801 
802 void
803 load_path::loader::remove_fcn_map (const std::string& dir,
804  const string_vector& fcn_files)
805 {
806  octave_idx_type len = fcn_files.length ();
807 
808  for (octave_idx_type k = 0; k < len; k++)
809  {
810  std::string fname = fcn_files[k];
811 
812  std::string ext;
813  std::string base = fname;
814 
815  size_t pos = fname.rfind ('.');
816 
817  if (pos != std::string::npos)
818  {
819  base = fname.substr (0, pos);
820  ext = fname.substr (pos);
821  }
822 
823  file_info_list_type& file_info_list = fcn_map[base];
824 
825  for (file_info_list_iterator p = file_info_list.begin ();
826  p != file_info_list.end ();
827  p++)
828  {
829  if (p->dir_name == dir)
830  {
831  file_info_list.erase (p);
832 
833  if (file_info_list.empty ())
834  fcn_map.erase (fname);
835 
836  break;
837  }
838  }
839  }
840 }
841 
842 void
844 {
845  private_fcn_map_iterator p = private_fcn_map.find (dir);
846 
847  if (p != private_fcn_map.end ())
848  private_fcn_map.erase (p);
849 }
850 
851 void
852 load_path::loader::remove_method_map (const std::string& dir)
853 {
854  for (method_map_iterator i = method_map.begin ();
855  i != method_map.end ();
856  i++)
857  {
858  std::string class_name = i->first;
859 
860  fcn_map_type& fm = i->second;
861 
862  std::string full_dir_name = file_ops::concat (dir, "@" + class_name);
863 
864  for (fcn_map_iterator q = fm.begin (); q != fm.end (); q++)
865  {
866  file_info_list_type& file_info_list = q->second;
867 
868  if (file_info_list.size () == 1)
869  continue;
870  else
871  {
872  for (file_info_list_iterator p = file_info_list.begin ();
873  p != file_info_list.end (); p++)
874  {
875  if (p->dir_name == full_dir_name)
876  {
877  file_info_list.erase (p);
878 
879  // FIXME: if there are no other elements, we
880  // should remove this element of fm but calling
881  // erase here would invalidate the iterator q.
882 
883  break;
884  }
885  }
886  }
887  }
888  }
889 }
890 
891 bool
892 load_path::do_remove (const std::string& dir_arg)
893 {
894  bool retval = false;
895 
896  if (! dir_arg.empty ())
897  {
898  if (dir_arg == ".")
899  {
900  warning ("rmpath: can't remove \".\" from path");
901 
902  // Avoid additional warnings.
903  retval = true;
904  }
905  else
906  {
907  std::string dir = file_ops::tilde_expand (dir_arg);
908 
909  dir = strip_trailing_separators (dir);
910 
912 
913  if (i != dir_info_list.end ())
914  {
915  retval = true;
916 
917  if (remove_hook)
918  remove_hook (dir);
919 
920  dir_info& di = *i;
921 
922  remove (di);
923 
924  dir_info_list.erase (i);
925  }
926  }
927  }
928 
929  return retval;
930 }
931 
932 void
933 load_path::remove (const dir_info& di, const std::string& pname)
934 {
935  loader& l = get_loader (pname);
936 
937  l.remove (di);
938 
939  dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
940 
941  for (dir_info::const_package_dir_map_iterator p = package_dir_map.begin ();
942  p != package_dir_map.end (); ++p)
943  {
944  std::string full_name = p->first;
945 
946  if (! pname.empty ())
947  full_name = pname + "." + full_name;
948 
949  remove (p->second, full_name);
950  }
951 }
952 
953 void
955 {
956  std::string dir = di.dir_name;
957 
958  string_vector fcn_files = di.fcn_files;
959 
960  dir_list.remove (dir);
961 
962  remove_fcn_map (dir, fcn_files);
963 
964  remove_private_fcn_map (dir);
965 
966  remove_method_map (dir);
967 }
968 
969 void
971 {
972  // I don't see a better way to do this because we need to
973  // preserve the correct directory ordering for new files that
974  // have appeared.
975 
977 
978  loader_map.clear ();
979 
980  for (dir_info_list_iterator p = dir_info_list.begin ();
981  p != dir_info_list.end ();
982  p++)
983  {
984  dir_info& di = *p;
985 
986  di.update ();
987 
988  add (di, true);
989  }
990 }
991 
992 bool
993 load_path::check_file_type (std::string& fname, int type, int possible_types,
994  const std::string& fcn, const char *who)
995 {
996  bool retval = false;
997 
998  if (type == load_path::OCT_FILE)
999  {
1000  if ((type & possible_types) == load_path::OCT_FILE)
1001  {
1002  fname += ".oct";
1003  retval = true;
1004  }
1005  }
1006  else if (type == load_path::M_FILE)
1007  {
1008  if ((type & possible_types) == load_path::M_FILE)
1009  {
1010  fname += ".m";
1011  retval = true;
1012  }
1013  }
1014  else if (type == load_path::MEX_FILE)
1015  {
1016  if ((type & possible_types) == load_path::MEX_FILE)
1017  {
1018  fname += ".mex";
1019  retval = true;
1020  }
1021  }
1022  else if (type == (load_path::M_FILE | load_path::OCT_FILE))
1023  {
1024  if (possible_types & load_path::OCT_FILE)
1025  {
1026  fname += ".oct";
1027  retval = true;
1028  }
1029  else if (possible_types & load_path::M_FILE)
1030  {
1031  fname += ".m";
1032  retval = true;
1033  }
1034  }
1035  else if (type == (load_path::M_FILE | load_path::MEX_FILE))
1036  {
1037  if (possible_types & load_path::MEX_FILE)
1038  {
1039  fname += ".mex";
1040  retval = true;
1041  }
1042  else if (possible_types & load_path::M_FILE)
1043  {
1044  fname += ".m";
1045  retval = true;
1046  }
1047  }
1048  else if (type == (load_path::OCT_FILE | load_path::MEX_FILE))
1049  {
1050  if (possible_types & load_path::OCT_FILE)
1051  {
1052  fname += ".oct";
1053  retval = true;
1054  }
1055  else if (possible_types & load_path::MEX_FILE)
1056  {
1057  fname += ".mex";
1058  retval = true;
1059  }
1060  }
1061  else if (type == (load_path::M_FILE | load_path::OCT_FILE
1063  {
1064  if (possible_types & load_path::OCT_FILE)
1065  {
1066  fname += ".oct";
1067  retval = true;
1068  }
1069  else if (possible_types & load_path::MEX_FILE)
1070  {
1071  fname += ".mex";
1072  retval = true;
1073  }
1074  else if (possible_types & load_path::M_FILE)
1075  {
1076  fname += ".m";
1077  retval = true;
1078  }
1079  }
1080  else
1081  error ("%s: %s: invalid type code = %d", who, fcn.c_str (), type);
1082 
1083  return retval;
1084 }
1085 
1086 std::string
1087 load_path::loader::find_fcn (const std::string& fcn, std::string& dir_name,
1088  int type) const
1089 {
1090  std::string retval;
1091 
1092  // update ();
1093 
1094  if (fcn.length () > 0 && fcn[0] == '@')
1095  {
1096  size_t pos = fcn.find ('/');
1097 
1098  if (pos != std::string::npos)
1099  {
1100  std::string class_name = fcn.substr (1, pos-1);
1101  std::string meth = fcn.substr (pos+1);
1102 
1103  retval = find_method (class_name, meth, dir_name);
1104  }
1105  else
1106  retval = std::string ();
1107  }
1108  else
1109  {
1110  dir_name = std::string ();
1111 
1112  const_fcn_map_iterator p = fcn_map.find (fcn);
1113 
1114  if (p != fcn_map.end ())
1115  {
1116  const file_info_list_type& file_info_list = p->second;
1117 
1118  for (const_file_info_list_iterator i = file_info_list.begin ();
1119  i != file_info_list.end ();
1120  i++)
1121  {
1122  const file_info& fi = *i;
1123 
1124  retval = file_ops::concat (fi.dir_name, fcn);
1125 
1126  if (check_file_type (retval, type, fi.types,
1127  fcn, "load_path::do_find_fcn"))
1128  {
1129  dir_name = fi.dir_name;
1130  break;
1131  }
1132  else
1133  retval = std::string ();
1134  }
1135  }
1136  }
1137 
1138  return retval;
1139 }
1140 
1141 std::string
1142 load_path::loader::find_private_fcn (const std::string& dir,
1143  const std::string& fcn, int type) const
1144 {
1145  std::string retval;
1146 
1147  // update ();
1148 
1149  const_private_fcn_map_iterator q = private_fcn_map.find (dir);
1150 
1151  if (q != private_fcn_map.end ())
1152  {
1153  const dir_info::fcn_file_map_type& m = q->second;
1154 
1155  dir_info::const_fcn_file_map_iterator p = m.find (fcn);
1156 
1157  if (p != m.end ())
1158  {
1159  std::string fname
1160  = file_ops::concat (file_ops::concat (dir, "private"), fcn);
1161 
1162  if (check_file_type (fname, type, p->second, fcn,
1163  "load_path::find_private_fcn"))
1164  retval = fname;
1165  }
1166  }
1167 
1168  return retval;
1169 }
1170 
1171 std::string
1172 load_path::loader::find_method (const std::string& class_name,
1173  const std::string& meth,
1174  std::string& dir_name, int type) const
1175 {
1176  std::string retval;
1177 
1178  // update ();
1179 
1180  dir_name = std::string ();
1181 
1182  const_method_map_iterator q = method_map.find (class_name);
1183 
1184  if (q != method_map.end ())
1185  {
1186  const fcn_map_type& m = q->second;
1187 
1188  const_fcn_map_iterator p = m.find (meth);
1189 
1190  if (p != m.end ())
1191  {
1192  const file_info_list_type& file_info_list = p->second;
1193 
1194  for (const_file_info_list_iterator i = file_info_list.begin ();
1195  i != file_info_list.end ();
1196  i++)
1197  {
1198  const file_info& fi = *i;
1199 
1200  retval = file_ops::concat (fi.dir_name, meth);
1201 
1202  bool found = check_file_type (retval, type, fi.types,
1203  meth, "load_path::do_find_method");
1204 
1205  if (found)
1206  {
1207  dir_name = fi.dir_name;
1208  break;
1209  }
1210  else
1211  retval = std::string ();
1212  }
1213  }
1214  }
1215 
1216  return retval;
1217 }
1218 
1219 std::list<std::string>
1220 load_path::loader::methods (const std::string& class_name) const
1221 {
1222  std::list<std::string> retval;
1223 
1224  // update ();
1225 
1226  const_method_map_iterator q = method_map.find (class_name);
1227 
1228  if (q != method_map.end ())
1229  {
1230  const fcn_map_type& m = q->second;
1231 
1232  for (const_fcn_map_iterator p = m.begin (); p != m.end (); p++)
1233  retval.push_back (p->first);
1234  }
1235 
1236  if (! retval.empty ())
1237  retval.sort ();
1238 
1239  return retval;
1240 }
1241 
1242 bool
1243 load_path::is_package (const std::string& name) const
1244 {
1245  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1246  p != dir_info_list.end ();
1247  p++)
1248  {
1249  if (p->is_package (name))
1250  return true;
1251  }
1252 
1253  return false;
1254 }
1255 
1256 std::list<std::string>
1257 load_path::do_overloads (const std::string& meth) const
1258 {
1259  std::list<std::string> retval;
1260 
1261  // update ();
1262 
1263  default_loader.overloads (meth, retval);
1264 
1265  for (const_loader_map_iterator l = loader_map.begin ();
1266  l != loader_map.end (); ++l)
1267  l->second.overloads (meth, retval);
1268 
1269  return retval;
1270 }
1271 
1272 void
1273 load_path::loader::overloads (const std::string& meth,
1274  std::list<std::string>& l) const
1275 {
1276  for (const_method_map_iterator q = method_map.begin ();
1277  q != method_map.end (); q++)
1278  {
1279  const fcn_map_type& m = q->second;
1280 
1281  if (m.find (meth) != m.end ())
1282  {
1283  std::string class_name = q->first;
1284 
1285  if (! prefix.empty ())
1286  class_name = prefix + "." + class_name;
1287 
1288  l.push_back (class_name);
1289  }
1290  }
1291 }
1292 
1293 // Should we cache all files in private directories, or is it OK to just
1294 // look them up each time as needed?
1295 
1296 std::string
1297 find_private_file (const std::string& fname)
1298 {
1299  std::string retval;
1300 
1301  // Look in private directory corresponding to current function (if
1302  // any).
1303 
1305 
1306  if (curr_fcn)
1307  {
1308  // Even for private functions, dir_name doesn't contain the
1309  // "private" directory component so we append it here in all
1310  // cases.
1311 
1312  std::string dir_name = curr_fcn->dir_name ();
1313 
1314  if (! dir_name.empty ())
1315  {
1316  std::string pfname = dir_name + file_ops::dir_sep_str ()
1317  + "private" + file_ops::dir_sep_str () + fname;
1318 
1319  file_stat fs (pfname);
1320 
1321  if (fs.exists () && fs.is_reg ())
1322  retval = pfname;
1323  }
1324  }
1325 
1326  return retval;
1327 }
1328 
1329 std::string
1330 load_path::do_find_file (const std::string& file) const
1331 {
1332  std::string retval;
1333 
1336  {
1337  file_stat fs (file);
1338 
1339  return fs.exists () ? file : retval;
1340  }
1341  else
1342  {
1343  std::string tfile = find_private_file (file);
1344 
1345  if (! tfile.empty ())
1346  return tfile;
1347  }
1348 
1349  if (file.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos)
1350  {
1351  // Given name has a directory separator, so append it to each
1352  // element of the load path in turn.
1353 
1354  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1355  p != dir_info_list.end ();
1356  p++)
1357  {
1358  std::string tfile = file_ops::concat (p->dir_name, file);
1359 
1360  file_stat fs (tfile);
1361 
1362  if (fs.exists ())
1363  return tfile;
1364  }
1365  }
1366  else
1367  {
1368  // Look in cache.
1369 
1370  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1371  p != dir_info_list.end ();
1372  p++)
1373  {
1374  string_vector all_files = p->all_files;
1375 
1376  octave_idx_type len = all_files.length ();
1377 
1378  for (octave_idx_type i = 0; i < len; i++)
1379  {
1380  if (all_files[i] == file)
1381  return file_ops::concat (p->dir_name, file);
1382  }
1383  }
1384  }
1385 
1386  return retval;
1387 }
1388 
1389 std::string
1390 load_path::do_find_dir (const std::string& dir) const
1391 {
1392  std::string retval;
1393 
1394  if (dir.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos
1397  {
1398  file_stat fs (dir);
1399 
1400  if (fs.exists () && fs.is_dir ())
1401  return dir;
1402  }
1403  else
1404  {
1405  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1406  p != dir_info_list.end ();
1407  p++)
1408  {
1409  std::string dname = octave_env::make_absolute (p->dir_name);
1410 
1411  size_t dname_len = dname.length ();
1412 
1413  if (dname.substr (dname_len - 1) == file_ops::dir_sep_str ())
1414  {
1415  dname = dname.substr (0, dname_len - 1);
1416  dname_len--;
1417  }
1418 
1419  size_t dir_len = dir.length ();
1420 
1421  if (dname_len > dir_len
1422  && file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
1423  && dir.compare (dname.substr (dname_len - dir_len)) == 0)
1424  {
1425  file_stat fs (p->dir_name);
1426 
1427  if (fs.exists () && fs.is_dir ())
1428  return p->dir_name;
1429  }
1430  }
1431  }
1432 
1433  return retval;
1434 }
1435 
1437 load_path::do_find_matching_dirs (const std::string& dir) const
1438 {
1439  std::list<std::string> retlist;
1440 
1441  if (dir.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos
1444  {
1445  file_stat fs (dir);
1446 
1447  if (fs.exists () && fs.is_dir ())
1448  retlist.push_back (dir);
1449  }
1450  else
1451  {
1452  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1453  p != dir_info_list.end ();
1454  p++)
1455  {
1456  std::string dname = octave_env::make_absolute (p->dir_name);
1457 
1458  size_t dname_len = dname.length ();
1459 
1460  if (dname.substr (dname_len - 1) == file_ops::dir_sep_str ())
1461  {
1462  dname = dname.substr (0, dname_len - 1);
1463  dname_len--;
1464  }
1465 
1466  size_t dir_len = dir.length ();
1467 
1468  if (dname_len > dir_len
1469  && file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
1470  && dir.compare (dname.substr (dname_len - dir_len)) == 0)
1471  {
1472  file_stat fs (p->dir_name);
1473 
1474  if (fs.exists () && fs.is_dir ())
1475  retlist.push_back (p->dir_name);
1476  }
1477  }
1478  }
1479 
1480  return retlist;
1481 }
1482 
1483 std::string
1485 {
1486  std::string retval;
1487 
1488  std::string dir_name;
1489  std::string file_name;
1490 
1491  octave_idx_type flen = flist.length ();
1492  octave_idx_type rel_flen = 0;
1493 
1494  string_vector rel_flist (flen);
1495 
1496  for (octave_idx_type i = 0; i < flen; i++)
1497  {
1498  std::string file = flist[i];
1499 
1500  if (file.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos)
1501  {
1504  {
1505  file_stat fs (file);
1506 
1507  if (fs.exists ())
1508  return file;
1509  }
1510  else
1511  {
1512  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1513  p != dir_info_list.end ();
1514  p++)
1515  {
1516  std::string tfile = file_ops::concat (p->dir_name, file);
1517 
1518  file_stat fs (tfile);
1519 
1520  if (fs.exists ())
1521  return tfile;
1522  }
1523  }
1524  }
1525  else
1526  rel_flist[rel_flen++] = file;
1527  }
1528 
1529  rel_flist.resize (rel_flen);
1530 
1531  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1532  p != dir_info_list.end ();
1533  p++)
1534  {
1535  string_vector all_files = p->all_files;
1536 
1537  octave_idx_type len = all_files.length ();
1538 
1539  for (octave_idx_type i = 0; i < len; i++)
1540  {
1541  for (octave_idx_type j = 0; j < rel_flen; j++)
1542  {
1543  if (all_files[i] == rel_flist[j])
1544  {
1545  dir_name = p->dir_name;
1546  file_name = rel_flist[j];
1547 
1548  goto done;
1549  }
1550  }
1551  }
1552  }
1553 
1554 done:
1555 
1556  if (! dir_name.empty ())
1557  retval = file_ops::concat (dir_name, file_name);
1558 
1559  return retval;
1560 }
1561 
1564 {
1565  std::list<std::string> retlist;
1566 
1567  std::string dir_name;
1568  std::string file_name;
1569 
1570  octave_idx_type flen = flist.length ();
1571  octave_idx_type rel_flen = 0;
1572 
1573  string_vector rel_flist (flen);
1574 
1575  for (octave_idx_type i = 0; i < flen; i++)
1576  {
1577  std::string file = flist[i];
1578 
1579  if (file.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos)
1580  {
1583  {
1584  file_stat fs (file);
1585 
1586  if (fs.exists ())
1587  retlist.push_back (file);
1588  }
1589  else
1590  {
1591  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1592  p != dir_info_list.end ();
1593  p++)
1594  {
1595  std::string tfile = file_ops::concat (p->dir_name, file);
1596 
1597  file_stat fs (tfile);
1598 
1599  if (fs.exists ())
1600  retlist.push_back (tfile);
1601  }
1602  }
1603  }
1604  else
1605  rel_flist[rel_flen++] = file;
1606  }
1607 
1608  rel_flist.resize (rel_flen);
1609 
1610  for (const_dir_info_list_iterator p = dir_info_list.begin ();
1611  p != dir_info_list.end (); p++)
1612  {
1613  string_vector all_files = p->all_files;
1614 
1615  octave_idx_type len = all_files.length ();
1616 
1617  for (octave_idx_type i = 0; i < len; i++)
1618  {
1619  for (octave_idx_type j = 0; j < rel_flen; j++)
1620  {
1621  if (all_files[i] == rel_flist[j])
1622  retlist.push_back (file_ops::concat (p->dir_name,
1623  rel_flist[j]));
1624  }
1625  }
1626  }
1627 
1628  return retlist;
1629 }
1630 
1633 {
1634  size_t len = dir_info_list.size ();
1635 
1636  string_vector retval (len);
1637 
1638  octave_idx_type k = 0;
1639 
1640  for (const_dir_info_list_iterator i = dir_info_list.begin ();
1641  i != dir_info_list.end ();
1642  i++)
1643  retval[k++] = i->dir_name;
1644 
1645  return retval;
1646 }
1647 
1648 std::list<std::string>
1650 {
1651  std::list<std::string> retval;
1652 
1653  for (const_dir_info_list_iterator i = dir_info_list.begin ();
1654  i != dir_info_list.end ();
1655  i++)
1656  retval.push_back (i->dir_name);
1657 
1658  return retval;
1659 }
1660 
1662 load_path::do_files (const std::string& dir, bool omit_exts) const
1663 {
1664  string_vector retval;
1665 
1667 
1668  if (p != dir_info_list.end ())
1669  retval = p->fcn_files;
1670 
1671  if (omit_exts)
1672  {
1673  octave_idx_type len = retval.length ();
1674 
1675  for (octave_idx_type i = 0; i < len; i++)
1676  {
1677  std::string fname = retval[i];
1678 
1679  size_t pos = fname.rfind ('.');
1680 
1681  if (pos != std::string::npos)
1682  retval[i] = fname.substr (0, pos);
1683  }
1684  }
1685 
1686  return retval;
1687 }
1688 
1691 {
1692  return default_loader.fcn_names ();
1693 }
1694 
1697 {
1698  size_t len = fcn_map.size ();
1699 
1700  string_vector retval (len);
1701 
1702  octave_idx_type count = 0;
1703 
1704  for (const_fcn_map_iterator p = fcn_map.begin ();
1705  p != fcn_map.end ();
1706  p++)
1707  retval[count++] = p->first;
1708 
1709  return retval;
1710 }
1711 
1712 std::string
1714 {
1715  std::string xpath;
1716 
1717  string_vector xdirs = load_path::dirs ();
1718 
1719  octave_idx_type len = xdirs.length ();
1720 
1721  if (len > 0)
1722  xpath = xdirs[0];
1723 
1724  for (octave_idx_type i = 1; i < len; i++)
1725  xpath += dir_path::path_sep_str () + xdirs[i];
1726 
1727  return xpath;
1728 }
1729 
1730 void
1731 print_types (std::ostream& os, int types)
1732 {
1733  bool printed_type = false;
1734 
1735  if (types & load_path::OCT_FILE)
1736  {
1737  os << "oct";
1738  printed_type = true;
1739  }
1740 
1741  if (types & load_path::MEX_FILE)
1742  {
1743  if (printed_type)
1744  os << "|";
1745  os << "mex";
1746  printed_type = true;
1747  }
1748 
1749  if (types & load_path::M_FILE)
1750  {
1751  if (printed_type)
1752  os << "|";
1753  os << "m";
1754  printed_type = true;
1755  }
1756 }
1757 
1758 void
1759 print_fcn_list (std::ostream& os,
1761 {
1763  p != lst.end ();
1764  p++)
1765  {
1766  os << " " << p->first << " (";
1767 
1768  print_types (os, p->second);
1769 
1770  os << ")\n";
1771  }
1772 }
1773 
1776 {
1777  octave_idx_type n = lst.size ();
1778 
1779  string_vector retval (n);
1780 
1781  octave_idx_type count = 0;
1782 
1784  p != lst.end ();
1785  p++)
1786  {
1787  std::string nm = p->first;
1788 
1789  int types = p->second;
1790 
1791  if (types & load_path::OCT_FILE)
1792  nm += ".oct";
1793  else if (types & load_path::MEX_FILE)
1794  nm += ".mex";
1795  else
1796  nm += ".m";
1797 
1798  retval[count++] = nm;
1799  }
1800 
1801  return retval;
1802 }
1803 
1804 void
1805 load_path::do_display (std::ostream& os) const
1806 {
1807  for (const_dir_info_list_iterator i = dir_info_list.begin ();
1808  i != dir_info_list.end ();
1809  i++)
1810  {
1811  string_vector fcn_files = i->fcn_files;
1812 
1813  if (! fcn_files.empty ())
1814  {
1815  os << "\n*** function files in " << i->dir_name << ":\n\n";
1816 
1817  fcn_files.list_in_columns (os);
1818  }
1819 
1820  const dir_info::method_file_map_type& method_file_map
1821  = i->method_file_map;
1822 
1823  if (! method_file_map.empty ())
1824  {
1826  p = method_file_map.begin (); p != method_file_map.end (); p++)
1827  {
1828  os << "\n*** methods in " << i->dir_name
1829  << "/@" << p->first << ":\n\n";
1830 
1831  const dir_info::class_info& ci = p->second;
1832 
1833  string_vector method_files = get_file_list (ci.method_file_map);
1834 
1835  method_files.list_in_columns (os);
1836  }
1837  }
1838  }
1839 
1840  default_loader.display (os);
1841 
1842  for (const_loader_map_iterator l = loader_map.begin ();
1843  l != loader_map.end (); ++l)
1844  l->second.display (os);
1845 }
1846 
1847 // True if a path is contained in a path list separated by path_sep_char
1848 static bool
1849 in_path_list (const std::string& path_list, const std::string& path)
1850 {
1851  size_t ps = path.size ();
1852  size_t pls = path_list.size ();
1853  size_t pos = path_list.find (path);
1854  char psc = dir_path::path_sep_char ();
1855  while (pos != std::string::npos)
1856  {
1857  if ((pos == 0 || path_list[pos-1] == psc)
1858  && (pos + ps == pls || path_list[pos + ps] == psc))
1859  return true;
1860  else
1861  pos = path_list.find (path, pos + 1);
1862  }
1863 
1864  return false;
1865 }
1866 
1867 void
1868 load_path::add (const dir_info& di, bool at_end,
1869  const std::string& pname) const
1870 {
1871  loader& l = get_loader (pname);
1872 
1873  l.add (di, at_end);
1874 
1875  dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1876 
1877  for (dir_info::const_package_dir_map_iterator p = package_dir_map.begin ();
1878  p != package_dir_map.end (); ++p)
1879  {
1880  std::string full_name = p->first;
1881 
1882  if (! pname.empty ())
1883  full_name = pname + "." + full_name;
1884 
1885  add (p->second, at_end, full_name);
1886  }
1887 }
1888 
1889 void
1891 {
1892  std::string dir_name = di.dir_name;
1893 
1894  string_vector fcn_files = di.fcn_files;
1895 
1896  octave_idx_type len = fcn_files.length ();
1897 
1898  for (octave_idx_type i = 0; i < len; i++)
1899  {
1900  std::string fname = fcn_files[i];
1901 
1902  std::string ext;
1903  std::string base = fname;
1904 
1905  size_t pos = fname.rfind ('.');
1906 
1907  if (pos != std::string::npos)
1908  {
1909  base = fname.substr (0, pos);
1910  ext = fname.substr (pos);
1911  }
1912 
1913  file_info_list_type& file_info_list = fcn_map[base];
1914 
1915  file_info_list_iterator p = file_info_list.begin ();
1916 
1917  while (p != file_info_list.end ())
1918  {
1919  if (p->dir_name == dir_name)
1920  break;
1921 
1922  p++;
1923  }
1924 
1925  int t = 0;
1926  if (ext == ".m")
1927  t = load_path::M_FILE;
1928  else if (ext == ".oct")
1929  t = load_path::OCT_FILE;
1930  else if (ext == ".mex")
1931  t = load_path::MEX_FILE;
1932 
1933  if (p == file_info_list.end ())
1934  {
1935  file_info fi (dir_name, t);
1936 
1937  if (at_end)
1938  file_info_list.push_back (fi);
1939  else
1940  {
1941  // Warn if a built-in or library function is being shadowed.
1942 
1943  if (! file_info_list.empty ())
1944  {
1945  file_info& old = file_info_list.front ();
1946 
1947  // FIXME: do we need to be more careful about the
1948  // way we look for old.dir_name in sys_path to avoid
1949  // partial matches?
1950 
1951  // Don't warn about Contents.m files since we expect
1952  // more than one to exist in the load path.
1953 
1954  if (fname != "Contents.m"
1955  && sys_path.find (old.dir_name) != std::string::npos
1956  && in_path_list (sys_path, old.dir_name))
1957  {
1958  std::string fcn_path = file_ops::concat (dir_name, fname);
1959 
1960  warning_with_id ("Octave:shadowed-function",
1961  "function %s shadows a core library function",
1962  fcn_path.c_str ());
1963  }
1964  }
1966  {
1967  std::string fcn_path = file_ops::concat (dir_name, fname);
1968  warning_with_id ("Octave:shadowed-function",
1969  "function %s shadows a built-in function",
1970  fcn_path.c_str ());
1971  }
1972 
1973  file_info_list.push_front (fi);
1974  }
1975  }
1976  else
1977  {
1978  file_info& fi = *p;
1979 
1980  fi.types |= t;
1981  }
1982  }
1983 }
1984 
1985 void
1987 {
1988  dir_info::fcn_file_map_type private_file_map = di.private_file_map;
1989 
1990  if (! private_file_map.empty ())
1991  private_fcn_map[di.dir_name] = private_file_map;
1992 }
1993 
1994 void
1996 {
1997  std::string dir_name = di.dir_name;
1998 
1999  // <CLASS_NAME, CLASS_INFO>
2000  dir_info::method_file_map_type method_file_map = di.method_file_map;
2001 
2002  for (dir_info::const_method_file_map_iterator q = method_file_map.begin ();
2003  q != method_file_map.end ();
2004  q++)
2005  {
2006  std::string class_name = q->first;
2007 
2008  fcn_map_type& fm = method_map[class_name];
2009 
2010  std::string full_dir_name
2011  = file_ops::concat (dir_name, "@" + class_name);
2012 
2013  const dir_info::class_info& ci = q->second;
2014 
2015  // <FCN_NAME, TYPES>
2017 
2018  for (dir_info::const_fcn_file_map_iterator p = m.begin ();
2019  p != m.end ();
2020  p++)
2021  {
2022  std::string base = p->first;
2023 
2024  int types = p->second;
2025 
2026  file_info_list_type& file_info_list = fm[base];
2027 
2028  file_info_list_iterator p2 = file_info_list.begin ();
2029 
2030  while (p2 != file_info_list.end ())
2031  {
2032  if (p2->dir_name == full_dir_name)
2033  break;
2034 
2035  p2++;
2036  }
2037 
2038  if (p2 == file_info_list.end ())
2039  {
2040  file_info fi (full_dir_name, types);
2041 
2042  if (at_end)
2043  file_info_list.push_back (fi);
2044  else
2045  file_info_list.push_front (fi);
2046  }
2047  else
2048  {
2049  // FIXME: is this possible?
2050 
2051  file_info& fi = *p2;
2052 
2053  fi.types = types;
2054  }
2055  }
2056 
2057  // <FCN_NAME, TYPES>
2058  dir_info::fcn_file_map_type private_file_map = ci.private_file_map;
2059 
2060  if (! private_file_map.empty ())
2061  private_fcn_map[full_dir_name] = private_file_map;
2062  }
2063 }
2064 
2065 void
2066 load_path::loader::display (std::ostream& os) const
2067 {
2068  os << "*** loader: " << (prefix.empty () ? "<top-level>" : prefix) << "\n\n";
2069 
2070  for (std::list<std::string>::const_iterator s = dir_list.begin ();
2071  s != dir_list.end (); ++s)
2072  os << *s << "\n";
2073  os << "\n";
2074 
2075  for (const_private_fcn_map_iterator i = private_fcn_map.begin ();
2076  i != private_fcn_map.end (); i++)
2077  {
2078  os << "\n*** private functions in "
2079  << file_ops::concat (i->first, "private") << ":\n\n";
2080 
2081  print_fcn_list (os, i->second);
2082  }
2083 
2084 #if defined (DEBUG_LOAD_PATH)
2085 
2086  for (const_fcn_map_iterator i = fcn_map.begin ();
2087  i != fcn_map.end ();
2088  i++)
2089  {
2090  os << i->first << ":\n";
2091 
2092  const file_info_list_type& file_info_list = i->second;
2093 
2094  for (const_file_info_list_iterator p = file_info_list.begin ();
2095  p != file_info_list.end ();
2096  p++)
2097  {
2098  os << " " << p->dir_name << " (";
2099 
2100  print_types (os, p->types);
2101 
2102  os << ")\n";
2103  }
2104  }
2105 
2106  for (const_method_map_iterator i = method_map.begin ();
2107  i != method_map.end ();
2108  i++)
2109  {
2110  os << "CLASS " << i->first << ":\n";
2111 
2112  const fcn_map_type& fm = i->second;
2113 
2114  for (const_fcn_map_iterator q = fm.begin ();
2115  q != fm.end ();
2116  q++)
2117  {
2118  os << " " << q->first << ":\n";
2119 
2120  const file_info_list_type& file_info_list = q->second;
2121 
2122  for (const_file_info_list_iterator p = file_info_list.begin ();
2123  p != file_info_list.end ();
2124  p++)
2125  {
2126  os << " " << p->dir_name << " (";
2127 
2128  print_types (os, p->types);
2129 
2130  os << ")\n";
2131  }
2132  }
2133  }
2134 
2135  os << "\n";
2136 
2137 #endif
2138 }
2139 
2140 std::string
2141 genpath (const std::string& dirname, const string_vector& skip)
2142 {
2143  std::string retval;
2144 
2145  dir_entry dir (dirname);
2146 
2147  if (dir)
2148  {
2149  retval = dirname;
2150 
2151  string_vector dirlist = dir.read ().sort (false);
2152 
2153  octave_idx_type len = dirlist.length ();
2154 
2155  for (octave_idx_type i = 0; i < len; i++)
2156  {
2157  std::string elt = dirlist[i];
2158 
2159  bool skip_p = (elt == "." || elt == ".." || elt[0] == '@'
2160  || elt[0] == '+');
2161 
2162  if (! skip_p)
2163  {
2164  for (octave_idx_type j = 0; j < skip.length (); j++)
2165  {
2166  skip_p = (elt == skip[j]);
2167  if (skip_p)
2168  break;
2169  }
2170 
2171  if (! skip_p)
2172  {
2173  std::string nm = file_ops::concat (dirname, elt);
2174 
2175  file_stat fs (nm);
2176 
2177  if (fs && fs.is_dir ())
2178  retval += dir_path::path_sep_str () + genpath (nm, skip);
2179  }
2180  }
2181  }
2182  }
2183 
2184  return retval;
2185 }
2186 
2187 std::list<std::string>
2188 load_path::do_get_all_package_names (bool only_top_level) const
2189 {
2190  std::list<std::string> retval;
2191 
2192  for (const_loader_map_iterator l = loader_map.begin ();
2193  l != loader_map.end (); ++l)
2194  {
2195  if (! only_top_level || l->first.find ('.') == std::string::npos)
2196  retval.push_back (l->first);
2197  }
2198 
2199  return retval;
2200 }
2201 
2202 static void
2203 execute_pkg_add_or_del (const std::string& dir,
2204  const std::string& script_file)
2205 {
2207  return;
2208 
2209  unwind_protect frame;
2210 
2211  std::string file = file_ops::concat (dir, script_file);
2212 
2213  file_stat fs (file);
2214 
2215  if (fs.exists ())
2216  source_file (file, "base");
2217 }
2218 
2219 void
2220 execute_pkg_add (const std::string& dir)
2221 {
2222  execute_pkg_add_or_del (dir, "PKG_ADD");
2223 }
2224 
2225 void
2226 execute_pkg_del (const std::string& dir)
2227 {
2228  execute_pkg_add_or_del (dir, "PKG_DEL");
2229 }
2230 
2231 DEFUN (genpath, args, ,
2232  "-*- texinfo -*-\n\
2233 @deftypefn {Built-in Function} {} genpath (@var{dir})\n\
2234 @deftypefnx {Built-in Function} {} genpath (@var{dir}, @var{skip}, @dots{})\n\
2235 Return a path constructed from @var{dir} and all its subdirectories.\n\
2236 \n\
2237 If additional string parameters are given, the resulting path will exclude\n\
2238 directories with those names.\n\
2239 @end deftypefn")
2240 {
2241  octave_value retval;
2242 
2243  octave_idx_type nargin = args.length ();
2244 
2245  if (nargin == 1)
2246  {
2247  std::string dirname = args(0).string_value ();
2248 
2249  if (! error_state)
2250  retval = genpath (dirname);
2251  else
2252  error ("genpath: DIR must be a string");
2253  }
2254  else if (nargin > 1)
2255  {
2256  std::string dirname = args(0).string_value ();
2257 
2258  string_vector skip (nargin - 1);
2259 
2260  for (octave_idx_type i = 1; i < nargin; i++)
2261  {
2262  skip[i-1] = args(i).string_value ();
2263 
2264  if (error_state)
2265  break;
2266  }
2267 
2268  if (! error_state)
2269  retval = genpath (dirname, skip);
2270  else
2271  error ("genpath: all arguments must be strings");
2272  }
2273  else
2274  print_usage ();
2275 
2276  return retval;
2277 }
2278 
2279 static void
2281 {
2282  load_path::update ();
2283 
2284  // FIXME: maybe we should rename this variable since it is being
2285  // used for more than keeping track of the prompt time.
2286 
2287  // This will force updated functions to be found.
2289 }
2290 
2291 DEFUN (rehash, , ,
2292  "-*- texinfo -*-\n\
2293 @deftypefn {Built-in Function} {} rehash ()\n\
2294 Reinitialize Octave's load path directory cache.\n\
2295 @end deftypefn")
2296 {
2297  octave_value_list retval;
2298 
2299  rehash_internal ();
2300 
2301  return retval;
2302 }
2303 
2305  "-*- texinfo -*-\n\
2306 @deftypefn {Built-in Function} {} command_line_path (@dots{})\n\
2307 Return the command line path variable.\n\
2308 \n\
2309 @seealso{path, addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\
2310 @end deftypefn")
2311 {
2313 }
2314 
2315 DEFUN (restoredefaultpath, , ,
2316  "-*- texinfo -*-\n\
2317 @deftypefn {Built-in Function} {} restoredefaultpath (@dots{})\n\
2318 Restore Octave's path to its initial state at startup.\n\
2319 \n\
2320 @seealso{path, addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\
2321 @end deftypefn")
2322 {
2323  load_path::initialize (true);
2324 
2326 }
2327 
2328 // Return Octave's original default list of directories in which to
2329 // search for function files. This corresponds to the path that
2330 // exists prior to running the system's octaverc file or the user's
2331 // ~/.octaverc file
2332 
2333 DEFUN (__pathorig__, , ,
2334  "-*- texinfo -*-\n\
2335 @deftypefn {Built-in Function} {@var{val} =} __pathorig__ ()\n\
2336 Undocumented internal function.\n\
2337 @end deftypefn")
2338 {
2340 }
2341 
2342 DEFUN (path, args, nargout,
2343  "-*- texinfo -*-\n\
2344 @deftypefn {Built-in Function} {} path (@dots{})\n\
2345 Modify or display Octave's load path.\n\
2346 \n\
2347 If @var{nargin} and @var{nargout} are zero, display the elements of\n\
2348 Octave's load path in an easy to read format.\n\
2349 \n\
2350 If @var{nargin} is zero and nargout is greater than zero, return the\n\
2351 current load path.\n\
2352 \n\
2353 If @var{nargin} is greater than zero, concatenate the arguments,\n\
2354 separating them with @code{pathsep}. Set the internal search path\n\
2355 to the result and return it.\n\
2356 \n\
2357 No checks are made for duplicate elements.\n\
2358 @seealso{addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\
2359 @end deftypefn")
2360 {
2361  octave_value retval;
2362 
2363  int argc = args.length () + 1;
2364 
2365  string_vector argv = args.make_argv ("path");
2366 
2367  if (! error_state)
2368  {
2369  if (argc > 1)
2370  {
2371  std::string path = argv[1];
2372 
2373  for (int i = 2; i < argc; i++)
2374  path += dir_path::path_sep_str () + argv[i];
2375 
2376  load_path::set (path, true);
2377 
2378  rehash_internal ();
2379  }
2380 
2381  if (nargout > 0)
2382  retval = load_path::path ();
2383  else if (argc == 1 && nargout == 0)
2384  {
2385  octave_stdout <<
2386  "\nOctave's search path contains the following directories:\n\n";
2387 
2389 
2391 
2392  octave_stdout << "\n";
2393  }
2394  }
2395 
2396  return retval;
2397 }
2398 
2399 DEFUN (addpath, args, nargout,
2400  "-*- texinfo -*-\n\
2401 @deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})\n\
2402 @deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})\n\
2403 Add named directories to the function search path.\n\
2404 \n\
2405 If @var{option} is @qcode{\"-begin\"} or 0 (the default), prepend the\n\
2406 directory name to the current path. If @var{option} is @qcode{\"-end\"}\n\
2407 or 1, append the directory name to the current path.\n\
2408 Directories added to the path must exist.\n\
2409 \n\
2410 In addition to accepting individual directory arguments, lists of\n\
2411 directory names separated by @code{pathsep} are also accepted. For example:\n\
2412 \n\
2413 @example\n\
2414 addpath (\"dir1:/dir2:~/dir3\")\n\
2415 @end example\n\
2416 @seealso{path, rmpath, genpath, pathdef, savepath, pathsep}\n\
2417 @end deftypefn")
2418 {
2419  octave_value retval;
2420 
2421  // Originally written by Bill Denney and Etienne Grossman. Heavily
2422  // modified and translated to C++ by jwe.
2423 
2424  if (nargout > 0)
2425  retval = load_path::path ();
2426 
2427  int nargin = args.length ();
2428 
2429  if (nargin > 0)
2430  {
2431  bool append = false;
2432 
2433  octave_value option_arg = args(nargin-1);
2434 
2435  if (option_arg.is_string ())
2436  {
2437  std::string option = option_arg.string_value ();
2438 
2439  if (option == "-end")
2440  {
2441  append = true;
2442  nargin--;
2443  }
2444  else if (option == "-begin")
2445  nargin--;
2446  }
2447  else if (option_arg.is_numeric_type ())
2448  {
2449  int val = option_arg.int_value ();
2450 
2451  if (! error_state)
2452  {
2453  if (val == 0)
2454  nargin--;
2455  else if (val == 1)
2456  {
2457  append = true;
2458  nargin--;
2459  }
2460  else
2461  {
2462  error ("addpath: expecting final argument to be 1 or 0");
2463  return retval;
2464  }
2465  }
2466  else
2467  {
2468  error ("addpath: expecting final argument to be 1 or 0");
2469  return retval;
2470  }
2471  }
2472 
2473  bool need_to_update = false;
2474 
2475  for (int i = 0; i < nargin; i++)
2476  {
2477  if (args(i).is_string ())
2478  {
2479  std::string arg = args(i).string_value ();
2480 
2481  std::list<std::string> dir_elts = split_path (arg);
2482 
2483  if (! append)
2484  std::reverse (dir_elts.begin (), dir_elts.end ());
2485 
2486  for (std::list<std::string>::const_iterator p = dir_elts.begin ();
2487  p != dir_elts.end ();
2488  p++)
2489  {
2490  std::string dir = *p;
2491 
2492  //dir = regexprep (dir_elts{j}, '//+', "/");
2493  //dir = regexprep (dir, '/$', "");
2494 
2495  if (append)
2496  load_path::append (dir, true);
2497  else
2498  load_path::prepend (dir, true);
2499 
2500  need_to_update = true;
2501  }
2502  }
2503  else
2504  error ("addpath: all arguments must be strings");
2505  }
2506 
2507  if (need_to_update)
2508  rehash_internal ();
2509  }
2510  else
2511  print_usage ();
2512 
2513  return retval;
2514 }
2515 
2516 DEFUN (rmpath, args, nargout,
2517  "-*- texinfo -*-\n\
2518 @deftypefn {Built-in Function} {} rmpath (@var{dir1}, @dots{})\n\
2519 Remove @var{dir1}, @dots{} from the current function search path.\n\
2520 \n\
2521 In addition to accepting individual directory arguments, lists of\n\
2522 directory names separated by @code{pathsep} are also accepted. For example:\n\
2523 \n\
2524 @example\n\
2525 rmpath (\"dir1:/dir2:~/dir3\")\n\
2526 @end example\n\
2527 @seealso{path, addpath, genpath, pathdef, savepath, pathsep}\n\
2528 @end deftypefn")
2529 {
2530  // Originally by Etienne Grossmann. Heavily modified and translated
2531  // to C++ by jwe.
2532 
2533  octave_value retval;
2534 
2535  if (nargout > 0)
2536  retval = load_path::path ();
2537 
2538  int nargin = args.length ();
2539 
2540  if (nargin > 0)
2541  {
2542  bool need_to_update = false;
2543 
2544  for (int i = 0; i < nargin; i++)
2545  {
2546  if (args(i).is_string ())
2547  {
2548  std::string arg = args(i).string_value ();
2549  std::list<std::string> dir_elts = split_path (arg);
2550 
2551  for (std::list<std::string>::const_iterator p = dir_elts.begin ();
2552  p != dir_elts.end ();
2553  p++)
2554  {
2555  std::string dir = *p;
2556 
2557  //dir = regexprep (dir_elts{j}, '//+', "/");
2558  //dir = regexprep (dir, '/$', "");
2559 
2560  if (! load_path::remove (dir))
2561  warning ("rmpath: %s: not found", dir.c_str ());
2562  else
2563  need_to_update = true;
2564  }
2565  }
2566  else
2567  error ("addpath: all arguments must be strings");
2568  }
2569 
2570  if (need_to_update)
2571  rehash_internal ();
2572  }
2573  else
2574  print_usage ();
2575 
2576  return retval;
2577 }
2578 
2579 DEFUN (__dump_load_path__, , , "")
2580 {
2582 
2583  return octave_value_list ();
2584 }
fcn_map_type::iterator fcn_map_iterator
Definition: load-path.h:475
static void maybe_add_path_elts(std::string &path, const std::string &dir)
Definition: load-path.cc:565
bool is_reg(void) const
Definition: file-stat.cc:74
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:696
void update(void)
Definition: load-path.cc:56
void remove_private_fcn_map(const std::string &dir)
Definition: load-path.cc:843
static std::string system_path(void)
Definition: load-path.h:278
static bool in_path_list(const std::string &path_list, const std::string &path)
Definition: load-path.cc:1849
void do_update(void) const
Definition: load-path.cc:970
friend void print_types(std::ostream &os, int types)
Definition: load-path.cc:1731
void add_to_fcn_map(const dir_info &di, bool at_end)
Definition: load-path.cc:1890
std::string error(void) const
Definition: file-stat.h:136
std::set< std::string > init_dirs
Definition: load-path.h:610
method_file_map_type method_file_map
Definition: load-path.h:395
std::string find_private_file(const std::string &fname)
Definition: load-path.cc:1297
bool same_file(const std::string &f, const std::string &g)
Definition: utils.cc:133
std::string Vlocal_oct_file_dir
Definition: defaults.cc:71
fcn_file_map_type private_file_map
Definition: load-path.h:394
method_map_type::iterator method_map_iterator
Definition: load-path.h:488
static void display(std::ostream &os)
Definition: load-path.h:254
void get_package_dir(const std::string &d, const std::string &package_name)
Definition: load-path.cc:315
void get_file_list(const std::string &d)
Definition: load-path.cc:175
std::string do_find_dir(const std::string &dir) const
Definition: load-path.cc:1390
string_vector read(void)
Definition: dir-ops.cc:70
void source_file(const std::string &file_name, const std::string &context, bool verbose, bool require_file, const std::string &warn_for)
Definition: oct-parse.cc:8405
static std::string path_sep_str(void)
Definition: pathsearch.h:95
std::string Vlocal_fcn_file_dir
Definition: defaults.cc:75
static void prepend(const std::string &dir, bool warn=false)
Definition: load-path.h:74
string_vector do_find_matching_dirs(const std::string &dir) const
Definition: load-path.cc:1437
std::map< std::string, int > fcn_file_map_type
Definition: load-path.h:294
static std::string command_line_path
Definition: load-path.h:620
OCTINTERP_API void print_usage(void)
Definition: defun.cc:51
std::string Vlocal_ver_fcn_file_dir
Definition: defaults.cc:73
dir_info_list_type::iterator dir_info_list_iterator
Definition: load-path.h:459
static void append(const std::string &dir, bool warn=false)
Definition: load-path.h:68
std::map< std::string, dir_info > package_dir_map_type
Definition: load-path.h:330
void get_private_file_map(const std::string &d)
Definition: load-path.cc:295
bool is_numeric_type(void) const
Definition: ov.h:663
loader & get_loader(const std::string &name) const
Definition: load-path.h:665
bool empty(void) const
Definition: str-vec.h:73
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix=std::string()) const
Definition: str-vec.cc:215
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:730
string_vector do_find_all_first_of(const string_vector &files) const
Definition: load-path.cc:1563
file_info_list_type::const_iterator const_file_info_list_iterator
Definition: load-path.h:468
fcn_file_map_type private_file_map
Definition: load-path.h:320
dir_info_list_type dir_info_list
Definition: load-path.h:608
void protect_var(T &var)
void remove(const dir_info &di)
Definition: load-path.cc:954
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:44
void error(const char *fmt,...)
Definition: error.cc:476
private_fcn_map_type::const_iterator const_private_fcn_map_iterator
Definition: load-path.h:481
void move_method_map(const std::string &dir, bool at_end)
Definition: load-path.cc:457
std::string Vfcn_file_dir
Definition: defaults.cc:82
static abs_dir_cache_type abs_dir_cache
Definition: load-path.h:624
private_fcn_map_type::iterator private_fcn_map_iterator
Definition: load-path.h:482
void(* hook_fcn_ptr)(const std::string &dir)
Definition: load-path.h:46
std::string find_fcn(const std::string &fcn, std::string &dir_name, int type=M_FILE|OCT_FILE|MEX_FILE) const
Definition: load-path.cc:1087
std::string do_find_first_of(const string_vector &files) const
Definition: load-path.cc:1484
void add(const dir_info &di, bool at_end, const std::string &pname=std::string()) const
Definition: load-path.cc:1868
void stamp(void)
Definition: oct-time.cc:84
void overloads(const std::string &meth, std::list< std::string > &l) const
Definition: load-path.cc:1273
string_vector do_fcn_names(void) const
Definition: load-path.cc:1690
void do_initialize(bool set_initial_path)
Definition: load-path.cc:579
static const int MEX_FILE
Definition: load-path.h:287
std::string dir_name
Definition: load-path.h:387
method_map_type::const_iterator const_method_map_iterator
Definition: load-path.h:487
static void execute_pkg_add_or_del(const std::string &dir, const std::string &script_file)
Definition: load-path.cc:2203
void move(const dir_info &di, bool at_end, const std::string &pname=std::string())
Definition: load-path.cc:519
load_path(void)
Definition: load-path.h:41
F77_RET_T const double const double double * d
static void rehash_internal(void)
Definition: load-path.cc:2280
std::string Voct_data_dir
Definition: defaults.cc:77
octave_time dir_time_last_checked
Definition: load-path.h:391
void remove_fcn_map(const std::string &dir, const string_vector &fcn_files)
Definition: load-path.cc:803
static std::string tilde_expand(const std::string &)
Definition: file-ops.cc:286
void do_append(const std::string &dir, bool warn)
Definition: load-path.cc:713
string_vector fcn_files
Definition: load-path.h:393
static hook_fcn_ptr remove_hook
Definition: load-path.h:618
std::list< file_info > file_info_list_type
Definition: load-path.h:466
static std::string concat(const std::string &, const std::string &)
Definition: file-ops.cc:360
static void cleanup_instance(void)
Definition: load-path.h:614
std::list< std::string > methods(const std::string &class_name) const
Definition: load-path.cc:1220
std::map< std::string, file_info_list_type > fcn_map_type
Definition: load-path.h:472
std::string do_find_file(const std::string &file) const
Definition: load-path.cc:1330
static hook_fcn_ptr add_hook
Definition: load-path.h:616
static char path_sep_char(void)
Definition: pathsearch.h:85
octave_time Vlast_prompt_time
Definition: input.cc:97
bool valid_identifier(const char *s)
Definition: utils.cc:77
std::string Vlocal_api_fcn_file_dir
Definition: defaults.cc:74
std::string string_value(bool force=false) const
Definition: ov.h:897
fcn_file_map_type::const_iterator const_fcn_file_map_iterator
Definition: load-path.h:296
string_vector do_files(const std::string &dir, bool omit_exts) const
Definition: load-path.cc:1662
bool exists(void) const
Definition: file-stat.h:134
static void add(fptr f)
void resize(octave_idx_type n, const std::string &rfv=std::string())
Definition: str-vec.h:91
std::string find_method(const std::string &class_name, const std::string &meth, std::string &dir_name, int type=M_FILE|OCT_FILE|MEX_FILE) const
Definition: load-path.cc:1172
static std::string make_absolute(const std::string &s, const std::string &dot_path=get_current_directory())
Definition: oct-env.cc:132
static bool instance_ok(void)
Definition: load-path.cc:322
static std::string sys_path
Definition: load-path.h:622
std::string dir_name
Definition: load-path.h:439
bool is_string(void) const
Definition: ov.h:562
std::map< std::string, dir_info > abs_dir_cache_type
Definition: load-path.h:461
friend dir_info::fcn_file_map_type get_fcn_files(const std::string &d)
Definition: load-path.cc:243
void add(const dir_info &di, bool at_end)
Definition: load-path.h:517
void add_to_private_fcn_map(const dir_info &di)
Definition: load-path.cc:1986
int error_state
Definition: error.cc:101
static std::string getenv(const std::string &name)
Definition: oct-env.cc:238
void do_prepend(const std::string &dir, bool warn)
Definition: load-path.cc:720
static void initialize(bool set_initial_path=false)
Definition: load-path.h:50
std::list< std::string > do_overloads(const std::string &meth) const
Definition: load-path.cc:1257
std::list< std::string > do_get_all_package_names(bool only_top_level) const
Definition: load-path.cc:2188
loader default_loader
Definition: load-path.h:606
std::string find_private_fcn(const std::string &dir, const std::string &fcn, int type=M_FILE|OCT_FILE|MEX_FILE) const
Definition: load-path.cc:1142
std::list< std::string > do_dir_list(void) const
Definition: load-path.cc:1649
dir_info_list_type::const_iterator const_dir_info_list_iterator
Definition: load-path.h:458
void execute_pkg_del(const std::string &dir)
Definition: load-path.cc:2226
friend string_vector get_file_list(const dir_info::fcn_file_map_type &lst)
Definition: load-path.cc:1775
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
string_vector & sort(bool make_uniq=false)
Definition: str-vec.cc:107
octave_idx_type length(void) const
Definition: ov.cc:1525
static bool absolute_pathname(const std::string &s)
Definition: oct-env.cc:111
string_vector do_dirs(void) const
Definition: load-path.cc:1632
void move(const dir_info &di, bool at_end)
Definition: load-path.cc:540
static bool rooted_relative_pathname(const std::string &s)
Definition: oct-env.cc:118
std::string do_path(void) const
Definition: load-path.cc:1713
file_info_list_type::iterator file_info_list_iterator
Definition: load-path.h:469
void get_method_file_map(const std::string &d, const std::string &class_name)
Definition: load-path.cc:301
static octave_user_function * get_curr_fcn(scope_id scope=xcurrent_scope)
Definition: symtab.h:2281
void move_fcn_map(const std::string &dir, const string_vector &fcn_files, bool at_end)
Definition: load-path.cc:408
abs_dir_cache_type::iterator abs_dir_cache_iterator
Definition: load-path.h:464
package_dir_map_type::const_iterator const_package_dir_map_iterator
Definition: load-path.h:332
std::string Vlocal_ver_oct_file_dir
Definition: defaults.cc:69
static load_path * instance
Definition: load-path.h:612
const_dir_info_list_iterator find_dir_info(const std::string &dir) const
Definition: load-path.cc:347
double arg(double x)
Definition: lo-mappers.h:37
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
Definition: colamd.cc:111
method_file_map_type::const_iterator const_method_file_map_iterator
Definition: load-path.h:326
void warning(const char *fmt,...)
Definition: error.cc:681
std::string dir_name(void) const
Definition: ov-fcn.h:123
std::string error(void) const
Definition: dir-ops.h:71
static std::string dir_sep_chars(void)
Definition: file-ops.h:68
void do_set(const std::string &p, bool warn, bool is_init=false)
Definition: load-path.cc:660
octave_idx_type length(void) const
Number of elements in the array.
Definition: Array.h:267
octave_time mtime(void) const
Definition: file-stat.h:118
static bool set_initial_path
Definition: octave.cc:118
#define octave_stdout
Definition: pager.h:144
void execute_pkg_add(const std::string &dir)
Definition: load-path.cc:2220
std::string Voct_file_dir
Definition: defaults.cc:81
static void update(void)
Definition: load-path.h:85
static std::string strip_trailing_separators(const std::string &dir_arg)
Definition: load-path.cc:729
void remove_method_map(const std::string &dir)
Definition: load-path.cc:852
void do_clear(void)
Definition: load-path.cc:617
string_vector fcn_names(void) const
Definition: load-path.cc:1696
fcn_map_type::const_iterator const_fcn_map_iterator
Definition: load-path.h:474
static double fi[256]
Definition: randmtzig.c:443
void add_to_method_map(const dir_info &di, bool at_end)
Definition: load-path.cc:1995
static std::list< std::string > split_path(const std::string &p)
Definition: load-path.cc:627
fcn_file_map_type method_file_map
Definition: load-path.h:319
static bool is_dir_sep(char c)
Definition: file-ops.h:73
static const int M_FILE
Definition: load-path.h:285
bool is_dir(void) const
Definition: file-stat.cc:56
static string_vector dirs(void)
Definition: load-path.h:227
void do_add(const std::string &dir, bool at_end, bool warn)
Definition: load-path.cc:745
static std::list< std::string > dir_list(void)
Definition: load-path.h:232
Definition: dir-ops.h:30
void do_move(dir_info_list_iterator i, bool at_end)
Definition: load-path.cc:501
void run_first(void)
Definition: unwind-prot.h:62
bool contains(const std::string &dir) const
Definition: load-path.cc:383
package_dir_map_type package_dir_map
Definition: load-path.h:396
bool is_package(const std::string &name) const
Definition: load-path.cc:1243
octave_time time_resolution(void) const
Definition: file-stat.h:80
loader_map_type::const_iterator const_loader_map_iterator
Definition: load-path.h:601
bool do_remove(const std::string &dir)
Definition: load-path.cc:892
static void set(const std::string &p, bool warn=false)
Definition: load-path.h:62
static bool is_built_in_function_name(const std::string &name)
Definition: symtab.h:1493
static std::string get_command_line_path(void)
Definition: load-path.h:272
static std::string dir_sep_str(void)
Definition: file-ops.h:63
friend void print_fcn_list(std::ostream &os, const dir_info::fcn_file_map_type &lst)
Definition: load-path.cc:1759
bool is_package(const std::string &name) const
Definition: load-path.cc:113
void display(std::ostream &out) const
Definition: load-path.cc:2066
static bool check_file_type(std::string &fname, int type, int possible_types, const std::string &fcn, const char *who)
Definition: load-path.cc:993
loader_map_type loader_map
Definition: load-path.h:604
void clear(void)
Definition: load-path.h:535
static const int OCT_FILE
Definition: load-path.h:286
void initialize(void)
Definition: load-path.cc:134
static std::string path(void)
Definition: load-path.h:249
std::map< std::string, class_info > method_file_map_type
Definition: load-path.h:324
static bool remove(const std::string &dir)
Definition: load-path.h:80
bool octave_interpreter_ready
Definition: toplev.cc:100
std::string genpath(const std::string &dirname, const string_vector &skip)
Definition: load-path.cc:2141
bool do_contains_canonical(const std::string &dir) const
Definition: load-path.cc:389
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
void do_display(std::ostream &os) const
Definition: load-path.cc:1805
std::string Vlocal_api_oct_file_dir
Definition: defaults.cc:70