示例#1
0
/* Only the type of *op has been checked. */
int
zcopy_dict(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    int code;

    check_type(*op1, t_dictionary);
    check_dict_read(*op1);
    check_dict_write(*op);
    if (!imemory->gs_lib_ctx->dict_auto_expand &&
	(dict_length(op) != 0 || dict_maxlength(op) < dict_length(op1))
	)
	return_error(e_rangecheck);
    code = idict_copy(op1, op);
    if (code < 0)
	return code;
    /*
     * In Level 1 systems, we must copy the access attributes too.
     * The only possible effect this can have is to make the
     * copy read-only if the original dictionary is read-only.
     */
    if (!level2_enabled)
	r_copy_attrs(dict_access_ref(op), a_write, dict_access_ref(op1));
    ref_assign(op1, op);
    pop(1);
    return 0;
}
示例#2
0
int
dict_param_list_write(dict_param_list *plist, ref *pdict, const ref *pwanted,
		      gs_ref_memory_t *imem)
{
    check_dict_write(*pdict);
    plist->u.w.write = dict_param_write;
    plist->enumerate = dict_param_enumerate;
    ref_param_write_init((iparam_list *) plist, pwanted, imem);
    plist->dict = *pdict;
    return 0;
}
示例#3
0
/* <string> <index> <int> put - */
static int
zput(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    os_ptr op2 = op1 - 1;
    byte *sdata;
    uint ssize;

    switch (r_type(op2)) {
	case t_dictionary:
	    if (i_ctx_p->in_superexec == 0)
		check_dict_write(*op2);
	    {
		int code = idict_put(op2, op1, op);

		if (code < 0)
		    return code;	/* error */
	    }
	    break;
	case t_array:
	    check_write(*op2);
	    check_int_ltu(*op1, r_size(op2));
	    store_check_dest(op2, op);
	    {
		ref *eltp = op2->value.refs + (uint) op1->value.intval;

		ref_assign_old(op2, eltp, op, "put");
	    }
	    break;
	case t_mixedarray:	/* packed arrays are read-only */
	case t_shortarray:
	    return_error(e_invalidaccess);
	case t_string:
	    sdata = op2->value.bytes;
	    ssize = r_size(op2);
str:	    check_write(*op2);
	    check_int_ltu(*op1, ssize);
	    check_int_leu(*op, 0xff);
	    sdata[(uint)op1->value.intval] = (byte)op->value.intval;
	    break;
	case t_astruct:
	    if (gs_object_type(imemory, op2->value.pstruct) != &st_bytes)
		return_error(e_typecheck);
	    sdata = r_ptr(op2, byte);
	    ssize = gs_object_size(imemory, op2->value.pstruct);
	    goto str;
	default:
	    return_op_typecheck(op2);
    }
    pop(3);
    return 0;
}
示例#4
0
/*
 * We make this into a separate procedure because
 * the interpreter will almost always call it directly.
 */
