summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt7
-rw-r--r--automotive-dlt-c++.pc.in9
-rw-r--r--automotive-dlt.spec.in19
-rw-r--r--include/dlt/CMakeLists.txt7
-rw-r--r--include/dlt/dlt_cpp_extension.hpp238
-rw-r--r--tests/CMakeLists.txt5
-rw-r--r--tests/dlt-test-cpp-extension.cpp118
7 files changed, 401 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a036676..8497dc5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,6 +68,7 @@ option(WITH_DLT_EXAMPLES "Set to ON to build src/examples binaries"
option(WITH_DLT_SYSTEM "Set to ON to build src/system binaries" ON)
option(WITH_DLT_DBUS "Set to ON to build src/dbus binaries" ON)
option(WITH_DLT_TESTS "Set to ON to build src/test binaries" ON)
+option(WITH_DLT_CXX11_EXT "Set to ON to build C++11 extensions" ON)
# RPM settings
set( GENIVI_RPM_RELEASE "1")#${DLT_REVISION}")
set( LICENSE "Mozilla Public License Version 2.0" )
@@ -120,6 +121,11 @@ configure_file(${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.spec.in ${PROJECT_BINARY_DIR}
configure_file(${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.pc.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT devel)
+if(${WITH_DLT_CXX11_EXT})
+ configure_file(${CMAKE_SOURCE_DIR}/${PROJECT_NAME}-c++.pc.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-c++.pc @ONLY)
+ install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-c++.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT devel)
+endif()
+
IF(${CMAKE_INSTALL_PREFIX} STREQUAL "/usr")
set(CONFIGURATION_FILES_DIR "/etc")
ELSE()
@@ -172,6 +178,7 @@ message( STATUS "WITH_DLT_DBUS = ${WITH_DLT_DBUS}")
message( STATUS "WITH_DLT_TESTS = ${WITH_DLT_TESTS}")
message( STATUS "WITH_DLT_SHM_ENABLE = ${WITH_DLT_SHM_ENABLE}" )
message( STATUS "WITH_DLTTEST = ${WITH_DLTTEST}" )
+message( STATUS "WITH_DLT_CXX11_EXT = ${WITH_DLT_CXX11_EXT}" )
message( STATUS "WITH_CHECK_CONFIG_FILE = ${WITH_CHECK_CONFIG_FILE}" )
message( STATUS "WITH_TESTSCRIPTS = ${WITH_TESTSCRIPTS}" )
message( STATUS "WITH_GPROF = ${WITH_GPROF}" )
diff --git a/automotive-dlt-c++.pc.in b/automotive-dlt-c++.pc.in
new file mode 100644
index 0000000..3e950ae
--- /dev/null
+++ b/automotive-dlt-c++.pc.in
@@ -0,0 +1,9 @@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+includedir=${exec_prefix}/include
+
+Name: DLT C++
+Description: Diagnostic Log and Trace C++ extensions
+Version: @DLTCPP_VERSION@
+Requires: automotive-dlt
+Cflags: -std=c++11
+
diff --git a/automotive-dlt.spec.in b/automotive-dlt.spec.in
index eeb7221..ec5fe53 100644
--- a/automotive-dlt.spec.in
+++ b/automotive-dlt.spec.in
@@ -24,7 +24,8 @@ Vendor: BMW Group AG
License: @LICENSE@
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
-Requires: %{name} = %{version}-%{release}, pkgconfig
+BuildRequires: pkg-configure
+BuildRequires: cmake
%description
This component provides a standardised log and trace interface, based on the
@@ -50,11 +51,21 @@ This component provides the documentation for %{name}.
%package devel
Summary: %{name} - Diagnostic Log and Trace: Development files
Group: Development/Libraries
-Requires: %{name} = %{version}-%{release}, pkgconfig
+Requires: %{name} = %{version}-%{release}
+Provides: pkgconfig(%{name})
%description devel
This component provides the development libraries and includes for %{name}.
+%package c++-devel
+Summary: %{name} - Diagnostic Log and Trace: Development files
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}-devel
+Provides: pkgconfig(%{name}-c++)
+
+%description c++devel
+This component adds a C++ extension for %{name}.
+
%prep
%setup -q
@@ -135,3 +146,7 @@ rm -rf $RPM_BUILD_ROOT
%files devel
%{_includedir}/dlt/*.h
%{_libdir}/pkgconfig/@PROJECT_NAME@.pc
+
+%files c++-devel
+%{_includedir}/dlt/*.hpp
+%{_libdir}/pkgconfig/@PROJECT_NAME@-c++.pc
diff --git a/include/dlt/CMakeLists.txt b/include/dlt/CMakeLists.txt
index a137206..057af1f 100644
--- a/include/dlt/CMakeLists.txt
+++ b/include/dlt/CMakeLists.txt
@@ -18,3 +18,10 @@
install(FILES dlt.h dlt_user.h dlt_user_macros.h dlt_client.h dlt_protocol.h dlt_common.h dlt_types.h dlt_version.h dlt_shm.h dlt_offline_trace.h dlt_filetransfer.h dlt_common_api.h
DESTINATION include/dlt
COMPONENT devel)
+
+
+if(${WITH_DLT_CXX11_EXT})
+ install(FILES dlt_cpp_extension.hpp
+ DESTINATION include/dlt
+ COMPONENT devel)
+endif() \ No newline at end of file
diff --git a/include/dlt/dlt_cpp_extension.hpp b/include/dlt/dlt_cpp_extension.hpp
new file mode 100644
index 0000000..8949658
--- /dev/null
+++ b/include/dlt/dlt_cpp_extension.hpp
@@ -0,0 +1,238 @@
+/**
+ * @licence app begin@
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_cpp_extension.hpp
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+
+#ifndef DLT_CPP_EXTENSION_HPP
+#define DLT_CPP_EXTENSION_HPP
+
+#include <dlt/dlt.h>
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+
+
+template<typename T>
+int32_t logToDlt(DltContextData &log, T const &value) = delete;
+
+
+template<>
+inline int32_t logToDlt(DltContextData &log, int8_t const &value)
+{
+ return dlt_user_log_write_int8(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, int16_t const &value)
+{
+ return dlt_user_log_write_int16(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, int32_t const &value)
+{
+ return dlt_user_log_write_int32(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, int64_t const &value)
+{
+ return dlt_user_log_write_int64(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, uint8_t const &value)
+{
+ return dlt_user_log_write_uint8(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, uint16_t const &value)
+{
+ return dlt_user_log_write_uint16(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, uint32_t const &value)
+{
+ return dlt_user_log_write_uint32(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, uint64_t const &value)
+{
+ return dlt_user_log_write_uint64(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, float32_t const &value)
+{
+ return dlt_user_log_write_float32(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, double const &value)
+{
+ return dlt_user_log_write_float64(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, bool const &value)
+{
+ return dlt_user_log_write_bool(&log, value);
+}
+
+static inline int32_t logToDlt(DltContextData &log, char const * const value)
+{
+ return dlt_user_log_write_utf8_string(&log, value);
+}
+
+static inline int32_t logToDlt(DltContextData &log, char * const value)
+{
+ return dlt_user_log_write_utf8_string(&log, value);
+}
+
+template<>
+inline int32_t logToDlt(DltContextData &log, std::string const &value)
+{
+ return dlt_user_log_write_utf8_string(&log, value.c_str());
+}
+
+
+/* stl types */
+template<>
+int32_t logToDlt(DltContextData &log, std::string const &value);
+
+template<typename _Tp, typename _Alloc = std::allocator<_Tp>>
+static inline int32_t logToDlt(DltContextData &log, std::vector<_Tp, _Alloc > const & value)
+{
+ int result = 0;
+
+ for (auto elem: value)
+ {
+ result += logToDlt(log, elem);
+ }
+
+ if (result != 0)
+ {
+ result = -1;
+ }
+ return result;
+}
+
+template<typename _Tp, typename _Alloc = std::allocator<_Tp>>
+static inline int32_t logToDlt(DltContextData &log, std::list<_Tp, _Alloc > const & value)
+{
+ int result = 0;
+
+ for (auto elem: value)
+ {
+ result += logToDlt(log, elem);
+ }
+
+ if (result != 0)
+ {
+ result = -1;
+ }
+ return result;
+}
+
+template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
+ typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >>
+static inline int32_t logToDlt(DltContextData &log, std::map<_Key, _Tp, _Compare, _Alloc > const & value)
+{
+ int result = 0;
+
+ for (auto elem: value)
+ {
+ result += logToDlt(log, elem.first);
+ result += logToDlt(log, elem.second);
+ }
+
+ if (result != 0)
+ {
+ result = -1;
+ }
+ return result;
+}
+
+
+//variadic functions using C11 standard
+template<typename First>
+static inline int32_t logToDltVariadic(DltContextData &log, First const &valueA)
+{
+ return logToDlt(log, valueA);
+}
+
+template<typename First, typename... Rest>
+static inline int32_t logToDltVariadic(DltContextData &log, First const &valueA, const Rest&... valueB)
+{
+ int result = logToDlt(log, valueA) + logToDltVariadic(log, valueB...);
+ if ( result != 0 )
+ {
+ result = -1;
+ }
+ return result;
+}
+
+
+/**
+ * @brief macro to write a log message with variable number of arguments and without the need to specify the type of log data
+ *
+ * The macro can be used with any type that provides a logToDlt function.
+ *
+ * Example:
+ * DLT_LOG_CXX(dltContext, DLT_LV_X, "text", valueA, valueB, ...)
+ */
+#define DLT_LOG_CXX(CONTEXT, LOGLEVEL, ...)\
+ do{ \
+ DltContextData log; \
+ if (dlt_user_log_write_start(&CONTEXT,&log,LOGLEVEL)>0) \
+ { \
+ logToDltVariadic(log, ##__VA_ARGS__); \
+ dlt_user_log_write_finish(&log); \
+ } \
+ } while(0)
+
+/**
+ * @brief macro to write a log message with variable number of arguments and without the need to specify the type of log data.
+ *
+ * The macro can be used with any type that provides a logToDlt function.
+ * This includes all the types that are code generated.
+ *
+ * This macro is similar to \c DLT_LOG_CXX. However, it adds the current function name as the first log argument.
+ *
+ * Example:
+ * DLT_LOG_FCN_CXX(dltContext, DLT_LV_X, "text", valueA, valueB, ...)
+ */
+#define DLT_LOG_FCN_CXX(CONTEXT, LOGLEVEL, ...) \
+ do { \
+ DltContextData log; \
+ if (dlt_user_log_write_start(&CONTEXT, &log, LOGLEVEL) > 0) \
+ { \
+ dlt_user_log_write_string(&log, __PRETTY_FUNCTION__); \
+ logToDltVariadic(log, ##__VA_ARGS__); \
+ dlt_user_log_write_finish(&log); \
+ } \
+ } while(0)
+
+
+#endif /* DLT_CPP_EXTENSION_HPP */
+
+
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 6cc1006..5ce6945 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -21,3 +21,8 @@ target_link_libraries(dlt_test_receiver dlt)
target_link_libraries(dlt_env_ll_unit_test gtest gtest_main dlt)
target_link_libraries(dlt-test-preregister-context gtest gtest_main dlt)
+if(${WITH_DLT_CXX11_EXT})
+ add_executable(dlt-test-cpp-extension dlt-test-cpp-extension.cpp)
+ set_target_properties(dlt-test-cpp-extension PROPERTIES COMPILE_FLAGS "-std=c++11")
+ target_link_libraries(dlt-test-cpp-extension gtest gtest_main dlt)
+endif() \ No newline at end of file
diff --git a/tests/dlt-test-cpp-extension.cpp b/tests/dlt-test-cpp-extension.cpp
new file mode 100644
index 0000000..ce9f1db
--- /dev/null
+++ b/tests/dlt-test-cpp-extension.cpp
@@ -0,0 +1,118 @@
+/**
+ * @licence app begin@
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt-test-cpp-extension.cpp
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+#include "dlt_cpp_extension.hpp"
+#include <stdio.h>
+#include <string.h>
+
+
+struct MyStruct
+{
+ int64_t uuid;
+ int32_t interfaceId;
+ int32_t registrationState;
+};
+
+
+template<>
+inline int logToDlt(DltContextData & log, MyStruct const & value)
+{
+ int result = 0;
+
+ result += dlt_user_log_write_string(&log, "(");
+ result += logToDlt(log, value.uuid);
+ result += dlt_user_log_write_string(&log, ",");
+ result += logToDlt(log, value.interfaceId);
+ result += dlt_user_log_write_string(&log, ",");
+ result += logToDlt(log, value.registrationState);
+ result += dlt_user_log_write_string(&log, ")");
+
+ if (result != 0)
+ {
+ result = -1;
+ }
+
+ return result;
+}
+
+
+/**
+ * Sample code to show usage of the cpp-extension
+ * mainly the variadic templates
+ */
+int main()
+{
+ if (dlt_register_app("TCPP", "Test cpp extension") < 0)
+ {
+ printf("Failed to register application\n");
+ return -1;
+ }
+
+ DltContext ctx;
+ if (dlt_register_context_ll_ts(&ctx, "TCPP", "Test cpp extension", DLT_LOG_INFO, DLT_TRACE_STATUS_OFF) < 0)
+ {
+ printf("Failed to register context\n");
+ return -1;
+ }
+
+ dlt_enable_local_print();
+ dlt_verbose_mode();
+
+ DLT_LOG(ctx, DLT_LOG_WARN, DLT_STRING("a message")); /* the classic way to go */
+
+ int an_int = 42;
+ float a_float = 22.7;
+ DLT_LOG_FCN_CXX(ctx, DLT_LOG_WARN, "Testing DLT_LOG_CXX_FCN", an_int, a_float);
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, 1.0, 65);
+
+ /* Example for logging user-defined types */
+ MyStruct myData = { 1u, 2u, 3u};
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, "MyStruct myData", myData);
+
+ char * non_const_string = (char *)malloc(17);
+ memcpy(non_const_string, "non_const_string", 16);
+ non_const_string[16] = 0;
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, "char *", non_const_string);
+
+ std::string aString = "std::string";
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, "std::string", aString);
+
+ std::vector<int> intVector;
+ intVector.push_back(0);
+ intVector.push_back(1);
+ intVector.push_back(2);
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, "vector", intVector);
+
+ std::vector<double> doubleList;
+ doubleList.push_back(10.);
+ doubleList.push_back(11.);
+ doubleList.push_back(12.);
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, "list", doubleList);
+
+ std::map<const char *, int> testMap;
+ testMap["apple"] = 100;
+ testMap["plum"] = 200;
+ testMap["orange"] = 300;
+ DLT_LOG_CXX(ctx, DLT_LOG_WARN, "map", testMap);
+
+ dlt_unregister_context(&ctx);
+ dlt_unregister_app();
+
+ return 0;
+}