#ifndef lint static char sccsid[] = "@(#)procdict.c 9.4 88/01/19 Copyright 1987 Sun Micro"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /*- Make processes look like dictionaries procdict.c, Thu Apr 17 09:12:06 1986 James Gosling, Sun Microsystems */ #ifdef REF #include #include #endif #include "PostScript.h" #define ix_state 0 #define ix_errorcode 1 #define ix_execee 2 #define ix_operandstack 3 #define ix_executionstack 4 #define ix_dictionarystack 5 #define ix_interests 6 #define ix_errordetaillevel 7 #define ix_sendcontexts 8 static procaccess(obj, set, value) register struct body *obj; int set; register struct object value; { register struct execution_environment *ee = current_process; register struct object *optop = ee->optop; assert(obj != 0); if (obj->type != process_type) { ee->error_code = unregistered_error_code; return; } switch (set) { case GET_MAGIC(ix_state): set_typed_bodied_object(ee->optop, keyword_type, get_name(process_event_name(obj), -1)); ee->optop++; break; case GET_MAGIC(ix_errorcode): set_typed_bodied_object(ee->optop, keyword_type, get_name(error_names[(int) obj->body.process.env->error_code], -1)); ee->optop++; break; case GET_MAGIC(ix_execee): *ee->optop = obj->body.process.env->execee; object_incref(ee->optop); ee->optop++; break; case GET_MAGIC(ix_operandstack): { register struct execution_environment *nee; register size; register struct object *dest, *source; nee = obj->body.process.env; source = nee->underflow; size = nee->optop - nee->underflow; if (ee == nee) size -= 2; if (size < 0) size = 0; *ee->optop = make_array(size); dest = body_of(ee->optop)->body.array.objects; while (--size >= 0) { object_incref(source); *dest++ = *source++; } ee->optop++; } break; case GET_MAGIC(ix_executionstack): { register struct execution_environment *nee; register size; register struct object *dest; register struct execution_stack *stackent; nee = obj->body.process.env; stackent = nee->execution_stack; size = nee->pos ? nee->pos - stackent + 1 : 0; assert(size >= 0 && size < 100000); *ee->optop = make_array(size * 2); ee->optop->value.substring.length = 0; dest = body_of(ee->optop)->body.array.objects; while (--size >= 0) { if (stackent->executed.type != null_type) switch (stackent->type) { case array_body_execution: set_fixed_object(dest + 1, fracti(stackent->executed.value.substring.length - stackent->env.array.left)); goto common; case file_execution: set_fixed_object(dest + 1, 0); common: *dest = stackent->executed; object_incref(dest); ee->optop->value.substring.length += 2; dest += 2; break; } stackent++; } ee->optop++; } break; case GET_MAGIC(ix_dictionarystack): { register struct execution_environment *nee; register size; register struct object *dest; register struct dictstack_ent *dictent; nee = obj->body.process.env; dictent = nee->dictionary_stack; size = nee->dict_top - dictent; *ee->optop = make_array(size); dest = body_of(ee->optop)->body.array.objects; while (--size >= 0) { if (dictent->obj) { set_typed_bodied_object(dest, dictent->obj->type, dictent->obj); if (dictent->obj->type == canvas_type) dest->value.canvas = dictent->obj->body.canvas.canvas; } else { set_typed_bodied_object(dest, dictionary_type, dictent->body); dest->value.substring.length = dictent->body->body.array.size; } object_incref(dest); dest++; dictent++; } ee->optop++; } break; case GET_MAGIC(ix_interests): { register struct execution_environment *proc; register struct body *il, *b; register struct object *dest; register int n = 0; proc = obj->body.process.env; il = proc->interests; while (il) { il = il->body.event.next_int; n++; } *ee->optop = make_array(n); b = body_of(ee->optop); b->body.array.used = n; for (dest = b->body.array.objects, il = proc->interests; n--; dest++) { incref(il); set_typed_bodied_object(dest, event_type, il); il = il->body.event.next_int; } ee->optop++; } break; case GET_MAGIC(ix_errordetaillevel): set_fixed_object(ee->optop, fracti(obj->body.process.env->detail_desired)); ee->optop++; break; case SET_MAGIC(ix_errordetaillevel): if (value.type != fixed_type) { ee->error_code = typecheck_error_code; return; } obj->body.process.env->detail_desired = roundfr(value.value.fixed); break; case GET_MAGIC(ix_sendcontexts): { register struct execution_stack *es; register struct object *oldoptop = ee->optop; register struct execution_environment *other; register first = 1; other = obj->body.process.env; for (es = other->pos; es >= other->execution_stack; es--) if (es->type == send_execution) { if (ee->optop + 2 > ee->overflow && grow_stack(ee, 2) < 0) { ee->error_code = stackoverflow_error_code; return; } if (first) { set_typed_bodied_object(ee->optop, dictionary_type, other->dictionary_stack[es->env.send.topdict].body); assert(body_of(ee->optop)->type == dictionary_type); object_incref(ee->optop); ee->optop++; first = 0; } *ee->optop = es->executed.type == array_type ? body_of(&es->executed)->body.array.objects[0] : es->executed; if (ee->optop->type == dictionary_type) { object_incref(ee->optop); ee->optop++; } } oldoptop[0] = make_growable_object(array_type, oldoptop, ee->optop - oldoptop); ee->optop = oldoptop+1; } break; #ifdef notdef case SET_MAGIC(ix_state): case SET_MAGIC(ix_errorcode): case SET_MAGIC(ix_execee): case SET_MAGIC(ix_operandstack): case SET_MAGIC(ix_executionstack): case SET_MAGIC(ix_dictionarystack): case SET_MAGIC(ix_interests): #endif default: ee->error_code = invalidaccess_error_code; break; } } initialize_procdict() { register struct body *pd = new_dict(20); struct object o; dict_table[(int) process_type] = pd; pd->refcnt = maximum_refcnt; set_typed_bodied_object(&o, dictionary_type, pd); define_object(system_dictionary, "magic:procdict", o); define_magic("State", pd, procaccess, ix_state, 0, 1); define_magic("ErrorCode", pd, procaccess, ix_errorcode, 0, 1); define_magic("Execee", pd, procaccess, ix_execee, 0, 1); define_magic("OperandStack", pd, procaccess, ix_operandstack, 0, 1); define_magic("ExecutionStack", pd, procaccess, ix_executionstack, 0, 1); define_magic("DictionaryStack", pd, procaccess, ix_dictionarystack, 0, 1); define_magic("Interests", pd, procaccess, ix_interests, 0, 1); define_magic("ErrorDetailLevel", pd, procaccess, ix_errordetaillevel, 0, 1); define_magic("SendContexts", pd, procaccess, ix_sendcontexts, 0, 1); }