postscript
La gestion des erreurs
Recherche…
Syntaxe
{ -code- } arrêté { -error- } { -no-error- } ifelse% erreur capture d'image
$ error / errorname get% stackunderflow typecheck rangecheck etc
$ error / newerror get% bool. mettre faux pour désactiver l'erreur
$ error / ostack obtient% copy de la pile d'opérande au point d'erreurerrordict / stackoverflow { -additional-code- / stackoverflow signalerror}
% exécuter du code supplémentaire sur les types d'erreurs (ici, l'erreur / stackoverflow).
Remarques
La gestion des erreurs en postscript comporte deux niveaux. Cette dichotomie s'applique à la fois à la manière dont l'interprète gère les erreurs et aux moyens dont dispose l'utilisateur (le programmeur) pour contrôler le traitement.
Le niveau inférieur est un stop ... stopped
structure de contrôle inhabituel stop ... stopped
. stopped
se comporte un peu comme une construction en boucle dans la mesure où il établit une marque sur la pile d'exécution à laquelle on peut accéder si l'opérateur de exit
(pour une boucle) ou l'opérateur d' stop
(pour un contexte stopped
) est appelé. Contrairement à une construction en boucle, stopped
génère un booléen sur la pile indiquant si l' stop
été appelé (sinon, la procédure passée à stopped
est connue pour s'être achevée).
Lorsqu'une erreur PostScript se produit, comme stackunderflow
peut-être, l'interpréteur recherche le nom de l'erreur dans errordict
qui vit dans systemdict
. Si l'utilisateur n'a pas remplacé la procédure dans errordict
, la procédure d'erreur par défaut prendra des instantanés de toute la pile et les placera dans $error
, un autre dictionnaire dans systemdict
. Enfin, la procédure par défaut appelle stop
ce qui fait sortir le programme utilisateur de la pile exec et exécute la procédure d'impression d'erreur de l'interpréteur appelée handleerror
en errordict
.
Donc, en utilisant toutes ces connaissances, vous pouvez intercepter des erreurs en encapsulant une section de code dans { ... } stopped
. Vous pouvez relancer une erreur en appelant stop
. Vous pouvez déterminer le type d'erreur survenue avec $error /errorname get
.
Vous pouvez également modifier le comportement par défaut pour un type d'erreur spécifique en remplaçant la procédure portant ce nom par errordict
. Ou changez le format d’impression du rapport d’erreur en remplaçant /handleerror
dans errordict
.
Y a-t-il un point actuel?
Rendement true
sur la pile si le point currentpoint
s'exécute avec succès, ou false
s'il signale une erreur /nocurrentpoint
.
{currentpoint pop pop} stopped not % bool
Séquence d'événements lorsqu'une erreur est signalée
La séquence d'une erreur est généralement:
- L'erreur est déclenchée en recherchant le nom de l'erreur en
errordict
et en exécutant cette procédure. - la procédure d'
errordict
appelle l'appel designalerror
, en lui passant le nom de l'erreur. -
signalerror
prend des instantanés des piles, en enregistrant les instantanés dans$error
, puis les appelsstop
. -
stop
ouvre la pile exec jusqu’au contexte clos le plus proche établi par l’opérateur arrêté. - Si le programme n'a pas établi son propre contexte arrêté pour détecter l'erreur, il sera attrapé par un niveau externe
stopped { errordict /handleerror get exec } if
le code de démarrage l'avait appelé pour placer l'ensemble du programme utilisateur. -
handleerror
utilise les informations de$error
pour imprimer un rapport d'erreur.
Signaler (lancer) une erreur
La plupart des outils sont standardisés à l'exception du nom de l'opérateur pour lancer une erreur. Dans Adobe interpreters, il s'appelle .error
. Dans ghostscript, cela s'appelle signalerror
. Ainsi, avec cette ligne, vous pouvez utiliser signalerror
dans le code postscript pour les interpréteurs Adobe, ghostscript ou xpost.
/.error where {pop /signalerror /.error load def} if
nom de commande errorname signalerror -
Prenez des instantanés de la pile en $error
, puis stop
.
Par exemple.
% my proc only accepts integer
/proc {
dup type /integertype ne {
/proc cvx /typecheck signalerror
} if
% ... rest of proc ...
} def
Attraper une erreur
Comme l'action finale du gestionnaire d'erreurs par défaut consiste à appeler stop
, vous pouvez intercepter les erreurs des opérateurs en insérant du code dans une construction { ... } stopped
.
{
0 array
1 get
} stopped {
$error /errorname get =
} if
va imprimer " rangecheck
", l'erreur signalée par get
lorsque l'index est en dehors de la plage acceptable pour ce tableau.
Re-lancer des erreurs
Cet extrait implémente une procédure qui se comporte comme un opérateur de boucle PostScript. Si l'utilisateur proc
appelle la exit
, il attrape la invalidexit
erreur de fixer le dictstack pour la end
à la fin. Toute autre erreur, sauf invalidexit
est renvoyée en appelant 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 ()=