[comp.sources.bugs] Postscript Interpereter bugs & enhancements

jm36+@andrew.cmu.edu (John Gardiner Myers) (01/08/88)

#--------------------------Cut Here--------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before the "#! /bin/sh" line,
# then unpack it by saving it in a file and typing "sh file."
#
# Wrapped by John Gardiner Myers (jm36) at ithaca.andrew.cmu.edu on Sun Jan  3 
16:33:37 1988
#
# unpacks with default permissions
#
# Contents : CHANGES.JGM Diff.psrc Diff.source DoPatch
#	postscript/demos/buildcachefont.ps
#
if `test ! -s CHANGES.JGM`
then
echo "x - CHANGES.JGM"
cat > CHANGES.JGM << '@EOF'
Here is a patch that makes several bug fixes and enhancements to the 
Postscript
interpreter recently posted.  The changes are:


Bugs fixed:

Half-implemented the missing operator "vmstatus".  The number of savelevels is
correct (as far as the broken implementation of "save" and "restore" allow),
but the amount of memory used and free is a lie.

Implemented the missing operator "noaccess".

Fixed a bug in the operator "stopped".  Previously it only worked on arrays,
but now it works on any executable object.

Fixed the parsing bug for reals with a trailing period (e.g. "4.") which
resulted in the "undefined in operater exec" errors reported to the net.

Changed an occurance of the variable "signed" to "signedp" as the former is an
ANSI C keyword.

Added a version of the missing file postscript/demos/buildcachefont.ps


Enhancements made:

Macroized PanicIf()

Changed "undefined in operator exec" errors to instead report 
"undefined in operator foo", where "foo" is the operator that was undefined.

Fixed imagemask to deal better with images that have to be shrunk.  Bitmapped
fonts intended for 300 dpi printers look much better now.
(Change courtesy of Christopher Cox, cc4b@andrew.cmu.edu)

Tweaked makefile to deal better with sun3.

Added "getenv" operator.  The syntax is:
	<string> getenv <string> <true>
if the environment variable exists, or
	<string> getenv <false>
if it does not.


				John G. Myers
				jm36@andrew.cmu.edu
				jgm@k.gp.cs.cmu.edu
@EOF
else
  echo "shar: Will not over write CHANGES.JGM"
fi
if `test ! -s Diff.psrc`
then
echo "x - Diff.psrc"
cat > Diff.psrc << '@EOF'
diff -cr orig/postscript/psrc ./postscript/psrc
*** orig/postscript/psrc	Sun Jan  3 14:22:51 1988
--- ./postscript/psrc	Sun Dec 13 22:58:09 1987
***************
*** 10,17 ****
  
  /bind {} def
  
! /save { gsave /save } def
! /restore { grestore pop } def
  /raise { errordict exch get exec } def
  
  /beep ( ) dup 0 7 put def
--- 10,21 ----
  
  /bind {} def
  
! %% Start mods by jgm
! /$$SAVELEVEL 0 def
! /save { gsave /save /$$SAVELEVEL $$SAVELEVEL 1 add def } def
! /restore { grestore pop /$$SAVELEVEL $$SAVELEVEL 1 sub def } def
! /vmstatus { $$SAVELEVEL 10000 10000 } def
! %% End mods by jgm
  /raise { errordict exch get exec } def
  
  /beep ( ) dup 0 7 put def
@EOF
else
  echo "shar: Will not over write Diff.psrc"
fi
if `test ! -s Diff.source`
then
echo "x - Diff.source"
cat > Diff.source << '@EOF'
diff -cr orig/source/array.c ./source/array.c
*** orig/source/array.c	Sun Jan  3 14:21:55 1988
--- ./source/array.c	Sat Dec 12 01:05:28 1987
***************
*** 17,22 ****
--- 17,23 ----
  
  static int forAll (), ForAll (), PReadOnly (), PExecOnly (), PrCheck (), 
PwCheck ();
  static int PutInterval (), GetInterval (), Put (), Get (), Length (), Copy 
