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