summaryrefslogtreecommitdiff
path: root/gs/psi/gs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/psi/gs.c')
-rw-r--r--gs/psi/gs.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/gs/psi/gs.c b/gs/psi/gs.c
new file mode 100644
index 000000000..c08706749
--- /dev/null
+++ b/gs/psi/gs.c
@@ -0,0 +1,131 @@
+/* Copyright (C) 2001-2006 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id$ */
+/* 'main' program for Ghostscript */
+#include "ghost.h"
+#include "imain.h"
+#include "imainarg.h"
+#include "iapi.h"
+#include "iminst.h"
+#include "ierrors.h"
+#include "gsmalloc.h"
+
+#ifdef __GNUC__
+# if (__GNUC__ == 2 && __GNUC_MINOR__ == 96)
+# define NEED_COMMIT_STACK 1
+# endif
+#endif
+
+
+/* Define an optional array of strings for testing. */
+/*#define RUN_STRINGS */
+#ifdef RUN_STRINGS
+static const char *run_strings[] =
+{
+ "2 vmreclaim /SAVE save def 2 vmreclaim",
+ "(saved\n) print flush",
+ "SAVE restore (restored\n) print flush 2 vmreclaim",
+ "(done\n) print flush quit",
+ 0
+};
+
+#endif
+
+#ifdef NEED_COMMIT_STACK
+/*
+ * It is well known that GCC 2.96 for x86 sometimes forgets to adjust $esp
+ * and leaves automatic variables at small distance below the stack pointer.
+ * Apparently, when the access to the automatic variable causes a page fault
+ * Linux sends a SEGV signal if the access happens below the stack pointer.
+ * Pre-loading the stack pages resolves the problem.
+ */
+static void
+commit_stack_pages( void )
+{
+ char buf[65536]; /* In most cases GS lives in 64K stack */
+ int i;
+ for ( i = 0; i < sizeof(buf) - 1; i += 1024)
+ buf[i] = 0;
+}
+#endif
+
+
+int
+main(int argc, char *argv[])
+{
+ int exit_status, code;
+ gs_main_instance *minst;
+ gs_memory_t *mem;
+
+#ifdef NEED_COMMIT_STACK /* hack for bug in gcc 2.96 */
+ commit_stack_pages();
+#endif
+ exit_status = 0;
+ mem = gs_malloc_init(NULL);
+ minst = gs_main_alloc_instance(mem);
+ code = gs_main_init_with_args(minst, argc, argv);
+
+#ifdef RUN_STRINGS
+ { /* Run a list of strings (for testing). */
+ const char **pstr = run_strings;
+
+ for (; *pstr; ++pstr) {
+ int exit_code;
+ ref error_object;
+ int code;
+
+ fprintf(stdout, "{%s} =>\n", *pstr);
+ fflush(stdout);
+ code = gs_main_run_string(minst, *pstr, 0,
+ &exit_code, &error_object);
+ zflush(osp);
+ fprintf(stdout, " => code = %d\n", code);
+ fflush(stdout);
+ if (code < 0) {
+ gs_to_exit(1);
+ return 1;
+ }
+ }
+ }
+#endif
+
+ if (code >= 0)
+ code = gs_main_run_start(minst);
+
+ exit_status = 0;
+ switch (code) {
+ case 0:
+ case e_Info:
+ case e_Quit:
+ break;
+ case e_Fatal:
+ exit_status = 1;
+ break;
+ default:
+ exit_status = 255;
+ }
+
+ gs_to_exit_with_code(minst->heap, exit_status, code);
+ gs_malloc_release(mem);
+
+ switch (exit_status) {
+ case 0:
+ exit_status = exit_OK;
+ break;
+ case 1:
+ exit_status = exit_FAILED;
+ break;
+ }
+ return exit_status;
+}