From: David Bremner Date: Sat, 25 Mar 2017 14:51:03 +0000 (-0300) Subject: Merge branch 'release' X-Git-Tag: 0.25_rc0~89 X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=commitdiff_plain;h=d877240f4e097eb3dd477409a24155c10e0b3c17;hp=bf84665cc01b50ce80cf1df369db6a6c1ff523dd Merge branch 'release' wildcard search fixes, plus release busywork --- diff --git a/Makefile b/Makefile index 0ef57fa9..d2010fe4 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,35 @@ include Makefile.config global_deps = Makefile Makefile.config Makefile.local \ $(subdirs:%=%/Makefile) $(subdirs:%=%/Makefile.local) +INCLUDE_MORE := yes +ifneq ($(filter clean distclean dataclean, $(word 1, $(MAKECMDGOALS))),) +CLEAN_GOAL := $(word 1, $(MAKECMDGOALS)) + +# If there are more goals following CLEAN_GOAL, run $(MAKE)s in parts. +ifneq ($(word 2, $(MAKECMDGOALS)),) +INCLUDE_MORE := no +FOLLOWING_GOALS := $(wordlist 2, 99, $(MAKECMDGOALS)) + +.PHONY: $(FOLLOWING_GOALS) make_in_parts +$(FOLLOWING_GOALS): + @true +$(CLEAN_GOAL): make_in_parts +make_in_parts: + $(MAKE) $(CLEAN_GOAL) + $(MAKE) $(FOLLOWING_GOALS) configure_options="$(configure_options)" +endif + +else +CLEAN_GOAL := +endif + +# Potentially speedup make clean, distclean and dataclean ; avoid +# re-creating Makefile.config if it exists but configure is newer. +ifneq ($(CLEAN_GOAL),) +Makefile.config: | $(srcdir)/configure +else Makefile.config: $(srcdir)/configure +endif ifeq ($(configure_options),) @echo "" @echo "Note: Calling ./configure with no command-line arguments. This is often fine," @@ -33,9 +61,11 @@ ifeq ($(configure_options),) endif $(srcdir)/configure $(configure_options) +ifeq ($(INCLUDE_MORE),yes) # runtime variable definitions available in all subdirs include $(srcdir)/Makefile.global # Finally, include all of the Makefile.local fragments where all the # real work is done. include $(subdirs:%=%/Makefile.local) Makefile.local +endif diff --git a/Makefile.global b/Makefile.global index 7a78e9b5..cae4c7d1 100644 --- a/Makefile.global +++ b/Makefile.global @@ -52,7 +52,7 @@ PV_FILE=bindings/python/notmuch/version.py STD_CFLAGS := -std=gnu99 FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CPPFLAGS) $(STD_CFLAGS) $(CFLAGS) $(WARN_CFLAGS) $(extra_cflags) $(CONFIGURE_CFLAGS) FINAL_CXXFLAGS = $(CPPFLAGS) $(CXXFLAGS) $(WARN_CXXFLAGS) $(extra_cflags) $(extra_cxxflags) $(CONFIGURE_CXXFLAGS) -FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Lutil -lutil -Llib -lnotmuch +FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Lutil -lnotmuch_util -Llib -lnotmuch ifeq ($(LIBDIR_IN_LDCONFIG),0) FINAL_NOTMUCH_LDFLAGS += $(RPATH_LDFLAGS) endif diff --git a/Makefile.local b/Makefile.local index e75b6eae..03eafaaa 100644 --- a/Makefile.local +++ b/Makefile.local @@ -241,7 +241,7 @@ notmuch_client_modules = $(notmuch_client_srcs:.c=.o) notmuch.o: version.stamp -notmuch: $(notmuch_client_modules) lib/libnotmuch.a util/libutil.a parse-time-string/libparse-time-string.a +notmuch: $(notmuch_client_modules) lib/libnotmuch.a util/libnotmuch_util.a parse-time-string/libparse-time-string.a $(call quiet,CXX $(CFLAGS)) $^ $(FINAL_LIBNOTMUCH_LDFLAGS) -o $@ notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME) diff --git a/bindings/Makefile.local b/bindings/Makefile.local index 11d11d4b..17b561ca 100644 --- a/bindings/Makefile.local +++ b/bindings/Makefile.local @@ -8,6 +8,7 @@ ifeq ($(HAVE_RUBY_DEV),1) cd $(dir)/ruby && \ EXTRA_LDFLAGS="$(NO_UNDEFINED_LDFLAGS)" \ LIBNOTMUCH="../../lib/$(LINKER_NAME)" \ + NOTMUCH_SRCDIR='$(NOTMUCH_SRCDIR)' \ ruby extconf.rb --vendor $(MAKE) -C $(dir)/ruby endif diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 67fb1c41..8f918069 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -86,6 +86,11 @@ class Database(object): _get_version.argtypes = [NotmuchDatabaseP] _get_version.restype = c_uint + """notmuch_database_get_revision""" + _get_revision = nmlib.notmuch_database_get_revision + _get_revision.argtypes = [NotmuchDatabaseP, POINTER(c_char_p)] + _get_revision.restype = c_uint + """notmuch_database_open""" _open = nmlib.notmuch_database_open _open.argtypes = [c_char_p, c_uint, POINTER(NotmuchDatabaseP)] @@ -261,6 +266,17 @@ class Database(object): self._assert_db_is_initialized() return Database._get_version(self._db) + def get_revision (self): + """Returns the committed database revison and UUID + + :returns: (revison, uuid) The database revision as a positive integer + and the UUID of the database. + """ + self._assert_db_is_initialized() + uuid = c_char_p () + revision = Database._get_revision(self._db, byref (uuid)) + return (revision, uuid.value.decode ('utf-8')) + _needs_upgrade = nmlib.notmuch_database_needs_upgrade _needs_upgrade.argtypes = [NotmuchDatabaseP] _needs_upgrade.restype = bool diff --git a/bindings/python/notmuch/query.py b/bindings/python/notmuch/query.py index a0f4f64b..06c7b11b 100644 --- a/bindings/python/notmuch/query.py +++ b/bindings/python/notmuch/query.py @@ -134,10 +134,10 @@ class Query(object): self._assert_query_is_initialized() self._exclude_tag(self._query, _str(tagname)) - """notmuch_query_search_threads_st""" - _search_threads_st = nmlib.notmuch_query_search_threads_st - _search_threads_st.argtypes = [NotmuchQueryP, POINTER(NotmuchThreadsP)] - _search_threads_st.restype = c_uint + """notmuch_query_search_threads""" + _search_threads = nmlib.notmuch_query_search_threads + _search_threads.argtypes = [NotmuchQueryP, POINTER(NotmuchThreadsP)] + _search_threads.restype = c_uint def search_threads(self): """Execute a query for threads @@ -155,7 +155,7 @@ class Query(object): """ self._assert_query_is_initialized() threads_p = NotmuchThreadsP() # == NULL - status = Query._search_threads_st(self._query, byref(threads_p)) + status = Query._search_threads(self._query, byref(threads_p)) if status != 0: raise NotmuchError(status) @@ -164,9 +164,9 @@ class Query(object): return Threads(threads_p, self) """notmuch_query_search_messages_st""" - _search_messages_st = nmlib.notmuch_query_search_messages_st - _search_messages_st.argtypes = [NotmuchQueryP, POINTER(NotmuchMessagesP)] - _search_messages_st.restype = c_uint + _search_messages = nmlib.notmuch_query_search_messages + _search_messages.argtypes = [NotmuchQueryP, POINTER(NotmuchMessagesP)] + _search_messages.restype = c_uint def search_messages(self): """Filter messages according to the query and return @@ -177,7 +177,7 @@ class Query(object): """ self._assert_query_is_initialized() msgs_p = NotmuchMessagesP() # == NULL - status = Query._search_messages_st(self._query, byref(msgs_p)) + status = Query._search_messages(self._query, byref(msgs_p)) if status != 0: raise NotmuchError(status) @@ -185,7 +185,7 @@ class Query(object): raise NullPointerError return Messages(msgs_p, self) - _count_messages = nmlib.notmuch_query_count_messages_st + _count_messages = nmlib.notmuch_query_count_messages _count_messages.argtypes = [NotmuchQueryP, POINTER(c_uint)] _count_messages.restype = c_uint @@ -204,7 +204,7 @@ class Query(object): raise NotmuchError(status) return count.value - _count_threads = nmlib.notmuch_query_count_threads_st + _count_threads = nmlib.notmuch_query_count_threads _count_threads.argtypes = [NotmuchQueryP, POINTER(c_uint)] _count_threads.restype = c_uint diff --git a/bindings/python/notmuch/version.py b/bindings/python/notmuch/version.py index ae192fe1..bfdcf7ed 100644 --- a/bindings/python/notmuch/version.py +++ b/bindings/python/notmuch/version.py @@ -1,3 +1,3 @@ # this file should be kept in sync with ../../../version __VERSION__ = '0.24.1' -SOVERSION = '4' +SOVERSION = '5' diff --git a/bindings/ruby/extconf.rb b/bindings/ruby/extconf.rb index ddaa6841..161de5a2 100644 --- a/bindings/ruby/extconf.rb +++ b/bindings/ruby/extconf.rb @@ -5,7 +5,7 @@ require 'mkmf' -dir = File.join('..', '..', 'lib') +dir = File.join(ENV['NOTMUCH_SRCDIR'], 'lib') # includes $INCFLAGS = "-I#{dir} #{$INCFLAGS}" diff --git a/bindings/ruby/query.c b/bindings/ruby/query.c index ce66926c..8b46d700 100644 --- a/bindings/ruby/query.c +++ b/bindings/ruby/query.c @@ -138,7 +138,7 @@ notmuch_rb_query_search_threads (VALUE self) Data_Get_Notmuch_Query (self, query); - status = notmuch_query_search_threads_st (query, &threads); + status = notmuch_query_search_threads (query, &threads); if (status) notmuch_rb_status_raise (status); @@ -159,7 +159,7 @@ notmuch_rb_query_search_messages (VALUE self) Data_Get_Notmuch_Query (self, query); - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (status) notmuch_rb_status_raise (status); @@ -180,7 +180,7 @@ notmuch_rb_query_count_messages (VALUE self) Data_Get_Notmuch_Query (self, query); - status = notmuch_query_count_messages_st (query, &count); + status = notmuch_query_count_messages (query, &count); if (status) notmuch_rb_status_raise (status); @@ -201,7 +201,7 @@ notmuch_rb_query_count_threads (VALUE self) Data_Get_Notmuch_Query (self, query); - status = notmuch_query_count_threads_st (query, &count); + status = notmuch_query_count_threads (query, &count); if (status) notmuch_rb_status_raise (status); diff --git a/configure b/configure index fa77eb8f..03131275 100755 --- a/configure +++ b/configure @@ -19,7 +19,12 @@ To work around this problem you may try to execute: # Store original IFS value so it can be changed (and restored) in many places. readonly DEFAULT_IFS="$IFS" +# The top-level directory for the source. This ./configure and all Makefiles +# are good with ${srcdir} usually being relative. Some components (e.g. tests) +# are executed in subdirectories and for those it is simpler to use +# ${NOTMUCH_SRCDIR} which holds absolute path to the source. srcdir=$(dirname "$0") +NOTMUCH_SRCDIR=$(cd "$srcdir" && pwd) subdirs="util compat lib parse-time-string completion doc emacs" subdirs="${subdirs} performance-test test test/test-databases" @@ -42,6 +47,12 @@ if [ "$srcdir" != "." ]; then # Emacs only likes to generate compiled files next to the .el files # by default so copy these as well (which is not ideal). cp -a "$srcdir"/emacs/*.el emacs + + # We were not able to create fully working Makefile using ruby mkmf.rb + # so ruby bindings source files are copied as well (ditto -- not ideal). + mkdir bindings/ruby + cp -a "$srcdir"/bindings/ruby/*.[ch] bindings/ruby + cp -a "$srcdir"/bindings/ruby/extconf.rb bindings/ruby fi # Set several defaults (optionally specified by the user in @@ -352,8 +363,8 @@ int main(void) { return 0; } EOF -if ${CC} ${CFLAGS} _libversion.c -o _libversion > /dev/null 2>&1 && \ - ./_libversion > _libversion.sh && . ./_libversion.sh +if ${CC} ${CFLAGS} -I"$srcdir" _libversion.c -o _libversion > /dev/null 2>&1 \ + && ./_libversion > _libversion.sh && . ./_libversion.sh then printf "OK.\n" else @@ -493,8 +504,7 @@ else fi if ! pkg-config --exists zlib; then - ${CC} ${zlib_cflags} -o compat/gen_zlib_pc \ - "$srcdir"/compat/gen_zlib_pc.c ${zlib_ldflags} > /dev/null 2>&1 && + ${CC} -o compat/gen_zlib_pc "$srcdir"/compat/gen_zlib_pc.c >/dev/null 2>&1 && compat/gen_zlib_pc > compat/zlib.pc && PKG_CONFIG_PATH="$PKG_CONFIG_PATH":compat && export PKG_CONFIG_PATH @@ -914,6 +924,7 @@ cat > Makefile.config < sh.config <= ${source:Version}) +Depends: ${misc:Depends}, ${python:Depends}, libnotmuch5 (>= ${source:Version}) Description: python interface to the notmuch mail search and index library Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses @@ -87,7 +87,7 @@ Description: python interface to the notmuch mail search and index library Package: python3-notmuch Architecture: all Section: python -Depends: ${misc:Depends}, ${python3:Depends}, libnotmuch4 (>= ${source:Version}) +Depends: ${misc:Depends}, ${python3:Depends}, libnotmuch5 (>= ${source:Version}) Description: Python 3 interface to the notmuch mail search and index library Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses @@ -167,7 +167,7 @@ Package: notmuch-dbg Architecture: any Section: debug Priority: extra -Depends: ${shlibs:Depends}, ${misc:Depends}, libnotmuch4 (= ${binary:Version}) +Depends: ${shlibs:Depends}, ${misc:Depends}, libnotmuch5 (= ${binary:Version}) Description: thread-based email index, search and tagging - debugging symbols Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses diff --git a/debian/libnotmuch4.install b/debian/libnotmuch4.install deleted file mode 100644 index a513b475..00000000 --- a/debian/libnotmuch4.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libnotmuch.so.* diff --git a/debian/libnotmuch4.symbols b/debian/libnotmuch4.symbols deleted file mode 100644 index 9bfec1a1..00000000 --- a/debian/libnotmuch4.symbols +++ /dev/null @@ -1,126 +0,0 @@ -libnotmuch.so.4 libnotmuch4 #MINVER# - notmuch_built_with@Base 0.23~rc0 - notmuch_config_list_destroy@Base 0.23~rc0 - notmuch_config_list_key@Base 0.23~rc0 - notmuch_config_list_move_to_next@Base 0.23~rc0 - notmuch_config_list_valid@Base 0.23~rc0 - notmuch_config_list_value@Base 0.23~rc0 - notmuch_database_add_message@Base 0.3 - notmuch_database_begin_atomic@Base 0.9~rc1 - notmuch_database_close@Base 0.13~rc1 - notmuch_database_compact@Base 0.17~rc1 - notmuch_database_create@Base 0.3 - notmuch_database_create_verbose@Base 0.20~rc1 - notmuch_database_destroy@Base 0.13~rc1 - notmuch_database_end_atomic@Base 0.9~rc1 - notmuch_database_find_message@Base 0.9~rc2 - notmuch_database_find_message_by_filename@Base 0.9~rc2 - notmuch_database_get_all_tags@Base 0.3 - notmuch_database_get_config@Base 0.23~rc0 - notmuch_database_get_config_list@Base 0.23~rc0 - notmuch_database_get_directory@Base 0.3 - notmuch_database_get_path@Base 0.3 - notmuch_database_get_revision@Base 0.21~rc1 - notmuch_database_get_version@Base 0.3 - notmuch_database_needs_upgrade@Base 0.3 - notmuch_database_open@Base 0.3 - notmuch_database_open_verbose@Base 0.20~rc1 - notmuch_database_remove_message@Base 0.3 - notmuch_database_set_config@Base 0.23~rc0 - notmuch_database_status_string@Base 0.20~rc1 - notmuch_database_upgrade@Base 0.3 - notmuch_directory_delete@Base 0.21~rc1 - notmuch_directory_destroy@Base 0.3 - notmuch_directory_get_child_directories@Base 0.3 - notmuch_directory_get_child_files@Base 0.3 - notmuch_directory_get_mtime@Base 0.3 - notmuch_directory_set_mtime@Base 0.3 - notmuch_filenames_destroy@Base 0.3 - notmuch_filenames_get@Base 0.3 - notmuch_filenames_move_to_next@Base 0.3 - notmuch_filenames_valid@Base 0.3 - notmuch_message_add_property@Base 0.23~rc0 - notmuch_message_add_tag@Base 0.3 - notmuch_message_destroy@Base 0.3 - notmuch_message_freeze@Base 0.3 - notmuch_message_get_date@Base 0.3 - notmuch_message_get_filename@Base 0.3 - notmuch_message_get_filenames@Base 0.5 - notmuch_message_get_flag@Base 0.3 - notmuch_message_get_header@Base 0.3 - notmuch_message_get_message_id@Base 0.3 - notmuch_message_get_properties@Base 0.23~rc0 - notmuch_message_get_property@Base 0.23~rc0 - notmuch_message_get_replies@Base 0.3 - notmuch_message_get_tags@Base 0.3 - notmuch_message_get_thread_id@Base 0.3 - notmuch_message_maildir_flags_to_tags@Base 0.5 - notmuch_message_properties_destroy@Base 0.23~rc0 - notmuch_message_properties_key@Base 0.23~rc0 - notmuch_message_properties_move_to_next@Base 0.23~rc0 - notmuch_message_properties_valid@Base 0.23~rc0 - notmuch_message_properties_value@Base 0.23~rc0 - notmuch_message_remove_all_properties@Base 0.23~rc0 - notmuch_message_remove_all_tags@Base 0.3 - notmuch_message_remove_property@Base 0.23~rc0 - notmuch_message_remove_tag@Base 0.3 - notmuch_message_set_flag@Base 0.3 - notmuch_message_tags_to_maildir_flags@Base 0.5 - notmuch_message_thaw@Base 0.3 - notmuch_messages_collect_tags@Base 0.3 - notmuch_messages_destroy@Base 0.3 - notmuch_messages_get@Base 0.3 - notmuch_messages_move_to_next@Base 0.3 - notmuch_messages_valid@Base 0.3 - notmuch_query_add_tag_exclude@Base 0.12~rc1 - notmuch_query_count_messages@Base 0.3 - notmuch_query_count_messages_st@Base 0.21~rc1 - notmuch_query_count_threads@Base 0.10~rc1 - notmuch_query_count_threads_st@Base 0.21~rc1 - notmuch_query_create@Base 0.3 - notmuch_query_destroy@Base 0.3 - notmuch_query_get_database@Base 0.21~rc1 - notmuch_query_get_query_string@Base 0.4 - notmuch_query_get_sort@Base 0.4 - notmuch_query_search_messages@Base 0.3 - notmuch_query_search_messages_st@Base 0.20~rc1 - notmuch_query_search_threads@Base 0.3 - notmuch_query_search_threads_st@Base 0.20~rc1 - notmuch_query_set_omit_excluded@Base 0.13~rc1 - notmuch_query_set_sort@Base 0.3 - notmuch_status_to_string@Base 0.3 - notmuch_tags_destroy@Base 0.3 - notmuch_tags_get@Base 0.3 - notmuch_tags_move_to_next@Base 0.3 - notmuch_tags_valid@Base 0.3 - notmuch_thread_destroy@Base 0.3 - notmuch_thread_get_authors@Base 0.3 - notmuch_thread_get_matched_messages@Base 0.3 - notmuch_thread_get_messages@Base 0.16 - notmuch_thread_get_newest_date@Base 0.3 - notmuch_thread_get_oldest_date@Base 0.3 - notmuch_thread_get_subject@Base 0.3 - notmuch_thread_get_tags@Base 0.3 - notmuch_thread_get_thread_id@Base 0.3 - notmuch_thread_get_toplevel_messages@Base 0.3 - notmuch_thread_get_total_messages@Base 0.3 - notmuch_threads_destroy@Base 0.3 - notmuch_threads_get@Base 0.3 - notmuch_threads_move_to_next@Base 0.3 - notmuch_threads_valid@Base 0.3 - (c++)"typeinfo for Xapian::LogicError@Base" 0.6.1 - (c++)"typeinfo for Xapian::RuntimeError@Base" 0.6.1 - (c++)"typeinfo for Xapian::DocNotFoundError@Base" 0.6.1 - (c++)"typeinfo for Xapian::InvalidArgumentError@Base" 0.6.1 - (c++)"typeinfo for Xapian::Error@Base" 0.6.1 - (c++)"typeinfo for Xapian::DatabaseError@Base" 0.24~rc0 - (c++)"typeinfo for Xapian::DatabaseModifiedError@Base" 0.24~rc0 - (c++|optional=present with Xapian 1.4)"typeinfo for Xapian::QueryParserError@Base" 0.23~rc0 - (c++)"typeinfo name for Xapian::LogicError@Base" 0.6.1 - (c++)"typeinfo name for Xapian::RuntimeError@Base" 0.6.1 - (c++)"typeinfo name for Xapian::DocNotFoundError@Base" 0.6.1 - (c++)"typeinfo name for Xapian::InvalidArgumentError@Base" 0.6.1 - (c++)"typeinfo name for Xapian::Error@Base" 0.6.1 - (c++)"typeinfo name for Xapian::DatabaseError@Base" 0.24~rc0 - (c++)"typeinfo name for Xapian::DatabaseModifiedError@Base" 0.24~rc0 - (c++|optional=present with Xapian 1.4)"typeinfo name for Xapian::QueryParserError@Base" 0.23~rc0 diff --git a/debian/libnotmuch5.install b/debian/libnotmuch5.install new file mode 100644 index 00000000..a513b475 --- /dev/null +++ b/debian/libnotmuch5.install @@ -0,0 +1 @@ +usr/lib/*/libnotmuch.so.* diff --git a/debian/libnotmuch5.symbols b/debian/libnotmuch5.symbols new file mode 100644 index 00000000..9f3323ff --- /dev/null +++ b/debian/libnotmuch5.symbols @@ -0,0 +1,126 @@ +libnotmuch.so.5 libnotmuch5 #MINVER# + notmuch_built_with@Base 0.23~rc0 + notmuch_config_list_destroy@Base 0.23~rc0 + notmuch_config_list_key@Base 0.23~rc0 + notmuch_config_list_move_to_next@Base 0.23~rc0 + notmuch_config_list_valid@Base 0.23~rc0 + notmuch_config_list_value@Base 0.23~rc0 + notmuch_database_add_message@Base 0.3 + notmuch_database_begin_atomic@Base 0.9~rc1 + notmuch_database_close@Base 0.13~rc1 + notmuch_database_compact@Base 0.17~rc1 + notmuch_database_create@Base 0.3 + notmuch_database_create_verbose@Base 0.20~rc1 + notmuch_database_destroy@Base 0.13~rc1 + notmuch_database_end_atomic@Base 0.9~rc1 + notmuch_database_find_message@Base 0.9~rc2 + notmuch_database_find_message_by_filename@Base 0.9~rc2 + notmuch_database_get_all_tags@Base 0.3 + notmuch_database_get_config@Base 0.23~rc0 + notmuch_database_get_config_list@Base 0.23~rc0 + notmuch_database_get_directory@Base 0.3 + notmuch_database_get_path@Base 0.3 + notmuch_database_get_revision@Base 0.21~rc1 + notmuch_database_get_version@Base 0.3 + notmuch_database_needs_upgrade@Base 0.3 + notmuch_database_open@Base 0.3 + notmuch_database_open_verbose@Base 0.20~rc1 + notmuch_database_remove_message@Base 0.3 + notmuch_database_set_config@Base 0.23~rc0 + notmuch_database_status_string@Base 0.20~rc1 + notmuch_database_upgrade@Base 0.3 + notmuch_directory_delete@Base 0.21~rc1 + notmuch_directory_destroy@Base 0.3 + notmuch_directory_get_child_directories@Base 0.3 + notmuch_directory_get_child_files@Base 0.3 + notmuch_directory_get_mtime@Base 0.3 + notmuch_directory_set_mtime@Base 0.3 + notmuch_filenames_destroy@Base 0.3 + notmuch_filenames_get@Base 0.3 + notmuch_filenames_move_to_next@Base 0.3 + notmuch_filenames_valid@Base 0.3 + notmuch_message_add_property@Base 0.23~rc0 + notmuch_message_add_tag@Base 0.3 + notmuch_message_destroy@Base 0.3 + notmuch_message_freeze@Base 0.3 + notmuch_message_get_date@Base 0.3 + notmuch_message_get_filename@Base 0.3 + notmuch_message_get_filenames@Base 0.5 + notmuch_message_get_flag@Base 0.3 + notmuch_message_get_header@Base 0.3 + notmuch_message_get_message_id@Base 0.3 + notmuch_message_get_properties@Base 0.23~rc0 + notmuch_message_get_property@Base 0.23~rc0 + notmuch_message_get_replies@Base 0.3 + notmuch_message_get_tags@Base 0.3 + notmuch_message_get_thread_id@Base 0.3 + notmuch_message_maildir_flags_to_tags@Base 0.5 + notmuch_message_properties_destroy@Base 0.23~rc0 + notmuch_message_properties_key@Base 0.23~rc0 + notmuch_message_properties_move_to_next@Base 0.23~rc0 + notmuch_message_properties_valid@Base 0.23~rc0 + notmuch_message_properties_value@Base 0.23~rc0 + notmuch_message_remove_all_properties@Base 0.23~rc0 + notmuch_message_remove_all_tags@Base 0.3 + notmuch_message_remove_property@Base 0.23~rc0 + notmuch_message_remove_tag@Base 0.3 + notmuch_message_set_flag@Base 0.3 + notmuch_message_tags_to_maildir_flags@Base 0.5 + notmuch_message_thaw@Base 0.3 + notmuch_messages_collect_tags@Base 0.3 + notmuch_messages_destroy@Base 0.3 + notmuch_messages_get@Base 0.3 + notmuch_messages_move_to_next@Base 0.3 + notmuch_messages_valid@Base 0.3 + notmuch_query_add_tag_exclude@Base 0.12~rc1 + notmuch_query_count_messages@Base 0.3 + notmuch_query_count_messages_st@Base 0.21~rc1 + notmuch_query_count_threads@Base 0.10~rc1 + notmuch_query_count_threads_st@Base 0.21~rc1 + notmuch_query_create@Base 0.3 + notmuch_query_destroy@Base 0.3 + notmuch_query_get_database@Base 0.21~rc1 + notmuch_query_get_query_string@Base 0.4 + notmuch_query_get_sort@Base 0.4 + notmuch_query_search_messages@Base 0.3 + notmuch_query_search_messages_st@Base 0.20~rc1 + notmuch_query_search_threads@Base 0.3 + notmuch_query_search_threads_st@Base 0.20~rc1 + notmuch_query_set_omit_excluded@Base 0.13~rc1 + notmuch_query_set_sort@Base 0.3 + notmuch_status_to_string@Base 0.3 + notmuch_tags_destroy@Base 0.3 + notmuch_tags_get@Base 0.3 + notmuch_tags_move_to_next@Base 0.3 + notmuch_tags_valid@Base 0.3 + notmuch_thread_destroy@Base 0.3 + notmuch_thread_get_authors@Base 0.3 + notmuch_thread_get_matched_messages@Base 0.3 + notmuch_thread_get_messages@Base 0.16 + notmuch_thread_get_newest_date@Base 0.3 + notmuch_thread_get_oldest_date@Base 0.3 + notmuch_thread_get_subject@Base 0.3 + notmuch_thread_get_tags@Base 0.3 + notmuch_thread_get_thread_id@Base 0.3 + notmuch_thread_get_toplevel_messages@Base 0.3 + notmuch_thread_get_total_messages@Base 0.3 + notmuch_threads_destroy@Base 0.3 + notmuch_threads_get@Base 0.3 + notmuch_threads_move_to_next@Base 0.3 + notmuch_threads_valid@Base 0.3 + (c++)"typeinfo for Xapian::LogicError@Base" 0.6.1 + (c++)"typeinfo for Xapian::RuntimeError@Base" 0.6.1 + (c++)"typeinfo for Xapian::DocNotFoundError@Base" 0.6.1 + (c++)"typeinfo for Xapian::InvalidArgumentError@Base" 0.6.1 + (c++)"typeinfo for Xapian::Error@Base" 0.6.1 + (c++)"typeinfo for Xapian::DatabaseError@Base" 0.24~rc0 + (c++)"typeinfo for Xapian::DatabaseModifiedError@Base" 0.24~rc0 + (c++|optional=present with Xapian 1.4)"typeinfo for Xapian::QueryParserError@Base" 0.23~rc0 + (c++)"typeinfo name for Xapian::LogicError@Base" 0.6.1 + (c++)"typeinfo name for Xapian::RuntimeError@Base" 0.6.1 + (c++)"typeinfo name for Xapian::DocNotFoundError@Base" 0.6.1 + (c++)"typeinfo name for Xapian::InvalidArgumentError@Base" 0.6.1 + (c++)"typeinfo name for Xapian::Error@Base" 0.6.1 + (c++)"typeinfo name for Xapian::DatabaseError@Base" 0.24~rc0 + (c++)"typeinfo name for Xapian::DatabaseModifiedError@Base" 0.24~rc0 + (c++|optional=present with Xapian 1.4)"typeinfo name for Xapian::QueryParserError@Base" 0.23~rc0 diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el index 68a7e9f3..0af727ef 100644 --- a/emacs/notmuch-crypto.el +++ b/emacs/notmuch-crypto.el @@ -21,6 +21,7 @@ ;;; Code: +(require 'epg) (require 'notmuch-lib) (defcustom notmuch-crypto-process-mime nil @@ -140,7 +141,7 @@ mode." (with-selected-window window (with-current-buffer buffer (goto-char (point-max)) - (call-process "gpg" nil t t "--list-keys" fingerprint)) + (call-process epg-gpg-program nil t t "--list-keys" fingerprint)) (recenter -1)))) (defun notmuch-crypto-sigstatus-error-callback (button) @@ -151,9 +152,9 @@ mode." (with-selected-window window (with-current-buffer buffer (goto-char (point-max)) - (call-process "gpg" nil t t "--recv-keys" keyid) + (call-process epg-gpg-program nil t t "--recv-keys" keyid) (insert "\n") - (call-process "gpg" nil t t "--list-keys" keyid)) + (call-process epg-gpg-program nil t t "--list-keys" keyid)) (recenter -1)) (notmuch-show-refresh-view))) diff --git a/lib/Makefile.local b/lib/Makefile.local index cd92fc79..d36fd5a0 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -60,8 +60,8 @@ libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o) $(dir)/libnotmuch.a: $(libnotmuch_modules) $(call quiet,AR) rcs $@ $^ -$(dir)/$(LIBNAME): $(libnotmuch_modules) notmuch.sym util/libutil.a parse-time-string/libparse-time-string.a - $(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) $(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@ util/libutil.a parse-time-string/libparse-time-string.a +$(dir)/$(LIBNAME): $(libnotmuch_modules) notmuch.sym util/libnotmuch_util.a parse-time-string/libparse-time-string.a + $(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) $(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@ util/libnotmuch_util.a parse-time-string/libparse-time-string.a notmuch.sym: $(srcdir)/$(dir)/notmuch.h $(libnotmuch_modules) sh $(srcdir)/$(lib)/gen-version-script.sh $< $(libnotmuch_modules) > $@ diff --git a/lib/database.cc b/lib/database.cc index b7fc53ee..5bc131a3 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -1493,7 +1493,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch, query = notmuch_query_create (notmuch, ""); unsigned msg_count; - status = notmuch_query_count_messages_st (query, &msg_count); + status = notmuch_query_count_messages (query, &msg_count); if (status) goto DONE; @@ -1531,7 +1531,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch, query = notmuch_query_create (notmuch, ""); - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (status) goto DONE; for (; @@ -2493,53 +2493,53 @@ notmuch_database_add_message (notmuch_database_t *notmuch, if (ret) goto DONE; - try { - /* Before we do any real work, (especially before doing a - * potential SHA-1 computation on the entire file's contents), - * let's make sure that what we're looking at looks like an - * actual email message. - */ - from = _notmuch_message_file_get_header (message_file, "from"); - subject = _notmuch_message_file_get_header (message_file, "subject"); - to = _notmuch_message_file_get_header (message_file, "to"); + /* Before we do any real work, (especially before doing a + * potential SHA-1 computation on the entire file's contents), + * let's make sure that what we're looking at looks like an + * actual email message. + */ + from = _notmuch_message_file_get_header (message_file, "from"); + subject = _notmuch_message_file_get_header (message_file, "subject"); + to = _notmuch_message_file_get_header (message_file, "to"); + + if ((from == NULL || *from == '\0') && + (subject == NULL || *subject == '\0') && + (to == NULL || *to == '\0')) { + ret = NOTMUCH_STATUS_FILE_NOT_EMAIL; + goto DONE; + } - if ((from == NULL || *from == '\0') && - (subject == NULL || *subject == '\0') && - (to == NULL || *to == '\0')) - { - ret = NOTMUCH_STATUS_FILE_NOT_EMAIL; - goto DONE; - } + /* Now that we're sure it's mail, the first order of business + * is to find a message ID (or else create one ourselves). + */ + header = _notmuch_message_file_get_header (message_file, "message-id"); + if (header && *header != '\0') { + message_id = _parse_message_id (message_file, header, NULL); - /* Now that we're sure it's mail, the first order of business - * is to find a message ID (or else create one ourselves). */ + /* So the header value isn't RFC-compliant, but it's + * better than no message-id at all. + */ + if (message_id == NULL) + message_id = talloc_strdup (message_file, header); + } - header = _notmuch_message_file_get_header (message_file, "message-id"); - if (header && *header != '\0') { - message_id = _parse_message_id (message_file, header, NULL); + if (message_id == NULL ) { + /* No message-id at all, let's generate one by taking a + * hash over the file's contents. + */ + char *sha1 = _notmuch_sha1_of_file (filename); - /* So the header value isn't RFC-compliant, but it's - * better than no message-id at all. */ - if (message_id == NULL) - message_id = talloc_strdup (message_file, header); + /* If that failed too, something is really wrong. Give up. */ + if (sha1 == NULL) { + ret = NOTMUCH_STATUS_FILE_ERROR; + goto DONE; } - if (message_id == NULL ) { - /* No message-id at all, let's generate one by taking a - * hash over the file's contents. */ - char *sha1 = _notmuch_sha1_of_file (filename); - - /* If that failed too, something is really wrong. Give up. */ - if (sha1 == NULL) { - ret = NOTMUCH_STATUS_FILE_ERROR; - goto DONE; - } - - message_id = talloc_asprintf (message_file, - "notmuch-sha1-%s", sha1); - free (sha1); - } + message_id = talloc_asprintf (message_file, "notmuch-sha1-%s", sha1); + free (sha1); + } + try { /* Now that we have a message ID, we get a message object, * (which may or may not reference an existing document in the * database). */ diff --git a/lib/message.cc b/lib/message.cc index 36a07a88..f8215a49 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -1034,10 +1034,16 @@ _notmuch_message_set_header_values (notmuch_message_t *message, /* GMime really doesn't want to see a NULL date, so protect its * sensibilities. */ - if (date == NULL || *date == '\0') + if (date == NULL || *date == '\0') { time_value = 0; - else + } else { time_value = g_mime_utils_header_decode_date (date, NULL); + /* + * Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=779923 + */ + if (time_value < 0) + time_value = 0; + } message->doc.add_value (NOTMUCH_VALUE_TIMESTAMP, Xapian::sortable_serialise (time_value)); @@ -1123,7 +1129,7 @@ _notmuch_message_delete (notmuch_message_t *message) query = notmuch_query_create (notmuch, query_string); if (query == NULL) return NOTMUCH_STATUS_OUT_OF_MEMORY; - status = notmuch_query_count_messages_st (query, &count); + status = notmuch_query_count_messages (query, &count); if (status) { notmuch_query_destroy (query); return status; diff --git a/lib/notmuch.h b/lib/notmuch.h index 16da8be9..d374dc96 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -55,8 +55,8 @@ NOTMUCH_BEGIN_DECLS * The library version number. This must agree with the soname * version in Makefile.local. */ -#define LIBNOTMUCH_MAJOR_VERSION 4 -#define LIBNOTMUCH_MINOR_VERSION 4 +#define LIBNOTMUCH_MAJOR_VERSION 5 +#define LIBNOTMUCH_MINOR_VERSION 0 #define LIBNOTMUCH_MICRO_VERSION 0 @@ -179,6 +179,11 @@ typedef enum _notmuch_status { * passed to a function expecting an absolute path. */ NOTMUCH_STATUS_PATH_ERROR, + /** + * The requested operation was ignored. Depending on the function, + * this may not be an actual error. + */ + NOTMUCH_STATUS_IGNORED, /** * One of the arguments violates the preconditions for the * function, in a way not covered by a more specific argument. @@ -812,10 +817,20 @@ notmuch_query_get_sort (const notmuch_query_t *query); /** * Add a tag that will be excluded from the query results by default. - * This exclusion will be overridden if this tag appears explicitly in + * This exclusion will be ignored if this tag appears explicitly in * the query. + * + * @returns + * + * NOTMUCH_STATUS_SUCCESS: excluded was added successfully. + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occured. + * Most likely a problem lazily parsing the query string. + * + * NOTMUCH_STATUS_IGNORED: tag is explicitely present in the query, so + * not excluded. */ -void +notmuch_status_t notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); /** @@ -855,24 +870,22 @@ notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); * notmuch_threads_destroy function, but there's no good reason * to call it if the query is about to be destroyed). * - * @since libnotmuch 4.2 (notmuch 0.20) + * @since libnotmuch 5.0 (notmuch 0.25) */ notmuch_status_t -notmuch_query_search_threads_st (notmuch_query_t *query, - notmuch_threads_t **out); +notmuch_query_search_threads (notmuch_query_t *query, + notmuch_threads_t **out); /** - * Like notmuch_query_search_threads_st, but without a status return. - * - * If a Xapian exception occurs this function will return NULL. + * Deprecated alias for notmuch_query_search_threads. * - * @deprecated Deprecated as of libnotmuch 4.3 (notmuch 0.21). Please - * use notmuch_query_search_threads_st instead. + * @deprecated Deprecated as of libnotmuch 5 (notmuch 0.25). Please + * use notmuch_query_search_threads instead. * */ -NOTMUCH_DEPRECATED(4,3) -notmuch_threads_t * -notmuch_query_search_threads (notmuch_query_t *query); +NOTMUCH_DEPRECATED(5,0) +notmuch_status_t +notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out); /** * Execute a query for messages, returning a notmuch_messages_t object @@ -913,23 +926,23 @@ notmuch_query_search_threads (notmuch_query_t *query); * * If a Xapian exception occurs this function will return NULL. * - * @since libnotmuch 4.2 (notmuch 0.20) + * @since libnotmuch 5 (notmuch 0.25) */ notmuch_status_t -notmuch_query_search_messages_st (notmuch_query_t *query, - notmuch_messages_t **out); +notmuch_query_search_messages (notmuch_query_t *query, + notmuch_messages_t **out); /** - * Like notmuch_query_search_messages, but without a status return. - * - * If a Xapian exception occurs this function will return NULL. + * Deprecated alias for notmuch_query_search_messages * - * @deprecated Deprecated as of libnotmuch 4.3 (notmuch 0.21). Please use - * notmuch_query_search_messages_st instead. + * @deprecated Deprecated as of libnotmuch 5 (notmuch 0.25). Please use + * notmuch_query_search_messages instead. * */ -NOTMUCH_DEPRECATED(4,3) -notmuch_messages_t * -notmuch_query_search_messages (notmuch_query_t *query); + +NOTMUCH_DEPRECATED(5,0) +notmuch_status_t +notmuch_query_search_messages_st (notmuch_query_t *query, + notmuch_messages_t **out); /** * Destroy a notmuch_query_t along with any associated resources. @@ -1010,22 +1023,21 @@ notmuch_threads_destroy (notmuch_threads_t *threads); * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occured. The * value of *count is not defined. * - * @since libnotmuch 4.3 (notmuch 0.21) + * @since libnotmuch 5 (notmuch 0.25) */ notmuch_status_t -notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count); +notmuch_query_count_messages (notmuch_query_t *query, unsigned int *count); /** - * like notmuch_query_count_messages_st, but without a status return. + * Deprecated alias for notmuch_query_count_messages * - * May return 0 in the case of errors. * - * @deprecated Deprecated since libnotmuch 4.3 (notmuch 0.21). Please - * use notmuch_query_count_messages_st instead. + * @deprecated Deprecated since libnotmuch 5.0 (notmuch 0.25). Please + * use notmuch_query_count_messages instead. */ -NOTMUCH_DEPRECATED(4,3) -unsigned int -notmuch_query_count_messages (notmuch_query_t *query); +NOTMUCH_DEPRECATED(5,0) +notmuch_status_t +notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count); /** * Return the number of threads matching a search. @@ -1047,22 +1059,20 @@ notmuch_query_count_messages (notmuch_query_t *query); * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occured. The * value of *count is not defined. * - * @since libnotmuch 4.3 (notmuch 0.21) + * @since libnotmuch 5 (notmuch 0.25) */ notmuch_status_t -notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count); +notmuch_query_count_threads (notmuch_query_t *query, unsigned *count); /** - * like notmuch_query_count_threads, but without a status return. + * Deprecated alias for notmuch_query_count_threads * - * May return 0 in case of errors. - * - * @deprecated Deprecated as of libnotmuch 4.3 (notmuch 0.21). Please + * @deprecated Deprecated as of libnotmuch 5.0 (notmuch 0.25). Please * use notmuch_query_count_threads_st instead. */ -NOTMUCH_DEPRECATED(4,3) -unsigned int -notmuch_query_count_threads (notmuch_query_t *query); +NOTMUCH_DEPRECATED(5,0) +notmuch_status_t +notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count); /** * Get the thread ID of 'thread'. diff --git a/lib/query.cc b/lib/query.cc index 59e9141a..212e27f0 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -177,29 +177,22 @@ notmuch_query_get_sort (const notmuch_query_t *query) return query->sort; } -void +notmuch_status_t notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) { notmuch_status_t status; char *term; status = _notmuch_query_ensure_parsed (query); - /* The following is not ideal error handling, but to avoid - * breaking the ABI, we can live with it for now. In particular at - * least in the notmuch CLI, any syntax error in the query is - * caught in a later call to _notmuch_query_ensure_parsed with a - * better error path. - * - * TODO: add status return to this function. - */ if (status) - return; + return status; term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); if (query->terms.count(term) != 0) - return; /* XXX report ignoring exclude? */ + return NOTMUCH_STATUS_IGNORED; _notmuch_string_list_append (query->exclude_terms, term); + return NOTMUCH_STATUS_SUCCESS; } /* We end up having to call the destructors explicitly because we had @@ -233,20 +226,16 @@ _notmuch_exclude_tags (notmuch_query_t *query) return exclude_query; } -notmuch_messages_t * -notmuch_query_search_messages (notmuch_query_t *query) + +notmuch_status_t +notmuch_query_search_messages_st (notmuch_query_t *query, + notmuch_messages_t **out) { - notmuch_status_t status; - notmuch_messages_t *messages; - status = notmuch_query_search_messages_st (query, &messages); - if (status) - return NULL; - else - return messages; + return notmuch_query_search_messages (query, out); } notmuch_status_t -notmuch_query_search_messages_st (notmuch_query_t *query, +notmuch_query_search_messages (notmuch_query_t *query, notmuch_messages_t **out) { return _notmuch_query_search_documents (query, "mail", out); @@ -497,22 +486,15 @@ _notmuch_threads_destructor (notmuch_threads_t *threads) return 0; } - -notmuch_threads_t * -notmuch_query_search_threads (notmuch_query_t *query) +notmuch_status_t +notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out) { - notmuch_status_t status; - notmuch_threads_t *threads; - status = notmuch_query_search_threads_st (query, &threads); - if (status) - return NULL; - else - return threads; + return notmuch_query_search_threads(query, out); } notmuch_status_t -notmuch_query_search_threads_st (notmuch_query_t *query, - notmuch_threads_t **out) +notmuch_query_search_threads (notmuch_query_t *query, + notmuch_threads_t **out) { notmuch_threads_t *threads; notmuch_messages_t *messages; @@ -526,7 +508,7 @@ notmuch_query_search_threads_st (notmuch_query_t *query, threads->query = query; - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (status) { talloc_free (threads); return status; @@ -609,18 +591,14 @@ notmuch_threads_destroy (notmuch_threads_t *threads) talloc_free (threads); } -unsigned int -notmuch_query_count_messages (notmuch_query_t *query) +notmuch_status_t +notmuch_query_count_messages_st (notmuch_query_t *query, unsigned *count_out) { - notmuch_status_t status; - unsigned int count; - - status = notmuch_query_count_messages_st (query, &count); - return status ? 0 : count; + return notmuch_query_count_messages (query, count_out); } notmuch_status_t -notmuch_query_count_messages_st (notmuch_query_t *query, unsigned *count_out) +notmuch_query_count_messages (notmuch_query_t *query, unsigned *count_out) { return _notmuch_query_count_documents (query, "mail", count_out); } @@ -695,18 +673,14 @@ _notmuch_query_count_documents (notmuch_query_t *query, const char *type, unsign return NOTMUCH_STATUS_SUCCESS; } -unsigned -notmuch_query_count_threads (notmuch_query_t *query) +notmuch_status_t +notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count) { - notmuch_status_t status; - unsigned int count; - - status = notmuch_query_count_threads_st (query, &count); - return status ? 0 : count; + return notmuch_query_count_threads (query, count); } notmuch_status_t -notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count) +notmuch_query_count_threads (notmuch_query_t *query, unsigned *count) { notmuch_messages_t *messages; GHashTable *hash; @@ -715,7 +689,7 @@ notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count) sort = query->sort; query->sort = NOTMUCH_SORT_UNSORTED; - ret = notmuch_query_search_messages_st (query, &messages); + ret = notmuch_query_search_messages (query, &messages); if (ret) return ret; query->sort = sort; diff --git a/lib/thread.cc b/lib/thread.cc index 84ee5298..561ca5be 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -505,7 +505,7 @@ _notmuch_thread_create (void *ctx, * oldest or newest subject is desired. */ notmuch_query_set_sort (thread_id_query, NOTMUCH_SORT_OLDEST_FIRST); - status = notmuch_query_search_messages_st (thread_id_query, &messages); + status = notmuch_query_search_messages (thread_id_query, &messages); if (status) goto DONE; diff --git a/mime-node.c b/mime-node.c index c9b82330..f719422e 100644 --- a/mime-node.c +++ b/mime-node.c @@ -322,20 +322,21 @@ mime_node_child (mime_node_t *parent, int child) static mime_node_t * _mime_node_seek_dfs_walk (mime_node_t *node, int *n) { - mime_node_t *ret = NULL; int i; if (*n == 0) return node; *n -= 1; - for (i = 0; i < node->nchildren && !ret; i++) { + for (i = 0; i < node->nchildren; i++) { mime_node_t *child = mime_node_child (node, i); - ret = _mime_node_seek_dfs_walk (child, n); - if (!ret) - talloc_free (child); + mime_node_t *ret = _mime_node_seek_dfs_walk (child, n); + if (ret) + return ret; + + talloc_free (child); } - return ret; + return NULL; } mime_node_t * diff --git a/notmuch-client.h b/notmuch-client.h index 10991224..7a674873 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -83,7 +83,6 @@ typedef struct notmuch_show_params { notmuch_bool_t entire_thread; notmuch_bool_t omit_excluded; notmuch_bool_t output_body; - notmuch_bool_t raw; int part; notmuch_crypto_t crypto; notmuch_bool_t include_html; diff --git a/notmuch-count.c b/notmuch-count.c index 35a2aa70..a05b430d 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -43,7 +43,7 @@ count_files (notmuch_query_t *query) notmuch_status_t status; int count = 0; - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (print_status_query ("notmuch count", query, status)) return -1; @@ -87,18 +87,23 @@ print_count (notmuch_database_t *notmuch, const char *query_str, return -1; } - for (i = 0; i < exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, exclude_tags[i]); + for (i = 0; i < exclude_tags_length; i++) { + status = notmuch_query_add_tag_exclude (query, exclude_tags[i]); + if (status && status != NOTMUCH_STATUS_IGNORED) { + print_status_query ("notmuch count", query, status); + return -1; + } + } switch (output) { case OUTPUT_MESSAGES: - status = notmuch_query_count_messages_st (query, &ucount); + status = notmuch_query_count_messages (query, &ucount); if (print_status_query ("notmuch count", query, status)) return -1; printf ("%u", ucount); break; case OUTPUT_THREADS: - status = notmuch_query_count_threads_st (query, &ucount); + status = notmuch_query_count_threads (query, &ucount); if (print_status_query ("notmuch count", query, status)) return -1; printf ("%u", ucount); diff --git a/notmuch-dump.c b/notmuch-dump.c index e7965cea..0cbcdc16 100644 --- a/notmuch-dump.c +++ b/notmuch-dump.c @@ -240,7 +240,7 @@ database_dump_file (notmuch_database_t *notmuch, gzFile output, */ notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED); - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (print_status_query ("notmuch dump", query, status)) return EXIT_FAILURE; diff --git a/notmuch-new.c b/notmuch-new.c index 13212639..e2822e23 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -905,10 +905,9 @@ print_results (const add_files_state_t *state) state->processed_files == 1 ? "file" : "total files"); notmuch_time_print_formatted_seconds (elapsed); if (elapsed > 1) - printf (" (%d files/sec.).\033[K\n", + printf (" (%d files/sec.)", (int) (state->processed_files / elapsed)); - else - printf (".\033[K\n"); + printf (".%s\n", (state->output_is_a_tty) ? "\033[K" : ""); } if (state->added_messages) diff --git a/notmuch-reply.c b/notmuch-reply.c index 8c894974..2fa6e5a3 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -630,7 +630,7 @@ static int do_reply(notmuch_config_t *config, if (format == FORMAT_JSON || format == FORMAT_SEXP) { unsigned count; - status = notmuch_query_count_messages_st (query, &count); + status = notmuch_query_count_messages (query, &count); if (print_status_query ("notmuch reply", query, status)) return 1; @@ -645,7 +645,7 @@ static int do_reply(notmuch_config_t *config, sp = sprinter_sexp_create (config, stdout); } - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (print_status_query ("notmuch reply", query, status)) return 1; @@ -701,11 +701,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) int opt_index; notmuch_show_params_t params = { .part = -1, - .crypto = { - .verify = FALSE, - .decrypt = FALSE, - .gpgpath = NULL - } }; int format = FORMAT_DEFAULT; int reply_all = TRUE; diff --git a/notmuch-search.c b/notmuch-search.c index 8c65d5ad..019e14ee 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -123,7 +123,7 @@ do_search_threads (search_context_t *ctx) if (ctx->offset < 0) { unsigned count; notmuch_status_t status; - status = notmuch_query_count_threads_st (ctx->query, &count); + status = notmuch_query_count_threads (ctx->query, &count); if (print_status_query ("notmuch search", ctx->query, status)) return 1; @@ -132,7 +132,7 @@ do_search_threads (search_context_t *ctx) ctx->offset = 0; } - status = notmuch_query_search_threads_st (ctx->query, &threads); + status = notmuch_query_search_threads (ctx->query, &threads); if (print_status_query("notmuch search", ctx->query, status)) return 1; @@ -529,7 +529,7 @@ do_search_messages (search_context_t *ctx) if (ctx->offset < 0) { unsigned count; notmuch_status_t status; - status = notmuch_query_count_messages_st (ctx->query, &count); + status = notmuch_query_count_messages (ctx->query, &count); if (print_status_query ("notmuch search", ctx->query, status)) return 1; @@ -538,7 +538,7 @@ do_search_messages (search_context_t *ctx) ctx->offset = 0; } - status = notmuch_query_search_messages_st (ctx->query, &messages); + status = notmuch_query_search_messages (ctx->query, &messages); if (print_status_query ("notmuch search", ctx->query, status)) return 1; @@ -629,7 +629,7 @@ do_search_tags (const search_context_t *ctx) tags = notmuch_database_get_all_tags (notmuch); } else { notmuch_status_t status; - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (print_status_query ("notmuch search", query, status)) return 1; @@ -735,11 +735,19 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar if (ctx->exclude != NOTMUCH_EXCLUDE_FALSE) { const char **search_exclude_tags; size_t search_exclude_tags_length; + notmuch_status_t status; search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_length); - for (i = 0; i < search_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (ctx->query, search_exclude_tags[i]); + + for (i = 0; i < search_exclude_tags_length; i++) { + status = notmuch_query_add_tag_exclude (ctx->query, search_exclude_tags[i]); + if (status && status != NOTMUCH_STATUS_IGNORED) { + print_status_query ("notmuch search", ctx->query, status); + return EXIT_FAILURE; + } + } + notmuch_query_set_omit_excluded (ctx->query, ctx->exclude); } diff --git a/notmuch-show.c b/notmuch-show.c index 1954096d..7021008e 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -22,48 +22,6 @@ #include "gmime-filter-reply.h" #include "sprinter.h" -static notmuch_status_t -format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node, - int indent, const notmuch_show_params_t *params); - -static const notmuch_show_format_t format_text = { - .new_sprinter = sprinter_text_create, - .part = format_part_text, -}; - -static notmuch_status_t -format_part_sprinter_entry (const void *ctx, sprinter_t *sp, mime_node_t *node, - int indent, const notmuch_show_params_t *params); - -static const notmuch_show_format_t format_json = { - .new_sprinter = sprinter_json_create, - .part = format_part_sprinter_entry, -}; - -static const notmuch_show_format_t format_sexp = { - .new_sprinter = sprinter_sexp_create, - .part = format_part_sprinter_entry, -}; - -static notmuch_status_t -format_part_mbox (const void *ctx, sprinter_t *sp, mime_node_t *node, - int indent, const notmuch_show_params_t *params); - -static const notmuch_show_format_t format_mbox = { - .new_sprinter = sprinter_text_create, - .part = format_part_mbox, -}; - -static notmuch_status_t -format_part_raw (unused (const void *ctx), sprinter_t *sp, mime_node_t *node, - unused (int indent), - unused (const notmuch_show_params_t *params)); - -static const notmuch_show_format_t format_raw = { - .new_sprinter = sprinter_text_create, - .part = format_part_raw, -}; - static const char * _get_tags_as_string (const void *ctx, notmuch_message_t *message) { @@ -950,7 +908,7 @@ do_show_single (void *ctx, notmuch_status_t status; unsigned int count; - status = notmuch_query_count_messages_st (query, &count); + status = notmuch_query_count_messages (query, &count); if (print_status_query ("notmuch show", query, status)) return 1; @@ -959,7 +917,7 @@ do_show_single (void *ctx, return 1; } - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (print_status_query ("notmuch show", query, status)) return 1; @@ -989,7 +947,7 @@ do_show (void *ctx, notmuch_messages_t *messages; notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS; - status= notmuch_query_search_threads_st (query, &threads); + status= notmuch_query_search_threads (query, &threads); if (print_status_query ("notmuch show", query, status)) return 1; @@ -1029,10 +987,43 @@ enum { NOTMUCH_FORMAT_RAW }; +static const notmuch_show_format_t format_json = { + .new_sprinter = sprinter_json_create, + .part = format_part_sprinter_entry, +}; + +static const notmuch_show_format_t format_sexp = { + .new_sprinter = sprinter_sexp_create, + .part = format_part_sprinter_entry, +}; + +static const notmuch_show_format_t format_text = { + .new_sprinter = sprinter_text_create, + .part = format_part_text, +}; + +static const notmuch_show_format_t format_mbox = { + .new_sprinter = sprinter_text_create, + .part = format_part_mbox, +}; + +static const notmuch_show_format_t format_raw = { + .new_sprinter = sprinter_text_create, + .part = format_part_raw, +}; + +static const notmuch_show_format_t *formatters[] = { + [NOTMUCH_FORMAT_JSON] = &format_json, + [NOTMUCH_FORMAT_SEXP] = &format_sexp, + [NOTMUCH_FORMAT_TEXT] = &format_text, + [NOTMUCH_FORMAT_MBOX] = &format_mbox, + [NOTMUCH_FORMAT_RAW] = &format_raw, +}; + enum { - ENTIRE_THREAD_DEFAULT, - ENTIRE_THREAD_TRUE, - ENTIRE_THREAD_FALSE, + ENTIRE_THREAD_DEFAULT = -1, + ENTIRE_THREAD_FALSE = FALSE, + ENTIRE_THREAD_TRUE = TRUE, }; /* The following is to allow future options to be added more easily */ @@ -1048,25 +1039,20 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_query_t *query; char *query_string; int opt_index, ret; - const notmuch_show_format_t *format = &format_text; + const notmuch_show_format_t *formatter; sprinter_t *sprinter; notmuch_show_params_t params = { .part = -1, .omit_excluded = TRUE, .output_body = TRUE, - .crypto = { - .verify = FALSE, - .decrypt = FALSE, - .gpgpath = NULL - }, - .include_html = FALSE }; - int format_sel = NOTMUCH_FORMAT_NOT_SPECIFIED; + int format = NOTMUCH_FORMAT_NOT_SPECIFIED; int exclude = EXCLUDE_TRUE; int entire_thread = ENTIRE_THREAD_DEFAULT; + notmuch_bool_t single_message; notmuch_opt_desc_t options[] = { - { NOTMUCH_OPT_KEYWORD, &format_sel, "format", 'f', + { NOTMUCH_OPT_KEYWORD, &format, "format", 'f', (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON }, { "text", NOTMUCH_FORMAT_TEXT }, { "sexp", NOTMUCH_FORMAT_SEXP }, @@ -1102,40 +1088,25 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) if (params.crypto.decrypt) params.crypto.verify = TRUE; - if (format_sel == NOTMUCH_FORMAT_NOT_SPECIFIED) { + /* specifying a part implies single message display */ + single_message = params.part >= 0; + + if (format == NOTMUCH_FORMAT_NOT_SPECIFIED) { /* if part was requested and format was not specified, use format=raw */ if (params.part >= 0) - format_sel = NOTMUCH_FORMAT_RAW; + format = NOTMUCH_FORMAT_RAW; else - format_sel = NOTMUCH_FORMAT_TEXT; + format = NOTMUCH_FORMAT_TEXT; } - switch (format_sel) { - case NOTMUCH_FORMAT_JSON: - format = &format_json; - break; - case NOTMUCH_FORMAT_TEXT: - format = &format_text; - break; - case NOTMUCH_FORMAT_SEXP: - format = &format_sexp; - break; - case NOTMUCH_FORMAT_MBOX: + if (format == NOTMUCH_FORMAT_MBOX) { if (params.part > 0) { fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n"); return EXIT_FAILURE; } - - format = &format_mbox; - break; - case NOTMUCH_FORMAT_RAW: - format = &format_raw; - /* If --format=raw specified without specifying part, we can only - * output single message, so set part=0 */ - if (params.part < 0) - params.part = 0; - params.raw = TRUE; - break; + } else if (format == NOTMUCH_FORMAT_RAW) { + /* raw format only supports single message display */ + single_message = TRUE; } notmuch_exit_if_unsupported_format (); @@ -1143,10 +1114,12 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) /* Default is entire-thread = FALSE except for format=json and * format=sexp. */ if (entire_thread == ENTIRE_THREAD_DEFAULT) { - if (format == &format_json || format == &format_sexp) - entire_thread = ENTIRE_THREAD_TRUE; + if (format == NOTMUCH_FORMAT_JSON || format == NOTMUCH_FORMAT_SEXP) + params.entire_thread = TRUE; else - entire_thread = ENTIRE_THREAD_FALSE; + params.entire_thread = FALSE; + } else { + params.entire_thread = entire_thread; } if (!params.output_body) { @@ -1154,22 +1127,17 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) fprintf (stderr, "Warning: --body=false is incompatible with --part > 0. Disabling.\n"); params.output_body = TRUE; } else { - if (format != &format_json && format != &format_sexp) + if (format != NOTMUCH_FORMAT_JSON && format != NOTMUCH_FORMAT_SEXP) fprintf (stderr, "Warning: --body=false only implemented for format=json and format=sexp\n"); } } if (params.include_html && - (format_sel != NOTMUCH_FORMAT_JSON && format_sel != NOTMUCH_FORMAT_SEXP)) { + (format != NOTMUCH_FORMAT_JSON && format != NOTMUCH_FORMAT_SEXP)) { fprintf (stderr, "Warning: --include-html only implemented for format=json and format=sexp\n"); } - if (entire_thread == ENTIRE_THREAD_TRUE) - params.entire_thread = TRUE; - else - params.entire_thread = FALSE; - query_string = query_string_from_args (config, argc-opt_index, argv+opt_index); if (query_string == NULL) { fprintf (stderr, "Out of memory\n"); @@ -1196,32 +1164,42 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) } /* Create structure printer. */ - sprinter = format->new_sprinter(config, stdout); + formatter = formatters[format]; + sprinter = formatter->new_sprinter(config, stdout); /* If a single message is requested we do not use search_excludes. */ - if (params.part >= 0) - ret = do_show_single (config, query, format, sprinter, ¶ms); - else { + if (single_message) { + ret = do_show_single (config, query, formatter, sprinter, ¶ms); + } else { /* We always apply set the exclude flag. The * exclude=true|false option controls whether or not we return * threads that only match in an excluded message */ const char **search_exclude_tags; size_t search_exclude_tags_length; unsigned int i; + notmuch_status_t status; search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_length); - for (i = 0; i < search_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); + + for (i = 0; i < search_exclude_tags_length; i++) { + status = notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); + if (status && status != NOTMUCH_STATUS_IGNORED) { + print_status_query ("notmuch show", query, status); + ret = -1; + goto DONE; + } + } if (exclude == EXCLUDE_FALSE) { notmuch_query_set_omit_excluded (query, FALSE); params.omit_excluded = FALSE; } - ret = do_show (config, query, format, sprinter, ¶ms); + ret = do_show (config, query, formatter, sprinter, ¶ms); } + DONE: notmuch_crypto_cleanup (¶ms.crypto); notmuch_query_destroy (query); notmuch_database_destroy (notmuch); diff --git a/notmuch-tag.c b/notmuch-tag.c index 18d78ddd..9c03754d 100644 --- a/notmuch-tag.c +++ b/notmuch-tag.c @@ -121,7 +121,7 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string, /* tagging is not interested in any special sort order */ notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED); - status = notmuch_query_search_messages_st (query, &messages); + status = notmuch_query_search_messages (query, &messages); if (print_status_query ("notmuch tag", query, status)) return status; diff --git a/performance-test/M02-show.sh b/performance-test/M02-show.sh new file mode 100755 index 00000000..d73035ea --- /dev/null +++ b/performance-test/M02-show.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +test_description='show' + +. ./perf-test-lib.sh || exit 1 + +memory_start + +memory_run 'show *' "notmuch show '*' 1>/dev/null" +memory_run 'show --format=json *' "notmuch show --format=json '*' 1>/dev/null" +memory_run 'show --format=sexp *' "notmuch show --format=sexp '*' 1>/dev/null" + +memory_done diff --git a/performance-test/M03-search.sh b/performance-test/M03-search.sh new file mode 100755 index 00000000..8d026eee --- /dev/null +++ b/performance-test/M03-search.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +test_description='search' + +. ./perf-test-lib.sh || exit 1 + +memory_start + +memory_run 'search *' "notmuch search '*' 1>/dev/null" +memory_run 'search --format=json *' "notmuch search --format=json '*' 1>/dev/null" +memory_run 'search --format=sexp *' "notmuch search --format=sexp '*' 1>/dev/null" + +memory_done diff --git a/performance-test/perf-test-lib.sh b/performance-test/perf-test-lib.sh index 00d2f1c6..c89d5aab 100644 --- a/performance-test/perf-test-lib.sh +++ b/performance-test/perf-test-lib.sh @@ -149,7 +149,7 @@ memory_run () printf "[ %d ]\t%s\n" $test_count "$1" - NOTMUCH_TALLOC_REPORT="$talloc_log" valgrind --leak-check=full --log-file="$log_file" $2 + NOTMUCH_TALLOC_REPORT="$talloc_log" eval "valgrind --leak-check=full --log-file='$log_file' $2" awk '/LEAK SUMMARY/,/suppressed/ { sub(/^==[0-9]*==/," "); print }' "$log_file" echo diff --git a/test/Makefile.local b/test/Makefile.local index f8cf90d0..0df72c92 100644 --- a/test/Makefile.local +++ b/test/Makefile.local @@ -12,15 +12,15 @@ smtp_dummy_srcs = \ smtp_dummy_modules = $(smtp_dummy_srcs:.c=.o) -$(dir)/arg-test: $(dir)/arg-test.o command-line-arguments.o util/libutil.a +$(dir)/arg-test: $(dir)/arg-test.o command-line-arguments.o util/libnotmuch_util.a $(call quiet,CC) $^ -o $@ $(LDFLAGS) -$(dir)/hex-xcode: $(dir)/hex-xcode.o command-line-arguments.o util/libutil.a +$(dir)/hex-xcode: $(dir)/hex-xcode.o command-line-arguments.o util/libnotmuch_util.a $(call quiet,CC) $^ -o $@ $(LDFLAGS) $(TALLOC_LDFLAGS) random_corpus_deps = $(dir)/random-corpus.o $(dir)/database-test.o \ notmuch-config.o status.o command-line-arguments.o \ - lib/libnotmuch.a util/libutil.a \ + lib/libnotmuch.a util/libnotmuch_util.a \ parse-time-string/libparse-time-string.a $(dir)/random-corpus: $(random_corpus_deps) @@ -61,7 +61,7 @@ test-binaries: $(TEST_BINARIES) test: all test-binaries ifeq ($V,) - @echo 'Use "$(MAKE) V=1" to print test headings and PASSing results.' + @echo 'Use "$(MAKE) V=1" to see the details for passing and known broken tests.' @env NOTMUCH_TEST_QUIET=1 ${test_src_dir}/notmuch-test $(OPTIONS) else # The user has explicitly enabled quiet execution. diff --git a/test/README b/test/README index 104a120e..f2499bce 100644 --- a/test/README +++ b/test/README @@ -33,6 +33,17 @@ chosen directory to your PATH before running the tests. e.g. env PATH=/opt/gnu/bin:$PATH make test +For FreeBSD you need to install latest gdb from ports or packages and +provide path to it in TEST_GDB environment variable before executing +the tests, native FreeBSD gdb does not not work. If you install +coreutils, which provides GNU versions of basic utils like 'date' and +'base64' on FreeBSD, the test suite will use these instead of the +native ones. This provides robustness against portability issues with +these system tools. Most often the tests are written, reviewed and +tested on Linux system so such portability issues arise from time to +time. + + Running Tests ------------- The easiest way to run tests is to say "make test", (or simply run the @@ -189,16 +200,21 @@ Test harness library There are a handful helper functions defined in the test harness library for your script to use. - test_expect_success