예제 #1
0
/* or if they are identical. */
void
packed_get(const gs_memory_t *mem, const ref_packed * packed, ref * pref)
{
    const ref_packed elt = *packed;
    uint value = elt & packed_value_mask;

    switch (elt >> r_packed_type_shift) {
	default:		/* (shouldn't happen) */
	    make_null(pref);
	    break;
	case pt_executable_operator:
	    op_index_ref(value, pref);
	    break;
	case pt_integer:
	    make_int(pref, (int)value + packed_min_intval);
	    break;
	case pt_literal_name:
	    name_index_ref(mem, value, pref);
	    break;
	case pt_executable_name:
	    name_index_ref(mem, value, pref);
	    r_set_attrs(pref, a_executable);
	    break;
	case pt_full_ref:
	case pt_full_ref + 1:
	    ref_assign(pref, (const ref *)packed);
    }
}
예제 #2
0
void
debug_print_packed_ref(const ref_packed *pref)
{	ushort elt = *pref;
	ref nref;
	switch ( elt >> packed_type_shift )
	   {
	case pt_executable_operator:
	  dprintf("<op_name>");
	  elt &= packed_int_mask;
	  op_index_ref(elt, &nref);
	  debug_print_ref(&nref);
	  break;
	case pt_integer:
	  dprintf1("<int> %d", (int)(elt & packed_int_mask) + packed_min_intval);
	  break;
	case pt_literal_name: case pt_literal_name+1:
	  dprintf("<lit_name>"); elt &= packed_max_name_index; goto ptn;
	case pt_executable_name: case pt_executable_name+1:
	  dprintf("<exec_name>"); elt &= packed_max_name_index;
ptn:	  name_index_ref(elt, &nref);
	  dprintf2("(0x%lx#%x)", (ulong)nref.value.pname, elt);
	  debug_print_name(&nref);
	  break;
	   }
}
예제 #3
0
파일: zchar.c 프로젝트: ststeiger/ghostsvg
/* Convert a glyph to a ref. */
void
glyph_ref(const gs_memory_t *mem, gs_glyph glyph, ref * gref)
{
    if (glyph < gs_min_cid_glyph)
        name_index_ref(mem, glyph, gref);
    else
	make_int(gref, glyph - gs_min_cid_glyph);
}
예제 #4
0
/* Print a ref */
void
debug_print_full_ref(const ref *pref)
{	unsigned size = r_size(pref);
	ref nref;
	dprintf1("(%x)", r_type_attrs(pref));
	switch ( r_type(pref) )
	   {
	case t_array:
	  dprintf2("array(%u)0x%lx", size, (ulong)pref->value.refs); break;
	case t_boolean:
	  dprintf1("boolean %x", pref->value.index); break;
	case t_condition:
	  dprintf1("condition 0x%lx", (ulong)pref->value.pcond); break;
	case t_device:
	  dprintf1("device 0x%lx", (ulong)pref->value.pdevice); break;
	case t_dictionary:
	  dprintf3("dict(%u/%u)0x%lx",
		   dict_length(pref), dict_maxlength(pref),
		   (ulong)pref->value.pdict);
	  break;
	case t_file:
	  dprintf1("file 0x%lx", (ulong)pref->value.pfile); break;
	case t_gstate:
	  dprintf1("gstate 0x%lx", (ulong)pref->value.pgstate); break;
	case t_integer: dprintf1("int %ld", pref->value.intval); break;
	case t_lock:
	  dprintf1("lock 0x%lx", (ulong)pref->value.plock); break;
	case t_mark: dprintf("mark"); break;
	case t_mixedarray:
	  dprintf2("mixed packedarray(%u)0x%lx", size,
		   (ulong)pref->value.packed); break;
	case t_name:
	  dprintf2("name(0x%lx#%x)", (ulong)pref->value.pname,
		   name_index(pref));
	  debug_print_name(pref);
	  break;
	case t_null: dprintf("null"); break;
	case t_oparray:
	  dprintf1("op_array(0x%x)", size);
	  name_index_ref(op_array_nx_table[size - op_def_count], &nref);
	  debug_print_name(&nref);
	  break;
	case t_operator:
	  dprintf1("op(0x%x", size);
	  if ( size )
	    dprintf1(":%s", (const char *)(op_def_table[size]->oname + 1));
	  dprintf1(")0x%lx", (ulong)pref->value.opproc);
	  break;
	case t_real: dprintf1("real %f", pref->value.realval); break;
	case t_shortarray:
	  dprintf2("short packedarray(%u)0x%lx", size,
		   (ulong)pref->value.packed); break;
	case t_string:
	  dprintf2("string(%u)0x%lx", size, (ulong)pref->value.bytes); break;
	default: dprintf1("type 0x%x", r_type(pref));
	   }
}
예제 #5
0
/*
 * This routine translates a gs_separation_name value into a character string
 * pointer and a string length.
 */
