summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2013-06-19 21:26:20 -0400
committerJasper St. Pierre <jstpierre@mecheye.net>2013-06-19 21:34:16 -0400
commit826282db8c23fc1c4bba1985c643a626ff1f0c2c (patch)
treea74b710d491ff74af89cbfd6e03dafc71a144385
parent077fc095208e8429400763f0e41ac7c8884e8c1e (diff)
downloadlibgsystem-826282db8c23fc1c4bba1985c643a626ff1f0c2c.tar.gz
fileutils: Add gs_system_get_relpath
This will properly emit "../../foo" now for files with different parents.
-rw-r--r--gsystem-file-utils.c75
-rw-r--r--gsystem-file-utils.h2
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