changeset 5832:5e41e06f6a78

[project @ 2006-05-26 21:41:32 by jwe]
author jwe
date Fri, 26 May 2006 21:42:22 +0000
parents b0d4ff99a0c5
children f145cb46d31f
files src/ChangeLog src/DLD-FUNCTIONS/__gnuplot_raw__.l src/DLD-FUNCTIONS/dispatch.cc src/DLD-FUNCTIONS/fftw_wisdom.cc src/Makefile.in src/defaults.cc src/defaults.h.in src/dirfns.cc src/fn-cache.cc src/help.cc src/input.cc src/load-path.cc src/load-path.h src/octave.cc src/parse.y src/pr-output.cc src/utils.cc src/variables.cc
diffstat 18 files changed, 1903 insertions(+), 415 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri May 26 21:06:00 2006 +0000
+++ b/src/ChangeLog	Fri May 26 21:42:22 2006 +0000
@@ -1,3 +1,38 @@
+2006-05-26  John W. Eaton  <jwe@octave.org>
+
+	* load-path.cc (genpath, maybe_add_path_elts, Fgenpath, Frehash,
+	Fpath, Fpathdef): Move here from defaults.cc.
+	* load-path.cc, load-path.h: New files.
+	* Makefile.in (INCLUDES, DIST_SRC): Add them to the lists.
+	* help.cc (make_name_list, simple_help): Use load_path instead of
+	octave_fcn_file_name_cache.
+	(Flookfor): Use load_path instead of Vload_path_dir_path.
+	* octave.cc (octave_main):  Likewise.
+	* parse.y (load_fcn_from_file): Likewise.
+	* utils.cc (Ffile_in_loadpath, file_in_path, fcn_file_in_path,
+	oct_file_in_path): Likewise.
+	* variables.cc (symbol_exist, symbol_out_of_date): Likewise.
+	* DLD-FUNCTIONS/fftw_wisdom.cc (Ffftw_wisdom): Likewise.
+	* utils.cc (Ffind_first_of_in_loadpath): Delete.
+	* input.cc (octave_gets): Call load_path::update here.
+	* dirfns.cc (octave_change_to_directory): Likewise.
+	* defaults.cc (VLOADPATH, VDEFAULT_LOADPATH, Vload_path_dir_path,
+	maybe_add_or_del_packages, update_load_path_dir_path,
+	execute_default_pkg_add_files, set_load_path): Delete.
+	* defaults.h.in (Vload_path_dir_path,
+	execute_default_pkg_add_files, maybe_add_default_load_path,
+	set_load_path): Delete decls.
+
+	* fn-cache.h, fn-cache.cc: Delete.
+	* Makefile.in (INCLUDES, DIST_SRC): Remove them from the lists.
+
+	* input.cc (octave_gets): Only update Vlast_prompt_time if we are
+	interactive and actually printing a prompt.  Don't print prompt if
+	reading startup files or command line files.  Initialize
+	Vlast_prompt_time to 0.
+
+	* pr-output.cc (set_format): Always include space for sign.
+	
 2006-05-23  John W. Eaton  <jwe@octave.org>
 
 	* load-save.cc (Fsave): Use tellp instead of pubseekoff to
@@ -179,7 +214,7 @@
 	(symbols_of_defaults): Delete DEFVARs and function.
 
 	* pr-output.cc (set_output_prec_and_fw): Set Voutput_precision and
-	Voutput_max_field_width directly instad of calling
+	Voutput_max_field_width directly instead of calling
 	bind_builtin_variable.
 
 	* octave.cc (octave_main, maximum_braindamage):
