예제 #1
0
static int
zpathforall(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_path_enum *penum;
    int code;

    check_proc(op[-3]);
    check_proc(op[-2]);
    check_proc(op[-1]);
    check_proc(*op);
    check_estack(8);
    if ((penum = gs_path_enum_alloc(imemory, "pathforall")) == 0)
	return_error(e_VMerror);
    code = gs_path_enum_init(penum, igs);
    if (code < 0) {
	ifree_object(penum, "path_cleanup");
	return code;
    }
    /* Push a mark, the four procedures, and the path enumerator. */
    push_mark_estack(es_for, path_cleanup);	/* iterator */
    memcpy(esp + 1, op - 3, 4 * sizeof(ref));	/* 4 procs */
    esp += 5;
    make_istruct(esp, 0, penum);
    push_op_estack(path_continue);
    pop(4);
    op -= 4;
    return o_push_estack;
}
예제 #2
0
/* <executable_file> .execfile - */
static int
zexecfile(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_type_access(*op, t_file, a_executable | a_read | a_execute);
    check_estack(4);		/* cleanup, file, finish, file */
    push_mark_estack(es_other, execfile_cleanup);
    *++esp = *op;
    push_op_estack(execfile_finish);
    return zexec(i_ctx_p);
}
예제 #3
0
static int
zloop(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_proc(*op);
    check_estack(4);
    /* Push a mark and the procedure, and invoke */
    /* the continuation operator. */
    push_mark_estack(es_for, no_cleanup);
    *++esp = *op;
    make_op_estack(esp + 1, loop_continue);
    pop(1);
    return loop_continue(i_ctx_p);
}
예제 #4
0
/* <obj> <result> <mask> .stopped <result> */
static int
zzstopped(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    check_type(*op, t_integer);
    check_op(3);
    /* Mark the execution stack, and push the default result */
    /* in case control returns normally. */
    check_estack(5);
    push_mark_estack(es_stopped, no_cleanup);
    *++esp = op[-1];		/* save the result */
    *++esp = *op;		/* save the signal mask */
    push_op_estack(stopped_push);
    push_op_estack(zexec);	/* execute the operand */
    pop(2);
    return o_push_estack;
}
예제 #5
0
/* the stacks would get restored in case of an error. */
static int
zstopped(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_op(1);
    /* Mark the execution stack, and push the default result */
    /* in case control returns normally. */
    check_estack(5);
    push_mark_estack(es_stopped, no_cleanup);
    ++esp;
    make_false(esp);		/* save the result */
    ++esp;
    make_int(esp, 1);		/* save the signal mask */
    push_op_estack(stopped_push);
    push_op_estack(zexec);	/* execute the operand */
    return o_push_estack;
}
예제 #6
0
int
zrepeat(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    check_proc(*op);
    check_type(op[-1], t_integer);
    if (op[-1].value.intval < 0)
        return_error(e_rangecheck);
    check_estack(5);
    /* Push a mark, the count, and the procedure, and invoke */
    /* the continuation operator. */
    push_mark_estack(es_for, no_cleanup);
    *++esp = op[-1];
    *++esp = *op;
    make_op_estack(esp + 1, repeat_continue);
    pop(2);
    return repeat_continue(i_ctx_p);
}
예제 #7
0
static int
zfilenameforall(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    file_enum *pfen;
    gx_io_device *iodev = NULL;
    gs_parsed_file_name_t pname;
    int code = 0;

    check_write_type(*op, t_string);
    check_proc(op[-1]);
    check_read_type(op[-2], t_string);
    /* Push a mark, the iodev, devicenamelen, the scratch string, the enumerator, */
    /* and the procedure, and invoke the continuation. */
    check_estack(7);
    /* Get the iodevice */
    code = parse_file_name(op - 2, &pname, i_ctx_p->LockFilePermissions);
    if (code < 0)
	return code;
    iodev = (pname.iodev == NULL) ? iodev_default : pname.iodev;

    /* Check for several conditions that just cause us to return success */
    if (pname.len == 0 || iodev->procs.enumerate_files == iodev_no_enumerate_files) {
        pop(3);
        return 0;	/* no pattern, or device not found -- just return */
    }
    pfen = iodev->procs.enumerate_files(iodev, (const char *)pname.fname,
    		pname.len, imemory);
    if (pfen == 0)
	return_error(e_VMerror);
    push_mark_estack(es_for, file_cleanup);
    ++esp;
    make_istruct(esp, 0, iodev);
    ++esp;
    make_int(esp, r_size(op-2) - pname.len);
    *++esp = *op;
    ++esp;
    make_istruct(esp, 0, pfen);
    *++esp = op[-1];
    pop(3);
    code = file_continue(i_ctx_p);
    return (code == o_pop_estack ? o_push_estack : code);
}
예제 #8
0
/*
 * Do a callout to an OtherSubr implemented in PostScript.
 * The caller must have done a check_estack(4 + num_args).
 */
