Mercurial > hg > octave-nkf
view 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 |
line wrap: on
line source
/* Copyright (C) 2006, 2007, 2008 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <algorithm> #include "dir-ops.h" #include "file-ops.h" #include "file-stat.h" #include "oct-env.h" #include "pathsearch.h" #include "defaults.h" #include "defun.h" #include "input.h" #include "load-path.h" #include "pager.h" #include "parse.h" #include "toplev.h" #include "unwind-prot.h" #include "utils.h" load_path *load_path::instance = 0; load_path::hook_function_ptr load_path::add_hook = execute_pkg_add; load_path::hook_function_ptr load_path::remove_hook = execute_pkg_del; std::string load_path::command_line_path; std::string load_path::sys_path; void load_path::dir_info::update (void) { if (is_relative) initialize (); else { file_stat fs (dir_name); if (fs) { if (fs.mtime () != dir_mtime) initialize (); } else { std::string msg = fs.error (); warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); } } } void load_path::dir_info::initialize (void) { is_relative = ! octave_env::absolute_pathname (dir_name); file_stat fs (dir_name); if (fs) { dir_mtime = fs.mtime (); bool has_private_subdir = get_file_list (dir_name); if (! error_state) { if (has_private_subdir) { std::string pdn = file_ops::concat (dir_name, "private"); get_private_function_map (pdn); } } } else { std::string msg = fs.error (); warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); } } bool load_path::dir_info::get_file_list (const std::string& d) { bool has_private_subdir = false; dir_entry dir (d); if (dir) { string_vector flist = dir.read (); octave_idx_type len = flist.length (); all_files.resize (len); fcn_files.resize (len); octave_idx_type all_files_count = 0; octave_idx_type fcn_files_count = 0; for (octave_idx_type i = 0; i < len; i++) { std::string fname = flist[i]; std::string full_name = file_ops::concat (d, fname); file_stat fs (full_name); if (fs) { if (fs.is_dir ()) { if (! has_private_subdir && fname == "private") has_private_subdir = true; } else { all_files[all_files_count++] = fname; size_t pos = fname.rfind ('.'); if (pos != NPOS) { std::string ext = fname.substr (pos); if (ext == ".m" || ext == ".oct" || ext == ".mex") { std::string base = fname.substr (0, pos); if (valid_identifier (base)) fcn_files[fcn_files_count++] = fname; } } } } } all_files.resize (all_files_count); fcn_files.resize (fcn_files_count); } else { std::string msg = dir.error (); warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); } return has_private_subdir; } void load_path::dir_info::get_private_function_map (const std::string& d) { dir_entry dir (d); if (dir) { string_vector flist = dir.read (); octave_idx_type len = flist.length (); for (octave_idx_type i = 0; i < len; i++) { std::string fname = flist[i]; std::string ext; std::string base = fname; size_t pos = fname.rfind ('.'); if (pos != NPOS) { base = fname.substr (0, pos); ext = fname.substr (pos); if (valid_identifier (base)) { int t = 0; if (ext == ".m") t = load_path::M_FILE; else if (ext == ".oct") t = load_path::OCT_FILE; else if (ext == ".mex") t = load_path::MEX_FILE; private_function_map[base] |= t; } } } } else { std::string msg = dir.error (); warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); } } bool load_path::instance_ok (void) { bool retval = true; if (! instance) instance = new load_path (); if (! instance) { ::error ("unable to create load path object!"); retval = false; } return retval; } load_path::const_dir_info_list_iterator load_path::find_dir_info (const std::string& dir_arg) const { std::string dir = file_ops::tilde_expand (dir_arg); const_dir_info_list_iterator retval = dir_info_list.begin (); while (retval != dir_info_list.end ()) { if (retval->dir_name == dir) break; retval++; } return retval; } load_path::dir_info_list_iterator load_path::find_dir_info (const std::string& dir_arg) { std::string dir = file_ops::tilde_expand (dir_arg); dir_info_list_iterator retval = dir_info_list.begin (); while (retval != dir_info_list.end ()) { if (retval->dir_name == dir) break; retval++; } return retval; } bool load_path::contains (const std::string& dir) const { return find_dir_info (dir) != dir_info_list.end (); } void load_path::move (dir_info_list_iterator i, bool at_end) { if (dir_info_list.size () > 1) { dir_info di = *i; dir_info_list.erase (i); if (at_end) dir_info_list.push_back (di); else dir_info_list.push_front (di); std::string dir = di.dir_name; string_vector fcn_files = di.fcn_files; octave_idx_type len = fcn_files.length (); for (octave_idx_type k = 0; k < len; k++) { std::string fname = fcn_files[k]; std::string ext; std::string base = fname; size_t pos = fname.rfind ('.'); if (pos != NPOS) { base = fname.substr (0, pos); ext = fname.substr (pos); } std::list<file_info>& file_info_list = fcn_map[base]; if (file_info_list.size () == 1) continue; else { for (std::list<file_info>::iterator p = file_info_list.begin (); p != file_info_list.end (); p++) { if (p->dir_name == dir) { file_info fi = *p; file_info_list.erase (p); if (at_end) file_info_list.push_back (fi); else file_info_list.push_front (fi); break; } } } } } } static void maybe_add_path_elts (std::string& path, const std::string& dir) { std::string tpath = genpath (dir); if (! tpath.empty ()) { if (path.empty ()) path = tpath; else path += dir_path::path_sep_str + tpath; } } void load_path::do_initialize (bool set_initial_path) { sys_path = ""; if (set_initial_path) { maybe_add_path_elts (sys_path, Vlocal_ver_oct_file_dir); maybe_add_path_elts (sys_path, Vlocal_api_oct_file_dir); maybe_add_path_elts (sys_path, Vlocal_oct_file_dir); maybe_add_path_elts (sys_path, Vlocal_ver_fcn_file_dir); maybe_add_path_elts (sys_path, Vlocal_api_fcn_file_dir); maybe_add_path_elts (sys_path, Vlocal_fcn_file_dir); maybe_add_path_elts (sys_path, Voct_file_dir); maybe_add_path_elts (sys_path, Vfcn_file_dir); } std::string tpath = load_path::command_line_path; if (tpath.empty ()) tpath = octave_env::getenv ("OCTAVE_PATH"); std::string xpath = "."; if (! tpath.empty ()) xpath += dir_path::path_sep_str + tpath; if (! sys_path.empty ()) xpath += dir_path::path_sep_str + sys_path; do_set (xpath, false); } void load_path::do_clear (void) { dir_info_list.clear (); fcn_map.clear (); do_append (".", false); } static std::list<std::string> split_path (const std::string& p) { std::list<std::string> retval; size_t beg = 0; size_t end = p.find (dir_path::path_sep_char); size_t len = p.length (); while (end != NPOS) { std::string elt = p.substr (beg, end-beg); if (! elt.empty ()) retval.push_back (elt); beg = end + 1; if (beg == len) break; end = p.find (dir_path::path_sep_char, beg); } std::string elt = p.substr (beg); if (! elt.empty ()) retval.push_back (elt); return retval; } void load_path::do_set (const std::string& p, bool warn) { do_clear (); std::list<std::string> elts = split_path (p); // Temporarily disable add hook. unwind_protect_fptr (add_hook); add_hook = 0; for (std::list<std::string>::const_iterator i = elts.begin (); i != elts.end (); i++) do_append (*i, warn); // Restore add hook and execute for all newly added directories. unwind_protect::run (); for (dir_info_list_iterator i = dir_info_list.begin (); i != dir_info_list.end (); i++) { if (add_hook) add_hook (i->dir_name); } } void load_path::do_append (const std::string& dir, bool warn) { if (! dir.empty ()) do_add (dir, true, warn); } void load_path::do_prepend (const std::string& dir, bool warn) { if (! dir.empty ()) do_add (dir, false, warn); } void load_path::do_add (const std::string& dir_arg, bool at_end, bool warn) { size_t len = dir_arg.length (); if (len > 1 && dir_arg.substr (len-2) == "//") warning_with_id ("Octave:recursive-path-search", "trailing `//' is no longer special in search path elements"); std::string dir = file_ops::tilde_expand (dir_arg); dir_info_list_iterator i = find_dir_info (dir); if (i != dir_info_list.end ()) move (i, at_end); else { file_stat fs (dir); if (fs) { if (fs.is_dir ()) { dir_info di (dir); if (! error_state) { if (at_end) dir_info_list.push_back (di); else dir_info_list.push_front (di); add_to_fcn_map (di, true); if (add_hook) add_hook (dir); } } else if (warn) warning ("addpath: %s: not a directory", dir_arg.c_str ()); } else if (warn) { std::string msg = fs.error (); warning ("addpath: %s: %s", dir_arg.c_str (), msg.c_str ()); } } // FIXME -- is there a better way to do this? i = find_dir_info ("."); if (i != dir_info_list.end ()) move (i, false); else panic_impossible (); } bool load_path::do_remove (const std::string& dir_arg) { bool retval = false; if (! dir_arg.empty ()) { if (dir_arg == ".") { warning ("rmpath: can't remove \".\" from path"); // Avoid additional warnings. retval = true; } else { std::string dir = file_ops::tilde_expand (dir_arg); dir_info_list_iterator i = find_dir_info (dir); if (i != dir_info_list.end ()) { retval = true; if (remove_hook) remove_hook (dir); string_vector fcn_files = i->fcn_files; dir_info_list.erase (i); octave_idx_type len = fcn_files.length (); for (octave_idx_type k = 0; k < len; k++) { std::string fname = fcn_files[k]; std::string ext; std::string base = fname; size_t pos = fname.rfind ('.'); if (pos != NPOS) { base = fname.substr (0, pos); ext = fname.substr (pos); } std::list<file_info>& file_info_list = fcn_map[base]; for (std::list<file_info>::iterator p = file_info_list.begin (); p != file_info_list.end (); p++) { if (p->dir_name == dir) { file_info_list.erase (p); if (file_info_list.empty ()) fcn_map.erase (fname); break; } } } } } } return retval; } void load_path::do_update (void) const { // I don't see a better way to do this because we need to // preserve the correct directory ordering for new files that // have appeared. fcn_map.clear (); for (dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) { dir_info& di = *p; di.update (); add_to_fcn_map (di, true); } } std::string load_path::do_find_fcn (const std::string& fcn, int type) const { std::string retval; update (); const_fcn_map_iterator p = fcn_map.find (fcn); if (p != fcn_map.end ()) { const std::list<file_info>& file_info_list = p->second; for (const_file_info_list_iterator i = file_info_list.begin (); i != file_info_list.end (); i++) { const file_info& fi = *i; int t = fi.types; retval = file_ops::concat (fi.dir_name, fcn); if (type == load_path::OCT_FILE) { if ((type & t) == load_path::OCT_FILE) { retval += ".oct"; break; } } else if (type == load_path::M_FILE) { if ((type & t) == load_path::M_FILE) { retval += ".m"; break; } } else if (type == load_path::MEX_FILE) { if ((type & t) == load_path::MEX_FILE) { retval += ".mex"; break; } } else if (type == (load_path::M_FILE | load_path::OCT_FILE)) { if (t & load_path::OCT_FILE) { retval += ".oct"; break; } else if (t & load_path::M_FILE) { retval += ".m"; break; } } else if (type == (load_path::M_FILE | load_path::MEX_FILE)) { if (t & load_path::MEX_FILE) { retval += ".mex"; break; } else if (t & load_path::M_FILE) { retval += ".m"; break; } } else if (type == (load_path::OCT_FILE | load_path::MEX_FILE)) { if (t & load_path::OCT_FILE) { retval += ".oct"; break; } else if (t & load_path::MEX_FILE) { retval += ".mex"; break; } } else if (type == (load_path::M_FILE | load_path::OCT_FILE | load_path::MEX_FILE)) { if (t & load_path::OCT_FILE) { retval += ".oct"; break; } else if (t & load_path::MEX_FILE) { retval += ".mex"; break; } else if (t & load_path::M_FILE) { retval += ".m"; break; } } else error ("load_path::do_find_fcn: %s: invalid type code = %d", fcn.c_str (), type); // Reset the return string, in case the above tesst fail. retval = std::string (); } } return retval; } std::string load_path::do_find_file (const std::string& file) const { std::string retval; if (file.find_first_of (file_ops::dir_sep_chars) != NPOS) { if (octave_env::absolute_pathname (file) || octave_env::rooted_relative_pathname (file)) { file_stat fs (file); if (fs.exists ()) return file; } else { for (const_dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) { std::string tfile = file_ops::concat (p->dir_name, file); file_stat fs (tfile); if (fs.exists ()) return tfile; } } } else { for (const_dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) { string_vector all_files = p->all_files; octave_idx_type len = all_files.length (); for (octave_idx_type i = 0; i < len; i++) { if (all_files[i] == file) return file_ops::concat (p->dir_name, file); } } } return retval; } std::string load_path::do_find_dir (const std::string& dir) const { std::string retval; if (dir.find_first_of (file_ops::dir_sep_chars) != std::string::npos && (octave_env::absolute_pathname (dir) || octave_env::rooted_relative_pathname (dir))) { file_stat fs (dir); if (fs.exists () && fs.is_dir ()) return dir; } else { for (const_dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) { std::string dname = p->dir_name; size_t dname_len = dname.length (); if (dname.substr (dname_len - 1) == file_ops::dir_sep_str) dname = dname.substr (0, dname_len - 1); size_t dir_len = dir.length (); if (dname_len >= dir_len && file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) && dir.compare (dname.substr (dname_len - dir_len)) == 0) { file_stat fs (p->dir_name); if (fs.exists () && fs.is_dir ()) return p->dir_name; } } } return retval; } std::string load_path::do_find_first_of (const string_vector& flist) const { std::string retval; std::string dir_name; std::string file_name; octave_idx_type flen = flist.length (); octave_idx_type rel_flen = 0; string_vector rel_flist (flen); for (octave_idx_type i = 0; i < flen; i++) { if (octave_env::absolute_pathname (flist[i])) { file_stat fs (flist[i]); if (fs.exists ()) return flist[i]; } else rel_flist[rel_flen++] = flist[i]; } rel_flist.resize (rel_flen); for (const_dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) { string_vector all_files = p->all_files; octave_idx_type len = all_files.length (); for (octave_idx_type i = 0; i < len; i++) { for (octave_idx_type j = 0; j < rel_flen; j++) { if (all_files[i] == rel_flist[j]) { dir_name = p->dir_name; file_name = rel_flist[j]; goto done; } } } } done: if (! dir_name.empty ()) retval = file_ops::concat (dir_name, file_name); return retval; } string_vector load_path::do_find_all_first_of (const string_vector& flist) const { std::list<std::string> retlist; std::string dir_name; std::string file_name; octave_idx_type flen = flist.length (); octave_idx_type rel_flen = 0; string_vector rel_flist (flen); for (octave_idx_type i = 0; i < flen; i++) { if (octave_env::absolute_pathname (flist[i])) { file_stat fs (flist[i]); if (fs.exists ()) retlist.push_back (flist[i]); } else rel_flist[rel_flen++] = flist[i]; } rel_flist.resize (rel_flen); for (const_dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) { string_vector all_files = p->all_files; octave_idx_type len = all_files.length (); for (octave_idx_type i = 0; i < len; i++) { for (octave_idx_type j = 0; j < rel_flen; j++) { if (all_files[i] == rel_flist[j]) retlist.push_back (file_ops::concat (p->dir_name, rel_flist[j])); } } } size_t retsize = retlist.size (); string_vector retval (retsize); for (size_t i = 0; i < retsize; i++) { retval[i] = retlist.front (); retlist.pop_front (); } return retval; } string_vector load_path::do_dirs (void) const { size_t len = dir_info_list.size (); string_vector retval (len); octave_idx_type k = 0; for (const_dir_info_list_iterator i = dir_info_list.begin (); i != dir_info_list.end (); i++) retval[k++] = i->dir_name; return retval; } std::list<std::string> load_path::do_dir_list (void) const { std::list<std::string> retval; for (const_dir_info_list_iterator i = dir_info_list.begin (); i != dir_info_list.end (); i++) retval.push_back (i->dir_name); return retval; } string_vector load_path::do_files (const std::string& dir) const { string_vector retval; const_dir_info_list_iterator i = find_dir_info (dir); if (i != dir_info_list.end ()) retval = i->fcn_files; return retval; } string_vector load_path::do_fcn_names (void) const { size_t len = fcn_map.size (); string_vector retval (len); octave_idx_type count = 0; for (const_fcn_map_iterator p = fcn_map.begin (); p != fcn_map.end (); p++) retval[count++] = p->first; return retval; } std::string load_path::do_path (void) const { std::string xpath; string_vector xdirs = load_path::dirs (); octave_idx_type len = xdirs.length (); if (len > 0) xpath = xdirs[0]; for (octave_idx_type i = 1; i < len; i++) xpath += dir_path::path_sep_str + xdirs[i]; return xpath; } void load_path::do_display (std::ostream& os) const { for (const_dir_info_list_iterator i = dir_info_list.begin (); i != dir_info_list.end (); i++) { string_vector fcn_files = i->fcn_files; if (! fcn_files.empty ()) { os << "\n*** function files in " << i->dir_name << ":\n\n"; fcn_files.list_in_columns (os); } #if defined (DEBUG_LOAD_PATH) const std::map<std::string, int>& private_function_map = i->private_function_map; if (private_function_map.size () > 0) { os << "private:\n"; for (std::map<std::string, int>::const_iterator p = private_function_map.begin (); p != private_function_map.end (); p++) { os << " " << p->first << " ("; bool printed_type = false; int types = p->second; if (types & load_path::OCT_FILE) { os << "oct"; printed_type = true; } if (types & load_path::MEX_FILE) { if (printed_type) os << "|"; os << "mex"; printed_type = true; } if (types & load_path::M_FILE) { if (printed_type) os << "|"; os << "m"; printed_type = true; } os << ")\n"; } os << "\n"; } #endif } #if defined (DEBUG_LOAD_PATH) for (const_fcn_map_iterator i = fcn_map.begin (); i != fcn_map.end (); i++) { os << i->first << ":\n"; const std::list<file_info>& file_info_list = i->second; for (const_file_info_list_iterator p = file_info_list.begin (); p != file_info_list.end (); p++) { os << " " << p->dir_name << " ("; bool printed_type = false; if (p->types & load_path::OCT_FILE) { os << "oct"; printed_type = true; } if (p->types & load_path::MEX_FILE) { if (printed_type) os << "|"; os << "mex"; printed_type = true; } if (p->types & load_path::M_FILE) { if (printed_type) os << "|"; os << "m"; printed_type = true; } os << ")\n"; } } os << "\n"; #endif } void load_path::add_to_fcn_map (const dir_info& di, bool at_end) const { std::string dir_name = di.dir_name; string_vector fcn_files = di.fcn_files; octave_idx_type len = fcn_files.length (); for (octave_idx_type i = 0; i < len; i++) { std::string fname = fcn_files[i]; std::string ext; std::string base = fname; size_t pos = fname.rfind ('.'); if (pos != NPOS) { base = fname.substr (0, pos); ext = fname.substr (pos); } std::list<file_info>& file_info_list = fcn_map[base]; file_info_list_iterator p = file_info_list.begin (); while (p != file_info_list.end ()) { if (p->dir_name == dir_name) break; p++; } int t = 0; if (ext == ".m") t = load_path::M_FILE; else if (ext == ".oct") t = load_path::OCT_FILE; else if (ext == ".mex") t = load_path::MEX_FILE; if (p == file_info_list.end ()) { file_info fi (dir_name, t); if (at_end) file_info_list.push_back (fi); else file_info_list.push_front (fi); } else { file_info& fi = *p; fi.types |= t; } } } std::string genpath (const std::string& dirname, const string_vector& skip) { std::string retval; dir_entry dir (dirname); if (dir) { retval = dirname; string_vector dirlist = dir.read (); octave_idx_type len = dirlist.length (); for (octave_idx_type i = 0; i < len; i++) { std::string elt = dirlist[i]; // FIXME -- the caller should be able to specify the list of // directories to skip in addition to "." and "..". bool skip_p = (elt == "." || elt == ".."); if (! skip_p) { for (octave_idx_type j = 0; j < skip.length (); j++) { skip_p = (elt == skip[j]); if (skip_p) break; } if (! skip_p) { std::string nm = file_ops::concat (dirname, elt); file_stat fs (nm); if (fs && fs.is_dir ()) retval += dir_path::path_sep_str + genpath (nm); } } } } return retval; } static void execute_pkg_add_or_del (const std::string& dir, const std::string& script_file) { if (! octave_interpreter_ready) return; unwind_protect::begin_frame ("execute_pkg_add_or_del"); unwind_protect_bool (input_from_startup_file); input_from_startup_file = true; std::string file = file_ops::concat (dir, script_file); file_stat fs (file); if (fs.exists ()) source_file (file, "base"); unwind_protect::run_frame ("execute_pkg_add_or_del"); } void execute_pkg_add (const std::string& dir) { execute_pkg_add_or_del (dir, "PKG_ADD"); } void execute_pkg_del (const std::string& dir) { execute_pkg_add_or_del (dir, "PKG_DEL"); } DEFUN (genpath, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} genpath (@var{dir})\n\ Return a path constructed from @var{dir} and all its subdirectories.\n\ @end deftypefn") { octave_value retval; if (args.length () == 1) { std::string dirname = args(0).string_value (); if (! error_state) retval = genpath (dirname); else error ("genpath: expecting argument to be a character string"); } else print_usage (); return retval; } DEFUN (rehash, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} rehash ()\n\ Reinitialize Octave's load path directory cache.\n\ @end deftypefn") { octave_value_list retval; load_path::update (); // FIXME -- maybe we should rename this variable since it is being // used for more than keeping track of the prompt time. // This will force updated functions to be found. Vlast_prompt_time.stamp (); return retval; } DEFUN (pathdef, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} pathdef ()\n\ Return the default list of directories in which to search for function\n\ files.\n\ @seealso{path, addpath, rmpath, genpath, savepath, pathsep}\n\ @end deftypefn") { return octave_value (load_path::system_path ()); } DEFUN (path, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} path (@dots{})\n\ Modify or display Octave's load path.\n\ \n\ If @var{nargin} and @var{nargout} are zero, display the elements of\n\ Octave's load path in an easy to read format.\n\ \n\ If @var{nargin} is zero and nargout is greater than zero, return the\n\ current load path.\n\ \n\ If @var{nargin} is greater than zero, concatenate the arguments,\n\ separating them with @code{pathsep()}. Set the internal search path\n\ to the result and return it.\n\ \n\ No checks are made for duplicate elements.\n\ @seealso{addpath, rmpath, genpath, pathdef, savepath, pathsep}\n\ @end deftypefn") { octave_value retval; int argc = args.length () + 1; string_vector argv = args.make_argv ("path"); if (! error_state) { if (argc > 1) { std::string path = argv[1]; for (int i = 2; i < argc; i++) path += dir_path::path_sep_str + argv[i]; load_path::set (path, true); } if (nargout > 0) retval = load_path::path (); else if (argc == 1 && nargout == 0) { octave_stdout << "\nOctave's search path contains the following directories:\n\n"; string_vector dirs = load_path::dirs (); dirs.list_in_columns (octave_stdout); octave_stdout << "\n"; } } return retval; } DEFCMD (addpath, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})\n\ @deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})\n\ Add @var{dir1}, @dots{} to the current function search path. If\n\ @var{option} is @samp{\"-begin\"} or 0 (the default), prepend the\n\ directory name to the current path. If @var{option} is @samp{\"-end\"}\n\ or 1, append the directory name to the current path.\n\ Directories added to the path must exist.\n\ @seealso{path, rmpath, genpath, pathdef, savepath, pathsep}\n\ @end deftypefn") { octave_value retval; // Originally written by Bill Denney and Etienne Grossman. Heavily // modified and translated to C++ by jwe. if (nargout > 0) retval = load_path::path (); int nargin = args.length (); if (nargin > 0) { bool append = false; octave_value option_arg = args(nargin-1); if (option_arg.is_string ()) { std::string option = option_arg.string_value (); if (option == "-end") { append = true; nargin--; } else if (option == "-begin") nargin--; } else if (option_arg.is_numeric_type ()) { int val = option_arg.int_value (); if (! error_state) { if (val == 0) append = false; else if (val == 1) append = true; else { error ("addpath: expecting final argument to be 1 or 0"); return retval; } } else { error ("addpath: expecting final argument to be 1 or 0"); return retval; } } for (int i = 0; i < nargin; i++) { std::string arg = args(i).string_value (); if (! error_state) { std::list<std::string> dir_elts = split_path (arg); for (std::list<std::string>::const_iterator p = dir_elts.begin (); p != dir_elts.end (); p++) { std::string dir = *p; //dir = regexprep (dir_elts{j}, "//+", "/"); //dir = regexprep (dir, "/$", ""); if (append) load_path::append (dir, true); else load_path::prepend (dir, true); } } else error ("addpath: expecting all args to be character strings"); } } else print_usage (); return retval; } DEFCMD (rmpath, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} rmpath (@var{dir1}, @dots{})\n\ Remove @var{dir1}, @dots{} from the current function search path.\n\ \n\ @seealso{path, addpath, genpath, pathdef, savepath, pathsep}\n\ @end deftypefn") { // Originally by Etienne Grossmann. Heavily modified and translated // to C++ by jwe. octave_value retval; if (nargout > 0) retval = load_path::path (); int nargin = args.length (); if (nargin > 0) { for (int i = 0; i < nargin; i++) { std::string arg = args(i).string_value (); if (! error_state) { std::list<std::string> dir_elts = split_path (arg); for (std::list<std::string>::const_iterator p = dir_elts.begin (); p != dir_elts.end (); p++) { std::string dir = *p; //dir = regexprep (dir_elts{j}, "//+", "/"); //dir = regexprep (dir, "/$", ""); if (! load_path::remove (dir)) warning ("rmpath: %s: not found", dir.c_str ()); } } else error ("addpath: expecting all args to be character strings"); } } else print_usage (); return retval; } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */