[patch] support back-references when bulk renaming

Rogutes <[email protected]> Thu, 27 Nov 2008 21:35:55 +0200
Newsgroups gmane.comp.desktop.rox.devel
Message-ID <[email protected]>
Hello,

If my patch seems awkward (I hardly know C and just tried to mimic the
surrounding code), then this is a feature request.

I thought it would be nice to have back-references support in the bulk
renaming dialog, so one could, for example, type

Replace: "\(.*\) (\([0-9]\{4\}\))"
With: "[\2]: \1"

so Old:
title (1999).xxx
title (2000).yyy
title (1980).zzz

would become New:
[1999]: title.xxx
[2000]: title.yyy
[1980]: title.zzz

-- 
Regards,
RogutÄ—s

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

_______________________________________________
rox-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rox-devel
0001-Support-back-references-when-bulk-renaming.patch (text/plain, 4.2 KB)
>From 941fc65578285c6b3697ddcd67704844514f6489 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Rogut=C4=97s?= <[email protected]>
Date: Thu, 27 Nov 2008 21:07:45 +0200
Subject: [PATCH] Support back-references when bulk renaming.
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1.6.0.4"

This is a multi-part message in MIME format.
--------------1.6.0.4
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


Back references from \0 to \9 can be used in the "With:" field of the
bulk renaming dialog. Every back-reference is replaced by a captured
substring from the "Replace:" field.
As a side effect, \0, \1, ..., \9 become special characters and they
have to be escaped with an additional backslash (e.g. \\9), but only
if there is a corresponding substring.
---
 ROX-Filer/src/bulk_rename.c |   60 ++++++++++++++++++++++++++++++++++++------
 1 files changed, 51 insertions(+), 9 deletions(-)


--------------1.6.0.4
Content-Type: text/x-patch; name="941fc65578285c6b3697ddcd67704844514f6489.diff"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="941fc65578285c6b3697ddcd67704844514f6489.diff"

diff --git a/ROX-Filer/src/bulk_rename.c b/ROX-Filer/src/bulk_rename.c
index c733886..fa55202 100644
--- a/ROX-Filer/src/bulk_rename.c
+++ b/ROX-Filer/src/bulk_rename.c
@@ -113,7 +113,10 @@ void bulk_rename(const char *dir, GList *items)
 	gtk_tooltips_set_tip(tooltips, with_entry,
 			_("The first match in each filename will be replaced "
 			"by this string. "
-			"There are no special characters."), NULL);
+			"The only special characters are back-references from "
+			"\\0 to \\9, but only if there is a corresponding "
+			" captured non-empty substring. "
+			"Back-references can be escaped with a backslash."), NULL);
 
 	button = gtk_button_new_with_label(_("Apply"));
 	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
@@ -204,6 +207,7 @@ static void update_model(GtkListStore *list, regex_t *replace, const char *with)
 {
 	GtkTreeIter iter;
 	GtkTreeModel *model = (GtkTreeModel *) list;
+	int max_subs = 9;
 	int n_matched = 0;
 	int n_changed = 0;
 	int with_len;
@@ -218,26 +222,63 @@ static void update_model(GtkListStore *list, regex_t *replace, const char *with)
 
 	do
 	{
-		regmatch_t match;
+		regmatch_t match[max_subs];
 		char *old = NULL;
 
 		gtk_tree_model_get(model, &iter, 1, &old, -1);
 
-		if (regexec(replace, old, 1, &match, 0) == 0)
+		if (regexec(replace, old, max_subs, match, 0) == 0)
 		{
 			char *new;
+			char *with_exp;
 			int new_len;
+			int with_exp_len = with_len;
+			int slide = 0;
+
+			with_exp = g_malloc(with_len);
+			strcpy(with_exp, with);
 
 			n_matched++;
-			g_return_if_fail(match.rm_so != -1);
+			g_return_if_fail(match[0].rm_so != -1);
+
+			int i;
+			for (i = 0; i < with_len; i++)
+			{
+				if (with[i] == '\\' && with[i+1] >= '0' && with[i+1]-'0' <= max_subs)
+				{
+					int subpat = with[i+1]-'0';
+					int exp_len = match[subpat].rm_eo - match[subpat].rm_so;
+
+					if (exp_len > 0 && (i == 0 || with[i-1] != '\\'))
+					{
+						with_exp_len = strlen(with_exp) + exp_len - 1;
+
+						with_exp = g_realloc(with_exp, with_exp_len);
+
+						strncpy(with_exp + i + slide, old + match[subpat].rm_so, exp_len);
+						strcpy(with_exp + i + slide + exp_len, with + i + 2);
+
+						g_return_if_fail(with_exp[with_exp_len - 1] == '\0');
+
+						if ((exp_len) == 1)
+							slide--;
+						else
+							slide += exp_len - 2;
+
+						i++;
+					}
+				}
+			}
+			with_exp_len = strlen(with_exp);
+
+			new_len = match[0].rm_so + with_exp_len +
+				  (strlen(old) - match[0].rm_eo) + 1;
 
-			new_len = match.rm_so + with_len +
-				  (strlen(old) - match.rm_eo) + 1;
 			new = g_malloc(new_len);
 
-			strncpy(new, old, match.rm_so);
-			strcpy(new + match.rm_so, with);
-			strcpy(new + match.rm_so + with_len, old + match.rm_eo);
+			strncpy(new, old, match[0].rm_so);
+			strcpy(new + match[0].rm_so, with_exp);
+			strcpy(new + match[0].rm_so + with_exp_len, old + match[0].rm_eo);
 
 			g_return_if_fail(new[new_len - 1] == '\0');
 
@@ -248,6 +289,7 @@ static void update_model(GtkListStore *list, regex_t *replace, const char *with)
 			}
 
 			g_free(new);
+			g_free(with_exp);
 		}
 		g_free(old);
 

--------------1.6.0.4--