Mercurial > hg > octave-nkf
annotate src/load-path.cc @ 11919:66881d20101d release-3-0-x
grid.m: handle minor grid option
author | Doug Stewart <dastew@sympatico.ca> |
---|---|
date | Fri, 16 Jan 2009 07:27:19 +0100 |
parents | 3342d1a7c4c9 |
children |
rev | line source |
---|---|
5832 | 1 /* |
2 | |
11740 | 3 Copyright (C) 2006, 2007, 2008 John W. Eaton |
5832 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
5832 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
5832 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <algorithm> | |
28 | |
29 #include "dir-ops.h" | |
30 #include "file-ops.h" | |
31 #include "file-stat.h" | |
32 #include "oct-env.h" | |
33 #include "pathsearch.h" | |
34 | |
35 #include "defaults.h" | |
36 #include "defun.h" | |
37 #include "input.h" | |
38 #include "load-path.h" | |
39 #include "pager.h" | |
40 #include "parse.h" | |
41 #include "toplev.h" | |
42 #include "unwind-prot.h" | |
43 #include "utils.h" | |
44 | |
45 load_path *load_path::instance = 0; | |
46 load_path::hook_function_ptr load_path::add_hook = execute_pkg_add; | |
47 load_path::hook_function_ptr load_path::remove_hook = execute_pkg_del; | |
48 std::string load_path::command_line_path; | |
6630 | 49 std::string load_path::sys_path; |
5832 | 50 |
51 void | |
52 load_path::dir_info::update (void) | |
53 { | |
54 if (is_relative) | |
55 initialize (); | |
56 else | |
57 { | |
58 file_stat fs (dir_name); | |
59 | |
60 if (fs) | |
61 { | |
62 if (fs.mtime () != dir_mtime) | |
63 initialize (); | |
64 } | |
65 else | |
66 { | |
67 std::string msg = fs.error (); | |
68 warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); | |
69 } | |
70 } | |
71 } | |
72 | |
73 void | |
74 load_path::dir_info::initialize (void) | |
75 { | |
76 is_relative = ! octave_env::absolute_pathname (dir_name); | |
77 | |
78 file_stat fs (dir_name); | |
79 | |
80 if (fs) | |
81 { | |
82 dir_mtime = fs.mtime (); | |
83 | |
84 bool has_private_subdir = get_file_list (dir_name); | |
85 | |
86 if (! error_state) | |
87 { | |
88 if (has_private_subdir) | |
89 { | |
7272 | 90 std::string pdn = file_ops::concat (dir_name, "private"); |
5832 | 91 |
92 get_private_function_map (pdn); | |
93 } | |
94 } | |
95 } | |
96 else | |
97 { | |
98 std::string msg = fs.error (); | |
99 warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); | |
100 } | |
101 } | |
102 | |
103 bool | |
104 load_path::dir_info::get_file_list (const std::string& d) | |
105 { | |
106 bool has_private_subdir = false; | |
107 | |
108 dir_entry dir (d); | |
109 | |
110 if (dir) | |
111 { | |
112 string_vector flist = dir.read (); | |
113 | |
114 octave_idx_type len = flist.length (); | |
115 | |
116 all_files.resize (len); | |
117 fcn_files.resize (len); | |
118 | |
119 octave_idx_type all_files_count = 0; | |
120 octave_idx_type fcn_files_count = 0; | |
121 | |
122 for (octave_idx_type i = 0; i < len; i++) | |
123 { | |
124 std::string fname = flist[i]; | |
125 | |
7272 | 126 std::string full_name = file_ops::concat (d, fname); |
5832 | 127 |
128 file_stat fs (full_name); | |
129 | |
130 if (fs) | |
131 { | |
132 if (fs.is_dir ()) | |
133 { | |
134 if (! has_private_subdir && fname == "private") | |
135 has_private_subdir = true; | |
136 } | |
137 else | |
138 { | |
139 all_files[all_files_count++] = fname; | |
140 | |
141 size_t pos = fname.rfind ('.'); | |
142 | |
143 if (pos != NPOS) | |
144 { | |
145 std::string ext = fname.substr (pos); | |
146 | |
5864 | 147 if (ext == ".m" || ext == ".oct" || ext == ".mex") |
5832 | 148 { |
149 std::string base = fname.substr (0, pos); | |
150 | |
151 if (valid_identifier (base)) | |
152 fcn_files[fcn_files_count++] = fname; | |
153 } | |
154 } | |
155 } | |
156 } | |
157 } | |
158 | |
159 all_files.resize (all_files_count); | |
160 fcn_files.resize (fcn_files_count); | |
161 } | |
162 else | |
163 { | |
164 std::string msg = dir.error (); | |
165 warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); | |
166 } | |
167 | |
168 return has_private_subdir; | |
169 } | |
170 | |
171 void | |
172 load_path::dir_info::get_private_function_map (const std::string& d) | |
173 { | |
174 dir_entry dir (d); | |
175 | |
176 if (dir) | |
177 { | |
178 string_vector flist = dir.read (); | |
179 | |
180 octave_idx_type len = flist.length (); | |
181 | |
182 for (octave_idx_type i = 0; i < len; i++) | |
183 { | |
184 std::string fname = flist[i]; | |
185 | |
186 std::string ext; | |
187 std::string base = fname; | |
188 | |
189 size_t pos = fname.rfind ('.'); | |
190 | |
191 if (pos != NPOS) | |
192 { | |
193 base = fname.substr (0, pos); | |
194 ext = fname.substr (pos); | |
195 | |
196 if (valid_identifier (base)) | |
197 { | |
198 int t = 0; | |
199 | |
200 if (ext == ".m") | |
201 t = load_path::M_FILE; | |
202 else if (ext == ".oct") | |
203 t = load_path::OCT_FILE; | |
5864 | 204 else if (ext == ".mex") |
205 t = load_path::MEX_FILE; | |
5832 | 206 |
207 private_function_map[base] |= t; | |
208 } | |
209 } | |
210 } | |
211 } | |
212 else | |
213 { | |
214 std::string msg = dir.error (); | |
215 warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); | |
216 } | |
217 } | |
218 | |
219 bool | |
220 load_path::instance_ok (void) | |
221 { | |
222 bool retval = true; | |
223 | |
224 if (! instance) | |
225 instance = new load_path (); | |
226 | |
227 if (! instance) | |
228 { | |
229 ::error ("unable to create load path object!"); | |
230 | |
231 retval = false; | |
232 } | |
233 | |
234 return retval; | |
235 } | |
236 | |
237 load_path::const_dir_info_list_iterator | |
5919 | 238 load_path::find_dir_info (const std::string& dir_arg) const |
5832 | 239 { |
5919 | 240 std::string dir = file_ops::tilde_expand (dir_arg); |
241 | |
5832 | 242 const_dir_info_list_iterator retval = dir_info_list.begin (); |
243 | |
244 while (retval != dir_info_list.end ()) | |
245 { | |
246 if (retval->dir_name == dir) | |
247 break; | |
248 | |
249 retval++; | |
250 } | |
251 | |
252 return retval; | |
253 } | |
254 | |
255 load_path::dir_info_list_iterator | |
5919 | 256 load_path::find_dir_info (const std::string& dir_arg) |
5832 | 257 { |
5919 | 258 std::string dir = file_ops::tilde_expand (dir_arg); |
259 | |
5832 | 260 dir_info_list_iterator retval = dir_info_list.begin (); |
261 | |
262 while (retval != dir_info_list.end ()) | |
263 { | |
264 if (retval->dir_name == dir) | |
265 break; | |
266 | |
267 retval++; | |
268 } | |
269 | |
270 return retval; | |
271 } | |
272 | |
273 bool | |
274 load_path::contains (const std::string& dir) const | |
275 { | |
276 return find_dir_info (dir) != dir_info_list.end (); | |
277 } | |
278 | |
279 void | |
280 load_path::move (dir_info_list_iterator i, bool at_end) | |
281 { | |
282 if (dir_info_list.size () > 1) | |
283 { | |
284 dir_info di = *i; | |
285 | |
286 dir_info_list.erase (i); | |
287 | |
288 if (at_end) | |
289 dir_info_list.push_back (di); | |
290 else | |
291 dir_info_list.push_front (di); | |
292 | |
293 std::string dir = di.dir_name; | |
294 | |
295 string_vector fcn_files = di.fcn_files; | |
296 | |
297 octave_idx_type len = fcn_files.length (); | |
298 | |
299 for (octave_idx_type k = 0; k < len; k++) | |
300 { | |
301 std::string fname = fcn_files[k]; | |
302 | |
303 std::string ext; | |
304 std::string base = fname; | |
305 | |
306 size_t pos = fname.rfind ('.'); | |
307 | |
308 if (pos != NPOS) | |
309 { | |
310 base = fname.substr (0, pos); | |
311 ext = fname.substr (pos); | |
312 } | |
313 | |
314 std::list<file_info>& file_info_list = fcn_map[base]; | |
315 | |
316 if (file_info_list.size () == 1) | |
317 continue; | |
318 else | |
319 { | |
320 for (std::list<file_info>::iterator p = file_info_list.begin (); | |
321 p != file_info_list.end (); | |
322 p++) | |
323 { | |
324 if (p->dir_name == dir) | |
325 { | |
6149 | 326 file_info fi = *p; |
5832 | 327 |
328 file_info_list.erase (p); | |
329 | |
330 if (at_end) | |
331 file_info_list.push_back (fi); | |
332 else | |
333 file_info_list.push_front (fi); | |
334 | |
335 break; | |
336 } | |
337 } | |
338 } | |
339 } | |
340 } | |
341 } | |
342 | |
343 static void | |
344 maybe_add_path_elts (std::string& path, const std::string& dir) | |
345 { | |
346 std::string tpath = genpath (dir); | |
347 | |
348 if (! tpath.empty ()) | |
11614 | 349 { |
350 if (path.empty ()) | |
351 path = tpath; | |
352 else | |
353 path += dir_path::path_sep_str + tpath; | |
354 } | |
5832 | 355 } |
356 | |
357 void | |
6365 | 358 load_path::do_initialize (bool set_initial_path) |
5832 | 359 { |
11614 | 360 sys_path = ""; |
5832 | 361 |
6365 | 362 if (set_initial_path) |
363 { | |
6626 | 364 maybe_add_path_elts (sys_path, Vlocal_ver_oct_file_dir); |
365 maybe_add_path_elts (sys_path, Vlocal_api_oct_file_dir); | |
366 maybe_add_path_elts (sys_path, Vlocal_oct_file_dir); | |
367 maybe_add_path_elts (sys_path, Vlocal_ver_fcn_file_dir); | |
368 maybe_add_path_elts (sys_path, Vlocal_api_fcn_file_dir); | |
369 maybe_add_path_elts (sys_path, Vlocal_fcn_file_dir); | |
370 maybe_add_path_elts (sys_path, Voct_file_dir); | |
371 maybe_add_path_elts (sys_path, Vfcn_file_dir); | |
6365 | 372 } |
5832 | 373 |
374 std::string tpath = load_path::command_line_path; | |
375 | |
376 if (tpath.empty ()) | |
11856
ee51db2f6a6a
load-path.cc (load_path::do_initialize): look for OCTAVE_PATH in the environment, not OCTAVE_LOADPATH
John W. Eaton <jwe@octave.org>
parents:
11843
diff
changeset
|
377 tpath = octave_env::getenv ("OCTAVE_PATH"); |
5832 | 378 |
379 std::string xpath = "."; | |
380 | |
381 if (! tpath.empty ()) | |
382 xpath += dir_path::path_sep_str + tpath; | |
383 | |
11614 | 384 if (! sys_path.empty ()) |
11836
7b8f1b431b03
load-path.cc (load_path::initialize): include separator when appending sys_path
Kim Hansen
parents:
11814
diff
changeset
|
385 xpath += dir_path::path_sep_str + sys_path; |
5832 | 386 |
6119 | 387 do_set (xpath, false); |
5832 | 388 } |
389 | |
390 void | |
391 load_path::do_clear (void) | |
392 { | |
393 dir_info_list.clear (); | |
394 fcn_map.clear (); | |
5867 | 395 |
396 do_append (".", false); | |
5832 | 397 } |
398 | |
399 static std::list<std::string> | |
400 split_path (const std::string& p) | |
401 { | |
402 std::list<std::string> retval; | |
403 | |
404 size_t beg = 0; | |
405 size_t end = p.find (dir_path::path_sep_char); | |
406 | |
407 size_t len = p.length (); | |
408 | |
409 while (end != NPOS) | |
410 { | |
411 std::string elt = p.substr (beg, end-beg); | |
412 | |
413 if (! elt.empty ()) | |
414 retval.push_back (elt); | |
415 | |
416 beg = end + 1; | |
417 | |
418 if (beg == len) | |
419 break; | |
420 | |
421 end = p.find (dir_path::path_sep_char, beg); | |
422 } | |
423 | |
424 std::string elt = p.substr (beg); | |
425 | |
426 if (! elt.empty ()) | |
427 retval.push_back (elt); | |
428 | |
429 return retval; | |
430 } | |
431 | |
432 void | |
5867 | 433 load_path::do_set (const std::string& p, bool warn) |
5832 | 434 { |
435 do_clear (); | |
436 | |
437 std::list<std::string> elts = split_path (p); | |
438 | |
439 // Temporarily disable add hook. | |
440 | |
5854 | 441 unwind_protect_fptr (add_hook); |
5832 | 442 |
443 add_hook = 0; | |
444 | |
445 for (std::list<std::string>::const_iterator i = elts.begin (); | |
446 i != elts.end (); | |
447 i++) | |
5867 | 448 do_append (*i, warn); |
5832 | 449 |
450 // Restore add hook and execute for all newly added directories. | |
451 | |
452 unwind_protect::run (); | |
453 | |
454 for (dir_info_list_iterator i = dir_info_list.begin (); | |
455 i != dir_info_list.end (); | |
456 i++) | |
457 { | |
458 if (add_hook) | |
459 add_hook (i->dir_name); | |
460 } | |
461 } | |
462 | |
463 void | |
5867 | 464 load_path::do_append (const std::string& dir, bool warn) |
5832 | 465 { |
466 if (! dir.empty ()) | |
5867 | 467 do_add (dir, true, warn); |
468 } | |
5832 | 469 |
5867 | 470 void |
471 load_path::do_prepend (const std::string& dir, bool warn) | |
472 { | |
473 if (! dir.empty ()) | |
474 do_add (dir, false, warn); | |
5832 | 475 } |
476 | |
477 void | |
5919 | 478 load_path::do_add (const std::string& dir_arg, bool at_end, bool warn) |
5832 | 479 { |
5919 | 480 size_t len = dir_arg.length (); |
5911 | 481 |
5919 | 482 if (len > 1 && dir_arg.substr (len-2) == "//") |
5911 | 483 warning_with_id ("Octave:recursive-path-search", |
484 "trailing `//' is no longer special in search path elements"); | |
485 | |
5919 | 486 std::string dir = file_ops::tilde_expand (dir_arg); |
487 | |
5867 | 488 dir_info_list_iterator i = find_dir_info (dir); |
489 | |
490 if (i != dir_info_list.end ()) | |
491 move (i, at_end); | |
492 else | |
5832 | 493 { |
5867 | 494 file_stat fs (dir); |
5832 | 495 |
5867 | 496 if (fs) |
5832 | 497 { |
5867 | 498 if (fs.is_dir ()) |
499 { | |
500 dir_info di (dir); | |
5832 | 501 |
5867 | 502 if (! error_state) |
503 { | |
504 if (at_end) | |
505 dir_info_list.push_back (di); | |
506 else | |
507 dir_info_list.push_front (di); | |
508 | |
509 add_to_fcn_map (di, true); | |
5832 | 510 |
5867 | 511 if (add_hook) |
512 add_hook (dir); | |
513 } | |
5832 | 514 } |
5867 | 515 else if (warn) |
5919 | 516 warning ("addpath: %s: not a directory", dir_arg.c_str ()); |
5832 | 517 } |
5867 | 518 else if (warn) |
519 { | |
520 std::string msg = fs.error (); | |
5919 | 521 warning ("addpath: %s: %s", dir_arg.c_str (), msg.c_str ()); |
5867 | 522 } |
523 } | |
5832 | 524 |
5867 | 525 // FIXME -- is there a better way to do this? |
5832 | 526 |
5867 | 527 i = find_dir_info ("."); |
5832 | 528 |
5867 | 529 if (i != dir_info_list.end ()) |
5871 | 530 move (i, false); |
5867 | 531 else |
532 panic_impossible (); | |
5832 | 533 } |
534 | |
535 bool | |
5919 | 536 load_path::do_remove (const std::string& dir_arg) |
5832 | 537 { |
538 bool retval = false; | |
539 | |
5919 | 540 if (! dir_arg.empty ()) |
5832 | 541 { |
5919 | 542 if (dir_arg == ".") |
5867 | 543 { |
544 warning ("rmpath: can't remove \".\" from path"); | |
5832 | 545 |
5867 | 546 // Avoid additional warnings. |
5832 | 547 retval = true; |
5867 | 548 } |
549 else | |
550 { | |
5919 | 551 std::string dir = file_ops::tilde_expand (dir_arg); |
552 | |
5867 | 553 dir_info_list_iterator i = find_dir_info (dir); |
5832 | 554 |
5867 | 555 if (i != dir_info_list.end ()) |
556 { | |
557 retval = true; | |
5832 | 558 |
6825 | 559 if (remove_hook) |
560 remove_hook (dir); | |
561 | |
5867 | 562 string_vector fcn_files = i->fcn_files; |
563 | |
564 dir_info_list.erase (i); | |
5832 | 565 |
5867 | 566 octave_idx_type len = fcn_files.length (); |
567 | |
568 for (octave_idx_type k = 0; k < len; k++) | |
569 { | |
570 std::string fname = fcn_files[k]; | |
5832 | 571 |
5867 | 572 std::string ext; |
573 std::string base = fname; | |
574 | |
575 size_t pos = fname.rfind ('.'); | |
5832 | 576 |
5867 | 577 if (pos != NPOS) |
578 { | |
579 base = fname.substr (0, pos); | |
580 ext = fname.substr (pos); | |
581 } | |
582 | |
583 std::list<file_info>& file_info_list = fcn_map[base]; | |
5832 | 584 |
5867 | 585 for (std::list<file_info>::iterator p = file_info_list.begin (); |
586 p != file_info_list.end (); | |
587 p++) | |
588 { | |
589 if (p->dir_name == dir) | |
590 { | |
591 file_info_list.erase (p); | |
5832 | 592 |
5867 | 593 if (file_info_list.empty ()) |
594 fcn_map.erase (fname); | |
595 | |
596 break; | |
597 } | |
598 } | |
5832 | 599 } |
600 } | |
601 } | |
602 } | |
603 | |
604 return retval; | |
605 } | |
606 | |
607 void | |
608 load_path::do_update (void) const | |
609 { | |
610 // I don't see a better way to do this because we need to | |
611 // preserve the correct directory ordering for new files that | |
612 // have appeared. | |
613 | |
614 fcn_map.clear (); | |
615 | |
616 for (dir_info_list_iterator p = dir_info_list.begin (); | |
617 p != dir_info_list.end (); | |
618 p++) | |
619 { | |
620 dir_info& di = *p; | |
621 | |
622 di.update (); | |
623 | |
624 add_to_fcn_map (di, true); | |
625 } | |
626 } | |
627 | |
628 std::string | |
629 load_path::do_find_fcn (const std::string& fcn, int type) const | |
630 { | |
631 std::string retval; | |
632 | |
633 update (); | |
634 | |
635 const_fcn_map_iterator p = fcn_map.find (fcn); | |
636 | |
637 if (p != fcn_map.end ()) | |
638 { | |
639 const std::list<file_info>& file_info_list = p->second; | |
640 | |
641 for (const_file_info_list_iterator i = file_info_list.begin (); | |
642 i != file_info_list.end (); | |
643 i++) | |
644 { | |
645 const file_info& fi = *i; | |
646 | |
647 int t = fi.types; | |
648 | |
7272 | 649 retval = file_ops::concat (fi.dir_name, fcn); |
5832 | 650 |
651 if (type == load_path::OCT_FILE) | |
652 { | |
653 if ((type & t) == load_path::OCT_FILE) | |
654 { | |
655 retval += ".oct"; | |
656 break; | |
657 } | |
658 } | |
659 else if (type == load_path::M_FILE) | |
660 { | |
661 if ((type & t) == load_path::M_FILE) | |
662 { | |
663 retval += ".m"; | |
664 break; | |
665 } | |
666 } | |
5864 | 667 else if (type == load_path::MEX_FILE) |
668 { | |
669 if ((type & t) == load_path::MEX_FILE) | |
670 { | |
671 retval += ".mex"; | |
672 break; | |
673 } | |
674 } | |
5832 | 675 else if (type == (load_path::M_FILE | load_path::OCT_FILE)) |
676 { | |
677 if (t & load_path::OCT_FILE) | |
678 { | |
679 retval += ".oct"; | |
680 break; | |
681 } | |
682 else if (t & load_path::M_FILE) | |
683 { | |
684 retval += ".m"; | |
685 break; | |
686 } | |
687 } | |
5864 | 688 else if (type == (load_path::M_FILE | load_path::MEX_FILE)) |
689 { | |
690 if (t & load_path::MEX_FILE) | |
691 { | |
692 retval += ".mex"; | |
693 break; | |
694 } | |
695 else if (t & load_path::M_FILE) | |
696 { | |
697 retval += ".m"; | |
698 break; | |
699 } | |
700 } | |
701 else if (type == (load_path::OCT_FILE | load_path::MEX_FILE)) | |
702 { | |
703 if (t & load_path::OCT_FILE) | |
704 { | |
705 retval += ".oct"; | |
706 break; | |
707 } | |
708 else if (t & load_path::MEX_FILE) | |
709 { | |
710 retval += ".mex"; | |
711 break; | |
712 } | |
713 } | |
714 else if (type == (load_path::M_FILE | load_path::OCT_FILE | |
715 | load_path::MEX_FILE)) | |
716 { | |
717 if (t & load_path::OCT_FILE) | |
718 { | |
719 retval += ".oct"; | |
720 break; | |
721 } | |
722 else if (t & load_path::MEX_FILE) | |
723 { | |
724 retval += ".mex"; | |
725 break; | |
726 } | |
727 else if (t & load_path::M_FILE) | |
728 { | |
729 retval += ".m"; | |
730 break; | |
731 } | |
732 } | |
5832 | 733 else |
734 error ("load_path::do_find_fcn: %s: invalid type code = %d", | |
735 fcn.c_str (), type); | |
6196 | 736 |
737 // Reset the return string, in case the above tesst fail. | |
738 retval = std::string (); | |
5832 | 739 } |
740 } | |
741 | |
742 return retval; | |
743 } | |
744 | |
745 std::string | |
746 load_path::do_find_file (const std::string& file) const | |
747 { | |
748 std::string retval; | |
749 | |
6850 | 750 if (file.find_first_of (file_ops::dir_sep_chars) != NPOS) |
5832 | 751 { |
6838 | 752 if (octave_env::absolute_pathname (file) |
753 || octave_env::rooted_relative_pathname (file)) | |
754 { | |
755 file_stat fs (file); | |
5832 | 756 |
6838 | 757 if (fs.exists ()) |
758 return file; | |
759 } | |
760 else | |
761 { | |
762 for (const_dir_info_list_iterator p = dir_info_list.begin (); | |
763 p != dir_info_list.end (); | |
764 p++) | |
765 { | |
7272 | 766 std::string tfile = file_ops::concat (p->dir_name, file); |
5832 | 767 |
6838 | 768 file_stat fs (tfile); |
6159 | 769 |
6838 | 770 if (fs.exists ()) |
771 return tfile; | |
5832 | 772 } |
773 } | |
774 } | |
6838 | 775 else |
776 { | |
777 for (const_dir_info_list_iterator p = dir_info_list.begin (); | |
778 p != dir_info_list.end (); | |
779 p++) | |
780 { | |
781 string_vector all_files = p->all_files; | |
6159 | 782 |
6838 | 783 octave_idx_type len = all_files.length (); |
784 | |
785 for (octave_idx_type i = 0; i < len; i++) | |
786 { | |
787 if (all_files[i] == file) | |
7272 | 788 return file_ops::concat (p->dir_name, file); |
6838 | 789 } |
790 } | |
791 } | |
5832 | 792 |
793 return retval; | |
794 } | |
795 | |
796 std::string | |
11814
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
797 load_path::do_find_dir (const std::string& dir) const |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
798 { |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
799 std::string retval; |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
800 |
11843
d1b8260dbc76
fix problems from transplant 7552
Jaroslav Hajek <highegg@gmail.com>
parents:
11836
diff
changeset
|
801 if (dir.find_first_of (file_ops::dir_sep_chars) != std::string::npos |
11814
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
802 && (octave_env::absolute_pathname (dir) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
803 || octave_env::rooted_relative_pathname (dir))) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
804 { |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
805 file_stat fs (dir); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
806 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
807 if (fs.exists () && fs.is_dir ()) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
808 return dir; |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
809 } |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
810 else |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
811 { |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
812 for (const_dir_info_list_iterator p = dir_info_list.begin (); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
813 p != dir_info_list.end (); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
814 p++) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
815 { |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
816 std::string dname = p->dir_name; |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
817 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
818 size_t dname_len = dname.length (); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
819 |
11843
d1b8260dbc76
fix problems from transplant 7552
Jaroslav Hajek <highegg@gmail.com>
parents:
11836
diff
changeset
|
820 if (dname.substr (dname_len - 1) == file_ops::dir_sep_str) |
11814
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
821 dname = dname.substr (0, dname_len - 1); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
822 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
823 size_t dir_len = dir.length (); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
824 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
825 if (dname_len >= dir_len |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
826 && file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
827 && dir.compare (dname.substr (dname_len - dir_len)) == 0) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
828 { |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
829 file_stat fs (p->dir_name); |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
830 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
831 if (fs.exists () && fs.is_dir ()) |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
832 return p->dir_name; |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
833 } |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
834 } |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
835 } |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
836 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
837 return retval; |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
838 } |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
839 |
2ca993580aca
Add a search for Contents.m files to the help function
David Bateman <dbateman@free.fr>
parents:
11740
diff
changeset
|
840 std::string |
5832 | 841 load_path::do_find_first_of (const string_vector& flist) const |
842 { | |
843 std::string retval; | |
844 | |
845 std::string dir_name; | |
846 std::string file_name; | |
847 | |
848 octave_idx_type flen = flist.length (); | |
849 octave_idx_type rel_flen = 0; | |
850 | |
851 string_vector rel_flist (flen); | |
852 | |
853 for (octave_idx_type i = 0; i < flen; i++) | |
854 { | |
855 if (octave_env::absolute_pathname (flist[i])) | |
856 { | |
857 file_stat fs (flist[i]); | |
858 | |
859 if (fs.exists ()) | |
860 return flist[i]; | |
861 } | |
862 else | |
863 rel_flist[rel_flen++] = flist[i]; | |
864 } | |
865 | |
866 rel_flist.resize (rel_flen); | |
867 | |
868 for (const_dir_info_list_iterator p = dir_info_list.begin (); | |
869 p != dir_info_list.end (); | |
870 p++) | |
871 { | |
872 string_vector all_files = p->all_files; | |
873 | |
874 octave_idx_type len = all_files.length (); | |
875 | |
876 for (octave_idx_type i = 0; i < len; i++) | |
877 { | |
878 for (octave_idx_type j = 0; j < rel_flen; j++) | |
879 { | |
880 if (all_files[i] == rel_flist[j]) | |
881 { | |
882 dir_name = p->dir_name; | |
883 file_name = rel_flist[j]; | |
6159 | 884 |
885 goto done; | |
5832 | 886 } |
887 } | |
888 } | |
889 } | |
890 | |
6159 | 891 done: |
892 | |
5832 | 893 if (! dir_name.empty ()) |
7272 | 894 retval = file_ops::concat (dir_name, file_name); |
5832 | 895 |
896 return retval; | |
897 } | |
898 | |
899 string_vector | |
900 load_path::do_find_all_first_of (const string_vector& flist) const | |
901 { | |
902 std::list<std::string> retlist; | |
903 | |
904 std::string dir_name; | |
905 std::string file_name; | |
906 | |
907 octave_idx_type flen = flist.length (); | |
908 octave_idx_type rel_flen = 0; | |
909 | |
910 string_vector rel_flist (flen); | |
911 | |
912 for (octave_idx_type i = 0; i < flen; i++) | |
913 { | |
914 if (octave_env::absolute_pathname (flist[i])) | |
915 { | |
916 file_stat fs (flist[i]); | |
917 | |
918 if (fs.exists ()) | |
919 retlist.push_back (flist[i]); | |
920 } | |
921 else | |
922 rel_flist[rel_flen++] = flist[i]; | |
923 } | |
924 | |
925 rel_flist.resize (rel_flen); | |
926 | |
927 for (const_dir_info_list_iterator p = dir_info_list.begin (); | |
928 p != dir_info_list.end (); | |
929 p++) | |
930 { | |
931 string_vector all_files = p->all_files; | |
932 | |
933 octave_idx_type len = all_files.length (); | |
934 | |
935 for (octave_idx_type i = 0; i < len; i++) | |
936 { | |
937 for (octave_idx_type j = 0; j < rel_flen; j++) | |
938 { | |
939 if (all_files[i] == rel_flist[j]) | |
940 retlist.push_back | |
7272 | 941 (file_ops::concat (p->dir_name, rel_flist[j])); |
5832 | 942 } |
943 } | |
944 } | |
945 | |
946 size_t retsize = retlist.size (); | |
947 | |
948 string_vector retval (retsize); | |
949 | |
950 for (size_t i = 0; i < retsize; i++) | |
951 { | |
952 retval[i] = retlist.front (); | |
953 | |
954 retlist.pop_front (); | |
955 } | |
956 | |
957 return retval; | |
958 } | |
959 | |
960 string_vector | |
961 load_path::do_dirs (void) const | |
962 { | |
963 size_t len = dir_info_list.size (); | |
964 | |
965 string_vector retval (len); | |
966 | |
967 octave_idx_type k = 0; | |
968 | |
969 for (const_dir_info_list_iterator i = dir_info_list.begin (); | |
970 i != dir_info_list.end (); | |
971 i++) | |
972 retval[k++] = i->dir_name; | |
973 | |
974 return retval; | |
975 } | |
976 | |
977 std::list<std::string> | |
978 load_path::do_dir_list (void) const | |
979 { | |
980 std::list<std::string> retval; | |
981 | |
982 for (const_dir_info_list_iterator i = dir_info_list.begin (); | |
983 i != dir_info_list.end (); | |
984 i++) | |
985 retval.push_back (i->dir_name); | |
986 | |
987 return retval; | |
988 } | |
989 | |
990 string_vector | |
991 load_path::do_files (const std::string& dir) const | |
992 { | |
993 string_vector retval; | |
994 | |
995 const_dir_info_list_iterator i = find_dir_info (dir); | |
996 | |
997 if (i != dir_info_list.end ()) | |
998 retval = i->fcn_files; | |
999 | |
1000 return retval; | |
1001 } | |
1002 | |
1003 string_vector | |
1004 load_path::do_fcn_names (void) const | |
1005 { | |
1006 size_t len = fcn_map.size (); | |
1007 | |
1008 string_vector retval (len); | |
1009 | |
1010 octave_idx_type count = 0; | |
1011 | |
1012 for (const_fcn_map_iterator p = fcn_map.begin (); | |
1013 p != fcn_map.end (); | |
1014 p++) | |
1015 retval[count++] = p->first; | |
1016 | |
1017 return retval; | |
1018 } | |
1019 | |
1020 std::string | |
1021 load_path::do_path (void) const | |
1022 { | |
1023 std::string xpath; | |
1024 | |
1025 string_vector xdirs = load_path::dirs (); | |
1026 | |
1027 octave_idx_type len = xdirs.length (); | |
1028 | |
1029 if (len > 0) | |
1030 xpath = xdirs[0]; | |
1031 | |
1032 for (octave_idx_type i = 1; i < len; i++) | |
1033 xpath += dir_path::path_sep_str + xdirs[i]; | |
1034 | |
1035 return xpath; | |
1036 } | |
1037 | |
1038 void | |
1039 load_path::do_display (std::ostream& os) const | |
1040 { | |
1041 for (const_dir_info_list_iterator i = dir_info_list.begin (); | |
1042 i != dir_info_list.end (); | |
1043 i++) | |
1044 { | |
1045 string_vector fcn_files = i->fcn_files; | |
1046 | |
1047 if (! fcn_files.empty ()) | |
1048 { | |
1049 os << "\n*** function files in " << i->dir_name << ":\n\n"; | |
1050 | |
1051 fcn_files.list_in_columns (os); | |
1052 } | |
1053 | |
1054 #if defined (DEBUG_LOAD_PATH) | |
1055 | |
1056 const std::map<std::string, int>& private_function_map | |
1057 = i->private_function_map; | |
1058 | |
1059 if (private_function_map.size () > 0) | |
1060 { | |
1061 os << "private:\n"; | |
1062 | |
1063 for (std::map<std::string, int>::const_iterator p = private_function_map.begin (); | |
1064 p != private_function_map.end (); | |
1065 p++) | |
1066 { | |
1067 os << " " << p->first << " ("; | |
1068 | |
1069 bool printed_type = false; | |
1070 | |
1071 int types = p->second; | |
1072 | |
1073 if (types & load_path::OCT_FILE) | |
1074 { | |
1075 os << "oct"; | |
1076 printed_type = true; | |
1077 } | |
1078 | |
5864 | 1079 if (types & load_path::MEX_FILE) |
1080 { | |
1081 if (printed_type) | |
1082 os << "|"; | |
1083 os << "mex"; | |
1084 printed_type = true; | |
1085 } | |
1086 | |
5832 | 1087 if (types & load_path::M_FILE) |
1088 { | |
1089 if (printed_type) | |
1090 os << "|"; | |
1091 os << "m"; | |
1092 printed_type = true; | |
1093 } | |
1094 | |
1095 os << ")\n"; | |
1096 } | |
1097 | |
1098 os << "\n"; | |
1099 } | |
1100 #endif | |
1101 } | |
1102 | |
1103 #if defined (DEBUG_LOAD_PATH) | |
1104 | |
1105 for (const_fcn_map_iterator i = fcn_map.begin (); | |
1106 i != fcn_map.end (); | |
1107 i++) | |
1108 { | |
1109 os << i->first << ":\n"; | |
1110 | |
1111 const std::list<file_info>& file_info_list = i->second; | |
1112 | |
1113 for (const_file_info_list_iterator p = file_info_list.begin (); | |
1114 p != file_info_list.end (); | |
1115 p++) | |
1116 { | |
1117 os << " " << p->dir_name << " ("; | |
1118 | |
1119 bool printed_type = false; | |
1120 | |
1121 if (p->types & load_path::OCT_FILE) | |
1122 { | |
1123 os << "oct"; | |
1124 printed_type = true; | |
1125 } | |
1126 | |
5864 | 1127 if (p->types & load_path::MEX_FILE) |
1128 { | |
1129 if (printed_type) | |
1130 os << "|"; | |
1131 os << "mex"; | |
1132 printed_type = true; | |
1133 } | |
1134 | |
5832 | 1135 if (p->types & load_path::M_FILE) |
1136 { | |
1137 if (printed_type) | |
1138 os << "|"; | |
1139 os << "m"; | |
1140 printed_type = true; | |
1141 } | |
1142 | |
1143 os << ")\n"; | |
1144 } | |
1145 } | |
1146 | |
1147 os << "\n"; | |
1148 | |
1149 #endif | |
1150 } | |
1151 | |
1152 void | |
1153 load_path::add_to_fcn_map (const dir_info& di, bool at_end) const | |
1154 { | |
1155 std::string dir_name = di.dir_name; | |
1156 | |
1157 string_vector fcn_files = di.fcn_files; | |
1158 | |
1159 octave_idx_type len = fcn_files.length (); | |
1160 | |
1161 for (octave_idx_type i = 0; i < len; i++) | |
1162 { | |
1163 std::string fname = fcn_files[i]; | |
1164 | |
1165 std::string ext; | |
1166 std::string base = fname; | |
1167 | |
1168 size_t pos = fname.rfind ('.'); | |
1169 | |
1170 if (pos != NPOS) | |
1171 { | |
1172 base = fname.substr (0, pos); | |
1173 ext = fname.substr (pos); | |
1174 } | |
1175 | |
1176 std::list<file_info>& file_info_list = fcn_map[base]; | |
1177 | |
1178 file_info_list_iterator p = file_info_list.begin (); | |
1179 | |
1180 while (p != file_info_list.end ()) | |
1181 { | |
1182 if (p->dir_name == dir_name) | |
1183 break; | |
1184 | |
1185 p++; | |
1186 } | |
1187 | |
1188 int t = 0; | |
1189 if (ext == ".m") | |
1190 t = load_path::M_FILE; | |
1191 else if (ext == ".oct") | |
1192 t = load_path::OCT_FILE; | |
5864 | 1193 else if (ext == ".mex") |
1194 t = load_path::MEX_FILE; | |
5832 | 1195 |
1196 if (p == file_info_list.end ()) | |
1197 { | |
1198 file_info fi (dir_name, t); | |
1199 | |
1200 if (at_end) | |
1201 file_info_list.push_back (fi); | |
1202 else | |
1203 file_info_list.push_front (fi); | |
1204 } | |
1205 else | |
1206 { | |
1207 file_info& fi = *p; | |
1208 | |
1209 fi.types |= t; | |
1210 } | |
1211 } | |
1212 } | |
1213 | |
1214 std::string | |
1215 genpath (const std::string& dirname, const string_vector& skip) | |
1216 { | |
1217 std::string retval; | |
1218 | |
5871 | 1219 dir_entry dir (dirname); |
5832 | 1220 |
1221 if (dir) | |
1222 { | |
1223 retval = dirname; | |
1224 | |
1225 string_vector dirlist = dir.read (); | |
1226 | |
1227 octave_idx_type len = dirlist.length (); | |
1228 | |
1229 for (octave_idx_type i = 0; i < len; i++) | |
1230 { | |
1231 std::string elt = dirlist[i]; | |
1232 | |
1233 // FIXME -- the caller should be able to specify the list of | |
1234 // directories to skip in addition to "." and "..". | |
1235 | |
1236 bool skip_p = (elt == "." || elt == ".."); | |
1237 | |
1238 if (! skip_p) | |
1239 { | |
1240 for (octave_idx_type j = 0; j < skip.length (); j++) | |
1241 { | |
1242 skip_p = (elt == skip[j]); | |
1243 if (skip_p) | |
1244 break; | |
1245 } | |
1246 | |
1247 if (! skip_p) | |
1248 { | |
7272 | 1249 std::string nm = file_ops::concat (dirname, elt); |
5832 | 1250 |
1251 file_stat fs (nm); | |
1252 | |
1253 if (fs && fs.is_dir ()) | |
1254 retval += dir_path::path_sep_str + genpath (nm); | |
1255 } | |
1256 } | |
1257 } | |
1258 } | |
1259 | |
1260 return retval; | |
1261 } | |
1262 | |
1263 static void | |
1264 execute_pkg_add_or_del (const std::string& dir, | |
1265 const std::string& script_file) | |
1266 { | |
1267 if (! octave_interpreter_ready) | |
1268 return; | |
1269 | |
1270 unwind_protect::begin_frame ("execute_pkg_add_or_del"); | |
1271 | |
1272 unwind_protect_bool (input_from_startup_file); | |
1273 | |
1274 input_from_startup_file = true; | |
1275 | |
7272 | 1276 std::string file = file_ops::concat (dir, script_file); |
5832 | 1277 |
5978 | 1278 file_stat fs (file); |
5832 | 1279 |
1280 if (fs.exists ()) | |
5975 | 1281 source_file (file, "base"); |
5832 | 1282 |
1283 unwind_protect::run_frame ("execute_pkg_add_or_del"); | |
1284 } | |
1285 | |
1286 void | |
1287 execute_pkg_add (const std::string& dir) | |
1288 { | |
1289 execute_pkg_add_or_del (dir, "PKG_ADD"); | |
1290 } | |
1291 | |
1292 void | |
1293 execute_pkg_del (const std::string& dir) | |
1294 { | |
1295 execute_pkg_add_or_del (dir, "PKG_DEL"); | |
1296 } | |
1297 | |
1298 DEFUN (genpath, args, , | |
1299 "-*- texinfo -*-\n\ | |
1300 @deftypefn {Built-in Function} {} genpath (@var{dir})\n\ | |
11885
3342d1a7c4c9
spelling corrections
Brian Gough<bjg@network-theory.co.uk>
parents:
11856
diff
changeset
|
1301 Return a path constructed from @var{dir} and all its subdirectories.\n\ |
5832 | 1302 @end deftypefn") |
1303 { | |
1304 octave_value retval; | |
1305 | |
1306 if (args.length () == 1) | |
1307 { | |
1308 std::string dirname = args(0).string_value (); | |
1309 | |
1310 if (! error_state) | |
1311 retval = genpath (dirname); | |
1312 else | |
1313 error ("genpath: expecting argument to be a character string"); | |
1314 } | |
1315 else | |
1316 print_usage (); | |
1317 | |
1318 return retval; | |
1319 } | |
1320 | |
1321 DEFUN (rehash, , , | |
1322 "-*- texinfo -*-\n\ | |
1323 @deftypefn {Built-in Function} {} rehash ()\n\ | |
6644 | 1324 Reinitialize Octave's load path directory cache.\n\ |
5832 | 1325 @end deftypefn") |
1326 { | |
1327 octave_value_list retval; | |
1328 | |
1329 load_path::update (); | |
1330 | |
1331 // FIXME -- maybe we should rename this variable since it is being | |
1332 // used for more than keeping track of the prompt time. | |
1333 | |
1334 // This will force updated functions to be found. | |
1335 Vlast_prompt_time.stamp (); | |
1336 | |
1337 return retval; | |
1338 } | |
1339 | |
1340 DEFUN (pathdef, , , | |
1341 "-*- texinfo -*-\n\ | |
1342 @deftypefn {Built-in Function} {@var{val} =} pathdef ()\n\ | |
1343 Return the default list of directories in which to search for function\n\ | |
1344 files.\n\ | |
1345 @seealso{path, addpath, rmpath, genpath, savepath, pathsep}\n\ | |
1346 @end deftypefn") | |
1347 { | |
6630 | 1348 return octave_value (load_path::system_path ()); |
5832 | 1349 } |
1350 | |
1351 DEFUN (path, args, nargout, | |
1352 "-*- texinfo -*-\n\ | |
6678 | 1353 @deftypefn {Built-in Function} {} path (@dots{})\n\ |
6644 | 1354 Modify or display Octave's load path.\n\ |
5832 | 1355 \n\ |
1356 If @var{nargin} and @var{nargout} are zero, display the elements of\n\ | |
6644 | 1357 Octave's load path in an easy to read format.\n\ |
5832 | 1358 \n\ |
1359 If @var{nargin} is zero and nargout is greater than zero, return the\n\ | |
6644 | 1360 current load path.\n\ |
5832 | 1361 \n\ |
1362 If @var{nargin} is greater than zero, concatenate the arguments,\n\ | |
1363 separating them with @code{pathsep()}. Set the internal search path\n\ | |
1364 to the result and return it.\n\ | |
1365 \n\ | |
1366 No checks are made for duplicate elements.\n\ | |
1367 @seealso{addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\ | |
1368 @end deftypefn") | |
1369 { | |
1370 octave_value retval; | |
1371 | |
1372 int argc = args.length () + 1; | |
1373 | |
1374 string_vector argv = args.make_argv ("path"); | |
1375 | |
1376 if (! error_state) | |
1377 { | |
1378 if (argc > 1) | |
1379 { | |
1380 std::string path = argv[1]; | |
1381 | |
1382 for (int i = 2; i < argc; i++) | |
5867 | 1383 path += dir_path::path_sep_str + argv[i]; |
5832 | 1384 |
5867 | 1385 load_path::set (path, true); |
5832 | 1386 } |
1387 | |
1388 if (nargout > 0) | |
1389 retval = load_path::path (); | |
1390 else if (argc == 1 && nargout == 0) | |
1391 { | |
1392 octave_stdout << "\nOctave's search path contains the following directories:\n\n"; | |
1393 | |
1394 string_vector dirs = load_path::dirs (); | |
1395 | |
1396 dirs.list_in_columns (octave_stdout); | |
1397 | |
1398 octave_stdout << "\n"; | |
1399 } | |
1400 } | |
1401 | |
1402 return retval; | |
1403 } | |
1404 | |
1405 DEFCMD (addpath, args, nargout, | |
1406 "-*- texinfo -*-\n\ | |
6678 | 1407 @deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})\n\ |
1408 @deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})\n\ | |
5832 | 1409 Add @var{dir1}, @dots{} to the current function search path. If\n\ |
1410 @var{option} is @samp{\"-begin\"} or 0 (the default), prepend the\n\ | |
1411 directory name to the current path. If @var{option} is @samp{\"-end\"}\n\ | |
1412 or 1, append the directory name to the current path.\n\ | |
1413 Directories added to the path must exist.\n\ | |
1414 @seealso{path, rmpath, genpath, pathdef, savepath, pathsep}\n\ | |
1415 @end deftypefn") | |
1416 { | |
1417 octave_value retval; | |
1418 | |
1419 // Originally written by Bill Denney and Etienne Grossman. Heavily | |
1420 // modified and translated to C++ by jwe. | |
1421 | |
1422 if (nargout > 0) | |
1423 retval = load_path::path (); | |
1424 | |
1425 int nargin = args.length (); | |
1426 | |
1427 if (nargin > 0) | |
1428 { | |
1429 bool append = false; | |
1430 | |
1431 octave_value option_arg = args(nargin-1); | |
1432 | |
1433 if (option_arg.is_string ()) | |
1434 { | |
1435 std::string option = option_arg.string_value (); | |
1436 | |
1437 if (option == "-end") | |
1438 { | |
1439 append = true; | |
1440 nargin--; | |
1441 } | |
1442 else if (option == "-begin") | |
1443 nargin--; | |
1444 } | |
1445 else if (option_arg.is_numeric_type ()) | |
1446 { | |
1447 int val = option_arg.int_value (); | |
1448 | |
1449 if (! error_state) | |
1450 { | |
1451 if (val == 0) | |
1452 append = false; | |
1453 else if (val == 1) | |
1454 append = true; | |
1455 else | |
1456 { | |
1457 error ("addpath: expecting final argument to be 1 or 0"); | |
1458 return retval; | |
1459 } | |
1460 } | |
1461 else | |
1462 { | |
1463 error ("addpath: expecting final argument to be 1 or 0"); | |
1464 return retval; | |
1465 } | |
1466 } | |
1467 | |
1468 for (int i = 0; i < nargin; i++) | |
1469 { | |
1470 std::string arg = args(i).string_value (); | |
1471 | |
1472 if (! error_state) | |
1473 { | |
1474 std::list<std::string> dir_elts = split_path (arg); | |
1475 | |
1476 for (std::list<std::string>::const_iterator p = dir_elts.begin (); | |
1477 p != dir_elts.end (); | |
1478 p++) | |
1479 { | |
1480 std::string dir = *p; | |
1481 | |
1482 //dir = regexprep (dir_elts{j}, "//+", "/"); | |
1483 //dir = regexprep (dir, "/$", ""); | |
1484 | |
5867 | 1485 if (append) |
1486 load_path::append (dir, true); | |
5832 | 1487 else |
5867 | 1488 load_path::prepend (dir, true); |
5832 | 1489 } |
1490 } | |
1491 else | |
1492 error ("addpath: expecting all args to be character strings"); | |
1493 } | |
1494 } | |
1495 else | |
1496 print_usage (); | |
1497 | |
1498 return retval; | |
1499 } | |
1500 | |
1501 DEFCMD (rmpath, args, nargout, | |
1502 "-*- texinfo -*-\n\ | |
6678 | 1503 @deftypefn {Built-in Function} {} rmpath (@var{dir1}, @dots{})\n\ |
5832 | 1504 Remove @var{dir1}, @dots{} from the current function search path.\n\ |
1505 \n\ | |
1506 @seealso{path, addpath, genpath, pathdef, savepath, pathsep}\n\ | |
1507 @end deftypefn") | |
1508 { | |
1509 // Originally by Etienne Grossmann. Heavily modified and translated | |
1510 // to C++ by jwe. | |
1511 | |
1512 octave_value retval; | |
1513 | |
1514 if (nargout > 0) | |
1515 retval = load_path::path (); | |
1516 | |
1517 int nargin = args.length (); | |
1518 | |
1519 if (nargin > 0) | |
1520 { | |
1521 for (int i = 0; i < nargin; i++) | |
1522 { | |
1523 std::string arg = args(i).string_value (); | |
1524 | |
1525 if (! error_state) | |
1526 { | |
1527 std::list<std::string> dir_elts = split_path (arg); | |
1528 | |
1529 for (std::list<std::string>::const_iterator p = dir_elts.begin (); | |
1530 p != dir_elts.end (); | |
1531 p++) | |
1532 { | |
1533 std::string dir = *p; | |
1534 | |
1535 //dir = regexprep (dir_elts{j}, "//+", "/"); | |
1536 //dir = regexprep (dir, "/$", ""); | |
1537 | |
1538 if (! load_path::remove (dir)) | |
1539 warning ("rmpath: %s: not found", dir.c_str ()); | |
1540 } | |
1541 } | |
1542 else | |
1543 error ("addpath: expecting all args to be character strings"); | |
1544 } | |
1545 } | |
1546 else | |
1547 print_usage (); | |
1548 | |
1549 return retval; | |
1550 } | |
1551 | |
1552 /* | |
1553 ;;; Local Variables: *** | |
1554 ;;; mode: C++ *** | |
1555 ;;; End: *** | |
1556 */ |