pxd: initial work
[pspp] / src / processor / processor.c
diff --git a/src/processor/processor.c b/src/processor/processor.c
new file mode 100644 (file)
index 0000000..6b7c6c7
--- /dev/null
@@ -0,0 +1,188 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2012 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
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_FPU_CONTROL_H
+#include <fpu_control.h>
+#endif
+#if HAVE_FENV_H
+#include <fenv.h>
+#endif
+#if HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
+#include <unistd.h>
+
+#include "data/dataset.h"
+#include "data/dictionary.h"
+#include "data/file-handle-def.h"
+#include "data/file-name.h"
+#include "data/session.h"
+#include "data/settings.h"
+#include "data/variable.h"
+#include "gsl/gsl_errno.h"
+#include "language/command.h"
+#include "language/lexer/lexer.h"
+#include "language/lexer/include-path.h"
+#include "libpspp/argv-parser.h"
+#include "libpspp/compiler.h"
+#include "libpspp/i18n.h"
+#include "libpspp/message.h"
+#include "libpspp/version.h"
+#include "math/random.h"
+#include "output/driver.h"
+#include "output/message-item.h"
+#include "ui/source-init-opts.h"
+
+#include "gl/fatal-signal.h"
+#include "gl/progname.h"
+#include "gl/relocatable.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+static void bug_handler(int sig);
+static void fpu_init (void);
+
+/* Program entry point. */
+int
+main (int argc, char **argv)
+{
+  char s[128];
+
+  set_program_name (argv[0]);
+
+  signal (SIGABRT, bug_handler);
+  signal (SIGSEGV, bug_handler);
+  signal (SIGFPE, bug_handler);
+
+  i18n_init ();
+  fpu_init ();
+  gsl_set_error_handler_off ();
+
+  fh_init ();
+  settings_init ();
+  random_init ();
+
+  //msg_set_handler (output_msg, lexer);
+
+  while (fgets (s, sizeof s, stdin))
+    {
+      struct pspp_proc_request *request;
+      struct pxd_object *object;
+      struct pxd_id id;
+      int n = -1;
+
+      if (sscanf (s, PXD_ID_FMT"%n", PXD_ID_SCAN_ARGS (&id), &n) <= 0 || n < 0)
+        {
+          printf ("bad input format\n");
+          fflush (stdout);
+          continue;
+        }
+
+      object = pxd_fetch (pxd, &id);
+      if (object == NULL)
+        {
+          printf (PXD_ID_FMT": object not found\n", PXD_ID_ARGS (&id));
+          fflush (stdout);
+          continue;
+        }
+
+      request = pspp_proc_request_load (object, pxd);
+      pxd_object_unref (object);
+      if (request == NULL)
+        {
+          printf (PXD_ID_FMT": bad request\n", PXD_ID_FMT (&id));
+          fflush (stdout);
+          continue;
+        }
+
+      reply = pspp_proc_request_execute (request);
+      if (reply == NULL)
+        {
+          printf (PXD_ID_FMT": could not execute request\n", PXD_ID_FMT (&id));
+          fflush (stdout);
+          continue;
+        }
+
+      object = pspp_proc_reply_save (reply, pxd);
+      pspp_proc_reply_destroy (reply);
+      if (object == NULL)
+        {
+          printf (PXD_ID_FMT": could not save reply\n", PXD_ID_FMT (&id));
+          fflush (stdout);
+          continue;
+        }
+
+      printf (PXD_ID_FMT"\n", PXD_ID_FMT (pxd_object_id (object)));
+      fflush (stdout);
+      pxd_object_unref (object);
+
+      /* XXX what keeps the reply from getting garbage collected? */
+    }
+
+  random_done ();
+  settings_done ();
+  fh_done ();
+  lex_destroy (lexer);
+  output_close ();
+  i18n_done ();
+}
+\f
+static void
+fpu_init (void)
+{
+#if HAVE_FEHOLDEXCEPT
+  fenv_t foo;
+  feholdexcept (&foo);
+#elif HAVE___SETFPUCW && defined(_FPU_IEEE)
+  __setfpucw (_FPU_IEEE);
+#elif HAVE_FPSETMASK
+  fpsetmask (0);
+#endif
+}
+
+/* If a segfault happens, issue a message to that effect and halt */
+static void
+bug_handler(int sig)
+{
+  /* Reset SIG to its default handling so that if it happens again we won't
+     recurse. */
+  signal (sig, SIG_DFL);
+
+  switch (sig)
+    {
+    case SIGABRT:
+      request_bug_report("Assertion Failure/Abort");
+      break;
+    case SIGFPE:
+      request_bug_report("Floating Point Exception");
+      break;
+    case SIGSEGV:
+      request_bug_report("Segmentation Violation");
+      break;
+    default:
+      request_bug_report("Unknown");
+      break;
+    }
+
+  /* Re-raise the signal so that we terminate with the correct status. */
+  raise (sig);
+}