static int
type1_call_OtherSubr(i_ctx_t *i_ctx_p, const gs_type1exec_state * pcxs,
                     int (*cont) (i_ctx_t *),
                     const ref * pos)
{
    /* Move the Type 1 interpreter state to the heap. */
    gs_type1exec_state *hpcxs =
        ialloc_struct(gs_type1exec_state, &st_gs_type1exec_state,
                      "type1_call_OtherSubr");

    if (hpcxs == 0)
        return_error(e_VMerror);
    *hpcxs = *pcxs;
    gs_type1_set_callback_data(&hpcxs->cis, hpcxs);
    push_mark_estack(es_show, op_type1_cleanup);
    ++esp;
    make_istruct(esp, 0, hpcxs);
    return type1_push_OtherSubr(i_ctx_p, pcxs, cont, pos);
}
예제 #9
0
static int
zimage_data_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
		  gx_image_enum_common_t * pie, const ref * sources, int npop)
{
    int num_sources = pie->num_planes;
    int inumpush = NUM_PUSH(num_sources);
    int code;
    gs_image_enum *penum;
    int px;
    const ref *pp;
    bool string_sources = true;

    check_estack(inumpush + 2);	/* stuff above, + continuation + proc */
    make_int(EBOT_NUM_SOURCES(esp), num_sources);
    /*
     * Note that the data sources may be procedures, strings, or (Level
     * 2 only) files.  (The Level 1 reference manual says that Level 1
     * requires procedures, but Adobe Level 1 interpreters also accept
     * strings.)  The sources must all be of the same type.
     *
     * The Adobe documentation explicitly says that if two or more of the
     * data sources are the same or inter-dependent files, the result is not
     * defined.  We don't have a problem with the bookkeeping for
     * inter-dependent files, since each one has its own buffer, but we do
     * have to be careful if two or more sources are actually the same file.
     * That is the reason for the aliasing information described above.
     */
    for (px = 0, pp = sources; px < num_sources; px++, pp++) {
	es_ptr ep = EBOT_SOURCE(esp, px);

	make_int(ep + 1, 1);	/* default is no aliasing */
	switch (r_type(pp)) {
	    case t_file:
		if (!level2_enabled)
		    return_error(e_typecheck);
		/* Check for aliasing. */
		{
		    int pi;

		    for (pi = 0; pi < px; ++pi)
			if (sources[pi].value.pfile == pp->value.pfile) {
			    /* Record aliasing */
			    make_int(ep + 1, -pi);
			    EBOT_SOURCE(esp, pi)[1].value.intval++;
			    break;
			}
		}
		string_sources = false;
		/* falls through */
	    case t_string:
		if (r_type(pp) != r_type(sources)) {
    		    if (pie != NULL)
		        gx_image_end(pie, false);    /* Clean up pie */
		    return_error(e_typecheck);
		}
		check_read(*pp);
		break;
	    default:
		if (!r_is_proc(sources)) {
    		    static const char ds[] = "DataSource";
                    if (pie != NULL)
                        gx_image_end(pie, false);    /* Clean up pie */
                    gs_errorinfo_put_pair(i_ctx_p, ds, sizeof(ds) - 1, pp);
		    return_error(e_typecheck);
		}
		check_proc(*pp);
		string_sources = false;
	}
	*ep = *pp;
    }
    /* Always place the image enumerator into local memory,
       because pie may have local objects inherited from igs,
       which may be local when the current allocation mode is global. 
       Bug 688140. */
    if ((penum = gs_image_enum_alloc(imemory_local, "image_setup")) == 0)
	return_error(e_VMerror);
    code = gs_image_enum_init(penum, pie, (const gs_data_image_t *)pim, igs);
    if (code != 0 || (pie->skipping && string_sources)) {		/* error, or empty image */
	int code1 = gs_image_cleanup_and_free_enum(penum, igs);

	if (code >= 0)		/* empty image */
	    pop(npop);
	if (code >= 0 && code1 < 0)
	    code = code1;
	return code;
    }
    push_mark_estack(es_other, image_cleanup);
    esp += inumpush - 1;
    make_int(ETOP_PLANE_INDEX(esp), 0);
    make_int(ETOP_NUM_SOURCES(esp), num_sources);
    make_struct(esp, avm_local, penum);
    switch (r_type(sources)) {
	case t_file:
	    push_op_estack(image_file_continue);
	    break;
	case t_string:
	    push_op_estack(image_string_continue);
	    break;
	default:		/* procedure */
	    push_op_estack(image_proc_process);
	    break;
    }
    pop(npop);
    return o_push_estack;
}