DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T z

⟦bc829e9d2⟧ TextFile

    Length: 7339 (0x1cab)
    Types: TextFile
    Names: »ztype.c«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦ff23ba0e6⟧ »./ghostscript-1.3.tar.Z« 
        └─⟦a24a58cd3⟧ 
            └─⟦this⟧ »ztype.c« 

TextFile

/* Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
   Distributed by Free Software Foundation, Inc.

This file is part of Ghostscript.

Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.  Refer
to the Ghostscript General Public License for full details.

Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License.  A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities.  It should be in a file named COPYING.  Among other
things, the copyright notice and this notice must be preserved on all
copies.  */

/* ztype.c */
/* Type, attribute, and conversion operators for GhostScript */
#include <stdio.h>			/* for stream.h */
#include <math.h>
#include "ghost.h"
#include "errors.h"
#include "oper.h"
#include "store.h"
#include "stream.h"

/* Forward references */
private int access_check(P3(ref *, int, int));

/* Max and min integer values expressed as reals. */
float min_int_real = (float)-0x7fffffffL-1;	/* some compilers can't */
					/* handle -0x80000000L */
float max_int_real = 0x7fffffffL;

/* .typenumber */
int
ztypenumber(register ref *op)
{	check_op(1);
	make_int(op, r_btype(op));
	return 0;
}

/* cvlit */
int
zcvlit(register ref *op)
{	check_op(1);
	r_clear_attrs(op, a_executable);
	return 0;
}

/* cvx */
int
zcvx(register ref *op)
{	check_op(1);
	r_set_attrs(op, a_executable);
	return 0;
}

/* xcheck */
int
zxcheck(register ref *op)
{	check_op(1);
	make_bool(op, (r_attrs(op) & a_executable ? 1 : 0));
	return 0;
}

/* executeonly */
int
zexecuteonly(register ref *op)
{	check_op(1);
	if ( r_type(op) == t_dictionary ) return e_typecheck;
	return access_check(op, a_execute, 1);
}

/* noaccess */
int
znoaccess(register ref *op)
{	return access_check(op, 0, 1);
}

/* readonly */
int
zreadonly(register ref *op)
{	return access_check(op, a_read+a_execute, 1);
}

/* rcheck */
int
zrcheck(register ref *op)
{	int code = access_check(op, a_read, 0);
	if ( code >= 0 ) make_bool(op, code);
	return code;
}

/* wcheck */
int
zwcheck(register ref *op)
{	int code = access_check(op, a_write, 0);
	if ( code >= 0 ) make_bool(op, code);
	return code;
}

/* cvi */
int
zcvi(register ref *op)
{	float fval;
	switch ( r_type(op) )
	   {
	case t_integer: return 0;
	case t_real: fval = op->value.realval; break;
	default: return e_typecheck;
	case t_string:
	   {	stream st;
		ref nref;
		int code;
		sread_string(&st, op->value.bytes, op->size);
		code = scan_number(&st, &nref);
		if ( code ) return code;	/* error condition */
		if ( sgetc(&st) != EOFC ) return e_syntaxerror;
		if ( r_type(&nref) == t_integer ) { *op = nref; return 0; }
		/* Otherwise, result was a real */
		fval = nref.value.realval;
	   }
	   }
	/* Check if a real will fit into an integer value */
	fval = (fval < 0 ? ceil(fval) : floor(fval));
	if ( fval < min_int_real || fval > max_int_real )
		return e_rangecheck;
	make_int(op, fval);		/* fval has no fraction part */
	return 0;
}

/* cvn */
int
zcvn(register ref *op)
{	int exec;
	int code;
	check_type(*op, t_string);
	if ( !(r_attrs(op) & a_read) ) return e_invalidaccess;
	exec = r_attrs(op) & a_executable;
	code = name_ref(op->value.bytes, op->size, op, 1);
	if ( code ) return code;
	r_set_attrs(op, exec);
	return 0;
   }

/* cvr */
int
zcvr(register ref *op)
{	switch ( r_type(op) )
	   {
	case t_integer: make_real(op, op->value.intval);
	case t_real: return 0;
	default: return e_typecheck;
	case t_string:
	   {	stream st;
		ref nref;
		int code;
		sread_string(&st, op->value.bytes, op->size);
		code = scan_number(&st, &nref);
		if ( code ) return code;	/* error condition */
		if ( sgetc(&st) != EOFC ) return e_syntaxerror;
		if ( r_type(&nref) == t_real ) { *op = nref; return 0; }
		/* Otherwise, result was an integer */
		make_real(op, nref.value.intval);
		return 0;
	   }
	   }
}

