postscript
Obsługa błędów
Szukaj…
Składnia
{ -code- } zatrzymał { -error- } { -no-error- } ifelse% błąd przechwytuje ramkę
$ error / errorname get% stackunderflow typecheck rangecheck itp
$ error / newerror get% bool. wpisz false, aby dezaktywować błąd
$ error / ostack dostaje% kopii stosu operandów w punkcie błęduerrordict / stackoverflow { -dodatkowy- kod- / błąd przesyłania sygnału sterującego} wstaw
% wykonać dodatkowy kod dla rodzajów błędów (tutaj błąd / stackoverflow).
Uwagi
Istnieją dwa poziomy obsługi błędów w PostScript. Ta dychotomia dotyczy zarówno sposobu, w jaki interpreter obsługuje błędy, jak i środków dostępnych dla użytkownika (programisty) do kontrolowania obsługi.
Niższy poziom to niezwykłe stop ... stopped
struktury kontrolnej stop ... stopped
. stopped
zachowuje się bardzo podobnie do konstrukcji zapętlonej, ponieważ ustanawia znak na stosie wykonawczym, do którego można przeskoczyć, jeśli zostanie wywołany operator exit
(dla pętli) lub operator stop
(dla stopped
kontekstu). W odróżnieniu od pętli konstruktu stopped
daje wartość logiczną na stosie, określający, czy stop
nazwano (inaczej procedury przekazywane do stopped
wiadomo, że wykonana do końca.
Gdy wystąpi błąd PostScript, na przykład może stackunderflow
być stackunderflow
, interpreter sprawdza nazwę błędu w errordict
który żyje w systemdict
. Jeśli użytkownik nie zastąpił procedury w errordict
, wówczas domyślna procedura błędu wykona migawki całego stosu i errordict
je w $error
, innym słowniku w systemdict
. Na koniec, domyślna procedura wywoła stop
który wyskakuje z programu użytkownika ze stosu exec i wykonuje handleerror
procedurę drukowania błędów interpretera zwaną errordict
.
Wykorzystując całą tę wiedzę, możesz wychwycić błędy, { ... } stopped
zawijanie części kodu w { ... } stopped
. Możesz ponownie wyrzucić błąd, wywołując stop
. Możesz określić, jaki typ błędu wystąpił za pomocą $error /errorname get
.
Możesz także zmienić domyślne zachowanie dla określonego rodzaju błędu, zastępując procedurę tą nazwą w errordict
. Lub zmień format drukowania raportu o błędach, zastępując /handleerror
w errordict
.
Czy jest punkt prądu?
Daje wartość true
na stosie, jeśli punkt currentpoint
zostanie currentpoint
pomyślnie, lub false
jeśli /nocurrentpoint
błąd /nocurrentpoint
.
{currentpoint pop pop} stopped not % bool
Sekwencja zdarzeń, gdy sygnalizowany jest błąd
Sekwencja błędu to zwykle:
- błąd jest wywoływany przez wyszukiwanie nazwy błędu w
errordict
i wykonanie tej procedury. -
errordict
procedura nazywasignalerror
, przekazując mu nazwę błędu. -
signalerror
wykonuje migawki stosów, zapisując migawki w$error
, a następnie wywołujestop
. -
stop
wyskakuje stos exec aż do najbliższego otaczającego zatrzymanego kontekstu ustanowionego przez zatrzymany operator. - jeśli program nie stworzył własnego kontekstu zatrzymania w celu wychwycenia błędu, zostanie przechwycony przez
stopped { errordict /handleerror get exec } if
poziomie zewnętrznymstopped { errordict /handleerror get exec } if
który został wywołany przez kod startowy w celustopped { errordict /handleerror get exec } if
całego programu użytkownika. -
handleerror
wykorzystuje informacje zawarte w$error
do wydrukowania raportu o błędzie.
Sygnalizacja (wyrzucenie) błędu
Większość narzędzi jest znormalizowana, z wyjątkiem nazwy operatora, aby zgłosić błąd. W interpreterach Adobe nazywa się to .error
. W ghostscript nazywa się to signalerror
. Tak więc w tym wierszu możesz użyć signalerror
w kodzie postscriptowym dla interpreterów Adobe lub ghostscript lub xpost.
/.error where {pop /signalerror /.error load def} if
nazwa_polecenia errorname signalerror -
Wykonaj migawki stosu z $error
, a następnie stop
.
Na przykład.
% my proc only accepts integer
/proc {
dup type /integertype ne {
/proc cvx /typecheck signalerror
} if
% ... rest of proc ...
} def
Łapanie błędu
Ponieważ ostatecznym działaniem domyślnej procedury obsługi błędów jest wywołanie stop
, można wychwycić błędy od operatorów, włączając kod w konstrukcję { ... } stopped
.
{
0 array
1 get
} stopped {
$error /errorname get =
} if
wypisze „ rangecheck
”, błąd sygnalizowany przez get
gdy indeks znajduje się poza dopuszczalnym zakresem dla tej tablicy.
Błędy ponownego rzucania
Ten fragment kodu implementuje procedurę, która zachowuje się jak operator zapętlający PostScript. Jeśli użytkownik proc
nazywa exit
, to łapie invalidexit
błąd naprawić dictstack do end
na końcu. Każdy inny błąd oprócz invalidexit
jest ponownie zgłaszany przez wywołanie 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 ()=