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
errordictet en exécutant cette procédure. - la procédure d'
errordictappelle l'appel designalerror, en lui passant le nom de l'erreur. -
signalerrorprend des instantanés des piles, en enregistrant les instantanés dans$error, puis les appelsstop. -
stopouvre 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 } ifle code de démarrage l'avait appelé pour placer l'ensemble du programme utilisateur. -
handleerrorutilise les informations de$errorpour 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 ()=