#ifndef lint static char sccsid[] = "@(#)typedprint.c 9.4 88/01/19 Copyright 1987 Sun Micro"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /*- Print typed objects typedprint.c, Thu Apr 17 15:08:34 1986 */ #ifdef REF #include #include #endif #include "PostScript.h" #include "encoding.h" #if defined(vax) struct ieee_single { unsigned int mant:23; unsigned int exp:8; unsigned int sign:1; }; #endif printobj(o) struct object o; { register PSFILE *f = current_process->stdprnt->body.file.outbuf; switch (o.type) { default: psio_putc(enc_nonobject, f); break; case string_type:{ register n = o.value.substring.length; register char *s = body_of(&o)->body.string.chars + o.value.substring.start; if (n < 16) psio_putc(enc_short_string + n, f); else { if (n < 256) psio_putc(enc_string + 0, f); else { psio_putc(enc_string + 1, f); psio_putc(n >> 8, f); } psio_putc(n, f); } while (--n >= 0) psio_putc(*s++, f); } break; case fixed_type:{ register n; register fractbytes = 2 << 2; register an; n = o.value.fixed; if ((n & 0377) == 0) n >>= 8, fractbytes -= 1 << 2; if ((n & 0377) == 0) n >>= 8, fractbytes -= 1 << 2; an = n < 0 ? -n : n; if (an < 128) psio_putc(fractbytes + enc_int, f); else { if (an < (1 << 15)) psio_putc(fractbytes + enc_int + 1, f); else { if (an < (1 << 23)) psio_putc(fractbytes + enc_int + 2, f); else { psio_putc(fractbytes + enc_int + 3, f); psio_putc(n >> 24, f); } psio_putc(n >> 16, f); } psio_putc(n >> 8, f); } psio_putc(n, f); } break; case real_type: { union { float f; char b[4]; #if defined(vax) struct ieee_single ieee_f; #endif } u; psio_putc(enc_IEEEfloat, f); u.f = o.value.real; #if defined(vax) /* the first u is used as a float, * the second as a struct ieee_single return value. * Note This function is not very safe... */ vax_ieee_float(&u.f, &u.ieee_f); #endif #if defined(mc68000) || defined(sparc) psio_putc(u.b[0], f); psio_putc(u.b[1], f); psio_putc(u.b[2], f); psio_putc(u.b[3], f); #endif #if defined(vax) || defined(i386) psio_putc(u.b[3], f); psio_putc(u.b[2], f); psio_putc(u.b[1], f); psio_putc(u.b[0], f); #endif } break; case array_type:{ register struct object *el = (body_of(&o)->body.array.objects + o.value.substring.start); register n = o.value.substring.length; if (n < 256) psio_putc(enc_array, f); else { psio_putc(enc_array + 1, f); psio_putc(n >> 8, f); } psio_putc(n, f); while (--n >= 0) printobj(*el++); } break; } } static typedprint(ee) register struct execution_environment *ee; { if (ee->stdprnt->body.file.outbuf == 0 || psio_error(ee->stdprnt->body.file.outbuf)) { ee->error_code == ioerror_error_code; return; } ee->optop--; printobj(*ee->optop); object_decref(ee->optop); } static tagprint(ee) register struct execution_environment *ee; { register PSFILE *f = ee->stdprnt->body.file.outbuf; if (ee->optop[-1].type != fixed_type) { ee->error_code = typecheck_error_code; return; } if (f == 0 || psio_error(f)) { ee->error_code == ioerror_error_code; return; } psio_putc(enc_tag, f); psio_putc(ee->optop[-1].value.fixed>>24, f); psio_putc(ee->optop[-1].value.fixed>>16, f); ee->optop--; } initialize_typedprint() { define_operator("typedprint", typedprint, 0, 1, 0); define_operator("tagprint", tagprint, 0, 1, 0); } #if defined(vax) /* Vax single precision floating point */ struct vax_single { unsigned int mant1:7; unsigned int exp:8; unsigned int sign:1; unsigned int mant2:16; }; #define VAX_SNG_BIAS 0x81 #define IEEE_SNG_BIAS 0x7f static struct sgl_limits { struct vax_single s; struct ieee_single ieee; } sgl_limits[2] = { {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ { 0x0, 0xff, 0x0 }}, /* Max IEEE */ {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ { 0x0, 0x0, 0x0 }} /* Min IEEE */ }; /* * The value rfp is a return value only. It will generally be * the same pointer as 'fp'. This is done since functions can not return * compound types (like struct ieee_single). */ static vax_ieee_float(fp, rfp) float *fp; struct ieee_single *rfp; { struct ieee_single is; struct vax_single vs; struct sgl_limits *lim; int i; vs = *((struct vax_single *)fp); for (i = 0, lim = sgl_limits; i < sizeof(sgl_limits)/sizeof(struct sgl_limits); i++, lim++) { if ((vs.mant2 == lim->s.mant2) && (vs.exp == lim->s.exp) && (vs.mant1 == lim->s.mant1)) { is = lim->ieee; goto returnit; } } is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; is.mant = (vs.mant1 << 16) | vs.mant2; returnit: is.sign = vs.sign; rfp->mant = is.mant; rfp->exp = is.exp; rfp->sign = is.sign; } #endif /* vax */