postscript
Обработка ошибок
Поиск…
Синтаксис
{ -code- } остановлен { -error- } { -no-error- } ifelse% error catching frame
$ error / errorname get% stackunderflow typecheck rangecheck и т. д.
$ error / newerror get% bool. положить false для деактивации ошибки
$ error / ostack get% копия стека операнда в точке ошибкиerrordict / stackoverflow { -additional-code- / stackoverflow signalerror} put
% выполнить дополнительный код по типам ошибок (здесь, ошибка / stackoverflow).
замечания
В postscript есть два уровня обработки ошибок. Эта дихотомия применяется как к тому, как интерпретатор обрабатывает ошибки, так и средства, доступные пользователю (программисту) для управления обработкой.
Нижний уровень - это необычная управляющая структура, stop ... stopped
. stopped
ведет себя так же, как петлевая конструкция, в том, что он устанавливает метку в стеке выполнения, которую можно перепрыгнуть, если вызывается оператор exit
(для цикла) или оператор stop
(для stopped
-контекста). В отличие от конструкции цикла, stop
stopped
вывод булеана в стеке, указав, была ли вызвана stop
(в противном случае, как известно, процедура, переданная для stopped
завершилась до завершения.
Когда возникает ошибка PostScript, например, stackunderflow
, интерпретатор просматривает имя ошибки в errordict
которое живет в systemdict
. Если пользователь не заменил процедуру в errordict
, тогда по умолчанию будет выполняться моментальная errordict
всего стека и поместить их в $error
, другой словарь в systemdict
. Наконец, процедура по умолчанию вызовет stop
который выталкивает пользовательскую программу из стека exec и выполняет процедуру печати ошибок интерпретатора, называемую handleerror
в errordict
.
Поэтому, используя все эти знания, вы можете ловить ошибки, завернув раздел кода в { ... } stopped
. Вы можете восстановить ошибку, вызвав stop
. Вы можете определить, какой тип ошибки произошел с $error /errorname get
.
Вы также можете изменить поведение по умолчанию для определенного типа ошибки, заменив процедуру таким именем в errordict
. Или измените формат печати отчета об ошибке, заменив /handleerror
в errordict
.
Есть ли текущая точка?
Допустим true
в стеке, если currentpoint
выполняется успешно, или false
если она сигнализирует ошибку /nocurrentpoint
.
{currentpoint pop pop} stopped not % bool
Последовательность событий, когда сигнализируется ошибка
Последовательность для ошибки обычно:
- ошибка запускается путем поиска имени ошибки в
errordict
и выполнения этой процедуры. -
errordict
процедура вызываетsignalerror
, передавая ей имя ошибки. -
signalerror
принимает моментальные снимки стеков, сохраняя моментальные снимки в$error
, а затем вызываетstop
. -
stop
вытесняет стек exec до ближайшего закрытого контекста, установленного остановленным оператором. - если программа не установила свой собственный остановленный контекст, чтобы поймать ошибку, она будет поймана на внешнем уровне,
stopped { errordict /handleerror get exec } if
был вызван кодом запуска, чтобы скопировать всю программу пользователя. -
handleerror
использует информацию в$error
для вывода отчета об ошибке.
Сигнализация (выброс) ошибки
Большинство инструментов стандартизированы, за исключением имени оператора, чтобы выдать ошибку. В интерпретаторах Adobe он называется .error
. В ghostscript он называется signalerror
. Таким образом, с помощью этой строки вы можете использовать signalerror
в коде postscript для интерпретаторов Adobe или ghostscript или xpost.
/.error where {pop /signalerror /.error load def} if
имя_команды errorname signalerror -
Возьмите снимки стека в $error
, а затем stop
.
Например.
% my proc only accepts integer
/proc {
dup type /integertype ne {
/proc cvx /typecheck signalerror
} if
% ... rest of proc ...
} def
Ловля ошибки
Поскольку конечным действием обработчика ошибок по умолчанию является вызов stop
, вы можете уловить ошибки от операторов, заключая код в { ... } stopped
конструкцию.
{
0 array
1 get
} stopped {
$error /errorname get =
} if
будет печатать « rangecheck
», ошибка, сигнализируемая get
когда индекс выходит за допустимый диапазон для этого массива.
Ошибки повторного броска
Этот фрагмент реализует процедуру, которая ведет себя как оператор циклов postcript. Если пользователь proc
вызывает exit
, он ловит invalidexit
ошибку исправить dictstack для end
в конец. Любая другая ошибка, кроме invalidexit
, перезаписывается вызовом 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 ()=