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 /* for qsort */ +#include /* 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 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; irun_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 x"); - 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 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 x"); + 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 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 or x"); - return e_Fatal; - case 1: /* -r */ - yres = xres; - case 2: /* -rx */ - 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 or x"); + return e_Fatal; + case 1: /* -r */ + yres = xres; + case 2: /* -rx */ + 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 ------ */ /* .filelineedit */ -/* 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 */ /* token -true- */ /* token -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;