Add some language-binding friendly variants
authorMatthias Clasen <matthiasc@src.gnome.org>
Thu, 23 Jun 2005 05:50:53 +0000 (05:50 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Thu, 23 Jun 2005 05:50:53 +0000 (05:50 +0000)
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-8
glib/gfileutils.c
glib/gfileutils.h
glib/glib.symbols
tests/strfunc-test.c

index 561ad89..f84cdd8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2005-06-23  Matthias Clasen  <mclasen@redhat.com>
+
+       * glib/glib.symbols: 
+       * glib/gfileutils.h: 
+       * glib/gfileutils.c (g_build_pathv, g_build_filenamev): 
+       Variants of g_build_path() and g_build_filename()
+       which take a string array instead of varargs.  
+       (#149092, Todd A. Fisher)
+
+       * tests/strfunc-test.c: Add tests for g_build_pathv() 
+       and g_build_filenamev().
+
 2005-06-22  Tor Lillqvist  <tml@novell.com>
 
        * glib/gfileutils.c
index 561ad89..f84cdd8 100644 (file)
@@ -1,3 +1,15 @@
+2005-06-23  Matthias Clasen  <mclasen@redhat.com>
+
+       * glib/glib.symbols: 
+       * glib/gfileutils.h: 
+       * glib/gfileutils.c (g_build_pathv, g_build_filenamev): 
+       Variants of g_build_path() and g_build_filename()
+       which take a string array instead of varargs.  
+       (#149092, Todd A. Fisher)
+
+       * tests/strfunc-test.c: Add tests for g_build_pathv() 
+       and g_build_filenamev().
+
 2005-06-22  Tor Lillqvist  <tml@novell.com>
 
        * glib/gfileutils.c
index 561ad89..f84cdd8 100644 (file)
@@ -1,3 +1,15 @@
+2005-06-23  Matthias Clasen  <mclasen@redhat.com>
+
+       * glib/glib.symbols: 
+       * glib/gfileutils.h: 
+       * glib/gfileutils.c (g_build_pathv, g_build_filenamev): 
+       Variants of g_build_path() and g_build_filename()
+       which take a string array instead of varargs.  
+       (#149092, Todd A. Fisher)
+
+       * tests/strfunc-test.c: Add tests for g_build_pathv() 
+       and g_build_filenamev().
+
 2005-06-22  Tor Lillqvist  <tml@novell.com>
 
        * glib/gfileutils.c
index 561ad89..f84cdd8 100644 (file)
@@ -1,3 +1,15 @@
+2005-06-23  Matthias Clasen  <mclasen@redhat.com>
+
+       * glib/glib.symbols: 
+       * glib/gfileutils.h: 
+       * glib/gfileutils.c (g_build_pathv, g_build_filenamev): 
+       Variants of g_build_path() and g_build_filename()
+       which take a string array instead of varargs.  
+       (#149092, Todd A. Fisher)
+
+       * tests/strfunc-test.c: Add tests for g_build_pathv() 
+       and g_build_filenamev().
+
 2005-06-22  Tor Lillqvist  <tml@novell.com>
 
        * glib/gfileutils.c
index 2833a21..1be2962 100644 (file)
@@ -1570,9 +1570,10 @@ g_file_open_tmp (const gchar *tmpl,
 #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);
@@ -1581,10 +1582,14 @@ g_build_pathv (const gchar *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)
     {
@@ -1595,7 +1600,10 @@ g_build_pathv (const gchar *separator,
       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;
@@ -1666,6 +1674,32 @@ g_build_pathv (const gchar *separator,
 }
 
 /**
+ * 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
@@ -1712,54 +1746,20 @@ g_build_path (const gchar *separator,
   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;
@@ -1767,13 +1767,15 @@ g_build_filename (const gchar *first_element,
   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;
@@ -1783,7 +1785,10 @@ g_build_filename (const gchar *first_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;
@@ -1845,8 +1850,6 @@ g_build_filename (const gchar *first_element,
       is_first = FALSE;
     }
 
-  va_end (args);
-
   if (single_element)
     {
       g_string_free (result, TRUE);
@@ -1859,7 +1862,75 @@ g_build_filename (const gchar *first_element,
   
       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;
 }
 
 /**
index 885ed7c..0aa0852 100644 (file)
@@ -103,9 +103,13 @@ gint    g_file_open_tmp      (const gchar  *tmpl,
 
 gchar *g_build_path     (const gchar *separator,
                         const gchar *first_element,
-                        ...) G_GNUC_NULL_TERMINATED;
+                        ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+gchar *g_build_pathv    (const gchar  *separator,
+                        gchar       **args) G_GNUC_MALLOC;
+
 gchar *g_build_filename (const gchar *first_element,
-                        ...) G_GNUC_NULL_TERMINATED;
+                        ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+gchar *g_build_filenamev (gchar      **args) G_GNUC_MALLOC;
 
 int    g_mkdir_with_parents (const gchar *pathname,
                             int          mode);
index ff7dabb..116acd5 100644 (file)
@@ -250,8 +250,10 @@ g_set_error G_GNUC_PRINTF(4,5)
 
 #if IN_HEADER(__G_FILEUTILS_H__)
 #if IN_FILE(__G_FILEUTILS_C__)
-g_build_filename G_GNUC_NULL_TERMINATED
-g_build_path G_GNUC_NULL_TERMINATED
+g_build_filename G_GNUC_MALLOC G_GNUC_NULL_TERMINATED
+g_build_filenamev G_GNUC_MALLOC
+g_build_path G_GNUC_MALLOC G_GNUC_NULL_TERMINATED
+g_build_pathv G_GNUC_MALLOC 
 g_file_error_from_errno
 g_file_error_quark
 g_file_get_contents PRIVATE
index 09fb1c5..f861b44 100644 (file)
@@ -225,6 +225,7 @@ main (int   argc,
   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);
@@ -480,6 +481,120 @@ main (int   argc,
   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), ""));
@@ -506,6 +621,53 @@ main (int   argc,
   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 */
@@ -537,6 +699,62 @@ main (int   argc,
   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