blob: f6da26a059b24fbe503534a5e8b805aa32574771 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
%!PS-Adobe-1.0
%% NOTE: don't use "end" operator until initialization is finished
%% NOTE: and push userdict into the dictionary stack.
%% NOTE: otherwise all initialization will fails due to invalid
%% NOTE: dictionary stack. at this time, systemdict is only in
%% NOTE: the dictionary stack.
% create userdict if it's not defined
false .setglobal
systemdict /userdict known not {
systemdict /userdict 200 dict .forceput % need to avoid the object sanity check.
} if
% change an allocation mode to global
true .setglobal
%%
%% Define procedures
%%
%%%
%%% pre-required operators
% key any odef -
/odef {
{
% prepare for error recovery
count copy count 2 idiv array astore
$error /.ostack 3 -1 roll put
null stopped {
$error /command null put
clear $error /.ostack get aload pop
stop
} if
} % -key- -any- -proc-
dup 13 4 -1 roll .forceput % -key- -proc-
dup 15 get % -key- -proc- -proc-
2 3 index .forceput
.odef
} bind .odef
%% disable .forceput for security reason
systemdict /.forceput .undef
systemdict /.odef .undef
%%%
%%% these aren't official operators/procedures for PostScript
% -string- runlibfile -
/runlibfile {
.findlibfile {
run
} if
} bind odef
% -file- any write=only -
/write=only {
.stringcvs writestring
} bind odef
% -file- any write==only -
/write==only {
.write==only
} bind odef
% any =only -
/=only {
(%stdout) (w) file exch write=only
} bind odef
% any ==only -
/==only {
(%stdout) (w) file exch write==only
} bind odef
% -string- -string- .concatstring -string-
/.concatstring {
exch dup length 2 index length add string
dup dup 4 2 roll copy
length 4 -1 roll putinterval
} bind def
% - .printversion -
/.printversion {
.product print .revision dup 1000000 idiv exch 1000000 mod dup 1000 idiv exch 1000 mod
( ) print 3 -1 roll ==only (.) print exch ==only (.) print ==only
( \(r) print .hgrevision ==only (\)\n\n) print
} bind def
% - .promptmsg -string-
/.promptmsg {
count mark (PS) 3 -1 roll dup 0 ne {
([) exch 4 string cvs (])
counttomark 1 sub {
.concatstring
} repeat
} {
pop
} ifelse
(>) .concatstring
exch pop
} bind def
systemdict /.statementedit known {
/..statementedit {
% null isn't exactly used. it's just pushed to align the depth of the stack.
.promptmsg //null exch .statementedit exch pop
} bind def
} {
/..statementedit {
prompt (%statementedit) (r) file
} bind def
} ifelse
%%%
%%% Level 1 operators
% string seek anchorsearch post match true | string false
/anchorsearch {
1 index 3 1 roll search {
length 0 eq {
3 -1 roll pop true
} {
pop pop false
} ifelse
} if
} bind odef
% any -string- cvs -substring-
/cvs {
exch .stringcvs exch copy
} bind odef
% key font|cidfont definefont font|cidfont
/definefont {
.definefont
} bind odef
% - executive -
/executive {
{
{
{..statementedit} stopped {
% need to detect an empty line separately to take care of /undefinedfilename.
$error /newerror get {
$error /errorname get /undefinedfilename eq {
pop pop .clearerror exit
} {
% we don't care of this error here.
stop
} ifelse
} if
} if
dup type /filetype eq {cvx exec} if
} stopped {
$error /newerror get {
errordict /handleerror get exec
.clearerror
} if
} if
} loop
} bind def
% key findfont -dict-
/findfont {
.findfont
} bind odef
% num floor num
/floor {
dup cvi
1 index 1 index sub
0 lt {
1 sub
} if
exch type /realtype eq {cvr} if
} bind odef
% -key- load -value-
/load {
dup where {
exch get
} {
/load errordict /undefined get exec
} ifelse
} bind odef
% matrix -matrix-
/matrix {
6 array identmatrix
} bind odef
% pstack -
/pstack {
0 1 count 3 sub {index ==} for
} bind odef
% - prompt -
/prompt {
.promptmsg print flush
} bind odef
% -array- index -array- putinterval -
% -string- index -string- putinterval -
/putinterval {
dup length
2 index add
3 index length gt {
/putinterval cvx
errordict /rangecheck get exec
} if
{2 index 2 index 3 -1 roll put 1 add} forall
pop pop
} bind odef
% - quit -
/quit {
0 .quit
} bind odef
% -string- run -
/run {
(r) file cvx exec
} bind odef
% stack -
/stack {
0 1 count 3 sub {index =} for
} bind odef
% key value store -
/store {
1 index where {
} {
currentdict
} ifelse
3 1 roll put
} bind odef
% key undefinefont -
/undefinefont {
.undefinefont
} bind odef
% - version -string-
/version {
(1000)
} odef
% any = -
/= {
=only (\n) print
} bind odef
% any == -
/== {
==only (\n) print
} bind odef
%% Initialize error procedures
% <command> <error> .seterror -
/.seterror {
$error /newerror true put
$error exch /errorname exch put
$error exch /command exch put
$error /.isstop true put
$error /recordstacks known {
$error /recordstacks get
} {
true
} ifelse {
% record stacks
count copy count 2 idiv array astore $error /ostack 3 -1 roll put
countexecstack array execstack $error /estack 3 -1 roll % -dict- /estack -array-
% modify estack to make a correct stack when an error actually happened
dup length 1 sub 0 exch getinterval % -dict- /estack -array-
dup length array copy % -dict- /estack -array-
dup dup length 1 sub $error /command get put put
countdictstack array dictstack $error /dstack 3 -1 roll put
} if
} bind def
% <command> <error> .defaulterrorhandler -
/.defaulterrorhandler {
% enter the local allocation mode in advance to avoid /invalidaccess again.
false .setglobal
.seterror
stop
} bind def
% - handleerror -
/handleerror {
errordict /handleerror get exec
} bind odef
% - .printerror -
/.printerror {
% stacking $error and evaluate the value doesn't work.
% because the executable object may be in the dictionary.
% it will does into the estack directly then.
$error /newerror get {
(Error: ) print $error /errorname get ==only
( in ) print $error /command get ==only
(\n) print
% save objects in current ostack
count array astore
$error /ostack known {
$error /ostack get dup length
(Operand Stack[) print =only (]:\n) print
{( ) print ==only} forall
(\n) print
} if
$error /estack known {
$error /estack get dup length
(Execution Stack[) print =only (]:\n) print
{( ) print ==only} forall
(\n) print
} if
$error /dstack known {
$error /dstack get dup length
(Dictionary stack[) print =only (]:\n) print
{
( ) print
dup type /dicttype eq {
(--dict:) print
dup length ==only (/) print dup maxlength ==only
dup wcheck not {
((ro)) print
} if
/gcheck where {
pop gcheck {
((G))
} {
((L))
} ifelse print
} {
pop
} ifelse (--) print
} {
==only
} ifelse
} forall
(\n) print
} if
% restore objects
aload pop
} if
} bind def
mark /dictfull /dictstackoverflow /dictstackunderflow /execstackoverflow
/interrupt /invalidaccess /invalidexit /invalidfileaccess /invalidfont
/invalidrestore /ioerror /limitcheck /nocurrentpoint /rangecheck
/stackoverflow /stackunderflow /syntaxerror /timeout /typecheck /undefined
/undefinedfilename /undefinedresult /unmatchedmark /unregistered /VMerror
counttomark {
dup [exch {.defaulterrorhandler} /exec load] cvx bind errordict 3 1 roll put
} repeat
cleartomark
% initialize PostScript Level specific things.
systemdict /languagelevel known {
languagelevel 2 gt {
(hg_init_lv2.ps) run
} if
} if
false .setglobal
userdict begin
%%
%% almost initialization finished here
%% and allows 'end' operator to be described now.
%%
%% initialize $error dictionary
% $error is a built-in dictionary on hieroglyph.
$error begin
/newerror false def
/command null def
end
%% initialize handleerror in errordict
errordict begin
/handleerror /.printerror load def
end
%% initialize serverdict
serverdict begin
/exitserver { } def
end
%%
%% Initialize the plugins
%%
.initplugins
%%
%% ready to go
%%
.printversion
% if JOBSERVER isn't true, it means one gives the initializer to libretto_vm_startjob().
% so no need to read PS from stdin.
serverdict /JOBSERVER get {
systemdict /.loadhistory known {
(.hghistory) .loadhistory
} if
.startjobserver executive
systemdict /.savehistory known {
(.hghistory) .savehistory
} if
} if
|