changeset 5189:85b315ad5f7d

[project @ 2005-03-04 02:46:08 by jwe]
author jwe
date Fri, 04 Mar 2005 02:46:08 +0000
parents fd90c6df7d52
children 2021bbfff5fd
files src/ChangeLog src/input.cc src/input.h src/octave.cc src/ov-bool-sparse.h src/parse.h src/parse.y src/toplev.cc src/toplev.h
diffstat 9 files changed, 169 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,34 @@
 2005-03-03  John W. Eaton  <jwe@octave.org>
 
+	* input.cc (input_from_command_line_file): Move definition here.
+	* parse.y: From here.
+	* input.h (input_from_command_line_file): Move decl here.
+	* parse.h: From here.
+
+	* input.cc (octave_gets):
+	Don't save history if input is from command line file.
+
+	* parse.y (parse_and_execute, parse_fcn_file, eval_string):
+	Don't alter value of input_from_command_line_file here.
+	(input_from_command_line_file): Default value is false.
+	(eval_string): Turn off line editing here.
+
+	* toplev.cc, toplev.h (main_loop): Delete fun_to_call arg and all uses.
+
+	* octave.cc (fun_to_call): Delete static variable.
+	(persist, code_to_eval): New static variables.
+	(long_opts): Delete --funcall, add --eval and --persist.
+	(usage_string, verbose_usage, octave_main): Likewise.
+	(FUNCALL_OPTION): Delete.
+	(EVAL_OPTION, PERSIST_OPTION): New macros.
+	(maximum_braindamage): Set persist to true.
+	(execute_eval_option_code): New function.
+	(restore_program_name): New function.
+	(execute_command_line_file): New function.
+	(octave_main): Call execute_eval_option code and
+	execute_command_line file.  If persist, go interactive even after
+	evaluating --eval code and/or command-line file.
+
 	* ov-bool-sparse.h, ov-bool-sparse.cc
 	(octave_sparse_bool_matrix::sparse_matrix_value,
 	octave_sparse_bool_matrix::sparse_complex_matrix_value):
--- a/src/input.cc
+++ b/src/input.cc
@@ -103,6 +103,10 @@
 // current_eval_string yet.
 bool input_from_eval_string_pending = false;
 
+// TRUE means that input is coming from a file that was named on
+// the command line.
+bool input_from_command_line_file = false;
+
 // TRUE means we're parsing a function file.
 bool reading_fcn_file = false;
 
