From 49a0e12b9ce3608c5fa9a6c3e7d1786c59c94ae3 Mon Sep 17 00:00:00 2001 From: Jasper van de Gronde Date: Wed, 2 Jun 2010 16:01:33 +0200 Subject: [PATCH] Fix for bug #283769 (emergency save fails) --- src/inkscape.cpp | 80 ++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/inkscape.cpp b/src/inkscape.cpp index d876be6ec..6361e36c1 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -595,6 +595,8 @@ inkscape_crash_handler (int /*signum*/) strftime (sptstr, 256, "%Y_%m_%d_%H_%M_%S", sptm); gint count = 0; + gchar *curdir = g_get_current_dir(); // This one needs to be freed explicitly + gchar *inkscapedir = g_path_get_dirname(INKSCAPE->argv0); // Needs to be freed GSList *savednames = NULL; GSList *failednames = NULL; for (std::map::iterator iter = inkscape->document_set.begin(); @@ -604,55 +606,57 @@ inkscape_crash_handler (int /*signum*/) Inkscape::XML::Node *repr; repr = sp_document_repr_root (doc); if (doc->isModifiedSinceSave()) { - const gchar *docname, *d0, *d; - gchar n[64], c[1024]; - FILE *file; + const gchar *docname; /* originally, the document name was retrieved from * the sodipod:docname attribute */ docname = doc->name; if (docname) { - /* fixme: Quick hack to remove emergency file suffix */ - d0 = strrchr ((char*)docname, '.'); + /* Removes an emergency save suffix if present: /(.*)\.[0-9_]*\.[0-9_]*\.[~\.]*$/\1/ */ + const char* d0 = strrchr ((char*)docname, '.'); if (d0 && (d0 > docname)) { - d0 = strrchr ((char*)(d0 - 1), '.'); - if (d0 && (d0 > docname)) { - d = d0; - while (isdigit (*d) || (*d == '.') || (*d == '_')) d += 1; - if (*d) { - memcpy (n, docname, MIN (d0 - docname - 1, 64)); - n[63] = '\0'; - docname = n; - } + const char* d = d0; + unsigned int dots = 0; + while ((isdigit (*d) || *d=='_' || *d=='.') && d>docname && dots<2) { + d -= 1; + if (*d=='.') dots++; + } + if (*d=='.' && d>docname && dots==2) { + char n[64]; + size_t len = MIN (d - docname, 63); + memcpy (n, docname, len); + n[len] = '\0'; + docname = n; } } } - if (!docname || !*docname) docname = "emergency"; - // try saving to the profile location + + // Emergency filename + char c[1024]; g_snprintf (c, 1024, "%.256s.%s.%d.svg", docname, sptstr, count); - gchar * location = homedir_path(c); - Inkscape::IO::dump_fopen_call(location, "E"); - file = Inkscape::IO::fopen_utf8name(location, "w"); - g_snprintf (c, 1024, "%s", location); // we want the complete path to be stored in c (for reporting purposes) - g_free(location); - if (!file) { - // try saving to /tmp - g_snprintf (c, 1024, "/tmp/inkscape-%.256s.%s.%d.svg", docname, sptstr, count); - Inkscape::IO::dump_fopen_call(c, "G"); - file = Inkscape::IO::fopen_utf8name(c, "w"); - } - if (!file) { - // try saving to the current directory - gchar *curdir = g_get_current_dir(); - g_snprintf (c, 1024, "inkscape-%.256s.%s.%d.svg", docname, sptstr, count); - Inkscape::IO::dump_fopen_call(c, "F"); - file = Inkscape::IO::fopen_utf8name(c, "w"); - // store the complete path in c so that it can be reported later - gchar * location = g_build_filename(curdir, c, NULL); - g_snprintf (c, 1024, "%s", location); - g_free(location); + + // Find a location + const char* locations[] = { + doc->base, + g_get_home_dir(), + g_get_tmp_dir(), + curdir, + inkscapedir + }; + FILE *file; + for(size_t i=0; idocument(), file, SP_SVG_NS_URI); savednames = g_slist_prepend (savednames, g_strdup (c)); @@ -663,6 +667,8 @@ inkscape_crash_handler (int /*signum*/) count++; } } + g_free(curdir); + g_free(inkscapedir); savednames = g_slist_reverse (savednames); failednames = g_slist_reverse (failednames); -- 2.30.2