On Dec 7, 2004, at 4:07 AM, Clayton, Nik wrote:
Michael G Schwern wrote:On Mon, Dec 06, 2004 at 10:00:32AM -0000, Clayton, Nik wrote:Then you have one of ok() or ok2() at your disposal. ok()'s first
parameter is the code to test. The second parameter is the test name.
This is a printf()like format string, and the third and subsequent
parameters should fill out any values in the string.
ok(a_func() == 0, "test name"); ok(some_func(i), "some_func(%d)", i);
Why add that extra auto-sprintf complexity? Can't the user do the exact same thing with:
ok(some_func(i), sprintf("some_func(%d)", i));
Yes they can. It was just an easy feature to add.
er, sprintf() isn't so easy in C --- the caller must supply the buffer, and the return value is the number of chars written to the buffer, so it would become this:
char temp[SOME_BIG_SIZE]; ... sprintf (temp, "some_func(%d)", i); ok (some_func(i), temp);
if it didn't work like this, sprintf() would have to malloc() a new buffer (a la glib's g_strdup_printf()), which means you'd have to free() it, which would look even worse:
char * temp; ... temp = g_strdup_printf ("some_func(%d)", i); ok (some_func(i), temp); g_free (temp);
writing your own printf-style macros is actually a very common idiom for getting around this sort of technical problem. they, of course, raise the further problem that GCC's vararg macros are not portable, and C99's vararg macros are not yet universally supported.
Making the test name a sprintf string can complicate things
if they want to do formatting themselves, they have the extra problem of
escaping their result for sprintf.
Also, folks putting in bare strings might be surprised.
ok( tax(.05), "taxing at 5%" );
True. I'll take this under advisement. :-)
if it's documented to be a printf() string, it won't take too long to be understood. a common alternative (e.g. for bindings) is
ok_literal (bool condition, const char * not_a_printf_string);
but again, that's not as convenient.
ok(1 == 1, "1 equals one"); /* PRINT: ok 1 - 1 equals 1 */ ok2(1 == 2); /* PRINT: not ok 2 - 1 == 2 */
Why the split? You can do variable length argument lists in C.
Right. And this may be my ignorance showing here, but as I understand
it, if you do that you must have an argument that hints at how many optional
arguments are present.
no, you're absolutely correct --- while C does support variadic function calls, C has no way of knowing how many arguments are on the stack, and must take hints from its other arguments.
printf looks for as many arguments as they are format specifiers in its format strings, and other functions look for a sentinel on the stack, such as NULL or -1, e.g.
ok (1 == 2, NULL); /* no further arguments */
which, in this case, is slightly pointless.
Finally, there's exit_status(), which returns an int suitable for use when return'ing from main(), or calling exit(). You should always do one of:
return exit_status(); exit(exit_status());
What is this for? <--- possible C ignorance
not sure what the question is exactly, so i'll throw spaghetti at the wall --- in C, returning from main() is equivalent to exiting the program. main()'s return value is used as the exit status. Test::Harness uses the program's exit status as one of the indicators that the program worked correctly.
exit_status() is required to do this, since a library can't intercept all
the ways a program might exit *and* change the exit code (again, AFAIK).
you'd have to use non-portable LD_PRELOAD tricks to override the implementation of exit() used by the program, and that's just not a good idea.
-- I don't have a drinking problem, 'cept when i can't get drink. -- Tom Waits