summaryrefslogtreecommitdiff
path: root/libguile/filesys.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2010-04-19 16:39:11 +0200
committerAndy Wingo <wingo@pobox.com>2010-04-19 16:39:11 +0200
commit22457d5730b2d5302c55a8f1f4c07470be975021 (patch)
tree8f5d07f95bff0346203331f203218c12f1bba045 /libguile/filesys.c
parent0abc21094420dc00312cfa74788e5d9c1524b04a (diff)
downloadguile-22457d5730b2d5302c55a8f1f4c07470be975021.tar.gz
filesystem trickery to scm_i_relativize_path in filesys.c; bugfix.
* libguile/filesys.h: * libguile/filesys.c (scm_i_relativize_path): New function, moved here from fports.c. Internal for now; we can make it external though if people like its interface. * libguile/fports.c (fport_canonicalize_filename): Move all of the tricky bits to filesys.c. Also fixes a bug in which a delimiter wasn't stripped.
Diffstat (limited to 'libguile/filesys.c')
-rw-r--r--libguile/filesys.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/libguile/filesys.c b/libguile/filesys.c
index 0dbcc2b12..68d90d926 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -1654,6 +1654,52 @@ SCM_DEFINE (scm_canonicalize_path, "canonicalize-path", 1, 0, 0,
}
#undef FUNC_NAME
+SCM
+scm_i_relativize_path (SCM path, SCM in_path)
+{
+ char *str, *canon;
+ SCM scanon;
+
+ str = scm_to_locale_string (path);
+ canon = canonicalize_file_name (str);
+ free (str);
+
+ if (!canon)
+ return SCM_BOOL_F;
+
+ scanon = scm_take_locale_string (canon);
+
+ for (; scm_is_pair (in_path); in_path = scm_cdr (in_path))
+ if (scm_is_true (scm_string_prefix_p (scm_car (in_path),
+ scanon,
+ SCM_UNDEFINED, SCM_UNDEFINED,
+ SCM_UNDEFINED, SCM_UNDEFINED)))
+ {
+ size_t len = scm_c_string_length (scm_car (in_path));
+
+ /* The path either has a trailing delimiter or doesn't. scanon will be
+ delimited by single delimiters. In the case in which the path does
+ not have a trailing delimiter, add one to the length to strip off the
+ delimiter within scanon. */
+ if (!len
+#ifdef __MINGW32__
+ || (scm_i_string_ref (scm_car (in_path), len - 1) != '/'
+ && scm_i_string_ref (scm_car (in_path), len - 1) != '\\')
+#else
+ || scm_i_string_ref (scm_car (in_path), len - 1) != '/'
+#endif
+ )
+ len++;
+
+ if (scm_c_string_length (scanon) > len)
+ return scm_substring (scanon, scm_from_size_t (len), SCM_UNDEFINED);
+ else
+ return SCM_BOOL_F;
+ }
+
+ return SCM_BOOL_F;
+}
+