nautilus/nautilus-name-length.patch

361 lines
14 KiB
Diff
Raw Normal View History

http://bugzilla.gnome.org/show_bug.cgi?id=364843
Keep the generated names for "reallylongfilename (copy).txt" from
overflowing the maximum allowed length for path names. Patch by
Dave Camp <dave@novell.com>.
Index: libnautilus-private/nautilus-file-operations.c
================================================================================
--- libnautilus-private/nautilus-file-operations.c
+++ libnautilus-private/nautilus-file-operations.c
@@ -1163,19 +1163,58 @@
}
}
+
+static char *
+shorten_string (const char *base, int reduce_by)
+{
+ int len;
+ char *ret;
+ const char *p;
+
+ len = strlen (base);
+ len -= reduce_by;
+
+ if (len <= 0) {
+ return NULL;
+ }
+
+ ret = g_malloc (len + 1);
+
+ p = base;
+ while (len) {
+ char *next;
+ next = g_utf8_next_char (p);
+ if (next - p > len || *next == '\0') {
+ break;
+ }
+
+ len -= next - p;
+ p = next;
+ }
+
+ if (p - base == 0) {
+ g_free (ret);
+ return NULL;
+ } else {
+ memcpy (ret, base, p - base);
+ ret[p-base] = '\0';
+ return ret;
+ }
+}
+
/* Note that we have these two separate functions with separate format
* strings for ease of localization.
*/
static char *
-get_link_name (char *name, int count)
+get_link_name (char *name, int count, int max_length)
{
char *result;
char *unescaped_name;
char *unescaped_tmp_name;
char *unescaped_result;
char *new_file;
-
+ int unescaped_result_size;
const char *format;
g_assert (name != NULL);
@@ -1210,6 +1249,17 @@
break;
}
unescaped_result = g_strdup_printf (format, unescaped_name);
+ if (max_length > 0 && (unescaped_result_size = strlen (unescaped_result)) > max_length) {
+ char *new_name;
+
+ new_name = shorten_string (unescaped_name, unescaped_result_size - max_length);
+ if (new_name) {
+ g_free (unescaped_result);
+ unescaped_result = g_strdup_printf (format, new_name);
+ g_assert (strlen (unescaped_result) <= max_length);
+ g_free (new_name);
+ }
+ }
} else {
/* Handle special cases for the first few numbers of each ten.
@@ -1238,6 +1288,17 @@
break;
}
unescaped_result = g_strdup_printf (format, count, unescaped_name);
+ if (max_length > 0 && (unescaped_result_size = strlen (unescaped_result)) > max_length) {
+ char *new_name;
+
+ new_name = shorten_string (unescaped_name, unescaped_result_size - max_length);
+ if (new_name) {
+ g_free (unescaped_result);
+ unescaped_result = g_strdup_printf (format, count, new_name);
+ g_assert (strlen (unescaped_result) <= max_length);
+ g_free (new_name);
+ }
+ }
}
new_file = g_filename_from_utf8 (unescaped_result, -1, NULL, NULL, NULL);
result = gnome_vfs_escape_path_string (new_file);
@@ -1434,11 +1495,11 @@
}
static char *
-make_next_duplicate_name (const char *base, const char *suffix, int count)
+make_next_duplicate_name (const char *base, const char *suffix, int count, int max_length)
{
const char *format;
char *result;
-
+ int name_size;
if (count < 1) {
g_warning ("bad count %d in get_duplicate_name", count);
@@ -1463,6 +1524,18 @@
}
result = g_strdup_printf (format, base, suffix);
+
+ if (max_length > 0 && (name_size = strlen (result)) > max_length) {
+ char *new_base;
+
+ new_base = shorten_string (base, name_size - max_length);
+ if (new_base) {
+ g_free (result);
+ result = g_strdup_printf (format, new_base, suffix);
+ g_assert (strlen (result) <= max_length);
+ g_free (new_base);
+ }
+ }
} else {
/* Handle special cases for the first few numbers of each ten.
@@ -1506,13 +1579,25 @@
}
result = g_strdup_printf (format, base, count, suffix);
+ if (max_length > 0 && (name_size = strlen (result)) > max_length) {
+ char *new_base;
+
+ new_base = shorten_string (base, name_size - max_length);
+ if (new_base) {
+ g_free (result);
+ result = g_strdup_printf (format, new_base, count, suffix);
+ g_assert (strlen (result) <= max_length);
+ g_free (new_base);
+
+ }
+ }
}
return result;
}
static char *
-get_duplicate_name (const char *name, int count_increment)
+get_duplicate_name (const char *name, int count_increment, int max_length)
{
char *result;
char *name_base;
@@ -1520,7 +1605,7 @@
int count;
parse_previous_duplicate_name (name, &name_base, &suffix, &count);
- result = make_next_duplicate_name (name_base, suffix, count + count_increment);
+ result = make_next_duplicate_name (name_base, suffix, count + count_increment, max_length);
g_free (name_base);
@@ -1528,7 +1613,7 @@
}
static char *
-get_next_duplicate_name (char *name, int count_increment)
+get_next_duplicate_name (char *name, int count_increment, int max_length)
{
char *unescaped_name;
char *unescaped_tmp_name;
@@ -1554,7 +1639,7 @@
g_free (unescaped_tmp_name);
- unescaped_result = get_duplicate_name (unescaped_name, count_increment);
+ unescaped_result = get_duplicate_name (unescaped_name, count_increment, max_length);
g_free (unescaped_name);
new_file = g_filename_from_utf8 (unescaped_result, -1, NULL, NULL, NULL);
@@ -1565,21 +1650,74 @@
}
static int
+get_max_name_length (const char *text_uri)
+{
+ int max_length;
+ GnomeVFSURI *uri;
+ char *dir;
+ long max_path;
+ long max_name;
+
+ max_length = -1;
+
+ uri = gnome_vfs_uri_new (text_uri);
+ if (!uri) {
+ return max_length;
+ }
+
+ if (strcmp (gnome_vfs_uri_get_scheme (uri), "file") != 0) {
+ gnome_vfs_uri_unref (uri);
+ return max_length;
+ }
+
+ dir = gnome_vfs_uri_extract_dirname (uri);
+
+ max_path = pathconf (dir, _PC_PATH_MAX);
+ max_name = pathconf (dir, _PC_NAME_MAX);
+
+ if (max_name == -1 && max_path == -1) {
+ max_length = -1;
+ } else if (max_name == -1 && max_path != -1) {
+ max_length = max_path - (strlen (dir) + 1);
+ } else if (max_name != -1 && max_path == -1) {
+ max_length = max_name;
+ } else {
+ int leftover;
+
+ leftover = max_path - (strlen (dir) + 1);
+
+ max_length = MIN (leftover, max_name);
+ }
+
+ g_free (dir);
+
+ gnome_vfs_uri_unref (uri);
+
+ return max_length;
+}
+
+static int
handle_transfer_duplicate (GnomeVFSXferProgressInfo *progress_info,
TransferInfo *transfer_info)
{
+ int max_length;
+
+ max_length = get_max_name_length (progress_info->target_name);
+
switch (transfer_info->kind) {
case TRANSFER_LINK:
progress_info->duplicate_name = get_link_name
(progress_info->duplicate_name,
- progress_info->duplicate_count);
+ progress_info->duplicate_count,
+ max_length);
break;
case TRANSFER_COPY:
case TRANSFER_MOVE_TO_TRASH:
progress_info->duplicate_name = get_next_duplicate_name
(progress_info->duplicate_name,
- progress_info->duplicate_count);
+ progress_info->duplicate_count,
+ max_length);
break;
default:
break;
@@ -2722,47 +2860,47 @@
setlocale (LC_MESSAGES, "C");
/* test the next duplicate name generator */
- EEL_CHECK_STRING_RESULT (get_duplicate_name (" (copy)", 1), " (another copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo", 1), "foo (copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name (".bashrc", 1), ".bashrc (copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name (".foo.txt", 1), ".foo (copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo", 1), "foo foo (copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo.txt", 1), "foo (copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt", 1), "foo foo (copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt txt", 1), "foo foo (copy).txt txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...txt", 1), "foo (copy)...txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...", 1), "foo (copy)...");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo. (copy)", 1), "foo. (another copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy)", 1), "foo (another copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy).txt", 1), "foo (another copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy)", 1), "foo (3rd copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy).txt", 1), "foo (3rd copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (another copy).txt", 1), "foo foo (3rd copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy)", 1), "foo (14th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy).txt", 1), "foo (14th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy)", 1), "foo (22nd copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy).txt", 1), "foo (22nd copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy)", 1), "foo (23rd copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy).txt", 1), "foo (23rd copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy)", 1), "foo (24th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy).txt", 1), "foo (24th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy)", 1), "foo (25th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy).txt", 1), "foo (25th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy)", 1), "foo foo (25th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy).txt", 1), "foo foo (25th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (100000000000000th copy).txt", 1), "foo foo (copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy)", 1), "foo (11th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy).txt", 1), "foo (11th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy)", 1), "foo (12th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy).txt", 1), "foo (12th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy)", 1), "foo (13th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy).txt", 1), "foo (13th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy)", 1), "foo (111th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy).txt", 1), "foo (111th copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy)", 1), "foo (123rd copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy).txt", 1), "foo (123rd copy).txt");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy)", 1), "foo (124th copy)");
- EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy).txt", 1), "foo (124th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name (" (copy)", 1, -1), " (another copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo", 1, -1), "foo (copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name (".bashrc", 1, -1), ".bashrc (copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name (".foo.txt", 1, -1), ".foo (copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo", 1, -1), "foo foo (copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo.txt", 1, -1), "foo (copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt", 1, -1), "foo foo (copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt txt", 1, -1), "foo foo (copy).txt txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...txt", 1, -1), "foo (copy)...txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...", 1, -1), "foo (copy)...");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo. (copy)", 1, -1), "foo. (another copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy)", 1, -1), "foo (another copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy).txt", 1, -1), "foo (another copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy)", 1, -1), "foo (3rd copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy).txt", 1, -1), "foo (3rd copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (another copy).txt", 1, -1), "foo foo (3rd copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy)", 1, -1), "foo (14th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy).txt", 1, -1), "foo (14th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy)", 1, -1), "foo (22nd copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy).txt", 1, -1), "foo (22nd copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy)", 1, -1), "foo (23rd copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy).txt", 1, -1), "foo (23rd copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy)", 1, -1), "foo (24th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy).txt", 1, -1), "foo (24th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy)", 1, -1), "foo (25th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy).txt", 1, -1), "foo (25th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy)", 1, -1), "foo foo (25th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy).txt", 1, -1), "foo foo (25th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (100000000000000th copy).txt", 1, -1), "foo foo (copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy)", 1, -1), "foo (11th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy).txt", 1, -1), "foo (11th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy)", 1, -1), "foo (12th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy).txt", 1, -1), "foo (12th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy)", 1, -1), "foo (13th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy).txt", 1, -1), "foo (13th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy)", 1, -1), "foo (111th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy).txt", 1, -1), "foo (111th copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy)", 1, -1), "foo (123rd copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy).txt", 1, -1), "foo (123rd copy).txt");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy)", 1, -1), "foo (124th copy)");
+ EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy).txt", 1, -1), "foo (124th copy).txt");
setlocale (LC_MESSAGES, "");
}