# 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
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
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
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:
# (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:
- 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"; \
# 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
+ 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:
@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.
# (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
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/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 \
@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 \
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 \
@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 \
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@
-EBOOKCONTACTS_CFLAGS = @EBOOKCONTACTS_CFLAGS@
-EBOOKCONTACTS_LIBS = @EBOOKCONTACTS_LIBS@
EBOOK_CFLAGS = @EBOOK_CFLAGS@
EBOOK_LIBS = @EBOOK_LIBS@
EBOOK_VERSION_CFLAGS = @EBOOK_VERSION_CFLAGS@
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@
@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@ @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_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@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_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 \
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
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/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)
-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/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)
@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/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__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
@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
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-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 \
@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@ @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.
@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_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)
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:
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"; \
# 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
+ 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:
+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
-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
------------------------------------------------
: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
/* "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
/* "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
#! /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.
# 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=''
KEYRING_CFLAGS
FILE_LIBS
FILE_CFLAGS
-EBOOKCONTACTS_LIBS
-EBOOKCONTACTS_CFLAGS
EDS_VERSION_LIBS
EDS_VERSION_CFLAGS
ENABLE_ECAL_FALSE
DBUS_CFLAGS
COND_GIO_GDBUS_FALSE
COND_GIO_GDBUS_TRUE
+SYNCEVO_DBUS_SERVER_ARGS
COND_DBUS_FALSE
COND_DBUS_TRUE
COND_CORE_FALSE
ENABLE_BLUETOOTH_TRUE
ENABLE_OBEX_FALSE
ENABLE_OBEX_TRUE
+DLT_LIBS
+DLT_CFLAGS
BLUEZ_LIBS
BLUEZ_CFLAGS
LIBOPENOBEX_LIBS
with_ca_certificates
enable_libcurl
enable_libsoup
+enable_dlt
+with_dlt_syncevolution
enable_bluetooth
enable_ssl_certificate_check
enable_gtk
LIBOPENOBEX_LIBS
BLUEZ_CFLAGS
BLUEZ_LIBS
+DLT_CFLAGS
+DLT_LIBS
DBUS_CFLAGS
DBUS_LIBS
LIBNOTIFY_CFLAGS
EBOOK_VERSION_LIBS
EDS_VERSION_CFLAGS
EDS_VERSION_LIBS
-EBOOKCONTACTS_CFLAGS
-EBOOKCONTACTS_LIBS
KEYRING_CFLAGS
KEYRING_LIBS
KCALEXTENDED_CFLAGS
# 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]...
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
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
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
- 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
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]
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
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
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.
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 $@
+
+
+
+
# Minimum version of libsynthesis as defined in its
# configure script and thus .pc files:
# 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
-test "x$CPPUNIT_CONFIG" != 'xno' || as_fn_error $? "\"cppunit-config not found.\"" "$LINENO" 5
-
# 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`
-#fi
+fi
# 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 :
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_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.
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
_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; }
fi
-elif test "$enable_dbus_service" = "yes"; then
+elif test "$enable_dbus_service" != "no"; then
# syncevo-dbus-server needs localization
:
else
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
- 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
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
- 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
_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
- 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
- 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
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
- 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
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
- 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
_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
- 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
- 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; }
- 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
{ $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_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 :
# 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
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\\"
# 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".
# 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?
-#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`
-#fi
+fi
AC_SUBST(CPPUNIT_CXXFLAGS)
AC_SUBST(CPPUNIT_LDFLAGS)
# 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],
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])
-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_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
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])
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
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
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);
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");
}
# 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],
--- /dev/null
+/*
+ * 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 = ¤t;
+ }
+ 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
--- /dev/null
+/*
+ * 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
#include <syncevo/SuspendFlags.h>
#include <syncevo/LogRedirect.h>
#include <syncevo/LogSyslog.h>
+#include <syncevo/LogDLT.h>
#include <syncevo/GLibSupport.h>
+#ifdef USE_DLT
+# include <dlt.h>
+#endif
+
using namespace SyncEvo;
using namespace GDBusCXX;
int logLevelDBus = 2;
gboolean stdoutEnabled = false;
gboolean syslogEnabled = true;
+#ifdef USE_DLT
+ gboolean dltEnabled = false;
+#endif
#ifdef ENABLE_DBUS_PIM
gboolean startPIM = false;
#endif
"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.",
// 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));
[D-BUS Service]
Name=org.syncevolution
-Exec=@libexecdir@/syncevo-dbus-server
+Exec=@libexecdir@/syncevo-dbus-server @SYNCEVO_DBUS_SERVER_ARGS@
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
+ '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
return compare;
}
-void IndividualData::init(const IndividualCompare *compare,
+bool IndividualData::init(const IndividualCompare *compare,
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) {
- 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
}
}
+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) {
* 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);
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.
#include <syncevo/BoostHelper.h>
+#include <boost/dynamic_bitset.hpp>
+
#include <syncevo/declarations.h>
SE_BEGIN_CXX
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())
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,
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));
for (size_t index = 0; index < m_entries.size(); index++) {
IndividualData &previous = *old[index],
¤t = 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
{
FolksIndividualAggregatorCXX m_folks;
boost::shared_ptr<LocaleFactory> m_locale;
+ bool m_localeChanged;
bool m_isQuiescent;
boost::weak_ptr<FullView> m_self;
Timeout m_waitForIdle;
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,
#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/locid.h>
SE_GLIB_TYPE(EBookQuery, e_book_query)
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));
{
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,
- Mode mode) :
+ int mode) :
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)
{
+ 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) {
- case CASE_SENSITIVE:
- // Search directly, no preprocessing.
+ case EXACT:
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());
}
/**
+ * 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,
return false;
}
switch (m_mode) {
- case CASE_SENSITIVE:
+ case EXACT:
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;
}
}
return false;
}
switch (m_mode) {
- case CASE_SENSITIVE:
+ case EXACT:
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;
}
}
return false;
}
switch (m_mode) {
- case CASE_SENSITIVE:
+ case EXACT:
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;
}
}
return false;
}
switch (m_mode) {
- case CASE_SENSITIVE:
+ case EXACT:
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;
}
}
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;
- Mode m_mode;
+ int m_mode;
// 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;
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)
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)
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)
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)
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)
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)
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)
{
}
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)
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
/**
- * 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
{
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
{
- 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;
}
}
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,
- 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
// 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,
- m_tel.c_str()),
+ tel.c_str()),
TRANSFER_REF);
PlainGStr filter(e_book_query_to_string(query.get()));
return filter.get();
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
}
};
-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;
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)))
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") {
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) {
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);
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
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.
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;
}
};
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 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
*/
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.
*/
- virtual void precompute(FolksIndividual *individual, Precomputed &precomputed) const = 0;
+ virtual bool precompute(FolksIndividual *individual, Precomputed &precomputed) const = 0;
};
SE_END_CXX
#include "../resource.h"
#include "../client.h"
#include "../session.h"
+#include "../localed-listener.h"
#include <syncevo/IniConfigNode.h>
#include <syncevo/BoostHelper.h>
m_mainThread(g_thread_self()),
m_server(server),
m_locale(LocaleFactory::createFactory()),
+ m_localedListener(LocaledListener::create()),
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()
"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()) {
}
}
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");
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<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) {}
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) :
m_view(view),
m_locale(locale),
m_owner(owner),
+ m_filter(filter),
// use ViewAgent interface
m_quiescent(m_viewAgent, "Quiescent"),
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)
boost::shared_ptr<ViewResource> viewResource(new ViewResource(view,
locale,
owner,
+ filter,
connection,
ID,
agentPath));
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);
}
+
+ /**
+ * 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;
boost::shared_ptr<ViewResource> viewResource(ViewResource::create(view,
m_locale,
client,
+ filter,
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());
}
// 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();
#include <syncevo/declarations.h>
SE_BEGIN_CXX
+class LocaledListener;
+
/**
* Implementation of org._01.pim.contacts.Manager.
*/
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;
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() */
[D-BUS Service]
Name=org._01.pim.contacts
-Exec=@libexecdir@/syncevo-dbus-server
+Exec=@libexecdir@/syncevo-dbus-server @SYNCEVO_DBUS_SERVER_ARGS@
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:
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.
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().
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)
+ 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.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
+ addressbooks = []
uid = self.uidPrefix + 'foo2'
+ addressbooks.append('peer-' + uid)
peers[uid] = {'protocol': 'PBAP',
'address': 'xxx'}
self.manager.SetPeer(uid,
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'
+ addressbooks.append('peer-' + uid)
peers[uid] = {'protocol': 'PBAP',
'address': 'yyy'}
self.manager.SetPeer(uid,
self.assertEqual(expected, self.currentSources())
uid = self.uidPrefix + 'xyz'
+ addressbooks.append('peer-' + uid)
peers[uid] = {'protocol': 'PBAP',
'address': 'zzz'}
self.manager.SetPeer(uid,
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)
# 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.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+ 'sort =\n'],
+ self.readManagerIni())
# EDS workaround
time.sleep(2)
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.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+ 'sort =\n'],
+ self.readManagerIni())
# EDS workaround
time.sleep(2)
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.assertEqual(['active = ' + ' '.join([x.replace('peer-', 'pim-manager-') for x in addressbooks]) + '\n',
+ 'sort =\n'],
+ self.readManagerIni())
# 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):
# 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',
# 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):
# 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)
- 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)
- 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)
- 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'])
self.setUpView()
msg = None
+ view = None
try:
# Insert new contacts and calculate their family names.
names = []
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")
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')),
),
)
(),
)
+ @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)
#include "read-operations.h"
-#include <boost/signals.hpp>
+#include <boost/signals2.hpp>
SE_BEGIN_CXX
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_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
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_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 += \
*/
class SessionHelperLogger : public Logger
{
- boost::shared_ptr<LogRedirect> m_parentLogger;
+ Handle m_parentLogger;
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)
{
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,
}
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 &&
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,
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"),
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);
#include <syncevo/SyncContext.h>
#include <syncevo/BoostHelper.h>
+#ifdef USE_DLT
+#include <syncevo/LogDLT.h>
+#endif
+
#include <memory>
#include <boost/foreach.hpp>
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
// 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());
}
}
#include <syncevo/SuspendFlags.h>
#include <syncevo/SyncContext.h>
#include <syncevo/LogRedirect.h>
+#include <syncevo/LogDLT.h>
using namespace SyncEvo;
using namespace GDBusCXX;
}
void onConnect(const DBusConnectionPtr &conn,
- const boost::shared_ptr<LogRedirect> &parentLogger,
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));
}
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);
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)));
#! /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
#include <config.h>
-#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
-
-#include <boost/bind.hpp>
-
#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
-#endif // HAVE_EDS && USE_EDS_CLIENT
#include <config.h>
+#include <boost/shared_ptr.hpp>
+
#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
#include <syncevo/GLibSupport.h>
#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;
SE_GOBJECT_TYPE(ESource)
SE_GOBJECT_TYPE(EClient)
+#endif // HAVE_EDS && USE_EDS_CLIENT
+
#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.
* 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.
*/
- static ESourceRegistryCXX getESourceRegistry();
+ static ESourceRegistryCXX getESourceRegistry()
+ {
+ return EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).sync();
+ }
private:
Bool m_loading;
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
-#endif // HAVE_EDS && USE_EDS_CLIENT
#endif // INCL_SYNCEVO_EDS_CLIENT
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
#include <syncevo/DBusTraits.h>
#include <syncevo/SuspendFlags.h>
#include <syncevo/LogRedirect.h>
+#include <syncevo/LogDLT.h>
#include <syncevo/BoostHelper.h>
#include <synthesis/syerror.h>
}
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));
{
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());
}
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();
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
// 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()
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
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_processName(NULL)
+ m_processName(NULL),
+ m_flags(flags)
{
}
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,
- const char *function);
+ const char *function,
+ int flags = 0);
};
/**
#include <synthesis/SDK_util.h>
#include <synthesis/san.h>
+#ifdef USE_DLT
+# include <dlt.h>
+#endif
+
#include "test.h"
#include <syncevo/declarations.h>
{
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);
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
{
}
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()) {
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.
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"
- " <filename>" <<
- LogfileBasename << "</filename>" <<
+ " <filename>" << (useDLT ? "" : LogfileBasename) << "</filename>" <<
" <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";
- 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";
}
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) {
- void *dlhandle;
if (isDir (dirpath + '/' + entry)) {
/* This is a 2-level dir, this corresponds to loading
* backends from current building directory. The library
}
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);
- // 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()){
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 // EVOLUTION_COMPATIBILITY
-
int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
int EDSAbiHaveIcal;
int SyncEvoHaveLibbluetooth;
initialized = true;
}
-#ifdef EVOLUTION_COMPATIBILITY
# ifdef HAVE_EDS
edshandle =
findSymbols("libedataserver-1.2.so", 7, 16,
}
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" {
#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;
/** 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
#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
# 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();
\
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 \
$(TRANSPORT_LIBS) \
@LIBS@ \
$(src_syncevo_ldadd) \
+ $(DLT_LIBS) \
$(DBUS_LIBS) \
$(NSS_LIBS)
if ENABLE_MODULES
$(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)"\"
-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
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@
-EBOOKCONTACTS_CFLAGS = @EBOOKCONTACTS_CFLAGS@
-EBOOKCONTACTS_LIBS = @EBOOKCONTACTS_LIBS@
EBOOK_CFLAGS = @EBOOK_CFLAGS@
EBOOK_LIBS = @EBOOK_LIBS@
EBOOK_VERSION_CFLAGS = @EBOOK_VERSION_CFLAGS@
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@
# 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>
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:
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLT_CFLAGS = @DLT_CFLAGS@
+DLT_LIBS = @DLT_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
--- /dev/null
+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.
/* 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
LIBECAL_CFLAGS
LIBICAL_LIBS
LIBICAL_CFLAGS
+DLT_LIBS
+DLT_CFLAGS
PCRE_LIBS
PCRE_CFLAGS
SQLITE3_LIBS
enable_debug_logs
enable_sqlite
enable_regex
+enable_dlt
enable_libical
enable_evolution_compatibility
with_xmltok
SQLITE3_LIBS
PCRE_CFLAGS
PCRE_LIBS
+DLT_CFLAGS
+DLT_LIBS
LIBICAL_CFLAGS
LIBICAL_LIBS
LIBECAL_CFLAGS
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
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
# Define the identity of the package.
PACKAGE=synthesis
- VERSION=3.4.0.16.10
+ VERSION=3.4.0.16.11
cat >>confdefs.h <<_ACEOF
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 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 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"
;;
*-*-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=$?
-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
- 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.
-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
- 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.
-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
- 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
-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
- 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
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
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
-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
- 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.
-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
- 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
-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
- 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
_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_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
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")
-I$(srcdir)/DB_interfaces/api_db/ \
-I$(srcdir)/sysync_SDK/Sources/ \
$(PCRE_CFLAGS) \
+ $(DLT_CFLAGS) \
$(SQLITE3_CFLAGS) \
$(ZLIB_CFLAGS) \
$(XMLPARSE_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
-I$(srcdir)/DB_interfaces/api_db/ \
-I$(srcdir)/sysync_SDK/Sources/ \
$(PCRE_CFLAGS) \
+ $(DLT_CFLAGS) \
$(SQLITE3_CFLAGS) \
$(ZLIB_CFLAGS) \
$(XMLPARSE_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
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLT_CFLAGS = @DLT_CFLAGS@
+DLT_LIBS = @DLT_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
-I$(srcdir)/DB_interfaces/api_db/ \
-I$(srcdir)/sysync_SDK/Sources/ \
$(PCRE_CFLAGS) \
+ $(DLT_CFLAGS) \
$(SQLITE3_CFLAGS) \
$(ZLIB_CFLAGS) \
$(XMLPARSE_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
bool getLocalDeviceID(string &aURI)
{
char szHostname[100];
- struct hostent *pHostEnt=NULL;
string hostName;
// get name of own machine
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
+#endif
hostName=szHostname; // just name of machine
}
// generate URI from name
#include "platform_thread.h"
#endif
+#ifdef USE_DLT
+#include <dlt.h>
+#endif
+
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
"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
};
#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)
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;
}
} // 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) {
+#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();
// 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
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;