Imported Upstream version 1.3.99.5_20131030_SE_05e5911_SYSYNC_69de386 upstream/1.3.99.5_20131030_SE_05e5911_SYSYNC_69de386
authorroot <root@pohly-mobl1.fritz.box>
Wed, 20 Nov 2013 15:20:38 +0000 (15:20 +0000)
committerroot <root@pohly-mobl1.fritz.box>
Wed, 20 Nov 2013 15:20:38 +0000 (15:20 +0000)
62 files changed:
Makefile.am
Makefile.in
NEWS
README
config.h.in
configure
configure.ac
src/backends/activesync/configure-sub.in
src/backends/evolution/EvolutionContactSource.cpp
src/backends/evolution/EvolutionSyncSource.cpp
src/backends/evolution/configure-sub.in
src/dbus/server/localed-listener.cpp [new file with mode: 0644]
src/dbus/server/localed-listener.h [new file with mode: 0644]
src/dbus/server/main.cpp
src/dbus/server/org.syncevolution.service.in
src/dbus/server/pim/README
src/dbus/server/pim/folks.cpp
src/dbus/server/pim/folks.h
src/dbus/server/pim/full-view.cpp
src/dbus/server/pim/full-view.h
src/dbus/server/pim/locale-factory-boost.cpp
src/dbus/server/pim/locale-factory.cpp
src/dbus/server/pim/locale-factory.h
src/dbus/server/pim/manager.cpp
src/dbus/server/pim/manager.h
src/dbus/server/pim/org._01.pim.contacts.service.in
src/dbus/server/pim/testpim.py
src/dbus/server/presence-status.h
src/dbus/server/server.am
src/dbus/server/session-helper.cpp
src/dbus/server/session-helper.h
src/dbus/server/session.cpp
src/dbus/server/sync-helper.cpp
src/dbus/server/syncevo-dbus-server-startup.sh.in
src/syncevo/EDSClient.cpp
src/syncevo/EDSClient.h
src/syncevo/GLibSupport.h
src/syncevo/LocalTransportAgent.cpp
src/syncevo/LogDLT.cpp [new file with mode: 0644]
src/syncevo/LogDLT.h [new file with mode: 0644]
src/syncevo/LogRedirect.cpp
src/syncevo/LogStdout.cpp
src/syncevo/Logging.cpp
src/syncevo/Logging.h
src/syncevo/SyncContext.cpp
src/syncevo/SyncSource.cpp
src/syncevo/eds_abi_wrapper.cpp
src/syncevo/eds_abi_wrapper.h
src/syncevo/syncevo.am
src/synthesis-includes/Makefile.in
src/synthesis/ChangeLog
src/synthesis/Makefile.in
src/synthesis/README.DLT [new file with mode: 0644]
src/synthesis/config.h.in
src/synthesis/configure
src/synthesis/configure.in
src/synthesis/src/Makefile.am
src/synthesis/src/Makefile.am.in
src/synthesis/src/Makefile.in
src/synthesis/src/platform_adapters/linux/configfiles.cpp
src/synthesis/src/sysync/debuglogger.cpp
src/synthesis/src/sysync/debuglogger.h

index 9be9aec..ed83c92 100644 (file)
@@ -68,6 +68,13 @@ DEV_FILE_PATTERN = $(1)$(2)/include $(1)$(2)/lib/*.so $(1)$(2)/lib/*.a $(1)$(2)/
 # be packaged separately.
 DEV_FILE_PATTERN += $(1)$(2)/lib/syncevolution/backends/syncactivesync.so
 
 # be packaged separately.
 DEV_FILE_PATTERN += $(1)$(2)/lib/syncevolution/backends/syncactivesync.so
 
+# It is possible to have additional .so backend files included in the
+# binary archives. The additional backend files must be named in the
+# EXTRA_BACKENDS env or make variable with their full file paths,
+# separated by spaces. They will be renamed to <basename>-2.so. See
+# also ScannedBackends in SyncSource.cpp.
+ADD_EXTRA_BACKENDS = set -e; for i in $(EXTRA_BACKENDS); do cp $$i $(1)/$(BACKENDS_DIRECTORY)/`basename $$i .so`-2.so; done
+
 # binary distribution as .tar.gz
 if COND_DBUS
 # when building with D-Bus, we have no choice: the service has to go into /usr
 # binary distribution as .tar.gz
 if COND_DBUS
 # when building with D-Bus, we have no choice: the service has to go into /usr
@@ -83,6 +90,7 @@ distbin : $(distbin_docs) INSTALL-tar-gz all
        mkdir -p $(distdir)/usr/share/doc/syncevolution
        cp $(srcdir)/INSTALL-tar-gz $(distdir)/INSTALL
        cp $(filter-out all, $+) $(distdir)/usr/share/doc/syncevolution
        mkdir -p $(distdir)/usr/share/doc/syncevolution
        cp $(srcdir)/INSTALL-tar-gz $(distdir)/INSTALL
        cp $(filter-out all, $+) $(distdir)/usr/share/doc/syncevolution
+       $(call ADD_EXTRA_BACKENDS, $(distdir))
        tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
        rm -rf $(distdir)
 else
        tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
        rm -rf $(distdir)
 else
@@ -96,6 +104,7 @@ distbin : $(distbin_docs) all
        rm -rf $(call DEV_FILE_PATTERN,$(distdir),/)
        for i in `find $(distdir) -type d | sort -r`; do rmdir $$i 2>/dev/null || true; done
        cp $(filter-out all, $+) $(distdir)
        rm -rf $(call DEV_FILE_PATTERN,$(distdir),/)
        for i in `find $(distdir) -type d | sort -r`; do rmdir $$i 2>/dev/null || true; done
        cp $(filter-out all, $+) $(distdir)
+       $(call ADD_EXTRA_BACKENDS, $(distdir))
        tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
        rm -rf $(distdir)
 endif
        tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
        rm -rf $(distdir)
 endif
@@ -250,6 +259,7 @@ checkinstall/dist/$(distdir): all
        rm -rf $@
        $(MAKE) install DESTDIR=`pwd`/$@
        $(MAKE) installcheck DESTDIR=`pwd`/$@
        rm -rf $@
        $(MAKE) install DESTDIR=`pwd`/$@
        $(MAKE) installcheck DESTDIR=`pwd`/$@
+       $(call ADD_EXTRA_BACKENDS, $@)
        rm -rf $(call DEV_FILE_PATTERN,$@,/usr)
 clean-local: clean_dist
 clean_dist:
        rm -rf $(call DEV_FILE_PATTERN,$@,/usr)
 clean-local: clean_dist
 clean_dist:
@@ -298,10 +308,12 @@ if ENABLE_EVOLUTION_COMPATIBILITY
 # (relevant in that case and for static builds) for dependencies on
 # problematic libraries and symbols
 #
 # (relevant in that case and for static builds) for dependencies on
 # problematic libraries and symbols
 #
+# Exclude *-2.so, these are EXTRA_BACKENDS for which other rules apply.
+#
 # ical_strdup is an exception because it is in SyncEvolution.
 all_local_installchecks += toplevel_so_check
 toplevel_so_check:
 # ical_strdup is an exception because it is in SyncEvolution.
 all_local_installchecks += toplevel_so_check
 toplevel_so_check:
-       for i in `find $(DESTDIR)/$(libdir)/syncevolution $(DESTDIR)/$(libdir)/libsyncevo* $(DESTDIR)/$(libdir)/libsynthesis* -name *.so` $(DESTDIR)/$(bindir)/syncevolution; \
+       for i in `find $(DESTDIR)/$(libdir)/syncevolution $(DESTDIR)/$(libdir)/libsyncevo* $(DESTDIR)/$(libdir)/libsynthesis* -name *.so | grep -v -2.so` $(DESTDIR)/$(bindir)/syncevolution; \
        do \
          if objdump -T -C $$i | grep -v :: | grep '\*UND\*' | sort | grep -v -w ical_strdup | grep -e ical -e " e_"; then \
            echo "$$i should not depend on EDS, libical or libbluetooth"; \
        do \
          if objdump -T -C $$i | grep -v :: | grep '\*UND\*' | sort | grep -v -w ical_strdup | grep -e ical -e " e_"; then \
            echo "$$i should not depend on EDS, libical or libbluetooth"; \
@@ -406,8 +418,15 @@ dist-hook: $(all_dist_hooks)
 # Force sequential installation. This is a workaround for relinking failures
 # during concurrent distcheck (a backend was relinked against not yet installed
 # libsyncevolution.la).
 # Force sequential installation. This is a workaround for relinking failures
 # during concurrent distcheck (a backend was relinked against not yet installed
 # libsyncevolution.la).
+#
+# Also used to add additional backends.
 install-am: all-am
        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am
        @$(MAKE) $(AM_MAKEFLAGS) install-data-am
 install-am: all-am
        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am
        @$(MAKE) $(AM_MAKEFLAGS) install-data-am
+       for i in $(EXTRA_BACKENDS); do $(INSTALL) $$i $(DESTDIR)/$(BACKENDS_DIRECTORY)/`basename $$i .so`-2.so; done
+
+# Necessary for "make distcheck": must not leave files behind.
+uninstall-local:
+       rm -f $(DESTDIR)/$(BACKENDS_DIRECTORY)/*-2.so
 
 .DELETE_ON_ERROR:
 
 .DELETE_ON_ERROR:
index 1ef31b3..2fab6cd 100644 (file)
@@ -372,7 +372,7 @@ EXTRA_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 
 @COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_66 = $(DBUS_PIM_PLUGIN_LDFLAGS)
 @COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_67 = $(FOLKS_LIBS) $(DBUS_PIM_PLUGIN_LIBS) $(PHONENUMBERS_LIBS)
 
 @COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_66 = $(DBUS_PIM_PLUGIN_LDFLAGS)
 @COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_67 = $(FOLKS_LIBS) $(DBUS_PIM_PLUGIN_LIBS) $(PHONENUMBERS_LIBS)
-@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_68 = $(FOLKS_CFLAGS) $(DBUS_PIM_PLUGIN_CFLAGS) $(PHONENUMBERS_CFLAGS)
+@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_68 = $(FOLKS_CFLAGS) $(DBUS_PIM_PLUGIN_CFLAGS) $(PHONENUMBERS_CFLAGS) $(DLT_CFLAGS)
 
 # Need to list all plugins here and not include the active one in the regular
 # source list above, because "make dist" would only include the configured one.
 
 # Need to list all plugins here and not include the active one in the regular
 # source list above, because "make dist" would only include the configured one.
@@ -508,6 +508,8 @@ EXTRA_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 # (relevant in that case and for static builds) for dependencies on
 # problematic libraries and symbols
 #
 # (relevant in that case and for static builds) for dependencies on
 # problematic libraries and symbols
 #
+# Exclude *-2.so, these are EXTRA_BACKENDS for which other rules apply.
+#
 # ical_strdup is an exception because it is in SyncEvolution.
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@am__append_106 = toplevel_so_check
 # libneon is intentionally not linked against, to choose between
 # ical_strdup is an exception because it is in SyncEvolution.
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@am__append_106 = toplevel_so_check
 # libneon is intentionally not linked against, to choose between
@@ -1060,7 +1062,8 @@ am__src_dbus_server_libsyncevodbusserver_la_SOURCES_DIST =  \
        src/dbus/server/connection.h src/dbus/server/connman-client.h \
        src/dbus/server/dbus-callbacks.h \
        src/dbus/server/dbus-user-interface.h \
        src/dbus/server/connection.h src/dbus/server/connman-client.h \
        src/dbus/server/dbus-callbacks.h \
        src/dbus/server/dbus-user-interface.h \
-       src/dbus/server/exceptions.h src/dbus/server/info-req.h \
+       src/dbus/server/exceptions.h \
+       src/dbus/server/localed-listener.h src/dbus/server/info-req.h \
        src/dbus/server/network-manager-client.h \
        src/dbus/server/presence-status.h \
        src/dbus/server/progress-data.h \
        src/dbus/server/network-manager-client.h \
        src/dbus/server/presence-status.h \
        src/dbus/server/progress-data.h \
@@ -1092,7 +1095,9 @@ am__src_dbus_server_libsyncevodbusserver_la_SOURCES_DIST =  \
        src/dbus/server/connman-client.cpp \
        src/dbus/server/dbus-callbacks.cpp \
        src/dbus/server/dbus-user-interface.cpp \
        src/dbus/server/connman-client.cpp \
        src/dbus/server/dbus-callbacks.cpp \
        src/dbus/server/dbus-user-interface.cpp \
-       src/dbus/server/exceptions.cpp src/dbus/server/info-req.cpp \
+       src/dbus/server/exceptions.cpp \
+       src/dbus/server/localed-listener.cpp \
+       src/dbus/server/info-req.cpp \
        src/dbus/server/network-manager-client.cpp \
        src/dbus/server/presence-status.cpp \
        src/dbus/server/progress-data.cpp \
        src/dbus/server/network-manager-client.cpp \
        src/dbus/server/presence-status.cpp \
        src/dbus/server/progress-data.cpp \
@@ -1128,6 +1133,7 @@ am__src_dbus_server_libsyncevodbusserver_la_SOURCES_DIST =  \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-dbus-callbacks.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-dbus-user-interface.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-dbus-callbacks.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-dbus-user-interface.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo \
+@COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-network-manager-client.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-presence-status.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-network-manager-client.lo \
 @COND_DBUS_TRUE@       src/dbus/server/src_dbus_server_libsyncevodbusserver_la-presence-status.lo \
@@ -1228,7 +1234,8 @@ am__src_syncevo_libsyncevolution_la_SOURCES_DIST =  \
        src/syncevo/ThreadSupport.h src/syncevo/SyncML.h \
        src/syncevo/SyncML.cpp src/syncevo/SynthesisEngine.h \
        src/syncevo/SynthesisEngine.cpp src/syncevo/Logging.h \
        src/syncevo/ThreadSupport.h src/syncevo/SyncML.h \
        src/syncevo/SyncML.cpp src/syncevo/SynthesisEngine.h \
        src/syncevo/SynthesisEngine.cpp src/syncevo/Logging.h \
-       src/syncevo/Logging.cpp src/syncevo/LogStdout.h \
+       src/syncevo/Logging.cpp src/syncevo/LogDLT.h \
+       src/syncevo/LogDLT.cpp src/syncevo/LogStdout.h \
        src/syncevo/LogStdout.cpp src/syncevo/LogRedirect.h \
        src/syncevo/LogRedirect.cpp src/syncevo/LogSyslog.h \
        src/syncevo/LogSyslog.cpp src/syncevo/TransportAgent.h \
        src/syncevo/LogStdout.cpp src/syncevo/LogRedirect.h \
        src/syncevo/LogRedirect.cpp src/syncevo/LogSyslog.h \
        src/syncevo/LogSyslog.cpp src/syncevo/TransportAgent.h \
@@ -1281,6 +1288,7 @@ am__src_syncevo_libsyncevolution_la_SOURCES_DIST =  \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-SyncML.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-SynthesisEngine.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-SyncML.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-SynthesisEngine.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo \
+@COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogRedirect.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogSyslog.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogRedirect.lo \
 @COND_CORE_TRUE@       src/syncevo/src_syncevo_libsyncevolution_la-LogSyslog.lo \
@@ -2224,13 +2232,13 @@ DBUS_SERVICES_DIR = @DBUS_SERVICES_DIR@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLLTOOL = @DLLTOOL@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLLTOOL = @DLLTOOL@
+DLT_CFLAGS = @DLT_CFLAGS@
+DLT_LIBS = @DLT_LIBS@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 EASCLIENT_CFLAGS = @EASCLIENT_CFLAGS@
 EASCLIENT_DEPENDENCIES = @EASCLIENT_DEPENDENCIES@
 EASCLIENT_LIBS = @EASCLIENT_LIBS@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 EASCLIENT_CFLAGS = @EASCLIENT_CFLAGS@
 EASCLIENT_DEPENDENCIES = @EASCLIENT_DEPENDENCIES@
 EASCLIENT_LIBS = @EASCLIENT_LIBS@
-EBOOKCONTACTS_CFLAGS = @EBOOKCONTACTS_CFLAGS@
-EBOOKCONTACTS_LIBS = @EBOOKCONTACTS_LIBS@
 EBOOK_CFLAGS = @EBOOK_CFLAGS@
 EBOOK_LIBS = @EBOOK_LIBS@
 EBOOK_VERSION_CFLAGS = @EBOOK_VERSION_CFLAGS@
 EBOOK_CFLAGS = @EBOOK_CFLAGS@
 EBOOK_LIBS = @EBOOK_LIBS@
 EBOOK_VERSION_CFLAGS = @EBOOK_VERSION_CFLAGS@
@@ -2405,6 +2413,7 @@ SYNCEVOLUTION_CXXFLAGS = @SYNCEVOLUTION_CXXFLAGS@
 SYNCEVOLUTION_LDADD = @SYNCEVOLUTION_LDADD@ $(am__append_83)
 SYNCEVOLUTION_LIBS = @SYNCEVOLUTION_LIBS@
 SYNCEVOLUTION_LOCALEDIR = @SYNCEVOLUTION_LOCALEDIR@
 SYNCEVOLUTION_LDADD = @SYNCEVOLUTION_LDADD@ $(am__append_83)
 SYNCEVOLUTION_LIBS = @SYNCEVOLUTION_LIBS@
 SYNCEVOLUTION_LOCALEDIR = @SYNCEVOLUTION_LOCALEDIR@
+SYNCEVO_DBUS_SERVER_ARGS = @SYNCEVO_DBUS_SERVER_ARGS@
 SYNCEVO_WFLAGS = @SYNCEVO_WFLAGS@
 SYNCSOURCES = @SYNCSOURCES@
 SYNTHESIS = @SYNTHESIS@
 SYNCEVO_WFLAGS = @SYNCEVO_WFLAGS@
 SYNCSOURCES = @SYNCSOURCES@
 SYNTHESIS = @SYNTHESIS@
@@ -2751,6 +2760,7 @@ src_cppflags = -I$(top_srcdir)/src $(am__append_3) $(am__append_8) \
 @COND_CORE_TRUE@       src/syncevo/SynthesisEngine.h \
 @COND_CORE_TRUE@       src/syncevo/SynthesisEngine.cpp \
 @COND_CORE_TRUE@       src/syncevo/Logging.h src/syncevo/Logging.cpp \
 @COND_CORE_TRUE@       src/syncevo/SynthesisEngine.h \
 @COND_CORE_TRUE@       src/syncevo/SynthesisEngine.cpp \
 @COND_CORE_TRUE@       src/syncevo/Logging.h src/syncevo/Logging.cpp \
+@COND_CORE_TRUE@       src/syncevo/LogDLT.h src/syncevo/LogDLT.cpp \
 @COND_CORE_TRUE@       src/syncevo/LogStdout.h \
 @COND_CORE_TRUE@       src/syncevo/LogStdout.cpp \
 @COND_CORE_TRUE@       src/syncevo/LogRedirect.h \
 @COND_CORE_TRUE@       src/syncevo/LogStdout.h \
 @COND_CORE_TRUE@       src/syncevo/LogStdout.cpp \
 @COND_CORE_TRUE@       src/syncevo/LogRedirect.h \
@@ -2851,7 +2861,8 @@ src_cppflags = -I$(top_srcdir)/src $(am__append_3) $(am__append_8) \
 @COND_CORE_TRUE@       @EPACKAGE_LIBS@ @GIO_LIBS@ @GTHREAD_LIBS@ \
 @COND_CORE_TRUE@       @GLIB_LIBS@ $(SYNTHESIS_LIBS) $(PCRECPP_LIBS) \
 @COND_CORE_TRUE@       $(TRANSPORT_LIBS) @LIBS@ $(src_syncevo_ldadd) \
 @COND_CORE_TRUE@       @EPACKAGE_LIBS@ @GIO_LIBS@ @GTHREAD_LIBS@ \
 @COND_CORE_TRUE@       @GLIB_LIBS@ $(SYNTHESIS_LIBS) $(PCRECPP_LIBS) \
 @COND_CORE_TRUE@       $(TRANSPORT_LIBS) @LIBS@ $(src_syncevo_ldadd) \
-@COND_CORE_TRUE@       $(DBUS_LIBS) $(NSS_LIBS) $(am__append_27)
+@COND_CORE_TRUE@       $(DLT_LIBS) $(DBUS_LIBS) $(NSS_LIBS) \
+@COND_CORE_TRUE@       $(am__append_27)
 @COND_CORE_TRUE@src_syncevo_libsyncevolution_la_CXXFLAGS = \
 @COND_CORE_TRUE@  $(PCRECPP_CFLAGS) \
 @COND_CORE_TRUE@  $(TRANSPORT_CFLAGS) \
 @COND_CORE_TRUE@src_syncevo_libsyncevolution_la_CXXFLAGS = \
 @COND_CORE_TRUE@  $(PCRECPP_CFLAGS) \
 @COND_CORE_TRUE@  $(TRANSPORT_CFLAGS) \
@@ -2865,13 +2876,14 @@ src_cppflags = -I$(top_srcdir)/src $(am__append_3) $(am__append_8) \
 
 @COND_CORE_TRUE@src_syncevo_libsyncevolution_la_CPPFLAGS = \
 @COND_CORE_TRUE@  $(src_syncevo_cppflags) \
 
 @COND_CORE_TRUE@src_syncevo_libsyncevolution_la_CPPFLAGS = \
 @COND_CORE_TRUE@  $(src_syncevo_cppflags) \
+@COND_CORE_TRUE@  $(DLT_CFLAGS) \
 @COND_CORE_TRUE@  $(DBUS_CFLAGS) \
 @COND_CORE_TRUE@  -DDATA_DIR=\""$(pkgdatadir)"\" \
 @COND_CORE_TRUE@  -DXML_CONFIG_DIR=\""$(datadir)/syncevolution/xml"\" \
 @COND_CORE_TRUE@  -DTEMPLATE_DIR=\""$(datadir)/syncevolution/templates"\" \
 @COND_CORE_TRUE@  -DLIBDIR=\""$(libdir)"\"
 
 @COND_CORE_TRUE@  $(DBUS_CFLAGS) \
 @COND_CORE_TRUE@  -DDATA_DIR=\""$(pkgdatadir)"\" \
 @COND_CORE_TRUE@  -DXML_CONFIG_DIR=\""$(datadir)/syncevolution/xml"\" \
 @COND_CORE_TRUE@  -DTEMPLATE_DIR=\""$(datadir)/syncevolution/templates"\" \
 @COND_CORE_TRUE@  -DLIBDIR=\""$(libdir)"\"
 
-@COND_CORE_TRUE@src_syncevo_libsyncevolution_la_DEPENDENCIES = $(SYNTHESIS_DEP) $(src_syncevo_ldadd)
+@COND_CORE_TRUE@src_syncevo_libsyncevolution_la_DEPENDENCIES = $(SYNTHESIS_DEP) $(filter %.la, $(src_syncevo_ldadd))
 @COND_CORE_TRUE@@ENABLE_MODULES_FALSE@src_syncevo_libsyncevolution_la_LDFLAGS = -static
 @COND_CORE_TRUE@@ENABLE_MODULES_TRUE@src_syncevo_libsyncevolution_la_LDFLAGS = 
 
 @COND_CORE_TRUE@@ENABLE_MODULES_FALSE@src_syncevo_libsyncevolution_la_LDFLAGS = -static
 @COND_CORE_TRUE@@ENABLE_MODULES_TRUE@src_syncevo_libsyncevolution_la_LDFLAGS = 
 
@@ -3286,6 +3298,7 @@ src_cppflags = -I$(top_srcdir)/src $(am__append_3) $(am__append_8) \
 @COND_DBUS_TRUE@       src/dbus/server/dbus-callbacks.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/dbus-user-interface.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/exceptions.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/dbus-callbacks.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/dbus-user-interface.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/exceptions.cpp \
+@COND_DBUS_TRUE@       src/dbus/server/localed-listener.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/info-req.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/network-manager-client.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/presence-status.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/info-req.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/network-manager-client.cpp \
 @COND_DBUS_TRUE@       src/dbus/server/presence-status.cpp \
@@ -3636,6 +3649,13 @@ TEST_README_FILES = $(wildcard $(top_srcdir)/test/README.*)
 DEV_FILE_PATTERN = $(1)$(2)/include $(1)$(2)/lib/*.so $(1)$(2)/lib/*.a \
        $(1)$(2)/lib/*.la $(1)$(2)/lib/*/*.la $(1)$(2)/lib/pkgconfig \
        $(1)$(2)/lib/syncevolution/backends/syncactivesync.so
 DEV_FILE_PATTERN = $(1)$(2)/include $(1)$(2)/lib/*.so $(1)$(2)/lib/*.a \
        $(1)$(2)/lib/*.la $(1)$(2)/lib/*/*.la $(1)$(2)/lib/pkgconfig \
        $(1)$(2)/lib/syncevolution/backends/syncactivesync.so
+
+# It is possible to have additional .so backend files included in the
+# binary archives. The additional backend files must be named in the
+# EXTRA_BACKENDS env or make variable with their full file paths,
+# separated by spaces. They will be renamed to <basename>-2.so. See
+# also ScannedBackends in SyncSource.cpp.
+ADD_EXTRA_BACKENDS = set -e; for i in $(EXTRA_BACKENDS); do cp $$i $(1)/$(BACKENDS_DIRECTORY)/`basename $$i .so`-2.so; done
 IPHONE_FILENAME = syncevolution-$(VERSION)-iphone.zip
 TYPE_deb = -D
 TYPE_rpm = -R
 IPHONE_FILENAME = syncevolution-$(VERSION)-iphone.zip
 TYPE_deb = -D
 TYPE_rpm = -R
@@ -4696,6 +4716,9 @@ src/dbus/server/src_dbus_server_libsyncevodbusserver_la-dbus-user-interface.lo:
 src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo:  \
        src/dbus/server/$(am__dirstamp) \
        src/dbus/server/$(DEPDIR)/$(am__dirstamp)
 src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo:  \
        src/dbus/server/$(am__dirstamp) \
        src/dbus/server/$(DEPDIR)/$(am__dirstamp)
+src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo:  \
+       src/dbus/server/$(am__dirstamp) \
+       src/dbus/server/$(DEPDIR)/$(am__dirstamp)
 src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo:  \
        src/dbus/server/$(am__dirstamp) \
        src/dbus/server/$(DEPDIR)/$(am__dirstamp)
 src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo:  \
        src/dbus/server/$(am__dirstamp) \
        src/dbus/server/$(DEPDIR)/$(am__dirstamp)
@@ -4831,6 +4854,9 @@ src/syncevo/src_syncevo_libsyncevolution_la-SynthesisEngine.lo:  \
 src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo:  \
        src/syncevo/$(am__dirstamp) \
        src/syncevo/$(DEPDIR)/$(am__dirstamp)
 src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo:  \
        src/syncevo/$(am__dirstamp) \
        src/syncevo/$(DEPDIR)/$(am__dirstamp)
+src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo:  \
+       src/syncevo/$(am__dirstamp) \
+       src/syncevo/$(DEPDIR)/$(am__dirstamp)
 src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo:  \
        src/syncevo/$(am__dirstamp) \
        src/syncevo/$(DEPDIR)/$(am__dirstamp)
 src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo:  \
        src/syncevo/$(am__dirstamp) \
        src/syncevo/$(DEPDIR)/$(am__dirstamp)
@@ -5872,6 +5898,8 @@ mostlyclean-compile:
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.$(OBJEXT)
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.$(OBJEXT)
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo
+       -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.$(OBJEXT)
+       -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-main.$(OBJEXT)
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-main.lo
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-network-manager-client.$(OBJEXT)
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-main.$(OBJEXT)
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-main.lo
        -rm -f src/dbus/server/src_dbus_server_libsyncevodbusserver_la-network-manager-client.$(OBJEXT)
@@ -5974,6 +6002,8 @@ mostlyclean-compile:
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-IniConfigNode.lo
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LocalTransportAgent.$(OBJEXT)
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LocalTransportAgent.lo
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-IniConfigNode.lo
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LocalTransportAgent.$(OBJEXT)
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LocalTransportAgent.lo
+       -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.$(OBJEXT)
+       -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogRedirect.$(OBJEXT)
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogRedirect.lo
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.$(OBJEXT)
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogRedirect.$(OBJEXT)
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogRedirect.lo
        -rm -f src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.$(OBJEXT)
@@ -6192,6 +6222,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-dbus-user-interface.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-exceptions.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-dbus-user-interface.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-exceptions.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-localed-listener.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-main.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-network-manager-client.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-notification-backend-libnotify.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-main.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-network-manager-client.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-notification-backend-libnotify.Plo@am__quote@
@@ -6269,6 +6300,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-IdentityProvider.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-IniConfigNode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LocalTransportAgent.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-IdentityProvider.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-IniConfigNode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LocalTransportAgent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogDLT.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogRedirect.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogSyslog.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogRedirect.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogSyslog.Plo@am__quote@
@@ -7302,6 +7334,13 @@ src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo: src/dbus/
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_dbus_server_libsyncevodbusserver_la_CPPFLAGS) $(CPPFLAGS) $(src_dbus_server_libsyncevodbusserver_la_CXXFLAGS) $(CXXFLAGS) -c -o src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo `test -f 'src/dbus/server/exceptions.cpp' || echo '$(srcdir)/'`src/dbus/server/exceptions.cpp
 
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_dbus_server_libsyncevodbusserver_la_CPPFLAGS) $(CPPFLAGS) $(src_dbus_server_libsyncevodbusserver_la_CXXFLAGS) $(CXXFLAGS) -c -o src/dbus/server/src_dbus_server_libsyncevodbusserver_la-exceptions.lo `test -f 'src/dbus/server/exceptions.cpp' || echo '$(srcdir)/'`src/dbus/server/exceptions.cpp
 
+src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo: src/dbus/server/localed-listener.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_dbus_server_libsyncevodbusserver_la_CPPFLAGS) $(CPPFLAGS) $(src_dbus_server_libsyncevodbusserver_la_CXXFLAGS) $(CXXFLAGS) -MT src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo -MD -MP -MF src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-localed-listener.Tpo -c -o src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo `test -f 'src/dbus/server/localed-listener.cpp' || echo '$(srcdir)/'`src/dbus/server/localed-listener.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-localed-listener.Tpo src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-localed-listener.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/dbus/server/localed-listener.cpp' object='src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_dbus_server_libsyncevodbusserver_la_CPPFLAGS) $(CPPFLAGS) $(src_dbus_server_libsyncevodbusserver_la_CXXFLAGS) $(CXXFLAGS) -c -o src/dbus/server/src_dbus_server_libsyncevodbusserver_la-localed-listener.lo `test -f 'src/dbus/server/localed-listener.cpp' || echo '$(srcdir)/'`src/dbus/server/localed-listener.cpp
+
 src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo: src/dbus/server/info-req.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_dbus_server_libsyncevodbusserver_la_CPPFLAGS) $(CPPFLAGS) $(src_dbus_server_libsyncevodbusserver_la_CXXFLAGS) $(CXXFLAGS) -MT src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo -MD -MP -MF src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Tpo -c -o src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo `test -f 'src/dbus/server/info-req.cpp' || echo '$(srcdir)/'`src/dbus/server/info-req.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Tpo src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Plo
 src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo: src/dbus/server/info-req.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_dbus_server_libsyncevodbusserver_la_CPPFLAGS) $(CPPFLAGS) $(src_dbus_server_libsyncevodbusserver_la_CXXFLAGS) $(CXXFLAGS) -MT src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo -MD -MP -MF src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Tpo -c -o src/dbus/server/src_dbus_server_libsyncevodbusserver_la-info-req.lo `test -f 'src/dbus/server/info-req.cpp' || echo '$(srcdir)/'`src/dbus/server/info-req.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Tpo src/dbus/server/$(DEPDIR)/src_dbus_server_libsyncevodbusserver_la-info-req.Plo
@@ -7505,6 +7544,13 @@ src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo: src/syncevo/Logging.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_syncevo_libsyncevolution_la_CPPFLAGS) $(CPPFLAGS) $(src_syncevo_libsyncevolution_la_CXXFLAGS) $(CXXFLAGS) -c -o src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo `test -f 'src/syncevo/Logging.cpp' || echo '$(srcdir)/'`src/syncevo/Logging.cpp
 
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_syncevo_libsyncevolution_la_CPPFLAGS) $(CPPFLAGS) $(src_syncevo_libsyncevolution_la_CXXFLAGS) $(CXXFLAGS) -c -o src/syncevo/src_syncevo_libsyncevolution_la-Logging.lo `test -f 'src/syncevo/Logging.cpp' || echo '$(srcdir)/'`src/syncevo/Logging.cpp
 
+src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo: src/syncevo/LogDLT.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_syncevo_libsyncevolution_la_CPPFLAGS) $(CPPFLAGS) $(src_syncevo_libsyncevolution_la_CXXFLAGS) $(CXXFLAGS) -MT src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo -MD -MP -MF src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogDLT.Tpo -c -o src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo `test -f 'src/syncevo/LogDLT.cpp' || echo '$(srcdir)/'`src/syncevo/LogDLT.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogDLT.Tpo src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogDLT.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/syncevo/LogDLT.cpp' object='src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_syncevo_libsyncevolution_la_CPPFLAGS) $(CPPFLAGS) $(src_syncevo_libsyncevolution_la_CXXFLAGS) $(CXXFLAGS) -c -o src/syncevo/src_syncevo_libsyncevolution_la-LogDLT.lo `test -f 'src/syncevo/LogDLT.cpp' || echo '$(srcdir)/'`src/syncevo/LogDLT.cpp
+
 src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo: src/syncevo/LogStdout.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_syncevo_libsyncevolution_la_CPPFLAGS) $(CPPFLAGS) $(src_syncevo_libsyncevolution_la_CXXFLAGS) $(CXXFLAGS) -MT src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo -MD -MP -MF src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Tpo -c -o src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo `test -f 'src/syncevo/LogStdout.cpp' || echo '$(srcdir)/'`src/syncevo/LogStdout.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Tpo src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Plo
 src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo: src/syncevo/LogStdout.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_syncevo_libsyncevolution_la_CPPFLAGS) $(CPPFLAGS) $(src_syncevo_libsyncevolution_la_CXXFLAGS) $(CXXFLAGS) -MT src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo -MD -MP -MF src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Tpo -c -o src/syncevo/src_syncevo_libsyncevolution_la-LogStdout.lo `test -f 'src/syncevo/LogStdout.cpp' || echo '$(srcdir)/'`src/syncevo/LogStdout.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Tpo src/syncevo/$(DEPDIR)/src_syncevo_libsyncevolution_la-LogStdout.Plo