(), Eq ();
+ static int PNoAccess (); /*jgm*/
  
  int ExecArray ();
  Object Marker;
***************
*** 53,58 ****
--- 54,60 ----
   	TypeInstallOp (Array, "length",	 	PLength,	1, 1, 0, 0, Array);
   	TypeInstallOp (Array, "copy", 		Copy,		2, 0, 0, 0, Array, Array);
   	TypeInstallOp (Array, "forall", 	ForAll,		2, 0, 0, 4, Array, Array);
+  	TypeInstallOp (Array, "noaccess", 	PNoAccess,	1, 1, 0, 0, Array); /*jgm*/
   	TypeInstallOp (Array, "executeonly", 	PExecOnly,	1, 1, 0, 0, Array);
   	TypeInstallOp (Array, "readonly", 	PReadOnly,	1, 1, 0, 0, Array);
   	TypeInstallOp (Array, "rcheck", 	PrCheck,	1, 1, 0, 0, Array);
***************
*** 385,390 ****
--- 387,398 ----
   	 		body[i] = Pop (OpStack);
   	 	return Push (OpStack, array);
   	 }
+  }
+ 
+ /* PNoAccess by jgm */
+ static int PNoAccess (item) Object item;
+  {
+  	return Push (OpStack, NoAccess (item));
   }
  
  static int PExecOnly (item) Object item;
diff -cr orig/source/cache.c ./source/cache.c
*** orig/source/cache.c	Sun Jan  3 14:22:42 1988
--- ./source/cache.c	Thu Dec 10 21:26:47 1987
***************
*** 501,512 ****
  	if ((ccache = SearchCache (m, BodyFontID (DictLoad (gstate->font, Fid)))) 
== NULL)
   		return Error (PInvFont);
   	
-   	Message (disk_name);
  	VOID sprintf (disk_name,
   		"%s/cache/%.*s/%3d%3d%3d%3d",
   		library,
   		lengthName (font_name), BodyName (font_name),
   		(int) right.vx, (int) right.vy, (int) bottom.vx, (int) bottom.vy);
   	
   	if ((fp = fopen (disk_name, "w")) == NULL)
   		return Error (PInvFileAccess);
--- 501,512 ----
  	if ((ccache = SearchCache (m, BodyFontID (DictLoad (gstate->font, Fid)))) 
== NULL)
   		return Error (PInvFont);
   	
  	VOID sprintf (disk_name,
   		"%s/cache/%.*s/%3d%3d%3d%3d",
   		library,
   		lengthName (font_name), BodyName (font_name),
   		(int) right.vx, (int) right.vy, (int) bottom.vx, (int) bottom.vy);
+   	Message (disk_name); /* moved from before to after prev line -- jgm */
   	
   	if ((fp = fopen (disk_name, "w")) == NULL)
   		return Error (PInvFileAccess);
diff -cr orig/source/config.c ./source/config.c
*** orig/source/config.c	Sun Jan  3 14:19:54 1988
--- ./source/config.c	Fri Jan  1 13:58:10 1988
***************
*** 87,91 ****
   	Install ("polytype",		DictFrom (Poly));
  	Install ("fonttype",		DictFrom (FontID));
  	
! 	Install ("version",	StringFrom ("Version 1.4"));
   }
--- 87,91 ----
   	Install ("polytype",		DictFrom (Poly));
  	Install ("fonttype",		DictFrom (FontID));
  	
! 	Install ("version",	StringFrom ("Version 1.4 with mods by jgm")); /* jgm */
   }
diff -cr orig/source/control.c ./source/control.c
*** orig/source/control.c	Sun Jan  3 14:26:55 1988
--- ./source/control.c	Sun Dec 13 23:13:46 1987
***************
*** 65,71 ****
   	InstallOp ("loop",	PLoop,		1, 0, 0, 4, Array);
  	InstallOp ("exit",	PExit,		0, 0, 0, 0);
   	InstallOp ("stop",	PStop,		0, 1, 0, 0);
