[PATCH] Add a few tests for searching LWN emails.
On Fri, 28 Jan 2011 15:17:54 -0700, Jake Edge wrote: > Hi Carl and Thomas, > > On Sat, 29 Jan 2011 05:59:38 +1000 Carl Worth wrote: > > > Yes, I believe this is related to the dot in the name. From my > > recollection a name with an address requires quoting. So the header > > that is currently formatted as: > > > > From: LWN.net Weekly Notification > > > > should instead be: > > > > From: "LWN.net Weekly Notification" > > I am by no means an expert, but http://www.ietf.org/rfc/rfc2821.txt > would seem to indicate that names with a '.' in them don't need to be > quoted as there are several lines in the Scenarios section that look > like: > > C: From: John Q. Public > > unless the problem is XXX.yyy (i.e. no spaces on either side of the > '.'), but that seems like a pretty arbitrary differentiator (i.e. 'Q. ' > is fine, but 'LWN.net' isn't) The syntax is defined in http://www.faqs.org/rfcs/rfc2822.html in particular section 3.2.4. From that it appears the unquoted use of [a-Z][.a-Z]* is valid. However, I shall leave the intricacies to those whose understand and appreciate the whole problem... -Chris -- Chris Wilson, Intel Open Source Technology Centre
Re: [PATCH] Add a few tests for searching LWN emails.
On Fri, 28 Jan 2011 15:17:54 -0700, Jake Edge j...@lwn.net wrote: Hi Carl and Thomas, On Sat, 29 Jan 2011 05:59:38 +1000 Carl Worth wrote: Yes, I believe this is related to the dot in the name. From my recollection a name with an address requires quoting. So the header that is currently formatted as: From: LWN.net Weekly Notification l...@lwn.net should instead be: From: LWN.net Weekly Notification l...@lwn.net I am by no means an expert, but http://www.ietf.org/rfc/rfc2821.txt would seem to indicate that names with a '.' in them don't need to be quoted as there are several lines in the Scenarios section that look like: C: From: John Q. Public j...@bar.com unless the problem is XXX.yyy (i.e. no spaces on either side of the '.'), but that seems like a pretty arbitrary differentiator (i.e. 'Q. ' is fine, but 'LWN.net' isn't) The syntax is defined in http://www.faqs.org/rfcs/rfc2822.html in particular section 3.2.4. From that it appears the unquoted use of [a-Z][.a-Z]* is valid. However, I shall leave the intricacies to those whose understand and appreciate the whole problem... -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] Makefile: specify libnotmuch.so location with -rpath
In order to handle installation into user directories, it is convenient to encode the library location into the search path for the notmuch executable. This is achieved for the GNU linker with the -rpath argument. --- Makefile.local |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.local b/Makefile.local index 5bb570b..77d2c45 100644 --- a/Makefile.local +++ b/Makefile.local @@ -31,7 +31,7 @@ GPG_FILE=$(SHA1_FILE).asc # Smash together user's values with our extra values FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CFLAGS) $(WARN_CFLAGS) $(CONFIGURE_CFLAGS) $(extra_cflags) FINAL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(CONFIGURE_CXXFLAGS) $(extra_cflags) $(extra_cxxflags) -FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Llib -lnotmuch +FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Wl,-rpath=$(prefix)/lib -Llib -lnotmuch FINAL_NOTMUCH_LINKER = CC ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1) FINAL_NOTMUCH_LDFLAGS += $(CONFIGURE_LDFLAGS) -- 1.7.0.5
[PATCH] Makefile: specify libnotmuch.so location with -rpath
In order to handle installation into user directories, it is convenient to encode the library location into the search path for the notmuch executable. This is achieved for the GNU linker with the -rpath argument. --- Makefile.local |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.local b/Makefile.local index 5bb570b..77d2c45 100644 --- a/Makefile.local +++ b/Makefile.local @@ -31,7 +31,7 @@ GPG_FILE=$(SHA1_FILE).asc # Smash together user's values with our extra values FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CFLAGS) $(WARN_CFLAGS) $(CONFIGURE_CFLAGS) $(extra_cflags) FINAL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(CONFIGURE_CXXFLAGS) $(extra_cflags) $(extra_cxxflags) -FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Llib -lnotmuch +FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Wl,-rpath=$(prefix)/lib -Llib -lnotmuch FINAL_NOTMUCH_LINKER = CC ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1) FINAL_NOTMUCH_LDFLAGS += $(CONFIGURE_LDFLAGS) -- 1.7.0.5 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[notmuch] [PATCH] [RFC] notmuch search: Return a non-zero exitcode if the search returns no hits.
If the user is explicitly searching for a message, then if notmuch fails to find it, it is useful to set a failure exit code. This makes it easier for scripting. However, we will want to then distinguish between fatal errors (such as out-of-memory, invalid arguments, corrupt db, etc) from the simple no message. To that end, we introduce a set of enumerated exit-codes which may prove useful to use consistently across notmuch. (I'm not that convinced highly differentiated errors is particularly useful, though separate CONFIG_ERROR and DATABASE_ERROR would seem to have value for scripts.) --- notmuch-search.c | 34 -- 1 files changed, 24 insertions(+), 10 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index dc44eb6..6ca903b 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -20,7 +20,17 @@ #include "notmuch-client.h" -static void +/* XXX After some review, make these universal? */ +enum { +NOTMUCH_EXIT_SUCCESS = 0, +NOTMUCH_EXIT_NOT_FOUND, +NOTMUCH_EXIT_INVALID_ARGUMENT, +NOTMUCH_EXIT_SYSTEM_ERROR, /* XXX just out-of-memory? */ +NOTMUCH_EXIT_CONFIG_ERROR, +NOTMUCH_EXIT_DATABASE_ERROR, +}; + +static int do_search_threads (const void *ctx, notmuch_query_t *query, notmuch_sort_t sort) @@ -30,6 +40,7 @@ do_search_threads (const void *ctx, notmuch_tags_t *tags; time_t date; const char *relative_date; +int count = 0; for (threads = notmuch_query_search_threads (query); notmuch_threads_has_more (threads); @@ -67,7 +78,10 @@ do_search_threads (const void *ctx, printf (")\n"); notmuch_thread_destroy (thread); + count++; } + +return count; } int @@ -94,11 +108,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) sort = NOTMUCH_SORT_NEWEST_FIRST; } else { fprintf (stderr, "Invalid value for --sort: %s\n", opt); - return 1; + return NOTMUCH_EXIT_INVALID_ARGUMENT; } } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); - return 1; + return NOTMUCH_EXIT_INVALID_ARGUMENT; } } @@ -107,35 +121,35 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) - return 1; + return NOTMUCH_EXIT_CONFIG_ERROR; notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) - return 1; + return NOTMUCH_EXIT_DATABASE_ERROR; query_str = query_string_from_args (ctx, argc, argv); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return NOTMUCH_EXIT_SYSTEM_ERROR; } if (*query_str == '\0') { fprintf (stderr, "Error: notmuch search requires at least one search term.\n"); - return 1; + return NOTMUCH_EXIT_INVALID_ARGUMENT; } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return NOTMUCH_EXIT_SYSTEM_ERROR; } notmuch_query_set_sort (query, sort); -do_search_threads (ctx, query, sort); +i = do_search_threads (ctx, query, sort); notmuch_query_destroy (query); notmuch_database_close (notmuch); -return 0; +return i ? NOTMUCH_EXIT_SUCCESS : NOTMUCH_EXIT_NOT_FOUND; } -- 1.6.6
[notmuch] [PATCH] [RFC] notmuch search: Return a non-zero exitcode if the search returns no hits.
If the user is explicitly searching for a message, then if notmuch fails to find it, it is useful to set a failure exit code. This makes it easier for scripting. However, we will want to then distinguish between fatal errors (such as out-of-memory, invalid arguments, corrupt db, etc) from the simple no message. To that end, we introduce a set of enumerated exit-codes which may prove useful to use consistently across notmuch. (I'm not that convinced highly differentiated errors is particularly useful, though separate CONFIG_ERROR and DATABASE_ERROR would seem to have value for scripts.) --- notmuch-search.c | 34 -- 1 files changed, 24 insertions(+), 10 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index dc44eb6..6ca903b 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -20,7 +20,17 @@ #include notmuch-client.h -static void +/* XXX After some review, make these universal? */ +enum { +NOTMUCH_EXIT_SUCCESS = 0, +NOTMUCH_EXIT_NOT_FOUND, +NOTMUCH_EXIT_INVALID_ARGUMENT, +NOTMUCH_EXIT_SYSTEM_ERROR, /* XXX just out-of-memory? */ +NOTMUCH_EXIT_CONFIG_ERROR, +NOTMUCH_EXIT_DATABASE_ERROR, +}; + +static int do_search_threads (const void *ctx, notmuch_query_t *query, notmuch_sort_t sort) @@ -30,6 +40,7 @@ do_search_threads (const void *ctx, notmuch_tags_t *tags; time_t date; const char *relative_date; +int count = 0; for (threads = notmuch_query_search_threads (query); notmuch_threads_has_more (threads); @@ -67,7 +78,10 @@ do_search_threads (const void *ctx, printf ()\n); notmuch_thread_destroy (thread); + count++; } + +return count; } int @@ -94,11 +108,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) sort = NOTMUCH_SORT_NEWEST_FIRST; } else { fprintf (stderr, Invalid value for --sort: %s\n, opt); - return 1; + return NOTMUCH_EXIT_INVALID_ARGUMENT; } } else { fprintf (stderr, Unrecognized option: %s\n, argv[i]); - return 1; + return NOTMUCH_EXIT_INVALID_ARGUMENT; } } @@ -107,35 +121,35 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) - return 1; + return NOTMUCH_EXIT_CONFIG_ERROR; notmuch = notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY); if (notmuch == NULL) - return 1; + return NOTMUCH_EXIT_DATABASE_ERROR; query_str = query_string_from_args (ctx, argc, argv); if (query_str == NULL) { fprintf (stderr, Out of memory.\n); - return 1; + return NOTMUCH_EXIT_SYSTEM_ERROR; } if (*query_str == '\0') { fprintf (stderr, Error: notmuch search requires at least one search term.\n); - return 1; + return NOTMUCH_EXIT_INVALID_ARGUMENT; } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, Out of memory\n); - return 1; + return NOTMUCH_EXIT_SYSTEM_ERROR; } notmuch_query_set_sort (query, sort); -do_search_threads (ctx, query, sort); +i = do_search_threads (ctx, query, sort); notmuch_query_destroy (query); notmuch_database_close (notmuch); -return 0; +return i ? NOTMUCH_EXIT_SUCCESS : NOTMUCH_EXIT_NOT_FOUND; } -- 1.6.6 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[notmuch] semi-usable notmuch-gtk client
On Mon, 07 Dec 2009 09:57:12 -0800, Carl Worth wrote: > On Mon, 07 Dec 2009 16:42:42 +0530, "Aneesh Kumar K. V" linux.vnet.ibm.com> wrote: > > While discussing notmuch with some of the gnome developers they pointed > > me to http://live.gnome.org/Anjal/ . The interface is suited to the way > > notmuch displays threads. So i guess it would really cool if we can get > > anjal to use nomuch as one of the backend. > > > > That should also make sure you get a working mailclient in gtk with > > minimal changes > > Thanks for mentioning this, Aneesh. > > Hooking up Anjal to notmuch was an idea that Chris Wilson had almost > immediately after playing with notmuch. I think he even started poking > around in the Anjal code base to see how much work this would be. > > Chris, did you make any progress worth mentioning in your > investigations? Before being distracted again, the impression I got from reading Anjal was that to integrate with it, you needed to understand evolution-data-server and camel. Anjal itself seems to be a relatively thin message/folder viewer and composer, with the details hidden behind camel. So the next step, I felt, would be to see whether you could write a notmuch data store for evolution. -ickle -- Chris Wilson, Intel Open Source Technology Centre
Re: [notmuch] semi-usable notmuch-gtk client
On Mon, 07 Dec 2009 09:57:12 -0800, Carl Worth cwo...@cworth.org wrote: On Mon, 07 Dec 2009 16:42:42 +0530, Aneesh Kumar K. V aneesh.ku...@linux.vnet.ibm.com wrote: While discussing notmuch with some of the gnome developers they pointed me to http://live.gnome.org/Anjal/ . The interface is suited to the way notmuch displays threads. So i guess it would really cool if we can get anjal to use nomuch as one of the backend. That should also make sure you get a working mailclient in gtk with minimal changes Thanks for mentioning this, Aneesh. Hooking up Anjal to notmuch was an idea that Chris Wilson had almost immediately after playing with notmuch. I think he even started poking around in the Anjal code base to see how much work this would be. Chris, did you make any progress worth mentioning in your investigations? Before being distracted again, the impression I got from reading Anjal was that to integrate with it, you needed to understand evolution-data-server and camel. Anjal itself seems to be a relatively thin message/folder viewer and composer, with the details hidden behind camel. So the next step, I felt, would be to see whether you could write a notmuch data store for evolution. -ickle -- Chris Wilson, Intel Open Source Technology Centre ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[notmuch] [PATCH] notmuch-new: Eliminate tallocs whilst construct filenames.
Excerpts from Carl Worth's message of Fri Nov 27 13:23:06 + 2009: > On Sun, 22 Nov 2009 00:57:10 +0000, Chris Wilson chris-wilson.co.uk> wrote: > > The majority of filenames will fit within PATH_MAX [4096] (because > > that's a hard limit imposed by the filesystems) so we can avoid an > > allocation per lookup and thereby eliminate a large proportion of the > > overhead of scanning a maildir. > > Hi Chris, > > I *know* I composed a reply to this message earlier, but apparently > you're right that it never went out. (*sigh*---if only I had a reliable > mail client[*]). I hear there's one called sup... ;-) > Anyway, on to the promised review of the patch: > > The basic idea of this I really like, of course. Thanks for helping to > improve the efficiency of notmuch. But this part I don't: It's a bit outdated now, the impact of the asprintf overhead is lost with the introduction of the scandir. I'm sure the profiles will indicate something else to improve beyond xapian... > One might argue that the error-cleanup goto is a common and > well-understood idiom, so that it's not bad to have. The problem I have > with it is how much work it is to verify. If I'm reading one line of > code in the middle of a function that's testing for an error case and > handling it with goto, then I need to: > > 1. Verify this condition, and that a return value variable gets >set. > > 2. Check down at the end of the function to ensure the correct >objects are freed and the correct return value is returned. > > 3. Check back up at the beginning of the function to ensure the >relevant objects are initialized to NULL. > > And beyond verification, one has to code in these three places > simultaneously as well. > > Meanwhile, by taking advantage of talloc like I did in the original > version of this code, an error return becomes a much more local decision > and is much simpler to code. The issue I see with the "error, continue" pattern is that we are in danger of not reporting the first error but the last one. The common practice is abort on error and cleanup, and this single instance is inconsistent with the rest of the error handling everywhere else in notmuch-new.c. The argument to counter your 3 points is the unified unwind approach where there is just a single exit path that handles both error and normal returns. (You always have to set the appropriate error value whether you continue or abort.) The advantage of talloc is that it provides a convenient allocation context that not only groups object by their associated lifetimes, but provides a single point of access for reaping allocations on unwind. I don't see how talloc affects the decision process on how to actually handle errors, but it does make it easier to cleanup afterwards. Is notmuch ready for fault-injection yet? Maybe once you have a nasty testsuite... -ickle -- Chris Wilson, Intel Open Source Technology Centre
[notmuch] [PATCH] notmuch-new: Check for non-fatal errors from stat()
Currently we assume that all errors on stat() a dname is fatal (but continue anyway and report the error at the end). However, some errors reported by stat() such as a missing file or insufficient privilege, we can simply ignore and skip the file. For the others, such as a fault (unlikely!) or out-of-memory, we handle like the other fatal errors by jumping to the end. Signed-off-by: Chris Wilson --- notmuch-new.c | 13 - 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index 3cde3a7..71224c5 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -168,10 +168,21 @@ add_files_recursive (notmuch_database_t *notmuch, next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name); if (stat (next, st)) { + int err = errno; + + switch (err) { + case ENOENT: + /* The file was removed between scandir and now... */ + case EPERM: + case EACCES: + /* We can't read this file so don't add it to the cache. */ + continue; + } + fprintf (stderr, "Error reading %s: %s\n", next, strerror (errno)); ret = NOTMUCH_STATUS_FILE_ERROR; - continue; + goto DONE; } if (S_ISREG (st->st_mode)) { -- 1.6.5.3
[notmuch] [PATCH] notmuch-new: Remove the tiresome joke from the output.
As I see this every time I poll for new mail, the joke becomes very old very quickly. The other instances of "not much" are shown much less often and have a much more natural style, this one however feels forced, impairing the humorous effect. Signed-off-by: Chris "the critic" Wilson --- notmuch-new.c |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index e32b92a..3cde3a7 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -483,12 +483,10 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) } } if (add_files_state.added_messages) { - printf ("Added %d new %s to the database (not much, really).\n", + printf ("Added %d new %s to the database.\n", add_files_state.added_messages, add_files_state.added_messages == 1 ? "message" : "messages"); -} else { - printf ("No new mail---and that's not much.\n"); } if (elapsed > 1 && ! add_files_state.saw_read_only_directory) { -- 1.6.5.3
[notmuch] [PATCH] notmuch-new: Eliminate tallocs whilst construct filenames.
The majority of filenames will fit within PATH_MAX [4096] (because that's a hard limit imposed by the filesystems) so we can avoid an allocation per lookup and thereby eliminate a large proportion of the overhead of scanning a maildir. Signed-off-by: Chris Wilson --- notmuch-new.c | 75 ++-- 1 files changed, 45 insertions(+), 30 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index 0dd2784..13559d1 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -107,6 +107,7 @@ add_files_recursive (notmuch_database_t *notmuch, add_files_state_t *state) { DIR *dir = NULL; +char buf[4096]; struct dirent *entry = NULL; char *next = NULL; time_t path_mtime, path_dbtime; @@ -114,6 +115,7 @@ add_files_recursive (notmuch_database_t *notmuch, notmuch_message_t *message = NULL; struct dirent **namelist = NULL; int num_entries; +int path_len, dname_len; /* If we're told to, we bail out on encountering a read-only * directory, (with this being a clear clue from the user to @@ -140,6 +142,12 @@ add_files_recursive (notmuch_database_t *notmuch, int i=0; +path_len = strlen (path); +if (path_len + 2 < (int) sizeof (buf)) { + memcpy (buf, path, path_len); + buf[path_len] = '/'; +} + while (!interrupted) { if (i == num_entries) break; @@ -164,37 +172,42 @@ add_files_recursive (notmuch_database_t *notmuch, continue; } - next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name); + dname_len = strlen (entry->d_name); + if (path_len + dname_len + 2 < (int) sizeof (buf)) { + memcpy (buf + path_len + 1, entry->d_name, dname_len); + buf[path_len + dname_len + 1] = '\0'; + next = buf; + } else { + next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name); + } if (stat (next, st)) { fprintf (stderr, "Error reading %s: %s\n", next, strerror (errno)); ret = NOTMUCH_STATUS_FILE_ERROR; - continue; - } - - if (S_ISREG (st->st_mode)) { - /* If the file hasn't been modified since the last -* add_files, then we need not look at it. */ - if (path_dbtime == 0 || st->st_mtime > path_dbtime) { - state->processed_files++; - - status = notmuch_database_add_message (notmuch, next, ); - switch (status) { - /* success */ + } else { + if (S_ISREG (st->st_mode)) { + /* If the file hasn't been modified since the last +* add_files, then we need not look at it. */ + if (path_dbtime == 0 || st->st_mtime > path_dbtime) { + state->processed_files++; + + status = notmuch_database_add_message (notmuch, next, ); + switch (status) { + /* success */ case NOTMUCH_STATUS_SUCCESS: state->added_messages++; tag_inbox_and_unread (message); break; - /* Non-fatal issues (go on to next file) */ + /* Non-fatal issues (go on to next file) */ case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: - /* Stay silent on this one. */ + /* Stay silent on this one. */ break; case NOTMUCH_STATUS_FILE_NOT_EMAIL: fprintf (stderr, "Note: Ignoring non-mail file: %s\n", next); break; - /* Fatal issues. Don't process anymore. */ + /* Fatal issues. Don't process anymore. */ case NOTMUCH_STATUS_READONLY_DATABASE: case NOTMUCH_STATUS_XAPIAN_EXCEPTION: case NOTMUCH_STATUS_OUT_OF_MEMORY: @@ -210,25 +223,27 @@ add_files_recursive (notmuch_database_t *notmuch, case NOTMUCH_STATUS_LAST_STATUS: INTERNAL_ERROR ("add_message returned unexpected value: %d", status); goto DONE; - } + } - if (message) { - notmuch_message_destroy (message); - message = NULL; - } + if (message) { + notmuch_message_destroy (message); + message = NULL; + } - if (do_add_files_print_progress) { - do_add_files_print_progress = 0; - add_files_print_progress (state); + if (do_add_files_print_progress) { +
[notmuch] [PATCH 2/2] notmuch-new: Only print the regular progress report when on a tty
Check that the stdout is connected to an interactive terminal with isatty() before installing the periodic timer to print progress reports. Signed-off-by: Chris Wilson --- notmuch-new.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/notmuch-new.c b/notmuch-new.c index 1616ee9..0dd2784 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -20,6 +20,8 @@ #include "notmuch-client.h" +#include + static volatile sig_atomic_t do_add_files_print_progress = 0; static void @@ -273,7 +275,7 @@ add_files (notmuch_database_t *notmuch, } /* Setup our handler for SIGALRM */ -if (! debugger_is_active ()) { +if (isatty (fileno (stdout)) && ! debugger_is_active ()) { memset (, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigalrm; sigemptyset (_mask); -- 1.6.5.3
[notmuch] [PATCH 1/2] notmuch-new: Only install SIGALRM if not running under gdb
I felt sorry for Carl trying to step through an exception from xapian and suffering from the SIGALARMs.. We can detect if the user launched notmuch under a debugger by either checking our cmdline for the presence of the gdb string or querying if valgrind is controlling our process. For the latter we need to add a compile time check for the valgrind development library, and so add the initial support to build Makefile.config from configure. Signed-off-by: Chris Wilson Reviewed-by: Carl Worth [ickle: And do not install the timer when under the debugger] --- Makefile.config |1 + Makefile.local |3 ++- configure| 21 + debugger.c | 47 +++ notmuch-client.h |3 +++ notmuch-new.c| 49 - 6 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 debugger.c diff --git a/Makefile.config b/Makefile.config index d72a39e..ddc7436 100644 --- a/Makefile.config +++ b/Makefile.config @@ -1,2 +1,3 @@ prefix = /usr/local bash_completion_dir = /etc/bash_completion.d +CFLAGS += -DHAVE_VALGRIND diff --git a/Makefile.local b/Makefile.local index 3c99624..efe76c8 100644 --- a/Makefile.local +++ b/Makefile.local @@ -3,6 +3,8 @@ all: notmuch notmuch.1.gz emacs: notmuch.elc notmuch_client_srcs = \ + debugger.c \ + gmime-filter-reply.c\ notmuch.c \ notmuch-config.c\ notmuch-dump.c \ @@ -14,7 +16,6 @@ notmuch_client_srcs = \ notmuch-show.c \ notmuch-tag.c \ notmuch-time.c \ - gmime-filter-reply.c\ query-string.c \ show-message.c diff --git a/configure b/configure index fe46c8e..b4770ec 100755 --- a/configure +++ b/configure @@ -53,6 +53,14 @@ else errors=$((errors + 1)) fi +if pkg-config --modversion valgrind > /dev/null 2>&1; then +echo "Checking for valgrind development files... Yes." +have_valgrind=-DHAVE_VALGRIND +else +echo "Checking for valgrind development files... No." +have_valgrind= +fi + if [ $errors -gt 0 ]; then cat < Makefile.config <http://www.gnu.org/licenses/ . + * + * Author: Chris Wilson + */ + +#include "notmuch-client.h" + +#include + +#if HAVE_VALGRIND +#include +#else +#define RUNNING_ON_VALGRIND 0 +#endif + +notmuch_bool_t +debugger_is_active (void) +{ +char buf[1024]; + +if (RUNNING_ON_VALGRIND) + return TRUE; + +sprintf (buf, "/proc/%d/exe", getppid ()); +if (readlink (buf, buf, sizeof (buf)) != -1 && + strncmp (basename (buf), "gdb", 3) == 0) +{ + return TRUE; +} + +return FALSE; +} diff --git a/notmuch-client.h b/notmuch-client.h index b65aa77..ea77686 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -179,4 +179,7 @@ notmuch_config_set_user_other_email (notmuch_config_t *config, const char *other_email[], size_t length); +notmuch_bool_t +debugger_is_active (void); + #endif diff --git a/notmuch-new.c b/notmuch-new.c index 43cc4fb..1616ee9 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -259,6 +259,7 @@ add_files (notmuch_database_t *notmuch, notmuch_status_t status; struct sigaction action; struct itimerval timerval; +notmuch_bool_t timer_is_active = FALSE; if (stat (path, )) { fprintf (stderr, "Error reading directory %s: %s\n", @@ -272,31 +273,37 @@ add_files (notmuch_database_t *notmuch, } /* Setup our handler for SIGALRM */ -memset (, 0, sizeof (struct sigaction)); -action.sa_handler = handle_sigalrm; -sigemptyset (_mask); -action.sa_flags = SA_RESTART; -sigaction (SIGALRM, , NULL); - -/* Then start a timer to send SIGALRM once per second. */ -timerval.it_interval.tv_sec = 1; -timerval.it_interval.tv_usec = 0; -timerval.it_value.tv_sec = 1; -timerval.it_value.tv_usec = 0; -setitimer (ITIMER_REAL, , NULL); +if (! debugger_is_active ()) { + memset (, 0, sizeof (struct sigaction)); + action.sa_handler = handle_sigalrm; + sigemptyset (_mask); + action.sa_flags = SA_RESTART; + sigaction (SIGALRM, , NULL); + + /* Then start a timer to send SIGALRM once per second. */ + timerval.it_interval.tv_sec = 1; + timerval.it_interval.tv_usec = 0; + timerval.it_value.tv_sec = 1; + timerval.it_value.tv_usec = 0; + setitimer (ITIMER_REAL, , NULL); + + timer_is_active = TRUE; +} status = add_files_recursive (notmuch, path, , state); /* Now stop the timer. */ -timerval.it_interval.tv_sec = 0; -timerval.it_interval.tv_usec = 0; -timerval.it_value.tv_sec = 0; -timerval.it_value.tv_usec = 0; -setitimer (ITIMER_REAL, ,
[notmuch] Avoid installing SIGALRMs when under the debugger.
Gah, I'm tired and using "git send-email HEAD^" is too easy. Here is the most recent pair of patches in possibly a working state. -ickle
[notmuch] [PATCH] notmuch-new: Only install SIGALRM if not running under gdb
I felt sorry for Carl trying to step through an exception from xapian and suffering from the SIGALARMs.. We can detect if the user launched notmuch under a debugger by either checking our cmdline for the presence of the gdb string or querying if valgrind is controlling our process. For the latter we need to add a compile time check for the valgrind development library, and so add the initial support to build Makefile.config from configure. Signed-off-by: Chris Wilson Reviewed-by: Carl Worth [ickle: And do not install the timer] --- Makefile.config |1 + Makefile.local |3 ++- configure| 21 + debugger.c | 47 +++ notmuch-client.h |3 +++ notmuch-new.c| 12 +++- 6 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 debugger.c diff --git a/Makefile.config b/Makefile.config index d72a39e..ddc7436 100644 --- a/Makefile.config +++ b/Makefile.config @@ -1,2 +1,3 @@ prefix = /usr/local bash_completion_dir = /etc/bash_completion.d +CFLAGS += -DHAVE_VALGRIND diff --git a/Makefile.local b/Makefile.local index 3c99624..efe76c8 100644 --- a/Makefile.local +++ b/Makefile.local @@ -3,6 +3,8 @@ all: notmuch notmuch.1.gz emacs: notmuch.elc notmuch_client_srcs = \ + debugger.c \ + gmime-filter-reply.c\ notmuch.c \ notmuch-config.c\ notmuch-dump.c \ @@ -14,7 +16,6 @@ notmuch_client_srcs = \ notmuch-show.c \ notmuch-tag.c \ notmuch-time.c \ - gmime-filter-reply.c\ query-string.c \ show-message.c diff --git a/configure b/configure index fe46c8e..b4770ec 100755 --- a/configure +++ b/configure @@ -53,6 +53,14 @@ else errors=$((errors + 1)) fi +if pkg-config --modversion valgrind > /dev/null 2>&1; then +echo "Checking for valgrind development files... Yes." +have_valgrind=-DHAVE_VALGRIND +else +echo "Checking for valgrind development files... No." +have_valgrind= +fi + if [ $errors -gt 0 ]; then cat < Makefile.config <http://www.gnu.org/licenses/ . + * + * Author: Chris Wilson + */ + +#include "notmuch-client.h" + +#include + +#if HAVE_VALGRIND +#include +#else +#define RUNNING_ON_VALGRIND 0 +#endif + +notmuch_bool_t +debugger_is_active (void) +{ +char buf[1024]; + +if (RUNNING_ON_VALGRIND) + return TRUE; + +sprintf (buf, "/proc/%d/exe", getppid ()); +if (readlink (buf, buf, sizeof (buf)) != -1 && + strncmp (basename (buf), "gdb", 3) == 0) +{ + return TRUE; +} + +return FALSE; +} diff --git a/notmuch-client.h b/notmuch-client.h index b65aa77..ea77686 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -179,4 +179,7 @@ notmuch_config_set_user_other_email (notmuch_config_t *config, const char *other_email[], size_t length); +notmuch_bool_t +debugger_is_active (void); + #endif diff --git a/notmuch-new.c b/notmuch-new.c index 43cc4fb..18ba2bd 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -272,11 +272,13 @@ add_files (notmuch_database_t *notmuch, } /* Setup our handler for SIGALRM */ -memset (, 0, sizeof (struct sigaction)); -action.sa_handler = handle_sigalrm; -sigemptyset (_mask); -action.sa_flags = SA_RESTART; -sigaction (SIGALRM, , NULL); +if (! debugger_is_active ()) { + memset (, 0, sizeof (struct sigaction)); + action.sa_handler = handle_sigalrm; + sigemptyset (_mask); + action.sa_flags = SA_RESTART; + sigaction (SIGALRM, , NULL); +} /* Then start a timer to send SIGALRM once per second. */ timerval.it_interval.tv_sec = 1; -- 1.6.5.3
[notmuch] [PATCH] notmuch-new: Only install SIGALRM if not running under gdb
I felt sorry for Carl trying to step through an exception from xapian and suffering from the SIGALARMs.. We can detect if the user launched notmuch under a debugger by either checking our cmdline for the presence of the gdb string or querying if valgrind is controlling our process. For the latter we need to add a compile time check for the valgrind development library, and so add the initial support to build Makefile.config from configure. Signed-off-by: Chris Wilson Reviewed-by: Carl Worth --- Makefile.config |1 + Makefile.local |3 ++- configure| 21 + debugger.c | 47 +++ notmuch-client.h |3 +++ notmuch-new.c| 12 +++- 6 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 debugger.c diff --git a/Makefile.config b/Makefile.config index d72a39e..ddc7436 100644 --- a/Makefile.config +++ b/Makefile.config @@ -1,2 +1,3 @@ prefix = /usr/local bash_completion_dir = /etc/bash_completion.d +CFLAGS += -DHAVE_VALGRIND diff --git a/Makefile.local b/Makefile.local index 3c99624..efe76c8 100644 --- a/Makefile.local +++ b/Makefile.local @@ -3,6 +3,8 @@ all: notmuch notmuch.1.gz emacs: notmuch.elc notmuch_client_srcs = \ + debugger.c \ + gmime-filter-reply.c\ notmuch.c \ notmuch-config.c\ notmuch-dump.c \ @@ -14,7 +16,6 @@ notmuch_client_srcs = \ notmuch-show.c \ notmuch-tag.c \ notmuch-time.c \ - gmime-filter-reply.c\ query-string.c \ show-message.c diff --git a/configure b/configure index fe46c8e..b4770ec 100755 --- a/configure +++ b/configure @@ -53,6 +53,14 @@ else errors=$((errors + 1)) fi +if pkg-config --modversion valgrind > /dev/null 2>&1; then +echo "Checking for valgrind development files... Yes." +have_valgrind=-DHAVE_VALGRIND +else +echo "Checking for valgrind development files... No." +have_valgrind= +fi + if [ $errors -gt 0 ]; then cat < Makefile.config <http://www.gnu.org/licenses/ . + * + * Author: Chris Wilson + */ + +#include "notmuch-client.h" + +#include + +#if HAVE_VALGRIND +#include +#else +#define RUNNING_ON_VALGRIND 0 +#endif + +notmuch_bool_t +debugger_is_active (void) +{ +char buf[1024]; + +if (RUNNING_ON_VALGRIND) + return TRUE; + +sprintf (buf, "/proc/%d/exe", getppid ()); +if (readlink (buf, buf, sizeof (buf)) != -1 && + strncmp (basename (buf), "gdb", 3) == 0) +{ + return TRUE; +} + +return FALSE; +} diff --git a/notmuch-client.h b/notmuch-client.h index b65aa77..ea77686 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -179,4 +179,7 @@ notmuch_config_set_user_other_email (notmuch_config_t *config, const char *other_email[], size_t length); +notmuch_bool_t +debugger_is_active (void); + #endif diff --git a/notmuch-new.c b/notmuch-new.c index 43cc4fb..18ba2bd 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -272,11 +272,13 @@ add_files (notmuch_database_t *notmuch, } /* Setup our handler for SIGALRM */ -memset (, 0, sizeof (struct sigaction)); -action.sa_handler = handle_sigalrm; -sigemptyset (_mask); -action.sa_flags = SA_RESTART; -sigaction (SIGALRM, , NULL); +if (! debugger_is_active ()) { + memset (, 0, sizeof (struct sigaction)); + action.sa_handler = handle_sigalrm; + sigemptyset (_mask); + action.sa_flags = SA_RESTART; + sigaction (SIGALRM, , NULL); +} /* Then start a timer to send SIGALRM once per second. */ timerval.it_interval.tv_sec = 1; -- 1.6.5.3
[notmuch] [PATCH] lib/database.cc: coding style
Carl claims he must have been distracted when he wrote this... Signed-off-by: Chris Wilson --- lib/database.cc | 18 +++--- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 207246c..0f95aa1 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -147,17 +147,20 @@ _find_prefix (const char *name) { unsigned int i; -for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_INTERNAL); i++) +for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_INTERNAL); i++) { if (strcmp (name, BOOLEAN_PREFIX_INTERNAL[i].name) == 0) return BOOLEAN_PREFIX_INTERNAL[i].prefix; +} -for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) +for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) { if (strcmp (name, BOOLEAN_PREFIX_EXTERNAL[i].name) == 0) return BOOLEAN_PREFIX_EXTERNAL[i].prefix; +} -for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) +for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) { if (strcmp (name, PROBABILISTIC_PREFIX[i].name) == 0) return PROBABILISTIC_PREFIX[i].prefix; +} INTERNAL_ERROR ("No prefix exists for '%s'\n", name); @@ -293,13 +296,14 @@ skip_space_and_comments (const char **str) int nesting = 1; s++; while (*s && nesting) { - if (*s == '(') + if (*s == '(') { nesting++; - else if (*s == ')') + } else if (*s == ')') { nesting--; - else if (*s == '\\') + } else if (*s == '\\') { if (*(s+1)) s++; + } s++; } } @@ -508,7 +512,7 @@ notmuch_database_open (const char *path) error.get_msg().c_str()); notmuch = NULL; } - + DONE: if (notmuch_path) free (notmuch_path); -- 1.6.5.3
[notmuch] [PATCH] Makefile: Magic silent rules.
Use the facilities of GNU make to create a magic function that will on the first invocation print a description of how to enable verbose compile lines and then print the quiet rule. Signed-off-by: Chris Wilson Signed-off-by: Carl Worth Cc: Mikhail Gusarov [ickle: Rebased, and duplicate command string eliminated.] [ickle: Fixed verbose bug pointed out by Mikhail] --- Makefile | 23 --- Makefile.local |4 ++-- lib/Makefile.local |2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 3fedcf1..5d8f321 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ WARN_FLAGS=-Wall -Wextra -Wmissing-declarations -Wwrite-strings -Wswitch-enum CFLAGS=-O2 +# Additional programs that are used during the compilation process. +EMACS ?= emacs +GZIP ?= gzip + # Additional flags that we will append to whatever the user set. # These aren't intended for the user to manipulate. extra_cflags := $(shell pkg-config --cflags glib-2.0 gmime-2.4 talloc) @@ -31,14 +35,27 @@ include lib/Makefile.local # And get user settings from the output of configure include Makefile.config +# The user has not set any verbosity, default to quiet mode and inform the +# user how to enable verbose compiles. +ifeq ($(V),) +quiet_DOC := "Use \"$(MAKE) V=1\" to see the verbose compile lines.\n" +quiet = @echo $(quiet_DOC)$(eval quiet_DOC:=)" $1 $@"; $($1) +endif +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @echo " $1$@"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + %.o: %.cc $(all_deps) - $(CXX) -c $(CXXFLAGS) $< -o $@ + $(call quiet,CXX) -c $(CXXFLAGS) $< -o $@ %.o: %.c $(all_deps) - $(CC) -c $(CFLAGS) $< -o $@ + $(call quiet,CC) -c $(CFLAGS) $< -o $@ %.elc: %.el - emacs -batch -f batch-byte-compile $< + $(call quiet,EMACS) -batch -f batch-byte-compile $< .deps/%.d: %.c $(all_deps) @set -e; rm -f $@; mkdir -p $$(dirname $@) ; \ diff --git a/Makefile.local b/Makefile.local index 3c99624..5fd5d4f 100644 --- a/Makefile.local +++ b/Makefile.local @@ -20,10 +20,10 @@ notmuch_client_srcs = \ notmuch_client_modules = $(notmuch_client_srcs:.c=.o) notmuch: $(notmuch_client_modules) lib/notmuch.a - $(CXX) $^ $(LDFLAGS) -o $@ + $(call quiet,CXX) $^ $(LDFLAGS) -o $@ notmuch.1.gz: notmuch.1 - gzip --stdout notmuch.1 > notmuch.1.gz + $(call quiet,GZIP) --stdout $^ > $@ install: all notmuch.1.gz for d in $(DESTDIR)$(prefix)/bin/ $(DESTDIR)$(prefix)/share/man/man1 \ diff --git a/lib/Makefile.local b/lib/Makefile.local index 79f7b0b..a7562c9 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -18,7 +18,7 @@ libnotmuch_cxx_srcs = \ libnotmuch_modules = $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o) $(dir)/notmuch.a: $(libnotmuch_modules) - $(AR) rcs $@ $^ + $(call quiet,AR) rcs $@ $^ SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs) CLEAN := $(CLEAN) $(libnotmuch_modules) $(dir)/notmuch.a -- 1.6.5.3
[notmuch] [PATCH] Permit opening the notmuch database in read-only mode.
We only rarely need to actually open the database for writing, but we always create a Xapian::WritableDatabase. This has the effect of preventing searches and like whilst updating the index. Signed-off-by: Chris Wilson Acked-by: Carl Worth [ickle: Updated to add WRITABLE mode to notmuch-new] --- lib/database-private.h |3 ++- lib/database.cc| 31 --- lib/message.cc | 15 +-- lib/notmuch-private.h |1 + lib/notmuch.h | 13 +++-- notmuch-dump.c |3 ++- notmuch-new.c |4 +++- notmuch-reply.c|3 ++- notmuch-restore.c |3 ++- notmuch-search.c |3 ++- notmuch-show.c |3 ++- notmuch-tag.c |3 ++- 12 files changed, 66 insertions(+), 19 deletions(-) diff --git a/lib/database-private.h b/lib/database-private.h index 76e26ce..79c7916 100644 --- a/lib/database-private.h +++ b/lib/database-private.h @@ -27,7 +27,8 @@ struct _notmuch_database { char *path; -Xapian::WritableDatabase *xapian_db; +notmuch_database_mode_t mode; +Xapian::Database *xapian_db; Xapian::QueryParser *query_parser; Xapian::TermGenerator *term_gen; }; diff --git a/lib/database.cc b/lib/database.cc index 207246c..fb38664 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -172,6 +172,8 @@ notmuch_status_to_string (notmuch_status_t status) return "No error occurred"; case NOTMUCH_STATUS_OUT_OF_MEMORY: return "Out of memory"; +case NOTMUCH_STATUS_READONLY_DATABASE: + return "The database is read-only"; case NOTMUCH_STATUS_XAPIAN_EXCEPTION: return "A Xapian exception occurred"; case NOTMUCH_STATUS_FILE_ERROR: @@ -438,7 +440,8 @@ notmuch_database_create (const char *path) goto DONE; } -notmuch = notmuch_database_open (path); +notmuch = notmuch_database_open (path, +NOTMUCH_DATABASE_MODE_WRITABLE); DONE: if (notmuch_path) @@ -448,7 +451,8 @@ notmuch_database_create (const char *path) } notmuch_database_t * -notmuch_database_open (const char *path) +notmuch_database_open (const char *path, + notmuch_database_mode_t mode) { notmuch_database_t *notmuch = NULL; char *notmuch_path = NULL, *xapian_path = NULL; @@ -481,9 +485,14 @@ notmuch_database_open (const char *path) if (notmuch->path[strlen (notmuch->path) - 1] == '/') notmuch->path[strlen (notmuch->path) - 1] = '\0'; +notmuch->mode = mode; try { - notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path, - Xapian::DB_CREATE_OR_OPEN); + if (mode == NOTMUCH_DATABASE_MODE_WRITABLE) { + notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path, + Xapian::DB_CREATE_OR_OPEN); + } else { + notmuch->xapian_db = new Xapian::Database (xapian_path); + } notmuch->query_parser = new Xapian::QueryParser; notmuch->term_gen = new Xapian::TermGenerator; notmuch->term_gen->set_stemmer (Xapian::Stem ("english")); @@ -521,7 +530,8 @@ notmuch_database_open (const char *path) void notmuch_database_close (notmuch_database_t *notmuch) { -notmuch->xapian_db->flush (); +if (notmuch->mode == NOTMUCH_DATABASE_MODE_WRITABLE) + (static_cast (notmuch->xapian_db))->flush (); delete notmuch->term_gen; delete notmuch->query_parser; @@ -567,11 +577,18 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch, const char *key, time_t timestamp) { Xapian::Document doc; +Xapian::WritableDatabase *db; unsigned int doc_id; notmuch_private_status_t status; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; char *db_key = NULL; +if (notmuch->mode == NOTMUCH_DATABASE_MODE_READONLY) { + fprintf (stderr, "Attempted to update a read-only database.\n"); + return NOTMUCH_STATUS_READONLY_DATABASE; +} + +db = static_cast (notmuch->xapian_db); db_key = timestamp_db_key (key); try { @@ -586,9 +603,9 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch, doc.add_term (term); talloc_free (term); - notmuch->xapian_db->add_document (doc); + db->add_document (doc); } else { - notmuch->xapian_db->replace_document (doc_id, doc); + db->replace_document (doc_id, doc); } } catch (Xapian::Error ) { diff --git a/lib/message.cc b/lib/message.cc index e0b8a8e..7ba06c9 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -168,9 +168,15 @@ _notmuch_message_create_for_message_id (notmuch_database_t *notmuch, { notmuch_message
[notmuch] [PATCH] Permit opening the notmuch database in read-only mode.
We only rarely need to actually open the database for writing, but we always create a Xapian::WritableDatabase. This has the effect of preventing searches and like whilst updating the index. Signed-off-by: Chris Wilson Acked-by: Carl Worth --- lib/database-private.h |3 ++- lib/database.cc| 31 --- lib/message.cc | 15 +-- lib/notmuch-private.h |1 + lib/notmuch.h | 13 +++-- notmuch-dump.c |3 ++- notmuch-new.c |4 +++- notmuch-reply.c|3 ++- notmuch-restore.c |3 ++- notmuch-search.c |3 ++- notmuch-show.c |3 ++- notmuch-tag.c |3 ++- 12 files changed, 66 insertions(+), 19 deletions(-) diff --git a/lib/database-private.h b/lib/database-private.h index 76e26ce..79c7916 100644 --- a/lib/database-private.h +++ b/lib/database-private.h @@ -27,7 +27,8 @@ struct _notmuch_database { char *path; -Xapian::WritableDatabase *xapian_db; +notmuch_database_mode_t mode; +Xapian::Database *xapian_db; Xapian::QueryParser *query_parser; Xapian::TermGenerator *term_gen; }; diff --git a/lib/database.cc b/lib/database.cc index 207246c..fb38664 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -172,6 +172,8 @@ notmuch_status_to_string (notmuch_status_t status) return "No error occurred"; case NOTMUCH_STATUS_OUT_OF_MEMORY: return "Out of memory"; +case NOTMUCH_STATUS_READONLY_DATABASE: + return "The database is read-only"; case NOTMUCH_STATUS_XAPIAN_EXCEPTION: return "A Xapian exception occurred"; case NOTMUCH_STATUS_FILE_ERROR: @@ -438,7 +440,8 @@ notmuch_database_create (const char *path) goto DONE; } -notmuch = notmuch_database_open (path); +notmuch = notmuch_database_open (path, +NOTMUCH_DATABASE_MODE_WRITABLE); DONE: if (notmuch_path) @@ -448,7 +451,8 @@ notmuch_database_create (const char *path) } notmuch_database_t * -notmuch_database_open (const char *path) +notmuch_database_open (const char *path, + notmuch_database_mode_t mode) { notmuch_database_t *notmuch = NULL; char *notmuch_path = NULL, *xapian_path = NULL; @@ -481,9 +485,14 @@ notmuch_database_open (const char *path) if (notmuch->path[strlen (notmuch->path) - 1] == '/') notmuch->path[strlen (notmuch->path) - 1] = '\0'; +notmuch->mode = mode; try { - notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path, - Xapian::DB_CREATE_OR_OPEN); + if (mode == NOTMUCH_DATABASE_MODE_WRITABLE) { + notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path, + Xapian::DB_CREATE_OR_OPEN); + } else { + notmuch->xapian_db = new Xapian::Database (xapian_path); + } notmuch->query_parser = new Xapian::QueryParser; notmuch->term_gen = new Xapian::TermGenerator; notmuch->term_gen->set_stemmer (Xapian::Stem ("english")); @@ -521,7 +530,8 @@ notmuch_database_open (const char *path) void notmuch_database_close (notmuch_database_t *notmuch) { -notmuch->xapian_db->flush (); +if (notmuch->mode == NOTMUCH_DATABASE_MODE_WRITABLE) + (static_cast (notmuch->xapian_db))->flush (); delete notmuch->term_gen; delete notmuch->query_parser; @@ -567,11 +577,18 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch, const char *key, time_t timestamp) { Xapian::Document doc; +Xapian::WritableDatabase *db; unsigned int doc_id; notmuch_private_status_t status; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; char *db_key = NULL; +if (notmuch->mode == NOTMUCH_DATABASE_MODE_READONLY) { + fprintf (stderr, "Attempted to update a read-only database.\n"); + return NOTMUCH_STATUS_READONLY_DATABASE; +} + +db = static_cast (notmuch->xapian_db); db_key = timestamp_db_key (key); try { @@ -586,9 +603,9 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch, doc.add_term (term); talloc_free (term); - notmuch->xapian_db->add_document (doc); + db->add_document (doc); } else { - notmuch->xapian_db->replace_document (doc_id, doc); + db->replace_document (doc_id, doc); } } catch (Xapian::Error ) { diff --git a/lib/message.cc b/lib/message.cc index e0b8a8e..7ba06c9 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -168,9 +168,15 @@ _notmuch_message_create_for_message_id (notmuch_database_t *notmuch, { notmuch_message_t *message; Xapian::Document doc; +Xapian::Writ
[notmuch] [PATCH] Makefile: Magic silent rules.
Use the facilities of GNU make to create a magic function that will on the first invocation print a description of how to enable verbose compile lines and then print the quiet rule. Signed-off-by: Chris Wilson Signed-off-by: Carl Worth Cc: Mikhail Gusarov --- Makefile | 22 +++--- Makefile.local |4 ++-- lib/Makefile.local |2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 3fedcf1..77e70ed 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ WARN_FLAGS=-Wall -Wextra -Wmissing-declarations -Wwrite-strings -Wswitch-enum CFLAGS=-O2 +# Additional programs that are used during the compilation process. +EMACS ?= emacs +GZIP ?= gzip + # Additional flags that we will append to whatever the user set. # These aren't intended for the user to manipulate. extra_cflags := $(shell pkg-config --cflags glib-2.0 gmime-2.4 talloc) @@ -31,14 +35,26 @@ include lib/Makefile.local # And get user settings from the output of configure include Makefile.config +# The user has not set any verbosity, default to quiet mode and inform the +# user how to enable verbose compiles. +ifeq ($(V),) +quiet_DOC := "Use \"$(MAKE) V=1\" to see the verbose compile lines.\n" +quiet = @echo $(quiet_DOC)$(eval quiet_DOC:=)" $1 $@"; $($1) +endif +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @echo " $1$@"; $($1) +endif +# Otherwise, print the full command line. + %.o: %.cc $(all_deps) - $(CXX) -c $(CXXFLAGS) $< -o $@ + $(call quiet,CXX) -c $(CXXFLAGS) $< -o $@ %.o: %.c $(all_deps) - $(CC) -c $(CFLAGS) $< -o $@ + $(call quiet,CC) -c $(CFLAGS) $< -o $@ %.elc: %.el - emacs -batch -f batch-byte-compile $< + $(call quiet,EMACS) -batch -f batch-byte-compile $< .deps/%.d: %.c $(all_deps) @set -e; rm -f $@; mkdir -p $$(dirname $@) ; \ diff --git a/Makefile.local b/Makefile.local index 3c99624..5fd5d4f 100644 --- a/Makefile.local +++ b/Makefile.local @@ -20,10 +20,10 @@ notmuch_client_srcs = \ notmuch_client_modules = $(notmuch_client_srcs:.c=.o) notmuch: $(notmuch_client_modules) lib/notmuch.a - $(CXX) $^ $(LDFLAGS) -o $@ + $(call quiet,CXX) $^ $(LDFLAGS) -o $@ notmuch.1.gz: notmuch.1 - gzip --stdout notmuch.1 > notmuch.1.gz + $(call quiet,GZIP) --stdout $^ > $@ install: all notmuch.1.gz for d in $(DESTDIR)$(prefix)/bin/ $(DESTDIR)$(prefix)/share/man/man1 \ diff --git a/lib/Makefile.local b/lib/Makefile.local index 79f7b0b..a7562c9 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -18,7 +18,7 @@ libnotmuch_cxx_srcs = \ libnotmuch_modules = $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o) $(dir)/notmuch.a: $(libnotmuch_modules) - $(AR) rcs $@ $^ + $(call quiet,AR) rcs $@ $^ SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs) CLEAN := $(CLEAN) $(libnotmuch_modules) $(dir)/notmuch.a -- 1.6.5.3
[notmuch] [PATCH] Makefile: Magic silent rules.
Use the facilities of GNU make to create a magic function that will on the first invocation print a description of how to enable verbose compile lines and then print the quiet rule. Signed-off-by: Chris Wilson Signed-off-by: Carl Worth Cc: Mikhail Gusarov --- Makefile | 18 +++--- Makefile.local |2 +- lib/Makefile.local |2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 0411cbb..96fcdd5 100644 --- a/Makefile +++ b/Makefile @@ -28,14 +28,26 @@ include lib/Makefile.local # And get user settings from the output of configure include Makefile.config +# The user has not set any verbosity, default to quiet mode and inform the +# user how to enable verbose compiles. +ifeq ($(V),) +quiet_DOC := "Use \"$(MAKE) V=1\" to see the verbose compile lines.\n" +quiet = @echo $(quiet_DOC)$(eval quiet_DOC:=)" $1 $@"; +endif +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @echo " $1$@"; +endif +# Otherwise, print the full command line. + %.o: %.cc - $(CXX) -c $(CFLAGS) $(CXXFLAGS) $< -o $@ + $(call quiet,CXX) $(CXX) -c $(CFLAGS) $(CXXFLAGS) $< -o $@ %.o: %.c - $(CC) -c $(CFLAGS) $< -o $@ + $(call quiet,CC) $(CC) -c $(CFLAGS) $< -o $@ %.elc: %.el - emacs -batch -f batch-byte-compile $< + $(call quiet,EMACS) emacs -batch -f batch-byte-compile $< .deps/%.d: %.c @set -e; rm -f $@; mkdir -p $$(dirname $@) ; \ diff --git a/Makefile.local b/Makefile.local index ecd4ceb..115de0e 100644 --- a/Makefile.local +++ b/Makefile.local @@ -20,7 +20,7 @@ notmuch_client_srcs = \ notmuch_client_modules = $(notmuch_client_srcs:.c=.o) notmuch: $(notmuch_client_modules) lib/notmuch.a - $(CXX) $^ $(LDFLAGS) -o $@ + $(call quiet,CXX) $(CXX) $^ $(LDFLAGS) -o $@ notmuch.1.gz: notmuch.1 gzip --stdout notmuch.1 > notmuch.1.gz diff --git a/lib/Makefile.local b/lib/Makefile.local index 79f7b0b..f635da7 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -18,7 +18,7 @@ libnotmuch_cxx_srcs = \ libnotmuch_modules = $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o) $(dir)/notmuch.a: $(libnotmuch_modules) - $(AR) rcs $@ $^ + $(call quiet,AR) $(AR) rcs $@ $^ SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs) CLEAN := $(CLEAN) $(libnotmuch_modules) $(dir)/notmuch.a -- 1.6.5.3
[notmuch] Recommended Coding Style?
Excerpts from Jan Janak's message of Fri Nov 20 15:08:31 + 2009: > Is there any recommended coding style for the C/C++ code in notmuch? My prediction is that Carl will go with something close to what he wrote for Cairo: http://cgit.freedesktop.org/cairo/tree/CODING_STYLE He may or may not change to a more kernel style, but he definitely will not mandate 3-space indents. ;-) -ickle -- Chris Wilson, Intel Open Source Technology Centre
[notmuch] [PATCH 2/2] reply: Pointer mismatch.
Apparently typeof (size_t) != unsigned int on my x86-64. --- notmuch-reply.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/notmuch-reply.c b/notmuch-reply.c index 4a4a782..344b6e3 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -78,7 +78,7 @@ address_is_users (const char *address, notmuch_config_t *config) { const char *primary; char **other; -unsigned int i, other_len; +size_t i, other_len; primary = notmuch_config_get_user_primary_email (config); if (strcmp (primary, address) == 0) -- 1.6.5.2
[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once
Currently the same `pkg-config ...` is executed for every target, so just store the results in a variable. --- Makefile |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 96aaa73..023b2ec 100644 --- a/Makefile +++ b/Makefile @@ -4,15 +4,16 @@ CFLAGS=-O2 # Additional flags that we will append to whatever the user set. # These aren't intended for the user to manipulate. -extra_cflags = `pkg-config --cflags glib-2.0 gmime-2.4 talloc` -extra_cxxflags = `xapian-config --cxxflags` +extra_cflags := $(shell pkg-config --cflags glib-2.0 gmime-2.4 talloc) +extra_cxxflags := $(shell xapian-config --cxxflags) # Now smash together user's values with our extra values override CFLAGS += $(WARN_FLAGS) $(extra_cflags) override CXXFLAGS += $(WARN_FLAGS) $(extra_cflags) $(extra_cxxflags) -override LDFLAGS += `pkg-config --libs glib-2.0 gmime-2.4 talloc` \ - `xapian-config --libs` +override LDFLAGS += \ + $(shell pkg-config --libs glib-2.0 gmime-2.4 talloc) \ + $(shell xapian-config --libs) # Include our local Makefile.local first so that its first target is default include Makefile.local -- 1.6.5.2