--- a/src/DLD-FUNCTIONS/__gnuplot_raw__.l	Fri May 26 21:06:00 2006 +0000
+++ b/src/DLD-FUNCTIONS/__gnuplot_raw__.l	Fri May 26 21:42:22 2006 +0000
@@ -1647,7 +1647,7 @@
 
 DEFUN_DLD (__gnuplot_set__, args, ,
   "-*- texinfo -*-\n\
-@deffn {{Loadable Function} __gnuplot_set__ options\n\
+@deffn {Loadable Function} __gnuplot_set__ options\n\
 Set plotting options for gnuplot\n\
 @end deffn")
 {
@@ -1661,7 +1661,7 @@
 
 DEFUN_DLD (__gnuplot_show__, args, ,
   "-*- texinfo -*-\n\
-@deffn {{Loadable Function} __gnuplot_show__ options\n\
+@deffn {Loadable Function} __gnuplot_show__ options\n\
 Show plotting options.\n\
 @end deffn")
 {
--- a/src/DLD-FUNCTIONS/dispatch.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/DLD-FUNCTIONS/dispatch.cc	Fri May 26 21:42:22 2006 +0000
@@ -537,22 +537,24 @@
 %! dispatch('dispatch_x','length','string')
 %! assert(dispatch_x(3),3)
 %! assert(dispatch_x("a"),1)
-%! pause(1);
+%! sleep (2);
 %! system("echo 'function a=dispatch_x(a),++a;'>dispatch_x.m");
+%! rehash();
 %! assert(dispatch_x(3),4)
 %! assert(dispatch_x("a"),1)
 %!test 
-%! system("rm dispatch_x.m");
+%! unlink("dispatch_x.m");
 
 %!test # replace dispatch m-file
 %! system("echo 'function a=dispatch_y(a)'>dispatch_y.m");
 %! dispatch('hello','dispatch_y','complex scalar')
 %! assert(hello(3i),3i)
-%! pause(1);
+%! sleep (2);
 %! system("echo 'function a=dispatch_y(a),++a;'>dispatch_y.m");
+%! rehash();
 %! assert(hello(3i),1+3i)
 %!test 
-%! system("rm dispatch_y.m");
+%! unlink("dispatch_y.m");
 
 FIXME add tests for preservation of mark_as_command status.
 
--- a/src/DLD-FUNCTIONS/fftw_wisdom.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/DLD-FUNCTIONS/fftw_wisdom.cc	Fri May 26 21:42:22 2006 +0000
@@ -37,6 +37,7 @@
 #include "file-ops.h"
 #include "gripes.h"
 #include "lo-mappers.h"
+#include "load-path.h"
 #include "oct-env.h"
 #include "oct-obj.h"
 #include "sighandlers.h"
@@ -111,7 +112,7 @@
 
       std::string str = args(0).string_value ();
       std::string wisdom = octave_env::make_absolute
-	(Vload_path_dir_path.find_first_of (str), octave_env::getcwd ());
+	(load_path::find_file (str), octave_env::getcwd ());
 
       // FIXME -- should probably protect FILE* resources with
       // auto_ptr or similar...
--- a/src/Makefile.in	Fri May 26 21:06:00 2006 +0000
+++ b/src/Makefile.in	Fri May 26 21:42:22 2006 +0000
@@ -95,8 +95,8 @@
 
 INCLUDES := Cell.h base-list.h c-file-ptr-stream.h comment-list.h \
 	defun-dld.h defun-int.h defun.h dirfns.h dynamic-ld.h \
-	error.h file-io.h fn-cache.h gripes.h help.h input.h \
-	lex.h load-save.h ls-hdf5.h ls-mat-ascii.h ls-mat4.h \
+	error.h file-io.h gripes.h help.h input.h \
+	lex.h load-path.h load-save.h ls-hdf5.h ls-mat-ascii.h ls-mat4.h \
 	ls-mat5.h ls-oct-ascii.h ls-oct-binary.h ls-utils.h \
 	oct-errno.h oct-fstrm.h oct-hist.h oct-iostrm.h oct-map.h oct-obj.h \
 	oct-prcstrm.h oct-procbuf.h oct-stdstrm.h oct-stream.h zfstream.h \
@@ -163,8 +163,8 @@
 
 DIST_SRC := Cell.cc bitfcns.cc c-file-ptr-stream.cc comment-list.cc \
 	cutils.c data.cc debug.cc defaults.cc defun.cc dirfns.cc \
-	dynamic-ld.cc error.cc file-io.cc fn-cache.cc gripes.cc \
-	help.cc input.cc lex.l load-save.cc ls-hdf5.cc \
+	dynamic-ld.cc error.cc file-io.cc gripes.cc \
+	help.cc input.cc lex.l load-path.cc load-save.cc ls-hdf5.cc \
 	ls-mat-ascii.cc ls-mat4.cc ls-mat5.cc ls-oct-ascii.cc \
 	ls-oct-binary.cc ls-utils.cc main.c mappers.cc matherr.c \
 	oct-fstrm.cc oct-hist.cc oct-iostrm.cc oct-map.cc \
--- a/src/defaults.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/defaults.cc	Fri May 26 21:42:22 2006 +0000
@@ -50,6 +50,7 @@
 #include "gripes.h"
 #include "help.h"
 #include "input.h"
+#include "load-path.h"
 #include "oct-obj.h"
 #include "ov.h"
 #include "parse.h"
@@ -85,16 +86,6 @@
 // (--exec-path path)
 static std::string VEXEC_PATH;
 
-// Load path specified on command line.
-// (--path path; -p path)
-static std::string VLOADPATH;
-
-// The default load path with OCTAVE_HOME appropriately substituted.
-static std::string VDEFAULT_LOADPATH;
-
-// And the cached directory path corresponding to Vload_path.
-dir_path Vload_path_dir_path;
-
 // Name of the editor to be invoked by the edit_history command.
 std::string VEDITOR;
 
@@ -106,83 +97,6 @@
 // Name of the FFTW wisdom program.
 std::string Vfftw_wisdom_program;
 
-// Each element of A and B should be directory names.  For each
-// element of A not in the list B, execute SCRIPT_FILE in that
-// directory if it exists.
-
-static void
-maybe_add_or_del_packages (const string_vector& a,
-			   const string_vector& b,
-			   const std::string& script_file)
-{
-  if (! octave_interpreter_ready)
-    return;
-
-  unwind_protect::begin_frame ("maybe_add_or_del_packages");
-
-  unwind_protect_bool (input_from_startup_file);
-
-  input_from_startup_file = true;
-
-  octave_idx_type a_len = a.length ();
-  octave_idx_type b_len = b.length ();
-
-  for (octave_idx_type i = 0; i < a_len; i++)
-    {
-      std::string a_dir = a[i];
-
-      bool found = false;
-
-      for (octave_idx_type j = 0; j < b_len; j++)
-	{
-	  if (b[j] == a_dir)
-	    {
-	      found = true;
-	      break;
-	    }
-	}
-
-      if (! found)
-	{
-	  std::string file = a_dir + file_ops::dir_sep_str + script_file;
-
-	  file_stat fs = file_stat (file);
-
-	  if (fs.exists ())
-	    source_file (file);
-
-	  if (error_state)
-	    return;
-	}
-    }
-
-  unwind_protect::run_frame ("maybe_add_or_del_packages");
-}
-
-static void
-update_load_path_dir_path (void)
-{
-  string_vector old_dirs = Vload_path_dir_path.all_directories ();
-
-  Vload_path_dir_path = dir_path (VLOADPATH, "");
-
-  string_vector new_dirs = Vload_path_dir_path.all_directories ();
-
-  maybe_add_or_del_packages (old_dirs, new_dirs, "PKG_DEL");
-
-  if (! error_state)
-    maybe_add_or_del_packages (new_dirs, old_dirs, "PKG_ADD");
-}
-
-void
-execute_default_pkg_add_files (void)
-{
-  string_vector old_dirs;
-  string_vector new_dirs = Vload_path_dir_path.all_directories ();
-  
-  maybe_add_or_del_packages (new_dirs, old_dirs, "PKG_ADD");
-}
-
 static std::string
 subst_octave_home (const std::string& s)
 {
@@ -337,81 +251,6 @@
   octave_env::putenv ("PATH", VEXEC_PATH);
 }
 
-static std::string
-genpath (const std::string& dirname)
-{
-  std::string retval;
-
-  std::string full_dirname = file_ops::tilde_expand (dirname);
-
-  dir_entry dir (full_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];
-
-	  if (elt != "." && elt != ".." && elt != "private")
-	    {
-	      std::string nm = full_dirname + file_ops::dir_sep_str + elt;
-
-	      file_stat fs (nm);
-
-	      if (fs && fs.is_dir ())
-		retval += dir_path::path_sep_str + genpath (nm);
-	    }
-	}
-    }
-
-  return retval;
-}
-
-static void
-maybe_add_path_elts (std::string& pathvar, const std::string& dir)
-{
-  std::string tpath = genpath (dir);
-
-  if (! tpath.empty ())
-    pathvar += dir_path::path_sep_str + tpath;
-}
-
-void
-set_load_path (const std::string& path)
-{
-  VDEFAULT_LOADPATH = ":";
-
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vlocal_ver_oct_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vlocal_api_oct_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vlocal_oct_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vlocal_ver_fcn_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vlocal_api_fcn_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vlocal_fcn_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Voct_file_dir);
-  maybe_add_path_elts (VDEFAULT_LOADPATH, Vfcn_file_dir);
-
-  std::string tpath = path;
-
-  if (tpath.empty ())
-    tpath = octave_env::getenv ("OCTAVE_LOADPATH");
-
-  VLOADPATH = ".";
-
-  if (! tpath.empty ())
-    VLOADPATH += dir_path::path_sep_str + tpath;
-
-  if (VDEFAULT_LOADPATH != ":")
-    VLOADPATH += VDEFAULT_LOADPATH;
-
-  update_load_path_dir_path ();
-}
-
 void
 set_image_path (const std::string& path)
 {
@@ -425,7 +264,10 @@
   if (! tpath.empty ())
     VIMAGE_PATH += dir_path::path_sep_str + tpath;
 
-  maybe_add_path_elts (VIMAGE_PATH, Vimage_dir);
+  tpath = genpath (Vimage_dir, "");
+
+  if (! tpath.empty ())
+    VIMAGE_PATH += dir_path::path_sep_str + tpath;
 }
 
 static void
