Fix #117925 (Dov Grobgeld):
authorTor Lillqvist <tml@iki.fi>
Sat, 16 Aug 2003 19:45:25 +0000 (19:45 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Sat, 16 Aug 2003 19:45:25 +0000 (19:45 +0000)
2003-08-16  Tor Lillqvist  <tml@iki.fi>

Fix #117925 (Dov Grobgeld):

* glib/gutils.c (g_find_program_in_path, g_basename,
g_path_get_basename, g_path_is_absolute, g_path_skip_root,
g_path_get_dirname, g_get_any_init): On Win32, look also for
slashes ('/') as pathname separators.

* glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
contains a pathname separator, include the actual one in the error
message, instead of always the canonical one.

(g_build_filename): Separate implementation on Win32 that looks
for either slash or backslash. Document Unix/Windows differences.

* tests/testglib.c
* tests/strfunc-test.c: Test above functionality on Win32.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib/gfileutils.c
glib/gutils.c
tests/strfunc-test.c
tests/testglib.c

index 6b3a18e..841bcc6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2003-08-16  Tor Lillqvist  <tml@iki.fi>
+
+       Fix #117925 (Dov Grobgeld):
+
+       * glib/gutils.c (g_find_program_in_path, g_basename,
+       g_path_get_basename, g_path_is_absolute, g_path_skip_root,
+       g_path_get_dirname, g_get_any_init): On Win32, look also for
+       slashes ('/') as pathname separators.
+
+       * glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
+       contains a pathname separator, include the actual one in the error
+       message, instead of always the canonical one.
+
+       (g_build_filename): Separate implementation on Win32 that looks
+       for either slash or backslash. Document Unix/Windows differences.
+
+       * tests/testglib.c
+       * tests/strfunc-test.c: Test above functionality on Win32.
+
 2003-08-15  Tor Lillqvist  <tml@iki.fi>
 
        * glib/gmain.c (g_poll): [Win32] Don't exceed handle array
index 6b3a18e..841bcc6 100644 (file)
@@ -1,3 +1,22 @@
+2003-08-16  Tor Lillqvist  <tml@iki.fi>
+
+       Fix #117925 (Dov Grobgeld):
+
+       * glib/gutils.c (g_find_program_in_path, g_basename,
+       g_path_get_basename, g_path_is_absolute, g_path_skip_root,
+       g_path_get_dirname, g_get_any_init): On Win32, look also for
+       slashes ('/') as pathname separators.
+
+       * glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
+       contains a pathname separator, include the actual one in the error
+       message, instead of always the canonical one.
+
+       (g_build_filename): Separate implementation on Win32 that looks
+       for either slash or backslash. Document Unix/Windows differences.
+
+       * tests/testglib.c
+       * tests/strfunc-test.c: Test above functionality on Win32.
+
 2003-08-15  Tor Lillqvist  <tml@iki.fi>
 
        * glib/gmain.c (g_poll): [Win32] Don't exceed handle array
index 6b3a18e..841bcc6 100644 (file)
@@ -1,3 +1,22 @@
+2003-08-16  Tor Lillqvist  <tml@iki.fi>
+
+       Fix #117925 (Dov Grobgeld):
+
+       * glib/gutils.c (g_find_program_in_path, g_basename,
+       g_path_get_basename, g_path_is_absolute, g_path_skip_root,
+       g_path_get_dirname, g_get_any_init): On Win32, look also for
+       slashes ('/') as pathname separators.
+
+       * glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
+       contains a pathname separator, include the actual one in the error
+       message, instead of always the canonical one.
+
+       (g_build_filename): Separate implementation on Win32 that looks
+       for either slash or backslash. Document Unix/Windows differences.
+
+       * tests/testglib.c
+       * tests/strfunc-test.c: Test above functionality on Win32.
+
 2003-08-15  Tor Lillqvist  <tml@iki.fi>
 
        * glib/gmain.c (g_poll): [Win32] Don't exceed handle array
index 6b3a18e..841bcc6 100644 (file)
@@ -1,3 +1,22 @@
+2003-08-16  Tor Lillqvist  <tml@iki.fi>
+
+       Fix #117925 (Dov Grobgeld):
+
+       * glib/gutils.c (g_find_program_in_path, g_basename,
+       g_path_get_basename, g_path_is_absolute, g_path_skip_root,
+       g_path_get_dirname, g_get_any_init): On Win32, look also for
+       slashes ('/') as pathname separators.
+
+       * glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
+       contains a pathname separator, include the actual one in the error
+       message, instead of always the canonical one.
+
+       (g_build_filename): Separate implementation on Win32 that looks
+       for either slash or backslash. Document Unix/Windows differences.
+
+       * tests/testglib.c
+       * tests/strfunc-test.c: Test above functionality on Win32.
+
 2003-08-15  Tor Lillqvist  <tml@iki.fi>
 
        * glib/gmain.c (g_poll): [Win32] Don't exceed handle array
index 6b3a18e..841bcc6 100644 (file)
@@ -1,3 +1,22 @@
+2003-08-16  Tor Lillqvist  <tml@iki.fi>
+
+       Fix #117925 (Dov Grobgeld):
+
+       * glib/gutils.c (g_find_program_in_path, g_basename,
+       g_path_get_basename, g_path_is_absolute, g_path_skip_root,
+       g_path_get_dirname, g_get_any_init): On Win32, look also for
+       slashes ('/') as pathname separators.
+
+       * glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
+       contains a pathname separator, include the actual one in the error
+       message, instead of always the canonical one.
+
+       (g_build_filename): Separate implementation on Win32 that looks
+       for either slash or backslash. Document Unix/Windows differences.
+
+       * tests/testglib.c
+       * tests/strfunc-test.c: Test above functionality on Win32.
+
 2003-08-15  Tor Lillqvist  <tml@iki.fi>
 
        * glib/gmain.c (g_poll): [Win32] Don't exceed handle array
index 6b3a18e..841bcc6 100644 (file)
@@ -1,3 +1,22 @@
+2003-08-16  Tor Lillqvist  <tml@iki.fi>
+
+       Fix #117925 (Dov Grobgeld):
+
+       * glib/gutils.c (g_find_program_in_path, g_basename,
+       g_path_get_basename, g_path_is_absolute, g_path_skip_root,
+       g_path_get_dirname, g_get_any_init): On Win32, look also for
+       slashes ('/') as pathname separators.
+
+       * glib/gfileutils.c (g_file_open_tmp): Ditto. If the template
+       contains a pathname separator, include the actual one in the error
+       message, instead of always the canonical one.
+
+       (g_build_filename): Separate implementation on Win32 that looks
+       for either slash or backslash. Document Unix/Windows differences.
+
+       * tests/testglib.c
+       * tests/strfunc-test.c: Test above functionality on Win32.
+
 2003-08-15  Tor Lillqvist  <tml@iki.fi>
 
        * glib/gmain.c (g_poll): [Win32] Don't exceed handle array
index 121d81b..0381c80 100644 (file)
 
 #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:
  * @filename: a filename to test
@@ -749,21 +755,26 @@ g_file_open_tmp (const gchar *tmpl,
   const char *tmpdir;
   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;
     }
@@ -781,7 +792,7 @@ g_file_open_tmp (const gchar *tmpl,
 
   tmpdir = g_get_tmp_dir ();
 
-  if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
+  if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
     sep = "";
   else
     sep = G_DIR_SEPARATOR_S;
@@ -964,8 +975,17 @@ g_build_path (const gchar *separator,
  * @Varargs: remaining elements in path, terminated by %NULL
  * 
  * 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 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
@@ -977,6 +997,7 @@ gchar *
 g_build_filename (const gchar *first_element, 
                  ...)
 {
+#ifndef G_OS_WIN32
   gchar *str;
   va_list args;
 
@@ -985,6 +1006,111 @@ g_build_filename (const gchar *first_element,
   va_end (args);
 
   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 6ea3b71..a90d3a3 100644 (file)
 #include <libintl.h>
 #endif
 
+/* G_IS_DIR_SEPARATOR probably should be made public in GLib 2.4 */
+#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
+
 const guint glib_major_version = GLIB_MAJOR_VERSION;
 const guint glib_minor_version = GLIB_MINOR_VERSION;
 const guint glib_micro_version = GLIB_MICRO_VERSION;
@@ -250,7 +257,11 @@ g_find_program_in_path (const gchar *program)
    * don't look in PATH.
    */
   if (g_path_is_absolute (program)
-      || strchr (program, G_DIR_SEPARATOR) != NULL)
+      || strchr (program, G_DIR_SEPARATOR) != NULL
+#ifdef G_OS_WIN32
+      || strchr (program, '/') != NULL
+#endif
+      )
     {
       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE))
         return g_strdup (program);
@@ -402,6 +413,15 @@ g_basename (const gchar       *file_name)
   g_return_val_if_fail (file_name != NULL, NULL);
   
   base = strrchr (file_name, G_DIR_SEPARATOR);
+
+#ifdef G_OS_WIN32
+  {
+    gchar *q = strrchr (file_name, '/');
+    if (base == NULL || (q != NULL && q > base))
+       base = q;
+  }
+#endif
+
   if (base)
     return base + 1;
 
@@ -442,7 +462,7 @@ g_path_get_basename (const gchar   *file_name)
   
   last_nonslash = strlen (file_name) - 1;
 
-  while (last_nonslash >= 0 && file_name [last_nonslash] == G_DIR_SEPARATOR)
+  while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
     last_nonslash--;
 
   if (last_nonslash == -1)
@@ -457,7 +477,7 @@ g_path_get_basename (const gchar   *file_name)
 
   base = last_nonslash;
 
-  while (base >=0 && file_name [base] != G_DIR_SEPARATOR)
+  while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
     base--;
 
 #ifdef G_OS_WIN32
@@ -477,16 +497,12 @@ g_path_is_absolute (const gchar *file_name)
 {
   g_return_val_if_fail (file_name != NULL, FALSE);
   
-  if (file_name[0] == G_DIR_SEPARATOR
-#ifdef G_OS_WIN32
-      || file_name[0] == '/'
-#endif
-                                    )
+  if (G_IS_DIR_SEPARATOR (file_name[0]))
     return TRUE;
 
 #ifdef G_OS_WIN32
   /* Recognize drive letter on native Windows */
-  if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && (file_name[2] == G_DIR_SEPARATOR || file_name[2] == '/'))
+  if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
     return TRUE;
 #endif /* G_OS_WIN32 */
 
@@ -499,23 +515,32 @@ g_path_skip_root (const gchar *file_name)
   g_return_val_if_fail (file_name != NULL, NULL);
   
 #ifdef G_PLATFORM_WIN32
-  /* Skip \\server\share (Win32) or //server/share (Cygwin) */
-  if (file_name[0] == G_DIR_SEPARATOR &&
-      file_name[1] == G_DIR_SEPARATOR &&
+  /* Skip \\server\share or //server/share */
+  if (G_IS_DIR_SEPARATOR (file_name[0]) &&
+      G_IS_DIR_SEPARATOR (file_name[1]) &&
       file_name[2])
     {
       gchar *p;
 
-      if ((p = strchr (file_name + 2, G_DIR_SEPARATOR)) > file_name + 2 &&
+      p = strchr (file_name + 2, G_DIR_SEPARATOR);
+#ifdef G_OS_WIN32
+      {
+       gchar *q = strchr (file_name + 2, '/');
+       if (p == NULL || (q != NULL && q < p))
+         p = q;
+      }
+#endif
+      if (p &&
+         p > file_name + 2 &&
          p[1])
        {
          file_name = p + 1;
 
-         while (file_name[0] && file_name[0] != G_DIR_SEPARATOR)
+         while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
            file_name++;
 
          /* Possibly skip a backslash after the share name */
-         if (file_name[0] == G_DIR_SEPARATOR)
+         if (G_IS_DIR_SEPARATOR (file_name[0]))
            file_name++;
 
          return (gchar *)file_name;
@@ -524,16 +549,16 @@ g_path_skip_root (const gchar *file_name)
 #endif
   
   /* Skip initial slashes */
-  if (file_name[0] == G_DIR_SEPARATOR)
+  if (G_IS_DIR_SEPARATOR (file_name[0]))
     {
-      while (file_name[0] == G_DIR_SEPARATOR)
+      while (G_IS_DIR_SEPARATOR (file_name[0]))
        file_name++;
       return (gchar *)file_name;
     }
 
 #ifdef G_OS_WIN32
   /* Skip X:\ */
-  if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
+  if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
     return (gchar *)file_name + 3;
 #endif
 
@@ -549,9 +574,16 @@ g_path_get_dirname (const gchar       *file_name)
   g_return_val_if_fail (file_name != NULL, NULL);
   
   base = strrchr (file_name, G_DIR_SEPARATOR);
+#ifdef G_OS_WIN32
+  {
+    gchar *q = strrchr (file_name, '/');
+    if (base == NULL || (q != NULL && q > base))
+       base = q;
+  }
+#endif
   if (!base)
     return g_strdup (".");
-  while (base > file_name && *base == G_DIR_SEPARATOR)
+  while (base > file_name && G_IS_DIR_SEPARATOR (*base))
     base--;
   len = (guint) 1 + base - file_name;
   
@@ -792,7 +824,7 @@ g_get_any_init (void)
          gsize k;    
          g_tmp_dir = g_strdup (P_tmpdir);
          k = strlen (g_tmp_dir);
-         if (k > 1 && g_tmp_dir[k - 1] == G_DIR_SEPARATOR)
+         if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
            g_tmp_dir[k - 1] = '\0';
        }
 #endif
index eeb7c97..dbac5e1 100644 (file)
@@ -441,6 +441,39 @@ 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));
 
+#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
 
   {
index 5695754..54a9153 100644 (file)
@@ -336,7 +336,6 @@ main (int   argc,
     gchar *filename;
     gchar *dirname;
   } dirname_checks[] = {
-#ifndef G_OS_WIN32
     { "/", "/" },
     { "////", "/" },
     { ".////", "." },
@@ -345,14 +344,16 @@ main (int   argc,
     { "a/b", "a" },
     { "a/b/", "a/b" },
     { "c///", "c" },
-#else
+#ifdef G_OS_WIN32
     { "\\", "\\" },
     { ".\\\\\\\\", "." },
     { "..\\", ".." },
     { "..\\\\\\\\", ".." },
     { "a\\b", "a" },
-    { "a\\b\\", "a\\b" },
-    { "c\\\\\\", "c" },
+    { "a\\b/", "a\\b" },
+    { "a/b\\", "a/b" },
+    { "c\\\\/", "c" },
+    { "//\\", "/" },
 #endif
 #ifdef G_WITH_CYGWIN
     { "//server/share///x", "//server/share" },
@@ -367,13 +368,12 @@ main (int   argc,
     gchar *filename;
     gchar *without_root;
   } skip_root_checks[] = {
-#ifndef G_OS_WIN32
     { "/", "" },
     { "//", "" },
     { "/foo", "foo" },
     { "//foo", "foo" },
     { "a/b", NULL },
-#else
+#ifdef G_OS_WIN32
     { "\\", "" },
     { "\\foo", "foo" },
     { "\\\\server\\foo", "" },
@@ -448,6 +448,15 @@ main (int   argc,
   g_assert (strcmp (string, "file") == 0);
   g_free (string);
   g_print ("ok\n");
+#ifdef G_OS_WIN32
+  string = g_path_get_basename ("/foo/dir/");
+  g_assert (strcmp (string, "dir") == 0);
+  g_free (string);
+  string = g_path_get_basename ("/foo/file");
+  g_assert (strcmp (string, "file") == 0);
+  g_free (string);
+  g_print ("ok\n");
+#endif
 
   g_print ("checking g_path_get_dirname()...");
   for (i = 0; i < n_dirname_checks; i++)
@@ -1171,6 +1180,11 @@ main (int   argc,
 
   g_print ("ok\n");
 
+  if (g_get_charset (&string))
+    g_print ("current charset is UTF-8: %s\n", string);
+  else
+    g_print ("current charset is not UTF-8: %s\n", string);
+
 #ifdef G_PLATFORM_WIN32
   g_print ("current locale: %s\n", g_win32_getlocale ());
   g_print ("GLib DLL name tested for: %s\n", glib_dll);
@@ -1235,6 +1249,18 @@ main (int   argc,
   close (fd);
   g_clear_error (&error);
 
+#ifdef G_OS_WIN32
+  strcpy (template, "zap/barXXXXXX");
+  fd = g_file_open_tmp (template, &name_used, &error);
+  if (fd != -1)
+    g_print ("g_file_open_tmp works even if template contains '/'\n");
+  else
+    g_print ("g_file_open_tmp correctly returns error: %s\n",
+            error->message);
+  close (fd);
+  g_clear_error (&error);
+#endif
+
   strcpy (template, "zapXXXXXX");
   fd = g_file_open_tmp (template, &name_used, &error);
   if (fd == -1)