summaryrefslogtreecommitdiff
path: root/gs/src/imain.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/imain.c')
-rw-r--r--gs/src/imain.c252
1 files changed, 92 insertions, 160 deletions
diff --git a/gs/src/imain.c b/gs/src/imain.c
index efa4ce113..227ec3755 100644
--- a/gs/src/imain.c
+++ b/gs/src/imain.c
@@ -18,16 +18,6 @@
/* Common support for interpreter front ends */
#include "memory_.h"
#include "string_.h"
-/* Capture stdin/out/err before gs.h redefines them. */
-#include <stdio.h>
-#include <stdlib.h>
-private void
-set_stdfiles(FILE * stdfiles[3])
-{
- stdfiles[0] = stdin;
- stdfiles[1] = stdout;
- stdfiles[2] = stderr;
-}
#include "ghost.h"
#include "gp.h"
#include "gscdefs.h" /* for gs_init_file */
@@ -58,27 +48,43 @@ set_stdfiles(FILE * stdfiles[3])
#include "isave.h" /* for prototypes */
#include "interp.h"
#include "ivmspace.h"
-#include "idisp.h" /* for setting display device callback */
#include "iplugin.h"
/* ------ Exported data ------ */
-/* Define the default instance of the interpreter. */
-/* Currently, this is the *only possible* instance, because most of */
-/* the places that need to take an explicit instance argument don't. */
-private gs_main_instance the_gs_main_instance;
-gs_main_instance *
-gs_main_instance_default(void)
+/** using backpointers retrieve minst from any memory pointer
+ *
+ */
+gs_main_instance*
+get_minst_from_memory(const gs_memory_t *mem)
{
- /* Determine whether the instance has been initialized. */
- if (the_gs_main_instance.memory_chunk_size == 0)
- the_gs_main_instance = gs_main_instance_init_values;
- return &the_gs_main_instance;
+#ifdef PSI_INCLUDED
+ extern gs_main_instance *ps_impl_get_minst( const gs_memory_t *mem );
+ return ps_impl_get_minst(mem);
+#else
+ return (gs_main_instance*)mem->gs_lib_ctx->top_of_system;
+#endif
}
-/* Define the interpreter's name table. We'll move it somewhere better */
-/* eventually.... */
-name_table *the_gs_name_table;
+/** construct main instance caller needs to retain */
+gs_main_instance *
+gs_main_alloc_instance(gs_memory_t *mem)
+{
+ gs_main_instance *minst = 0;
+ if (mem) {
+ minst = (gs_main_instance *) gs_alloc_bytes_immovable(mem,
+ sizeof(gs_main_instance),
+ "init_main_instance");
+ memcpy(minst, &gs_main_instance_init_values, sizeof(gs_main_instance_init_values));
+ minst->heap = mem;
+
+# ifndef PSI_INCLUDED
+ mem->gs_lib_ctx->top_of_system = minst;
+ /* else top of system is pl_universe */
+# endif
+ }
+ return minst;
+}
/* ------ Forward references ------ */
@@ -88,45 +94,38 @@ private void print_resource_usage(const gs_main_instance *,
/* ------ Initialization ------ */
-/* Save the real stdio files. */
-void
-gs_get_real_stdio(FILE * stdfiles[3])
-{
- set_stdfiles(stdfiles);
-}
-
/* Initialization to be done before anything else. */
int
gs_main_init0(gs_main_instance * minst, FILE * in, FILE * out, FILE * err,
int max_lib_paths)
{
- gs_memory_t *heap;
ref *paths;
- /* Set our versions of stdin/out/err. */
- gs_stdin = minst->fstdin = in;
- gs_stdout = minst->fstdout = out;
- gs_stderr = minst->fstderr = err;
/* Do platform-dependent initialization. */
/* We have to do this as the very first thing, */
/* because it detects attempts to run 80N86 executables (N>0) */
/* on incompatible processors. */
gp_init();
+
+ /* Initialize the imager. */
+# ifndef PSI_INCLUDED
+ /* Reset debugging flags */
+ memset(gs_debug, 0, 128);
+ gs_log_errors = 0; /* gs_debug['#'] = 0 */
+# else
+ /* plmain settings remain in effect */
+# endif
gp_get_usertime(minst->base_time);
- /* Initialize the imager. */
- heap = gs_lib_init0(gs_stdout);
- if (heap == 0)
- return_error(e_VMerror);
- minst->heap = heap;
+
/* Initialize the file search paths. */
- paths = (ref *) gs_alloc_byte_array(heap, max_lib_paths, sizeof(ref),
+ paths = (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref),
"lib_path array");
if (paths == 0) {
- gs_lib_finit(1, e_VMerror);
+ gs_lib_finit(1, e_VMerror, minst->heap);
return_error(e_VMerror);
}
make_array(&minst->lib_path.container, avm_foreign, max_lib_paths,
- (ref *) gs_alloc_byte_array(heap, max_lib_paths, sizeof(ref),
+ (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref),
"lib_path array"));
make_array(&minst->lib_path.list, avm_foreign | a_readonly, 0,
minst->lib_path.container.value.refs);
@@ -145,7 +144,7 @@ gs_main_init1(gs_main_instance * minst)
if (minst->init_done < 1) {
gs_dual_memory_t idmem;
int code =
- ialloc_init(&idmem, (gs_raw_memory_t *)&gs_memory_default,
+ ialloc_init(&idmem, minst->heap,
minst->memory_chunk_size, gs_have_level2());
if (code < 0)
@@ -161,9 +160,9 @@ gs_main_init1(gs_main_instance * minst)
if (nt == 0)
return_error(e_VMerror);
- the_gs_name_table = nt;
+ mem->gs_lib_ctx->gs_name_table = nt;
code = gs_register_struct_root(mem, NULL,
- (void **)&the_gs_name_table,
+ (void **)&mem->gs_lib_ctx->gs_name_table,
"the_gs_name_table");
if (code < 0)
return code;
@@ -207,6 +206,9 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
ref refpop;
int code;
+ /* set interpreter pointer to lib_path */
+ minst->i_ctx_p->lib_path = &minst->lib_path;
+
code = gs_interpret(&minst->i_ctx_p, pref,
user_errors, pexit_code, perror_object);
while ((code == e_NeedStdin) || (code == e_NeedStdout) ||
@@ -226,7 +228,7 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
int count = esp[0].tas.rsize;
int rcode = 0;
if (str != NULL)
- rcode = gs_main_outwrite(minst, str, count);
+ rcode = outwrite(imemory, str, count);
if (rcode < 0)
return_error(e_ioerror);
}
@@ -248,7 +250,7 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
int count = esp[0].tas.rsize;
int rcode = 0;
if (str != NULL)
- rcode = gs_main_errwrite(minst, str, count);
+ rcode = errwrite(str, count);
if (rcode < 0)
return_error(e_ioerror);
}
@@ -266,12 +268,14 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
* esp[-1] = file, stdin stream
* We read from stdin then pop these 2 items.
*/
- if (minst->stdin_fn)
- count = (*minst->stdin_fn)(minst->caller_handle,
- minst->stdin_buf, count);
+ if (minst->heap->gs_lib_ctx->stdin_fn)
+ count = (*minst->heap->gs_lib_ctx->stdin_fn)
+ (minst->heap->gs_lib_ctx->caller_handle,
+ minst->stdin_buf, count);
else
count = gp_stdin_read(minst->stdin_buf, count,
- minst->stdin_is_interactive, minst->fstdin);
+ minst->heap->gs_lib_ctx->stdin_is_interactive,
+ minst->heap->gs_lib_ctx->fstdin);
if (count < 0)
return_error(e_ioerror);
@@ -348,8 +352,12 @@ gs_main_init2(gs_main_instance * minst)
return code;
minst->init_done = 2;
i_ctx_p = minst->i_ctx_p; /* init file may change it */
+ /* NB this is to be done with device parameters
+ * both minst->display and display_set_callback() are going away
+ */
if (minst->display)
code = display_set_callback(minst, minst->display);
+
if (code < 0)
return code;
}
@@ -465,10 +473,11 @@ gs_main_lib_open(gs_main_instance * minst, const char *file_name, ref * pfile)
byte fn[maxfn];
uint len;
- return lib_file_open(NULL /* Don't check permissions here, because permlist
- isn't ready running init files. */
- , file_name, strlen(file_name), fn, maxfn,
- &len, pfile, imemory);
+ return lib_file_open( &minst->lib_path,
+ NULL /* Don't check permissions here, because permlist
+ isn't ready running init files. */
+ , file_name, strlen(file_name), fn, maxfn,
+ &len, pfile, imemory);
}
/* Open and execute a file. */
@@ -728,7 +737,7 @@ gs_pop_string(gs_main_instance * minst, gs_string * result)
return code;
switch (r_type(&vref)) {
case t_name:
- name_string_ref(&vref, &vref);
+ name_string_ref(minst->heap, &vref, &vref);
code = 1;
goto rstr;
case t_string:
@@ -771,7 +780,7 @@ private char *gs_main_tempnames(gs_main_instance *minst)
/* get lengths of temporary filenames */
idict = dict_first(tempfiles);
while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) {
- if (obj_string_data(&keyval[0], &data, &size) >= 0)
+ if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0)
len += size + 1;
}
if (len != 0)
@@ -782,7 +791,7 @@ private char *gs_main_tempnames(gs_main_instance *minst)
idict = dict_first(tempfiles);
i = 0;
while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) {
- if (obj_string_data(&keyval[0], &data, &size) >= 0) {
+ if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0) {
memcpy(tempnames+i, (const char *)data, size);
i+= size;
tempnames[i++] = '\0';
@@ -801,6 +810,10 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code)
int exit_code;
ref error_object;
char *tempnames;
+
+ /* NB: need to free gs_name_table
+ */
+
/*
* Previous versions of this code closed the devices in the
* device list here. Since these devices are now prototypes,
@@ -851,19 +864,20 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code)
/* Do the equivalent of a restore "past the bottom". */
/* This will release all memory, close all open files, etc. */
if (minst->init_done >= 1) {
- gs_raw_memory_t *mem_raw = i_ctx_p->memory.current->parent;
+ gs_memory_t *mem_raw = i_ctx_p->memory.current->non_gc_memory;
i_plugin_holder *h = i_ctx_p->plugin_list;
alloc_restore_all(idmemory);
i_plugin_finit(mem_raw, h);
}
/* clean up redirected stdout */
- if (minst->fstdout2 && (minst->fstdout2 != minst->fstdout)
- && (minst->fstdout2 != minst->fstderr)) {
- fclose(minst->fstdout2);
- minst->fstdout2 = (FILE *)NULL;
+ if (minst->heap->gs_lib_ctx->fstdout2
+ && (minst->heap->gs_lib_ctx->fstdout2 != minst->heap->gs_lib_ctx->fstdout)
+ && (minst->heap->gs_lib_ctx->fstdout2 != minst->heap->gs_lib_ctx->fstderr)) {
+ fclose(minst->heap->gs_lib_ctx->fstdout2);
+ minst->heap->gs_lib_ctx->fstdout2 = (FILE *)NULL;
}
- minst->stdout_is_redirected = 0;
- minst->stdout_to_stderr = 0;
+ minst->heap->gs_lib_ctx->stdout_is_redirected = 0;
+ minst->heap->gs_lib_ctx->stdout_to_stderr = 0;
/* remove any temporary files, after ghostscript has closed files */
if (tempnames) {
char *p = tempnames;
@@ -873,23 +887,23 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code)
}
free(tempnames);
}
- gs_lib_finit(exit_status, code);
+ gs_lib_finit(exit_status, code, minst->heap);
return exit_status;
}
int
-gs_to_exit_with_code(int exit_status, int code)
+gs_to_exit_with_code(const gs_memory_t *mem, int exit_status, int code)
{
- return gs_finit(exit_status, code);
+ return gs_main_finit(get_minst_from_memory(mem), exit_status, code);
}
int
-gs_to_exit(int exit_status)
+gs_to_exit(const gs_memory_t *mem, int exit_status)
{
- return gs_to_exit_with_code(exit_status, 0);
+ return gs_to_exit_with_code(mem, exit_status, 0);
}
void
-gs_abort(void)
+gs_abort(const gs_memory_t *mem)
{
- gs_to_exit(1);
+ gs_to_exit(mem, 1);
/* it's fatal calling OS independent exit() */
gp_do_exit(1);
}
@@ -943,93 +957,11 @@ gs_main_dump_stack(gs_main_instance *minst, int code, ref * perror_object)
dprintf1("\nUnexpected interpreter error %d.\n", code);
if (perror_object != 0) {
dputs("Error object: ");
- debug_print_ref(perror_object);
+ debug_print_ref(minst->heap, perror_object);
dputc('\n');
}
- debug_dump_stack(&o_stack, "Operand stack");
- debug_dump_stack(&e_stack, "Execution stack");
- debug_dump_stack(&d_stack, "Dictionary stack");
-}
-/* Backward compatibility */
-void
-gs_debug_dump_stack(int code, ref * perror_object)
-{
- gs_main_dump_stack(gs_main_instance_default(), code, perror_object);
-}
-
-
-/* Provide a single point for all "C" stdout and stderr.
- * Eventually these will always be referenced through an instance structure.
- * We don't know which instance is running (and currently only one
- * instance is possible) so use the default instance.
- */
-
-int
-gs_main_outwrite(gs_main_instance *minst, const char *str, int len)
-{
- int code;
- FILE *fout;
- if (len == 0)
- return 0;
- if (minst->stdout_is_redirected) {
- if (minst->stdout_to_stderr)
- return gs_main_errwrite(minst, str, len);
- fout = minst->fstdout2;
- }
- else if (minst->stdout_fn) {
- return (*minst->stdout_fn)(minst->caller_handle, str, len);
- }
- else {
- fout = minst->fstdout;
- }
- code = fwrite(str, 1, len, fout);
- fflush(fout);
- return code;
+ debug_dump_stack(minst->heap, &o_stack, "Operand stack");
+ debug_dump_stack(minst->heap, &e_stack, "Execution stack");
+ debug_dump_stack(minst->heap, &d_stack, "Dictionary stack");
}
-int
-gs_main_errwrite(gs_main_instance *minst, const char *str, int len)
-{
- int code;
- if (len == 0)
- return 0;
- if (minst->stderr_fn)
- return (*minst->stderr_fn)(minst->caller_handle, str, len);
- code = fwrite(str, 1, len, minst->fstderr);
- fflush(minst->fstderr);
- return code;
-}
-
-int outwrite(const char *str, int len)
-{
- return gs_main_outwrite(gs_main_instance_default(), str, len);
-}
-
-int errwrite(const char *str, int len)
-{
- return gs_main_errwrite(gs_main_instance_default(), str, len);
-}
-
-void outflush(void)
-{
- gs_main_instance * minst = gs_main_instance_default();
- if (minst->stdout_is_redirected) {
- if (minst->stdout_to_stderr) {
- if (!minst->stderr_fn)
- fflush(minst->fstderr);
- }
- else
- fflush(minst->fstdout2);
- }
- else if (!minst->stdout_fn)
- fflush(minst->fstdout);
-}
-
-void errflush(void)
-{
- gs_main_instance * minst = gs_main_instance_default();
- if (!minst->stderr_fn)
- fflush(minst->fstderr);
-}
-
-