Add g_build_path(), g_build_filename(), to create separated paths,
authorOwen Taylor <otaylor@redhat.com>
Mon, 10 Sep 2001 13:30:41 +0000 (13:30 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Mon, 10 Sep 2001 13:30:41 +0000 (13:30 +0000)
Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>

        * glib/gfileutils.[ch]: Add g_build_path(),
        g_build_filename(), to create separated paths,
        suppressing duplicate separators, from varargs
        lists.

        * tests/strfunc-test.c: Add tests for g_build_path(),
        g_build_filename().

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

index 551b251..77152ea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 551b251..77152ea 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep  8 17:14:51 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * glib/gfileutils.[ch]: Add g_build_path(), 
+       g_build_filename(), to create separated paths, 
+       suppressing duplicate separators, from varargs
+       lists.
+
+       * tests/strfunc-test.c: Add tests for g_build_path(),
+       g_build_filename().
+
 Sat Sep  8 14:11:53 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/Makefile.am (libglib_1_3_la_SOURCES): Add
index 031cbde..a11048a 100644 (file)
@@ -28,6 +28,7 @@
 #endif
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
@@ -697,3 +698,121 @@ g_file_open_tmp (const char *tmpl,
 
   return retval;
 }
+
+static gchar *
+g_build_pathv (const gchar *separator,
+              const gchar *first_element,
+              va_list      args)
+{
+  GString *result;
+  gint separator_len = strlen (separator);
+  gboolean is_first = TRUE;
+  const gchar *next_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;
+
+      start = element;
+      
+      if (is_first)
+       is_first = FALSE;
+      else if (separator_len)
+       {
+         while (start &&
+                strncmp (start, separator, separator_len) == 0)
+           start += separator_len;
+       }
+
+      end = start + strlen (start);
+      
+      if (next_element && separator_len)
+       {
+         while (end > start + separator_len &&
+                strncmp (end - separator_len, separator, separator_len) == 0)
+           end -= separator_len;
+       }
+
+      if (end > start)
+       {
+         if (result->len > 0)
+           g_string_append (result, separator);
+
+         g_string_append_len (result, start, end - start);
+       }
+    }
+  
+  return g_string_free (result, FALSE);
+}
+
+/**
+ * g_build_path:
+ * @separator: a string used to separator the elements of the path.
+ * @first_element: the first element in the path
+ * 
+ * Create a path from a series of elements using @separator as the
+ * separator between elements. At the boundary between two elements,
+ * any trailing occurrences of separator in the first element, or
+ * leading occurrences of separator in the second element are removed
+ * and exactly one copy of the separator is inserted.
+ * 
+ * Return value: a newly allocated string that must be freed with g_free().
+ **/
+gchar *
+g_build_path (const gchar *separator,
+             const gchar *first_element,
+             ...)
+{
+  gchar *str;
+  va_list args;
+
+  g_return_val_if_fail (separator != NULL, NULL);
+
+  va_start (args, first_element);
+  str = g_build_pathv (separator, first_element, args);
+  va_end (args);
+
+  return str;
+}
+
+/**
+ * g_build_filename:
+ * @first_element: the first element in the path
+ * 
+ * Create a filename from a series of elements using the correct
+ * separator for filenames. This function behaves identically
+ * to g_build_path (G_DIR_SEPARATOR_S, first_element, ....)
+ *
+ * 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);
+  str = g_build_pathv (G_DIR_SEPARATOR_S, first_element, args);
+  va_end (args);
+
+  return str;
+}
index 161a131..f966e01 100644 (file)
@@ -88,6 +88,12 @@ int     g_file_open_tmp      (const char   *tmpl,
                              char        **name_used,
                              GError      **error);
 
+gchar *g_build_path     (const gchar *separator,
+                        const gchar *first_element,
+                        ...);
+gchar *g_build_filename (const gchar *first_element,
+                        ...);
+
 G_END_DECLS
 
 #endif /* __G_FILEUTILS_H__ */
index 30ff116..fa3089a 100644 (file)
@@ -81,6 +81,17 @@ strv_check (gchar **strv, ...)
 }
 
 static gboolean