/* cvrs */
int
zcvrs(register ref *op)
{	int radix;
	long ival;
	ulong val;
	byte digits[31];
	byte *endp = &digits[31];
	byte *dp = endp;
	check_type(op[-1], t_integer);
	if ( op[-1].value.intval < 2 || op[-1].value.intval > 36 )
		return e_rangecheck;
	radix = op[-1].value.intval;
	check_type(*op, t_string);
	switch ( r_type(op - 2) )
	   {
	case t_integer: ival = op[-2].value.intval; break;
	case t_real:	/****** SHOULD USE cvi HERE ******/
	default:
		return e_typecheck;
	   }
	val = (ival < 0 ? -ival : ival);
	do
	   {	*--dp = val % radix + '0';
		val /= radix;
	   }
	while ( val );
	if ( ival < 0 ) *--dp = '-';
	if ( endp - dp > op->size ) return e_rangecheck;
	memcpy(op->value.bytes, dp, (uint)(endp - dp));
	op->size = endp - dp;
	r_set_attrs(op, a_subrange);
	op[-2] = *op;
	pop(2);
	return 0;
}

/* cvs */
int
zcvs(register ref *op)
{	extern ref *name_string_ref(P2(ref *, ref *));
	ref *op1 = op - 1;
	byte buf[25];			/* big enough for any float */
	byte *str = buf;
	int len;
	check_type(*op, t_string);
	switch ( r_type(op1) )
	   {
	case t_boolean:
		str = (byte *)(op1->value.index ? "true" : "false");
		break;
	case t_integer:
		sprintf(buf, "%ld", op1->value.intval);
		break;
	case t_name:
	   {	ref stref;
		name_string_ref(op1, &stref);	/* name string */
		str = stref.value.bytes, len = stref.size;
	   }
		goto nl;
	case t_operator:
		/****** HOW TO GET THE NAME? ******/
		sprintf(buf, "operator %lx", (ulong)op1->value.opproc);
		break;
	case t_real:
		sprintf(buf, "%g", op1->value.realval);
		break;
	case t_string:
		str = op1->value.bytes, len = op1->size;
		goto nl;
	default:
		check_op(1);
		str = (byte *)"--nostringval--";
	   }
	len = strlen(str);
nl:	if ( len > op->size ) return e_rangecheck;
	memcpy(op->value.bytes, str, len);
	op[-1] = *op;
	op[-1].size = len;
	r_set_attrs(op - 1, a_subrange);
	pop(1);
	return 0;
}

/* ------ Initialization procedure ------ */

void
ztype_op_init()
{	static op_def my_defs[] = {
		{"1cvi", zcvi},
		{"1cvlit", zcvlit},
		{"1cvn", zcvn},
		{"1cvr", zcvr},
		{"3cvrs", zcvrs},
		{"2cvs", zcvs},
		{"1cvx", zcvx},
		{"1executeonly", zexecuteonly},
		{"1noaccess", znoaccess},
		{"1rcheck", zrcheck},
		{"1readonly", zreadonly},
		{"1.typenumber", ztypenumber},
		{"1wcheck", zwcheck},
		{"1xcheck", zxcheck},
		op_def_end
	};
	z_op_init(my_defs);
}

/* ------ Internal routines ------ */

/* Test or modify the access of an object. */
/* If modify = 1, restrict to the selected access and return 0; */
/* if modify = 0, return 1 if the object had the access, 0 if not. */
/* Return an error code if the object is not of appropriate type, */
/* or if the object did not have the access already when modify=1. */
private int
access_check(ref *op,
    int access,				/* mask for attrs */
    int modify)				/* if true, reduce access */
{	switch ( r_type(op) )
	   {
	default: return e_typecheck;
	case t_array: case t_dictionary: case t_file:
	case t_packedarray: case t_string: ;
	   }
	if ( modify )
	   {	if ( ~r_attrs(op) & access )
			return e_invalidaccess;
		r_clear_attrs(op, a_all);
		r_set_attrs(op, access);
		return 0;
	   }
	else
	   {	return (r_attrs(op) & access) == access;
	   }
}