HOST: Use more modern syntax.
[pspp] / src / language / command.c
index c00d94b9c4b3597bcc2416ae0e29fd56018b229f..9f90db93a941af0762b20e4f02b3f6e4758d8732 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include <config.h>
 
-#include <language/command.h>
+#include "language/command.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <errno.h>
-#include <unistd.h>
-
-#include <data/casereader.h>
-#include <data/dictionary.h>
-#include <data/procedure.h>
-#include <data/settings.h>
-#include <data/variable.h>
-#include <language/lexer/lexer.h>
-#include <language/prompt.h>
-#include <libpspp/assertion.h>
-#include <libpspp/compiler.h>
-#include <libpspp/message.h>
-#include <libpspp/message.h>
-#include <libpspp/str.h>
-#include <output/manager.h>
-#include <output/table.h>
-#include <libpspp/getl.h>
-
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#if HAVE_READLINE
-#include <readline/readline.h>
-#endif
+
+#include "data/casereader.h"
+#include "data/dictionary.h"
+#include "data/procedure.h"
+#include "data/settings.h"
+#include "data/variable.h"
+#include "language/lexer/lexer.h"
+#include "language/prompt.h"
+#include "libpspp/assertion.h"
+#include "libpspp/compiler.h"
+#include "libpspp/message.h"
+#include "libpspp/str.h"
+#include "libpspp/getl.h"
+#include "output/text-item.h"
 
 #include "xalloc.h"
 #include "xmalloca.h"
@@ -143,11 +132,7 @@ cmd_parse_in_state (struct lexer *lexer, struct dataset *ds,
 {
   int result;
 
-  som_new_series ();
-
   result = do_parse_command (lexer, ds, state);
-  if (cmd_result_is_failure (result))
-    lex_discard_rest_of_command (lexer);
 
   assert (!proc_is_open (ds));
   unset_cmd_algorithm ();
@@ -175,8 +160,9 @@ static enum cmd_result
 do_parse_command (struct lexer *lexer,
                  struct dataset *ds, enum cmd_state state)
 {
-  const struct command *command;
+  const struct command *command = NULL;
   enum cmd_result result;
+  bool opened = false;
 
   /* Read the command's first token. */
   prompt_set_style (PROMPT_FIRST);
@@ -203,53 +189,54 @@ do_parse_command (struct lexer *lexer,
       result = CMD_FAILURE;
       goto finish;
     }
-  else if (command->function == NULL)
+  text_item_submit (text_item_create (TEXT_ITEM_COMMAND_OPEN, command->name));
+  opened = true;
+
+  if (command->function == NULL)
     {
       msg (SE, _("%s is not yet implemented."), command->name);
       result = CMD_NOT_IMPLEMENTED;
-      goto finish;
     }
   else if ((command->flags & F_TESTING) && !settings_get_testing_mode ())
     {
       msg (SE, _("%s may be used only in testing mode."), command->name);
       result = CMD_FAILURE;
-      goto finish;
     }
   else if ((command->flags & F_ENHANCED) && settings_get_syntax () != ENHANCED)
     {
       msg (SE, _("%s may be used only in enhanced syntax mode."),
            command->name);
       result = CMD_FAILURE;
-      goto finish;
     }
   else if (!in_correct_state (command, state))
     {
       report_state_mismatch (command, state);
       result = CMD_FAILURE;
-      goto finish;
     }
-
-  /* Execute command. */
-  msg_set_command_name (command->name);
-  tab_set_command_name (command->name);
-  result = command->function (lexer, ds);
-  tab_set_command_name (NULL);
-  msg_set_command_name (NULL);
+  else
+    {
+      /* Execute command. */
+      result = command->function (lexer, ds);
+    }
 
   assert (cmd_result_is_valid (result));
 
  finish:
-  if ( cmd_result_is_failure (result))
+  if (cmd_result_is_failure (result))
     {
-      const struct source_stream *cs = lex_get_source_stream (lexer);
-
-      if ( source_stream_current_error_mode (cs) == ERRMODE_STOP )
+      lex_discard_rest_of_command (lexer);
+      if (source_stream_current_error_mode (
+            lex_get_source_stream (lexer)) == ERRMODE_STOP )
        {
          msg (MW, _("Error encountered while ERROR=STOP is effective."));
          result = CMD_CASCADING_FAILURE;
        }
     }
 
+  if (opened)
+    text_item_submit (text_item_create (TEXT_ITEM_COMMAND_CLOSE,
+                                        command->name));
+
   return result;
 }
 
@@ -689,9 +676,9 @@ report_state_mismatch (const struct command *command, enum cmd_state state)
         }
     }
   else if (state == CMD_STATE_INPUT_PROGRAM)