@@ -10741,7 +10787,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
        uninstall-dist_src_testcases_templates_clients_phone_nokia_s40DATA \
        uninstall-docDATA uninstall-libLTLIBRARIES \
        uninstall-libexecPROGRAMS uninstall-libexecSCRIPTS \
        uninstall-dist_src_testcases_templates_clients_phone_nokia_s40DATA \
        uninstall-docDATA uninstall-libLTLIBRARIES \
        uninstall-libexecPROGRAMS uninstall-libexecSCRIPTS \
-       uninstall-man uninstall-nodist_accounts_providersDATA \
+       uninstall-local uninstall-man \
+       uninstall-nodist_accounts_providersDATA \
        uninstall-nodist_accounts_servicesDATA \
        uninstall-nodist_binSCRIPTS \
        uninstall-nodist_src_dbus_qt_libsyncevolution_qt_dbus_includeHEADERS \
        uninstall-nodist_accounts_servicesDATA \
        uninstall-nodist_binSCRIPTS \
        uninstall-nodist_src_dbus_qt_libsyncevolution_qt_dbus_includeHEADERS \
@@ -10900,7 +10947,7 @@ uninstall-man: uninstall-man1
        uninstall-dist_src_testcases_templates_clients_phone_nokia_s40DATA \
        uninstall-docDATA uninstall-libLTLIBRARIES \
        uninstall-libexecPROGRAMS uninstall-libexecSCRIPTS \
        uninstall-dist_src_testcases_templates_clients_phone_nokia_s40DATA \
        uninstall-docDATA uninstall-libLTLIBRARIES \
        uninstall-libexecPROGRAMS uninstall-libexecSCRIPTS \
-       uninstall-man uninstall-man1 \
+       uninstall-local uninstall-man uninstall-man1 \
        uninstall-nodist_accounts_providersDATA \
        uninstall-nodist_accounts_servicesDATA \
        uninstall-nodist_binSCRIPTS \
        uninstall-nodist_accounts_providersDATA \
        uninstall-nodist_accounts_servicesDATA \
        uninstall-nodist_binSCRIPTS \
@@ -11159,11 +11206,11 @@ src/dbus/interfaces/%.xml: src/dbus/interfaces/%-full.xml src/dbus/interfaces/.s
 @ENABLE_QT_DBUS_TRUE@  && perl -pi -e 's/SYNCEVO-(\w*)-FULL_H/SYNCEVO_$$1_FULL_H/' src/dbus/qt/syncevo-$*-full.* \
 @ENABLE_QT_DBUS_TRUE@  && echo 'timestamp' >$@
 @COND_DBUS_TRUE@$(src_dbus_server_script): $(src_dbus_server_script_in)
 @ENABLE_QT_DBUS_TRUE@  && perl -pi -e 's/SYNCEVO-(\w*)-FULL_H/SYNCEVO_$$1_FULL_H/' src/dbus/qt/syncevo-$*-full.* \
 @ENABLE_QT_DBUS_TRUE@  && echo 'timestamp' >$@
 @COND_DBUS_TRUE@$(src_dbus_server_script): $(src_dbus_server_script_in)
-@COND_DBUS_TRUE@       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
+@COND_DBUS_TRUE@       @sed -e "s|\@libexecdir\@|$(libexecdir)|" -e "s|\@SYNCEVO_DBUS_SERVER_ARGS\@|$(SYNCEVO_DBUS_SERVER_ARGS)|" $< >$@
 @COND_DBUS_TRUE@$(src_dbus_server_desktop): $(src_dbus_server_desktop_in)
 @COND_DBUS_TRUE@       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
 @COND_DBUS_TRUE@src/dbus/server/%.service: src/dbus/server/%.service.in
 @COND_DBUS_TRUE@$(src_dbus_server_desktop): $(src_dbus_server_desktop_in)
 @COND_DBUS_TRUE@       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
 @COND_DBUS_TRUE@src/dbus/server/%.service: src/dbus/server/%.service.in
-@COND_DBUS_TRUE@       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
+@COND_DBUS_TRUE@       @sed -e "s|\@libexecdir\@|$(libexecdir)|" -e "s|\@SYNCEVO_DBUS_SERVER_ARGS\@|$(SYNCEVO_DBUS_SERVER_ARGS)|" $< >$@
 
 # if this will pose a problem then see the link below, probably the solution
 # here will need to be used.
 
 # if this will pose a problem then see the link below, probably the solution
 # here will need to be used.
@@ -11329,6 +11376,7 @@ src/test: src/client-test
 @COND_DBUS_TRUE@       mkdir -p $(distdir)/usr/share/doc/syncevolution
 @COND_DBUS_TRUE@       cp $(srcdir)/INSTALL-tar-gz $(distdir)/INSTALL
 @COND_DBUS_TRUE@       cp $(filter-out all, $+) $(distdir)/usr/share/doc/syncevolution
 @COND_DBUS_TRUE@       mkdir -p $(distdir)/usr/share/doc/syncevolution
 @COND_DBUS_TRUE@       cp $(srcdir)/INSTALL-tar-gz $(distdir)/INSTALL
 @COND_DBUS_TRUE@       cp $(filter-out all, $+) $(distdir)/usr/share/doc/syncevolution
+@COND_DBUS_TRUE@       $(call ADD_EXTRA_BACKENDS, $(distdir))
 @COND_DBUS_TRUE@       tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
 @COND_DBUS_TRUE@       rm -rf $(distdir)
 # without D-Bus, we can simply create an archive with a bin directory
 @COND_DBUS_TRUE@       tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
 @COND_DBUS_TRUE@       rm -rf $(distdir)
 # without D-Bus, we can simply create an archive with a bin directory
@@ -11341,6 +11389,7 @@ src/test: src/client-test
 @COND_DBUS_FALSE@      rm -rf $(call DEV_FILE_PATTERN,$(distdir),/)
 @COND_DBUS_FALSE@      for i in `find $(distdir) -type d | sort -r`; do rmdir $$i 2>/dev/null || true; done
 @COND_DBUS_FALSE@      cp $(filter-out all, $+) $(distdir)
 @COND_DBUS_FALSE@      rm -rf $(call DEV_FILE_PATTERN,$(distdir),/)
 @COND_DBUS_FALSE@      for i in `find $(distdir) -type d | sort -r`; do rmdir $$i 2>/dev/null || true; done
 @COND_DBUS_FALSE@      cp $(filter-out all, $+) $(distdir)
+@COND_DBUS_FALSE@      $(call ADD_EXTRA_BACKENDS, $(distdir))
 @COND_DBUS_FALSE@      tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
 @COND_DBUS_FALSE@      rm -rf $(distdir)
 
 @COND_DBUS_FALSE@      tar zcf $(distdir)-$(BINSUFFIX).tar.gz $(distdir)
 @COND_DBUS_FALSE@      rm -rf $(distdir)
 
@@ -11425,6 +11474,7 @@ checkinstall/dist/$(distdir): all
        rm -rf $@
        $(MAKE) install DESTDIR=`pwd`/$@
        $(MAKE) installcheck DESTDIR=`pwd`/$@
        rm -rf $@
        $(MAKE) install DESTDIR=`pwd`/$@
        $(MAKE) installcheck DESTDIR=`pwd`/$@
+       $(call ADD_EXTRA_BACKENDS, $@)
        rm -rf $(call DEV_FILE_PATTERN,$@,/usr)
 clean-local: clean_dist
 clean_dist:
        rm -rf $(call DEV_FILE_PATTERN,$@,/usr)
 clean-local: clean_dist
 clean_dist:
@@ -11461,7 +11511,7 @@ dot_dist_hook:
          echo 'A git checkout is required to generate a ChangeLog.' >&2; \
        fi
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@toplevel_so_check:
          echo 'A git checkout is required to generate a ChangeLog.' >&2; \
        fi
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@toplevel_so_check:
-@ENABLE_EVOLUTION_COMPATIBILITY_TRUE@  for i in `find $(DESTDIR)/$(libdir)/syncevolution $(DESTDIR)/$(libdir)/libsyncevo* $(DESTDIR)/$(libdir)/libsynthesis* -name *.so` $(DESTDIR)/$(bindir)/syncevolution; \
+@ENABLE_EVOLUTION_COMPATIBILITY_TRUE@  for i in `find $(DESTDIR)/$(libdir)/syncevolution $(DESTDIR)/$(libdir)/libsyncevo* $(DESTDIR)/$(libdir)/libsynthesis* -name *.so | grep -v -2.so` $(DESTDIR)/$(bindir)/syncevolution; \
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@  do \
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@    if objdump -T -C $$i | grep -v :: | grep '\*UND\*' | sort | grep -v -w ical_strdup | grep -e ical -e " e_"; then \
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@      echo "$$i should not depend on EDS, libical or libbluetooth"; \
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@  do \
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@    if objdump -T -C $$i | grep -v :: | grep '\*UND\*' | sort | grep -v -w ical_strdup | grep -e ical -e " e_"; then \
 @ENABLE_EVOLUTION_COMPATIBILITY_TRUE@      echo "$$i should not depend on EDS, libical or libbluetooth"; \
@@ -11533,9 +11583,16 @@ dist-hook: $(all_dist_hooks)
 # Force sequential installation. This is a workaround for relinking failures
 # during concurrent distcheck (a backend was relinked against not yet installed
 # libsyncevolution.la).
 # Force sequential installation. This is a workaround for relinking failures
 # during concurrent distcheck (a backend was relinked against not yet installed
 # libsyncevolution.la).
+#
+# Also used to add additional backends.
 install-am: all-am
        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am
        @$(MAKE) $(AM_MAKEFLAGS) install-data-am
 install-am: all-am
        @$(MAKE) $(AM_MAKEFLAGS) install-exec-am
        @$(MAKE) $(AM_MAKEFLAGS) install-data-am
+       for i in $(EXTRA_BACKENDS); do $(INSTALL) $$i $(DESTDIR)/$(BACKENDS_DIRECTORY)/`basename $$i .so`-2.so; done
+
+# Necessary for "make distcheck": must not leave files behind.
+uninstall-local:
+       rm -f $(DESTDIR)/$(BACKENDS_DIRECTORY)/*-2.so
 
 .DELETE_ON_ERROR:
 
 
 .DELETE_ON_ERROR:
 
diff --git a/NEWS b/NEWS
index cc4f0ae..225fe37 100644 (file)
--- a/NEWS
+++ b/NEWS
+SyncEvolution 1.3.99.6, xxxxxxxxxx
+==================================
+
+This update focuses on SyncEvolution in IVI again. It adds support for
+GENIVI Diagnostic Log and Trace (DLT) and enhances searching in the
+unified address book.
+
+Binaries on syncevolution.org now work with EDS < 3.6 *and* >= 3.6.
+
+Details:
+
+* libsynthesis: avoid redundant (and sometimes slow) getaddrbyname() (FDO #70771)
+
+  The network lookup of the hostname can be slow (10 second delay when
+  not connected) and shouldn't be necessary anyway, so disable it.
+
+* PIM Manager: case-insensitive and transliterated search (FDO #56524)
+
+* PIM: accent-insensitive and transliterated search (FDO #56524)
+
+  Accent-insensitive search ignores accents, using the same code as in
+  EDS.  Transliterated search ignores foreign scripts by transliterating
+  search term and contact properties to Latin first. That one is using
+  ICU directly in the same way as EDS, but doesn't use the EDS
+  ETransliterator class to avoid extra string copying.
+
+  This commit changes the default behavior such that searching is by
+  default most permissive (case- and accent-insensitive, does
+  transliteration). Flags exist to restore more restrictive matching.
+
+* PIM: relax phone number matching
+
+  Previously, the current default country was used to turn phone numbers
+  without an explicit country code into full E164 numbers, which then
+  had to match the search term when doing a caller ID lookup.
+
+  This was inconsistent with EDS, where a weaker
+  EQUALS_NATIONAL_PHONE_NUMBER was done. The difference is that a
+  comparison between a number with country code matches one without if
+  the national number of the same, regardless of the current default
+  country. This is better because it reduces the influence of the hard
+  to guess default country on matching.
+
+  Another advantage of this change is the lower memory consumption and
+  faster comparison, because strings are now stored in 4 + 8 byte
+  numbers instead of strings of varying length.
+
+* PIM: fix incorrect write into pim-manager.ini (FDO #70772)
+
+  Removing a peer accidentally wrote the updated list of active
+  address books into the "sort" property of pim-manager.ini, which
+  then prevented starting the PIM Manager.
+
+* PIM: ignore broken sort order in config (FDO #70772)
+
+  Failure to set the sort order from pim-manager.ini should not
+  prevent the startup of the PIM Manager because the client cannot
+  really diagnose and fix the problem. It is better to try again with
+  the default sort order.
+
+* PIM: adapt to locale changes at runtime (FDO #66618)
+
+  Listen to signals from localed D-Bus system service and update all
+  internal state which depends on the current locale. This state includes:
+  - pre-computed data in all loaded contacts
+  - filtering (for example, case sensitivity is locale dependent)
+  - the sort order
+
+  This feature can be controlled by setting the SYNCEVOLUTION_LOCALED
+  env variable:
+  - "session" - use a localed instance on the D-Bus session bus instead
+    of the system instance. This was originally meant for
+    testing, but might also be useful for per-user setting changes.
+  - "none" - disables the feature
+
+* D-Bus server: support DLT (FDO #66769)
+
+  Diagnostic Log and Trace (DLT) manages a sequence of log messages,
+  with remote controllable level of detail. SyncEvolution optionally
+  (can be chosen at compile time and again at runtime) uses DLT
+  instead of its own syncevolution-log.html files. See README-DLT.rst
+  for more information.
+
+  To use the feature, configure SyncEvolution with
+  "--enable-dbus-server=--dlt --no-syslog"
+
+* EDS: enhanced compatibility mode
+
+  SyncEvolution compiled for EDS < 3.6 can now also load EDS backends
+  compiled for EDS >= 3.6. The packaging for syncevolution.org uses
+  that to bundle EDS backends compiled on different distros in the
+  same package.
+
+* EDS: SYNCEVOLUTION_EBOOK_QUERY env variable
+
+  Setting the SYNCEVOLUTION_EBOOK_QUERY env variable to a valid EBook
+  query string limits the results to contacts matching that
+  query. Useful only in combination with --print-items or
+  --export. Only implemented for EDS >= 3.6.
+
+* EDS: fix compile problem with boost and EDS > 3.36
+
+  This fixes the following problem, seen with Boost 1.53.0 on altlinux
+  when compiling for EDS >= 3.6:
+
+    /usr/include/boost/smart_ptr/shared_ptr.hpp: In instantiation of 'typename boost::detail::sp_array_access<T>::type boost::shared_ptr<T>::operator[](std::ptrdiff_t) const [with T = char*; typename boost::detail::sp_array_access<T>::type = void; std::ptrdiff_t = long int]':
+    src/backends/evolution/EvolutionSyncSource.cpp:163:38: required from here
+    /usr/include/boost/smart_ptr/shared_ptr.hpp:663:22: error: return-statement with a value, in function returning 'void' [-fpermissive]
+    make[2]: *** [src/backends/evolution/src_backends_evolution_syncecal_la-EvolutionSyncSource.lo]
+
+
 SyncEvolution 1.3.99.5, 01.10.2013
 ==================================
 
 SyncEvolution now supports Google CalDAV/CardDAV with OAuth2
 SyncEvolution 1.3.99.5, 01.10.2013
 ==================================
 
 SyncEvolution now supports Google CalDAV/CardDAV with OAuth2
-authentication. These are the open protocol that Google currently and
-thus the recommended way of syncing with Google, replacing ActiveSync
-and SyncML (both no longer available to all Google customers).
+authentication. These are the open protocol that Google currently
+supports and thus the recommended way of syncing with Google,
+replacing ActiveSync and SyncML (both no longer available to all
+Google customers).
 
 Support for Google CardDAV is new. Because of a vCard encoding issue
 on the server side, spaces in long notes may get removed. Like
 
 Support for Google CardDAV is new. Because of a vCard encoding issue
 on the server side, spaces in long notes may get removed. Like
diff --git a/README b/README
index db77cb3..6c79129 100644 (file)
--- a/README
+++ b/README
@@ -7,8 +7,8 @@ synchronize personal information management data
 ------------------------------------------------
 
 :Manual section: 1
 ------------------------------------------------
 
 :Manual section: 1
-:Version: 1.3.99.5
-:Date: 2013-10-01
+:Version: 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386
+:Date: 2013-10-30
 
 
 SYNOPSIS
 
 
 SYNOPSIS
index 835f3dc..690c556 100644 (file)
@@ -9,6 +9,15 @@
 /* "SyncML DevInf DevType" */
 #undef DEVICE_TYPE
 
 /* "SyncML DevInf DevType" */
 #undef DEVICE_TYPE
 
+/* "DLT app ID for syncevo-dbus-helper" */
+#undef DLT_SYNCEVO_DBUS_HELPER_ID
+
+/* "DLT app ID for syncevo-dbus-server" */
+#undef DLT_SYNCEVO_DBUS_SERVER_ID
+
+/* "DLT app ID for syncevo-local-helper" */
+#undef DLT_SYNCEVO_LOCAL_HELPER_ID
+
 /* ActiveSync available */
 #undef ENABLE_ACTIVESYNC
 
 /* ActiveSync available */
 #undef ENABLE_ACTIVESYNC
 
 /* "using Synthesis engine" */
 #undef SYNTHESIS
 
 /* "using Synthesis engine" */
 #undef SYNTHESIS
 
+/* "optionally use GENIVI Diagnostic Log and Trace for logging" */
+#undef USE_DLT
+
 /* use e_book/cal_client_* calls */
 #undef USE_EDS_CLIENT
 
 /* use e_book/cal_client_* calls */
 #undef USE_EDS_CLIENT
 
index 035aca7..60dceb5 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for syncevolution 1.3.99.5.
+# Generated by GNU Autoconf 2.69 for syncevolution 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='syncevolution'
 PACKAGE_TARNAME='syncevolution'
 # Identity of this package.
 PACKAGE_NAME='syncevolution'
 PACKAGE_TARNAME='syncevolution'
-PACKAGE_VERSION='1.3.99.5'
-PACKAGE_STRING='syncevolution 1.3.99.5'
+PACKAGE_VERSION='1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386'
+PACKAGE_STRING='syncevolution 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -717,8 +717,6 @@ KEYRING_LIBS
 KEYRING_CFLAGS
 FILE_LIBS
 FILE_CFLAGS
 KEYRING_CFLAGS
 FILE_LIBS
 FILE_CFLAGS
-EBOOKCONTACTS_LIBS
-EBOOKCONTACTS_CFLAGS
 EDS_VERSION_LIBS
 EDS_VERSION_CFLAGS
 ENABLE_ECAL_FALSE
 EDS_VERSION_LIBS
 EDS_VERSION_CFLAGS
 ENABLE_ECAL_FALSE
@@ -862,6 +860,7 @@ DBUS_LIBS
 DBUS_CFLAGS
 COND_GIO_GDBUS_FALSE
 COND_GIO_GDBUS_TRUE
 DBUS_CFLAGS
 COND_GIO_GDBUS_FALSE
 COND_GIO_GDBUS_TRUE
+SYNCEVO_DBUS_SERVER_ARGS
 COND_DBUS_FALSE
 COND_DBUS_TRUE
 COND_CORE_FALSE
 COND_DBUS_FALSE
 COND_DBUS_TRUE
 COND_CORE_FALSE
@@ -877,6 +876,8 @@ ENABLE_BLUETOOTH_FALSE
 ENABLE_BLUETOOTH_TRUE
 ENABLE_OBEX_FALSE
 ENABLE_OBEX_TRUE
 ENABLE_BLUETOOTH_TRUE
 ENABLE_OBEX_FALSE
 ENABLE_OBEX_TRUE
+DLT_LIBS
+DLT_CFLAGS
 BLUEZ_LIBS
 BLUEZ_CFLAGS
 LIBOPENOBEX_LIBS
 BLUEZ_LIBS
 BLUEZ_CFLAGS
 LIBOPENOBEX_LIBS
@@ -1051,6 +1052,8 @@ enable_maemo
 with_ca_certificates
 enable_libcurl
 enable_libsoup
 with_ca_certificates
 enable_libcurl
 enable_libsoup
+enable_dlt
+with_dlt_syncevolution
 enable_bluetooth
 enable_ssl_certificate_check
 enable_gtk
 enable_bluetooth
 enable_ssl_certificate_check
 enable_gtk
@@ -1119,6 +1122,8 @@ LIBOPENOBEX_CFLAGS
 LIBOPENOBEX_LIBS
 BLUEZ_CFLAGS
 BLUEZ_LIBS
 LIBOPENOBEX_LIBS
 BLUEZ_CFLAGS
 BLUEZ_LIBS
+DLT_CFLAGS
+DLT_LIBS
 DBUS_CFLAGS
 DBUS_LIBS
 LIBNOTIFY_CFLAGS
 DBUS_CFLAGS
 DBUS_LIBS
 LIBNOTIFY_CFLAGS
@@ -1159,8 +1164,6 @@ EBOOK_VERSION_CFLAGS
 EBOOK_VERSION_LIBS
 EDS_VERSION_CFLAGS
 EDS_VERSION_LIBS
 EBOOK_VERSION_LIBS
 EDS_VERSION_CFLAGS
 EDS_VERSION_LIBS
-EBOOKCONTACTS_CFLAGS
-EBOOKCONTACTS_LIBS
 KEYRING_CFLAGS
 KEYRING_LIBS
 KCALEXTENDED_CFLAGS
 KEYRING_CFLAGS
 KEYRING_LIBS
 KCALEXTENDED_CFLAGS
@@ -1734,7 +1737,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures syncevolution 1.3.99.5 to adapt to many kinds of systems.
+\`configure' configures syncevolution 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1804,7 +1807,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of syncevolution 1.3.99.5:";;
+     short | recursive ) echo "Configuration of syncevolution 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386:";;
    esac
   cat <<\_ACEOF
 
    esac
   cat <<\_ACEOF
 
@@ -1852,6 +1855,8 @@ Optional Features:
                           the Maemo 2.0 until at least 3.0 EDS-Dbus
   --enable-libcurl        enable libcurl as transport layer
   --enable-libsoup        enable libsoup as transport layer
                           the Maemo 2.0 until at least 3.0 EDS-Dbus
   --enable-libcurl        enable libcurl as transport layer
   --enable-libsoup        enable libsoup as transport layer
+  --enable-dlt            enable logging via GENIVI Diagnostic Log and Trace
+                          (DLT)
   --enable-bluetooth      enable bluetooth transport support
   --disable-ssl-certificate-check
                           Disable SSL certificate checking in all server
   --enable-bluetooth      enable bluetooth transport support
   --disable-ssl-certificate-check
                           Disable SSL certificate checking in all server
@@ -1873,9 +1878,14 @@ Optional Features:
                           built when --enable-gui is not used.
   --enable-core           enables building the core SyncEvolution (library,
                           backends)
                           built when --enable-gui is not used.
   --enable-core           enables building the core SyncEvolution (library,
                           backends)
-  --enable-dbus-service   enables building the dbus service executable and all
+  --enable-dbus-service=args
+                          Enables building the dbus service executable and all
                           related features (the DBus wrapper library, command
                           related features (the DBus wrapper library, command
-                          line usage of server, etc).
+                          line usage of server, etc). The optional arguments
+                          are syncevo-dbus-server command line arguments that
+                          are used when auto-starting via D-Bus or .desktop
+                          file. By default, the daemon logs to syslog. This
+                          can be changed via command line arguments.
   --enable-notify         send notifications for automatic sync events, using
                           libnotify
   --enable-notify-compatibility
   --enable-notify         send notifications for automatic sync events, using
                           libnotify
   --enable-notify-compatibility
@@ -1990,6 +2000,10 @@ Optional Packages:
                           using libcurl (because it has its own default), a
                           list of paths known to work for Debian and Red Hat
                           otherwise.
                           using libcurl (because it has its own default), a
                           list of paths known to work for Debian and Red Hat
                           otherwise.
+  --with-dlt-syncevolution=SYNS,SYNH,SYNL
+                          controls the application IDs used by
+                          syncevo-dbus-server, syncevo-dbus-helper and
+                          syncevo-local-sync
   --with-gio-gdbus        enables use of GIO's GDBus instead of the in-tree,
                           Bluez gdbus.
   --with-boost-locale[=special-lib]
   --with-gio-gdbus        enables use of GIO's GDBus instead of the in-tree,
                           Bluez gdbus.
   --with-boost-locale[=special-lib]
@@ -2051,6 +2065,8 @@ Some influential environment variables:
   BLUEZ_CFLAGS
               C compiler flags for BLUEZ, overriding pkg-config
   BLUEZ_LIBS  linker flags for BLUEZ, overriding pkg-config
   BLUEZ_CFLAGS
               C compiler flags for BLUEZ, overriding pkg-config
   BLUEZ_LIBS  linker flags for BLUEZ, overriding pkg-config
+  DLT_CFLAGS  C compiler flags for DLT, overriding pkg-config
+  DLT_LIBS    linker flags for DLT, overriding pkg-config
   DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config
   DBUS_LIBS   linker flags for DBUS, overriding pkg-config
   LIBNOTIFY_CFLAGS
   DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config
   DBUS_LIBS   linker flags for DBUS, overriding pkg-config
   LIBNOTIFY_CFLAGS
@@ -2119,10 +2135,6 @@ Some influential environment variables:
               C compiler flags for EDS_VERSION, overriding pkg-config
   EDS_VERSION_LIBS
               linker flags for EDS_VERSION, overriding pkg-config
               C compiler flags for EDS_VERSION, overriding pkg-config
   EDS_VERSION_LIBS
               linker flags for EDS_VERSION, overriding pkg-config
-  EBOOKCONTACTS_CFLAGS
-              C compiler flags for EBOOKCONTACTS, overriding pkg-config
-  EBOOKCONTACTS_LIBS
-              linker flags for EBOOKCONTACTS, overriding pkg-config
   KEYRING_CFLAGS
               C compiler flags for KEYRING, overriding pkg-config
   KEYRING_LIBS
   KEYRING_CFLAGS
               C compiler flags for KEYRING, overriding pkg-config
   KEYRING_LIBS
@@ -2239,7 +2251,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-syncevolution configure 1.3.99.5
+syncevolution configure 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2879,7 +2891,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by syncevolution $as_me 1.3.99.5, which was
+It was created by syncevolution $as_me 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3267,6 +3279,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
 
 
 
+
+
+
+
 # Minimum version of libsynthesis as defined in its
 # configure script and thus .pc files:
 
 # Minimum version of libsynthesis as defined in its
 # configure script and thus .pc files:
 
@@ -3794,7 +3810,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='syncevolution'
 
 # Define the identity of the package.
  PACKAGE='syncevolution'
- VERSION='1.3.99.5'
+ VERSION='1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386'
 
 
 cat >>confdefs.h <<_ACEOF
 
 
 cat >>confdefs.h <<_ACEOF
 
 
 
 
 
 
-test "x$CPPUNIT_CONFIG" != 'xno' || as_fn_error $? "\"cppunit-config not found.\"" "$LINENO" 5
-
 # cppunit needed?
 # cppunit needed?
-#if test "x$enable_unit_tests" = 'xyes' || test "x$enable_integration_tests" = 'xyes'
-#then
+if test "x$enable_unit_tests" = 'xyes' || test "x$enable_integration_tests" = 'xyes'; then
+  test "x$CPPUNIT_CONFIG" != 'xno' || as_fn_error $? "\"cppunit-config not found.\"" "$LINENO" 5
+fi
+if test "x$CPPUNIT_CONFIG" != 'xno'; then
+  # Export the flags if available, even if not enabled. This allows
+  # "make src/client-test" in cases where "make all" would not build
+  # client-test.
   CPPUNIT_CXXFLAGS=`$CPPUNIT_CONFIG --cflags`
   CPPUNIT_LDFLAGS=`$CPPUNIT_CONFIG --libs`
   CPPUNIT_CXXFLAGS=`$CPPUNIT_CONFIG --cflags`
   CPPUNIT_LDFLAGS=`$CPPUNIT_CONFIG --libs`
-#fi
+fi
 
 
 
 
 
 
 # SoupTransportAgent depends on glib
 case "$TRANSPORT" in *libsoup*) need_glib=yes;; esac
 
 # SoupTransportAgent depends on glib
 case "$TRANSPORT" in *libsoup*) need_glib=yes;; esac
 
+# Check whether --enable-dlt was given.
+if test "${enable_dlt+set}" = set; then :
+  enableval=$enable_dlt; enable_dlt=$enableval
+               test $enable_dlt = "yes" || test $enable_dlt = "no" || as_fn_error $? "invalid value of --enable-dlt: $enableval" "$LINENO" 5
+else
+  enable_dlt="no"
+fi
+
+if test "$enable_dlt" = "yes"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DLT" >&5
+$as_echo_n "checking for DLT... " >&6; }
+
+if test -n "$DLT_CFLAGS"; then
+    pkg_cv_DLT_CFLAGS="$DLT_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"automotive-dlt\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "automotive-dlt") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_DLT_CFLAGS=`$PKG_CONFIG --cflags "automotive-dlt" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$DLT_LIBS"; then
+    pkg_cv_DLT_LIBS="$DLT_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"automotive-dlt\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "automotive-dlt") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_DLT_LIBS=`$PKG_CONFIG --libs "automotive-dlt" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               DLT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "automotive-dlt" 2>&1`
+        else
+               DLT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "automotive-dlt" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$DLT_PKG_ERRORS" >&5
+
+       as_fn_error $? "dlt not found, required for --enable-dlt" "$LINENO" 5
+elif test $pkg_failed = untried; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+       as_fn_error $? "dlt not found, required for --enable-dlt" "$LINENO" 5
+else
+       DLT_CFLAGS=$pkg_cv_DLT_CFLAGS
+       DLT_LIBS=$pkg_cv_DLT_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       USE_DLT=1
+fi
+
+$as_echo "#define USE_DLT 1" >>confdefs.h
+
+
+# Check whether --with-dlt-syncevolution was given.
+if test "${with_dlt_syncevolution+set}" = set; then :
+  withval=$with_dlt_syncevolution; with_dlt_ids="$withval"
+else
+  with_dlt_ids="SYNS,SYNH,SYNL"
+fi
+
+    syns=`echo $with_dlt_ids | cut -d , -f 1`
+    synh=`echo $with_dlt_ids | cut -d , -f 2`
+    synl=`echo $with_dlt_ids | cut -d , -f 3`
+
+cat >>confdefs.h <<_ACEOF
+#define DLT_SYNCEVO_DBUS_SERVER_ID "$syns"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DLT_SYNCEVO_DBUS_HELPER_ID "$synh"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DLT_SYNCEVO_LOCAL_HELPER_ID "$synl"
+_ACEOF
+
+fi
+
 bluetooth_disabled=no
 # Check whether --enable-bluetooth was given.
 if test "${enable_bluetooth+set}" = set; then :
 bluetooth_disabled=no
 # Check whether --enable-bluetooth was given.
 if test "${enable_bluetooth+set}" = set; then :
@@ -17675,7 +17805,7 @@ else
                fi
 fi
 
                fi
 fi
 
- if test "$enable_dbus_service" = "yes"; then
+ if test "$enable_dbus_service" != "no"; then
   COND_DBUS_TRUE=
   COND_DBUS_FALSE='#'
 else
   COND_DBUS_TRUE=
   COND_DBUS_FALSE='#'
 else
@@ -17683,6 +17813,10 @@ else
   COND_DBUS_FALSE=
 fi
 
   COND_DBUS_FALSE=
 fi
 
+if test "$enable_dbus_service" != "no" && test "$enable_dbus_service" != "yes"; then
+   SYNCEVO_DBUS_SERVER_ARGS="$enable_dbus_service"
+fi
+
 
 
 # Check whether --with-gio-gdbus was given.
 
 
 # Check whether --with-gio-gdbus was given.
@@ -17933,7 +18067,7 @@ fi
 
 fi
 
 
 fi
 
-if test $enable_dbus_service = "yes"; then
+if test "$enable_dbus_service" != "no"; then
     if test -z "$XSLT"; then
        as_fn_error $? "xsltproc not found, is required for D-Bus service" "$LINENO" 5
     fi
     if test -z "$XSLT"; then
        as_fn_error $? "xsltproc not found, is required for D-Bus service" "$LINENO" 5
     fi
@@ -18709,7 +18843,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
 _ACEOF
 
 
-if test $enable_gui != "no" || test $enable_dbus_service = "yes"; then
+if test "$enable_gui" != "no" || test "$enable_dbus_service" != "no"; then
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
 $as_echo_n "checking whether NLS is requested... " >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
 $as_echo_n "checking whether NLS is requested... " >&6; }
@@ -20532,7 +20666,7 @@ $as_echo "yes" >&6; }
 
 fi
 
 
 fi
 
-elif test "$enable_dbus_service" = "yes"; then
+elif test "$enable_dbus_service" != "no"; then
     # syncevo-dbus-server needs localization
     :
 else
     # syncevo-dbus-server needs localization
     :
 else
@@ -21071,12 +21205,12 @@ if test -n "$SYNTHESIS_CFLAGS"; then
     pkg_cv_SYNTHESIS_CFLAGS="$SYNTHESIS_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     pkg_cv_SYNTHESIS_CFLAGS="$SYNTHESIS_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.10\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.10") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.11\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.11") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_SYNTHESIS_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.16.10" 2>/dev/null`
+  pkg_cv_SYNTHESIS_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.16.11" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -21088,12 +21222,12 @@ if test -n "$SYNTHESIS_LIBS"; then
     pkg_cv_SYNTHESIS_LIBS="$SYNTHESIS_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     pkg_cv_SYNTHESIS_LIBS="$SYNTHESIS_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.10\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.10") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.11\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.11") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_SYNTHESIS_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.16.10" 2>/dev/null`
+  pkg_cv_SYNTHESIS_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.16.11" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -21114,14 +21248,14 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.16.10" 2>&1`
+               SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.16.11" 2>&1`
         else
         else
-               SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.16.10" 2>&1`
+               SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.16.11" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$SYNTHESIS_PKG_ERRORS" >&5
 
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$SYNTHESIS_PKG_ERRORS" >&5
 
-       as_fn_error $? "Package requirements (synthesis >= 3.4.0.16.10) were not met:
+       as_fn_error $? "Package requirements (synthesis >= 3.4.0.16.11) were not met:
 
 $SYNTHESIS_PKG_ERRORS
 
 
 $SYNTHESIS_PKG_ERRORS
 
