#ifndef lint static char sccsid[] = "@(#)misc.c 9.6 88/01/20"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /*- Miscellaneous routines for the PostScript interpreter misc.c, Wed Jan 22 12:52:43 1986 David Rosenthal, Sun Microsystems */ #include #ifdef REF #include #endif #ifndef SYSVREF #include #endif #include "PostScript.h" #include "encoding.h" struct object syscommon_vec[32+256]; /* The set of globally defined compressed input tokens */ struct object * typed_result_matrix(mat, obj_type) struct object mat; { register struct object *ret, *p; if (mat.type != array_type || mat.value.substring.length < 6) return 0; ret = &body_of(&mat)->body.array.objects[mat.value.substring.start]; mat.value.substring.length = 6; for (p = &ret[6]; --p >= ret;) { object_decref(p); set_typed_object(p, obj_type); } return ret; } struct object * result_matrix(mat) struct object mat; { register struct object *ret, *p; if (mat.type != array_type || mat.value.substring.length < 6) return 0; ret = &body_of(&mat)->body.array.objects[mat.value.substring.start]; mat.value.substring.length = 6; for (p = &ret[6]; --p >= ret;) { object_decref(p); set_typed_object(p, fixed_type); } return ret; } struct object * arg_matrix(mat) struct object mat; { register struct object *ret, *p; if (mat.type != array_type || mat.value.substring.length < 6) return 0; ret = &body_of(&mat)->body.array.objects[mat.value.substring.start]; mat.value.substring.length = 6; for (p = &ret[6]; --p >= ret;) if (p->type != fixed_type) if (p->type == real_type) { p->type = fixed_type; p->value.fixed = fractf(p->value.real); } else return 0; return ret; } /* CURRENTFILE file */ currentfile(ee) register struct execution_environment *ee; { register struct execution_stack *les, *es = ee->pos; register struct object *optop = ee->optop; set_entire_typed_object(optop, null_type); for (les = es; les >= ee->execution_stack; les--) if (les->type == file_execution) { *optop = les->executed; object_incref(optop); optop->executable = 0; break; } ee->optop++; } /* file BYTESAVAILABLE int */ bytesavailable(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; if (optop[-1].type != file_type) ee->error_code = typecheck_error_code; else { register PSFILE *f = (body_of(optop - 1))->body.file.inbuf; if (f && !psio_error(f)) set_fixed_object(optop - 1, fracti(f->cnt)); else set_fixed_object(optop - 1, fracti(-1)); } } /* object n SETSYSINPUTTOKEN - */ setsysinputtoken(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; register n; if (optop[-1].type != fixed_type || object_has_refcnt(optop - 2)) { ee->error_code = typecheck_error_code; return; } n = cfloorfr(optop[-1].value.fixed); if (n < 0 || n >= sizeof syscommon_vec / sizeof syscommon_vec[0]) { ee->error_code = rangecheck_error_code; return; } syscommon_vec[n] = optop[-2]; ee->optop -= 2; } /* object n [file] SETFILEINPUTTOKEN - */ setfileinputtoken(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop, *dst; register n; register struct body *b; if (optop[-1].type != file_type) { currentfile(ee); optop = ee->optop; } else if (optop - 3 < ee->underflow) { ee->error_code = stackunderflow_error_code; return; } if (optop[-2].type != fixed_type || optop[-1].type != file_type) { ee->error_code = typecheck_error_code; return; } n = cfloorfr(optop[-2].value.fixed); if (n < 0 || n >= 32 + 4 * 256) { ee->error_code = rangecheck_error_code; return; } b = body_of(optop - 1); if (n >= b->body.file.ntok) { register ntok = n + 10; if (b->body.file.tok) b->body.file.tok = (struct object *) snooprealloc("misc.c", b->body.file.tok, ntok * sizeof(struct object)); else b->body.file.tok = (struct object *) snoopalloc("misc.c", ntok * sizeof(struct object)); bzero(b->body.file.tok + b->body.file.ntok, (ntok - b->body.file.ntok) * sizeof(struct object)); b->body.file.ntok = ntok; } dst = &b->body.file.tok[n]; object_decref(dst); *dst = optop[-3]; /* don't have to incref dst since we're pulling it off the stack and would just have to decref it again anyway */ ee->optop -= 3; } #ifndef REF static outofbandprint(ee) register struct execution_environment *ee; { char buf[1]; register PSFILE *psf = ee->stdprnt->body.file.outbuf; if (ee->optop[-1].type != fixed_type) { ee->error_code = typecheck_error_code; return; } if (psf == 0 || psio_error(psf)) { ee->error_code = ioerror_error_code; return; } buf[0] = cfloorfr(ee->optop[-1].value.fixed); ee->optop--; send(psio_fileno(psf), buf, sizeof buf, MSG_OOB); } #endif static userdict(ee) register struct execution_environment *ee; { if (ee->dict_top - ee->dictionary_stack < 2) { ee->error_code = stackunderflow_error_code; return; } set_typed_bodied_object(ee->optop, dictionary_type, ee->dictionary_stack[1].body); ee->optop->value.substring.length = ee->dictionary_stack[1].body->body.array.size; incref(ee->dictionary_stack[1].body); ee->optop++; } static vmstatus(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; set_fixed_object(optop,QVMavail*((1<<16)/1000)); set_fixed_object(optop+1,QVMused*((1<<16)/1000)); #ifdef mc68000 #ifdef SUN asm(" .globl curbrk\n"); asm(" movl curbrk,_VMbreak\n"); #else VMbreak = (int)sbrk(0); #endif #else VMbreak = (int)sbrk(0); #endif set_fixed_object(optop+2, VMbreak*((1<<16)/1000)); ee->optop += 3; } static setdash(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; register alen, i; fract buf[40]; if (optop[-1].type != fixed_type || optop[-2].type != array_type) { typecheck_error: ee->error_code = typecheck_error_code; return; } alen = optop[-2].value.substring.length; if (alen > sizeof buf / sizeof buf[0]) alen = sizeof buf / sizeof buf[0]; optop = body_of(optop-2)->body.array.objects + optop[-2].value.substring.start; for (i = 0; i < alen; i++, optop++) switch (optop->type) { case fixed_type: buf[i] = optop->value.fixed; break; case real_type: buf[i] = optop->value.real; break; default: goto typecheck_error; } cs_setdash(&ee->gontext, buf, alen, ee->optop[-1].value.fixed); decref(body_of(ee->optop - 2)); ee->optop -= 2; } static currentdash(ee) register struct execution_environment *ee; { register struct object *optop = ee->optop; fract *arr; fract offset; int len; cs_currentdash(&ee->gontext, &arr, &len, &offset); set_fixed_object(optop+1, offset); *optop = make_array(len); optop = body_of(optop)->body.array.objects; while (--len >= 0) { set_fixed_object(optop, *arr); arr++; optop++; } ee->optop += 2; } static dashpath(ee) register struct execution_environment *ee; { cs_dashpath(&ee->gontext); } initialize_miscellaneous() { define_operator("setsysinputtoken", setsysinputtoken, 0, 2, 0); define_operator("setfileinputtoken", setfileinputtoken, 0, 2, 0); define_operator("currentfile", currentfile, 0, 0, 1); #ifndef REF define_operator("outofbandprint", outofbandprint, 0, 1, 0); #endif define_operator("userdict", userdict, 0, 0, 1); define_operator("vmstatus", vmstatus, 0, 0, 3); define_operator("bytesavailable", bytesavailable, 0, 1, 1); define_operator("setdash", setdash, 0, 2, 0); define_operator("currentdash", currentdash, 0, 0, 2); define_operator("dashpath", dashpath, 0, 0, 0); }