Esempio n. 1
0
File: zmisc.c Progetto: hackqiang/gs
/* <string> .pcachequery false */
static int
zpcachequery(i_ctx_t *i_ctx_p)
{
        os_ptr op = osp;
        int len;
        char *key;
        byte *string;
        int code = 0;

        check_read_type(*op, t_string);
        len = r_size(op);
        key = op->value.bytes;
        len = gp_cache_query(GP_CACHE_TYPE_TEST, key, len, (void**)&string, &pcache_alloc_callback, i_ctx_p);
        if (len < 0) {
                make_false(op);
                return 0;
        }
        if (string == NULL)
                return_error(e_VMerror);
        make_string(op, a_all | icurrent_space, len, string);

        push(1);
        make_true(op);

        return code;
}
Esempio n. 2
0
File: zmisc.c Progetto: hackqiang/gs
/* - .defaultpapersize false */
static int
zdefaultpapersize(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    byte *value;
    int len = 0;

    if (gp_defaultpapersize((char *)0, &len) > 0) {
        /* no default paper size */
        push(1);
        make_false(op);
        return 0;
    }

    value = ialloc_string(len, "defaultpapersize value");
    if (value == 0) {
        return_error(e_VMerror);
    }
    DISCARD(gp_defaultpapersize((char *)value, &len));	/* can't fail */
    /* Delete the stupid C string terminator. */
    value = iresize_string(value, len, len - 1,
                           "defaultpapersize value");	/* can't fail */
    push(2);
    make_string(op - 1, a_all | icurrent_space, len - 1, value);
    make_true(op);
    return 0;
}
Esempio n. 3
0
File: zmisc.c Progetto: hackqiang/gs
/* <int> .oserrorstring false */
static int
zoserrorstring(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const char *str;
    int code;
    uint len;
    byte ch;

    check_type(*op, t_integer);
    str = gp_strerror((int)op->value.intval);
    if (str == 0 || (len = strlen(str)) == 0) {
        make_false(op);
        return 0;
    }
    check_ostack(1);
    code = string_to_ref(str, op, iimemory, ".oserrorstring");
    if (code < 0)
        return code;
    /* Strip trailing end-of-line characters. */
    while ((len = r_size(op)) != 0 &&
           ((ch = op->value.bytes[--len]) == '\r' || ch == '\n')
        )
        r_dec_size(op, 1);
    push(1);
    make_true(op);
    return 0;
}
Esempio n. 4
0
/* <file> .filename false */
static int
zfilename(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    stream *s;
    gs_const_string fname;
    byte *str;

    check_file(s, op);
    if (sfilename(s, &fname) < 0) {
	make_false(op);
	return 0;
    }
    check_ostack(1);
    str = ialloc_string(fname.size, "filename");
    if (str == 0)
	return_error(e_VMerror);
    memcpy(str, fname.data, fname.size);
    push(1);			/* can't fail */
    make_const_string( op - 1 , 
		      a_all | imemory_space((const struct gs_ref_memory_s*) imemory), 
		      fname.size, 
		      str);
    make_true(op);
    return 0;
}
Esempio n. 5
0
File: zmisc.c Progetto: hackqiang/gs
/* <string> getenv false */
static int
zgetenv(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    char *str;
    byte *value;
    int len = 0;

    check_read_type(*op, t_string);
    str = ref_to_string(op, imemory, "getenv key");
    if (str == 0)
        return_error(e_VMerror);
    if (gp_getenv(str, (char *)0, &len) > 0) {	/* key missing */
        ifree_string((byte *) str, r_size(op) + 1, "getenv key");
        make_false(op);
        return 0;
    }
    value = ialloc_string(len, "getenv value");
    if (value == 0) {
        ifree_string((byte *) str, r_size(op) + 1, "getenv key");
        return_error(e_VMerror);
    }
    DISCARD(gp_getenv(str, (char *)value, &len));	/* can't fail */
    ifree_string((byte *) str, r_size(op) + 1, "getenv key");
    /* Delete the stupid C string terminator. */
    value = iresize_string(value, len, len - 1,
                           "getenv value");	/* can't fail */
    push(1);
    make_string(op - 1, a_all | icurrent_space, len - 1, value);
    make_true(op);
    return 0;
}
Esempio n. 6
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;
}
Esempio n. 7
0
/* <string> .libfile <string> false */
int                             /* exported for zsysvm.c */
zlibfile(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;
    byte cname[DEFAULT_BUFFER_SIZE];
    uint clen;
    gs_parsed_file_name_t pname;
    stream *s;
    gx_io_device *iodev_dflt;

    check_ostack(2);
    code = parse_file_name(op, &pname, i_ctx_p->LockFilePermissions, imemory);
    if (code < 0)
        return code;
    iodev_dflt = iodev_default(imemory);
    if (pname.iodev == NULL)
        pname.iodev = iodev_dflt;
    if (pname.iodev != iodev_dflt) { /* Non-OS devices don't have search paths (yet). */
        code = zopen_file(i_ctx_p, &pname, "r", &s, imemory);
        if (code >= 0) {
            code = ssetfilename(s, op->value.const_bytes, r_size(op));
            if (code < 0) {
                sclose(s);
                return_error(e_VMerror);
            }
        }
        if (code < 0) {
            push(1);
            make_false(op);
            return 0;
        }
        make_stream_file(op, s, "r");
    } else {
        ref fref;

        code = lib_file_open(i_ctx_p->lib_path, imemory, i_ctx_p, pname.fname, pname.len,
                             (char *)cname, sizeof(cname), &clen, &fref);
        if (code >= 0) {
            s = fptr(&fref);
            code = ssetfilename(s, cname, clen);
            if (code < 0) {
                sclose(s);
                return_error(e_VMerror);
            }
        }
        if (code < 0) {
            if (code == e_VMerror || code == e_invalidfileaccess)
                return code;
            push(1);
            make_false(op);
            return 0;
        }
        ref_assign(op, &fref);
    }
    push(1);
    make_true(op);
    return 0;
}
Esempio n. 8
0
int
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);
            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;
        }
    }
}
Esempio n. 9
0
/* - .currentpagedevice <dict> <bool> */
static int
zcurrentpagedevice(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gx_device *dev = gs_currentdevice(igs);

    push(2);
    if ((*dev_proc(dev, get_page_device))(dev) != 0) {
        op[-1] = istate->pagedevice;
        make_true(op);
    } else {
        make_null(op - 1);
        make_false(op);
    }
    return 0;
}
Esempio n. 10
0
/* - .currentshowpagecount false */
static int
zcurrentshowpagecount(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gx_device *dev = gs_currentdevice(igs);

    if ((*dev_proc(dev, get_page_device))(dev) == 0) {
        push(1);
        make_false(op);
    } else {
        push(2);
        make_int(op - 1, dev->ShowpageCount);
        make_true(op);
    }
    return 0;
}
Esempio n. 11
0
/* <mask> .instopped <result> true */
static int
zinstopped(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count;

    check_type(*op, t_integer);
    count = count_to_stopped(i_ctx_p, op->value.intval);
    if (count) {
        push(1);
        op[-1] = *ref_stack_index(&e_stack, count - 2);		/* default result */
        make_true(op);
    } else
        make_false(op);
    return 0;
}
Esempio n. 12
0
/* Common code for token reading. */
static int
token_continue(i_ctx_t *i_ctx_p, scanner_state * pstate, bool save)
{
    os_ptr op = osp;
    int code;
    ref token;

    /* Note that gs_scan_token may change osp! */
    pop(1);                     /* remove the file or scanner state */
again:
    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);
            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");
    }
    return code;
}
Esempio n. 13
0
/* <dict> <key> .knownget false */
static int
zknownget(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    register os_ptr op1 = op - 1;
    ref *pvalue;

    check_type(*op1, t_dictionary);
    check_dict_read(*op1);
    if (dict_find(op1, op, &pvalue) <= 0) {
	make_false(op1);
	pop(1);
    } else {
	ref_assign(op1, pvalue);
	make_true(op);
    }
    return 0;
}
Esempio n. 14
0
/* [<req_x> <req_y>] [<med_x0> <med_y0> (<med_x1> <med_y1> | )]
 *     <policy> <orient|null> <roll> <matrix|null> .matchpagesize
 *   <matrix|null> <med_x> <med_y> true   -or-  false
 */