@@ -21208,12 +21342,12 @@ if test -n "$WITH_SYNTHESIS_SRC_CFLAGS"; then
     pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS="$WITH_SYNTHESIS_SRC_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS="$WITH_SYNTHESIS_SRC_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.10\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.10") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.11\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.11") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.16.10" 2>/dev/null`
+  pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.16.11" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -21225,12 +21359,12 @@ if test -n "$WITH_SYNTHESIS_SRC_LIBS"; then
     pkg_cv_WITH_SYNTHESIS_SRC_LIBS="$WITH_SYNTHESIS_SRC_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     pkg_cv_WITH_SYNTHESIS_SRC_LIBS="$WITH_SYNTHESIS_SRC_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.10\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.10") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.16.11\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.16.11") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_WITH_SYNTHESIS_SRC_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.16.10" 2>/dev/null`
+  pkg_cv_WITH_SYNTHESIS_SRC_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.16.11" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -21251,18 +21385,18 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.16.10" 2>&1`
+               WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.16.11" 2>&1`
         else
         else
-               WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.16.10" 2>&1`
+               WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.16.11" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$WITH_SYNTHESIS_SRC_PKG_ERRORS" >&5
 
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$WITH_SYNTHESIS_SRC_PKG_ERRORS" >&5
 
-       as_fn_error $? "need at least libsynthesis >= 3.4.0.16.10; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
+       as_fn_error $? "need at least libsynthesis >= 3.4.0.16.11; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
 elif test $pkg_failed = untried; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 elif test $pkg_failed = untried; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-       as_fn_error $? "need at least libsynthesis >= 3.4.0.16.10; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
+       as_fn_error $? "need at least libsynthesis >= 3.4.0.16.11; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
 else
        WITH_SYNTHESIS_SRC_CFLAGS=$pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS
        WITH_SYNTHESIS_SRC_LIBS=$pkg_cv_WITH_SYNTHESIS_SRC_LIBS
 else
        WITH_SYNTHESIS_SRC_CFLAGS=$pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS
        WITH_SYNTHESIS_SRC_LIBS=$pkg_cv_WITH_SYNTHESIS_SRC_LIBS
@@ -21453,7 +21587,7 @@ if test "$enable_activesync" = "yes"; then
                 { $as_echo "$as_me:${as_lineno-$LINENO}: configuring activesyncd using the $ACTIVESYNCDSRC source code" >&5
 $as_echo "$as_me: configuring activesyncd using the $ACTIVESYNCDSRC source code" >&6;}
                 ( set -x; cd src/backends/activesync/activesyncd/build &&
                 { $as_echo "$as_me:${as_lineno-$LINENO}: configuring activesyncd using the $ACTIVESYNCDSRC source code" >&5
 $as_echo "$as_me: configuring activesyncd using the $ACTIVESYNCDSRC source code" >&6;}
                 ( set -x; cd src/backends/activesync/activesyncd/build &&
-                  $ACTIVESYNCDSRC/configure --disable-eplugin --disable-camel-backend --prefix=`pwd`/../install) ||
+                  $ACTIVESYNCDSRC/configure --disable-eplugin --disable-camel-backend --disable-qtconfig --prefix=`pwd`/../install) ||
                 as_fn_error $? "configuring activesyncd failed" "$LINENO" 5
 
                 # hard-coded replacement for pkg-config: necessary because
                 as_fn_error $? "configuring activesyncd failed" "$LINENO" 5
 
                 # hard-coded replacement for pkg-config: necessary because
@@ -22228,99 +22362,9 @@ $as_echo "yes" >&6; }
 
 $as_echo "#define USE_EDS_CLIENT 1" >>confdefs.h
 
 
 $as_echo "#define USE_EDS_CLIENT 1" >>confdefs.h
 
-                           # When using it, then we also need libebook-contacts-1.2
-                           # for the ESourceBackendSummary extension.
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EBOOKCONTACTS" >&5
-$as_echo_n "checking for EBOOKCONTACTS... " >&6; }
-
-if test -n "$EBOOKCONTACTS_CFLAGS"; then
-    pkg_cv_EBOOKCONTACTS_CFLAGS="$EBOOKCONTACTS_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libebook-contacts-1.2\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libebook-contacts-1.2") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_EBOOKCONTACTS_CFLAGS=`$PKG_CONFIG --cflags "libebook-contacts-1.2" 2>/dev/null`
-                     test "x$?" != "x0" && pkg_failed=yes
-else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
-fi
-if test -n "$EBOOKCONTACTS_LIBS"; then
-    pkg_cv_EBOOKCONTACTS_LIBS="$EBOOKCONTACTS_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libebook-contacts-1.2\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libebook-contacts-1.2") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-  pkg_cv_EBOOKCONTACTS_LIBS=`$PKG_CONFIG --libs "libebook-contacts-1.2" 2>/dev/null`
-                     test "x$?" != "x0" && pkg_failed=yes
-else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
-fi
-
-
-
-if test $pkg_failed = yes; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
-        _pkg_short_errors_supported=yes
-else
-        _pkg_short_errors_supported=no
-fi
-        if test $_pkg_short_errors_supported = yes; then
-               EBOOKCONTACTS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libebook-contacts-1.2" 2>&1`
-        else
-               EBOOKCONTACTS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libebook-contacts-1.2" 2>&1`
-        fi
-       # Put the nasty error message in config.log where it belongs
-       echo "$EBOOKCONTACTS_PKG_ERRORS" >&5
-
-       as_fn_error $? "Package requirements (libebook-contacts-1.2) were not met:
-
-$EBOOKCONTACTS_PKG_ERRORS
-
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
-
-Alternatively, you may set the environment variables EBOOKCONTACTS_CFLAGS
-and EBOOKCONTACTS_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details." "$LINENO" 5
-elif test $pkg_failed = untried; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
-
-Alternatively, you may set the environment variables EBOOKCONTACTS_CFLAGS
-and EBOOKCONTACTS_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.
-
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details" "$LINENO" 5; }
-else
-       EBOOKCONTACTS_CFLAGS=$pkg_cv_EBOOKCONTACTS_CFLAGS
-       EBOOKCONTACTS_LIBS=$pkg_cv_EBOOKCONTACTS_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-fi
+                           # Was used for a while (ESourceBackendSummarySetup), but not anymore.
+                           # Don't depend on it, it wasn't in 3.6 yet.
+                           # PKG_CHECK_MODULES(EBOOKCONTACTS, libebook-contacts-1.2)
                            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for e_book_client_new_direct in -lebook-1.2" >&5
 $as_echo_n "checking for e_book_client_new_direct in -lebook-1.2... " >&6; }
 if ${ac_cv_lib_ebook_1_2_e_book_client_new_direct+:} false; then :
                            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for e_book_client_new_direct in -lebook-1.2" >&5
 $as_echo_n "checking for e_book_client_new_direct in -lebook-1.2... " >&6; }
 if ${ac_cv_lib_ebook_1_2_e_book_client_new_direct+:} false; then :
@@ -26033,7 +26077,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by syncevolution $as_me 1.3.99.5, which was
+This file was extended by syncevolution $as_me 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -26099,7 +26143,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-syncevolution config.status 1.3.99.5
+syncevolution config.status 1.3.99.5+20131030+SE+05e5911+SYSYNC+69de386
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 3acbd07..a0893b4 100644 (file)
@@ -25,7 +25,7 @@ SE_CHECK_FOR_STABLE_RELEASE
 
 # Minimum version of libsynthesis as defined in its
 # configure script and thus .pc files:
 
 # Minimum version of libsynthesis as defined in its
 # configure script and thus .pc files:
-define([SYNTHESIS_MIN_VERSION], [3.4.0.16.10])
+define([SYNTHESIS_MIN_VERSION], [3.4.0.16.11])
 
 # Line above is patched by gen-autotools.sh. Handle
 # both "yes" and "no".
 
 # Line above is patched by gen-autotools.sh. Handle
 # both "yes" and "no".
@@ -166,14 +166,17 @@ AC_CHECK_HEADERS(signal.h dlfcn.h)
 # cppunit-config is used even when both unit tests and integration tests are disabled.
 AC_PATH_PROG([CPPUNIT_CONFIG], [cppunit-config], [no])
 
 # cppunit-config is used even when both unit tests and integration tests are disabled.
 AC_PATH_PROG([CPPUNIT_CONFIG], [cppunit-config], [no])
 
-test "x$CPPUNIT_CONFIG" != 'xno' || AC_MSG_ERROR("cppunit-config not found.")
-
 # cppunit needed?
 # cppunit needed?
-#if test "x$enable_unit_tests" = 'xyes' || test "x$enable_integration_tests" = 'xyes'
-#then
+if test "x$enable_unit_tests" = 'xyes' || test "x$enable_integration_tests" = 'xyes'; then
+  test "x$CPPUNIT_CONFIG" != 'xno' || AC_MSG_ERROR("cppunit-config not found.")
+fi
+if test "x$CPPUNIT_CONFIG" != 'xno'; then
+  # Export the flags if available, even if not enabled. This allows
+  # "make src/client-test" in cases where "make all" would not build
+  # client-test.
   CPPUNIT_CXXFLAGS=`$CPPUNIT_CONFIG --cflags`
   CPPUNIT_LDFLAGS=`$CPPUNIT_CONFIG --libs`
   CPPUNIT_CXXFLAGS=`$CPPUNIT_CONFIG --cflags`
   CPPUNIT_LDFLAGS=`$CPPUNIT_CONFIG --libs`
-#fi
+fi
 AC_SUBST(CPPUNIT_CXXFLAGS)
 AC_SUBST(CPPUNIT_LDFLAGS)
 
 AC_SUBST(CPPUNIT_CXXFLAGS)
 AC_SUBST(CPPUNIT_LDFLAGS)
 
@@ -287,6 +290,30 @@ AC_ARG_ENABLE(libsoup,
 # SoupTransportAgent depends on glib
 case "$TRANSPORT" in *libsoup*) need_glib=yes;; esac
 
 # SoupTransportAgent depends on glib
 case "$TRANSPORT" in *libsoup*) need_glib=yes;; esac
 
+AC_ARG_ENABLE(dlt,
+              AS_HELP_STRING([--enable-dlt],
+                             [enable logging via GENIVI Diagnostic Log and Trace (DLT)]),
+              [enable_dlt=$enableval
+               test $enable_dlt = "yes" || test $enable_dlt = "no" || AC_ERROR([invalid value of --enable-dlt: $enableval])],
+              [enable_dlt="no"])
+if test "$enable_dlt" = "yes"; then
+    PKG_CHECK_MODULES(DLT, automotive-dlt,
+                      [USE_DLT=1],
+                      [AC_ERROR([dlt not found, required for --enable-dlt])])
+    AC_DEFINE(USE_DLT, 1, "optionally use GENIVI Diagnostic Log and Trace for logging")
+    AC_ARG_WITH([dlt-syncevolution],
+                AS_HELP_STRING([--with-dlt-syncevolution=SYNS,SYNH,SYNL],
+                               [controls the application IDs used by syncevo-dbus-server, syncevo-dbus-helper and syncevo-local-sync]),
+                [with_dlt_ids="$withval"],
+                [with_dlt_ids="SYNS,SYNH,SYNL"])
+    syns=`echo $with_dlt_ids | cut -d , -f 1`
+    synh=`echo $with_dlt_ids | cut -d , -f 2`
+    synl=`echo $with_dlt_ids | cut -d , -f 3`
+    AC_DEFINE_UNQUOTED(DLT_SYNCEVO_DBUS_SERVER_ID, "$syns", "DLT app ID for syncevo-dbus-server")
+    AC_DEFINE_UNQUOTED(DLT_SYNCEVO_DBUS_HELPER_ID, "$synh", "DLT app ID for syncevo-dbus-helper")
+    AC_DEFINE_UNQUOTED(DLT_SYNCEVO_LOCAL_HELPER_ID, "$synl", "DLT app ID for syncevo-local-helper")
+fi
+
 bluetooth_disabled=no
 AC_ARG_ENABLE(bluetooth,
               AS_HELP_STRING([--enable-bluetooth],
 bluetooth_disabled=no
 AC_ARG_ENABLE(bluetooth,
               AS_HELP_STRING([--enable-bluetooth],
@@ -438,16 +465,24 @@ AC_ARG_ENABLE(core,
 AM_CONDITIONAL([COND_CORE], [test "$enable_core" = "yes"])
 
 AC_ARG_ENABLE(dbus-service,
 AM_CONDITIONAL([COND_CORE], [test "$enable_core" = "yes"])
 
 AC_ARG_ENABLE(dbus-service,
-              AS_HELP_STRING([--enable-dbus-service],
-                             [enables building the dbus service executable and all related features
-                             (the DBus wrapper library, command line usage of server, etc).]),
+              AS_HELP_STRING([--enable-dbus-service=args],
+                             [Enables building the dbus service executable and all related features
+                             (the DBus wrapper library, command line usage of server, etc).
+                             The optional arguments are syncevo-dbus-server command line arguments
+                             that are used when auto-starting via D-Bus or .desktop file. By default,
+                             the daemon logs to syslog. This can be changed via command line arguments.
+                             ]),
               enable_dbus_service="$enableval",
               [if test $enable_gui = "no"; then
                   enable_dbus_service="no"
                else
                   enable_dbus_service="yes"
                fi])
               enable_dbus_service="$enableval",
               [if test $enable_gui = "no"; then
                   enable_dbus_service="no"
                else
                   enable_dbus_service="yes"
                fi])
-AM_CONDITIONAL([COND_DBUS], [test "$enable_dbus_service" = "yes"])
+AM_CONDITIONAL([COND_DBUS], [test "$enable_dbus_service" != "no"])
+if test "$enable_dbus_service" != "no" && test "$enable_dbus_service" != "yes"; then
+   SYNCEVO_DBUS_SERVER_ARGS="$enable_dbus_service"
+fi
+AC_SUBST(SYNCEVO_DBUS_SERVER_ARGS)
 
 AC_ARG_WITH([gio-gdbus],
             AS_HELP_STRING([--with-gio-gdbus],
 
 AC_ARG_WITH([gio-gdbus],
             AS_HELP_STRING([--with-gio-gdbus],
@@ -477,7 +512,7 @@ AS_IF([test "x$with_gio_gdbus" = "xyes"],
                     AC_DEFINE(NEED_DBUS_WATCH_GET_UNIX_FD, 1,
                     [Define to 1 if you need the dbus_watch_get_unix_fd() function.]))])
 
                     AC_DEFINE(NEED_DBUS_WATCH_GET_UNIX_FD, 1,
                     [Define to 1 if you need the dbus_watch_get_unix_fd() function.]))])
 
-if test $enable_dbus_service = "yes"; then
+if test "$enable_dbus_service" != "no"; then
     if test -z "$XSLT"; then
        AC_MSG_ERROR([xsltproc not found, is required for D-Bus service])
     fi
     if test -z "$XSLT"; then
        AC_MSG_ERROR([xsltproc not found, is required for D-Bus service])
     fi
@@ -600,7 +635,7 @@ DBUS_SERVICES_DIR="${datadir}/dbus-1/services"
 AC_SUBST(DBUS_SERVICES_DIR)
 AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Location of D-Bus services directory])
 
 AC_SUBST(DBUS_SERVICES_DIR)
 AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Location of D-Bus services directory])
 
-if test $enable_gui != "no" || test $enable_dbus_service = "yes"; then
+if test "$enable_gui" != "no" || test "$enable_dbus_service" != "no"; then
     IT_PROG_INTLTOOL([0.37.1])
     GETTEXT_PACKAGE=syncevolution
     AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The gettext package name])
     IT_PROG_INTLTOOL([0.37.1])
     GETTEXT_PACKAGE=syncevolution
     AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The gettext package name])
@@ -664,7 +699,7 @@ if test $enable_gui != "no"; then
 
     PKG_CHECK_MODULES(GUI, $gui_modules)
 
 
     PKG_CHECK_MODULES(GUI, $gui_modules)
 
-elif test "$enable_dbus_service" = "yes"; then
+elif test "$enable_dbus_service" != "no"; then
     # syncevo-dbus-server needs localization
     :
 else
     # syncevo-dbus-server needs localization
     :
 else
index 701b538..47f3d38 100644 (file)
@@ -24,7 +24,7 @@ if test "$enable_activesync" = "yes"; then
                 mkdir -p src/backends/activesync/activesyncd/build
                 AC_MSG_NOTICE([configuring activesyncd using the $ACTIVESYNCDSRC source code])
                 ( set -x; cd src/backends/activesync/activesyncd/build &&
                 mkdir -p src/backends/activesync/activesyncd/build
                 AC_MSG_NOTICE([configuring activesyncd using the $ACTIVESYNCDSRC source code])
                 ( set -x; cd src/backends/activesync/activesyncd/build &&
-                  $ACTIVESYNCDSRC/configure --disable-eplugin --disable-camel-backend --prefix=`pwd`/../install) ||
+                  $ACTIVESYNCDSRC/configure --disable-eplugin --disable-camel-backend --disable-qtconfig --prefix=`pwd`/../install) ||
                 AC_MSG_ERROR([configuring activesyncd failed])
 
                 # hard-coded replacement for pkg-config: necessary because
                 AC_MSG_ERROR([configuring activesyncd failed])
 
                 # hard-coded replacement for pkg-config: necessary because
index e6ff652..545a1d0 100644 (file)
@@ -380,7 +380,13 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
     EBookClientView *view;
 
     EBookQueryCXX allItemsQuery(e_book_query_any_field_contains(""), TRANSFER_REF);
     EBookClientView *view;
 
     EBookQueryCXX allItemsQuery(e_book_query_any_field_contains(""), TRANSFER_REF);