int
gs_get_colorname_string(const gs_memory_t *mem, gs_separation_name colorname_index,
			unsigned char **ppstr, unsigned int *pname_size)
{
    ref nref;

    name_index_ref(mem, colorname_index, &nref);
    name_string_ref(mem, &nref, &nref);
    return obj_string_data(mem, &nref, (const unsigned char**) ppstr, pname_size);
}
예제 #6
0
/* Get the name of a glyph. */
static int
zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr)
{
    ref nref, sref;

    if (index >= gs_min_cid_glyph) {	/* Fabricate a numeric name. */
        char cid_name[sizeof(gs_glyph) * 3 + 1];
        int code;

        sprintf(cid_name, "%lu", (ulong) index);
        code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name),
                        &nref, 1);
        if (code < 0)
            return code;
    } else
        name_index_ref(font->memory, index, &nref);
    name_string_ref(font->memory, &nref, &sref);
    pstr->data = sref.value.const_bytes;
    pstr->size = r_size(&sref);
    return 0;
}
예제 #7
0
static gs_char
gs_font_map_glyph_by_dict(const gs_memory_t *mem, const ref *map, gs_glyph glyph)
{
    ref *v, n;
    if (glyph >= gs_min_cid_glyph) {
        uint cid = glyph - gs_min_cid_glyph;

        if (dict_find_string(map, "CIDCount", &v) > 0) {
            /* This is a CIDDEcoding resource. */
            make_int(&n, cid / 256);
            if (dict_find(map, &n, &v) > 0) {
                ref vv;

                if (array_get(mem, v, cid % 256, &vv) == 0 && r_type(&vv) == t_integer)
                    return vv.value.intval;
            }
            return GS_NO_CHAR; /* Absent in the map. */
        }
        /* This is GlyphNames2Unicode dictionary. */
        make_int(&n, cid);
    } else
        name_index_ref(mem, glyph, &n);
     if (dict_find(map, &n, &v) > 0) {
        if (r_has_type(v, t_string)) {
            int i, l = r_size(v);
            gs_char c = 0;

            for (i = 0; i < l; i++)
                c = (c << 8) | v->value.const_bytes[i];
            return c;
        }
        if (r_type(v) == t_integer)
            return v->value.intval;
    }
    return GS_NO_CHAR; /* Absent in the map. */
}
예제 #8
0
파일: zmisc.c 프로젝트: hackqiang/gs
static int
zbind(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint depth = 1;
    ref defn;
    register os_ptr bsp;

    switch (r_type(op)) {
        case t_array:
            if (!r_has_attr(op, a_write)) {
                return 0;	/* per PLRM3 */
            }
        case t_mixedarray:
        case t_shortarray:
            defn = *op;
            break;
        case t_oparray:
            defn = *op->value.const_refs;
            break;
        default:
            return_op_typecheck(op);
    }
    push(1);
    *op = defn;
    bsp = op;
    /*
     * We must not make the top-level procedure read-only,
     * but we must bind it even if it is read-only already.
     *
     * Here are the invariants for the following loop:
     *      `depth' elements have been pushed on the ostack;
     *      For i < depth, p = ref_stack_index(&o_stack, i):
     *        *p is an array (or packedarray) ref.
     */
    while (depth) {
        while (r_size(bsp)) {
            ref_packed *const tpp = (ref_packed *)bsp->value.packed; /* break const */

            r_dec_size(bsp, 1);
            if (r_is_packed(tpp)) {
                /* Check for a packed executable name */
                ushort elt = *tpp;

                if (r_packed_is_exec_name(&elt)) {
                    ref nref;
                    ref *pvalue;

                    name_index_ref(imemory, packed_name_index(&elt),
                                   &nref);
                    if ((pvalue = dict_find_name(&nref)) != 0 &&
                        r_is_ex_oper(pvalue)
                        ) {
                        store_check_dest(bsp, pvalue);
                        /*
                         * Always save the change, since this can only
                         * happen once.
                         */
                        ref_do_save(bsp, tpp, "bind");
                        *tpp = pt_tag(pt_executable_operator) +
                            op_index(pvalue);
                    }
                }
                bsp->value.packed = tpp + 1;
            } else {
                ref *const tp = bsp->value.refs++;

                switch (r_type(tp)) {
                    case t_name:	/* bind the name if an operator */
                        if (r_has_attr(tp, a_executable)) {
                            ref *pvalue;

                            if ((pvalue = dict_find_name(tp)) != 0 &&
                                r_is_ex_oper(pvalue)
                                ) {
                                store_check_dest(bsp, pvalue);
                                ref_assign_old(bsp, tp, pvalue, "bind");
                            }
                        }
                        break;
                    case t_array:	/* push into array if writable */
                        if (!r_has_attr(tp, a_write))
                            break;
                    case t_mixedarray:
                    case t_shortarray:
                        if (r_has_attr(tp, a_executable)) {
                            /* Make reference read-only */
                            r_clear_attrs(tp, a_write);
                            if (bsp >= ostop) {
                                /* Push a new stack block. */
                                ref temp;
                                int code;

                                temp = *tp;
                                osp = bsp;
                                code = ref_stack_push(&o_stack, 1);
                                if (code < 0) {
                                    ref_stack_pop(&o_stack, depth);
                                    return_error(code);
                                }
                                bsp = osp;
                                *bsp = temp;
                            } else
                                *++bsp = *tp;
                            depth++;
                        }
                }
            }
        }
        bsp--;
        depth--;
        if (bsp < osbot) {	/* Pop back to the previous stack block. */
            osp = bsp;
            ref_stack_pop_block(&o_stack);
            bsp = osp;
        }
    }
    osp = bsp;
    return 0;
}
예제 #9
0
int
obj_cvp(const ref * op, byte * str, uint len, uint * prlen,
	int full_print, uint start_pos, const gs_memory_t *mem, bool restart)
{
    char buf[50];  /* big enough for any float, double, or struct name */
    const byte *data = (const byte *)buf;
    uint size;
    int code;
    ref nref;

    if (full_print) {
	static const char * const type_strings[] = { REF_TYPE_PRINT_STRINGS };

	switch (r_btype(op)) {
	case t_boolean:
	case t_integer:
	    break;
	case t_real: {
	    /*
	     * To get fully accurate output results for IEEE
	     * single-precision floats (24 bits of mantissa), the ANSI %g
	     * default of 6 digits is not enough; 9 are needed.
	     * Unfortunately, using %.9g for floats (as opposed to doubles)
	     * produces unfortunate artifacts such as 0.01 5 mul printing as
	     * 0.049999997.  Therefore, we print using %g, and if the result
	     * isn't accurate enough, print again using %.9g.
	     * Unfortunately, a few PostScript programs 'know' that the
	     * printed representation of floats fits into 6 digits (e.g.,
	     * with cvs).  We resolve this by letting cvs, cvrs, and = do
	     * what the Adobe interpreters appear to do (use %g), and only
	     * produce accurate output for ==, for which there is no
	     * analogue of cvs.  What a hack!
	     */
	    float value = op->value.realval;
	    float scanned;

	    sprintf(buf, "%g", value);
	    sscanf(buf, "%f", &scanned);
	    if (scanned != value)
		sprintf(buf, "%.9g", value);
	    ensure_dot(buf);
	    goto rs;
	}
	case t_operator:
	case t_oparray:  
	    code = obj_cvp(op, (byte *)buf + 2, sizeof(buf) - 4, &size, 0, 0, mem, restart);
	    if (code < 0) 
		return code;
	    buf[0] = buf[1] = buf[size + 2] = buf[size + 3] = '-';
	    size += 4;
	    goto nl;
	case t_name:	 
	    if (r_has_attr(op, a_executable)) {
		code = obj_string_data(mem, op, &data, &size);
		if (code < 0)
		    return code;
		goto nl;
	    }
	    if (start_pos > 0)
		return obj_cvp(op, str, len, prlen, 0, start_pos - 1, mem, restart);
	    if (len < 1)
		return_error(e_rangecheck);
	    code = obj_cvp(op, str + 1, len - 1, prlen, 0, 0, mem, restart);
	    if (code < 0)
		return code;
	    str[0] = '/';
	    ++*prlen;
	    return code;
	case t_null:
	    data = (const byte *)"null";
	    goto rs;
	case t_string:  
	    if (!r_has_attr(op, a_read))
		goto other;
	    size = r_size(op);
	    {
		bool truncate = (full_print == 1 && size > CVP_MAX_STRING);
		stream_cursor_read r;
		stream_cursor_write w;
		uint skip;
		byte *wstr;
		uint len1;
		int status = 1;

		if (start_pos == 0) {
		    if (len < 1)
			return_error(e_rangecheck);
		    str[0] = '(';
		    skip = 0;
		    wstr = str + 1;
		} else {
		    skip = start_pos - 1;
		    wstr = str;
		}
		len1 = len + (str - wstr);
		r.ptr = op->value.const_bytes - 1;
		r.limit = r.ptr + (truncate ? CVP_MAX_STRING : size);
		while (skip && status == 1) {
		    uint written;

		    w.ptr = (byte *)buf - 1;
		    w.limit = w.ptr + min(skip + len1, sizeof(buf));
		    status = s_PSSE_template.process(NULL, &r, &w, false);
		    written = w.ptr - ((byte *)buf - 1);
		    if (written > skip) {
			written -= skip;
			memcpy(wstr, buf + skip, written);
			wstr += written;
			skip = 0;
			break;
		    }
		    skip -= written;
		}
		/*
		 * We can reach here with status == 0 (and skip != 0) if
		 * start_pos lies within the trailing ")" or  "...)".
		 */
		if (status == 0) {
#ifdef DEBUG
		    if (skip > (truncate ? 4 : 1)) {
			return_error(e_Fatal);
		    }
#endif
		}
		w.ptr = wstr - 1;
		w.limit = str - 1 + len;
		if (status == 1)
		    status = s_PSSE_template.process(NULL, &r, &w, false);
		*prlen = w.ptr - (str - 1);
		if (status != 0)
		    return 1;
		if (truncate) {
		    if (len - *prlen < 4 - skip)
			return 1;
		    memcpy(w.ptr + 1, "...)" + skip, 4 - skip);
		    *prlen += 4 - skip;
		} else {
		    if (len - *prlen < 1 - skip)
			return 1;
		    memcpy(w.ptr + 1, ")" + skip, 1 - skip);
		    *prlen += 1 - skip;
		}
	    }
	    return 0;
	case t_astruct:
	case t_struct:    
	    if (r_is_foreign(op)) {
		/* gs_object_type may not work. */
		data = (const byte *)"-foreign-struct-";
		goto rs;
	    }
	    if (!mem) {
		data = (const byte *)"-(struct)-";
		goto rs;
	    }
	    data = (const byte *)
		gs_struct_type_name_string(
				gs_object_type(mem,
				    (const obj_header_t *)op->value.pstruct));
	    size = strlen((const char *)data);
	    if (size > 4 && !memcmp(data + size - 4, "type", 4))
		size -= 4;
	    if (size > sizeof(buf) - 2)
		return_error(e_rangecheck);
	    buf[0] = '-';
	    memcpy(buf + 1, data, size);
	    buf[size + 1] = '-';
	    size += 2;
	    data = (const byte *)buf;
	    goto nl;
	default:
other:
	    {
		int rtype = r_btype(op);

		if (rtype > countof(type_strings))
		    return_error(e_rangecheck);
		data = (const byte *)type_strings[rtype];
		if (data == 0)
		    return_error(e_rangecheck);
	    }
	    goto rs;
	}
    }	
    /* full_print = 0 */
    switch (r_btype(op)) {
    case t_boolean:
	data = (const byte *)(op->value.boolval ? "true" : "false");
	break;
    case t_integer:
	sprintf(buf, "%ld", op->value.intval);
	break;
    case t_string:
	check_read(*op);
	/* falls through */
    case t_name:
	code = obj_string_data(mem, op, &data, &size);
	if (code < 0)
	    return code;
	goto nl;
    case t_oparray: {
	uint index = op_index(op);
	const op_array_table *opt = op_index_op_array_table(index);

	name_index_ref(mem, opt->nx_table[index - opt->base_index], &nref);
	name_string_ref(mem, &nref, &nref);
	code = obj_string_data(mem, &nref, &data, &size);
	if (code < 0)
	    return code;
	goto nl;
    }
    case t_operator: {
	/* Recover the name from the initialization table. */
	uint index = op_index(op);

	/*
	 * Check the validity of the index.  (An out-of-bounds index
	 * is only possible when examining an invalid object using
	 * the debugger.)
	 */
	if (index > 0 && index < op_def_count) {
	    data = (const byte *)(op_index_def(index)->oname + 1);
	    break;
	}
	/* Internal operator, no name. */
	sprintf(buf, "@0x%lx", (ulong) op->value.opproc);
	break;
    }
    case t_real:
	/*
	 * The value 0.0001 is a boundary case that the Adobe interpreters
	 * print in f-format but at least some gs versions print in
	 * e-format, presumably because of differences in the underlying C
	 * library implementation.  Work around this here.
	 */
	if (op->value.realval == (float)0.0001) {
	    strcpy(buf, "0.0001");
	} else {
	    sprintf(buf, "%g", op->value.realval);
	}
	ensure_dot(buf);
	break;
    default:
	data = (const byte *)"--nostringval--";
    }
rs: size = strlen((const char *)data);
nl: if (size < start_pos)
	return_error(e_rangecheck);
    if (!restart && size > len)
	return_error(e_rangecheck);
    size -= start_pos;
    *prlen = min(size, len);
    memmove(str, data + start_pos, *prlen);
    return (size > len);
}
예제 #10
0
파일: idstack.c 프로젝트: 99years/plan9
/*
 * Look up a name on the dictionary stack.
 * Return the pointer to the value if found, 0 if not.
 */
