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
errordictierrordictoch genomföra denna procedur. -
errordictförfaranden kallarsignalerror, vilket skickar felnamnet. -
signalerrortar ögonblicksbilder av staplarna, sparar ögonblicksbilderna i$erroroch ringer sedanstop. -
stoppoppar 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 } ifsom kallades av startkoden för att fäste hela användarprogrammet. -
handleerroranvänder informationen i$erroratt 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 ()=