@@ -535,8 +377,6 @@
 
   set_exec_path ();
 
-  set_load_path ();
-
   set_image_path ();
 
   set_default_info_file ();
@@ -552,42 +392,6 @@
   set_site_defaults_file ();
 }
 
-DEFUN (genpath, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} genpath (@var{dir})\n\
-Return a path constructed from @var{dir} and all its subdiretories.\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 @code{LOADPATH} directory cache.\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  Vload_path_dir_path.rehash ();
-
-  return retval;
-}
-
 DEFUN (EDITOR, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {@var{val} =} EDITOR ()\n\
@@ -654,91 +458,6 @@
   return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (IMAGE_PATH);
 }
 
-DEFUN (path, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn {Function File} {} path (@dots{})\n\
-Modify or display Octave's @code{LOADPATH}.\n\
-\n\
-If @var{nargin} and @var{nargout} are zero, display the elements of\n\
-Octave's @code{LOADPATH} in an easy to read format.\n\
-\n\
-If @var{nargin} is zero and nargout is greater than zero, return the\n\
-current value of @code{LOADPATH}.\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;
-
-	  size_t plen = path.length ();
-
-	  if (! ((plen == 1 && path[0] == ':')
-		 || (plen > 1
-		     && path.substr (0, 2) == ("." + dir_path::path_sep_str))))
-	    path = "." + dir_path::path_sep_str + path;
-
-	  VLOADPATH = path;
-
-	  // By resetting the last prompt time variable, we will force
-	  // checks for out of date symbols even if the change to
-	  // LOADPATH and subsequent function calls happen between
-	  // prompts.
-
-	  // FIXME -- maybe we should rename
-	  // Vlast_prompt_time_stamp since the new usage doesn't really
-	  // fit with the current name?
-
-	  Vlast_prompt_time.stamp ();
-
-	  update_load_path_dir_path ();
-	}
-
-      if (nargout > 0)
-	retval = VLOADPATH;
-      else if (argc == 1 && nargout == 0)
-	{
-	  octave_stdout << "\nOctave's search path contains the following directories:\n\n";
-
-	  string_vector sv = Vload_path_dir_path.all_directories ();
-
-	  sv.list_in_columns (octave_stdout);
-
-	  octave_stdout << "\n";
-	}
-    }
-
-  return retval;
-}
-
-DEFUN (pathdef, , ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {@var{val} =} DEFAULT_LOADPATH ()\n\
-Return the default list of directories in which to search for function\n\
-files.\n\
-@seealso{LOADPATH}\n\
-@end deftypefn")
-{
-  return octave_value (VDEFAULT_LOADPATH);
-}
-  
 DEFUN (OCTAVE_HOME, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} OCTAVE_HOME ()\n\
--- a/src/defaults.h.in	Fri May 26 21:06:00 2006 +0000
+++ b/src/defaults.h.in	Fri May 26 21:42:22 2006 +0000
@@ -180,9 +180,6 @@
 
 extern std::string Vimage_dir;
 
-// And the cached directory path corresponding to Vload_path.
-extern dir_path Vload_path_dir_path;
-
 // Name of the editor to be invoked by the edit_history command.
 extern std::string VEDITOR;
 
@@ -192,14 +189,9 @@
 // Name of the FFTW wisdom program.
 extern std::string Vfftw_wisdom_program;
 
-extern void execute_default_pkg_add_files (void);
-
-extern std::string maybe_add_default_load_path (const std::string& pathstring);
-
 extern void install_defaults (void);
 
 extern void set_exec_path (const std::string& path = std::string ());
-extern void set_load_path (const std::string& path = std::string ());
 extern void set_image_path (const std::string& path = std::string ());
 
 #endif
--- a/src/dirfns.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/dirfns.cc	Fri May 26 21:42:22 2006 +0000
@@ -55,6 +55,7 @@
 #include "error.h"
 #include "gripes.h"
 #include "input.h"
+#include "load-path.h"
 #include "oct-obj.h"
 #include "pager.h"
 #include "procstream.h"
@@ -68,19 +69,18 @@
 // directory tree.
 static bool Vconfirm_recursive_rmdir = true;
 
-// FIXME -- changing the plotter directory should be handled
-// by registering a function for octave_env::chdir to call so that
-// this function can be eliminated.
-
 static int
 octave_change_to_directory (const std::string& newdir)
 {
   int cd_ok = octave_env::chdir (newdir);
 
   if (cd_ok)
-    // FIXME -- this should be handled as a list of functions
-    // to call so users can add their own chdir handlers.
-    /* do_external_plotter_cd (newdir) */;
+    {
+      // FIXME -- should this be handled as a list of functions
+      // to call so users can add their own chdir handlers?
+
+      load_path::update ();
+    }
   else
     {
       using namespace std;
@@ -681,8 +681,8 @@
 }
 
 DEFUN (filesep, args, ,
-    "-*- texinfo -*-\n\
-@detypefn {Built-in Function} {} filesep ()\n\
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} filesep ()\n\
 Return the system-dependent character used to separate directory names.\n\
 @seealso{pathsep, dir, ls}\n\
 @end deftypefn")
--- a/src/fn-cache.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/fn-cache.cc	Fri May 26 21:42:22 2006 +0000
@@ -49,7 +49,7 @@
 {
   bool something_changed = false;
 
-  dir_path p = path.empty () ? Vload_path_dir_path : dir_path (path);
+  dir_path p /* = path.empty () ? Vload_path_dir_path : dir_path (path) */;
 
   string_vector dirs = p.all_directories ();
 
@@ -112,7 +112,7 @@
 
   int total_len = 0;
 
-  dir_path p = path.empty () ? Vload_path_dir_path : dir_path (path);
+  dir_path p /* = path.empty () ? Vload_path_dir_path : dir_path (path) */;
 
   string_vector dirs = p.all_directories ();
 
--- a/src/help.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/help.cc	Fri May 26 21:42:22 2006 +0000
@@ -54,6 +54,7 @@
 #include "gripes.h"
 #include "help.h"
 #include "input.h"
+#include "load-path.h"
 #include "oct-obj.h"
 #include "ov-usr-fcn.h"
 #include "pager.h"
@@ -437,9 +438,9 @@
 yesno = \"yes\"\n\
 \n\
 switch yesno\n\
-  case {\"Yes\" \"yes\" \"YES\" \"y\" \"Y\"}\n\
+  case @{\"Yes\" \"yes\" \"YES\" \"y\" \"Y\"@}\n\
     value = 1;\n\
-  case {\"No\" \"no\" \"NO\" \"n\" \"N\"}\n\
+  case @{\"No\" \"no\" \"NO\" \"n\" \"N\"@}\n\
     value = 0;\n\
   otherwise\n\
     error (\"invalid value\");\n\
@@ -564,7 +565,7 @@
     lcl = curr_sym_tab->name_list ();
   int lcl_len = lcl.length ();
 
-  string_vector ffl = octave_fcn_file_name_cache::list_no_suffix ();
+  string_vector ffl = load_path::fcn_names ();
   int ffl_len = ffl.length ();
 
   string_vector afl = autoloaded_functions ();
@@ -684,26 +685,7 @@
 
   // Also need to search octave_path for script files.
 
-  string_vector dirs = Vload_path_dir_path.all_directories ();
-
-  int len = dirs.length ();
-
-  for (int i = 0; i < len; i++)
-    {
-      string_vector names = octave_fcn_file_name_cache::list (dirs[i]);
-
-      if (! names.empty ())
-	{
-	  std::string dir
-	    = octave_env::make_absolute (dirs[i], octave_env::getcwd ());
-
-	  octave_stdout << "\n*** function files in " << dir << ":\n\n";
-
-	  names.qsort ();
-
-	  names.list_in_columns (octave_stdout);
-	}
-    }
+  load_path::display (octave_stdout);
 
   string_vector autoloaded = autoloaded_functions ();
 
@@ -1881,13 +1863,13 @@
 	    }
 	}
 
-      string_vector dirs = Vload_path_dir_path.all_directories ();
+      string_vector dirs = load_path::dirs ();
 
       int len = dirs.length ();
 
       for (int i = 0; i < len; i++)
 	{
-	  names = octave_fcn_file_name_cache::list (dirs[i]);
+	  names = load_path::files (dirs[i]);
 
 	  if (! names.empty ())
 	    {
@@ -1912,19 +1894,18 @@
 		  if (!sr)
 		    {
 		      // Check if this version is first in the path
-		      string_vector tmp (2);
-		      tmp(0) = name + ".oct";
-		      tmp(1) = name + ".m";
-		      std::string file_name = 
-			Vload_path_dir_path.find_first_of (tmp);
 
-		      if (file_name == dirs[i] + tmp(0)
-			  || file_name == dirs[i] + tmp(1))
+		      std::string file_name = load_path::find_fcn (name);
+		      
+		      std::string dir = dirs[i] + file_ops::dir_sep_str;
+
+		      if (file_name == dir + name + ".oct"
+			  || file_name == dir + name + ".m")
 			{
 			  bool symbol_found;
 
 			  std::string h;
-			  if (file_name == dirs[i] + tmp(0))
+			  if (file_name == dir + name + ".oct")
 			    {
 			      // oct-file. Must load to get help
 			      sr = lookup_by_name (name, false);
@@ -1970,7 +1951,8 @@
 		    }
 
 		  // Check if this function has autoloaded functions attached to it
-		  std::string file_name = Vload_path_dir_path.find_first_of (names(j));
+		  std::string file_name = load_path::find_fcn (name);
+
 		  string_vector autoload_fcns = reverse_lookup_autoload (file_name);
 
 		  if (! autoload_fcns.empty ())
--- a/src/input.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/input.cc	Fri May 26 21:42:22 2006 +0000
@@ -54,6 +54,7 @@
 #include "gripes.h"
 #include "help.h"
 #include "input.h"
+#include "load-path.h"
 #include "oct-map.h"
 #include "oct-hist.h"
 #include "toplev.h"
@@ -90,7 +91,7 @@
 int Vecho_executing_commands = ECHO_OFF;
 
 // The time we last printed a prompt.
-octave_time Vlast_prompt_time;
+octave_time Vlast_prompt_time = 0.0;
 
 // Character to append after successful command-line completion attempts.
 static char Vcompletion_append_char = ' ';
@@ -212,10 +213,11 @@
 
   std::string retval;
 
-  Vlast_prompt_time.stamp ();
-
   if ((interactive || forced_interactive)
-      && (! (reading_fcn_file || reading_script_file)))
+      && (! (reading_fcn_file
+	     || reading_script_file
+	     || input_from_startup_file
+	     || input_from_command_line_file)))
     {
       std::string ps = (promptflag > 0) ? VPS1 : VPS2;
 
@@ -227,7 +229,14 @@
 
       octave_diary << prompt;
 
+      Vlast_prompt_time.stamp ();
+
       retval = gnu_readline (prompt);
+
+      // There is no need to update the load_path cache if there is no
+      // user input.
+      if (! retval.empty ())
+	load_path::update ();
     }
   else
     retval = gnu_readline ("");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/load-path.cc	Fri May 26 21:42:22 2006 +0000
@@ -0,0 +1,1425 @@
+/*
+
+Copyright (C) 2006 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 2, 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, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+#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;
+
+static std::string Vsystem_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 = dir_name + file_ops::dir_sep_str + "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 = d + file_ops::dir_sep_str + 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")
+			{
+			  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;
+
+		  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) const
+{
+  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)
+{
+  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 ())
+    path += dir_path::path_sep_str + tpath;
+}
+
+void
+load_path::do_initialize (void)
+{
+  Vsystem_path = ":";
+
+  maybe_add_path_elts (Vsystem_path, Vlocal_ver_oct_file_dir);
+  maybe_add_path_elts (Vsystem_path, Vlocal_api_oct_file_dir);
+  maybe_add_path_elts (Vsystem_path, Vlocal_oct_file_dir);
+  maybe_add_path_elts (Vsystem_path, Vlocal_ver_fcn_file_dir);
+  maybe_add_path_elts (Vsystem_path, Vlocal_api_fcn_file_dir);
+  maybe_add_path_elts (Vsystem_path, Vlocal_fcn_file_dir);
+  maybe_add_path_elts (Vsystem_path, Voct_file_dir);
+  maybe_add_path_elts (Vsystem_path, Vfcn_file_dir);
+
+  std::string tpath = load_path::command_line_path;
+
+  if (tpath.empty ())
+    tpath = octave_env::getenv ("OCTAVE_LOADPATH");
+
+  std::string xpath = ".";
+
+  if (! tpath.empty ())
+    xpath += dir_path::path_sep_str + tpath;
+
+  if (Vsystem_path != ":")
+    xpath += Vsystem_path;
+
+  do_set (xpath + ":::");
+}
+
+void
+load_path::do_clear (void)
+{
+  dir_info_list.clear ();
+  fcn_map.clear ();
+}
+
+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)
+{
+  do_clear ();
+
+  std::list<std::string> elts = split_path (p);
+
+  // Temporarily disable add hook.
+
+  unwind_protect_ptr (add_hook);
+
+  add_hook = 0;
+
+  for (std::list<std::string>::const_iterator i = elts.begin ();
+       i != elts.end ();
+       i++)
+    do_append (*i);
+
+  // 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)
+{
+  if (! dir.empty ())
+    {
+      dir_info_list_iterator i = find_dir_info (dir);
+
+      if (i != dir_info_list.end ())
+	move (i, true);
+      else
+	{
+	  dir_info di (dir);
+
+	  if (! error_state)
+	    {
+	      dir_info_list.push_back (di);
+
+	      add_to_fcn_map (di, true);
+
+	      if (add_hook)
+		add_hook (dir);
+	    }
+	}
+    }
+}
+
+void
+load_path::do_prepend (const std::string& dir)
+{
+  if (! dir.empty ())
+    {
+      dir_info_list_iterator i = find_dir_info (dir);
+
+      if (i != dir_info_list.end ())
+	move (i, false);
+      else
+	{
+	  dir_info di (dir);
+
+	  if (! error_state)
+	    {
+	      dir_info_list.push_front (di);
+
+	      add_to_fcn_map (di, false);
+
+	      if (add_hook)
+		add_hook (dir);
+	    }
+	}
+
+      // 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)
+{
+  bool retval = false;
+
+  if (! dir.empty ())
+    {
+      if (dir == ".")
+	warning ("rmpath: can't remove \".\" from path");
+
+      dir_info_list_iterator i = find_dir_info (dir);
+
+      if (i != dir_info_list.end ())
+	{
+	  retval = true;
+
+	  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;
+		    }
+		}
+	    }
+
+	  if (remove_hook)
+	    remove_hook (dir);
+	}
+    }
+
+  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 = fi.dir_name + file_ops::dir_sep_str + 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::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
+	    error ("load_path::do_find_fcn: %s: invalid type code = %d",
+		   fcn.c_str (), type);
+	}
+    }
+
+  return retval;
+}
+
+std::string
+load_path::do_find_file (const std::string& file) const
+{
+  std::string retval;
+
+  if (octave_env::absolute_pathname (file))
+    {
+      file_stat fs (file);
+
+      if (fs.exists ())
+	return file;
+    }
+
+  std::string dir_name;
+
+  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)
+	    {
+	      dir_name = p->dir_name;
+	      break;
+	    }
+	}
+    }
+
+  if (! dir_name.empty ())
+    retval = dir_name + file_ops::dir_sep_str + file;
+
+  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];
+		  break;
+		}
+	    }
+	}
+    }
+
+  if (! dir_name.empty ())
+    retval = dir_name + file_ops::dir_sep_str + 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
+		  (p->dir_name + file_ops::dir_sep_str + 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::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::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;
+
+      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;
+
+  std::string full_dirname = file_ops::tilde_expand (dirname);
+
+  dir_entry dir (full_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 = full_dirname + file_ops::dir_sep_str + 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 = dir + file_ops::dir_sep_str + script_file;
+
+  file_stat fs = file_stat (file);
+
+  if (fs.exists ())
+    source_file (file);
+
+  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 subdiretories.\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 @code{LOADPATH} 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 (Vsystem_path);
+}
+
+DEFUN (path, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn {Function File} {} path (@dots{})\n\
+Modify or display Octave's @code{LOADPATH}.\n\
+\n\
+If @var{nargin} and @var{nargout} are zero, display the elements of\n\
+Octave's @code{LOADPATH} in an easy to read format.\n\
+\n\
+If @var{nargin} is zero and nargout is greater than zero, return the\n\
+current value of @code{LOADPATH}.\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;
+
+	  size_t plen = path.length ();
+
+	  if (! ((plen == 1 && path[0] == ':')
+		 || (plen > 1
+		     && path.substr (0, 2) == ("." + dir_path::path_sep_str))))
+	    path = "." + dir_path::path_sep_str + path;
+
+	  load_path::set (path);
+	}
+
+      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 {Function File} {} addpath (@var{dir1}, @dots{})\n\
+@deftypefnx {Function File} {} 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;
+	    }
+	}
+
+      std::list<std::string> xpath = load_path::dir_list ();
+
+      // Strip "." for now.  Calling path to set the path will restore it.
+
+      xpath.remove (".");
+
+      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 (dir == "." && append)
+		    warning ("addpath: \".\" is always first in the path");
+
+		  file_stat fs (dir);
+
+		  if (fs)
+		    {
+		      if (fs.is_dir ())
+			{
+			  if (append)
+			    load_path::append (dir);
+			  else
+			    load_path::prepend (dir);
+			}
+		      else
+			warning ("addpath: %s: not a directory", dir.c_str ());
+		    }
+		  else
+		    {
+		      std::string msg = fs.error ();
+		      warning ("addpath: %s: %s", dir.c_str (), msg.c_str ());
+		    }
+		}
+	    }
+	  else
+	    error ("addpath: expecting all args to be character strings");
+	}
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFCMD (rmpath, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} 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)
+    {
+      std::list<std::string> xpath = load_path::dir_list ();
+
+      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: ***
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/load-path.h	Fri May 26 21:42:22 2006 +0000
@@ -0,0 +1,337 @@
+/*
+
+Copyright (C) 2006 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 2, 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, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+#if !defined (octave_load_path_h)
+#define octave_load_path_h 1
+
+#include <iostream>
+#include <list>
+#include <map>
+#include <string>
+
+#include "str-vec.h"
+
+class
+load_path
+{
+protected:
+
+  load_path (void) : dir_info_list (), fcn_map () { }
+
+public:
+
+  typedef void (*hook_function_ptr) (const std::string& dir);
+
+  ~load_path (void) { }
+
+  static void initialize (void)
+  {
+    if (instance_ok ())
+      instance->do_initialize ();
+  }
+
+  static void clear (void)
+  {
+    if (instance_ok ())
+      instance->do_clear ();
+  }
+
+  static void set (const std::string& p)
+  {
+    if (instance_ok ())
+      instance->do_set (p);
+  }
+
+  static void append (const std::string& dir)
+  {
+    if (instance_ok ())
+      instance->do_append (dir);
+  }
+
+  static void prepend (const std::string& dir)
+  {
+    if (instance_ok ())
+      instance->do_prepend (dir);
+  }
+
+  static bool remove (const std::string& dir)
+  {
+    return instance_ok () ? instance->do_remove (dir) : false;
+  }
+
+  static void update (void)
+  {
+    if (instance_ok ())
+      instance->do_update ();
+  }
+
+  static std::string find_fcn (const std::string& fcn)
+  {
+    return instance_ok ()
+      ? instance->do_find_fcn (fcn) : std::string ();
+  }
+
+  static std::string find_fcn_file (const std::string& fcn)
+  {
+    return instance_ok () ?
+      instance->do_find_fcn (fcn, M_FILE) : std::string ();
+  }
+
+  static std::string find_oct_file (const std::string& fcn)
+  {
+    return instance_ok () ?
+      instance->do_find_fcn (fcn, OCT_FILE) : std::string ();
+  }
+
+  static std::string find_file (const std::string& file)
+  {
+    return instance_ok ()
+      ? instance->do_find_file (file) : std::string ();
+  }
+
+  static std::string find_first_of (const string_vector& files)
+  {
+    return instance_ok () ?
+      instance->do_find_first_of (files) : std::string ();
+  }
+
+  static string_vector find_all_first_of (const string_vector& files)
+  {
+    return instance_ok () ?
+      instance->do_find_all_first_of (files) : string_vector ();
+  }
+
+  static string_vector dirs (void)
+  {
+    return instance_ok () ? instance->do_dirs () : string_vector ();
+  }
+
+  static std::list<std::string> dir_list (void)
+  {
+    return instance_ok ()
+      ? instance->do_dir_list () : std::list<std::string> ();
+  }
+
+  static string_vector files (const std::string& dir)
+  {
+    return instance_ok () ? instance->do_files (dir) : string_vector ();
+  }
+
+  static string_vector fcn_names (void)
+  {
+    return instance_ok () ? instance->do_fcn_names () : string_vector ();
+  }
+
+  static std::string path (void)
+  {
+    return instance_ok () ? instance->do_path () : std::string ();
+  }
+
+  static void display (std::ostream& os)
+  {
+    if (instance_ok ())
+      instance->do_display (os);
+  }
+
+  static void set_add_hook (hook_function_ptr f) { add_hook = f; }
+
+  static void set_remove_hook (hook_function_ptr f) { remove_hook = f; }
+
+  static void set_command_line_path (const std::string& p)
+  {
+    command_line_path = p;
+  }
+
+private:
+
+  static const int M_FILE = 1;
+  static const int OCT_FILE = 2;
+
+  class dir_info
+  {
+  public:
+
+    dir_info (const std::string& d) : dir_name (d) { initialize (); }
+
+    dir_info (const dir_info& di)
+      : dir_name (di.dir_name), is_relative (di.is_relative),
+	dir_mtime (di.dir_mtime), all_files (di.all_files),
+	fcn_files (di.fcn_files),
+	private_function_map (di.private_function_map) { }
+
+    ~dir_info (void) { }
+
+    dir_info& operator = (const dir_info& di)
+    {
+      if (&di != this)
+	{
+	  dir_name = di.dir_name;
+	  is_relative = di.is_relative;
+	  dir_mtime = di.dir_mtime;
+	  all_files = di.all_files;
+	  fcn_files = di.fcn_files;
+	  private_function_map = di.private_function_map;
+	}
+
+      return *this;
+    }
+
+    void update (void);
+
+    std::string dir_name;
+    bool is_relative;
+    octave_time dir_mtime;
+    string_vector all_files;
+    string_vector fcn_files;
+    std::map<std::string, int> private_function_map;
+
+  private:
+
+    void initialize (void);
+
+    bool get_file_list (const std::string& d);
+
+    void get_private_function_map (const std::string& d);
+  };
+
+  class file_info
+  {
+  public:
+
+    file_info (const std::string& d, int t) : dir_name (d), types (t) { }
+
+    file_info (const file_info& fi)
+      : dir_name (fi.dir_name), types (fi.types) { }
+
+    ~file_info (void) { }
+
+    file_info& operator = (const file_info& fi)
+    {
+      if (&fi != this)
+	{
+	  dir_name = fi.dir_name;
+	  types = fi.types;
+	}
+
+      return *this;
+    }
+
+    std::string dir_name;
+    int types;
+  };
+
+  // We maintain two ways of looking at the same information.
+  //
+  // First, a list of directories and the set of "public" files and
+  // private files (those found in the special "private" subdirectory)
+  // in each directory.
+  //
+  // Second, a map from file names (the union of all "public" files for all
+  // directories, but without filename exteinsions) to a list of
+  // corresponding information (directory name and file types).  This
+  // way, we can quickly find shadowed file names and look up all
+  // overloaded functions (in the "@" directories used to implement
+  // classes).
+
+  mutable std::list<dir_info> dir_info_list;
+
+  mutable std::map<std::string, std::list<file_info> > fcn_map;
+
+  static load_path *instance;
+
+  static hook_function_ptr add_hook;
+
+  static hook_function_ptr remove_hook;
+
+  static std::string command_line_path;
+
+  static bool instance_ok (void);
+
+  typedef std::list<dir_info>::const_iterator const_dir_info_list_iterator;
+  typedef std::list<dir_info>::iterator dir_info_list_iterator;
+
+  typedef std::map<std::string, std::list<file_info> >::const_iterator const_fcn_map_iterator;
+  typedef std::map<std::string, std::list<file_info> >::iterator fcn_map_iterator;
+
+  typedef std::list<file_info>::const_iterator const_file_info_list_iterator;
+  typedef std::list<file_info>::iterator file_info_list_iterator;
+
+  const_dir_info_list_iterator find_dir_info (const std::string& dir) const;
+  dir_info_list_iterator find_dir_info (const std::string& dir);
+
+  bool contains (const std::string& dir) const;
+
+  void move (std::list<dir_info>::iterator i, bool at_end);
+
+  void do_initialize (void);
+
+  void do_clear (void);
+
+  void do_set (const std::string& p);
+
+  void do_append (const std::string& dir);
+
+  void do_prepend (const std::string& dir);
+
+  bool do_remove (const std::string& dir);
+
+  void do_update (void) const;
+
+  std::string do_find_fcn (const std::string& fcn,
+			   int type = M_FILE | OCT_FILE) const;
+
+  std::string do_find_file (const std::string& file) const;
+
+  std::string do_find_first_of (const string_vector& files) const;
+
+  string_vector do_find_all_first_of (const string_vector& files) const;
+
+  string_vector do_dirs (void) const;
+
+  std::list<std::string> do_dir_list (void) const;
+
+  string_vector do_files (const std::string& dir) const;
+
+  string_vector do_fcn_names (void) const;
+
+  std::string do_path (void) const;
+
+  void do_display (std::ostream& os) const;
+
+  void add_to_fcn_map (const dir_info& di, bool at_end) const;
+};
+
+extern std::string
+genpath (const std::string& dir, const string_vector& skip = "private");
+
+extern void execute_pkg_add (const std::string& dir);
+extern void execute_pkg_del (const std::string& dir);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
--- a/src/octave.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/octave.cc	Fri May 26 21:42:22 2006 +0000
@@ -58,6 +58,7 @@
 #include "file-io.h"
 #include "input.h"
 #include "lex.h"
+#include "load-path.h"
 #include "octave.h"
 #include "oct-hist.h"
 #include "oct-map.h"
@@ -578,7 +579,7 @@
 
 	case 'p':
 	  if (args.optarg ())
-	    set_load_path (args.optarg ());
+	    load_path::set_command_line_path (args.optarg ());
 	  break;
 
 	case 'q':
@@ -675,7 +676,7 @@
 
   initialize_version_info ();
 
-  execute_default_pkg_add_files ();
+  load_path::initialize ();
 
   execute_startup_files ();
 
--- a/src/parse.y	Fri May 26 21:06:00 2006 +0000
+++ b/src/parse.y	Fri May 26 21:42:22 2006 +0000
@@ -60,6 +60,7 @@
 #include "error.h"
 #include "input.h"
 #include "lex.h"
+#include "load-path.h"
 #include "oct-hist.h"
 #include "oct-map.h"
 #include "ov-fcn-handle.h"
@@ -3350,7 +3351,7 @@
   am_iter p = autoload_map.find (nm);
 
   if (p != autoload_map.end ())
-    retval = octave_env::make_absolute (Vload_path_dir_path.find (p->second),
+    retval = octave_env::make_absolute (load_path::find_file (p->second),
 					octave_env::getcwd ());
 
   return retval;
@@ -3413,13 +3414,8 @@
 	  exec_script = true;
 	}
       else
-	{
-	  names[0] = nm + ".oct";
-	  names[1] = nm + ".m";
-
-	  file = octave_env::make_absolute (Vload_path_dir_path.find_first_of (names),
-					    octave_env::getcwd ());
-	}
+	file = octave_env::make_absolute
+	  (load_path::find_fcn (nm), octave_env::getcwd ());
     }
 
   int len = file.length ();
--- a/src/pr-output.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/pr-output.cc	Fri May 26 21:42:22 2006 +0000
@@ -318,7 +318,7 @@
     }
   else if (inf_or_nan || int_only)
     {
-      fw = digits;
+      fw = 1 + digits;
       if (inf_or_nan && fw < 4)
 	fw = 4;
       rd = fw;
@@ -338,7 +338,7 @@
 	  digits = -digits + 1;
 	}
 
-      fw = ld + 1 + rd;
+      fw = 1 + ld + 1 + rd;
       if (inf_or_nan && fw < 4)
 	fw = 4;
     }
@@ -478,7 +478,7 @@
       ld = ld_max > ld_min ? ld_max : ld_min;
       rd = rd_max > rd_min ? rd_max : rd_min;
 
-      fw = ld + 1 + rd;
+      fw = 1 + ld + 1 + rd;
       if (inf_or_nan && fw < 4)
 	fw = 4;
     }
@@ -626,7 +626,7 @@
       ld = ld_max > ld_min ? ld_max : ld_min;
       rd = rd_max > rd_min ? rd_max : rd_min;
 
-      i_fw = r_fw = ld + 1 + rd;
+      i_fw = r_fw = 1 + ld + 1 + rd;
       if (inf_or_nan && i_fw < 4)
 	i_fw = r_fw = 4;
     }
@@ -806,7 +806,7 @@
       ld = ld_max > ld_min ? ld_max : ld_min;
       rd = rd_max > rd_min ? rd_max : rd_min;
 
-      i_fw = r_fw = ld + 1 + rd;
+      i_fw = r_fw = 1 + ld + 1 + rd;
       if (inf_or_nan && i_fw < 4)
 	i_fw = r_fw = 4;
     }
@@ -981,7 +981,7 @@
       ld = ld_max > ld_min ? ld_max : ld_min;
       rd = rd_max > rd_min ? rd_max : rd_min;
 
-      fw = sign + ld + 1 + rd;
+      fw = sign + 1 + ld + 1 + rd;
     }
 
   if (! (bank_format || hex_format || bit_format)
--- a/src/utils.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/utils.cc	Fri May 26 21:42:22 2006 +0000
@@ -58,6 +58,7 @@
 #include "error.h"
 #include "gripes.h"
 #include "input.h"
+#include "load-path.h"
 #include "oct-errno.h"
 #include "oct-hist.h"
 #include "oct-obj.h"
@@ -295,8 +296,7 @@
 	  if (nargin == 1)
 	    {
 	      std::string fname = octave_env::make_absolute
-		(Vload_path_dir_path.find_first_of (names),
-		 octave_env::getcwd ());
+		(load_path::find_first_of (names), octave_env::getcwd ());
 
 	      if (fname.empty ())
 		retval = Matrix ();
@@ -308,7 +308,7 @@
 	      std::string opt = args(1).string_value ();
 
 	      if (! error_state && opt == "all")
-		retval = Cell (make_absolute (Vload_path_dir_path.find_all_first_of (names)));
+		retval = Cell (make_absolute (load_path::find_all_first_of (names)));
 	      else
 		error ("file_in_loadpath: invalid option");
 	    }
@@ -399,8 +399,10 @@
   if (! suffix.empty ())
     nm.append (suffix);
 
-  return octave_env::make_absolute (Vload_path_dir_path.find (nm),
-				    octave_env::getcwd ());
+  return std::string ();
+
+  return octave_env::make_absolute
+    (load_path::find_file (nm), octave_env::getcwd ());
 }
 
 // See if there is an function file in the path.  If so, return the
@@ -415,10 +417,17 @@
   
   if (len > 0)
     {
-      if (len > 2 && name [len - 2] == '.' && name [len - 1] == 'm')
-	retval = file_in_path (name, "");
+      if (octave_env::absolute_pathname (name))
+	{
+	  file_stat fs (name);
+
+	  if (fs.exists ())
+	    retval = name;
+	}
+      else if (len > 2 && name [len - 2] == '.' && name [len - 1] == 'm')
+	retval = load_path::find_fcn_file (name.substr (0, len-2));
       else
-	retval = file_in_path (name, ".m");
+	retval = load_path::find_fcn_file (name);
     }
 
   return retval;
@@ -436,11 +445,18 @@
   
   if (len > 0)
     {
-      if (len > 4 && name [len - 4] == '.' && name [len - 3] == 'o'
-	  && name [len - 2] == 'c' && name [len - 1] == 't')
-	retval = file_in_path (name, "");
+      if (octave_env::absolute_pathname (name))
+	{
+	  file_stat fs (name);
+
+	  if (fs.exists ())
+	    retval = name;
+	}
+      else if (len > 4 && name [len - 4] == '.' && name [len - 3] == 'o'
+	       && name [len - 2] == 'c' && name [len - 1] == 't')
+	retval = load_path::find_oct_file (name.substr (0, len-4));
       else
-	retval = file_in_path (name, ".oct");
+	retval = load_path::find_oct_file (name);
     }
 
   return retval;
@@ -657,23 +673,6 @@
   return retval;
 }
 
-DEFUN (find_first_of_in_loadpath, args, , "")
-{
-  octave_value retval;
-
-  if (args.length () == 1)
-    {
-      string_vector names = args(0).all_strings ();
-
-      if (! error_state)
-	retval = Vload_path_dir_path.find_all_first_of (names);
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
 DEFUNX ("errno", Ferrno, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {@var{err} =} errno ()\n\
--- a/src/variables.cc	Fri May 26 21:06:00 2006 +0000
+++ b/src/variables.cc	Fri May 26 21:42:22 2006 +0000
@@ -46,6 +46,7 @@
 #include "help.h"
 #include "input.h"
 #include "lex.h"
+#include "load-path.h"
 #include "oct-map.h"
 #include "oct-obj.h"
 #include "ov.h"
@@ -812,22 +813,15 @@
 	  std::string file_name = lookup_autoload (name);
 
 	  if (file_name.empty ())
-	    {
-	      string_vector names (2);
-
-	      names(0) = name + ".oct";
-	      names(1) = name + ".m";
-
-	      file_name = Vload_path_dir_path.find_first_of (names);
-	    }
+	    file_name = load_path::find_fcn (name);
 
 	  size_t len = file_name.length ();
 
-	  if (! file_name.empty ())
+	  if (len > 0)
 	    {
 	      if (type == "any" || type == "file")
 		{
-		  if (file_name.substr (len-4) == ".oct")
+		  if (len > 4 && file_name.substr (len-4) == ".oct")
 		    retval = 3;
 		  else
 		    retval = 2;
@@ -1031,12 +1025,8 @@
 
 		      if (file.empty ())
 			{
-			  names[0] = nm + ".oct";
-			  names[1] = nm + ".m";
-
 			  file = octave_env::make_absolute
-			    (Vload_path_dir_path.find_first_of (names),
-			     octave_env::getcwd ());
+			    (load_path::find_fcn (nm), octave_env::getcwd ());
 			}
 		    }