@@ -234,7 +238,7 @@
 
   if (! current_input_line.empty ())
     {
-      if (! input_from_startup_file)
+      if (! (input_from_startup_file || input_from_command_line_file))
 	command_history::add (current_input_line);
 
       if (! (reading_fcn_file || reading_script_file))
--- a/src/input.h
+++ b/src/input.h
@@ -49,6 +49,10 @@
 // current_eval_string yet.
 extern bool input_from_eval_string_pending;
 
+// TRUE means that input is coming from a file that was named on
+// the command line.
+extern bool input_from_command_line_file;
+
 // TRUE means we're parsing a function file.
 extern bool reading_fcn_file;
 
--- a/src/octave.cc
+++ b/src/octave.cc
@@ -108,8 +108,8 @@
 
 // Usage message
 static const char *usage_string = 
-  "octave [-?HVdfhiqvx] [--debug] [--echo-commands] [--exec-path path]\n\
-       [--funcall FUNC] [--help] [--info-file file] [--info-program prog]\n\
+  "octave [-?HVdfhiqvx] [--debug] [--echo-commands] [--eval CODE]\n\
+       [--exec-path path] [--help] [--info-file file] [--info-program prog]\n\
        [--interactive] [--no-history] [--no-init-file] [--no-line-editing]\n\
        [--no-site-file] [-p path] [--path path] [--silent] [--traditional]\n\
        [--verbose] [--version] [file]";
@@ -119,27 +119,30 @@
 // to prevent getopt from permuting arguments!
 static const char *short_opts = "+?HVdfhip:qvx";
 
-// The name of the optional initial function to call at startup.
-// (--funcall FUNC)
-static std::string fun_to_call;
+// The code to evaluate at startup (--eval CODE)
+static std::string code_to_eval;
+
+// If TRUE, don't exit after evaluating code given by --eval option.
+static bool persist = false;
 
 // Long options.  See the comments in getopt.h for the meanings of the
 // fields in this structure.
-#define EXEC_PATH_OPTION 1
-#define FUNCALL_OPTION 2
+#define EVAL_OPTION 1
+#define EXEC_PATH_OPTION 2
 #define INFO_FILE_OPTION 3
 #define INFO_PROG_OPTION 4
 #define NO_INIT_FILE_OPTION 5
 #define NO_LINE_EDITING_OPTION 6
 #define NO_SITE_FILE_OPTION 7
-#define TRADITIONAL_OPTION 8
+#define PERSIST_OPTION 8
+#define TRADITIONAL_OPTION 9
 long_options long_opts[] =
   {
     { "debug",            prog_args::no_arg,       0, 'd' },
     { "braindead",        prog_args::no_arg,       0, TRADITIONAL_OPTION },
     { "echo-commands",    prog_args::no_arg,       0, 'x' },
+    { "eval",             prog_args::required_arg, 0, EVAL_OPTION },
     { "exec-path",        prog_args::required_arg, 0, EXEC_PATH_OPTION },
-    { "funcall",          prog_args::required_arg,  0, FUNCALL_OPTION },
     { "help",             prog_args::no_arg,       0, 'h' },
     { "info-file",        prog_args::required_arg, 0, INFO_FILE_OPTION },
     { "info-program",     prog_args::required_arg, 0, INFO_PROG_OPTION },
@@ -150,6 +153,7 @@
     { "no-site-file",     prog_args::no_arg,       0, NO_SITE_FILE_OPTION },
     { "norc",             prog_args::no_arg,       0, 'f' },
     { "path",             prog_args::required_arg, 0, 'p' },
+    { "persist",          prog_args::no_arg,       0, PERSIST_OPTION },
     { "quiet",            prog_args::no_arg,       0, 'q' },
     { "silent",           prog_args::no_arg,       0, 'q' },
     { "traditional",      prog_args::no_arg,       0, TRADITIONAL_OPTION },
@@ -211,9 +215,6 @@
 {
   unwind_protect::begin_frame ("execute_startup_files");
 
-  // XXX FIXME XXX -- need to make it possible to set this in startup
-  // files.
-
   unwind_protect_bool (input_from_startup_file);
 
   input_from_startup_file = true;
@@ -291,6 +292,68 @@
   unwind_protect::run_frame ("execute_startup_files");
 }
 
+static int
+execute_eval_option_code (const std::string& code)
+{
+  unwind_protect::begin_frame ("execute_eval_option_code");
+
+  unwind_protect_bool (interactive);
+
+  interactive = false;
+
+  int parse_status = 0;
+
+  eval_string (code, false, parse_status, 0);
+
+  unwind_protect::run_frame ("execute_eval_option_code");
+
+  return parse_status;
+}
+
+static void
+restore_program_name (void *)
+{
+  bind_builtin_variable ("program_invocation_name",
+			 octave_env::get_program_invocation_name ());
+
+  bind_builtin_variable ("program_name", octave_env::get_program_name ());
+}
+
+static void
+execute_command_line_file (const std::string& fname)
+{
+  unwind_protect::begin_frame ("execute_command_line_file");
+
+  unwind_protect_bool (interactive);
+  unwind_protect_bool (reading_script_file);
+  unwind_protect_bool (input_from_command_line_file);
+
+  unwind_protect_str (curr_fcn_file_name);
+  unwind_protect_str (curr_fcn_file_full_name);
+
+  unwind_protect::add (restore_program_name, 0);
+
+  interactive = false;
+  reading_script_file = true;
+  input_from_command_line_file = true;
+
+  curr_fcn_file_name = fname;
+  curr_fcn_file_full_name = curr_fcn_file_name;
+
+  bind_builtin_variable ("program_invocation_name", curr_fcn_file_name);
+
+  size_t pos = curr_fcn_file_name.find_last_of (file_ops::dir_sep_chars);
+  
+  std::string tmp = (pos != NPOS)
+    ? curr_fcn_file_name.substr (pos+1) : curr_fcn_file_name;
+
+  bind_builtin_variable ("program_name", tmp);
+
+  parse_and_execute (fname, false, "octave");
+ 
+  unwind_protect::run_frame ("execute_command_line_file");
+}
+
 // Usage message with extra help.
 
 static void
@@ -305,7 +368,7 @@
   --debug, -d             Enter parser debugging mode.\n\
   --echo-commands, -x     Echo commands as they are executed.\n\
   --exec-path PATH        Set path for executing subprograms.\n\
-  --funcall FUNC          Call Octave function FUNC with no arguments.\n\
+  --eval CODE             Evaluate CODE and exit when done unless --persist.\n\
   --help, -h, -?          Print short help message and exit.\n\
   --info-file FILE        Use top-level info file FILE.\n\
   --info-program PROGRAM  Use PROGRAM for reading info files.\n\
@@ -316,6 +379,7 @@
   --no-site-file          Don't read the site-wide octaverc file.\n\
   --norc, -f              Don't read any initialization files.\n\
   --path PATH, -p PATH    Set initial LOADPATH to PATH.\n\
+  --persist               Go interactive after --eval or reading from FILE.\n\
   --silent, -q            Don't print message at startup.\n\
   --traditional           Set compatibility variables.\n\
   --verbose, -V           Enable verbose output in some cases.\n\
@@ -360,6 +424,8 @@
 static void
 maximum_braindamage (void)
 {
+  persist = true;
+
   bind_builtin_variable ("PS1", ">> ");
   bind_builtin_variable ("PS2", "");
   bind_builtin_variable ("beep_on_error", true);
@@ -469,16 +535,16 @@
 	  print_version_and_exit ();
 	  break;
 
+	case EVAL_OPTION:
+	  if (args.optarg ())
+	    code_to_eval = args.optarg ();
+	  break;
+
 	case EXEC_PATH_OPTION:
 	  if (args.optarg ())
 	    bind_builtin_variable ("EXEC_PATH", args.optarg ());
 	  break;
 
-	case FUNCALL_OPTION:
-	  if (args.optarg ())
-	    fun_to_call = args.optarg ();
-	  break;
-
 	case INFO_FILE_OPTION:
 	  if (args.optarg ())
 	    bind_builtin_variable ("INFO_FILE", args.optarg ());
@@ -505,6 +571,10 @@
 	  traditional = true;
 	  break;
 
+	case PERSIST_OPTION:
+	  persist = true;
+	  break;
+
 	default:
 	  usage ();
 	  break;
@@ -541,9 +611,14 @@
   if (! inhibit_startup_message && reading_startup_message_printed)
     std::cout << std::endl;
 
-  // Avoid counting commands executed from startup files.
+  // Is input coming from a terminal?  If so, we are probably
+  // interactive.
 
-  command_editor::reset_current_command_number (1);
+  interactive = (! embedded
+		 && isatty (fileno (stdin)) && isatty (fileno (stdout)));
+
+  if (! interactive)
+    line_editing = false;
 
   // If there is an extra argument, see if it names a file to read.
   // Additional arguments are taken as command line options for the
@@ -553,53 +628,41 @@
 
   int remaining_args = argc - last_arg_idx;
 
-  if (remaining_args > 0)
+  if (! code_to_eval.empty ())
     {
-      reading_script_file = true;
-
-      curr_fcn_file_name = argv[last_arg_idx];
-      curr_fcn_file_full_name = curr_fcn_file_name;
-
-      FILE *infile = get_input_from_file (curr_fcn_file_name);
-
-      if (infile)
-	{
-	  input_from_command_line_file = true;
-
-	  bind_builtin_variable ("program_invocation_name",
-				 curr_fcn_file_name);
-
-	  size_t pos
-	    = curr_fcn_file_name.find_last_of (file_ops::dir_sep_chars);
-
-	  std::string tmp = (pos != NPOS)
-	    ? curr_fcn_file_name.substr (pos+1) : curr_fcn_file_name;
-
-	  bind_builtin_variable ("program_name", tmp);
-
-	  intern_argv (remaining_args, argv+last_arg_idx);
-
-	  command_editor::blink_matching_paren (false);
-
-	  switch_to_buffer (create_buffer (infile));
-	}
-      else
-	clean_up_and_exit (1);
-    }
-  else
-    {
-      // Is input coming from a terminal?  If so, we are probably
-      // interactive.
-
-      interactive = (! embedded
-		     && isatty (fileno (stdin)) && isatty (fileno (stdout)));
+      // We probably want all the args for an --eval option.
 
       intern_argv (argc, argv);
 
-      if (! embedded)
-	switch_to_buffer (create_buffer (get_input_from_stdin ()));
+      int parse_status = execute_eval_option_code (code_to_eval);
+
+      if (! (persist && remaining_args > 0))
+	return (parse_status || error_state ? 1 : 0);
     }
 
+  if (remaining_args > 0)
+    {
+      // If we are running an executable script (#! /bin/octave) then
+      // we should only see the args passed to the script.
+
+      intern_argv (remaining_args, argv+last_arg_idx);
+
+      execute_command_line_file (argv[last_arg_idx]);
+
+      if (! persist)
+	return (error_state ? 1 : 0);
+    }
+
+  // Avoid counting commands executed from startup files.
+
+  command_editor::reset_current_command_number (1);
+
+  // Now argv should have the full set of args.
+  intern_argv (argc, argv);
+
+  if (! embedded)
+    switch_to_buffer (create_buffer (get_input_from_stdin ()));
+
   // Force input to be echoed if not really interactive, but the user
   // has forced interactive behavior.
 
@@ -612,13 +675,10 @@
       bind_builtin_variable ("echo_executing_commands", ECHO_CMD_LINE);
     }
 
-  if (! interactive)
-    line_editing = false;
-
   if (embedded)
     return 1;
 
-  int retval = main_loop (fun_to_call);
+  int retval = main_loop ();
 
   if (retval == 1 && ! error_state)
     retval = 0;
--- a/src/ov-bool-sparse.h
+++ b/src/ov-bool-sparse.h
@@ -117,7 +117,7 @@
 
   SparseComplexMatrix sparse_complex_matrix_value (bool = false) const;
 
-  SparseBoolMatrix sparse_bool_matrix_value (void) const
+  SparseBoolMatrix sparse_bool_matrix_value (bool = false) const
     { return matrix; }
 
   octave_value convert_to_str_internal (bool pad, bool force) const;
--- a/src/parse.h
+++ b/src/parse.h
@@ -66,10 +66,6 @@
 // TRUE means input is coming from startup file.
 extern bool input_from_startup_file;
 
-// TRUE means that input is coming from a file that was named on
-// the command line.
-extern bool input_from_command_line_file;
-
 // TRUE means that we are in the process of evaluating a function
 // body.  The parser might be called in that case if we are looking at
 // an eval() statement.
--- a/src/parse.y
+++ b/src/parse.y
@@ -130,10 +130,6 @@
 // TRUE means input is coming from startup file.
 bool input_from_startup_file = false;
 
-// TRUE means that input is coming from a file that was named on
-// the command line.
-bool input_from_command_line_file = true;
-
 // TRUE means that we are in the process of evaluating a function
 // body.  The parser might be called in that case if we are looking at
 // an eval() statement.
@@ -2854,12 +2850,10 @@
   switch_to_buffer (new_buf);
 
   unwind_protect_bool (line_editing);
-  unwind_protect_bool (input_from_command_line_file);
   unwind_protect_bool (get_input_from_eval_string);
   unwind_protect_bool (parser_end_of_input);
 
   line_editing = false;
-  input_from_command_line_file = false;
   get_input_from_eval_string = false;
   parser_end_of_input = false;
 
@@ -3253,14 +3247,12 @@
 	  unwind_protect_int (Vecho_executing_commands);
 	  unwind_protect_bool (Vsaving_history);
 	  unwind_protect_bool (reading_fcn_file);
-	  unwind_protect_bool (input_from_command_line_file);
 	  unwind_protect_bool (get_input_from_eval_string);
 	  unwind_protect_bool (parser_end_of_input);
 
 	  Vecho_executing_commands = ECHO_OFF;
 	  Vsaving_history = false;
 	  reading_fcn_file = true;
-	  input_from_command_line_file = false;
 	  get_input_from_eval_string = false;
 	  parser_end_of_input = false;
 
@@ -3575,14 +3567,15 @@
 
   unwind_protect_bool (get_input_from_eval_string);
   unwind_protect_bool (input_from_eval_string_pending);
-  unwind_protect_bool (input_from_command_line_file);
   unwind_protect_bool (parser_end_of_input);
+  unwind_protect_bool (line_editing);
   unwind_protect_str (current_eval_string);
 
   get_input_from_eval_string = true;
   input_from_eval_string_pending = true;
-  input_from_command_line_file = false;
   parser_end_of_input = false;
+  line_editing = false;
+
   current_eval_string = s;
 
   unwind_protect_ptr (global_command);
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -111,7 +111,7 @@
 }
 
 int
-main_loop (const std::string& fun_to_call)
+main_loop (void)
 {
   octave_save_signal_mask ();
 
@@ -137,9 +137,6 @@
 
   octave_initialized = true;
 
-  if (! fun_to_call.empty ())
-    feval (fun_to_call);
-
   // The big loop.
 
   int retval = 0;
--- a/src/toplev.h
+++ b/src/toplev.h
@@ -36,8 +36,7 @@
 extern void
 clean_up_and_exit (int) GCC_ATTR_NORETURN;
 
-extern int
-main_loop (const std::string& fun_to_call);
+extern int main_loop (void);
 
 extern void
 do_octave_atexit (void);