#endif
static gchar *
-g_build_pathv (const gchar *separator,
- const gchar *first_element,
- va_list args)
+g_build_path_va (const gchar *separator,
+ const gchar *first_element,
+ va_list args,
+ gchar **str_array)
{
GString *result;
gint separator_len = strlen (separator);
const gchar *single_element = NULL;
const gchar *next_element;
const gchar *last_trailing = NULL;
+ gint i = 0;
result = g_string_new (NULL);
- next_element = first_element;
+ if (str_array)
+ next_element = str_array[i++];
+ else
+ next_element = first_element;
while (TRUE)
{
if (next_element)
{
element = next_element;
- next_element = va_arg (args, gchar *);
+ if (str_array)
+ next_element = str_array[i++];
+ else
+ next_element = va_arg (args, gchar *);
}
else
break;
}
/**
+ * g_build_pathv:
+ * @separator: a string used to separator the elements of the path.
+ * @args: %NULL-terminated array of strings containing the path elements.
+ *
+ * Behaves exactly like g_build_path(), but takes the path elements
+ * as a string array, instead of varargs. This function is mainly
+ * meant for language bindings.
+ *
+ * Return value: a newly-allocated string that must be freed with g_free().
+ *
+ * Since: 2.8
+ */
+gchar *
+g_build_pathv (const gchar *separator,
+ gchar **args)
+{
+ va_list va_args;
+
+ if (!args)
+ return NULL;
+
+ return g_build_path_va (separator, NULL, va_args, args);
+}
+
+
+/**
* g_build_path:
* @separator: a string used to separator the elements of the path.
* @first_element: the first element in the path
g_return_val_if_fail (separator != NULL, NULL);
va_start (args, first_element);
- str = g_build_pathv (separator, first_element, args);
+ str = g_build_path_va (separator, first_element, args, NULL);
va_end (args);
return str;
}
-/**
- * g_build_filename:
- * @first_element: the first element in the path
- * @Varargs: remaining elements in path, terminated by %NULL
- *
- * Creates a filename from a series of elements using the correct
- * separator for filenames.
- *
- * On Unix, this function behaves identically to <literal>g_build_path
- * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
- *
- * On Windows, it takes into account that either the backslash
- * (<literal>\</literal> or slash (<literal>/</literal>) can be used
- * as separator in filenames, but otherwise behaves as on Unix. When
- * file pathname separators need to be inserted, the one that last
- * previously occurred in the parameters (reading from left to right)
- * is used.
- *
- * No attempt is made to force the resulting filename to be an absolute
- * path. If the first element is a relative path, the result will
- * be a relative path.
- *
- * Return value: a newly-allocated string that must be freed with g_free().
- **/
-gchar *
-g_build_filename (const gchar *first_element,
- ...)
+static gchar *
+g_build_filename_va (const gchar *first_element,
+ va_list args,
+ gchar **str_array)
{
-#ifndef G_OS_WIN32
- gchar *str;
- va_list args;
-
- va_start (args, first_element);
- str = g_build_pathv (G_DIR_SEPARATOR_S, first_element, args);
- va_end (args);
-
- return str;
-#else
- /* Code copied from g_build_pathv(), and modifed to use two
+ /* Code copied from g_build_pathv(), and modified to use two
* alternative single-character separators.
*/
- va_list args;
GString *result;
gboolean is_first = TRUE;
gboolean have_leading = FALSE;
const gchar *next_element;
const gchar *last_trailing = NULL;
gchar current_separator = '\\';
-
- va_start (args, first_element);
+ gint i = 0;
result = g_string_new (NULL);
- next_element = first_element;
-
+ if (str_array)
+ next_element = str_array[i++];
+ else
+ next_element = first_element;
+
while (TRUE)
{
const gchar *element;
if (next_element)
{
element = next_element;
- next_element = va_arg (args, gchar *);
+ if (str_array)
+ next_element = str_array[i++];
+ else
+ next_element = va_arg (args, gchar *);
}
else
break;
is_first = FALSE;
}
- va_end (args);
-
if (single_element)
{
g_string_free (result, TRUE);
return g_string_free (result, FALSE);
}
+}
+
+/**
+ * g_build_filenamev:
+ * @args: %NULL-terminated array of strings containing the path elements.
+ *
+ * Behaves exactly like g_build_filename(), but takes the path elements
+ * as a string array, instead of varargs. This function is mainly
+ * meant for language bindings.
+ *
+ * Return value: a newly-allocated string that must be freed with g_free().
+ *
+ * Since: 2.8
+ */
+gchar *
+g_build_filenamev (gchar **args)
+{
+ gchar *str;
+ va_list va_args;
+
+#ifndef G_OS_WIN32
+ str = g_build_path_va (G_DIR_SEPARATOR_S, NULL, va_args, args);
+#else
+ str = g_build_pathname_va (NULL, va_args, args);
+#endif
+
+ return str;
+}
+
+/**
+ * g_build_filename:
+ * @first_element: the first element in the path
+ * @Varargs: remaining elements in path, terminated by %NULL
+ *
+ * Creates a filename from a series of elements using the correct
+ * separator for filenames.
+ *
+ * On Unix, this function behaves identically to <literal>g_build_path
+ * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
+ *
+ * On Windows, it takes into account that either the backslash
+ * (<literal>\</literal> or slash (<literal>/</literal>) can be used
+ * as separator in filenames, but otherwise behaves as on Unix. When
+ * file pathname separators need to be inserted, the one that last
+ * previously occurred in the parameters (reading from left to right)
+ * is used.
+ *
+ * No attempt is made to force the resulting filename to be an absolute
+ * path. If the first element is a relative path, the result will
+ * be a relative path.
+ *
+ * Return value: a newly-allocated string that must be freed with g_free().
+ **/
+gchar *
+g_build_filename (const gchar *first_element,
+ ...)
+{
+ gchar *str;
+ va_list args;
+
+ va_start (args, first_element);
+#ifndef G_OS_WIN32
+ str = g_build_path_va (G_DIR_SEPARATOR_S, first_element, args, NULL);
+#else
+ str = g_build_pathname_va (first_element, args, NULL);
#endif
+ va_end (args);
+
+ return str;
}
/**
gchar *string;
gchar *vec[] = { "Foo", "Bar", NULL };
gchar **copy;
+ gchar *args[10];
TEST (NULL, g_ascii_strcasecmp ("FroboZZ", "frobozz") == 0);
TEST (NULL, g_ascii_strcasecmp ("frobozz", "frobozz") == 0);
TEST (NULL, str_check (g_build_path ("::", ":::x:::", ":::y:::", ":::z:::", NULL), ":::x::::y::::z:::"));
TEST (NULL, str_check (g_build_path ("::", "::::x::::", "::::y::::", "::::z::::", NULL), "::::x::y::z::::"));
+ args[0] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("", args), ""));
+ args[0] = ""; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("", args), ""));
+ args[0] = "x"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("", args), "x"));
+ args[0] = "x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("", args), "xy"));
+ args[0] = "x"; args[1] = "y"; args[2] = "z", args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("", args), "xyz"));
+
+ args[0] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ""));
+ args[0] = ":"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":"));
+ args[0] = ":x"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x"));
+ args[0] = "x:"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:"));
+ args[0] = ""; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x"));
+ args[0] = ""; args[1] = ":x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x"));
+ args[0] = ":"; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x"));
+ args[0] = "::"; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "::x"));
+ args[0] = "x"; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x"));
+ args[0] = "x:"; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:"));
+ args[0] = "x"; args[1] = ":"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:"));
+ args[0] = "x"; args[1] = "::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x::"));
+ args[0] = "x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:y"));
+ args[0] = ":x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x:y"));
+ args[0] = "x"; args[1] = "y:"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:y:"));
+ args[0] = ":x:"; args[1] = ":y:"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x:y:"));
+ args[0] = ":x::"; args[1] = "::y:"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x:y:"));
+ args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:y"));
+ args[0] = "x"; args[1] = ":"; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:y"));
+ args[0] = "x"; args[1] = "::"; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:y"));
+ args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "x:y:z"));
+ args[0] = ":x:"; args[1] = ":y:"; args[2] = ":z:"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), ":x:y:z:"));
+ args[0] = "::x::"; args[1] = "::y::"; args[2] = "::z::"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv (":", args), "::x:y:z::"));
+
+ args[0] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), ""));
+ args[0] = "::"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::"));
+ args[0] = ":::"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), ":::"));
+ args[0] = "::x"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x"));
+ args[0] = "x::"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::"));
+ args[0] = ""; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x"));
+ args[0] = ""; args[1] = "::x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x"));
+ args[0] = "::"; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x"));
+ args[0] = "::::"; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::::x"));
+ args[0] = "x"; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x"));
+ args[0] = "x::"; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::"));
+ args[0] = "x"; args[1] = "::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::"));
+ /* This following is weird, but keeps the definition simple */
+ args[0] = "x"; args[1] = ":::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x:::::"));
+ args[0] = "x"; args[1] = "::::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::::"));
+ args[0] = "x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::y"));
+ args[0] = "::x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x::y"));
+ args[0] = "x"; args[1] = "y::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::y::"));
+ args[0] = "::x::"; args[1] = "::y::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x::y::"));
+ args[0] = "::x:::"; args[1] = ":::y::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x::::y::"));
+ args[0] = "::x::::"; args[1] = "::::y::"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x::y::"));
+ args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::y"));
+ args[0] = "x"; args[1] = "::"; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::y"));
+ args[0] = "x"; args[1] = "::::"; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::y"));
+ args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "x::y::z"));
+ args[0] = "::x::"; args[1] = "::y::"; args[2] = "::z::"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::x::y::z::"));
+ args[0] = ":::x:::"; args[1] = ":::y:::"; args[2] = ":::z:::"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), ":::x::::y::::z:::"));
+ args[0] = "::::x::::"; args[1] = "::::y::::"; args[2] = "::::z::::"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_pathv ("::", args), "::::x::y::z::::"));
+
#define S G_DIR_SEPARATOR_S
TEST (NULL, str_check (g_build_filename (NULL), ""));
TEST (NULL, str_check (g_build_filename (S"x"S, S"y"S, S"z"S, NULL), S"x"S"y"S"z"S));
TEST (NULL, str_check (g_build_filename (S S"x"S S, S S"y"S S, S S"z"S S, NULL), S S"x"S"y"S"z"S S));
+ args[0] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), ""));
+ args[0] = S; args[1] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S));
+ args[0] = S"x"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"));
+ args[0] = "x"S; args[1] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S));
+ args[0] = ""; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"));
+ args[0] = ""; args[1] = S"x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"));
+ args[0] = S; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"));
+ args[0] = S S; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S S"x"));
+ args[0] = "x"; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"));
+ args[0] = "x"S; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S));
+ args[0] = "x"; args[1] = S; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S));
+ args[0] = "x"; args[1] = S S; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S S));
+ args[0] = "x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"));
+ args[0] = S"x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"S"y"));
+ args[0] = "x"; args[1] = "y"S; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"S));
+ args[0] = S"x"S; args[1] = S"y"S; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"S"y"S));
+ args[0] = S"x"S S; args[1] = S S"y"S; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"S"y"S));
+ args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"));
+ args[0] = "x"; args[1] = S; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"));
+ args[0] = "x"; args[1] = S S; args[2] = "y"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"));
+ args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"S"z"));
+ args[0] = S"x"S; args[1] = S"y"S; args[2] = S"z"S; args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S"x"S"y"S"z"S));
+ args[0] = S S"x"S S; args[1] = S S"y"S S; args[2] = S S"z"S S; args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), S S"x"S"y"S"z"S S));
+
#ifdef G_OS_WIN32
/* Test also using the slash as file name separator */
TEST (NULL, str_check (g_build_filename ("x", S "y", "z", U, "a", "b", NULL), "x"S"y"S"z"U"a"U"b"));
TEST (NULL, str_check (g_build_filename (U"x"U, U"y"U, U"z"U, NULL), U"x"U"y"U"z"U));
TEST (NULL, str_check (g_build_filename (U U"x"U U, U U"y"U U, U U"z"U U, NULL), U U"x"U"y"U"z"U U));
+
+ args[0] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), ""));
+ args[0] = U; args[1] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U));
+ args[0] = U"x"; args[1] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"));
+ args[0] = "x"U; args[1] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U));
+ args[0] = ""; args[1] = U"x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"));
+ args[0] = ""; args[1] = U"x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"));
+ args[0] = U; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"));
+ args[0] = U U; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U U"x"));
+ args[0] = U S; args[1] = "x"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U S"x"));
+ args[0] = "x"U; args[1] = ""; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U));
+ args[0] = "x"S"y"; args[1] = "z"U"a"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"S"z"U"a"));
+ args[0] = "x"; args[1] = U; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U));
+ args[0] = "x"; args[1] = U U; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U U));
+ args[0] = "x"; args[1] = S U; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S U));
+ args[0] = U"x"; args[1] = "y"; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"U"y"));
+ args[0] = "x"; args[1] = "y"U; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U"y"U));
+ args[0] = U"x"U; args[1] = U"y"U; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"U"y"U));
+ args[0] = U"x"U U; args[1] = U U"y"U; args[2] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"U"y"U));
+ args[0] = "x"; args[1] = U; args[2] = "y", args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U"y"));
+ args[0] = "x"; args[1] = U U; args[2] = "y", args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U"y"));
+ args[0] = "x"; args[1] = U S; args[2] = "y", args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"));
+ args[0] = "x"; args[1] = S U; args[2] = "y", args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U"y"));
+ args[0] = "x"; args[1] = U "y"; args[2] = "z", args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"U"y"U"z"));
+ args[0] = "x"; args[1] = S "y"; args[2] = "z", args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"S"z"));
+ args[0] = "x"; args[1] = S "y"; args[2] = "z", args[3] = U;
+ args[4] = "a"; args[5] = "b"; args[6] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), "x"S"y"S"z"U"a"U"b"));
+ args[0] = U"x"U; args[1] = U"y"U; args[2] = U"z"U, args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U"x"U"y"U"z"U));
+ args[0] = U U"x"U U; args[1] = U U"y"U U; args[2] = U U"z"U U, args[3] = NULL;
+ TEST (NULL, str_check (g_build_filenamev (args), U U"x"U"y"U"z"U U));
#endif /* G_OS_WIN32 */
#undef S