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 ()=