8520 lines
288 KiB
Diff
8520 lines
288 KiB
Diff
diff -up ghostscript-9.00/psi/imainarg.c.scan_token ghostscript-9.00/psi/imainarg.c
|
|
--- ghostscript-9.00/psi/imainarg.c.scan_token 2010-05-04 19:47:12.000000000 +0100
|
|
+++ ghostscript-9.00/psi/imainarg.c 2011-01-14 17:16:12.596867462 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2007 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -16,13 +16,13 @@
|
|
#include "ctype_.h"
|
|
#include "memory_.h"
|
|
#include "string_.h"
|
|
-#include <stdlib.h> /* for qsort */
|
|
+#include <stdlib.h> /* for qsort */
|
|
|
|
#include "ghost.h"
|
|
#include "gp.h"
|
|
#include "gsargs.h"
|
|
#include "gscdefs.h"
|
|
-#include "gsmalloc.h" /* for gs_malloc_limit */
|
|
+#include "gsmalloc.h" /* for gs_malloc_limit */
|
|
#include "gsmdebug.h"
|
|
#include "gxdevice.h"
|
|
#include "gxdevmem.h"
|
|
@@ -31,9 +31,9 @@
|
|
#include "ierrors.h"
|
|
#include "estack.h"
|
|
#include "ialloc.h"
|
|
-#include "strimpl.h" /* for sfilter.h */
|
|
-#include "sfilter.h" /* for iscan.h */
|
|
-#include "ostack.h" /* must precede iscan.h */
|
|
+#include "strimpl.h" /* for sfilter.h */
|
|
+#include "sfilter.h" /* for iscan.h */
|
|
+#include "ostack.h" /* must precede iscan.h */
|
|
#include "iscan.h"
|
|
#include "iconf.h"
|
|
#include "imain.h"
|
|
@@ -42,7 +42,7 @@
|
|
#include "iminst.h"
|
|
#include "iname.h"
|
|
#include "store.h"
|
|
-#include "files.h" /* requires stream.h */
|
|
+#include "files.h" /* requires stream.h */
|
|
#include "interp.h"
|
|
#include "iutil.h"
|
|
#include "ivmspace.h"
|
|
@@ -86,8 +86,8 @@ static void esc_strcat(char *, const cha
|
|
static int runarg(gs_main_instance *, const char *, const char *, const char *, int);
|
|
static int run_string(gs_main_instance *, const char *, int);
|
|
static int run_finish(gs_main_instance *, int, int, ref *);
|
|
-static int try_stdout_redirect(gs_main_instance * minst,
|
|
- const char *command, const char *filename);
|
|
+static int try_stdout_redirect(gs_main_instance * minst,
|
|
+ const char *command, const char *filename);
|
|
|
|
/* Forward references for help printout */
|
|
static void print_help(gs_main_instance *);
|
|
@@ -106,8 +106,8 @@ static FILE *
|
|
gs_main_arg_fopen(const char *fname, void *vminst)
|
|
{
|
|
gs_main_set_lib_paths((gs_main_instance *) vminst);
|
|
- return lib_fopen(&((gs_main_instance *)vminst)->lib_path,
|
|
- ((gs_main_instance *)vminst)->heap, fname);
|
|
+ return lib_fopen(&((gs_main_instance *)vminst)->lib_path,
|
|
+ ((gs_main_instance *)vminst)->heap, fname);
|
|
}
|
|
static void
|
|
set_debug_flags(const char *arg, char *flags)
|
|
@@ -115,7 +115,7 @@ set_debug_flags(const char *arg, char *f
|
|
byte value = (*arg == '-' ? (++arg, 0) : 0xff);
|
|
|
|
while (*arg)
|
|
- flags[*arg++ & 127] = value;
|
|
+ flags[*arg++ & 127] = value;
|
|
}
|
|
|
|
int
|
|
@@ -126,10 +126,10 @@ gs_main_init_with_args(gs_main_instance
|
|
int code;
|
|
|
|
arg_init(&args, (const char **)argv, argc,
|
|
- gs_main_arg_fopen, (void *)minst);
|
|
+ gs_main_arg_fopen, (void *)minst);
|
|
code = gs_main_init0(minst, 0, 0, 0, GS_MAX_LIB_DIRS);
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
/* This first check is not needed on VMS since GS_LIB evaluates to the same
|
|
value as that returned by gs_lib_default_path. Also, since GS_LIB is
|
|
defined as a searchlist logical and getenv only returns the first entry
|
|
@@ -138,42 +138,42 @@ gs_main_init_with_args(gs_main_instance
|
|
*/
|
|
#ifndef __VMS
|
|
{
|
|
- int len = 0;
|
|
- int code = gp_getenv(GS_LIB, (char *)0, &len);
|
|
+ int len = 0;
|
|
+ int code = gp_getenv(GS_LIB, (char *)0, &len);
|
|
|
|
- if (code < 0) { /* key present, value doesn't fit */
|
|
- char *path = (char *)gs_alloc_bytes(minst->heap, len, "GS_LIB");
|
|
+ if (code < 0) { /* key present, value doesn't fit */
|
|
+ char *path = (char *)gs_alloc_bytes(minst->heap, len, "GS_LIB");
|
|
|
|
- gp_getenv(GS_LIB, path, &len); /* can't fail */
|
|
- minst->lib_path.env = path;
|
|
- }
|
|
+ gp_getenv(GS_LIB, path, &len); /* can't fail */
|
|
+ minst->lib_path.env = path;
|
|
+ }
|
|
}
|
|
#endif /* __VMS */
|
|
minst->lib_path.final = gs_lib_default_path;
|
|
code = gs_main_set_lib_paths(minst);
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
/* Prescan the command line for --help and --version. */
|
|
{
|
|
- int i;
|
|
- bool helping = false;
|
|
+ int i;
|
|
+ bool helping = false;
|
|
|
|
- for (i = 1; i < argc; ++i)
|
|
- if (!strcmp(argv[i], "--")) {
|
|
- /* A PostScript program will be interpreting all the */
|
|
- /* remaining switches, so stop scanning. */
|
|
- helping = false;
|
|
- break;
|
|
- } else if (!strcmp(argv[i], "--help")) {
|
|
- print_help(minst);
|
|
- helping = true;
|
|
- } else if (!strcmp(argv[i], "--version")) {
|
|
- print_version(minst);
|
|
- puts(minst->heap, ""); /* \n */
|
|
- helping = true;
|
|
- }
|
|
- if (helping)
|
|
- return e_Info;
|
|
+ for (i = 1; i < argc; ++i)
|
|
+ if (!strcmp(argv[i], "--")) {
|
|
+ /* A PostScript program will be interpreting all the */
|
|
+ /* remaining switches, so stop scanning. */
|
|
+ helping = false;
|
|
+ break;
|
|
+ } else if (!strcmp(argv[i], "--help")) {
|
|
+ print_help(minst);
|
|
+ helping = true;
|
|
+ } else if (!strcmp(argv[i], "--version")) {
|
|
+ print_version(minst);
|
|
+ puts(minst->heap, ""); /* \n */
|
|
+ helping = true;
|
|
+ }
|
|
+ if (helping)
|
|
+ return e_Info;
|
|
}
|
|
/* Execute files named in the command line, */
|
|
/* processing options along the way. */
|
|
@@ -182,58 +182,58 @@ gs_main_init_with_args(gs_main_instance
|
|
minst->run_start = true;
|
|
|
|
{
|
|
- int len = 0;
|
|
- int code = gp_getenv(GS_OPTIONS, (char *)0, &len);
|
|
+ int len = 0;
|
|
+ int code = gp_getenv(GS_OPTIONS, (char *)0, &len);
|
|
|
|
- if (code < 0) { /* key present, value doesn't fit */
|
|
- char *opts =
|
|
- (char *)gs_alloc_bytes(minst->heap, len, "GS_OPTIONS");
|
|
-
|
|
- gp_getenv(GS_OPTIONS, opts, &len); /* can't fail */
|
|
- if (arg_push_memory_string(&args, opts, false, minst->heap))
|
|
- return e_Fatal;
|
|
- }
|
|
+ if (code < 0) { /* key present, value doesn't fit */
|
|
+ char *opts =
|
|
+ (char *)gs_alloc_bytes(minst->heap, len, "GS_OPTIONS");
|
|
+
|
|
+ gp_getenv(GS_OPTIONS, opts, &len); /* can't fail */
|
|
+ if (arg_push_memory_string(&args, opts, false, minst->heap))
|
|
+ return e_Fatal;
|
|
+ }
|
|
}
|
|
while ((arg = arg_next(&args, &code)) != 0) {
|
|
- switch (*arg) {
|
|
- case '-':
|
|
- code = swproc(minst, arg, &args);
|
|
- if (code < 0)
|
|
- return code;
|
|
- if (code > 0)
|
|
- outprintf(minst->heap, "Unknown switch %s - ignoring\n", arg);
|
|
- if (gs_debug[':'] && arg[1] == 'Z') {
|
|
- int i;
|
|
-
|
|
- dprintf1("%% Init started, instance 0x%p, with args: ", minst);
|
|
- for (i=1; i<argc; i++)
|
|
- dprintf1("%s ", argv[i]);
|
|
- dprintf("\n");
|
|
- }
|
|
- break;
|
|
- default:
|
|
- code = argproc(minst, arg);
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
+ switch (*arg) {
|
|
+ case '-':
|
|
+ code = swproc(minst, arg, &args);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ if (code > 0)
|
|
+ outprintf(minst->heap, "Unknown switch %s - ignoring\n", arg);
|
|
+ if (gs_debug[':'] && arg[1] == 'Z') {
|
|
+ int i;
|
|
+
|
|
+ dprintf1("%% Init started, instance 0x%p, with args: ", minst);
|
|
+ for (i=1; i<argc; i++)
|
|
+ dprintf1("%s ", argv[i]);
|
|
+ dprintf("\n");
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ code = argproc(minst, arg);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
}
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
|
|
code = gs_main_init2(minst);
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
|
|
if (gs_debug[':']) {
|
|
- int i;
|
|
+ int i;
|
|
|
|
- dprintf1("%% Init done, instance 0x%p, with args: ", minst);
|
|
- for (i=1; i<argc; i++)
|
|
- dprintf1("%s ", argv[i]);
|
|
- dprintf("\n");
|
|
+ dprintf1("%% Init done, instance 0x%p, with args: ", minst);
|
|
+ for (i=1; i<argc; i++)
|
|
+ dprintf1("%s ", argv[i]);
|
|
+ dprintf("\n");
|
|
}
|
|
if (!minst->run_start)
|
|
- return e_Quit;
|
|
+ return e_Quit;
|
|
return code ;
|
|
}
|
|
|
|
@@ -259,417 +259,417 @@ swproc(gs_main_instance * minst, const c
|
|
i_initial_enter_name(minst->i_ctx_p, nstr, pvalue)
|
|
|
|
make_true(&vtrue);
|
|
- arg += 2; /* skip - and letter */
|
|
+ arg += 2; /* skip - and letter */
|
|
switch (sw) {
|
|
- default:
|
|
- return 1;
|
|
- case 0: /* read stdin as a file char-by-char */
|
|
- /* This is a ******HACK****** for Ghostview. */
|
|
- minst->heap->gs_lib_ctx->stdin_is_interactive = true;
|
|
- goto run_stdin;
|
|
- case '_': /* read stdin with normal buffering */
|
|
- minst->heap->gs_lib_ctx->stdin_is_interactive = false;
|
|
+ default:
|
|
+ return 1;
|
|
+ case 0: /* read stdin as a file char-by-char */
|
|
+ /* This is a ******HACK****** for Ghostview. */
|
|
+ minst->heap->gs_lib_ctx->stdin_is_interactive = true;
|
|
+ goto run_stdin;
|
|
+ case '_': /* read stdin with normal buffering */
|
|
+ minst->heap->gs_lib_ctx->stdin_is_interactive = false;
|
|
run_stdin:
|
|
- minst->run_start = false; /* don't run 'start' */
|
|
- /* Set NOPAUSE so showpage won't try to read from stdin. */
|
|
- code = swproc(minst, "-dNOPAUSE", pal);
|
|
- if (code)
|
|
- return code;
|
|
- code = gs_main_init2(minst); /* Finish initialization */
|
|
- if (code < 0)
|
|
- return code;
|
|
-
|
|
- code = run_string(minst, ".runstdin", runFlush);
|
|
- if (code < 0)
|
|
- return code;
|
|
- break;
|
|
- case '-': /* run with command line args */
|
|
- case '+':
|
|
- pal->expand_ats = false;
|
|
- case '@': /* ditto with @-expansion */
|
|
- {
|
|
- const char *psarg = arg_next(pal, &code);
|
|
-
|
|
- if (code < 0)
|
|
- return e_Fatal;
|
|
- if (psarg == 0) {
|
|
- outprintf(minst->heap, "Usage: gs ... -%c file.ps arg1 ... argn\n", sw);
|
|
- arg_finit(pal);
|
|
- return e_Fatal;
|
|
- }
|
|
- psarg = arg_copy(psarg, minst->heap);
|
|
- if (psarg == NULL)
|
|
- return e_Fatal;
|
|
- code = gs_main_init2(minst);
|
|
- if (code < 0)
|
|
- return code;
|
|
- code = run_string(minst, "userdict/ARGUMENTS[", 0);
|
|
- if (code < 0)
|
|
- return code;
|
|
- while ((arg = arg_next(pal, &code)) != 0) {
|
|
- char *fname = arg_copy(arg, minst->heap);
|
|
- if (fname == NULL)
|
|
- return e_Fatal;
|
|
- code = runarg(minst, "", fname, "", runInit);
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
- if (code < 0)
|
|
- return e_Fatal;
|
|
- runarg(minst, "]put", psarg, ".runfile", runInit | runFlush);
|
|
- return e_Quit;
|
|
- }
|
|
- case 'A': /* trace allocator */
|
|
- switch (*arg) {
|
|
- case 0:
|
|
- gs_alloc_debug = 1;
|
|
- break;
|
|
- case '-':
|
|
- gs_alloc_debug = 0;
|
|
- break;
|
|
- default:
|
|
- puts(minst->heap, "-A may only be followed by -");
|
|
- return e_Fatal;
|
|
- }
|
|
- break;
|
|
- case 'B': /* set run_string buffer size */
|
|
- if (*arg == '-')
|
|
- minst->run_buffer_size = 0;
|
|
- else {
|
|
- uint bsize;
|
|
-
|
|
- if (sscanf((const char *)arg, "%u", &bsize) != 1 ||
|
|
- bsize <= 0 || bsize > MAX_BUFFERED_SIZE
|
|
- ) {
|
|
- outprintf(minst->heap,
|
|
- "-B must be followed by - or size between 1 and %u\n",
|
|
- MAX_BUFFERED_SIZE);
|
|
- return e_Fatal;
|
|
- }
|
|
- minst->run_buffer_size = bsize;
|
|
- }
|
|
- break;
|
|
- case 'c': /* code follows */
|
|
- {
|
|
- bool ats = pal->expand_ats;
|
|
-
|
|
- code = gs_main_init2(minst);
|
|
- if (code < 0)
|
|
- return code;
|
|
- pal->expand_ats = false;
|
|
- while ((arg = arg_next(pal, &code)) != 0) {
|
|
- char *sarg;
|
|
-
|
|
- if (arg[0] == '@' ||
|
|
- (arg[0] == '-' && !isdigit((unsigned char)arg[1]))
|
|
- )
|
|
- break;
|
|
- sarg = arg_copy(arg, minst->heap);
|
|
- if (sarg == NULL)
|
|
- return e_Fatal;
|
|
- code = runarg(minst, "", sarg, ".runstring", 0);
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
- if (code < 0)
|
|
- return e_Fatal;
|
|
- if (arg != 0) {
|
|
- char *p = arg_copy(arg, minst->heap);
|
|
- if (p == NULL)
|
|
- return e_Fatal;
|
|
- arg_push_string(pal, p, true);
|
|
- }
|
|
- pal->expand_ats = ats;
|
|
- break;
|
|
- }
|
|
- case 'E': /* log errors */
|
|
- switch (*arg) {
|
|
- case 0:
|
|
- gs_log_errors = 1;
|
|
- break;
|
|
- case '-':
|
|
- gs_log_errors = 0;
|
|
- break;
|
|
- default:
|
|
- puts(minst->heap, "-E may only be followed by -");
|
|
- return e_Fatal;
|
|
- }
|
|
- break;
|
|
- case 'f': /* run file of arbitrary name */
|
|
- if (*arg != 0) {
|
|
- code = argproc(minst, arg);
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
- break;
|
|
- case 'F': /* run file with buffer_size = 1 */
|
|
- if (!*arg) {
|
|
- puts(minst->heap, "-F requires a file name");
|
|
- return e_Fatal;
|
|
- } {
|
|
- uint bsize = minst->run_buffer_size;
|
|
-
|
|
- minst->run_buffer_size = 1;
|
|
- code = argproc(minst, arg);
|
|
- minst->run_buffer_size = bsize;
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
- break;
|
|
- case 'g': /* define device geometry */
|
|
- {
|
|
- long width, height;
|
|
- ref value;
|
|
-
|
|
- if ((code = gs_main_init1(minst)) < 0)
|
|
- return code;
|
|
- if (sscanf((const char *)arg, "%ldx%ld", &width, &height) != 2) {
|
|
- puts(minst->heap, "-g must be followed by <width>x<height>");
|
|
- return e_Fatal;
|
|
- }
|
|
- make_int(&value, width);
|
|
- initial_enter_name("DEVICEWIDTH", &value);
|
|
- make_int(&value, height);
|
|
- initial_enter_name("DEVICEHEIGHT", &value);
|
|
- initial_enter_name("FIXEDMEDIA", &vtrue);
|
|
- break;
|
|
- }
|
|
- case 'h': /* print help */
|
|
- case '?': /* ditto */
|
|
- print_help(minst);
|
|
- return e_Info; /* show usage info on exit */
|
|
- case 'I': /* specify search path */
|
|
- {
|
|
- char *path = arg_copy(arg, minst->heap);
|
|
- if (path == NULL)
|
|
- return e_Fatal;
|
|
- gs_main_add_lib_path(minst, path);
|
|
- }
|
|
- break;
|
|
- case 'K': /* set malloc limit */
|
|
- {
|
|
- long msize = 0;
|
|
- gs_malloc_memory_t *rawheap = gs_malloc_wrapped_contents(minst->heap);
|
|
-
|
|
- sscanf((const char *)arg, "%ld", &msize);
|
|
- if (msize <= 0 || msize > max_long >> 10) {
|
|
- outprintf(minst->heap, "-K<numK> must have 1 <= numK <= %ld\n",
|
|
- max_long >> 10);
|
|
- return e_Fatal;
|
|
- }
|
|
- rawheap->limit = msize << 10;
|
|
- }
|
|
- break;
|
|
- case 'M': /* set memory allocation increment */
|
|
- {
|
|
- unsigned msize = 0;
|
|
+ minst->run_start = false; /* don't run 'start' */
|
|
+ /* Set NOPAUSE so showpage won't try to read from stdin. */
|
|
+ code = swproc(minst, "-dNOPAUSE", pal);
|
|
+ if (code)
|
|
+ return code;
|
|
+ code = gs_main_init2(minst); /* Finish initialization */
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+
|
|
+ code = run_string(minst, ".runstdin", runFlush);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ break;
|
|
+ case '-': /* run with command line args */
|
|
+ case '+':
|
|
+ pal->expand_ats = false;
|
|
+ case '@': /* ditto with @-expansion */
|
|
+ {
|
|
+ const char *psarg = arg_next(pal, &code);
|
|
+
|
|
+ if (code < 0)
|
|
+ return e_Fatal;
|
|
+ if (psarg == 0) {
|
|
+ outprintf(minst->heap, "Usage: gs ... -%c file.ps arg1 ... argn\n", sw);
|
|
+ arg_finit(pal);
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ psarg = arg_copy(psarg, minst->heap);
|
|
+ if (psarg == NULL)
|
|
+ return e_Fatal;
|
|
+ code = gs_main_init2(minst);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ code = run_string(minst, "userdict/ARGUMENTS[", 0);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ while ((arg = arg_next(pal, &code)) != 0) {
|
|
+ char *fname = arg_copy(arg, minst->heap);
|
|
+ if (fname == NULL)
|
|
+ return e_Fatal;
|
|
+ code = runarg(minst, "", fname, "", runInit);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
+ if (code < 0)
|
|
+ return e_Fatal;
|
|
+ runarg(minst, "]put", psarg, ".runfile", runInit | runFlush);
|
|
+ return e_Quit;
|
|
+ }
|
|
+ case 'A': /* trace allocator */
|
|
+ switch (*arg) {
|
|
+ case 0:
|
|
+ gs_alloc_debug = 1;
|
|
+ break;
|
|
+ case '-':
|
|
+ gs_alloc_debug = 0;
|
|
+ break;
|
|
+ default:
|
|
+ puts(minst->heap, "-A may only be followed by -");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ break;
|
|
+ case 'B': /* set run_string buffer size */
|
|
+ if (*arg == '-')
|
|
+ minst->run_buffer_size = 0;
|
|
+ else {
|
|
+ uint bsize;
|
|
+
|
|
+ if (sscanf((const char *)arg, "%u", &bsize) != 1 ||
|
|
+ bsize <= 0 || bsize > MAX_BUFFERED_SIZE
|
|
+ ) {
|
|
+ outprintf(minst->heap,
|
|
+ "-B must be followed by - or size between 1 and %u\n",
|
|
+ MAX_BUFFERED_SIZE);
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ minst->run_buffer_size = bsize;
|
|
+ }
|
|
+ break;
|
|
+ case 'c': /* code follows */
|
|
+ {
|
|
+ bool ats = pal->expand_ats;
|
|
+
|
|
+ code = gs_main_init2(minst);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ pal->expand_ats = false;
|
|
+ while ((arg = arg_next(pal, &code)) != 0) {
|
|
+ char *sarg;
|
|
+
|
|
+ if (arg[0] == '@' ||
|
|
+ (arg[0] == '-' && !isdigit((unsigned char)arg[1]))
|
|
+ )
|
|
+ break;
|
|
+ sarg = arg_copy(arg, minst->heap);
|
|
+ if (sarg == NULL)
|
|
+ return e_Fatal;
|
|
+ code = runarg(minst, "", sarg, ".runstring", 0);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
+ if (code < 0)
|
|
+ return e_Fatal;
|
|
+ if (arg != 0) {
|
|
+ char *p = arg_copy(arg, minst->heap);
|
|
+ if (p == NULL)
|
|
+ return e_Fatal;
|
|
+ arg_push_string(pal, p, true);
|
|
+ }
|
|
+ pal->expand_ats = ats;
|
|
+ break;
|
|
+ }
|
|
+ case 'E': /* log errors */
|
|
+ switch (*arg) {
|
|
+ case 0:
|
|
+ gs_log_errors = 1;
|
|
+ break;
|
|
+ case '-':
|
|
+ gs_log_errors = 0;
|
|
+ break;
|
|
+ default:
|
|
+ puts(minst->heap, "-E may only be followed by -");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ break;
|
|
+ case 'f': /* run file of arbitrary name */
|
|
+ if (*arg != 0) {
|
|
+ code = argproc(minst, arg);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
+ break;
|
|
+ case 'F': /* run file with buffer_size = 1 */
|
|
+ if (!*arg) {
|
|
+ puts(minst->heap, "-F requires a file name");
|
|
+ return e_Fatal;
|
|
+ } {
|
|
+ uint bsize = minst->run_buffer_size;
|
|
+
|
|
+ minst->run_buffer_size = 1;
|
|
+ code = argproc(minst, arg);
|
|
+ minst->run_buffer_size = bsize;
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
+ break;
|
|
+ case 'g': /* define device geometry */
|
|
+ {
|
|
+ long width, height;
|
|
+ ref value;
|
|
+
|
|
+ if ((code = gs_main_init1(minst)) < 0)
|
|
+ return code;
|
|
+ if (sscanf((const char *)arg, "%ldx%ld", &width, &height) != 2) {
|
|
+ puts(minst->heap, "-g must be followed by <width>x<height>");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ make_int(&value, width);
|
|
+ initial_enter_name("DEVICEWIDTH", &value);
|
|
+ make_int(&value, height);
|
|
+ initial_enter_name("DEVICEHEIGHT", &value);
|
|
+ initial_enter_name("FIXEDMEDIA", &vtrue);
|
|
+ break;
|
|
+ }
|
|
+ case 'h': /* print help */
|
|
+ case '?': /* ditto */
|
|
+ print_help(minst);
|
|
+ return e_Info; /* show usage info on exit */
|
|
+ case 'I': /* specify search path */
|
|
+ {
|
|
+ char *path = arg_copy(arg, minst->heap);
|
|
+ if (path == NULL)
|
|
+ return e_Fatal;
|
|
+ gs_main_add_lib_path(minst, path);
|
|
+ }
|
|
+ break;
|
|
+ case 'K': /* set malloc limit */
|
|
+ {
|
|
+ long msize = 0;
|
|
+ gs_malloc_memory_t *rawheap = gs_malloc_wrapped_contents(minst->heap);
|
|
+
|
|
+ sscanf((const char *)arg, "%ld", &msize);
|
|
+ if (msize <= 0 || msize > max_long >> 10) {
|
|
+ outprintf(minst->heap, "-K<numK> must have 1 <= numK <= %ld\n",
|
|
+ max_long >> 10);
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ rawheap->limit = msize << 10;
|
|
+ }
|
|
+ break;
|
|
+ case 'M': /* set memory allocation increment */
|
|
+ {
|
|
+ unsigned msize = 0;
|
|
|
|
- sscanf((const char *)arg, "%u", &msize);
|
|
+ sscanf((const char *)arg, "%u", &msize);
|
|
#if ARCH_INTS_ARE_SHORT
|
|
- if (msize <= 0 || msize >= 64) {
|
|
- puts(minst->heap, "-M must be between 1 and 63");
|
|
- return e_Fatal;
|
|
- }
|
|
+ if (msize <= 0 || msize >= 64) {
|
|
+ puts(minst->heap, "-M must be between 1 and 63");
|
|
+ return e_Fatal;
|
|
+ }
|
|
#endif
|
|
- minst->memory_chunk_size = msize << 10;
|
|
- }
|
|
- break;
|
|
- case 'N': /* set size of name table */
|
|
- {
|
|
- unsigned nsize = 0;
|
|
+ minst->memory_chunk_size = msize << 10;
|
|
+ }
|
|
+ break;
|
|
+ case 'N': /* set size of name table */
|
|
+ {
|
|
+ unsigned nsize = 0;
|
|
|
|
- sscanf((const char *)arg, "%d", &nsize);
|
|
+ sscanf((const char *)arg, "%d", &nsize);
|
|
#if ARCH_INTS_ARE_SHORT
|
|
- if (nsize < 2 || nsize > 64) {
|
|
- puts(minst->heap, "-N must be between 2 and 64");
|
|
- return e_Fatal;
|
|
- }
|
|
+ if (nsize < 2 || nsize > 64) {
|
|
+ puts(minst->heap, "-N must be between 2 and 64");
|
|
+ return e_Fatal;
|
|
+ }
|
|
#endif
|
|
- minst->name_table_size = (ulong) nsize << 10;
|
|
- }
|
|
- break;
|
|
- case 'o': /* set output file name and batch mode */
|
|
- {
|
|
- const char *adef;
|
|
- char *str;
|
|
- ref value;
|
|
- int len;
|
|
-
|
|
- if (arg[0] == 0) {
|
|
- adef = arg_next(pal, &code);
|
|
- if (code < 0)
|
|
- return code;
|
|
- } else
|
|
- adef = arg;
|
|
- if ((code = gs_main_init1(minst)) < 0)
|
|
- return code;
|
|
- len = strlen(adef);
|
|
- str = (char *)gs_alloc_bytes(minst->heap, (uint)len, "-o");
|
|
- memcpy(str, adef, len);
|
|
- make_const_string(&value, a_readonly | avm_foreign,
|
|
- len, (const byte *)str);
|
|
- initial_enter_name("OutputFile", &value);
|
|
- initial_enter_name("NOPAUSE", &vtrue);
|
|
- initial_enter_name("BATCH", &vtrue);
|
|
- }
|
|
- break;
|
|
- case 'P': /* choose whether search '.' first */
|
|
- if (!strcmp(arg, ""))
|
|
- minst->search_here_first = true;
|
|
- else if (!strcmp(arg, "-"))
|
|
- minst->search_here_first = false;
|
|
- else {
|
|
- puts(minst->heap, "Only -P or -P- is allowed.");
|
|
- return e_Fatal;
|
|
- }
|
|
- break;
|
|
- case 'q': /* quiet startup */
|
|
- if ((code = gs_main_init1(minst)) < 0)
|
|
- return code;
|
|
- initial_enter_name("QUIET", &vtrue);
|
|
- break;
|
|
- case 'r': /* define device resolution */
|
|
- {
|
|
- float xres, yres;
|
|
- ref value;
|
|
-
|
|
- if ((code = gs_main_init1(minst)) < 0)
|
|
- return code;
|
|
- switch (sscanf((const char *)arg, "%fx%f", &xres, &yres)) {
|
|
- default:
|
|
- puts(minst->heap, "-r must be followed by <res> or <xres>x<yres>");
|
|
- return e_Fatal;
|
|
- case 1: /* -r<res> */
|
|
- yres = xres;
|
|
- case 2: /* -r<xres>x<yres> */
|
|
- make_real(&value, xres);
|
|
- initial_enter_name("DEVICEXRESOLUTION", &value);
|
|
- make_real(&value, yres);
|
|
- initial_enter_name("DEVICEYRESOLUTION", &value);
|
|
- initial_enter_name("FIXEDRESOLUTION", &vtrue);
|
|
- }
|
|
- break;
|
|
- }
|
|
- case 'D': /* define name */
|
|
- case 'd':
|
|
- case 'S': /* define name as string */
|
|
- case 's':
|
|
- {
|
|
- char *adef = arg_copy(arg, minst->heap);
|
|
- char *eqp;
|
|
- bool isd = (sw == 'D' || sw == 'd');
|
|
- ref value;
|
|
-
|
|
- if (adef == NULL)
|
|
- return e_Fatal;
|
|
- eqp = strchr(adef, '=');
|
|
-
|
|
- if (eqp == NULL)
|
|
- eqp = strchr(adef, '#');
|
|
- /* Initialize the object memory, scanner, and */
|
|
- /* name table now if needed. */
|
|
- if ((code = gs_main_init1(minst)) < 0)
|
|
- return code;
|
|
- if (eqp == adef) {
|
|
- puts(minst->heap, "Usage: -dname, -dname=token, -sname=string");
|
|
- return e_Fatal;
|
|
- }
|
|
- if (eqp == NULL) {
|
|
- if (isd)
|
|
- make_true(&value);
|
|
- else
|
|
- make_empty_string(&value, a_readonly);
|
|
- } else {
|
|
- int code;
|
|
- i_ctx_t *i_ctx_p = minst->i_ctx_p;
|
|
- uint space = icurrent_space;
|
|
-
|
|
- *eqp++ = 0;
|
|
- ialloc_set_space(idmemory, avm_system);
|
|
- if (isd) {
|
|
- stream astream;
|
|
- scanner_state state;
|
|
-
|
|
- s_init(&astream, NULL);
|
|
- sread_string(&astream,
|
|
- (const byte *)eqp, strlen(eqp));
|
|
- scanner_init_stream(&state, &astream);
|
|
- code = scan_token(minst->i_ctx_p, &value, &state);
|
|
- if (code) {
|
|
- puts(minst->heap, "-dname= must be followed by a valid token");
|
|
- return e_Fatal;
|
|
- }
|
|
- if (r_has_type_attrs(&value, t_name,
|
|
- a_executable)) {
|
|
- ref nsref;
|
|
+ minst->name_table_size = (ulong) nsize << 10;
|
|
+ }
|
|
+ break;
|
|
+ case 'o': /* set output file name and batch mode */
|
|
+ {
|
|
+ const char *adef;
|
|
+ char *str;
|
|
+ ref value;
|
|
+ int len;
|
|
+
|
|
+ if (arg[0] == 0) {
|
|
+ adef = arg_next(pal, &code);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ } else
|
|
+ adef = arg;
|
|
+ if ((code = gs_main_init1(minst)) < 0)
|
|
+ return code;
|
|
+ len = strlen(adef);
|
|
+ str = (char *)gs_alloc_bytes(minst->heap, (uint)len, "-o");
|
|
+ memcpy(str, adef, len);
|
|
+ make_const_string(&value, a_readonly | avm_foreign,
|
|
+ len, (const byte *)str);
|
|
+ initial_enter_name("OutputFile", &value);
|
|
+ initial_enter_name("NOPAUSE", &vtrue);
|
|
+ initial_enter_name("BATCH", &vtrue);
|
|
+ }
|
|
+ break;
|
|
+ case 'P': /* choose whether search '.' first */
|
|
+ if (!strcmp(arg, ""))
|
|
+ minst->search_here_first = true;
|
|
+ else if (!strcmp(arg, "-"))
|
|
+ minst->search_here_first = false;
|
|
+ else {
|
|
+ puts(minst->heap, "Only -P or -P- is allowed.");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ break;
|
|
+ case 'q': /* quiet startup */
|
|
+ if ((code = gs_main_init1(minst)) < 0)
|
|
+ return code;
|
|
+ initial_enter_name("QUIET", &vtrue);
|
|
+ break;
|
|
+ case 'r': /* define device resolution */
|
|
+ {
|
|
+ float xres, yres;
|
|
+ ref value;
|
|
+
|
|
+ if ((code = gs_main_init1(minst)) < 0)
|
|
+ return code;
|
|
+ switch (sscanf((const char *)arg, "%fx%f", &xres, &yres)) {
|
|
+ default:
|
|
+ puts(minst->heap, "-r must be followed by <res> or <xres>x<yres>");
|
|
+ return e_Fatal;
|
|
+ case 1: /* -r<res> */
|
|
+ yres = xres;
|
|
+ case 2: /* -r<xres>x<yres> */
|
|
+ make_real(&value, xres);
|
|
+ initial_enter_name("DEVICEXRESOLUTION", &value);
|
|
+ make_real(&value, yres);
|
|
+ initial_enter_name("DEVICEYRESOLUTION", &value);
|
|
+ initial_enter_name("FIXEDRESOLUTION", &vtrue);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ case 'D': /* define name */
|
|
+ case 'd':
|
|
+ case 'S': /* define name as string */
|
|
+ case 's':
|
|
+ {
|
|
+ char *adef = arg_copy(arg, minst->heap);
|
|
+ char *eqp;
|
|
+ bool isd = (sw == 'D' || sw == 'd');
|
|
+ ref value;
|
|
+
|
|
+ if (adef == NULL)
|
|
+ return e_Fatal;
|
|
+ eqp = strchr(adef, '=');
|
|
+
|
|
+ if (eqp == NULL)
|
|
+ eqp = strchr(adef, '#');
|
|
+ /* Initialize the object memory, scanner, and */
|
|
+ /* name table now if needed. */
|
|
+ if ((code = gs_main_init1(minst)) < 0)
|
|
+ return code;
|
|
+ if (eqp == adef) {
|
|
+ puts(minst->heap, "Usage: -dname, -dname=token, -sname=string");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ if (eqp == NULL) {
|
|
+ if (isd)
|
|
+ make_true(&value);
|
|
+ else
|
|
+ make_empty_string(&value, a_readonly);
|
|
+ } else {
|
|
+ int code;
|
|
+ i_ctx_t *i_ctx_p = minst->i_ctx_p;
|
|
+ uint space = icurrent_space;
|
|
+
|
|
+ *eqp++ = 0;
|
|
+ ialloc_set_space(idmemory, avm_system);
|
|
+ if (isd) {
|
|
+ stream astream;
|
|
+ scanner_state state;
|
|
+
|
|
+ s_init(&astream, NULL);
|
|
+ sread_string(&astream,
|
|
+ (const byte *)eqp, strlen(eqp));
|
|
+ gs_scanner_init_stream(&state, &astream);
|
|
+ code = gs_scan_token(minst->i_ctx_p, &value, &state);
|
|
+ if (code) {
|
|
+ puts(minst->heap, "-dname= must be followed by a valid token");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ if (r_has_type_attrs(&value, t_name,
|
|
+ a_executable)) {
|
|
+ ref nsref;
|
|
|
|
- name_string_ref(minst->heap, &value, &nsref);
|
|
+ name_string_ref(minst->heap, &value, &nsref);
|
|
#define string_is(nsref, str, len)\
|
|
(r_size(&(nsref)) == (len) &&\
|
|
!strncmp((const char *)(nsref).value.const_bytes, str, (len)))
|
|
- if (string_is(nsref, "null", 4))
|
|
- make_null(&value);
|
|
- else if (string_is(nsref, "true", 4))
|
|
- make_true(&value);
|
|
- else if (string_is(nsref, "false", 5))
|
|
- make_false(&value);
|
|
- else {
|
|
- puts(minst->heap,
|
|
- "-dvar=name requires name=null, true, or false");
|
|
- return e_Fatal;
|
|
- }
|
|
+ if (string_is(nsref, "null", 4))
|
|
+ make_null(&value);
|
|
+ else if (string_is(nsref, "true", 4))
|
|
+ make_true(&value);
|
|
+ else if (string_is(nsref, "false", 5))
|
|
+ make_false(&value);
|
|
+ else {
|
|
+ puts(minst->heap,
|
|
+ "-dvar=name requires name=null, true, or false");
|
|
+ return e_Fatal;
|
|
+ }
|
|
#undef name_is_string
|
|
- }
|
|
- } else {
|
|
- int len = strlen(eqp);
|
|
- char *str =
|
|
- (char *)gs_alloc_bytes(minst->heap,
|
|
- (uint) len, "-s");
|
|
-
|
|
- if (str == 0) {
|
|
- lprintf("Out of memory!\n");
|
|
- return e_Fatal;
|
|
- }
|
|
- memcpy(str, eqp, len);
|
|
- make_const_string(&value,
|
|
- a_readonly | avm_foreign,
|
|
- len, (const byte *)str);
|
|
- if ((code = try_stdout_redirect(minst, adef, eqp)) < 0)
|
|
- return code;
|
|
- }
|
|
- ialloc_set_space(idmemory, space);
|
|
- }
|
|
- /* Enter the name in systemdict. */
|
|
- initial_enter_name(adef, &value);
|
|
- break;
|
|
- }
|
|
- case 'T':
|
|
+ }
|
|
+ } else {
|
|
+ int len = strlen(eqp);
|
|
+ char *str =
|
|
+ (char *)gs_alloc_bytes(minst->heap,
|
|
+ (uint) len, "-s");
|
|
+
|
|
+ if (str == 0) {
|
|
+ lprintf("Out of memory!\n");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ memcpy(str, eqp, len);
|
|
+ make_const_string(&value,
|
|
+ a_readonly | avm_foreign,
|
|
+ len, (const byte *)str);
|
|
+ if ((code = try_stdout_redirect(minst, adef, eqp)) < 0)
|
|
+ return code;
|
|
+ }
|
|
+ ialloc_set_space(idmemory, space);
|
|
+ }
|
|
+ /* Enter the name in systemdict. */
|
|
+ initial_enter_name(adef, &value);
|
|
+ break;
|
|
+ }
|
|
+ case 'T':
|
|
set_debug_flags(arg, vd_flags);
|
|
- break;
|
|
- case 'u': /* undefine name */
|
|
- if (!*arg) {
|
|
- puts(minst->heap, "-u requires a name to undefine.");
|
|
- return e_Fatal;
|
|
- }
|
|
- if ((code = gs_main_init1(minst)) < 0)
|
|
- return code;
|
|
- i_initial_remove_name(minst->i_ctx_p, arg);
|
|
- break;
|
|
- case 'v': /* print revision */
|
|
- print_revision(minst);
|
|
- return e_Info;
|
|
+ break;
|
|
+ case 'u': /* undefine name */
|
|
+ if (!*arg) {
|
|
+ puts(minst->heap, "-u requires a name to undefine.");
|
|
+ return e_Fatal;
|
|
+ }
|
|
+ if ((code = gs_main_init1(minst)) < 0)
|
|
+ return code;
|
|
+ i_initial_remove_name(minst->i_ctx_p, arg);
|
|
+ break;
|
|
+ case 'v': /* print revision */
|
|
+ print_revision(minst);
|
|
+ return e_Info;
|
|
/*#ifdef DEBUG */
|
|
- /*
|
|
- * Here we provide a place for inserting debugging code that can be
|
|
- * run in place of the normal interpreter code.
|
|
- */
|
|
- case 'X':
|
|
- code = gs_main_init2(minst);
|
|
- if (code < 0)
|
|
- return code;
|
|
- {
|
|
- int xec; /* exit_code */
|
|
- ref xeo; /* error_object */
|
|
+ /*
|
|
+ * Here we provide a place for inserting debugging code that can be
|
|
+ * run in place of the normal interpreter code.
|
|
+ */
|
|
+ case 'X':
|
|
+ code = gs_main_init2(minst);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ {
|
|
+ int xec; /* exit_code */
|
|
+ ref xeo; /* error_object */
|
|
|
|
#define start_x()\
|
|
gs_main_run_string_begin(minst, 1, &xec, &xeo)
|
|
@@ -677,16 +677,16 @@ run_stdin:
|
|
gs_main_run_string_continue(minst, str, strlen(str), 1, &xec, &xeo)
|
|
#define stop_x()\
|
|
gs_main_run_string_end(minst, 1, &xec, &xeo)
|
|
- start_x();
|
|
- run_x("\216\003abc");
|
|
- run_x("== flush\n");
|
|
- stop_x();
|
|
- }
|
|
- return e_Quit;
|
|
+ start_x();
|
|
+ run_x("\216\003abc");
|
|
+ run_x("== flush\n");
|
|
+ stop_x();
|
|
+ }
|
|
+ return e_Quit;
|
|
/*#endif */
|
|
- case 'Z':
|
|
+ case 'Z':
|
|
set_debug_flags(arg, gs_debug);
|
|
- break;
|
|
+ break;
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -709,10 +709,10 @@ esc_strcat(char *dest, const char *src)
|
|
|
|
*d++ = '<';
|
|
for (p = src; *p; p++) {
|
|
- byte c = (byte) * p;
|
|
+ byte c = (byte) * p;
|
|
|
|
- *d++ = hex[c >> 4];
|
|
- *d++ = hex[c & 0xf];
|
|
+ *d++ = hex[c >> 4];
|
|
+ *d++ = hex[c & 0xf];
|
|
}
|
|
*d++ = '>';
|
|
*d = 0;
|
|
@@ -722,7 +722,7 @@ esc_strcat(char *dest, const char *src)
|
|
static int
|
|
argproc(gs_main_instance * minst, const char *arg)
|
|
{
|
|
- int code = gs_main_init1(minst); /* need i_ctx_p to proceed */
|
|
+ int code = gs_main_init1(minst); /* need i_ctx_p to proceed */
|
|
char *filearg;
|
|
|
|
if (code < 0)
|
|
@@ -731,11 +731,11 @@ argproc(gs_main_instance * minst, const
|
|
if (filearg == NULL)
|
|
return e_Fatal;
|
|
if (minst->run_buffer_size) {
|
|
- /* Run file with run_string. */
|
|
- return run_buffered(minst, filearg);
|
|
+ /* Run file with run_string. */
|
|
+ return run_buffered(minst, filearg);
|
|
} else {
|
|
- /* Run file directly in the normal way. */
|
|
- return runarg(minst, "", filearg, ".runfile", runInit | runFlush);
|
|
+ /* Run file directly in the normal way. */
|
|
+ return runarg(minst, "", filearg, ".runfile", runInit | runFlush);
|
|
}
|
|
}
|
|
static int
|
|
@@ -747,32 +747,32 @@ run_buffered(gs_main_instance * minst, c
|
|
int code;
|
|
|
|
if (in == 0) {
|
|
- outprintf(minst->heap, "Unable to open %s for reading", arg);
|
|
- return_error(e_invalidfileaccess);
|
|
+ outprintf(minst->heap, "Unable to open %s for reading", arg);
|
|
+ return_error(e_invalidfileaccess);
|
|
}
|
|
code = gs_main_init2(minst);
|
|
if (code < 0) {
|
|
fclose(in);
|
|
- return code;
|
|
+ return code;
|
|
}
|
|
code = gs_main_run_string_begin(minst, minst->user_errors,
|
|
- &exit_code, &error_object);
|
|
+ &exit_code, &error_object);
|
|
if (!code) {
|
|
- char buf[MAX_BUFFERED_SIZE];
|
|
- int count;
|
|
+ char buf[MAX_BUFFERED_SIZE];
|
|
+ int count;
|
|
|
|
- code = e_NeedInput;
|
|
- while ((count = fread(buf, 1, minst->run_buffer_size, in)) > 0) {
|
|
- code = gs_main_run_string_continue(minst, buf, count,
|
|
- minst->user_errors,
|
|
- &exit_code, &error_object);
|
|
- if (code != e_NeedInput)
|
|
- break;
|
|
- }
|
|
- if (code == e_NeedInput) {
|
|
- code = gs_main_run_string_end(minst, minst->user_errors,
|
|
- &exit_code, &error_object);
|
|
- }
|
|
+ code = e_NeedInput;
|
|
+ while ((count = fread(buf, 1, minst->run_buffer_size, in)) > 0) {
|
|
+ code = gs_main_run_string_continue(minst, buf, count,
|
|
+ minst->user_errors,
|
|
+ &exit_code, &error_object);
|
|
+ if (code != e_NeedInput)
|
|
+ break;
|
|
+ }
|
|
+ if (code == e_NeedInput) {
|
|
+ code = gs_main_run_string_end(minst, minst->user_errors,
|
|
+ &exit_code, &error_object);
|
|
+ }
|
|
}
|
|
fclose(in);
|
|
zflush(minst->i_ctx_p);
|
|
@@ -788,15 +788,15 @@ runarg(gs_main_instance * minst, const c
|
|
char *line;
|
|
|
|
if (options & runInit) {
|
|
- code = gs_main_init2(minst); /* Finish initialization */
|
|
+ code = gs_main_init2(minst); /* Finish initialization */
|
|
|
|
- if (code < 0)
|
|
- return code;
|
|
+ if (code < 0)
|
|
+ return code;
|
|
}
|
|
line = (char *)gs_alloc_bytes(minst->heap, len, "argproc");
|
|
if (line == 0) {
|
|
- lprintf("Out of memory!\n");
|
|
- return_error(e_VMerror);
|
|
+ lprintf("Out of memory!\n");
|
|
+ return_error(e_VMerror);
|
|
}
|
|
strcpy(line, pre);
|
|
esc_strcat(line, arg);
|
|
@@ -812,29 +812,29 @@ run_string(gs_main_instance * minst, con
|
|
int exit_code;
|
|
ref error_object;
|
|
int code = gs_main_run_string(minst, str, minst->user_errors,
|
|
- &exit_code, &error_object);
|
|
+ &exit_code, &error_object);
|
|
|
|
if ((options & runFlush) || code != 0) {
|
|
- zflush(minst->i_ctx_p); /* flush stdout */
|
|
- zflushpage(minst->i_ctx_p); /* force display update */
|
|
+ zflush(minst->i_ctx_p); /* flush stdout */
|
|
+ zflushpage(minst->i_ctx_p); /* force display update */
|
|
}
|
|
return run_finish(minst, code, exit_code, &error_object);
|
|
}
|
|
static int
|
|
run_finish(gs_main_instance *minst, int code, int exit_code,
|
|
- ref * perror_object)
|
|
+ ref * perror_object)
|
|
{
|
|
switch (code) {
|
|
- case e_Quit:
|
|
- case 0:
|
|
- break;
|
|
- case e_Fatal:
|
|
- emprintf1(minst->heap,
|
|
+ case e_Quit:
|
|
+ case 0:
|
|
+ break;
|
|
+ case e_Fatal:
|
|
+ emprintf1(minst->heap,
|
|
"Unrecoverable error, exit code %d\n",
|
|
exit_code);
|
|
- break;
|
|
- default:
|
|
- gs_main_dump_stack(minst, code, perror_object);
|
|
+ break;
|
|
+ default:
|
|
+ gs_main_dump_stack(minst, code, perror_object);
|
|
}
|
|
return code;
|
|
}
|
|
@@ -848,34 +848,34 @@ run_finish(gs_main_instance *minst, int
|
|
* File is closed at program exit (if not stdout/err)
|
|
* or when -sstdout is used again.
|
|
*/
|
|
-static int
|
|
-try_stdout_redirect(gs_main_instance * minst,
|
|
+static int
|
|
+try_stdout_redirect(gs_main_instance * minst,
|
|
const char *command, const char *filename)
|
|
{
|
|
if (strcmp(command, "stdout") == 0) {
|
|
- minst->heap->gs_lib_ctx->stdout_to_stderr = 0;
|
|
- minst->heap->gs_lib_ctx->stdout_is_redirected = 0;
|
|
- /* If stdout already being redirected and it is not stdout
|
|
- * or stderr, close it
|
|
- */
|
|
- 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;
|
|
- }
|
|
- /* If stdout is being redirected, set minst->fstdout2 */
|
|
- if ( (filename != 0) && strlen(filename) &&
|
|
- strcmp(filename, "-") && strcmp(filename, "%stdout") ) {
|
|
- if (strcmp(filename, "%stderr") == 0) {
|
|
- minst->heap->gs_lib_ctx->stdout_to_stderr = 1;
|
|
- }
|
|
- else if ((minst->heap->gs_lib_ctx->fstdout2 =
|
|
- fopen(filename, "w")) == (FILE *)NULL)
|
|
- return_error(e_invalidfileaccess);
|
|
- minst->heap->gs_lib_ctx->stdout_is_redirected = 1;
|
|
- }
|
|
- return 0;
|
|
+ minst->heap->gs_lib_ctx->stdout_to_stderr = 0;
|
|
+ minst->heap->gs_lib_ctx->stdout_is_redirected = 0;
|
|
+ /* If stdout already being redirected and it is not stdout
|
|
+ * or stderr, close it
|
|
+ */
|
|
+ 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;
|
|
+ }
|
|
+ /* If stdout is being redirected, set minst->fstdout2 */
|
|
+ if ( (filename != 0) && strlen(filename) &&
|
|
+ strcmp(filename, "-") && strcmp(filename, "%stdout") ) {
|
|
+ if (strcmp(filename, "%stderr") == 0) {
|
|
+ minst->heap->gs_lib_ctx->stdout_to_stderr = 1;
|
|
+ }
|
|
+ else if ((minst->heap->gs_lib_ctx->fstdout2 =
|
|
+ fopen(filename, "w")) == (FILE *)NULL)
|
|
+ return_error(e_invalidfileaccess);
|
|
+ minst->heap->gs_lib_ctx->stdout_is_redirected = 1;
|
|
+ }
|
|
+ return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
@@ -919,13 +919,13 @@ print_help(gs_main_instance * minst)
|
|
print_paths(minst);
|
|
/* Check if we have the %rom device */
|
|
for (i = 0; i < gx_io_device_table_count; i++) {
|
|
- const gx_io_device *iodev = gx_io_device_table[i];
|
|
- const char *dname = iodev->dname;
|
|
+ const gx_io_device *iodev = gx_io_device_table[i];
|
|
+ const char *dname = iodev->dname;
|
|
|
|
- if (dname && strlen(dname) == 5 && !memcmp("%rom%", dname, 5)) {
|
|
- have_rom_device = 1;
|
|
- break;
|
|
- }
|
|
+ if (dname && strlen(dname) == 5 && !memcmp("%rom%", dname, 5)) {
|
|
+ have_rom_device = 1;
|
|
+ break;
|
|
+ }
|
|
}
|
|
if (have_rom_device) {
|
|
outprintf(minst->heap, "Initialization files are compiled into the executable.\n");
|
|
@@ -939,10 +939,10 @@ print_revision(const gs_main_instance *m
|
|
{
|
|
printf_program_ident(minst->heap, gs_product, gs_revision);
|
|
outprintf(minst->heap, " (%d-%02d-%02d)\n%s\n",
|
|
- (int)(gs_revisiondate / 10000),
|
|
- (int)(gs_revisiondate / 100 % 100),
|
|
- (int)(gs_revisiondate % 100),
|
|
- gs_copyright);
|
|
+ (int)(gs_revisiondate / 10000),
|
|
+ (int)(gs_revisiondate / 100 % 100),
|
|
+ (int)(gs_revisiondate % 100),
|
|
+ gs_copyright);
|
|
}
|
|
|
|
/* Print the version number. */
|
|
@@ -975,41 +975,41 @@ print_devices(const gs_main_instance *mi
|
|
outprintf(minst->heap, " %s\n", gs_devicename(gs_getdefaultdevice()));
|
|
outprintf(minst->heap, "%s", help_devices);
|
|
{
|
|
- int i;
|
|
- int pos = 100;
|
|
- const gx_device *pdev;
|
|
- const char **names;
|
|
- size_t ndev = 0;
|
|
-
|
|
- for (i = 0; gs_getdevice(i) != 0; i++)
|
|
- ;
|
|
- ndev = (size_t)i;
|
|
- names = (const char **)gs_alloc_bytes(minst->heap, ndev * sizeof(const char*), "print_devices");
|
|
- if (names == (const char **)NULL) { /* old-style unsorted device list */
|
|
- for (i = 0; (pdev = gs_getdevice(i)) != 0; i++) {
|
|
- const char *dname = gs_devicename(pdev);
|
|
- int len = strlen(dname);
|
|
-
|
|
- if (pos + 1 + len > 76)
|
|
- outprintf(minst->heap, "\n "), pos = 2;
|
|
- outprintf(minst->heap, " %s", dname);
|
|
- pos += 1 + len;
|
|
- }
|
|
- }
|
|
- else { /* new-style sorted device list */
|
|
- for (i = 0; (pdev = gs_getdevice(i)) != 0; i++)
|
|
- names[i] = gs_devicename(pdev);
|
|
- qsort((void*)names, ndev, sizeof(const char*), cmpstr);
|
|
- for (i = 0; i < ndev; i++) {
|
|
- int len = strlen(names[i]);
|
|
-
|
|
- if (pos + 1 + len > 76)
|
|
- outprintf(minst->heap, "\n "), pos = 2;
|
|
- outprintf(minst->heap, " %s", names[i]);
|
|
- pos += 1 + len;
|
|
- }
|
|
- gs_free(minst->heap, (char *)names, ndev * sizeof(const char*), 1, "print_devices");
|
|
- }
|
|
+ int i;
|
|
+ int pos = 100;
|
|
+ const gx_device *pdev;
|
|
+ const char **names;
|
|
+ size_t ndev = 0;
|
|
+
|
|
+ for (i = 0; gs_getdevice(i) != 0; i++)
|
|
+ ;
|
|
+ ndev = (size_t)i;
|
|
+ names = (const char **)gs_alloc_bytes(minst->heap, ndev * sizeof(const char*), "print_devices");
|
|
+ if (names == (const char **)NULL) { /* old-style unsorted device list */
|
|
+ for (i = 0; (pdev = gs_getdevice(i)) != 0; i++) {
|
|
+ const char *dname = gs_devicename(pdev);
|
|
+ int len = strlen(dname);
|
|
+
|
|
+ if (pos + 1 + len > 76)
|
|
+ outprintf(minst->heap, "\n "), pos = 2;
|
|
+ outprintf(minst->heap, " %s", dname);
|
|
+ pos += 1 + len;
|
|
+ }
|
|
+ }
|
|
+ else { /* new-style sorted device list */
|
|
+ for (i = 0; (pdev = gs_getdevice(i)) != 0; i++)
|
|
+ names[i] = gs_devicename(pdev);
|
|
+ qsort((void*)names, ndev, sizeof(const char*), cmpstr);
|
|
+ for (i = 0; i < ndev; i++) {
|
|
+ int len = strlen(names[i]);
|
|
+
|
|
+ if (pos + 1 + len > 76)
|
|
+ outprintf(minst->heap, "\n "), pos = 2;
|
|
+ outprintf(minst->heap, " %s", names[i]);
|
|
+ pos += 1 + len;
|
|
+ }
|
|
+ gs_free(minst->heap, (char *)names, ndev * sizeof(const char*), 1, "print_devices");
|
|
+ }
|
|
}
|
|
outprintf(minst->heap, "\n");
|
|
}
|
|
@@ -1020,17 +1020,17 @@ print_emulators(const gs_main_instance *
|
|
{
|
|
outprintf(minst->heap, "%s", help_emulators);
|
|
{
|
|
- const ref *pes;
|
|
+ const ref *pes;
|
|
|
|
- for (pes = gs_emulator_name_array;
|
|
- pes->value.const_bytes != 0; pes++
|
|
- )
|
|
- /*
|
|
- * Even though gs_emulator_name_array is declared and used as
|
|
- * an array of string refs, each string is actually a
|
|
- * (null terminated) C string.
|
|
- */
|
|
- outprintf(minst->heap, " %s", (const char *)pes->value.const_bytes);
|
|
+ for (pes = gs_emulator_name_array;
|
|
+ pes->value.const_bytes != 0; pes++
|
|
+ )
|
|
+ /*
|
|
+ * Even though gs_emulator_name_array is declared and used as
|
|
+ * an array of string refs, each string is actually a
|
|
+ * (null terminated) C string.
|
|
+ */
|
|
+ outprintf(minst->heap, " %s", (const char *)pes->value.const_bytes);
|
|
}
|
|
outprintf(minst->heap, "\n");
|
|
}
|
|
@@ -1042,38 +1042,38 @@ print_paths(gs_main_instance * minst)
|
|
outprintf(minst->heap, "%s", help_paths);
|
|
gs_main_set_lib_paths(minst);
|
|
{
|
|
- uint count = r_size(&minst->lib_path.list);
|
|
- uint i;
|
|
- int pos = 100;
|
|
- char fsepr[3];
|
|
-
|
|
- fsepr[0] = ' ', fsepr[1] = gp_file_name_list_separator,
|
|
- fsepr[2] = 0;
|
|
- for (i = 0; i < count; ++i) {
|
|
- const ref *prdir =
|
|
- minst->lib_path.list.value.refs + i;
|
|
- uint len = r_size(prdir);
|
|
- const char *sepr = (i == count - 1 ? "" : fsepr);
|
|
-
|
|
- if (1 + pos + strlen(sepr) + len > 76)
|
|
- outprintf(minst->heap, "\n "), pos = 2;
|
|
- outprintf(minst->heap, " ");
|
|
- /*
|
|
- * This is really ugly, but it's necessary because some
|
|
- * platforms rely on all console output being funneled through
|
|
- * outprintf. We wish we could just do:
|
|
- fwrite(prdir->value.bytes, 1, len, minst->fstdout);
|
|
- */
|
|
- {
|
|
- const char *p = (const char *)prdir->value.bytes;
|
|
- uint j;
|
|
-
|
|
- for (j = len; j; j--)
|
|
- outprintf(minst->heap, "%c", *p++);
|
|
- }
|
|
- outprintf(minst->heap, "%s", sepr);
|
|
- pos += 1 + len + strlen(sepr);
|
|
- }
|
|
+ uint count = r_size(&minst->lib_path.list);
|
|
+ uint i;
|
|
+ int pos = 100;
|
|
+ char fsepr[3];
|
|
+
|
|
+ fsepr[0] = ' ', fsepr[1] = gp_file_name_list_separator,
|
|
+ fsepr[2] = 0;
|
|
+ for (i = 0; i < count; ++i) {
|
|
+ const ref *prdir =
|
|
+ minst->lib_path.list.value.refs + i;
|
|
+ uint len = r_size(prdir);
|
|
+ const char *sepr = (i == count - 1 ? "" : fsepr);
|
|
+
|
|
+ if (1 + pos + strlen(sepr) + len > 76)
|
|
+ outprintf(minst->heap, "\n "), pos = 2;
|
|
+ outprintf(minst->heap, " ");
|
|
+ /*
|
|
+ * This is really ugly, but it's necessary because some
|
|
+ * platforms rely on all console output being funneled through
|
|
+ * outprintf. We wish we could just do:
|
|
+ fwrite(prdir->value.bytes, 1, len, minst->fstdout);
|
|
+ */
|
|
+ {
|
|
+ const char *p = (const char *)prdir->value.bytes;
|
|
+ uint j;
|
|
+
|
|
+ for (j = len; j; j--)
|
|
+ outprintf(minst->heap, "%c", *p++);
|
|
+ }
|
|
+ outprintf(minst->heap, "%s", sepr);
|
|
+ pos += 1 + len + strlen(sepr);
|
|
+ }
|
|
}
|
|
outprintf(minst->heap, "\n");
|
|
}
|
|
@@ -1086,8 +1086,8 @@ print_help_trailer(const gs_main_instanc
|
|
const char *use_htm = "Use.htm", *p = buffer;
|
|
uint blen = sizeof(buffer);
|
|
|
|
- if (gp_file_name_combine(gs_doc_directory, strlen(gs_doc_directory),
|
|
- use_htm, strlen(use_htm), false, buffer, &blen) != gp_combine_success)
|
|
- p = use_htm;
|
|
+ if (gp_file_name_combine(gs_doc_directory, strlen(gs_doc_directory),
|
|
+ use_htm, strlen(use_htm), false, buffer, &blen) != gp_combine_success)
|
|
+ p = use_htm;
|
|
outprintf(minst->heap, help_trailer, p);
|
|
}
|
|
diff -up ghostscript-9.00/psi/imain.c.scan_token ghostscript-9.00/psi/imain.c
|
|
--- ghostscript-9.00/psi/imain.c.scan_token 2010-05-04 19:47:12.000000000 +0100
|
|
+++ ghostscript-9.00/psi/imain.c 2011-01-14 17:17:36.221792489 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -18,51 +18,51 @@
|
|
#include "string_.h"
|
|
#include "ghost.h"
|
|
#include "gp.h"
|
|
-#include "gscdefs.h" /* for gs_init_file */
|
|
+#include "gscdefs.h" /* for gs_init_file */
|
|
#include "gslib.h"
|
|
-#include "gsmatrix.h" /* for gxdevice.h */
|
|
-#include "gsutil.h" /* for bytes_compare */
|
|
+#include "gsmatrix.h" /* for gxdevice.h */
|
|
+#include "gsutil.h" /* for bytes_compare */
|
|
#include "gxdevice.h"
|
|
#include "gxalloc.h"
|
|
-#include "gxiodev.h" /* for iodev struct */
|
|
+#include "gxiodev.h" /* for iodev struct */
|
|
#include "gzstate.h"
|
|
#include "ierrors.h"
|
|
#include "oper.h"
|
|
-#include "iconf.h" /* for gs_init_* imports */
|
|
+#include "iconf.h" /* for gs_init_* imports */
|
|
#include "idebug.h"
|
|
#include "idict.h"
|
|
-#include "iname.h" /* for name_init */
|
|
+#include "iname.h" /* for name_init */
|
|
#include "dstack.h"
|
|
#include "estack.h"
|
|
-#include "ostack.h" /* put here for files.h */
|
|
-#include "stream.h" /* for files.h */
|
|
+#include "ostack.h" /* put here for files.h */
|
|
+#include "stream.h" /* for files.h */
|
|
#include "files.h"
|
|
#include "ialloc.h"
|
|
#include "iinit.h"
|
|
-#include "strimpl.h" /* for sfilter.h */
|
|
-#include "sfilter.h" /* for iscan.h */
|
|
+#include "strimpl.h" /* for sfilter.h */
|
|
+#include "sfilter.h" /* for iscan.h */
|
|
#include "iscan.h"
|
|
#include "main.h"
|
|
#include "store.h"
|
|
-#include "isave.h" /* for prototypes */
|
|
+#include "isave.h" /* for prototypes */
|
|
#include "interp.h"
|
|
#include "ivmspace.h"
|
|
-#include "idisp.h" /* for setting display device callback */
|
|
+#include "idisp.h" /* for setting display device callback */
|
|
#include "iplugin.h"
|
|
|
|
/* ------ Exported data ------ */
|
|
|
|
-/** using backpointers retrieve minst from any memory pointer
|
|
- *
|
|
+/** using backpointers retrieve minst from any memory pointer
|
|
+ *
|
|
*/
|
|
-gs_main_instance*
|
|
+gs_main_instance*
|
|
get_minst_from_memory(const gs_memory_t *mem)
|
|
{
|
|
#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;
|
|
+ return (gs_main_instance*)mem->gs_lib_ctx->top_of_system;
|
|
#endif
|
|
}
|
|
|
|
@@ -74,14 +74,14 @@ gs_main_alloc_instance(gs_memory_t *mem)
|
|
if (mem == NULL)
|
|
return NULL;
|
|
|
|
- minst = (gs_main_instance *)gs_alloc_bytes_immovable(mem,
|
|
+ minst = (gs_main_instance *)gs_alloc_bytes_immovable(mem,
|
|
sizeof(gs_main_instance),
|
|
"init_main_instance");
|
|
if (minst == NULL)
|
|
return NULL;
|
|
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 */
|
|
@@ -116,14 +116,14 @@ get_local_op_array(const gs_memory_t *me
|
|
|
|
static int gs_run_init_file(gs_main_instance *, int *, ref *);
|
|
void print_resource_usage(const gs_main_instance *,
|
|
- gs_dual_memory_t *, const char *);
|
|
+ gs_dual_memory_t *, const char *);
|
|
|
|
/* ------ Initialization ------ */
|
|
|
|
/* 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)
|
|
+ int max_lib_paths)
|
|
{
|
|
ref *paths;
|
|
|
|
@@ -133,11 +133,11 @@ gs_main_init0(gs_main_instance * minst,
|
|
/* on incompatible processors. */
|
|
gp_init();
|
|
|
|
- /* Initialize the imager. */
|
|
+ /* Initialize the imager. */
|
|
# ifndef PSI_INCLUDED
|
|
/* Reset debugging flags */
|
|
memset(gs_debug, 0, 128);
|
|
- gs_log_errors = 0; /* gs_debug['#'] = 0 */
|
|
+ gs_log_errors = 0; /* gs_debug['#'] = 0 */
|
|
# else
|
|
/* plmain settings remain in effect */
|
|
# endif
|
|
@@ -145,16 +145,16 @@ gs_main_init0(gs_main_instance * minst,
|
|
|
|
/* Initialize the file search paths. */
|
|
paths = (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref),
|
|
- "lib_path array");
|
|
+ "lib_path array");
|
|
if (paths == 0) {
|
|
- gs_lib_finit(1, e_VMerror, minst->heap);
|
|
- return_error(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(minst->heap, max_lib_paths, sizeof(ref),
|
|
- "lib_path array"));
|
|
+ (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);
|
|
+ minst->lib_path.container.value.refs);
|
|
minst->lib_path.env = 0;
|
|
minst->lib_path.final = 0;
|
|
minst->lib_path.count = 0;
|
|
@@ -171,42 +171,42 @@ gs_main_init1(gs_main_instance * minst)
|
|
extern init_proc(gs_iodev_init);
|
|
|
|
if (minst->init_done < 1) {
|
|
- gs_dual_memory_t idmem;
|
|
- int code =
|
|
- ialloc_init(&idmem, minst->heap,
|
|
- minst->memory_chunk_size, gs_have_level2());
|
|
-
|
|
- if (code < 0)
|
|
- return code;
|
|
- code = gs_lib_init1((gs_memory_t *)idmem.space_system);
|
|
- if (code < 0)
|
|
- return code;
|
|
- alloc_save_init(&idmem);
|
|
- {
|
|
- gs_memory_t *mem = (gs_memory_t *)idmem.space_system;
|
|
- name_table *nt = names_init(minst->name_table_size,
|
|
- idmem.space_system);
|
|
-
|
|
- if (nt == 0)
|
|
- return_error(e_VMerror);
|
|
- mem->gs_lib_ctx->gs_name_table = nt;
|
|
- code = gs_register_struct_root(mem, NULL,
|
|
- (void **)&mem->gs_lib_ctx->gs_name_table,
|
|
- "the_gs_name_table");
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
- code = obj_init(&minst->i_ctx_p, &idmem); /* requires name_init */
|
|
- if (code < 0)
|
|
- return code;
|
|
+ gs_dual_memory_t idmem;
|
|
+ int code =
|
|
+ ialloc_init(&idmem, minst->heap,
|
|
+ minst->memory_chunk_size, gs_have_level2());
|
|
+
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ code = gs_lib_init1((gs_memory_t *)idmem.space_system);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ alloc_save_init(&idmem);
|
|
+ {
|
|
+ gs_memory_t *mem = (gs_memory_t *)idmem.space_system;
|
|
+ name_table *nt = names_init(minst->name_table_size,
|
|
+ idmem.space_system);
|
|
+
|
|
+ if (nt == 0)
|
|
+ return_error(e_VMerror);
|
|
+ mem->gs_lib_ctx->gs_name_table = nt;
|
|
+ code = gs_register_struct_root(mem, NULL,
|
|
+ (void **)&mem->gs_lib_ctx->gs_name_table,
|
|
+ "the_gs_name_table");
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
+ code = obj_init(&minst->i_ctx_p, &idmem); /* requires name_init */
|
|
+ if (code < 0)
|
|
+ return code;
|
|
code = i_plugin_init(minst->i_ctx_p);
|
|
- if (code < 0)
|
|
- return code;
|
|
- i_ctx_p = minst->i_ctx_p;
|
|
- code = gs_iodev_init(imemory);
|
|
- if (code < 0)
|
|
- return code;
|
|
- minst->init_done = 1;
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ i_ctx_p = minst->i_ctx_p;
|
|
+ code = gs_iodev_init(imemory);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ minst->init_done = 1;
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -220,7 +220,7 @@ init2_make_string_array(i_ctx_t *i_ctx_p
|
|
|
|
for (; ifp->value.bytes != 0; ifp++);
|
|
make_tasv(&ifa, t_array, a_readonly | avm_foreign,
|
|
- ifp - srefs, const_refs, srefs);
|
|
+ ifp - srefs, const_refs, srefs);
|
|
initial_enter_name(aname, &ifa);
|
|
}
|
|
|
|
@@ -229,16 +229,16 @@ init2_make_string_array(i_ctx_t *i_ctx_p
|
|
* callouts were handled here instead of in the stream processing.
|
|
*/
|
|
static int
|
|
-gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
|
|
- int *pexit_code, ref * perror_object)
|
|
+gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
|
|
+ int *pexit_code, ref * perror_object)
|
|
{
|
|
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);
|
|
+ code = gs_interpret(&minst->i_ctx_p, pref,
|
|
+ user_errors, pexit_code, perror_object);
|
|
return code;
|
|
}
|
|
|
|
@@ -249,53 +249,53 @@ gs_main_init2(gs_main_instance * minst)
|
|
int code = gs_main_init1(minst);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
i_ctx_p = minst->i_ctx_p;
|
|
if (minst->init_done < 2) {
|
|
- int code, exit_code;
|
|
- ref error_object;
|
|
+ int code, exit_code;
|
|
+ ref error_object;
|
|
|
|
- code = zop_init(i_ctx_p);
|
|
- if (code < 0)
|
|
- return code;
|
|
- code = op_init(i_ctx_p); /* requires obj_init */
|
|
- if (code < 0)
|
|
- return code;
|
|
-
|
|
- /* Set up the array of additional initialization files. */
|
|
- init2_make_string_array(i_ctx_p, gs_init_file_array, "INITFILES");
|
|
- /* Set up the array of emulator names. */
|
|
- init2_make_string_array(i_ctx_p, gs_emulator_name_array, "EMULATORS");
|
|
- /* Pass the search path. */
|
|
- code = initial_enter_name("LIBPATH", &minst->lib_path.list);
|
|
- if (code < 0)
|
|
- return code;
|
|
-
|
|
- /* Execute the standard initialization file. */
|
|
- code = gs_run_init_file(minst, &exit_code, &error_object);
|
|
- if (code < 0)
|
|
- 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)
|
|
- if ((code = display_set_callback(minst, minst->display)) < 0)
|
|
- return code;
|
|
+ code = zop_init(i_ctx_p);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ code = op_init(i_ctx_p); /* requires obj_init */
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+
|
|
+ /* Set up the array of additional initialization files. */
|
|
+ init2_make_string_array(i_ctx_p, gs_init_file_array, "INITFILES");
|
|
+ /* Set up the array of emulator names. */
|
|
+ init2_make_string_array(i_ctx_p, gs_emulator_name_array, "EMULATORS");
|
|
+ /* Pass the search path. */
|
|
+ code = initial_enter_name("LIBPATH", &minst->lib_path.list);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+
|
|
+ /* Execute the standard initialization file. */
|
|
+ code = gs_run_init_file(minst, &exit_code, &error_object);
|
|
+ if (code < 0)
|
|
+ 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)
|
|
+ if ((code = display_set_callback(minst, minst->display)) < 0)
|
|
+ return code;
|
|
|
|
#ifndef PSI_INCLUDED
|
|
- if ((code = gs_main_run_string(minst,
|
|
- "JOBSERVER "
|
|
- " { false 0 .startnewjob } "
|
|
- " { NOOUTERSAVE not { save pop } if } "
|
|
- "ifelse", 0, &exit_code,
|
|
- &error_object)) < 0)
|
|
- return code;
|
|
+ if ((code = gs_main_run_string(minst,
|
|
+ "JOBSERVER "
|
|
+ " { false 0 .startnewjob } "
|
|
+ " { NOOUTERSAVE not { save pop } if } "
|
|
+ "ifelse", 0, &exit_code,
|
|
+ &error_object)) < 0)
|
|
+ return code;
|
|
#endif /* PSI_INCLUDED */
|
|
}
|
|
if (gs_debug_c(':'))
|
|
- print_resource_usage(minst, &gs_imemory, "Start");
|
|
+ print_resource_usage(minst, &gs_imemory, "Start");
|
|
gp_readline_init(&minst->readline_data, imemory_system);
|
|
return 0;
|
|
}
|
|
@@ -311,23 +311,23 @@ file_path_add(gs_file_path * pfp, const
|
|
const char *dpath = dirs;
|
|
|
|
if (dirs == 0)
|
|
- return 0;
|
|
- for (;;) { /* Find the end of the next directory name. */
|
|
- const char *npath = dpath;
|
|
-
|
|
- while (*npath != 0 && *npath != gp_file_name_list_separator)
|
|
- npath++;
|
|
- if (npath > dpath) {
|
|
- if (len == r_size(&pfp->container))
|
|
- return_error(e_limitcheck);
|
|
- make_const_string(&pfp->container.value.refs[len],
|
|
- avm_foreign | a_readonly,
|
|
- npath - dpath, (const byte *)dpath);
|
|
- ++len;
|
|
- }
|
|
- if (!*npath)
|
|
- break;
|
|
- dpath = npath + 1;
|
|
+ return 0;
|
|
+ for (;;) { /* Find the end of the next directory name. */
|
|
+ const char *npath = dpath;
|
|
+
|
|
+ while (*npath != 0 && *npath != gp_file_name_list_separator)
|
|
+ npath++;
|
|
+ if (npath > dpath) {
|
|
+ if (len == r_size(&pfp->container))
|
|
+ return_error(e_limitcheck);
|
|
+ make_const_string(&pfp->container.value.refs[len],
|
|
+ avm_foreign | a_readonly,
|
|
+ npath - dpath, (const byte *)dpath);
|
|
+ ++len;
|
|
+ }
|
|
+ if (!*npath)
|
|
+ break;
|
|
+ dpath = npath + 1;
|
|
}
|
|
r_set_size(&pfp->list, len);
|
|
return 0;
|
|
@@ -340,17 +340,17 @@ gs_main_add_lib_path(gs_main_instance *
|
|
/* Account for the possibility that the first element */
|
|
/* is gp_current_directory name added by set_lib_paths. */
|
|
int first_is_here =
|
|
- (r_size(&minst->lib_path.list) != 0 &&
|
|
- minst->lib_path.container.value.refs[0].value.bytes ==
|
|
- (const byte *)gp_current_directory_name ? 1 : 0);
|
|
+ (r_size(&minst->lib_path.list) != 0 &&
|
|
+ minst->lib_path.container.value.refs[0].value.bytes ==
|
|
+ (const byte *)gp_current_directory_name ? 1 : 0);
|
|
int code;
|
|
|
|
r_set_size(&minst->lib_path.list, minst->lib_path.count +
|
|
- first_is_here);
|
|
+ first_is_here);
|
|
code = file_path_add(&minst->lib_path, lpath);
|
|
minst->lib_path.count = r_size(&minst->lib_path.list) - first_is_here;
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
return gs_main_set_lib_paths(minst);
|
|
}
|
|
|
|
@@ -366,49 +366,49 @@ gs_main_set_lib_paths(gs_main_instance *
|
|
{
|
|
ref *paths = minst->lib_path.container.value.refs;
|
|
int first_is_here =
|
|
- (r_size(&minst->lib_path.list) != 0 &&
|
|
- paths[0].value.bytes == (const byte *)gp_current_directory_name ? 1 : 0);
|
|
+ (r_size(&minst->lib_path.list) != 0 &&
|
|
+ paths[0].value.bytes == (const byte *)gp_current_directory_name ? 1 : 0);
|
|
int code = 0;
|
|
int count = minst->lib_path.count;
|
|
int i, have_rom_device = 0;
|
|
|
|
if (minst->search_here_first) {
|
|
- if (!(first_is_here ||
|
|
- (r_size(&minst->lib_path.list) != 0 &&
|
|
- !bytes_compare((const byte *)gp_current_directory_name,
|
|
- strlen(gp_current_directory_name),
|
|
- paths[0].value.bytes,
|
|
- r_size(&paths[0]))))
|
|
- ) {
|
|
- memmove(paths + 1, paths, count * sizeof(*paths));
|
|
- make_const_string(paths, avm_foreign | a_readonly,
|
|
- strlen(gp_current_directory_name),
|
|
- (const byte *)gp_current_directory_name);
|
|
- }
|
|
+ if (!(first_is_here ||
|
|
+ (r_size(&minst->lib_path.list) != 0 &&
|
|
+ !bytes_compare((const byte *)gp_current_directory_name,
|
|
+ strlen(gp_current_directory_name),
|
|
+ paths[0].value.bytes,
|
|
+ r_size(&paths[0]))))
|
|
+ ) {
|
|
+ memmove(paths + 1, paths, count * sizeof(*paths));
|
|
+ make_const_string(paths, avm_foreign | a_readonly,
|
|
+ strlen(gp_current_directory_name),
|
|
+ (const byte *)gp_current_directory_name);
|
|
+ }
|
|
} else {
|
|
- if (first_is_here)
|
|
- memmove(paths, paths + 1, count * sizeof(*paths));
|
|
+ if (first_is_here)
|
|
+ memmove(paths, paths + 1, count * sizeof(*paths));
|
|
}
|
|
r_set_size(&minst->lib_path.list,
|
|
- count + (minst->search_here_first ? 1 : 0));
|
|
+ count + (minst->search_here_first ? 1 : 0));
|
|
if (minst->lib_path.env != 0)
|
|
- code = file_path_add(&minst->lib_path, minst->lib_path.env);
|
|
+ code = file_path_add(&minst->lib_path, minst->lib_path.env);
|
|
/* now put the %rom%lib/ device path before the gs_lib_default_path on the list */
|
|
for (i = 0; i < gx_io_device_table_count; i++) {
|
|
- const gx_io_device *iodev = gx_io_device_table[i];
|
|
- const char *dname = iodev->dname;
|
|
+ const gx_io_device *iodev = gx_io_device_table[i];
|
|
+ const char *dname = iodev->dname;
|
|
|
|
- if (dname && strlen(dname) == 5 && !memcmp("%rom%", dname, 5)) {
|
|
- have_rom_device = 1;
|
|
- break;
|
|
- }
|
|
+ if (dname && strlen(dname) == 5 && !memcmp("%rom%", dname, 5)) {
|
|
+ have_rom_device = 1;
|
|
+ break;
|
|
+ }
|
|
}
|
|
if (have_rom_device && code >= 0) {
|
|
- code = file_path_add(&minst->lib_path, "%rom%Resource/Init/");
|
|
- code = file_path_add(&minst->lib_path, "%rom%lib/");
|
|
+ code = file_path_add(&minst->lib_path, "%rom%Resource/Init/");
|
|
+ code = file_path_add(&minst->lib_path, "%rom%lib/");
|
|
}
|
|
if (minst->lib_path.final != 0 && code >= 0)
|
|
- code = file_path_add(&minst->lib_path, minst->lib_path.final);
|
|
+ code = file_path_add(&minst->lib_path, minst->lib_path.final);
|
|
return code;
|
|
}
|
|
|
|
@@ -424,9 +424,9 @@ gs_main_lib_open(gs_main_instance * mins
|
|
uint len;
|
|
|
|
return lib_file_open(&minst->lib_path, imemory,
|
|
- NULL, /* Don't check permissions here, because permlist
|
|
- isn't ready running init files. */
|
|
- file_name, strlen(file_name), fn, maxfn, &len, pfile);
|
|
+ NULL, /* Don't check permissions here, because permlist
|
|
+ isn't ready running init files. */
|
|
+ file_name, strlen(file_name), fn, maxfn, &len, pfile);
|
|
}
|
|
|
|
/* Open and execute a file. */
|
|
@@ -437,19 +437,19 @@ gs_main_run_file(gs_main_instance * mins
|
|
int code = gs_main_run_file_open(minst, file_name, &initial_file);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
return gs_main_interpret(minst, &initial_file, user_errors,
|
|
- pexit_code, perror_object);
|
|
+ pexit_code, perror_object);
|
|
}
|
|
int
|
|
gs_main_run_file_open(gs_main_instance * minst, const char *file_name, ref * pfref)
|
|
{
|
|
gs_main_set_lib_paths(minst);
|
|
if (gs_main_lib_open(minst, file_name, pfref) < 0) {
|
|
- emprintf1(minst->heap,
|
|
+ emprintf1(minst->heap,
|
|
"Can't find initialization file %s.\n",
|
|
file_name);
|
|
- return_error(e_Fatal);
|
|
+ return_error(e_Fatal);
|
|
}
|
|
r_set_attrs(pfref, a_execute + a_executable);
|
|
return 0;
|
|
@@ -468,57 +468,57 @@ gs_run_init_file(gs_main_instance * mins
|
|
gs_main_set_lib_paths(minst);
|
|
code = gs_main_run_file_open(minst, gs_init_file, &ifile);
|
|
if (code < 0) {
|
|
- *pexit_code = 255;
|
|
- return code;
|
|
+ *pexit_code = 255;
|
|
+ return code;
|
|
}
|
|
/* Check to make sure the first token is an integer */
|
|
/* (for the version number check.) */
|
|
- scanner_init(&state, &ifile);
|
|
- code = scan_token(i_ctx_p, &first_token, &state);
|
|
+ gs_scanner_init(&state, &ifile);
|
|
+ code = gs_scan_token(i_ctx_p, &first_token, &state);
|
|
if (code != 0 || !r_has_type(&first_token, t_integer)) {
|
|
- emprintf1(minst->heap,
|
|
+ emprintf1(minst->heap,
|
|
"Initialization file %s does not begin with an integer.\n",
|
|
gs_init_file);
|
|
- *pexit_code = 255;
|
|
- return_error(e_Fatal);
|
|
+ *pexit_code = 255;
|
|
+ return_error(e_Fatal);
|
|
}
|
|
*++osp = first_token;
|
|
r_set_attrs(&ifile, a_executable);
|
|
return gs_main_interpret(minst, &ifile, minst->user_errors,
|
|
- pexit_code, perror_object);
|
|
+ pexit_code, perror_object);
|
|
}
|
|
|
|
/* Run a string. */
|
|
int
|
|
gs_main_run_string(gs_main_instance * minst, const char *str, int user_errors,
|
|
- int *pexit_code, ref * perror_object)
|
|
+ int *pexit_code, ref * perror_object)
|
|
{
|
|
return gs_main_run_string_with_length(minst, str, (uint) strlen(str),
|
|
- user_errors,
|
|
- pexit_code, perror_object);
|
|
+ user_errors,
|
|
+ pexit_code, perror_object);
|
|
}
|
|
int
|
|
gs_main_run_string_with_length(gs_main_instance * minst, const char *str,
|
|
- uint length, int user_errors, int *pexit_code, ref * perror_object)
|
|
+ uint length, int user_errors, int *pexit_code, ref * perror_object)
|
|
{
|
|
int code;
|
|
|
|
code = gs_main_run_string_begin(minst, user_errors,
|
|
- pexit_code, perror_object);
|
|
+ pexit_code, perror_object);
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
code = gs_main_run_string_continue(minst, str, length, user_errors,
|
|
- pexit_code, perror_object);
|
|
+ pexit_code, perror_object);
|
|
if (code != e_NeedInput)
|
|
- return code;
|
|
+ return code;
|
|
return gs_main_run_string_end(minst, user_errors,
|
|
- pexit_code, perror_object);
|
|
+ pexit_code, perror_object);
|
|
}
|
|
|
|
/* Set up for a suspendable run_string. */
|
|
int
|
|
gs_main_run_string_begin(gs_main_instance * minst, int user_errors,
|
|
- int *pexit_code, ref * perror_object)
|
|
+ int *pexit_code, ref * perror_object)
|
|
{
|
|
const char *setup = ".runstringbegin";
|
|
ref rstr;
|
|
@@ -526,35 +526,35 @@ gs_main_run_string_begin(gs_main_instanc
|
|
|
|
gs_main_set_lib_paths(minst);
|
|
make_const_string(&rstr, avm_foreign | a_readonly | a_executable,
|
|
- strlen(setup), (const byte *)setup);
|
|
+ strlen(setup), (const byte *)setup);
|
|
code = gs_main_interpret(minst, &rstr, user_errors, pexit_code,
|
|
- perror_object);
|
|
+ perror_object);
|
|
return (code == e_NeedInput ? 0 : code == 0 ? e_Fatal : code);
|
|
}
|
|
/* Continue running a string with the option of suspending. */
|
|
int
|
|
gs_main_run_string_continue(gs_main_instance * minst, const char *str,
|
|
- uint length, int user_errors, int *pexit_code, ref * perror_object)
|
|
+ uint length, int user_errors, int *pexit_code, ref * perror_object)
|
|
{
|
|
ref rstr;
|
|
|
|
if (length == 0)
|
|
- return 0; /* empty string signals EOF */
|
|
+ return 0; /* empty string signals EOF */
|
|
make_const_string(&rstr, avm_foreign | a_readonly, length,
|
|
- (const byte *)str);
|
|
+ (const byte *)str);
|
|
return gs_main_interpret(minst, &rstr, user_errors, pexit_code,
|
|
- perror_object);
|
|
+ perror_object);
|
|
}
|
|
/* Signal EOF when suspended. */
|
|
int
|
|
gs_main_run_string_end(gs_main_instance * minst, int user_errors,
|
|
- int *pexit_code, ref * perror_object)
|
|
+ int *pexit_code, ref * perror_object)
|
|
{
|
|
ref rstr;
|
|
|
|
make_empty_const_string(&rstr, avm_foreign | a_readonly);
|
|
return gs_main_interpret(minst, &rstr, user_errors, pexit_code,
|
|
- perror_object);
|
|
+ perror_object);
|
|
}
|
|
|
|
/* ------ Operand stack access ------ */
|
|
@@ -568,7 +568,7 @@ push_value(gs_main_instance *minst, ref
|
|
int code = ref_stack_push(&o_stack, 1);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
*ref_stack_index(&o_stack, 0L) = *pvalue;
|
|
return 0;
|
|
}
|
|
@@ -602,12 +602,12 @@ gs_push_real(gs_main_instance * minst, f
|
|
|
|
int
|
|
gs_push_string(gs_main_instance * minst, byte * chars, uint length,
|
|
- bool read_only)
|
|
+ bool read_only)
|
|
{
|
|
ref vref;
|
|
|
|
make_string(&vref, avm_foreign | (read_only ? a_readonly : a_all),
|
|
- length, (byte *) chars);
|
|
+ length, (byte *) chars);
|
|
return push_value(minst, &vref);
|
|
}
|
|
|
|
@@ -615,7 +615,7 @@ static int
|
|
pop_value(i_ctx_t *i_ctx_p, ref * pvalue)
|
|
{
|
|
if (!ref_stack_count(&o_stack))
|
|
- return_error(e_stackunderflow);
|
|
+ return_error(e_stackunderflow);
|
|
*pvalue = *ref_stack_index(&o_stack, 0L);
|
|
return 0;
|
|
}
|
|
@@ -628,7 +628,7 @@ gs_pop_boolean(gs_main_instance * minst,
|
|
int code = pop_value(i_ctx_p, &vref);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
check_type_only(vref, t_boolean);
|
|
*result = vref.value.boolval;
|
|
ref_stack_pop(&o_stack, 1);
|
|
@@ -643,7 +643,7 @@ gs_pop_integer(gs_main_instance * minst,
|
|
int code = pop_value(i_ctx_p, &vref);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
check_type_only(vref, t_integer);
|
|
*result = vref.value.intval;
|
|
ref_stack_pop(&o_stack, 1);
|
|
@@ -658,16 +658,16 @@ gs_pop_real(gs_main_instance * minst, fl
|
|
int code = pop_value(i_ctx_p, &vref);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
switch (r_type(&vref)) {
|
|
- case t_real:
|
|
- *result = vref.value.realval;
|
|
- break;
|
|
- case t_integer:
|
|
- *result = (float)(vref.value.intval);
|
|
- break;
|
|
- default:
|
|
- return_error(e_typecheck);
|
|
+ case t_real:
|
|
+ *result = vref.value.realval;
|
|
+ break;
|
|
+ case t_integer:
|
|
+ *result = (float)(vref.value.intval);
|
|
+ break;
|
|
+ default:
|
|
+ return_error(e_typecheck);
|
|
}
|
|
ref_stack_pop(&o_stack, 1);
|
|
return 0;
|
|
@@ -681,19 +681,19 @@ gs_pop_string(gs_main_instance * minst,
|
|
int code = pop_value(i_ctx_p, &vref);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
switch (r_type(&vref)) {
|
|
- case t_name:
|
|
- name_string_ref(minst->heap, &vref, &vref);
|
|
- code = 1;
|
|
- goto rstr;
|
|
- case t_string:
|
|
- code = (r_has_attr(&vref, a_write) ? 0 : 1);
|
|
- rstr:result->data = vref.value.bytes;
|
|
- result->size = r_size(&vref);
|
|
- break;
|
|
- default:
|
|
- return_error(e_typecheck);
|
|
+ case t_name:
|
|
+ name_string_ref(minst->heap, &vref, &vref);
|
|
+ code = 1;
|
|
+ goto rstr;
|
|
+ case t_string:
|
|
+ code = (r_has_attr(&vref, a_write) ? 0 : 1);
|
|
+ rstr:result->data = vref.value.bytes;
|
|
+ result->size = r_size(&vref);
|
|
+ break;
|
|
+ default:
|
|
+ return_error(e_typecheck);
|
|
}
|
|
ref_stack_pop(&o_stack, 1);
|
|
return code;
|
|
@@ -702,10 +702,10 @@ gs_pop_string(gs_main_instance * minst,
|
|
/* ------ Termination ------ */
|
|
|
|
/* Get the names of temporary files.
|
|
- * Each name is null terminated, and the last name is
|
|
+ * Each name is null terminated, and the last name is
|
|
* terminated by a double null.
|
|
* We retrieve the names of temporary files just before
|
|
- * the interpreter finishes, and then delete the files
|
|
+ * the interpreter finishes, and then delete the files
|
|
* after the interpreter has closed all files.
|
|
*/
|
|
static char *gs_main_tempnames(gs_main_instance *minst)
|
|
@@ -713,7 +713,7 @@ static char *gs_main_tempnames(gs_main_i
|
|
i_ctx_t *i_ctx_p = minst->i_ctx_p;
|
|
ref *SAFETY;
|
|
ref *tempfiles;
|
|
- ref keyval[2]; /* for key and value */
|
|
+ ref keyval[2]; /* for key and value */
|
|
char *tempnames = NULL;
|
|
int i;
|
|
int idict;
|
|
@@ -722,29 +722,29 @@ static char *gs_main_tempnames(gs_main_i
|
|
uint size;
|
|
if (minst->init_done >= 2) {
|
|
if (dict_find_string(systemdict, "SAFETY", &SAFETY) <= 0 ||
|
|
- dict_find_string(SAFETY, "tempfiles", &tempfiles) <= 0)
|
|
- return NULL;
|
|
- /* get lengths of temporary filenames */
|
|
- idict = dict_first(tempfiles);
|
|
- while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) {
|
|
- if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0)
|
|
- len += size + 1;
|
|
- }
|
|
- if (len != 0)
|
|
- tempnames = (char *)malloc(len+1);
|
|
- if (tempnames) {
|
|
- memset(tempnames, 0, len+1);
|
|
- /* copy temporary filenames */
|
|
- idict = dict_first(tempfiles);
|
|
- i = 0;
|
|
- while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) {
|
|
- if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0) {
|
|
- memcpy(tempnames+i, (const char *)data, size);
|
|
- i+= size;
|
|
- tempnames[i++] = '\0';
|
|
- }
|
|
- }
|
|
- }
|
|
+ dict_find_string(SAFETY, "tempfiles", &tempfiles) <= 0)
|
|
+ return NULL;
|
|
+ /* get lengths of temporary filenames */
|
|
+ idict = dict_first(tempfiles);
|
|
+ while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) {
|
|
+ if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0)
|
|
+ len += size + 1;
|
|
+ }
|
|
+ if (len != 0)
|
|
+ tempnames = (char *)malloc(len+1);
|
|
+ if (tempnames) {
|
|
+ memset(tempnames, 0, len+1);
|
|
+ /* copy temporary filenames */
|
|
+ idict = dict_first(tempfiles);
|
|
+ i = 0;
|
|
+ while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) {
|
|
+ if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0) {
|
|
+ memcpy(tempnames+i, (const char *)data, size);
|
|
+ i+= size;
|
|
+ tempnames[i++] = '\0';
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
return tempnames;
|
|
}
|
|
@@ -768,7 +768,7 @@ gs_main_finit(gs_main_instance * minst,
|
|
* alloc_restore_all will close dynamically allocated devices.
|
|
*/
|
|
tempnames = gs_main_tempnames(minst);
|
|
- /*
|
|
+ /*
|
|
* Close the "main" device, because it may need to write out
|
|
* data before destruction. pdfwrite needs so.
|
|
*/
|
|
@@ -876,7 +876,7 @@ gs_abort(const gs_memory_t *mem)
|
|
* but more often than not, that will trip another abort and create
|
|
* an infinite recursion. So just abort without trying to cleanup.
|
|
*/
|
|
- gp_do_exit(1);
|
|
+ gp_do_exit(1);
|
|
}
|
|
|
|
/* ------ Debugging ------ */
|
|
@@ -884,38 +884,38 @@ gs_abort(const gs_memory_t *mem)
|
|
/* Print resource usage statistics. */
|
|
void
|
|
print_resource_usage(const gs_main_instance * minst, gs_dual_memory_t * dmem,
|
|
- const char *msg)
|
|
+ const char *msg)
|
|
{
|
|
ulong allocated = 0, used = 0;
|
|
long utime[2];
|
|
|
|
gp_get_realtime(utime);
|
|
{
|
|
- int i;
|
|
+ int i;
|
|
|
|
- for (i = 0; i < countof(dmem->spaces_indexed); ++i) {
|
|
- gs_ref_memory_t *mem = dmem->spaces_indexed[i];
|
|
+ for (i = 0; i < countof(dmem->spaces_indexed); ++i) {
|
|
+ gs_ref_memory_t *mem = dmem->spaces_indexed[i];
|
|
|
|
- if (mem != 0 && (i == 0 || mem != dmem->spaces_indexed[i - 1])) {
|
|
- gs_memory_status_t status;
|
|
- gs_ref_memory_t *mem_stable =
|
|
- (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
|
|
-
|
|
- gs_memory_status((gs_memory_t *)mem, &status);
|
|
- allocated += status.allocated;
|
|
- used += status.used;
|
|
- if (mem_stable != mem) {
|
|
- gs_memory_status((gs_memory_t *)mem_stable, &status);
|
|
- allocated += status.allocated;
|
|
- used += status.used;
|
|
- }
|
|
- }
|
|
- }
|
|
+ if (mem != 0 && (i == 0 || mem != dmem->spaces_indexed[i - 1])) {
|
|
+ gs_memory_status_t status;
|
|
+ gs_ref_memory_t *mem_stable =
|
|
+ (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
|
|
+
|
|
+ gs_memory_status((gs_memory_t *)mem, &status);
|
|
+ allocated += status.allocated;
|
|
+ used += status.used;
|
|
+ if (mem_stable != mem) {
|
|
+ gs_memory_status((gs_memory_t *)mem_stable, &status);
|
|
+ allocated += status.allocated;
|
|
+ used += status.used;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
dprintf4("%% %s time = %g, memory allocated = %lu, used = %lu\n",
|
|
- msg, utime[0] - minst->base_time[0] +
|
|
- (utime[1] - minst->base_time[1]) / 1000000000.0,
|
|
- allocated, used);
|
|
+ msg, utime[0] - minst->base_time[0] +
|
|
+ (utime[1] - minst->base_time[1]) / 1000000000.0,
|
|
+ allocated, used);
|
|
}
|
|
|
|
/* Dump the stacks after interpretation */
|
|
@@ -924,12 +924,12 @@ gs_main_dump_stack(gs_main_instance *min
|
|
{
|
|
i_ctx_t *i_ctx_p = minst->i_ctx_p;
|
|
|
|
- zflush(i_ctx_p); /* force out buffered output */
|
|
+ zflush(i_ctx_p); /* force out buffered output */
|
|
dprintf1("\nUnexpected interpreter error %d.\n", code);
|
|
if (perror_object != 0) {
|
|
- dputs("Error object: ");
|
|
- debug_print_ref(minst->heap, perror_object);
|
|
- dputc('\n');
|
|
+ dputs("Error object: ");
|
|
+ debug_print_ref(minst->heap, perror_object);
|
|
+ dputc('\n');
|
|
}
|
|
debug_dump_stack(minst->heap, &o_stack, "Operand stack");
|
|
debug_dump_stack(minst->heap, &e_stack, "Execution stack");
|
|
diff -up ghostscript-9.00/psi/interp.c.scan_token ghostscript-9.00/psi/interp.c
|
|
--- ghostscript-9.00/psi/interp.c.scan_token 2010-05-06 17:00:28.000000000 +0100
|
|
+++ ghostscript-9.00/psi/interp.c 2011-01-14 17:16:12.602867532 +0000
|
|
@@ -16,8 +16,8 @@
|
|
#include "memory_.h"
|
|
#include "string_.h"
|
|
#include "ghost.h"
|
|
-#include "gsstruct.h" /* for iastruct.h */
|
|
-#include "gserrors.h" /* for gpcheck.h */
|
|
+#include "gsstruct.h" /* for iastruct.h */
|
|
+#include "gserrors.h" /* for gpcheck.h */
|
|
#include "stream.h"
|
|
#include "ierrors.h"
|
|
#include "estack.h"
|
|
@@ -26,24 +26,24 @@
|
|
#include "icontext.h"
|
|
#include "icremap.h"
|
|
#include "idebug.h"
|
|
-#include "igstate.h" /* for handling e_RemapColor */
|
|
+#include "igstate.h" /* for handling e_RemapColor */
|
|
#include "inamedef.h"
|
|
-#include "iname.h" /* for the_name_table */
|
|
+#include "iname.h" /* for the_name_table */
|
|
#include "interp.h"
|
|
#include "ipacked.h"
|
|
-#include "ostack.h" /* must precede iscan.h */
|
|
-#include "strimpl.h" /* for sfilter.h */
|
|
-#include "sfilter.h" /* for iscan.h */
|
|
+#include "ostack.h" /* must precede iscan.h */
|
|
+#include "strimpl.h" /* for sfilter.h */
|
|
+#include "sfilter.h" /* for iscan.h */
|
|
#include "iscan.h"
|
|
#include "iddict.h"
|
|
#include "isave.h"
|
|
#include "istack.h"
|
|
#include "itoken.h"
|
|
-#include "iutil.h" /* for array_get */
|
|
+#include "iutil.h" /* for array_get */
|
|
#include "ivmspace.h"
|
|
#include "iinit.h"
|
|
#include "dstack.h"
|
|
-#include "files.h" /* for file_check_read */
|
|
+#include "files.h" /* for file_check_read */
|
|
#include "oper.h"
|
|
#include "store.h"
|
|
#include "gpcheck.h"
|
|
@@ -86,16 +86,16 @@ call_operator(op_proc_t op_proc, i_ctx_t
|
|
if_debug1('!', "[!]operator %s\n", op_get_name_string(op_proc));
|
|
# else
|
|
if_debug3('!', "[!][es=%d os=%d]operator %s\n",
|
|
- esp-i_ctx_p->exec_stack.stack.bot,
|
|
- osp-i_ctx_p->op_stack.stack.bot,
|
|
- op_get_name_string(op_proc));
|
|
+ esp-i_ctx_p->exec_stack.stack.bot,
|
|
+ osp-i_ctx_p->op_stack.stack.bot,
|
|
+ op_get_name_string(op_proc));
|
|
# endif
|
|
# endif
|
|
code = op_proc(i_ctx_p);
|
|
# if defined(DEBUG_TRACE_PS_OPERATORS) && defined(SHOW_STACK_DEPTHS)
|
|
if_debug2('!', "[!][es=%d os=%d]\n",
|
|
- esp-i_ctx_p->exec_stack.stack.bot,
|
|
- osp-i_ctx_p->op_stack.stack.bot);
|
|
+ esp-i_ctx_p->exec_stack.stack.bot,
|
|
+ osp-i_ctx_p->op_stack.stack.bot);
|
|
# endif
|
|
return code; /* A good place for a conditional breakpoint. */
|
|
}
|
|
@@ -109,10 +109,10 @@ struct stats_interp_s {
|
|
long top;
|
|
long lit, lit_array, exec_array, exec_operator, exec_name;
|
|
long x_add, x_def, x_dup, x_exch, x_if, x_ifelse,
|
|
- x_index, x_pop, x_roll, x_sub;
|
|
+ x_index, x_pop, x_roll, x_sub;
|
|
long find_name, name_lit, name_proc, name_oparray, name_operator;
|
|
long p_full, p_exec_operator, p_exec_oparray, p_exec_non_x_operator,
|
|
- p_integer, p_lit_name, p_exec_name;
|
|
+ p_integer, p_lit_name, p_exec_name;
|
|
long p_find_name, p_name_lit, p_name_proc;
|
|
} stats_interp;
|
|
# define INCR(v) (++(stats_interp.v))
|
|
@@ -156,7 +156,7 @@ static int zcurrentstackprotect(i_ctx_t
|
|
* and therefore pushes 16 values).
|
|
*/
|
|
#define MIN_BLOCK_OSTACK 16
|
|
-const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK; /* for iinit.c */
|
|
+const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK; /* for iinit.c */
|
|
|
|
/*
|
|
* Define the initial maximum size of the execution stack (MaxExecStack
|
|
@@ -235,7 +235,7 @@ typedef enum {
|
|
} special_op_types;
|
|
|
|
#define num_special_ops ((int)tx_next_op - tx_op)
|
|
-const int gs_interp_num_special_ops = num_special_ops; /* for iinit.c */
|
|
+const int gs_interp_num_special_ops = num_special_ops; /* for iinit.c */
|
|
const int tx_next_index = tx_next_op;
|
|
|
|
/*
|
|
@@ -279,16 +279,16 @@ const op_def interp2_op_defs[] = {
|
|
/* Initialize the interpreter. */
|
|
int
|
|
gs_interp_init(i_ctx_t **pi_ctx_p, const ref *psystem_dict,
|
|
- gs_dual_memory_t *dmem)
|
|
+ gs_dual_memory_t *dmem)
|
|
{
|
|
/* Create and initialize a context state. */
|
|
gs_context_state_t *pcst = 0;
|
|
int code = context_state_alloc(&pcst, psystem_dict, dmem);
|
|
|
|
if (code >= 0)
|
|
- code = context_state_load(pcst);
|
|
+ code = context_state_load(pcst);
|
|
if (code < 0)
|
|
- lprintf1("Fatal error %d in gs_interp_init!", code);
|
|
+ lprintf1("Fatal error %d in gs_interp_init!", code);
|
|
*pi_ctx_p = pcst;
|
|
return code;
|
|
}
|
|
@@ -300,51 +300,51 @@ int
|
|
gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst)
|
|
{
|
|
gs_ref_memory_t *smem =
|
|
- (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
|
|
+ (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
|
|
ref stk;
|
|
|
|
#define REFS_SIZE_OSTACK OS_REFS_SIZE(MAX_OSTACK)
|
|
#define REFS_SIZE_ESTACK ES_REFS_SIZE(MAX_ESTACK)
|
|
#define REFS_SIZE_DSTACK DS_REFS_SIZE(MAX_DSTACK)
|
|
gs_alloc_ref_array(smem, &stk, 0,
|
|
- REFS_SIZE_OSTACK + REFS_SIZE_ESTACK +
|
|
- REFS_SIZE_DSTACK, "gs_interp_alloc_stacks");
|
|
+ REFS_SIZE_OSTACK + REFS_SIZE_ESTACK +
|
|
+ REFS_SIZE_DSTACK, "gs_interp_alloc_stacks");
|
|
|
|
{
|
|
- ref_stack_t *pos = &pcst->op_stack.stack;
|
|
+ ref_stack_t *pos = &pcst->op_stack.stack;
|
|
|
|
- r_set_size(&stk, REFS_SIZE_OSTACK);
|
|
- ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL,
|
|
- smem, NULL);
|
|
- ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow);
|
|
- ref_stack_set_max_count(pos, MAX_OSTACK);
|
|
- stk.value.refs += REFS_SIZE_OSTACK;
|
|
+ r_set_size(&stk, REFS_SIZE_OSTACK);
|
|
+ ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL,
|
|
+ smem, NULL);
|
|
+ ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow);
|
|
+ ref_stack_set_max_count(pos, MAX_OSTACK);
|
|
+ stk.value.refs += REFS_SIZE_OSTACK;
|
|
}
|
|
|
|
{
|
|
- ref_stack_t *pes = &pcst->exec_stack.stack;
|
|
- ref euop;
|
|
+ ref_stack_t *pes = &pcst->exec_stack.stack;
|
|
+ ref euop;
|
|
|
|
- r_set_size(&stk, REFS_SIZE_ESTACK);
|
|
- make_oper(&euop, 0, estack_underflow);
|
|
- ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop,
|
|
- smem, NULL);
|
|
- ref_stack_set_error_codes(pes, e_ExecStackUnderflow,
|
|
- e_execstackoverflow);
|
|
- /**************** E-STACK EXPANSION IS NYI. ****************/
|
|
- ref_stack_allow_expansion(pes, false);
|
|
- ref_stack_set_max_count(pes, MAX_ESTACK);
|
|
- stk.value.refs += REFS_SIZE_ESTACK;
|
|
+ r_set_size(&stk, REFS_SIZE_ESTACK);
|
|
+ make_oper(&euop, 0, estack_underflow);
|
|
+ ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop,
|
|
+ smem, NULL);
|
|
+ ref_stack_set_error_codes(pes, e_ExecStackUnderflow,
|
|
+ e_execstackoverflow);
|
|
+ /**************** E-STACK EXPANSION IS NYI. ****************/
|
|
+ ref_stack_allow_expansion(pes, false);
|
|
+ ref_stack_set_max_count(pes, MAX_ESTACK);
|
|
+ stk.value.refs += REFS_SIZE_ESTACK;
|
|
}
|
|
|
|
{
|
|
- ref_stack_t *pds = &pcst->dict_stack.stack;
|
|
+ ref_stack_t *pds = &pcst->dict_stack.stack;
|
|
|
|
- r_set_size(&stk, REFS_SIZE_DSTACK);
|
|
- ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL);
|
|
- ref_stack_set_error_codes(pds, e_dictstackunderflow,
|
|
- e_dictstackoverflow);
|
|
- ref_stack_set_max_count(pds, MAX_DSTACK);
|
|
+ r_set_size(&stk, REFS_SIZE_DSTACK);
|
|
+ ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL);
|
|
+ ref_stack_set_error_codes(pds, e_dictstackunderflow,
|
|
+ e_dictstackoverflow);
|
|
+ ref_stack_set_max_count(pds, MAX_DSTACK);
|
|
}
|
|
|
|
#undef REFS_SIZE_OSTACK
|
|
@@ -393,11 +393,11 @@ gs_interp_make_oper(ref * opref, op_proc
|
|
int i;
|
|
|
|
for (i = num_special_ops; i > 0 && proc != interp1_op_defs[i].proc; --i)
|
|
- DO_NOTHING;
|
|
+ DO_NOTHING;
|
|
if (i > 0)
|
|
- make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc);
|
|
+ make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc);
|
|
else
|
|
- make_tasv(opref, t_operator, a_executable, idx, opproc, proc);
|
|
+ make_tasv(opref, t_operator, a_executable, idx, opproc, proc);
|
|
}
|
|
|
|
/*
|
|
@@ -411,9 +411,9 @@ interp_reclaim(i_ctx_t **pi_ctx_p, int s
|
|
int code;
|
|
|
|
gs_register_struct_root(imemory_system, &ctx_root,
|
|
- (void **)pi_ctx_p, "interp_reclaim(pi_ctx_p)");
|
|
+ (void **)pi_ctx_p, "interp_reclaim(pi_ctx_p)");
|
|
code = (*idmemory->reclaim)(idmemory, space);
|
|
- i_ctx_p = *pi_ctx_p; /* may have moved */
|
|
+ i_ctx_p = *pi_ctx_p; /* may have moved */
|
|
gs_unregister_root(imemory_system, &ctx_root, "interp_reclaim(pi_ctx_p)");
|
|
return code;
|
|
}
|
|
@@ -431,16 +431,16 @@ interp_reclaim(i_ctx_t **pi_ctx_p, int s
|
|
static int gs_call_interp(i_ctx_t **, ref *, int, int *, ref *);
|
|
int
|
|
gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, int *pexit_code,
|
|
- ref * perror_object)
|
|
+ ref * perror_object)
|
|
{
|
|
i_ctx_t *i_ctx_p = *pi_ctx_p;
|
|
gs_gc_root_t error_root;
|
|
int code;
|
|
|
|
gs_register_ref_root(imemory_system, &error_root,
|
|
- (void **)&perror_object, "gs_interpret");
|
|
+ (void **)&perror_object, "gs_interpret");
|
|
code = gs_call_interp(pi_ctx_p, pref, user_errors, pexit_code,
|
|
- perror_object);
|
|
+ perror_object);
|
|
i_ctx_p = *pi_ctx_p;
|
|
gs_unregister_root(imemory_system, &error_root, "gs_interpret");
|
|
/* Avoid a dangling reference to a stack-allocated GC signal. */
|
|
@@ -449,7 +449,7 @@ gs_interpret(i_ctx_t **pi_ctx_p, ref * p
|
|
}
|
|
static int
|
|
gs_call_interp(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
|
|
- int *pexit_code, ref * perror_object)
|
|
+ int *pexit_code, ref * perror_object)
|
|
{
|
|
ref *epref = pref;
|
|
ref doref;
|
|
@@ -466,181 +466,181 @@ again:
|
|
/* Avoid a dangling error object that might get traced by a future GC. */
|
|
make_null(perror_object);
|
|
o_stack.requested = e_stack.requested = d_stack.requested = 0;
|
|
- while (gc_signal) { /* Some routine below triggered a GC. */
|
|
- gs_gc_root_t epref_root;
|
|
+ while (gc_signal) { /* Some routine below triggered a GC. */
|
|
+ gs_gc_root_t epref_root;
|
|
|
|
- gc_signal = 0;
|
|
- /* Make sure that doref will get relocated properly if */
|
|
- /* a garbage collection happens with epref == &doref. */
|
|
- gs_register_ref_root(imemory_system, &epref_root,
|
|
- (void **)&epref, "gs_call_interp(epref)");
|
|
- code = interp_reclaim(pi_ctx_p, -1);
|
|
- i_ctx_p = *pi_ctx_p;
|
|
- gs_unregister_root(imemory_system, &epref_root,
|
|
- "gs_call_interp(epref)");
|
|
- if (code < 0)
|
|
- return code;
|
|
+ gc_signal = 0;
|
|
+ /* Make sure that doref will get relocated properly if */
|
|
+ /* a garbage collection happens with epref == &doref. */
|
|
+ gs_register_ref_root(imemory_system, &epref_root,
|
|
+ (void **)&epref, "gs_call_interp(epref)");
|
|
+ code = interp_reclaim(pi_ctx_p, -1);
|
|
+ i_ctx_p = *pi_ctx_p;
|
|
+ gs_unregister_root(imemory_system, &epref_root,
|
|
+ "gs_call_interp(epref)");
|
|
+ if (code < 0)
|
|
+ return code;
|
|
}
|
|
code = interp(pi_ctx_p, epref, perror_object);
|
|
i_ctx_p = *pi_ctx_p;
|
|
if (!r_has_type(&i_ctx_p->error_object, t__invalid)) {
|
|
- *perror_object = i_ctx_p->error_object;
|
|
- make_t(&i_ctx_p->error_object, t__invalid);
|
|
+ *perror_object = i_ctx_p->error_object;
|
|
+ make_t(&i_ctx_p->error_object, t__invalid);
|
|
}
|
|
/* Prevent a dangling reference to the GC signal in ticks_left */
|
|
/* in the frame of interp, but be prepared to do a GC if */
|
|
/* an allocation in this routine asks for it. */
|
|
set_gc_signal(i_ctx_p, &gc_signal, 1);
|
|
- if (esp < esbot) /* popped guard entry */
|
|
- esp = esbot;
|
|
+ if (esp < esbot) /* popped guard entry */
|
|
+ esp = esbot;
|
|
switch (code) {
|
|
- case e_Fatal:
|
|
- *pexit_code = 255;
|
|
- return code;
|
|
- case e_Quit:
|
|
- *perror_object = osp[-1];
|
|
- *pexit_code = code = osp->value.intval;
|
|
- osp -= 2;
|
|
- return
|
|
- (code == 0 ? e_Quit :
|
|
- code < 0 && code > -100 ? code : e_Fatal);
|
|
- case e_InterpreterExit:
|
|
- return 0;
|
|
- case e_ExecStackUnderflow:
|
|
+ case e_Fatal:
|
|
+ *pexit_code = 255;
|
|
+ return code;
|
|
+ case e_Quit:
|
|
+ *perror_object = osp[-1];
|
|
+ *pexit_code = code = osp->value.intval;
|
|
+ osp -= 2;
|
|
+ return
|
|
+ (code == 0 ? e_Quit :
|
|
+ code < 0 && code > -100 ? code : e_Fatal);
|
|
+ case e_InterpreterExit:
|
|
+ return 0;
|
|
+ case e_ExecStackUnderflow:
|
|
/****** WRONG -- must keep mark blocks intact ******/
|
|
- ref_stack_pop_block(&e_stack);
|
|
- doref = *perror_object;
|
|
- epref = &doref;
|
|
- goto again;
|
|
- case e_VMreclaim:
|
|
- /* Do the GC and continue. */
|
|
- code = interp_reclaim(pi_ctx_p,
|
|
- (osp->value.intval == 2 ?
|
|
- avm_global : avm_local));
|
|
- i_ctx_p = *pi_ctx_p;
|
|
- /****** What if code < 0? ******/
|
|
- make_oper(&doref, 0, zpop);
|
|
- epref = &doref;
|
|
- goto again;
|
|
- case e_NeedInput:
|
|
- case e_interrupt:
|
|
- return code;
|
|
+ ref_stack_pop_block(&e_stack);
|
|
+ doref = *perror_object;
|
|
+ epref = &doref;
|
|
+ goto again;
|
|
+ case e_VMreclaim:
|
|
+ /* Do the GC and continue. */
|
|
+ code = interp_reclaim(pi_ctx_p,
|
|
+ (osp->value.intval == 2 ?
|
|
+ avm_global : avm_local));
|
|
+ i_ctx_p = *pi_ctx_p;
|
|
+ /****** What if code < 0? ******/
|
|
+ make_oper(&doref, 0, zpop);
|
|
+ epref = &doref;
|
|
+ goto again;
|
|
+ case e_NeedInput:
|
|
+ case e_interrupt:
|
|
+ return code;
|
|
}
|
|
/* Adjust osp in case of operand stack underflow */
|
|
if (osp < osbot - 1)
|
|
- osp = osbot - 1;
|
|
+ osp = osbot - 1;
|
|
/* We have to handle stack over/underflow specially, because */
|
|
/* we might be able to recover by adding or removing a block. */
|
|
switch (code) {
|
|
- case e_dictstackoverflow:
|
|
- /* We don't have to handle this specially: */
|
|
- /* The only places that could generate it */
|
|
- /* use check_dstack, which does a ref_stack_extend, */
|
|
- /* so if` we get this error, it's a real one. */
|
|
- if (osp >= ostop) {
|
|
- if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
|
|
- return ccode;
|
|
- }
|
|
+ case e_dictstackoverflow:
|
|
+ /* We don't have to handle this specially: */
|
|
+ /* The only places that could generate it */
|
|
+ /* use check_dstack, which does a ref_stack_extend, */
|
|
+ /* so if` we get this error, it's a real one. */
|
|
+ if (osp >= ostop) {
|
|
+ if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
|
|
+ return ccode;
|
|
+ }
|
|
/* Skip system dictionaries for CET 20-02-02 */
|
|
- ccode = copy_stack(i_ctx_p, &d_stack, min_dstack_size, &saref);
|
|
- if (ccode < 0)
|
|
- return ccode;
|
|
- ref_stack_pop_to(&d_stack, min_dstack_size);
|
|
- dict_set_top();
|
|
- *++osp = saref;
|
|
- break;
|
|
- case e_dictstackunderflow:
|
|
- if (ref_stack_pop_block(&d_stack) >= 0) {
|
|
- dict_set_top();
|
|
- doref = *perror_object;
|
|
- epref = &doref;
|
|
- goto again;
|
|
- }
|
|
- break;
|
|
- case e_execstackoverflow:
|
|
- /* We don't have to handle this specially: */
|
|
- /* The only places that could generate it */
|
|
- /* use check_estack, which does a ref_stack_extend, */
|
|
- /* so if we get this error, it's a real one. */
|
|
- if (osp >= ostop) {
|
|
- if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
|
|
- return ccode;
|
|
- }
|
|
- ccode = copy_stack(i_ctx_p, &e_stack, 0, &saref);
|
|
- if (ccode < 0)
|
|
- return ccode;
|
|
- {
|
|
- uint count = ref_stack_count(&e_stack);
|
|
- uint limit = ref_stack_max_count(&e_stack) - ES_HEADROOM;
|
|
-
|
|
- if (count > limit) {
|
|
- /*
|
|
- * If there is an e-stack mark within MIN_BLOCK_ESTACK of
|
|
- * the new top, cut the stack back to remove the mark.
|
|
- */
|
|
- int skip = count - limit;
|
|
- int i;
|
|
-
|
|
- for (i = skip; i < skip + MIN_BLOCK_ESTACK; ++i) {
|
|
- const ref *ep = ref_stack_index(&e_stack, i);
|
|
-
|
|
- if (r_has_type_attrs(ep, t_null, a_executable)) {
|
|
- skip = i + 1;
|
|
- break;
|
|
- }
|
|
- }
|
|
- pop_estack(i_ctx_p, skip);
|
|
- }
|
|
- }
|
|
- *++osp = saref;
|
|
- break;
|
|
- case e_stackoverflow:
|
|
- if (ref_stack_extend(&o_stack, o_stack.requested) >= 0) { /* We can't just re-execute the object, because */
|
|
- /* it might be a procedure being pushed as a */
|
|
- /* literal. We check for this case specially. */
|
|
- doref = *perror_object;
|
|
- if (r_is_proc(&doref)) {
|
|
- *++osp = doref;
|
|
- make_null_proc(&doref);
|
|
- }
|
|
- epref = &doref;
|
|
- goto again;
|
|
- }
|
|
- ccode = copy_stack(i_ctx_p, &o_stack, 0, &saref);
|
|
- if (ccode < 0)
|
|
- return ccode;
|
|
- ref_stack_clear(&o_stack);
|
|
- *++osp = saref;
|
|
- break;
|
|
- case e_stackunderflow:
|
|
- if (ref_stack_pop_block(&o_stack) >= 0) {
|
|
- doref = *perror_object;
|
|
- epref = &doref;
|
|
- goto again;
|
|
- }
|
|
- break;
|
|
+ ccode = copy_stack(i_ctx_p, &d_stack, min_dstack_size, &saref);
|
|
+ if (ccode < 0)
|
|
+ return ccode;
|
|
+ ref_stack_pop_to(&d_stack, min_dstack_size);
|
|
+ dict_set_top();
|
|
+ *++osp = saref;
|
|
+ break;
|
|
+ case e_dictstackunderflow:
|
|
+ if (ref_stack_pop_block(&d_stack) >= 0) {
|
|
+ dict_set_top();
|
|
+ doref = *perror_object;
|
|
+ epref = &doref;
|
|
+ goto again;
|
|
+ }
|
|
+ break;
|
|
+ case e_execstackoverflow:
|
|
+ /* We don't have to handle this specially: */
|
|
+ /* The only places that could generate it */
|
|
+ /* use check_estack, which does a ref_stack_extend, */
|
|
+ /* so if we get this error, it's a real one. */
|
|
+ if (osp >= ostop) {
|
|
+ if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
|
|
+ return ccode;
|
|
+ }
|
|
+ ccode = copy_stack(i_ctx_p, &e_stack, 0, &saref);
|
|
+ if (ccode < 0)
|
|
+ return ccode;
|
|
+ {
|
|
+ uint count = ref_stack_count(&e_stack);
|
|
+ uint limit = ref_stack_max_count(&e_stack) - ES_HEADROOM;
|
|
+
|
|
+ if (count > limit) {
|
|
+ /*
|
|
+ * If there is an e-stack mark within MIN_BLOCK_ESTACK of
|
|
+ * the new top, cut the stack back to remove the mark.
|
|
+ */
|
|
+ int skip = count - limit;
|
|
+ int i;
|
|
+
|
|
+ for (i = skip; i < skip + MIN_BLOCK_ESTACK; ++i) {
|
|
+ const ref *ep = ref_stack_index(&e_stack, i);
|
|
+
|
|
+ if (r_has_type_attrs(ep, t_null, a_executable)) {
|
|
+ skip = i + 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ pop_estack(i_ctx_p, skip);
|
|
+ }
|
|
+ }
|
|
+ *++osp = saref;
|
|
+ break;
|
|
+ case e_stackoverflow:
|
|
+ if (ref_stack_extend(&o_stack, o_stack.requested) >= 0) { /* We can't just re-execute the object, because */
|
|
+ /* it might be a procedure being pushed as a */
|
|
+ /* literal. We check for this case specially. */
|
|
+ doref = *perror_object;
|
|
+ if (r_is_proc(&doref)) {
|
|
+ *++osp = doref;
|
|
+ make_null_proc(&doref);
|
|
+ }
|
|
+ epref = &doref;
|
|
+ goto again;
|
|
+ }
|
|
+ ccode = copy_stack(i_ctx_p, &o_stack, 0, &saref);
|
|
+ if (ccode < 0)
|
|
+ return ccode;
|
|
+ ref_stack_clear(&o_stack);
|
|
+ *++osp = saref;
|
|
+ break;
|
|
+ case e_stackunderflow:
|
|
+ if (ref_stack_pop_block(&o_stack) >= 0) {
|
|
+ doref = *perror_object;
|
|
+ epref = &doref;
|
|
+ goto again;
|
|
+ }
|
|
+ break;
|
|
}
|
|
if (user_errors < 0)
|
|
- return code;
|
|
+ return code;
|
|
if (gs_errorname(i_ctx_p, code, &error_name) < 0)
|
|
- return code; /* out-of-range error code! */
|
|
+ return code; /* out-of-range error code! */
|
|
/*
|
|
* For greater Adobe compatibility, only the standard PostScript errors
|
|
* are defined in errordict; the rest are in gserrordict.
|
|
*/
|
|
if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
|
|
- (dict_find(perrordict, &error_name, &epref) <= 0 &&
|
|
- (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
|
- dict_find(perrordict, &error_name, &epref) <= 0))
|
|
- )
|
|
- return code; /* error name not in errordict??? */
|
|
+ (dict_find(perrordict, &error_name, &epref) <= 0 &&
|
|
+ (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
|
+ dict_find(perrordict, &error_name, &epref) <= 0))
|
|
+ )
|
|
+ return code; /* error name not in errordict??? */
|
|
doref = *epref;
|
|
epref = &doref;
|
|
/* Push the error object on the operand stack if appropriate. */
|
|
if (!ERROR_IS_INTERRUPT(code)) {
|
|
- /* Replace the error object if within an oparray or .errorexec. */
|
|
- *++osp = *perror_object;
|
|
- errorexec_find(i_ctx_p, osp);
|
|
+ /* Replace the error object if within an oparray or .errorexec. */
|
|
+ *++osp = *perror_object;
|
|
+ errorexec_find(i_ctx_p, osp);
|
|
}
|
|
goto again;
|
|
}
|
|
@@ -658,21 +658,21 @@ set_gc_signal(i_ctx_t *i_ctx_p, int *psi
|
|
int i;
|
|
|
|
for (i = 0; i < countof(idmemory->spaces_indexed); i++) {
|
|
- gs_ref_memory_t *mem = idmemory->spaces_indexed[i];
|
|
- gs_ref_memory_t *mem_stable;
|
|
+ gs_ref_memory_t *mem = idmemory->spaces_indexed[i];
|
|
+ gs_ref_memory_t *mem_stable;
|
|
|
|
- if (mem == 0)
|
|
- continue;
|
|
- for (;; mem = mem_stable) {
|
|
- mem_stable = (gs_ref_memory_t *)
|
|
- gs_memory_stable((gs_memory_t *)mem);
|
|
- gs_memory_gc_status(mem, &stat);
|
|
- stat.psignal = psignal;
|
|
- stat.signal_value = value;
|
|
- gs_memory_set_gc_status(mem, &stat);
|
|
- if (mem_stable == mem)
|
|
- break;
|
|
- }
|
|
+ if (mem == 0)
|
|
+ continue;
|
|
+ for (;; mem = mem_stable) {
|
|
+ mem_stable = (gs_ref_memory_t *)
|
|
+ gs_memory_stable((gs_memory_t *)mem);
|
|
+ gs_memory_gc_status(mem, &stat);
|
|
+ stat.psignal = psignal;
|
|
+ stat.signal_value = value;
|
|
+ gs_memory_set_gc_status(mem, &stat);
|
|
+ if (mem_stable == mem)
|
|
+ break;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -691,8 +691,8 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_s
|
|
ialloc_set_space(idmemory, avm_local);
|
|
code = ialloc_ref_array(arr, a_all, size, "copy_stack");
|
|
if (code >= 0)
|
|
- code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
|
|
- "copy_stack");
|
|
+ code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
|
|
+ "copy_stack");
|
|
ialloc_set_space(idmemory, save_space);
|
|
return code;
|
|
}
|
|
@@ -704,9 +704,9 @@ gs_errorname(i_ctx_t *i_ctx_p, int code,
|
|
ref *perrordict, *pErrorNames;
|
|
|
|
if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
|
|
- dict_find_string(systemdict, "ErrorNames", &pErrorNames) <= 0
|
|
- )
|
|
- return_error(e_undefined); /* errordict or ErrorNames not found?! */
|
|
+ dict_find_string(systemdict, "ErrorNames", &pErrorNames) <= 0
|
|
+ )
|
|
+ return_error(e_undefined); /* errordict or ErrorNames not found?! */
|
|
return array_get(imemory, pErrorNames, (long)(-code - 1), perror_name);
|
|
}
|
|
|
|
@@ -720,12 +720,12 @@ gs_errorinfo_put_string(i_ctx_t *i_ctx_p
|
|
int code = string_to_ref(str, &rstr, iimemory, "gs_errorinfo_put_string");
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
if (dict_find_string(systemdict, "$error", &pderror) <= 0 ||
|
|
- !r_has_type(pderror, t_dictionary) ||
|
|
- idict_put_string(pderror, "errorinfo", &rstr) < 0
|
|
- )
|
|
- return_error(e_Fatal);
|
|
+ !r_has_type(pderror, t_dictionary) ||
|
|
+ idict_put_string(pderror, "errorinfo", &rstr) < 0
|
|
+ )
|
|
+ return_error(e_Fatal);
|
|
return 0;
|
|
}
|
|
|
|
@@ -764,14 +764,14 @@ interp(i_ctx_t **pi_ctx_p /* context for
|
|
# define IREF ((const ref *)iref_packed)
|
|
#endif
|
|
#define SET_IREF(rp) (iref_packed = (const ref_packed *)(rp))
|
|
- register int icount = 0; /* # of consecutive tokens at iref */
|
|
- register os_ptr iosp = osp; /* private copy of osp */
|
|
- register es_ptr iesp = esp; /* private copy of esp */
|
|
+ register int icount = 0; /* # of consecutive tokens at iref */
|
|
+ register os_ptr iosp = osp; /* private copy of osp */
|
|
+ register es_ptr iesp = esp; /* private copy of esp */
|
|
int code;
|
|
- ref token; /* token read from file or string, */
|
|
- /* must be declared in this scope */
|
|
+ ref token; /* token read from file or string, */
|
|
+ /* must be declared in this scope */
|
|
register const ref *pvalue = 0;
|
|
- uint opindex; /* needed for oparrays */
|
|
+ uint opindex; /* needed for oparrays */
|
|
os_ptr whichp;
|
|
|
|
/*
|
|
@@ -783,10 +783,10 @@ interp(i_ctx_t **pi_ctx_p /* context for
|
|
* will remain available on Intel processors.
|
|
*/
|
|
struct interp_error_s {
|
|
- int code;
|
|
- int line;
|
|
- const ref *obj;
|
|
- ref full;
|
|
+ int code;
|
|
+ int line;
|
|
+ const ref *obj;
|
|
+ ref full;
|
|
} ierror;
|
|
|
|
/*
|
|
@@ -866,51 +866,51 @@ interp(i_ctx_t **pi_ctx_p /* context for
|
|
/* so we push the argument on the estack and enter */
|
|
/* the loop at the bottom. */
|
|
if (iesp >= estop)
|
|
- return_with_error(e_execstackoverflow, pref);
|
|
+ return_with_error(e_execstackoverflow, pref);
|
|
++iesp;
|
|
ref_assign_inline(iesp, pref);
|
|
goto bot;
|
|
top:
|
|
- /*
|
|
- * This is the top of the interpreter loop.
|
|
- * iref points to the ref being interpreted.
|
|
- * Note that this might be an element of a packed array,
|
|
- * not a real ref: we carefully arranged the first 16 bits of
|
|
- * a ref and of a packed array element so they could be distinguished
|
|
- * from each other. (See ghost.h and packed.h for more detail.)
|
|
- */
|
|
+ /*
|
|
+ * This is the top of the interpreter loop.
|
|
+ * iref points to the ref being interpreted.
|
|
+ * Note that this might be an element of a packed array,
|
|
+ * not a real ref: we carefully arranged the first 16 bits of
|
|
+ * a ref and of a packed array element so they could be distinguished
|
|
+ * from each other. (See ghost.h and packed.h for more detail.)
|
|
+ */
|
|
INCR(top);
|
|
#ifdef DEBUG
|
|
/* Do a little validation on the top o-stack entry. */
|
|
if (iosp >= osbot &&
|
|
- (r_type(iosp) == t__invalid || r_type(iosp) >= tx_next_op)
|
|
- ) {
|
|
- lprintf("Invalid value on o-stack!\n");
|
|
- return_with_error_iref(e_Fatal);
|
|
+ (r_type(iosp) == t__invalid || r_type(iosp) >= tx_next_op)
|
|
+ ) {
|
|
+ lprintf("Invalid value on o-stack!\n");
|
|
+ return_with_error_iref(e_Fatal);
|
|
}
|
|
if (gs_debug['I'] ||
|
|
- (gs_debug['i'] &&
|
|
- (r_is_packed(iref_packed) ?
|
|
- r_packed_is_name(iref_packed) :
|
|
- r_has_type(IREF, t_name)))
|
|
- ) {
|
|
- os_ptr save_osp = osp; /* avoid side-effects */
|
|
- es_ptr save_esp = esp;
|
|
-
|
|
- osp = iosp;
|
|
- esp = iesp;
|
|
- dlprintf5("d%u,e%u<%u>0x%lx(%d): ",
|
|
- ref_stack_count(&d_stack), ref_stack_count(&e_stack),
|
|
- ref_stack_count(&o_stack), (ulong)IREF, icount);
|
|
- debug_print_ref(imemory, IREF);
|
|
- if (iosp >= osbot) {
|
|
- dputs(" // ");
|
|
- debug_print_ref(imemory, iosp);
|
|
- }
|
|
- dputc('\n');
|
|
- osp = save_osp;
|
|
- esp = save_esp;
|
|
- dflush();
|
|
+ (gs_debug['i'] &&
|
|
+ (r_is_packed(iref_packed) ?
|
|
+ r_packed_is_name(iref_packed) :
|
|
+ r_has_type(IREF, t_name)))
|
|
+ ) {
|
|
+ os_ptr save_osp = osp; /* avoid side-effects */
|
|
+ es_ptr save_esp = esp;
|
|
+
|
|
+ osp = iosp;
|
|
+ esp = iesp;
|
|
+ dlprintf5("d%u,e%u<%u>0x%lx(%d): ",
|
|
+ ref_stack_count(&d_stack), ref_stack_count(&e_stack),
|
|
+ ref_stack_count(&o_stack), (ulong)IREF, icount);
|
|
+ debug_print_ref(imemory, IREF);
|
|
+ if (iosp >= osbot) {
|
|
+ dputs(" // ");
|
|
+ debug_print_ref(imemory, iosp);
|
|
+ }
|
|
+ dputc('\n');
|
|
+ osp = save_osp;
|
|
+ esp = save_esp;
|
|
+ dflush();
|
|
}
|
|
#endif
|
|
/* Objects that have attributes (arrays, dictionaries, files, and strings) */
|
|
@@ -927,23 +927,23 @@ interp(i_ctx_t **pi_ctx_p /* context for
|
|
* What a nuisance!
|
|
*/
|
|
switch (r_type_xe(iref_packed)) {
|
|
- /* Access errors. */
|
|
+ /* Access errors. */
|
|
#define cases_invalid()\
|
|
case plain(t__invalid): case plain_exec(t__invalid)
|
|
- cases_invalid():
|
|
- return_with_error_iref(e_Fatal);
|
|
+ cases_invalid():
|
|
+ return_with_error_iref(e_Fatal);
|
|
#define cases_nox()\
|
|
case nox_exec(t_array): case nox_exec(t_dictionary):\
|
|
case nox_exec(t_file): case nox_exec(t_string):\
|
|
case nox_exec(t_mixedarray): case nox_exec(t_shortarray)
|
|
- cases_nox():
|
|
- return_with_error_iref(e_invalidaccess);
|
|
- /*
|
|
- * Literal objects. We have to enumerate all the types.
|
|
- * In fact, we have to include some extra plain_exec entries
|
|
- * just to populate the switch. We break them up into groups
|
|
- * to avoid overflowing some preprocessors.
|
|
- */
|
|
+ cases_nox():
|
|
+ return_with_error_iref(e_invalidaccess);
|
|
+ /*
|
|
+ * Literal objects. We have to enumerate all the types.
|
|
+ * In fact, we have to include some extra plain_exec entries
|
|
+ * just to populate the switch. We break them up into groups
|
|
+ * to avoid overflowing some preprocessors.
|
|
+ */
|
|
#define cases_lit_1()\
|
|
case lit(t_array): case nox(t_array):\
|
|
case plain(t_boolean): case plain_exec(t_boolean):\
|
|
@@ -968,673 +968,673 @@ interp(i_ctx_t **pi_ctx_p /* context for
|
|
case plain(t_device): case plain_exec(t_device):\
|
|
case plain(t_struct): case plain_exec(t_struct):\
|
|
case plain(t_astruct): case plain_exec(t_astruct)
|
|
- /* Executable arrays are treated as literals in direct execution. */
|
|
+ /* Executable arrays are treated as literals in direct execution. */
|
|
#define cases_lit_array()\
|
|
case exec(t_array): case exec(t_mixedarray): case exec(t_shortarray)
|
|
- cases_lit_1():
|
|
- cases_lit_2():
|
|
- cases_lit_3():
|
|
- cases_lit_4():
|
|
- cases_lit_5():
|
|
- INCR(lit);
|
|
- break;
|
|
- cases_lit_array():
|
|
- INCR(lit_array);
|
|
- break;
|
|
- /* Special operators. */
|
|
- case plain_exec(tx_op_add):
|
|
-x_add: INCR(x_add);
|
|
- if ((code = zop_add(iosp)) < 0)
|
|
- return_with_error_tx_op(code);
|
|
- iosp--;
|
|
- next_either();
|
|
- case plain_exec(tx_op_def):
|
|
-x_def: INCR(x_def);
|
|
- osp = iosp; /* sync o_stack */
|
|
- if ((code = zop_def(i_ctx_p)) < 0)
|
|
- return_with_error_tx_op(code);
|
|
- iosp -= 2;
|
|
- next_either();
|
|
- case plain_exec(tx_op_dup):
|
|
-x_dup: INCR(x_dup);
|
|
- if (iosp < osbot)
|
|
- return_with_error_tx_op(e_stackunderflow);
|
|
- if (iosp >= ostop) {
|
|
- o_stack.requested = 1;
|
|
+ cases_lit_1():
|
|
+ cases_lit_2():
|
|
+ cases_lit_3():
|
|
+ cases_lit_4():
|
|
+ cases_lit_5():
|
|
+ INCR(lit);
|
|
+ break;
|
|
+ cases_lit_array():
|
|
+ INCR(lit_array);
|
|
+ break;
|
|
+ /* Special operators. */
|
|
+ case plain_exec(tx_op_add):
|
|
+x_add: INCR(x_add);
|
|
+ if ((code = zop_add(iosp)) < 0)
|
|
+ return_with_error_tx_op(code);
|
|
+ iosp--;
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_def):
|
|
+x_def: INCR(x_def);
|
|
+ osp = iosp; /* sync o_stack */
|
|
+ if ((code = zop_def(i_ctx_p)) < 0)
|
|
+ return_with_error_tx_op(code);
|
|
+ iosp -= 2;
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_dup):
|
|
+x_dup: INCR(x_dup);
|
|
+ if (iosp < osbot)
|
|
+ return_with_error_tx_op(e_stackunderflow);
|
|
+ if (iosp >= ostop) {
|
|
+ o_stack.requested = 1;
|
|
return_with_error_tx_op(e_stackoverflow);
|
|
}
|
|
- iosp++;
|
|
- ref_assign_inline(iosp, iosp - 1);
|
|
- next_either();
|
|
- case plain_exec(tx_op_exch):
|
|
-x_exch: INCR(x_exch);
|
|
- if (iosp <= osbot)
|
|
- return_with_error_tx_op(e_stackunderflow);
|
|
- ref_assign_inline(&token, iosp);
|
|
- ref_assign_inline(iosp, iosp - 1);
|
|
- ref_assign_inline(iosp - 1, &token);
|
|
- next_either();
|
|
- case plain_exec(tx_op_if):
|
|
-x_if: INCR(x_if);
|
|
- if (!r_is_proc(iosp))
|
|
- return_with_error_tx_op(check_proc_failed(iosp));
|
|
- if (!r_has_type(iosp - 1, t_boolean))
|
|
- return_with_error_tx_op((iosp <= osbot ?
|
|
- e_stackunderflow : e_typecheck));
|
|
- if (!iosp[-1].value.boolval) {
|
|
- iosp -= 2;
|
|
- next_either();
|
|
- }
|
|
- if (iesp >= estop)
|
|
- return_with_error_tx_op(e_execstackoverflow);
|
|
- store_state_either(iesp);
|
|
- whichp = iosp;
|
|
- iosp -= 2;
|
|
- goto ifup;
|
|
- case plain_exec(tx_op_ifelse):
|
|
+ iosp++;
|
|
+ ref_assign_inline(iosp, iosp - 1);
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_exch):
|
|
+x_exch: INCR(x_exch);
|
|
+ if (iosp <= osbot)
|
|
+ return_with_error_tx_op(e_stackunderflow);
|
|
+ ref_assign_inline(&token, iosp);
|
|
+ ref_assign_inline(iosp, iosp - 1);
|
|
+ ref_assign_inline(iosp - 1, &token);
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_if):
|
|
+x_if: INCR(x_if);
|
|
+ if (!r_is_proc(iosp))
|
|
+ return_with_error_tx_op(check_proc_failed(iosp));
|
|
+ if (!r_has_type(iosp - 1, t_boolean))
|
|
+ return_with_error_tx_op((iosp <= osbot ?
|
|
+ e_stackunderflow : e_typecheck));
|
|
+ if (!iosp[-1].value.boolval) {
|
|
+ iosp -= 2;
|
|
+ next_either();
|
|
+ }
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_tx_op(e_execstackoverflow);
|
|
+ store_state_either(iesp);
|
|
+ whichp = iosp;
|
|
+ iosp -= 2;
|
|
+ goto ifup;
|
|
+ case plain_exec(tx_op_ifelse):
|
|
x_ifelse: INCR(x_ifelse);
|
|
- if (!r_is_proc(iosp))
|
|
- return_with_error_tx_op(check_proc_failed(iosp));
|
|
- if (!r_is_proc(iosp - 1))
|
|
- return_with_error_tx_op(check_proc_failed(iosp - 1));
|
|
- if (!r_has_type(iosp - 2, t_boolean))
|
|
- return_with_error_tx_op((iosp < osbot + 2 ?
|
|
- e_stackunderflow : e_typecheck));
|
|
- if (iesp >= estop)
|
|
- return_with_error_tx_op(e_execstackoverflow);
|
|
- store_state_either(iesp);
|
|
- whichp = (iosp[-2].value.boolval ? iosp - 1 : iosp);
|
|
- iosp -= 3;
|
|
- /* Open code "up" for the array case(s) */
|
|
- ifup:if ((icount = r_size(whichp) - 1) <= 0) {
|
|
- if (icount < 0)
|
|
- goto up; /* 0-element proc */
|
|
- SET_IREF(whichp->value.refs); /* 1-element proc */
|
|
- if (--ticks_left > 0)
|
|
- goto top;
|
|
- }
|
|
- ++iesp;
|
|
- /* Do a ref_assign, but also set iref. */
|
|
- iesp->tas = whichp->tas;
|
|
- SET_IREF(iesp->value.refs = whichp->value.refs);
|
|
- if (--ticks_left > 0)
|
|
- goto top;
|
|
- goto slice;
|
|
- case plain_exec(tx_op_index):
|
|
+ if (!r_is_proc(iosp))
|
|
+ return_with_error_tx_op(check_proc_failed(iosp));
|
|
+ if (!r_is_proc(iosp - 1))
|
|
+ return_with_error_tx_op(check_proc_failed(iosp - 1));
|
|
+ if (!r_has_type(iosp - 2, t_boolean))
|
|
+ return_with_error_tx_op((iosp < osbot + 2 ?
|
|
+ e_stackunderflow : e_typecheck));
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_tx_op(e_execstackoverflow);
|
|
+ store_state_either(iesp);
|
|
+ whichp = (iosp[-2].value.boolval ? iosp - 1 : iosp);
|
|
+ iosp -= 3;
|
|
+ /* Open code "up" for the array case(s) */
|
|
+ ifup:if ((icount = r_size(whichp) - 1) <= 0) {
|
|
+ if (icount < 0)
|
|
+ goto up; /* 0-element proc */
|
|
+ SET_IREF(whichp->value.refs); /* 1-element proc */
|
|
+ if (--ticks_left > 0)
|
|
+ goto top;
|
|
+ }
|
|
+ ++iesp;
|
|
+ /* Do a ref_assign, but also set iref. */
|
|
+ iesp->tas = whichp->tas;
|
|
+ SET_IREF(iesp->value.refs = whichp->value.refs);
|
|
+ if (--ticks_left > 0)
|
|
+ goto top;
|
|
+ goto slice;
|
|
+ case plain_exec(tx_op_index):
|
|
x_index: INCR(x_index);
|
|
- osp = iosp; /* zindex references o_stack */
|
|
- if ((code = zindex(i_ctx_p)) < 0)
|
|
- return_with_error_tx_op(code);
|
|
- next_either();
|
|
- case plain_exec(tx_op_pop):
|
|
-x_pop: INCR(x_pop);
|
|
- if (iosp < osbot)
|
|
- return_with_error_tx_op(e_stackunderflow);
|
|
- iosp--;
|
|
- next_either();
|
|
- case plain_exec(tx_op_roll):
|
|
-x_roll: INCR(x_roll);
|
|
- osp = iosp; /* zroll references o_stack */
|
|
- if ((code = zroll(i_ctx_p)) < 0)
|
|
- return_with_error_tx_op(code);
|
|
- iosp -= 2;
|
|
- next_either();
|
|
- case plain_exec(tx_op_sub):
|
|
-x_sub: INCR(x_sub);
|
|
- if ((code = zop_sub(iosp)) < 0)
|
|
- return_with_error_tx_op(code);
|
|
- iosp--;
|
|
- next_either();
|
|
- /* Executable types. */
|
|
- case plain_exec(t_null):
|
|
- goto bot;
|
|
- case plain_exec(t_oparray):
|
|
- /* Replace with the definition and go again. */
|
|
- INCR(exec_array);
|
|
- opindex = op_index(IREF);
|
|
- pvalue = IREF->value.const_refs;
|
|
- opst: /* Prepare to call a t_oparray procedure in *pvalue. */
|
|
- store_state(iesp);
|
|
- oppr: /* Record the stack depths in case of failure. */
|
|
- if (iesp >= estop - 4)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- iesp += 5;
|
|
- osp = iosp; /* ref_stack_count_inline needs this */
|
|
- make_mark_estack(iesp - 4, es_other, oparray_cleanup);
|
|
- make_int(iesp - 3, opindex); /* for .errorexec effect */
|
|
- make_int(iesp - 2, ref_stack_count_inline(&o_stack));
|
|
- make_int(iesp - 1, ref_stack_count_inline(&d_stack));
|
|
- make_op_estack(iesp, oparray_pop);
|
|
- goto pr;
|
|
- prst: /* Prepare to call the procedure (array) in *pvalue. */
|
|
- store_state(iesp);
|
|
- pr: /* Call the array in *pvalue. State has been stored. */
|
|
- if ((icount = r_size(pvalue) - 1) <= 0) {
|
|
- if (icount < 0)
|
|
- goto up; /* 0-element proc */
|
|
- SET_IREF(pvalue->value.refs); /* 1-element proc */
|
|
- if (--ticks_left > 0)
|
|
- goto top;
|
|
- }
|
|
- if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- ++iesp;
|
|
- /* Do a ref_assign, but also set iref. */
|
|
- iesp->tas = pvalue->tas;
|
|
- SET_IREF(iesp->value.refs = pvalue->value.refs);
|
|
- if (--ticks_left > 0)
|
|
- goto top;
|
|
- goto slice;
|
|
- case plain_exec(t_operator):
|
|
- INCR(exec_operator);
|
|
- if (--ticks_left <= 0) { /* The following doesn't work, */
|
|
- /* and I can't figure out why. */
|
|
+ osp = iosp; /* zindex references o_stack */
|
|
+ if ((code = zindex(i_ctx_p)) < 0)
|
|
+ return_with_error_tx_op(code);
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_pop):
|
|
+x_pop: INCR(x_pop);
|
|
+ if (iosp < osbot)
|
|
+ return_with_error_tx_op(e_stackunderflow);
|
|
+ iosp--;
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_roll):
|
|
+x_roll: INCR(x_roll);
|
|
+ osp = iosp; /* zroll references o_stack */
|
|
+ if ((code = zroll(i_ctx_p)) < 0)
|
|
+ return_with_error_tx_op(code);
|
|
+ iosp -= 2;
|
|
+ next_either();
|
|
+ case plain_exec(tx_op_sub):
|
|
+x_sub: INCR(x_sub);
|
|
+ if ((code = zop_sub(iosp)) < 0)
|
|
+ return_with_error_tx_op(code);
|
|
+ iosp--;
|
|
+ next_either();
|
|
+ /* Executable types. */
|
|
+ case plain_exec(t_null):
|
|
+ goto bot;
|
|
+ case plain_exec(t_oparray):
|
|
+ /* Replace with the definition and go again. */
|
|
+ INCR(exec_array);
|
|
+ opindex = op_index(IREF);
|
|
+ pvalue = IREF->value.const_refs;
|
|
+ opst: /* Prepare to call a t_oparray procedure in *pvalue. */
|
|
+ store_state(iesp);
|
|
+ oppr: /* Record the stack depths in case of failure. */
|
|
+ if (iesp >= estop - 4)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ iesp += 5;
|
|
+ osp = iosp; /* ref_stack_count_inline needs this */
|
|
+ make_mark_estack(iesp - 4, es_other, oparray_cleanup);
|
|
+ make_int(iesp - 3, opindex); /* for .errorexec effect */
|
|
+ make_int(iesp - 2, ref_stack_count_inline(&o_stack));
|
|
+ make_int(iesp - 1, ref_stack_count_inline(&d_stack));
|
|
+ make_op_estack(iesp, oparray_pop);
|
|
+ goto pr;
|
|
+ prst: /* Prepare to call the procedure (array) in *pvalue. */
|
|
+ store_state(iesp);
|
|
+ pr: /* Call the array in *pvalue. State has been stored. */
|
|
+ if ((icount = r_size(pvalue) - 1) <= 0) {
|
|
+ if (icount < 0)
|
|
+ goto up; /* 0-element proc */
|
|
+ SET_IREF(pvalue->value.refs); /* 1-element proc */
|
|
+ if (--ticks_left > 0)
|
|
+ goto top;
|
|
+ }
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ ++iesp;
|
|
+ /* Do a ref_assign, but also set iref. */
|
|
+ iesp->tas = pvalue->tas;
|
|
+ SET_IREF(iesp->value.refs = pvalue->value.refs);
|
|
+ if (--ticks_left > 0)
|
|
+ goto top;
|
|
+ goto slice;
|
|
+ case plain_exec(t_operator):
|
|
+ INCR(exec_operator);
|
|
+ if (--ticks_left <= 0) { /* The following doesn't work, */
|
|
+ /* and I can't figure out why. */
|
|
/****** goto sst; ******/
|
|
- }
|
|
- esp = iesp; /* save for operator */
|
|
- osp = iosp; /* ditto */
|
|
- /* Operator routines take osp as an argument. */
|
|
- /* This is just a convenience, since they adjust */
|
|
- /* osp themselves to reflect the results. */
|
|
- /* Operators that (net) push information on the */
|
|
- /* operand stack must check for overflow: */
|
|
- /* this normally happens automatically through */
|
|
- /* the push macro (in oper.h). */
|
|
- /* Operators that do not typecheck their operands, */
|
|
- /* or take a variable number of arguments, */
|
|
- /* must check explicitly for stack underflow. */
|
|
- /* (See oper.h for more detail.) */
|
|
- /* Note that each case must set iosp = osp: */
|
|
- /* this is so we can switch on code without having to */
|
|
- /* store it and reload it (for dumb compilers). */
|
|
- switch (code = call_operator(real_opproc(IREF), i_ctx_p)) {
|
|
- case 0: /* normal case */
|
|
- case 1: /* alternative success case */
|
|
- iosp = osp;
|
|
- next();
|
|
- case o_push_estack: /* store the state and go to up */
|
|
- store_state(iesp);
|
|
- opush:iosp = osp;
|
|
- iesp = esp;
|
|
- if (--ticks_left > 0)
|
|
- goto up;
|
|
- goto slice;
|
|
- case o_pop_estack: /* just go to up */
|
|
- opop:iosp = osp;
|
|
- if (esp == iesp)
|
|
- goto bot;
|
|
- iesp = esp;
|
|
- goto up;
|
|
- case o_reschedule:
|
|
- store_state(iesp);
|
|
- goto res;
|
|
- case e_RemapColor:
|
|
-oe_remap: store_state(iesp);
|
|
-remap: if (iesp + 2 >= estop) {
|
|
- esp = iesp;
|
|
- code = ref_stack_extend(&e_stack, 2);
|
|
- if (code < 0)
|
|
- return_with_error_iref(code);
|
|
- iesp = esp;
|
|
- }
|
|
- packed_get(imemory, iref_packed, iesp + 1);
|
|
- make_oper(iesp + 2, 0,
|
|
- r_ptr(&istate->remap_color_info,
|
|
- int_remap_color_info_t)->proc);
|
|
- iesp += 2;
|
|
- goto up;
|
|
- }
|
|
- iosp = osp;
|
|
- iesp = esp;
|
|
- return_with_code_iref();
|
|
- case plain_exec(t_name):
|
|
- INCR(exec_name);
|
|
- pvalue = IREF->value.pname->pvalue;
|
|
- if (!pv_valid(pvalue)) {
|
|
- uint nidx = names_index(int_nt, IREF);
|
|
- uint htemp;
|
|
-
|
|
- INCR(find_name);
|
|
- if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0)
|
|
- return_with_error_iref(e_undefined);
|
|
- }
|
|
- /* Dispatch on the type of the value. */
|
|
- /* Again, we have to over-populate the switch. */
|
|
- switch (r_type_xe(pvalue)) {
|
|
- cases_invalid():
|
|
- return_with_error_iref(e_Fatal);
|
|
- cases_nox(): /* access errors */
|
|
- return_with_error_iref(e_invalidaccess);
|
|
- cases_lit_1():
|
|
- cases_lit_2():
|
|
- cases_lit_3():
|
|
- cases_lit_4():
|
|
- cases_lit_5():
|
|
- INCR(name_lit);
|
|
- /* Just push the value */
|
|
- if (iosp >= ostop)
|
|
- return_with_stackoverflow(pvalue);
|
|
- ++iosp;
|
|
- ref_assign_inline(iosp, pvalue);
|
|
- next();
|
|
- case exec(t_array):
|
|
- case exec(t_mixedarray):
|
|
- case exec(t_shortarray):
|
|
- INCR(name_proc);
|
|
- /* This is an executable procedure, execute it. */
|
|
- goto prst;
|
|
- case plain_exec(tx_op_add):
|
|
- goto x_add;
|
|
- case plain_exec(tx_op_def):
|
|
- goto x_def;
|
|
- case plain_exec(tx_op_dup):
|
|
- goto x_dup;
|
|
- case plain_exec(tx_op_exch):
|
|
- goto x_exch;
|
|
- case plain_exec(tx_op_if):
|
|
- goto x_if;
|
|
- case plain_exec(tx_op_ifelse):
|
|
- goto x_ifelse;
|
|
- case plain_exec(tx_op_index):
|
|
- goto x_index;
|
|
- case plain_exec(tx_op_pop):
|
|
- goto x_pop;
|
|
- case plain_exec(tx_op_roll):
|
|
- goto x_roll;
|
|
- case plain_exec(tx_op_sub):
|
|
- goto x_sub;
|
|
- case plain_exec(t_null):
|
|
- goto bot;
|
|
- case plain_exec(t_oparray):
|
|
- INCR(name_oparray);
|
|
- opindex = op_index(pvalue);
|
|
- pvalue = (const ref *)pvalue->value.const_refs;
|
|
- goto opst;
|
|
- case plain_exec(t_operator):
|
|
- INCR(name_operator);
|
|
- { /* Shortcut for operators. */
|
|
- /* See above for the logic. */
|
|
- if (--ticks_left <= 0) { /* The following doesn't work, */
|
|
- /* and I can't figure out why. */
|
|
+ }
|
|
+ esp = iesp; /* save for operator */
|
|
+ osp = iosp; /* ditto */
|
|
+ /* Operator routines take osp as an argument. */
|
|
+ /* This is just a convenience, since they adjust */
|
|
+ /* osp themselves to reflect the results. */
|
|
+ /* Operators that (net) push information on the */
|
|
+ /* operand stack must check for overflow: */
|
|
+ /* this normally happens automatically through */
|
|
+ /* the push macro (in oper.h). */
|
|
+ /* Operators that do not typecheck their operands, */
|
|
+ /* or take a variable number of arguments, */
|
|
+ /* must check explicitly for stack underflow. */
|
|
+ /* (See oper.h for more detail.) */
|
|
+ /* Note that each case must set iosp = osp: */
|
|
+ /* this is so we can switch on code without having to */
|
|
+ /* store it and reload it (for dumb compilers). */
|
|
+ switch (code = call_operator(real_opproc(IREF), i_ctx_p)) {
|
|
+ case 0: /* normal case */
|
|
+ case 1: /* alternative success case */
|
|
+ iosp = osp;
|
|
+ next();
|
|
+ case o_push_estack: /* store the state and go to up */
|
|
+ store_state(iesp);
|
|
+ opush:iosp = osp;
|
|
+ iesp = esp;
|
|
+ if (--ticks_left > 0)
|
|
+ goto up;
|
|
+ goto slice;
|
|
+ case o_pop_estack: /* just go to up */
|
|
+ opop:iosp = osp;
|
|
+ if (esp == iesp)
|
|
+ goto bot;
|
|
+ iesp = esp;
|
|
+ goto up;
|
|
+ case o_reschedule:
|
|
+ store_state(iesp);
|
|
+ goto res;
|
|
+ case e_RemapColor:
|
|
+oe_remap: store_state(iesp);
|
|
+remap: if (iesp + 2 >= estop) {
|
|
+ esp = iesp;
|
|
+ code = ref_stack_extend(&e_stack, 2);
|
|
+ if (code < 0)
|
|
+ return_with_error_iref(code);
|
|
+ iesp = esp;
|
|
+ }
|
|
+ packed_get(imemory, iref_packed, iesp + 1);
|
|
+ make_oper(iesp + 2, 0,
|
|
+ r_ptr(&istate->remap_color_info,
|
|
+ int_remap_color_info_t)->proc);
|
|
+ iesp += 2;
|
|
+ goto up;
|
|
+ }
|
|
+ iosp = osp;
|
|
+ iesp = esp;
|
|
+ return_with_code_iref();
|
|
+ case plain_exec(t_name):
|
|
+ INCR(exec_name);
|
|
+ pvalue = IREF->value.pname->pvalue;
|
|
+ if (!pv_valid(pvalue)) {
|
|
+ uint nidx = names_index(int_nt, IREF);
|
|
+ uint htemp;
|
|
+
|
|
+ INCR(find_name);
|
|
+ if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0)
|
|
+ return_with_error_iref(e_undefined);
|
|
+ }
|
|
+ /* Dispatch on the type of the value. */
|
|
+ /* Again, we have to over-populate the switch. */
|
|
+ switch (r_type_xe(pvalue)) {
|
|
+ cases_invalid():
|
|
+ return_with_error_iref(e_Fatal);
|
|
+ cases_nox(): /* access errors */
|
|
+ return_with_error_iref(e_invalidaccess);
|
|
+ cases_lit_1():
|
|
+ cases_lit_2():
|
|
+ cases_lit_3():
|
|
+ cases_lit_4():
|
|
+ cases_lit_5():
|
|
+ INCR(name_lit);
|
|
+ /* Just push the value */
|
|
+ if (iosp >= ostop)
|
|
+ return_with_stackoverflow(pvalue);
|
|
+ ++iosp;
|
|
+ ref_assign_inline(iosp, pvalue);
|
|
+ next();
|
|
+ case exec(t_array):
|
|
+ case exec(t_mixedarray):
|
|
+ case exec(t_shortarray):
|
|
+ INCR(name_proc);
|
|
+ /* This is an executable procedure, execute it. */
|
|
+ goto prst;
|
|
+ case plain_exec(tx_op_add):
|
|
+ goto x_add;
|
|
+ case plain_exec(tx_op_def):
|
|
+ goto x_def;
|
|
+ case plain_exec(tx_op_dup):
|
|
+ goto x_dup;
|
|
+ case plain_exec(tx_op_exch):
|
|
+ goto x_exch;
|
|
+ case plain_exec(tx_op_if):
|
|
+ goto x_if;
|
|
+ case plain_exec(tx_op_ifelse):
|
|
+ goto x_ifelse;
|
|
+ case plain_exec(tx_op_index):
|
|
+ goto x_index;
|
|
+ case plain_exec(tx_op_pop):
|
|
+ goto x_pop;
|
|
+ case plain_exec(tx_op_roll):
|
|
+ goto x_roll;
|
|
+ case plain_exec(tx_op_sub):
|
|
+ goto x_sub;
|
|
+ case plain_exec(t_null):
|
|
+ goto bot;
|
|
+ case plain_exec(t_oparray):
|
|
+ INCR(name_oparray);
|
|
+ opindex = op_index(pvalue);
|
|
+ pvalue = (const ref *)pvalue->value.const_refs;
|
|
+ goto opst;
|
|
+ case plain_exec(t_operator):
|
|
+ INCR(name_operator);
|
|
+ { /* Shortcut for operators. */
|
|
+ /* See above for the logic. */
|
|
+ if (--ticks_left <= 0) { /* The following doesn't work, */
|
|
+ /* and I can't figure out why. */
|
|
/****** goto sst; ******/
|
|
- }
|
|
- esp = iesp;
|
|
- osp = iosp;
|
|
- switch (code = call_operator(real_opproc(pvalue),
|
|
- i_ctx_p)
|
|
- ) {
|
|
- case 0: /* normal case */
|
|
- case 1: /* alternative success case */
|
|
- iosp = osp;
|
|
- next();
|
|
- case o_push_estack:
|
|
- store_state(iesp);
|
|
- goto opush;
|
|
- case o_pop_estack:
|
|
- goto opop;
|
|
- case o_reschedule:
|
|
- store_state(iesp);
|
|
- goto res;
|
|
- case e_RemapColor:
|
|
- goto oe_remap;
|
|
- }
|
|
- iosp = osp;
|
|
- iesp = esp;
|
|
- return_with_error(code, pvalue);
|
|
- }
|
|
- case plain_exec(t_name):
|
|
- case exec(t_file):
|
|
- case exec(t_string):
|
|
- default:
|
|
- /* Not a procedure, reinterpret it. */
|
|
- store_state(iesp);
|
|
- icount = 0;
|
|
- SET_IREF(pvalue);
|
|
- goto top;
|
|
- }
|
|
- case exec(t_file):
|
|
- { /* Executable file. Read the next token and interpret it. */
|
|
- stream *s;
|
|
- scanner_state sstate;
|
|
-
|
|
- check_read_known_file(i_ctx_p, s, IREF, return_with_error_iref);
|
|
- rt:
|
|
- if (iosp >= ostop) /* check early */
|
|
- return_with_stackoverflow_iref();
|
|
- osp = iosp; /* scan_token uses ostack */
|
|
- scanner_init_options(&sstate, IREF, i_ctx_p->scanner_options);
|
|
- again:
|
|
- code = scan_token(i_ctx_p, &token, &sstate);
|
|
- iosp = osp; /* ditto */
|
|
- switch (code) {
|
|
- case 0: /* read a token */
|
|
- /* It's worth checking for literals, which make up */
|
|
- /* the majority of input tokens, before storing the */
|
|
- /* state on the e-stack. Note that because of //, */
|
|
- /* the token may have *any* type and attributes. */
|
|
- /* Note also that executable arrays aren't executed */
|
|
- /* at the top level -- they're treated as literals. */
|
|
- if (!r_has_attr(&token, a_executable) ||
|
|
- r_is_array(&token)
|
|
- ) { /* If scan_token used the o-stack, */
|
|
- /* we know we can do a push now; if not, */
|
|
- /* the pre-check is still valid. */
|
|
- iosp++;
|
|
- ref_assign_inline(iosp, &token);
|
|
- goto rt;
|
|
- }
|
|
- store_state(iesp);
|
|
- /* Push the file on the e-stack */
|
|
- if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- esfile_set_cache(++iesp);
|
|
- ref_assign_inline(iesp, IREF);
|
|
- SET_IREF(&token);
|
|
- icount = 0;
|
|
- goto top;
|
|
- case e_undefined: /* //name undefined */
|
|
- scanner_error_object(i_ctx_p, &sstate, &token);
|
|
- return_with_error(code, &token);
|
|
- case scan_EOF: /* end of file */
|
|
- esfile_clear_cache();
|
|
- goto bot;
|
|
- case scan_BOS:
|
|
- /* Binary object sequences */
|
|
- /* ARE executed at the top level. */
|
|
- store_state(iesp);
|
|
- /* Push the file on the e-stack */
|
|
- if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- esfile_set_cache(++iesp);
|
|
- ref_assign_inline(iesp, IREF);
|
|
- pvalue = &token;
|
|
- goto pr;
|
|
- case scan_Refill:
|
|
- store_state(iesp);
|
|
- /* iref may point into the exec stack; */
|
|
- /* save its referent now. */
|
|
- ref_assign_inline(&token, IREF);
|
|
- /* Push the file on the e-stack */
|
|
- if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- ++iesp;
|
|
- ref_assign_inline(iesp, &token);
|
|
- esp = iesp;
|
|
- osp = iosp;
|
|
- code = scan_handle_refill(i_ctx_p, &sstate, true,
|
|
- ztokenexec_continue);
|
|
- scan_cont:
|
|
- iosp = osp;
|
|
- iesp = esp;
|
|
- switch (code) {
|
|
- case 0:
|
|
- iesp--; /* don't push the file */
|
|
- goto again; /* stacks are unchanged */
|
|
- case o_push_estack:
|
|
- esfile_clear_cache();
|
|
- if (--ticks_left > 0)
|
|
- goto up;
|
|
- goto slice;
|
|
- }
|
|
- /* must be an error */
|
|
- iesp--; /* don't push the file */
|
|
- return_with_code_iref();
|
|
- case scan_Comment:
|
|
- case scan_DSC_Comment: {
|
|
- /* See scan_Refill above for comments. */
|
|
- ref file_token;
|
|
-
|
|
- store_state(iesp);
|
|
- ref_assign_inline(&file_token, IREF);
|
|
- if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- ++iesp;
|
|
- ref_assign_inline(iesp, &file_token);
|
|
- esp = iesp;
|
|
- osp = iosp;
|
|
- code = ztoken_handle_comment(i_ctx_p,
|
|
- &sstate, &token,
|
|
- code, true, true,
|
|
- ztokenexec_continue);
|
|
- }
|
|
- goto scan_cont;
|
|
- default: /* error */
|
|
- ref_assign_inline(&token, IREF);
|
|
- scanner_error_object(i_ctx_p, &sstate, &token);
|
|
- return_with_error(code, &token);
|
|
- }
|
|
- }
|
|
- case exec(t_string):
|
|
- { /* Executable string. Read a token and interpret it. */
|
|
- stream ss;
|
|
- scanner_state sstate;
|
|
-
|
|
- s_init(&ss, NULL);
|
|
- sread_string(&ss, IREF->value.bytes, r_size(IREF));
|
|
- scanner_init_stream_options(&sstate, &ss, SCAN_FROM_STRING);
|
|
- osp = iosp; /* scan_token uses ostack */
|
|
- code = scan_token(i_ctx_p, &token, &sstate);
|
|
- iosp = osp; /* ditto */
|
|
- switch (code) {
|
|
- case 0: /* read a token */
|
|
- case scan_BOS: /* binary object sequence */
|
|
- store_state(iesp);
|
|
- /* If the updated string isn't empty, push it back */
|
|
- /* on the e-stack. */
|
|
- {
|
|
- uint size = sbufavailable(&ss);
|
|
-
|
|
- if (size) {
|
|
- if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
- ++iesp;
|
|
- iesp->tas.type_attrs = IREF->tas.type_attrs;
|
|
- iesp->value.const_bytes = sbufptr(&ss);
|
|
- r_set_size(iesp, size);
|
|
- }
|
|
- }
|
|
- if (code == 0) {
|
|
- SET_IREF(&token);
|
|
- icount = 0;
|
|
- goto top;
|
|
- }
|
|
- /* Handle BOS specially */
|
|
- pvalue = &token;
|
|
- goto pr;
|
|
- case scan_EOF: /* end of string */
|
|
- goto bot;
|
|
- case scan_Refill: /* error */
|
|
- code = gs_note_error(e_syntaxerror);
|
|
- default: /* error */
|
|
- ref_assign_inline(&token, IREF);
|
|
- scanner_error_object(i_ctx_p, &sstate, &token);
|
|
- return_with_error(code, &token);
|
|
- }
|
|
- }
|
|
- /* Handle packed arrays here by re-dispatching. */
|
|
- /* This also picks up some anomalous cases of non-packed arrays. */
|
|
- default:
|
|
- {
|
|
- uint index;
|
|
-
|
|
- switch (*iref_packed >> r_packed_type_shift) {
|
|
- case pt_full_ref:
|
|
- case pt_full_ref + 1:
|
|
- INCR(p_full);
|
|
- if (iosp >= ostop)
|
|
- return_with_stackoverflow_iref();
|
|
- /* We know this can't be an executable object */
|
|
- /* requiring special handling, so we just push it. */
|
|
- ++iosp;
|
|
- /* We know that refs are properly aligned: */
|
|
- /* see packed.h for details. */
|
|
- ref_assign_inline(iosp, IREF);
|
|
- next();
|
|
- case pt_executable_operator:
|
|
- index = *iref_packed & packed_value_mask;
|
|
- if (--ticks_left <= 0) { /* The following doesn't work, */
|
|
- /* and I can't figure out why. */
|
|
+ }
|
|
+ esp = iesp;
|
|
+ osp = iosp;
|
|
+ switch (code = call_operator(real_opproc(pvalue),
|
|
+ i_ctx_p)
|
|
+ ) {
|
|
+ case 0: /* normal case */
|
|
+ case 1: /* alternative success case */
|
|
+ iosp = osp;
|
|
+ next();
|
|
+ case o_push_estack:
|
|
+ store_state(iesp);
|
|
+ goto opush;
|
|
+ case o_pop_estack:
|
|
+ goto opop;
|
|
+ case o_reschedule:
|
|
+ store_state(iesp);
|
|
+ goto res;
|
|
+ case e_RemapColor:
|
|
+ goto oe_remap;
|
|
+ }
|
|
+ iosp = osp;
|
|
+ iesp = esp;
|
|
+ return_with_error(code, pvalue);
|
|
+ }
|
|
+ case plain_exec(t_name):
|
|
+ case exec(t_file):
|
|
+ case exec(t_string):
|
|
+ default:
|
|
+ /* Not a procedure, reinterpret it. */
|
|
+ store_state(iesp);
|
|
+ icount = 0;
|
|
+ SET_IREF(pvalue);
|
|
+ goto top;
|
|
+ }
|
|
+ case exec(t_file):
|
|
+ { /* Executable file. Read the next token and interpret it. */
|
|
+ stream *s;
|
|
+ scanner_state sstate;
|
|
+
|
|
+ check_read_known_file(i_ctx_p, s, IREF, return_with_error_iref);
|
|
+ rt:
|
|
+ if (iosp >= ostop) /* check early */
|
|
+ return_with_stackoverflow_iref();
|
|
+ osp = iosp; /* gs_scan_token uses ostack */
|
|
+ gs_scanner_init_options(&sstate, IREF, i_ctx_p->scanner_options);
|
|
+ again:
|
|
+ code = gs_scan_token(i_ctx_p, &token, &sstate);
|
|
+ iosp = osp; /* ditto */
|
|
+ switch (code) {
|
|
+ case 0: /* read a token */
|
|
+ /* It's worth checking for literals, which make up */
|
|
+ /* the majority of input tokens, before storing the */
|
|
+ /* state on the e-stack. Note that because of //, */
|
|
+ /* the token may have *any* type and attributes. */
|
|
+ /* Note also that executable arrays aren't executed */
|
|
+ /* at the top level -- they're treated as literals. */
|
|
+ if (!r_has_attr(&token, a_executable) ||
|
|
+ r_is_array(&token)
|
|
+ ) { /* If gs_scan_token used the o-stack, */
|
|
+ /* we know we can do a push now; if not, */
|
|
+ /* the pre-check is still valid. */
|
|
+ iosp++;
|
|
+ ref_assign_inline(iosp, &token);
|
|
+ goto rt;
|
|
+ }
|
|
+ store_state(iesp);
|
|
+ /* Push the file on the e-stack */
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ esfile_set_cache(++iesp);
|
|
+ ref_assign_inline(iesp, IREF);
|
|
+ SET_IREF(&token);
|
|
+ icount = 0;
|
|
+ goto top;
|
|
+ case e_undefined: /* //name undefined */
|
|
+ gs_scanner_error_object(i_ctx_p, &sstate, &token);
|
|
+ return_with_error(code, &token);
|
|
+ case scan_EOF: /* end of file */
|
|
+ esfile_clear_cache();
|
|
+ goto bot;
|
|
+ case scan_BOS:
|
|
+ /* Binary object sequences */
|
|
+ /* ARE executed at the top level. */
|
|
+ store_state(iesp);
|
|
+ /* Push the file on the e-stack */
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ esfile_set_cache(++iesp);
|
|
+ ref_assign_inline(iesp, IREF);
|
|
+ pvalue = &token;
|
|
+ goto pr;
|
|
+ case scan_Refill:
|
|
+ store_state(iesp);
|
|
+ /* iref may point into the exec stack; */
|
|
+ /* save its referent now. */
|
|
+ ref_assign_inline(&token, IREF);
|
|
+ /* Push the file on the e-stack */
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ ++iesp;
|
|
+ ref_assign_inline(iesp, &token);
|
|
+ esp = iesp;
|
|
+ osp = iosp;
|
|
+ code = gs_scan_handle_refill(i_ctx_p, &sstate, true,
|
|
+ ztokenexec_continue);
|
|
+ scan_cont:
|
|
+ iosp = osp;
|
|
+ iesp = esp;
|
|
+ switch (code) {
|
|
+ case 0:
|
|
+ iesp--; /* don't push the file */
|
|
+ goto again; /* stacks are unchanged */
|
|
+ case o_push_estack:
|
|
+ esfile_clear_cache();
|
|
+ if (--ticks_left > 0)
|
|
+ goto up;
|
|
+ goto slice;
|
|
+ }
|
|
+ /* must be an error */
|
|
+ iesp--; /* don't push the file */
|
|
+ return_with_code_iref();
|
|
+ case scan_Comment:
|
|
+ case scan_DSC_Comment: {
|
|
+ /* See scan_Refill above for comments. */
|
|
+ ref file_token;
|
|
+
|
|
+ store_state(iesp);
|
|
+ ref_assign_inline(&file_token, IREF);
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ ++iesp;
|
|
+ ref_assign_inline(iesp, &file_token);
|
|
+ esp = iesp;
|
|
+ osp = iosp;
|
|
+ code = ztoken_handle_comment(i_ctx_p,
|
|
+ &sstate, &token,
|
|
+ code, true, true,
|
|
+ ztokenexec_continue);
|
|
+ }
|
|
+ goto scan_cont;
|
|
+ default: /* error */
|
|
+ ref_assign_inline(&token, IREF);
|
|
+ gs_scanner_error_object(i_ctx_p, &sstate, &token);
|
|
+ return_with_error(code, &token);
|
|
+ }
|
|
+ }
|
|
+ case exec(t_string):
|
|
+ { /* Executable string. Read a token and interpret it. */
|
|
+ stream ss;
|
|
+ scanner_state sstate;
|
|
+
|
|
+ s_init(&ss, NULL);
|
|
+ sread_string(&ss, IREF->value.bytes, r_size(IREF));
|
|
+ gs_scanner_init_stream_options(&sstate, &ss, SCAN_FROM_STRING);
|
|
+ osp = iosp; /* gs_scan_token uses ostack */
|
|
+ code = gs_scan_token(i_ctx_p, &token, &sstate);
|
|
+ iosp = osp; /* ditto */
|
|
+ switch (code) {
|
|
+ case 0: /* read a token */
|
|
+ case scan_BOS: /* binary object sequence */
|
|
+ store_state(iesp);
|
|
+ /* If the updated string isn't empty, push it back */
|
|
+ /* on the e-stack. */
|
|
+ {
|
|
+ uint size = sbufavailable(&ss);
|
|
+
|
|
+ if (size) {
|
|
+ if (iesp >= estop)
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
+ ++iesp;
|
|
+ iesp->tas.type_attrs = IREF->tas.type_attrs;
|
|
+ iesp->value.const_bytes = sbufptr(&ss);
|
|
+ r_set_size(iesp, size);
|
|
+ }
|
|
+ }
|
|
+ if (code == 0) {
|
|
+ SET_IREF(&token);
|
|
+ icount = 0;
|
|
+ goto top;
|
|
+ }
|
|
+ /* Handle BOS specially */
|
|
+ pvalue = &token;
|
|
+ goto pr;
|
|
+ case scan_EOF: /* end of string */
|
|
+ goto bot;
|
|
+ case scan_Refill: /* error */
|
|
+ code = gs_note_error(e_syntaxerror);
|
|
+ default: /* error */
|
|
+ ref_assign_inline(&token, IREF);
|
|
+ gs_scanner_error_object(i_ctx_p, &sstate, &token);
|
|
+ return_with_error(code, &token);
|
|
+ }
|
|
+ }
|
|
+ /* Handle packed arrays here by re-dispatching. */
|
|
+ /* This also picks up some anomalous cases of non-packed arrays. */
|
|
+ default:
|
|
+ {
|
|
+ uint index;
|
|
+
|
|
+ switch (*iref_packed >> r_packed_type_shift) {
|
|
+ case pt_full_ref:
|
|
+ case pt_full_ref + 1:
|
|
+ INCR(p_full);
|
|
+ if (iosp >= ostop)
|
|
+ return_with_stackoverflow_iref();
|
|
+ /* We know this can't be an executable object */
|
|
+ /* requiring special handling, so we just push it. */
|
|
+ ++iosp;
|
|
+ /* We know that refs are properly aligned: */
|
|
+ /* see packed.h for details. */
|
|
+ ref_assign_inline(iosp, IREF);
|
|
+ next();
|
|
+ case pt_executable_operator:
|
|
+ index = *iref_packed & packed_value_mask;
|
|
+ if (--ticks_left <= 0) { /* The following doesn't work, */
|
|
+ /* and I can't figure out why. */
|
|
/****** goto sst_short; ******/
|
|
- }
|
|
- if (!op_index_is_operator(index)) {
|
|
- INCR(p_exec_oparray);
|
|
- store_state_short(iesp);
|
|
- opindex = index;
|
|
- /* Call the operator procedure. */
|
|
- index -= op_def_count;
|
|
- pvalue = (const ref *)
|
|
- (index < r_size(&i_ctx_p->op_array_table_global.table) ?
|
|
- i_ctx_p->op_array_table_global.table.value.const_refs +
|
|
- index :
|
|
- i_ctx_p->op_array_table_local.table.value.const_refs +
|
|
- (index - r_size(&i_ctx_p->op_array_table_global.table)));
|
|
- goto oppr;
|
|
- }
|
|
- INCR(p_exec_operator);
|
|
- /* See the main plain_exec(t_operator) case */
|
|
- /* for details of what happens here. */
|
|
+ }
|
|
+ if (!op_index_is_operator(index)) {
|
|
+ INCR(p_exec_oparray);
|
|
+ store_state_short(iesp);
|
|
+ opindex = index;
|
|
+ /* Call the operator procedure. */
|
|
+ index -= op_def_count;
|
|
+ pvalue = (const ref *)
|
|
+ (index < r_size(&i_ctx_p->op_array_table_global.table) ?
|
|
+ i_ctx_p->op_array_table_global.table.value.const_refs +
|
|
+ index :
|
|
+ i_ctx_p->op_array_table_local.table.value.const_refs +
|
|
+ (index - r_size(&i_ctx_p->op_array_table_global.table)));
|
|
+ goto oppr;
|
|
+ }
|
|
+ INCR(p_exec_operator);
|
|
+ /* See the main plain_exec(t_operator) case */
|
|
+ /* for details of what happens here. */
|
|
#if PACKED_SPECIAL_OPS
|
|
- /*
|
|
- * We arranged in iinit.c that the special ops
|
|
- * have operator indices starting at 1.
|
|
- *
|
|
- * The (int) cast in the next line is required
|
|
- * because some compilers don't allow arithmetic
|
|
- * involving two different enumerated types.
|
|
- */
|
|
+ /*
|
|
+ * We arranged in iinit.c that the special ops
|
|
+ * have operator indices starting at 1.
|
|
+ *
|
|
+ * The (int) cast in the next line is required
|
|
+ * because some compilers don't allow arithmetic
|
|
+ * involving two different enumerated types.
|
|
+ */
|
|
# define case_xop(xop) case xop - (int)tx_op + 1
|
|
- switch (index) {
|
|
- case_xop(tx_op_add):goto x_add;
|
|
- case_xop(tx_op_def):goto x_def;
|
|
- case_xop(tx_op_dup):goto x_dup;
|
|
- case_xop(tx_op_exch):goto x_exch;
|
|
- case_xop(tx_op_if):goto x_if;
|
|
- case_xop(tx_op_ifelse):goto x_ifelse;
|
|
- case_xop(tx_op_index):goto x_index;
|
|
- case_xop(tx_op_pop):goto x_pop;
|
|
- case_xop(tx_op_roll):goto x_roll;
|
|
- case_xop(tx_op_sub):goto x_sub;
|
|
- case 0: /* for dumb compilers */
|
|
- default:
|
|
- ;
|
|
- }
|
|
+ switch (index) {
|
|
+ case_xop(tx_op_add):goto x_add;
|
|
+ case_xop(tx_op_def):goto x_def;
|
|
+ case_xop(tx_op_dup):goto x_dup;
|
|
+ case_xop(tx_op_exch):goto x_exch;
|
|
+ case_xop(tx_op_if):goto x_if;
|
|
+ case_xop(tx_op_ifelse):goto x_ifelse;
|
|
+ case_xop(tx_op_index):goto x_index;
|
|
+ case_xop(tx_op_pop):goto x_pop;
|
|
+ case_xop(tx_op_roll):goto x_roll;
|
|
+ case_xop(tx_op_sub):goto x_sub;
|
|
+ case 0: /* for dumb compilers */
|
|
+ default:
|
|
+ ;
|
|
+ }
|
|
# undef case_xop
|
|
#endif
|
|
- INCR(p_exec_non_x_operator);
|
|
- esp = iesp;
|
|
- osp = iosp;
|
|
- switch (code = call_operator(op_index_proc(index), i_ctx_p)) {
|
|
- case 0:
|
|
- case 1:
|
|
- iosp = osp;
|
|
- next_short();
|
|
- case o_push_estack:
|
|
- store_state_short(iesp);
|
|
- goto opush;
|
|
- case o_pop_estack:
|
|
- iosp = osp;
|
|
- if (esp == iesp) {
|
|
- next_short();
|
|
- }
|
|
- iesp = esp;
|
|
- goto up;
|
|
- case o_reschedule:
|
|
- store_state_short(iesp);
|
|
- goto res;
|
|
- case e_RemapColor:
|
|
- store_state_short(iesp);
|
|
- goto remap;
|
|
- }
|
|
- iosp = osp;
|
|
- iesp = esp;
|
|
- return_with_code_iref();
|
|
- case pt_integer:
|
|
- INCR(p_integer);
|
|
- if (iosp >= ostop)
|
|
- return_with_stackoverflow_iref();
|
|
- ++iosp;
|
|
- make_int(iosp,
|
|
- ((int)*iref_packed & packed_int_mask) +
|
|
- packed_min_intval);
|
|
- next_short();
|
|
- case pt_literal_name:
|
|
- INCR(p_lit_name);
|
|
- {
|
|
- uint nidx = *iref_packed & packed_value_mask;
|
|
-
|
|
- if (iosp >= ostop)
|
|
- return_with_stackoverflow_iref();
|
|
- ++iosp;
|
|
- name_index_ref_inline(int_nt, nidx, iosp);
|
|
- next_short();
|
|
- }
|
|
- case pt_executable_name:
|
|
- INCR(p_exec_name);
|
|
- {
|
|
- uint nidx = *iref_packed & packed_value_mask;
|
|
-
|
|
- pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue;
|
|
- if (!pv_valid(pvalue)) {
|
|
- uint htemp;
|
|
-
|
|
- INCR(p_find_name);
|
|
- if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) {
|
|
- names_index_ref(int_nt, nidx, &token);
|
|
- return_with_error(e_undefined, &token);
|
|
- }
|
|
- }
|
|
- if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) { /* Literal, push it. */
|
|
- INCR(p_name_lit);
|
|
- if (iosp >= ostop)
|
|
- return_with_stackoverflow_iref();
|
|
- ++iosp;
|
|
- ref_assign_inline(iosp, pvalue);
|
|
- next_short();
|
|
- }
|
|
- if (r_is_proc(pvalue)) { /* This is an executable procedure, */
|
|
- /* execute it. */
|
|
- INCR(p_name_proc);
|
|
- store_state_short(iesp);
|
|
- goto pr;
|
|
- }
|
|
- /* Not a literal or procedure, reinterpret it. */
|
|
- store_state_short(iesp);
|
|
- icount = 0;
|
|
- SET_IREF(pvalue);
|
|
- goto top;
|
|
- }
|
|
- /* default can't happen here */
|
|
- }
|
|
- }
|
|
+ INCR(p_exec_non_x_operator);
|
|
+ esp = iesp;
|
|
+ osp = iosp;
|
|
+ switch (code = call_operator(op_index_proc(index), i_ctx_p)) {
|
|
+ case 0:
|
|
+ case 1:
|
|
+ iosp = osp;
|
|
+ next_short();
|
|
+ case o_push_estack:
|
|
+ store_state_short(iesp);
|
|
+ goto opush;
|
|
+ case o_pop_estack:
|
|
+ iosp = osp;
|
|
+ if (esp == iesp) {
|
|
+ next_short();
|
|
+ }
|
|
+ iesp = esp;
|
|
+ goto up;
|
|
+ case o_reschedule:
|
|
+ store_state_short(iesp);
|
|
+ goto res;
|
|
+ case e_RemapColor:
|
|
+ store_state_short(iesp);
|
|
+ goto remap;
|
|
+ }
|
|
+ iosp = osp;
|
|
+ iesp = esp;
|
|
+ return_with_code_iref();
|
|
+ case pt_integer:
|
|
+ INCR(p_integer);
|
|
+ if (iosp >= ostop)
|
|
+ return_with_stackoverflow_iref();
|
|
+ ++iosp;
|
|
+ make_int(iosp,
|
|
+ ((int)*iref_packed & packed_int_mask) +
|
|
+ packed_min_intval);
|
|
+ next_short();
|
|
+ case pt_literal_name:
|
|
+ INCR(p_lit_name);
|
|
+ {
|
|
+ uint nidx = *iref_packed & packed_value_mask;
|
|
+
|
|
+ if (iosp >= ostop)
|
|
+ return_with_stackoverflow_iref();
|
|
+ ++iosp;
|
|
+ name_index_ref_inline(int_nt, nidx, iosp);
|
|
+ next_short();
|
|
+ }
|
|
+ case pt_executable_name:
|
|
+ INCR(p_exec_name);
|
|
+ {
|
|
+ uint nidx = *iref_packed & packed_value_mask;
|
|
+
|
|
+ pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue;
|
|
+ if (!pv_valid(pvalue)) {
|
|
+ uint htemp;
|
|
+
|
|
+ INCR(p_find_name);
|
|
+ if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) {
|
|
+ names_index_ref(int_nt, nidx, &token);
|
|
+ return_with_error(e_undefined, &token);
|
|
+ }
|
|
+ }
|
|
+ if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) { /* Literal, push it. */
|
|
+ INCR(p_name_lit);
|
|
+ if (iosp >= ostop)
|
|
+ return_with_stackoverflow_iref();
|
|
+ ++iosp;
|
|
+ ref_assign_inline(iosp, pvalue);
|
|
+ next_short();
|
|
+ }
|
|
+ if (r_is_proc(pvalue)) { /* This is an executable procedure, */
|
|
+ /* execute it. */
|
|
+ INCR(p_name_proc);
|
|
+ store_state_short(iesp);
|
|
+ goto pr;
|
|
+ }
|
|
+ /* Not a literal or procedure, reinterpret it. */
|
|
+ store_state_short(iesp);
|
|
+ icount = 0;
|
|
+ SET_IREF(pvalue);
|
|
+ goto top;
|
|
+ }
|
|
+ /* default can't happen here */
|
|
+ }
|
|
+ }
|
|
}
|
|
/* Literal type, just push it. */
|
|
if (iosp >= ostop)
|
|
- return_with_stackoverflow_iref();
|
|
+ return_with_stackoverflow_iref();
|
|
++iosp;
|
|
ref_assign_inline(iosp, IREF);
|
|
bot:next();
|
|
- out: /* At most 1 more token in the current procedure. */
|
|
+ out: /* At most 1 more token in the current procedure. */
|
|
/* (We already decremented icount.) */
|
|
if (!icount) {
|
|
- /* Pop the execution stack for tail recursion. */
|
|
- iesp--;
|
|
- iref_packed = IREF_NEXT(iref_packed);
|
|
- goto top;
|
|
+ /* Pop the execution stack for tail recursion. */
|
|
+ iesp--;
|
|
+ iref_packed = IREF_NEXT(iref_packed);
|
|
+ goto top;
|
|
}
|
|
up:if (--ticks_left < 0)
|
|
- goto slice;
|
|
+ goto slice;
|
|
/* See if there is anything left on the execution stack. */
|
|
if (!r_is_proc(iesp)) {
|
|
- SET_IREF(iesp--);
|
|
- icount = 0;
|
|
- goto top;
|
|
+ SET_IREF(iesp--);
|
|
+ icount = 0;
|
|
+ goto top;
|
|
}
|
|
- SET_IREF(iesp->value.refs); /* next element of array */
|
|
+ SET_IREF(iesp->value.refs); /* next element of array */
|
|
icount = r_size(iesp) - 1;
|
|
- if (icount <= 0) { /* <= 1 more elements */
|
|
- iesp--; /* pop, or tail recursion */
|
|
- if (icount < 0)
|
|
- goto up;
|
|
+ if (icount <= 0) { /* <= 1 more elements */
|
|
+ iesp--; /* pop, or tail recursion */
|
|
+ if (icount < 0)
|
|
+ goto up;
|
|
}
|
|
goto top;
|
|
res:
|
|
@@ -1643,46 +1643,46 @@ res:
|
|
*pi_ctx_p = i_ctx_p;
|
|
code = (*i_ctx_p->reschedule_proc)(pi_ctx_p);
|
|
i_ctx_p = *pi_ctx_p;
|
|
- sched: /* We've just called a scheduling procedure. */
|
|
+ sched: /* We've just called a scheduling procedure. */
|
|
/* The interpreter state is in memory; iref is not current. */
|
|
if (code < 0) {
|
|
- set_error(code);
|
|
- /*
|
|
- * We need a real object to return as the error object.
|
|
- * (It only has to last long enough to store in
|
|
- * *perror_object.)
|
|
- */
|
|
- make_null_proc(&ierror.full);
|
|
- SET_IREF(ierror.obj = &ierror.full);
|
|
- goto error_exit;
|
|
+ set_error(code);
|
|
+ /*
|
|
+ * We need a real object to return as the error object.
|
|
+ * (It only has to last long enough to store in
|
|
+ * *perror_object.)
|
|
+ */
|
|
+ make_null_proc(&ierror.full);
|
|
+ SET_IREF(ierror.obj = &ierror.full);
|
|
+ goto error_exit;
|
|
}
|
|
/* Reload state information from memory. */
|
|
iosp = osp;
|
|
iesp = esp;
|
|
goto up;
|
|
-#if 0 /****** ****** ***** */
|
|
- sst: /* Time-slice, but push the current object first. */
|
|
+#if 0 /****** ****** ***** */
|
|
+ sst: /* Time-slice, but push the current object first. */
|
|
store_state(iesp);
|
|
if (iesp >= estop)
|
|
- return_with_error_iref(e_execstackoverflow);
|
|
+ return_with_error_iref(e_execstackoverflow);
|
|
iesp++;
|
|
ref_assign_inline(iesp, iref);
|
|
#endif /****** ****** ***** */
|
|
- slice: /* It's time to time-slice or garbage collect. */
|
|
+ slice: /* It's time to time-slice or garbage collect. */
|
|
/* iref is not live, so we don't need to do a store_state. */
|
|
osp = iosp;
|
|
esp = iesp;
|
|
/* If ticks_left <= -100, we need to GC now. */
|
|
- if (ticks_left <= -100) { /* We need to garbage collect now. */
|
|
- *pi_ctx_p = i_ctx_p;
|
|
- code = interp_reclaim(pi_ctx_p, -1);
|
|
- i_ctx_p = *pi_ctx_p;
|
|
+ if (ticks_left <= -100) { /* We need to garbage collect now. */
|
|
+ *pi_ctx_p = i_ctx_p;
|
|
+ code = interp_reclaim(pi_ctx_p, -1);
|
|
+ i_ctx_p = *pi_ctx_p;
|
|
} else if (i_ctx_p->time_slice_proc != NULL) {
|
|
- *pi_ctx_p = i_ctx_p;
|
|
- code = (*i_ctx_p->time_slice_proc)(pi_ctx_p);
|
|
- i_ctx_p = *pi_ctx_p;
|
|
+ *pi_ctx_p = i_ctx_p;
|
|
+ code = (*i_ctx_p->time_slice_proc)(pi_ctx_p);
|
|
+ i_ctx_p = *pi_ctx_p;
|
|
} else
|
|
- code = 0;
|
|
+ code = 0;
|
|
ticks_left = i_ctx_p->time_slice_ticks;
|
|
set_code_on_interrupt(imemory, &code);
|
|
goto sched;
|
|
@@ -1695,38 +1695,38 @@ res:
|
|
ierror.obj = IREF;
|
|
rwe:
|
|
if (!r_is_packed(iref_packed))
|
|
- store_state(iesp);
|
|
+ store_state(iesp);
|
|
else {
|
|
- /*
|
|
- * We need a real object to return as the error object.
|
|
- * (It only has to last long enough to store in *perror_object.)
|
|
- */
|
|
- packed_get(imemory, (const ref_packed *)ierror.obj, &ierror.full);
|
|
- store_state_short(iesp);
|
|
- if (IREF == ierror.obj)
|
|
- SET_IREF(&ierror.full);
|
|
- ierror.obj = &ierror.full;
|
|
+ /*
|
|
+ * We need a real object to return as the error object.
|
|
+ * (It only has to last long enough to store in *perror_object.)
|
|
+ */
|
|
+ packed_get(imemory, (const ref_packed *)ierror.obj, &ierror.full);
|
|
+ store_state_short(iesp);
|
|
+ if (IREF == ierror.obj)
|
|
+ SET_IREF(&ierror.full);
|
|
+ ierror.obj = &ierror.full;
|
|
}
|
|
error_exit:
|
|
- if (ERROR_IS_INTERRUPT(ierror.code)) { /* We must push the current object being interpreted */
|
|
- /* back on the e-stack so it will be re-executed. */
|
|
- /* Currently, this is always an executable operator, */
|
|
- /* but it might be something else someday if we check */
|
|
- /* for interrupts in the interpreter loop itself. */
|
|
- if (iesp >= estop)
|
|
- code = e_execstackoverflow;
|
|
- else {
|
|
- iesp++;
|
|
- ref_assign_inline(iesp, IREF);
|
|
- }
|
|
+ if (ERROR_IS_INTERRUPT(ierror.code)) { /* We must push the current object being interpreted */
|
|
+ /* back on the e-stack so it will be re-executed. */
|
|
+ /* Currently, this is always an executable operator, */
|
|
+ /* but it might be something else someday if we check */
|
|
+ /* for interrupts in the interpreter loop itself. */
|
|
+ if (iesp >= estop)
|
|
+ code = e_execstackoverflow;
|
|
+ else {
|
|
+ iesp++;
|
|
+ ref_assign_inline(iesp, IREF);
|
|
+ }
|
|
}
|
|
esp = iesp;
|
|
osp = iosp;
|
|
ref_assign_inline(perror_object, ierror.obj);
|
|
#ifdef DEBUG
|
|
if (ierror.code == e_InterpreterExit) {
|
|
- /* Do not call gs_log_error to reduce the noise. */
|
|
- return e_InterpreterExit;
|
|
+ /* Do not call gs_log_error to reduce the noise. */
|
|
+ return e_InterpreterExit;
|
|
}
|
|
#endif
|
|
return gs_log_error(ierror.code, __FILE__, ierror.line);
|
|
@@ -1744,7 +1744,7 @@ oparray_pop(i_ctx_t *i_ctx_p)
|
|
/* This procedure is called only from pop_estack. */
|
|
static int
|
|
oparray_cleanup(i_ctx_t *i_ctx_p)
|
|
-{ /* esp points just below the cleanup procedure. */
|
|
+{ /* esp points just below the cleanup procedure. */
|
|
es_ptr ep = esp;
|
|
uint ocount_old = (uint) ep[3].value.intval;
|
|
uint dcount_old = (uint) ep[4].value.intval;
|
|
@@ -1752,10 +1752,10 @@ oparray_cleanup(i_ctx_t *i_ctx_p)
|
|
uint dcount = ref_stack_count(&d_stack);
|
|
|
|
if (ocount > ocount_old)
|
|
- ref_stack_pop(&o_stack, ocount - ocount_old);
|
|
+ ref_stack_pop(&o_stack, ocount - ocount_old);
|
|
if (dcount > dcount_old) {
|
|
- ref_stack_pop(&d_stack, dcount - dcount_old);
|
|
- dict_set_top();
|
|
+ ref_stack_pop(&d_stack, dcount - dcount_old);
|
|
+ dict_set_top();
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -1775,11 +1775,11 @@ oparray_find(i_ctx_t *i_ctx_p)
|
|
ref *ep;
|
|
|
|
for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) {
|
|
- if (r_is_estack_mark(ep) &&
|
|
- (ep->value.opproc == oparray_cleanup ||
|
|
- ep->value.opproc == oparray_no_cleanup)
|
|
- )
|
|
- return ep;
|
|
+ if (r_is_estack_mark(ep) &&
|
|
+ (ep->value.opproc == oparray_cleanup ||
|
|
+ ep->value.opproc == oparray_no_cleanup)
|
|
+ )
|
|
+ return ep;
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -1794,15 +1794,15 @@ zerrorexec(i_ctx_t *i_ctx_p)
|
|
int code;
|
|
|
|
check_op(2);
|
|
- check_estack(4); /* mark/cleanup, errobj, pop, obj */
|
|
+ check_estack(4); /* mark/cleanup, errobj, pop, obj */
|
|
push_mark_estack(es_other, errorexec_cleanup);
|
|
*++esp = op[-1];
|
|
push_op_estack(errorexec_pop);
|
|
code = zexec(i_ctx_p);
|
|
if (code >= 0)
|
|
- pop(1);
|
|
+ pop(1);
|
|
else
|
|
- esp -= 3; /* undo our additions to estack */
|
|
+ esp -= 3; /* undo our additions to estack */
|
|
return code;
|
|
}
|
|
|
|
@@ -1817,12 +1817,12 @@ zfinderrorobject(i_ctx_t *i_ctx_p)
|
|
ref errobj;
|
|
|
|
if (errorexec_find(i_ctx_p, &errobj)) {
|
|
- push(2);
|
|
- op[-1] = errobj;
|
|
- make_true(op);
|
|
+ push(2);
|
|
+ op[-1] = errobj;
|
|
+ make_true(op);
|
|
} else {
|
|
- push(1);
|
|
- make_false(op);
|
|
+ push(1);
|
|
+ make_false(op);
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -1839,24 +1839,24 @@ errorexec_find(i_ctx_t *i_ctx_p, ref *pe
|
|
const ref *ep;
|
|
|
|
for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) {
|
|
- if (r_is_estack_mark(ep)) {
|
|
- if (ep->value.opproc == oparray_cleanup) {
|
|
- /* See oppr: above. */
|
|
- uint opindex = (uint)ep[1].value.intval;
|
|
- if (opindex == 0) /* internal operator, ignore */
|
|
- continue;
|
|
- op_index_ref(imemory, opindex, perror_object);
|
|
- return 1;
|
|
- }
|
|
- if (ep->value.opproc == oparray_no_cleanup)
|
|
- return 0; /* protection disabled */
|
|
- if (ep->value.opproc == errorexec_cleanup) {
|
|
- if (r_has_type(ep + 1, t_null))
|
|
- return 0;
|
|
- *perror_object = ep[1]; /* see .errorexec above */
|
|
- return 1;
|
|
- }
|
|
- }
|
|
+ if (r_is_estack_mark(ep)) {
|
|
+ if (ep->value.opproc == oparray_cleanup) {
|
|
+ /* See oppr: above. */
|
|
+ uint opindex = (uint)ep[1].value.intval;
|
|
+ if (opindex == 0) /* internal operator, ignore */
|
|
+ continue;
|
|
+ op_index_ref(imemory, opindex, perror_object);
|
|
+ return 1;
|
|
+ }
|
|
+ if (ep->value.opproc == oparray_no_cleanup)
|
|
+ return 0; /* protection disabled */
|
|
+ if (ep->value.opproc == errorexec_cleanup) {
|
|
+ if (r_has_type(ep + 1, t_null))
|
|
+ return 0;
|
|
+ *perror_object = ep[1]; /* see .errorexec above */
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -1886,9 +1886,9 @@ zsetstackprotect(i_ctx_t *i_ctx_p)
|
|
|
|
check_type(*op, t_boolean);
|
|
if (ep == 0)
|
|
- return_error(e_rangecheck);
|
|
+ return_error(e_rangecheck);
|
|
ep->value.opproc =
|
|
- (op->value.boolval ? oparray_cleanup : oparray_no_cleanup);
|
|
+ (op->value.boolval ? oparray_cleanup : oparray_no_cleanup);
|
|
pop(1);
|
|
return 0;
|
|
}
|
|
@@ -1902,7 +1902,7 @@ zcurrentstackprotect(i_ctx_t *i_ctx_p)
|
|
ref *ep = oparray_find(i_ctx_p);
|
|
|
|
if (ep == 0)
|
|
- return_error(e_rangecheck);
|
|
+ return_error(e_rangecheck);
|
|
push(1);
|
|
make_bool(op, ep->value.opproc == oparray_cleanup);
|
|
return 0;
|
|
diff -up ghostscript-9.00/psi/iscan.c.scan_token ghostscript-9.00/psi/iscan.c
|
|
--- ghostscript-9.00/psi/iscan.c.scan_token 2010-04-26 16:29:28.000000000 +0100
|
|
+++ ghostscript-9.00/psi/iscan.c 2011-01-14 17:16:12.610867620 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -18,25 +18,25 @@
|
|
#include "string_.h"
|
|
#include "stream.h"
|
|
#include "ierrors.h"
|
|
-#include "btoken.h" /* for ref_binary_object_format */
|
|
-#include "files.h" /* for fptr */
|
|
+#include "btoken.h" /* for ref_binary_object_format */
|
|
+#include "files.h" /* for fptr */
|
|
#include "ialloc.h"
|
|
-#include "idict.h" /* for //name lookup */
|
|
-#include "dstack.h" /* ditto */
|
|
+#include "idict.h" /* for //name lookup */
|
|
+#include "dstack.h" /* ditto */
|
|
#include "ilevel.h"
|
|
#include "iname.h"
|
|
#include "ipacked.h"
|
|
#include "iparray.h"
|
|
-#include "strimpl.h" /* for string decoding */
|
|
-#include "sa85d.h" /* ditto */
|
|
-#include "sfilter.h" /* ditto */
|
|
-#include "ostack.h" /* for accumulating proc bodies; */
|
|
- /* must precede iscan.h */
|
|
-#include "iscan.h" /* defines interface */
|
|
+#include "strimpl.h" /* for string decoding */
|
|
+#include "sa85d.h" /* ditto */
|
|
+#include "sfilter.h" /* ditto */
|
|
+#include "ostack.h" /* for accumulating proc bodies; */
|
|
+ /* must precede iscan.h */
|
|
+#include "iscan.h" /* defines interface */
|
|
#include "iscanbin.h"
|
|
#include "iscannum.h"
|
|
#include "istream.h"
|
|
-#include "istruct.h" /* for RELOC_REF_VAR */
|
|
+#include "istruct.h" /* for RELOC_REF_VAR */
|
|
#include "iutil.h"
|
|
#include "ivmspace.h"
|
|
#include "store.h"
|
|
@@ -47,13 +47,13 @@
|
|
|
|
/* Procedure for handling DSC comments if desired. */
|
|
/* Set at initialization if a DSC handling module is included. */
|
|
-int (*scan_dsc_proc) (const byte *, uint) = NULL;
|
|
+int (*gs_scan_dsc_proc) (const byte *, uint) = NULL;
|
|
|
|
/* Procedure for handling all comments if desired. */
|
|
/* Set at initialization if a comment handling module is included. */
|
|
-/* If both scan_comment_proc and scan_dsc_proc are set, */
|
|
+/* If both gs_scan_comment_proc and gs_scan_dsc_proc are set, */
|
|
/* scan_comment_proc is called only for non-DSC comments. */
|
|
-int (*scan_comment_proc) (const byte *, uint) = NULL;
|
|
+int (*gs_scan_comment_proc) (const byte *, uint) = NULL;
|
|
|
|
/*
|
|
* Level 2 includes some changes in the scanner:
|
|
@@ -63,7 +63,7 @@ int (*scan_comment_proc) (const byte *,
|
|
* - Character codes above 127 introduce binary objects.
|
|
* We explicitly enable or disable these changes here.
|
|
*/
|
|
-#define scan_enable_level2 level2_enabled /* from ilevel.h */
|
|
+#define scan_enable_level2 level2_enabled /* from ilevel.h */
|
|
|
|
/* ------ Dynamic strings ------ */
|
|
|
|
@@ -82,7 +82,7 @@ static void
|
|
dynamic_free(da_ptr pda)
|
|
{
|
|
if (pda->is_dynamic)
|
|
- gs_free_string(pda->memory, pda->base, da_size(pda), "scanner");
|
|
+ gs_free_string(pda->memory, pda->base, da_size(pda), "scanner");
|
|
}
|
|
|
|
/* Resize a dynamic string. */
|
|
@@ -96,16 +96,16 @@ dynamic_resize(da_ptr pda, uint new_size
|
|
byte *base;
|
|
|
|
if (pda->is_dynamic) {
|
|
- base = gs_resize_string(mem, pda->base, old_size,
|
|
- new_size, "scanner");
|
|
- if (base == 0)
|
|
- return_error(e_VMerror);
|
|
- } else { /* switching from static to dynamic */
|
|
- base = gs_alloc_string(mem, new_size, "scanner");
|
|
- if (base == 0)
|
|
- return_error(e_VMerror);
|
|
- memcpy(base, pda->base, min(old_size, new_size));
|
|
- pda->is_dynamic = true;
|
|
+ base = gs_resize_string(mem, pda->base, old_size,
|
|
+ new_size, "scanner");
|
|
+ if (base == 0)
|
|
+ return_error(e_VMerror);
|
|
+ } else { /* switching from static to dynamic */
|
|
+ base = gs_alloc_string(mem, new_size, "scanner");
|
|
+ if (base == 0)
|
|
+ return_error(e_VMerror);
|
|
+ memcpy(base, pda->base, min(old_size, new_size));
|
|
+ pda->is_dynamic = true;
|
|
}
|
|
pda->base = base;
|
|
pda->next = base + pos;
|
|
@@ -122,17 +122,17 @@ dynamic_grow(da_ptr pda, byte * next, ui
|
|
{
|
|
uint old_size = da_size(pda);
|
|
uint new_size = (old_size < 10 ? 20 :
|
|
- old_size >= (max_size >> 1) ? max_size :
|
|
- old_size << 1);
|
|
+ old_size >= (max_size >> 1) ? max_size :
|
|
+ old_size << 1);
|
|
int code;
|
|
|
|
pda->next = next;
|
|
if (old_size >= max_size)
|
|
- return_error(e_limitcheck);
|
|
+ return_error(e_limitcheck);
|
|
while ((code = dynamic_resize(pda, new_size)) < 0 &&
|
|
- new_size > old_size
|
|
- ) { /* Try trimming down the requested new size. */
|
|
- new_size -= (new_size - old_size + 1) >> 1;
|
|
+ new_size > old_size
|
|
+ ) { /* Try trimming down the requested new size. */
|
|
+ new_size -= (new_size - old_size + 1) >> 1;
|
|
}
|
|
return code;
|
|
}
|
|
@@ -145,11 +145,11 @@ dynamic_save(da_ptr pda)
|
|
if (!pda->is_dynamic && pda->base != pda->buf) {
|
|
int len = da_size(pda);
|
|
|
|
- if (len > sizeof(pda->buf))
|
|
+ if (len > sizeof(pda->buf))
|
|
len = sizeof(pda->buf);
|
|
memcpy(pda->buf, pda->base, len);
|
|
- pda->next = pda->buf + len;
|
|
- pda->base = pda->buf;
|
|
+ pda->next = pda->buf + len;
|
|
+ pda->base = pda->buf;
|
|
}
|
|
}
|
|
|
|
@@ -161,10 +161,10 @@ dynamic_make_string(i_ctx_t *i_ctx_p, re
|
|
int code = dynamic_resize(pda, size);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
make_tasv_new(pref, t_string,
|
|
- a_all | imemory_space((gs_ref_memory_t *) pda->memory),
|
|
- size, bytes, pda->base);
|
|
+ a_all | imemory_space((gs_ref_memory_t *) pda->memory),
|
|
+ size, bytes, pda->base);
|
|
return 0;
|
|
}
|
|
|
|
@@ -172,7 +172,7 @@ dynamic_make_string(i_ctx_t *i_ctx_p, re
|
|
|
|
/* GC procedures */
|
|
#define ssarray ssptr->s_ss.binary.bin_array
|
|
-static
|
|
+static
|
|
CLEAR_MARKS_PROC(scanner_clear_marks)
|
|
{
|
|
scanner_state *const ssptr = vptr;
|
|
@@ -181,7 +181,7 @@ CLEAR_MARKS_PROC(scanner_clear_marks)
|
|
r_clear_attrs(&ssarray, l_mark);
|
|
r_clear_attrs(&ssptr->s_error.object, l_mark);
|
|
}
|
|
-static
|
|
+static
|
|
ENUM_PTRS_WITH(scanner_enum_ptrs, scanner_state *ssptr) return 0;
|
|
case 0:
|
|
ENUM_RETURN_REF(&ssptr->s_file);
|
|
@@ -189,13 +189,13 @@ case 1:
|
|
ENUM_RETURN_REF(&ssptr->s_error.object);
|
|
case 2:
|
|
if (ssptr->s_scan_type == scanning_none ||
|
|
- !ssptr->s_da.is_dynamic
|
|
- )
|
|
- ENUM_RETURN(0);
|
|
+ !ssptr->s_da.is_dynamic
|
|
+ )
|
|
+ ENUM_RETURN(0);
|
|
return ENUM_STRING2(ssptr->s_da.base, da_size(&ssptr->s_da));
|
|
case 3:
|
|
if (ssptr->s_scan_type != scanning_binary)
|
|
- return 0;
|
|
+ return 0;
|
|
ENUM_RETURN_REF(&ssarray);
|
|
ENUM_PTRS_END
|
|
static RELOC_PTRS_WITH(scanner_reloc_ptrs, scanner_state *ssptr)
|
|
@@ -203,18 +203,18 @@ static RELOC_PTRS_WITH(scanner_reloc_ptr
|
|
RELOC_REF_VAR(ssptr->s_file);
|
|
r_clear_attrs(&ssptr->s_file, l_mark);
|
|
if (ssptr->s_scan_type != scanning_none && ssptr->s_da.is_dynamic) {
|
|
- gs_string sda;
|
|
+ gs_string sda;
|
|
|
|
- sda.data = ssptr->s_da.base;
|
|
- sda.size = da_size(&ssptr->s_da);
|
|
- RELOC_STRING_VAR(sda);
|
|
- ssptr->s_da.limit = sda.data + sda.size;
|
|
- ssptr->s_da.next = sda.data + (ssptr->s_da.next - ssptr->s_da.base);
|
|
- ssptr->s_da.base = sda.data;
|
|
+ sda.data = ssptr->s_da.base;
|
|
+ sda.size = da_size(&ssptr->s_da);
|
|
+ RELOC_STRING_VAR(sda);
|
|
+ ssptr->s_da.limit = sda.data + sda.size;
|
|
+ ssptr->s_da.next = sda.data + (ssptr->s_da.next - ssptr->s_da.base);
|
|
+ ssptr->s_da.base = sda.data;
|
|
}
|
|
if (ssptr->s_scan_type == scanning_binary) {
|
|
- RELOC_REF_VAR(ssarray);
|
|
- r_clear_attrs(&ssarray, l_mark);
|
|
+ RELOC_REF_VAR(ssarray);
|
|
+ r_clear_attrs(&ssarray, l_mark);
|
|
}
|
|
RELOC_REF_VAR(ssptr->s_error.object);
|
|
r_clear_attrs(&ssptr->s_error.object, l_mark);
|
|
@@ -225,7 +225,7 @@ public_st_scanner_state_dynamic();
|
|
|
|
/* Initialize a scanner. */
|
|
void
|
|
-scanner_init_options(scanner_state *sstate, const ref *fop, int options)
|
|
+gs_scanner_init_options(scanner_state *sstate, const ref *fop, int options)
|
|
{
|
|
ref_assign(&sstate->s_file, fop);
|
|
sstate->s_scan_type = scanning_none;
|
|
@@ -233,8 +233,8 @@ scanner_init_options(scanner_state *ssta
|
|
sstate->s_options = options;
|
|
SCAN_INIT_ERROR(sstate);
|
|
}
|
|
-void scanner_init_stream_options(scanner_state *sstate, stream *s,
|
|
- int options)
|
|
+void gs_scanner_init_stream_options(scanner_state *sstate, stream *s,
|
|
+ int options)
|
|
{
|
|
/*
|
|
* The file 'object' will never be accessed, but it must be in correct
|
|
@@ -243,7 +243,7 @@ void scanner_init_stream_options(scanner
|
|
ref fobj;
|
|
|
|
make_file(&fobj, a_read, 0, s);
|
|
- scanner_init_options(sstate, &fobj, options);
|
|
+ gs_scanner_init_options(sstate, &fobj, options);
|
|
}
|
|
|
|
/*
|
|
@@ -251,42 +251,42 @@ void scanner_init_stream_options(scanner
|
|
* --token--, if any, or <0 if no special error object is available.
|
|
*/
|
|
int
|
|
-scanner_error_object(i_ctx_t *i_ctx_p, const scanner_state *pstate,
|
|
- ref *pseo)
|
|
+gs_scanner_error_object(i_ctx_t *i_ctx_p, const scanner_state *pstate,
|
|
+ ref *pseo)
|
|
{
|
|
if (!r_has_type(&pstate->s_error.object, t__invalid)) {
|
|
- ref_assign(pseo, &pstate->s_error.object);
|
|
- return 0;
|
|
+ ref_assign(pseo, &pstate->s_error.object);
|
|
+ return 0;
|
|
}
|
|
if (pstate->s_error.string[0]) {
|
|
- int len = strlen(pstate->s_error.string);
|
|
+ int len = strlen(pstate->s_error.string);
|
|
|
|
- if (pstate->s_error.is_name) {
|
|
- int code = name_ref(imemory, (const byte *)pstate->s_error.string, len, pseo, 1);
|
|
+ if (pstate->s_error.is_name) {
|
|
+ int code = name_ref(imemory, (const byte *)pstate->s_error.string, len, pseo, 1);
|
|
|
|
- if (code < 0)
|
|
- return code;
|
|
- r_set_attrs(pseo, a_executable); /* Adobe compatibility */
|
|
- return 0;
|
|
- } else {
|
|
- byte *estr = ialloc_string(len, "scanner_error_object");
|
|
-
|
|
- if (estr == 0)
|
|
- return -1; /* VMerror */
|
|
- memcpy(estr, (const byte *)pstate->s_error.string, len);
|
|
- make_string(pseo, a_all | icurrent_space, len, estr);
|
|
- return 0;
|
|
- }
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ r_set_attrs(pseo, a_executable); /* Adobe compatibility */
|
|
+ return 0;
|
|
+ } else {
|
|
+ byte *estr = ialloc_string(len, "gs_scanner_error_object");
|
|
+
|
|
+ if (estr == 0)
|
|
+ return -1; /* VMerror */
|
|
+ memcpy(estr, (const byte *)pstate->s_error.string, len);
|
|
+ make_string(pseo, a_all | icurrent_space, len, estr);
|
|
+ return 0;
|
|
+ }
|
|
}
|
|
- return -1; /* no error object */
|
|
+ return -1; /* no error object */
|
|
}
|
|
|
|
-/* Handle a scan_Refill return from scan_token. */
|
|
-/* This may return o_push_estack, 0 (meaning just call scan_token again), */
|
|
-/* or an error code. */
|
|
+/* Handle a scan_Refill return from gs_scan_token. */
|
|
+/* This may return o_push_estack, 0 (meaning just call gs_scan_token */
|
|
+/* again), or an error code. */
|
|
int
|
|
-scan_handle_refill(i_ctx_t *i_ctx_p, scanner_state * sstate,
|
|
- bool save, op_proc_t cont)
|
|
+gs_scan_handle_refill(i_ctx_t *i_ctx_p, scanner_state * sstate,
|
|
+ bool save, op_proc_t cont)
|
|
{
|
|
const ref *const fop = &sstate->s_file;
|
|
stream *s = fptr(fop);
|
|
@@ -294,41 +294,41 @@ scan_handle_refill(i_ctx_t *i_ctx_p, sca
|
|
int status;
|
|
|
|
if (s->end_status == EOFC) {
|
|
- /* More data needed, but none available, so this is a syntax error. */
|
|
- return_error(e_syntaxerror);
|
|
+ /* More data needed, but none available, so this is a syntax error. */
|
|
+ return_error(e_syntaxerror);
|
|
}
|
|
status = s_process_read_buf(s);
|
|
if (sbufavailable(s) > avail)
|
|
- return 0;
|
|
+ return 0;
|
|
if (status == 0)
|
|
- status = s->end_status;
|
|
+ status = s->end_status;
|
|
switch (status) {
|
|
- case EOFC:
|
|
- /* We just discovered that we're at EOF. */
|
|
- /* Let the caller find this out. */
|
|
- return 0;
|
|
- case ERRC:
|
|
- return_error(e_ioerror);
|
|
- case INTC:
|
|
- case CALLC:
|
|
- {
|
|
- ref rstate[1];
|
|
- scanner_state *pstate;
|
|
-
|
|
- if (save) {
|
|
- pstate = (scanner_state *)
|
|
- ialloc_struct(scanner_state_dynamic, &st_scanner_state_dynamic,
|
|
- "scan_handle_refill");
|
|
- if (pstate == 0)
|
|
- return_error(e_VMerror);
|
|
- ((scanner_state_dynamic *)pstate)->mem = imemory;
|
|
- *pstate = *sstate;
|
|
- } else
|
|
- pstate = sstate;
|
|
- make_istruct(&rstate[0], 0, pstate);
|
|
- return s_handle_read_exception(i_ctx_p, status, fop,
|
|
- rstate, 1, cont);
|
|
- }
|
|
+ case EOFC:
|
|
+ /* We just discovered that we're at EOF. */
|
|
+ /* Let the caller find this out. */
|
|
+ return 0;
|
|
+ case ERRC:
|
|
+ return_error(e_ioerror);
|
|
+ case INTC:
|
|
+ case CALLC:
|
|
+ {
|
|
+ ref rstate[1];
|
|
+ scanner_state *pstate;
|
|
+
|
|
+ if (save) {
|
|
+ pstate = (scanner_state *)
|
|
+ ialloc_struct(scanner_state_dynamic, &st_scanner_state_dynamic,
|
|
+ "gs_scan_handle_refill");
|
|
+ if (pstate == 0)
|
|
+ return_error(e_VMerror);
|
|
+ ((scanner_state_dynamic *)pstate)->mem = imemory;
|
|
+ *pstate = *sstate;
|
|
+ } else
|
|
+ pstate = sstate;
|
|
+ make_istruct(&rstate[0], 0, pstate);
|
|
+ return s_handle_read_exception(i_ctx_p, status, fop,
|
|
+ rstate, 1, cont);
|
|
+ }
|
|
}
|
|
/* No more data available, but no exception. */
|
|
/* A filter is consuming headers but returns nothing. */
|
|
@@ -341,7 +341,7 @@ scan_handle_refill(i_ctx_t *i_ctx_p, sca
|
|
*/
|
|
static int
|
|
scan_comment(i_ctx_t *i_ctx_p, ref *pref, scanner_state *pstate,
|
|
- const byte * base, const byte * end, bool saved)
|
|
+ const byte * base, const byte * end, bool saved)
|
|
{
|
|
uint len = (uint) (end - base);
|
|
int code;
|
|
@@ -350,50 +350,50 @@ scan_comment(i_ctx_t *i_ctx_p, ref *pref
|
|
#endif
|
|
|
|
if (len > 1 && (base[1] == '%' || base[1] == '!')) {
|
|
- /* Process as a DSC comment if requested. */
|
|
+ /* Process as a DSC comment if requested. */
|
|
#ifdef DEBUG
|
|
- if (gs_debug_c('%')) {
|
|
- dlprintf2("[%%%%%s%c]", sstr, (len >= 3 ? '+' : '-'));
|
|
- debug_print_string(base, len);
|
|
- dputs("\n");
|
|
- }
|
|
+ if (gs_debug_c('%')) {
|
|
+ dlprintf2("[%%%%%s%c]", sstr, (len >= 3 ? '+' : '-'));
|
|
+ debug_print_string(base, len);
|
|
+ dputs("\n");
|
|
+ }
|
|
#endif
|
|
- if (scan_dsc_proc != NULL) {
|
|
- code = scan_dsc_proc(base, len);
|
|
- return (code < 0 ? code : 0);
|
|
- }
|
|
- if (pstate->s_options & SCAN_PROCESS_DSC_COMMENTS) {
|
|
- code = scan_DSC_Comment;
|
|
- goto comment;
|
|
- }
|
|
- /* Treat as an ordinary comment. */
|
|
+ if (gs_scan_dsc_proc != NULL) {
|
|
+ code = gs_scan_dsc_proc(base, len);
|
|
+ return (code < 0 ? code : 0);
|
|
+ }
|
|
+ if (pstate->s_options & SCAN_PROCESS_DSC_COMMENTS) {
|
|
+ code = scan_DSC_Comment;
|
|
+ goto comment;
|
|
+ }
|
|
+ /* Treat as an ordinary comment. */
|
|
}
|
|
#ifdef DEBUG
|
|
else {
|
|
- if (gs_debug_c('%')) {
|
|
- dlprintf2("[%% %s%c]", sstr, (len >= 2 ? '+' : '-'));
|
|
- debug_print_string(base, len);
|
|
- dputs("\n");
|
|
- }
|
|
+ if (gs_debug_c('%')) {
|
|
+ dlprintf2("[%% %s%c]", sstr, (len >= 2 ? '+' : '-'));
|
|
+ debug_print_string(base, len);
|
|
+ dputs("\n");
|
|
+ }
|
|
}
|
|
#endif
|
|
- if (scan_comment_proc != NULL) {
|
|
- code = scan_comment_proc(base, len);
|
|
- return (code < 0 ? code : 0);
|
|
+ if (gs_scan_comment_proc != NULL) {
|
|
+ code = gs_scan_comment_proc(base, len);
|
|
+ return (code < 0 ? code : 0);
|
|
}
|
|
if (pstate->s_options & SCAN_PROCESS_COMMENTS) {
|
|
- code = scan_Comment;
|
|
- goto comment;
|
|
+ code = scan_Comment;
|
|
+ goto comment;
|
|
}
|
|
return 0;
|
|
comment:
|
|
{
|
|
- byte *cstr = ialloc_string(len, "scan_comment");
|
|
+ byte *cstr = ialloc_string(len, "scan_comment");
|
|
|
|
- if (cstr == 0)
|
|
- return_error(e_VMerror);
|
|
- memcpy(cstr, base, len);
|
|
- make_string(pref, a_all | icurrent_space, len, cstr);
|
|
+ if (cstr == 0)
|
|
+ return_error(e_VMerror);
|
|
+ memcpy(cstr, base, len);
|
|
+ make_string(pref, a_all | icurrent_space, len, cstr);
|
|
}
|
|
return code;
|
|
}
|
|
@@ -402,8 +402,8 @@ scan_comment(i_ctx_t *i_ctx_p, ref *pref
|
|
/* Update the string if succesful. */
|
|
/* Store the error object in i_ctx_p->error_object if not. */
|
|
int
|
|
-scan_string_token_options(i_ctx_t *i_ctx_p, ref * pstr, ref * pref,
|
|
- int options)
|
|
+gs_scan_string_token_options(i_ctx_t *i_ctx_p, ref * pstr, ref * pref,
|
|
+ int options)
|
|
{
|
|
stream st;
|
|
stream *s = &st;
|
|
@@ -411,31 +411,31 @@ scan_string_token_options(i_ctx_t *i_ctx
|
|
int code;
|
|
|
|
if (!r_has_attr(pstr, a_read))
|
|
- return_error(e_invalidaccess);
|
|
+ return_error(e_invalidaccess);
|
|
s_init(s, NULL);
|
|
sread_string(s, pstr->value.bytes, r_size(pstr));
|
|
- scanner_init_stream_options(&state, s, options | SCAN_FROM_STRING);
|
|
- switch (code = scan_token(i_ctx_p, pref, &state)) {
|
|
- default: /* error or comment */
|
|
- if (code < 0)
|
|
- break;
|
|
- /* falls through */
|
|
- case 0: /* read a token */
|
|
- case scan_BOS:
|
|
- {
|
|
- uint pos = stell(s);
|
|
-
|
|
- pstr->value.bytes += pos;
|
|
- r_dec_size(pstr, pos);
|
|
- }
|
|
- break;
|
|
- case scan_Refill: /* error */
|
|
- code = gs_note_error(e_syntaxerror);
|
|
- case scan_EOF:
|
|
- break;
|
|
+ gs_scanner_init_stream_options(&state, s, options | SCAN_FROM_STRING);
|
|
+ switch (code = gs_scan_token(i_ctx_p, pref, &state)) {
|
|
+ default: /* error or comment */
|
|
+ if (code < 0)
|
|
+ break;
|
|
+ /* falls through */
|
|
+ case 0: /* read a token */
|
|
+ case scan_BOS:
|
|
+ {
|
|
+ uint pos = stell(s);
|
|
+
|
|
+ pstr->value.bytes += pos;
|
|
+ r_dec_size(pstr, pos);
|
|
+ }
|
|
+ break;
|
|
+ case scan_Refill: /* error */
|
|
+ code = gs_note_error(e_syntaxerror);
|
|
+ case scan_EOF:
|
|
+ break;
|
|
}
|
|
if (code < 0)
|
|
- scanner_error_object(i_ctx_p, &state, &i_ctx_p->error_object);
|
|
+ gs_scanner_error_object(i_ctx_p, &state, &i_ctx_p->error_object);
|
|
return code;
|
|
}
|
|
|
|
@@ -448,7 +448,7 @@ scan_string_token_options(i_ctx_t *i_ctx
|
|
* as well as for scan_Refill.
|
|
*/
|
|
int
|
|
-scan_token(i_ctx_t *i_ctx_p, ref * pref, scanner_state * pstate)
|
|
+gs_scan_token(i_ctx_t *i_ctx_p, ref * pref, scanner_state * pstate)
|
|
{
|
|
stream *const s = pstate->s_file.value.pfile;
|
|
ref *myref = pref;
|
|
@@ -474,7 +474,7 @@ scan_token(i_ctx_t *i_ctx_p, ref * pref,
|
|
if ( osp >= osbot ) osp--;\
|
|
else ref_stack_pop(&o_stack, 1)
|
|
int max_name_ctype =
|
|
- (recognize_btokens()? ctype_name : ctype_btoken);
|
|
+ (recognize_btokens()? ctype_name : ctype_btoken);
|
|
|
|
#define scan_sign(sign, ptr)\
|
|
switch ( *ptr ) {\
|
|
@@ -512,42 +512,42 @@ scan_token(i_ctx_t *i_ctx_p, ref * pref,
|
|
|
|
sptr = endptr = NULL; /* Quiet compiler */
|
|
if (pstate->s_pstack != 0) {
|
|
- if_not_spush1()
|
|
- return retcode;
|
|
- myref = osp;
|
|
+ if_not_spush1()
|
|
+ return retcode;
|
|
+ myref = osp;
|
|
}
|
|
/* Check whether we are resuming after an interruption. */
|
|
if (pstate->s_scan_type != scanning_none) {
|
|
- sstate = *pstate;
|
|
- if (!da.is_dynamic && da.base != da.buf) {
|
|
- /* The da contains some self-referencing pointers. */
|
|
- /* Fix them up now. */
|
|
- uint next = da.next - da.base;
|
|
- uint limit = da.limit - da.base;
|
|
-
|
|
- da.base = da.buf;
|
|
- da.next = da.buf + next;
|
|
- da.limit = da.buf + limit;
|
|
- }
|
|
- daptr = da.next;
|
|
- switch (scan_type) {
|
|
- case scanning_binary:
|
|
- retcode = (*sstate.s_ss.binary.cont)
|
|
- (i_ctx_p, myref, &sstate);
|
|
- scan_begin_inline();
|
|
- if (retcode == scan_Refill)
|
|
- goto pause;
|
|
- goto sret;
|
|
- case scanning_comment:
|
|
- scan_begin_inline();
|
|
- goto cont_comment;
|
|
- case scanning_name:
|
|
- goto cont_name;
|
|
- case scanning_string:
|
|
- goto cont_string;
|
|
- default:
|
|
- return_error(e_Fatal);
|
|
- }
|
|
+ sstate = *pstate;
|
|
+ if (!da.is_dynamic && da.base != da.buf) {
|
|
+ /* The da contains some self-referencing pointers. */
|
|
+ /* Fix them up now. */
|
|
+ uint next = da.next - da.base;
|
|
+ uint limit = da.limit - da.base;
|
|
+
|
|
+ da.base = da.buf;
|
|
+ da.next = da.buf + next;
|
|
+ da.limit = da.buf + limit;
|
|
+ }
|
|
+ daptr = da.next;
|
|
+ switch (scan_type) {
|
|
+ case scanning_binary:
|
|
+ retcode = (*sstate.s_ss.binary.cont)
|
|
+ (i_ctx_p, myref, &sstate);
|
|
+ scan_begin_inline();
|
|
+ if (retcode == scan_Refill)
|
|
+ goto pause;
|
|
+ goto sret;
|
|
+ case scanning_comment:
|
|
+ scan_begin_inline();
|
|
+ goto cont_comment;
|
|
+ case scanning_name:
|
|
+ goto cont_name;
|
|
+ case scanning_string:
|
|
+ goto cont_string;
|
|
+ default:
|
|
+ return_error(e_Fatal);
|
|
+ }
|
|
}
|
|
/* Fetch any state variables that are relevant even if */
|
|
/* scan_type == scanning_none. */
|
|
@@ -564,658 +564,658 @@ scan_token(i_ctx_t *i_ctx_p, ref * pref,
|
|
top:c = scan_getc();
|
|
if_debug1('S', (c >= 32 && c <= 126 ? "`%c'" : c >= 0 ? "`\\%03o'" : "`%d'"), c);
|
|
switch (c) {
|
|
- case ' ':
|
|
- case '\f':
|
|
- case '\t':
|
|
- case char_CR:
|
|
- case char_EOL:
|
|
- case char_NULL:
|
|
- goto top;
|
|
- case 0x04: /* see ctrld above */
|
|
- if (c == ctrld) /* treat as ordinary name char */
|
|
- goto begin_name;
|
|
- case '[':
|
|
- case ']':
|
|
- s1[0] = (byte) c;
|
|
- retcode = name_ref(imemory, s1, 1, myref, 1); /* can't fail */
|
|
- r_set_attrs(myref, a_executable);
|
|
- break;
|
|
- case '<':
|
|
- if (scan_enable_level2) {
|
|
- ensure2(scanning_none);
|
|
- c = scan_getc();
|
|
- switch (c) {
|
|
- case '<':
|
|
- scan_putback();
|
|
- name_type = 0;
|
|
- try_number = false;
|
|
- goto try_funny_name;
|
|
- case '~':
|
|
- s_A85D_init_inline(&sstate.s_ss.a85d);
|
|
- sstate.s_ss.st.template = &s_A85D_template;
|
|
- goto str;
|
|
- }
|
|
- scan_putback();
|
|
- }
|
|
- s_AXD_init_inline(&sstate.s_ss.axd);
|
|
- sstate.s_ss.st.template = &s_AXD_template;
|
|
- str:scan_end_inline();
|
|
- dynamic_init(&da, imemory);
|
|
- cont_string:for (;;) {
|
|
- stream_cursor_write w;
|
|
-
|
|
- w.ptr = da.next - 1;
|
|
- w.limit = da.limit - 1;
|
|
- status = (*sstate.s_ss.st.template->process)
|
|
- (&sstate.s_ss.st, &s->cursor.r, &w,
|
|
- s->end_status == EOFC);
|
|
- if (!check_only)
|
|
- da.next = w.ptr + 1;
|
|
- switch (status) {
|
|
- case 0:
|
|
- status = s->end_status;
|
|
- if (status < 0) {
|
|
- if (status == EOFC) {
|
|
- if (check_only) {
|
|
- retcode = scan_Refill;
|
|
- scan_type = scanning_string;
|
|
- goto suspend;
|
|
- } else
|
|
- sreturn(e_syntaxerror);
|
|
- }
|
|
- break;
|
|
- }
|
|
- s_process_read_buf(s);
|
|
- continue;
|
|
- case 1:
|
|
- if (!check_only) {
|
|
- retcode = dynamic_grow(&da, da.next, max_string_size);
|
|
- if (retcode == e_VMerror) {
|
|
- scan_type = scanning_string;
|
|
- goto suspend;
|
|
- } else if (retcode < 0)
|
|
- sreturn(retcode);
|
|
- }
|
|
- continue;
|
|
- }
|
|
- break;
|
|
- }
|
|
- scan_begin_inline();
|
|
- switch (status) {
|
|
- default:
|
|
- /*case ERRC: */
|
|
- sreturn(e_syntaxerror);
|
|
- case INTC:
|
|
- case CALLC:
|
|
- scan_type = scanning_string;
|
|
- goto pause;
|
|
- case EOFC:
|
|
- ;
|
|
- }
|
|
- retcode = dynamic_make_string(i_ctx_p, myref, &da, da.next);
|
|
- if (retcode < 0) { /* VMerror */
|
|
- sputback(s); /* rescan ) */
|
|
- scan_type = scanning_string;
|
|
- goto suspend;
|
|
- }
|
|
- break;
|
|
- case '(':
|
|
- sstate.s_ss.pssd.from_string =
|
|
- ((pstate->s_options & SCAN_FROM_STRING) != 0) &&
|
|
- !scan_enable_level2;
|
|
- s_PSSD_partially_init_inline(&sstate.s_ss.pssd);
|
|
- sstate.s_ss.st.template = &s_PSSD_template;
|
|
- goto str;
|
|
- case '{':
|
|
- if (pstack == 0) { /* outermost procedure */
|
|
- if_not_spush1() {
|
|
- scan_putback();
|
|
- scan_type = scanning_none;
|
|
- goto pause_ret;
|
|
- }
|
|
- pdepth = ref_stack_count_inline(&o_stack);
|
|
- }
|
|
- make_int(osp, pstack);
|
|
- pstack = ref_stack_count_inline(&o_stack);
|
|
- if_debug3('S', "[S{]d=%d, s=%d->%d\n",
|
|
- pdepth, (int)osp->value.intval, pstack);
|
|
- goto snext;
|
|
- case '>':
|
|
- if (scan_enable_level2) {
|
|
- ensure2(scanning_none);
|
|
- name_type = 0;
|
|
- try_number = false;
|
|
- goto try_funny_name;
|
|
- }
|
|
- /* falls through */
|
|
- case ')':
|
|
- sreturn(e_syntaxerror);
|
|
- case '}':
|
|
- if (pstack == 0)
|
|
- sreturn(e_syntaxerror);
|
|
- osp--;
|
|
- {
|
|
- uint size = ref_stack_count_inline(&o_stack) - pstack;
|
|
- ref arr;
|
|
-
|
|
- if_debug4('S', "[S}]d=%d, s=%d->%d, c=%d\n",
|
|
- pdepth, pstack,
|
|
- (pstack == pdepth ? 0 :
|
|
- ref_stack_index(&o_stack, size)->value.intval),
|
|
- size + pstack);
|
|
- myref = (pstack == pdepth ? pref : &arr);
|
|
- if (check_only) {
|
|
- make_empty_array(myref, 0);
|
|
- ref_stack_pop(&o_stack, size);
|
|
- } else if (ref_array_packing.value.boolval) {
|
|
- retcode = make_packed_array(myref, &o_stack, size,
|
|
- idmemory, "scanner(packed)");
|
|
- if (retcode < 0) { /* must be VMerror */
|
|
- osp++;
|
|
- scan_putback();
|
|
- scan_type = scanning_none;
|
|
- goto pause_ret;
|
|
- }
|
|
- r_set_attrs(myref, a_executable);
|
|
- } else {
|
|
- retcode = ialloc_ref_array(myref,
|
|
- a_executable + a_all, size,
|
|
- "scanner(proc)");
|
|
- if (retcode < 0) { /* must be VMerror */
|
|
- osp++;
|
|
- scan_putback();
|
|
- scan_type = scanning_none;
|
|
- goto pause_ret;
|
|
- }
|
|
- retcode = ref_stack_store(&o_stack, myref, size, 0, 1,
|
|
- false, idmemory, "scanner");
|
|
- if (retcode < 0) {
|
|
- ifree_ref_array(myref, "scanner(proc)");
|
|
- sreturn(retcode);
|
|
- }
|
|
- ref_stack_pop(&o_stack, size);
|
|
- }
|
|
- if (pstack == pdepth) { /* This was the top-level procedure. */
|
|
- spop1();
|
|
- pstack = 0;
|
|
- } else {
|
|
- if (osp < osbot)
|
|
- ref_stack_pop_block(&o_stack);
|
|
- pstack = osp->value.intval;
|
|
- *osp = arr;
|
|
- goto snext;
|
|
- }
|
|
- }
|
|
- break;
|
|
- case '/':
|
|
- /*
|
|
- * If the last thing in the input is a '/', don't try to read
|
|
- * any more data.
|
|
- */
|
|
- if (sptr >= endptr && s->end_status != EOFC) {
|
|
- refill2(scanning_none);
|
|
- }
|
|
- c = scan_getc();
|
|
- if (!PDFScanRules && (c == '/')) {
|
|
- name_type = 2;
|
|
- c = scan_getc();
|
|
- } else
|
|
- name_type = 1;
|
|
- try_number = false;
|
|
- switch (decoder[c]) {
|
|
- case ctype_name:
|
|
- default:
|
|
- goto do_name;
|
|
- case ctype_btoken:
|
|
- if (!recognize_btokens())
|
|
- goto do_name;
|
|
- /* otherwise, an empty name */
|
|
- case ctype_exception:
|
|
- case ctype_space:
|
|
- /*
|
|
- * Amazingly enough, the Adobe implementations don't accept
|
|
- * / or // followed by [, ], <<, or >>, so we do the same.
|
|
- * (Older versions of our code had a ctype_other case here
|
|
- * that handled these specially.)
|
|
- */
|
|
- case ctype_other:
|
|
- if (c == ctrld) /* see above */
|
|
- goto do_name;
|
|
- da.base = da.limit = daptr = 0;
|
|
- da.is_dynamic = false;
|
|
- goto nx;
|
|
- }
|
|
- case '%':
|
|
- { /* Scan as much as possible within the buffer. */
|
|
- const byte *base = sptr;
|
|
- const byte *end;
|
|
-
|
|
- while (++sptr < endptr) /* stop 1 char early */
|
|
- switch (*sptr) {
|
|
- case char_CR:
|
|
- end = sptr;
|
|
- if (sptr[1] == char_EOL)
|
|
- sptr++;
|
|
- cend: /* Check for externally processed comments. */
|
|
- retcode = scan_comment(i_ctx_p, myref, &sstate,
|
|
- base, end, false);
|
|
- if (retcode != 0)
|
|
- goto comment;
|
|
- goto top;
|
|
- case char_EOL:
|
|
- case '\f':
|
|
- end = sptr;
|
|
- goto cend;
|
|
- }
|
|
- /*
|
|
- * We got to the end of the buffer while inside a comment.
|
|
- * If there is a possibility that we must pass the comment
|
|
- * to an external procedure, move what we have collected
|
|
- * so far into a private buffer now.
|
|
- */
|
|
+ case ' ':
|
|
+ case '\f':
|
|
+ case '\t':
|
|
+ case char_CR:
|
|
+ case char_EOL:
|
|
+ case char_NULL:
|
|
+ goto top;
|
|
+ case 0x04: /* see ctrld above */
|
|
+ if (c == ctrld) /* treat as ordinary name char */
|
|
+ goto begin_name;
|
|
+ case '[':
|
|
+ case ']':
|
|
+ s1[0] = (byte) c;
|
|
+ retcode = name_ref(imemory, s1, 1, myref, 1); /* can't fail */
|
|
+ r_set_attrs(myref, a_executable);
|
|
+ break;
|
|
+ case '<':
|
|
+ if (scan_enable_level2) {
|
|
+ ensure2(scanning_none);
|
|
+ c = scan_getc();
|
|
+ switch (c) {
|
|
+ case '<':
|
|
+ scan_putback();
|
|
+ name_type = 0;
|
|
+ try_number = false;
|
|
+ goto try_funny_name;
|
|
+ case '~':
|
|
+ s_A85D_init_inline(&sstate.s_ss.a85d);
|
|
+ sstate.s_ss.st.template = &s_A85D_template;
|
|
+ goto str;
|
|
+ }
|
|
+ scan_putback();
|
|
+ }
|
|
+ s_AXD_init_inline(&sstate.s_ss.axd);
|
|
+ sstate.s_ss.st.template = &s_AXD_template;
|
|
+ str:scan_end_inline();
|
|
+ dynamic_init(&da, imemory);
|
|
+ cont_string:for (;;) {
|
|
+ stream_cursor_write w;
|
|
+
|
|
+ w.ptr = da.next - 1;
|
|
+ w.limit = da.limit - 1;
|
|
+ status = (*sstate.s_ss.st.template->process)
|
|
+ (&sstate.s_ss.st, &s->cursor.r, &w,
|
|
+ s->end_status == EOFC);
|
|
+ if (!check_only)
|
|
+ da.next = w.ptr + 1;
|
|
+ switch (status) {
|
|
+ case 0:
|
|
+ status = s->end_status;
|
|
+ if (status < 0) {
|
|
+ if (status == EOFC) {
|
|
+ if (check_only) {
|
|
+ retcode = scan_Refill;
|
|
+ scan_type = scanning_string;
|
|
+ goto suspend;
|
|
+ } else
|
|
+ sreturn(e_syntaxerror);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ s_process_read_buf(s);
|
|
+ continue;
|
|
+ case 1:
|
|
+ if (!check_only) {
|
|
+ retcode = dynamic_grow(&da, da.next, max_string_size);
|
|
+ if (retcode == e_VMerror) {
|
|
+ scan_type = scanning_string;
|
|
+ goto suspend;
|
|
+ } else if (retcode < 0)
|
|
+ sreturn(retcode);
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ scan_begin_inline();
|
|
+ switch (status) {
|
|
+ default:
|
|
+ /*case ERRC: */
|
|
+ sreturn(e_syntaxerror);
|
|
+ case INTC:
|
|
+ case CALLC:
|
|
+ scan_type = scanning_string;
|
|
+ goto pause;
|
|
+ case EOFC:
|
|
+ ;
|
|
+ }
|
|
+ retcode = dynamic_make_string(i_ctx_p, myref, &da, da.next);
|
|
+ if (retcode < 0) { /* VMerror */
|
|
+ sputback(s); /* rescan ) */
|
|
+ scan_type = scanning_string;
|
|
+ goto suspend;
|
|
+ }
|
|
+ break;
|
|
+ case '(':
|
|
+ sstate.s_ss.pssd.from_string =
|
|
+ ((pstate->s_options & SCAN_FROM_STRING) != 0) &&
|
|
+ !scan_enable_level2;
|
|
+ s_PSSD_partially_init_inline(&sstate.s_ss.pssd);
|
|
+ sstate.s_ss.st.template = &s_PSSD_template;
|
|
+ goto str;
|
|
+ case '{':
|
|
+ if (pstack == 0) { /* outermost procedure */
|
|
+ if_not_spush1() {
|
|
+ scan_putback();
|
|
+ scan_type = scanning_none;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ pdepth = ref_stack_count_inline(&o_stack);
|
|
+ }
|
|
+ make_int(osp, pstack);
|
|
+ pstack = ref_stack_count_inline(&o_stack);
|
|
+ if_debug3('S', "[S{]d=%d, s=%d->%d\n",
|
|
+ pdepth, (int)osp->value.intval, pstack);
|
|
+ goto snext;
|
|
+ case '>':
|
|
+ if (scan_enable_level2) {
|
|
+ ensure2(scanning_none);
|
|
+ name_type = 0;
|
|
+ try_number = false;
|
|
+ goto try_funny_name;
|
|
+ }
|
|
+ /* falls through */
|
|
+ case ')':
|
|
+ sreturn(e_syntaxerror);
|
|
+ case '}':
|
|
+ if (pstack == 0)
|
|
+ sreturn(e_syntaxerror);
|
|
+ osp--;
|
|
+ {
|
|
+ uint size = ref_stack_count_inline(&o_stack) - pstack;
|
|
+ ref arr;
|
|
+
|
|
+ if_debug4('S', "[S}]d=%d, s=%d->%d, c=%d\n",
|
|
+ pdepth, pstack,
|
|
+ (pstack == pdepth ? 0 :
|
|
+ ref_stack_index(&o_stack, size)->value.intval),
|
|
+ size + pstack);
|
|
+ myref = (pstack == pdepth ? pref : &arr);
|
|
+ if (check_only) {
|
|
+ make_empty_array(myref, 0);
|
|
+ ref_stack_pop(&o_stack, size);
|
|
+ } else if (ref_array_packing.value.boolval) {
|
|
+ retcode = make_packed_array(myref, &o_stack, size,
|
|
+ idmemory, "scanner(packed)");
|
|
+ if (retcode < 0) { /* must be VMerror */
|
|
+ osp++;
|
|
+ scan_putback();
|
|
+ scan_type = scanning_none;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ r_set_attrs(myref, a_executable);
|
|
+ } else {
|
|
+ retcode = ialloc_ref_array(myref,
|
|
+ a_executable + a_all, size,
|
|
+ "scanner(proc)");
|
|
+ if (retcode < 0) { /* must be VMerror */
|
|
+ osp++;
|
|
+ scan_putback();
|
|
+ scan_type = scanning_none;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ retcode = ref_stack_store(&o_stack, myref, size, 0, 1,
|
|
+ false, idmemory, "scanner");
|
|
+ if (retcode < 0) {
|
|
+ ifree_ref_array(myref, "scanner(proc)");
|
|
+ sreturn(retcode);
|
|
+ }
|
|
+ ref_stack_pop(&o_stack, size);
|
|
+ }
|
|
+ if (pstack == pdepth) { /* This was the top-level procedure. */
|
|
+ spop1();
|
|
+ pstack = 0;
|
|
+ } else {
|
|
+ if (osp < osbot)
|
|
+ ref_stack_pop_block(&o_stack);
|
|
+ pstack = osp->value.intval;
|
|
+ *osp = arr;
|
|
+ goto snext;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ case '/':
|
|
+ /*
|
|
+ * If the last thing in the input is a '/', don't try to read
|
|
+ * any more data.
|
|
+ */
|
|
+ if (sptr >= endptr && s->end_status != EOFC) {
|
|
+ refill2(scanning_none);
|
|
+ }
|
|
+ c = scan_getc();
|
|
+ if (!PDFScanRules && (c == '/')) {
|
|
+ name_type = 2;
|
|
+ c = scan_getc();
|
|
+ } else
|
|
+ name_type = 1;
|
|
+ try_number = false;
|
|
+ switch (decoder[c]) {
|
|
+ case ctype_name:
|
|
+ default:
|
|
+ goto do_name;
|
|
+ case ctype_btoken:
|
|
+ if (!recognize_btokens())
|
|
+ goto do_name;
|
|
+ /* otherwise, an empty name */
|
|
+ case ctype_exception:
|
|
+ case ctype_space:
|
|
+ /*
|
|
+ * Amazingly enough, the Adobe implementations don't accept
|
|
+ * / or // followed by [, ], <<, or >>, so we do the same.
|
|
+ * (Older versions of our code had a ctype_other case here
|
|
+ * that handled these specially.)
|
|
+ */
|
|
+ case ctype_other:
|
|
+ if (c == ctrld) /* see above */
|
|
+ goto do_name;
|
|
+ da.base = da.limit = daptr = 0;
|
|
+ da.is_dynamic = false;
|
|
+ goto nx;
|
|
+ }
|
|
+ case '%':
|
|
+ { /* Scan as much as possible within the buffer. */
|
|
+ const byte *base = sptr;
|
|
+ const byte *end;
|
|
+
|
|
+ while (++sptr < endptr) /* stop 1 char early */
|
|
+ switch (*sptr) {
|
|
+ case char_CR:
|
|
+ end = sptr;
|
|
+ if (sptr[1] == char_EOL)
|
|
+ sptr++;
|
|
+ cend: /* Check for externally processed comments. */
|
|
+ retcode = scan_comment(i_ctx_p, myref, &sstate,
|
|
+ base, end, false);
|
|
+ if (retcode != 0)
|
|
+ goto comment;
|
|
+ goto top;
|
|
+ case char_EOL:
|
|
+ case '\f':
|
|
+ end = sptr;
|
|
+ goto cend;
|
|
+ }
|
|
+ /*
|
|
+ * We got to the end of the buffer while inside a comment.
|
|
+ * If there is a possibility that we must pass the comment
|
|
+ * to an external procedure, move what we have collected
|
|
+ * so far into a private buffer now.
|
|
+ */
|
|
#define comment_line da.buf
|
|
- --sptr;
|
|
- comment_line[1] = 0;
|
|
- {
|
|
- /* Could be an externally processable comment. */
|
|
- uint len = sptr + 1 - base;
|
|
- if (len > sizeof(comment_line))
|
|
- len = sizeof(comment_line);
|
|
-
|
|
- memcpy(comment_line, base, len);
|
|
- daptr = comment_line + len;
|
|
- }
|
|
- da.base = comment_line;
|
|
- da.is_dynamic = false;
|
|
- }
|
|
- /* Enter here to continue scanning a comment. */
|
|
- /* daptr must be set. */
|
|
- cont_comment:for (;;) {
|
|
- switch ((c = scan_getc())) {
|
|
- default:
|
|
- if (c < 0)
|
|
- switch (c) {
|
|
- case INTC:
|
|
- case CALLC:
|
|
- da.next = daptr;
|
|
- scan_type = scanning_comment;
|
|
- goto pause;
|
|
- case EOFC:
|
|
- /*
|
|
- * One would think that an EOF in a comment
|
|
- * should be a syntax error, but there are
|
|
- * quite a number of files that end that way.
|
|
- */
|
|
- goto end_comment;
|
|
- default:
|
|
- sreturn(e_syntaxerror);
|
|
- }
|
|
- if (daptr < comment_line + max_comment_line)
|
|
- *daptr++ = c;
|
|
- continue;
|
|
- case char_CR:
|
|
- case char_EOL:
|
|
- case '\f':
|
|
- end_comment:
|
|
- retcode = scan_comment(i_ctx_p, myref, &sstate,
|
|
- comment_line, daptr, true);
|
|
- if (retcode != 0)
|
|
- goto comment;
|
|
- goto top;
|
|
- }
|
|
- }
|
|
+ --sptr;
|
|
+ comment_line[1] = 0;
|
|
+ {
|
|
+ /* Could be an externally processable comment. */
|
|
+ uint len = sptr + 1 - base;
|
|
+ if (len > sizeof(comment_line))
|
|
+ len = sizeof(comment_line);
|
|
+
|
|
+ memcpy(comment_line, base, len);
|
|
+ daptr = comment_line + len;
|
|
+ }
|
|
+ da.base = comment_line;
|
|
+ da.is_dynamic = false;
|
|
+ }
|
|
+ /* Enter here to continue scanning a comment. */
|
|
+ /* daptr must be set. */
|
|
+ cont_comment:for (;;) {
|
|
+ switch ((c = scan_getc())) {
|
|
+ default:
|
|
+ if (c < 0)
|
|
+ switch (c) {
|
|
+ case INTC:
|
|
+ case CALLC:
|
|
+ da.next = daptr;
|
|
+ scan_type = scanning_comment;
|
|
+ goto pause;
|
|
+ case EOFC:
|
|
+ /*
|
|
+ * One would think that an EOF in a comment
|
|
+ * should be a syntax error, but there are
|
|
+ * quite a number of files that end that way.
|
|
+ */
|
|
+ goto end_comment;
|
|
+ default:
|
|
+ sreturn(e_syntaxerror);
|
|
+ }
|
|
+ if (daptr < comment_line + max_comment_line)
|
|
+ *daptr++ = c;
|
|
+ continue;
|
|
+ case char_CR:
|
|
+ case char_EOL:
|
|
+ case '\f':
|
|
+ end_comment:
|
|
+ retcode = scan_comment(i_ctx_p, myref, &sstate,
|
|
+ comment_line, daptr, true);
|
|
+ if (retcode != 0)
|
|
+ goto comment;
|
|
+ goto top;
|
|
+ }
|
|
+ }
|
|
#undef comment_line
|
|
- /*NOTREACHED */
|
|
- case EOFC:
|
|
- if (pstack != 0) {
|
|
- if (check_only)
|
|
- goto pause;
|
|
- sreturn(e_syntaxerror);
|
|
- }
|
|
- retcode = scan_EOF;
|
|
- break;
|
|
- case ERRC:
|
|
- sreturn(e_ioerror);
|
|
-
|
|
- /* Check for a Level 2 funny name (<< or >>). */
|
|
- /* c is '<' or '>'. We already did an ensure2. */
|
|
- try_funny_name:
|
|
- {
|
|
- int c1 = scan_getc();
|
|
-
|
|
- if (c1 == c) {
|
|
- s1[0] = s1[1] = c;
|
|
- name_ref(imemory, s1, 2, myref, 1); /* can't fail */
|
|
- goto have_name;
|
|
- }
|
|
- scan_putback();
|
|
- }
|
|
- sreturn(e_syntaxerror);
|
|
-
|
|
- /* Handle separately the names that might be a number. */
|
|
- case '0':
|
|
- case '1':
|
|
- case '2':
|
|
- case '3':
|
|
- case '4':
|
|
- case '5':
|
|
- case '6':
|
|
- case '7':
|
|
- case '8':
|
|
- case '9':
|
|
- case '.':
|
|
- sign = 0;
|
|
- nr: /*
|
|
- * Skip a leading sign, if any, by conditionally passing
|
|
- * sptr + 1 rather than sptr. Also, if the last character
|
|
- * in the buffer is a CR, we must stop the scan 1 character
|
|
- * early, to be sure that we can test for CR+LF within the
|
|
- * buffer, by passing endptr rather than endptr + 1.
|
|
- */
|
|
- retcode = scan_number(sptr + (sign & 1),
|
|
- endptr /*(*endptr == char_CR ? endptr : endptr + 1) */ ,
|
|
- sign, myref, &newptr, i_ctx_p->scanner_options);
|
|
- if (retcode == 1 && decoder[newptr[-1]] == ctype_space) {
|
|
- sptr = newptr - 1;
|
|
- if (*sptr == char_CR && sptr[1] == char_EOL)
|
|
- sptr++;
|
|
- retcode = 0;
|
|
- ref_mark_new(myref);
|
|
- break;
|
|
- }
|
|
- name_type = 0;
|
|
- try_number = true;
|
|
- goto do_name;
|
|
- case '+':
|
|
- sign = 1;
|
|
- goto nr;
|
|
- case '-':
|
|
- sign = -1;
|
|
- goto nr;
|
|
+ /*NOTREACHED */
|
|
+ case EOFC:
|
|
+ if (pstack != 0) {
|
|
+ if (check_only)
|
|
+ goto pause;
|
|
+ sreturn(e_syntaxerror);
|
|
+ }
|
|
+ retcode = scan_EOF;
|
|
+ break;
|
|
+ case ERRC:
|
|
+ sreturn(e_ioerror);
|
|
+
|
|
+ /* Check for a Level 2 funny name (<< or >>). */
|
|
+ /* c is '<' or '>'. We already did an ensure2. */
|
|
+ try_funny_name:
|
|
+ {
|
|
+ int c1 = scan_getc();
|
|
+
|
|
+ if (c1 == c) {
|
|
+ s1[0] = s1[1] = c;
|
|
+ name_ref(imemory, s1, 2, myref, 1); /* can't fail */
|
|
+ goto have_name;
|
|
+ }
|
|
+ scan_putback();
|
|
+ }
|
|
+ sreturn(e_syntaxerror);
|
|
+
|
|
+ /* Handle separately the names that might be a number. */
|
|
+ case '0':
|
|
+ case '1':
|
|
+ case '2':
|
|
+ case '3':
|
|
+ case '4':
|
|
+ case '5':
|
|
+ case '6':
|
|
+ case '7':
|
|
+ case '8':
|
|
+ case '9':
|
|
+ case '.':
|
|
+ sign = 0;
|
|
+ nr: /*
|
|
+ * Skip a leading sign, if any, by conditionally passing
|
|
+ * sptr + 1 rather than sptr. Also, if the last character
|
|
+ * in the buffer is a CR, we must stop the scan 1 character
|
|
+ * early, to be sure that we can test for CR+LF within the
|
|
+ * buffer, by passing endptr rather than endptr + 1.
|
|
+ */
|
|
+ retcode = scan_number(sptr + (sign & 1),
|
|
+ endptr /*(*endptr == char_CR ? endptr : endptr + 1) */ ,
|
|
+ sign, myref, &newptr, i_ctx_p->scanner_options);
|
|
+ if (retcode == 1 && decoder[newptr[-1]] == ctype_space) {
|
|
+ sptr = newptr - 1;
|
|
+ if (*sptr == char_CR && sptr[1] == char_EOL)
|
|
+ sptr++;
|
|
+ retcode = 0;
|
|
+ ref_mark_new(myref);
|
|
+ break;
|
|
+ }
|
|
+ name_type = 0;
|
|
+ try_number = true;
|
|
+ goto do_name;
|
|
+ case '+':
|
|
+ sign = 1;
|
|
+ goto nr;
|
|
+ case '-':
|
|
+ sign = -1;
|
|
+ goto nr;
|
|
|
|
- /* Check for a binary object */
|
|
+ /* Check for a binary object */
|
|
#define case4(c) case c: case c+1: case c+2: case c+3
|
|
- case4(128): case4(132): case4(136): case4(140):
|
|
- case4(144): case4(148): case4(152): case4(156):
|
|
+ case4(128): case4(132): case4(136): case4(140):
|
|
+ case4(144): case4(148): case4(152): case4(156):
|
|
#undef case4
|
|
- if (recognize_btokens()) {
|
|
- scan_end_inline();
|
|
- retcode = scan_binary_token(i_ctx_p, myref, &sstate);
|
|
- scan_begin_inline();
|
|
- if (retcode == scan_Refill)
|
|
- goto pause;
|
|
- break;
|
|
- }
|
|
- /* Not a binary object, fall through. */
|
|
-
|
|
- /* The default is a name. */
|
|
- default:
|
|
- if (c < 0) {
|
|
- dynamic_init(&da, name_memory(imemory)); /* da state must be clean */
|
|
- scan_type = scanning_none;
|
|
- goto pause;
|
|
- }
|
|
- /* Populate the switch with enough cases to force */
|
|
- /* simple compilers to use a dispatch rather than tests. */
|
|
- case '!':
|
|
- case '"':
|
|
- case '#':
|
|
- case '$':
|
|
- case '&':
|
|
- case '\'':
|
|
- case '*':
|
|
- case ',':
|
|
- case '=':
|
|
- case ':':
|
|
- case ';':
|
|
- case '?':
|
|
- case '@':
|
|
- case 'A':
|
|
- case 'B':
|
|
- case 'C':
|
|
- case 'D':
|
|
- case 'E':
|
|
- case 'F':
|
|
- case 'G':
|
|
- case 'H':
|
|
- case 'I':
|
|
- case 'J':
|
|
- case 'K':
|
|
- case 'L':
|
|
- case 'M':
|
|
- case 'N':
|
|
- case 'O':
|
|
- case 'P':
|
|
- case 'Q':
|
|
- case 'R':
|
|
- case 'S':
|
|
- case 'T':
|
|
- case 'U':
|
|
- case 'V':
|
|
- case 'W':
|
|
- case 'X':
|
|
- case 'Y':
|
|
- case 'Z':
|
|
- case '\\':
|
|
- case '^':
|
|
- case '_':
|
|
- case '`':
|
|
- case 'a':
|
|
- case 'b':
|
|
- case 'c':
|
|
- case 'd':
|
|
- case 'e':
|
|
- case 'f':
|
|
- case 'g':
|
|
- case 'h':
|
|
- case 'i':
|
|
- case 'j':
|
|
- case 'k':
|
|
- case 'l':
|
|
- case 'm':
|
|
- case 'n':
|
|
- case 'o':
|
|
- case 'p':
|
|
- case 'q':
|
|
- case 'r':
|
|
- case 's':
|
|
- case 't':
|
|
- case 'u':
|
|
- case 'v':
|
|
- case 'w':
|
|
- case 'x':
|
|
- case 'y':
|
|
- case 'z':
|
|
- case '|':
|
|
- case '~':
|
|
- begin_name:
|
|
- /* Common code for scanning a name. */
|
|
- /* try_number and name_type are already set. */
|
|
- /* We know c has ctype_name (or maybe ctype_btoken, */
|
|
- /* or is ^D) or is a digit. */
|
|
- name_type = 0;
|
|
- try_number = false;
|
|
- do_name:
|
|
- /* Try to scan entirely within the stream buffer. */
|
|
- /* We stop 1 character early, so we don't switch buffers */
|
|
- /* looking ahead if the name is terminated by \r\n. */
|
|
- da.base = (byte *) sptr;
|
|
- da.is_dynamic = false;
|
|
- {
|
|
- const byte *endp1 = endptr - 1;
|
|
-
|
|
- do {
|
|
- if (sptr >= endp1) /* stop 1 early! */
|
|
- goto dyn_name;
|
|
- }
|
|
- while (decoder[*++sptr] <= max_name_ctype || *sptr == ctrld); /* digit or name */
|
|
- }
|
|
- /* Name ended within the buffer. */
|
|
- daptr = (byte *) sptr;
|
|
- c = *sptr;
|
|
- goto nx;
|
|
- dyn_name: /* Name extended past end of buffer. */
|
|
- scan_end_inline();
|
|
- /* Initialize the dynamic area. */
|
|
- /* We have to do this before the next */
|
|
- /* sgetc, which will overwrite the buffer. */
|
|
- da.limit = (byte *)++ sptr;
|
|
- da.memory = name_memory(imemory);
|
|
- retcode = dynamic_grow(&da, da.limit, name_max_string);
|
|
- if (retcode < 0) {
|
|
- dynamic_save(&da);
|
|
- if (retcode != e_VMerror)
|
|
- sreturn(retcode);
|
|
- scan_type = scanning_name;
|
|
- goto pause_ret;
|
|
- }
|
|
- daptr = da.next;
|
|
- /* Enter here to continue scanning a name. */
|
|
- /* daptr must be set. */
|
|
- cont_name:scan_begin_inline();
|
|
- while (decoder[c = scan_getc()] <= max_name_ctype || c == ctrld) {
|
|
- if (daptr == da.limit) {
|
|
- retcode = dynamic_grow(&da, daptr,
|
|
- name_max_string);
|
|
- if (retcode < 0) {
|
|
- dynamic_save(&da);
|
|
- if (retcode != e_VMerror)
|
|
- sreturn(retcode);
|
|
- scan_putback();
|
|
- scan_type = scanning_name;
|
|
- goto pause_ret;
|
|
- }
|
|
- daptr = da.next;
|
|
- }
|
|
- *daptr++ = c;
|
|
- }
|
|
- nx:switch (decoder[c]) {
|
|
- case ctype_other:
|
|
- if (c == ctrld) /* see above */
|
|
- break;
|
|
- case ctype_btoken:
|
|
- scan_putback();
|
|
- break;
|
|
- case ctype_space:
|
|
- /* Check for \r\n */
|
|
- if (c == char_CR) {
|
|
- if (sptr >= endptr) { /* ensure2 *//* We have to check specially for */
|
|
- /* the case where the very last */
|
|
- /* character of a file is a CR. */
|
|
- if (s->end_status != EOFC) {
|
|
- sptr--;
|
|
- goto pause_name;
|
|
- }
|
|
- } else if (sptr[1] == char_EOL)
|
|
- sptr++;
|
|
- }
|
|
- break;
|
|
- case ctype_exception:
|
|
- switch (c) {
|
|
- case INTC:
|
|
- case CALLC:
|
|
- goto pause_name;
|
|
- case ERRC:
|
|
- sreturn(e_ioerror);
|
|
- case EOFC:
|
|
- break;
|
|
- }
|
|
- }
|
|
- /* Check for a number */
|
|
- if (try_number) {
|
|
- const byte *base = da.base;
|
|
-
|
|
- scan_sign(sign, base);
|
|
- retcode = scan_number(base, daptr, sign, myref, &newptr, i_ctx_p->scanner_options);
|
|
- if (retcode == 1) {
|
|
- ref_mark_new(myref);
|
|
- retcode = 0;
|
|
- } else if (retcode != e_syntaxerror) {
|
|
- dynamic_free(&da);
|
|
- if (name_type == 2)
|
|
- sreturn(e_syntaxerror);
|
|
- break; /* might be e_limitcheck */
|
|
- }
|
|
- }
|
|
- if (da.is_dynamic) { /* We've already allocated the string on the heap. */
|
|
- uint size = daptr - da.base;
|
|
-
|
|
- retcode = name_ref(imemory, da.base, size, myref, -1);
|
|
- if (retcode >= 0) {
|
|
- dynamic_free(&da);
|
|
- } else {
|
|
- retcode = dynamic_resize(&da, size);
|
|
- if (retcode < 0) { /* VMerror */
|
|
- if (c != EOFC)
|
|
- scan_putback();
|
|
- scan_type = scanning_name;
|
|
- goto pause_ret;
|
|
- }
|
|
- retcode = name_ref(imemory, da.base, size, myref, 2);
|
|
- }
|
|
- } else {
|
|
- retcode = name_ref(imemory, da.base, (uint) (daptr - da.base),
|
|
- myref, !s->foreign);
|
|
- }
|
|
- /* Done scanning. Check for preceding /'s. */
|
|
- if (retcode < 0) {
|
|
- if (retcode != e_VMerror)
|
|
- sreturn(retcode);
|
|
- if (!da.is_dynamic) {
|
|
- da.next = daptr;
|
|
- dynamic_save(&da);
|
|
- }
|
|
- if (c != EOFC)
|
|
- scan_putback();
|
|
- scan_type = scanning_name;
|
|
- goto pause_ret;
|
|
- }
|
|
- have_name:switch (name_type) {
|
|
- case 0: /* ordinary executable name */
|
|
- if (r_has_type(myref, t_name)) /* i.e., not a number */
|
|
- r_set_attrs(myref, a_executable);
|
|
- case 1: /* quoted name */
|
|
- break;
|
|
- case 2: /* immediate lookup */
|
|
- {
|
|
- ref *pvalue;
|
|
-
|
|
- if (!r_has_type(myref, t_name) ||
|
|
- (pvalue = dict_find_name(myref)) == 0) {
|
|
- ref_assign(&sstate.s_error.object, myref);
|
|
- r_set_attrs(&sstate.s_error.object,
|
|
- a_executable); /* Adobe compatibility */
|
|
- sreturn(e_undefined);
|
|
- }
|
|
- if (pstack != 0 &&
|
|
- r_space(pvalue) > ialloc_space(idmemory)
|
|
- )
|
|
- sreturn(e_invalidaccess);
|
|
- ref_assign_new(myref, pvalue);
|
|
- }
|
|
- }
|
|
+ if (recognize_btokens()) {
|
|
+ scan_end_inline();
|
|
+ retcode = scan_binary_token(i_ctx_p, myref, &sstate);
|
|
+ scan_begin_inline();
|
|
+ if (retcode == scan_Refill)
|
|
+ goto pause;
|
|
+ break;
|
|
+ }
|
|
+ /* Not a binary object, fall through. */
|
|
+
|
|
+ /* The default is a name. */
|
|
+ default:
|
|
+ if (c < 0) {
|
|
+ dynamic_init(&da, name_memory(imemory)); /* da state must be clean */
|
|
+ scan_type = scanning_none;
|
|
+ goto pause;
|
|
+ }
|
|
+ /* Populate the switch with enough cases to force */
|
|
+ /* simple compilers to use a dispatch rather than tests. */
|
|
+ case '!':
|
|
+ case '"':
|
|
+ case '#':
|
|
+ case '$':
|
|
+ case '&':
|
|
+ case '\'':
|
|
+ case '*':
|
|
+ case ',':
|
|
+ case '=':
|
|
+ case ':':
|
|
+ case ';':
|
|
+ case '?':
|
|
+ case '@':
|
|
+ case 'A':
|
|
+ case 'B':
|
|
+ case 'C':
|
|
+ case 'D':
|
|
+ case 'E':
|
|
+ case 'F':
|
|
+ case 'G':
|
|
+ case 'H':
|
|
+ case 'I':
|
|
+ case 'J':
|
|
+ case 'K':
|
|
+ case 'L':
|
|
+ case 'M':
|
|
+ case 'N':
|
|
+ case 'O':
|
|
+ case 'P':
|
|
+ case 'Q':
|
|
+ case 'R':
|
|
+ case 'S':
|
|
+ case 'T':
|
|
+ case 'U':
|
|
+ case 'V':
|
|
+ case 'W':
|
|
+ case 'X':
|
|
+ case 'Y':
|
|
+ case 'Z':
|
|
+ case '\\':
|
|
+ case '^':
|
|
+ case '_':
|
|
+ case '`':
|
|
+ case 'a':
|
|
+ case 'b':
|
|
+ case 'c':
|
|
+ case 'd':
|
|
+ case 'e':
|
|
+ case 'f':
|
|
+ case 'g':
|
|
+ case 'h':
|
|
+ case 'i':
|
|
+ case 'j':
|
|
+ case 'k':
|
|
+ case 'l':
|
|
+ case 'm':
|
|
+ case 'n':
|
|
+ case 'o':
|
|
+ case 'p':
|
|
+ case 'q':
|
|
+ case 'r':
|
|
+ case 's':
|
|
+ case 't':
|
|
+ case 'u':
|
|
+ case 'v':
|
|
+ case 'w':
|
|
+ case 'x':
|
|
+ case 'y':
|
|
+ case 'z':
|
|
+ case '|':
|
|
+ case '~':
|
|
+ begin_name:
|
|
+ /* Common code for scanning a name. */
|
|
+ /* try_number and name_type are already set. */
|
|
+ /* We know c has ctype_name (or maybe ctype_btoken, */
|
|
+ /* or is ^D) or is a digit. */
|
|
+ name_type = 0;
|
|
+ try_number = false;
|
|
+ do_name:
|
|
+ /* Try to scan entirely within the stream buffer. */
|
|
+ /* We stop 1 character early, so we don't switch buffers */
|
|
+ /* looking ahead if the name is terminated by \r\n. */
|
|
+ da.base = (byte *) sptr;
|
|
+ da.is_dynamic = false;
|
|
+ {
|
|
+ const byte *endp1 = endptr - 1;
|
|
+
|
|
+ do {
|
|
+ if (sptr >= endp1) /* stop 1 early! */
|
|
+ goto dyn_name;
|
|
+ }
|
|
+ while (decoder[*++sptr] <= max_name_ctype || *sptr == ctrld); /* digit or name */
|
|
+ }
|
|
+ /* Name ended within the buffer. */
|
|
+ daptr = (byte *) sptr;
|
|
+ c = *sptr;
|
|
+ goto nx;
|
|
+ dyn_name: /* Name extended past end of buffer. */
|
|
+ scan_end_inline();
|
|
+ /* Initialize the dynamic area. */
|
|
+ /* We have to do this before the next */
|
|
+ /* sgetc, which will overwrite the buffer. */
|
|
+ da.limit = (byte *)++ sptr;
|
|
+ da.memory = name_memory(imemory);
|
|
+ retcode = dynamic_grow(&da, da.limit, name_max_string);
|
|
+ if (retcode < 0) {
|
|
+ dynamic_save(&da);
|
|
+ if (retcode != e_VMerror)
|
|
+ sreturn(retcode);
|
|
+ scan_type = scanning_name;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ daptr = da.next;
|
|
+ /* Enter here to continue scanning a name. */
|
|
+ /* daptr must be set. */
|
|
+ cont_name:scan_begin_inline();
|
|
+ while (decoder[c = scan_getc()] <= max_name_ctype || c == ctrld) {
|
|
+ if (daptr == da.limit) {
|
|
+ retcode = dynamic_grow(&da, daptr,
|
|
+ name_max_string);
|
|
+ if (retcode < 0) {
|
|
+ dynamic_save(&da);
|
|
+ if (retcode != e_VMerror)
|
|
+ sreturn(retcode);
|
|
+ scan_putback();
|
|
+ scan_type = scanning_name;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ daptr = da.next;
|
|
+ }
|
|
+ *daptr++ = c;
|
|
+ }
|
|
+ nx:switch (decoder[c]) {
|
|
+ case ctype_other:
|
|
+ if (c == ctrld) /* see above */
|
|
+ break;
|
|
+ case ctype_btoken:
|
|
+ scan_putback();
|
|
+ break;
|
|
+ case ctype_space:
|
|
+ /* Check for \r\n */
|
|
+ if (c == char_CR) {
|
|
+ if (sptr >= endptr) { /* ensure2 *//* We have to check specially for */
|
|
+ /* the case where the very last */
|
|
+ /* character of a file is a CR. */
|
|
+ if (s->end_status != EOFC) {
|
|
+ sptr--;
|
|
+ goto pause_name;
|
|
+ }
|
|
+ } else if (sptr[1] == char_EOL)
|
|
+ sptr++;
|
|
+ }
|
|
+ break;
|
|
+ case ctype_exception:
|
|
+ switch (c) {
|
|
+ case INTC:
|
|
+ case CALLC:
|
|
+ goto pause_name;
|
|
+ case ERRC:
|
|
+ sreturn(e_ioerror);
|
|
+ case EOFC:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ /* Check for a number */
|
|
+ if (try_number) {
|
|
+ const byte *base = da.base;
|
|
+
|
|
+ scan_sign(sign, base);
|
|
+ retcode = scan_number(base, daptr, sign, myref, &newptr, i_ctx_p->scanner_options);
|
|
+ if (retcode == 1) {
|
|
+ ref_mark_new(myref);
|
|
+ retcode = 0;
|
|
+ } else if (retcode != e_syntaxerror) {
|
|
+ dynamic_free(&da);
|
|
+ if (name_type == 2)
|
|
+ sreturn(e_syntaxerror);
|
|
+ break; /* might be e_limitcheck */
|
|
+ }
|
|
+ }
|
|
+ if (da.is_dynamic) { /* We've already allocated the string on the heap. */
|
|
+ uint size = daptr - da.base;
|
|
+
|
|
+ retcode = name_ref(imemory, da.base, size, myref, -1);
|
|
+ if (retcode >= 0) {
|
|
+ dynamic_free(&da);
|
|
+ } else {
|
|
+ retcode = dynamic_resize(&da, size);
|
|
+ if (retcode < 0) { /* VMerror */
|
|
+ if (c != EOFC)
|
|
+ scan_putback();
|
|
+ scan_type = scanning_name;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ retcode = name_ref(imemory, da.base, size, myref, 2);
|
|
+ }
|
|
+ } else {
|
|
+ retcode = name_ref(imemory, da.base, (uint) (daptr - da.base),
|
|
+ myref, !s->foreign);
|
|
+ }
|
|
+ /* Done scanning. Check for preceding /'s. */
|
|
+ if (retcode < 0) {
|
|
+ if (retcode != e_VMerror)
|
|
+ sreturn(retcode);
|
|
+ if (!da.is_dynamic) {
|
|
+ da.next = daptr;
|
|
+ dynamic_save(&da);
|
|
+ }
|
|
+ if (c != EOFC)
|
|
+ scan_putback();
|
|
+ scan_type = scanning_name;
|
|
+ goto pause_ret;
|
|
+ }
|
|
+ have_name:switch (name_type) {
|
|
+ case 0: /* ordinary executable name */
|
|
+ if (r_has_type(myref, t_name)) /* i.e., not a number */
|
|
+ r_set_attrs(myref, a_executable);
|
|
+ case 1: /* quoted name */
|
|
+ break;
|
|
+ case 2: /* immediate lookup */
|
|
+ {
|
|
+ ref *pvalue;
|
|
+
|
|
+ if (!r_has_type(myref, t_name) ||
|
|
+ (pvalue = dict_find_name(myref)) == 0) {
|
|
+ ref_assign(&sstate.s_error.object, myref);
|
|
+ r_set_attrs(&sstate.s_error.object,
|
|
+ a_executable); /* Adobe compatibility */
|
|
+ sreturn(e_undefined);
|
|
+ }
|
|
+ if (pstack != 0 &&
|
|
+ r_space(pvalue) > ialloc_space(idmemory)
|
|
+ )
|
|
+ sreturn(e_invalidaccess);
|
|
+ ref_assign_new(myref, pvalue);
|
|
+ }
|
|
+ }
|
|
}
|
|
sret:if (retcode < 0) {
|
|
- scan_end_inline();
|
|
- pstate->s_error = sstate.s_error;
|
|
- if (pstack != 0) {
|
|
- if (retcode == e_undefined)
|
|
- *pref = *osp; /* return undefined name as error token */
|
|
- ref_stack_pop(&o_stack,
|
|
- ref_stack_count(&o_stack) - (pdepth - 1));
|
|
- }
|
|
- return retcode;
|
|
+ scan_end_inline();
|
|
+ pstate->s_error = sstate.s_error;
|
|
+ if (pstack != 0) {
|
|
+ if (retcode == e_undefined)
|
|
+ *pref = *osp; /* return undefined name as error token */
|
|
+ ref_stack_pop(&o_stack,
|
|
+ ref_stack_count(&o_stack) - (pdepth - 1));
|
|
+ }
|
|
+ return retcode;
|
|
}
|
|
/* If we are at the top level, return the object, */
|
|
/* otherwise keep going. */
|
|
if (pstack == 0) {
|
|
- scan_end_inline();
|
|
- return retcode;
|
|
+ scan_end_inline();
|
|
+ return retcode;
|
|
}
|
|
snext:if_not_spush1() {
|
|
- scan_end_inline();
|
|
- scan_type = scanning_none;
|
|
- goto save;
|
|
+ scan_end_inline();
|
|
+ scan_type = scanning_none;
|
|
+ goto save;
|
|
}
|
|
myref = osp;
|
|
goto top;
|
|
@@ -1233,7 +1233,7 @@ scan_token(i_ctx_t *i_ctx_p, ref * pref,
|
|
scan_end_inline();
|
|
suspend:
|
|
if (pstack != 0)
|
|
- osp--; /* myref */
|
|
+ osp--; /* myref */
|
|
save:
|
|
*pstate = sstate;
|
|
return retcode;
|
|
@@ -1241,7 +1241,7 @@ scan_token(i_ctx_t *i_ctx_p, ref * pref,
|
|
/* Handle a scanned comment. */
|
|
comment:
|
|
if (retcode < 0)
|
|
- goto sret;
|
|
+ goto sret;
|
|
scan_end_inline();
|
|
scan_type = scanning_none;
|
|
goto save;
|
|
diff -up ghostscript-9.00/psi/iscan.h.scan_token ghostscript-9.00/psi/iscan.h
|
|
--- ghostscript-9.00/psi/iscan.h.scan_token 2010-04-26 16:29:28.000000000 +0100
|
|
+++ ghostscript-9.00/psi/iscan.h 2011-01-14 17:16:12.617867701 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -23,7 +23,7 @@
|
|
#include "inamestr.h"
|
|
|
|
/*
|
|
- * Define the state of the scanner. Before calling scan_token initially,
|
|
+ * Define the state of the scanner. Before first calling gs_scan_token,
|
|
* the caller must initialize the state by calling scanner_state_init.
|
|
* Most of the state is only used if scanning is suspended because of
|
|
* an interrupt or a callout.
|
|
@@ -44,15 +44,16 @@ typedef struct scanner_state_s scanner_s
|
|
* Define a structure for dynamically growable strings.
|
|
* If is_dynamic is true, base/next/limit point to a string on the heap;
|
|
* if is_dynamic is false, base/next/limit point either to the local buffer
|
|
- * or (only while control is inside scan_token) into the source stream buffer.
|
|
+ * or (only while control is inside gs_scan_token) into the source stream
|
|
+ * buffer.
|
|
*/
|
|
-#define max_comment_line 255 /* max size of an externally processable comment */
|
|
+#define max_comment_line 255 /* max size of an externally processable comment */
|
|
typedef struct dynamic_area_s {
|
|
byte *base;
|
|
byte *next;
|
|
byte *limit;
|
|
bool is_dynamic;
|
|
- byte buf[max_name_string]; /* initial buffer, enough for a valid string */
|
|
+ byte buf[max_name_string]; /* initial buffer, enough for a valid string */
|
|
gs_memory_t *memory;
|
|
} dynamic_area;
|
|
|
|
@@ -65,48 +66,48 @@ typedef struct scan_binary_state_s {
|
|
int (*cont)(i_ctx_t *, ref *, scanner_state *);
|
|
ref bin_array;
|
|
uint index;
|
|
- uint max_array_index; /* largest legal index in objects */
|
|
- uint min_string_index; /* smallest legal index in strings */
|
|
+ uint max_array_index; /* largest legal index in objects */
|
|
+ uint min_string_index; /* smallest legal index in strings */
|
|
uint top_size;
|
|
uint size;
|
|
- int token_type; /* binary token type for error reporting */
|
|
- ulong lsize; /* b.o.s. size ibid. */
|
|
+ int token_type; /* binary token type for error reporting */
|
|
+ ulong lsize; /* b.o.s. size ibid. */
|
|
} scan_binary_state;
|
|
|
|
/* Define the scanner state. */
|
|
struct scanner_state_s {
|
|
- ref s_file; /* source file */
|
|
- uint s_pstack; /* stack depth when starting current */
|
|
- /* procedure, after pushing old pstack */
|
|
- uint s_pdepth; /* pstack for very first { encountered, */
|
|
- /* for error recovery */
|
|
+ ref s_file; /* source file */
|
|
+ uint s_pstack; /* stack depth when starting current */
|
|
+ /* procedure, after pushing old pstack */
|
|
+ uint s_pdepth; /* pstack for very first { encountered, */
|
|
+ /* for error recovery */
|
|
int s_options;
|
|
enum {
|
|
- scanning_none,
|
|
- scanning_binary,
|
|
- scanning_comment,
|
|
- scanning_name,
|
|
- scanning_string
|
|
+ scanning_none,
|
|
+ scanning_binary,
|
|
+ scanning_comment,
|
|
+ scanning_name,
|
|
+ scanning_string
|
|
} s_scan_type;
|
|
dynamic_area s_da;
|
|
- union sss_ { /* scanning sub-state */
|
|
- scan_binary_state binary; /* binary */
|
|
- struct sns_ { /* name */
|
|
- int s_name_type; /* number of /'s preceding a name */
|
|
- bool s_try_number; /* true if should try scanning name */
|
|
- /* as number */
|
|
- } s_name;
|
|
- stream_state st; /* string */
|
|
- stream_A85D_state a85d; /* string */
|
|
- stream_AXD_state axd; /* string */
|
|
- stream_PSSD_state pssd; /* string */
|
|
+ union sss_ { /* scanning sub-state */
|
|
+ scan_binary_state binary; /* binary */
|
|
+ struct sns_ { /* name */
|
|
+ int s_name_type; /* number of /'s preceding a name */
|
|
+ bool s_try_number; /* true if should try scanning name */
|
|
+ /* as number */
|
|
+ } s_name;
|
|
+ stream_state st; /* string */
|
|
+ stream_A85D_state a85d; /* string */
|
|
+ stream_AXD_state axd; /* string */
|
|
+ stream_PSSD_state pssd; /* string */
|
|
} s_ss;
|
|
/* The following are used only to return information for errors. */
|
|
- struct se_ { /* scanner error */
|
|
- ref object; /* normally t__invalid */
|
|
- bool is_name; /* true if 'string' is name, false if string */
|
|
+ struct se_ { /* scanner error */
|
|
+ ref object; /* normally t__invalid */
|
|
+ bool is_name; /* true if 'string' is name, false if string */
|
|
#define SCANNER_MAX_ERROR_STRING 120 /* adhoc, for Adobe-compatible messages */
|
|
- char string[SCANNER_MAX_ERROR_STRING+1]; /* normally empty */
|
|
+ char string[SCANNER_MAX_ERROR_STRING+1]; /* normally empty */
|
|
} s_error;
|
|
#define SCAN_INIT_ERROR(pstate)\
|
|
(make_t(&(pstate)->s_error.object, t__invalid),\
|
|
@@ -122,81 +123,81 @@ typedef struct scanner_state_dynamic_s {
|
|
|
|
/* The type descriptor is public only for checking. */
|
|
extern_st(st_scanner_state_dynamic);
|
|
-#define public_st_scanner_state_dynamic() /* in iscan.c */\
|
|
+#define public_st_scanner_state_dynamic() /* in iscan.c */\
|
|
gs_public_st_complex_only(st_scanner_state_dynamic, scanner_state_dynamic, "scanner state",\
|
|
scanner_clear_marks, scanner_enum_ptrs, scanner_reloc_ptrs, 0)
|
|
|
|
/* Initialize a scanner with a given set of options. */
|
|
-#define SCAN_FROM_STRING 1 /* true if string is source of data */
|
|
- /* (for Level 1 `\' handling) */
|
|
-#define SCAN_CHECK_ONLY 2 /* true if just checking for syntax errors */
|
|
- /* and complete statements (no value) */
|
|
-#define SCAN_PROCESS_COMMENTS 4 /* return scan_Comment for comments */
|
|
- /* (all comments or only non-DSC) */
|
|
+#define SCAN_FROM_STRING 1 /* true if string is source of data */
|
|
+ /* (for Level 1 `\' handling) */
|
|
+#define SCAN_CHECK_ONLY 2 /* true if just checking for syntax errors */
|
|
+ /* and complete statements (no value) */
|
|
+#define SCAN_PROCESS_COMMENTS 4 /* return scan_Comment for comments */
|
|
+ /* (all comments or only non-DSC) */
|
|
#define SCAN_PROCESS_DSC_COMMENTS 8 /* return scan_DSC_Comment */
|
|
-#define SCAN_PDF_RULES 16 /* PDF scanning rules (for names) */
|
|
-#define SCAN_PDF_INV_NUM 32 /* Adobe ignores invalid numbers */
|
|
- /* This is for compatibility with Adobe */
|
|
- /* Acrobat Reader */
|
|
+#define SCAN_PDF_RULES 16 /* PDF scanning rules (for names) */
|
|
+#define SCAN_PDF_INV_NUM 32 /* Adobe ignores invalid numbers */
|
|
+ /* This is for compatibility with Adobe */
|
|
+ /* Acrobat Reader */
|
|
#define SCAN_PDF_UNSIGNED 64 /* Scan 2147483648..4294967295 as unsigned numbers */
|
|
/* This is needed in some contexts for */
|
|
/* compatibility with Adobe */
|
|
-void scanner_init_options(scanner_state *sstate, const ref *fop,
|
|
- int options);
|
|
-#define scanner_init(sstate, fop)\
|
|
- scanner_init_options(sstate, fop, 0)
|
|
-void scanner_init_stream_options(scanner_state *sstate, stream *s,
|
|
- int options);
|
|
-#define scanner_init_stream(sstate, s)\
|
|
- scanner_init_stream_options(sstate, s, 0)
|
|
+void gs_scanner_init_options(scanner_state *sstate, const ref *fop,
|
|
+ int options);
|
|
+#define gs_scanner_init(sstate, fop)\
|
|
+ gs_scanner_init_options(sstate, fop, 0)
|
|
+void gs_scanner_init_stream_options(scanner_state *sstate, stream *s,
|
|
+ int options);
|
|
+#define gs_scanner_init_stream(sstate, s)\
|
|
+ gs_scanner_init_stream_options(sstate, s, 0)
|
|
|
|
/*
|
|
* Read a token from a stream. As usual, 0 is a normal return,
|
|
* <0 is an error. There are also some special return codes:
|
|
*/
|
|
-#define scan_BOS 1 /* binary object sequence */
|
|
-#define scan_EOF 2 /* end of stream */
|
|
-#define scan_Refill 3 /* get more input data, then call again */
|
|
-#define scan_Comment 4 /* comment, non-DSC if processing DSC */
|
|
-#define scan_DSC_Comment 5 /* DSC comment */
|
|
-int scan_token(i_ctx_t *i_ctx_p, ref * pref, scanner_state * pstate);
|
|
+#define scan_BOS 1 /* binary object sequence */
|
|
+#define scan_EOF 2 /* end of stream */
|
|
+#define scan_Refill 3 /* get more input data, then call again */
|
|
+#define scan_Comment 4 /* comment, non-DSC if processing DSC */
|
|
+#define scan_DSC_Comment 5 /* DSC comment */
|
|
+int gs_scan_token(i_ctx_t *i_ctx_p, ref * pref, scanner_state * pstate);
|
|
|
|
/*
|
|
- * Read a token from a string. Return like scan_token, but also
|
|
+ * Read a token from a string. Return like gs_scan_token, but also
|
|
* update the string to move past the token (if no error).
|
|
*/
|
|
-int scan_string_token_options(i_ctx_t *i_ctx_p, ref * pstr, ref * pref,
|
|
- int options);
|
|
-#define scan_string_token(i_ctx_p, pstr, pref)\
|
|
- scan_string_token_options(i_ctx_p, pstr, pref, 0)
|
|
+int gs_scan_string_token_options(i_ctx_t *i_ctx_p, ref * pstr, ref * pref,
|
|
+ int options);
|
|
+#define gs_scan_string_token(i_ctx_p, pstr, pref)\
|
|
+ gs_scan_string_token_options(i_ctx_p, pstr, pref, 0)
|
|
|
|
/*
|
|
* Return the "error object" to be stored in $error.command instead of
|
|
* --token--, if any, or -1 if no special error object is required.
|
|
*/
|
|
-int scanner_error_object(i_ctx_t *i_ctx_p, const scanner_state *pstate,
|
|
- ref *pseo);
|
|
+int gs_scanner_error_object(i_ctx_t *i_ctx_p, const scanner_state *pstate,
|
|
+ ref *pseo);
|
|
|
|
/*
|
|
- * Handle a scan_Refill return from scan_token.
|
|
- * This may return o_push_estack, 0 (meaning just call scan_token again),
|
|
- * or an error code.
|
|
+ * Handle a scan_Refill return from gs_scan_token.
|
|
+ * This may return o_push_estack, 0 (meaning just call gs_scan_token
|
|
+ * again), or an error code.
|
|
*/
|
|
-int scan_handle_refill(i_ctx_t *i_ctx_p, scanner_state * pstate,
|
|
- bool save, op_proc_t cont);
|
|
+int gs_scan_handle_refill(i_ctx_t *i_ctx_p, scanner_state * pstate,
|
|
+ bool save, op_proc_t cont);
|
|
|
|
/*
|
|
* Define the procedure "hook" for parsing DSC comments. If not NULL,
|
|
* this procedure is called for every DSC comment seen by the scanner.
|
|
*/
|
|
-extern int (*scan_dsc_proc) (const byte *, uint);
|
|
+extern int (*gs_scan_dsc_proc) (const byte *, uint);
|
|
|
|
/*
|
|
* Define the procedure "hook" for parsing general comments. If not NULL,
|
|
* this procedure is called for every comment seen by the scanner.
|
|
- * If both scan_dsc_proc and scan_comment_proc are set,
|
|
- * scan_comment_proc is called only for non-DSC comments.
|
|
+ * If both gs_scan_dsc_proc and gs_scan_comment_proc are set,
|
|
+ * gs_scan_comment_proc is called only for non-DSC comments.
|
|
*/
|
|
-extern int (*scan_comment_proc) (const byte *, uint);
|
|
+extern int (*gs_scan_comment_proc) (const byte *, uint);
|
|
|
|
#endif /* iscan_INCLUDED */
|
|
diff -up ghostscript-9.00/psi/itoken.h.scan_token ghostscript-9.00/psi/itoken.h
|
|
--- ghostscript-9.00/psi/itoken.h.scan_token 2008-08-28 23:48:19.000000000 +0100
|
|
+++ ghostscript-9.00/psi/itoken.h 2011-01-14 17:16:12.618867712 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -24,16 +24,16 @@
|
|
int ztokenexec_continue(i_ctx_t *i_ctx_p);
|
|
|
|
/*
|
|
- * Handle a scan_Comment or scan_DSC_Comment return from scan_token.
|
|
+ * Handle a scan_Comment or scan_DSC_Comment return from gs_scan_token.
|
|
*/
|
|
#ifndef scanner_state_DEFINED
|
|
# define scanner_state_DEFINED
|
|
typedef struct scanner_state_s scanner_state;
|
|
#endif
|
|
int ztoken_handle_comment(i_ctx_t *i_ctx_p,
|
|
- scanner_state *sstate, const ref *ptoken,
|
|
- int scan_code, bool save, bool push_file,
|
|
- op_proc_t cont);
|
|
+ scanner_state *sstate, const ref *ptoken,
|
|
+ int scan_code, bool save, bool push_file,
|
|
+ op_proc_t cont);
|
|
|
|
/*
|
|
* Update the cached scanner_options in the context state after doing a
|
|
diff -up ghostscript-9.00/psi/ziodev.c.scan_token ghostscript-9.00/psi/ziodev.c
|
|
--- ghostscript-9.00/psi/ziodev.c.scan_token 2010-04-15 18:13:30.000000000 +0100
|
|
+++ ghostscript-9.00/psi/ziodev.c 2011-01-14 17:16:12.620867730 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -25,10 +25,10 @@
|
|
#include "ialloc.h"
|
|
#include "iscan.h"
|
|
#include "ivmspace.h"
|
|
-#include "gxiodev.h" /* must come after stream.h */
|
|
- /* and before files.h */
|
|
+#include "gxiodev.h" /* must come after stream.h */
|
|
+ /* and before files.h */
|
|
#include "files.h"
|
|
-#include "scanchar.h" /* for char_EOL */
|
|
+#include "scanchar.h" /* for char_EOL */
|
|
#include "store.h"
|
|
#include "ierrors.h"
|
|
|
|
@@ -38,11 +38,11 @@ extern const char iodev_dtype_stdio[];
|
|
/* Define the special devices. */
|
|
#define iodev_special(dname, init, open) {\
|
|
dname, iodev_dtype_stdio,\
|
|
- { init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
|
|
- iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
|
|
- iodev_no_enumerate_files, NULL, NULL,\
|
|
- iodev_no_get_params, iodev_no_put_params\
|
|
- }\
|
|
+ { init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
|
|
+ iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
|
|
+ iodev_no_enumerate_files, NULL, NULL,\
|
|
+ iodev_no_get_params, iodev_no_put_params\
|
|
+ }\
|
|
}
|
|
|
|
/*
|
|
@@ -53,12 +53,12 @@ extern const char iodev_dtype_stdio[];
|
|
* immediately afterwards so as not to wind up with dangling references.
|
|
*/
|
|
|
|
-#define LINEEDIT_BUF_SIZE 20 /* initial size, not fixed size */
|
|
+#define LINEEDIT_BUF_SIZE 20 /* initial size, not fixed size */
|
|
/*static iodev_proc_open_device(lineedit_open);*/ /* no longer used */
|
|
const gx_io_device gs_iodev_lineedit =
|
|
iodev_special("%lineedit%", iodev_no_init, iodev_no_open_device);
|
|
|
|
-#define STATEMENTEDIT_BUF_SIZE 50 /* initial size, not fixed size */
|
|
+#define STATEMENTEDIT_BUF_SIZE 50 /* initial size, not fixed size */
|
|
/*static iodev_proc_open_device(statementedit_open);*/ /* no longer used */
|
|
const gx_io_device gs_iodev_statementedit =
|
|
iodev_special("%statementedit%", iodev_no_init, iodev_no_open_device);
|
|
@@ -75,24 +75,24 @@ zgetiodevice(i_ctx_t *i_ctx_p)
|
|
|
|
check_type(*op, t_integer);
|
|
iodev = gs_getiodevice(imemory, (int)(op->value.intval));
|
|
- if (iodev == 0) /* index out of range */
|
|
- return_error(e_rangecheck);
|
|
+ if (iodev == 0) /* index out of range */
|
|
+ return_error(e_rangecheck);
|
|
dname = (const byte *)iodev->dname;
|
|
if (dname == 0)
|
|
- make_null(op);
|
|
+ make_null(op);
|
|
else
|
|
- make_const_string(op, a_readonly | avm_foreign,
|
|
- strlen((const char *)dname), dname);
|
|
+ make_const_string(op, a_readonly | avm_foreign,
|
|
+ strlen((const char *)dname), dname);
|
|
return 0;
|
|
}
|
|
|
|
/* ------ %lineedit and %statementedit ------ */
|
|
|
|
/* <file> <bool> <int> <string> .filelineedit <file> */
|
|
-/* This opens %statementedit% or %lineedit% and is also the
|
|
+/* This opens %statementedit% or %lineedit% and is also the
|
|
* continuation proc for callouts.
|
|
* Input:
|
|
- * string is the statement/line buffer,
|
|
+ * string is the statement/line buffer,
|
|
* int is the write index into string
|
|
* bool is true if %statementedit%
|
|
* file is stdin
|
|
@@ -100,7 +100,7 @@ zgetiodevice(i_ctx_t *i_ctx_p)
|
|
* file is a string based stream
|
|
* We store the line being read in a PostScript string.
|
|
* This limits the size to max_string_size (64k).
|
|
- * This could be increased by storing the input line in something
|
|
+ * This could be increased by storing the input line in something
|
|
* other than a PostScript string.
|
|
*/
|
|
int
|
|
@@ -122,165 +122,165 @@ zfilelineedit(i_ctx_t *i_ctx_p)
|
|
*/
|
|
gs_string *const buf = &str;
|
|
|
|
- check_type(*op, t_string); /* line assembled so far */
|
|
+ check_type(*op, t_string); /* line assembled so far */
|
|
buf->data = op->value.bytes;
|
|
buf->size = op->tas.rsize;
|
|
- check_type(*(op-1), t_integer); /* index */
|
|
+ check_type(*(op-1), t_integer); /* index */
|
|
count = (op-1)->value.intval;
|
|
- check_type(*(op-2), t_boolean); /* statementedit/lineedit */
|
|
+ check_type(*(op-2), t_boolean); /* statementedit/lineedit */
|
|
statement = (op-2)->value.boolval;
|
|
- check_read_file(i_ctx_p, ins, op - 3); /* %stdin */
|
|
+ check_read_file(i_ctx_p, ins, op - 3); /* %stdin */
|
|
|
|
/* extend string */
|
|
initial_buf_size = statement ? STATEMENTEDIT_BUF_SIZE : LINEEDIT_BUF_SIZE;
|
|
if (initial_buf_size > max_string_size)
|
|
- return_error(e_limitcheck);
|
|
+ return_error(e_limitcheck);
|
|
if (!buf->data || (buf->size < initial_buf_size)) {
|
|
- count = 0;
|
|
- buf->data = gs_alloc_string(imemory_system, initial_buf_size,
|
|
- "zfilelineedit(buffer)");
|
|
- if (buf->data == 0)
|
|
- return_error(e_VMerror);
|
|
+ count = 0;
|
|
+ buf->data = gs_alloc_string(imemory_system, initial_buf_size,
|
|
+ "zfilelineedit(buffer)");
|
|
+ if (buf->data == 0)
|
|
+ return_error(e_VMerror);
|
|
op->value.bytes = buf->data;
|
|
- op->tas.rsize = buf->size = initial_buf_size;
|
|
+ op->tas.rsize = buf->size = initial_buf_size;
|
|
}
|
|
|
|
rd:
|
|
code = zreadline_from(ins, buf, imemory_system, &count, &in_eol);
|
|
if (buf->size > max_string_size) {
|
|
- /* zreadline_from reallocated the buffer larger than
|
|
- * is valid for a PostScript string.
|
|
- * Return an error, but first realloc the buffer
|
|
- * back to a legal size.
|
|
- */
|
|
- byte *nbuf = gs_resize_string(imemory_system, buf->data, buf->size,
|
|
- max_string_size, "zfilelineedit(shrink buffer)");
|
|
- if (nbuf == 0)
|
|
- return_error(e_VMerror);
|
|
- op->value.bytes = buf->data = nbuf;
|
|
- op->tas.rsize = buf->size = max_string_size;
|
|
- return_error(e_limitcheck);
|
|
+ /* zreadline_from reallocated the buffer larger than
|
|
+ * is valid for a PostScript string.
|
|
+ * Return an error, but first realloc the buffer
|
|
+ * back to a legal size.
|
|
+ */
|
|
+ byte *nbuf = gs_resize_string(imemory_system, buf->data, buf->size,
|
|
+ max_string_size, "zfilelineedit(shrink buffer)");
|
|
+ if (nbuf == 0)
|
|
+ return_error(e_VMerror);
|
|
+ op->value.bytes = buf->data = nbuf;
|
|
+ op->tas.rsize = buf->size = max_string_size;
|
|
+ return_error(e_limitcheck);
|
|
}
|
|
|
|
op->value.bytes = buf->data; /* zreadline_from sometimes resizes the buffer. */
|
|
op->tas.rsize = buf->size;
|
|
|
|
switch (code) {
|
|
- case EOFC:
|
|
- code = gs_note_error(e_undefinedfilename);
|
|
- /* falls through */
|
|
- case 0:
|
|
- break;
|
|
- default:
|
|
- code = gs_note_error(e_ioerror);
|
|
- break;
|
|
- case CALLC:
|
|
- {
|
|
- ref rfile;
|
|
- (op-1)->value.intval = count;
|
|
- /* callout is for stdin */
|
|
- make_file(&rfile, a_readonly | avm_system, ins->read_id, ins);
|
|
- code = s_handle_read_exception(i_ctx_p, code, &rfile,
|
|
- NULL, 0, zfilelineedit);
|
|
- }
|
|
- break;
|
|
- case 1: /* filled buffer */
|
|
- {
|
|
- uint nsize = buf->size;
|
|
- byte *nbuf;
|
|
-
|
|
- if (nsize >= max_string_size) {
|
|
- code = gs_note_error(e_limitcheck);
|
|
- break;
|
|
- }
|
|
- else if (nsize >= max_string_size / 2)
|
|
- nsize= max_string_size;
|
|
- else
|
|
- nsize = buf->size * 2;
|
|
- nbuf = gs_resize_string(imemory_system, buf->data, buf->size, nsize,
|
|
- "zfilelineedit(grow buffer)");
|
|
- if (nbuf == 0) {
|
|
- code = gs_note_error(e_VMerror);
|
|
- break;
|
|
- }
|
|
- op->value.bytes = buf->data = nbuf;
|
|
- op->tas.rsize = buf->size = nsize;
|
|
- goto rd;
|
|
- }
|
|
+ case EOFC:
|
|
+ code = gs_note_error(e_undefinedfilename);
|
|
+ /* falls through */
|
|
+ case 0:
|
|
+ break;
|
|
+ default:
|
|
+ code = gs_note_error(e_ioerror);
|
|
+ break;
|
|
+ case CALLC:
|
|
+ {
|
|
+ ref rfile;
|
|
+ (op-1)->value.intval = count;
|
|
+ /* callout is for stdin */
|
|
+ make_file(&rfile, a_readonly | avm_system, ins->read_id, ins);
|
|
+ code = s_handle_read_exception(i_ctx_p, code, &rfile,
|
|
+ NULL, 0, zfilelineedit);
|
|
+ }
|
|
+ break;
|
|
+ case 1: /* filled buffer */
|
|
+ {
|
|
+ uint nsize = buf->size;
|
|
+ byte *nbuf;
|
|
+
|
|
+ if (nsize >= max_string_size) {
|
|
+ code = gs_note_error(e_limitcheck);
|
|
+ break;
|
|
+ }
|
|
+ else if (nsize >= max_string_size / 2)
|
|
+ nsize= max_string_size;
|
|
+ else
|
|
+ nsize = buf->size * 2;
|
|
+ nbuf = gs_resize_string(imemory_system, buf->data, buf->size, nsize,
|
|
+ "zfilelineedit(grow buffer)");
|
|
+ if (nbuf == 0) {
|
|
+ code = gs_note_error(e_VMerror);
|
|
+ break;
|
|
+ }
|
|
+ op->value.bytes = buf->data = nbuf;
|
|
+ op->tas.rsize = buf->size = nsize;
|
|
+ goto rd;
|
|
+ }
|
|
}
|
|
if (code != 0)
|
|
- return code;
|
|
+ return code;
|
|
if (statement) {
|
|
- /* If we don't have a complete token, keep going. */
|
|
- stream st;
|
|
- stream *ts = &st;
|
|
- scanner_state state;
|
|
- ref ignore_value;
|
|
- uint depth = ref_stack_count(&o_stack);
|
|
- int code;
|
|
-
|
|
- /* Add a terminating EOL. */
|
|
- if (count + 1 > buf->size) {
|
|
- uint nsize;
|
|
- byte *nbuf;
|
|
-
|
|
- nsize = buf->size + 1;
|
|
- if (nsize > max_string_size) {
|
|
- return_error(gs_note_error(e_limitcheck));
|
|
- }
|
|
- else {
|
|
- nbuf = gs_resize_string(imemory_system, buf->data, buf->size, nsize,
|
|
- "zfilelineedit(grow buffer)");
|
|
- if (nbuf == 0) {
|
|
- code = gs_note_error(e_VMerror);
|
|
- return_error(code);
|
|
- }
|
|
- op->value.bytes = buf->data = nbuf;
|
|
- op->tas.rsize = buf->size = nsize;
|
|
- }
|
|
- }
|
|
- buf->data[count++] = char_EOL;
|
|
- s_init(ts, NULL);
|
|
- sread_string(ts, buf->data, count);
|
|
+ /* If we don't have a complete token, keep going. */
|
|
+ stream st;
|
|
+ stream *ts = &st;
|
|
+ scanner_state state;
|
|
+ ref ignore_value;
|
|
+ uint depth = ref_stack_count(&o_stack);
|
|
+ int code;
|
|
+
|
|
+ /* Add a terminating EOL. */
|
|
+ if (count + 1 > buf->size) {
|
|
+ uint nsize;
|
|
+ byte *nbuf;
|
|
+
|
|
+ nsize = buf->size + 1;
|
|
+ if (nsize > max_string_size) {
|
|
+ return_error(gs_note_error(e_limitcheck));
|
|
+ }
|
|
+ else {
|
|
+ nbuf = gs_resize_string(imemory_system, buf->data, buf->size, nsize,
|
|
+ "zfilelineedit(grow buffer)");
|
|
+ if (nbuf == 0) {
|
|
+ code = gs_note_error(e_VMerror);
|
|
+ return_error(code);
|
|
+ }
|
|
+ op->value.bytes = buf->data = nbuf;
|
|
+ op->tas.rsize = buf->size = nsize;
|
|
+ }
|
|
+ }
|
|
+ buf->data[count++] = char_EOL;
|
|
+ s_init(ts, NULL);
|
|
+ sread_string(ts, buf->data, count);
|
|
sc:
|
|
- scanner_init_stream_options(&state, ts, SCAN_CHECK_ONLY);
|
|
- code = scan_token(i_ctx_p, &ignore_value, &state);
|
|
- ref_stack_pop_to(&o_stack, depth);
|
|
- if (code < 0)
|
|
- code = scan_EOF; /* stop on scanner error */
|
|
- switch (code) {
|
|
- case 0: /* read a token */
|
|
- case scan_BOS:
|
|
- goto sc; /* keep going until we run out of data */
|
|
- case scan_Refill:
|
|
- goto rd;
|
|
- case scan_EOF:
|
|
- break;
|
|
- default: /* error */
|
|
- return code;
|
|
- }
|
|
+ gs_scanner_init_stream_options(&state, ts, SCAN_CHECK_ONLY);
|
|
+ code = gs_scan_token(i_ctx_p, &ignore_value, &state);
|
|
+ ref_stack_pop_to(&o_stack, depth);
|
|
+ if (code < 0)
|
|
+ code = scan_EOF; /* stop on scanner error */
|
|
+ switch (code) {
|
|
+ case 0: /* read a token */
|
|
+ case scan_BOS:
|
|
+ goto sc; /* keep going until we run out of data */
|
|
+ case scan_Refill:
|
|
+ goto rd;
|
|
+ case scan_EOF:
|
|
+ break;
|
|
+ default: /* error */
|
|
+ return code;
|
|
+ }
|
|
}
|
|
buf->data = gs_resize_string(imemory_system, buf->data, buf->size, count,
|
|
- "zfilelineedit(resize buffer)");
|
|
+ "zfilelineedit(resize buffer)");
|
|
if (buf->data == 0)
|
|
- return_error(e_VMerror);
|
|
+ return_error(e_VMerror);
|
|
op->value.bytes = buf->data;
|
|
op->tas.rsize = buf->size;
|
|
|
|
s = file_alloc_stream(imemory_system, "zfilelineedit(stream)");
|
|
if (s == 0)
|
|
- return_error(e_VMerror);
|
|
+ return_error(e_VMerror);
|
|
|
|
sread_string(s, buf->data, count);
|
|
s->save_close = s->procs.close;
|
|
s->procs.close = file_close_disable;
|
|
|
|
filename = statement ? gs_iodev_statementedit.dname
|
|
- : gs_iodev_lineedit.dname;
|
|
+ : gs_iodev_lineedit.dname;
|
|
code = ssetfilename(s, (const byte *)filename, strlen(filename)+1);
|
|
if (code < 0) {
|
|
- sclose(s);
|
|
- return_error(e_VMerror);
|
|
+ sclose(s);
|
|
+ return_error(e_VMerror);
|
|
}
|
|
|
|
pop(3);
|
|
diff -up ghostscript-9.00/psi/ztoken.c.scan_token ghostscript-9.00/psi/ztoken.c
|
|
--- ghostscript-9.00/psi/ztoken.c.scan_token 2010-04-26 16:29:28.000000000 +0100
|
|
+++ ghostscript-9.00/psi/ztoken.c 2011-01-14 17:16:12.621867740 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -17,19 +17,19 @@
|
|
#include "stat_.h" /* get system header early to avoid name clash on Cygwin */
|
|
#include "ghost.h"
|
|
#include "oper.h"
|
|
-#include "dstack.h" /* for dict_find_name */
|
|
+#include "dstack.h" /* for dict_find_name */
|
|
#include "estack.h"
|
|
-#include "gsstruct.h" /* for iscan.h */
|
|
+#include "gsstruct.h" /* for iscan.h */
|
|
#include "gsutil.h"
|
|
#include "stream.h"
|
|
#include "files.h"
|
|
#include "store.h"
|
|
-#include "strimpl.h" /* for sfilter.h */
|
|
-#include "sfilter.h" /* for iscan.h */
|
|
+#include "strimpl.h" /* for sfilter.h */
|
|
+#include "sfilter.h" /* for iscan.h */
|
|
#include "idict.h"
|
|
#include "iname.h"
|
|
#include "iscan.h"
|
|
-#include "itoken.h" /* for prototypes */
|
|
+#include "itoken.h" /* for prototypes */
|
|
|
|
/* <file> token <obj> -true- */
|
|
/* <string> token <post> <obj> -true- */
|
|
@@ -42,47 +42,47 @@ ztoken(i_ctx_t *i_ctx_p)
|
|
os_ptr op = osp;
|
|
|
|
switch (r_type(op)) {
|
|
- default:
|
|
- return_op_typecheck(op);
|
|
- case t_file: {
|
|
- stream *s;
|
|
- scanner_state state;
|
|
-
|
|
- check_read_file(i_ctx_p, s, op);
|
|
- check_ostack(1);
|
|
- scanner_init(&state, op);
|
|
- return token_continue(i_ctx_p, &state, true);
|
|
- }
|
|
- case t_string: {
|
|
- ref token;
|
|
- /* -1 is to remove the string operand in case of error. */
|
|
- int orig_ostack_depth = ref_stack_count(&o_stack) - 1;
|
|
- int code;
|
|
-
|
|
- /* Don't pop the operand in case of invalidaccess. */
|
|
- if (!r_has_attr(op, a_read))
|
|
- return_error(e_invalidaccess);
|
|
- code = scan_string_token(i_ctx_p, op, &token);
|
|
- switch (code) {
|
|
- case scan_EOF: /* no tokens */
|
|
- make_false(op);
|
|
- return 0;
|
|
- default:
|
|
- if (code < 0) {
|
|
- /*
|
|
- * Clear anything that may have been left on the ostack,
|
|
- * including the string operand.
|
|
- */
|
|
- if (orig_ostack_depth < ref_stack_count(&o_stack))
|
|
- pop(ref_stack_count(&o_stack)- orig_ostack_depth);
|
|
- return code;
|
|
- }
|
|
- }
|
|
- push(2);
|
|
- op[-1] = token;
|
|
- make_true(op);
|
|
- return 0;
|
|
- }
|
|
+ default:
|
|
+ return_op_typecheck(op);
|
|
+ case t_file: {
|
|
+ stream *s;
|
|
+ scanner_state state;
|
|
+
|
|
+ check_read_file(i_ctx_p, s, op);
|
|
+ check_ostack(1);
|
|
+ gs_scanner_init(&state, op);
|
|
+ return token_continue(i_ctx_p, &state, true);
|
|
+ }
|
|
+ case t_string: {
|
|
+ ref token;
|
|
+ /* -1 is to remove the string operand in case of error. */
|
|
+ int orig_ostack_depth = ref_stack_count(&o_stack) - 1;
|
|
+ int code;
|
|
+
|
|
+ /* Don't pop the operand in case of invalidaccess. */
|
|
+ if (!r_has_attr(op, a_read))
|
|
+ return_error(e_invalidaccess);
|
|
+ code = gs_scan_string_token(i_ctx_p, op, &token);
|
|
+ switch (code) {
|
|
+ case scan_EOF: /* no tokens */
|
|
+ make_false(op);
|
|
+ return 0;
|
|
+ default:
|
|
+ if (code < 0) {
|
|
+ /*
|
|
+ * Clear anything that may have been left on the ostack,
|
|
+ * including the string operand.
|
|
+ */
|
|
+ if (orig_ostack_depth < ref_stack_count(&o_stack))
|
|
+ pop(ref_stack_count(&o_stack)- orig_ostack_depth);
|
|
+ return code;
|
|
+ }
|
|
+ }
|
|
+ push(2);
|
|
+ op[-1] = token;
|
|
+ make_true(op);
|
|
+ return 0;
|
|
+ }
|
|
}
|
|
}
|
|
/* Continue reading a token after an interrupt or callout. */
|
|
@@ -105,42 +105,42 @@ token_continue(i_ctx_t *i_ctx_p, scanner
|
|
int code;
|
|
ref token;
|
|
|
|
- /* Note that scan_token may change osp! */
|
|
- pop(1); /* remove the file or scanner state */
|
|
+ /* Note that gs_scan_token may change osp! */
|
|
+ pop(1); /* remove the file or scanner state */
|
|
again:
|
|
- code = scan_token(i_ctx_p, &token, pstate);
|
|
+ code = gs_scan_token(i_ctx_p, &token, pstate);
|
|
op = osp;
|
|
switch (code) {
|
|
- default: /* error */
|
|
- if (code > 0) /* comment, not possible */
|
|
- code = gs_note_error(e_syntaxerror);
|
|
- scanner_error_object(i_ctx_p, pstate, &i_ctx_p->error_object);
|
|
- break;
|
|
- case scan_BOS:
|
|
- code = 0;
|
|
- case 0: /* read a token */
|
|
- push(2);
|
|
- ref_assign(op - 1, &token);
|
|
- make_true(op);
|
|
- break;
|
|
- case scan_EOF: /* no tokens */
|
|
- push(1);
|
|
- make_false(op);
|
|
- code = 0;
|
|
- break;
|
|
- case scan_Refill: /* need more data */
|
|
- code = scan_handle_refill(i_ctx_p, pstate, save,
|
|
- ztoken_continue);
|
|
- switch (code) {
|
|
- case 0: /* state is not copied to the heap */
|
|
- goto again;
|
|
- case o_push_estack:
|
|
- return code;
|
|
- }
|
|
- break; /* error */
|
|
+ default: /* error */
|
|
+ if (code > 0) /* comment, not possible */
|
|
+ code = gs_note_error(e_syntaxerror);
|
|
+ gs_scanner_error_object(i_ctx_p, pstate, &i_ctx_p->error_object);
|
|
+ break;
|
|
+ case scan_BOS:
|
|
+ code = 0;
|
|
+ case 0: /* read a token */
|
|
+ push(2);
|
|
+ ref_assign(op - 1, &token);
|
|
+ make_true(op);
|
|
+ break;
|
|
+ case scan_EOF: /* no tokens */
|
|
+ push(1);
|
|
+ make_false(op);
|
|
+ code = 0;
|
|
+ break;
|
|
+ case scan_Refill: /* need more data */
|
|
+ code = gs_scan_handle_refill(i_ctx_p, pstate, save,
|
|
+ ztoken_continue);
|
|
+ switch (code) {
|
|
+ case 0: /* state is not copied to the heap */
|
|
+ goto again;
|
|
+ case o_push_estack:
|
|
+ return code;
|
|
+ }
|
|
+ break; /* error */
|
|
}
|
|
- if (code <= 0 && !save) { /* Deallocate the scanner state record. */
|
|
- ifree_object(pstate, "token_continue");
|
|
+ if (code <= 0 && !save) { /* Deallocate the scanner state record. */
|
|
+ ifree_object(pstate, "token_continue");
|
|
}
|
|
return code;
|
|
}
|
|
@@ -149,7 +149,7 @@ again:
|
|
/* Read a token and do what the interpreter would do with it. */
|
|
/* This is different from token + exec because literal procedures */
|
|
/* are not executed (although binary object sequences ARE executed). */
|
|
-int ztokenexec_continue(i_ctx_t *); /* export for interpreter */
|
|
+int ztokenexec_continue(i_ctx_t *); /* export for interpreter */
|
|
static int tokenexec_continue(i_ctx_t *, scanner_state *, bool);
|
|
int
|
|
ztokenexec(i_ctx_t *i_ctx_p)
|
|
@@ -160,7 +160,7 @@ ztokenexec(i_ctx_t *i_ctx_p)
|
|
|
|
check_read_file(i_ctx_p, s, op);
|
|
check_estack(1);
|
|
- scanner_init(&state, op);
|
|
+ gs_scanner_init(&state, op);
|
|
return tokenexec_continue(i_ctx_p, &state, true);
|
|
}
|
|
/* Continue reading a token for execution after an interrupt or callout. */
|
|
@@ -183,61 +183,61 @@ tokenexec_continue(i_ctx_t *i_ctx_p, sca
|
|
{
|
|
os_ptr op;
|
|
int code;
|
|
- /* Note that scan_token may change osp! */
|
|
+ /* Note that gs_scan_token may change osp! */
|
|
pop(1);
|
|
again:
|
|
check_estack(1);
|
|
- code = scan_token(i_ctx_p, (ref *) (esp + 1), pstate);
|
|
+ code = gs_scan_token(i_ctx_p, (ref *) (esp + 1), pstate);
|
|
op = osp;
|
|
switch (code) {
|
|
- case 0:
|
|
- if (r_is_proc(esp + 1)) { /* Treat procedure as a literal. */
|
|
- push(1);
|
|
- ref_assign(op, esp + 1);
|
|
- code = 0;
|
|
- break;
|
|
- }
|
|
- /* falls through */
|
|
- case scan_BOS:
|
|
- ++esp;
|
|
- code = o_push_estack;
|
|
- break;
|
|
- case scan_EOF: /* no tokens */
|
|
- code = 0;
|
|
- break;
|
|
- case scan_Refill: /* need more data */
|
|
- code = scan_handle_refill(i_ctx_p, pstate, save,
|
|
- ztokenexec_continue);
|
|
- switch (code) {
|
|
- case 0: /* state is not copied to the heap */
|
|
- goto again;
|
|
- case o_push_estack:
|
|
- return code;
|
|
- }
|
|
- break; /* error */
|
|
- case scan_Comment:
|
|
- case scan_DSC_Comment:
|
|
- return ztoken_handle_comment(i_ctx_p, pstate, esp + 1, code,
|
|
- save, true, ztokenexec_continue);
|
|
- default: /* error */
|
|
- scanner_error_object(i_ctx_p, pstate, &i_ctx_p->error_object);
|
|
- break;
|
|
+ case 0:
|
|
+ if (r_is_proc(esp + 1)) { /* Treat procedure as a literal. */
|
|
+ push(1);
|
|
+ ref_assign(op, esp + 1);
|
|
+ code = 0;
|
|
+ break;
|
|
+ }
|
|
+ /* falls through */
|
|
+ case scan_BOS:
|
|
+ ++esp;
|
|
+ code = o_push_estack;
|
|
+ break;
|
|
+ case scan_EOF: /* no tokens */
|
|
+ code = 0;
|
|
+ break;
|
|
+ case scan_Refill: /* need more data */
|
|
+ code = gs_scan_handle_refill(i_ctx_p, pstate, save,
|
|
+ ztokenexec_continue);
|
|
+ switch (code) {
|
|
+ case 0: /* state is not copied to the heap */
|
|
+ goto again;
|
|
+ case o_push_estack:
|
|
+ return code;
|
|
+ }
|
|
+ break; /* error */
|
|
+ case scan_Comment:
|
|
+ case scan_DSC_Comment:
|
|
+ return ztoken_handle_comment(i_ctx_p, pstate, esp + 1, code,
|
|
+ save, true, ztokenexec_continue);
|
|
+ default: /* error */
|
|
+ gs_scanner_error_object(i_ctx_p, pstate, &i_ctx_p->error_object);
|
|
+ break;
|
|
}
|
|
- if (!save) { /* Deallocate the scanner state record. */
|
|
- gs_free_object(((scanner_state_dynamic *)pstate)->mem, pstate, "token_continue");
|
|
+ if (!save) { /* Deallocate the scanner state record. */
|
|
+ gs_free_object(((scanner_state_dynamic *)pstate)->mem, pstate, "token_continue");
|
|
}
|
|
return code;
|
|
}
|
|
|
|
/*
|
|
- * Handle a scan_Comment or scan_DSC_Comment return from scan_token
|
|
+ * Handle a scan_Comment or scan_DSC_Comment return from gs_scan_token
|
|
* (scan_code) by calling out to %Process[DSC]Comment. The continuation
|
|
* procedure expects the scanner state on the o-stack.
|
|
*/
|
|
int
|
|
ztoken_handle_comment(i_ctx_t *i_ctx_p, scanner_state *sstate,
|
|
- const ref *ptoken, int scan_code,
|
|
- bool save, bool push_file, op_proc_t cont)
|
|
+ const ref *ptoken, int scan_code,
|
|
+ bool save, bool push_file, op_proc_t cont)
|
|
{
|
|
const char *proc_name;
|
|
scanner_state *pstate;
|
|
@@ -247,39 +247,39 @@ ztoken_handle_comment(i_ctx_t *i_ctx_p,
|
|
|
|
switch (scan_code) {
|
|
case scan_Comment:
|
|
- proc_name = "%ProcessComment";
|
|
- break;
|
|
+ proc_name = "%ProcessComment";
|
|
+ break;
|
|
case scan_DSC_Comment:
|
|
- proc_name = "%ProcessDSCComment";
|
|
- break;
|
|
+ proc_name = "%ProcessDSCComment";
|
|
+ break;
|
|
default:
|
|
- return_error(e_Fatal); /* can't happen */
|
|
+ return_error(e_Fatal); /* can't happen */
|
|
}
|
|
/*
|
|
* We can't use check_ostack here, because it returns on overflow.
|
|
*/
|
|
/*check_ostack(2);*/
|
|
if (ostop - osp < 2) {
|
|
- code = ref_stack_extend(&o_stack, 2);
|
|
- if (code < 0)
|
|
- return code;
|
|
+ code = ref_stack_extend(&o_stack, 2);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
}
|
|
check_estack(3);
|
|
code = name_enter_string(imemory, proc_name, esp + 3);
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
if (save) {
|
|
- pstate = (scanner_state *)ialloc_struct(scanner_state_dynamic, &st_scanner_state_dynamic,
|
|
- "ztoken_handle_comment");
|
|
- if (pstate == 0)
|
|
- return_error(e_VMerror);
|
|
- ((scanner_state_dynamic *)pstate)->mem = imemory;
|
|
- *pstate = *sstate;
|
|
+ pstate = (scanner_state *)ialloc_struct(scanner_state_dynamic, &st_scanner_state_dynamic,
|
|
+ "ztoken_handle_comment");
|
|
+ if (pstate == 0)
|
|
+ return_error(e_VMerror);
|
|
+ ((scanner_state_dynamic *)pstate)->mem = imemory;
|
|
+ *pstate = *sstate;
|
|
} else
|
|
- pstate = sstate;
|
|
+ pstate = sstate;
|
|
/* Save the token now -- it might be on the e-stack. */
|
|
if (!pstate->s_pstack)
|
|
- osp[2] = *ptoken;
|
|
+ osp[2] = *ptoken;
|
|
/*
|
|
* Push the continuation, scanner state, file, and callout procedure
|
|
* on the e-stack.
|
|
@@ -288,28 +288,28 @@ ztoken_handle_comment(i_ctx_t *i_ctx_p,
|
|
make_istruct(esp + 2, 0, pstate);
|
|
ppcproc = dict_find_name(esp + 3);
|
|
if (ppcproc == 0) {
|
|
- /*
|
|
- * This can only happen during initialization.
|
|
- * Pop the comment string from the o-stack if needed (see below).
|
|
- */
|
|
- if (pstate->s_pstack)
|
|
- --osp;
|
|
- esp += 2; /* do run the continuation */
|
|
+ /*
|
|
+ * This can only happen during initialization.
|
|
+ * Pop the comment string from the o-stack if needed (see below).
|
|
+ */
|
|
+ if (pstate->s_pstack)
|
|
+ --osp;
|
|
+ esp += 2; /* do run the continuation */
|
|
} else {
|
|
- /*
|
|
- * Push the file and comment string on the o-stack.
|
|
- * If we were inside { }, the comment string is already on the stack.
|
|
- */
|
|
- if (pstate->s_pstack) {
|
|
- op = ++osp;
|
|
- *op = op[-1];
|
|
- } else {
|
|
- op = osp += 2;
|
|
- /* *op = *ptoken; */ /* saved above */
|
|
- }
|
|
- op[-1] = pstate->s_file;
|
|
- esp[3] = *ppcproc;
|
|
- esp += 3;
|
|
+ /*
|
|
+ * Push the file and comment string on the o-stack.
|
|
+ * If we were inside { }, the comment string is already on the stack.
|
|
+ */
|
|
+ if (pstate->s_pstack) {
|
|
+ op = ++osp;
|
|
+ *op = op[-1];
|
|
+ } else {
|
|
+ op = osp += 2;
|
|
+ /* *op = *ptoken; */ /* saved above */
|
|
+ }
|
|
+ op[-1] = pstate->s_file;
|
|
+ esp[3] = *ppcproc;
|
|
+ esp += 3;
|
|
}
|
|
return o_push_estack;
|
|
}
|
|
@@ -337,17 +337,17 @@ ztoken_scanner_options(const ref *upref,
|
|
int i;
|
|
|
|
for (i = 0; i < countof(named_options); ++i) {
|
|
- const named_scanner_option_t *pnso = &named_options[i];
|
|
- ref *ppcproc;
|
|
- int code = dict_find_string(upref, pnso->pname, &ppcproc);
|
|
-
|
|
- /* Update the options only if the parameter has changed. */
|
|
- if (code >= 0) {
|
|
- if (r_has_type(ppcproc, t_null))
|
|
- options &= ~pnso->option;
|
|
- else
|
|
- options |= pnso->option;
|
|
- }
|
|
+ const named_scanner_option_t *pnso = &named_options[i];
|
|
+ ref *ppcproc;
|
|
+ int code = dict_find_string(upref, pnso->pname, &ppcproc);
|
|
+
|
|
+ /* Update the options only if the parameter has changed. */
|
|
+ if (code >= 0) {
|
|
+ if (r_has_type(ppcproc, t_null))
|
|
+ options &= ~pnso->option;
|
|
+ else
|
|
+ options |= pnso->option;
|
|
+ }
|
|
}
|
|
return options;
|
|
}
|
|
@@ -361,11 +361,11 @@ ztoken_get_scanner_option(const ref *psr
|
|
const named_scanner_option_t *pnso;
|
|
|
|
for (pnso = named_options + countof(named_options); pnso-- != named_options;) {
|
|
- if (!bytes_compare((const byte *)pnso->pname, strlen(pnso->pname),
|
|
- psref->value.const_bytes, r_size(psref))) {
|
|
- *pname = pnso->pname;
|
|
- return (options & pnso->option ? 1 : 0);
|
|
- }
|
|
+ if (!bytes_compare((const byte *)pnso->pname, strlen(pnso->pname),
|
|
+ psref->value.const_bytes, r_size(psref))) {
|
|
+ *pname = pnso->pname;
|
|
+ return (options & pnso->option ? 1 : 0);
|
|
+ }
|
|
}
|
|
return -1;
|
|
}
|
|
@@ -376,7 +376,7 @@ const op_def ztoken_op_defs[] =
|
|
{
|
|
{"1token", ztoken},
|
|
{"1.tokenexec", ztokenexec},
|
|
- /* Internal operators */
|
|
+ /* Internal operators */
|
|
{"2%ztoken_continue", ztoken_continue},
|
|
{"2%ztokenexec_continue", ztokenexec_continue},
|
|
op_def_end(0)
|
|
diff -up ghostscript-9.00/psi/ztype.c.scan_token ghostscript-9.00/psi/ztype.c
|
|
--- ghostscript-9.00/psi/ztype.c.scan_token 2009-06-05 06:55:54.000000000 +0100
|
|
+++ ghostscript-9.00/psi/ztype.c 2011-01-14 17:16:12.623867766 +0000
|
|
@@ -1,6 +1,6 @@
|
|
/* Copyright (C) 2001-2006 Artifex Software, Inc.
|
|
All Rights Reserved.
|
|
-
|
|
+
|
|
This software is provided AS-IS with no warranty, either express or
|
|
implied.
|
|
|
|
@@ -19,15 +19,15 @@
|
|
#include "gsexit.h"
|
|
#include "ghost.h"
|
|
#include "oper.h"
|
|
-#include "imemory.h" /* for register_ref_root */
|
|
+#include "imemory.h" /* for register_ref_root */
|
|
#include "idict.h"
|
|
#include "iname.h"
|
|
-#include "stream.h" /* for iscan.h */
|
|
-#include "strimpl.h" /* for sfilter.h for picky compilers */
|
|
-#include "sfilter.h" /* ditto */
|
|
+#include "stream.h" /* for iscan.h */
|
|
+#include "strimpl.h" /* for sfilter.h for picky compilers */
|
|
+#include "sfilter.h" /* ditto */
|
|
#include "iscan.h"
|
|
#include "iutil.h"
|
|
-#include "dstack.h" /* for dict_set_top */
|
|
+#include "dstack.h" /* for dict_set_top */
|
|
#include "store.h"
|
|
|
|
/*
|
|
@@ -69,23 +69,23 @@ ztype(i_ctx_t *i_ctx_p)
|
|
int code = array_get(imemory, op, (long)r_btype(op - 1), &tnref);
|
|
|
|
if (code < 0)
|
|
- return code;
|
|
+ return code;
|
|
if (!r_has_type(&tnref, t_name)) {
|
|
- /* Must be either a stack underflow or a t_[a]struct. */
|
|
- check_op(2);
|
|
- { /* Get the type name from the structure. */
|
|
- const char *sname =
|
|
- gs_struct_type_name_string(gs_object_type(imemory,
|
|
- op[-1].value.pstruct));
|
|
- int code = name_ref(imemory, (const byte *)sname, strlen(sname),
|
|
- (ref *) (op - 1), 0);
|
|
-
|
|
- if (code < 0)
|
|
- return code;
|
|
- }
|
|
- r_set_attrs(op - 1, a_executable);
|
|
+ /* Must be either a stack underflow or a t_[a]struct. */
|
|
+ check_op(2);
|
|
+ { /* Get the type name from the structure. */
|
|
+ const char *sname =
|
|
+ gs_struct_type_name_string(gs_object_type(imemory,
|
|
+ op[-1].value.pstruct));
|
|
+ int code = name_ref(imemory, (const byte *)sname, strlen(sname),
|
|
+ (ref *) (op - 1), 0);
|
|
+
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ }
|
|
+ r_set_attrs(op - 1, a_executable);
|
|
} else {
|
|
- ref_assign(op - 1, &tnref);
|
|
+ ref_assign(op - 1, &tnref);
|
|
}
|
|
pop(1);
|
|
return 0;
|
|
@@ -101,17 +101,17 @@ ztypenames(i_ctx_t *i_ctx_p)
|
|
|
|
check_ostack(t_next_index);
|
|
for (i = 0; i < t_next_index; i++) {
|
|
- ref *const rtnp = op + 1 + i;
|
|
+ ref *const rtnp = op + 1 + i;
|
|
|
|
- if (i >= countof(tnames) || tnames[i] == 0)
|
|
- make_null(rtnp);
|
|
- else {
|
|
- int code = name_enter_string(imemory, tnames[i], rtnp);
|
|
-
|
|
- if (code < 0)
|
|
- return code;
|
|
- r_set_attrs(rtnp, a_executable);
|
|
- }
|
|
+ if (i >= countof(tnames) || tnames[i] == 0)
|
|
+ make_null(rtnp);
|
|
+ else {
|
|
+ int code = name_enter_string(imemory, tnames[i], rtnp);
|
|
+
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ r_set_attrs(rtnp, a_executable);
|
|
+ }
|
|
}
|
|
osp += t_next_index;
|
|
return 0;
|
|
@@ -144,10 +144,10 @@ zcvx(i_ctx_t *i_ctx_p)
|
|
* exist in executable form anywhere outside the e-stack.
|
|
*/
|
|
if (r_has_type(op, t_operator) &&
|
|
- ((opidx = op_index(op)) == 0 ||
|
|
- op_def_is_internal(op_index_def(opidx)))
|
|
- )
|
|
- return_error(e_rangecheck);
|
|
+ ((opidx = op_index(op)) == 0 ||
|
|
+ op_def_is_internal(op_index_def(opidx)))
|
|
+ )
|
|
+ return_error(e_rangecheck);
|
|
aop = ACCESS_REF(op);
|
|
r_set_attrs(aop, a_executable);
|
|
return 0;
|
|
@@ -172,7 +172,7 @@ zexecuteonly(i_ctx_t *i_ctx_p)
|
|
|
|
check_op(1);
|
|
if (r_has_type(op, t_dictionary))
|
|
- return_error(e_typecheck);
|
|
+ return_error(e_typecheck);
|
|
return access_check(i_ctx_p, a_execute, true);
|
|
}
|
|
|
|
@@ -184,20 +184,20 @@ znoaccess(i_ctx_t *i_ctx_p)
|
|
|
|
check_op(1);
|
|
if (r_has_type(op, t_dictionary)) {
|
|
- ref *aop = dict_access_ref(op);
|
|
-
|
|
- /* CPSI throws invalidaccess when seting noaccess to a readonly dictionary (CET 13-13-6) : */
|
|
- if (!r_has_attrs(aop, a_write)) {
|
|
- if (!r_has_attrs(aop, a_read) && !r_has_attrs(aop, a_execute)) {
|
|
- /* Already noaccess - do nothing (CET 24-09-1). */
|
|
- return 0;
|
|
- }
|
|
- return_error(e_invalidaccess);
|
|
- }
|
|
-
|
|
- /* Don't allow removing read access to permanent dictionaries. */
|
|
- if (dict_is_permanent_on_dstack(op))
|
|
- return_error(e_invalidaccess);
|
|
+ ref *aop = dict_access_ref(op);
|
|
+
|
|
+ /* CPSI throws invalidaccess when seting noaccess to a readonly dictionary (CET 13-13-6) : */
|
|
+ if (!r_has_attrs(aop, a_write)) {
|
|
+ if (!r_has_attrs(aop, a_read) && !r_has_attrs(aop, a_execute)) {
|
|
+ /* Already noaccess - do nothing (CET 24-09-1). */
|
|
+ return 0;
|
|
+ }
|
|
+ return_error(e_invalidaccess);
|
|
+ }
|
|
+
|
|
+ /* Don't allow removing read access to permanent dictionaries. */
|
|
+ if (dict_is_permanent_on_dstack(op))
|
|
+ return_error(e_invalidaccess);
|
|
}
|
|
return access_check(i_ctx_p, 0, true);
|
|
}
|
|
@@ -217,7 +217,7 @@ zrcheck(i_ctx_t *i_ctx_p)
|
|
int code = access_check(i_ctx_p, a_read, false);
|
|
|
|
if (code >= 0)
|
|
- make_bool(op, code), code = 0;
|
|
+ make_bool(op, code), code = 0;
|
|
return code;
|
|
}
|
|
|
|
@@ -229,7 +229,7 @@ zwcheck(i_ctx_t *i_ctx_p)
|
|
int code = access_check(i_ctx_p, a_write, false);
|
|
|
|
if (code >= 0)
|
|
- make_bool(op, code), code = 0;
|
|
+ make_bool(op, code), code = 0;
|
|
return code;
|
|
}
|
|
|
|
@@ -242,39 +242,39 @@ zcvi(i_ctx_t *i_ctx_p)
|
|
float fval;
|
|
|
|
switch (r_type(op)) {
|
|
- case t_integer:
|
|
- return 0;
|
|
- case t_real:
|
|
- fval = op->value.realval;
|
|
- break;
|
|
- default:
|
|
- return_op_typecheck(op);
|
|
- case t_string:
|
|
- {
|
|
- ref str, token;
|
|
- int code;
|
|
-
|
|
- ref_assign(&str, op);
|
|
- code = scan_string_token(i_ctx_p, &str, &token);
|
|
- if (code > 0) /* anything other than a plain token */
|
|
- code = gs_note_error(e_syntaxerror);
|
|
- if (code < 0)
|
|
- return code;
|
|
- switch (r_type(&token)) {
|
|
- case t_integer:
|
|
- *op = token;
|
|
- return 0;
|
|
- case t_real:
|
|
- fval = token.value.realval;
|
|
- break;
|
|
- default:
|
|
- return_error(e_typecheck);
|
|
- }
|
|
- }
|
|
+ case t_integer:
|
|
+ return 0;
|
|
+ case t_real:
|
|
+ fval = op->value.realval;
|
|
+ break;
|
|
+ default:
|
|
+ return_op_typecheck(op);
|
|
+ case t_string:
|
|
+ {
|
|
+ ref str, token;
|
|
+ int code;
|
|
+
|
|
+ ref_assign(&str, op);
|
|
+ code = gs_scan_string_token(i_ctx_p, &str, &token);
|
|
+ if (code > 0) /* anything other than a plain token */
|
|
+ code = gs_note_error(e_syntaxerror);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ switch (r_type(&token)) {
|
|
+ case t_integer:
|
|
+ *op = token;
|
|
+ return 0;
|
|
+ case t_real:
|
|
+ fval = token.value.realval;
|
|
+ break;
|
|
+ default:
|
|
+ return_error(e_typecheck);
|
|
+ }
|
|
+ }
|
|
}
|
|
if (!REAL_CAN_BE_INT(fval))
|
|
- return_error(e_rangecheck);
|
|
- make_int(op, (long)fval); /* truncates towards 0 */
|
|
+ return_error(e_rangecheck);
|
|
+ make_int(op, (long)fval); /* truncates towards 0 */
|
|
return 0;
|
|
}
|
|
|
|
@@ -296,34 +296,34 @@ zcvr(i_ctx_t *i_ctx_p)
|
|
os_ptr op = osp;
|
|
|
|
switch (r_type(op)) {
|
|
- case t_integer:
|
|
- make_real(op, (float)op->value.intval);
|
|
- case t_real:
|
|
- return 0;
|
|
- default:
|
|
- return_op_typecheck(op);
|
|
- case t_string:
|
|
- {
|
|
- ref str, token;
|
|
- int code;
|
|
-
|
|
- ref_assign(&str, op);
|
|
- code = scan_string_token(i_ctx_p, &str, &token);
|
|
- if (code > 0) /* anything other than a plain token */
|
|
- code = gs_note_error(e_syntaxerror);
|
|
- if (code < 0)
|
|
- return code;
|
|
- switch (r_type(&token)) {
|
|
- case t_integer:
|
|
- make_real(op, (float)token.value.intval);
|
|
- return 0;
|
|
- case t_real:
|
|
- *op = token;
|
|
- return 0;
|
|
- default:
|
|
- return_error(e_typecheck);
|
|
- }
|
|
- }
|
|
+ case t_integer:
|
|
+ make_real(op, (float)op->value.intval);
|
|
+ case t_real:
|
|
+ return 0;
|
|
+ default:
|
|
+ return_op_typecheck(op);
|
|
+ case t_string:
|
|
+ {
|
|
+ ref str, token;
|
|
+ int code;
|
|
+
|
|
+ ref_assign(&str, op);
|
|
+ code = gs_scan_string_token(i_ctx_p, &str, &token);
|
|
+ if (code > 0) /* anything other than a plain token */
|
|
+ code = gs_note_error(e_syntaxerror);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ switch (r_type(&token)) {
|
|
+ case t_integer:
|
|
+ make_real(op, (float)token.value.intval);
|
|
+ return 0;
|
|
+ case t_real:
|
|
+ *op = token;
|
|
+ return 0;
|
|
+ default:
|
|
+ return_error(e_typecheck);
|
|
+ }
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -336,60 +336,60 @@ zcvrs(i_ctx_t *i_ctx_p)
|
|
|
|
check_type(op[-1], t_integer);
|
|
if (op[-1].value.intval < 2 || op[-1].value.intval > 36)
|
|
- return_error(e_rangecheck);
|
|
+ return_error(e_rangecheck);
|
|
radix = op[-1].value.intval;
|
|
check_write_type(*op, t_string);
|
|
if (radix == 10) {
|
|
- switch (r_type(op - 2)) {
|
|
- case t_integer:
|
|
- case t_real:
|
|
- {
|
|
- int code = convert_to_string(imemory, op - 2, op);
|
|
-
|
|
- if (code < 0)
|
|
- return code;
|
|
- pop(2);
|
|
- return 0;
|
|
- }
|
|
+ switch (r_type(op - 2)) {
|
|
+ case t_integer:
|
|
+ case t_real:
|
|
+ {
|
|
+ int code = convert_to_string(imemory, op - 2, op);
|
|
+
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ pop(2);
|
|
+ return 0;
|
|
+ }
|
|
case t__invalid:
|
|
return_error(e_stackunderflow);
|
|
- default:
|
|
- return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
|
|
- }
|
|
+ default:
|
|
+ return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
|
|
+ }
|
|
} else {
|
|
- uint ival;
|
|
- byte digits[sizeof(ulong) * 8];
|
|
- byte *endp = &digits[countof(digits)];
|
|
- byte *dp = endp;
|
|
-
|
|
- switch (r_type(op - 2)) {
|
|
- case t_integer:
|
|
- ival = (uint) op[-2].value.intval;
|
|
- break;
|
|
- case t_real:
|
|
- {
|
|
- float fval = op[-2].value.realval;
|
|
-
|
|
- if (!REAL_CAN_BE_INT(fval))
|
|
- return_error(e_rangecheck);
|
|
- ival = (ulong) (long)fval;
|
|
- } break;
|
|
+ uint ival;
|
|
+ byte digits[sizeof(ulong) * 8];
|
|
+ byte *endp = &digits[countof(digits)];
|
|
+ byte *dp = endp;
|
|
+
|
|
+ switch (r_type(op - 2)) {
|
|
+ case t_integer:
|
|
+ ival = (uint) op[-2].value.intval;
|
|
+ break;
|
|
+ case t_real:
|
|
+ {
|
|
+ float fval = op[-2].value.realval;
|
|
+
|
|
+ if (!REAL_CAN_BE_INT(fval))
|
|
+ return_error(e_rangecheck);
|
|
+ ival = (ulong) (long)fval;
|
|
+ } break;
|
|
case t__invalid:
|
|
return_error(e_stackunderflow);
|
|
- default:
|
|
- return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
|
|
- }
|
|
- do {
|
|
- int dit = ival % radix;
|
|
-
|
|
- *--dp = dit + (dit < 10 ? '0' : ('A' - 10));
|
|
- ival /= radix;
|
|
- }
|
|
- while (ival);
|
|
- if (endp - dp > r_size(op))
|
|
- return_error(e_rangecheck);
|
|
- memcpy(op->value.bytes, dp, (uint) (endp - dp));
|
|
- r_set_size(op, endp - dp);
|
|
+ default:
|
|
+ return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
|
|
+ }
|
|
+ do {
|
|
+ int dit = ival % radix;
|
|
+
|
|
+ *--dp = dit + (dit < 10 ? '0' : ('A' - 10));
|
|
+ ival /= radix;
|
|
+ }
|
|
+ while (ival);
|
|
+ if (endp - dp > r_size(op))
|
|
+ return_error(e_rangecheck);
|
|
+ memcpy(op->value.bytes, dp, (uint) (endp - dp));
|
|
+ r_set_size(op, endp - dp);
|
|
}
|
|
op[-2] = *op;
|
|
pop(2);
|
|
@@ -407,7 +407,7 @@ zcvs(i_ctx_t *i_ctx_p)
|
|
check_op(2);
|
|
code = convert_to_string(imemory, op - 1, op);
|
|
if (code >= 0)
|
|
- pop(1);
|
|
+ pop(1);
|
|
return code;
|
|
}
|
|
|
|
@@ -443,43 +443,43 @@ const op_def ztype_op_defs[] =
|
|
/* or if the object did not have the access already when modify=1. */
|
|
static int
|
|
access_check(i_ctx_t *i_ctx_p,
|
|
- int access, /* mask for attrs */
|
|
- bool modify) /* if true, reduce access */
|
|
+ int access, /* mask for attrs */
|
|
+ bool modify) /* if true, reduce access */
|
|
{
|
|
os_ptr op = osp;
|
|
ref *aop;
|
|
|
|
switch (r_type(op)) {
|
|
- case t_dictionary:
|
|
- aop = dict_access_ref(op);
|
|
- if (modify) {
|
|
- if (!r_has_attrs(aop, access))
|
|
- return_error(e_invalidaccess);
|
|
- ref_save(op, aop, "access_check(modify)");
|
|
- r_clear_attrs(aop, a_all);
|
|
- r_set_attrs(aop, access);
|
|
- dict_set_top();
|
|
- return 0;
|
|
- }
|
|
- break;
|
|
- case t_array:
|
|
- case t_file:
|
|
- case t_string:
|
|
- case t_mixedarray:
|
|
- case t_shortarray:
|
|
- case t_astruct:
|
|
- case t_device:;
|
|
- if (modify) {
|
|
- if (!r_has_attrs(op, access))
|
|
- return_error(e_invalidaccess);
|
|
- r_clear_attrs(op, a_all);
|
|
- r_set_attrs(op, access);
|
|
- return 0;
|
|
- }
|
|
- aop = op;
|
|
- break;
|
|
- default:
|
|
- return_op_typecheck(op);
|
|
+ case t_dictionary:
|
|
+ aop = dict_access_ref(op);
|
|
+ if (modify) {
|
|
+ if (!r_has_attrs(aop, access))
|
|
+ return_error(e_invalidaccess);
|
|
+ ref_save(op, aop, "access_check(modify)");
|
|
+ r_clear_attrs(aop, a_all);
|
|
+ r_set_attrs(aop, access);
|
|
+ dict_set_top();
|
|
+ return 0;
|
|
+ }
|
|
+ break;
|
|
+ case t_array:
|
|
+ case t_file:
|
|
+ case t_string:
|
|
+ case t_mixedarray:
|
|
+ case t_shortarray:
|
|
+ case t_astruct:
|
|
+ case t_device:;
|
|
+ if (modify) {
|
|
+ if (!r_has_attrs(op, access))
|
|
+ return_error(e_invalidaccess);
|
|
+ r_clear_attrs(op, a_all);
|
|
+ r_set_attrs(op, access);
|
|
+ return 0;
|
|
+ }
|
|
+ aop = op;
|
|
+ break;
|
|
+ default:
|
|
+ return_op_typecheck(op);
|
|
}
|
|
return (r_has_attrs(aop, access) ? 1 : 0);
|
|
}
|
|
@@ -495,29 +495,29 @@ convert_to_string(const gs_memory_t *mem
|
|
int code = obj_cvs(mem, op1, op->value.bytes, r_size(op), &len, &pstr);
|
|
|
|
if (code < 0) {
|
|
- /*
|
|
- * Some common downloaded error handlers assume that
|
|
- * operator names don't exceed a certain fixed size.
|
|
- * To work around this bit of bad design, we implement
|
|
- * a special hack here: if we got a rangecheck, and
|
|
- * the object is an operator whose name begins with
|
|
- * %, ., or @, we just truncate the name.
|
|
- */
|
|
- if (code == e_rangecheck)
|
|
- switch (r_btype(op1)) {
|
|
- case t_oparray:
|
|
- case t_operator:
|
|
- if (pstr != 0)
|
|
- switch (*pstr) {
|
|
- case '%':
|
|
- case '.':
|
|
- case '@':
|
|
- len = r_size(op);
|
|
- memcpy(op->value.bytes, pstr, len);
|
|
- goto ok;
|
|
- }
|
|
- }
|
|
- return code;
|
|
+ /*
|
|
+ * Some common downloaded error handlers assume that
|
|
+ * operator names don't exceed a certain fixed size.
|
|
+ * To work around this bit of bad design, we implement
|
|
+ * a special hack here: if we got a rangecheck, and
|
|
+ * the object is an operator whose name begins with
|
|
+ * %, ., or @, we just truncate the name.
|
|
+ */
|
|
+ if (code == e_rangecheck)
|
|
+ switch (r_btype(op1)) {
|
|
+ case t_oparray:
|
|
+ case t_operator:
|
|
+ if (pstr != 0)
|
|
+ switch (*pstr) {
|
|
+ case '%':
|
|
+ case '.':
|
|
+ case '@':
|
|
+ len = r_size(op);
|
|
+ memcpy(op->value.bytes, pstr, len);
|
|
+ goto ok;
|
|
+ }
|
|
+ }
|
|
+ return code;
|
|
}
|
|
ok:
|
|
*op1 = *op;
|