diff src/parse.y @ 5484:2ff5363a16bd

[project @ 2005-10-06 17:12:12 by jwe]
author jwe
date Thu, 06 Oct 2005 17:12:13 +0000
parents e2f85b298a74
children 61d6cebd243b
line wrap: on
line diff
--- a/src/parse.y	Wed Oct 05 07:54:51 2005 +0000
+++ b/src/parse.y	Thu Oct 06 17:12:13 2005 +0000
@@ -39,6 +39,8 @@
 #include <cstdlib>
 #endif
 
+#include <map>
+
 #include "Cell.h"
 #include "Matrix.h"
 #include "cmd-edit.h"
@@ -146,6 +148,12 @@
 // contain nested functions.
 std::string parent_function_name;
 
+// TRUE means we are in the process of autoloading a function.
+static bool autoloading = false;
+
+// List of autoloads (function -> file mapping).
+static std::map<std::string, std::string> autoload_map;
+
 // Forward declarations for some functions defined at the bottom of
 // the file.
 
@@ -2510,9 +2518,9 @@
   // file.  Matlab doesn't provide a diagnostic (it ignores the stated
   // name).
 
-  if (reading_fcn_file)
+  if (reading_fcn_file || autoloading)
     {
-      if (! lexer_flags.parsing_nested_function
+      if (! (lexer_flags.parsing_nested_function || autoloading)
           && curr_fcn_file_name != id_name)
 	{
 	  if (Vwarn_function_name_clash)
@@ -3167,13 +3175,18 @@
 }
 
 std::string
-get_help_from_file (const std::string& path)
+get_help_from_file (const std::string& nm, bool& symbol_found,
+		    bool include_file_info)
 {
   std::string retval;
 
-  if (! path.empty ())
+  std::string file = fcn_file_in_path (nm);
+
+  if (! file.empty ())
     {
-      FILE *fptr = fopen (path.c_str (), "r");
+      symbol_found = true;
+
+      FILE *fptr = fopen (file.c_str (), "r");
 
       if (fptr)
 	{
@@ -3181,6 +3194,9 @@
 
 	  retval = gobble_leading_white_space (fptr, true, true, false);
 
+	  if (! retval.empty () && include_file_info)
+	    retval = nm + " is the file: " + file + "\n\n" + retval;
+
 	  unwind_protect::run ();
 	}
     }
@@ -3355,9 +3371,19 @@
   return script_file_executed;
 }
 
+std::string
+lookup_autoload (const std::string& nm)
+{
+  return
+    octave_env::make_absolute (Vload_path_dir_path.find (autoload_map[nm]),
+			       octave_env::getcwd ());
+}
+
 bool
 load_fcn_from_file (const std::string& nm, bool exec_script)
 {
+  unwind_protect::begin_frame ("load_fcn_from_file");
+
   bool script_file_executed = false;
 
   string_vector names (2);
@@ -3374,12 +3400,23 @@
     }
   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 = lookup_autoload (nm);
+
+      if (! file.empty ())
+	{
+	  unwind_protect_bool (autoloading);
+
+	  autoloading = true;
+	  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 ());
+	}
     }
 
   int len = file.length ();
@@ -3393,22 +3430,28 @@
     {
       // These are needed by yyparse.
 
-      unwind_protect::begin_frame ("load_fcn_from_file");
-
       unwind_protect_str (curr_fcn_file_name);
       unwind_protect_str (curr_fcn_file_full_name);
 
       curr_fcn_file_name = nm;
       curr_fcn_file_full_name = file;
 
-      script_file_executed = parse_fcn_file (file, exec_script);
-
-      if (! (error_state || script_file_executed))
-	force_link_to_function (nm);
-
-      unwind_protect::run_frame ("load_fcn_from_file");
+      script_file_executed = parse_fcn_file (file, exec_script, autoloading);
+
+      if (! error_state)
+	{
+	  if (autoloading)
+	    {
+	      script_file_executed = false;
+	      force_link_to_function (nm);
+	    }
+	  else if (! script_file_executed)
+	    force_link_to_function (nm);
+	}
     }
 
+  unwind_protect::run_frame ("load_fcn_from_file");
+
   return script_file_executed;
 }
 
@@ -3418,6 +3461,29 @@
   return load_fcn_from_file (sym_rec->name (), exec_script);
 }
 
+DEFCMD (autoload, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\
+Define @var{function} to autoload from @var{file}.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 2)
+    {
+      string_vector argv = args.make_argv ("autoload");
+
+      if (! error_state)
+	autoload_map[argv[1]] = argv[2];
+    }
+  else
+    print_usage ("autoload");
+
+  return retval;
+}
+
 void
 source_file (const std::string file_name)
 {