[libgsystem] fileutils: Add gs_system_get_relpath



commit 826282db8c23fc1c4bba1985c643a626ff1f0c2c
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Jun 19 21:26:20 2013 -0400

    fileutils: Add gs_system_get_relpath
    
    This will properly emit "../../foo" now for files with different parents.

 gsystem-file-utils.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gsystem-file-utils.h |    2 +
 2 files changed, 77 insertions(+), 0 deletions(-)
---
diff --git a/gsystem-file-utils.c b/gsystem-file-utils.c
index 00f86f6..5fb0252 100644
--- a/gsystem-file-utils.c
+++ b/gsystem-file-utils.c
@@ -892,3 +892,78 @@ gs_file_load_contents_utf8 (GFile         *file,
   return ret_contents;
 }
 
+static int
+path_common_directory (char *one,
+                       char *two)
+{
+  int dir_index = 0;
+  int i = 0;
+
+  while (*one && *two)
+    {
+      if (*one != *two)
+        break;
+      if (*one == '/')
+        dir_index = i + 1;
+
+      one++;
+      two++;
+      i++;
+    }
+
+  return dir_index;
+}
+
+/**
+ * gs_file_get_relpath:
+ * @one: The first #GFile
+ * @two: The second #GFile
+ *
+ * Like gs_file_get_relative_path(), but does not mandate that
+ * the two files have any parent in common. This function will
+ * instead insert "../" where appropriate.
+ *
+ * Returns: (transfer full): The relative path between the two.
+ */
+gchar *
+gs_file_get_relpath (GFile *one,
+                     GFile *two)
+{
+  gchar *simple_path;
+  gchar *one_path, *one_suffix;
+  gchar *two_path, *two_suffix;
+  GString *path;
+  int index;
+
+  simple_path = g_file_get_relative_path (one, two);
+  if (simple_path)
+    return simple_path;
+
+  one_path = g_file_get_path (one);
+  two_path = g_file_get_path (two);
+
+  index = path_common_directory (one_path, two_path);
+  one_suffix = one_path + index;
+  two_suffix = two_path + index;
+
+  path = g_string_new ("");
+
+  /* For every leftover path segment one has, append "../" so
+   * that we reach the same directory. */
+  while (*one_suffix)
+    {
+      g_string_append (path, "../");
+      one_suffix = strchr (one_suffix, '/');
+      if (one_suffix == NULL)
+        break;
+      one_suffix++;
+    }
+
+  /* And now append the leftover stuff on two's side. */
+  g_string_append (path, two_suffix);
+
+  g_free (one_path);
+  g_free (two_path);
+
+  return g_string_free (path, FALSE);
+}
diff --git a/gsystem-file-utils.h b/gsystem-file-utils.h
index 83f65ce..9eb8576 100644
--- a/gsystem-file-utils.h
+++ b/gsystem-file-utils.h
@@ -98,6 +98,8 @@ gchar *gs_file_load_contents_utf8 (GFile         *file,
                                    GCancellable  *cancellable,
                                    GError       **error);
 
+gchar *gs_file_get_relpath (GFile *one,
+                            GFile *two);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]