postscript
Foutafhandeling
Zoeken…
Syntaxis
{ -code- } gestopt { -error- } { -no- error-} ifelse% foutopvangframe
$ error / errorname krijg% stackunderflow typecheck bereikcontrole enz
$ error / newerror krijg% bool. zet false om de fout te deactiveren
$ error / ostack krijgt% kopie van operandstapel op het foutpuntfout / stackoverflow { -aanvullende code- / stackoverflow signalerror} gezet
% voert extra code uit op soorten fouten (hier de / stackoverflow-fout).
Opmerkingen
Er zijn twee niveaus voor foutafhandeling in postscript. Deze tweedeling is zowel van toepassing op de manier waarop de tolk fouten verwerkt, als op de middelen die de gebruiker (programmeur) ter beschikking staan om de afhandeling te regelen.
Het lagere niveau is een ongewone besturingsstructuur stop ... stopped
. stopped
gedraagt zich net als een lusconstructie in die zin dat het een markering op de uitvoeringsstapel vaststelt waarnaar kan worden gesprongen als de exit
operator (voor een lus) of stop
operator (voor een stopped
-context) wordt aangeroepen. In tegenstelling tot een lusconstructie levert stopped
een Boolean op de stapel op die aangeeft of stop
werd aangeroepen (anders is bekend dat de aan stopped
doorgegeven procedure volledig is uitgevoerd.
Als een PostScript-fout optreedt, zoals stackunderflow
misschien, de tolk kijkt op de naam van de fout in errordict
die leeft in systemdict
. Als de gebruiker de procedure niet heeft vervangen errordict
, dan zal de standaard fout procedure snapshots van de stapel te nemen en plaats ze in $error
, een ander woordenboek in systemdict
. Ten slotte zal de standaardprocedure stop
aanroepen stop
waarmee het gebruikersprogramma uit de exec-stapel wordt handleerror
errordict
de tolk wordt uitgevoerd, genaamd handleerror
in errordict
.
Dus het gebruik van al deze kennis, kun je fouten op te vangen door het wikkelen van een deel van de code in { ... } stopped
. U kunt een fout opnieuw melden door stop
bellen. U kunt bepalen welk type fout is opgetreden met $error /errorname get
.
U kunt ook het standaardgedrag voor een specifiek type fout wijzigen door de procedure te vervangen door die naam in errordict
. Of wijzig het formaat van het afdrukken van het foutenrapport door /handleerror
te vervangen in errordict
.
Is er een actueel punt?
Geef true
op de stapel op als currentpoint
succes wordt uitgevoerd, of false
als het een /nocurrentpoint
fout /nocurrentpoint
.
{currentpoint pop pop} stopped not % bool
Volgorde van gebeurtenissen wanneer een fout wordt gesignaleerd
De volgorde voor een fout is meestal:
- fout wordt geactiveerd door de
errordict
op te zoeken in fout en deze procedure uit te voeren. - de
errordict
procedure roeptsignalerror
en geeft deze deerrordict
. -
signalerror
maakt snapshots van de stapels, slaat de snapshots op in$error
enstop
vervolgens. -
stop
springt de exec-stapel tot de dichtstbijzijnde omringendestop
die door de stopoperator is vastgesteld. - als het programma geen eigen gestopte context heeft ingesteld om de fout op te vangen, wordt het opgevangen door een buitenste niveau
stopped { errordict /handleerror get exec } if
dat door de opstartcode werd aangeroepen om het hele gebruikersprogramma testopped { errordict /handleerror get exec } if
. -
handleerror
gebruikt de informatie in$error
om een foutenrapport af te drukken.
Een fout signaleren (gooien)
De meeste tools zijn gestandaardiseerd met uitzondering van de naam van de operator om een fout te maken. In Adobe-tolken wordt dit .error
. In ghostscript wordt het signalerror
. Dus met deze regel kun je signalerror
in postscript-code voor Adobe-tolken of ghostscript of xpost.
/.error where {pop /signalerror /.error load def} if
opdrachtnaam errorname signalerror -
Maak snapshots van de stapel in $error
en stop
.
Bijv.
% my proc only accepts integer
/proc {
dup type /integertype ne {
/proc cvx /typecheck signalerror
} if
% ... rest of proc ...
} def
Er is een fout opgetreden
Aangezien de laatste actie van de standaardfoutafhandelaar het aanroepen van stop
, kunt u fouten van operators opmerken door code in een { ... } stopped
construct op te nemen.
{
0 array
1 get
} stopped {
$error /errorname get =
} if
zal " rangecheck
" afdrukken, de fout die wordt aangegeven door get
wanneer de index zich buiten het acceptabele bereik voor die array bevindt.
Fouten opnieuw gooien
Dit fragment implementeert een procedure die zich gedraagt als een postscript-lusoperator. Als de gebruiker proc
exit
noemt, wordt de invalidexit
fout opgevangen om de dictstack voor het end
aan het einde te repareren. Elke andere fout behalve invalidexit
wordt opnieuw gegenereerd door stop
bellen.
% 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 ()=