--- /dev/null
+/* 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);
+}