GNU Octave  3.8.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.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2006-2013 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 #if !defined (octave_load_path_h)
25 #define octave_load_path_h 1
26 
27 #include <iosfwd>
28 #include <list>
29 #include <map>
30 #include <string>
31 
32 #include "pathsearch.h"
33 #include "str-vec.h"
34 
35 class
38 {
39 protected:
40 
41  load_path (void)
42  : dir_info_list (), fcn_map (), private_fcn_map (), method_map (),
43  init_dirs () { }
44 
45 public:
46 
47  typedef void (*hook_fcn_ptr) (const std::string& dir);
48 
49  ~load_path (void) { }
50 
51  static void initialize (bool set_initial_path = false)
52  {
53  if (instance_ok ())
54  instance->do_initialize (set_initial_path);
55  }
56 
57  static void clear (void)
58  {
59  if (instance_ok ())
60  instance->do_clear ();
61  }
62 
63  static void set (const std::string& p, bool warn = false)
64  {
65  if (instance_ok ())
66  instance->do_set (p, warn);
67  }
68 
69  static void append (const std::string& dir, bool warn = false)
70  {
71  if (instance_ok ())
72  instance->do_append (dir, warn);
73  }
74 
75  static void prepend (const std::string& dir, bool warn = false)
76  {
77  if (instance_ok ())
78  instance->do_prepend (dir, warn);
79  }
80 
81  static bool remove (const std::string& dir)
82  {
83  return instance_ok () ? instance->do_remove (dir) : false;
84  }
85 
86  static void update (void)
87  {
88  if (instance_ok ())
89  instance->do_update ();
90  }
91 
92  static bool contains_canonical (const std::string& dir_name)
93  {
94  return instance_ok () ? instance->do_contains_canonical (dir_name) : false;
95  }
96 
97  static std::string find_method (const std::string& class_name,
98  const std::string& meth,
99  std::string& dir_name)
100  {
101  return instance_ok ()
102  ? instance->do_find_method (class_name, meth, dir_name)
103  : std::string ();
104  }
105 
106  static std::string find_method (const std::string& class_name,
107  const std::string& meth)
108  {
109  std::string dir_name;
110  return find_method (class_name, meth, dir_name);
111  }
112 
113  static std::list<std::string> methods (const std::string& class_name)
114  {
115  return instance_ok ()
116  ? instance->do_methods (class_name) : std::list<std::string> ();
117  }
118 
119  static std::list<std::string> overloads (const std::string& meth)
120  {
121  return instance_ok ()
122  ? instance->do_overloads (meth) : std::list<std::string> ();
123  }
124 
125  static std::string find_fcn (const std::string& fcn, std::string& dir_name)
126  {
127  return instance_ok ()
128  ? instance->do_find_fcn (fcn, dir_name) : std::string ();
129  }
130 
131  static std::string find_fcn (const std::string& fcn)
132  {
133  std::string dir_name;
134  return find_fcn (fcn, dir_name);
135  }
136 
137  static std::string find_private_fcn (const std::string& dir,
138  const std::string& fcn)
139  {
140  return instance_ok ()
141  ? instance->do_find_private_fcn (dir, fcn) : std::string ();
142  }
143 
144  static std::string find_fcn_file (const std::string& fcn)
145  {
146  std::string dir_name;
147 
148  return instance_ok () ?
149  instance->do_find_fcn (fcn, dir_name, M_FILE) : std::string ();
150  }
151 
152  static std::string find_oct_file (const std::string& fcn)
153  {
154  std::string dir_name;
155 
156  return instance_ok () ?
157  instance->do_find_fcn (fcn, dir_name, OCT_FILE) : std::string ();
158  }
159 
160  static std::string find_mex_file (const std::string& fcn)
161  {
162  std::string dir_name;
163 
164  return instance_ok () ?
165  instance->do_find_fcn (fcn, dir_name, MEX_FILE) : std::string ();
166  }
167 
168  static std::string find_file (const std::string& file)
169  {
170  return instance_ok ()
171  ? instance->do_find_file (file) : std::string ();
172  }
173 
174  static std::string find_dir (const std::string& dir)
175  {
176  return instance_ok ()
177  ? instance->do_find_dir (dir) : std::string ();
178  }
179 
180  static string_vector find_matching_dirs (const std::string& dir)
181  {
182  return instance_ok ()
183  ? instance->do_find_matching_dirs (dir) : string_vector ();
184  }
185 
186  static std::string find_first_of (const string_vector& files)
187  {
188  return instance_ok () ?
189  instance->do_find_first_of (files) : std::string ();
190  }
191 
192  static string_vector find_all_first_of (const string_vector& files)
193  {
194  return instance_ok () ?
195  instance->do_find_all_first_of (files) : string_vector ();
196  }
197 
198  static string_vector dirs (void)
199  {
200  return instance_ok () ? instance->do_dirs () : string_vector ();
201  }
202 
203  static std::list<std::string> dir_list (void)
204  {
205  return instance_ok ()
206  ? instance->do_dir_list () : std::list<std::string> ();
207  }
208 
209  static string_vector files (const std::string& dir, bool omit_exts = false)
210  {
211  return instance_ok ()
212  ? instance->do_files (dir, omit_exts) : string_vector ();
213  }
214 
215  static string_vector fcn_names (void)
216  {
217  return instance_ok () ? instance->do_fcn_names () : string_vector ();
218  }
219 
220  static std::string path (void)
221  {
222  return instance_ok () ? instance->do_path () : std::string ();
223  }
224 
225  static void display (std::ostream& os)
226  {
227  if (instance_ok ())
228  instance->do_display (os);
229  }
230 
231  static void set_add_hook (hook_fcn_ptr f) { add_hook = f; }
232 
233  static void set_remove_hook (hook_fcn_ptr f) { remove_hook = f; }
234 
235  static void set_command_line_path (const std::string& p)
236  {
237  if (command_line_path.empty ())
238  command_line_path = p;
239  else
241  }
242 
243  static std::string get_command_line_path (void)
244  {
245  return instance_ok () ? instance->do_get_command_line_path ()
246  : std::string ();
247  }
248 
249  static std::string system_path (void)
250  {
251  return instance_ok () ? instance->do_system_path () : std::string ();
252  }
253 
254 private:
255 
256  static const int M_FILE = 1;
257  static const int OCT_FILE = 2;
258  static const int MEX_FILE = 4;
259 
260  class dir_info
261  {
262  public:
263 
264  // <FCN_NAME, TYPE>
265  typedef std::map<std::string, int> fcn_file_map_type;
266 
267  typedef fcn_file_map_type::const_iterator const_fcn_file_map_iterator;
268  typedef fcn_file_map_type::iterator fcn_file_map_iterator;
269 
270  struct class_info
271  {
272  class_info (void) : method_file_map (), private_file_map () { }
273 
274  class_info (const class_info& ci)
275  : method_file_map (ci.method_file_map),
276  private_file_map (ci.private_file_map) { }
277 
278  class_info& operator = (const class_info& ci)
279  {
280  if (this != &ci)
281  {
282  method_file_map = ci.method_file_map;
283  private_file_map = ci.private_file_map;
284  }
285  return *this;
286  }
287 
288  ~class_info (void) { }
289 
292  };
293 
294  // <CLASS_NAME, CLASS_INFO>
295  typedef std::map<std::string, class_info> method_file_map_type;
296 
297  typedef method_file_map_type::const_iterator const_method_file_map_iterator;
298  typedef method_file_map_type::iterator method_file_map_iterator;
299 
300  // This default constructor is only provided so we can create a
301  // std::map of dir_info objects. You should not use this
302  // constructor for any other purpose.
303  dir_info (void)
304  : dir_name (), abs_dir_name (), is_relative (false),
305  dir_mtime (), dir_time_last_checked (),
306  all_files (), fcn_files (), private_file_map (), method_file_map ()
307  { }
308 
309  dir_info (const std::string& d)
310  : dir_name (d), abs_dir_name (), is_relative (false),
311  dir_mtime (), dir_time_last_checked (),
312  all_files (), fcn_files (), private_file_map (), method_file_map ()
313  {
314  initialize ();
315  }
316 
317  dir_info (const dir_info& di)
318  : dir_name (di.dir_name), abs_dir_name (di.abs_dir_name),
319  is_relative (di.is_relative),
320  dir_mtime (di.dir_mtime),
321  dir_time_last_checked (di.dir_time_last_checked),
322  all_files (di.all_files), fcn_files (di.fcn_files),
323  private_file_map (di.private_file_map),
324  method_file_map (di.method_file_map) { }
325 
326  ~dir_info (void) { }
327 
328  dir_info& operator = (const dir_info& di)
329  {
330  if (&di != this)
331  {
332  dir_name = di.dir_name;
333  abs_dir_name = di.abs_dir_name;
334  is_relative = di.is_relative;
335  dir_mtime = di.dir_mtime;
336  dir_time_last_checked = di.dir_time_last_checked;
337  all_files = di.all_files;
338  fcn_files = di.fcn_files;
339  private_file_map = di.private_file_map;
340  method_file_map = di.method_file_map;
341  }
342 
343  return *this;
344  }
345 
346  void update (void);
347 
348  std::string dir_name;
349  std::string abs_dir_name;
357 
358  private:
359 
360  void initialize (void);
361 
362  void get_file_list (const std::string& d);
363 
364  void get_private_file_map (const std::string& d);
365 
366  void get_method_file_map (const std::string& d,
367  const std::string& class_name);
368 
369  friend fcn_file_map_type get_fcn_files (const std::string& d);
370  };
371 
372  class file_info
373  {
374  public:
375 
376  file_info (const std::string& d, int t) : dir_name (d), types (t) { }
377 
379  : dir_name (fi.dir_name), types (fi.types) { }
380 
381  ~file_info (void) { }
382 
383  file_info& operator = (const file_info& fi)
384  {
385  if (&fi != this)
386  {
387  dir_name = fi.dir_name;
388  types = fi.types;
389  }
390 
391  return *this;
392  }
393 
394  std::string dir_name;
395  int types;
396  };
397 
398  // We maintain two ways of looking at the same information.
399  //
400  // First, a list of directories and the set of "public" files and
401  // private files (those found in the special "private" subdirectory)
402  // in each directory.
403  //
404  // Second, a map from file names (the union of all "public" files for all
405  // directories, but without filename extensions) to a list of
406  // corresponding information (directory name and file types). This
407  // way, we can quickly find shadowed file names and look up all
408  // overloaded functions (in the "@" directories used to implement
409  // classes).
410 
411  typedef std::list<dir_info> dir_info_list_type;
412 
413  typedef dir_info_list_type::const_iterator const_dir_info_list_iterator;
414  typedef dir_info_list_type::iterator dir_info_list_iterator;
415 
416  typedef std::map<std::string, dir_info> abs_dir_cache_type;
417 
418  typedef abs_dir_cache_type::const_iterator const_abs_dir_cache_iterator;
419  typedef abs_dir_cache_type::iterator abs_dir_cache_iterator;
420 
421  typedef std::list<file_info> file_info_list_type;
422 
423  typedef file_info_list_type::const_iterator const_file_info_list_iterator;
424  typedef file_info_list_type::iterator file_info_list_iterator;
425 
426  // <FCN_NAME, FILE_INFO_LIST>
427  typedef std::map<std::string, file_info_list_type> fcn_map_type;
428 
429  typedef fcn_map_type::const_iterator const_fcn_map_iterator;
430  typedef fcn_map_type::iterator fcn_map_iterator;
431 
432  // <DIR_NAME, <FCN_NAME, TYPE>>
433  typedef std::map<std::string, dir_info::fcn_file_map_type>
435 
436  typedef private_fcn_map_type::const_iterator const_private_fcn_map_iterator;
437  typedef private_fcn_map_type::iterator private_fcn_map_iterator;
438 
439  // <CLASS_NAME, <FCN_NAME, FILE_INFO_LIST>>
440  typedef std::map<std::string, fcn_map_type> method_map_type;
441 
442  typedef method_map_type::const_iterator const_method_map_iterator;
443  typedef method_map_type::iterator method_map_iterator;
444 
445  mutable dir_info_list_type dir_info_list;
446 
447  mutable fcn_map_type fcn_map;
448 
450 
451  mutable method_map_type method_map;
452 
453  mutable std::set<std::string> init_dirs;
454 
456 
457  static void cleanup_instance (void) { delete instance; instance = 0; }
458 
459  static hook_fcn_ptr add_hook;
460 
461  static hook_fcn_ptr remove_hook;
462 
463  static std::string command_line_path;
464 
465  static std::string sys_path;
466 
467  static abs_dir_cache_type abs_dir_cache;
468 
469  static bool instance_ok (void);
470 
471  const_dir_info_list_iterator find_dir_info (const std::string& dir) const;
472  dir_info_list_iterator find_dir_info (const std::string& dir);
473 
474  bool contains (const std::string& dir) const;
475 
476  bool do_contains_canonical (const std::string& dir) const;
477 
478  void move_fcn_map (const std::string& dir,
479  const string_vector& fcn_files, bool at_end);
480 
481  void move_method_map (const std::string& dir, bool at_end);
482 
483  void move (std::list<dir_info>::iterator i, bool at_end);
484 
485  void do_initialize (bool set_initial_path);
486 
487  void do_clear (void);
488 
489  void do_set (const std::string& p, bool warn, bool is_init = false);
490 
491  void do_append (const std::string& dir, bool warn);
492 
493  void do_prepend (const std::string& dir, bool warn);
494 
495  void do_add (const std::string& dir, bool at_end, bool warn);
496 
497  void remove_fcn_map (const std::string& dir, const string_vector& fcn_files);
498 
499  void remove_private_fcn_map (const std::string& dir);
500 
501  void remove_method_map (const std::string& dir);
502 
503  bool do_remove (const std::string& dir);
504 
505  void do_update (void) const;
506 
507  static bool
508  check_file_type (std::string& fname, int type, int possible_types,
509  const std::string& fcn, const char *who);
510 
511  std::string do_find_fcn (const std::string& fcn,
512  std::string& dir_name,
513  int type = M_FILE | OCT_FILE | MEX_FILE) const;
514 
515  std::string do_find_private_fcn (const std::string& dir,
516  const std::string& fcn,
517  int type = M_FILE | OCT_FILE | MEX_FILE) const;
518 
519  std::string do_find_method (const std::string& class_name,
520  const std::string& meth,
521  std::string& dir_name,
522  int type = M_FILE | OCT_FILE | MEX_FILE) const;
523 
524  std::list<std::string> do_methods (const std::string& class_name) const;
525 
526  std::list<std::string> do_overloads (const std::string& meth) const;
527 
528  std::string do_find_file (const std::string& file) const;
529 
530  std::string do_find_dir (const std::string& dir) const;
531 
532  string_vector do_find_matching_dirs (const std::string& dir) const;
533 
534  std::string do_find_first_of (const string_vector& files) const;
535 
536  string_vector do_find_all_first_of (const string_vector& files) const;
537 
538  string_vector do_dirs (void) const;
539 
540  std::list<std::string> do_dir_list (void) const;
541 
542  string_vector do_files (const std::string& dir, bool omit_exts) const;
543 
544  string_vector do_fcn_names (void) const;
545 
546  std::string do_path (void) const;
547 
548  friend void print_types (std::ostream& os, int types);
549 
551 
552  friend void
553  print_fcn_list (std::ostream& os, const dir_info::fcn_file_map_type& lst);
554 
555  void do_display (std::ostream& os) const;
556 
557  std::string do_system_path (void) const { return sys_path; }
558 
559  std::string do_get_command_line_path (void) const
560  { return command_line_path; }
561 
562  void add_to_fcn_map (const dir_info& di, bool at_end) const;
563 
564  void add_to_private_fcn_map (const dir_info& di) const;
565 
566  void add_to_method_map (const dir_info& di, bool at_end) const;
567 
568  friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d);
569 };
570 
571 extern std::string
572 genpath (const std::string& dir, const string_vector& skip = "private");
573 
574 extern void execute_pkg_add (const std::string& dir);
575 extern void execute_pkg_del (const std::string& dir);
576 
577 #endif