postscript
Gestione degli errori
Ricerca…
Sintassi
{ -code- } stopped { -error- } { -no- error-} ifelse% error catching frame
$ error / errorname ottiene% stackunderflow typecheck rangecheck ecc
$ error / newerror ottiene% bool. mettere false per disattivare l'errore
$ error / ostack ottiene una copia% della pila degli operandi al punto di erroreerrordict / stackoverflow { -additional-code- / stackoverflow signalerror} put
% esegue codice aggiuntivo sui tipi di errori (qui, l'errore / stackoverflow).
Osservazioni
Ci sono due livelli per la gestione degli errori in postscript. Questa dicotomia si applica sia al modo in cui l'interprete gestisce gli errori sia ai mezzi a disposizione dell'utente (programmatore) per controllare la gestione.
Il livello più basso è una struttura di controllo insolita stop ... stopped
. stopped
comporta come un costrutto di looping in quanto stabilisce un mark nello stack di esecuzione che può essere saltato-to se viene chiamato l'operatore exit
(per un loop) o l'operatore stop
(per un stopped
-context). A differenza di un costrutto di loop, stopped
restituisce un booleano sullo stack che indica se è stato chiamato stop
(altrimenti la procedura passata a stopped
è nota per essere eseguita fino al completamento.
Quando si verifica un errore PostScript, come forse lo stackunderflow
, l'interprete cerca errordict
il nome errordict
che vive in systemdict
. Se l'utente non ha sostituito la procedura in errordict
, la procedura di errore predefinita eseguirà istantanee di tutto lo stack e le systemdict
in $error
, un altro dizionario in systemdict
. Infine, la procedura predefinita chiamerà stop
che apre il programma utente dallo stack exec ed esegue la procedura di stampa degli errori handleerror
chiamata handleerror
in errordict
.
Quindi, utilizzando tutte queste conoscenze, è possibile rilevare gli errori avvolgendo una sezione di codice in { ... } stopped
. Puoi ribaltare un errore chiamando stop
. È possibile determinare quale tipo di errore si è verificato con $error /errorname get
.
È anche possibile modificare il comportamento predefinito per un tipo specifico di errore sostituendo errordict
la procedura con quel nome. O modificare il formato di stampa del rapporto errori sostituendo /handleerror
in errordict
.
C'è un punto corrente?
Rendi true
nello stack se currentpoint
viene eseguito correttamente o false
se segnala un errore /nocurrentpoint
.
{currentpoint pop pop} stopped not % bool
Sequenza di eventi quando viene segnalato un errore
La sequenza per un errore è solitamente:
- l'errore viene attivato cercando il nome dell'errore
errordict
ed eseguendo questa procedura. -
errordict
procedura richiedesignalerror
, passandogli il nome di errore. -
signalerror
prende le istantanee degli stack, salvando le istantanee in$error
, e quindi le chiamatestop
. -
stop
apre la pila exec fino a quando il contesto arrestato più vicino è stato stabilito dall'operatore arrestato. - se il programma non ha stabilito il proprio contesto interrotto per catturare l'errore, verrà catturato da un livello esterno
stopped { errordict /handleerror get exec } if
stato chiamato dal codice di avvio per raggruppare l'intero programma utente. -
handleerror
utilizza le informazioni in$error
per stampare un report di errore.
Segnalazione (lancio) di un errore
La maggior parte degli strumenti è standardizzata con l'eccezione del nome dell'operatore per generare un errore. Negli interpreti Adobe, si chiama .error
. In ghostscript, si chiama signalerror
. Quindi con questa linea puoi usare signalerror
nel codice postscript per interpreti Adobe o ghostscript o xpost.
/.error where {pop /signalerror /.error load def} if
nomecomando errorname SignalError -
Scatta istantanee dello stack in $error
, quindi stop
.
Per esempio.
% my proc only accepts integer
/proc {
dup type /integertype ne {
/proc cvx /typecheck signalerror
} if
% ... rest of proc ...
} def
Cattura un errore
Poiché l'azione finale del gestore di errori predefinito consiste nel chiamare stop
, è possibile rilevare gli errori dagli operatori racchiudendo il codice in un costrutto { ... } stopped
.
{
0 array
1 get
} stopped {
$error /errorname get =
} if
stamperà " rangecheck
", l'errore segnalato da get
quando l'indice è al di fuori dell'intervallo accettabile per quella matrice.
Rilanciare gli errori
Questo snippet implementa una procedura che si comporta come un operatore di loop di postscript. Se l'utente proc
chiama exit
, rileva l'errore invalidexit
per correggere il dictstack per la end
alla fine. Qualsiasi altro errore tranne invalidexit
viene nuovamente generato chiamando stop
.
% array n proc . -
% Like `forall` but delivers length=n subsequences produced by getinterval
/fortuple { 4 dict begin
0 {offset proc n arr} {exch def} forall
/arr load length n idiv
{
{
/arr load offset n getinterval
[ /proc load currentdict end /begin cvx ] cvx exec
/offset offset n add def
} stopped {
$error /errorname get /invalidexit eq
{ 1 dict begin exit }{ stop } ifelse
} if
} repeat
end
} def
%[ 0 1 10 {} for ] 3 {} fortuple pstack clear ()=