ref *
dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
{
    ds_ptr pdref = pds->stack.p;

/* Since we know the hash function is the identity function, */
/* there's no point in allocating a separate variable for it. */
#define hash dict_name_index_hash(nidx)
    ref_packed kpack = packed_name_key(nidx);

    do {
	dict *pdict = pdref->value.pdict;
	uint size = npairs(pdict);
	const gs_memory_t *mem = dict_mem(pdict);
#ifdef DEBUG
	if (gs_debug_c('D')) {
	    ref dnref;

	    name_index_ref(mem, nidx, &dnref);
	    dlputs("[D]lookup ");
	    debug_print_name(mem, &dnref);
	    dprintf3(" in 0x%lx(%u/%u)\n",
		     (ulong) pdict, dict_length(pdref),
		     dict_maxlength(pdref));
	}
#endif
#define INCR_DEPTH(pdref)\
  INCR(depth[min(MAX_STATS_DEPTH, pds->stack.p - pdref)])
	if (dict_is_packed(pdict)) {
	    packed_search_1(INCR_DEPTH(pdref),
			    return packed_search_value_pointer,
			    DO_NOTHING, goto miss);
	    packed_search_2(INCR_DEPTH(pdref),
			    return packed_search_value_pointer,
			    DO_NOTHING, break);
	  miss:;
	} else {
	    ref *kbot = pdict->keys.value.refs;
	    register ref *kp;
	    int wrap = 0;

	    /* Search the dictionary */
	    for (kp = kbot + dict_hash_mod(hash, size) + 2;;) {
		--kp;
		if (r_has_type(kp, t_name)) {
		    if (name_index(mem, kp) == nidx) {
			INCR_DEPTH(pdref);
			return pdict->values.value.refs + (kp - kbot);
		    }
		} else if (r_has_type(kp, t_null)) {	/* Empty, deleted, or wraparound. */
		    /* Figure out which. */
		    if (!r_has_attr(kp, a_executable))
			break;
		    if (kp == kbot) {	/* wrap */
			if (wrap++)
			    break;	/* 2 wraps */
			kp += size + 1;
		    }
		}
	    }
	}
#undef INCR_DEPTH
    }