]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/ghostscript/errpage.ps
sed: allow whitespace after ! negation (thanks k0ga)
[plan9front.git] / sys / lib / ghostscript / errpage.ps
1 %!
2 %    Copyright (C) 1992, 1996, 1998 Aladdin Enterprises.  All rights reserved.
3
4 % This software is provided AS-IS with no warranty, either express or
5 % implied.
6
7 % This software is distributed under license and may not be copied,
8 % modified or distributed except as expressly authorized under the terms
9 % of the license contained in the file LICENSE in this distribution.
10
11 % For more information about licensing, please refer to
12 % http://www.ghostscript.com/licensing/. For information on
13 % commercial licensing, go to http://www.artifex.com/licensing/ or
14 % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
15 % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
16
17 % $Id: errpage.ps,v 1.4 2002/02/21 21:49:28 giles Exp $
18 % Print an informative error page if an error occurs.
19 % Inspired by Adobe's `ehandler.ps' and David Holzgang's PinPoint.
20
21 /EPdict 80 dict def
22 EPdict begin
23
24 /escale 12 def
25 /efont /Helvetica findfont escale scalefont def
26 /eheight escale 1.2 mul def
27
28 % Miscellaneous utilities
29 /xdef
30  { exch def
31  } bind def
32
33 % Define `show' equivalents of = and ==
34
35 /show=
36  { =string { cvs } stopped { pop pop (==unprintable==) } if show
37  } bind def
38
39 /.dict 18 dict def
40 .dict begin
41   /.buf =string def
42   /.cvp {.buf cvs show} bind def
43   /.nop {(-) .p type .cvp (-) .p} bind def
44   /.p {show} bind def
45   /.p1 {( ) dup 0 4 -1 roll put show} bind def
46   /.print
47         {dup type .dict exch known
48          {dup type exec} {.nop} ifelse
49         } bind def
50   /integertype /.cvp load def
51   /nulltype { pop (null) .p } bind def
52   /realtype /.cvp load def
53   /booleantype /.cvp load def
54   /nametype
55         {dup xcheck not {(/) .p} if
56          dup length .buf length gt
57           {dup length string}
58           {.buf}
59          ifelse cvs .p} bind def
60   /arraytype
61         {dup rcheck
62           {dup xcheck {(})({)} {(])([)} ifelse .p
63            exch () exch
64            {exch .p .print ( )} forall pop .p}
65           {.nop}
66          ifelse} bind def
67   /operatortype
68         {(--) .p .cvp (--) .p} bind def
69   /packedarraytype /arraytype load def
70   /stringtype
71         {dup rcheck
72           {(\() .p
73            {/.ch exch def
74             .ch 32 lt .ch 127 ge or
75             {(\\) .p .ch 8#1000 add 8 .buf cvrs 1 3 getinterval .p}
76             {.ch 40 eq .ch 41 eq or .ch 92 eq or
77              {(\\) .p} if
78              .ch .p1}
79             ifelse}
80            forall (\)) .p}
81           {.nop}
82          ifelse} bind def
83 end
84 /show==
85  { .dict begin .print end
86  } bind def
87
88 % Printing utilities
89
90 /eol
91  { /ey ey eheight sub def
92    ex ey moveto
93  } bind def
94 /setx
95  { /ex xdef ex ey moveto
96  } bind def
97 /setxy
98  { /ey xdef /ex xdef
99    ex ey moveto
100  } bind def
101 /indent
102  { /lx ex def
103    (    ) show currentpoint setxy
104  } bind def
105 /unindent
106  { lx setx
107  } bind def
108
109 % Get the name of the n'th dictionary on the (saved) dictionary stack.
110 /nthdictname    % n -> name true | false
111  { dup dstack exch get
112    exch -1 0
113     { dstack exch get
114        { 2 index eq { exch pop exit } { pop } ifelse
115        }
116       forall
117       dup type /nametype eq { exit } if
118     }
119    for
120    dup type /nametype eq { true } { pop false } ifelse
121  } bind def
122
123 % Find the name of a currently executing procedure.
124 /findprocname   % <proctail> findprocname <dstackindex> <procname> true
125                 % <proctail> findprocname false
126  { dup length /proclength xdef
127    dup type cvlit /proctype xdef
128    dstack length 1 sub -1 0
129     { dup dstack exch get
130        { dup type proctype eq
131           { dup rcheck { dup length } { -1 } ifelse proclength gt
132              { dup length proclength sub proclength getinterval 3 index eq
133                 { 3 -1 roll pop exit }
134                 { pop }
135                ifelse
136              }
137              { pop pop
138              }
139             ifelse
140           }
141           { pop pop
142           }
143          ifelse
144        }
145       forall
146       dup type /nametype eq { exit } if
147       pop
148     }
149    for
150    dup type /nametype eq { true } { pop false } ifelse
151  } bind def
152
153 % Error printing routine.
154 % The top 2 elements of the o-stack are systemdict and EPdict.
155 % For the moment, we ignore the possibility of stack overflow or VMerror.
156 /showerror      % <command> <countexecstack> <errorname> showerror -
157  {
158         % Restore the error handlers.
159
160    saveerrordict { errordict 3 1 roll put } forall
161    $error /recordstacks false put
162
163         % Save information from the stacks.
164
165    /saveerror xdef
166    countexecstack array execstack
167    0 3 -1 roll 1 sub getinterval
168    /estack xdef
169    /savecommand xdef
170
171    countdictstack array dictstack
172    dup length 2 sub 0 exch getinterval
173    /dstack xdef
174
175         % Save state variables that will be reset.
176         % (We could save and print a lot more of the graphics state.)
177
178    /savefont currentfont def
179    mark { savefont /FontName get =string cvs cvn } stopped
180     { cleartomark null }
181     { exch pop dup length 0 eq { pop null } if }
182    ifelse /savefontname xdef
183    efont setfont
184
185     { currentpoint } stopped { null null } if
186    /savey xdef /savex xdef
187    0 0
188     { pop pop }
189     { pop pop 1 add }
190     { pop pop pop pop pop pop exch 1 add exch }
191     { }
192    pathforall
193    /savelines xdef /savecurves xdef
194    /savepathbbox { [ pathbbox ] } stopped { pop null } if def
195
196    initmatrix
197
198    clippath pathbbox
199      /savecliptop xdef /saveclipright xdef
200      /saveclipbottom xdef /saveclipleft xdef
201    initclip
202
203    initgraphics
204
205         % Eject the current page.
206
207    showpage
208
209         % Print the page heading.
210
211    18 clippath pathbbox newpath
212    4 1 roll pop pop pop eheight sub 12 sub setxy
213    product (Product: )
214    statusdict /printername known
215     { 100 string statusdict begin printername end
216       dup length 0 gt
217        { exch pop exch pop (Printer name: ) }
218        { pop }
219       ifelse
220     }
221    if show show eol
222    (Interpreter version ) show version show eol
223    (Error: ) show saveerror show= eol
224    (Command being executed: ) show /savecommand load show= eol
225    currentfile { fileposition } stopped
226     { pop }
227     { (Position in input file: ) show show= eol }
228    ifelse eol
229
230         % Print the current graphics state.
231
232    (Page parameters:) show eol indent
233    (page size: ) show
234      gsave clippath pathbbox grestore
235      exch 3 index sub show= (pt x ) show
236      exch sub show= (pt) show pop eol
237    (current position: ) show
238    savex null eq
239     { (none) show }
240     { (x = ) show savex show= (, y = ) show savey show= }
241    ifelse eol
242    savelines savecurves add 0 eq
243     { (current path is empty) show
244     }
245     { (current path: ) show savelines show= ( line(s), ) show
246       savecurves show= ( curve(s)) show eol
247       (path bounding box: ) show savepathbbox show==
248     }
249    ifelse eol
250    (current font: ) show
251      savefontname dup null eq
252       { pop (--no name--) show }
253       { show= ( ) show
254         gsave
255         savefontname findfont /FontMatrix get matrix invertmatrix
256         grestore
257         savefont /FontMatrix get matrix concatmatrix
258         dup 1 get 0 eq 1 index 2 get 0 eq and
259         1 index 4 get 0 eq and 1 index 5 get 0 eq and
260         1 index 0 get 2 index 3 get eq and
261          { 0 get show= (pt) show }
262          { (scaled by ) show show= }
263         ifelse
264       }
265      ifelse eol
266    eol unindent
267
268         % Print the operand stack.
269
270    /stky ey def
271    (Operand stack:) show eol indent
272    count { show== eol } repeat
273    eol unindent
274
275         % Print the dictionary stack.
276
277    (Dictionary stack:) show eol indent
278    dstack length 1 sub -1 0
279     { nthdictname { show= } { (<unknown>) show } ifelse eol
280     } for
281    eol unindent
282
283         % Print the execution stack.
284
285    280 stky setxy
286    (Execution stack:) show eol indent
287    estack length 1 sub -1 1
288     { estack exch get
289       dup type /operatortype eq
290        { show= eol
291        }
292        { dup type dup /arraytype eq exch /packedarraytype eq or
293           { dup xcheck
294              { dup rcheck
295                 { findprocname
296                    { show= nthdictname { ( in ) show show= } if eol
297                    }
298                   if
299                 }
300                 { pop
301                 }
302                ifelse
303              }
304              { pop
305              }
306             ifelse
307           }
308           { pop
309           }
310          ifelse
311        }
312       ifelse
313     } for eol unindent
314
315         % Print the next few lines of input.
316         % Unfortunately, this crashes on an Adobe printer.
317
318 (
319    (Next few lines of input:) show eol indent
320    /input currentfile def
321    mark { 4
322     { input ( ) readstring not { pop exit } if
323       dup 0 get dup 10 eq
324        { pop pop eol 1 sub dup 0 eq { pop exit } if }
325        { dup 13 eq { pop pop } { pop show } ifelse }
326       ifelse
327     }
328    loop } stopped cleartomark eol unindent
329 ) pop
330
331         % Wrap up.
332
333    showpage
334    quit
335
336  } def
337
338 % Define the common procedure for handling errors.
339 /doerror
340  { systemdict begin EPdict begin showerror
341  } bind def
342
343 end
344
345 % Install our own error handlers.
346
347 /EPinstall
348  { EPdict begin
349    /saveerrordict errordict length dict def
350    errordict saveerrordict copy pop
351    errordict
352     { pop [ /countexecstack load 2 index cvlit /doerror load /exec load ] cvx
353       errordict 3 1 roll put
354     } forall
355    errordict /handleerror
356      [ /countexecstack load /handleerror /doerror load /exec load
357      ] cvx
358    put
359    end
360  } bind def
361
362 EPinstall