-    msg (SE, _("%s is not allowed inside INPUT PROGRAM."), command->name);
+    msg (SE, _("%s is not allowed inside %s."), command->name, "INPUT PROGRAM" );
   else if (state == CMD_STATE_FILE_TYPE)
-    msg (SE, _("%s is not allowed inside FILE TYPE."), command->name);
+    msg (SE, _("%s is not allowed inside %s."), command->name, "FILE TYPE");
 
   return false;
 }
@@ -790,124 +777,6 @@ cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
   return CMD_SUCCESS;
 }
 
-#if HAVE_FORK && HAVE_EXECL
-/* Spawn an interactive shell process. */
-static bool
-shell (void)
-{
-  int pid;
-
-  pid = fork ();
-  switch (pid)
-    {
-    case 0:
-      {
-       const char *shell_fn;
-       char *shell_process;
-
-       {
-         int i;
-
-         for (i = 3; i < 20; i++)
-           close (i);
-       }
-
-       shell_fn = getenv ("SHELL");
-       if (shell_fn == NULL)
-         shell_fn = "/bin/sh";
-
-       {
-         const char *cp = strrchr (shell_fn, '/');
-         cp = cp ? &cp[1] : shell_fn;
-         shell_process = xmalloca (strlen (cp) + 8);
-         strcpy (shell_process, "-");
-         strcat (shell_process, cp);
-         if (strcmp (cp, "sh"))
-           shell_process[0] = '+';
-       }
-
-       execl (shell_fn, shell_process, NULL);
-
-       _exit (1);
-      }
-
-    case -1:
-      msg (SE, _("Couldn't fork: %s."), strerror (errno));
-      return false;
-
-    default:
-      assert (pid > 0);
-      while (wait (NULL) != pid)
-       ;
-      return true;
-    }
-}
-#else /* !(HAVE_FORK && HAVE_EXECL) */
-/* Don't know how to spawn an interactive shell. */
-static bool
-shell (void)
-{
-  msg (SE, _("Interactive shell not supported on this platform."));
-  return false;
-}
-#endif
-
-/* Executes the specified COMMAND in a subshell.  Returns true if
-   successful, false otherwise. */
-static bool
-run_command (const char *command)
-{
-  if (system (NULL) == 0)
-    {
-      msg (SE, _("Command shell not supported on this platform."));
-      return false;
-    }
-
-  /* Execute the command. */
-  if (system (command) == -1)
-    msg (SE, _("Error executing command: %s."), strerror (errno));
-
-  return true;
-}
-
-/* Parses, performs the HOST command. */
-int
-cmd_host (struct lexer *lexer, struct dataset *ds UNUSED)
-{
-  int look_ahead;
-
-  if (settings_get_safer_mode ())
-    {
-      msg (SE, _("This command not allowed when the SAFER option is set."));
-      return CMD_FAILURE;
-    }
-
-  look_ahead = lex_look_ahead (lexer);
-  if (look_ahead == '.')
-    {
-      lex_get (lexer);
-      return shell () ? CMD_SUCCESS : CMD_FAILURE;
-    }
-  else if (look_ahead == '\'' || look_ahead == '"')
-    {
-      bool ok;
-
-      lex_get (lexer);
-      if (!lex_force_string (lexer))
-        NOT_REACHED ();
-      ok = run_command (ds_cstr (lex_tokstr (lexer)));
-
-      lex_get (lexer);
-      return ok ? lex_end_of_command (lexer) : CMD_FAILURE;
-    }
-  else
-    {
-      bool ok = run_command (lex_rest_of_line (lexer));
-      lex_discard_line (lexer);
-      return ok ? CMD_SUCCESS : CMD_FAILURE;
-    }
-}
-
 /* Parses, performs the NEW FILE command. */
 int
 cmd_new_file (struct lexer *lexer, struct dataset *ds)