+str_check (gchar *str,
+          gchar *expected)
+{
+  gboolean ok = (strcmp (str, expected) == 0);
+
+  g_free (str);
+
+  return ok;
+}
+
+static gboolean
 test_isalnum (gchar c)
 {
   return g_ascii_isalnum (c);
@@ -354,5 +365,58 @@ main (int   argc,
 
   #undef TEST_DIGIT
 
+  /* Tests for g_build_path, g_build_filename */
+
+  TEST (NULL, str_check (g_build_path ("", NULL), ""));
+  TEST (NULL, str_check (g_build_path ("", "", NULL), ""));
+  TEST (NULL, str_check (g_build_path ("", "x", NULL), "x"));
+  TEST (NULL, str_check (g_build_path ("", "x", "y",  NULL), "xy"));
+  TEST (NULL, str_check (g_build_path ("", "x", "y", "z", NULL), "xyz"));
+
+  TEST (NULL, str_check (g_build_path (":", NULL), ""));
+  TEST (NULL, str_check (g_build_path (":", ":", NULL), ":"));
+  TEST (NULL, str_check (g_build_path (":", ":x", NULL), ":x"));
+  TEST (NULL, str_check (g_build_path (":", "x:", NULL), "x:"));
+  TEST (NULL, str_check (g_build_path (":", "x", "y",  NULL), "x:y"));
+  TEST (NULL, str_check (g_build_path (":", ":x", "y", NULL), ":x:y"));
+  TEST (NULL, str_check (g_build_path (":", "x", "y:", NULL), "x:y:"));
+  TEST (NULL, str_check (g_build_path (":", ":x:", ":y:", NULL), ":x:y:"));
+  TEST (NULL, str_check (g_build_path (":", ":x::", "::y:", NULL), ":x:y:"));
+  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:"));
+  TEST (NULL, str_check (g_build_path (":", "::x::", "::y::", "::z::", NULL), "::x:y:z::"));
+
+  TEST (NULL, str_check (g_build_path ("::", NULL), ""));
+  TEST (NULL, str_check (g_build_path ("::", "::", NULL), "::"));
+  TEST (NULL, str_check (g_build_path ("::", "::x", NULL), "::x"));
+  TEST (NULL, str_check (g_build_path ("::", "x::", NULL), "x::"));
+  TEST (NULL, str_check (g_build_path ("::", "x", "y",  NULL), "x::y"));
+  TEST (NULL, str_check (g_build_path ("::", "::x", "y", NULL), "::x::y"));
+  TEST (NULL, str_check (g_build_path ("::", "x", "y::", NULL), "x::y::"));
+  TEST (NULL, str_check (g_build_path ("::", "::x::", "::y::", NULL), "::x::y::"));
+  TEST (NULL, str_check (g_build_path ("::", "::x:::", ":::y::", NULL), "::x::::y::"));
+  TEST (NULL, str_check (g_build_path ("::", "::x::::", "::::y::", NULL), "::x::y::"));
+  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::"));
+  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::::"));
+
+#define S G_DIR_SEPARATOR_S
+
+  TEST (NULL, str_check (g_build_filename (NULL), ""));
+  TEST (NULL, str_check (g_build_filename (S, NULL), S));
+  TEST (NULL, str_check (g_build_filename (S"x", NULL), S"x"));
+  TEST (NULL, str_check (g_build_filename ("x"S, NULL), "x"S));
+  TEST (NULL, str_check (g_build_filename ("x", "y",  NULL), "x"S"y"));
+  TEST (NULL, str_check (g_build_filename (S"x", "y", NULL), S"x"S"y"));
+  TEST (NULL, str_check (g_build_filename ("x", "y"S, NULL), "x"S"y"S));
+  TEST (NULL, str_check (g_build_filename (S"x"S, S"y"S, NULL), S"x"S"y"S));
+  TEST (NULL, str_check (g_build_filename (S"x"S S, S S"y"S, NULL), S"x"S"y"S));
+  TEST (NULL, str_check (g_build_filename ("x", "y", "z", NULL), "x"S"y"S"z"));
+  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));
+
+#undef S
+
   return any_failed;
 }