home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
600-699
/
ff669.lha
/
Post
/
post17s.lzh
/
postinit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-13
|
8KB
|
331 lines
/* PostScript interpreter file "postinit.c" - initialiation (Amiga)
* (C) Adrian Aylward 1989, 1991
*
* This file contains the code to initialise the interpreter library and
* interpret a file or string. It is heavily Amiga dependent, and also
* Lattice dependent for the construction of file handles and the break
* and floating point error routines.
*/
# include "post.h"
# include <dos.h>
# include <exec/exec.h>
# include <exec/execbase.h>
# include <proto/dos.h>
# include <proto/exec.h>
# include <fcntl.h>
# include <ios1.h>
# include "postlib.h"
/* Assembler routines */
extern void flushpage(int y1, int y2);
extern int callextfunc(APTR func, int *argv, int argc);
/* The version number */
char version[] = POSTVER " Copyright Adrian Aylward 1989, 1992";
/* Lattice startup */
extern struct UFB _ufbs[];
/* External data (initialised to zero) */
APTR userdata, flushfunc, copyfunc;
int flushflag, flushlev, flushy1, flushy2;
int funcmax;
APTR *functab;
/* Machine type flags */
# ifdef M68881
short attnflags = AFF_68881|AFF_68020;
# else
short attnflags = 0;
# endif
/* Call external function */
void opcallextfunc(void)
{ struct object *token1, *token2, *aptr;
int argv[maxargs], argc, ires, func, i;
if (opernest < 2) error(errstackunderflow);
token2 = &operstack[opernest - 1];
token1 = token2 - 1;
if (token1->type != typeint) error(errtypecheck);
argc = token1->value.ival;
if (argc < 0) error(errrangecheck);
if (argc > maxargs) error(errlimitcheck);
if (opernest < argc + 3) error(errstackunderflow);
if (token2->type != typeint) error(errtypecheck);
func = token2->value.ival;
if (func < 0 || func >= funcmax) error(errrangecheck);
aptr = token1;
i = argc;
while (i)
{ i--;
aptr--;
switch (aptr->type)
{ case typeint:
case typereal:
case typebool:
argv[i] = aptr->value.ival;
break;
case typearray:
case typestring:
argv[i] = (int) vmvptr(aptr->value.vref);
break;
default:
error(errtypecheck);
}
}
aptr--;
ires = callextfunc(functab[func], argv, argc);
if (aptr->type == typenull)
argc++;
else if (aptr->type == typeint ||
aptr->type == typebool ||
aptr->type == typereal)
aptr->value.ival = ires;
else
error(errtypecheck);
opernest -= (argc + 2);
}
/* Initialise the interpreter
*
* N.B. this routine cannot use floating point, as we don't check for the
* presence of a fpu until after we have entered it */
int initialise(struct PSparm *parm)
{ memcpy((char *) &page, (char *) &parm->page, sizeof page);
userdata = parm->userdata;
flushfunc = parm->flushfunc;
copyfunc = parm->copyfunc;
funcmax = parm->funcmax;
functab = parm->functab;
/* Convert the DOS filehandles to unbuffered C files */
_ufbs[0].ufbfh = (long) parm->infh;
_ufbs[0].ufbflg |= UFB_RA|O_RAW|UFB_NC;
_ufbs[1].ufbfh = (long) parm->outfh;
_ufbs[1].ufbflg |= UFB_WA|O_RAW|UFB_NC;
_ufbs[2].ufbfh = (long) parm->errfh;
_ufbs[2].ufbflg |= UFB_WA|O_RAW|UFB_NC;
stdin->_file = 0;
stdin->_flag = _IOREAD;
stdout->_file = 1;
stdout->_flag = _IOWRT;
stderr->_file = 2;
stderr->_flag = _IOWRT;
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
/* Copy parameters and allocate memory */
memflen = parm->memflen;
memhlen = parm->memhlen;
memvmin = parm->memvlen;
memlmin = parm->memllen;
if (memflen == 0) memflen = defmemflen;
if (memhlen == 0) memhlen = defmemhlen;
if (memvmin == 0) memvmin = defmemvlen;
if (memlmin == 0) memlmin = defmemllen;
if (memflen < minmemflen) memflen = minmemflen;
if (memhlen < minmemhlen) memhlen = minmemhlen;
if (memvmin < minmemvlen) memvmin = minmemvlen;
if (memlmin < minmemllen) memlmin = minmemllen;
mempmin = memlmin / 3;
memlmin -= mempmin;
memllen = memplen = memilen = memxlen = memylen = 0;
memlbeg = mempbeg = memibeg = memxbeg = memybeg = NULL;
if ((memfbeg = memalloc(memflen)) == NULL ||
(memhbeg = memalloc(memhlen)) == NULL)
return 0;
/* Set up a temporary error trap and initialise the interpreter */
errorflag = 0;
if (setjmp(istate.errjmp) != 0)
{ fprintf(sstderr, "post: error: %s, during initialisation\n",
errorstring);
return errornum;
}
initint(1);
if (funcmax != 0) systemop(opcallextfunc, "callextfunc");
return -1;
}
/* Terminate interpreter */
void terminate(void)
{ tidyint();
memfree(memfbeg, memflen); memfbeg = NULL;
memfree(memhbeg, memhlen); memhbeg = NULL;
memfree(memlbeg, memllen); memlbeg = NULL; memllen = 0;
memfree(mempbeg, memplen); mempbeg = NULL; memplen = 0;
memfree(memibeg, memilen); memibeg = NULL; memilen = 0;
memfree(memxbeg, memxlen); memxbeg = NULL; memxlen = 0;
memfree(memybeg, memylen); memybeg = NULL; memylen = 0;
}
/* Interpret a string or file */
int intstring(char *string, int length, int flags)
{ struct object token, saveobj;
returncode = 0;
if (length < 0) length = strlen(string);
errorflag = 0;
if (setjmp(istate.errjmp) != 0) goto err;
prompting = 0;
if (flags & PSFLAGINTER)
{ prompting = 1;
fprintf(sstdout, "%s\n", version);
}
if (flags & PSFLAGSAVE)
vmsave(&saveobj);
if (flags & PSFLAGSTRING)
{ vmparm(0, string, length);
token.type = typestring;
token.flags = flagexec;
token.length = length;
token.value.vref = vmxref(0,0);
errorflag = 2;
interpret(&token);
errorflag = 0;
}
if (flags & PSFLAGFILE)
{ vmparm(0, NULL, 0);
fileopen(&token, openread | openfont, string, length);
token.flags |= flagexec;
errorflag = 2;
interpret(&token);
errorflag = 0;
fileclose(&token);
}
if (setjmp(istate.errjmp) != 0) goto err;
execnest = 0;
if (flags & PSFLAGCLEAR)
{ dictnest = 2;
opernest = 0;
}
if (flags & PSFLAGSAVE)
vmrest(saveobj.length, saveobj.value.ival);
if (flags & PSFLAGERASE)
erasepage();
if (returncode) return errornum;
return 0;
err:
fprintf(sstderr,
(flags & PSFLAGFILE) ?
"post: error: %s, file %*.*s\n" :
"post: error: %s\n",
errorstring, length, length, string);
return -1;
}
/* Convert an error number to a text string */
char *errstr(int errnum)
{ return (errnum > 0 && errnum <= errmax) ?
errortable[errnum] : NULL;
}
/* Dummy stub routine */
void stub(void)
{ return;
}
/* Dummy check abort routine */
void chkabort(void)
{ return;
}
/* A floating point error triggers "undefinedresult". */
void CXFERR(int code)
{ error(errundefinedresult);
}
/* A maths error triggers "undefinedresult". */
int matherr(struct exception *x)
{ error(errundefinedresult);
return 0;
}
/* Signal a floating point error */
void signalfpe(void)
{ error(errundefinedresult);
}
/* Signal an interrupt */
void signalint(int flag)
{ intsigflag = flag;
}
/* Set the page flush level */
int flushlevel(int lev)
{ if (lev == -1)
return flushlev++;
else
{ flushlev = lev;
if (lev == 0)
if (flushflag != 0)
{ flushflag = 0;
if (flushy1 != flushy2) flushpage(flushy1, flushy2);
}
return lev;
}
}
/* Flush the page to the screen, according to the level */
void flushlpage(int y1, int y2)
{ if (flushlev == 0)
{ if (y1 != y2) flushpage(y1, y2);
}
else
if (flushflag == 0)
{ flushflag = 1;
flushy1 = y1;
flushy2 = y2;
}
else
{ if (y1 < flushy1) flushy1 = y1;
if (y2 > flushy2) flushy2 = y2;
}
}
/* Allocate memory and clear it */
void *memalloc(int length)
{ return AllocMem(length, MEMF_CLEAR);
}
/* Free memory */
void memfree(void *beg, int length)
{ if (beg) FreeMem(beg, length);
}
/* End of file "postinit.c" */