Index: glib/gfileutils.c
===================================================================
RCS file: /cvs/gnome/glib/glib/gfileutils.c,v
retrieving revision 1.37
diff -u -2 -r1.37 gfileutils.c
--- glib/gfileutils.c	11 Dec 2002 23:40:09 -0000	1.37
+++ glib/gfileutils.c	16 Aug 2003 04:57:25 -0000
@@ -66,4 +66,10 @@
 #include "glibintl.h"
 
+#ifdef G_OS_WIN32
+#define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR || c == '/')
+#else
+#define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR)
+#endif
+
 /**
  * g_file_test:
@@ -750,19 +756,24 @@
   char *sep;
   char *fulltemplate;
+  const char *slash;
 
   if (tmpl == NULL)
     tmpl = ".XXXXXX";
 
-  if (strchr (tmpl, G_DIR_SEPARATOR)
+  if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
 #ifdef G_OS_WIN32
-      || strchr (tmpl, '/')
+      || (strchr (tmpl, '/') != NULL && (slash = "/"))
 #endif
-				    )
+      )
     {
+      char c[2];
+      c[0] = *slash;
+      c[1] = '\0';
+
       g_set_error (error,
 		   G_FILE_ERROR,
 		   G_FILE_ERROR_FAILED,
 		   _("Template '%s' invalid, should not contain a '%s'"),
-		   tmpl, G_DIR_SEPARATOR_S);
+		   tmpl, c);
 
       return -1;
@@ -782,5 +793,5 @@
   tmpdir = g_get_tmp_dir ();
 
-  if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
+  if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
     sep = "";
   else
@@ -965,6 +976,10 @@
  * 
  * Creates a filename from a series of elements using the correct
- * separator for filenames. This function behaves identically
- * to <literal>g_build_path (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
+ * 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 separators in filenames, but otherwise behaves as
+ * <literal>g_built_path()</literal>.
  *
  * No attempt is made to force the resulting filename to be an absolute
@@ -978,4 +993,5 @@
 		  ...)
 {
+#ifndef G_OS_WIN32
   gchar *str;
   va_list args;
@@ -986,3 +1002,108 @@
 
   return str;
+#else
+  /* Code copied from g_build_pathv(), and modifed to use two
+   * alternative single-character separators.
+   */
+  va_list args;
+  GString *result;
+  gboolean is_first = TRUE;
+  gboolean have_leading = FALSE;
+  const gchar *single_element = NULL;
+  const gchar *next_element;
+  const gchar *last_trailing = NULL;
+  gchar current_separator = '\\';
+
+  va_start (args, first_element);
+
+  result = g_string_new (NULL);
+
+  next_element = first_element;
+
+  while (TRUE)
+    {
+      const gchar *element;
+      const gchar *start;
+      const gchar *end;
+
+      if (next_element)
+	{
+	  element = next_element;
+	  next_element = va_arg (args, gchar *);
+	}
+      else
+	break;
+
+      /* Ignore empty elements */
+      if (!*element)
+	continue;
+      
+      start = element;
+
+      if (TRUE)
+	{
+	  while (start &&
+		 (*start == '\\' || *start == '/'))
+	    {
+	      current_separator = *start;
+	      start++;
+	    }
+	}
+
+      end = start + strlen (start);
+      
+      if (TRUE)
+	{
+	  while (end >= start + 1 &&
+		 (end[-1] == '\\' || end[-1] == '/'))
+	    {
+	      current_separator = end[-1];
+	      end--;
+	    }
+	  
+	  last_trailing = end;
+	  while (last_trailing >= element + 1 &&
+		 (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
+	    last_trailing--;
+
+	  if (!have_leading)
+	    {
+	      /* If the leading and trailing separator strings are in the
+	       * same element and overlap, the result is exactly that element
+	       */
+	      if (last_trailing <= start)
+		single_element = element;
+		  
+	      g_string_append_len (result, element, start - element);
+	      have_leading = TRUE;
+	    }
+	  else
+	    single_element = NULL;
+	}
+
+      if (end == start)
+	continue;
+
+      if (!is_first)
+	g_string_append_len (result, &current_separator, 1);
+      
+      g_string_append_len (result, start, end - start);
+      is_first = FALSE;
+    }
+
+  va_end (args);
+
+  if (single_element)
+    {
+      g_string_free (result, TRUE);
+      return g_strdup (single_element);
+    }
+  else
+    {
+      if (last_trailing)
+	g_string_append (result, last_trailing);
+  
+      return g_string_free (result, FALSE);
+    }
+#endif
 }
Index: tests/strfunc-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/strfunc-test.c,v
retrieving revision 1.19
diff -u -2 -r1.19 strfunc-test.c
--- tests/strfunc-test.c	26 Nov 2002 15:04:06 -0000	1.19
+++ tests/strfunc-test.c	16 Aug 2003 04:57:25 -0000
@@ -442,4 +442,37 @@
   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));
 
+#ifdef G_OS_WIN32
+
+  /* Test also using the slash as file name separator */
+#define U "/"
+  TEST (NULL, str_check (g_build_filename (NULL), ""));
+  TEST (NULL, str_check (g_build_filename (U, NULL), U));
+  TEST (NULL, str_check (g_build_filename (U"x", NULL), U"x"));
+  TEST (NULL, str_check (g_build_filename ("x"U, NULL), "x"U));
+  TEST (NULL, str_check (g_build_filename ("", U"x", NULL), U"x"));
+  TEST (NULL, str_check (g_build_filename ("", U"x", NULL), U"x"));
+  TEST (NULL, str_check (g_build_filename (U, "x", NULL), U"x"));
+  TEST (NULL, str_check (g_build_filename (U U, "x", NULL), U U"x"));
+  TEST (NULL, str_check (g_build_filename (U S, "x", NULL), U S"x"));
+  TEST (NULL, str_check (g_build_filename ("x"U, "", NULL), "x"U));
+  TEST (NULL, str_check (g_build_filename ("x"S"y", "z"U"a", NULL), "x"S"y"S"z"U"a"));
+  TEST (NULL, str_check (g_build_filename ("x", U, NULL), "x"U));
+  TEST (NULL, str_check (g_build_filename ("x", U U, NULL), "x"U U));
+  TEST (NULL, str_check (g_build_filename ("x", S U, NULL), "x"S U));
+  TEST (NULL, str_check (g_build_filename (U"x", "y", NULL), U"x"U"y"));
+  TEST (NULL, str_check (g_build_filename ("x", "y"U, NULL), "x"U"y"U));
+  TEST (NULL, str_check (g_build_filename (U"x"U, U"y"U, NULL), U"x"U"y"U));
+  TEST (NULL, str_check (g_build_filename (U"x"U U, U U"y"U, NULL), U"x"U"y"U));
+  TEST (NULL, str_check (g_build_filename ("x", U, "y",  NULL), "x"U"y"));
+  TEST (NULL, str_check (g_build_filename ("x", U U, "y",  NULL), "x"U"y"));
+  TEST (NULL, str_check (g_build_filename ("x", U S, "y",  NULL), "x"S"y"));
+  TEST (NULL, str_check (g_build_filename ("x", S U, "y",  NULL), "x"U"y"));
+  TEST (NULL, str_check (g_build_filename ("x", U "y", "z", NULL), "x"U"y"U"z"));
+  TEST (NULL, str_check (g_build_filename ("x", S "y", "z", NULL), "x"S"y"S"z"));
+  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));
+#endif /* G_OS_WIN32 */
+
 #undef S
 
