[dia] Fix relative path handling with Windows root directories
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] Fix relative path handling with Windows root directories
- Date: Sun, 11 Jan 2015 20:14:11 +0000 (UTC)
commit a9d2f0fa1a2af6ee2c9a6006b3af91517f6cb7b1
Author: Hans Breuer <hans breuer org>
Date: Sun Dec 14 17:56:10 2014 +0100
Fix relative path handling with Windows root directories
We have do deal with the special meaning of Windows drives, where 'c:' is
a reference to the current directory, but c:\ is the root path. For other
directory names the trailing backslash is stripped by g_path_get_dirname().
Bug reported on the mailing list:
https://mail.gnome.org/archives/dia-list/2014-November/msg00045.html
lib/dia_dirs.c | 11 +++-
objects/Misc/diagram_as_object.c | 2 +-
objects/standard/image.c | 125 ++++++--------------------------------
3 files changed, 30 insertions(+), 108 deletions(-)
---
diff --git a/lib/dia_dirs.c b/lib/dia_dirs.c
index c0672f7..99e8590 100644
--- a/lib/dia_dirs.c
+++ b/lib/dia_dirs.c
@@ -338,9 +338,16 @@ dia_relativize_filename (const gchar *master, const gchar *slave)
bp1 = g_path_get_dirname (master);
bp2 = g_path_get_dirname (slave);
- if (g_str_has_prefix (bp1, bp2)) {
+ /* the slave path has to be included in master to become relative */
+ if (g_str_has_prefix (bp2, bp1)) {
gchar *p;
- rel = g_strdup (slave + strlen (bp1) + 1);
+ /* We have do deal with the special meaning of Windows drives, where 'c:' is
+ * a reference to the current directory, but c:\ is the root path. For other
+ * directory names the trailing backslash is stripped by g_path_get_dirname().
+ * So only advance (+1) in slave when there is no trailing backslash.
+ */
+ rel = g_strdup (slave + strlen (bp1)
+ + (g_str_has_suffix (bp1, G_DIR_SEPARATOR_S) ? 0 : 1));
/* flip backslashes */
for (p = rel; *p != '\0'; p++)
if (*p == '\\') *p = '/';
diff --git a/objects/Misc/diagram_as_object.c b/objects/Misc/diagram_as_object.c
index 4516211..0a030ff 100644
--- a/objects/Misc/diagram_as_object.c
+++ b/objects/Misc/diagram_as_object.c
@@ -395,7 +395,7 @@ _dae_save (DiaObject *obj, ObjectNode obj_node, DiaContext *ctx)
gchar *dirname = g_path_get_dirname (dia_context_get_filename (ctx));
if (strstr (dae->filename, dirname) == dae->filename) {
saved_path = dae->filename;
- dae->filename += (strlen (dirname) + 1);
+ dae->filename += (strlen (dirname) + g_str_has_suffix (dirname, G_DIR_SEPARATOR_S) ? 0 : 1);
}
g_free (dirname);
}
diff --git a/objects/standard/image.c b/objects/standard/image.c
index 843cf8a..a2d556f 100644
--- a/objects/standard/image.c
+++ b/objects/standard/image.c
@@ -37,6 +37,7 @@
#include "dia_image.h"
#include "message.h"
#include "properties.h"
+#include "dia_dirs.h"
#include "tool-icons.h"
@@ -689,41 +690,9 @@ image_copy(Image *image)
return &newimage->element.object;
}
-/* Gets the directory path of a filename.
- Uses current working directory if filename is a relative pathname.
- Examples:
- /some/dir/file.gif => /some/dir
- dir/file.gif => /cwd/dir
-
-*/
-static char *
-get_directory(const char *filename)
-{
- char *cwd;
- char *directory;
- char *dirname;
-
- if (filename==NULL)
- return NULL;
-
- dirname = g_path_get_dirname(filename);
- if (g_path_is_absolute(dirname)) {
- directory = g_build_path(G_DIR_SEPARATOR_S, dirname, NULL);
- } else {
- cwd = g_get_current_dir();
- directory = g_build_path(G_DIR_SEPARATOR_S, cwd, dirname, NULL);
- g_free(cwd);
- }
- g_free(dirname);
-
- return directory;
-}
-
static void
image_save(Image *image, ObjectNode obj_node, DiaContext *ctx)
{
- char *diafile_dir;
-
element_save(&image->element, obj_node, ctx);
if (image->border_width != 0.1)
@@ -750,22 +719,14 @@ image_save(Image *image, ObjectNode obj_node, DiaContext *ctx)
data_add_real(new_attribute(obj_node, "angle"), image->angle, ctx);
if (image->file != NULL) {
- if (g_path_is_absolute(image->file)) { /* Absolute pathname */
- diafile_dir = get_directory(dia_context_get_filename (ctx));
-
- if (diafile_dir && strncmp(diafile_dir, image->file, strlen(diafile_dir))==0) {
- /* The image pathname has the dia file pathname in the begining */
- /* Save the relative path: */
- data_add_filename(new_attribute(obj_node, "file"),
- image->file + strlen(diafile_dir) + 1, ctx);
- } else {
- /* Save the absolute path: */
- data_add_filename(new_attribute(obj_node, "file"), image->file, ctx);
- }
- g_free(diafile_dir);
+ gchar *relative = dia_relativize_filename (dia_context_get_filename (ctx), image->file);
+
+ if (relative) {
+ /* The image pathname has the diagram file pathname in the beginning */
+ data_add_filename(new_attribute(obj_node, "file"), relative, ctx);
+ g_free (relative);
} else {
- /* Relative path. Must be an erronuous filename...
- Just save the filename. */
+ /* Save the absolute path: */
data_add_filename(new_attribute(obj_node, "file"), image->file, ctx);
}
}
@@ -857,74 +818,28 @@ image_load(ObjectNode obj_node, int version, DiaContext *ctx)
image->image = NULL;
if (strcmp(image->file, "")!=0) {
- diafile_dir = get_directory(dia_context_get_filename(ctx));
-
- if (g_path_is_absolute(image->file)) { /* Absolute pathname */
+ if ( g_path_is_absolute (image->file)
+ && g_file_test (image->file, G_FILE_TEST_IS_REGULAR)) { /* Absolute pathname */
image->image = dia_image_load(image->file);
- if (image->image == NULL) {
- /* Not found as abs path, try in same dir as diagram. */
- char *temp_string;
- const char *image_file_name = image->file;
- const char *psep;
-
- psep = strrchr(image->file, G_DIR_SEPARATOR);
- /* try the other G_OS as well */
- if (!psep)
- psep = strrchr(image->file, G_DIR_SEPARATOR == '/' ? '\\' : '/');
- if (psep)
- image_file_name = psep + 1;
-
- temp_string = g_build_filename(diafile_dir, image_file_name, NULL);
-
- image->image = dia_image_load(temp_string);
-
- if (image->image != NULL) {
- /* Found file in same dir as diagram. */
- message_warning(_("The image file '%s' was not found in the specified directory.\n"
- "Using the file '%s' instead.\n"), image->file, temp_string);
- g_free(image->file);
- image->file = temp_string;
- } else {
- g_free(temp_string);
-
- image->image = dia_image_load((char *)image_file_name);
- if (image->image != NULL) {
- char *tmp;
- /* Found file in current dir. */
- message_warning(_("The image file '%s' was not found in the specified directory.\n"
- "Using the file '%s' instead.\n"), image->file, image_file_name);
- tmp = image->file;
- image->file = g_strdup(image_file_name);
- g_free(tmp);
- } else {
- message_warning(_("The image file '%s' was not found.\n"),
- image_file_name);
- }
- }
- }
- } else { /* Relative pathname: */
- char *temp_string;
-
- temp_string = g_build_filename (diafile_dir, image->file, NULL);
-
- image->image = dia_image_load(temp_string);
+ } else { /* build from relative pathname */
+ gchar *image_filename = dia_absolutize_filename (dia_context_get_filename (ctx), image->file);
+ image->image = dia_image_load(image_filename);
if (image->image != NULL) {
- /* Found file in same dir as diagram. */
+ /* Found file in same directory as diagram. */
g_free(image->file);
- image->file = temp_string;
+ image->file = image_filename;
} else {
- g_free(temp_string);
-
+ /* not found as relative path, try literally */
+ g_free (image_filename);
+
image->image = dia_image_load(image->file);
if (image->image == NULL) {
- /* Didn't find file in current dir. */
- message_warning(_("The image file '%s' was not found.\n"),
- image->file);
+ /* Didn't find file in current directory. */
+ dia_context_add_message (ctx, _("The image file '%s' was not found.\n"), image->file);
}
}
}
- g_free(diafile_dir);
}
/* if we don't have an image yet try to recover it from inlined data */
if (!image->image) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]