!  	InstallOp ("stopped",	PStopped,	1, 1, 0, 3, Array);
   	InstallOp ("quit",	PQuit, 		0, 0, 0, 0);
   	InstallOp ("start",	PStart, 	0, 0, 0, 0);
   	InstallOp ("countexecstack",
--- 65,72 ----
   	InstallOp ("loop",	PLoop,		1, 0, 0, 4, Array);
  	InstallOp ("exit",	PExit,		0, 0, 0, 0);
   	InstallOp ("stop",	PStop,		0, 1, 0, 0);
! 	/* Changed from "Array" to "Poly" --jgm*/
!  	InstallOp ("stopped",	PStopped,	1, 1, 0, 3, Poly);
   	InstallOp ("quit",	PQuit, 		0, 0, 0, 0);
   	InstallOp ("start",	PStart, 	0, 0, 0, 0);
   	InstallOp ("countexecstack",
diff -cr orig/source/dictionary.c ./source/dictionary.c
*** orig/source/dictionary.c	Sun Jan  3 14:22:55 1988
--- ./source/dictionary.c	Sat Dec 12 01:06:49 1987
***************
*** 23,28 ****
--- 23,29 ----
  static int PDict (), PBegin (), PEnd (), PDef (), PStore (), PKnown (), 
PLoad ();
  static int PrCheck (), PwCheck (), PReadOnly (), EqDict (); 
  static int PWhere (), PMaxLength (), PCurrentDict (); 
+ static int PNoAccess (); /*jgm*/
  
  static int hash_tries = 0, hash_collisions = 0, hash_attempts = 0;
  static int PHashStats (), PDictHash ();
***************
*** 57,62 ****
--- 58,64 ----
  	TypeInstallOp (Dictionary, "length", 	LengthDict,	1, 1, 0, 0, Dictionary);
  	TypeInstallOp (Dictionary, "copy", 	CopyDict,	2, 0, 0, 0, Dictionary, 
Dictionary);
  	TypeInstallOp (Dictionary, "forall", 	ForDict,	2, 0, 0, 4, Dictionary, 
Array);
+  	TypeInstallOp (Dictionary, "noaccess", 	PNoAccess,	1, 1, 0, 0, 
Dictionary); /*jgm*/
   	TypeInstallOp (Dictionary, "readonly", 	PReadOnly,	1, 1, 0, 0, 
Dictionary);
   	TypeInstallOp (Dictionary, "rcheck", 	PrCheck,	1, 1, 0, 0, Dictionary);
   	TypeInstallOp (Dictionary, "wcheck", 	PwCheck,	1, 1, 0, 0, Dictionary);
***************
*** 511,516 ****
--- 513,524 ----
  static int PCurrentDict ()
   {
    	return Push (OpStack, Top (DictStack));
+  }
+ 
+ /* PNoAccess by jgm */
+ static int PNoAccess (item) Object item;
+  {
+  	return Push (OpStack, NoAccess (item));
   }
  
  static int PReadOnly (item) Object item;
diff -cr orig/source/image.c ./source/image.c
*** orig/source/image.c	Sun Jan  3 14:22:32 1988
--- ./source/image.c	Mon Dec 28 18:17:04 1987
***************
*** 353,363 ****
  	else
  	 {
  	 	middle2 = NewBitmapHardware (dwidth, h);
! 		for (i = 0; i < dwidth; i++)
! 			BitBlt (from, 	middle2,
! 				NewDevicePoint ((int) (i/xscale), 0), NewDevicePoint (i, 0),
  				NewDevicePoint (1, h),
  				ROP_OR);
  	 }
  	
  	if (dheight > h)
--- 353,365 ----
  	else
  	 {
  	 	middle2 = NewBitmapHardware (dwidth, h);
! 		/* begin changes by cc4b --jgm */
! 		for (i = 0; i < w; i++)
! 			BitBlt( from,  middle2,
! 				NewDevicePoint (i, 0), NewDevicePoint( (int) (i * xscale), 0),
  				NewDevicePoint (1, h),
  				ROP_OR);
+ 		/* end changes by cc4b --jgm */
  	 }
  	
  	if (dheight > h)
***************
*** 382,392 ****
  	else
  	 {
  		high2 = NewBitmapHardware (dwidth, dheight);
! 		for (i = 0; i < dheight; i++)
! 			BitBlt (middle2, high2,
! 				NewDevicePoint (0, (int) (i/yscale)), NewDevicePoint (0, i),
  				NewDevicePoint (dwidth, 1),
  				ROP_OR);
  	 }
   	return high2;
   }
--- 384,397 ----
  	else
  	 {
  		high2 = NewBitmapHardware (dwidth, dheight);
! 
! 		/* begin changes by cc4b --jgm */
! 		for (i = 0; i < h; i++ )
! 			BitBlt( middle2, high2,
! 				NewDevicePoint (0, i), NewDevicePoint( 0, (int) (i * yscale)),
  				NewDevicePoint (dwidth, 1),
  				ROP_OR);
+ 		/* end changes by cc4b  --jgm */
  	 }
   	return high2;
   }
