#ifndef lint static char sccsid[] = "@(#)errors.c 9.4 88/01/19 Copyright 1987 Sun Micro"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /*- Routines for dealing with error handling errors.c, Thu May 15 13:18:16 1986 James Gosling, Sun Microsystems */ #ifdef REF #include #include #endif #include "PostScript.h" static struct object error_table[((int) killprocess_error_code) + 1]; static struct object commandkey; static struct object dollar_error_key; static struct object dstackkey; static struct object errordictkey; static struct object errornamekey; static struct object estackkey; static struct object messagekey; static struct object newerrorkey; static struct object ostackkey; #define keyword(n) \ set_typed_bodied_object(&EXPAND(n)key, keyword_type, \ get_name("n", -1)) #define errkey(e) set_typed_bodied_object( \ &error_table[(int) EXPAND(e)_error_code], \ keyword_type, \ get_name("e", -1)) really_handle_error(ee) register struct execution_environment *ee; { register struct object *res, *pres = 0; if (ee->error_code == no_error_code) return; /* * Scan the dictionary stack for a dictionary that defines * "errordict", and where "errordict" defines an appropriate error * handler */ if (ee->error_code != stackoverflow_error_code && ee->error_code != execstackoverflow_error_code && ee->optop + 1 < ee->overflow) { register struct dictstack_ent *stackent = ee->dict_top; while (--stackent >= ee->dictionary_stack) if ((res = find_object_in_dictionary(errordictkey, stackent->body)) != 0 && res->type == dictionary_type && (pres = find_object_in_dictionary(error_table[(int) ee->error_code], body_of(res))) != 0) break; } if (pres == 0) defaulterroraction(ee); else { setup_dollar_error(ee); ee->error_code = no_error_code; object_incref(pres); *ee->optop = ee->execee; ee->optop++; ee->execee = *pres; } } static struct object NullObject; defaulterroraction(ee) register struct execution_environment *ee; { { register struct execution_stack *p = ee->pos; while (p >= ee->execution_stack) { if (p->type == stopped_execution) break; p--; } if (p < ee->execution_stack && ee->error_code != killprocess_error_code || ee->error_code == stackoverflow_error_code) { decode_process_state(ee->stddiag->body.file.outbuf, ee); if (ee->error_code == stackoverflow_error_code) { /* Hose out the stack on overflow */ while (ee->optop > ee->underflow) { ee->optop--; object_decref(ee->optop); } ee->optop = ee->underflow; } kill_process_group(ee); } } setup_dollar_error(ee); ee->error_code = no_error_code; ee->error_detail = 0; set_stop_primitive(ee); ee->execee.executable = 1; } static setup_dollar_error(ee) register struct execution_environment *ee; { if (ee->dict_top - 2 >= ee->dictionary_stack) { register struct body *edict; register struct object *obj; struct object arr; register size; edict = ee->dictionary_stack[1].body; assert(edict); if (obj = find_object_in_dictionary(dollar_error_key, edict)) edict = body_of(obj); else if (ee->detail_desired <= 0 && (obj = find_object_in_dictionary(dollar_error_key, system_dictionary))) edict = body_of(obj); else { struct object o; register struct body *new = new_dict(20); set_typed_bodied_object(&o, dictionary_type, new); define_object_in_dictionary(dollar_error_key, o, ee->detail_desired <= 0 ? system_dictionary : edict, 0); edict = new; } define_object_in_dictionary(errornamekey, error_table[(int) ee->error_code], edict, 0); { struct object TRUE; set_typed_object(&TRUE, boolean_type); TRUE.value.fixed = fracti(1); define_object_in_dictionary(newerrorkey, TRUE, edict, 0); } if (define_object_in_dictionary(commandkey, ee->execee, edict, 0) != no_error_code) object_decref(&ee->execee); if (ee->detail_desired > 0) { if ((obj = find_object_in_dictionary(messagekey, edict)) == 0 || obj->type != string_type || body_of(obj)->body.string.size < 100) { struct object newstr; newstr = make_string(2000, 0); if (define_object_in_dictionary(messagekey, newstr, edict, 0) != no_error_code) object_decref(&newstr); obj = find_object_in_dictionary(messagekey, edict); } if (obj != 0 && obj->type == string_type) { register PSFILE *f = psio_sopen(body_of(obj)->body.string.chars, body_of(obj)->body.string.size, "w"); if (f) { decode_process_state(f, ee); obj->value.substring.start = 0; obj->value.substring.length = psio_bytesoutput(f); psio_close(f); } } } else define_object_in_dictionary(messagekey, NullObject, edict, 0); if (ee->detail_desired > 1) { register realsize; arr = make_growable_object(array_type, ee->underflow, ee->optop - ee->underflow); for (obj = ee->optop; --obj >= ee->underflow;) { object_incref(obj); } define_object_in_dictionary(ostackkey, arr, edict, 0); size = ee->dict_top - ee->dictionary_stack; arr = make_array(size); obj = body_of(&arr)->body.array.objects; while (--size >= 0) { set_typed_bodied_object(&obj[size], dictionary_type, ee->dictionary_stack[size].body); incref(ee->dictionary_stack[size].body); } define_object_in_dictionary(dstackkey, arr, edict, 0); size = ee->pos - ee->execution_stack + 1; realsize = 0; while (--size >= 0) { if (ee->execution_stack[size].executed.type == array_type) realsize++; } arr = make_array(realsize); size = ee->pos - ee->execution_stack + 1; obj = body_of(&arr)->body.array.objects; while (--size >= 0) if (ee->execution_stack[size].executed.type == array_type) { realsize--; assert(realsize >= 0); obj[realsize] = ee->execution_stack[size].executed; object_incref(&obj[realsize]); } assert(realsize == 0); define_object_in_dictionary(estackkey, arr, edict, 0); } else { define_object_in_dictionary(dstackkey, NullObject, edict, 0); define_object_in_dictionary(estackkey, NullObject, edict, 0); define_object_in_dictionary(ostackkey, NullObject, edict, 0); } } } initialize_errors() { set_typed_bodied_object(&dollar_error_key, keyword_type, get_name("$error", -1)); keyword(command); keyword(dstack); keyword(errordict); keyword(errorname); keyword(estack); keyword(newerror); keyword(ostack); keyword(message); errkey(no); errkey(accept); errkey(dictfull); errkey(dictstackoverflow); errkey(dictstackunderflow); errkey(execstackoverflow); errkey(interrupt); errkey(invalidaccess); errkey(invalidexit); errkey(invalidfileaccess); errkey(invalidfont); errkey(invalidrestore); errkey(ioerror); errkey(limitcheck); errkey(nocurrentpoint); errkey(rangecheck); errkey(stackoverflow); errkey(stackunderflow); errkey(syntaxerror); errkey(timeout); errkey(typecheck); errkey(undefined); errkey(undefinedfilename); errkey(undefinedresult); errkey(unimplemented); errkey(unmatchedmark); errkey(unregistered); errkey(VMerror); errkey(killprocess); }