/* - 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); }
/* 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; }