diff -cr orig/source/integer.c ./source/integer.c
*** orig/source/integer.c	Sun Jan  3 14:21:32 1988
--- ./source/integer.c	Thu Dec 10 20:44:17 1987
***************
*** 72,80 ****
  
  int StrictMul (a, b) int a, b;
   {
!  	int atop, abot, btop, bbot, sum, signed;
   	
!  	signed = (a < 0) != (b < 0);
   	a = a < 0 ? -a : a;
   	b = b < 0 ? -b : b;
   	abot = a & LowMask;
--- 72,81 ----
  
  int StrictMul (a, b) int a, b;
   {
! 	/* Variable signed changed to signedp by jgm for ANSI C */
!  	int atop, abot, btop, bbot, sum, signedp;
   	
!  	signedp = (a < 0) != (b < 0);
   	a = a < 0 ? -a : a;
   	b = b < 0 ? -b : b;
   	abot = a & LowMask;
***************
*** 86,92 ****
   	sum = ((unsigned) sum >> Word2) + atop * btop;
   	if (sum != 0 || a * b < 0)
   		kill (getpid (), SIGFPE);
!  	return signed ? -a * b : a * b;
   }
  
  int StrictAdd (a, b) int a, b;
--- 87,93 ----
   	sum = ((unsigned) sum >> Word2) + atop * btop;
   	if (sum != 0 || a * b < 0)
   		kill (getpid (), SIGFPE);
!  	return signedp ? -a * b : a * b;
   }
  
  int StrictAdd (a, b) int a, b;
diff -cr orig/source/main.c ./source/main.c
*** orig/source/main.c	Sun Jan  3 14:22:13 1988
--- ./source/main.c	Sun Dec 13 00:40:04 1987
***************
*** 187,210 ****
    		 	Object newitem;
    		 	
    		 	newitem = Load (item);
!   		 	if (TypeOf (newitem) != Condition)
!   		 	 	item = newitem;
!   		 	
!   		 	if (!xCheck (item))
!  				res = Push (OpStack, item);
!   			else if (TypeOf (item) == Operator)
!   				res = ExecOperator (item);
!   			else if (TypeOf (item) == Array)
!   				res = ExecArray (item);
!   			else if (TypeOf (item) == File)
!   				res = ExecFile (item);
! 			else
!   			 {
!  		 		res = Push (OpStack, item);
!   		 		exop = Lookup (TypeOf (item), execName);
!   		 		if (TypeOf (exop) != Condition)
!   		 			VOID Push (ExecStack, exop);
!   		 	 }
     		 }
    		else
    		 {
--- 187,216 ----
    		 	Object newitem;
    		 	
    		 	newitem = Load (item);
! 			/* begin jgm */
! 			if (TypeOf (newitem) == Condition) {
! 			    VOID Push(OpStack, item);
! 			    res = Push(ExecStack, DictLoad(ErrorDict,PUndefined));
! 			} else {
! 			    /* end jgm */
! 			    item = newitem;
! 
! 			    if (!xCheck (item))
! 				res = Push (OpStack, item);
! 			    else if (TypeOf (item) == Operator)
! 				res = ExecOperator (item);
! 			    else if (TypeOf (item) == Array)
! 				res = ExecArray (item);
! 			    else if (TypeOf (item) == File)
! 				res = ExecFile (item);
! 			    else
! 			    {
! 				res = Push (OpStack, item);
! 				exop = Lookup (TypeOf (item), execName);
! 				if (TypeOf (exop) != Condition)
! 				    VOID Push (ExecStack, exop);
! 			    }
! 			} /* jgm */
     		 }
    		else
    		 {
***************
*** 340,350 ****
   		return TRUE;
   }
  