static int
zmatchpagesize(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_matrix mat;
    float ignore_mismatch = (float)max_long;
    gs_point media_size;
    int orient;
    bool roll;
    int code;

    check_type(op[-3], t_integer);
    if (r_has_type(op - 2, t_null))
	orient = -1;
    else {
	check_int_leu(op[-2], 3);
	orient = (int)op[-2].value.intval;
    }
    check_type(op[-1], t_boolean);
    roll = op[-1].value.boolval;
    code = zmatch_page_size(imemory, 
			    op - 5, op - 4, (int)op[-3].value.intval,
			    orient, roll,
			    &ignore_mismatch, &mat, &media_size);
    switch (code) {
	default:
	    return code;
	case 0:
	    make_false(op - 5);
	    pop(5);
	    break;
	case 1:
	    code = write_matrix(op, &mat);
	    if (code < 0 && !r_has_type(op, t_null))
		return code;
	    op[-5] = *op;
	    make_real(op - 4, media_size.x);
	    make_real(op - 3, media_size.y);
	    make_true(op - 2);
	    pop(2);
	    break;
    }
    return 0;
}
Esempio n. 15
0
/* convenience of reusing procedures that take 1 state parameter */
static int
zreadhexstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start, int odd)
{
    stream *s;
    uint len, nread;
    byte *str;
    int odd_byte = odd;
    stream_cursor_write cw;
    int status;

    check_read_file(s, op - 1);
    /*check_write_type(*op, t_string); *//* done by caller */
    str = op->value.bytes;
    len = r_size(op);
    cw.ptr = str + start - 1;
    cw.limit = str + len - 1;
    for (;;) {
	status = s_hex_process(&s->cursor.r, &cw, &odd_byte,
			       hex_ignore_garbage);
	if (status == 1) {	/* filled the string */
	    ref_assign_inline(op - 1, op);
	    make_true(op);
	    return 0;
	} else if (status != 0)	/* error or EOF */
	    break;
	/* Didn't fill, keep going. */
	status = spgetc(s);
	if (status < 0)
	    break;
	sputback(s);
    }
    nread = cw.ptr + 1 - str;
    if (status != EOFC) {	/* Error */
	nread |= odd_byte << 24;
        return handle_read_status(i_ctx_p, status, op - 1, &nread,
				  zreadhexstring_continue);
    }
    /* Reached end-of-file before filling the string. */
    /* Return an appropriate substring. */
    ref_assign_inline(op - 1, op);
    r_set_size(op - 1, nread);
    make_false(op);
    return 0;
}
Esempio n. 16
0
/* <string> <pattern> search <string> -false- */
static int
zsearch(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    uint size = r_size(op);
    uint count;
    byte *pat;
    byte *ptr;
    byte ch;

    check_read_type(*op1, t_string);
    check_read_type(*op, t_string);
    if (size > r_size(op1)) {	/* can't match */
        make_false(op);
        return 0;
    }
    count = r_size(op1) - size;
    ptr = op1->value.bytes;
    if (size == 0)
        goto found;
    pat = op->value.bytes;
    ch = pat[0];
    do {
        if (*ptr == ch && (size == 1 || !memcmp(ptr, pat, size)))
            goto found;
        ptr++;
    }
    while (count--);
    /* No match */
    make_false(op);
    return 0;
found:
    op->tas.type_attrs = op1->tas.type_attrs;
    op->value.bytes = ptr;
    r_set_size(op, size);
    push(2);
    op[-1] = *op1;
    r_set_size(op - 1, ptr - op[-1].value.bytes);
    op1->value.bytes = ptr + size;
    r_set_size(op1, count);
    make_true(op);
    return 0;
}
Esempio n. 17
0
/* <dict> .fontbbox -false- */
static int
zfontbbox(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double bbox[4];
    int code;

    check_type(*op, t_dictionary);
    check_dict_read(*op);
    code = font_bbox_param(imemory, op, bbox);
    if (code < 0)
	return code;
    if (bbox[0] < bbox[2] && bbox[1] < bbox[3]) {
	push(4);
	make_reals(op - 4, bbox, 4);
	make_true(op);
    } else {			/* No bbox, or an empty one. */
	make_false(op);
    }
    return 0;
}
Esempio n. 18
0
/* <string> <pattern> anchorsearch <string> -false- */
static int
zanchorsearch(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    uint size = r_size(op);

    check_read_type(*op, t_string);
    check_read_type(*op1, t_string);
    if (size <= r_size(op1) && !memcmp(op1->value.bytes, op->value.bytes, size)) {
        os_ptr op0 = op;

        push(1);
        *op0 = *op1;
        r_set_size(op0, size);
        op1->value.bytes += size;
        r_dec_size(op1, size);
        make_true(op);
    } else
        make_false(op);
    return 0;
}
Esempio n. 19
0
/* the stacks would get restored in case of an error. */
static int
zstop(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count = count_to_stopped(i_ctx_p, 1L);

    if (count) {
        /*
         * If there are any t_oparrays on the e-stack, they will pop
         * any new items from the o-stack.  Wait to push the 'true'
         * until we have run all the unwind procedures.
         */
        check_ostack(2);
        pop_estack(i_ctx_p, count);
        op = osp;
        push(1);
        make_true(op);
        return o_pop_estack;
    }
    /* No mark, quit.  (per Adobe documentation) */
    push(2);
    return unmatched_exit(op, zstop);
}
Esempio n. 20
0
static int
zeqproc(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref2_t stack[MAX_DEPTH + 1];
    ref2_t *top = stack;

    make_array(&stack[0].proc1, 0, 1, op - 1);
    make_array(&stack[0].proc2, 0, 1, op);
    for (;;) {
	long i;

	if (r_size(&top->proc1) == 0) {
	    /* Finished these arrays, go up to next level. */
	    if (top == stack) {
		/* We're done matching: it succeeded. */
		make_true(op - 1);
		pop(1);
		return 0;
	    }
	    --top;
	    continue;
	}
	/* Look at the next elements of the arrays. */
	i = r_size(&top->proc1) - 1;
	array_get(imemory, &top->proc1, i, &top[1].proc1);
	array_get(imemory, &top->proc2, i, &top[1].proc2);
	r_dec_size(&top->proc1, 1);
	++top;
	/*
	 * Amazingly enough, the objects' executable attributes are not
	 * required to match.  This means { x load } will match { /x load },
	 * even though this is clearly wrong.
	 */
#if 0
	if (r_has_attr(&top->proc1, a_executable) !=
	    r_has_attr(&top->proc2, a_executable)
	    )
	    break;
#endif
	if (obj_eq(imemory, &top->proc1, &top->proc2)) {
	    /* Names don't match strings. */
	    if (r_type(&top->proc1) != r_type(&top->proc2) &&
		(r_type(&top->proc1) == t_name ||
		 r_type(&top->proc2) == t_name)
		)
		break;
	    --top;		/* no recursion */
	    continue;
	}
	if (r_is_array(&top->proc1) && r_is_array(&top->proc2) &&
	    r_size(&top->proc1) == r_size(&top->proc2) &&
	    top < stack + (MAX_DEPTH - 1)
	    ) {
	    /* Descend into the arrays. */
	    continue;
	}
	break;
    }
    /* An exit from the loop indicates that matching failed. */
    make_false(op - 1);
    pop(1);
    return 0;
}
Esempio n. 21
0
static int
zmatchmedia(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr preq = op - 3;
    os_ptr pattr = op - 2;
    os_ptr ppol = op - 1;
    os_ptr pkeys = op;		/* *const */
    int policy_default;
    float best_mismatch = (float)max_long;	/* adhoc */
    float mepos_penalty;
    float mbest = best_mismatch;
    match_record_t match;
    ref no_priority;
    ref *ppriority;
    int mepos, orient;
    bool roll;
    int code;
    int ai;
    struct mkd_ {
	ref key, dict;
    } aelt;
    if (r_has_type(pattr, t_null)) {
	check_op(4);
	make_null(op - 3);
	make_true(op - 2);
	pop(2);
	return 0;
    }
    check_type(*preq, t_dictionary);
    check_dict_read(*preq);
    check_type(*pattr, t_dictionary);
    check_dict_read(*pattr);
    check_type(*ppol, t_dictionary);
    check_dict_read(*ppol);
    check_array(*pkeys);
    check_read(*pkeys);
    switch (code = dict_int_null_param(preq, "MediaPosition", 0, 0x7fff,
				       0, &mepos)) {
	default:
	    return code;
	case 2:
	case 1:
	    mepos = -1;
	case 0:;
    }
    switch (code = dict_int_null_param(preq, "Orientation", 0, 3,
				       0, &orient)) {
	default:
	    return code;
	case 2:
	case 1:
	    orient = -1;
	case 0:;
    }
    code = dict_bool_param(preq, "RollFedMedia", false, &roll);
    if (code < 0)
	return code;
    code = dict_int_param(ppol, "PolicyNotFound", 0, 7, 0,
			  &policy_default);
    if (code < 0)
	return code;
    if (dict_find_string(pattr, "Priority", &ppriority) > 0) {
	check_array_only(*ppriority);
	check_read(*ppriority);
    } else {
	make_empty_array(&no_priority, a_readonly);
	ppriority = &no_priority;
    }
    match.no_match_priority = r_size(ppriority);
    reset_match(&match);
    for (ai = dict_first(pattr);
	 (ai = dict_next(pattr, ai, (ref * /*[2]*/)&aelt)) >= 0;
	 ) {
	if (r_has_type(&aelt.dict, t_dictionary) &&
	    r_has_attr(dict_access_ref(&aelt.dict), a_read) &&
	    r_has_type(&aelt.key, t_integer)
	    ) {
	    bool match_all;
	    uint ki, pi;

	    code = dict_bool_param(&aelt.dict, "MatchAll", false,
				   &match_all);
	    if (code < 0)
		return code;
	    for (ki = 0; ki < r_size(pkeys); ki++) {
		ref key;
		ref kstr;
		ref *prvalue;
		ref *pmvalue;
		ref *ppvalue;
		int policy;

		array_get(imemory, pkeys, ki, &key);
		if (dict_find(&aelt.dict, &key, &pmvalue) <= 0)
		    continue;
		if (dict_find(preq, &key, &prvalue) <= 0 ||
		    r_has_type(prvalue, t_null)
		    ) {
		    if (match_all)
			goto no;
		    else
			continue;
		}
		/* Look for the Policies entry for this key. */
		if (dict_find(ppol, &key, &ppvalue) > 0) {
		    check_type_only(*ppvalue, t_integer);
		    policy = ppvalue->value.intval;
		} else
		    policy = policy_default;
	/*
	 * Match a requested attribute value with the attribute value in the
	 * description of a medium.  For all attributes except PageSize,
	 * matching means equality.  PageSize is special; see match_page_size
	 * below.
	 */
		if (r_has_type(&key, t_name) &&
		    (name_string_ref(imemory, &key, &kstr),
		     r_size(&kstr) == 8 &&
		     !memcmp(kstr.value.bytes, "PageSize", 8))
		    ) {
		    gs_matrix ignore_mat;
		    gs_point ignore_msize;

		    if (zmatch_page_size(imemory, prvalue, pmvalue,
					 policy, orient, roll,
					 &best_mismatch,
					 &ignore_mat,
					 &ignore_msize)
			<= 0)
			goto no;
		} else if (!obj_eq(imemory, prvalue, pmvalue))
		    goto no;
	    }

	    mepos_penalty = (mepos < 0 || aelt.key.value.intval == mepos) ?
		0 : .001;

	    /* We have a match. Save the match in case no better match is found */
	    if (r_has_type(&match.match_key, t_null)) 
		match.match_key = aelt.key;
	    /*
	     * If it is a better match than the current best it supersedes it 
	     * regardless of priority. If the match is the same, then update 
	     * to the current only if the key value is lower.
	     */
	    if (best_mismatch + mepos_penalty <= mbest) {
		if (best_mismatch + mepos_penalty < mbest  ||
		    (r_has_type(&match.match_key, t_integer) &&
		     match.match_key.value.intval > aelt.key.value.intval)) {
		    reset_match(&match);
		    match.match_key = aelt.key;
		    mbest = best_mismatch + mepos_penalty;
		}
	    }
	    /* In case of a tie, see if the new match has priority. */
	    for (pi = match.priority; pi > 0;) {
		ref pri;

		pi--;
		array_get(imemory, ppriority, pi, &pri);
		if (obj_eq(imemory, &aelt.key, &pri)) {	/* Yes, higher priority. */
		    match.best_key = aelt.key;
		    match.priority = pi;
		    break;
		}
	    }
no:;
	}
    }
    if (r_has_type(&match.match_key, t_null)) {
	make_false(op - 3);
	pop(3);
    } else {
	if (r_has_type(&match.best_key, t_null))
	    op[-3] = match.match_key;
	else
	    op[-3] = match.best_key;
	make_true(op - 2);
	pop(2);
    }
    return 0;
}
Esempio n. 22
0
/* initialize the dictionaries that hold operator definitions. */
int
obj_init(i_ctx_t **pi_ctx_p, gs_dual_memory_t *idmem)
{
    int level = gs_op_language_level();
    ref system_dict;
    i_ctx_t *i_ctx_p;
    int code;

    /*
     * Create systemdict.  The context machinery requires that
     * we do this before initializing the interpreter.
     */
    code = dict_alloc(idmem->space_global,
		      (level >= 3 ? SYSTEMDICT_LL3_SIZE :
		       level >= 2 ? SYSTEMDICT_LEVEL2_SIZE : SYSTEMDICT_SIZE),
		      &system_dict);
    if (code < 0)
	return code;

    /* Initialize the interpreter. */
    code = gs_interp_init(pi_ctx_p, &system_dict, idmem);
    if (code < 0)
	return code;
    i_ctx_p = *pi_ctx_p;

    {
#define icount countof(initial_dictionaries)
	ref idicts[icount];
	int i;
	const op_def *const *tptr;

	min_dstack_size = MIN_DSTACK_SIZE;

	refset_null(idicts, icount);

	/* Put systemdict on the dictionary stack. */
	if (level >= 2) {
	    dsp += 2;
	    /*
	     * For the moment, let globaldict be an alias for systemdict.
	     */
	    dsp[-1] = system_dict;
	    min_dstack_size++;
	} else {
	    ++dsp;
	}
	*dsp = system_dict;

	/* Create dictionaries which are to be homes for operators. */
	for (tptr = op_defs_all; *tptr != 0; tptr++) {
	    const op_def *def;

	    for (def = *tptr; def->oname != 0; def++)
		if (op_def_is_begin_dict(def)) {
		    if (make_initial_dict(i_ctx_p, def->oname, idicts) == 0)
			return_error(e_VMerror);
		}
	}

	/* Set up the initial dstack. */
	for (i = 0; i < countof(initial_dstack); i++) {
	    const char *dname = initial_dstack[i];

	    ++dsp;
	    if (!strcmp(dname, "userdict"))
		dstack_userdict_index = dsp - dsbot;
	    ref_assign(dsp, make_initial_dict(i_ctx_p, dname, idicts));
	}

	/* Enter names of referenced initial dictionaries into systemdict. */
	initial_enter_name("systemdict", systemdict);
	for (i = 0; i < icount; i++) {
	    ref *idict = &idicts[i];

	    if (!r_has_type(idict, t_null)) {
		/*
		 * Note that we enter the dictionary in systemdict
		 * even if it is in local VM.  There is a special
		 * provision in the garbage collector for this:
		 * see ivmspace.h for more information.
		 * In order to do this, we must temporarily
		 * identify systemdict as local, so that the
		 * store check in dict_put won't fail.
		 */
		uint save_space = r_space(systemdict);

		r_set_space(systemdict, avm_local);
		code = initial_enter_name(initial_dictionaries[i].name,
					  idict);
		r_set_space(systemdict, save_space);
		if (code < 0)
		    return code;
	    }
	}
#undef icount
    }

    gs_interp_reset(i_ctx_p);

    {
	ref vnull, vtrue, vfalse;

	make_null(&vnull);
	make_true(&vtrue);
	make_false(&vfalse);
	if ((code = initial_enter_name("null", &vnull)) < 0 ||
	    (code = initial_enter_name("true", &vtrue)) < 0 ||
	    (code = initial_enter_name("false", &vfalse)) < 0
	    )
	    return code;
    }

    /* Create the error name table */
    {
	int n = countof(gs_error_names) - 1;
	int i;
	ref era;

	code = ialloc_ref_array(&era, a_readonly, n, "ErrorNames");
	if (code < 0)
	    return code;
	for (i = 0; i < n; i++)
	  if ((code = name_enter_string(imemory, (const char *)gs_error_names[i],
					  era.value.refs + i)) < 0)
		return code;
	return initial_enter_name("ErrorNames", &era);
    }
}
Esempio n. 23
0
sexp eval_object(sexp object, sexp environment) {
tail_loop:
  if (is_quote_form(object)) return quotation_text(object);
  if (is_variable_form(object))
    return get_variable_value(object, environment);
  if (is_define_form(object)) {
    /* sexp value = eval_object(definition_value(object), environment); */
    /* add_binding(definition_variable(object), value, environment); */
    /* return value; */
    return eval_object(define2set(object), environment);
  }
  if (is_assignment_form(object)) {
    sexp value = eval_object(assignment_value(object), environment);
    set_binding(assignment_variable(object), value, environment);
    return value;
  }
  if (is_if_form(object)) {
    sexp test_part = if_test_part(object);
    sexp then_part = if_then_part(object);
    sexp else_part = if_else_part(object);
    if (!is_false(eval_object(test_part, environment))) {
      object = then_part;
    } else {
      object = else_part;
    }
    goto tail_loop;
  }
  if (is_lambda_form(object)) {
    sexp parameters = lambda_parameters(object);
    sexp body = lambda_body(object);
    return make_lambda_procedure(parameters, body, environment);
  }
  if (is_begin_form(object)) {
    return eval_begin(object, environment);
  }
  if (is_cond_form(object)) {
    object = cond2if(object);
    goto tail_loop;
  }
  if (is_let_form(object)) {
    object = let2lambda(object);
    goto tail_loop;
  }
  if (is_and_form(object)) {
    sexp tests = and_tests(object);
    if (is_null(tests))
      return make_true();
    while (is_pair(pair_cdr(tests))) {
      sexp result = eval_object(pair_car(tests), environment);
      if (is_false(result))
        return make_false();
      tests = pair_cdr(tests);
    }
    return eval_object(pair_car(tests), environment);
  }
  if (is_or_form(object)) {
    sexp tests = or_tests(object);
    if (is_null(tests))
      return make_false();
    while (is_pair(pair_cdr(tests))) {
      sexp result = eval_object(pair_car(tests), environment);
      if (!is_false(result))
        return result;
      tests = pair_cdr(tests);
    }
    return eval_object(pair_car(tests), environment);
  }
  if (is_macro_form(object)) {
    sexp pars = macro_parameters(object);
    sexp body = macro_body(object);
    return make_macro_procedure(pars, body, environment);
  }
  if (is_application_form(object)) {
    sexp operator = application_operator(object);
    sexp operands = application_operands(object);
    operator = eval_object(operator, environment);
    if (!is_function(operator) && !is_macro(operator)) {
      fprintf(stderr, "Illegal functional object ");
      write_object(operator, make_file_out_port(stderr));
      fprintf(stderr, " from ");
      write_object(pair_car(object), make_file_out_port(stderr));
      fputc('\n', stderr);
      exit(1);
    }
    /* Expand the macro before evaluating arguments */
    if (is_macro(operator)) {
      sexp body = macro_proc_body(operator);
      sexp vars = macro_proc_pars(operator);
      sexp def_env = macro_proc_env(operator);
      sexp object = make_pair(S("begin"), body);
      sexp env = extend_environment(vars, operands, def_env);
      sexp exp = eval_object(object, env);
      return eval_object(exp, environment);
    }
    operands = eval_arguments(operands, environment);
    /* if (is_apply(operator)) { */
    /*   operator = pair_car(operands); */
    /*   operands = apply_operands_conc(pair_cdr(operands)); */
    /* } */
    if (is_eval(operator)) {
      environment = pair_cadr(operands);
      object = pair_car(operands);
      goto tail_loop;
    }
    return eval_application(operator, operands);
  } else return object;
}