[RFC 3/5] cli: support shell globbing patterns in new.ignore

Subject: [RFC 3/5] cli: support shell globbing patterns in new.ignore

Date: Tue, 3 Nov 2015 21:49:31 +0200

To: notmuch@notmuchmail.org

Cc:

From: Jani Nikula


Keep the existing strcmp on the basename for backwards compatibility,
and additionally use the new.ignore entries as fnmatch(3) patterns on
the absolute filename. Note that it's not enough to add e.g. "foo*bar"
to the list; you will need to do "*/foo*bar" to match the path also.
---
 notmuch-new.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index da1d1be2ed3b..d06f9c906fc6 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -22,6 +22,7 @@
 #include "tag-util.h"
 
 #include <unistd.h>
+#include <fnmatch.h>
 
 typedef struct _filename_node {
     char *filename;
@@ -236,15 +237,31 @@ _entries_resemble_maildir (const char *path, struct dirent **entries, int count)
 /* Test if the file/directory is to be ignored.
  */
 static notmuch_bool_t
-_entry_in_ignore_list (const char *entry, add_files_state_t *state)
+_entry_in_ignore_list (const char *path, const char *entry,
+		       add_files_state_t *state)
 {
+    char *abspath;
+    notmuch_bool_t ret = FALSE;
     size_t i;
 
-    for (i = 0; i < state->new_ignore_length; i++)
-	if (strcmp (entry, state->new_ignore[i]) == 0)
-	    return TRUE;
+    if (state->new_ignore_length == 0)
+	return FALSE;
+
+    abspath = talloc_asprintf (NULL, "%s/%s", path, entry);
+    if (! abspath)
+	return FALSE;
 
-    return FALSE;
+    for (i = 0; i < state->new_ignore_length; i++) {
+	if (strcmp (entry, state->new_ignore[i]) == 0 ||
+	    fnmatch (state->new_ignore[i], abspath, 0) == 0) {
+	    ret = TRUE;
+	    break;
+	}
+    }
+
+    talloc_free (abspath);
+
+    return ret;
 }
 
 /* Add a single file to the database. */
@@ -443,7 +460,7 @@ add_files (notmuch_database_t *notmuch,
 	 * and because we don't care if dirent_type fails on entries
 	 * that are explicitly ignored.
 	 */
-	if (_entry_in_ignore_list (entry->d_name, state)) {
+	if (_entry_in_ignore_list (path, entry->d_name, state)) {
 	    if (state->debug)
 		printf ("(D) add_files, pass 1: explicitly ignoring %s/%s\n",
 			path, entry->d_name);
@@ -511,7 +528,7 @@ add_files (notmuch_database_t *notmuch,
         entry = fs_entries[i];
 
 	/* Ignore files & directories user has configured to be ignored */
-	if (_entry_in_ignore_list (entry->d_name, state)) {
+	if (_entry_in_ignore_list (path, entry->d_name, state)) {
 	    if (state->debug)
 		printf ("(D) add_files, pass 2: explicitly ignoring %s/%s\n",
 			path, entry->d_name);
@@ -744,7 +761,7 @@ count_files (const char *path, int *count, add_files_state_t *state)
 	/* Ignore any files/directories the user has configured to be
 	 * ignored
 	 */
-	if (_entry_in_ignore_list (entry->d_name, state)) {
+	if (_entry_in_ignore_list (path, entry->d_name, state)) {
 	    if (state->debug)
 		printf ("(D) count_files: explicitly ignoring %s/%s\n",
 			path, entry->d_name);
-- 
2.1.4


Thread: