コード例 #1
0
/* - 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);
}
コード例 #2
0
/* <key> where false */
int
zwhere(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref_stack_enum_t rsenum;

    check_op(1);
    ref_stack_enum_begin(&rsenum, &d_stack);
    do {
	const ref *const bot = rsenum.ptr;
	const ref *pdref = bot + rsenum.size;
	ref *pvalue;
	int code;

	while (pdref-- > bot) {
	    check_dict_read(*pdref);
	    code = dict_find(pdref, op, &pvalue);
	    if (code < 0 && code != e_dictfull)
		return code;
	    if (code > 0) {
		push(1);
		ref_assign(op - 1, pdref);
		make_true(op);
		return 0;
	    }
	}
    } while (ref_stack_enum_next(&rsenum));
    make_false(op);
    return 0;
}
コード例 #3
0
/* Get the current file from which the interpreter is reading. */
static ref *
zget_current_file(i_ctx_t *i_ctx_p)
{
    ref_stack_enum_t rsenum;

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

        for (; count; count--, ep--)
            if (r_has_type_attrs(ep, t_file, a_executable))
                return ep;
    } while (ref_stack_enum_next(&rsenum));
    return 0;
}
コード例 #4
0
ファイル: zchar.c プロジェクト: ststeiger/ghostsvg
/* 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 */
}
コード例 #5
0
/*
 * If the new save level is zero, fix up the contents of a stack
 * by clearing the l_new bit in all the entries (since we can't tolerate
 * values with l_new set if the save level is zero).
 * Also, in any case, fix up the e-stack by replacing empty executable
 * strings and closed executable files that are newer than the save
 * with canonical ones that aren't.
 *
 * Note that this procedure is only called if restore_check_stack succeeded.
 */
static void
restore_fix_stack(ref_stack_t * pstack, const alloc_save_t * asave,
                  bool is_estack)
{
    ref_stack_enum_t rsenum;

    ref_stack_enum_begin(&rsenum, pstack);
    do {
        ref *stkp = rsenum.ptr;
        uint size = rsenum.size;

        for (; size; stkp++, size--) {
            r_clear_attrs(stkp, l_new);		/* always do it, no harm */
            if (is_estack) {
                ref ofile;

                ref_assign(&ofile, stkp);
                switch (r_type(stkp)) {
                case t_string:
                    if (r_size(stkp) == 0 &&
                            alloc_is_since_save(stkp->value.bytes,
                                                asave)
                       ) {
                        make_empty_const_string(stkp,
                                                avm_foreign);
                        break;
                    }
                    continue;
                case t_file:
                    if (alloc_is_since_save(stkp->value.pfile,
                                            asave)
                       ) {
                        make_invalid_file(stkp);
                        break;
                    }
                    continue;
                default:
                    continue;
                }
                r_copy_attrs(stkp, a_all | a_executable,
                             &ofile);
            }
        }
    } while (ref_stack_enum_next(&rsenum));
}
コード例 #6
0
/*
 * 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;
}
コード例 #7
0
/* Check a stack to make sure all its elements are older than a save. */
static int
restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t * pstack,
                    const alloc_save_t * asave, bool is_estack)
{
    ref_stack_enum_t rsenum;

    ref_stack_enum_begin(&rsenum, pstack);
    do {
        const ref *stkp = rsenum.ptr;
        uint size = rsenum.size;

        for (; size; stkp++, size--) {
            const void *ptr;

            switch (r_type(stkp)) {
            case t_array:
                /*
                 * Zero-length arrays are a special case: see the
                 * t_*array case (label rr:) in igc.c:gc_trace.
                 */
                if (r_size(stkp) == 0) {
                    /*stkp->value.refs = (void *)0;*/
                    continue;
                }
                ptr = stkp->value.refs;
                break;
            case t_dictionary:
                ptr = stkp->value.pdict;
                break;
            case t_file:
                /* Don't check executable or closed literal */
                /* files on the e-stack. */
            {
                stream *s;

                if (is_estack &&
                        (r_has_attr(stkp, a_executable) ||
                         file_is_invalid(s, stkp))
                   )
                    continue;
            }
            ptr = stkp->value.pfile;
            break;
            case t_name:
                /* Names are special because of how they are allocated. */
                if (alloc_name_is_since_save((const gs_memory_t *)pstack->memory,
                                             stkp, asave))
                    return_error(e_invalidrestore);
                continue;
            case t_string:
                /* Don't check empty executable strings */
                /* on the e-stack. */
                if (r_size(stkp) == 0 &&
                        r_has_attr(stkp, a_executable) && is_estack
                   )
                    continue;
                ptr = stkp->value.bytes;
                break;
            case t_mixedarray:
            case t_shortarray:
                /* See the t_array case above. */
                if (r_size(stkp) == 0) {
                    /*stkp->value.packed = (void *)0;*/
                    continue;
                }
                ptr = stkp->value.packed;
                break;
            case t_device:
                ptr = stkp->value.pdevice;
                break;
            case t_fontID:
            case t_struct:
            case t_astruct:
                ptr = stkp->value.pstruct;
                break;
            case t_save:
                /* See the comment in isave.h regarding the following. */
                if (i_ctx_p->language_level <= 2)
                    continue;
                ptr = alloc_find_save(&gs_imemory, stkp->value.saveid);
                /*
                 * Invalid save objects aren't supposed to be possible
                 * in LL3, but just in case....
                 */
                if (ptr == 0)
                    return_error(e_invalidrestore);
                if (ptr == asave)
                    continue;
                break;
            default:
                continue;
            }
            if (alloc_is_since_save(ptr, asave))
                return_error(e_invalidrestore);
        }
    } while (ref_stack_enum_next(&rsenum));
    return 0;		/* OK */
}