File: gawk.info, Node: Assert Function, Next: Round Function, Prev: Strtonum Function, Up: General Functions
10.2.2 Assertions
-----------------
When writing large programs, it is often useful to know that a condition
or set of conditions is true. Before proceeding with a particular
computation, you make a statement about what you believe to be the case.
Such a statement is known as an "assertion". The C language provides an
'' header file and corresponding 'assert()' macro that a
programmer can use to make assertions. If an assertion fails, the
'assert()' macro arranges to print a diagnostic message describing the
condition that should have been true but was not, and then it kills the
program. In C, using 'assert()' looks this:
#include
int myfunc(int a, double b)
{
assert(a <= 5 && b >= 17.1);
...
}
If the assertion fails, the program prints a message similar to this:
prog.c:5: assertion failed: a <= 5 && b >= 17.1
The C language makes it possible to turn the condition into a string
for use in printing the diagnostic message. This is not possible in
'awk', so this 'assert()' function also requires a string version of the
condition that is being tested. Following is the function:
# assert --- assert that a condition is true. Otherwise, exit.
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
}
The 'assert()' function tests the 'condition' parameter. If it is
false, it prints a message to standard error, using the 'string'
parameter to describe the failed condition. It then sets the variable
'_assert_exit' to one and executes the 'exit' statement. The 'exit'
statement jumps to the 'END' rule. If the 'END' rule finds
'_assert_exit' to be true, it exits immediately.
The purpose of the test in the 'END' rule is to keep any other 'END'
rules from running. When an assertion fails, the program should exit
immediately. If no assertions fail, then '_assert_exit' is still false
when the 'END' rule is run normally, and the rest of the program's 'END'
rules execute. For all of this to work correctly, 'assert.awk' must be
the first source file read by 'awk'. The function can be used in a
program in the following way:
function myfunc(a, b)
{
assert(a <= 5 && b >= 17.1, "a <= 5 && b >= 17.1")
...
}
If the assertion fails, you see a message similar to the following:
mydata:1357: assertion failed: a <= 5 && b >= 17.1
There is a small problem with this version of 'assert()'. An 'END'
rule is automatically added to the program calling 'assert()'.
Normally, if a program consists of just a 'BEGIN' rule, the input files
and/or standard input are not read. However, now that the program has
an 'END' rule, 'awk' attempts to read the input data files or standard
input (*note Using BEGIN/END::), most likely causing the program to hang
as it waits for input.
There is a simple workaround to this: make sure that such a 'BEGIN'
rule always ends with an 'exit' statement.