Go to the first, previous, next, last section, table of contents.


Assertions

When writing large programs, it is often useful to be able 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);
     ...
}

If the assertion failed, the program would print a message similar to this:

prog.c:5: assertion failed: a <= 5 && b >= 17

The ANSI 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.

# assert --- assert that a condition is true. Otherwise exit.
# Arnold Robbins, arnold@gnu.ai.mit.edu, 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
}

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, then it exits immediately.

The purpose of the END rule with its test 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 will still be false when the END rule is run normally, and the rest of the program's END rules will execute. For all of this to work correctly, `assert.awk' must be the first source file read by awk.

You would use this function in your programs this way:

function myfunc(a, b)
{
     assert(a <= 5 && b >= 17, "a <= 5 && b >= 17")
     ...
}

If the assertion failed, you would see a message like this:

mydata:1357: assertion failed: a <= 5 && b >= 17

There is a problem with this version of assert, that it may not be possible to work around. 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 will attempt to read the input data files, or standard input (see section Startup and Cleanup Actions), most likely causing the program to hang, waiting for input.


Go to the first, previous, next, last section, table of contents.