int
zop_def(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    ref *pvslot;

    /* The following combines a check_op(2) with a type check. */
    switch (r_type(op1)) {
	case t_name: {
	    /* We can use the fast single-probe lookup here. */
	    uint nidx = name_index(imemory, op1);
	    uint htemp;

	    if_dict_find_name_by_index_top(nidx, htemp, pvslot) {
		if (dtop_can_store(op))
		    goto ra;
	    }
	    break;		/* handle all slower cases */
	    }
	case t_null:
	    return_error(e_typecheck);
	case t__invalid:
	    return_error(e_stackunderflow);
    }
    /*
     * Combine the check for a writable top dictionary with
     * the global/local store check.  See dstack.h for details.
     */
    if (!dtop_can_store(op)) {
	check_dict_write(*dsp);
	/*
	 * If the dictionary is writable, the problem must be
	 * an invalid store.
	 */
	return_error(e_invalidaccess);
    }
    /*
     * Save a level of procedure call in the common (redefinition)
     * case.  With the current interfaces, we pay a double lookup
     * in the uncommon case.
     */
    if (dict_find(dsp, op1, &pvslot) <= 0)
	return idict_put(dsp, op1, op);
ra:
    if ((pvslot->tas.type_attrs & (&i_ctx_p->memory)->test_mask) == 0)
	alloc_save_change(idmemory, &dsp->value.pdict->values, (ref_packed *)pvslot, "dict_put(value)");
    ref_assign_new_inline(pvslot,op);

    return 0;
}
示例#5
0
/* <dict> <key> .knownundef <bool> */
static int
zknownundef(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    int code;

    check_type(*op1, t_dictionary);
    check_dict_write(*op1);
    code = idict_undef(op1, op);
    make_bool(op1, code == 0);
    pop(1);
    return 0;
}
示例#6
0
/* Set actual frequency and angle in a dictionary. */
static int
dict_real_result(i_ctx_t *i_ctx_p, ref * pdict, const char *kstr, floatp val)
{
    int code = 0;
    ref *ignore;

    if (dict_find_string(pdict, kstr, &ignore) > 0) {
	ref rval;

	check_dict_write(*pdict);
	make_real(&rval, val);
	code = idict_put_string(pdict, kstr, &rval);
    }
    return code;
}
示例#7
0
/* <dict> <key> undef - */
static int
zundef(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    int code;

    check_type(*op1, t_dictionary);
    if (i_ctx_p->in_superexec == 0)
	check_dict_write(*op1);
    code = idict_undef(op1, op);
    if (code < 0 && code != e_undefined) /* ignore undefined error */
	return code;
    pop(2);
    return 0;
}
示例#8
0
/* <dict> <int> .setmaxlength - */
static int
zsetmaxlength(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    uint new_size;
    int code;

    check_type(*op1, t_dictionary);
    if (i_ctx_p->in_superexec == 0)
	check_dict_write(*op1);
    check_type(*op, t_integer);
    if (op->value.intval < 0)
	return_error(e_rangecheck);
    new_size = (uint) op->value.intval;
    if (dict_length(op - 1) > new_size)
	return_error(e_dictfull);
    code = idict_resize(op - 1, new_size);
    if (code >= 0)
	pop(2);
    return code;
}
示例#9
0
/* <dict> <string> .parse_dsc_comments <dict> <dsc code> */
static int
zparse_dsc_comments(i_ctx_t *i_ctx_p)
{
#define MAX_DSC_MSG_SIZE (DSC_LINE_LENGTH + 4)	/* Allow for %% and CR/LF */
    os_ptr const opString = osp;
    os_ptr const opDict = opString - 1;
    uint ssize;
    int comment_code, code;
    char dsc_buffer[MAX_DSC_MSG_SIZE + 2];
    const cmdlist_t *pCmdList = DSCcmdlist;
    const char * const *pBadList = BadCmdlist;
    ref * pvalue;
    CDSC * dsc_data = NULL;
    dict_param_list list;

    /*
     * Verify operand types and length of DSC comment string.  If a comment
     * is too long then we simply truncate it.  Russell's parser gets to
     * handle any errors that may result.  (Crude handling but the comment
     * is bad, so ...).
     */
    check_type(*opString, t_string);
    check_dict_write(*opDict);
    ssize = r_size(opString);
    if (ssize > MAX_DSC_MSG_SIZE)   /* need room for EOL + \0 */
        ssize = MAX_DSC_MSG_SIZE;
    /*
     * Pick up the comment string to be parsed.
     */
    memcpy(dsc_buffer, opString->value.bytes, ssize);
    dsc_buffer[ssize] = 0x0d;	    /* Russell wants a 'line end' */
    dsc_buffer[ssize + 1] = 0;	    /* Terminate string */
    /*
     * Skip data block comments (see comments in front of BadCmdList).
     */
    while (*pBadList && strncmp(*pBadList, dsc_buffer, strlen(*pBadList)))
        pBadList++;
    if (*pBadList) {		    /* If found in list, then skip comment */	
        comment_code = 0;	    /* Force NOP */
    }
    else {
        /*
         * Parse comments - use Russell Lang's DSC parser.  We need to get
         * data area for Russell Lang's parser.  Note: We have saved the
         * location of the data area for the parser in our DSC dict.
         */
        code = dict_find_string(opDict, dsc_dict_name, &pvalue);
	dsc_data = r_ptr(pvalue, dsc_data_t)->dsc_data_ptr;
        if (code < 0)
            return code;
        comment_code = dsc_scan_data(dsc_data, dsc_buffer, ssize + 1);
        if_debug1('%', "[%%].parse_dsc_comments: code = %d\n", comment_code);
	/*
	 * We ignore any errors from Russell's parser.  The only value that
	 * it will return for an error is -1 so there is very little information.
	 * We also do not want bad DSC comments to abort processing of an
	 * otherwise valid PS file.
	 */
        if (comment_code < 0)
	    comment_code = 0;
    }
    /*
     * Transfer data from DSC structure to postscript variables.
     * Look up proper handler in the local cmd decode list.
     */
    while (pCmdList->code && pCmdList->code != comment_code )
	pCmdList++;
    if (pCmdList->dsc_proc) {
	code = dict_param_list_write(&list, opDict, NULL, iimemory);
	if (code < 0)
	    return code;
	code = (pCmdList->dsc_proc)((gs_param_list *)&list, dsc_data);
	iparam_list_release(&list);
	if (code < 0)
	    return code;
    }

    /* Put DSC comment name onto operand stack (replace string). */

    return name_enter_string(imemory, pCmdList->comment_name, opString);
}