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