! PanicIf (cond, s) int cond; char *s;
!  {
!  	if (cond)
!  		Panic (s);
!  }
  
  Panic (s) char *s;
   {
--- 346,358 ----
   		return TRUE;
   }
  
! #ifdef needed /* Macroized --jgm */
! XPanicIf (cond, s) int cond; char *s;
! X {
! X 	if (cond)
! X 		Panic (s);
! X }
! #endif
  
  Panic (s) char *s;
   {
***************
*** 392,397 ****
--- 400,416 ----
  	return o;
   }
  
+ /* NoAccess by jgm */
+ Object NoAccess (o) Object o;
+  {
+  	if (o.type == Dictionary)
+  		o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE | EXECUTABLE);
+  	else
+  		o.flags &= ~(READABLE | WRITEABLE | EXECUTABLE);
+  	return o;
+  }
+ 
+ 
  Object ExecOnly (o) Object o;
   {
   	if (o.type == Dictionary)
***************
*** 398,404 ****
   		o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE);
   	else
   		o.flags &= ~(READABLE | WRITEABLE);
!  	return ReadOnly (o);
   }
  
  Object ReadOnly (o) Object o;
--- 417,423 ----
   		o.u.Dictionary->dict_flags &= ~(READABLE | WRITEABLE);
   	else
   		o.flags &= ~(READABLE | WRITEABLE);
!  	return o;   /* Removed redundant call to ReadOnly -- jgm */
   }
  
  Object ReadOnly (o) Object o;
diff -cr orig/source/main.h ./source/main.h
*** orig/source/main.h	Sun Jan  3 14:19:59 1988
--- ./source/main.h	Sat Dec 12 00:58:43 1987
***************
*** 74,79 ****
--- 74,80 ----
   	Object overflow, underflow, *stack_body;
   } *Stack, StackOb;
   
+ Object NoAccess (); /* jgm */
  Object SameFlags (), MakeObject (), Cvx (), Cvlit (), ReadOnly (), WriteOnly 
(), ExecOnly ();
  int OpCheck (), min (), rCheck (), wCheck (), xCheck ();
  Object MakeArray (), ParseArray (), getArray (), getIArray (), *BodyArray 
();
***************
*** 164,166 ****
--- 165,170 ----
  	((getchbuf = getc (BodyFile(file)->f.f_ptr)), \
  		((getchbuf != EOF) ? getchbuf : ((BodyFile(file)->available = 0), Close 
(file), EOF))) \
  	: GeneralGetch (file))
