Assert Function (The GNU Awk User’s Guide)
Next: Round Function, Previous: Strtonum Function, Up: General Functions [Contents][Index]
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 <assert.h>
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 <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
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 (see section 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 that such a BEGIN
rule always ends with an exit
statement.
Next: Round Function, Previous: Strtonum Function, Up: General Functions [Contents][Index]