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
errordicti wykonanie tej procedury. -
errordictprocedura nazywasignalerror, przekazując mu nazwę błędu. -
signalerrorwykonuje migawki stosów, zapisując migawki w$error, a następnie wywołujestop. -
stopwyskakuje 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 } ifpoziomie zewnętrznymstopped { errordict /handleerror get exec } ifktóry został wywołany przez kod startowy w celustopped { errordict /handleerror get exec } ifcałego programu użytkownika. -
handleerrorwykorzystuje informacje zawarte w$errordo 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 ()=