static gchar *test_run_seedstr = NULL;
static GRand *test_run_rand = NULL;
static gchar *test_run_name = "";
+static GSList **test_filename_free_list;
static guint test_run_forks = 0;
static guint test_run_count = 0;
static guint test_run_success = FALSE;
test_case_run (GTestCase *tc)
{
gchar *old_name = test_run_name, *old_base = g_strdup (test_uri_base);
+ GSList **old_free_list, *filename_free_list = NULL;
gboolean success = TRUE;
+ old_free_list = test_filename_free_list;
+ test_filename_free_list = &filename_free_list;
+
test_run_name = g_strconcat (old_name, "/", tc->name, NULL);
if (strstr (test_run_name, "/subprocess"))
{
}
out:
+ g_slist_free_full (filename_free_list, g_free);
+ test_filename_free_list = old_free_list;
g_free (test_run_name);
test_run_name = old_name;
g_free (test_uri_base);
g_free (tmsg);
}
+static gchar *
+g_test_build_filename_va (GTestFileType file_type,
+ const gchar *first_path,
+ va_list ap)
+{
+ const gchar *pathv[16];
+ gint num_path_segments;
+
+ if (file_type == G_TEST_DISTED)
+ pathv[0] = test_disted_files_dir;
+ else if (file_type == G_TEST_BUILT)
+ pathv[0] = test_built_files_dir;
+ else
+ g_assert_not_reached ();
+
+ pathv[1] = first_path;
+
+ for (num_path_segments = 2; num_path_segments < G_N_ELEMENTS (pathv); num_path_segments++)
+ {
+ pathv[num_path_segments] = va_arg (ap, const char *);
+ if (pathv[num_path_segments] == NULL)
+ break;
+ }
+
+ g_assert_cmpint (num_path_segments, <, G_N_ELEMENTS (pathv));
+
+ return g_build_filenamev ((gchar **) pathv);
+}
+
/**
* g_test_build_filename:
* @file_type: the type of file (built vs. disted)
const gchar *first_path,
...)
{
- const gchar *pathv[16];
- gint num_path_segments;
+ gchar *result;
va_list ap;
g_assert (g_test_initialized ());
+ va_start (ap, first_path);
+ result = g_test_build_filename_va (file_type, first_path, ap);
+ va_end (ap);
+
+ return result;
+}
+
+/**
+ * g_test_get_dir:
+ * @file_type: the type of file (built vs. disted)
+ *
+ * Gets the pathname of the directory containing test files of the type
+ * specified by @file_type.
+ *
+ * This is approximately the same as calling g_test_build_filename("."),
+ * but you don't need to free the return value.
+ *
+ * Returns: the path of the directory, owned by GLib
+ *
+ * Since: 2.38
+ **/
+const gchar *
+g_test_get_dir (GTestFileType file_type)
+{
+ g_assert (g_test_initialized ());
+
if (file_type == G_TEST_DISTED)
- pathv[0] = test_disted_files_dir;
+ return test_disted_files_dir;
else if (file_type == G_TEST_BUILT)
- pathv[0] = test_built_files_dir;
- else
- g_assert_not_reached ();
+ return test_built_files_dir;
- pathv[1] = first_path;
+ g_assert_not_reached ();
+}
+
+/**
+ * g_test_get_filename:
+ * @file_type: the type of file (built vs. disted)
+ * @first_path: the first segment of the pathname
+ * ...: NULL terminated additional path segments
+ *
+ * Gets the pathname to a data file that is required for a test.
+ *
+ * This is the same as g_test_build_filename() with two differences.
+ * The first difference is that must only use this function from within
+ * a testcase function. The second difference is that you need not free
+ * the return value -- it will be automatically freed when the testcase
+ * finishes running.
+ *
+ * It is safe to use this function from a thread inside of a testcase
+ * but you must ensure that all such uses occur before the main testcase
+ * function returns (ie: it is best to ensure that all threads have been
+ * joined).
+ *
+ * Returns: the path, automatically freed at the end of the testcase
+ *
+ * Since: 2.38
+ **/
+const gchar *
+g_test_get_filename (GTestFileType file_type,
+ const gchar *first_path,
+ ...)
+{
+ gchar *result;
+ GSList *node;
+ va_list ap;
+
+ g_assert (g_test_initialized ());
+ if (test_filename_free_list == NULL)
+ g_error ("g_test_get_filename() can only be used within testcase funcitons");
va_start (ap, first_path);
- for (num_path_segments = 2; num_path_segments < G_N_ELEMENTS (pathv); num_path_segments++)
- {
- pathv[num_path_segments] = va_arg (ap, const char *);
- if (pathv[num_path_segments] == NULL)
- break;
- }
+ result = g_test_build_filename_va (file_type, first_path, ap);
+ va_end (ap);
- g_assert_cmpint (num_path_segments, <, G_N_ELEMENTS (pathv));
+ node = g_slist_prepend (NULL, result);
+ do
+ node->next = *test_filename_free_list;
+ while (!g_atomic_pointer_compare_and_exchange (test_filename_free_list, node->next, node));
- return g_build_filenamev ((gchar **) pathv);
+ return result;
}
/* --- macros docs START --- */