+ 
+ /* Next line --jgm */
+ #define PanicIf(flag,s) do { if (flag) Panic(s); } while (0)
diff -cr orig/source/math.c ./source/math.c
*** orig/source/math.c	Sun Jan  3 14:20:43 1988
--- ./source/math.c	Fri Dec 11 22:54:46 1987
***************
*** 108,113 ****
--- 108,115 ----
   	 {
   	 	int olength = length, dval;
   	 	
+ 		if (length == 0) return MakeReal (sign * (double)ival); /*jgm*/
+ 
  		fval = ival;
   		dval = ParseInteger (&s, &length, 10);
   		fval += dval * pow (10.0, (float)(length - olength));
diff -cr orig/source/makefile ./source/makefile
*** orig/source/makefile	Sun Jan  3 14:19:33 1988
--- ./source/makefile	Sun Jan  3 15:37:00 1988
***************
*** 4,16 ****
  LIBS=libww.a -lsuntool -lsunwindow -lpixrect -g
  GRAPHICS=cache.o colour.o device.o fill.o font.o gsave.o image.o mat.o 
matrix.o\
  	pat.o path.o state.o stroke.o
  CFLAGS=-O
  
  PS:	$(OBJECTS) $(GRAPHICS) hard.o canon.a
  	cc $(CFLAGS)  $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS
  
! sunPS:	$(OBJECTS) $(GRAPHICS) hard.o canon.a pixrect
! 	cc $(CFLAGS)  $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm -lpixrect -o sunPS
  
  CPS:	$(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o
  	cc $(CFLAGS)  $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm 
`libs` -o CPS
--- 4,23 ----
  LIBS=libww.a -lsuntool -lsunwindow -lpixrect -g
  GRAPHICS=cache.o colour.o device.o fill.o font.o gsave.o image.o mat.o 
matrix.o\
  	pat.o path.o state.o stroke.o
+ 
+ # For SUN with 68881
+ #CFLAGS=-O -f68881
+ 
+ # For others
  CFLAGS=-O
  
+ #default: sunPS
+ 
  PS:	$(OBJECTS) $(GRAPHICS) hard.o canon.a
  	cc $(CFLAGS)  $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS
  
! sunPS:	$(OBJECTS) $(GRAPHICS) pixrect.o canon.a
! 	cc $(CFLAGS)  $(OBJECTS) $(GRAPHICS) pixrect.o canon.a -lm -lpixrect -o 
sunPS
  
  CPS:	$(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o
  	cc $(CFLAGS)  $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm 
`libs` -o CPS
***************
*** 31,39 ****
  all:	PS postscript viewer
  
  ww:	ww.o wwlib installww
- 
- pixrect:	pixrect.o
- 	cp pixrect.o hard.o
  
  sun:	ww wwsun
  
--- 38,43 ----
diff -cr orig/source/misc.c ./source/misc.c
*** orig/source/misc.c	Sun Jan  3 14:19:36 1988
--- ./source/misc.c	Sun Dec 13 22:03:56 1987
***************
*** 17,27 ****
--- 17,29 ----
  #endif
  
  static int PUserTime ();
+ static int PGetEnv (); /*jgm*/
   	
  InitMisc ()
   {
    	InstallOp ("usertime",	PUserTime,	0, 1, 0, 0);
   	InstallOp ("==", 	PolyFirst, 	1, 1, 0, 0, Poly);
+ 	InstallOp ("getenv",	PGetEnv,	1, 1, 0, 0, String); /*jgm*/
    }
  
  static int PUserTime ()
***************
*** 32,34 ****
--- 34,49 ----
  	times (&tbuf);
   	return Push (OpStack, MakeInteger ((int) (tbuf.tms_utime * 1000 / HZ)));
   }
+ 
+ /* PGetEnv by jgm */
+ static int PGetEnv(string) Object string;
+ {
+     char *s, *getenv();
+ 
+     s = getenv(BodyString(string));
+ 
+     if (s != NULL) {
+ 	VOID Push(OpStack, MakeString(s, strlen(s)));
+     }
+ 
+     return Push(OpStack, MakeBoolean(s != NULL));
diff -cr orig/source/string.c ./source/string.c
*** orig/source/string.c	Sun Jan  3 14:23:16 1988
--- ./source/string.c	Sat Dec 12 01:32:44 1987
***************
*** 22,27 ****
--- 22,28 ----
  static int Exec (), Token (), PString (), Search (), AnchorSearch (), Copy 
(), EqEq ();
  static int Length (), ForAll (), Get (), Put (), GetInterval (), PutInterval 
(), Eq (), Lt (), Le (), Gt (), Ge (), PrCheck (), PwCheck ();
  static int Cvi (), Cvr (), Cvs (), PReadOnly (), PExecOnly ();
+ static int PNoAccess (); /* jgm */
  
  InitString ()
   {
***************
*** 45,50 ****
--- 46,52 ----
   	TypeInstallOp (String, "put", 		Put,		3, 0, 0, 0, String, Integer, 
Integer);
   	TypeInstallOp (String, "getinterval", 	GetInterval,	3, 1, 0, 0, String, 
Integer, Integer);
   	TypeInstallOp (String, "putinterval", 	PutInterval,	3, 0, 0, 0, String, 
Integer, String);
+  	TypeInstallOp (String, "noaccess", 	PNoAccess,	1, 1, 0, 0, String); 
/*jgm*/
   	TypeInstallOp (String, "executeonly", 	PExecOnly,	1, 1, 0, 0, String);
   	TypeInstallOp (String, "readonly", 	PReadOnly,	1, 1, 0, 0, String);
   	TypeInstallOp (String, "rcheck", 	PrCheck,	1, 1, 0, 0, String);
***************
*** 530,535 ****
--- 532,543 ----
  	VOID Push (OpStack, False);
  	
  	return TRUE;
+  }
+ 
+ /* PNoAccess by jgm */
+ static int PNoAccess (item) Object item;
+  {
+  	return Push (OpStack, NoAccess (item));
   }
  
  static int PExecOnly (item) Object item;
diff -cr orig/source/viewer.c ./source/viewer.c
*** orig/source/viewer.c	Sun Jan  3 14:21:58 1988
--- ./source/viewer.c	Thu Dec 10 23:12:55 1987
***************
*** 310,318 ****
   	return res;
   }
  
! PanicIf (flag, s) int flag; char *s;
   {
-  	if (flag)
   		fprintf (stderr, "Viewer panic: %s\n", s),
   		exit (1);
   }
--- 310,318 ----
   	return res;
   }
  
! /* Removed conditional & changed PanicIf to Panic --jgm */
! Panic (s) char *s;
   {
   		fprintf (stderr, "Viewer panic: %s\n", s),
   		exit (1);
   }
@EOF
else
  echo "shar: Will not over write Diff.source"
fi
if `test ! -s DoPatch`
then
echo "x - DoPatch"
cat > DoPatch << '@EOF'
#!/bin/sh

(cd postscript ; patch) <Diff.psrc
(cd source ; patch) <Diff.source
@EOF
else
  echo "shar: Will not over write DoPatch"
fi
if `test ! -d postscript`
then
  mkdir postscript
  echo "mkdir postscript"
fi
if `test ! -d postscript/demos`
then
  mkdir postscript/demos
  echo "mkdir postscript/demos"
fi
if `test ! -s postscript/demos/buildcachefont.ps`
then
echo "x - postscript/demos/buildcachefont.ps"
cat > postscript/demos/buildcachefont.ps << '@EOF'
%!
%% Build the font cache
%% By John G. Myers

% fontname pointsize cachefont --
/cachefont {
	exch findfont exch scalefont setfont
	5 5 moveto
	( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ) show
	([\\]^_`abcdefghijklmnopqrstuvwxyz{|}~) show
	(\251\252\256\257\261\267\272\320) show
	savecurrentfont
	erasepage
} def

[  /Times-Roman /Helvetica /Times-Bold /Times-Italic /Helvetica-Oblique ]
{ dup 10 cachefont dup 12 cachefont 14 cachefont }
forall

@EOF
else
  echo "shar: Will not over write postscript/demos/buildcachefont.ps"
fi
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<!!!
      47     220    1474 CHANGES.JGM
      26     125     676 Diff.psrc
     554    2406   16397 Diff.source
       4      11      79 DoPatch
      19      55     468 postscript/demos/buildcachefont.ps
     650    2817   19094 total
!!!
wc CHANGES.JGM Diff.psrc Diff.source DoPatch 
postscript/demos/buildcachefont.ps | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
# to concatenate archives, remove anything after this line
exit 0