-    PlainGStr sexp(e_book_query_to_string (allItemsQuery.get()));
+    PlainGStr buffer(e_book_query_to_string (allItemsQuery.get()));
+    const char *sexp = getenv("SYNCEVOLUTION_EBOOK_QUERY");
+    if (sexp) {
+        SE_LOG_INFO(NULL, "restricting item set to items matching %s", sexp);
+    } else {
+        sexp = buffer;
+    }
 
     if (!e_book_client_get_view_sync(m_addressbook, sexp, &view, NULL, gerror)) {
         throwError( "getting the view" , gerror);
 
     if (!e_book_client_get_view_sync(m_addressbook, sexp, &view, NULL, gerror)) {
         throwError( "getting the view" , gerror);
index 1f8bbee..127eef1 100644 (file)
@@ -160,7 +160,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
         gerror.throwError("listing keys in main section");
     }
     for (int i = 0; keys.at(i); i++) {
         gerror.throwError("listing keys in main section");
     }
     for (int i = 0; keys.at(i); i++) {
-        if (boost::starts_with(keys[i], "DisplayName[")) {
+        if (boost::starts_with(keys.at(i), "DisplayName[")) {
             if (!g_key_file_remove_key(keyfile, mainSection, keys.at(i), gerror)) {
                 gerror.throwError("remove key");
             }
             if (!g_key_file_remove_key(keyfile, mainSection, keys.at(i), gerror)) {
                 gerror.throwError("remove key");
             }
index 940f2b1..e8ce189 100644 (file)
@@ -68,9 +68,9 @@ if test "$enable_evo" = "yes"; then
         # Only the EClient code supports the API in EDS 3.5.x.
         PKG_CHECK_MODULES(EDS_VERSION, [libedataserver-1.2 >= 3.5],
                           [AC_DEFINE(USE_EDS_CLIENT, 1, [use e_book/cal_client_* calls])
         # Only the EClient code supports the API in EDS 3.5.x.
         PKG_CHECK_MODULES(EDS_VERSION, [libedataserver-1.2 >= 3.5],
                           [AC_DEFINE(USE_EDS_CLIENT, 1, [use e_book/cal_client_* calls])
-                           # When using it, then we also need libebook-contacts-1.2
-                           # for the ESourceBackendSummary extension.
-                           PKG_CHECK_MODULES(EBOOKCONTACTS, libebook-contacts-1.2)
+                           # Was used for a while (ESourceBackendSummarySetup), but not anymore.
+                           # Don't depend on it, it wasn't in 3.6 yet.
+                           PKG_CHECK_MODULES(EBOOKCONTACTS, libebook-contacts-1.2)
                            AC_CHECK_LIB(ebook-1.2, e_book_client_new_direct,
                                         [AC_DEFINE(HAVE_E_BOOK_CLIENT_NEW_DIRECT, 1, [use e_book_client_new_direct])],
                                         [true],
                            AC_CHECK_LIB(ebook-1.2, e_book_client_new_direct,
                                         [AC_DEFINE(HAVE_E_BOOK_CLIENT_NEW_DIRECT, 1, [use e_book_client_new_direct])],
                                         [true],
diff --git a/src/dbus/server/localed-listener.cpp b/src/dbus/server/localed-listener.cpp
new file mode 100644 (file)
index 0000000..a0cb500
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#include "localed-listener.h"
+#include <syncevo/BoostHelper.h>
+#include <syncevo/Logging.h>
+#include <syncevo/util.h>
+
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <algorithm>
+
+SE_BEGIN_CXX
+
+static const char LOCALED_PATH[] = "/org/freedesktop/locale1";
+static const char LOCALED_INTERFACE[] = "org.freedesktop.locale1";
+static const char LOCALED_DESTINATION[] = "org.freedesktop.locale1";
+static const char LOCALED_LOCALE_PROPERTY[] = "Locale";
+
+/**
+ * Must be a complete list, because we need to know which variables
+ * we have to unset if not set remotely.
+ *
+ * Localed intentionally does not support LC_ALL. As localed.c says:
+ * "We don't list LC_ALL here on purpose. People should be using LANG instead."
+ */
+static const char * const LOCALED_ENV_VARS[] = {
+    "LANG",
+    "LC_CTYPE",
+    "LC_NUMERIC",
+    "LC_TIME",
+    "LC_COLLATE",
+    "LC_MONETARY",
+    "LC_MESSAGES",
+    "LC_PAPER",
+    "LC_NAME",
+    "LC_ADDRESS",
+    "LC_TELEPHONE",
+    "LC_MEASUREMENT",
+    "LC_IDENTIFICATION"
+};
+
+static const char PROPERTIES_INTERFACE[] = "org.freedesktop.DBus.Properties";
+static const char PROPERTIES_CHANGED_SIGNAL[] = "PropertiesChanged";
+static const char PROPERTIES_GET[] = "Get";
+
+LocaledListener::LocaledListener():
+    GDBusCXX::DBusRemoteObject(!strcmp(getEnv("SYNCEVOLUTION_LOCALED", ""), "none") ?
+                               NULL : /* simulate missing localed */
+                               GDBusCXX::dbus_get_bus_connection(!strcmp(getEnv("SYNCEVOLUTION_LOCALED", ""), "session") ?
+                                                                 "SESSION" : /* use our own localed stub */
+                                                                 "SYSTEM" /* use real localed */,
+                                                                 NULL, false, NULL),
+                               LOCALED_PATH,
+                               PROPERTIES_INTERFACE,
+                               LOCALED_DESTINATION),
+    m_propertiesChanged(*this, PROPERTIES_CHANGED_SIGNAL),
+    m_propertiesGet(*this, PROPERTIES_GET)
+{
+    if (getConnection()) {
+        m_propertiesChanged.activate(boost::bind(&LocaledListener::onPropertiesChange, this, _1, _2, _3));
+    } else {
+        SE_LOG_DEBUG(NULL, "localed: not activating, no connection");
+    }
+};
+
+
+boost::shared_ptr<LocaledListener> LocaledListener::create()
+{
+    static boost::weak_ptr<LocaledListener> singleton;
+    boost::shared_ptr<LocaledListener> self = singleton.lock();
+    if (!self) {
+        self.reset(new LocaledListener());
+        self->m_self = self;
+        singleton = self;
+    }
+    return self;
+};
+
+void LocaledListener::onPropertiesChange(const std::string &interface,
+                                         const Properties &properties,
+                                         const Invalidated &invalidated)
+{
+    if (interface == LOCALED_INTERFACE) {
+        boost::function<void (const LocaleEnv &env)> result(boost::bind(&LocaledListener::emitLocaleEnv, m_self, _1));
+        BOOST_FOREACH (const Properties::value_type &entry, properties) {
+            if (entry.first == LOCALED_LOCALE_PROPERTY) {
+                const LocaleEnv *locale = boost::get<LocaleEnv>(&entry.second);
+                if (locale) {
+                    SE_LOG_DEBUG(NULL, "localed: got new Locale");
+                    processLocaleProperty(*locale, "", false, result);
+                } else {
+                    SE_LOG_DEBUG(NULL, "localed: got new Locale of invalid type?! Ignore.");
+                }
+                return;
+            }
+        }
+        if (std::find(invalidated.begin(),
+                      invalidated.end(),
+                      LOCALED_LOCALE_PROPERTY) != invalidated.end()) {
+            SE_LOG_DEBUG(NULL, "localed: Locale changed, need to get new value");
+            m_propertiesGet.start(std::string(LOCALED_INTERFACE),
+                                  std::string(LOCALED_LOCALE_PROPERTY),
+                                  boost::bind(&LocaledListener::processLocaleProperty, m_self,
+                                              _1, _2, false,
+                                              result));
+        }
+        SE_LOG_DEBUG(NULL, "localed: ignoring irrelevant property change");
+    }
+}
+
+void LocaledListener::processLocaleProperty(const LocaleVariant &variant,
+                                            const std::string &error,
+                                            bool mustCall,
+                                            const ProcessLocalePropCB_t &result)
+{
+    SE_LOG_DEBUG(NULL, "localed: got Locale property: %s", error.empty() ? "<<successfully>>" : error.c_str());
+    const LocaleEnv *locale =
+        error.empty() ?
+        boost::get<LocaleEnv>(&variant) :
+        NULL;
+    LocaleEnv current;
+    if (!locale && mustCall) {
+        SE_LOG_DEBUG(NULL, "localed: using current environment as fallback");
+        BOOST_FOREACH (const char *name, LOCALED_ENV_VARS) {
+            const char *value = getenv(name);
+            if (value) {
+                current.push_back(StringPrintf("%s=%s", name, value));
+            }
+        }
+        locale = &current;
+    }
+    if (locale) {
+        result(*locale);
+    }
+}
+
+void LocaledListener::emitLocaleEnv(const LocaleEnv &env)
+{
+    SE_LOG_DEBUG(NULL, "localed: got environment: %s",
+                 boost::join(env, " ").c_str());
+    m_localeValues(env);
+}
+
+void LocaledListener::check(const boost::function<void (const LocaleEnv &env)> &result)
+{
+    if (getConnection()) {
+        SE_LOG_DEBUG(NULL, "localed: get current Locale property");
+        m_propertiesGet.start(std::string(LOCALED_INTERFACE),
+                              std::string(LOCALED_LOCALE_PROPERTY),
+                              boost::bind(&LocaledListener::processLocaleProperty, m_self, _1, _2, true, result));
+    } else {
+        processLocaleProperty(LocaleVariant(), "no D-Bus connection", true, result);
+    }
+}
+
+void LocaledListener::setLocale(const LocaleEnv &locale)
+{
+    bool modified = false;
+    BOOST_FOREACH (const char *name, LOCALED_ENV_VARS) {
+        const char *value = getenv(name);
+        std::string assignment = StringPrintf("%s=", name);
+        LocaleEnv::const_iterator instance = std::find_if(locale.begin(), locale.end(),
+                                                          boost::bind(boost::starts_with<std::string, std::string>, _1, name));
+        const char *newvalue = instance != locale.end() ? instance->c_str() + assignment.size() : NULL;
+        if ((value && newvalue && strcmp(value, newvalue)) ||
+            (!value && newvalue)) {
+            modified = true;
+            setenv(name, newvalue, true);
+            SE_LOG_DEBUG(NULL, "localed: %s = %s -> %s", name, value ? value : "<none>", newvalue);
+        } else if (value && !newvalue) {
+            modified = true;
+            unsetenv(name);
+            SE_LOG_DEBUG(NULL, "localed: %s = %s -> <none>", name, value);
+        }
+    }
+    SE_LOG_DEBUG(NULL, "localed: environment %s", modified ? "changed" : "unchanged");
+    if (modified) {
+        m_localeChanged();
+    }
+}
+
+SE_END_CXX
diff --git a/src/dbus/server/localed-listener.h b/src/dbus/server/localed-listener.h
new file mode 100644 (file)
index 0000000..8e54907
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#ifndef INCL_LOCALED_LISTENER
+#define INCL_LOCALED_LISTENER
+
+#include <gdbus-cxx-bridge.h>
+#include <boost/signals2.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+/**
+ * The D-Bus binding for http://www.freedesktop.org/wiki/Software/systemd/localed/
+ */
+class LocaledListener : public GDBusCXX::DBusRemoteObject
+{
+ public:
+    /**
+     * Singleton - at most one instance of LocaledListener will exist.
+     * It lives as long as one of the create() callers keeps the reference.
+     */
+    static boost::shared_ptr<LocaledListener> create();
+
+    /**
+     * array of var=value, for example LANG, LC_NUMERIC, etc.
+     */
+    typedef std::vector<std::string> LocaleEnv;
+
+    /**
+     * Emitted for each new set of env variables from localed.
+     * May or may not be different from what we have already.
+     */
+    boost::signals2::signal<void (const LocaleEnv &env)> m_localeValues;
+
+    /**
+     * The result callback is guaranteed to be invoked once,
+     * either with the current settings from localed or, if
+     * retrieving those fails, with the current environment.
+     */
+    void check(const boost::function<void (const LocaleEnv &env)> &result);
+
+    /**
+     * Updates current environment to match the one in the parameter.
+     * Emits m_localeChanged if and only if something really changed.
+     *
+     * Not called by default. To ensure that the current environment
+     * matches localed, do:
+     * - use current settings
+     * - m_localeValues -> setLocale
+     * - check -> setLocale
+     *
+     * Alternatively, one could wait until check() completes and only
+     * then use the current settings.
+     */
+    void setLocale(const LocaleEnv &locale);
+
+    typedef boost::signals2::signal<void ()> LocaleChangedSignal;
+    /**
+     * Emitted by setLocale() only if something really changed in the
+     * local environment.
+     */
+    LocaleChangedSignal m_localeChanged;
+
+ private:
+    boost::weak_ptr<LocaledListener> m_self;
+    typedef boost::variant<LocaleEnv> LocaleVariant;
+    typedef std::map<std::string, LocaleVariant> Properties;
+    typedef std::vector<std::string> Invalidated;
+    GDBusCXX::SignalWatch3<std::string, Properties, Invalidated> m_propertiesChanged;
+    GDBusCXX::DBusClientCall1<LocaleVariant> m_propertiesGet;
+
+    LocaledListener();
+    void onPropertiesChange(const std::string &interface,
+                            const Properties &properties,
+                            const Invalidated &invalidated);
+    typedef boost::function<void (const LocaleEnv &env)> ProcessLocalePropCB_t;
+    void processLocaleProperty(const LocaleVariant &locale,
+                               const std::string &error,
+                               bool mustCall,
+                               const ProcessLocalePropCB_t &result);
+    void emitLocaleEnv(const LocaleEnv &env);
+};
+
+SE_END_CXX
+
+#endif // INCL_LOCALED_LISTENER
index a8d8c6d..63c757b 100644 (file)
 #include <syncevo/SuspendFlags.h>
 #include <syncevo/LogRedirect.h>
 #include <syncevo/LogSyslog.h>
 #include <syncevo/SuspendFlags.h>
 #include <syncevo/LogRedirect.h>
 #include <syncevo/LogSyslog.h>
+#include <syncevo/LogDLT.h>
 #include <syncevo/GLibSupport.h>
 
 #include <syncevo/GLibSupport.h>
 
+#ifdef USE_DLT
+# include <dlt.h>
+#endif
+
 using namespace SyncEvo;
 using namespace GDBusCXX;
 
 using namespace SyncEvo;
 using namespace GDBusCXX;
 
@@ -100,6 +105,9 @@ int main(int argc, char **argv, char **envp)
         int logLevelDBus = 2;
         gboolean stdoutEnabled = false;
         gboolean syslogEnabled = true;
         int logLevelDBus = 2;
         gboolean stdoutEnabled = false;
         gboolean syslogEnabled = true;
+#ifdef USE_DLT
+        gboolean dltEnabled = false;
+#endif
 #ifdef ENABLE_DBUS_PIM
         gboolean startPIM = false;
 #endif
 #ifdef ENABLE_DBUS_PIM
         gboolean startPIM = false;
 #endif
@@ -115,6 +123,9 @@ int main(int argc, char **argv, char **envp)
               "Enable printing to stdout (result of operations) and stderr (errors/info/debug).",
               NULL },
             { "no-syslog", 's', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &syslogEnabled, "Disable printing to syslog.", NULL },
               "Enable printing to stdout (result of operations) and stderr (errors/info/debug).",
               NULL },
             { "no-syslog", 's', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &syslogEnabled, "Disable printing to syslog.", NULL },
+#ifdef USE_DLT
+            { "dlt", 0, 0, G_OPTION_ARG_NONE, &dltEnabled, "Enable logging via GENIVI Diagnostic Log and Trace.", NULL },
+#endif
 #ifdef ENABLE_DBUS_PIM
             { "start-pim", 'p', 0, G_OPTION_ARG_NONE, &startPIM,
               "Activate the PIM Manager (= unified address book) immediately.",
 #ifdef ENABLE_DBUS_PIM
             { "start-pim", 'p', 0, G_OPTION_ARG_NONE, &startPIM,
               "Activate the PIM Manager (= unified address book) immediately.",
@@ -154,6 +165,20 @@ int main(int argc, char **argv, char **envp)
         // Redirect output and optionally log to syslog.
         PushLogger<LogRedirect> redirect(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
         redirect->setLevel(stdoutEnabled ? level : Logger::NONE);
         // Redirect output and optionally log to syslog.
         PushLogger<LogRedirect> redirect(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
         redirect->setLevel(stdoutEnabled ? level : Logger::NONE);
+#ifdef USE_DLT
+        PushLogger<LoggerDLT> loggerdlt;
+        if (dltEnabled) {
+            // DLT logging with default log level DLT_LOG_WARN.  This
+            // default was chosen because DLT's own default,
+            // DLT_LOG_INFO, leads to too much output given that a lot
+            // of the standard messages in SyncEvolution and
+            // libsynthesis are labelled informational.
+            setenv("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", DLT_LOG_WARN).c_str(), true);
+            loggerdlt.reset(new LoggerDLT(DLT_SYNCEVO_DBUS_SERVER_ID, "SyncEvolution D-Bus server"));
+        } else {
+            unsetenv("SYNCEVOLUTION_USE_DLT");
+        }
+#endif
         PushLogger<LoggerSyslog> syslogger;
         if (syslogEnabled && level > Logger::NONE) {
             syslogger.reset(new LoggerSyslog(execName));
         PushLogger<LoggerSyslog> syslogger;
         if (syslogEnabled && level > Logger::NONE) {
             syslogger.reset(new LoggerSyslog(execName));
index db8a0b4..edc6376 100644 (file)
@@ -1,3 +1,3 @@
 [D-BUS Service]
 Name=org.syncevolution
 [D-BUS Service]
 Name=org.syncevolution
-Exec=@libexecdir@/syncevo-dbus-server
+Exec=@libexecdir@/syncevo-dbus-server @SYNCEVO_DBUS_SERVER_ARGS@
index 9620594..a83fe52 100644 (file)
@@ -187,12 +187,26 @@ Supported searches:
 
     Except for 'phones/value', all values are treated as text values.
     For text values, the default search without explicit flags is
 
     Except for 'phones/value', all values are treated as text values.
     For text values, the default search without explicit flags is
-    case-insensitive and accent-sensitive. Spaces between words
-    matter. This behavior can be modified by giving additional,
+    very tolerant, meaning that it ignores quite a few differences
+    between search term and value. The default search:
+    - transliterates any foreign script in search term and values
+      to Latin before comparison, thus finding 江 when searching
+      for Jiang and vice-versa
+    - is case-insensitive
+    - is accent-insensitive
+
+    Case and accent differences get removed after the optional
+    transliteration. Spaces between words always matter.
+
+    This behavior can be modified by giving additional,
     optional flags after the search value:
     'case-insensitive' - force case-insensitive search (available for the sake
     of consistency and just in case, should the default ever change)
     'case-sensitive' - force case-sensitive search
     optional flags after the search value:
     'case-insensitive' - force case-insensitive search (available for the sake
     of consistency and just in case, should the default ever change)
     'case-sensitive' - force case-sensitive search
+    'accent-insensitive', 'accent-sensitive' - same for accents
+    'transliteration' - force transliteration, i.e. explicitly choose the
+    current default
+    'no-transliteration' - disable transliteration
 
     For telephone numbers, only digits are compared. Latin alphabetic
     characters are treated as aliases for digits as they typically
 
     For telephone numbers, only digits are compared. Latin alphabetic
     characters are treated as aliases for digits as they typically
index 6fd4dba..9af83e7 100644 (file)
@@ -90,18 +90,20 @@ boost::shared_ptr<IndividualCompare> IndividualCompare::defaultCompare()
     return compare;
 }
 
     return compare;
 }
 
-void IndividualData::init(const IndividualCompare *compare,
+bool IndividualData::init(const IndividualCompare *compare,
                           const LocaleFactory *locale,
                           FolksIndividual *individual)
 {
                           const LocaleFactory *locale,
                           FolksIndividual *individual)
 {
+    bool precomputedModified = false;
     m_individual = FolksIndividualCXX(individual, ADD_REF);
     if (compare) {
         m_criteria.clear();
         compare->createCriteria(individual, m_criteria);
     }
     if (locale) {
     m_individual = FolksIndividualCXX(individual, ADD_REF);
     if (compare) {
         m_criteria.clear();
         compare->createCriteria(individual, m_criteria);
     }
     if (locale) {
-        locale->precompute(individual, m_precomputed);
+        precomputedModified = locale->precompute(individual, m_precomputed);
     }
     }
+    return precomputedModified;
 }
 
 bool IndividualCompare::compare(const Criteria_t &a, const Criteria_t &b) const
 }
 
 bool IndividualCompare::compare(const Criteria_t &a, const Criteria_t &b) const
@@ -275,6 +277,16 @@ void IndividualAggregator::setCompare(const boost::shared_ptr<IndividualCompare>
     }
 }
 
     }
 }
 
+void IndividualAggregator::setLocale(const boost::shared_ptr<LocaleFactory> &locale)
+{
+    m_locale = locale;
+
+    if (m_view) {
+        m_view->setLocale(m_locale);
+    }
+}
+
+
 void IndividualAggregator::start()
 {
     if (!m_view) {
 void IndividualAggregator::start()
 {
     if (!m_view) {
index 853240b..0f6d86f 100644 (file)
@@ -116,8 +116,10 @@ struct IndividualData
      * Sets all members to match the given individual, using the
      * compare instance to compute values. Both compare and locale may
      * be NULL.
      * Sets all members to match the given individual, using the
      * compare instance to compute values. Both compare and locale may
      * be NULL.
+     *
+     * Returns true if the precomputed values changed.
      */
      */
-    void init(const IndividualCompare *compare,
+    bool init(const IndividualCompare *compare,
               const LocaleFactory *locale,
               FolksIndividual *individual);
 
               const LocaleFactory *locale,
               FolksIndividual *individual);
 
@@ -315,6 +317,12 @@ class IndividualAggregator
     void setCompare(const boost::shared_ptr<IndividualCompare> &compare);
 
     /**
     void setCompare(const boost::shared_ptr<IndividualCompare> &compare);
 
     /**
+     * Change current locale. Must be followed by setCompare() to update
+     * any pre-computed data.
+     */
+    void setLocale(const boost::shared_ptr<LocaleFactory> &locale);
+
+    /**
      * Starts pulling and sorting of contacts.
      * Creates m_view and starts populating it.
      * Can be called multiple times.
      * Starts pulling and sorting of contacts.
      * Creates m_view and starts populating it.
      * Can be called multiple times.
index b0d5d7a..bc9fbe1 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <syncevo/BoostHelper.h>
 
 
 #include <syncevo/BoostHelper.h>
 
+#include <boost/dynamic_bitset.hpp>
+
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
@@ -28,6 +30,7 @@ FullView::FullView(const FolksIndividualAggregatorCXX &folks,
                    const boost::shared_ptr<LocaleFactory> &locale) :
     m_folks(folks),
     m_locale(locale),
                    const boost::shared_ptr<LocaleFactory> &locale) :
     m_folks(folks),
     m_locale(locale),
+    m_localeChanged(false), // set only after explicit setLocale()
     m_isQuiescent(false),
     // Ensure that there is a sort criteria.
     m_compare(IndividualCompare::defaultCompare())
     m_isQuiescent(false),
     // Ensure that there is a sort criteria.
     m_compare(IndividualCompare::defaultCompare())
@@ -104,6 +107,16 @@ boost::shared_ptr<FullView> FullView::create(const FolksIndividualAggregatorCXX
     return view;
 }
 
     return view;
 }
 
+
+void FullView::setLocale(const boost::shared_ptr<LocaleFactory> &locale)
+{
+    m_locale = locale;
+    m_localeChanged = true;
+
+    // Don't recompute all IndividualData content. That will be done
+    // as part of setCompare(), which must be called later.
+}
+
 void FullView::individualsChanged(GeeSet *added,
                                   GeeSet *removed,
                                   gchar *message,
 void FullView::individualsChanged(GeeSet *added,
                                   GeeSet *removed,
                                   gchar *message,
@@ -297,8 +310,17 @@ void FullView::setCompare(const boost::shared_ptr<IndividualCompare> &compare)
     memcpy(old.get(), m_entries.c_array(), sizeof(IndividualData *) * m_entries.size());
 
     // Change sort criteria and sort.
     memcpy(old.get(), m_entries.c_array(), sizeof(IndividualData *) * m_entries.size());
 
     // Change sort criteria and sort.
-    BOOST_FOREACH (IndividualData &data, m_entries) {
-        data.init(m_compare.get(), NULL, data.m_individual);
+    // Optionally also re-compute locale-dependent values, if
+    // the locale changed (see setLocale()).
+    LocaleFactory *locale = m_localeChanged ? m_locale.get() : NULL;
+    m_localeChanged = false;
+    boost::dynamic_bitset<size_t> modified(locale ? m_entries.size() : 0);
+    for (size_t i = 0; i < m_entries.size(); i++ ) {
+        IndividualData &data = m_entries[i];
+        bool preComputedModified = data.init(m_compare.get(), locale, data.m_individual);
+        if (locale && preComputedModified) {
+            modified.set(i);
+        }
     }
     m_entries.sort(IndividualDataCompare(m_compare));
 
     }
     m_entries.sort(IndividualDataCompare(m_compare));
 
@@ -306,7 +328,8 @@ void FullView::setCompare(const boost::shared_ptr<IndividualCompare> &compare)
     for (size_t index = 0; index < m_entries.size(); index++) {
         IndividualData &previous = *old[index],
             &current = m_entries[index];
     for (size_t index = 0; index < m_entries.size(); index++) {
         IndividualData &previous = *old[index],
             &current = m_entries[index];
-        if (previous.m_individual != current.m_individual) {
+        if (previous.m_individual != current.m_individual ||
+            (locale && modified[index])) {
             // Contact at the index changed. Don't try to find out
             // where it came from now. The effect is that temporarily
             // the same contact might be shown at two different
             // Contact at the index changed. Don't try to find out
             // where it came from now. The effect is that temporarily
             // the same contact might be shown at two different
index 3035fa5..40531fb 100644 (file)
@@ -33,6 +33,7 @@ class FullView : public IndividualView
 {
     FolksIndividualAggregatorCXX m_folks;
     boost::shared_ptr<LocaleFactory> m_locale;
 {
     FolksIndividualAggregatorCXX m_folks;
     boost::shared_ptr<LocaleFactory> m_locale;
+    bool m_localeChanged;
     bool m_isQuiescent;
     boost::weak_ptr<FullView> m_self;
     Timeout m_waitForIdle;
     bool m_isQuiescent;
     boost::weak_ptr<FullView> m_self;
     Timeout m_waitForIdle;
@@ -78,6 +79,12 @@ class FullView : public IndividualView
     static boost::shared_ptr<FullView> create(const FolksIndividualAggregatorCXX &folks,
                                               const boost::shared_ptr<LocaleFactory> &locale);
 
     static boost::shared_ptr<FullView> create(const FolksIndividualAggregatorCXX &folks,
                                               const boost::shared_ptr<LocaleFactory> &locale);
 
+    /**
+     * Change locale. Updating pre-computed data must be triggered by
+     * calling setCompare() later.
+     */
+    void setLocale(const boost::shared_ptr<LocaleFactory> &locale);
+
     /** FolksIndividualAggregator "individuals-changed" slot */
     void individualsChanged(GeeSet *added,
                             GeeSet *removed,
     /** FolksIndividualAggregator "individuals-changed" slot */
     void individualsChanged(GeeSet *added,
                             GeeSet *removed,
index 4cf2951..583602b 100644 (file)
 #include <phonenumbers/phonenumberutil.h>
 #include <phonenumbers/logger.h>
 #include <boost/locale.hpp>
 #include <phonenumbers/phonenumberutil.h>
 #include <phonenumbers/logger.h>
 #include <boost/locale.hpp>
+#include <boost/lexical_cast.hpp>
 
 #include <unicode/unistr.h>
 #include <unicode/translit.h>
 #include <unicode/bytestream.h>
 
 #include <unicode/unistr.h>
 #include <unicode/translit.h>
 #include <unicode/bytestream.h>
+#include <unicode/locid.h>
 
 SE_GLIB_TYPE(EBookQuery, e_book_query)
 
 
 SE_GLIB_TYPE(EBookQuery, e_book_query)
 
@@ -110,6 +112,8 @@ std::string CompareBoost::transform(const char *string) const
 
 std::string CompareBoost::transform(const std::string &string) const
 {
 
 std::string CompareBoost::transform(const std::string &string) const
 {
+    // TODO: use e_collator_generate_key
+
     if (m_trans.get()) {
         // std::string result;
         // m_trans->transliterate(icu::StringPiece(string), icu::StringByteSink<std::string>(&result));
     if (m_trans.get()) {
         // std::string result;
         // m_trans->transliterate(icu::StringPiece(string), icu::StringByteSink<std::string>(&result));
@@ -205,32 +209,63 @@ class AnyContainsBoost : public IndividualFilter
 {
 public:
     enum Mode {
 {
 public:
     enum Mode {
-        CASE_SENSITIVE,
-        CASE_INSENSITIVE
+        EXACT = 0,
+        CASE_INSENSITIVE = 1<<0,
+        ACCENT_INSENSITIVE = 1<<1,
+        TRANSLITERATE = 1<<2,
+        ALL =
+        CASE_INSENSITIVE|
+        ACCENT_INSENSITIVE|
+        TRANSLITERATE|
+        0
     };
 
     AnyContainsBoost(const std::locale &locale,
                      const std::string &searchValue,
     };
 
     AnyContainsBoost(const std::locale &locale,
                      const std::string &searchValue,
-                     Mode mode) :
+                     int mode) :
         m_locale(locale),
         m_locale(locale),
+        // For performance reasons we use ICU directly and thus need
+        // an ICU::Locale.
+        //         m_ICULocale(std::use_facet<boost::locale::info>(m_locale).language().c_str(),
+        //            std::use_facet<boost::locale::info>(m_locale).country().c_str(),
+        //            std::use_facet<boost::locale::info>(m_locale).variant().c_str()),
         // m_collator(std::use_facet<boost::locale::collator>(locale)),
         m_searchValue(searchValue),
         m_mode(mode)
     {
         // m_collator(std::use_facet<boost::locale::collator>(locale)),
         m_searchValue(searchValue),
         m_mode(mode)
     {
+        if (mode & TRANSLITERATE) {
+            UErrorCode status = U_ZERO_ERROR;
+            m_transliterator.reset(Transliterator::createInstance ("Any-Latin", UTRANS_FORWARD, status));
+            if (!m_transliterator ||
+                U_FAILURE(status)) {
+                SE_LOG_WARNING(NULL, "creating ICU Any-Latin Transliterator failed, error code %s; falling back to not transliterating", u_errorName(status));
+                m_transliterator.reset();
+                mode ^= TRANSLITERATE;
+                m_mode = mode;
+            }
+        }
+
         switch (mode) {
         switch (mode) {
-        case CASE_SENSITIVE:
-            // Search directly, no preprocessing.
+        case EXACT:
             break;
             break;
-        case CASE_INSENSITIVE:
-            // Locale-aware conversion to fold case (= case
-            // independent) representation before search.
-            m_searchValueTransformed = boost::locale::fold_case(m_searchValue, m_locale);
+        default:
+            m_searchValueTransformed = transform(m_searchValue);
             break;
         }
         m_searchValueTel = normalizePhoneText(m_searchValue.c_str());
     }
 
     /**
             break;
         }
         m_searchValueTel = normalizePhoneText(m_searchValue.c_str());
     }
 
     /**
+     * Turn filter arguments into bit field.
+     */
+    static int getFilterMode(const std::vector<LocaleFactory::Filter_t> &terms,
+                             size_t start);
+
+    /** simplify according to mode */
+    std::string transform(const char *in) const;
+    std::string transform(const std::string &in) const { return transform(in.c_str()); }
+
+    /**
      * The search text is not necessarily a full phone number,
      * therefore we cannot parse it with libphonenumber. Instead
      * do a sub-string search after telephone specific normalization,
      * The search text is not necessarily a full phone number,
      * therefore we cannot parse it with libphonenumber. Instead
      * do a sub-string search after telephone specific normalization,
@@ -271,12 +306,12 @@ public:
             return false;
         }
         switch (m_mode) {
             return false;
         }
         switch (m_mode) {
-        case CASE_SENSITIVE:
+        case EXACT:
             return boost::contains(text, m_searchValue);
             break;
             return boost::contains(text, m_searchValue);
             break;
-        case CASE_INSENSITIVE: {
-            std::string lower(boost::locale::fold_case(text, m_locale));
-            return boost::contains(lower, m_searchValueTransformed);
+        default: {
+            std::string transformed = transform(text);
+            return boost::contains(transformed, m_searchValueTransformed);
             break;
         }
         }
             break;
         }
         }
@@ -296,12 +331,12 @@ public:
             return false;
         }
         switch (m_mode) {
             return false;
         }
         switch (m_mode) {
-        case CASE_SENSITIVE:
+        case EXACT:
             return boost::equals(text, m_searchValue);
             break;
             return boost::equals(text, m_searchValue);
             break;
-        case CASE_INSENSITIVE: {
-            std::string lower(boost::locale::fold_case(text, m_locale));
-            return boost::equals(lower, m_searchValueTransformed);
+        default: {
+            std::string transformed = transform(text);
+            return boost::equals(transformed, m_searchValueTransformed);
             break;
         }
         }
             break;
         }
         }
@@ -321,12 +356,12 @@ public:
             return false;
         }
         switch (m_mode) {
             return false;
         }
         switch (m_mode) {
-        case CASE_SENSITIVE:
+        case EXACT:
             return boost::starts_with(text, m_searchValue);
             break;
             return boost::starts_with(text, m_searchValue);
             break;
-        case CASE_INSENSITIVE: {
-            std::string lower(boost::locale::fold_case(text, m_locale));
-            return boost::starts_with(lower, m_searchValueTransformed);
+        default:  {
+            std::string transformed = transform(text);
+            return boost::starts_with(transformed, m_searchValueTransformed);
             break;
         }
         }
             break;
         }
         }
@@ -346,12 +381,12 @@ public:
             return false;
         }
         switch (m_mode) {
             return false;
         }
         switch (m_mode) {
-        case CASE_SENSITIVE:
+        case EXACT:
             return boost::ends_with(text, m_searchValue);
             break;
             return boost::ends_with(text, m_searchValue);
             break;
-        case CASE_INSENSITIVE: {
-            std::string lower(boost::locale::fold_case(text, m_locale));
-            return boost::ends_with(lower, m_searchValueTransformed);
+        default: {
+            std::string transformed = transform(text);
+            return boost::ends_with(transformed, m_searchValueTransformed);
             break;
         }
         }
             break;
         }
         }
@@ -416,13 +451,62 @@ public:
 
 private:
     std::locale m_locale;
 
 private:
     std::locale m_locale;
+    // icu::Locale m_ICULocale;
+    boost::shared_ptr<icu::Transliterator> m_transliterator;
     std::string m_searchValue;
     std::string m_searchValueTransformed;
     std::string m_searchValueTel;
     std::string m_searchValue;
     std::string m_searchValueTransformed;
     std::string m_searchValueTel;
-    Mode m_mode;
+    int m_mode;
     // const bool (*m_contains)(const std::string &, const std::string &, const std::locale &);
 };
 
     // const bool (*m_contains)(const std::string &, const std::string &, const std::locale &);
 };
 
+std::string AnyContainsBoost::transform(const char *in) const
+{
+    icu::UnicodeString unicode = icu::UnicodeString::fromUTF8(in);
+    if (m_mode & TRANSLITERATE) {
+        m_transliterator->transliterate(unicode);
+    }
+    if (m_mode & CASE_INSENSITIVE) {
+        unicode.foldCase();
+    }
+    std::string utf8;
+    unicode.toUTF8String(utf8);
+    if (m_mode & ACCENT_INSENSITIVE) {
+        // Haven't found an easy way to do this with ICU.
+        // Use e_util_utf8_remove_accents(), which also ensures
+        // consistency with EDS.
+        PlainGStr res = e_util_utf8_remove_accents(utf8.c_str());
+        return std::string(res);
+    } else {
+        return utf8;
+    }
+}
+
+int AnyContainsBoost::getFilterMode(const std::vector<LocaleFactory::Filter_t> &terms,
+                                    size_t start)
+{
+    int mode = ALL;
+    for (size_t i = start; i < terms.size(); i++) {
+        const std::string flag = LocaleFactory::getFilterString(terms[i], "any-contains flag");
+        if (flag == "case-sensitive") {
+            mode &= ~CASE_INSENSITIVE;
+        } else if (flag == "case-insensitive") {
+            mode |= CASE_INSENSITIVE;
+        } else if (flag == "accent-sensitive") {
+            mode &= ~ACCENT_INSENSITIVE;
+        } else if (flag == "accent-insensitive") {
+            mode |= ACCENT_INSENSITIVE;
+        } else if (flag == "no-transliteration") {
+            mode &= ~TRANSLITERATE;
+        } else if (flag == "transliteration") {
+            mode |= TRANSLITERATE;
+        } else {
+            SE_THROW("unsupported filter flag: " + flag);
+        }
+    }
+    return mode;
+}
+
 class FilterFullName : public AnyContainsBoost
 {
     bool (AnyContainsBoost::*m_operation)(const char *text) const;
 class FilterFullName : public AnyContainsBoost
 {
     bool (AnyContainsBoost::*m_operation)(const char *text) const;
@@ -430,7 +514,7 @@ class FilterFullName : public AnyContainsBoost
 public:
     FilterFullName(const std::locale &locale,
                    const std::string &searchValue,
 public:
     FilterFullName(const std::locale &locale,
                    const std::string &searchValue,
-                   Mode mode,
+                   int mode,
                    bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                    bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -453,7 +537,7 @@ class FilterNickname : public AnyContainsBoost
 public:
     FilterNickname(const std::locale &locale,
                    const std::string &searchValue,
 public:
     FilterNickname(const std::locale &locale,
                    const std::string &searchValue,
-                   Mode mode,
+                   int mode,
                    bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                    bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -476,7 +560,7 @@ class FilterFamilyName : public AnyContainsBoost
 public:
     FilterFamilyName(const std::locale &locale,
                      const std::string &searchValue,
 public:
     FilterFamilyName(const std::locale &locale,
                      const std::string &searchValue,
-                     Mode mode,
+                     int mode,
                      bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                      bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -504,7 +588,7 @@ class FilterGivenName : public AnyContainsBoost
 public:
     FilterGivenName(const std::locale &locale,
                     const std::string &searchValue,
 public:
     FilterGivenName(const std::locale &locale,
                     const std::string &searchValue,
-                    Mode mode,
+                    int mode,
                     bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                     bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -532,7 +616,7 @@ class FilterAdditionalName : public AnyContainsBoost
 public:
     FilterAdditionalName(const std::locale &locale,
                          const std::string &searchValue,
 public:
     FilterAdditionalName(const std::locale &locale,
                          const std::string &searchValue,
-                         Mode mode,
+                         int mode,
                          bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                          bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -560,7 +644,7 @@ class FilterEmails : public AnyContainsBoost
 public:
     FilterEmails(const std::locale &locale,
                  const std::string &searchValue,
 public:
     FilterEmails(const std::locale &locale,
                  const std::string &searchValue,
-                 Mode mode,
+                 int mode,
                  bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                  bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -591,7 +675,7 @@ public:
     FilterTel(const std::locale &locale,
               const std::string &searchValue,
               bool (AnyContainsBoost::*operation)(const char *text) const) :
     FilterTel(const std::locale &locale,
               const std::string &searchValue,
               bool (AnyContainsBoost::*operation)(const char *text) const) :
-        AnyContainsBoost(locale, searchValue, CASE_SENSITIVE /* doesn't matter */),
+        AnyContainsBoost(locale, searchValue, 0 /* doesn't matter */),
         m_operation(operation)
     {
     }
         m_operation(operation)
     {
     }
@@ -620,7 +704,7 @@ protected:
 public:
     FilterAddr(const std::locale &locale,
                const std::string &searchValue,
 public:
     FilterAddr(const std::locale &locale,
                const std::string &searchValue,
-               Mode mode,
+               int mode,
                bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
                bool (AnyContainsBoost::*operation)(const char *text) const) :
         AnyContainsBoost(locale, searchValue, mode),
         m_operation(operation)
@@ -650,7 +734,7 @@ class FilterAddrPOBox : public FilterAddr
 public:
     FilterAddrPOBox(const std::locale &locale,
                     const std::string &searchValue,
 public:
     FilterAddrPOBox(const std::locale &locale,
                     const std::string &searchValue,
-                    Mode mode,
+                    int mode,
                     bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                     bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -668,7 +752,7 @@ class FilterAddrExtension : public FilterAddr
 public:
     FilterAddrExtension(const std::locale &locale,
                         const std::string &searchValue,
 public:
     FilterAddrExtension(const std::locale &locale,
                         const std::string &searchValue,
-                        Mode mode,
+                        int mode,
                         bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                         bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -686,7 +770,7 @@ class FilterAddrStreet : public FilterAddr
 public:
     FilterAddrStreet(const std::locale &locale,
                      const std::string &searchValue,
 public:
     FilterAddrStreet(const std::locale &locale,
                      const std::string &searchValue,
-                     Mode mode,
+                     int mode,
                      bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                      bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -704,7 +788,7 @@ class FilterAddrLocality : public FilterAddr
 public:
     FilterAddrLocality(const std::locale &locale,
                        const std::string &searchValue,
 public:
     FilterAddrLocality(const std::locale &locale,
                        const std::string &searchValue,
-                       Mode mode,
+                       int mode,
                        bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                        bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -722,7 +806,7 @@ class FilterAddrRegion : public FilterAddr
 public:
     FilterAddrRegion(const std::locale &locale,
                      const std::string &searchValue,
 public:
     FilterAddrRegion(const std::locale &locale,
                      const std::string &searchValue,
-                     Mode mode,
+                     int mode,
                      bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                      bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -740,7 +824,7 @@ class FilterAddrPostalCode : public FilterAddr
 public:
     FilterAddrPostalCode(const std::locale &locale,
                          const std::string &searchValue,
 public:
     FilterAddrPostalCode(const std::locale &locale,
                          const std::string &searchValue,
-                         Mode mode,
+                         int mode,
                          bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                          bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -758,7 +842,7 @@ class FilterAddrCountry : public FilterAddr
 public:
     FilterAddrCountry(const std::locale &locale,
                       const std::string &searchValue,
 public:
     FilterAddrCountry(const std::locale &locale,
                       const std::string &searchValue,
-                      Mode mode,
+                      int mode,
                       bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
                       bool (AnyContainsBoost::*operation)(const char *text) const) :
         FilterAddr(locale, searchValue, mode, operation)
     {
@@ -775,10 +859,16 @@ public:
 
 
 /**
 
 
 /**
- * Search value must be a valid caller ID. The telephone numbers
- * in the contacts may or may not be valid; only valid ones
- * will match. The user is expected to clean up that data to get
- * exact matches for the others.
+ * Search value must be a valid caller ID (with or without a country
+ * code). The telephone numbers in the contacts may or may not be
+ * valid; only valid ones will match. The user is expected to clean up
+ * that data to get exact matches for the others.
+ *
+ * The matching uses the same semantic as EQUALS_NATIONAL_PHONE_NUMBER:
+ * - If both numbers have an explicit country code, that code must be
+ *   the same for a match.
+ * - If one or both numbers have no country code, matching the national
+ *   part is enough for a match.
  */
 class PhoneStartsWith : public IndividualFilter
 {
  */
 class PhoneStartsWith : public IndividualFilter
 {
@@ -811,19 +901,19 @@ public:
             break;
         }
 
             break;
         }
 
-        // Search based on full internal format, without formatting.
-        // For example: +41446681800
-        //
-        // A prefix match is good enough. That way a caller ID
-        // with suppressed extension still matches a contact with
-        // extension.
-        m_phoneNumberUtil.Format(number, i18n::phonenumbers::PhoneNumberUtil::E164, &m_tel);
+        m_number.m_countryCode = number.country_code();
+        m_number.m_nationalNumber = number.national_number();
     }
 
     virtual bool matches(const IndividualData &data) const
     {
     }
 
     virtual bool matches(const IndividualData &data) const
     {
-        BOOST_FOREACH(const std::string &tel, data.m_precomputed.m_phoneNumbers) {
-            if (boost::starts_with(tel, m_tel)) {
+        BOOST_FOREACH(const SimpleE164 &number, data.m_precomputed.m_phoneNumbers) {
+            // National part must always match, country code only if
+            // set explicitly in both (NSN_MATCH in libphonenumber,
+            // EQUALS_NATIONAL_PHONE_NUMBER in EDS).
+            if (number.m_nationalNumber == m_number.m_nationalNumber &&
+                (!number.m_countryCode || !m_number.m_countryCode ||
+                 number.m_countryCode == m_number.m_countryCode)) {
                 return true;
             }
         }
                 return true;
             }
         }
@@ -832,12 +922,13 @@ public:
 
     virtual std::string getEBookFilter() const
     {
 
     virtual std::string getEBookFilter() const
     {
-        size_t len = std::min((size_t)4, m_tel.size());
+        std::string tel = m_number.toString();
+        size_t len = std::min((size_t)4, tel.size());
         EBookQueryCXX query(m_simpleEDSSearch ?
                             // A suffix match with a limited number of digits is most
                             // likely to find the right contacts.
                             e_book_query_field_test(E_CONTACT_TEL, E_BOOK_QUERY_ENDS_WITH,
         EBookQueryCXX query(m_simpleEDSSearch ?
                             // A suffix match with a limited number of digits is most
                             // likely to find the right contacts.
                             e_book_query_field_test(E_CONTACT_TEL, E_BOOK_QUERY_ENDS_WITH,
-                                                    m_tel.substr(m_tel.size() - len, len).c_str()) :
+                                                    tel.substr(tel.size() - len, len).c_str()) :
                             // We use EQUALS_NATIONAL_PHONE_NUMBER
                             // instead of EQUALS_PHONE_NUMBER here,
                             // because it will also match contacts
                             // We use EQUALS_NATIONAL_PHONE_NUMBER
                             // instead of EQUALS_PHONE_NUMBER here,
                             // because it will also match contacts
@@ -851,19 +942,19 @@ public:
                             // check that and not return a false match
                             // if the country code is different.
                             //
                             // check that and not return a false match
                             // if the country code is different.
                             //
-                            // At the moment, we pass the E164
-                            // formatted search term with a country
-                            // code here. The country code is the
-                            // current default one.  We could think
-                            // about passing the original search term
-                            // instead, to allow matches where contact
-                            // and search term have no country code,
-                            // but it is uncertain whether EDS
-                            // currently works that way. It looks like
-                            // it always adds the default country code
-                            // to the search term.
+                            // We try to pass the E164 string here. If
+                            // the search term had no country code,
+                            // that's a bit difficult because we can't
+                            // just add the default country code.
+                            // That would break the
+                            // NATIONAL_PHONE_NUMBER semantic because
+                            // EDS wouldn't know that the search term
+                            // had no country code. We resort to the
+                            // format of SimpleE164.toString(), which
+                            // is passing the national number
+                            // formatted as string.
                             e_book_query_field_test(E_CONTACT_TEL, E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER,
                             e_book_query_field_test(E_CONTACT_TEL, E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER,
-                                                    m_tel.c_str()),
+                                                    tel.c_str()),
                             TRANSFER_REF);
         PlainGStr filter(e_book_query_to_string(query.get()));
         return filter.get();
                             TRANSFER_REF);
         PlainGStr filter(e_book_query_to_string(query.get()));
         return filter.get();
@@ -873,7 +964,7 @@ private:
     const i18n::phonenumbers::PhoneNumberUtil &m_phoneNumberUtil;
     bool m_simpleEDSSearch;
     std::string m_country;
     const i18n::phonenumbers::PhoneNumberUtil &m_phoneNumberUtil;
     bool m_simpleEDSSearch;
     std::string m_country;
-    std::string m_tel;
+    SimpleE164 m_number;
 };
 
 class PhoneNumberLogger : public i18n::phonenumbers::Logger
 };
 
 class PhoneNumberLogger : public i18n::phonenumbers::Logger
@@ -911,23 +1002,6 @@ public:
     }
 };
 
     }
 };
 
-static AnyContainsBoost::Mode getFilterMode(const std::vector<LocaleFactory::Filter_t> &terms,
-                                            size_t start)
-{
-    AnyContainsBoost::Mode mode = AnyContainsBoost::CASE_INSENSITIVE;
-    for (size_t i = start; i < terms.size(); i++) {
-        const std::string flag = LocaleFactory::getFilterString(terms[i], "any-contains flag");
-        if (flag == "case-sensitive") {
-            mode = AnyContainsBoost::CASE_SENSITIVE;
-        } else if (flag == "case-insensitive") {
-            mode = AnyContainsBoost::CASE_INSENSITIVE;
-        } else {
-            SE_THROW("unsupported filter flag: " + flag);
-        }
-    }
-    return mode;
-}
-
 class LocaleFactoryBoost : public LocaleFactory
 {
     const i18n::phonenumbers::PhoneNumberUtil &m_phoneNumberUtil;
 class LocaleFactoryBoost : public LocaleFactory
 {
     const i18n::phonenumbers::PhoneNumberUtil &m_phoneNumberUtil;
@@ -940,7 +1014,7 @@ class LocaleFactoryBoost : public LocaleFactory
 public:
     LocaleFactoryBoost() :
         m_phoneNumberUtil(*i18n::phonenumbers::PhoneNumberUtil::GetInstance()),
 public:
     LocaleFactoryBoost() :
         m_phoneNumberUtil(*i18n::phonenumbers::PhoneNumberUtil::GetInstance()),
-        m_edsSupportsPhoneNumbers(e_phone_number_is_supported()),
+        m_edsSupportsPhoneNumbers(e_phone_number_is_supported() && !getenv("SYNCEVOLUTION_PIM_EDS_NO_E164")),
         m_locale(genLocale()),
         m_country(std::use_facet<boost::locale::info>(m_locale).country()),
         m_defaultCountryCode(StringPrintf("+%d", m_phoneNumberUtil.GetCountryCodeForRegion(m_country)))
         m_locale(genLocale()),
         m_country(std::use_facet<boost::locale::info>(m_locale).country()),
         m_defaultCountryCode(StringPrintf("+%d", m_phoneNumberUtil.GetCountryCodeForRegion(m_country)))
@@ -1048,7 +1122,7 @@ public:
                                                 func == &AnyContainsBoost::endsWithSearchText ? &AnyContainsBoost::endsWithSearchTel :
                                                 func));
                     } else {
                                                 func == &AnyContainsBoost::endsWithSearchText ? &AnyContainsBoost::endsWithSearchTel :
                                                 func));
                     } else {
-                        AnyContainsBoost::Mode mode = getFilterMode(terms, 3);
+                        int mode = AnyContainsBoost::getFilterMode(terms, 3);
                         if (field == "full-name") {
                             res.reset(new FilterFullName(m_locale, value, mode, func));
                         } else if (field == "nickname") {
                         if (field == "full-name") {
                             res.reset(new FilterFullName(m_locale, value, mode, func));
                         } else if (field == "nickname") {
@@ -1084,7 +1158,7 @@ public:
                         SE_THROW("missing search value");
                     }
                     const std::string &value = getFilterString(terms[1], "search string");
                         SE_THROW("missing search value");
                     }
                     const std::string &value = getFilterString(terms[1], "search string");
-                    AnyContainsBoost::Mode mode = getFilterMode(terms, 2);
+                    int mode = AnyContainsBoost::getFilterMode(terms, 2);
                     res.reset(new AnyContainsBoost(m_locale, value, mode));
                 } else if (operation == "phone") {
                     if (terms.size() != 2) {
                     res.reset(new AnyContainsBoost(m_locale, value, mode));
                 } else if (operation == "phone") {
                     if (terms.size() != 2) {
@@ -1104,9 +1178,10 @@ public:
         return res ? res : LocaleFactory::createFilter(filter, level);
     }
 
         return res ? res : LocaleFactory::createFilter(filter, level);
     }
 
-    virtual void precompute(FolksIndividual *individual, Precomputed &precomputed) const
+    virtual bool precompute(FolksIndividual *individual, Precomputed &precomputed) const
     {
     {
-        precomputed.m_phoneNumbers.clear();
+        LocaleFactory::Precomputed old;
+        std::swap(old, precomputed);
 
         FolksPhoneDetails *phoneDetails = FOLKS_PHONE_DETAILS(individual);
         GeeSet *phones = folks_phone_details_get_phone_numbers(phoneDetails);
 
         FolksPhoneDetails *phoneDetails = FOLKS_PHONE_DETAILS(individual);
         GeeSet *phones = folks_phone_details_get_phone_numbers(phoneDetails);
@@ -1116,7 +1191,8 @@ public:
                 reinterpret_cast<const gchar *>(folks_abstract_field_details_get_value(phone));
             if (value) {
                 if (m_edsSupportsPhoneNumbers) {
                 reinterpret_cast<const gchar *>(folks_abstract_field_details_get_value(phone));
             if (value) {
                 if (m_edsSupportsPhoneNumbers) {
-                    // TODO: check X-EVOLUTION-E164 (made lowercase by folks!).
+                    // Check X-EVOLUTION-E164 (made lowercase by folks!).
+                    //
                     // It has the format <local number>,<country code>,
                     // where <country code> happens to be in quotation marks.
                     // This ends up being split into individual values which
                     // It has the format <local number>,<country code>,
                     // where <country code> happens to be in quotation marks.
                     // This ends up being split into individual values which
@@ -1133,21 +1209,32 @@ public:
                         components.reserve(2);
                         BOOST_FOREACH (const gchar *component, GeeStringCollection(coll)) {
                             // Empty component represents an unset
                         components.reserve(2);
                         BOOST_FOREACH (const gchar *component, GeeStringCollection(coll)) {
                             // Empty component represents an unset
-                            // country code. Replace with the current
-                            // country code to form the full number.
-                            // Note that it is not certain whether we
-                            // get to see the empty component. At the
-                            // moment (EDS 3.7, folks 0.9.1), someone
-                            // swallows it.
-                            components.push_back(component[0] ? component : m_defaultCountryCode);
+                            // country code. Note that it is not
+                            // certain whether we get to see the empty
+                            // component. At the moment (EDS 3.7,
+                            // folks 0.9.1), someone swallows it.
+                            components.push_back(component);
                         }
                         }
-                        // Only one component? We must still miss the country code.
-                        if (components.size() == 1) {
-                            components.push_back(m_defaultCountryCode);
+                        if (!components.empty()) {
+                            // Only one component? We must still miss the country code.
+                            if (components.size() == 1) {
+                                components.push_back("");
+                            }
+                            std::sort(components.begin(), components.end());
+                            try {
+                                SimpleE164 number;
+                                number.m_countryCode = components[0].empty() ?
+                                    0 :
+                                    boost::lexical_cast<SimpleE164::CountryCode_t>(components[0]);
+                                number.m_nationalNumber = components[1].empty() ?
+                                    0 :
+                                    boost::lexical_cast<SimpleE164::NationalNumber_t>(components[1]);
+                                precomputed.m_phoneNumbers.push_back(number);
+                            } catch (const boost::bad_lexical_cast &ex) {
+                                SE_LOG_WARNING(NULL, "ignoring malformed X-EVOLUTION-E164 (sorted): %s",
+                                               boost::join(components, ", ").c_str());
+                            }
                         }
                         }
-                        std::sort(components.begin(), components.end());
-                        std::string normal = boost::join(components, "");
-                        precomputed.m_phoneNumbers.push_back(normal);
                     }
                     // Either EDS had a normalized value or there is none because
                     // the value is not a phone number. No need to try parsing again.
                     }
                     // Either EDS had a normalized value or there is none because
                     // the value is not a phone number. No need to try parsing again.
@@ -1158,12 +1245,16 @@ public:
                 i18n::phonenumbers::PhoneNumberUtil::ErrorType error =
                     m_phoneNumberUtil.Parse(value, m_country, &number);
                 if (error == i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) {
                 i18n::phonenumbers::PhoneNumberUtil::ErrorType error =
                     m_phoneNumberUtil.Parse(value, m_country, &number);
                 if (error == i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) {
-                    std::string tel;
-                    m_phoneNumberUtil.Format(number, i18n::phonenumbers::PhoneNumberUtil::E164, &tel);
-                    precomputed.m_phoneNumbers.push_back(tel);
+                    SimpleE164 e164;
+                    e164.m_countryCode = number.country_code();
+                    e164.m_nationalNumber = number.national_number();
+                    precomputed.m_phoneNumbers.push_back(e164);
                 }
             }
         }
                 }
             }
         }
+
+        // Now check if any phone number changed.
+        return old != precomputed;
     }
 };
 
     }
 };
 
index f30cf41..3b5b960 100644 (file)
 
 SE_BEGIN_CXX
 
 
 SE_BEGIN_CXX
 
+std::string SimpleE164::toString() const
+{
+    std::ostringstream out;
+    if (m_countryCode) {
+        out << "+" << m_countryCode;
+    }
+    if (m_nationalNumber) {
+        out << m_nationalNumber;
+    }
+    return out.str();
+}
+
+bool LocaleFactory::Precomputed::operator == (const LocaleFactory::Precomputed &other) const
+{
+    if (other.m_phoneNumbers.size() != m_phoneNumbers.size()) {
+        return false;
+    }
+    PhoneNumbers::const_iterator ita = other.m_phoneNumbers.begin();
+    PhoneNumbers::const_iterator itb = m_phoneNumbers.begin();
+    while (ita != other.m_phoneNumbers.end()) {
+        if (*ita != *itb) {
+            return false;
+        }
+        ++ita;
+        ++itb;
+    }
+    return true;
+}
+
 class Filter2StringVisitor : public boost::static_visitor<void>
 {
     std::ostringstream m_out;
 class Filter2StringVisitor : public boost::static_visitor<void>
 {
     std::ostringstream m_out;
index 48aee19..9a043ac 100644 (file)
@@ -39,6 +39,46 @@ SE_BEGIN_CXX
 class IndividualCompare;
 class IndividualFilter;
 
 class IndividualCompare;
 class IndividualFilter;
 
+/**
+ * Normalized phone numbers (E164). A subset of the full
+ * i18n::phonenumbers::PhoneNumber data.
+ */
+class SimpleE164
+{
+ public:
+    SimpleE164() : m_countryCode(0), m_nationalNumber(0) {}
+
+    typedef int32_t CountryCode_t;
+    typedef uint64_t NationalNumber_t;
+
+    /**
+     * Country code (for example, 49 for the +49 prefix of Germany),
+     * 0 if unknown/unset.
+     */
+    CountryCode_t m_countryCode;
+
+    /**
+     * Phone number after the country code as it would appear in E.164
+     * after the +<country> prefix, again given as binary value,
+     * 0 if unknown/unset.
+     */
+    NationalNumber_t m_nationalNumber;
+
+    /**
+     * +<country><national> if country code and national number are set,
+     * +<country> if only country code is set,
+     * <national> if only national number is set,
+     * empty string if both are unset.
+     */
+    std::string toString() const;
+
+    bool operator == (const SimpleE164 &other) const 
+    {
+        return m_countryCode == other.m_countryCode &&
+        m_nationalNumber == other.m_nationalNumber;
+    }
+    bool operator != (const SimpleE164 &other) const { return !(*this == other); }
+};
 
 /**
  * Factory for everything related to the current locale: sorting and
 
 /**
  * Factory for everything related to the current locale: sorting and
@@ -114,17 +154,16 @@ class LocaleFactory
      */
     struct Precomputed
     {
      */
     struct Precomputed
     {
-        /**
-         * Normalized phone numbers (E164). Contains only + and digits.
-         * TODO (?): store in more compact format.
-         */
-        std::vector<std::string> m_phoneNumbers;
+        typedef std::vector<SimpleE164> PhoneNumbers;
+        PhoneNumbers m_phoneNumbers;
+        bool operator == (const Precomputed &other) const;
+        bool operator != (const Precomputed &other) const { return !(*this == other); }
     };
 
     /**
      * (Re)set pre-computed data for an individual.
      */
     };
 
     /**
      * (Re)set pre-computed data for an individual.
      */
-    virtual void precompute(FolksIndividual *individual, Precomputed &precomputed) const = 0;
+    virtual bool precompute(FolksIndividual *individual, Precomputed &precomputed) const = 0;
 };
 
 SE_END_CXX
 };
 
 SE_END_CXX
index 7bc626d..5183284 100644 (file)
@@ -27,6 +27,7 @@
 #include "../resource.h"
 #include "../client.h"
 #include "../session.h"
 #include "../resource.h"
 #include "../client.h"
 #include "../session.h"
+#include "../localed-listener.h"
 
 #include <syncevo/IniConfigNode.h>
 #include <syncevo/BoostHelper.h>
 
 #include <syncevo/IniConfigNode.h>
 #include <syncevo/BoostHelper.h>
@@ -81,8 +82,15 @@ Manager::Manager(const boost::shared_ptr<Server> &server) :
     m_mainThread(g_thread_self()),
     m_server(server),
     m_locale(LocaleFactory::createFactory()),
     m_mainThread(g_thread_self()),
     m_server(server),
     m_locale(LocaleFactory::createFactory()),
+    m_localedListener(LocaledListener::create()),
     emitSyncProgress(*this, "SyncProgress")
 {
     emitSyncProgress(*this, "SyncProgress")
 {
+    // Update our own environment and sorting on each locale change.
+    m_localedListener->m_localeValues.connect(boost::bind(&LocaledListener::setLocale, m_localedListener.get(), _1));
+    m_localedListener->m_localeChanged.connect(boost::bind(&Manager::localeChanged, this));
+
+    // Get the environment once from localed, just to be sure.
+    m_localedListener->check(boost::bind(&LocaledListener::setLocale, boost::weak_ptr<LocaledListener>(m_localedListener), _1));
 }
 
 Manager::~Manager()
 }
 
 Manager::~Manager()
@@ -116,7 +124,6 @@ void Manager::init()
         "last/first";
     InitStateString active = m_configNode->readProperty(MANAGER_CONFIG_ACTIVE_ADDRESS_BOOKS_PROPERTY);
     m_enabledEBooks.clear();
         "last/first";
     InitStateString active = m_configNode->readProperty(MANAGER_CONFIG_ACTIVE_ADDRESS_BOOKS_PROPERTY);
     m_enabledEBooks.clear();
-    typedef boost::split_iterator<string::iterator> string_split_iterator;
     BOOST_FOREACH(const std::string &entry,
                   boost::tokenizer< boost::char_separator<char> >(active, boost::char_separator<char>(", \t"))) {
         if (!entry.empty()) {
     BOOST_FOREACH(const std::string &entry,
                   boost::tokenizer< boost::char_separator<char> >(active, boost::char_separator<char>(", \t"))) {
         if (!entry.empty()) {
@@ -124,7 +131,16 @@ void Manager::init()
         }
     }
     initFolks();
         }
     }
     initFolks();
-    initSorting(m_sortOrder);
+    try {
+        initSorting(m_sortOrder);
+    } catch (...) {
+        std::string explanation;
+        Exception::handle(explanation, HANDLE_EXCEPTION_NO_ERROR);
+        SE_LOG_WARNING(NULL, "Restoring sort order from config failed, falling back to default: %s",
+                       explanation.c_str());
+        m_sortOrder = "last/first";
+        initSorting(m_sortOrder);
+    }
     initDatabases();
 
     add(this, &Manager::start, "Start");
     initDatabases();
 
     add(this, &Manager::start, "Start");
@@ -257,6 +273,23 @@ void Manager::initSorting(const std::string &order)
     m_folks->setCompare(compare);
 }
 
     m_folks->setCompare(compare);
 }
 
+void Manager::localeChanged()
+{
+    // First update locale.
+    m_locale = LocaleFactory::createFactory();
+    // Change sorting. First install new locale in
+    // IndividualAggregator and through it in FullView.
+    if (m_folks) {
+        m_folks->setLocale(m_locale);
+    }
+    // Then update IndividualData of all loaded individuals by
+    // changing the sort order.
+    initSorting(m_sortOrder);
+
+    // Now update views.
+    m_localeChanged(m_locale);
+}
+
 boost::shared_ptr<Manager> Manager::create(const boost::shared_ptr<Server> &server)
 {
     boost::shared_ptr<Manager> manager(new Manager(server));
 boost::shared_ptr<Manager> Manager::create(const boost::shared_ptr<Server> &server)
 {
     boost::shared_ptr<Manager> manager(new Manager(server));
@@ -366,6 +399,7 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
     boost::shared_ptr<IndividualView> m_view;
     boost::shared_ptr<LocaleFactory> m_locale;
     boost::weak_ptr<Client> m_owner;
     boost::shared_ptr<IndividualView> m_view;
     boost::shared_ptr<LocaleFactory> m_locale;
     boost::weak_ptr<Client> m_owner;
+    LocaleFactory::Filter_t m_filter;
     struct Change {
         Change() : m_start(0), m_call(NULL) {}
 
     struct Change {
         Change() : m_start(0), m_call(NULL) {}
 
@@ -381,6 +415,7 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
     ViewResource(const boost::shared_ptr<IndividualView> view,
                  const boost::shared_ptr<LocaleFactory> &locale,
                  const boost::shared_ptr<Client> &owner,
     ViewResource(const boost::shared_ptr<IndividualView> view,
                  const boost::shared_ptr<LocaleFactory> &locale,
                  const boost::shared_ptr<Client> &owner,
+                 const LocaleFactory::Filter_t &filter,
                  GDBusCXX::connection_type *connection,
                  const GDBusCXX::Caller_t &ID,
                  const GDBusCXX::DBusObject_t &agentPath) :
                  GDBusCXX::connection_type *connection,
                  const GDBusCXX::Caller_t &ID,
                  const GDBusCXX::DBusObject_t &agentPath) :
@@ -394,6 +429,7 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
         m_view(view),
         m_locale(locale),
         m_owner(owner),
         m_view(view),
         m_locale(locale),
         m_owner(owner),
+        m_filter(filter),
 
         // use ViewAgent interface
         m_quiescent(m_viewAgent, "Quiescent"),
 
         // use ViewAgent interface
         m_quiescent(m_viewAgent, "Quiescent"),
@@ -707,6 +743,7 @@ public:
     static boost::shared_ptr<ViewResource> create(const boost::shared_ptr<IndividualView> &view,
                                                   const boost::shared_ptr<LocaleFactory> &locale,
                                                   const boost::shared_ptr<Client> &owner,
     static boost::shared_ptr<ViewResource> create(const boost::shared_ptr<IndividualView> &view,
                                                   const boost::shared_ptr<LocaleFactory> &locale,
                                                   const boost::shared_ptr<Client> &owner,
+                                                  const LocaleFactory::Filter_t &filter,
                                                   GDBusCXX::connection_type *connection,
                                                   const GDBusCXX::Caller_t &ID,
                                                   const GDBusCXX::DBusObject_t &agentPath)
                                                   GDBusCXX::connection_type *connection,
                                                   const GDBusCXX::Caller_t &ID,
                                                   const GDBusCXX::DBusObject_t &agentPath)
@@ -714,6 +751,7 @@ public:
         boost::shared_ptr<ViewResource> viewResource(new ViewResource(view,
                                                                       locale,
                                                                       owner,
         boost::shared_ptr<ViewResource> viewResource(new ViewResource(view,
                                                                       locale,
                                                                       owner,
+                                                                      filter,
                                                                       connection,
                                                                       ID,
                                                                       agentPath));
                                                                       connection,
                                                                       ID,
                                                                       agentPath));
@@ -770,10 +808,32 @@ public:
     void replaceSearch(const std::vector<LocaleFactory::Filter_t> &filterArray, bool refine)
     {
         // Same as in Search().
     void replaceSearch(const std::vector<LocaleFactory::Filter_t> &filterArray, bool refine)
     {
         // Same as in Search().
-        LocaleFactory::Filter_t filter = filterArray;
-        boost::shared_ptr<IndividualFilter> individualFilter = m_locale->createFilter(filter, 0);
+        m_filter = filterArray;
+        redoSearch(refine);
+    }
+
+    /**
+     * Start filtering again, using the current environment. To be
+     * called after a locale change or when m_filter changed.
+     *
+     * @param refine   true only if it is known to the caller that the new result set is
+     *                 a subset of the current one, false if uncertain
+     */
+    void redoSearch(bool refine)
+    {
+        boost::shared_ptr<IndividualFilter> individualFilter = m_locale->createFilter(m_filter, 0);
         m_view->replaceFilter(individualFilter, refine);
     }
         m_view->replaceFilter(individualFilter, refine);
     }
+
+    /**
+     * Change locale, then refilter because the filter may have changed.
+     */
+    void setLocale(const boost::shared_ptr<LocaleFactory> &locale)
+    {
+        m_locale = locale;
+        redoSearch(true);
+    }
+
 };
 unsigned int ViewResource::m_counter;
 
 };
 unsigned int ViewResource::m_counter;
 
@@ -897,11 +957,15 @@ void Manager::doSearch(const ESourceRegistryCXX &registry,
     boost::shared_ptr<ViewResource> viewResource(ViewResource::create(view,
                                                                       m_locale,
                                                                       client,
     boost::shared_ptr<ViewResource> viewResource(ViewResource::create(view,
                                                                       m_locale,
                                                                       client,
+                                                                      filter,
                                                                       getConnection(),
                                                                       ID,
                                                                       agentPath));
     client->attach(boost::shared_ptr<Resource>(viewResource));
 
                                                                       getConnection(),
                                                                       ID,
                                                                       agentPath));
     client->attach(boost::shared_ptr<Resource>(viewResource));
 
+    // Redo search when locale changes.
+    m_localeChanged.connect(LocaleChangedSignal::slot_type(&ViewResource::setLocale, viewResource.get(), _1).track(viewResource));
+
     // created local resource
     result->done(viewResource->getPath());
 }
     // created local resource
     result->done(viewResource->getPath());
 }
@@ -1272,7 +1336,7 @@ void Manager::doRemovePeer(const boost::shared_ptr<Session> &session,
     // doing so doesn't hurt.
     m_enabledEBooks.erase(localDatabaseName);
     initDatabases();
     // doing so doesn't hurt.
     m_enabledEBooks.erase(localDatabaseName);
     initDatabases();
-    m_configNode->writeProperty(MANAGER_CONFIG_SORT_PROPERTY,
+    m_configNode->writeProperty(MANAGER_CONFIG_ACTIVE_ADDRESS_BOOKS_PROPERTY,
                                 InitStateString(boost::join(m_enabledEBooks, " "), true));
     m_configNode->flush();
 
                                 InitStateString(boost::join(m_enabledEBooks, " "), true));
     m_configNode->flush();
 
index d43a523..e9fee00 100644 (file)
@@ -34,6 +34,8 @@
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
+class LocaledListener;
+
 /**
  * Implementation of org._01.pim.contacts.Manager.
  */
 /**
  * Implementation of org._01.pim.contacts.Manager.
  */
@@ -44,6 +46,7 @@ class Manager : public GDBusCXX::DBusObjectHelper
     boost::shared_ptr<Server> m_server;
     boost::shared_ptr<IndividualAggregator> m_folks;
     boost::shared_ptr<LocaleFactory> m_locale;
     boost::shared_ptr<Server> m_server;
     boost::shared_ptr<IndividualAggregator> m_folks;
     boost::shared_ptr<LocaleFactory> m_locale;
+    boost::shared_ptr<LocaledListener> m_localedListener;
     /** Stores "sort" property in XDG ~/.config/syncevolution/pim-manager.ini'. */
     boost::shared_ptr<ConfigNode> m_configNode;
     std::string m_sortOrder;
     /** Stores "sort" property in XDG ~/.config/syncevolution/pim-manager.ini'. */
     boost::shared_ptr<ConfigNode> m_configNode;
     std::string m_sortOrder;
@@ -64,6 +67,10 @@ class Manager : public GDBusCXX::DBusObjectHelper
     void initFolks();
     void initDatabases();
     void initSorting(const std::string &order);
     void initFolks();
     void initDatabases();
     void initSorting(const std::string &order);
+    void localeChanged();
+
+    typedef boost::signals2::signal<void (const boost::shared_ptr<LocaleFactory> &locale)> LocaleChangedSignal;
+    LocaleChangedSignal m_localeChanged;
 
  public:
     /** Manager.Start() */
 
  public:
     /** Manager.Start() */
index 54b1dfe..e892372 100644 (file)
@@ -1,3 +1,3 @@
 [D-BUS Service]
 Name=org._01.pim.contacts
 [D-BUS Service]
 Name=org._01.pim.contacts
-Exec=@libexecdir@/syncevo-dbus-server
+Exec=@libexecdir@/syncevo-dbus-server @SYNCEVO_DBUS_SERVER_ARGS@
index 7328ba5..a2e1f71 100755 (executable)
@@ -45,6 +45,8 @@ import codecs
 import pprint
 import shutil
 
 import pprint
 import shutil
 
+import localed
+
 # Update path so that testdbus.py can be found.
 pimFolder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0]))
 if pimFolder not in sys.path:
 # Update path so that testdbus.py can be found.
 pimFolder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0]))
 if pimFolder not in sys.path:
@@ -600,6 +602,16 @@ VERSION:3.0\r?
         return set([os.path.splitext(x)[0] for x in (os.path.exists(self.sourcedir) and os.listdir(self.sourcedir) or [])])
 
 
         return set([os.path.splitext(x)[0] for x in (os.path.exists(self.sourcedir) and os.listdir(self.sourcedir) or [])])
 
 
+    def readManagerIni(self):
+         '''returns content of manager.ini file, split into lines and sorted, None if not found'''
+         filename = os.path.join(xdg_root, "config", "syncevolution", "pim-manager.ini")
+         if os.path.exists(filename):
+              lines = open(filename, "r").readlines()
+              lines.sort()
+              return lines
+         else:
+              return None
+
 
 class TestContacts(TestPIMUtil, unittest.TestCase):
     """Tests for org._01.pim.contacts API.
 
 class TestContacts(TestPIMUtil, unittest.TestCase):
     """Tests for org._01.pim.contacts API.
@@ -634,6 +646,18 @@ XDG root.
         expected.add(self.managerPrefix + uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         expected.add(self.managerPrefix + uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['sort =\n'],
+                         self.readManagerIni())
+
+        # Check effect of SetActiveAddressBooks() on pim-manager.ini.
+        self.manager.SetActiveAddressBooks(['peer-' + uid])
+        self.assertEqual(['active = pim-manager-' + uid + '\n',
+                          'sort =\n'],
+                         self.readManagerIni())
+        self.manager.SetActiveAddressBooks([])
+        self.assertEqual(['active = \n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         # PIM Manager must not allow overwriting an existing config.
         # Uses the new name for SetPeer().
 
         # PIM Manager must not allow overwriting an existing config.
         # Uses the new name for SetPeer().
@@ -659,14 +683,21 @@ XDG root.
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = \n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
 
-        # add and remove foo again
+        # add and remove foo again, this time while its address book is active
         uid = self.uidPrefix + 'foo4' # work around EDS bug with reusing UID
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'xxx'}
         self.manager.SetPeer(uid,
                              peers[uid])
         expected.add(self.managerPrefix + uid)
         uid = self.uidPrefix + 'foo4' # work around EDS bug with reusing UID
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'xxx'}
         self.manager.SetPeer(uid,
                              peers[uid])
         expected.add(self.managerPrefix + uid)
+        self.manager.SetActiveAddressBooks(['peer-' + uid])
+        self.assertEqual(['active = pim-manager-' + uid + '\n',
+                          'sort =\n'],
+                         self.readManagerIni())
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         time.sleep(2)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         time.sleep(2)
@@ -675,9 +706,14 @@ XDG root.
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = \n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         # add foo, bar, xyz
 
         # add foo, bar, xyz
+        addressbooks = []
         uid = self.uidPrefix + 'foo2'
         uid = self.uidPrefix + 'foo2'
+        addressbooks.append('peer-' + uid)
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'xxx'}
         self.manager.SetPeer(uid,
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'xxx'}
         self.manager.SetPeer(uid,
@@ -685,8 +721,12 @@ XDG root.
         expected.add(self.managerPrefix + uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         expected.add(self.managerPrefix + uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = \n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         uid = self.uidPrefix + 'bar'
 
         uid = self.uidPrefix + 'bar'
+        addressbooks.append('peer-' + uid)
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'yyy'}
         self.manager.SetPeer(uid,
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'yyy'}
         self.manager.SetPeer(uid,
@@ -696,6 +736,7 @@ XDG root.
         self.assertEqual(expected, self.currentSources())
 
         uid = self.uidPrefix + 'xyz'
         self.assertEqual(expected, self.currentSources())
 
         uid = self.uidPrefix + 'xyz'
+        addressbooks.append('peer-' + uid)
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'zzz'}
         self.manager.SetPeer(uid,
         peers[uid] = {'protocol': 'PBAP',
                       'address': 'zzz'}
         self.manager.SetPeer(uid,
@@ -703,6 +744,15 @@ XDG root.
         expected.add(self.managerPrefix + uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         expected.add(self.managerPrefix + uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = \n',
+                          'sort =\n'],
+                         self.readManagerIni())
+
+        self.manager.SetActiveAddressBooks(addressbooks)
+        addressbooks.sort()
+        self.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         # EDS workaround
         time.sleep(2)
 
         # EDS workaround
         time.sleep(2)
@@ -710,9 +760,13 @@ XDG root.
         # remove yxz, bar, foo
         expected.remove(self.managerPrefix + uid)
         del peers[uid]
         # remove yxz, bar, foo
         expected.remove(self.managerPrefix + uid)
         del peers[uid]
+        addressbooks.remove('peer-' + uid)
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         # EDS workaround
         time.sleep(2)
 
         # EDS workaround
         time.sleep(2)
@@ -720,9 +774,13 @@ XDG root.
         uid = self.uidPrefix + 'bar'
         expected.remove(self.managerPrefix + uid)
         del peers[uid]
         uid = self.uidPrefix + 'bar'
         expected.remove(self.managerPrefix + uid)
         del peers[uid]
+        addressbooks.remove('peer-' + uid)
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         # EDS workaround
         time.sleep(2)
 
         # EDS workaround
         time.sleep(2)
@@ -730,13 +788,23 @@ XDG root.
         uid = self.uidPrefix + 'foo2'
         expected.remove(self.managerPrefix + uid)
         del peers[uid]
         uid = self.uidPrefix + 'foo2'
         expected.remove(self.managerPrefix + uid)
         del peers[uid]
+        addressbooks.remove('peer-' + uid)
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
         self.manager.RemovePeer(uid)
         self.assertEqual(peers, self.manager.GetAllPeers())
         self.assertEqual(expected, self.currentSources())
+        self.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+                          'sort =\n'],
+                         self.readManagerIni())
 
         # EDS workaround
         time.sleep(2)
 
 
         # EDS workaround
         time.sleep(2)
 
+    @property("snapshot", "broken-config")
+    def testBrokenConfig(self):
+        '''TestContacts.testBrokenConfig - start with broken pim-manager.ini'''
+        self.manager.Start()
+        self.assertEqual("last/first", self.manager.GetSortOrder())
+
     @timeout(os.environ.get('TESTPIM_TEST_SYNC_TESTCASES', False) and 300000 or 300)
     @property("snapshot", "simple-sort")
     def testSync(self):
     @timeout(os.environ.get('TESTPIM_TEST_SYNC_TESTCASES', False) and 300000 or 300)
     @property("snapshot", "simple-sort")
     def testSync(self):
@@ -1534,8 +1602,7 @@ END:VCARD''']):
         # Check that order was adapted and stored permanently.
         self.assertEqual("last/first", self.manager.GetSortOrder())
         self.assertIn("sort = last/first\n",
         # Check that order was adapted and stored permanently.
         self.assertEqual("last/first", self.manager.GetSortOrder())
         self.assertIn("sort = last/first\n",
-                      open(os.path.join(xdg_root, "config", "syncevolution", "pim-manager.ini"),
-                           "r").readlines())
+                      self.readManagerIni())
 
         # Contact in the middle may or may not become invalidated.
         self.runUntil('reordered',
 
         # Contact in the middle may or may not become invalidated.
         self.runUntil('reordered',
@@ -1984,8 +2051,7 @@ END:VCARD'''
         # assuming that the PIM Manager preserves that order (not really guaranteed
         # by the API, but is how it is implemented).
         self.assertIn('active = pim-manager-' + self.uidPrefix + 'a pim-manager-' + self.uidPrefix + 'b pim-manager-' + self.uidPrefix + 'c system-address-book\n',
         # assuming that the PIM Manager preserves that order (not really guaranteed
         # by the API, but is how it is implemented).
         self.assertIn('active = pim-manager-' + self.uidPrefix + 'a pim-manager-' + self.uidPrefix + 'b pim-manager-' + self.uidPrefix + 'c system-address-book\n',
-                      open(os.path.join(xdg_root, "config", "syncevolution", "pim-manager.ini"),
-                           "r").readlines())
+                      self.readManagerIni())
 
         for peer in active:
              for index in range(0, contactsPerPeer):
 
         for peer in active:
              for index in range(0, contactsPerPeer):
@@ -2397,26 +2463,40 @@ END:VCARD''']):
 
         # Find Abraham via caller ID for 089/7888-99 (country is Germany).
         view = ContactsView(self.manager)
 
         # Find Abraham via caller ID for 089/7888-99 (country is Germany).
         view = ContactsView(self.manager)
-        view.search([['phone', '+49897888']])
-        self.runUntil('"+49897888" search results',
+        view.search([['phone', '+4989788899']])
+        self.runUntil('"+4989788899" search results',
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.quiescentCount > 0)
         self.assertEqual(1, len(view.contacts))
         view.read(0, 1)
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.quiescentCount > 0)
         self.assertEqual(1, len(view.contacts))
         view.read(0, 1)
-        self.runUntil('+49897888 data',
+        self.runUntil('+4989788899 data',
+                      check=lambda: self.assertEqual([], view.errors),
+                      until=lambda: view.haveData(0))
+        self.assertEqual(u'Abraham', view.contacts[0]['structured-name']['given'])
+
+        # Find Abraham via caller ID for +44 89 7888-99 (Abraham has no country code
+        # set and matches, whereas Benjamin has +1 as country code and does not match).
+        view = ContactsView(self.manager)
+        view.search([['phone', '+4489788899']])
+        self.runUntil('"+4489788899" search results',
+                      check=lambda: self.assertEqual([], view.errors),
+                      until=lambda: view.quiescentCount > 0)
+        self.assertEqual(1, len(view.contacts))
+        view.read(0, 1)
+        self.runUntil('+4489788899 data',
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.haveData(0))
         self.assertEqual(u'Abraham', view.contacts[0]['structured-name']['given'])
 
         # Find Abraham via 089/7888-99 (not a full caller ID, but at least a valid phone number).
         view = ContactsView(self.manager)
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.haveData(0))
         self.assertEqual(u'Abraham', view.contacts[0]['structured-name']['given'])
 
         # Find Abraham via 089/7888-99 (not a full caller ID, but at least a valid phone number).
         view = ContactsView(self.manager)
-        view.search([['phone', '0897888']])
-        self.runUntil('"0897888" search results',
+        view.search([['phone', '089788899']])
+        self.runUntil('"089788899" search results',
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.quiescentCount > 0)
         self.assertEqual(1, len(view.contacts))
         view.read(0, 1)
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.quiescentCount > 0)
         self.assertEqual(1, len(view.contacts))
         view.read(0, 1)
-        self.runUntil('0897888 data',
+        self.runUntil('089788899 data',
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.haveData(0))
         self.assertEqual(u'Abraham', view.contacts[0]['structured-name']['given'])
                       check=lambda: self.assertEqual([], view.errors),
                       until=lambda: view.haveData(0))
         self.assertEqual(u'Abraham', view.contacts[0]['structured-name']['given'])
@@ -2433,6 +2513,7 @@ END:VCARD''']):
         self.setUpView()
 
         msg = None
         self.setUpView()
 
         msg = None
+        view = None
         try:
              # Insert new contacts and calculate their family names.
              names = []
         try:
              # Insert new contacts and calculate their family names.
              names = []
@@ -2503,6 +2584,7 @@ END:VCARD
                   raise Exception('%s:\n%s' % (msg, repr(ex))), None, info[2]
              else:
                   raise
                   raise Exception('%s:\n%s' % (msg, repr(ex))), None, info[2]
              else:
                   raise
+        return view
 
     @timeout(60)
     @property("ENV", "LC_TYPE=ja_JP.UTF-8 LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8")
 
     @timeout(60)
     @property("ENV", "LC_TYPE=ja_JP.UTF-8 LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8")
@@ -2521,13 +2603,19 @@ END:VCARD
          self.doFilter(# Names of all contacts, sorted as expected.
                        # 江 = jiāng = Jiang when using Pinyin and thus after Jeffries and before Meadows.
                        # 鳥 = niǎo before 女性 = nǚ xìng (see FDO #66618)
          self.doFilter(# Names of all contacts, sorted as expected.
                        # 江 = jiāng = Jiang when using Pinyin and thus after Jeffries and before Meadows.
                        # 鳥 = niǎo before 女性 = nǚ xìng (see FDO #66618)
-                       ('Adams', 'Jeffries', u'江', 'Meadows', u'鳥', u'女性' ),
-                       # 'J' not expected to find Jiang; searching
-                       # is meant to use Chinese letters.
-                       (([['any-contains', 'J']], ('Jeffries',)),
-                        ([['any-contains', u'江']], (u'江',)),
-                        ([['any-contains', u'jiāng']], ()),
-                        ([['any-contains', u'Jiang']], ()),
+                       ('Adams', 'Jeffries', u'江', 'jiang', 'Meadows', u'鳥', u'女性' ),
+                       # 'J' may or may not match Jiang; by default, it matches.
+                       (([['any-contains', 'J']], ('Jeffries', u'江', 'jiang')),
+                        ([['any-contains', 'J', 'no-transliteration']], ('Jeffries', 'jiang')),
+                        ([['any-contains', 'J', 'no-transliteration', 'case-sensitive']], ('Jeffries',)),
+                        ([['any-contains', u'江']], (u'江', 'jiang')),
+                        ([['any-contains', u'jiang']], (u'江', 'jiang')),
+                        ([['any-contains', u'jiāng']], (u'江', 'jiang')),
+                        ([['any-contains', u'jiāng', 'no-transliteration']], ('jiang',)),
+                        ([['any-contains', u'jiāng', 'accent-sensitive']], (u'江',)),
+                        ([['any-contains', u'jiāng', 'accent-sensitive', 'case-sensitive']], (u'江',)),
+                        ([['any-contains', u'Jiāng', 'accent-sensitive', 'case-sensitive']], ()),
+                        ([['any-contains', u'Jiang']], (u'江', 'jiang')),
                         ),
                        )
 
                         ),
                        )
 
@@ -2542,6 +2630,100 @@ END:VCARD
                        (),
                        )
 
                        (),
                        )
 
+    @timeout(60)
+    @property("ENV", "LC_TYPE=zh_CN.UTF-8 LANG=zh_CN.UTF-8")
+    def testLocaled(self):
+         # Use mixed Chinese/Western names, because then the locale really matters.
+         namespinyin = ('Adams', 'Jeffries', u'江', 'Meadows', u'鳥', u'女性' )
+         namesgerman = ('Adams', 'Jeffries', 'Meadows', u'女性', u'江', u'鳥' )
+         numtestcases = len(namespinyin)
+         self.doFilter(namespinyin, ())
+
+         daemon = localed.Localed()
+         msg = None
+         try:
+              # Broadcast Locale value together with PropertiesChanged signal.
+              self.view.quiescentCount = 0
+              daemon.SetLocale(['LC_TYPE=de_DE.UTF-8', 'LANG=de_DE.UTF-8'], False)
+              logging.log('reading contacts, German')
+              self.runUntil('German sorting',
+                            check=lambda: self.assertEqual([], self.view.errors),
+                            until=lambda: self.view.quiescentCount > 1)
+              self.view.read(0, numtestcases)
+              self.runUntil('German contacts',
+                            check=lambda: self.assertEqual([], self.view.errors),
+                            until=lambda: self.view.haveData(0, numtestcases))
+              for i, name in enumerate(namesgerman):
+                   msg = u'contact #%d with name %s in\n%s' % (i, name, pprint.pformat(self.stripDBus(self.view.contacts, sortLists=False)))
+                   self.assertEqual(name, self.view.contacts[i]['full-name'])
+
+              # Switch back to Pinyin without including the new value.
+              self.view.quiescentCount = 0
+              daemon.SetLocale(['LC_TYPE=zh_CN.UTF-8', 'LANG=zh_CN.UTF-8'], True)
+              logging.log('reading contacts, Pinyin')
+              self.runUntil('Pinyin sorting',
+                            check=lambda: self.assertEqual([], self.view.errors),
+                            until=lambda: self.view.quiescentCount > 1)
+              self.view.read(0, numtestcases)
+              self.runUntil('Pinyin contacts',
+                            check=lambda: self.assertEqual([], self.view.errors),
+                            until=lambda: self.view.haveData(0, numtestcases))
+              for i, name in enumerate(namespinyin):
+                   msg = u'contact #%d with name %s in\n%s' % (i, name, pprint.pformat(self.stripDBus(self.view.contacts, sortLists=False)))
+                   self.assertEqual(name, self.view.contacts[i]['full-name'])
+         except Exception, ex:
+             if msg:
+                  info = sys.exc_info()
+                  raise Exception('%s:\n%s' % (msg, repr(ex))), None, info[2]
+             else:
+                  raise
+
+    @timeout(60)
+    # Must disable usage of pre-computed phone numbers from EDS, because we can't tell EDS
+    # when locale is meant to change.
+    @property("ENV", "LANG=en_US.UTF-8 SYNCEVOLUTION_PIM_EDS_NO_E164=1")
+    def testLocaledPhone(self):
+         # Parsing of 1234-5 depends on locale: US drops the 1 from 1234
+         # Germany (and other countries) don't. Use that to match (or not match)
+         # a contact.
+         testcases = (('Doe', '''BEGIN:VCARD
+VERSION:3.0
+FN:Doe
+N:Doe;;;;
+TEL:12 34-5
+END:VCARD
+'''),)
+         names = ('Doe')
+         numtestcases = len(testcases)
+         view = self.doFilter(testcases,
+                              (([['phone', '+12345']], ('Doe',)),))
+
+         daemon = localed.Localed()
+         msg = None
+         try:
+              # Contact no longer matched because it's phone number normalization
+              # becomes different.
+              view.quiescentCount = 0
+              daemon.SetLocale(['LANG=de_DE.UTF-8'], True)
+              self.runUntil('German locale',
+                            check=lambda: self.assertEqual([], view.errors),
+                            until=lambda: view.quiescentCount > 1)
+              self.assertEqual(len(view.contacts), 0)
+
+              # Switch back to US.
+              view.quiescentCount = 0
+              daemon.SetLocale(['LANG=en_US.UTF-8'], True)
+              self.runUntil('US locale',
+                            check=lambda: self.assertEqual([], view.errors),
+                            until=lambda: view.quiescentCount > 1)
+              self.assertEqual(len(view.contacts), 1)
+         except Exception, ex:
+             if msg:
+                  info = sys.exc_info()
+                  raise Exception('%s:\n%s' % (msg, repr(ex))), None, info[2]
+             else:
+                  raise
+
     # Not supported correctly by ICU?
     # See icu-support "Subject: Austrian phone book sorting"
     # @timeout(60)
     # Not supported correctly by ICU?
     # See icu-support "Subject: Austrian phone book sorting"
     # @timeout(60)
index ddff6f1..3f6869e 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "read-operations.h"
 
 
 #include "read-operations.h"
 
-#include <boost/signals.hpp>
+#include <boost/signals2.hpp>
 
 SE_BEGIN_CXX
 
 
 SE_BEGIN_CXX
 
index ab01679..cd82028 100644 (file)
@@ -25,6 +25,7 @@ src_dbus_server_server_cpp_files = \
   src/dbus/server/dbus-callbacks.cpp \
   src/dbus/server/dbus-user-interface.cpp \
   src/dbus/server/exceptions.cpp \
   src/dbus/server/dbus-callbacks.cpp \
   src/dbus/server/dbus-user-interface.cpp \
   src/dbus/server/exceptions.cpp \
+  src/dbus/server/localed-listener.cpp \
   src/dbus/server/info-req.cpp \
   src/dbus/server/network-manager-client.cpp \
   src/dbus/server/presence-status.cpp \
   src/dbus/server/info-req.cpp \
   src/dbus/server/network-manager-client.cpp \
   src/dbus/server/presence-status.cpp \
@@ -82,7 +83,7 @@ nodist_src_dbus_server_libsyncevodbusserver_la_SOURCES += \
 
 src_dbus_server_libsyncevodbusserver_la_LDFLAGS += $(DBUS_PIM_PLUGIN_LDFLAGS)
 src_dbus_server_libsyncevodbusserver_la_LIBADD += $(FOLKS_LIBS) $(DBUS_PIM_PLUGIN_LIBS) $(PHONENUMBERS_LIBS)
 
 src_dbus_server_libsyncevodbusserver_la_LDFLAGS += $(DBUS_PIM_PLUGIN_LDFLAGS)
 src_dbus_server_libsyncevodbusserver_la_LIBADD += $(FOLKS_LIBS) $(DBUS_PIM_PLUGIN_LIBS) $(PHONENUMBERS_LIBS)
-src_dbus_server_libsyncevodbusserver_la_CXXFLAGS += $(FOLKS_CFLAGS) $(DBUS_PIM_PLUGIN_CFLAGS) $(PHONENUMBERS_CFLAGS)
+src_dbus_server_libsyncevodbusserver_la_CXXFLAGS += $(FOLKS_CFLAGS) $(DBUS_PIM_PLUGIN_CFLAGS) $(PHONENUMBERS_CFLAGS) $(DLT_CFLAGS)
 endif
 
 # Need to list all plugins here and not include the active one in the regular
 endif
 
 # Need to list all plugins here and not include the active one in the regular
@@ -128,7 +129,7 @@ src_dbus_server_autostart_DATA = $(src_dbus_server_desktop)
 
 libexec_SCRIPTS += $(src_dbus_server_script)
 $(src_dbus_server_script): $(src_dbus_server_script_in)
 
 libexec_SCRIPTS += $(src_dbus_server_script)
 $(src_dbus_server_script): $(src_dbus_server_script_in)
-       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
+       @sed -e "s|\@libexecdir\@|$(libexecdir)|" -e "s|\@SYNCEVO_DBUS_SERVER_ARGS\@|$(SYNCEVO_DBUS_SERVER_ARGS)|" $< >$@
 $(src_dbus_server_desktop): $(src_dbus_server_desktop_in)
        @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
 
 $(src_dbus_server_desktop): $(src_dbus_server_desktop_in)
        @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
 
@@ -137,7 +138,7 @@ src_dbus_server_service_files = $(src_dbus_server_service_files_in:.service.in=.
 src_dbus_server_servicedir = $(DBUS_SERVICES_DIR)
 src_dbus_server_service_DATA = $(src_dbus_server_service_files)
 src/dbus/server/%.service: src/dbus/server/%.service.in
 src_dbus_server_servicedir = $(DBUS_SERVICES_DIR)
 src_dbus_server_service_DATA = $(src_dbus_server_service_files)
 src/dbus/server/%.service: src/dbus/server/%.service.in
-       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
+       @sed -e "s|\@libexecdir\@|$(libexecdir)|" -e "s|\@SYNCEVO_DBUS_SERVER_ARGS\@|$(SYNCEVO_DBUS_SERVER_ARGS)|" $< >$@
 
 if COND_DBUS_PIM
 src_dbus_server_service_files_in += \
 
 if COND_DBUS_PIM
 src_dbus_server_service_files_in += \
index 7d23396..19776ea 100644 (file)
@@ -42,14 +42,13 @@ static void dumpString(const std::string &output)
  */
 class SessionHelperLogger : public Logger
 {
  */
 class SessionHelperLogger : public Logger
 {
-    boost::shared_ptr<LogRedirect> m_parentLogger;
+    Handle m_parentLogger;
     boost::shared_ptr<SessionHelper> m_helper;
     Level m_dbusLogLevel;
 
 public:
     boost::shared_ptr<SessionHelper> m_helper;
     Level m_dbusLogLevel;
 
 public:
-    SessionHelperLogger(const boost::shared_ptr<LogRedirect> &parentLogger,
-                        const boost::shared_ptr<SessionHelper> &helper):
-        m_parentLogger(parentLogger),
+    SessionHelperLogger(const boost::shared_ptr<SessionHelper> &helper):
+        m_parentLogger(Logger::instance()),
         m_helper(helper),
         m_dbusLogLevel(DEBUG)
     {
         m_helper(helper),
         m_dbusLogLevel(DEBUG)
     {
@@ -84,7 +83,7 @@ public:
             va_list argsCopy;
             va_copy(argsCopy, args);
             if (m_parentLogger) {
             va_list argsCopy;
             va_copy(argsCopy, args);
             if (m_parentLogger) {
-                m_parentLogger->messagev(options, format, argsCopy);
+                m_parentLogger.messagev(options, format, argsCopy);
             } else {
                 formatLines(options.m_level, DEBUG,
                             options.m_processName,
             } else {
                 formatLines(options.m_level, DEBUG,
                             options.m_processName,
@@ -94,10 +93,16 @@ public:
             }
             va_end(argsCopy);
         } else if (m_parentLogger) {
             }
             va_end(argsCopy);
         } else if (m_parentLogger) {
-            // Only flush parent logger, to capture output sent to
-            // stdout/stderr by some library and send it via D-Bus
-            // (recursively!)  before printing out own, new output.
-            m_parentLogger->flush();
+            // Pass through to parent, but marked in such a way that
+            // only the DLT and syslog logger will react to it, but
+            // not LogStdout. That's necessary because
+            // syncevo-dbus-server handles stdout for us.
+            va_list argsCopy;
+            va_copy(argsCopy, args);
+            MessageOptions buffer(options);
+            buffer.m_flags |= MessageOptions::ONLY_GLOBAL_LOG;
+            m_parentLogger.messagev(buffer, format, argsCopy);
+            va_end(argsCopy);
         }
 
         if (m_helper &&
         }
 
         if (m_helper &&
@@ -117,8 +122,7 @@ public:
 
 SessionHelper::SessionHelper(GMainLoop *loop,
                              const GDBusCXX::DBusConnectionPtr &conn,
 
 SessionHelper::SessionHelper(GMainLoop *loop,
                              const GDBusCXX::DBusConnectionPtr &conn,
-                             const boost::shared_ptr<ForkExecChild> &forkexec,
-                             const boost::shared_ptr<LogRedirect> &parentLogger) :
+                             const boost::shared_ptr<ForkExecChild> &forkexec) :
     GDBusCXX::DBusObjectHelper(conn,
                                std::string(SessionCommon::HELPER_PATH) + "/" + forkexec->getInstance(),
                                SessionCommon::HELPER_IFACE,
     GDBusCXX::DBusObjectHelper(conn,
                                std::string(SessionCommon::HELPER_PATH) + "/" + forkexec->getInstance(),
                                SessionCommon::HELPER_IFACE,
@@ -127,7 +131,7 @@ SessionHelper::SessionHelper(GMainLoop *loop,
     m_loop(loop),
     m_conn(conn),
     m_forkexec(forkexec),
     m_loop(loop),
     m_conn(conn),
     m_forkexec(forkexec),
-    m_logger(new SessionHelperLogger(parentLogger, boost::shared_ptr<SessionHelper>(this, NopDestructor()))),
+    m_logger(new SessionHelperLogger(boost::shared_ptr<SessionHelper>(this, NopDestructor()))),
     emitLogOutput(*this, "LogOutput"),
     emitSyncProgress(*this, "SyncProgress"),
     emitSourceProgress(*this, "SourceProgress"),
     emitLogOutput(*this, "LogOutput"),
     emitSyncProgress(*this, "SyncProgress"),
     emitSourceProgress(*this, "SourceProgress"),
index 3c38000..6f9dc0e 100644 (file)
@@ -85,8 +85,7 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
  public:
     SessionHelper(GMainLoop *loop,
                   const GDBusCXX::DBusConnectionPtr &conn,
  public:
     SessionHelper(GMainLoop *loop,
                   const GDBusCXX::DBusConnectionPtr &conn,
-                  const boost::shared_ptr<ForkExecChild> &forkexec,
-                  const boost::shared_ptr<LogRedirect> &parentLogger);
+                  const boost::shared_ptr<ForkExecChild> &forkexec);
     ~SessionHelper();
 
     void setDBusLogLevel(Logger::Level level);
     ~SessionHelper();
 
     void setDBusLogLevel(Logger::Level level);
index 12b5bb7..03c4ee1 100644 (file)
 #include <syncevo/SyncContext.h>
 #include <syncevo/BoostHelper.h>
 
 #include <syncevo/SyncContext.h>
 #include <syncevo/BoostHelper.h>
 
+#ifdef USE_DLT
+#include <syncevo/LogDLT.h>
+#endif
+
 #include <memory>
 
 #include <boost/foreach.hpp>
 #include <memory>
 
 #include <boost/foreach.hpp>
@@ -793,6 +797,11 @@ void Session::useHelperAsync(const SimpleResult &result)
             args.push_back("--dbus-verbosity");
             args.push_back(StringPrintf("%d", m_server.getDBusLogLevel()));
             m_forkExecParent = SyncEvo::ForkExecParent::create("syncevo-dbus-helper", args);
             args.push_back("--dbus-verbosity");
             args.push_back(StringPrintf("%d", m_server.getDBusLogLevel()));
             m_forkExecParent = SyncEvo::ForkExecParent::create("syncevo-dbus-helper", args);
+#ifdef USE_DLT
+            if (getenv("SYNCEVOLUTION_USE_DLT")) {
+                m_forkExecParent->addEnvVar("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", LoggerDLT::getCurrentDLTLogLevel()));
+            }
+#endif
             // We own m_forkExecParent, so the "this" pointer for
             // onConnect will live longer than the signal in
             // m_forkExecParent -> no need for resource
             // We own m_forkExecParent, so the "this" pointer for
             // onConnect will live longer than the signal in
             // m_forkExecParent -> no need for resource
@@ -884,6 +893,7 @@ static void Logging2Server(Server &server,
         // there is considered an error.
         Logger::MessageOptions options(Logger::strToLevel(strLevel.c_str()));
         options.m_processName = &procname;
         // there is considered an error.
         Logger::MessageOptions options(Logger::strToLevel(strLevel.c_str()));
         options.m_processName = &procname;
+        options.m_flags = Logger::MessageOptions::ALREADY_LOGGED;
         Logging2ServerAndStdout(server, path, options, "%s", explanation.c_str());
     }
 }
         Logging2ServerAndStdout(server, path, options, "%s", explanation.c_str());
     }
 }
index a564e9a..8fefb3c 100644 (file)
@@ -28,6 +28,7 @@
 #include <syncevo/SuspendFlags.h>
 #include <syncevo/SyncContext.h>
 #include <syncevo/LogRedirect.h>
 #include <syncevo/SuspendFlags.h>
 #include <syncevo/SyncContext.h>
 #include <syncevo/LogRedirect.h>
+#include <syncevo/LogDLT.h>
 
 using namespace SyncEvo;
 using namespace GDBusCXX;
 
 using namespace SyncEvo;
 using namespace GDBusCXX;
@@ -45,11 +46,10 @@ namespace {
     }
 
     void onConnect(const DBusConnectionPtr &conn,
     }
 
     void onConnect(const DBusConnectionPtr &conn,
-                   const boost::shared_ptr<LogRedirect> &parentLogger,
                    const boost::shared_ptr<ForkExecChild> &forkexec,
                    boost::shared_ptr<SessionHelper> &helper)
     {
                    const boost::shared_ptr<ForkExecChild> &forkexec,
                    boost::shared_ptr<SessionHelper> &helper)
     {
-        helper.reset(new SessionHelper(loop, conn, forkexec, parentLogger));
+        helper.reset(new SessionHelper(loop, conn, forkexec));
         helper->activate();
         helper->setDBusLogLevel(Logger::Level(logLevelDBus));
     }
         helper->activate();
         helper->setDBusLogLevel(Logger::Level(logLevelDBus));
     }
@@ -107,6 +107,14 @@ int main(int argc, char **argv, char **envp)
         redirect.reset(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
         pushRedirect.reset(redirect);
     }
         redirect.reset(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
         pushRedirect.reset(redirect);
     }
+#ifdef USE_DLT
+    // Set by syncevo-dbus-server for us.
+    bool useDLT = getenv("SYNCEVOLUTION_USE_DLT") != NULL;
+    PushLogger<LoggerDLT> loggerdlt;
+    if (useDLT) {
+        loggerdlt.reset(new LoggerDLT(DLT_SYNCEVO_DBUS_HELPER_ID, "SyncEvolution local sync helper"));
+    }
+#endif
     setvbuf(stderr, NULL, _IONBF, 0);
     setvbuf(stdout, NULL, _IONBF, 0);
 
     setvbuf(stderr, NULL, _IONBF, 0);
     setvbuf(stdout, NULL, _IONBF, 0);
 
@@ -140,7 +148,7 @@ int main(int argc, char **argv, char **envp)
 
         boost::shared_ptr<SessionHelper> helper;
         bool failed = false;
 
         boost::shared_ptr<SessionHelper> helper;
         bool failed = false;
-        forkexec->m_onConnect.connect(boost::bind(onConnect, _1, redirect,
+        forkexec->m_onConnect.connect(boost::bind(onConnect, _1,
                                                   boost::cref(forkexec),
                                                   boost::ref(helper)));
         forkexec->m_onFailure.connect(boost::bind(onFailure, _2, boost::ref(failed)));
                                                   boost::cref(forkexec),
                                                   boost::ref(helper)));
         forkexec->m_onFailure.connect(boost::bind(onFailure, _2, boost::ref(failed)));
index 8d19cf7..6f9d7ba 100755 (executable)
@@ -1,3 +1,3 @@
 #! /bin/sh
 sleep 120
 #! /bin/sh
 sleep 120
-exec @libexecdir@/syncevo-dbus-server 2>/dev/null 1>&1
+exec @libexecdir@/syncevo-dbus-server @SYNCEVO_DBUS_SERVER_ARGS@ 2>/dev/null 1>&1
index ad140c8..0325934 100644 (file)
 
 #include <config.h>
 
 
 #include <config.h>
 
-#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
-
-#include <boost/bind.hpp>
-
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
-EDSRegistryLoader &EDSRegistryLoader::singleton()
-{
-    static EDSRegistryLoader self;
-    return self;
-}
-
-void EDSRegistryLoader::getESourceRegistryAsync(const Callback_t &cb)
-{
-    singleton().async(cb);
-}
-
-void EDSRegistryLoader::async(const Callback_t &cb)
-{
-    if (m_registry || m_gerror) {
-        cb(m_registry, m_gerror);
-    } else {
-        m_pending.push_back(cb);
-        m_loading = true;
-        SYNCEVO_GLIB_CALL_ASYNC(e_source_registry_new,
-                                boost::bind(&EDSRegistryLoader::created,
-                                            this,
-                                            _1, _2),
-                                NULL);
-    }
-}
-
-ESourceRegistryCXX EDSRegistryLoader::getESourceRegistry()
-{
-    return singleton().sync();
-}
-
-ESourceRegistryCXX EDSRegistryLoader::sync()
-{
-    if (!m_loading) {
-        m_loading = true;
-        SYNCEVO_GLIB_CALL_ASYNC(e_source_registry_new,
-                                boost::bind(&EDSRegistryLoader::created,
-                                            this,
-                                            _1, _2),
-                                NULL);
-    }
-
-    while (true) {
-        if (m_registry) {
-            return m_registry;
-        }
-        if (m_gerror) {
-            m_gerror.throwError("creating source registry");
-        }
-        // Only master thread can drive the event processing.
-       if (g_main_context_is_owner(g_main_context_default())) {
-            g_main_context_iteration(NULL, true);
-        } else {
-            Sleep(0.1);
-        }
-    }
-}
-
-void EDSRegistryLoader::created(ESourceRegistry *registry, const GError *gerror) throw ()
+EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistryLoader> &loader)
 {
 {
-    try {
-        m_registry = ESourceRegistryCXX::steal(registry);
-        m_gerror = gerror;
-        BOOST_FOREACH (const Callback_t &cb, m_pending) {
-            cb(m_registry, m_gerror);
-        }
-    } catch (...) {
-        Exception::handle(HANDLE_EXCEPTION_FATAL);
+    static boost::shared_ptr<EDSRegistryLoader> singleton;
+    if (!singleton) {
+        singleton = loader;
     }
     }
+    return *singleton;
 }
 
 SE_END_CXX
 
 }
 
 SE_END_CXX
 
-#endif // HAVE_EDS && USE_EDS_CLIENT
index b7431c9..dd855a8 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <config.h>
 
 
 #include <config.h>
 
+#include <boost/shared_ptr.hpp>
+
 #if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
 
 #include <syncevo/GLibSupport.h>
 #if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
 
 #include <syncevo/GLibSupport.h>
@@ -29,6 +31,8 @@
 #include <libedataserver/libedataserver.h>
 #include <boost/function.hpp>
 #include <boost/utility.hpp>
 #include <libedataserver/libedataserver.h>
 #include <boost/function.hpp>
 #include <boost/utility.hpp>
+#include <boost/bind.hpp>
+#include <boost/lambda/core.hpp>
 #include <list>
 
 typedef SyncEvo::GListCXX<ESource, GList, SyncEvo::GObjectDestructor> ESourceListCXX;
 #include <list>
 
 typedef SyncEvo::GListCXX<ESource, GList, SyncEvo::GObjectDestructor> ESourceListCXX;
@@ -36,9 +40,25 @@ SE_GOBJECT_TYPE(ESourceRegistry)
 SE_GOBJECT_TYPE(ESource)
 SE_GOBJECT_TYPE(EClient)
 
 SE_GOBJECT_TYPE(ESource)
 SE_GOBJECT_TYPE(EClient)
 
+#endif // HAVE_EDS && USE_EDS_CLIENT
+
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
 #include <syncevo/declarations.h>
 SE_BEGIN_CXX
 
+// This code must always be compiled into libsyncevolution.
+// It may get used by backends which were compiled against
+// EDS >= 3.6 even when the libsyncevolution itself wasn't.
+class EDSRegistryLoader;
+EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistryLoader> &loader);
+
+// The following code implements EDSRegistryLoader.
+// For the sake of simplicity, its all in the header file,
+// so all users of it end up with a copy of the code and
+// then they can activate that code when instantiating the object
+// and passing it to EDSRegistryLoaderSingleton().
+
+#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
+
 /**
  * Creates ESourceRegistry on demand and shares it inside
  * SyncEvolution. It's never freed once used.
 /**
  * Creates ESourceRegistry on demand and shares it inside
  * SyncEvolution. It's never freed once used.
@@ -53,12 +73,18 @@ class EDSRegistryLoader : private boost::noncopyable
      * Callback gets invoked exactly once. If the registry pointer is empty,
      * then the error will explain why.
      */
      * Callback gets invoked exactly once. If the registry pointer is empty,
      * then the error will explain why.
      */
-    static void getESourceRegistryAsync(const Callback_t &cb);
+    static void getESourceRegistryAsync(const Callback_t &cb)
+    {
+        EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).async(cb);
+    }
 
     /**
      * Returns shared ESourceRegistry, throws error if creation failed.
      */
 
     /**
      * Returns shared ESourceRegistry, throws error if creation failed.
      */
-    static ESourceRegistryCXX getESourceRegistry();
+    static ESourceRegistryCXX getESourceRegistry()
+    {
+        return EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).sync();
+    }
 
  private:
     Bool m_loading;
 
  private:
     Bool m_loading;
@@ -66,13 +92,76 @@ class EDSRegistryLoader : private boost::noncopyable
     GErrorCXX m_gerror;
     std::list<Callback_t> m_pending;
 
     GErrorCXX m_gerror;
     std::list<Callback_t> m_pending;
 
-    static EDSRegistryLoader &singleton();
-    void async(const Callback_t &cb);
-    ESourceRegistryCXX sync();
-    void created(ESourceRegistry *registry, const GError *gerror) throw ();
+    void async(const Callback_t &cb)
+    {
+        if (m_registry || m_gerror) {
+            cb(m_registry, m_gerror);
+        } else {
+            m_pending.push_back(cb);
+#if 0
+            m_loading = true;
+            SYNCEVO_GLIB_CALL_ASYNC(e_source_registry_new,
+                                    boost::bind(&EDSRegistryLoader::created,
+                                                this,
+                                                _1, _2),
+                                    NULL);
+#else
+           ESourceRegistry *registry;
+           GErrorCXX gerror;
+           registry = e_source_registry_new_sync(NULL, gerror);
+           created(registry, gerror);
+#endif
+        }
+    }
+
+    ESourceRegistryCXX sync()
+    {
+#if 0
+        if (!m_loading) {
+            m_loading = true;
+            SYNCEVO_GLIB_CALL_ASYNC(e_source_registry_new,
+                                    boost::bind(&EDSRegistryLoader::created,
+                                                this,
+                                                _1, _2),
+                                    NULL);
+        }
+
+        GRunWhile(!boost::lambda::var(m_registry) && !boost::lambda::var(m_gerror));
+#else
+        if (!m_registry) {
+            ESourceRegistry *registry;
+            GErrorCXX gerror;
+            registry = e_source_registry_new_sync(NULL, gerror);
+            created(registry, gerror);
+        }
+#endif
+
+        if (m_registry) {
+            return m_registry;
+        }
+        if (m_gerror) {
+            m_gerror.throwError("creating source registry");
+        }
+        return m_registry;
+    }
+
+
+    void created(ESourceRegistry *registry, const GError *gerror) throw ()
+    {
+        try {
+            m_registry = ESourceRegistryCXX::steal(registry);
+            m_gerror = gerror;
+            BOOST_FOREACH (const Callback_t &cb, m_pending) {
+                cb(m_registry, m_gerror);
+            }
+        } catch (...) {
+            Exception::handle(HANDLE_EXCEPTION_FATAL);
+        }
+    }
 };
 
 };
 
+#endif // HAVE_EDS && USE_EDS_CLIENT
+
 SE_END_CXX
 
 SE_END_CXX
 
-#endif // HAVE_EDS && USE_EDS_CLIENT
 #endif // INCL_SYNCEVO_EDS_CLIENT
 #endif // INCL_SYNCEVO_EDS_CLIENT
index 1b3a8a5..11d0fb8 100644 (file)
@@ -636,6 +636,11 @@ class PlainGStrArray : public boost::shared_ptr<gchar *>
         PlainGStrArray(const PlainGStrArray &other) : boost::shared_ptr<char *>(other) {}
         operator gchar * const *() const { return &**this; }
         gchar * &at(size_t index) { return get()[index]; }
         PlainGStrArray(const PlainGStrArray &other) : boost::shared_ptr<char *>(other) {}
         operator gchar * const *() const { return &**this; }
         gchar * &at(size_t index) { return get()[index]; }
+ private:
+        // Hide this operator because boost::shared_ptr has problems with it,
+        // probably because of missing traits for a pointer type. Instead use
+        // at().
+        gchar * operator[] (size_t index);
 };
 
 // empty template, need specialization based on parameter and return types
 };
 
 // empty template, need specialization based on parameter and return types
index 3b0ce03..d348878 100644 (file)
@@ -27,6 +27,7 @@
 #include <syncevo/DBusTraits.h>
 #include <syncevo/SuspendFlags.h>
 #include <syncevo/LogRedirect.h>
 #include <syncevo/DBusTraits.h>
 #include <syncevo/SuspendFlags.h>
 #include <syncevo/LogRedirect.h>
+#include <syncevo/LogDLT.h>
 #include <syncevo/BoostHelper.h>
 
 #include <synthesis/syerror.h>
 #include <syncevo/BoostHelper.h>
 
 #include <synthesis/syerror.h>
@@ -100,6 +101,11 @@ void LocalTransportAgent::start()
     }
     m_status = ACTIVE;
     m_forkexec = ForkExecParent::create("syncevo-local-sync");
     }
     m_status = ACTIVE;
     m_forkexec = ForkExecParent::create("syncevo-local-sync");
+#ifdef USE_DLT
+    if (getenv("SYNCEVOLUTION_USE_DLT")) {
+        m_forkexec->addEnvVar("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", LoggerDLT::getCurrentDLTLogLevel()));
+    }
+#endif
     m_forkexec->m_onConnect.connect(boost::bind(&LocalTransportAgent::onChildConnect, this, _1));
     // fatal problems, including quitting child with non-zero status
     m_forkexec->m_onFailure.connect(boost::bind(&LocalTransportAgent::onFailure, this, _2));
     m_forkexec->m_onConnect.connect(boost::bind(&LocalTransportAgent::onChildConnect, this, _1));
     // fatal problems, including quitting child with non-zero status
     m_forkexec->m_onFailure.connect(boost::bind(&LocalTransportAgent::onFailure, this, _2));
@@ -177,6 +183,9 @@ void LocalTransportAgent::logChildOutput(const std::string &level, const std::st
 {
     Logger::MessageOptions options(Logger::strToLevel(level.c_str()));
     options.m_processName = &m_clientContext;
 {
     Logger::MessageOptions options(Logger::strToLevel(level.c_str()));
     options.m_processName = &m_clientContext;
+    // Child should have written this into its own log file and/or syslog/dlt already.
+    // Only pass it on to a user of the command line interface.
+    options.m_flags = Logger::MessageOptions::ALREADY_LOGGED;
     SyncEvo::Logger::instance().messageWithOptions(options, "%s", message.c_str());
 }
 
     SyncEvo::Logger::instance().messageWithOptions(options, "%s", message.c_str());
 }
 
@@ -1146,6 +1155,16 @@ int LocalTransportMain(int argc, char **argv)
             Logger::Handle handle(child->createLogger());
             logger.reset(handle);
         }
             Logger::Handle handle(child->createLogger());
             logger.reset(handle);
         }
+
+#ifdef USE_DLT
+        // Set by syncevo-dbus-server for us.
+        bool useDLT = getenv("SYNCEVOLUTION_USE_DLT") != NULL;
+        PushLogger<LoggerDLT> loggerdlt;
+        if (useDLT) {
+            loggerdlt.reset(new LoggerDLT(DLT_SYNCEVO_LOCAL_HELPER_ID, "SyncEvolution local sync helper"));
+        }
+#endif
+
         child->run();
         int ret = child->getReturnCode();
         logger.reset();
         child->run();
         int ret = child->getReturnCode();
         logger.reset();
diff --git a/src/syncevo/LogDLT.cpp b/src/syncevo/LogDLT.cpp
new file mode 100644 (file)
index 0000000..fd80859
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#include <syncevo/LogDLT.h>
+
+#ifdef USE_DLT
+
+#include <dlt.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+static DltLogLevelType SyncEvoLevel2DLTLevel(Logger::Level level)
+{
+    switch (level) {
+    case Logger::NONE: return DLT_LOG_OFF;
+    case Logger::ERROR: return DLT_LOG_ERROR;
+    case Logger::WARNING: return DLT_LOG_WARN;
+    case Logger::SHOW:
+    case Logger::INFO: return DLT_LOG_INFO;
+    case Logger::DEV:
+    case Logger::DEBUG: return DLT_LOG_DEBUG;
+    }
+    return DLT_LOG_OFF;
+}
+
+static LoggerDLT *LoggerDLTInstance;
+
+LoggerDLT::LoggerDLT(const char *appid, const char *description) :
+    m_parentLogger(Logger::instance()),
+    m_dltContext(calloc(1, sizeof(DltContext)))
+{
+    DLT_REGISTER_APP(appid, description);
+    int level = atoi(getEnv("SYNCEVOLUTION_USE_DLT", "-1"));
+    if (level > 0) {
+        DLT_REGISTER_CONTEXT_LL_TS(*(DltContext *)m_dltContext, "SYNC", "SyncEvolution messages",
+                                   (DltLogLevelType)level, DLT_TRACE_STATUS_OFF);
+    } else {
+        DLT_REGISTER_CONTEXT(*(DltContext *)m_dltContext, "SYNC", "SyncEvolution messages");
+    }
+    LoggerDLTInstance = this;
+}
+
+LoggerDLT::~LoggerDLT()
+{
+    DLT_UNREGISTER_CONTEXT(*(DltContext *)m_dltContext);
+    DLT_UNREGISTER_APP();
+    LoggerDLTInstance = NULL;
+}
+
+void LoggerDLT::messagev(const MessageOptions &options,
+                         const char *format,
+                         va_list args)
+{
+    // always to parent first (usually stdout):
+    // if the parent is a LogRedirect instance, then
+    // it'll flush its own output first, which ensures
+    // that the new output comes later (as desired)
+    {
+        va_list argscopy;
+        va_copy(argscopy, args);
+        m_parentLogger.messagev(options, format, argscopy);
+        va_end(argscopy);
+    }
+
+    DltContextData log;
+    if (!(options.m_flags & MessageOptions::ALREADY_LOGGED) &&
+        dlt_user_log_write_start((DltContext *)m_dltContext, &log, SyncEvoLevel2DLTLevel(options.m_level)) > 0) {
+        std::string buffer = StringPrintfV(format, args);
+        // Avoid almost empty messages. They are triggered by
+        // SyncEvolution to format the INFO output and don't add any
+        // valuable information to the DLT log.
+        if (!buffer.empty() &&
+            buffer != "\n") {
+            dlt_user_log_write_string(&log, buffer.c_str());
+            dlt_user_log_write_finish(&log);
+        }
+    }
+}
+
+int LoggerDLT::getCurrentDLTLogLevel()
+{
+    if (LoggerDLTInstance) {
+        for (int level = DLT_LOG_VERBOSE;
+             level > DLT_LOG_DEFAULT;
+             --level) {
+            DltContextData log;
+            // Emulates DLT_LOG(): logging active if dlt_user_log_write_start() returns something > 0.
+            // Otherwise discard the DltContextData without doing anything.
+            if (dlt_user_log_write_start((DltContext *)LoggerDLTInstance->m_dltContext, &log, (DltLogLevelType)level) > 0) {
+                return level;
+            }
+        }
+    }
+    return DLT_LOG_DEFAULT;
+}
+
+SE_END_CXX
+
+#endif // USE_DLT
diff --git a/src/syncevo/LogDLT.h b/src/syncevo/LogDLT.h
new file mode 100644 (file)
index 0000000..f93e1dc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#ifndef INCL_LOGDLT
+#define INCL_LOGDLT
+
+#include <config.h>
+
+#ifdef USE_DLT
+
+#include <syncevo/Logging.h>
+#include <syncevo/util.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+/**
+ * A logger which writes to DLT and passes log messages
+ * through to its parent.
+ */
+class LoggerDLT : public Logger
+{
+    Handle m_parentLogger;
+    // avoid dependency on dlt.h here
+    void *m_dltContext;
+
+public:
+    LoggerDLT(const char *appid, const char *description);
+    ~LoggerDLT();
+
+    virtual void messagev(const MessageOptions &options,
+                          const char *format,
+                          va_list args);
+
+    /**
+     * Extracts current log level from the LoggerDLT which was
+     * pushed onto the stack, DLT_LOG_DEFAULT if none active.
+     */
+    static int getCurrentDLTLogLevel();
+};
+
+SE_END_CXX
+
+#endif // USE_DLT
+#endif // INCL_LOGSYSLOG
index ca7666c..45640cc 100644 (file)
@@ -247,16 +247,18 @@ void LogRedirect::messagev(const MessageOptions &options,
 
     // check for other output first
     process();
 
     // check for other output first
     process();
-    // Choose output channel: SHOW goes to original stdout,
-    // everything else to stderr.
-    LoggerStdout::write(options.m_level == SHOW ?
-                        (m_out ? m_out : stdout) :
-                        (m_err ? m_err : stderr),
-                        options.m_level, getLevel(),
-                        options.m_prefix,
-                        options.m_processName,
-                        format,
-                        args);
+    if (!(options.m_flags & MessageOptions::ONLY_GLOBAL_LOG)) {
+        // Choose output channel: SHOW goes to original stdout,
+        // everything else to stderr.
+        LoggerStdout::write(options.m_level == SHOW ?
+                            (m_out ? m_out : stdout) :
+                            (m_err ? m_err : stderr),
+                            options.m_level, getLevel(),
+                            options.m_prefix,
+                            options.m_processName,
+                            format,
+                            args);
+    }
 }
 
 void LogRedirect::redirect(int original, FDs &fds) throw()
 }
 
 void LogRedirect::redirect(int original, FDs &fds) throw()
index f78ff9d..a2014e2 100644 (file)
@@ -84,10 +84,12 @@ void LoggerStdout::messagev(const MessageOptions &options,
                             const char *format,
                             va_list args)
 {
                             const char *format,
                             va_list args)
 {
-    write(m_file, options.m_level, getLevel(),
-          options.m_prefix,
-          options.m_processName,
-          format, args);
+    if (!(options.m_flags & MessageOptions::ONLY_GLOBAL_LOG)) {
+        write(m_file, options.m_level, getLevel(),
+              options.m_prefix,
+              options.m_processName,
+              format, args);
+    }
 }
 
 SE_END_CXX
 }
 
 SE_END_CXX
index 0e80947..837c882 100644 (file)
@@ -255,13 +255,15 @@ Logger::MessageOptions::MessageOptions(Level level,
                                        const std::string *prefix,
                                        const char *file,
                                        int line,
                                        const std::string *prefix,
                                        const char *file,
                                        int line,
-                                       const char *function) :
+                                       const char *function,
+                                       int flags) :
     m_level(level),
     m_prefix(prefix),
     m_file(file),
     m_line(line),
     m_function(function),
     m_level(level),
     m_prefix(prefix),
     m_file(file),
     m_line(line),
     m_function(function),
-    m_processName(NULL)
+    m_processName(NULL),
+    m_flags(flags)
 {
 }
 
 {
 }
 
index dde9e32..ce9a249 100644 (file)
@@ -199,13 +199,29 @@ class Logger
         const char *m_function;
         /** name of the process which originally created the message, if different from current one */
         const std::string *m_processName;
         const char *m_function;
         /** name of the process which originally created the message, if different from current one */
         const std::string *m_processName;
+        /** additional flags */
+        int m_flags;
+
+        enum {
+            /**
+             * The message was written into a global log (syslog, dlt, ...)
+             * already. Such a message must not be logged again.
+             */
+            ALREADY_LOGGED = 1<<0,
+            /**
+             * The message must be written into a global log,
+             * but not to stdout.
+             */
+            ONLY_GLOBAL_LOG = 1<<1
+        };
 
         MessageOptions(Level level);
         MessageOptions(Level level,
                        const std::string *prefix,
                        const char *file,
                        int line,
 
         MessageOptions(Level level);
         MessageOptions(Level level,
                        const std::string *prefix,
                        const char *file,
                        int line,
-                       const char *function);
+                       const char *function,
+                       int flags = 0);
     };
 
     /**
     };
 
     /**
index d157a19..13b0aaa 100644 (file)
@@ -73,6 +73,10 @@ using namespace std;
 #include <synthesis/SDK_util.h>
 #include <synthesis/san.h>
 
 #include <synthesis/SDK_util.h>
 #include <synthesis/san.h>
 
+#ifdef USE_DLT
+# include <dlt.h>
+#endif
+
 #include "test.h"
 
 #include <syncevo/declarations.h>
 #include "test.h"
 
 #include <syncevo/declarations.h>
@@ -279,6 +283,9 @@ class LogDirLogger : public Logger
 {
     Logger::Handle m_parentLogger;     /**< the logger which was active before we started to intercept messages */
     boost::weak_ptr<LogDir> m_logdir;  /**< grants access to report and Synthesis engine */
 {
     Logger::Handle m_parentLogger;     /**< the logger which was active before we started to intercept messages */
     boost::weak_ptr<LogDir> m_logdir;  /**< grants access to report and Synthesis engine */
+#ifdef USE_DLT
+    bool m_useDLT;                     /**< SyncEvolution and libsynthesis are logging to DLT */
+#endif
 
 public:
     LogDirLogger(const boost::weak_ptr<LogDir> &logdir);
 
 public:
     LogDirLogger(const boost::weak_ptr<LogDir> &logdir);
@@ -930,6 +937,9 @@ private:
 LogDirLogger::LogDirLogger(const boost::weak_ptr<LogDir> &logdir) :
     m_parentLogger(Logger::instance()),
     m_logdir(logdir)
 LogDirLogger::LogDirLogger(const boost::weak_ptr<LogDir> &logdir) :
     m_parentLogger(Logger::instance()),
     m_logdir(logdir)
+#ifdef USE_DLT
+    , m_useDLT(getenv("SYNCEVOLUTION_USE_DLT") != NULL)
+#endif
 {
 }
 
 {
 }
 
@@ -958,8 +968,16 @@ void LogDirLogger::messagev(const MessageOptions &options,
     m_parentLogger.messagev(options, format, argscopy);
     va_end(argscopy);
 
     m_parentLogger.messagev(options, format, argscopy);
     va_end(argscopy);
 
-    boost::shared_ptr<LogDir> logdir = m_logdir.lock();
-    if (logdir) {
+    // Special handling of our own messages: include in sync report
+    // (always, because that is how we did it traditionally) and write
+    // to our own syncevolution-log.html (if not already logged).
+    //
+    // The TestLocalSync.testServerFailure and some others check that
+    // we record the child's error message in our sync report. If we
+    // don't then it shows up later marked as an "error on the target
+    // side", which is probably not what we want.
+    boost::shared_ptr<LogDir> logdir;
+    if ((bool)(logdir = m_logdir.lock())) {
         if (logdir->m_report &&
             options.m_level <= ERROR &&
             logdir->m_report->getError().empty()) {
         if (logdir->m_report &&
             options.m_level <= ERROR &&
             logdir->m_report->getError().empty()) {
@@ -971,7 +989,14 @@ void LogDirLogger::messagev(const MessageOptions &options,
             logdir->m_report->setError(error);
         }
 
             logdir->m_report->setError(error);
         }
 
-        if (logdir->m_client.getEngine().get()) {
+        if (!(options.m_flags & MessageOptions::ALREADY_LOGGED) &&
+#ifdef USE_DLT
+            // Don't send to  libsynthesis if using DLT,
+            // because then it would end up getting logged
+            // in DLT twice.
+            !m_useDLT &&
+#endif
+            logdir->m_client.getEngine().get()) {
             va_list argscopy;
             va_copy(argscopy, args);
             // Once to Synthesis log, with full debugging.
             va_list argscopy;
             va_copy(argscopy, args);
             // Once to Synthesis log, with full debugging.
@@ -2646,23 +2671,77 @@ void SyncContext::getConfigXML(string &xml, string &configname)
         stringstream debug;
         bool logging = !m_sourceListPtr->getLogdir().empty();
         int loglevel = getLogLevel();
         stringstream debug;
         bool logging = !m_sourceListPtr->getLogdir().empty();
         int loglevel = getLogLevel();
+#ifdef USE_DLT
+        const char *useDLT = getenv("SYNCEVOLUTION_USE_DLT");
+#else
+        static const char *useDLT = NULL;
+#endif
 
         debug <<
             "  <debug>\n"
             // logpath is a config variable set by SyncContext::doSync()
             "    <logpath>$(logpath)</logpath>\n"
 
         debug <<
             "  <debug>\n"
             // logpath is a config variable set by SyncContext::doSync()
             "    <logpath>$(logpath)</logpath>\n"
-            "    <filename>" <<
-            LogfileBasename << "</filename>" <<
+            "    <filename>" << (useDLT ? "" : LogfileBasename) << "</filename>" <<
             "    <logflushmode>flush</logflushmode>\n"
             "    <logflushmode>flush</logflushmode>\n"
-            "    <logformat>html</logformat>\n"
-            "    <folding>auto</folding>\n"
-            "    <timestamp>yes</timestamp>\n"
-            "    <timestampall>yes</timestampall>\n"
+            "    <logformat>" << (useDLT ? "dlt" : "html") << "</logformat>\n"
+            "    <folding>auto</folding>\n" <<
+            (useDLT ?
+             "    <timestamp>no</timestamp>\n"
+             "    <timestampall>no</timestampall>\n" :
+             "    <timestamp>yes</timestamp>\n"
+             "    <timestampall>yes</timestampall>\n") <<
             "    <timedsessionlognames>no</timedsessionlognames>\n"
             "    <subthreadmode>separate</subthreadmode>\n"
             "    <logsessionstoglobal>yes</logsessionstoglobal>\n"
             "    <singlegloballog>yes</singlegloballog>\n";
             "    <timedsessionlognames>no</timedsessionlognames>\n"
             "    <subthreadmode>separate</subthreadmode>\n"
             "    <logsessionstoglobal>yes</logsessionstoglobal>\n"
             "    <singlegloballog>yes</singlegloballog>\n";
-        if (logging) {
+#ifdef USE_DLT
+        if (useDLT) {
+            const char *contexts[] = {
+                "PROT",
+                "SESS",
+                "ADMN",
+                "DATA",
+                "REMI",
+                "PARS",
+                "GEN",
+                "TRNS",
+                "SMLT",
+                "SYS"
+            };
+            BOOST_FOREACH (const char *context, contexts) {
+                // Help libsynthesis debuglogger.cpp set default log levels,
+                // based on our own one.
+                SE_LOG_DEBUG(NULL, "default libsynthesis DLT logging of %s = %s",
+                             context, useDLT);
+                setenv((std::string("LIBSYNTHESIS_") + context).c_str(),
+                       useDLT,
+                       false);
+            }
+
+            debug <<
+                // We have to enable all logging inside libsynthesis.
+                // The actual filtering then takes place inside DLT.
+                // Message logging is not supported.
+                "    <enable option=\"all\"/>\n"
+                // Allow logging outside of sessions.
+                "    <globallogs>yes</globallogs>\n"
+                // Don't try per-session logging, it all goes to DLT anyway.
+                "    <sessionlogs>yes</sessionlogs>\n"
+                ;
+
+            // Be extra verbose if currently enabled. Cannot be changed later on.
+            if (atoi(useDLT) > DLT_LOG_DEBUG) {
+                debug <<
+                    "    <enable option=\"userdata\"/>\n"
+                    "    <enable option=\"scripts\"/>\n";
+            }
+            if (atoi(useDLT) > DLT_LOG_DEBUG) {
+                debug <<
+                    "    <enable option=\"exotic\"/>\n";
+            }
+        } else
+#endif // USE_DLT
+            if (logging) {
             debug <<
                 "    <sessionlogs>yes</sessionlogs>\n"
                 "    <globallogs>yes</globallogs>\n";
             debug <<
                 "    <sessionlogs>yes</sessionlogs>\n"
                 "    <globallogs>yes</globallogs>\n";
index 04cb95d..391cc1d 100644 (file)
@@ -295,11 +295,13 @@ public:
         }
         boost::shared_ptr<ReadDir> dir (new ReadDir (backend_dir, false));
         string dirpath (backend_dir);
         }
         boost::shared_ptr<ReadDir> dir (new ReadDir (backend_dir, false));
         string dirpath (backend_dir);
+        // Base name (= no dir, no .so suffix) mapping to full file
+        // name (including .so).
+        std::map<std::string, std::string> candidates;
         // scan directories for matching module names
         do {
             debug<<"Scanning backend libraries in " <<dirpath <<endl;
             BOOST_FOREACH (const string &entry, *dir) {
         // scan directories for matching module names
         do {
             debug<<"Scanning backend libraries in " <<dirpath <<endl;
             BOOST_FOREACH (const string &entry, *dir) {
-                void *dlhandle;
                 if (isDir (dirpath + '/' + entry)) {
                     /* This is a 2-level dir, this corresponds to loading
                      * backends from current building directory. The library
                 if (isDir (dirpath + '/' + entry)) {
                     /* This is a 2-level dir, this corresponds to loading
                      * backends from current building directory. The library
@@ -311,25 +313,10 @@ public:
                     }
                     continue;
                 }
                     }
                     continue;
                 }
-                if (entry.rfind(".so") == entry.length()-3){
-
-                    // Open the shared object so that backend can register
-                    // itself. We keep that pointer, so never close the
-                    // module!
+                if (boost::ends_with(entry, ".so")) {
                     string fullpath = dirpath + '/' + entry;
                     fullpath = normalizePath(fullpath);
                     string fullpath = dirpath + '/' + entry;
                     fullpath = normalizePath(fullpath);
-                    // RTLD_LAZY is needed for the WebDAV backend, which
-                    // needs to do an explicit dlopen() of libneon in compatibility
-                    // mode before any of the neon functions can be resolved.
-                    dlhandle = dlopen(fullpath.c_str(), RTLD_LAZY|RTLD_GLOBAL);
-                    // remember which modules were found and which were not
-                    if (dlhandle) {
-                        debug<<"Loading backend library "<<entry<<endl;
-                        info<<"Loading backend library "<<fullpath<<endl;
-                        m_available.push_back(entry);
-                    } else {
-                        debug<<"Loading backend library "<<entry<<"failed "<< dlerror()<<endl;
-                    }
+                    candidates[entry.substr(0, entry.size() - 3)] = fullpath;
                 }
             }
             if (!dirs.empty()){
                 }
             }
             if (!dirs.empty()){
@@ -340,6 +327,53 @@ public:
                 break;
             }
         } while (true);
                 break;
             }
         } while (true);
+
+        // Look at foo-<version> before foo. If there is more than
+        // one version and the version sorts lexically, the "highest"
+        // one will be checked first, too.
+        //
+        // The intention is to try loading syncebook-2 (with explicit
+        // library dependencies) first, then skip syncebook if loading
+        // of syncebook-2 succeeded. If loading of syncebook-2 fails
+        // due to missing libraries, we proceed to use syncebook.
+        BOOST_REVERSE_FOREACH (const StringPair &entry, candidates) {
+            const std::string &basename = entry.first;
+            const std::string &fullpath = entry.second;
+            std::string replacement;
+            std::string modname;
+            size_t offset = basename.rfind('-');
+            if (offset != basename.npos) {
+                modname = basename.substr(offset);
+            } else {
+                modname = basename;
+            }
+            BOOST_FOREACH (const std::string &l, m_available) {
+                if (boost::starts_with(l, modname)) {
+                    replacement = l;
+                    break;
+                }
+            }
+            if (!replacement.empty()) {
+                debug << "Skipping " << basename << " = " << fullpath << " because a more recent version of it was already loaded: " << replacement;
+                continue;
+            }
+
+            // Open the shared object so that backend can register
+            // itself. We keep that pointer, so never close the
+            // module!
+            // RTLD_LAZY is needed for the WebDAV backend, which
+            // needs to do an explicit dlopen() of libneon in compatibility
+            // mode before any of the neon functions can be resolved.
+            void *dlhandle = dlopen(fullpath.c_str(), RTLD_LAZY|RTLD_GLOBAL);
+            // remember which modules were found and which were not
+            if (dlhandle) {
+                debug<<"Loading backend library "<<basename<<endl;
+                info<<"Loading backend library "<<fullpath<<endl;
+                m_available.push_back(basename);
+            } else {
+                debug<<"Loading backend library "<<basename<<"failed "<< dlerror()<<endl;
+            }
+        }
 #endif
     }
     list<string> m_available;
 #endif
     }
     list<string> m_available;
index 57da24b..0f4628c 100644 (file)
@@ -163,8 +163,6 @@ void *findSymbols(const char *libname, int minver, int maxver,
 
 }
 
 
 }
 
-#endif // EVOLUTION_COMPATIBILITY
-
 int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
 int EDSAbiHaveIcal;
 int SyncEvoHaveLibbluetooth;
 int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
 int EDSAbiHaveIcal;
 int SyncEvoHaveLibbluetooth;
@@ -179,7 +177,6 @@ extern "C" void EDSAbiWrapperInit()
         initialized = true;
     }
 
         initialized = true;
     }
 
-#ifdef EVOLUTION_COMPATIBILITY
 # ifdef HAVE_EDS
     edshandle =
     findSymbols("libedataserver-1.2.so", 7, 16,
 # ifdef HAVE_EDS
     edshandle =
     findSymbols("libedataserver-1.2.so", 7, 16,
@@ -412,24 +409,8 @@ extern "C" void EDSAbiWrapperInit()
     }
     SyncEvoHaveLibbluetooth = EDSAbiWrapperSingleton.sdp_connect != 0;
 # endif
     }
     SyncEvoHaveLibbluetooth = EDSAbiWrapperSingleton.sdp_connect != 0;
 # endif
-#else // EVOLUTION_COMPATIBILITY
-# ifdef HAVE_EDS
-    EDSAbiHaveEdataserver = true;
-# endif
-# ifdef ENABLE_EBOOK
-    EDSAbiHaveEbook = true;
-# endif
-# ifdef ENABLE_ECAL
-    EDSAbiHaveEcal = true;
-# endif
-# ifdef ENABLE_ICAL
-    EDSAbiHaveIcal = true;
-# endif
-# ifdef ENABLE_BLUETOOTH
-    SyncEvoHaveLibbluetooth = true;
-# endif
-#endif // EVOLUTION_COMPATIBILITY
 }
 }
+#endif // EVOLUTION_COMPATIBILITY
 
 extern "C" const char *EDSAbiWrapperInfo() { EDSAbiWrapperInit(); return lookupInfo.c_str(); }
 extern "C" const char *EDSAbiWrapperDebug() { EDSAbiWrapperInit(); return lookupDebug.c_str(); }
 
 extern "C" const char *EDSAbiWrapperInfo() { EDSAbiWrapperInit(); return lookupInfo.c_str(); }
 extern "C" const char *EDSAbiWrapperDebug() { EDSAbiWrapperInit(); return lookupDebug.c_str(); }
index 186fab2..bdf1595 100644 (file)
@@ -93,6 +93,8 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
+#ifdef EVOLUTION_COMPATIBILITY
+
 /** libebook, libecal, libedataserver available (currently checks for e_book_new/e_cal_new/e_source_group_peek_sources) */
 extern int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
 extern int EDSAbiHaveIcal;
 /** libebook, libecal, libedataserver available (currently checks for e_book_new/e_cal_new/e_source_group_peek_sources) */
 extern int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
 extern int EDSAbiHaveIcal;
@@ -100,7 +102,8 @@ extern int EDSAbiHaveIcal;
 /** libbluetooth available (checks sdp_connect()) */
 extern int SyncEvoHaveLibbluetooth;
 
 /** libbluetooth available (checks sdp_connect()) */
 extern int SyncEvoHaveLibbluetooth;
 
-#ifdef EVOLUTION_COMPATIBILITY
+/** initialize pointers to EDS functions, if necessary; can be called multiple times */
+void EDSAbiWrapperInit();
 
 /**
  * This is a struct instead of a namespace because that allows
 
 /**
  * This is a struct instead of a namespace because that allows
@@ -444,6 +447,23 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton;
 
 #else /* EVOLUTION_COMPATIBILITY */
 
 
 #else /* EVOLUTION_COMPATIBILITY */
 
+// This is necessary because in C++, 1 && 1 triggers
+// a warning with some gcc versions.
+#ifdef __cplusplus
+# define EDS_ABI_HACK_TRUE true
+#else
+# define EDS_ABI_HACK_TRUE 1
+#endif
+
+# define EDSAbiHaveEbook EDS_ABI_HACK_TRUE
+# define EDSAbiHaveEcal EDS_ABI_HACK_TRUE
+# define EDSAbiHaveEdataserver EDS_ABI_HACK_TRUE
+# define EDSAbiHaveIcal EDS_ABI_HACK_TRUE
+# define SyncEvoHaveLibbluetooth EDS_ABI_HACK_TRUE
+
+
+# define EDSAbiWrapperInit()
+
 # if !defined(EDS_ABI_WRAPPER_NO_REDEFINE) && defined(HAVE_LIBICAL_R)
 #  ifdef ENABLE_ICAL
 #   ifndef LIBICAL_MEMFIXES
 # if !defined(EDS_ABI_WRAPPER_NO_REDEFINE) && defined(HAVE_LIBICAL_R)
 #  ifdef ENABLE_ICAL
 #   ifndef LIBICAL_MEMFIXES
@@ -457,9 +477,6 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton;
 # endif /* EDS_ABI_WRAPPER_NO_REDEFINE */
 #endif /* EVOLUTION_COMPATIBILITY */
 
 # endif /* EDS_ABI_WRAPPER_NO_REDEFINE */
 #endif /* EVOLUTION_COMPATIBILITY */
 
-/** initialize pointers to EDS functions, if necessary; can be called multiple times */
-void EDSAbiWrapperInit();
-
 const char *EDSAbiWrapperInfo();
 const char *EDSAbiWrapperDebug();
 
 const char *EDSAbiWrapperInfo();
 const char *EDSAbiWrapperDebug();
 
index f5bd6a8..1794017 100644 (file)
@@ -49,6 +49,8 @@ src_syncevo_sources = \
   \
   src/syncevo/Logging.h \
   src/syncevo/Logging.cpp \
   \
   src/syncevo/Logging.h \
   src/syncevo/Logging.cpp \
+  src/syncevo/LogDLT.h \
+  src/syncevo/LogDLT.cpp \
   src/syncevo/LogStdout.h \
   src/syncevo/LogStdout.cpp \
   src/syncevo/LogRedirect.h \
   src/syncevo/LogStdout.h \
   src/syncevo/LogStdout.cpp \
   src/syncevo/LogRedirect.h \
@@ -212,6 +214,7 @@ src_syncevo_libsyncevolution_la_LIBADD = \
   $(TRANSPORT_LIBS) \
   @LIBS@ \
   $(src_syncevo_ldadd) \
   $(TRANSPORT_LIBS) \
   @LIBS@ \
   $(src_syncevo_ldadd) \
+  $(DLT_LIBS) \
   $(DBUS_LIBS) \
   $(NSS_LIBS)
 if ENABLE_MODULES
   $(DBUS_LIBS) \
   $(NSS_LIBS)
 if ENABLE_MODULES
@@ -228,12 +231,13 @@ src_syncevo_libsyncevolution_la_CFLAGS = \
   $(SYNCEVO_WFLAGS)
 src_syncevo_libsyncevolution_la_CPPFLAGS = \
   $(src_syncevo_cppflags) \
   $(SYNCEVO_WFLAGS)
 src_syncevo_libsyncevolution_la_CPPFLAGS = \
   $(src_syncevo_cppflags) \
+  $(DLT_CFLAGS) \
   $(DBUS_CFLAGS) \
   -DDATA_DIR=\""$(pkgdatadir)"\" \
   -DXML_CONFIG_DIR=\""$(datadir)/syncevolution/xml"\" \
   -DTEMPLATE_DIR=\""$(datadir)/syncevolution/templates"\" \
   -DLIBDIR=\""$(libdir)"\"
   $(DBUS_CFLAGS) \
   -DDATA_DIR=\""$(pkgdatadir)"\" \
   -DXML_CONFIG_DIR=\""$(datadir)/syncevolution/xml"\" \
   -DTEMPLATE_DIR=\""$(datadir)/syncevolution/templates"\" \
   -DLIBDIR=\""$(libdir)"\"
-src_syncevo_libsyncevolution_la_DEPENDENCIES = $(SYNTHESIS_DEP) $(src_syncevo_ldadd)
+src_syncevo_libsyncevolution_la_DEPENDENCIES = $(SYNTHESIS_DEP) $(filter %.la, $(src_syncevo_ldadd))
 
 # rule which is only relevant when compiling Synthesis in subdirectory
 src/build-synthesis/libsynthesissdk.la: $(SYNTHESIS_SUBDIR)/all
 
 # rule which is only relevant when compiling Synthesis in subdirectory
 src/build-synthesis/libsynthesissdk.la: $(SYNTHESIS_SUBDIR)/all
index 4f26bbb..e073aca 100644 (file)
@@ -140,13 +140,13 @@ DBUS_SERVICES_DIR = @DBUS_SERVICES_DIR@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLLTOOL = @DLLTOOL@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLLTOOL = @DLLTOOL@
+DLT_CFLAGS = @DLT_CFLAGS@
+DLT_LIBS = @DLT_LIBS@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 EASCLIENT_CFLAGS = @EASCLIENT_CFLAGS@
 EASCLIENT_DEPENDENCIES = @EASCLIENT_DEPENDENCIES@
 EASCLIENT_LIBS = @EASCLIENT_LIBS@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 EASCLIENT_CFLAGS = @EASCLIENT_CFLAGS@
 EASCLIENT_DEPENDENCIES = @EASCLIENT_DEPENDENCIES@
 EASCLIENT_LIBS = @EASCLIENT_LIBS@
-EBOOKCONTACTS_CFLAGS = @EBOOKCONTACTS_CFLAGS@
-EBOOKCONTACTS_LIBS = @EBOOKCONTACTS_LIBS@
 EBOOK_CFLAGS = @EBOOK_CFLAGS@
 EBOOK_LIBS = @EBOOK_LIBS@
 EBOOK_VERSION_CFLAGS = @EBOOK_VERSION_CFLAGS@
 EBOOK_CFLAGS = @EBOOK_CFLAGS@
 EBOOK_LIBS = @EBOOK_LIBS@
 EBOOK_VERSION_CFLAGS = @EBOOK_VERSION_CFLAGS@
@@ -321,6 +321,7 @@ SYNCEVOLUTION_CXXFLAGS = @SYNCEVOLUTION_CXXFLAGS@
 SYNCEVOLUTION_LDADD = @SYNCEVOLUTION_LDADD@
 SYNCEVOLUTION_LIBS = @SYNCEVOLUTION_LIBS@
 SYNCEVOLUTION_LOCALEDIR = @SYNCEVOLUTION_LOCALEDIR@
 SYNCEVOLUTION_LDADD = @SYNCEVOLUTION_LDADD@
 SYNCEVOLUTION_LIBS = @SYNCEVOLUTION_LIBS@
 SYNCEVOLUTION_LOCALEDIR = @SYNCEVOLUTION_LOCALEDIR@
+SYNCEVO_DBUS_SERVER_ARGS = @SYNCEVO_DBUS_SERVER_ARGS@
 SYNCEVO_WFLAGS = @SYNCEVO_WFLAGS@
 SYNCSOURCES = @SYNCSOURCES@
 SYNTHESIS = @SYNTHESIS@
 SYNCEVO_WFLAGS = @SYNCEVO_WFLAGS@
 SYNCSOURCES = @SYNCSOURCES@
 SYNTHESIS = @SYNTHESIS@
index 67e8026..678e359 100644 (file)
@@ -1,6 +1,28 @@
 # Generated by configure.  Do not edit.
 # Generated by configure.  Do not edit.
-# git revision 5cd3c49d8e51eb76be24049234c64922bcc3654e
-# git tag libsynthesis_3.4.0.47+syncevolution-1-3-99-4
+# git revision 69de3861f0d3b98e0f5791baea7254cdb2e7bce5
+# git tag libsynthesis_3.4.0.47+syncevolution-1-3-99-6
+
+2013-10-29  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * configure.in:
+
+       autotools: bump Linux/SyncEvolution sub-version for DLT support
+
+2013-10-27  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/platform_adapters/linux/configfiles.cpp:
+
+       Linux: avoid expensive network hostname lookup (FDO #70771)
+
+2013-10-22  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * README.DLT:
+       * configure.in:
+       * src/Makefile.am.in:
+       * src/sysync/debuglogger.cpp:
+       * src/sysync/debuglogger.h:
+
+       logging: support DLT
 
 2013-07-11  Patrick Ohly  <patrick.ohly@intel.com>
 
 
 2013-07-11  Patrick Ohly  <patrick.ohly@intel.com>
 
        Initial Commit by Synthesis AG for Open Source libsynthesis
        3.2.0.25 and libsmltk
 
        Initial Commit by Synthesis AG for Open Source libsynthesis
        3.2.0.25 and libsmltk
 
-hly@intel.com>
+:
+
+       CalDAV: fixed Google 404 workaround
+
+2012-03-09  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * Makefile.am:
+       * description:
+
+       packaging: added evolution and kde meta .deb packages
+
+2012-03-09  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/backends/kde/KDEPlatform.cpp:
+
+       KDE: use up-to-date version number in appinfo
+
+2012-03-08  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/syncevo/SyncContext.cpp:
+       * test/test-dbus.py:
+
+       D-Bus test: interactive password request in local sync
+
+2012-03-06  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/CmdlineSyncClient.cpp:
+       * src/CmdlineSyncClient.h:
+       * src/backends/gnome/GNOMEPlatformRegister.cpp:
+       * src/backends/kde/KDEPlatformRegister.cpp:
+       * src/dbus/server/dbus-sync.cpp:
+       * src/dbus/server/dbus-sync.h:
+       * src/dbus/server/dbus-user-interface.cpp:
+       * src/dbus/server/dbus-user-interface.h:
+       * src/dbus/server/read-operations.cpp:
+       * src/dbus/server/read-operations.h:
+       * src/dbus/server/session.cpp:
+       * src/syncevo/Cmdline.cpp:
+       * src/syncevo/LocalTransportAgent.cpp:
+       * src/syncevo/SyncConfig.cpp:
+       * src/syncevo/SyncConfig.h:
+       * src/syncevo/SyncContext.cpp:
+       * src/syncevo/SyncContext.h:
+       * src/syncevo/UserInterface.cpp:
+       * src/syncevo/UserInterface.h:
+       * src/syncevo/syncevo.am:
+       * src/syncevo/util.h:
+
+       SyncContext + ConfigUserInterface: code refactoring
+
+2012-03-08  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/backends/activesync/ActiveSyncSourceRegister.cpp:
+       * src/backends/addressbook/AddressBookSourceRegister.cpp:
+       * src/backends/akonadi/AkonadiSyncSourceRegister.cpp:
+       * src/backends/evolution/EvolutionCalendarSourceRegister.cpp:
+       * src/backends/evolution/EvolutionContactSourceRegister.cpp:
+       * src/backends/file/FileSyncSourceRegister.cpp:
+       * src/backends/kcalextended/KCalExtendedSourceRegister.cpp:
+       * src/backends/maemo/MaemoCalendarSourceRegister.cpp:
+       * src/backends/qtcontacts/QtContactsSourceRegister.cpp:
+       * src/backends/sqlite/SQLiteContactSourceRegister.cpp:
+       * src/backends/webdav/WebDAVSourceRegister.cpp:
+       * src/backends/xmlrpc/XMLRPCSyncSourceRegister.cpp:
+       * src/dbus/server/read-operations.cpp:
+       * src/syncevo/Cmdline.cpp:
+       * src/syncevo/SyncSource.cpp:
+       * src/syncevo/SyncSource.h:
+
+       SyncSource: remove special RegisterSyncSource::InactiveSource
+       pointer
+
+2012-03-06  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * configure.ac:
+       * src/CmdlineSyncClient.cpp:
+       * src/backends/gnome/GNOMEPlatform.cpp:
+       * src/backends/gnome/GNOMEPlatform.h:
+       * src/backends/gnome/GNOMEPlatformRegister.cpp:
+       * src/backends/gnome/configure-sub.in:
+       * src/backends/gnome/gnome.am:
+       * src/backends/kde/KDEPlatform.cpp:
+       * src/backends/kde/KDEPlatform.h:
+       * src/backends/kde/KDEPlatformRegister.cpp:
+       * src/backends/kde/configure-sub.in:
+       * src/backends/kde/kde.am:
+       * src/dbus/server/dbus-user-interface.cpp:
+       * src/dbus/server/server.am:
+       * src/src.am:
+       * src/syncevo/Cmdline.cpp:
+       * src/syncevo/SyncConfig.cpp:
+       * src/syncevo/SyncConfig.h:
+       * src/syncevo/SyncContext.cpp:
+       * src/syncevo/SyncContext.h:
+       * src/syncevo/syncevo.am:
+       * test/sys.supp:
+
+       KDE + GNOME: moved keyring/kwallet and KDE init into modules
+
+2012-03-08  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/syncevo/SyncConfig.h:
+       * src/syncevo/SyncContext.h:
+
+       SyncContext+SyncConfig: virtual destructor
+
+2012-03-07  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/sys.supp:
+
+       testing: valgrind suppressions for Debian Testing, part II
+
+2012-03-06  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/evo.supp:
+
+       evo.supp: ignore genuine leak in EDS
+
+2012-03-06  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/sys.supp:
+
+       sys.supp: ignore cond valgrind warning in libdb
+
+2012-03-07  Patrick Ohly  <patrick.ohly@intel.com>
+
+
+       Merge branch 'master' into pbap
+
+2012-03-06  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/syncevo/configs/scripting/04vcard-photo-inlining.xml:
+
+       sync: fixed inlining of EDS 3.4 PHOTO data
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/evo.supp:
+
+       Revert "testing: ignore real leak in libecal 3.2"
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/backends/evolution/EvolutionContactSource.cpp:
+       * src/backends/evolution/configure-sub.in:
+       * src/syncevo/eds_abi_wrapper.cpp:
+       * src/syncevo/eds_abi_wrapper.h:
+
+       EDS: added support for inlining local photo data in backup and
+       --export
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/dbus-session.sh:
+
+       dbus-session: updated auto-starting of EDS daemons
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/synccompare.pl:
+
+       synccompare: shorter data dump of PHOTO
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * src/backends/activesync/configure-sub.in:
+
+       ActiveSync: don't compile camel backend and eplugin
+
+2012-03-01  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/ClientTest.cpp:
+       * test/testcases/eds_event.ics.radicale.tem.patch:
+
+       Revert "testing: ignore Radicale detached recurrence issue"
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/resultchecker.py:
+
+       testing: fixed result checking for restart tests
+
+2012-03-02  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/runtests.py:
+
+       runtests.py: test combined contact/event sync with syncevohttp
+
+2012-02-13  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/ClientTest.cpp:
+       * test/ClientTest.h:
+       * test/runtests.py:
+
+       client-test: add Client::Sync::*::testTwoWayRestart
+
+2012-02-13  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/ClientTest.cpp:
+       * test/ClientTest.h:
+
+       CheckSyncReport: refactor check()
+
+2012-02-13  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/ClientTest.h:
+
+       SyncOptions: added comment to m_startCallback
+
+2012-02-13  Patrick Ohly  <patrick.ohly@intel.com>
+
+       * test/ClientTest.cpp:
+       * test/ClientTest.h:
+
+       ClientTest: refactored code for inserting and deleting items in
+       source test
+
+2012-02-13  Patrick Ohly  <patrick.ohly@intel.com>
 
        * src/syncevo/SyncContext.cpp:
        * src/syncevo/SyncContext.h:
 
        * src/syncevo/SyncContext.cpp:
        * src/syncevo/SyncContext.h:
index 63ea2e5..a7a5eba 100644 (file)
@@ -149,6 +149,8 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DLT_CFLAGS = @DLT_CFLAGS@
+DLT_LIBS = @DLT_LIBS@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
diff --git a/src/synthesis/README.DLT b/src/synthesis/README.DLT
new file mode 100644 (file)
index 0000000..2fc36fc
--- /dev/null
@@ -0,0 +1,90 @@
+GENIVI Diagnostic Log and Trace (DLT) support
+=============================================
+
+DLT is a logging mechanism defined by GENIVI. It supports the context
+of log message contexts (arbitrary groups, defined by the app or
+library) and levels (off, fatal, error, warning, information, debug,
+verbose). The log level can be set per context, using mechanisms
+provided by DLT (for example, interactively via DLT client connected
+to a system running the DLT daemon and apps using that daemon).
+
+If DLT support is enabled during compilation of libsynthesis (use
+--enable-dlt on Linux) and in the configuration (use "dlt" as
+"logformat" and ignore all other logging options), then libsynthesis
+uses DLT for logging instead of writing its own files.
+
+libsynthesis has no concept of a strictly ordered log level. Instead
+major categories are combined with minor ones, which allows enabling
+"more verbose" logging for some aspects of a major category while
+leaving "less verbose" ones disabled. When using DLT, a hard-coded
+mapping between minor categories and log level is used, so some
+flexibility is lost.
+
+The mapping is as follows:
+
+Context ID = Synthesis debug topic: description (from SySync_config_reference.pdf)
+
+PROT = "proto": SyncML protocol related information.
+SESS = "session": Session management related information.
+ADMN = "admin": Everything that has to do with administrative data (anchors,
+targets, map table).
+DATA = "data": Everything that has to do with handling user data (data objects).
+Actual user data will however be shown only if loglevel >= debug.
+REMI = "remoteinfo": This shows information delivered in the remote party's
+device information, such as manufacturer name, datatypes supported, fields supported
+etc.
+PARS = "parse": This shows information related to parsing and processing incoming
+data from the remote party. Actual user data will however be shown only if loglevel >=
+debug.
+GEN  = "generate": This shows information related to generating outgoing data for the remote
+party. Actual user data will however be shown only if loglevel >= debug.
+TRNS = "transp": Shows transport (http and TCP communication) related information.
+SMLT = "syncml_rtk": Messages generated by the SyncML Toolkit code.
+SYSY = "rest": Any other debug log message that does not fit in any of the above
+contexts.
+
+The default log level of each context can be set via env variables
+called LIBSYNTHESIS_<context ID>, with values from 0 (off) to 6
+(verbose).
+
+The log level of a message is derived from the other Synthesis debug topics:
+
+"error" => ERROR: error messages.
+
+"hot"=> INFO: most important information (of all topics). This should never
+be switched of (except when switching off debug logging completely).
+
+"userdata" => DEBUG: Anything that is user data. To create anonymized
+logs that do not show user's data, use a log level less than debug
+(and, depending on the database interface, "dbapi" as well, as it
+might show SQL commands revealing user data as well).
+
+"dbapi" => VERBOSE: Information related to accessing the database. For
+ODBC, this enables showing SQL statements issued to the database, for
+plugin datastores, this includes all communication with the plugins
+and also messages generated by the plugin itself (see "plugin" below).
+
+"plugin" => DEBUG: Messages generated by database adapter plugins.
+
+"scripts" => VERBOSE: This is useful to debug scripts, and shows each
+line of executed scripts (but only for enabled debug topics!). Switching
+this on can generate huge log files, so it should normally be switched
+off in productive environments.
+
+"expressions" => VERBOSE: Together with "scripts" this causes detailed
+step-by-step logging of script expression evaluation.
+
+"filter" => DEBUG. Information about data item filtering.
+
+"match" => VERBOSE: Information about matching data in slow sync. Note
+that together with "exotic" this can produce extremely large logs as
+matching is an O(N^2) operation, so use with care.
+
+"conflict" => DEBUG: Information about conflict resolution and data merging.
+
+"details" => increases log level by one. Enabling this option adds
+generally some more detail to the debug output.
+
+"exotic" => VERBOSE: Enabling this adds the highest level of exotic detail possible.
+This is usually only required to track down device interoperability issues or
+bugs in the server/config.
index f784e7e..2030561 100644 (file)
@@ -97,5 +97,8 @@
 /* libsynthesis.a linked statically */
 #undef UIAPI_LINKED
 
 /* libsynthesis.a linked statically */
 #undef UIAPI_LINKED
 
+/* "optionally use GENIVI Diagnostic Log and Trace for logging" */
+#undef USE_DLT
+
 /* Version number of package */
 #undef VERSION
 /* Version number of package */
 #undef VERSION
index ce25b3f..3a43f1a 100755 (executable)
@@ -754,6 +754,8 @@ LIBECAL_LIBS
 LIBECAL_CFLAGS
 LIBICAL_LIBS
 LIBICAL_CFLAGS
 LIBECAL_CFLAGS
 LIBICAL_LIBS
 LIBICAL_CFLAGS
+DLT_LIBS
+DLT_CFLAGS
 PCRE_LIBS
 PCRE_CFLAGS
 SQLITE3_LIBS
 PCRE_LIBS
 PCRE_CFLAGS
 SQLITE3_LIBS
@@ -891,6 +893,7 @@ enable_warnings
 enable_debug_logs
 enable_sqlite
 enable_regex
 enable_debug_logs
 enable_sqlite
 enable_regex
+enable_dlt
 enable_libical
 enable_evolution_compatibility
 with_xmltok
 enable_libical
 enable_evolution_compatibility
 with_xmltok
@@ -916,6 +919,8 @@ SQLITE3_CFLAGS
 SQLITE3_LIBS
 PCRE_CFLAGS
 PCRE_LIBS
 SQLITE3_LIBS
 PCRE_CFLAGS
 PCRE_LIBS
+DLT_CFLAGS
+DLT_LIBS
 LIBICAL_CFLAGS
 LIBICAL_LIBS
 LIBECAL_CFLAGS
 LIBICAL_CFLAGS
 LIBICAL_LIBS
 LIBECAL_CFLAGS
@@ -1553,6 +1558,8 @@ Optional Features:
                           libsqlite3, enabled by default
   --enable-regex          enable regular expression support in scripts,
                           depends on libpcre, enabled by default
                           libsqlite3, enabled by default
   --enable-regex          enable regular expression support in scripts,
                           depends on libpcre, enabled by default
+  --enable-dlt            enable logging mode "dlt" = GENIVI Diagnostic Log
+                          and Trace
   --enable-libical        use libical (if necessary, the one in libecal) to
                           improve time zone support, enabled by default if
                           necessary libs are found
   --enable-libical        use libical (if necessary, the one in libecal) to
                           improve time zone support, enabled by default if
                           necessary libs are found
@@ -1604,6 +1611,8 @@ Some influential environment variables:
               linker flags for SQLITE3, overriding pkg-config
   PCRE_CFLAGS C compiler flags for PCRE, overriding pkg-config
   PCRE_LIBS   linker flags for PCRE, overriding pkg-config
               linker flags for SQLITE3, overriding pkg-config
   PCRE_CFLAGS C compiler flags for PCRE, overriding pkg-config
   PCRE_LIBS   linker flags for PCRE, overriding pkg-config
+  DLT_CFLAGS  C compiler flags for DLT, overriding pkg-config
+  DLT_LIBS    linker flags for DLT, overriding pkg-config
   LIBICAL_CFLAGS
               C compiler flags for LIBICAL, overriding pkg-config
   LIBICAL_LIBS
   LIBICAL_CFLAGS
               C compiler flags for LIBICAL, overriding pkg-config
   LIBICAL_LIBS
@@ -2976,7 +2985,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=synthesis
 
 # Define the identity of the package.
  PACKAGE=synthesis
- VERSION=3.4.0.16.10
+ VERSION=3.4.0.16.11
 
 
 cat >>confdefs.h <<_ACEOF
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5067,13 +5076,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:5070: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:5079: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5073: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:5082: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5076: output\"" >&5)
+  (eval echo "\"\$as_me:5085: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -6279,7 +6288,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6282 "configure"' > conftest.$ac_ext
+  echo '#line 6291 "configure"' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -8334,11 +8343,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8337: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8346: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8341: \$? = $ac_status" >&5
+   echo "$as_me:8350: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8673,11 +8682,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8676: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8685: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8680: \$? = $ac_status" >&5
+   echo "$as_me:8689: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8778,11 +8787,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8781: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8790: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8785: \$? = $ac_status" >&5
+   echo "$as_me:8794: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -8833,11 +8842,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8836: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8845: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8840: \$? = $ac_status" >&5
+   echo "$as_me:8849: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -11217,7 +11226,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11220 "configure"
+#line 11229 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11313,7 +11322,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11316 "configure"
+#line 11325 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13269,11 +13278,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13272: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13281: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13276: \$? = $ac_status" >&5
+   echo "$as_me:13285: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -13368,11 +13377,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13371: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13380: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13375: \$? = $ac_status" >&5
+   echo "$as_me:13384: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -13420,11 +13429,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13423: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13432: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13427: \$? = $ac_status" >&5
+   echo "$as_me:13436: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15039,6 +15048,91 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
 _ACEOF
 
 
+# Check whether --enable-dlt was given.
+if test "${enable_dlt+set}" = set; then :
+  enableval=$enable_dlt; enable_dlt=$enableval
+               test $enable_dlt = "yes" || test $enable_dlt = "no" || as_fn_error "invalid value of --enable-dlt: $enableval" "$LINENO" 5
+else
+  enable_dlt="no"
+fi
+
+if test "$enable_dlt" = "yes"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DLT" >&5
+$as_echo_n "checking for DLT... " >&6; }
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$DLT_CFLAGS"; then
+        pkg_cv_DLT_CFLAGS="$DLT_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"automotive-dlt\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "automotive-dlt") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_DLT_CFLAGS=`$PKG_CONFIG --cflags "automotive-dlt" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+       pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$DLT_LIBS"; then
+        pkg_cv_DLT_LIBS="$DLT_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"automotive-dlt\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "automotive-dlt") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_DLT_LIBS=`$PKG_CONFIG --libs "automotive-dlt" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+       pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               DLT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "automotive-dlt"`
+        else
+               DLT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "automotive-dlt"`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$DLT_PKG_ERRORS" >&5
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                as_fn_error "dlt not found, required for --enable-dlt" "$LINENO" 5
+elif test $pkg_failed = untried; then
+       as_fn_error "dlt not found, required for --enable-dlt" "$LINENO" 5
+else
+       DLT_CFLAGS=$pkg_cv_DLT_CFLAGS
+       DLT_LIBS=$pkg_cv_DLT_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       USE_DLT=1
+fi
+
+$as_echo "#define USE_DLT 1" >>confdefs.h
+
+fi
+
 ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
 if test "x$ac_cv_header_zlib_h" = x""yes; then :
 
 ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
 if test "x$ac_cv_header_zlib_h" = x""yes; then :
 
index 2827e51..cf6a488 100644 (file)
@@ -4,7 +4,7 @@ AC_INIT(src/sysync/engineinterface.cpp)
 AC_CONFIG_MACRO_DIR([m4])
 # four digit upstream version, one additional digit for
 # Linux/SyncEvolution specific extensions:
 AC_CONFIG_MACRO_DIR([m4])
 # four digit upstream version, one additional digit for
 # Linux/SyncEvolution specific extensions:
-AM_INIT_AUTOMAKE(synthesis, 3.4.0.16.10)
+AM_INIT_AUTOMAKE(synthesis, 3.4.0.16.11)
 AM_CONFIG_HEADER(config.h)
 AC_LIBTOOL_DLOPEN
 
 AM_CONFIG_HEADER(config.h)
 AC_LIBTOOL_DLOPEN
 
@@ -72,6 +72,19 @@ else
 fi
 AC_DEFINE_UNQUOTED(ONOFF_REGEX_SUPPORT, $HAVE_PCRE, "regular expressions in scripts")
 
 fi
 AC_DEFINE_UNQUOTED(ONOFF_REGEX_SUPPORT, $HAVE_PCRE, "regular expressions in scripts")
 
+AC_ARG_ENABLE(dlt,
+              AS_HELP_STRING([--enable-dlt],
+                             [enable logging mode "dlt" = GENIVI Diagnostic Log and Trace]),
+              [enable_dlt=$enableval
+               test $enable_dlt = "yes" || test $enable_dlt = "no" || AC_ERROR([invalid value of --enable-dlt: $enableval])],
+              [enable_dlt="no"])
+if test "$enable_dlt" = "yes"; then
+    PKG_CHECK_MODULES(DLT, automotive-dlt,
+                      [USE_DLT=1],
+                      [AC_ERROR([dlt not found, required for --enable-dlt])])
+    AC_DEFINE(USE_DLT, 1, "optionally use GENIVI Diagnostic Log and Trace for logging")
+fi
+
 AC_CHECK_HEADER(zlib.h, , [AC_ERROR(zlib.h not found.)])
 AC_CHECK_HEADER(xmltok/xmlparse.h, have_system_xmltok="yes")
 AC_CHECK_HEADER(expat.h, have_system_expat="yes")
 AC_CHECK_HEADER(zlib.h, , [AC_ERROR(zlib.h not found.)])
 AC_CHECK_HEADER(xmltok/xmlparse.h, have_system_xmltok="yes")
 AC_CHECK_HEADER(expat.h, have_system_expat="yes")
index c401c1a..0d4f256 100644 (file)
@@ -71,6 +71,7 @@ libsynthesis_la_CFLAGS = \
        -I$(srcdir)/DB_interfaces/api_db/ \
        -I$(srcdir)/sysync_SDK/Sources/ \
        $(PCRE_CFLAGS) \
        -I$(srcdir)/DB_interfaces/api_db/ \
        -I$(srcdir)/sysync_SDK/Sources/ \
        $(PCRE_CFLAGS) \
+       $(DLT_CFLAGS) \
        $(SQLITE3_CFLAGS) \
        $(ZLIB_CFLAGS) \
        $(XMLPARSE_CFLAGS) \
        $(SQLITE3_CFLAGS) \
        $(ZLIB_CFLAGS) \
        $(XMLPARSE_CFLAGS) \
@@ -78,7 +79,7 @@ libsynthesis_la_CFLAGS = \
        $(LIBICAL_CFLAGS) \
        $(LIBECAL_CFLAGS)
 libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS)
        $(LIBICAL_CFLAGS) \
        $(LIBECAL_CFLAGS)
 libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS)
-libsynthesis_la_LIBADD = $(PCRE_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread
+libsynthesis_la_LIBADD = $(PCRE_LIBS) $(DLT_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread
 libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
        -Wl,--version-script=$(srcdir)/synthesis-linker.map
 libsynthesis_la_DEPENDENCIES = $(srcdir)/synthesis-linker.map libsmltk.la
 libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
        -Wl,--version-script=$(srcdir)/synthesis-linker.map
 libsynthesis_la_DEPENDENCIES = $(srcdir)/synthesis-linker.map libsmltk.la
index df2f34a..347dbe3 100644 (file)
@@ -71,6 +71,7 @@ libsynthesis_la_CFLAGS = \
        -I$(srcdir)/DB_interfaces/api_db/ \
        -I$(srcdir)/sysync_SDK/Sources/ \
        $(PCRE_CFLAGS) \
        -I$(srcdir)/DB_interfaces/api_db/ \
        -I$(srcdir)/sysync_SDK/Sources/ \
        $(PCRE_CFLAGS) \
+       $(DLT_CFLAGS) \
        $(SQLITE3_CFLAGS) \
        $(ZLIB_CFLAGS) \
        $(XMLPARSE_CFLAGS) \
        $(SQLITE3_CFLAGS) \
        $(ZLIB_CFLAGS) \
        $(XMLPARSE_CFLAGS) \
@@ -78,7 +79,7 @@ libsynthesis_la_CFLAGS = \
        $(LIBICAL_CFLAGS) \
        $(LIBECAL_CFLAGS)
 libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS)
        $(LIBICAL_CFLAGS) \
        $(LIBECAL_CFLAGS)
 libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS)
-libsynthesis_la_LIBADD = $(PCRE_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread
+libsynthesis_la_LIBADD = $(PCRE_LIBS) $(DLT_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread
 libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
        -Wl,--version-script=$(srcdir)/synthesis-linker.map
 libsynthesis_la_DEPENDENCIES = $(srcdir)/synthesis-linker.map libsmltk.la
 libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
        -Wl,--version-script=$(srcdir)/synthesis-linker.map
 libsynthesis_la_DEPENDENCIES = $(srcdir)/synthesis-linker.map libsmltk.la
index 8d4bbf8..9980f84 100644 (file)
@@ -412,6 +412,8 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DLT_CFLAGS = @DLT_CFLAGS@
+DLT_LIBS = @DLT_LIBS@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -585,6 +587,7 @@ libsynthesis_la_CFLAGS = \
        -I$(srcdir)/DB_interfaces/api_db/ \
        -I$(srcdir)/sysync_SDK/Sources/ \
        $(PCRE_CFLAGS) \
        -I$(srcdir)/DB_interfaces/api_db/ \
        -I$(srcdir)/sysync_SDK/Sources/ \
        $(PCRE_CFLAGS) \
+       $(DLT_CFLAGS) \
        $(SQLITE3_CFLAGS) \
        $(ZLIB_CFLAGS) \
        $(XMLPARSE_CFLAGS) \
        $(SQLITE3_CFLAGS) \
        $(ZLIB_CFLAGS) \
        $(XMLPARSE_CFLAGS) \
@@ -593,7 +596,7 @@ libsynthesis_la_CFLAGS = \
        $(LIBECAL_CFLAGS)
 
 libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS)
        $(LIBECAL_CFLAGS)
 
 libsynthesis_la_CXXFLAGS = $(libsynthesis_la_CFLAGS)
-libsynthesis_la_LIBADD = $(PCRE_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread
+libsynthesis_la_LIBADD = $(PCRE_LIBS) $(DLT_LIBS) $(SQLITE3_LIBS) $(XMLPARSE_LIBS) $(LIBICAL_LIBS) $(LIBECAL_LIBS) libsmltk.la -lz -ldl -lpthread
 libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
        -Wl,--version-script=$(srcdir)/synthesis-linker.map
 
 libsynthesis_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
        -Wl,--version-script=$(srcdir)/synthesis-linker.map
 
index ca2bd26..67e9de2 100755 (executable)
@@ -231,7 +231,6 @@ lineartime_t getFileModificationDate(const char *aFileName)
 bool getLocalDeviceID(string &aURI)
 {
   char     szHostname[100];
 bool getLocalDeviceID(string &aURI)
 {
   char     szHostname[100];
-  struct hostent *pHostEnt=NULL;
   string hostName;
 
   // get name of own machine
   string hostName;
 
   // get name of own machine
@@ -239,12 +238,25 @@ bool getLocalDeviceID(string &aURI)
     hostName="_unknown_";
   }
   else {
     hostName="_unknown_";
   }
   else {
+    // A network lookup of the domain name is not likely
+    // to yield any good result on most Linux consumer
+    // devices. It just causes a slowdown, in particular
+    // when the device is not currently connected (which
+    // does not necessarily prevent syncing, for example
+    // when using Bluetooth); 10 second delays have
+    // been observed while the network stack waits for
+    // a timeout (FDO #70771).
+    //
+    // To avoid that timeout, disable this code unconditionally.
+#if 0
+    struct hostent *pHostEnt=NULL;
     // get host entry
     pHostEnt = gethostbyname(szHostname);
     // return fully qualified name of machine as ID
     if (pHostEnt)
       hostName=pHostEnt->h_name; // DNS name of machine
     else
     // get host entry
     pHostEnt = gethostbyname(szHostname);
     // return fully qualified name of machine as ID
     if (pHostEnt)
       hostName=pHostEnt->h_name; // DNS name of machine
     else
+#endif
       hostName=szHostname; // just name of machine
   }
   // generate URI from name
       hostName=szHostname; // just name of machine
   }
   // generate URI from name
index be685d2..8f976d1 100755 (executable)
 #include "platform_thread.h"
 #endif
 
 #include "platform_thread.h"
 #endif
 
+#ifdef USE_DLT
+#include <dlt.h>
+#endif
+
 namespace sysync {
 
 namespace sysync {
 
+#ifdef USE_DLT
+static bool DbgDLTInitialized;
+static DltContext DbgProtoContext;
+static DltContext DbgSessionContext;
+static DltContext DbgAdminContext;
+static DltContext DbgDataContext;
+static DltContext DbgRemoteInfoContext;
+static DltContext DbgParseContext;
+static DltContext DbgGenerateContext;
+static DltContext DbgTranspContext;
+static DltContext DbgSyncMLTKContext;
+static DltContext DbgDefaultContext;
+#endif
+
+
 #ifndef HARDCODED_CONFIG
 
 // debug format modes
 #ifndef HARDCODED_CONFIG
 
 // debug format modes
@@ -32,6 +51,13 @@ cAppCharP const DbgOutFormatNames[numDbgOutFormats] = {
   "text",       // plain text format (but can be indented)
   "xml",        // XML format
   "html"        // HTML format
   "text",       // plain text format (but can be indented)
   "xml",        // XML format
   "html"        // HTML format
+#ifdef USE_DLT
+  // If DLT support is not enabled, then trying to uses it in a config
+  // will lead to a generic parse error. Might be good enough, although
+  // a dedicated error message about "DLT being disabled in this build"
+  // would be nicer.
+  , "dlt"         // GENIVI Diagnostic Log and Trace
+#endif
 };
 
 
 };
 
 
@@ -733,6 +759,39 @@ string TDebugLoggerBase::dbg2Link(const TDbgLocation &aTDbgLoc, const string &aT
 
 #endif // SYDEBUG_LOCATION
 
 
 #endif // SYDEBUG_LOCATION
 
+#ifdef USE_DLT
+static void DbgText2PlainText(const char *in, size_t len, std::string &out)
+{
+  const char *q=in;
+  const char *s=q;
+  const char *end=in + len;
+
+  while (q<end) {
+    if (*q=='&') {
+      if (end-q>=6 && strucmp(q,"&html;",6)==0) {
+        if (q>s) out.append(s,q-s);
+        // everything until next &html; must be filtered out
+        // - search next &html;
+        s=q=q+6;
+        while(q+6<=end && strucmp(q,"&html;",6)!=0) q++;
+        s=q=q+6;
+      }
+      else if (end-q>=4 && strucmp(q,"&sp;",4)==0) {
+        if (q>s) out.append(s,q-s);
+        s=q=q+4;
+        out += ' '; // convert to plain space
+      }
+      else
+        q++;
+    }
+    else {
+      q++;
+    }
+  }
+  if (q>s) out.append(s,q-s);
+}
+#endif // USE_DLT
+
 
 // output text to debug channel
 void TDebugLoggerBase::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted)
 
 // output text to debug channel
 void TDebugLoggerBase::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted)
@@ -759,6 +818,72 @@ void TDebugLoggerBase::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP
         return; // stop all efforts here
       }
     }
         return; // stop all efforts here
       }
     }
+
+#ifdef USE_DLT
+    // DLT logging logs everything in one chunk
+    if (fDbgOptionsP->fOutputFormat == dbgfmt_dlt) {
+      DltContext *context = &DbgDefaultContext;
+      if (aDbgMask & DBG_PROTO) {
+        context = &DbgProtoContext;
+      }
+      else if (aDbgMask & DBG_SESSION) {
+        context = &DbgSessionContext;
+      }
+      else if (aDbgMask & DBG_ADMIN) {
+        context = &DbgAdminContext;
+      }
+      else if (aDbgMask & DBG_DATA) {
+        context = &DbgDataContext;
+      }
+      else if (aDbgMask & DBG_REMOTEINFO) {
+        context = &DbgRemoteInfoContext;
+      }
+      else if (aDbgMask & DBG_PARSE) {
+        context = &DbgParseContext;
+      }
+      else if (aDbgMask & DBG_GEN) {
+        context = &DbgGenerateContext;
+      }
+      else if (aDbgMask & DBG_TRANSP) {
+        context = &DbgTranspContext;
+      }
+      else if (aDbgMask & (DBG_RTK_SML|DBG_RTK_XPT)) {
+        context = &DbgSyncMLTKContext;
+      }
+
+      DltLogLevelType level = DLT_LOG_VERBOSE;
+      if (level > DLT_LOG_INFO &&
+          (aDbgMask & DBG_HOT)) {
+        level = DLT_LOG_INFO;
+      }
+      if (level > DLT_LOG_ERROR &&
+          (aDbgMask & DBG_ERROR)) {
+        level = DLT_LOG_ERROR;
+      }
+      if (level > DLT_LOG_DEBUG &&
+          (aDbgMask & (DBG_USERDATA|DBG_PLUGIN|DBG_FILTER|DBG_CONFLICT))) {
+        level = DLT_LOG_DEBUG;
+      }
+      if (level < DLT_LOG_VERBOSE &&
+          (aDbgMask & DBG_DETAILS)) {
+        level = (DltLogLevelType)((int)level + 1);
+      }
+      if ((aTextSize > 0 && strlen(aText) > aTextSize) ||
+          strstr(aText, "&html;") ||
+          strstr(aText, "&sp;")) {
+            // Must make a copy and potentially filter out html markup.
+        string buffer;
+        buffer.reserve(aTextSize);
+        DbgText2PlainText(aText, aTextSize ? aTextSize : strlen(aText), buffer);
+        DLT_LOG(*context, level, DLT_STRING(buffer.c_str()));
+      } else {
+        // Fast path: log directly.
+        DLT_LOG(*context, level, DLT_STRING(aText));
+      }
+      return;
+    }
+#endif // USE_DLT
+
     // dissect into lines
     cAppCharP end=aTextSize ? aText+aTextSize : NULL;
     bool firstLine=true;
     // dissect into lines
     cAppCharP end=aTextSize ? aText+aTextSize : NULL;
     bool firstLine=true;
@@ -1325,11 +1450,47 @@ void TDebugLoggerBase::internalCloseBlocks(TDBG_LOCATION_PROTO cAppCharP aBlockN
   }
 } // TDebugLoggerBase::internalCloseBlocks
 
   }
 } // TDebugLoggerBase::internalCloseBlocks
 
+#ifdef USE_DLT
+static void RegisterContext(DltContext *aHandle, const char *aContextID, const char *aDescription)
+{
+  std::string envName = "LIBSYNTHESIS_";
+  envName += aContextID;
+  const char *value = getenv(envName.c_str());
+  if (value) {
+    // Explicit level.
+    DltLogLevelType level = (DltLogLevelType)atoi(value);
+    dlt_register_context_ll_ts(aHandle, aContextID, aDescription, level, DLT_TRACE_STATUS_OFF);
+  } else {
+    // Default level.
+    dlt_register_context(aHandle, aContextID, aDescription);
+  }
+}
+#endif // USE_DLT
 
 // start debugging output if needed and sets fOutStarted
 bool TDebugLoggerBase::DebugStartOutput(void)
 {
   if (!fOutStarted) {
 
 // start debugging output if needed and sets fOutStarted
 bool TDebugLoggerBase::DebugStartOutput(void)
 {
   if (!fOutStarted) {
+#ifdef USE_DLT
+    if (fDbgOptionsP && fDbgOptionsP->fOutputFormat==dbgfmt_dlt) {
+      // Register our logging contexts.
+      if (!DbgDLTInitialized) {
+        RegisterContext(&DbgProtoContext, "PROT", "SyncML protocol related information");
+        RegisterContext(&DbgSessionContext, "SESS", "session management related information");
+        RegisterContext(&DbgAdminContext, "ADMN", "verything that has to do with administrative data (anchors, targets, map table)");
+        RegisterContext(&DbgDataContext, "DATA", "Everything that has to do with handling user data (data objects). Actual user data will however be shown only if loglevel >= debug.");
+        RegisterContext(&DbgRemoteInfoContext, "REMI", "This shows information delivered in the remote party's device information, such as manufacturer name, datatypes supported, fields supported etc.");
+        RegisterContext(&DbgParseContext, "PARS", "This shows information related to parsing and processing incoming data from the remote party. Actual user data will however be shown only if loglevel >= debug.");
+        RegisterContext(&DbgGenerateContext, "GEN", "This shows information related to generating outgoing data for the remote party. Actual user data will however be shown only if loglevel >= debug.");
+        RegisterContext(&DbgTranspContext, "TRNS", "shows transport (http and TCP communication) related information");
+        RegisterContext(&DbgSyncMLTKContext, "SMLT", "messages generated by the SyncML Toolkit code");
+        RegisterContext(&DbgDefaultContext, "SYS", "any other libsynthesis debug log message that does not fit in any of the other contexts");
+        DbgDLTInitialized = true;
+      }
+      fOutStarted = true;
+    }
+    else
+#endif // USE_DLT
     if (fOutputLoggerP) {
       // using another logger, call it to start output
       fOutStarted = fOutputLoggerP->DebugStartOutput();
     if (fOutputLoggerP) {
       // using another logger, call it to start output
       fOutStarted = fOutputLoggerP->DebugStartOutput();
@@ -1396,6 +1557,23 @@ void TDebugLoggerBase::DebugFinalizeOutput(void)
 // Output single line to debug channel (includes indenting and other prefixing, but no further formatting)
 void TDebugLoggerBase::DebugPutLine(TDBG_LOCATION_PROTO cAppCharP aText, stringSize aTextSize, bool aPre)
 {
 // Output single line to debug channel (includes indenting and other prefixing, but no further formatting)
 void TDebugLoggerBase::DebugPutLine(TDBG_LOCATION_PROTO cAppCharP aText, stringSize aTextSize, bool aPre)
 {
+#ifdef USE_DLT
+  if (fDbgOptionsP && fDbgOptionsP->fOutputFormat==dbgfmt_dlt) {
+    // One example where this gets called is DebugVOpen/CloseBlock()
+    // with lines prepared as if we are printing plain text. Use
+    // a fairly neutral log level here.
+    if (aText) {
+      if (aTextSize > 0 && aTextSize < strlen(aText)) {
+        string buffer(aText, aTextSize);
+        DLT_LOG(DbgDefaultContext, DLT_LOG_INFO, DLT_STRING(buffer.c_str()));
+      } else {
+        DLT_LOG(DbgDefaultContext, DLT_LOG_INFO, DLT_STRING(aText));
+      }
+    }
+    return;
+  }
+#endif // USE_DLT
+
   if (!aText || (!fDbgOutP && !fOutputLoggerP)) return;
   if (*aText) {
     // not an empty line
   if (!aText || (!fDbgOutP && !fOutputLoggerP)) return;
   if (*aText) {
     // not an empty line
index a583365..3cc234e 100755 (executable)
@@ -30,6 +30,9 @@ typedef enum {
   dbgfmt_text,        ///< plain text format (but can be indented)
   dbgfmt_xml,         ///< XML format
   dbgfmt_html,        ///< HTML format
   dbgfmt_text,        ///< plain text format (but can be indented)
   dbgfmt_xml,         ///< XML format
   dbgfmt_html,        ///< HTML format
+#ifdef USE_DLT
+  dbgfmt_dlt,         ///< GENIVI Diagnostic Log and Trace
+#endif
   numDbgOutFormats
 } TDbgOutFormats;
 
   numDbgOutFormats
 } TDbgOutFormats;