"Fossies" - the Fresh Open Source Software Archive

Member "libgd-2.3.3/tests/gdtest/gdtest.c" (11 Sep 2021, 15782 Bytes) of package /linux/www/libgd-2.3.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #ifdef HAVE_CONFIG_H
    2 #include <config.h>
    3 #endif
    4 #include <assert.h>
    5 #include <setjmp.h>
    6 #include <stdlib.h>
    7 #include <stdio.h>
    8 #include <string.h>
    9 #include <math.h>
   10 #include <limits.h>
   11 #include <time.h>
   12 
   13 #ifdef HAVE_DIRENT_H
   14 #include <dirent.h>
   15 #endif
   16 #ifdef HAVE_UNISTD_H
   17 #include <unistd.h>
   18 #endif
   19 #ifdef HAVE_SYS_STAT_H
   20 #include <sys/stat.h>
   21 #endif
   22 #ifdef HAVE_SYS_TYPES_H
   23 #include <sys/types.h>
   24 #endif
   25 
   26 #if defined(_WIN32) && !defined(__MINGW32__) &&  !defined(__MINGW64__)
   27 #include "readdir.h"
   28 #include <errno.h>
   29 #endif
   30 #if defined(__MINGW32__) ||  defined(__MINGW64__)
   31 # define lstat stat
   32 #endif
   33 #include "gd_intern.h"
   34 
   35 /* GDTEST_TOP_DIR is defined in other compile ways except msys
   36  * test_config.h is created by windows/msys/run_test.sh*/
   37 #ifndef GDTEST_TOP_DIR
   38 #include <test_config.h>
   39 #endif
   40 
   41 #include "gd.h"
   42 
   43 #include "gdtest.h"
   44 
   45 /* max is already defined in windows/msvc */
   46 #ifndef max
   47     static inline int max(int a, int b) {return a > b ? a : b;}
   48 #endif
   49 
   50 void gdSilence(int priority, const char *format, va_list args)
   51 {
   52     (void)priority;
   53     (void)format;
   54     (void)args;
   55 }
   56 
   57 gdImagePtr gdTestImageFromPng(const char *filename)
   58 {
   59     gdImagePtr image;
   60     FILE *fp;
   61 
   62     /* If the path is relative, then assume it's in the tests/ dir. */
   63     if (filename[0] == '/' || filename[0] == '.'
   64 #ifdef _WIN32
   65     || filename[1] == ':'
   66 #endif
   67     ) {
   68         fp = fopen(filename, "rb");
   69     } else {
   70         fp = gdTestFileOpen(filename);
   71     }
   72 
   73     if (fp == NULL) {
   74         return NULL;
   75     }
   76 
   77     image = gdImageCreateFromPng(fp);
   78     fclose(fp);
   79     return image;
   80 }
   81 
   82 static char *tmpdir_base;
   83 int gdTestIsDir(char *path) {
   84 #if defined(_WIN32) && !defined(__MINGW32__) &&  !defined(__MINGW64__)
   85     WIN32_FILE_ATTRIBUTE_DATA data;
   86 
   87     if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data)) {
   88         return 0;
   89     }
   90     if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
   91         return 0;
   92     } else {
   93         return 1;
   94     }
   95 #else
   96     struct stat st;
   97     if (lstat(path, &st) != 0)
   98 
   99     if (S_ISDIR(st.st_mode))
  100         return 1;
  101     return 0;
  102 #endif
  103 }
  104 /* This is kind of hacky, but it's meant to be simple. */
  105 static void _clean_dir(const char *dir)
  106 {
  107     DIR *d;
  108     struct dirent *de;
  109 
  110     d = opendir(dir);
  111     if (d == NULL)
  112         return;
  113 
  114     if (chdir(dir) != 0)
  115         goto done;
  116 
  117     while ((de = readdir(d)) != NULL) {
  118         struct stat st;
  119 
  120         if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
  121             continue;
  122 #if defined(_WIN32) && !defined(__MINGW32__) &&  !defined(__MINGW64__)
  123     {
  124         WIN32_FILE_ATTRIBUTE_DATA data;
  125 
  126         if (!GetFileAttributesEx(de->d_name, GetFileExInfoStandard, &data)) {
  127             continue;
  128         }
  129         if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  130             _clean_dir(de->d_name);
  131         } else {
  132             unlink(de->d_name);
  133         }
  134     }
  135 #else
  136         if (lstat(de->d_name, &st) != 0)
  137             continue;
  138 
  139         if (S_ISDIR(st.st_mode))
  140             _clean_dir(de->d_name);
  141         else
  142             unlink(de->d_name);
  143 #endif
  144     }
  145 
  146     if (chdir("..")) {
  147         /* Ignore. */;
  148     }
  149 
  150  done:
  151     closedir(d);
  152     rmdir(dir);
  153 }
  154 
  155 static void tmpdir_cleanup(void)
  156 {
  157     _clean_dir(tmpdir_base);
  158     free(tmpdir_base);
  159 }
  160 
  161 #if defined(_WIN32) && !defined(__MINGW32__) &&  !defined(__MINGW64__)
  162 
  163 
  164 typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
  165 
  166 static MyGetSystemTimeAsFileTime get_time_func(void)
  167 {
  168     MyGetSystemTimeAsFileTime timefunc = NULL;
  169     HMODULE hMod = GetModuleHandle("kernel32.dll");
  170 
  171     if (hMod) {
  172         /* Max possible resolution <1us, win8/server2012 */
  173         timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
  174 
  175         if(!timefunc) {
  176             /* 100ns blocks since 01-Jan-1641 */
  177             timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
  178         }
  179     }
  180 
  181     return timefunc;
  182 }
  183 static MyGetSystemTimeAsFileTime timefunc = NULL;
  184 static int getfilesystemtime(struct timeval *tv)
  185 {
  186     FILETIME ft;
  187     unsigned __int64 ff = 0;
  188     ULARGE_INTEGER fft;
  189 
  190     if (timefunc == NULL) {
  191         timefunc = get_time_func();
  192     }
  193     timefunc(&ft);
  194 
  195     /*
  196      * Do not cast a pointer to a FILETIME structure to either a
  197      * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
  198      * via  http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
  199      */
  200     fft.HighPart = ft.dwHighDateTime;
  201     fft.LowPart = ft.dwLowDateTime;
  202     ff = fft.QuadPart;
  203 
  204     ff /= 10ULL; /* convert to microseconds */
  205     ff -= 11644473600000000ULL; /* convert to unix epoch */
  206 
  207     tv->tv_sec = (long)(ff / 1000000ULL);
  208     tv->tv_usec = (long)(ff % 1000000ULL);
  209 
  210     return 0;
  211 }
  212 #endif
  213 #if defined(_WIN32)
  214 
  215 static void randtemplate(char *template, size_t l) {
  216     // just to avoid calls within the same second 
  217     srand(time (NULL) + (unsigned int)template);
  218     for (size_t i = l - 6; i < l; i++) {
  219         int r = rand();
  220         if ((r / (RAND_MAX + 1)) > ((RAND_MAX + 1) / 2))
  221             template[i] = 'A' + (double) rand () / (RAND_MAX + 1) * ('Z' - 'A');
  222         else
  223             template[i] = 'a' + (double) rand () / (RAND_MAX + 1) * ('z' - 'a');
  224     }
  225 }
  226 
  227 char* strrstr (char* haystack, char* needle)
  228 {
  229   int needle_length = strlen(needle);
  230   char * haystack_end = haystack + strlen(haystack) - needle_length;
  231   char * p;
  232   int i;
  233 
  234   for(p = haystack_end; p >= haystack; --p)
  235   {
  236     for(i = 0; i < needle_length; ++i) {
  237       if(p[i] != needle[i])
  238         goto next;
  239     }
  240     return p;
  241 
  242     next:;
  243   }
  244   return 0;
  245 }
  246 
  247 
  248 static char *
  249 mkdtemp (char *tmpl)
  250 {
  251     size_t l;
  252     char attempts = 8;
  253     int res = 0;
  254 
  255     if (tmpl == NULL) {
  256         errno = EINVAL;
  257         return NULL;
  258     }
  259 
  260     l = strlen (tmpl);
  261     if (l < 6 || strcmp (&tmpl[l - 6], "XXXXXX") != 0) {
  262         errno = EINVAL;
  263         return NULL;
  264     }
  265     do {
  266         randtemplate (tmpl, l);
  267         res = mkdir(tmpl);
  268         attempts--;
  269     } while (attempts > 0 && res != 0 );
  270     
  271     if (res == 0) {
  272         return tmpl;
  273     }
  274     if (errno != EEXIST) {
  275         printf("Failed to create tmp dir, last attempt %s.", tmpl);
  276         return NULL;
  277     }
  278 
  279     /* We got out of the loop because we ran out of combinations to try.  */
  280     errno = EEXIST;
  281     return NULL;
  282 }
  283 #endif
  284 
  285 const char *gdTestTempDir(void)
  286 {
  287     if (tmpdir_base == NULL) {
  288         char *tmpdir;
  289 #if defined(_WIN32)  && !defined(__MINGW32__) &&  !defined(__MINGW64__)
  290         char tmpdir_root[MAXPATHLEN];
  291         size_t tmpdir_root_len = GetTempPath(MAX_PATH, tmpdir_root);
  292         if ((tmpdir_root_len + 30 > MAX_PATH) || (tmpdir_root_len == 0)) {
  293             printf("Tmp dir path too long or 0 length <%s>\n", tmpdir_root);
  294             return NULL;
  295         }
  296 #else
  297         char *tmpdir_root;
  298         tmpdir_root = getenv("TMPDIR");
  299         if (tmpdir_root == NULL) {
  300             // Mingw defines it
  301             tmpdir_root = getenv("TMP");
  302             if (tmpdir_root == NULL) {
  303                 // Fall back here.
  304                 tmpdir_root = "/tmp";
  305                 if (!gdTestIsDir(tmpdir_root)) {
  306                     printf("tmpdir failed to be used or initialized (%s).", tmpdir_root);
  307                     exit(2);
  308                 }
  309             }
  310         }
  311 #endif
  312 
  313         /* The constant here is a lazy over-estimate. */
  314         tmpdir = malloc(strlen(tmpdir_root) + 30);
  315         if (tmpdir == NULL) {
  316             printf("cannot alloc tmpdir path.");
  317             return NULL;
  318         }
  319 
  320 #if defined(_WIN32)
  321         sprintf(tmpdir, "%sgdtest.XXXXXX", tmpdir_root);
  322 #else
  323         sprintf(tmpdir, "%s/gdtest.XXXXXX", tmpdir_root);
  324 #endif
  325 
  326         tmpdir_base = mkdtemp(tmpdir);
  327         if (tmpdir_base == NULL) {
  328             printf("failed to generate the tmp dir path (%s).", tmpdir);
  329             return NULL;
  330         }
  331 
  332         atexit(tmpdir_cleanup);
  333     }
  334 
  335     return tmpdir_base;
  336 }
  337 
  338 char *gdTestTempFile(const char *template)
  339 {
  340     const char *tempdir = gdTestTempDir();
  341     char *ret;
  342     if (tempdir == NULL) {
  343         return NULL;
  344     }
  345 #if defined(_WIN32) && !defined(__MINGW32__) &&  !defined(__MINGW64__)
  346     {
  347         char *tmpfilename;
  348         UINT error;
  349 
  350         ret = malloc(MAX_PATH);
  351         if (ret == NULL) {
  352             printf("Failed to alloc tmp path");
  353             return NULL;
  354         }
  355         if (template == NULL) {
  356             error = GetTempFileName(tempdir,
  357                                           "gdtest",
  358                                           0,
  359                                           ret);
  360             if (error = 0)  {
  361                 printf("GetTempFileName failed.");
  362                 gdFree(ret);
  363                 return NULL;
  364             }
  365         } else {
  366             sprintf(ret, "%s\\%s", tempdir, template);
  367         }
  368     }
  369 #else
  370     if (template == NULL) {
  371         template = "gdtemp.XXXXXX";
  372     }
  373     ret = malloc(strlen(tempdir) + 10 + strlen(template));
  374     if (ret == NULL) {
  375         printf("Failed to alloc tmp path");
  376         return NULL;
  377     }
  378     sprintf(ret, "%s/%s", tempdir, template);
  379 
  380     if (strstr(template, "XXXXXX") != NULL) {
  381         int fd = mkstemp(ret);
  382         if (fd == -1) {
  383             printf("mkstemp failed");
  384             gdFree(ret);
  385             return NULL;
  386         }
  387         close(fd);
  388     }
  389 #endif
  390     return ret;
  391 }
  392 
  393 FILE *gdTestTempFp(void)
  394 {
  395     char *file = gdTestTempFile(NULL);
  396     FILE *fp = fopen(file, "wb");
  397     if (fp == NULL) {
  398         printf("fail to open tmp file");
  399         return NULL;
  400     }
  401     free(file);
  402     return fp;
  403 }
  404 
  405 char *gdTestFilePathV(const char *path, va_list args)
  406 {
  407     size_t len;
  408     const char *p;
  409     char *file;
  410     va_list args_len;
  411 
  412     /* Figure out how much space we need. */
  413     va_copy(args_len, args);
  414     len = strlen(GDTEST_TOP_DIR) + 1;
  415     p = path;
  416     do {
  417         len += strlen(p) + 1;
  418     } while ((p = va_arg(args_len, const char *)) != NULL);
  419     va_end(args_len);
  420 
  421     /* Now build the path. */
  422     file = malloc(len);
  423     if (file == NULL) {
  424         printf("failed to alloc path.");
  425         return NULL;
  426     }
  427     strcpy(file, GDTEST_TOP_DIR);
  428     p = path;
  429     do {
  430 #if defined(_WIN32) && !defined(__MINGW32__) &&  !defined(__MINGW64__)
  431         strcat(file, "\\");
  432 #else
  433         strcat(file, "/");
  434 #endif
  435         strcat(file, p);
  436 
  437     } while ((p = va_arg(args, const char *)) != NULL);
  438     va_end(args);
  439 
  440     return file;
  441 }
  442 
  443 char *gdTestFilePathX(const char *path, ...)
  444 {
  445     va_list args;
  446     va_start(args, path);
  447     return gdTestFilePathV(path, args);
  448 }
  449 
  450 FILE *gdTestFileOpenX(const char *path, ...)
  451 {
  452     va_list args;
  453     FILE *fp;
  454     char *file;
  455 
  456     va_start(args, path);
  457     file = gdTestFilePathV(path, args);
  458     fp = fopen(file, "rb");
  459     if (fp == NULL) {
  460         printf("failed to open path (rb).");
  461         return NULL;
  462     }
  463     free(file);
  464     return fp;
  465 }
  466 
  467 /* Compare two buffers, returning the number of pixels that are
  468  * different and the maximum difference of any single color channel in
  469  * result_ret.
  470  *
  471  * This function should be rewritten to compare all formats supported by
  472  * cairo_format_t instead of taking a mask as a parameter.
  473  */
  474 void gdTestImageDiff(gdImagePtr buf_a, gdImagePtr buf_b,
  475                      gdImagePtr buf_diff, CuTestImageResult *result_ret)
  476 {
  477     int x, y;
  478     int c1, c2;
  479 #   define UP_DIFF(var) result_ret->max_diff = max((var), result_ret->max_diff)
  480 
  481     for (y = 0; y < gdImageSY(buf_a); y++) {
  482         for (x = 0; x < gdImageSX(buf_a); x++) {
  483             c1 = gdImageGetTrueColorPixel(buf_a, x, y);
  484             c2 = gdImageGetTrueColorPixel(buf_b, x, y);
  485 
  486             /* check if the pixels are the same */
  487             if (c1 != c2) {
  488                 int r1,b1,g1,a1,r2,b2,g2,a2;
  489                 unsigned int diff_a,diff_r,diff_g,diff_b;
  490 
  491                 a1 = gdTrueColorGetAlpha(c1);
  492                 a2 = gdTrueColorGetAlpha(c2);
  493                 diff_a = abs (a1 - a2);
  494                 diff_a *= 4;  /* emphasize */
  495 
  496                 if (diff_a) {
  497                     diff_a += 128; /* make sure it's visible */
  498                 }
  499                 if (diff_a > gdAlphaMax) {
  500                     diff_a = gdAlphaMax/2;
  501                 }
  502 
  503                 r1 = gdTrueColorGetRed(c1);
  504                 r2 = gdTrueColorGetRed(c2);
  505                 diff_r = abs (r1 - r2);
  506                 // diff_r *= 4;  /* emphasize */
  507                 if (diff_r) {
  508                     diff_r += gdRedMax/2; /* make sure it's visible */
  509                 }
  510                 if (diff_r > 255) {
  511                     diff_r = 255;
  512                 }
  513                 UP_DIFF(diff_r);
  514 
  515                 g1 = gdTrueColorGetGreen(c1);
  516                 g2 = gdTrueColorGetGreen(c2);
  517                 diff_g = abs (g1 - g2);
  518 
  519                 diff_g *= 4;  /* emphasize */
  520                 if (diff_g) {
  521                     diff_g += gdGreenMax/2; /* make sure it's visible */
  522                 }
  523                 if (diff_g > 255) {
  524                     diff_g = 255;
  525                 }
  526                 UP_DIFF(diff_g);
  527 
  528                 b1 = gdTrueColorGetBlue(c1);
  529                 b2 = gdTrueColorGetBlue(c2);
  530                 diff_b = abs (b1 - b2);
  531                 diff_b *= 4;  /* emphasize */
  532                 if (diff_b) {
  533                     diff_b += gdBlueMax/2; /* make sure it's visible */
  534                 }
  535                 if (diff_b > 255) {
  536                     diff_b = 255;
  537                 }
  538                 UP_DIFF(diff_b);
  539 
  540                 result_ret->pixels_changed++;
  541                 if (buf_diff) gdImageSetPixel(buf_diff, x,y, gdTrueColorAlpha(diff_r, diff_g, diff_b, diff_a));
  542             } else {
  543                 if (buf_diff) gdImageSetPixel(buf_diff, x,y, gdTrueColorAlpha(255,255,255,0));
  544             }
  545         }
  546     }
  547 #   undef UP_DIFF
  548 }
  549 
  550 
  551 /* Return the largest difference between two corresponding pixels and
  552  * channels. */
  553 unsigned int gdMaxPixelDiff(gdImagePtr a, gdImagePtr b)
  554 {
  555     int diff = 0;
  556     int x, y;
  557 
  558     if (a == NULL || b == NULL || a->sx != b->sx || a->sy != b->sy)
  559         return UINT_MAX;
  560 
  561     for (x = 0; x < a->sx; x++) {
  562         for (y = 0; y < a->sy; y++) {
  563             int c1, c2;
  564 
  565             c1 = gdImageGetTrueColorPixel(a, x, y);
  566             c2 = gdImageGetTrueColorPixel(b, x, y);
  567             if (c1 == c2) continue;
  568 
  569             diff = max(diff, abs(gdTrueColorGetAlpha(c1) - gdTrueColorGetAlpha(c2)));
  570             diff = max(diff, abs(gdTrueColorGetRed(c1)   - gdTrueColorGetRed(c2)));
  571             diff = max(diff, abs(gdTrueColorGetGreen(c1) - gdTrueColorGetGreen(c2)));
  572             diff = max(diff, abs(gdTrueColorGetBlue(c1)  - gdTrueColorGetBlue(c2)));
  573         }/* for */
  574     }/* for */
  575 
  576     return diff;
  577 }
  578 
  579 int gdTestImageCompareToImage(const char* file, unsigned int line, const char* message,
  580                               gdImagePtr expected, gdImagePtr actual)
  581 {
  582     unsigned int width_a, height_a;
  583     unsigned int width_b, height_b;
  584     gdImagePtr surface_diff = NULL;
  585     CuTestImageResult result = {0, 0};
  586 
  587     (void)message;
  588 
  589     if (!actual) {
  590         _gdTestErrorMsg(file, line, "Image is NULL\n");
  591         goto fail;
  592     }
  593 
  594     width_a  = gdImageSX(expected);
  595     height_a = gdImageSY(expected);
  596     width_b  = gdImageSX(actual);
  597     height_b = gdImageSY(actual);
  598 
  599     if (width_a  != width_b  || height_a != height_b) {
  600         _gdTestErrorMsg(file, line,
  601                 "Image size mismatch: (%ux%u) vs. (%ux%u)\n       for %s vs. buffer\n",
  602                 width_a, height_a,
  603                 width_b, height_b,
  604                 file);
  605         goto fail;
  606     }
  607 
  608     surface_diff = gdImageCreateTrueColor(width_a, height_a);
  609 
  610     gdTestImageDiff(expected, actual, surface_diff, &result);
  611     if (result.pixels_changed>0) {
  612         char file_diff[255];
  613         char file_out[1024];
  614         FILE *fp;
  615         int len, p;
  616 
  617         _gdTestErrorMsg(file, line,
  618                 "Total pixels changed: %d with a maximum channel difference of %d.\n",
  619                 result.pixels_changed,
  620                 result.max_diff
  621             );
  622 
  623         p = len = strlen(file);
  624         p--;
  625 
  626         /* Use only the filename (and store it in the bld dir not the src dir
  627          */
  628         while(p > 0 && (file[p] != '/' && file[p] != '\\')) {
  629             p--;
  630         }
  631         sprintf(file_diff, "%s_%u_diff.png", file + p  + 1, line);
  632         sprintf(file_out, "%s_%u_out.png", file + p  + 1, line);
  633 
  634         fp = fopen(file_diff, "wb");
  635         if (!fp) goto fail;
  636         gdImagePng(surface_diff,fp);
  637         fclose(fp);
  638         gdImageDestroy(surface_diff);
  639 
  640         fp = fopen(file_out, "wb");
  641         if (!fp) goto fail;
  642         gdImagePng(actual, fp);
  643         fclose(fp);
  644         return 0;
  645     } else {
  646         if (surface_diff) {
  647             gdImageDestroy(surface_diff);
  648         }
  649         return 1;
  650     }
  651 
  652 fail:
  653     if (surface_diff) {
  654         gdImageDestroy(surface_diff);
  655     }
  656     return 1;
  657 }
  658 
  659 int gdTestImageCompareToFile(const char* file, unsigned int line, const char* message,
  660                              const char *expected_file, gdImagePtr actual)
  661 {
  662     gdImagePtr expected = 0;
  663     int res = 1;
  664 
  665     expected = gdTestImageFromPng(expected_file);
  666 
  667     if (!expected) {
  668         _gdTestErrorMsg(file, line, "Cannot open PNG <%s>\n", expected_file);
  669         res = 0;
  670     } else {
  671         res = gdTestImageCompareToImage(file, line, message, expected, actual);
  672         gdImageDestroy(expected);
  673     }
  674     return res;
  675 }
  676 
  677 static int failureCount = 0;
  678 
  679 int gdNumFailures() {
  680     return failureCount;
  681 }
  682 
  683 int _gdTestAssert(const char* file, unsigned int line, int condition)
  684 {
  685     if (condition) return 1;
  686     _gdTestErrorMsg(file, line, "Assert failed in <%s:%i>\n", file, line);
  687 
  688     ++failureCount;
  689 
  690     return 0;
  691 }
  692 
  693 int _gdTestAssertMsg(const char* file, unsigned int line, int condition, const char* message, ...)
  694 {
  695     va_list args;
  696 
  697     if (condition) return 1;
  698 
  699     fprintf(stderr, "%s:%u: ", file, line);
  700     va_start(args, message);
  701     vfprintf(stderr, message, args);
  702     va_end(args);
  703 
  704     fflush(stderr);
  705 
  706     ++failureCount;
  707 
  708     return 0;
  709 }
  710 
  711 int _gdTestErrorMsg(const char* file, unsigned int line, const char* format, ...) /* {{{ */
  712 {
  713     va_list args;
  714 
  715     fprintf(stderr, "%s:%u: ", file, line);
  716     va_start(args, format);
  717     vfprintf(stderr, format, args);
  718     va_end(args);
  719     fflush(stderr);
  720 
  721     ++failureCount;
  722 
  723     return 0;
  724 }
  725 /* }}} */