pxd: initial work
[pspp] / src / processor / processor.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2012 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include <signal.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #if HAVE_FPU_CONTROL_H
23 #include <fpu_control.h>
24 #endif
25 #if HAVE_FENV_H
26 #include <fenv.h>
27 #endif
28 #if HAVE_IEEEFP_H
29 #include <ieeefp.h>
30 #endif
31 #include <unistd.h>
32
33 #include "data/dataset.h"
34 #include "data/dictionary.h"
35 #include "data/file-handle-def.h"
36 #include "data/file-name.h"
37 #include "data/session.h"
38 #include "data/settings.h"
39 #include "data/variable.h"
40 #include "gsl/gsl_errno.h"
41 #include "language/command.h"
42 #include "language/lexer/lexer.h"
43 #include "language/lexer/include-path.h"
44 #include "libpspp/argv-parser.h"
45 #include "libpspp/compiler.h"
46 #include "libpspp/i18n.h"
47 #include "libpspp/message.h"
48 #include "libpspp/version.h"
49 #include "math/random.h"
50 #include "output/driver.h"
51 #include "output/message-item.h"
52 #include "ui/source-init-opts.h"
53
54 #include "gl/fatal-signal.h"
55 #include "gl/progname.h"
56 #include "gl/relocatable.h"
57
58 #include "gettext.h"
59 #define _(msgid) gettext (msgid)
60
61 static void bug_handler(int sig);
62 static void fpu_init (void);
63
64 /* Program entry point. */
65 int
66 main (int argc, char **argv)
67 {
68   char s[128];
69
70   set_program_name (argv[0]);
71
72   signal (SIGABRT, bug_handler);
73   signal (SIGSEGV, bug_handler);
74   signal (SIGFPE, bug_handler);
75
76   i18n_init ();
77   fpu_init ();
78   gsl_set_error_handler_off ();
79
80   fh_init ();
81   settings_init ();
82   random_init ();
83
84   //msg_set_handler (output_msg, lexer);
85
86   while (fgets (s, sizeof s, stdin))
87     {
88       struct pspp_proc_request *request;
89       struct pxd_object *object;
90       struct pxd_id id;
91       int n = -1;
92
93       if (sscanf (s, PXD_ID_FMT"%n", PXD_ID_SCAN_ARGS (&id), &n) <= 0 || n < 0)
94         {
95           printf ("bad input format\n");
96           fflush (stdout);
97           continue;
98         }
99
100       object = pxd_fetch (pxd, &id);
101       if (object == NULL)
102         {
103           printf (PXD_ID_FMT": object not found\n", PXD_ID_ARGS (&id));
104           fflush (stdout);
105           continue;
106         }
107
108       request = pspp_proc_request_load (object, pxd);
109       pxd_object_unref (object);
110       if (request == NULL)
111         {
112           printf (PXD_ID_FMT": bad request\n", PXD_ID_FMT (&id));
113           fflush (stdout);
114           continue;
115         }
116
117       reply = pspp_proc_request_execute (request);
118       if (reply == NULL)
119         {
120           printf (PXD_ID_FMT": could not execute request\n", PXD_ID_FMT (&id));
121           fflush (stdout);
122           continue;
123         }
124
125       object = pspp_proc_reply_save (reply, pxd);
126       pspp_proc_reply_destroy (reply);
127       if (object == NULL)
128         {
129           printf (PXD_ID_FMT": could not save reply\n", PXD_ID_FMT (&id));
130           fflush (stdout);
131           continue;
132         }
133
134       printf (PXD_ID_FMT"\n", PXD_ID_FMT (pxd_object_id (object)));
135       fflush (stdout);
136       pxd_object_unref (object);
137
138       /* XXX what keeps the reply from getting garbage collected? */
139     }
140
141   random_done ();
142   settings_done ();
143   fh_done ();
144   lex_destroy (lexer);
145   output_close ();
146   i18n_done ();
147 }
148 \f
149 static void
150 fpu_init (void)
151 {
152 #if HAVE_FEHOLDEXCEPT
153   fenv_t foo;
154   feholdexcept (&foo);
155 #elif HAVE___SETFPUCW && defined(_FPU_IEEE)
156   __setfpucw (_FPU_IEEE);
157 #elif HAVE_FPSETMASK
158   fpsetmask (0);
159 #endif
160 }
161
162 /* If a segfault happens, issue a message to that effect and halt */
163 static void
164 bug_handler(int sig)
165 {
166   /* Reset SIG to its default handling so that if it happens again we won't
167      recurse. */
168   signal (sig, SIG_DFL);
169
170   switch (sig)
171     {
172     case SIGABRT:
173       request_bug_report("Assertion Failure/Abort");
174       break;
175     case SIGFPE:
176       request_bug_report("Floating Point Exception");
177       break;
178     case SIGSEGV:
179       request_bug_report("Segmentation Violation");
180       break;
181     default:
182       request_bug_report("Unknown");
183       break;
184     }
185
186   /* Re-raise the signal so that we terminate with the correct status. */
187   raise (sig);
188 }