Home | History | Annotate | Download | only in glib
      1 /* GLib testing utilities
      2  * Copyright (C) 2007 Imendio AB
      3  * Authors: Tim Janik, Sven Herzberg
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Lesser General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Lesser General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Lesser General Public
     16  * License along with this library; if not, write to the
     17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     18  * Boston, MA 02111-1307, USA.
     19  */
     20 #include "config.h"
     21 #include "gtestutils.h"
     22 #include "galias.h"
     23 #include <sys/types.h>
     24 #ifdef G_OS_UNIX
     25 #include <sys/wait.h>
     26 #include <sys/time.h>
     27 #include <fcntl.h>
     28 #endif
     29 #include <string.h>
     30 #include <stdlib.h>
     31 #include <stdio.h>
     32 #ifdef HAVE_UNISTD_H
     33 #include <unistd.h>
     34 #endif
     35 #ifdef G_OS_WIN32
     36 #include <io.h>
     37 #endif
     38 #include <errno.h>
     39 #include <signal.h>
     40 #ifdef HAVE_SYS_SELECT_H
     41 #include <sys/select.h>
     42 #endif /* HAVE_SYS_SELECT_H */
     43 
     44 /* --- structures --- */
     45 struct GTestCase
     46 {
     47   gchar  *name;
     48   guint   fixture_size;
     49   void   (*fixture_setup)    (void*, gconstpointer);
     50   void   (*fixture_test)     (void*, gconstpointer);
     51   void   (*fixture_teardown) (void*, gconstpointer);
     52   gpointer test_data;
     53 };
     54 struct GTestSuite
     55 {
     56   gchar  *name;
     57   GSList *suites;
     58   GSList *cases;
     59 };
     60 typedef struct DestroyEntry DestroyEntry;
     61 struct DestroyEntry
     62 {
     63   DestroyEntry *next;
     64   GDestroyNotify destroy_func;
     65   gpointer       destroy_data;
     66 };
     67 
     68 /* --- prototypes --- */
     69 static void     test_run_seed                   (const gchar *rseed);
     70 static void     test_trap_clear                 (void);
     71 static guint8*  g_test_log_dump                 (GTestLogMsg *msg,
     72                                                  guint       *len);
     73 static void     gtest_default_log_handler       (const gchar    *log_domain,
     74                                                  GLogLevelFlags  log_level,
     75                                                  const gchar    *message,
     76                                                  gpointer        unused_data);
     77 
     78 
     79 /* --- variables --- */
     80 static int         test_log_fd = -1;
     81 static gboolean    test_mode_fatal = TRUE;
     82 static gboolean    g_test_run_once = TRUE;
     83 static gboolean    test_run_list = FALSE;
     84 static gchar      *test_run_seedstr = NULL;
     85 static GRand      *test_run_rand = NULL;
     86 static gchar      *test_run_name = "";
     87 static guint       test_run_forks = 0;
     88 static guint       test_run_count = 0;
     89 static guint       test_skip_count = 0;
     90 static GTimer     *test_user_timer = NULL;
     91 static double      test_user_stamp = 0;
     92 static GSList     *test_paths = NULL;
     93 static GTestSuite *test_suite_root = NULL;
     94 static int         test_trap_last_status = 0;
     95 static int         test_trap_last_pid = 0;
     96 static char       *test_trap_last_stdout = NULL;
     97 static char       *test_trap_last_stderr = NULL;
     98 static char       *test_uri_base = NULL;
     99 static gboolean    test_debug_log = FALSE;
    100 static DestroyEntry *test_destroy_queue = NULL;
    101 static GTestConfig mutable_test_config_vars = {
    102   FALSE,        /* test_initialized */
    103   TRUE,         /* test_quick */
    104   FALSE,        /* test_perf */
    105   FALSE,        /* test_verbose */
    106   FALSE,        /* test_quiet */
    107 };
    108 const GTestConfig * const g_test_config_vars = &mutable_test_config_vars;
    109 
    110 /* --- functions --- */
    111 const char*
    112 g_test_log_type_name (GTestLogType log_type)
    113 {
    114   switch (log_type)
    115     {
    116     case G_TEST_LOG_NONE:               return "none";
    117     case G_TEST_LOG_ERROR:              return "error";
    118     case G_TEST_LOG_START_BINARY:       return "binary";
    119     case G_TEST_LOG_LIST_CASE:          return "list";
    120     case G_TEST_LOG_SKIP_CASE:          return "skip";
    121     case G_TEST_LOG_START_CASE:         return "start";
    122     case G_TEST_LOG_STOP_CASE:          return "stop";
    123     case G_TEST_LOG_MIN_RESULT:         return "minperf";
    124     case G_TEST_LOG_MAX_RESULT:         return "maxperf";
    125     case G_TEST_LOG_MESSAGE:            return "message";
    126     }
    127   return "???";
    128 }
    129 
    130 static void
    131 g_test_log_send (guint         n_bytes,
    132                  const guint8 *buffer)
    133 {
    134   if (test_log_fd >= 0)
    135     {
    136       int r;
    137       do
    138         r = write (test_log_fd, buffer, n_bytes);
    139       while (r < 0 && errno == EINTR);
    140     }
    141   if (test_debug_log)
    142     {
    143       GTestLogBuffer *lbuffer = g_test_log_buffer_new ();
    144       GTestLogMsg *msg;
    145       guint ui;
    146       g_test_log_buffer_push (lbuffer, n_bytes, buffer);
    147       msg = g_test_log_buffer_pop (lbuffer);
    148       g_warn_if_fail (msg != NULL);
    149       g_warn_if_fail (lbuffer->data->len == 0);
    150       g_test_log_buffer_free (lbuffer);
    151       /* print message */
    152       g_printerr ("{*LOG(%s)", g_test_log_type_name (msg->log_type));
    153       for (ui = 0; ui < msg->n_strings; ui++)
    154         g_printerr (":{%s}", msg->strings[ui]);
    155       if (msg->n_nums)
    156         {
    157           g_printerr (":(");
    158           for (ui = 0; ui < msg->n_nums; ui++)
    159             g_printerr ("%s%.16Lg", ui ? ";" : "", msg->nums[ui]);
    160           g_printerr (")");
    161         }
    162       g_printerr (":LOG*}\n");
    163       g_test_log_msg_free (msg);
    164     }
    165 }
    166 
    167 static void
    168 g_test_log (GTestLogType lbit,
    169             const gchar *string1,
    170             const gchar *string2,
    171             guint        n_args,
    172             long double *largs)
    173 {
    174   gboolean fail = lbit == G_TEST_LOG_STOP_CASE && largs[0] != 0;
    175   GTestLogMsg msg;
    176   gchar *astrings[3] = { NULL, NULL, NULL };
    177   guint8 *dbuffer;
    178   guint32 dbufferlen;
    179 
    180   switch (lbit)
    181     {
    182     case G_TEST_LOG_START_BINARY:
    183       if (g_test_verbose())
    184         g_print ("GTest: random seed: %s\n", string2);
    185       break;
    186     case G_TEST_LOG_STOP_CASE:
    187       if (g_test_verbose())
    188         g_print ("GTest: result: %s\n", fail ? "FAIL" : "OK");
    189       else if (!g_test_quiet())
    190         g_print ("%s\n", fail ? "FAIL" : "OK");
    191       if (fail && test_mode_fatal)
    192         abort();
    193       break;
    194     case G_TEST_LOG_MIN_RESULT:
    195       if (g_test_verbose())
    196         g_print ("(MINPERF:%s)\n", string1);
    197       break;
    198     case G_TEST_LOG_MAX_RESULT:
    199       if (g_test_verbose())
    200         g_print ("(MAXPERF:%s)\n", string1);
    201       break;
    202     case G_TEST_LOG_MESSAGE:
    203       if (g_test_verbose())
    204         g_print ("(MSG: %s)\n", string1);
    205       break;
    206     default: ;
    207     }
    208 
    209   msg.log_type = lbit;
    210   msg.n_strings = (string1 != NULL) + (string1 && string2);
    211   msg.strings = astrings;
    212   astrings[0] = (gchar*) string1;
    213   astrings[1] = astrings[0] ? (gchar*) string2 : NULL;
    214   msg.n_nums = n_args;
    215   msg.nums = largs;
    216   dbuffer = g_test_log_dump (&msg, &dbufferlen);
    217   g_test_log_send (dbufferlen, dbuffer);
    218   g_free (dbuffer);
    219 
    220   switch (lbit)
    221     {
    222     case G_TEST_LOG_START_CASE:
    223       if (g_test_verbose())
    224         g_print ("GTest: run: %s\n", string1);
    225       else if (!g_test_quiet())
    226         g_print ("%s: ", string1);
    227       break;
    228     default: ;
    229     }
    230 }
    231 
    232 /* We intentionally parse the command line without GOptionContext
    233  * because otherwise you would never be able to test it.
    234  */
    235 static void
    236 parse_args (gint    *argc_p,
    237             gchar ***argv_p)
    238 {
    239   guint argc = *argc_p;
    240   gchar **argv = *argv_p;
    241   guint i, e;
    242   /* parse known args */
    243   for (i = 1; i < argc; i++)
    244     {
    245       if (strcmp (argv[i], "--g-fatal-warnings") == 0)
    246         {
    247           GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
    248           fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
    249           g_log_set_always_fatal (fatal_mask);
    250           argv[i] = NULL;
    251         }
    252       else if (strcmp (argv[i], "--keep-going") == 0 ||
    253                strcmp (argv[i], "-k") == 0)
    254         {
    255           test_mode_fatal = FALSE;
    256           argv[i] = NULL;
    257         }
    258       else if (strcmp (argv[i], "--debug-log") == 0)
    259         {
    260           test_debug_log = TRUE;
    261           argv[i] = NULL;
    262         }
    263       else if (strcmp ("--GTestLogFD", argv[i]) == 0 || strncmp ("--GTestLogFD=", argv[i], 13) == 0)
    264         {
    265           gchar *equal = argv[i] + 12;
    266           if (*equal == '=')
    267             test_log_fd = g_ascii_strtoull (equal + 1, NULL, 0);
    268           else if (i + 1 < argc)
    269             {
    270               argv[i++] = NULL;
    271               test_log_fd = g_ascii_strtoull (argv[i], NULL, 0);
    272             }
    273           argv[i] = NULL;
    274         }
    275       else if (strcmp ("--GTestSkipCount", argv[i]) == 0 || strncmp ("--GTestSkipCount=", argv[i], 17) == 0)
    276         {
    277           gchar *equal = argv[i] + 16;
    278           if (*equal == '=')
    279             test_skip_count = g_ascii_strtoull (equal + 1, NULL, 0);
    280           else if (i + 1 < argc)
    281             {
    282               argv[i++] = NULL;
    283               test_skip_count = g_ascii_strtoull (argv[i], NULL, 0);
    284             }
    285           argv[i] = NULL;
    286         }
    287       else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0)
    288         {
    289           gchar *equal = argv[i] + 2;
    290           if (*equal == '=')
    291             test_paths = g_slist_prepend (test_paths, equal + 1);
    292           else if (i + 1 < argc)
    293             {
    294               argv[i++] = NULL;
    295               test_paths = g_slist_prepend (test_paths, argv[i]);
    296             }
    297           argv[i] = NULL;
    298         }
    299       else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
    300         {
    301           gchar *equal = argv[i] + 2;
    302           const gchar *mode = "";
    303           if (*equal == '=')
    304             mode = equal + 1;
    305           else if (i + 1 < argc)
    306             {
    307               argv[i++] = NULL;
    308               mode = argv[i];
    309             }
    310           if (strcmp (mode, "perf") == 0)
    311             mutable_test_config_vars.test_perf = TRUE;
    312           else if (strcmp (mode, "slow") == 0)
    313             mutable_test_config_vars.test_quick = FALSE;
    314           else if (strcmp (mode, "thorough") == 0)
    315             mutable_test_config_vars.test_quick = FALSE;
    316           else if (strcmp (mode, "quick") == 0)
    317             {
    318               mutable_test_config_vars.test_quick = TRUE;
    319               mutable_test_config_vars.test_perf = FALSE;
    320             }
    321           else
    322             g_error ("unknown test mode: -m %s", mode);
    323           argv[i] = NULL;
    324         }
    325       else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0)
    326         {
    327           mutable_test_config_vars.test_quiet = TRUE;
    328           mutable_test_config_vars.test_verbose = FALSE;
    329           argv[i] = NULL;
    330         }
    331       else if (strcmp ("--verbose", argv[i]) == 0)
    332         {
    333           mutable_test_config_vars.test_quiet = FALSE;
    334           mutable_test_config_vars.test_verbose = TRUE;
    335           argv[i] = NULL;
    336         }
    337       else if (strcmp ("-l", argv[i]) == 0)
    338         {
    339           test_run_list = TRUE;
    340           argv[i] = NULL;
    341         }
    342       else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0)
    343         {
    344           gchar *equal = argv[i] + 6;
    345           if (*equal == '=')
    346             test_run_seedstr = equal + 1;
    347           else if (i + 1 < argc)
    348             {
    349               argv[i++] = NULL;
    350               test_run_seedstr = argv[i];
    351             }
    352           argv[i] = NULL;
    353         }
    354       else if (strcmp ("-?", argv[i]) == 0 || strcmp ("--help", argv[i]) == 0)
    355         {
    356           printf ("Usage:\n"
    357                   "  %s [OPTION...]\n\n"
    358                   "Help Options:\n"
    359                   "  -?, --help                     Show help options\n"
    360                   "Test Options:\n"
    361                   "  -l                             List test cases available in a test executable\n"
    362                   "  -seed=RANDOMSEED               Provide a random seed to reproduce test\n"
    363                   "                                 runs using random numbers\n"
    364                   "  --verbose                      Run tests verbosely\n"
    365                   "  -q, --quiet                    Run tests quietly\n"
    366                   "  -p TESTPATH                    execute all tests matching TESTPATH\n"
    367                   "  -m {perf|slow|thorough|quick}  Execute tests according modes\n"
    368                   "  --debug-log                    debug test logging output\n"
    369                   "  -k, --keep-going               gtester-specific argument\n"
    370                   "  --GTestLogFD=N                 gtester-specific argument\n"
    371                   "  --GTestSkipCount=N             gtester-specific argument\n",
    372                   argv[0]);
    373           exit (0);
    374         }
    375     }
    376   /* collapse argv */
    377   e = 1;
    378   for (i = 1; i < argc; i++)
    379     if (argv[i])
    380       {
    381         argv[e++] = argv[i];
    382         if (i >= e)
    383           argv[i] = NULL;
    384       }
    385   *argc_p = e;
    386 }
    387 
    388 /**
    389  * g_test_init:
    390  * @argc: Address of the @argc parameter of the main() function.
    391  *        Changed if any arguments were handled.
    392  * @argv: Address of the @argv parameter of main().
    393  *        Any parameters understood by g_test_init() stripped before return.
    394  * @Varargs: Reserved for future extension. Currently, you must pass %NULL.
    395  *
    396  * Initialize the GLib testing framework, e.g. by seeding the
    397  * test random number generator, the name for g_get_prgname()
    398  * and parsing test related command line args.
    399  * So far, the following arguments are understood:
    400  * <variablelist>
    401  *   <varlistentry>
    402  *     <term><option>-l</option></term>
    403  *     <listitem><para>
    404  *       list test cases available in a test executable.
    405  *     </para></listitem>
    406  *   </varlistentry>
    407  *   <varlistentry>
    408  *     <term><option>--seed=<replaceable>RANDOMSEED</replaceable></option></term>
    409  *     <listitem><para>
    410  *       provide a random seed to reproduce test runs using random numbers.
    411  *     </para></listitem>
    412  *     </varlistentry>
    413  *     <varlistentry>
    414  *       <term><option>--verbose</option></term>
    415  *       <listitem><para>run tests verbosely.</para></listitem>
    416  *     </varlistentry>
    417  *     <varlistentry>
    418  *       <term><option>-q</option>, <option>--quiet</option></term>
    419  *       <listitem><para>run tests quietly.</para></listitem>
    420  *     </varlistentry>
    421  *     <varlistentry>
    422  *       <term><option>-p <replaceable>TESTPATH</replaceable></option></term>
    423  *       <listitem><para>
    424  *         execute all tests matching <replaceable>TESTPATH</replaceable>.
    425  *       </para></listitem>
    426  *     </varlistentry>
    427  *     <varlistentry>
    428  *       <term><option>-m {perf|slow|thorough|quick}</option></term>
    429  *       <listitem><para>
    430  *         execute tests according to these test modes:
    431  *         <variablelist>
    432  *           <varlistentry>
    433  *             <term>perf</term>
    434  *             <listitem><para>
    435  *               performance tests, may take long and report results.
    436  *             </para></listitem>
    437  *           </varlistentry>
    438  *           <varlistentry>
    439  *             <term>slow, thorough</term>
    440  *             <listitem><para>
    441  *               slow and thorough tests, may take quite long and
    442  *               maximize coverage.
    443  *             </para></listitem>
    444  *           </varlistentry>
    445  *           <varlistentry>
    446  *             <term>quick</term>
    447  *             <listitem><para>
    448  *               quick tests, should run really quickly and give good coverage.
    449  *             </para></listitem>
    450  *           </varlistentry>
    451  *         </variablelist>
    452  *       </para></listitem>
    453  *     </varlistentry>
    454  *     <varlistentry>
    455  *       <term><option>--debug-log</option></term>
    456  *       <listitem><para>debug test logging output.</para></listitem>
    457  *     </varlistentry>
    458  *     <varlistentry>
    459  *       <term><option>-k</option>, <option>--keep-going</option></term>
    460  *       <listitem><para>gtester-specific argument.</para></listitem>
    461  *     </varlistentry>
    462  *     <varlistentry>
    463  *       <term><option>--GTestLogFD <replaceable>N</replaceable></option></term>
    464  *       <listitem><para>gtester-specific argument.</para></listitem>
    465  *     </varlistentry>
    466  *     <varlistentry>
    467  *       <term><option>--GTestSkipCount <replaceable>N</replaceable></option></term>
    468  *       <listitem><para>gtester-specific argument.</para></listitem>
    469  *     </varlistentry>
    470  *  </variablelist>
    471  *
    472  * Since: 2.16
    473  */
    474 void
    475 g_test_init (int    *argc,
    476              char ***argv,
    477              ...)
    478 {
    479   static char seedstr[4 + 4 * 8 + 1];
    480   va_list args;
    481   gpointer vararg1;
    482   /* make warnings and criticals fatal for all test programs */
    483   GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
    484   fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
    485   g_log_set_always_fatal (fatal_mask);
    486   /* check caller args */
    487   g_return_if_fail (argc != NULL);
    488   g_return_if_fail (argv != NULL);
    489   g_return_if_fail (g_test_config_vars->test_initialized == FALSE);
    490   mutable_test_config_vars.test_initialized = TRUE;
    491 
    492   va_start (args, argv);
    493   vararg1 = va_arg (args, gpointer); /* reserved for future extensions */
    494   va_end (args);
    495   g_return_if_fail (vararg1 == NULL);
    496 
    497   /* setup random seed string */
    498   g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x", g_random_int(), g_random_int(), g_random_int(), g_random_int());
    499   test_run_seedstr = seedstr;
    500 
    501   /* parse args, sets up mode, changes seed, etc. */
    502   parse_args (argc, argv);
    503   if (!g_get_prgname())
    504     g_set_prgname ((*argv)[0]);
    505 
    506   /* verify GRand reliability, needed for reliable seeds */
    507   if (1)
    508     {
    509       GRand *rg = g_rand_new_with_seed (0xc8c49fb6);
    510       guint32 t1 = g_rand_int (rg), t2 = g_rand_int (rg), t3 = g_rand_int (rg), t4 = g_rand_int (rg);
    511       /* g_print ("GRand-current: 0x%x 0x%x 0x%x 0x%x\n", t1, t2, t3, t4); */
    512       if (t1 != 0xfab39f9b || t2 != 0xb948fb0e || t3 != 0x3d31be26 || t4 != 0x43a19d66)
    513         g_warning ("random numbers are not GRand-2.2 compatible, seeds may be broken (check $G_RANDOM_VERSION)");
    514       g_rand_free (rg);
    515     }
    516 
    517   /* check rand seed */
    518   test_run_seed (test_run_seedstr);
    519 
    520   /* report program start */
    521   g_log_set_default_handler (gtest_default_log_handler, NULL);
    522   g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL);
    523 }
    524 
    525 static void
    526 test_run_seed (const gchar *rseed)
    527 {
    528   guint seed_failed = 0;
    529   if (test_run_rand)
    530     g_rand_free (test_run_rand);
    531   test_run_rand = NULL;
    532   while (strchr (" \t\v\r\n\f", *rseed))
    533     rseed++;
    534   if (strncmp (rseed, "R02S", 4) == 0)  /* seed for random generator 02 (GRand-2.2) */
    535     {
    536       const char *s = rseed + 4;
    537       if (strlen (s) >= 32)             /* require 4 * 8 chars */
    538         {
    539           guint32 seedarray[4];
    540           gchar *p, hexbuf[9] = { 0, };
    541           memcpy (hexbuf, s + 0, 8);
    542           seedarray[0] = g_ascii_strtoull (hexbuf, &p, 16);
    543           seed_failed += p != NULL && *p != 0;
    544           memcpy (hexbuf, s + 8, 8);
    545           seedarray[1] = g_ascii_strtoull (hexbuf, &p, 16);
    546           seed_failed += p != NULL && *p != 0;
    547           memcpy (hexbuf, s + 16, 8);
    548           seedarray[2] = g_ascii_strtoull (hexbuf, &p, 16);
    549           seed_failed += p != NULL && *p != 0;
    550           memcpy (hexbuf, s + 24, 8);
    551           seedarray[3] = g_ascii_strtoull (hexbuf, &p, 16);
    552           seed_failed += p != NULL && *p != 0;
    553           if (!seed_failed)
    554             {
    555               test_run_rand = g_rand_new_with_seed_array (seedarray, 4);
    556               return;
    557             }
    558         }
    559     }
    560   g_error ("Unknown or invalid random seed: %s", rseed);
    561 }
    562 
    563 /**
    564  * g_test_rand_int:
    565  *
    566  * Get a reproducible random integer number.
    567  *
    568  * The random numbers generated by the g_test_rand_*() family of functions
    569  * change with every new test program start, unless the --seed option is
    570  * given when starting test programs.
    571  *
    572  * For individual test cases however, the random number generator is
    573  * reseeded, to avoid dependencies between tests and to make --seed
    574  * effective for all test cases.
    575  *
    576  * Returns: a random number from the seeded random number generator.
    577  *
    578  * Since: 2.16
    579  */
    580 gint32
    581 g_test_rand_int (void)
    582 {
    583   return g_rand_int (test_run_rand);
    584 }
    585 
    586 /**
    587  * g_test_rand_int_range:
    588  * @begin: the minimum value returned by this function
    589  * @end:   the smallest value not to be returned by this function
    590  *
    591  * Get a reproducible random integer number out of a specified range,
    592  * see g_test_rand_int() for details on test case random numbers.
    593  *
    594  * Returns: a number with @begin <= number < @end.
    595  *
    596  * Since: 2.16
    597  */
    598 gint32
    599 g_test_rand_int_range (gint32          begin,
    600                        gint32          end)
    601 {
    602   return g_rand_int_range (test_run_rand, begin, end);
    603 }
    604 
    605 /**
    606  * g_test_rand_double:
    607  *
    608  * Get a reproducible random floating point number,
    609  * see g_test_rand_int() for details on test case random numbers.
    610  *
    611  * Returns: a random number from the seeded random number generator.
    612  *
    613  * Since: 2.16
    614  */
    615 double
    616 g_test_rand_double (void)
    617 {
    618   return g_rand_double (test_run_rand);
    619 }
    620 
    621 /**
    622  * g_test_rand_double_range:
    623  * @range_start: the minimum value returned by this function
    624  * @range_end: the minimum value not returned by this function
    625  *
    626  * Get a reproducible random floating pointer number out of a specified range,
    627  * see g_test_rand_int() for details on test case random numbers.
    628  *
    629  * Returns: a number with @range_start <= number < @range_end.
    630  *
    631  * Since: 2.16
    632  */
    633 double
    634 g_test_rand_double_range (double          range_start,
    635                           double          range_end)
    636 {
    637   return g_rand_double_range (test_run_rand, range_start, range_end);
    638 }
    639 
    640 /**
    641  * g_test_timer_start:
    642  *
    643  * Start a timing test. Call g_test_timer_elapsed() when the task is supposed
    644  * to be done. Call this function again to restart the timer.
    645  *
    646  * Since: 2.16
    647  */
    648 void
    649 g_test_timer_start (void)
    650 {
    651   if (!test_user_timer)
    652     test_user_timer = g_timer_new();
    653   test_user_stamp = 0;
    654   g_timer_start (test_user_timer);
    655 }
    656 
    657 /**
    658  * g_test_timer_elapsed:
    659  *
    660  * Get the time since the last start of the timer with g_test_timer_start().
    661  *
    662  * Returns: the time since the last start of the timer, as a double
    663  *
    664  * Since: 2.16
    665  */
    666 double
    667 g_test_timer_elapsed (void)
    668 {
    669   test_user_stamp = test_user_timer ? g_timer_elapsed (test_user_timer, NULL) : 0;
    670   return test_user_stamp;
    671 }
    672 
    673 /**
    674  * g_test_timer_last:
    675  *
    676  * Report the last result of g_test_timer_elapsed().
    677  *
    678  * Returns: the last result of g_test_timer_elapsed(), as a double
    679  *
    680  * Since: 2.16
    681  */
    682 double
    683 g_test_timer_last (void)
    684 {
    685   return test_user_stamp;
    686 }
    687 
    688 /**
    689  * g_test_minimized_result:
    690  * @minimized_quantity: the reported value
    691  * @format: the format string of the report message
    692  * @Varargs: arguments to pass to the printf() function
    693  *
    694  * Report the result of a performance or measurement test.
    695  * The test should generally strive to minimize the reported
    696  * quantities (smaller values are better than larger ones),
    697  * this and @minimized_quantity can determine sorting
    698  * order for test result reports.
    699  *
    700  * Since: 2.16
    701  */
    702 void
    703 g_test_minimized_result (double          minimized_quantity,
    704                          const char     *format,
    705                          ...)
    706 {
    707   long double largs = minimized_quantity;
    708   gchar *buffer;
    709   va_list args;
    710   va_start (args, format);
    711   buffer = g_strdup_vprintf (format, args);
    712   va_end (args);
    713   g_test_log (G_TEST_LOG_MIN_RESULT, buffer, NULL, 1, &largs);
    714   g_free (buffer);
    715 }
    716 
    717 /**
    718  * g_test_maximized_result:
    719  * @maximized_quantity: the reported value
    720  * @format: the format string of the report message
    721  * @Varargs: arguments to pass to the printf() function
    722  *
    723  * Report the result of a performance or measurement test.
    724  * The test should generally strive to maximize the reported
    725  * quantities (larger values are better than smaller ones),
    726  * this and @maximized_quantity can determine sorting
    727  * order for test result reports.
    728  *
    729  * Since: 2.16
    730  */
    731 void
    732 g_test_maximized_result (double          maximized_quantity,
    733                          const char     *format,
    734                          ...)
    735 {
    736   long double largs = maximized_quantity;
    737   gchar *buffer;
    738   va_list args;
    739   va_start (args, format);
    740   buffer = g_strdup_vprintf (format, args);
    741   va_end (args);
    742   g_test_log (G_TEST_LOG_MAX_RESULT, buffer, NULL, 1, &largs);
    743   g_free (buffer);
    744 }
    745 
    746 /**
    747  * g_test_message:
    748  * @format: the format string
    749  * @...:    printf-like arguments to @format
    750  *
    751  * Add a message to the test report.
    752  *
    753  * Since: 2.16
    754  */
    755 void
    756 g_test_message (const char *format,
    757                 ...)
    758 {
    759   gchar *buffer;
    760   va_list args;
    761   va_start (args, format);
    762   buffer = g_strdup_vprintf (format, args);
    763   va_end (args);
    764   g_test_log (G_TEST_LOG_MESSAGE, buffer, NULL, 0, NULL);
    765   g_free (buffer);
    766 }
    767 
    768 /**
    769  * g_test_bug_base:
    770  * @uri_pattern: the base pattern for bug URIs
    771  *
    772  * Specify the base URI for bug reports.
    773  *
    774  * The base URI is used to construct bug report messages for
    775  * g_test_message() when g_test_bug() is called.
    776  * Calling this function outside of a test case sets the
    777  * default base URI for all test cases. Calling it from within
    778  * a test case changes the base URI for the scope of the test
    779  * case only.
    780  * Bug URIs are constructed by appending a bug specific URI
    781  * portion to @uri_pattern, or by replacing the special string
    782  * '%s' within @uri_pattern if that is present.
    783  *
    784  * Since: 2.16
    785  */
    786 void
    787 g_test_bug_base (const char *uri_pattern)
    788 {
    789   g_free (test_uri_base);
    790   test_uri_base = g_strdup (uri_pattern);
    791 }
    792 
    793 /**
    794  * g_test_bug:
    795  * @bug_uri_snippet: Bug specific bug tracker URI portion.
    796  *
    797  * This function adds a message to test reports that
    798  * associates a bug URI with a test case.
    799  * Bug URIs are constructed from a base URI set with g_test_bug_base()
    800  * and @bug_uri_snippet.
    801  *
    802  * Since: 2.16
    803  */
    804 void
    805 g_test_bug (const char *bug_uri_snippet)
    806 {
    807   char *c;
    808   g_return_if_fail (test_uri_base != NULL);
    809   g_return_if_fail (bug_uri_snippet != NULL);
    810   c = strstr (test_uri_base, "%s");
    811   if (c)
    812     {
    813       char *b = g_strndup (test_uri_base, c - test_uri_base);
    814       char *s = g_strconcat (b, bug_uri_snippet, c + 2, NULL);
    815       g_free (b);
    816       g_test_message ("Bug Reference: %s", s);
    817       g_free (s);
    818     }
    819   else
    820     g_test_message ("Bug Reference: %s%s", test_uri_base, bug_uri_snippet);
    821 }
    822 
    823 /**
    824  * g_test_get_root:
    825  *
    826  * Get the toplevel test suite for the test path API.
    827  *
    828  * Returns: the toplevel #GTestSuite
    829  *
    830  * Since: 2.16
    831  */
    832 GTestSuite*
    833 g_test_get_root (void)
    834 {
    835   if (!test_suite_root)
    836     {
    837       test_suite_root = g_test_create_suite ("root");
    838       g_free (test_suite_root->name);
    839       test_suite_root->name = g_strdup ("");
    840     }
    841   return test_suite_root;
    842 }
    843 
    844 /**
    845  * g_test_run:
    846  *
    847  * Runs all tests under the toplevel suite which can be retrieved
    848  * with g_test_get_root(). Similar to g_test_run_suite(), the test
    849  * cases to be run are filtered according to
    850  * test path arguments (-p <replaceable>testpath</replaceable>) as
    851  * parsed by g_test_init().
    852  * g_test_run_suite() or g_test_run() may only be called once
    853  * in a program.
    854  *
    855  * Returns: 0 on success
    856  *
    857  * Since: 2.16
    858  */
    859 int
    860 g_test_run (void)
    861 {
    862   return g_test_run_suite (g_test_get_root());
    863 }
    864 
    865 /**
    866  * g_test_create_case:
    867  * @test_name:     the name for the test case
    868  * @data_size:     the size of the fixture data structure
    869  * @test_data:     test data argument for the test functions
    870  * @data_setup:    the function to set up the fixture data
    871  * @data_test:     the actual test function
    872  * @data_teardown: the function to teardown the fixture data
    873  *
    874  * Create a new #GTestCase, named @test_name, this API is fairly
    875  * low level, calling g_test_add() or g_test_add_func() is preferable.
    876  * When this test is executed, a fixture structure of size @data_size
    877  * will be allocated and filled with 0s. Then data_setup() is called
    878  * to initialize the fixture. After fixture setup, the actual test
    879  * function data_test() is called. Once the test run completed, the
    880  * fixture structure is torn down  by calling data_teardown() and
    881  * after that the memory is released.
    882  *
    883  * Splitting up a test run into fixture setup, test function and
    884  * fixture teardown is most usful if the same fixture is used for
    885  * multiple tests. In this cases, g_test_create_case() will be
    886  * called with the same fixture, but varying @test_name and
    887  * @data_test arguments.
    888  *
    889  * Returns: a newly allocated #GTestCase.
    890  *
    891  * Since: 2.16
    892  */
    893 GTestCase*
    894 g_test_create_case (const char     *test_name,
    895                     gsize           data_size,
    896                     gconstpointer   test_data,
    897                     void          (*data_setup) (void),
    898                     void          (*data_test) (void),
    899                     void          (*data_teardown) (void))
    900 {
    901   GTestCase *tc;
    902   g_return_val_if_fail (test_name != NULL, NULL);
    903   g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL);
    904   g_return_val_if_fail (test_name[0] != 0, NULL);
    905   g_return_val_if_fail (data_test != NULL, NULL);
    906   tc = g_slice_new0 (GTestCase);
    907   tc->name = g_strdup (test_name);
    908   tc->test_data = (gpointer) test_data;
    909   tc->fixture_size = data_size;
    910   tc->fixture_setup = (void*) data_setup;
    911   tc->fixture_test = (void*) data_test;
    912   tc->fixture_teardown = (void*) data_teardown;
    913   return tc;
    914 }
    915 
    916 void
    917 g_test_add_vtable (const char     *testpath,
    918                    gsize           data_size,
    919                    gconstpointer   test_data,
    920                    void          (*data_setup)    (void),
    921                    void          (*fixture_test_func) (void),
    922                    void          (*data_teardown) (void))
    923 {
    924   gchar **segments;
    925   guint ui;
    926   GTestSuite *suite;
    927 
    928   g_return_if_fail (testpath != NULL);
    929   g_return_if_fail (testpath[0] == '/');
    930   g_return_if_fail (fixture_test_func != NULL);
    931 
    932   suite = g_test_get_root();
    933   segments = g_strsplit (testpath, "/", -1);
    934   for (ui = 0; segments[ui] != NULL; ui++)
    935     {
    936       const char *seg = segments[ui];
    937       gboolean islast = segments[ui + 1] == NULL;
    938       if (islast && !seg[0])
    939         g_error ("invalid test case path: %s", testpath);
    940       else if (!seg[0])
    941         continue;       /* initial or duplicate slash */
    942       else if (!islast)
    943         {
    944           GTestSuite *csuite = g_test_create_suite (seg);
    945           g_test_suite_add_suite (suite, csuite);
    946           suite = csuite;
    947         }
    948       else /* islast */
    949         {
    950           GTestCase *tc = g_test_create_case (seg, data_size, test_data, data_setup, fixture_test_func, data_teardown);
    951           g_test_suite_add (suite, tc);
    952         }
    953     }
    954   g_strfreev (segments);
    955 }
    956 
    957 /**
    958  * g_test_add_func:
    959  * @testpath:   Slash-separated test case path name for the test.
    960  * @test_func:  The test function to invoke for this test.
    961  *
    962  * Create a new test case, similar to g_test_create_case(). However
    963  * the test is assumed to use no fixture, and test suites are automatically
    964  * created on the fly and added to the root fixture, based on the
    965  * slash-separated portions of @testpath.
    966  *
    967  * Since: 2.16
    968  */
    969 void
    970 g_test_add_func (const char     *testpath,
    971                  void          (*test_func) (void))
    972 {
    973   g_return_if_fail (testpath != NULL);
    974   g_return_if_fail (testpath[0] == '/');
    975   g_return_if_fail (test_func != NULL);
    976   g_test_add_vtable (testpath, 0, NULL, NULL, test_func, NULL);
    977 }
    978 
    979 /**
    980  * g_test_add_data_func:
    981  * @testpath:   Slash-separated test case path name for the test.
    982  * @test_data:  Test data argument for the test function.
    983  * @test_func:  The test function to invoke for this test.
    984  *
    985  * Create a new test case, similar to g_test_create_case(). However
    986  * the test is assumed to use no fixture, and test suites are automatically
    987  * created on the fly and added to the root fixture, based on the
    988  * slash-separated portions of @testpath. The @test_data argument
    989  * will be passed as first argument to @test_func.
    990  *
    991  * Since: 2.16
    992  */
    993 void
    994 g_test_add_data_func (const char     *testpath,
    995                       gconstpointer   test_data,
    996                       void          (*test_func) (gconstpointer))
    997 {
    998   g_return_if_fail (testpath != NULL);
    999   g_return_if_fail (testpath[0] == '/');
   1000   g_return_if_fail (test_func != NULL);
   1001   g_test_add_vtable (testpath, 0, test_data, NULL, (void(*)(void)) test_func, NULL);
   1002 }
   1003 
   1004 /**
   1005  * g_test_create_suite:
   1006  * @suite_name: a name for the suite
   1007  *
   1008  * Create a new test suite with the name @suite_name.
   1009  *
   1010  * Returns: A newly allocated #GTestSuite instance.
   1011  *
   1012  * Since: 2.16
   1013  */
   1014 GTestSuite*
   1015 g_test_create_suite (const char *suite_name)
   1016 {
   1017   GTestSuite *ts;
   1018   g_return_val_if_fail (suite_name != NULL, NULL);
   1019   g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL);
   1020   g_return_val_if_fail (suite_name[0] != 0, NULL);
   1021   ts = g_slice_new0 (GTestSuite);
   1022   ts->name = g_strdup (suite_name);
   1023   return ts;
   1024 }
   1025 
   1026 /**
   1027  * g_test_suite_add:
   1028  * @suite: a #GTestSuite
   1029  * @test_case: a #GTestCase
   1030  *
   1031  * Adds @test_case to @suite.
   1032  *
   1033  * Since: 2.16
   1034  */
   1035 void
   1036 g_test_suite_add (GTestSuite     *suite,
   1037                   GTestCase      *test_case)
   1038 {
   1039   g_return_if_fail (suite != NULL);
   1040   g_return_if_fail (test_case != NULL);
   1041   suite->cases = g_slist_prepend (suite->cases, test_case);
   1042 }
   1043 
   1044 /**
   1045  * g_test_suite_add_suite:
   1046  * @suite:       a #GTestSuite
   1047  * @nestedsuite: another #GTestSuite
   1048  *
   1049  * Adds @nestedsuite to @suite.
   1050  *
   1051  * Since: 2.16
   1052  */
   1053 void
   1054 g_test_suite_add_suite (GTestSuite     *suite,
   1055                         GTestSuite     *nestedsuite)
   1056 {
   1057   g_return_if_fail (suite != NULL);
   1058   g_return_if_fail (nestedsuite != NULL);
   1059   suite->suites = g_slist_prepend (suite->suites, nestedsuite);
   1060 }
   1061 
   1062 /**
   1063  * g_test_queue_free:
   1064  * @gfree_pointer: the pointer to be stored.
   1065  *
   1066  * Enqueue a pointer to be released with g_free() during the next
   1067  * teardown phase. This is equivalent to calling g_test_queue_destroy()
   1068  * with a destroy callback of g_free().
   1069  *
   1070  * Since: 2.16
   1071  */
   1072 void
   1073 g_test_queue_free (gpointer gfree_pointer)
   1074 {
   1075   if (gfree_pointer)
   1076     g_test_queue_destroy (g_free, gfree_pointer);
   1077 }
   1078 
   1079 /**
   1080  * g_test_queue_destroy:
   1081  * @destroy_func:       Destroy callback for teardown phase.
   1082  * @destroy_data:       Destroy callback data.
   1083  *
   1084  * This function enqueus a callback @destroy_func() to be executed
   1085  * during the next test case teardown phase. This is most useful
   1086  * to auto destruct allocted test resources at the end of a test run.
   1087  * Resources are released in reverse queue order, that means enqueueing
   1088  * callback A before callback B will cause B() to be called before
   1089  * A() during teardown.
   1090  *
   1091  * Since: 2.16
   1092  */
   1093 void
   1094 g_test_queue_destroy (GDestroyNotify destroy_func,
   1095                       gpointer       destroy_data)
   1096 {
   1097   DestroyEntry *dentry;
   1098   g_return_if_fail (destroy_func != NULL);
   1099   dentry = g_slice_new0 (DestroyEntry);
   1100   dentry->destroy_func = destroy_func;
   1101   dentry->destroy_data = destroy_data;
   1102   dentry->next = test_destroy_queue;
   1103   test_destroy_queue = dentry;
   1104 }
   1105 
   1106 static int
   1107 test_case_run (GTestCase *tc)
   1108 {
   1109   gchar *old_name = test_run_name, *old_base = g_strdup (test_uri_base);
   1110   test_run_name = g_strconcat (old_name, "/", tc->name, NULL);
   1111   if (++test_run_count <= test_skip_count)
   1112     g_test_log (G_TEST_LOG_SKIP_CASE, test_run_name, NULL, 0, NULL);
   1113   else if (test_run_list)
   1114     {
   1115       g_print ("%s\n", test_run_name);
   1116       g_test_log (G_TEST_LOG_LIST_CASE, test_run_name, NULL, 0, NULL);
   1117     }
   1118   else
   1119     {
   1120       GTimer *test_run_timer = g_timer_new();
   1121       long double largs[3];
   1122       void *fixture;
   1123       g_test_log (G_TEST_LOG_START_CASE, test_run_name, NULL, 0, NULL);
   1124       test_run_forks = 0;
   1125       g_timer_start (test_run_timer);
   1126       fixture = tc->fixture_size ? g_malloc0 (tc->fixture_size) : tc->test_data;
   1127       test_run_seed (test_run_seedstr);
   1128       if (tc->fixture_setup)
   1129         tc->fixture_setup (fixture, tc->test_data);
   1130       tc->fixture_test (fixture, tc->test_data);
   1131       test_trap_clear();
   1132       while (test_destroy_queue)
   1133         {
   1134           DestroyEntry *dentry = test_destroy_queue;
   1135           test_destroy_queue = dentry->next;
   1136           dentry->destroy_func (dentry->destroy_data);
   1137           g_slice_free (DestroyEntry, dentry);
   1138         }
   1139       if (tc->fixture_teardown)
   1140         tc->fixture_teardown (fixture, tc->test_data);
   1141       if (tc->fixture_size)
   1142         g_free (fixture);
   1143       g_timer_stop (test_run_timer);
   1144       largs[0] = 0; /* OK */
   1145       largs[1] = test_run_forks;
   1146       largs[2] = g_timer_elapsed (test_run_timer, NULL);
   1147       g_test_log (G_TEST_LOG_STOP_CASE, NULL, NULL, G_N_ELEMENTS (largs), largs);
   1148       g_timer_destroy (test_run_timer);
   1149     }
   1150   g_free (test_run_name);
   1151   test_run_name = old_name;
   1152   g_free (test_uri_base);
   1153   test_uri_base = old_base;
   1154   return 0;
   1155 }
   1156 
   1157 static int
   1158 g_test_run_suite_internal (GTestSuite *suite,
   1159                            const char *path)
   1160 {
   1161   guint n_bad = 0, n_good = 0, bad_suite = 0, l;
   1162   gchar *rest, *old_name = test_run_name;
   1163   GSList *slist, *reversed;
   1164   g_return_val_if_fail (suite != NULL, -1);
   1165   while (path[0] == '/')
   1166     path++;
   1167   l = strlen (path);
   1168   rest = strchr (path, '/');
   1169   l = rest ? MIN (l, rest - path) : l;
   1170   test_run_name = suite->name[0] == 0 ? g_strdup (test_run_name) : g_strconcat (old_name, "/", suite->name, NULL);
   1171   reversed = g_slist_reverse (g_slist_copy (suite->cases));
   1172   for (slist = reversed; slist; slist = slist->next)
   1173     {
   1174       GTestCase *tc = slist->data;
   1175       guint n = l ? strlen (tc->name) : 0;
   1176       if (l == n && strncmp (path, tc->name, n) == 0)
   1177         {
   1178           n_good++;
   1179           n_bad += test_case_run (tc) != 0;
   1180         }
   1181     }
   1182   g_slist_free (reversed);
   1183   reversed = g_slist_reverse (g_slist_copy (suite->suites));
   1184   for (slist = reversed; slist; slist = slist->next)
   1185     {
   1186       GTestSuite *ts = slist->data;
   1187       guint n = l ? strlen (ts->name) : 0;
   1188       if (l == n && strncmp (path, ts->name, n) == 0)
   1189         bad_suite += g_test_run_suite_internal (ts, rest ? rest : "") != 0;
   1190     }
   1191   g_slist_free (reversed);
   1192   g_free (test_run_name);
   1193   test_run_name = old_name;
   1194   return n_bad || bad_suite;
   1195 }
   1196 
   1197 /**
   1198  * g_test_run_suite:
   1199  * @suite: a #GTestSuite
   1200  *
   1201  * Execute the tests within @suite and all nested #GTestSuites.
   1202  * The test suites to be executed are filtered according to
   1203  * test path arguments (-p <replaceable>testpath</replaceable>)
   1204  * as parsed by g_test_init().
   1205  * g_test_run_suite() or g_test_run() may only be called once
   1206  * in a program.
   1207  *
   1208  * Returns: 0 on success
   1209  *
   1210  * Since: 2.16
   1211  */
   1212 int
   1213 g_test_run_suite (GTestSuite *suite)
   1214 {
   1215   guint n_bad = 0;
   1216   g_return_val_if_fail (g_test_config_vars->test_initialized, -1);
   1217   g_return_val_if_fail (g_test_run_once == TRUE, -1);
   1218   g_test_run_once = FALSE;
   1219   if (!test_paths)
   1220     test_paths = g_slist_prepend (test_paths, "");
   1221   while (test_paths)
   1222     {
   1223       const char *rest, *path = test_paths->data;
   1224       guint l, n = strlen (suite->name);
   1225       test_paths = g_slist_delete_link (test_paths, test_paths);
   1226       while (path[0] == '/')
   1227         path++;
   1228       if (!n) /* root suite, run unconditionally */
   1229         {
   1230           n_bad += 0 != g_test_run_suite_internal (suite, path);
   1231           continue;
   1232         }
   1233       /* regular suite, match path */
   1234       rest = strchr (path, '/');
   1235       l = strlen (path);
   1236       l = rest ? MIN (l, rest - path) : l;
   1237       if ((!l || l == n) && strncmp (path, suite->name, n) == 0)
   1238         n_bad += 0 != g_test_run_suite_internal (suite, rest ? rest : "");
   1239     }
   1240   return n_bad;
   1241 }
   1242 
   1243 static void
   1244 gtest_default_log_handler (const gchar    *log_domain,
   1245                            GLogLevelFlags  log_level,
   1246                            const gchar    *message,
   1247                            gpointer        unused_data)
   1248 {
   1249   const gchar *strv[16];
   1250   gchar *msg;
   1251   guint i = 0;
   1252   if (log_domain)
   1253     {
   1254       strv[i++] = log_domain;
   1255       strv[i++] = "-";
   1256     }
   1257   if (log_level & G_LOG_FLAG_FATAL)
   1258     strv[i++] = "FATAL-";
   1259   if (log_level & G_LOG_FLAG_RECURSION)
   1260     strv[i++] = "RECURSIVE-";
   1261   if (log_level & G_LOG_LEVEL_ERROR)
   1262     strv[i++] = "ERROR";
   1263   if (log_level & G_LOG_LEVEL_CRITICAL)
   1264     strv[i++] = "CRITICAL";
   1265   if (log_level & G_LOG_LEVEL_WARNING)
   1266     strv[i++] = "WARNING";
   1267   if (log_level & G_LOG_LEVEL_MESSAGE)
   1268     strv[i++] = "MESSAGE";
   1269   if (log_level & G_LOG_LEVEL_INFO)
   1270     strv[i++] = "INFO";
   1271   if (log_level & G_LOG_LEVEL_DEBUG)
   1272     strv[i++] = "DEBUG";
   1273   strv[i++] = ": ";
   1274   strv[i++] = message;
   1275   strv[i++] = NULL;
   1276   msg = g_strjoinv ("", (gchar**) strv);
   1277   g_test_log (G_TEST_LOG_ERROR, msg, NULL, 0, NULL);
   1278   g_log_default_handler (log_domain, log_level, message, unused_data);
   1279   g_free (msg);
   1280 }
   1281 
   1282 void
   1283 g_assertion_message (const char     *domain,
   1284                      const char     *file,
   1285                      int             line,
   1286                      const char     *func,
   1287                      const char     *message)
   1288 {
   1289   char lstr[32];
   1290   char *s;
   1291   if (!message)
   1292     message = "code should not be reached";
   1293   g_snprintf (lstr, 32, "%d", line);
   1294   s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "",
   1295                    "ERROR:", file, ":", lstr, ":",
   1296                    func, func[0] ? ":" : "",
   1297                    " ", message, NULL);
   1298   g_printerr ("**\n%s\n", s);
   1299   g_test_log (G_TEST_LOG_ERROR, s, NULL, 0, NULL);
   1300   g_free (s);
   1301   abort();
   1302 }
   1303 
   1304 void
   1305 g_assertion_message_expr (const char     *domain,
   1306                           const char     *file,
   1307                           int             line,
   1308                           const char     *func,
   1309                           const char     *expr)
   1310 {
   1311   char *s = g_strconcat ("assertion failed: (", expr, ")", NULL);
   1312   g_assertion_message (domain, file, line, func, s);
   1313   g_free (s);
   1314 }
   1315 
   1316 void
   1317 g_assertion_message_cmpnum (const char     *domain,
   1318                             const char     *file,
   1319                             int             line,
   1320                             const char     *func,
   1321                             const char     *expr,
   1322                             long double     arg1,
   1323                             const char     *cmp,
   1324                             long double     arg2,
   1325                             char            numtype)
   1326 {
   1327   char *s = NULL;
   1328   switch (numtype)
   1329     {
   1330     case 'i':   s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break;
   1331     case 'x':   s = g_strdup_printf ("assertion failed (%s): (0x%08" G_GINT64_MODIFIER "x %s 0x%08" G_GINT64_MODIFIER "x)", expr, (guint64) arg1, cmp, (guint64) arg2); break;
   1332     case 'f':   s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break;
   1333       /* ideally use: floats=%.7g double=%.17g */
   1334     }
   1335   g_assertion_message (domain, file, line, func, s);
   1336   g_free (s);
   1337 }
   1338 
   1339 void
   1340 g_assertion_message_cmpstr (const char     *domain,
   1341                             const char     *file,
   1342                             int             line,
   1343                             const char     *func,
   1344                             const char     *expr,
   1345                             const char     *arg1,
   1346                             const char     *cmp,
   1347                             const char     *arg2)
   1348 {
   1349   char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
   1350   a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL");
   1351   a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL");
   1352   g_free (t1);
   1353   g_free (t2);
   1354   s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
   1355   g_free (a1);
   1356   g_free (a2);
   1357   g_assertion_message (domain, file, line, func, s);
   1358   g_free (s);
   1359 }
   1360 
   1361 void
   1362 g_assertion_message_error (const char     *domain,
   1363 			   const char     *file,
   1364 			   int             line,
   1365 			   const char     *func,
   1366 			   const char     *expr,
   1367 			   GError         *error,
   1368 			   GQuark          error_domain,
   1369 			   int             error_code)
   1370 {
   1371   GString *gstring;
   1372 
   1373   /* This is used by both g_assert_error() and g_assert_no_error(), so there
   1374    * are three cases: expected an error but got the wrong error, expected
   1375    * an error but got no error, and expected no error but got an error.
   1376    */
   1377 
   1378   gstring = g_string_new ("assertion failed ");
   1379   if (error_domain)
   1380       g_string_append_printf (gstring, "(%s == (%s, %d)): ", expr,
   1381 			      g_quark_to_string (error_domain), error_code);
   1382   else
   1383     g_string_append_printf (gstring, "(%s == NULL): ", expr);
   1384 
   1385   if (error)
   1386       g_string_append_printf (gstring, "%s (%s, %d)", error->message,
   1387 			      g_quark_to_string (error->domain), error->code);
   1388   else
   1389     g_string_append_printf (gstring, "%s is NULL", expr);
   1390 
   1391   g_assertion_message (domain, file, line, func, gstring->str);
   1392   g_string_free (gstring, TRUE);
   1393 }
   1394 
   1395 /**
   1396  * g_strcmp0:
   1397  * @str1: a C string or %NULL
   1398  * @str2: another C string or %NULL
   1399  *
   1400  * Compares @str1 and @str2 like strcmp(). Handles %NULL
   1401  * gracefully by sorting it before non-%NULL strings.
   1402  *
   1403  * Returns: -1, 0 or 1, if @str1 is <, == or > than @str2.
   1404  *
   1405  * Since: 2.16
   1406  */
   1407 int
   1408 g_strcmp0 (const char     *str1,
   1409            const char     *str2)
   1410 {
   1411   if (!str1)
   1412     return -(str1 != str2);
   1413   if (!str2)
   1414     return str1 != str2;
   1415   return strcmp (str1, str2);
   1416 }
   1417 
   1418 #ifdef G_OS_UNIX
   1419 static int /* 0 on success */
   1420 kill_child (int  pid,
   1421             int *status,
   1422             int  patience)
   1423 {
   1424   int wr;
   1425   if (patience >= 3)    /* try graceful reap */
   1426     {
   1427       if (waitpid (pid, status, WNOHANG) > 0)
   1428         return 0;
   1429     }
   1430   if (patience >= 2)    /* try SIGHUP */
   1431     {
   1432       kill (pid, SIGHUP);
   1433       if (waitpid (pid, status, WNOHANG) > 0)
   1434         return 0;
   1435       g_usleep (20 * 1000); /* give it some scheduling/shutdown time */
   1436       if (waitpid (pid, status, WNOHANG) > 0)
   1437         return 0;
   1438       g_usleep (50 * 1000); /* give it some scheduling/shutdown time */
   1439       if (waitpid (pid, status, WNOHANG) > 0)
   1440         return 0;
   1441       g_usleep (100 * 1000); /* give it some scheduling/shutdown time */
   1442       if (waitpid (pid, status, WNOHANG) > 0)
   1443         return 0;
   1444     }
   1445   if (patience >= 1)    /* try SIGTERM */
   1446     {
   1447       kill (pid, SIGTERM);
   1448       if (waitpid (pid, status, WNOHANG) > 0)
   1449         return 0;
   1450       g_usleep (200 * 1000); /* give it some scheduling/shutdown time */
   1451       if (waitpid (pid, status, WNOHANG) > 0)
   1452         return 0;
   1453       g_usleep (400 * 1000); /* give it some scheduling/shutdown time */
   1454       if (waitpid (pid, status, WNOHANG) > 0)
   1455         return 0;
   1456     }
   1457   /* finish it off */
   1458   kill (pid, SIGKILL);
   1459   do
   1460     wr = waitpid (pid, status, 0);
   1461   while (wr < 0 && errno == EINTR);
   1462   return wr;
   1463 }
   1464 #endif
   1465 
   1466 static inline int
   1467 g_string_must_read (GString *gstring,
   1468                     int      fd)
   1469 {
   1470 #define STRING_BUFFER_SIZE     4096
   1471   char buf[STRING_BUFFER_SIZE];
   1472   gssize bytes;
   1473  again:
   1474   bytes = read (fd, buf, sizeof (buf));
   1475   if (bytes == 0)
   1476     return 0; /* EOF, calling this function assumes data is available */
   1477   else if (bytes > 0)
   1478     {
   1479       g_string_append_len (gstring, buf, bytes);
   1480       return 1;
   1481     }
   1482   else if (bytes < 0 && errno == EINTR)
   1483     goto again;
   1484   else /* bytes < 0 */
   1485     {
   1486       g_warning ("failed to read() from child process (%d): %s", test_trap_last_pid, g_strerror (errno));
   1487       return 1; /* ignore error after warning */
   1488     }
   1489 }
   1490 
   1491 static inline void
   1492 g_string_write_out (GString *gstring,
   1493                     int      outfd,
   1494                     int     *stringpos)
   1495 {
   1496   if (*stringpos < gstring->len)
   1497     {
   1498       int r;
   1499       do
   1500         r = write (outfd, gstring->str + *stringpos, gstring->len - *stringpos);
   1501       while (r < 0 && errno == EINTR);
   1502       *stringpos += MAX (r, 0);
   1503     }
   1504 }
   1505 
   1506 static void
   1507 test_trap_clear (void)
   1508 {
   1509   test_trap_last_status = 0;
   1510   test_trap_last_pid = 0;
   1511   g_free (test_trap_last_stdout);
   1512   test_trap_last_stdout = NULL;
   1513   g_free (test_trap_last_stderr);
   1514   test_trap_last_stderr = NULL;
   1515 }
   1516 
   1517 #ifdef G_OS_UNIX
   1518 
   1519 static int
   1520 sane_dup2 (int fd1,
   1521            int fd2)
   1522 {
   1523   int ret;
   1524   do
   1525     ret = dup2 (fd1, fd2);
   1526   while (ret < 0 && errno == EINTR);
   1527   return ret;
   1528 }
   1529 
   1530 static guint64
   1531 test_time_stamp (void)
   1532 {
   1533   GTimeVal tv;
   1534   guint64 stamp;
   1535   g_get_current_time (&tv);
   1536   stamp = tv.tv_sec;
   1537   stamp = stamp * 1000000 + tv.tv_usec;
   1538   return stamp;
   1539 }
   1540 
   1541 #endif
   1542 
   1543 /**
   1544  * g_test_trap_fork:
   1545  * @usec_timeout:    Timeout for the forked test in micro seconds.
   1546  * @test_trap_flags: Flags to modify forking behaviour.
   1547  *
   1548  * Fork the current test program to execute a test case that might
   1549  * not return or that might abort. The forked test case is aborted
   1550  * and considered failing if its run time exceeds @usec_timeout.
   1551  *
   1552  * The forking behavior can be configured with the #GTestTrapFlags flags.
   1553  *
   1554  * In the following example, the test code forks, the forked child
   1555  * process produces some sample output and exits successfully.
   1556  * The forking parent process then asserts successful child program
   1557  * termination and validates child program outputs.
   1558  *
   1559  * |[
   1560  *   static void
   1561  *   test_fork_patterns (void)
   1562  *   {
   1563  *     if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
   1564  *       {
   1565  *         g_print ("some stdout text: somagic17\n");
   1566  *         g_printerr ("some stderr text: semagic43\n");
   1567  *         exit (0); /&ast; successful test run &ast;/
   1568  *       }
   1569  *     g_test_trap_assert_passed();
   1570  *     g_test_trap_assert_stdout ("*somagic17*");
   1571  *     g_test_trap_assert_stderr ("*semagic43*");
   1572  *   }
   1573  * ]|
   1574  *
   1575  * This function is implemented only on Unix platforms.
   1576  *
   1577  * Returns: %TRUE for the forked child and %FALSE for the executing parent process.
   1578  *
   1579  * Since: 2.16
   1580  */
   1581 gboolean
   1582 g_test_trap_fork (guint64        usec_timeout,
   1583                   GTestTrapFlags test_trap_flags)
   1584 {
   1585 #ifdef G_OS_UNIX
   1586   gboolean pass_on_forked_log = FALSE;
   1587   int stdout_pipe[2] = { -1, -1 };
   1588   int stderr_pipe[2] = { -1, -1 };
   1589   int stdtst_pipe[2] = { -1, -1 };
   1590   test_trap_clear();
   1591   if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0 || pipe (stdtst_pipe) < 0)
   1592     g_error ("failed to create pipes to fork test program: %s", g_strerror (errno));
   1593   signal (SIGCHLD, SIG_DFL);
   1594   test_trap_last_pid = fork ();
   1595   if (test_trap_last_pid < 0)
   1596     g_error ("failed to fork test program: %s", g_strerror (errno));
   1597   if (test_trap_last_pid == 0)  /* child */
   1598     {
   1599       int fd0 = -1;
   1600       close (stdout_pipe[0]);
   1601       close (stderr_pipe[0]);
   1602       close (stdtst_pipe[0]);
   1603       if (!(test_trap_flags & G_TEST_TRAP_INHERIT_STDIN))
   1604         fd0 = open ("/dev/null", O_RDONLY);
   1605       if (sane_dup2 (stdout_pipe[1], 1) < 0 || sane_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && sane_dup2 (fd0, 0) < 0))
   1606         g_error ("failed to dup2() in forked test program: %s", g_strerror (errno));
   1607       if (fd0 >= 3)
   1608         close (fd0);
   1609       if (stdout_pipe[1] >= 3)
   1610         close (stdout_pipe[1]);
   1611       if (stderr_pipe[1] >= 3)
   1612         close (stderr_pipe[1]);
   1613       test_log_fd = stdtst_pipe[1];
   1614       return TRUE;
   1615     }
   1616   else                          /* parent */
   1617     {
   1618       GString *sout = g_string_new (NULL);
   1619       GString *serr = g_string_new (NULL);
   1620       guint64 sstamp;
   1621       int soutpos = 0, serrpos = 0, wr, need_wait = TRUE;
   1622       test_run_forks++;
   1623       close (stdout_pipe[1]);
   1624       close (stderr_pipe[1]);
   1625       close (stdtst_pipe[1]);
   1626       sstamp = test_time_stamp();
   1627       /* read data until we get EOF on all pipes */
   1628       while (stdout_pipe[0] >= 0 || stderr_pipe[0] >= 0 || stdtst_pipe[0] > 0)
   1629         {
   1630           fd_set fds;
   1631           struct timeval tv;
   1632           int ret;
   1633           FD_ZERO (&fds);
   1634           if (stdout_pipe[0] >= 0)
   1635             FD_SET (stdout_pipe[0], &fds);
   1636           if (stderr_pipe[0] >= 0)
   1637             FD_SET (stderr_pipe[0], &fds);
   1638           if (stdtst_pipe[0] >= 0)
   1639             FD_SET (stdtst_pipe[0], &fds);
   1640           tv.tv_sec = 0;
   1641           tv.tv_usec = MIN (usec_timeout ? usec_timeout : 1000000, 100 * 1000); /* sleep at most 0.5 seconds to catch clock skews, etc. */
   1642           ret = select (MAX (MAX (stdout_pipe[0], stderr_pipe[0]), stdtst_pipe[0]) + 1, &fds, NULL, NULL, &tv);
   1643           if (ret < 0 && errno != EINTR)
   1644             {
   1645               g_warning ("Unexpected error in select() while reading from child process (%d): %s", test_trap_last_pid, g_strerror (errno));
   1646               break;
   1647             }
   1648           if (stdout_pipe[0] >= 0 && FD_ISSET (stdout_pipe[0], &fds) &&
   1649               g_string_must_read (sout, stdout_pipe[0]) == 0)
   1650             {
   1651               close (stdout_pipe[0]);
   1652               stdout_pipe[0] = -1;
   1653             }
   1654           if (stderr_pipe[0] >= 0 && FD_ISSET (stderr_pipe[0], &fds) &&
   1655               g_string_must_read (serr, stderr_pipe[0]) == 0)
   1656             {
   1657               close (stderr_pipe[0]);
   1658               stderr_pipe[0] = -1;
   1659             }
   1660           if (stdtst_pipe[0] >= 0 && FD_ISSET (stdtst_pipe[0], &fds))
   1661             {
   1662               guint8 buffer[4096];
   1663               gint l, r = read (stdtst_pipe[0], buffer, sizeof (buffer));
   1664               if (r > 0 && test_log_fd > 0)
   1665                 do
   1666                   l = write (pass_on_forked_log ? test_log_fd : -1, buffer, r);
   1667                 while (l < 0 && errno == EINTR);
   1668               if (r == 0 || (r < 0 && errno != EINTR && errno != EAGAIN))
   1669                 {
   1670                   close (stdtst_pipe[0]);
   1671                   stdtst_pipe[0] = -1;
   1672                 }
   1673             }
   1674           if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDOUT))
   1675             g_string_write_out (sout, 1, &soutpos);
   1676           if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDERR))
   1677             g_string_write_out (serr, 2, &serrpos);
   1678           if (usec_timeout)
   1679             {
   1680               guint64 nstamp = test_time_stamp();
   1681               int status = 0;
   1682               sstamp = MIN (sstamp, nstamp); /* guard against backwards clock skews */
   1683               if (usec_timeout < nstamp - sstamp)
   1684                 {
   1685                   /* timeout reached, need to abort the child now */
   1686                   kill_child (test_trap_last_pid, &status, 3);
   1687                   test_trap_last_status = 1024; /* timeout */
   1688                   if (0 && WIFSIGNALED (status))
   1689                     g_printerr ("%s: child timed out and received: %s\n", G_STRFUNC, g_strsignal (WTERMSIG (status)));
   1690                   need_wait = FALSE;
   1691                   break;
   1692                 }
   1693             }
   1694         }
   1695       close (stdout_pipe[0]);
   1696       close (stderr_pipe[0]);
   1697       close (stdtst_pipe[0]);
   1698       if (need_wait)
   1699         {
   1700           int status = 0;
   1701           do
   1702             wr = waitpid (test_trap_last_pid, &status, 0);
   1703           while (wr < 0 && errno == EINTR);
   1704           if (WIFEXITED (status)) /* normal exit */
   1705             test_trap_last_status = WEXITSTATUS (status); /* 0..255 */
   1706           else if (WIFSIGNALED (status))
   1707             test_trap_last_status = (WTERMSIG (status) << 12); /* signalled */
   1708           else /* WCOREDUMP (status) */
   1709             test_trap_last_status = 512; /* coredump */
   1710         }
   1711       test_trap_last_stdout = g_string_free (sout, FALSE);
   1712       test_trap_last_stderr = g_string_free (serr, FALSE);
   1713       return FALSE;
   1714     }
   1715 #else
   1716   g_message ("Not implemented: g_test_trap_fork");
   1717 
   1718   return FALSE;
   1719 #endif
   1720 }
   1721 
   1722 /**
   1723  * g_test_trap_has_passed:
   1724  *
   1725  * Check the result of the last g_test_trap_fork() call.
   1726  *
   1727  * Returns: %TRUE if the last forked child terminated successfully.
   1728  *
   1729  * Since: 2.16
   1730  */
   1731 gboolean
   1732 g_test_trap_has_passed (void)
   1733 {
   1734   return test_trap_last_status == 0; /* exit_status == 0 && !signal && !coredump */
   1735 }
   1736 
   1737 /**
   1738  * g_test_trap_reached_timeout:
   1739  *
   1740  * Check the result of the last g_test_trap_fork() call.
   1741  *
   1742  * Returns: %TRUE if the last forked child got killed due to a fork timeout.
   1743  *
   1744  * Since: 2.16
   1745  */
   1746 gboolean
   1747 g_test_trap_reached_timeout (void)
   1748 {
   1749   return 0 != (test_trap_last_status & 1024); /* timeout flag */
   1750 }
   1751 
   1752 void
   1753 g_test_trap_assertions (const char     *domain,
   1754                         const char     *file,
   1755                         int             line,
   1756                         const char     *func,
   1757                         guint64         assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */
   1758                         const char     *pattern)
   1759 {
   1760 #ifdef G_OS_UNIX
   1761   gboolean must_pass = assertion_flags == 0;
   1762   gboolean must_fail = assertion_flags == 1;
   1763   gboolean match_result = 0 == (assertion_flags & 1);
   1764   const char *stdout_pattern = (assertion_flags & 2) ? pattern : NULL;
   1765   const char *stderr_pattern = (assertion_flags & 4) ? pattern : NULL;
   1766   const char *match_error = match_result ? "failed to match" : "contains invalid match";
   1767   if (test_trap_last_pid == 0)
   1768     g_error ("child process failed to exit after g_test_trap_fork() and before g_test_trap_assert*()");
   1769   if (must_pass && !g_test_trap_has_passed())
   1770     {
   1771       char *msg = g_strdup_printf ("child process (%d) of test trap failed unexpectedly", test_trap_last_pid);
   1772       g_assertion_message (domain, file, line, func, msg);
   1773       g_free (msg);
   1774     }
   1775   if (must_fail && g_test_trap_has_passed())
   1776     {
   1777       char *msg = g_strdup_printf ("child process (%d) did not fail as expected", test_trap_last_pid);
   1778       g_assertion_message (domain, file, line, func, msg);
   1779       g_free (msg);
   1780     }
   1781   if (stdout_pattern && match_result == !g_pattern_match_simple (stdout_pattern, test_trap_last_stdout))
   1782     {
   1783       char *msg = g_strdup_printf ("stdout of child process (%d) %s: %s", test_trap_last_pid, match_error, stdout_pattern);
   1784       g_assertion_message (domain, file, line, func, msg);
   1785       g_free (msg);
   1786     }
   1787   if (stderr_pattern && match_result == !g_pattern_match_simple (stderr_pattern, test_trap_last_stderr))
   1788     {
   1789       char *msg = g_strdup_printf ("stderr of child process (%d) %s: %s", test_trap_last_pid, match_error, stderr_pattern);
   1790       g_assertion_message (domain, file, line, func, msg);
   1791       g_free (msg);
   1792     }
   1793 #endif
   1794 }
   1795 
   1796 static void
   1797 gstring_overwrite_int (GString *gstring,
   1798                        guint    pos,
   1799                        guint32  vuint)
   1800 {
   1801   vuint = g_htonl (vuint);
   1802   g_string_overwrite_len (gstring, pos, (const gchar*) &vuint, 4);
   1803 }
   1804 
   1805 static void
   1806 gstring_append_int (GString *gstring,
   1807                     guint32  vuint)
   1808 {
   1809   vuint = g_htonl (vuint);
   1810   g_string_append_len (gstring, (const gchar*) &vuint, 4);
   1811 }
   1812 
   1813 static void
   1814 gstring_append_double (GString *gstring,
   1815                        double   vdouble)
   1816 {
   1817   union { double vdouble; guint64 vuint64; } u;
   1818   u.vdouble = vdouble;
   1819   u.vuint64 = GUINT64_TO_BE (u.vuint64);
   1820   g_string_append_len (gstring, (const gchar*) &u.vuint64, 8);
   1821 }
   1822 
   1823 static guint8*
   1824 g_test_log_dump (GTestLogMsg *msg,
   1825                  guint       *len)
   1826 {
   1827   GString *gstring = g_string_sized_new (1024);
   1828   guint ui;
   1829   gstring_append_int (gstring, 0);              /* message length */
   1830   gstring_append_int (gstring, msg->log_type);
   1831   gstring_append_int (gstring, msg->n_strings);
   1832   gstring_append_int (gstring, msg->n_nums);
   1833   gstring_append_int (gstring, 0);      /* reserved */
   1834   for (ui = 0; ui < msg->n_strings; ui++)
   1835     {
   1836       guint l = strlen (msg->strings[ui]);
   1837       gstring_append_int (gstring, l);
   1838       g_string_append_len (gstring, msg->strings[ui], l);
   1839     }
   1840   for (ui = 0; ui < msg->n_nums; ui++)
   1841     gstring_append_double (gstring, msg->nums[ui]);
   1842   *len = gstring->len;
   1843   gstring_overwrite_int (gstring, 0, *len);     /* message length */
   1844   return (guint8*) g_string_free (gstring, FALSE);
   1845 }
   1846 
   1847 static inline long double
   1848 net_double (const gchar **ipointer)
   1849 {
   1850   union { guint64 vuint64; double vdouble; } u;
   1851   guint64 aligned_int64;
   1852   memcpy (&aligned_int64, *ipointer, 8);
   1853   *ipointer += 8;
   1854   u.vuint64 = GUINT64_FROM_BE (aligned_int64);
   1855   return u.vdouble;
   1856 }
   1857 
   1858 static inline guint32
   1859 net_int (const gchar **ipointer)
   1860 {
   1861   guint32 aligned_int;
   1862   memcpy (&aligned_int, *ipointer, 4);
   1863   *ipointer += 4;
   1864   return g_ntohl (aligned_int);
   1865 }
   1866 
   1867 static gboolean
   1868 g_test_log_extract (GTestLogBuffer *tbuffer)
   1869 {
   1870   const gchar *p = tbuffer->data->str;
   1871   GTestLogMsg msg;
   1872   guint mlength;
   1873   if (tbuffer->data->len < 4 * 5)
   1874     return FALSE;
   1875   mlength = net_int (&p);
   1876   if (tbuffer->data->len < mlength)
   1877     return FALSE;
   1878   msg.log_type = net_int (&p);
   1879   msg.n_strings = net_int (&p);
   1880   msg.n_nums = net_int (&p);
   1881   if (net_int (&p) == 0)
   1882     {
   1883       guint ui;
   1884       msg.strings = g_new0 (gchar*, msg.n_strings + 1);
   1885       msg.nums = g_new0 (long double, msg.n_nums);
   1886       for (ui = 0; ui < msg.n_strings; ui++)
   1887         {
   1888           guint sl = net_int (&p);
   1889           msg.strings[ui] = g_strndup (p, sl);
   1890           p += sl;
   1891         }
   1892       for (ui = 0; ui < msg.n_nums; ui++)
   1893         msg.nums[ui] = net_double (&p);
   1894       if (p <= tbuffer->data->str + mlength)
   1895         {
   1896           g_string_erase (tbuffer->data, 0, mlength);
   1897           tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
   1898           return TRUE;
   1899         }
   1900     }
   1901   g_free (msg.nums);
   1902   g_strfreev (msg.strings);
   1903   g_error ("corrupt log stream from test program");
   1904   return FALSE;
   1905 }
   1906 
   1907 /**
   1908  * g_test_log_buffer_new:
   1909  *
   1910  * Internal function for gtester to decode test log messages, no ABI guarantees provided.
   1911  */
   1912 GTestLogBuffer*
   1913 g_test_log_buffer_new (void)
   1914 {
   1915   GTestLogBuffer *tb = g_new0 (GTestLogBuffer, 1);
   1916   tb->data = g_string_sized_new (1024);
   1917   return tb;
   1918 }
   1919 
   1920 /**
   1921  * g_test_log_buffer_free
   1922  *
   1923  * Internal function for gtester to free test log messages, no ABI guarantees provided.
   1924  */
   1925 void
   1926 g_test_log_buffer_free (GTestLogBuffer *tbuffer)
   1927 {
   1928   g_return_if_fail (tbuffer != NULL);
   1929   while (tbuffer->msgs)
   1930     g_test_log_msg_free (g_test_log_buffer_pop (tbuffer));
   1931   g_string_free (tbuffer->data, TRUE);
   1932   g_free (tbuffer);
   1933 }
   1934 
   1935 /**
   1936  * g_test_log_buffer_push
   1937  *
   1938  * Internal function for gtester to decode test log messages, no ABI guarantees provided.
   1939  */
   1940 void
   1941 g_test_log_buffer_push (GTestLogBuffer *tbuffer,
   1942                         guint           n_bytes,
   1943                         const guint8   *bytes)
   1944 {
   1945   g_return_if_fail (tbuffer != NULL);
   1946   if (n_bytes)
   1947     {
   1948       gboolean more_messages;
   1949       g_return_if_fail (bytes != NULL);
   1950       g_string_append_len (tbuffer->data, (const gchar*) bytes, n_bytes);
   1951       do
   1952         more_messages = g_test_log_extract (tbuffer);
   1953       while (more_messages);
   1954     }
   1955 }
   1956 
   1957 /**
   1958  * g_test_log_buffer_pop:
   1959  *
   1960  * Internal function for gtester to retrieve test log messages, no ABI guarantees provided.
   1961  */
   1962 GTestLogMsg*
   1963 g_test_log_buffer_pop (GTestLogBuffer *tbuffer)
   1964 {
   1965   GTestLogMsg *msg = NULL;
   1966   g_return_val_if_fail (tbuffer != NULL, NULL);
   1967   if (tbuffer->msgs)
   1968     {
   1969       GSList *slist = g_slist_last (tbuffer->msgs);
   1970       msg = slist->data;
   1971       tbuffer->msgs = g_slist_delete_link (tbuffer->msgs, slist);
   1972     }
   1973   return msg;
   1974 }
   1975 
   1976 /**
   1977  * g_test_log_msg_free:
   1978  *
   1979  * Internal function for gtester to free test log messages, no ABI guarantees provided.
   1980  */
   1981 void
   1982 g_test_log_msg_free (GTestLogMsg *tmsg)
   1983 {
   1984   g_return_if_fail (tmsg != NULL);
   1985   g_strfreev (tmsg->strings);
   1986   g_free (tmsg->nums);
   1987   g_free (tmsg);
   1988 }
   1989 
   1990 /* --- macros docs START --- */
   1991 /**
   1992  * g_test_add:
   1993  * @testpath:  The test path for a new test case.
   1994  * @Fixture:   The type of a fixture data structure.
   1995  * @tdata:     Data argument for the test functions.
   1996  * @fsetup:    The function to set up the fixture data.
   1997  * @ftest:     The actual test function.
   1998  * @fteardown: The function to tear down the fixture data.
   1999  *
   2000  * Hook up a new test case at @testpath, similar to g_test_add_func().
   2001  * A fixture data structure with setup and teardown function may be provided
   2002  * though, similar to g_test_create_case().
   2003  * g_test_add() is implemented as a macro, so that the fsetup(), ftest() and
   2004  * fteardown() callbacks can expect a @Fixture pointer as first argument in
   2005  * a type safe manner.
   2006  *
   2007  * Since: 2.16
   2008  **/
   2009 /* --- macros docs END --- */
   2010 
   2011 #define __G_TEST_UTILS_C__
   2012 #include "galiasdef.c"
   2013