GNU Octave 11.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
load-path.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2006-2026 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if ! defined (octave_load_path_h)
27#define octave_load_path_h 1
28
29#include "octave-config.h"
30
31#include <functional>
32#include <iosfwd>
33#include <list>
34#include <map>
35#include <set>
36#include <string>
37
38#include "oct-time.h"
39#include "pathsearch.h"
40#include "str-vec.h"
41
43
44class OCTINTERP_API load_path
45{
46public:
47
48 load_path (interpreter& interp);
49
50 typedef void (*hook_fcn_ptr) (const std::string& dir);
51
52 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (load_path)
53
54 ~load_path () = default;
55
56 void initialize (bool set_initial_path = false);
57
58 void clear ();
59
60 void set (const std::string& p, bool warn = false, bool is_init = false);
61
62 void append (const std::string& dir, bool warn = false);
63
64 void prepend (const std::string& dir, bool warn = false);
65
66 bool remove (const std::string& dir);
67
68 void update ();
69
70 bool contains_canonical (const std::string& dir_name) const;
71
72 bool contains_file_in_dir (const std::string& file_name,
73 const std::string& dir_name);
74
75 std::string find_method (const std::string& class_name,
76 const std::string& meth,
77 std::string& dir_name,
78 const std::string& pack_name = "")
79 {
80 return get_package (pack_name).find_method (class_name, meth, dir_name);
81 }
82
83 std::string find_method (const std::string& class_name,
84 const std::string& meth,
85 const std::string& pack_name = "")
86 {
87 std::string dir_name;
88 return find_method (class_name, meth, dir_name, pack_name);
89 }
90
91 std::list<std::string> methods (const std::string& class_name,
92 const std::string& pack_name = "")
93 {
94 return get_package (pack_name).methods (class_name);
95 }
96
97 std::list<std::string> overloads (const std::string& meth) const;
98
99 bool find_package (const std::string& package_name) const
100 {
101 return (m_package_map.find (package_name) != m_package_map.end ());
102 }
103
104 std::list<std::string>
105 get_all_package_names (bool only_top_level = true) const;
106
107 std::string find_fcn (const std::string& fcn, std::string& dir_name,
108 const std::string& pack_name = "")
109 {
110 return get_package (pack_name).find_fcn (fcn, dir_name);
111 }
112
113 std::string find_fcn (const std::string& fcn,
114 const std::string& pack_name = "")
115 {
116 std::string dir_name;
117 return find_fcn (fcn, dir_name, pack_name);
118 }
119
120 std::string find_private_fcn (const std::string& dir,
121 const std::string& fcn,
122 const std::string& pack_name = "")
123 {
124 return get_package (pack_name).find_private_fcn (dir, fcn);
125 }
126
127 std::string find_fcn_file (const std::string& fcn,
128 const std::string& pack_name = "")
129 {
130 std::string dir_name;
131 return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE);
132 }
133
134 std::string find_oct_file (const std::string& fcn,
135 const std::string& pack_name = "")
136 {
137 std::string dir_name;
138 return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE);
139 }
140
141 std::string find_mex_file (const std::string& fcn,
142 const std::string& pack_name = "")
143 {
144 std::string dir_name;
145 return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE);
146 }
147
148 std::string find_file (const std::string& file) const;
149
150 std::string find_dir (const std::string& dir) const;
151
152 string_vector find_matching_dirs (const std::string& dir) const;
153
154 std::string find_first_of (const string_vector& files) const;
155
156 string_vector find_all_first_of (const string_vector& files) const;
157
158 string_vector dirs () const;
159
160 std::list<std::string> dir_list () const;
161
162 string_vector files (const std::string& dir, bool omit_exts = false) const;
163
164 string_vector fcn_names () const;
165
166 std::string path () const;
167
168 void display (std::ostream& os) const;
169
170 std::function<void (const std::string&)> get_add_hook ()
171 {
172 return m_add_hook;
173 }
174
175 std::function<void (const std::string&)> get_remove_hook ()
176 {
177 return m_remove_hook;
178 }
179
180 void set_add_hook (const std::function<void (const std::string&)>& f)
181 {
182 m_add_hook = f;
183 }
184
185 void set_remove_hook (const std::function<void (const std::string&)>& f)
186 {
187 m_remove_hook = f;
188 }
189
190 void read_dir_config (const std::string& dir) const;
191
192 void execute_pkg_add (const std::string& dir);
193 void execute_pkg_del (const std::string& dir);
194
195 void set_command_line_path (const std::string& p)
196 {
197 if (m_command_line_path.empty ())
198 m_command_line_path = p;
199 else
200 m_command_line_path += directory_path::path_sep_str () + p;
201 }
202
203 std::string get_command_line_path () const
204 {
205 return m_command_line_path;
206 }
207
208 std::string system_path () const { return s_sys_path; }
209 void system_path (const std::string& sys_path)
210 {
211 s_sys_path = sys_path;
212 return;
213 }
214
215 void rehash ();
216
217 static const int M_FILE = 1;
218 static const int OCT_FILE = 2;
219 static const int MEX_FILE = 4;
220
221private:
222
223 class dir_info
224 {
225 public:
226
227 // <FCN_NAME, TYPE>
228 typedef std::map<std::string, int> fcn_file_map_type;
229
230 typedef fcn_file_map_type::const_iterator const_fcn_file_map_iterator;
231 typedef fcn_file_map_type::iterator fcn_file_map_iterator;
232
234 {
235 public:
236 class_info () : m_method_file_map (), m_private_file_map () { }
237
239 : m_method_file_map (ci.m_method_file_map),
240 m_private_file_map (ci.m_private_file_map)
241 { }
242
243 class_info& operator = (const class_info& ci)
244 {
245 if (this != &ci)
246 {
247 m_method_file_map = ci.m_method_file_map;
248 m_private_file_map = ci.m_private_file_map;
249 }
250 return *this;
251 }
252
253 ~class_info () = default;
254
255 fcn_file_map_type m_method_file_map;
256 fcn_file_map_type m_private_file_map;
257 };
258
259 // <CLASS_NAME, CLASS_INFO>
260 typedef std::map<std::string, class_info> method_file_map_type;
261
262 typedef method_file_map_type::const_iterator const_method_file_map_iterator;
263 typedef method_file_map_type::iterator method_file_map_iterator;
264
265 // <PACKAGE_NAME, DIR_INFO>
266 typedef std::map<std::string, dir_info> package_dir_map_type;
267
268 typedef package_dir_map_type::const_iterator const_package_dir_map_iterator;
269 typedef package_dir_map_type::iterator package_dir_map_iterator;
270
271 // This default constructor is only provided so we can create a
272 // std::map of dir_info objects. You should not use this
273 // constructor for any other purpose.
274 dir_info () = default;
275
276 dir_info (const std::string& d)
277 : m_dir_name (d), m_abs_dir_name (), m_is_relative (false),
278 m_dir_mtime (), m_dir_time_last_checked (), m_all_files (),
279 m_fcn_files (), m_private_file_map (), m_method_file_map (),
280 m_package_dir_map ()
281 {
282 initialize ();
283 }
284
285 dir_info (const dir_info&) = default;
286
287 ~dir_info () = default;
288
289 dir_info& operator = (const dir_info&) = default;
290
291 bool update ();
292
293 bool is_package (const std::string& name) const;
294
295 //--------
296
297 std::string m_dir_name;
298 std::string m_abs_dir_name;
299 bool m_is_relative;
300 sys::file_time m_dir_mtime;
301 sys::file_time m_dir_time_last_checked;
302 string_vector m_all_files;
303 string_vector m_fcn_files;
304 fcn_file_map_type m_private_file_map;
305 method_file_map_type m_method_file_map;
306 package_dir_map_type m_package_dir_map;
307
308 private:
309
310 void initialize ();
311
312 void get_file_list (const std::string& d);
313
314 void get_private_file_map (const std::string& d);
315
316 void get_method_file_map (const std::string& d,
317 const std::string& class_name);
318
319 void get_package_dir (const std::string& d,
320 const std::string& package_name);
321
322 friend fcn_file_map_type get_fcn_files (const std::string& d);
323 }; // end class dir_info
324
325 class file_info
326 {
327 public:
328
329 file_info () = delete;
330
331 file_info (const std::string& d, int t) : m_dir_name (d), m_types (t) { }
332
333 file_info (const file_info& fi)
334 : m_dir_name (fi.m_dir_name), m_types (fi.m_types) { }
335
336 ~file_info () = default;
337
339 {
340 if (&fi != this)
341 {
342 m_dir_name = fi.m_dir_name;
343 m_types = fi.m_types;
344 }
345
346 return *this;
347 }
348
349 //--------
350
351 std::string m_dir_name;
352 int m_types;
353 }; // end class file_info
354
355 // We maintain two ways of looking at the same information.
356 //
357 // First, a list of directories and the set of "public" files and
358 // private files (those found in the special "private" subdirectory)
359 // in each directory.
360 //
361 // Second, a map from filenames (the union of all "public" files for all
362 // directories, but without filename extensions) to a list of
363 // corresponding information (directory name and file types). This
364 // way, we can quickly find shadowed filenames and look up all
365 // overloaded functions (in the "@" directories used to implement
366 // classes).
367
368 typedef std::list<dir_info> dir_info_list_type;
369
370 typedef dir_info_list_type::const_iterator const_dir_info_list_iterator;
371 typedef dir_info_list_type::iterator dir_info_list_iterator;
372
373 typedef std::map<std::string, dir_info> abs_dir_cache_type;
374
375 typedef abs_dir_cache_type::const_iterator const_abs_dir_cache_iterator;
376 typedef abs_dir_cache_type::iterator abs_dir_cache_iterator;
377
378 typedef std::list<file_info> file_info_list_type;
379
380 typedef file_info_list_type::const_iterator const_file_info_list_iterator;
381 typedef file_info_list_type::iterator file_info_list_iterator;
382
383 // <FCN_NAME, FILE_INFO_LIST>
384 typedef std::map<std::string, file_info_list_type> fcn_map_type;
385
386 typedef fcn_map_type::const_iterator const_fcn_map_iterator;
387 typedef fcn_map_type::iterator fcn_map_iterator;
388
389 // <DIR_NAME, <FCN_NAME, TYPES>>
390 typedef std::map<std::string, dir_info::fcn_file_map_type>
391 private_fcn_map_type;
392
393 typedef private_fcn_map_type::const_iterator const_private_fcn_map_iterator;
394 typedef private_fcn_map_type::iterator private_fcn_map_iterator;
395
396 // <CLASS_NAME, <FCN_NAME, FILE_INFO_LIST>>
397 typedef std::map<std::string, fcn_map_type> method_map_type;
398
399 typedef method_map_type::const_iterator const_method_map_iterator;
400 typedef method_map_type::iterator method_map_iterator;
401
402 class package_info
403 {
404 public:
405
406 package_info (const std::string& package_name = "")
407 : m_package_name (package_name), m_dir_list (), m_fcn_map (),
408 m_private_fcn_map (), m_method_map ()
409 { }
410
411 package_info (const package_info& l)
412 : m_package_name (l.m_package_name), m_dir_list (l.m_dir_list),
413 m_private_fcn_map (l.m_private_fcn_map), m_method_map (l.m_method_map)
414 { }
415
416 ~package_info () = default;
417
418 package_info& operator = (const package_info& l)
419 {
420 if (&l != this)
421 {
422 m_package_name = l.m_package_name;
423 m_dir_list = l.m_dir_list;
424 m_fcn_map = l.m_fcn_map;
425 m_private_fcn_map = l.m_private_fcn_map;
426 m_method_map = l.m_method_map;
427 }
428
429 return *this;
430 }
431
432 void add (const dir_info& di, bool at_end, bool updating)
433 {
434 if (at_end)
435 m_dir_list.push_back (di.m_dir_name);
436 else
437 m_dir_list.push_front (di.m_dir_name);
438
439 add_to_fcn_map (di, at_end, updating);
440
441 add_to_private_fcn_map (di);
442
443 add_to_method_map (di, at_end);
444 }
445
446 void move (const dir_info& di, bool at_end);
447
448 void remove (const dir_info& di);
449
450 void clear ()
451 {
452 m_dir_list.clear ();
453
454 m_fcn_map.clear ();
455
456 m_private_fcn_map.clear ();
457
458 m_method_map.clear ();
459 }
460
461 void display (std::ostream& out) const;
462
463 std::string
464 find_fcn (const std::string& fcn, std::string& dir_name,
465 int type = M_FILE | OCT_FILE | MEX_FILE) const;
466
467 std::string
468 find_private_fcn (const std::string& dir, const std::string& fcn,
469 int type = M_FILE | OCT_FILE | MEX_FILE) const;
470
471 std::string
472 find_method (const std::string& class_name, const std::string& meth,
473 std::string& dir_name,
474 int type = M_FILE | OCT_FILE | MEX_FILE) const;
475
476 std::list<std::string> methods (const std::string& class_name) const;
477
478 void overloads (const std::string& meth, std::list<std::string>& l) const;
479
480 string_vector fcn_names () const;
481
482 private:
483
484 void add_to_fcn_map (const dir_info& di, bool at_end, bool updating);
485
486 void add_to_private_fcn_map (const dir_info& di);
487
488 void add_to_method_map (const dir_info& di, bool at_end);
489
490 void move_fcn_map (const std::string& dir,
491 const string_vector& fcn_files, bool at_end);
492
493 void move_method_map (const std::string& dir, bool at_end);
494
495 void remove_fcn_map (const std::string& dir,
496 const string_vector& fcn_files);
497
498 void remove_private_fcn_map (const std::string& dir);
499
500 void remove_method_map (const std::string& dir);
501
502 bool check_file_type (std::string& fname, int type, int possible_types,
503 const std::string& fcn, const char *who) const;
504
505 void print_types (std::ostream& os, int types) const;
506
507 void print_fcn_list (std::ostream& os,
508 const dir_info::fcn_file_map_type& lst) const;
509
510 //--------
511
512 std::string m_package_name;
513
514 std::list<std::string> m_dir_list;
515
516 fcn_map_type m_fcn_map;
517
518 private_fcn_map_type m_private_fcn_map;
519
520 method_map_type m_method_map;
521 }; // end class package_info
522
523 // <PACKAGE_NAME, PACKAGE_INFO>
524 typedef std::map<std::string, package_info> package_map_type;
525
526 typedef package_map_type::const_iterator const_package_map_iterator;
527 typedef package_map_type::iterator package_map_iterator;
528
529 std::function<void (const std::string&)> m_add_hook;
530
531 std::function<void (const std::string&)> m_remove_hook;
532
533 void execute_pkg_add_or_del (const std::string& dir,
534 const std::string& script_file);
535
536 const_dir_info_list_iterator find_dir_info (const std::string& dir) const;
537 dir_info_list_iterator find_dir_info (const std::string& dir);
538
539 bool contains (const std::string& dir) const;
540
541 void move (dir_info_list_iterator i, bool at_end);
542
543 void move (const dir_info& di, bool at_end, const std::string& pname = "");
544
545 void remove (const dir_info& di, const std::string& pname = "");
546
547 void add (const std::string& dir, bool at_end, bool warn);
548
549 void add (const dir_info& di, bool at_end, const std::string& pname = "",
550 bool updating = false);
551
552 bool is_package (const std::string& name) const;
553
554 package_info& get_package (const std::string& name)
555 {
556 if (! name.empty () && is_package (name))
557 {
558 package_map_iterator l = m_package_map.find (name);
559
560 if (l == m_package_map.end ())
561 l = m_package_map.insert (m_package_map.end (),
562 package_map_type::value_type (name, package_info (name)));
563
564 return l->second;
565 }
566
567 return m_top_level_package;
568 }
569
570 string_vector get_file_list (const dir_info::fcn_file_map_type& lst) const;
571
572 std::string find_private_file (const std::string& fname) const;
573
574 friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d);
575
576 //--------
577
578 static std::string s_sys_path;
579
580 static abs_dir_cache_type s_abs_dir_cache;
581
582 interpreter& m_interpreter;
583
584 package_map_type m_package_map;
585
586 package_info m_top_level_package;
587
588 dir_info_list_type m_dir_info_list;
589
590 std::set<std::string> m_init_dirs;
591
592 std::string m_command_line_path;
593
594}; // end class load_path
595
596extern std::string
597genpath (const std::string& dir, const string_vector& skip = "private");
598
599OCTAVE_END_NAMESPACE(octave)
600
601#endif
static std::string path_sep_str()
file_info & operator=(const file_info &)=default
~file_info()=default
std::string find_mex_file(const std::string &fcn, const std::string &pack_name="")
Definition load-path.h:141
void set_add_hook(const std::function< void(const std::string &)> &f)
Definition load-path.h:180
std::string find_oct_file(const std::string &fcn, const std::string &pack_name="")
Definition load-path.h:134
std::function< void(const std::string &)> get_remove_hook()
Definition load-path.h:175
void set_remove_hook(const std::function< void(const std::string &)> &f)
Definition load-path.h:185
bool find_package(const std::string &package_name) const
Definition load-path.h:99
std::string find_method(const std::string &class_name, const std::string &meth, const std::string &pack_name="")
Definition load-path.h:83
~load_path()=default
std::list< std::string > methods(const std::string &class_name, const std::string &pack_name="")
Definition load-path.h:91
std::string find_fcn(const std::string &fcn, const std::string &pack_name="")
Definition load-path.h:113
std::string system_path() const
Definition load-path.h:208
std::string find_fcn(const std::string &fcn, std::string &dir_name, const std::string &pack_name="")
Definition load-path.h:107
std::function< void(const std::string &)> get_add_hook()
Definition load-path.h:170
void system_path(const std::string &sys_path)
Definition load-path.h:209
std::string find_private_fcn(const std::string &dir, const std::string &fcn, const std::string &pack_name="")
Definition load-path.h:120
std::string find_fcn_file(const std::string &fcn, const std::string &pack_name="")
Definition load-path.h:127
void set_command_line_path(const std::string &p)
Definition load-path.h:195
std::string get_command_line_path() const
Definition load-path.h:203
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:75
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
load_path::dir_info::fcn_file_map_type get_fcn_files(const std::string &d)
std::string genpath(const std::string &dir, const string_vector &skip="private")
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE const F77_DBLE * f
fcn_file_map_type m_method_file_map
Definition load-path.h:255
class_info(const class_info &ci)
Definition load-path.h:238
fcn_file_map_type m_private_file_map
Definition load-path.h:256