postscript
Felhantering
Sök…
Syntax
{ -code- } stoppade { -error- } { -no-error- } ifelse% felupptagningsram
$ error / errorname get% stackunderflow typecheck rangecheck etc
$ error / newerror get% bool. sätta falskt för att inaktivera felet
$ error / ostack få% kopia av operand stack vid feleterrordict / stackoverflow { -adimental-code- / stackoverflow signalerror} put
% kör ytterligare kod för feltyper (här, / stackoverflow-felet).
Anmärkningar
Det finns två nivåer för felhantering i postscript. Denna dikotomi gäller både det sätt som tolkaren hanterar fel såväl som de medel som finns tillgängliga för användaren (programmeraren) för att styra hanteringen.
Den lägre nivån är ett ovanligt kontrollstoppstopp stop ... stopped
. stopped
uppför sig ungefär som en looping konstruktion i det att den etablerar ett märke på exekveringsstacken som kan hoppade-till om exit
operatören (för en slinga) eller stop
(för en stopped
-context) anropas. Till skillnad från en slingkonstruktion ger stopped
en Boolean på bunten som indikerar om stop
kallades (annars är det känt att proceduren som gått till stopped
har genomförts till slutförande.
När ett PostScript-fel inträffar, som kanske stackunderflow
, letar tolkaren upp errordict
namn i errordict
som lever i systemdict
. Om användaren inte har ersatt proceduren i errordict
standardfelproceduren ögonblicksbilder av alla stacken och placerar dem i $error
, en annan ordbok i systemdict
. Slutligen kommer standardproceduren att ringa stop
som skickar användarprogrammet från exec-stacken och exekverar handleerror
errordict
kallas handleerror
i errordict
.
Så med hjälp av all denna kunskap kan du fånga fel genom att lasta in ett avsnitt av koden i { ... } stopped
. Du kan rensa ett fel igen genom att ringa stop
. Du kan bestämma vilken typ av fel som inträffade med $error /errorname get
.
Du kan också ändra standardbeteendet för en viss typ av fel genom att ersätta proceduren med det namnet i errordict
. Eller ändra formatet för att skriva ut /handleerror
genom att ersätta /handleerror
i errordict
.
Finns det en aktuell punkt?
Utbyte true
på bunten om currentpoint
körs framgångsrikt eller false
om det signalerar ett /nocurrentpoint
fel.
{currentpoint pop pop} stopped not % bool
Sekvens av händelser när ett fel signaleras
Sekvensen för ett fel är vanligtvis:
- fel utlöses genom att leta upp
errordict
ierrordict
och genomföra denna procedur. -
errordict
förfaranden kallarsignalerror
, vilket skickar felnamnet. -
signalerror
tar ögonblicksbilder av staplarna, sparar ögonblicksbilderna i$error
och ringer sedanstop
. -
stop
poppar exec-stacken tills närmaste omslutande stoppade sammanhang upprättats av den stoppade operatören. - Om programmet inte har upprättat sitt eget stoppade sammanhang för att fånga felet, kommer det att fångas upp av en yttre nivå
stopped { errordict /handleerror get exec } if
som kallades av startkoden för att fäste hela användarprogrammet. -
handleerror
använder informationen i$error
att skriva ut en felrapport.
Signalerar (kastar) ett fel
De flesta av verktygen är standardiserade med undantag för operatörens namn för att kasta ett fel. I Adobe-tolkar kallas det .error
. I ghostscript kallas det signalerror
. Så med den här linjen kan du använda signalerror
i postscriptkod för Adobe-tolkar eller ghostscript eller xpost.
/.error where {pop /signalerror /.error load def} if
kommandonamn errorname signalerror -
Ta ögonblicksbilder av stacken i $error
och stop
.
T.ex.
% my proc only accepts integer
/proc {
dup type /integertype ne {
/proc cvx /typecheck signalerror
} if
% ... rest of proc ...
} def
Fånga ett fel
Eftersom den sista handlingen för standardfelhanteraren är att ringa stop
, kan du fånga fel från operatörer genom att bifoga kod i en { ... } stopped
konstruktion.
{
0 array
1 get
} stopped {
$error /errorname get =
} if
kommer att skriva ut " rangecheck
", det fel som signaleras av get
när indexet ligger utanför det acceptabla intervallet för den arrayen.
Omkastningsfel
Detta utdrag implementerar en procedur som uppträder som en postscript-looping-operatör. Om användaren proc
samtal exit
, fångar det det invalidexit
felet att fixa diktstacket för end
i slutet. Alla andra fel utom invalidexit
kastas om genom att ringa 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 ()=