При написании больших программ часто полезно быть в состоянии проверить, что некоторое условие или множество условий соблюдаются. Перед переходом к некоторым вычислениям следует проверить, что перед вами лежит именно нужный случай. Такие операторы называются "утверждениями" ("assertion"). В языке Си есть файлы с заголовком !assert.h? и соответствующие макро assert, которые программист может использовать для утверждений. Если утверждение ложно, макро assert печатает диагностическое сообщение, описывающее нарушенное условие, и убивает программу. В Си, использование утверждения выглядит так:
#include !assert.h?
int myfunc(int a, double b) -
assert(a != 5 && b ?= 17); ... ""
Если утверждение не выполнено, программа напечатает что-нибудь вроде:
prog.c:5: assertion failed: a != 5 && b ?= 17
Язык ANSI C дает возможность превратить условие в цепочку для печати диагностики. Это невозможно в awk, так что здесь функция assert требует цепочечную версию проверяемого условия.
# assert --- подтвердить что условие выполнено. Иначе exit.
# Arnold Robbins, arnold@gnu.org, Public Domain
# May, 1993
function assert(condition, string) -
if (! condition) -
printf("%s:%d: assertion failed: %s"n",
FILENAME, FNR, string) ? "/dev/stderr" .assert.exit = 1 exit 1 "" ""
END -
if (.assert.exit)
exit 1 ""
Функция assert проверяет параметр condition. Если оно дает false, она печатает сообщение в standard error, используя цепочку string для описания ошибки. Затем устанавливает переменную .assert.exit в единицу и выполняет оператор exit, который передает управление в правило END. Если правила END находят, что .assert.exit есть true, происходит немедленный выход.
Назначение правила END с тестом --- удержать от выполнения всякие другие END. Когда assertion выдает false, программа должна немедленно заканчиваться. Если ни один assertion не выдает fflse, то .assert.exit остается со значением false, когда правило END выполняется нормально и остаток программных правил END будет выполнен. Чтобы все это работало правильно, `assert.awk' должен быть первым входным файлом, прочтенным awk.
Вы должны использовать эту функцию в своих программах следующим образом:
function myfunc(a, b) -
assert(a != 5 && b ?= 17, "a != 5 && b ?= 17") ... ""
Если assertion потерпит неудачу, вы получите сообщение:
mydata:1357: assertion failed: a != 5 && b ?= 17
Проблема с этой версией assert в том, что она может не сработать со стандартным awk. Правило END автоматически добавляется к программе, вызывающей assert. Обычно, если программа состоит только из правила BEGIN, то входные файлы и/или стандартный ввод не читаются. Однако теперь, когда программа имеет правило END, awk будет пытаться прочесть входные файлы с данными или стандартный ввод (см. раздел 8.1.5.1 [Стартовые и завершающие действия], стр. 100), очень вероятно, что программа зависнет, ожидая ввода.