/* - exit - */
static int
zexit(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref_stack_enum_t rsenum;
    uint scanned = 0;

    ref_stack_enum_begin(&rsenum, &e_stack);
    do {
        uint used = rsenum.size;
        es_ptr ep = rsenum.ptr + used - 1;
        uint count = used;

        for (; count; count--, ep--)
            if (r_is_estack_mark(ep))
                switch (estack_mark_index(ep)) {
                    case es_for:
                        pop_estack(i_ctx_p, scanned + (used - count + 1));
                        return o_pop_estack;
                    case es_stopped:
                        return_error(e_invalidexit);	/* not a loop */
                }
        scanned += used;
    } while (ref_stack_enum_next(&rsenum));
    /* No mark, quit.  (per Adobe documentation) */
    push(2);
    return unmatched_exit(op, zexit);
}
Beispiel #2
0
/* Return 0 if we can't find the mark. */
static uint
op_show_find_index(i_ctx_t *i_ctx_p)
{
    ref_stack_enum_t rsenum;
    uint count = 0;

    ref_stack_enum_begin(&rsenum, &e_stack);
    do {
	es_ptr ep = rsenum.ptr;
	uint size = rsenum.size;

	for (ep += size - 1; size != 0; size--, ep--, count++)
	    if (r_is_estack_mark(ep) && estack_mark_index(ep) == es_show)
		return count;
    } while (ref_stack_enum_next(&rsenum));
    return 0;		/* no mark */
}
/*
 * Count the number of elements down to and including the first 'stopped'
 * mark on the e-stack with a given mask.  Return 0 if there is no 'stopped'
 * mark.
 */
static uint
count_to_stopped(i_ctx_t *i_ctx_p, long mask)
{
    ref_stack_enum_t rsenum;
    uint scanned = 0;

    ref_stack_enum_begin(&rsenum, &e_stack);
    do {
        uint used = rsenum.size;
        es_ptr ep = rsenum.ptr + used - 1;
        uint count = used;

        for (; count; count--, ep--) {
            if (r_is_estack_mark(ep)) {
                if (estack_mark_index(ep) == es_stopped &&
                  (ep[2].value.intval & mask) != 0)
                    return scanned + (used - count + 1);
            }
        }
        scanned += used;
    } while (ref_stack_enum_next(&rsenum));
    return 0;
}