+static const char*
+sindent (guint n)
+{
+ static const char spaces[] = " ";
+ int l = sizeof (spaces) - 1;
+ n = MIN (n, l);
+ return spaces + l - n;
+}
+
+static void G_GNUC_PRINTF (1, 2)
+test_log_printfe (const char *format,
+ ...)
+{
+ char *result;
+ int r;
+ va_list args;
+ va_start (args, format);
+ result = g_markup_vprintf_escaped (format, args);
+ va_end (args);
+ do
+ r = write (log_fd, result, strlen (result));
+ while (r < 0 && errno == EINTR);
+ g_free (result);
+}
+
+static void
+terminate (void)
+{
+ kill (getpid(), SIGTERM);
+ abort();
+}
+
+static void
+testcase_close (long double duration,
+ gint exit_status,
+ guint n_forks)
+{
+ g_return_if_fail (testcase_open > 0);
+ test_log_printfe ("%s<duration>%.6Lf</duration>\n", sindent (log_indent), duration);
+ test_log_printfe ("%s<status exit-status=\"%d\" n-forks=\"%d\" result=\"%s\"/>\n",
+ sindent (log_indent), exit_status, n_forks,
+ exit_status ? "failed" : "success");
+ log_indent -= 2;
+ test_log_printfe ("%s</testcase>\n", sindent (log_indent));
+ testcase_open--;
+ if (gtester_verbose)
+ g_print ("%s\n", exit_status ? "FAIL" : "OK");
+ if (exit_status && subtest_last_seed)
+ g_print ("GTester: last random seed: %s\n", subtest_last_seed);
+ if (exit_status)
+ testcase_fail_count += 1;
+ if (subtest_mode_fatal && exit_status)
+ terminate();
+}
+
+static void
+test_log_msg (GTestLogMsg *msg)
+{
+ switch (msg->log_type)
+ {
+ guint i;
+ gchar **strv;
+ case G_TEST_LOG_NONE:
+ case G_TEST_LOG_START_SUITE:
+ case G_TEST_LOG_STOP_SUITE:
+ break;
+ case G_TEST_LOG_ERROR:
+ strv = g_strsplit (msg->strings[0], "\n", -1);
+ for (i = 0; strv[i]; i++)
+ test_log_printfe ("%s<error>%s</error>\n", sindent (log_indent), strv[i]);
+ g_strfreev (strv);
+ break;
+ case G_TEST_LOG_START_BINARY:
+ test_log_printfe ("%s<binary file=\"%s\"/>\n", sindent (log_indent), msg->strings[0]);
+ subtest_last_seed = g_strdup (msg->strings[1]);
+ test_log_printfe ("%s<random-seed>%s</random-seed>\n", sindent (log_indent), subtest_last_seed);
+ break;
+ case G_TEST_LOG_LIST_CASE:
+ g_print ("%s\n", msg->strings[0]);
+ break;
+ case G_TEST_LOG_START_CASE:
+ testcase_count++;
+ if (gtester_verbose)
+ {
+ gchar *sc = g_strconcat (msg->strings[0], ":", NULL);
+ gchar *sleft = g_strdup_printf ("%-68s", sc);
+ g_free (sc);
+ g_print ("%70s ", sleft);
+ g_free (sleft);
+ }
+ g_return_if_fail (testcase_open == 0);
+ testcase_open++;
+ test_log_printfe ("%s<testcase path=\"%s\">\n", sindent (log_indent), msg->strings[0]);
+ log_indent += 2;
+ break;
+ case G_TEST_LOG_SKIP_CASE:
+ if (FALSE && gtester_verbose) /* enable to debug test case skipping logic */
+ {
+ gchar *sc = g_strconcat (msg->strings[0], ":", NULL);
+ gchar *sleft = g_strdup_printf ("%-68s", sc);
+ g_free (sc);
+ g_print ("%70s SKIPPED\n", sleft);
+ g_free (sleft);
+ }
+ test_log_printfe ("%s<testcase path=\"%s\" skipped=\"1\"/>\n", sindent (log_indent), msg->strings[0]);
+ break;
+ case G_TEST_LOG_STOP_CASE:
+ testcase_close (msg->nums[2], (int) msg->nums[0], (int) msg->nums[1]);
+ break;
+ case G_TEST_LOG_MIN_RESULT:
+ case G_TEST_LOG_MAX_RESULT:
+ test_log_printfe ("%s<performance minimize=\"%d\" maximize=\"%d\" value=\"%.16Lg\">\n",
+ sindent (log_indent), msg->log_type == G_TEST_LOG_MIN_RESULT, msg->log_type == G_TEST_LOG_MAX_RESULT, msg->nums[0]);
+ test_log_printfe ("%s%s\n", sindent (log_indent + 2), msg->strings[0]);
+ test_log_printfe ("%s</performance>\n", sindent (log_indent));
+ break;
+ case G_TEST_LOG_MESSAGE:
+ test_log_printfe ("%s<message>\n%s\n%s</message>\n", sindent (log_indent), msg->strings[0], sindent (log_indent));
+ break;
+ }
+}
+