You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
-#include <stdio.h>
-#include <gsl/gsl_errno.h>
#include "main.h"
+#include <gsl/gsl_errno.h>
+#include <signal.h>
+#include <stdio.h>
#include "cmdline.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
-#include "getline.h"
+#include "file-handle-def.h"
+#include "filename.h"
+#include "getl.h"
#include "glob.h"
#include "lexer.h"
#include "output.h"
-#include <signal.h>
+#include "progname.h"
+#include "random.h"
+#include "readln.h"
+#include "settings.h"
+#include "var.h"
+#include "version.h"
+
+#if HAVE_FPU_CONTROL_H
+#include <fpu_control.h>
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#if HAVE_FENV_H
+#include <fenv.h>
+#endif
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
#include <stdlib.h>
#include "debug-print.h"
-static void parse_script (void) NO_RETURN;
+static void i18n_init (void);
+static void fpu_init (void);
static void handle_error (int code);
static int execute_command (void);
-/* argv[0] with stripped leading directories. */
-char *pgmname;
-
/* Whether FINISH. has been executed. */
int finished;
-/* The current date in the form DD MMM YYYY. */
-char curdate[12];
-
-
/* If a segfault happens, issue a message to that effect and halt */
void bug_handler(int sig);
+/* Handle quit/term/int signals */
+void interrupt_handler(int sig);
+
/* Whether we're dropping down to interactive mode immediately because
we hit end-of-file unexpectedly (or whatever). */
int start_interactive;
-/* Initialise error handling on the gsl library */
-static void
-err_handler_gsl (const char *reason, const char *file,
- int line, int gsl_errno UNUSED)
-{
- msg(FE, _("gsl error at %s:%d; reason: \"%s\""), file,line,reason);
-}
-
/* Program entry point. */
int
main (int argc, char **argv)
{
signal (SIGSEGV, bug_handler);
+ signal (SIGFPE, bug_handler);
+ signal (SIGINT, interrupt_handler);
- gsl_set_error_handler(err_handler_gsl);
+ set_program_name ("pspp");
+ i18n_init ();
+ fpu_init ();
+ gsl_set_error_handler_off ();
- /* Initialization. */
- if (!outp_init ())
- err_hcf (0);
- init_glob (argc, argv);
- parse_command_line (argc, argv);
- if (!outp_read_devices ())
- msg (FE, _("Error initializing output drivers."));
+ outp_init ();
+ fn_init ();
+ fh_init ();
+ getl_initialize ();
+ readln_initialize ();
+ settings_init ();
+ random_init ();
- lex_init ();
+ default_dict = dict_create ();
- /* Execution. */
- parse_script ();
+ parse_command_line (argc, argv);
+ outp_read_devices ();
- /* Should never be reached */
- return (-1);
-}
+ lex_init ();
-/* Parses the entire script. */
-static void
-parse_script (void)
-{
while (!finished)
{
err_check_count ();
handle_error (execute_command ());
}
- err_hcf (err_error_count==0);
+ terminate (err_error_count == 0);
+ abort ();
+}
+
+/* Terminate PSPP. SUCCESS should be true to exit successfully,
+ false to exit as a failure. */
+void
+terminate (bool success)
+{
+ static bool terminating = false;
+ if (terminating)
+ return;
+ terminating = true;
+
+ err_done ();
+ outp_done ();
+
+ cancel_transformations ();
+ dict_destroy (default_dict);
+
+ random_done ();
+ settings_done ();
+ fh_done ();
+ lex_done ();
+ getl_uninitialize ();
+
+ exit (success ? EXIT_SUCCESS : EXIT_FAILURE);
}
/* Parse and execute a command, returning its return code. */
static int
execute_command (void)
{
+ int result;
+
/* Read the command's first token.
We may hit end of file.
If so, give the line reader a chance to proceed to the next file.
if (token != T_STOP)
break;
- if (!getl_perform_delayed_reset ())
- err_hcf (err_error_count==0);
+ /* Sets the options flag of the current script to 0, thus allowing it
+ to be read in. Returns nonzero if this action was taken, zero
+ otherwise. */
+ if (getl_head && getl_head->separate)
+ {
+ getl_head->separate = 0;
+ discard_variables ();
+ lex_reset_eof ();
+ }
+ else
+ terminate (err_error_count == 0);
}
/* Parse the command. */
getl_prompt = GETL_PRPT_CONTINUATION;
- return cmd_parse ();
+ result = cmd_parse ();
+
+ /* Unset the /ALGORITHM subcommand if it was used */
+ unset_cmd_algorithm ();
+
+ /* Clear any auxiliary data from the dictionary. */
+ dict_clear_aux (default_dict);
+
+ return result;
}
/* Print an error message corresponding to the command return code
assert (0);
}
- if (getl_reading_script)
+ if (getl_reading_script())
{
err_break ();
while (token != T_STOP && token != '.')
lex_discard_line ();
}
}
+\f
+static void
+i18n_init (void)
+{
+#if ENABLE_NLS
+#if HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ setlocale (LC_MONETARY, "");
+ bindtextdomain (PACKAGE, locale_dir);
+ textdomain (PACKAGE);
+#endif /* ENABLE_NLS */
+}
-
+static void
+fpu_init (void)
+{
+#if HAVE_FEHOLDEXCEPT
+ fenv_t foo;
+ feholdexcept (&foo);
+#elif HAVE___SETFPUCW && defined(_FPU_IEEE)
+ __setfpucw (_FPU_IEEE);
+#endif
+}
/* If a segfault happens, issue a message to that effect and halt */
void
-bug_handler(int sig UNUSED)
+bug_handler(int sig)
+{
+ switch (sig)
+ {
+ case SIGFPE:
+ request_bug_report_and_abort("Floating Point Exception");
+ break;
+ case SIGSEGV:
+ request_bug_report_and_abort("Segmentation Violation");
+ break;
+ default:
+ request_bug_report_and_abort("");
+ break;
+ }
+}
+
+
+void
+interrupt_handler(int sig UNUSED)
{
- request_bug_report_and_abort("Segmentation Violation");
+ terminate (false);
}