Node:Assert Function, Next:Round Function, Previous:Nextfile Function, Up:General Functions
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 <assert.h> header file
and corresponding assert macro that the 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 <assert.h>
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
rules 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
(see Startup and Cleanup Actions),
most likely causing the program to hang as it waits for input.
There is a simple workaround to this:
make sure the BEGIN rule always ends
with an exit statement.