Kaynağa Gözat

Fixes Lint converstion

Signed-off-by: Martin Melik Merkumians <melik-merkumians@acin.tuwien.ac.at>
Martin Melik Merkumians 5 yıl önce
ebeveyn
işleme
5c866fa3c8

+ 4 - 3
source/CMakeLists.txt

@@ -31,7 +31,7 @@ configure_file(
 	)
 
 find_path( OpENer_BUILDSUPPORT_DIR OpENer.cmake ${PROJECT_SOURCE_DIR}/buildsupport )
- 
+
 INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/OpENer.cmake )
 
 option(OPENER_PRODUCED_DATA_HAS_RUN_IDLE_HEADER "Shall produced data from OpENer also include a run idle header?" FALSE)
@@ -139,8 +139,9 @@ if( OpENer_TESTS )
   set( CPPUTEST_HOME "" CACHE PATH "Path to CppUTest directory" )
   INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/OpENer_Tests.cmake )
   INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/CodeCoverage.cmake )
-  set(COVERAGE_LCOV_EXCLUDES 'tests/*' 'usr/*' 'ports/POSIX/sample_application/*')
-  SETUP_TARGET_FOR_COVERAGE_LCOV(NAME ${PROJECT_NAME}_coverage EXECUTABLE OpENer_Tests DEPENDENCIES OpENer_Tests)
+  APPEND_COVERAGE_COMPILER_FLAGS()
+  # The used CppUTest framework does not support parallel jobs
+  SETUP_TARGET_FOR_COVERAGE_LCOV(NAME ${PROJECT_NAME}_coverage EXECUTABLE OpENer_Tests EXCLUDE "tests/*" "src/ports/*/sample_application/*")
   add_test_includes()
   add_subdirectory( tests )
 endif( OpENer_TESTS )

+ 189 - 53
source/buildsupport/CodeCoverage.cmake

@@ -41,21 +41,71 @@
 # 2017-06-02, Lars Bilke
 # - Merged with modified version from github.com/ufz/ogs
 #
+# 2019-05-06, Anatolii Kurotych
+# - Remove unnecessary --coverage flag
 #
+# 2019-12-13, FeRD (Frank Dana)
+# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor
+#   of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments.
+# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY
+# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list
+# - Set lcov basedir with -b argument
+# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be
+#   overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().)
+# - Delete output dir, .info file on 'make clean'
+# - Remove Python detection, since version mismatches will break gcovr
+# - Minor cleanup (lowercase function names, update examples...)
+#
+# 2019-12-19, FeRD (Frank Dana)
+# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets
+#
+# 2020-01-19, Bob Apthorpe
+# - Added gfortran support
+#
+# 2020-02-17, FeRD (Frank Dana)
+# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters
+#   in EXCLUDEs, and remove manual escaping from gcovr targets
+#
+# 2020-05-04, Mihchael Davis
+#     - Add -fprofile-abs-path to make gcno files contain absolute paths
+#     - Fix BASE_DIRECTORY not working when defined
+#     - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines
 # USAGE:
 #
 # 1. Copy this file into your cmake modules path.
 #
-# 2. Add the following line to your CMakeLists.txt:
+# 2. Add the following line to your CMakeLists.txt (best inside an if-condition
+#    using a CMake option() to enable it just optionally):
 #      include(CodeCoverage)
 #
 # 3. Append necessary compiler flags:
-#      APPEND_COVERAGE_COMPILER_FLAGS()
+#      append_coverage_compiler_flags()
+#
+# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og
 #
 # 4. If you need to exclude additional directories from the report, specify them
-#    using the COVERAGE_LCOV_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE_LCOV.
+#    using full paths in the COVERAGE_EXCLUDES variable before calling
+#    setup_target_for_coverage_*().
 #    Example:
-#      set(COVERAGE_LCOV_EXCLUDES 'dir1/*' 'dir2/*')
+#      set(COVERAGE_EXCLUDES
+#          '${PROJECT_SOURCE_DIR}/src/dir1/*'
+#          '/path/to/my/src/dir2/*')
+#    Or, use the EXCLUDE argument to setup_target_for_coverage_*().
+#    Example:
+#      setup_target_for_coverage_lcov(
+#          NAME coverage
+#          EXECUTABLE testrunner
+#          EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*")
+#
+# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set
+#     relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR)
+#     Example:
+#       set(COVERAGE_EXCLUDES "dir1/*")
+#       setup_target_for_coverage_gcovr_html(
+#           NAME coverage
+#           EXECUTABLE testrunner
+#           BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src"
+#           EXCLUDE "dir2/*")
 #
 # 5. Use the functions described below to create a custom make target which
 #    runs your test executable and produces a code coverage report.
@@ -73,7 +123,7 @@ find_program( GCOV_PATH gcov )
 find_program( LCOV_PATH  NAMES lcov lcov.bat lcov.exe lcov.perl)
 find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
 find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
-find_program( SIMPLE_PYTHON_EXECUTABLE python )
+find_program( CPPFILT_PATH NAMES c++filt )
 
 if(NOT GCOV_PATH)
     message(FATAL_ERROR "gcov not found! Aborting...")
@@ -84,12 +134,22 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
         message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
     endif()
 elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
-    message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+    if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "[Ff]lang")
+        # Do nothing; exit conditional without error if true
+    elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+        # Do nothing; exit conditional without error if true
+    else()
+        message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+    endif()
 endif()
 
-set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
+set(COVERAGE_COMPILER_FLAGS "-g -fprofile-arcs -ftest-coverage -fprofile-abs-path"
     CACHE INTERNAL "")
 
+set(CMAKE_Fortran_FLAGS_COVERAGE
+    ${COVERAGE_COMPILER_FLAGS}
+    CACHE STRING "Flags used by the Fortran compiler during coverage builds."
+    FORCE )
 set(CMAKE_CXX_FLAGS_COVERAGE
     ${COVERAGE_COMPILER_FLAGS}
     CACHE STRING "Flags used by the C++ compiler during coverage builds."
@@ -107,6 +167,7 @@ set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
     CACHE STRING "Flags used by the shared libraries linker during coverage builds."
     FORCE )
 mark_as_advanced(
+    CMAKE_Fortran_FLAGS_COVERAGE
     CMAKE_CXX_FLAGS_COVERAGE
     CMAKE_C_FLAGS_COVERAGE
     CMAKE_EXE_LINKER_FLAGS_COVERAGE
@@ -116,10 +177,8 @@ if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
     message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
 endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
 
-if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
     link_libraries(gcov)
-else()
-    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
 endif()
 
 # Defines a target for running and collection code coverage information
@@ -127,16 +186,22 @@ endif()
 # NOTE! The executable should always have a ZERO as exit code otherwise
 # the coverage generation will not complete.
 #
-# SETUP_TARGET_FOR_COVERAGE_LCOV(
+# setup_target_for_coverage_lcov(
 #     NAME testrunner_coverage                    # New target name
 #     EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
 #     DEPENDENCIES testrunner                     # Dependencies to build first
+#     BASE_DIRECTORY "../"                        # Base directory for report
+#                                                 #  (defaults to PROJECT_SOURCE_DIR)
+#     EXCLUDE "src/dir1/*" "src/dir2/*"           # Patterns to exclude (can be relative
+#                                                 #  to BASE_DIRECTORY, with CMake 3.4+)
+#     NO_DEMANGLE                                 # Don't demangle C++ symbols
+#                                                 #  even if c++filt is found
 # )
-function(SETUP_TARGET_FOR_COVERAGE_LCOV)
+function(setup_target_for_coverage_lcov)
 
-    set(options NONE)
-    set(oneValueArgs NAME)
-    set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
+    set(options NO_DEMANGLE)
+    set(oneValueArgs BASE_DIRECTORY NAME)
+    set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
     cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
     if(NOT LCOV_PATH)
@@ -147,27 +212,59 @@ function(SETUP_TARGET_FOR_COVERAGE_LCOV)
         message(FATAL_ERROR "genhtml not found! Aborting...")
     endif() # NOT GENHTML_PATH
 
+    # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
+    if(DEFINED Coverage_BASE_DIRECTORY)
+        get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
+    else()
+        set(BASEDIR ${PROJECT_SOURCE_DIR})
+    endif()
+
+    # Collect excludes (CMake 3.4+: Also compute absolute paths)
+    set(LCOV_EXCLUDES "")
+    foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_LCOV_EXCLUDES})
+        if(CMAKE_VERSION VERSION_GREATER 3.4)
+            get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
+        endif()
+        list(APPEND LCOV_EXCLUDES "${EXCLUDE}")
+    endforeach()
+    list(REMOVE_DUPLICATES LCOV_EXCLUDES)
+
+    # Conditional arguments
+    if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE})
+      set(GENHTML_EXTRA_ARGS "--demangle-cpp")
+    endif()
+
     # Setup target
     add_custom_target(${Coverage_NAME}
 
         # Cleanup lcov
-        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . --zerocounters
+        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . -b ${BASEDIR} --zerocounters
         # Create baseline to make sure untouched files show up in the report
-        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base
+        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -b ${BASEDIR} -o ${Coverage_NAME}.base
 
         # Run tests
         COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
 
         # Capturing lcov counters and generating report
-        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . --capture --output-file ${Coverage_NAME}.info
+        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . -b ${BASEDIR} --capture --output-file ${Coverage_NAME}.capture
         # add baseline counters
-        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.info --output-file ${Coverage_NAME}.total
-        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove ${Coverage_NAME}.total ${COVERAGE_LCOV_EXCLUDES} --output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
-        COMMAND ${GENHTML_PATH} ${Coverage_GENHTML_ARGS} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
-        COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
-
+        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.capture --output-file ${Coverage_NAME}.total
+        # filter collected data to final coverage report
+        COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove ${Coverage_NAME}.total ${LCOV_EXCLUDES} --output-file ${Coverage_NAME}.info
+
+        # Generate HTML output
+        COMMAND ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o ${Coverage_NAME} ${Coverage_NAME}.info
+
+        # Set output files as GENERATED (will be removed on 'make clean')
+        BYPRODUCTS
+            ${Coverage_NAME}.base
+            ${Coverage_NAME}.capture
+            ${Coverage_NAME}.total
+            ${Coverage_NAME}.info
+            ${Coverage_NAME}/index.html
         WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
         DEPENDS ${Coverage_DEPENDENCIES}
+        VERBATIM # Protect arguments to commands
         COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
     )
 
@@ -183,39 +280,56 @@ function(SETUP_TARGET_FOR_COVERAGE_LCOV)
         COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
     )
 
-endfunction() # SETUP_TARGET_FOR_COVERAGE_LCOV
+endfunction() # setup_target_for_coverage_lcov
 
 # Defines a target for running and collection code coverage information
 # Builds dependencies, runs the given executable and outputs reports.
 # NOTE! The executable should always have a ZERO as exit code otherwise
 # the coverage generation will not complete.
 #
-# SETUP_TARGET_FOR_COVERAGE_GCOVR_XML(
+# setup_target_for_coverage_gcovr_xml(
 #     NAME ctest_coverage                    # New target name
 #     EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
 #     DEPENDENCIES executable_target         # Dependencies to build first
+#     BASE_DIRECTORY "../"                   # Base directory for report
+#                                            #  (defaults to PROJECT_SOURCE_DIR)
+#     EXCLUDE "src/dir1/*" "src/dir2/*"      # Patterns to exclude (can be relative
+#                                            #  to BASE_DIRECTORY, with CMake 3.4+)
 # )
-function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
+function(setup_target_for_coverage_gcovr_xml)
 
     set(options NONE)
-    set(oneValueArgs NAME)
-    set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
+    set(oneValueArgs BASE_DIRECTORY NAME)
+    set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
     cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
-    if(NOT SIMPLE_PYTHON_EXECUTABLE)
-        message(FATAL_ERROR "python not found! Aborting...")
-    endif() # NOT SIMPLE_PYTHON_EXECUTABLE
-
     if(NOT GCOVR_PATH)
         message(FATAL_ERROR "gcovr not found! Aborting...")
     endif() # NOT GCOVR_PATH
 
-    # Combine excludes to several -e arguments
+    # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
+    if(DEFINED Coverage_BASE_DIRECTORY)
+        get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
+    else()
+        set(BASEDIR ${PROJECT_SOURCE_DIR})
+    endif()
+
+    # Collect excludes (CMake 3.4+: Also compute absolute paths)
     set(GCOVR_EXCLUDES "")
-    foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
-        list(APPEND GCOVR_EXCLUDES "-e")
+    foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
+        if(CMAKE_VERSION VERSION_GREATER 3.4)
+            get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
+        endif()
         list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
     endforeach()
+    list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
+
+    # Combine excludes to several -e arguments
+    set(GCOVR_EXCLUDE_ARGS "")
+    foreach(EXCLUDE ${GCOVR_EXCLUDES})
+        list(APPEND GCOVR_EXCLUDE_ARGS "-e")
+        list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
+    endforeach()
 
     add_custom_target(${Coverage_NAME}
         # Run tests
@@ -223,11 +337,13 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
 
         # Running gcovr
         COMMAND ${GCOVR_PATH} --xml
-            -r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
+            -r ${BASEDIR} ${GCOVR_EXCLUDE_ARGS}
             --object-directory=${PROJECT_BINARY_DIR}
             -o ${Coverage_NAME}.xml
+        BYPRODUCTS ${Coverage_NAME}.xml
         WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
         DEPENDS ${Coverage_DEPENDENCIES}
+        VERBATIM # Protect arguments to commands
         COMMENT "Running gcovr to produce Cobertura code coverage report."
     )
 
@@ -236,40 +352,56 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
         COMMAND ;
         COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml."
     )
-
-endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_XML
+endfunction() # setup_target_for_coverage_gcovr_xml
 
 # Defines a target for running and collection code coverage information
 # Builds dependencies, runs the given executable and outputs reports.
 # NOTE! The executable should always have a ZERO as exit code otherwise
 # the coverage generation will not complete.
 #
-# SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML(
+# setup_target_for_coverage_gcovr_html(
 #     NAME ctest_coverage                    # New target name
 #     EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
 #     DEPENDENCIES executable_target         # Dependencies to build first
+#     BASE_DIRECTORY "../"                   # Base directory for report
+#                                            #  (defaults to PROJECT_SOURCE_DIR)
+#     EXCLUDE "src/dir1/*" "src/dir2/*"      # Patterns to exclude (can be relative
+#                                            #  to BASE_DIRECTORY, with CMake 3.4+)
 # )
-function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
+function(setup_target_for_coverage_gcovr_html)
 
     set(options NONE)
-    set(oneValueArgs NAME)
-    set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
+    set(oneValueArgs BASE_DIRECTORY NAME)
+    set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
     cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
-    if(NOT SIMPLE_PYTHON_EXECUTABLE)
-        message(FATAL_ERROR "python not found! Aborting...")
-    endif() # NOT SIMPLE_PYTHON_EXECUTABLE
-
     if(NOT GCOVR_PATH)
         message(FATAL_ERROR "gcovr not found! Aborting...")
     endif() # NOT GCOVR_PATH
 
-    # Combine excludes to several -e arguments
+    # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
+    if(DEFINED Coverage_BASE_DIRECTORY)
+        get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
+    else()
+        set(BASEDIR ${PROJECT_SOURCE_DIR})
+    endif()
+
+    # Collect excludes (CMake 3.4+: Also compute absolute paths)
     set(GCOVR_EXCLUDES "")
-    foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
-        list(APPEND GCOVR_EXCLUDES "-e")
+    foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
+        if(CMAKE_VERSION VERSION_GREATER 3.4)
+            get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
+        endif()
         list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
     endforeach()
+    list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
+
+    # Combine excludes to several -e arguments
+    set(GCOVR_EXCLUDE_ARGS "")
+    foreach(EXCLUDE ${GCOVR_EXCLUDES})
+        list(APPEND GCOVR_EXCLUDE_ARGS "-e")
+        list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
+    endforeach()
 
     add_custom_target(${Coverage_NAME}
         # Run tests
@@ -280,11 +412,14 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
 
         # Running gcovr
         COMMAND ${GCOVR_PATH} --html --html-details
-            -r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
+            -r ${BASEDIR} ${GCOVR_EXCLUDE_ARGS}
             --object-directory=${PROJECT_BINARY_DIR}
             -o ${Coverage_NAME}/index.html
+
+        BYPRODUCTS ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html  # report directory
         WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
         DEPENDS ${Coverage_DEPENDENCIES}
+        VERBATIM # Protect arguments to commands
         COMMENT "Running gcovr to produce HTML code coverage report."
     )
 
@@ -294,10 +429,11 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
         COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
     )
 
-endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML
+endfunction() # setup_target_for_coverage_gcovr_html
 
-function(APPEND_COVERAGE_COMPILER_FLAGS)
+function(append_coverage_compiler_flags)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
+    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
     message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
-endfunction() # APPEND_COVERAGE_COMPILER_FLAGS
+endfunction() # append_coverage_compiler_flags

+ 22 - 22
source/src/cip/cipcommon.c

@@ -496,83 +496,83 @@ EipStatus GetAttributeSingle(CipInstance *RESTRICT const instance,
   return kEipStatusOkSend;
 }
 
-void EncodeCipBool(const void *const data,
+void EncodeCipBool(const CipBool *const data,
                    ENIPMessage *const outgoing_message) {
   AddSintToMessage(*(EipUint8 *) (data), outgoing_message);
 }
 
-void EncodeCipByte(const void *const data,
+void EncodeCipByte(const CipByte *const data,
                    ENIPMessage *const outgoing_message) {
   AddSintToMessage(*(EipUint8 *) (data), outgoing_message);
 }
 
-void EncodeCipWord(const void *const data,
+void EncodeCipWord(const CipWord *const data,
                    ENIPMessage *const outgoing_message) {
   AddIntToMessage(*(EipUint16 *) (data), outgoing_message);
 }
 
-void EncodeCipDword(const void *const data,
+void EncodeCipDword(const CipDword *const data,
                     ENIPMessage *const outgoing_message) {
   AddDintToMessage(*(EipUint32 *) (data), outgoing_message);
 }
 
-void EncodeCipLword(const void *const data,
+void EncodeCipLword(const CipLword *const data,
                     ENIPMessage *const outgoing_message) {
   AddLintToMessage(*(EipUint64 *) (data), outgoing_message);
 }
 
-void EncodeCipUsint(const void *const data,
+void EncodeCipUsint(const CipUsint *const data,
                     ENIPMessage *const outgoing_message) {
   AddSintToMessage(*(EipUint8 *) (data), outgoing_message);
 }
 
-void EncodeCipUint(const void *const data,
+void EncodeCipUint(const CipUint *const data,
                    ENIPMessage *const outgoing_message) {
   AddIntToMessage(*(EipUint16 *) (data), outgoing_message);
 }
 
-void EncodeCipUdint(const void *const data,
+void EncodeCipUdint(const CipUdint *const data,
                     ENIPMessage *const outgoing_message) {
   AddDintToMessage(*(EipUint32 *) (data), outgoing_message);
 }
 
-void EncodeCipUlint(const void *const data,
+void EncodeCipUlint(const CipUlint *const data,
                     ENIPMessage *const outgoing_message) {
   AddLintToMessage(*(EipUint64 *) (data), outgoing_message);
 }
 
-void EncodeCipSint(const void *const data,
+void EncodeCipSint(const CipSint *const data,
                    ENIPMessage *const outgoing_message) {
   AddSintToMessage(*(EipUint8 *) (data), outgoing_message);
 }
 
-void EncodeCipInt(const void *const data,
+void EncodeCipInt(const CipInt *const data,
                   ENIPMessage *const outgoing_message) {
   AddIntToMessage(*(EipUint16 *) (data), outgoing_message);
 }
 
-void EncodeCipDint(const void *const data,
+void EncodeCipDint(const CipDint *const data,
                    ENIPMessage *const outgoing_message) {
   AddDintToMessage(*(EipUint32 *) (data), outgoing_message);
 }
 
-void EncodeCipLint(const void *const data,
+void EncodeCipLint(const CipLint *const data,
                    ENIPMessage *const outgoing_message) {
   AddLintToMessage(*(EipUint64 *) (data), outgoing_message);
 }
 
-void EncodeCipReal(const void *const data,
+void EncodeCipReal(const CipReal *const data,
                    ENIPMessage *const outgoing_message) {
   AddDintToMessage(*(EipUint32 *) (data), outgoing_message);
 }
 
-void EncodeCipLreal(const void *const data,
+void EncodeCipLreal(const CipLreal *const data,
                     ENIPMessage *const outgoing_message) {
   AddLintToMessage(*(EipUint64 *) (data), outgoing_message);
 }
 
 
-void EncodeCipShortString(const void *const data,
+void EncodeCipShortString(const CipShortString *const data,
                           ENIPMessage *const outgoing_message) {
   CipShortString *const short_string = (CipShortString *) data;
 
@@ -585,7 +585,7 @@ void EncodeCipShortString(const void *const data,
   outgoing_message->used_message_length += short_string->length;
 }
 
-void EncodeCipString(const void *const data,
+void EncodeCipString(const CipString *const data,
                      ENIPMessage *const outgoing_message) {
   CipString *const string = (CipString *) data;
 
@@ -604,12 +604,12 @@ void EncodeCipString(const void *const data,
   }
 }
 
-void EncodeCipString2(const void *const data,
+void EncodeCipString2(const CipString2 *const data,
                       ENIPMessage *const outgoing_message) {
   OPENER_ASSERT(false); /* Not implemented yet */
 }
 
-void EncodeCipStringN(const void *const data,
+void EncodeCipStringN(const CipStringN *const data,
                       ENIPMessage *const outgoing_message) {
   OPENER_ASSERT(false); /* Not implemented yet */
 }
@@ -623,7 +623,7 @@ static void CipStringIHeaderEncoding(const CipStringIStruct *const string,
   EncodeCipUint(&(string->character_set), outgoing_message);
 }
 
-void EncodeCipStringI(const void *const data,
+void EncodeCipStringI(const CipStringI *const data,
                       ENIPMessage *const outgoing_message) {
   const CipStringI *const string_i = data;
   EncodeCipUsint(&(string_i->number_of_strings), outgoing_message);
@@ -648,7 +648,7 @@ void EncodeCipStringI(const void *const data,
   }
 }
 
-void EncodeCipByteArray(const void *const data,
+void EncodeCipByteArray(const CipByteArray *const data,
                         ENIPMessage *const outgoing_message) {
   OPENER_TRACE_INFO(" -> get attribute byte array\r\n");
   CipByteArray *cip_byte_array = (CipByteArray *) data;
@@ -659,7 +659,7 @@ void EncodeCipByteArray(const void *const data,
   outgoing_message->used_message_length += cip_byte_array->length;
 }
 
-void EncodeCipEPath(const void *const data,
+void EncodeCipEPath(const CipEpath *const data,
                     ENIPMessage *const outgoing_message) {
   EncodeEPath( (CipEpath *) data, outgoing_message );
 }

+ 2 - 1
source/src/cip/cipioconnection.c

@@ -92,7 +92,8 @@ EipUint16 ProcessProductionInhibitTime(CipConnectionObject *io_connection_object
                 io_connection_object)
               / 1000) ) {
         /* see section C-1.4.3.3 */
-        return kConnectionManagerExtendedStatusCodeRpiNotSupported; /**< RPI not supported. Extended Error code deprecated */
+        return
+          kConnectionManagerExtendedStatusCodeProductionInhibitTimerGreaterThanRpi;
       }
     }
   }

+ 9 - 1
source/src/cip/ciptypes.h

@@ -147,9 +147,17 @@ typedef struct {
  */
 typedef struct {
   EipUint16 length; /**< Length of the String (16 bit value) */
-  EipByte *string; /**< Pointer to the string data */
+  CipByte *string; /**< Pointer to the string data */
 } CipString;
 
+/** @brief CIP String2
+ *
+ */
+typedef struct {
+  EipUint16 length; /**< Length of the String (16 bit value) */
+  CipWord *string; /**< Pointer to the string data */
+} CipString2;
+
 /** @brief CIP String with variable symbol size
  *
  */

+ 8 - 14
source/src/enet_encap/endianconv.c

@@ -174,20 +174,14 @@ EipUint64 GetLintFromMessage(const EipUint8 **const buffer) {
 void AddLintToMessage(const EipUint64 data,
                       ENIPMessage *const outgoing_message) {
 
-  outgoing_message->current_message_position[0] = (EipUint8) (data >> 56) &
-                                                  0xFF;
-  outgoing_message->current_message_position[1] = (EipUint8) (data >> 48) &
-                                                  0xFF;
-  outgoing_message->current_message_position[2] = (EipUint8) (data >> 40) &
-                                                  0xFF;
-  outgoing_message->current_message_position[3] = (EipUint8) (data >> 32) &
-                                                  0xFF;
-  outgoing_message->current_message_position[4] = (EipUint8) (data >> 24) &
-                                                  0xFF;
-  outgoing_message->current_message_position[5] = (EipUint8) (data >> 16) &
-                                                  0xFF;
-  outgoing_message->current_message_position[6] = (EipUint8) (data >> 8) & 0xFF;
-  outgoing_message->current_message_position[7] = (EipUint8) (data) & 0xFF;
+  outgoing_message->current_message_position[0] = (EipUint8) (data);
+  outgoing_message->current_message_position[1] = (EipUint8) (data >> 8);
+  outgoing_message->current_message_position[2] = (EipUint8) (data >> 16);
+  outgoing_message->current_message_position[3] = (EipUint8) (data >> 24);
+  outgoing_message->current_message_position[4] = (EipUint8) (data >> 32);
+  outgoing_message->current_message_position[5] = (EipUint8) (data >> 40);
+  outgoing_message->current_message_position[6] = (EipUint8) (data >> 48);
+  outgoing_message->current_message_position[7] = (EipUint8) (data >> 56);
   outgoing_message->current_message_position += 8;
   outgoing_message->used_message_length += 8;
 }

+ 22 - 22
source/src/opener_api.h

@@ -311,70 +311,70 @@ void InsertGetSetCallback
  */
 
 
-void EncodeCipBool(const void *const data,
+void EncodeCipBool(const CipBool *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipByte(const void *const data,
+void EncodeCipByte(const CipByte *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipWord(const void *const data,
+void EncodeCipWord(const CipWord *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipDword(const void *const data,
+void EncodeCipDword(const CipDword *const data,
                     ENIPMessage *const outgoing_message);
 
-void EncodeCipLword(const void *const data,
+void EncodeCipLword(const CipLword *const data,
                     ENIPMessage *const outgoing_message);
 
-void EncodeCipUsint(const void *const data,
+void EncodeCipUsint(const CipUsint *const data,
                     ENIPMessage *const outgoing_message);
 
-void EncodeCipUint(const void *const data,
+void EncodeCipUint(const CipUint *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipUdint(const void *const data,
+void EncodeCipUdint(const CipUdint *const data,
                     ENIPMessage *const outgoing_message);
 
-void EncodeCipUlint(const void *const data,
+void EncodeCipUlint(const CipUlint *const data,
                     ENIPMessage *const outgoing_message);
 
-void EncodeCipSint(const void *const data,
+void EncodeCipSint(const CipSint *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipInt(const void *const data,
+void EncodeCipInt(const CipInt *const data,
                   ENIPMessage *const outgoing_message);
 
-void EncodeCipDint(const void *const data,
+void EncodeCipDint(const CipDint *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipLint(const void *const data,
+void EncodeCipLint(const CipLint *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipReal(const void *const data,
+void EncodeCipReal(const CipReal *const data,
                    ENIPMessage *const outgoing_message);
 
-void EncodeCipLreal(const void *const data,
+void EncodeCipLreal(const CipLreal *const data,
                     ENIPMessage *const outgoing_message);
 
-void EncodeCipShortString(const void *const data,
+void EncodeCipShortString(const CipShortString *const data,
                           ENIPMessage *const outgoing_message);
 
-void EncodeCipString(const void *const data,
+void EncodeCipString(const CipString *const data,
                      ENIPMessage *const outgoing_message);
 
-void EncodeCipString2(const void *const data,
+void EncodeCipString2(const CipString2 *const data,
                       ENIPMessage *const outgoing_message);
 
-void EncodeCipStringN(const void *const data,
+void EncodeCipStringN(const CipStringN *const data,
                       ENIPMessage *const outgoing_message);
 
-void EncodeCipStringI(const void *const data,
+void EncodeCipStringI(const CipStringI *const data,
                       ENIPMessage *const outgoing_message);
 
-void EncodeCipByteArray(const void *const data,
+void EncodeCipByteArray(const CipByteArray *const data,
                         ENIPMessage *const outgoing_message);
 
-void EncodeCipEPath(const void *const data,
+void EncodeCipEPath(const CipEpath *const data,
                     ENIPMessage *const outgoing_message);
 
 void EncodeCipEthernetLinkPhyisicalAddress(const void *const data,

+ 15 - 12
source/src/ports/POSIX/main.c

@@ -116,7 +116,7 @@ int main(int argc,
 
   /* Setup the CIP Layer. All objects are initialized with the default
    * values for the attribute contents. */
-  CipStackInit(unique_connection_id);
+  EipStatus eip_status = CipStackInit(unique_connection_id);
 
   CipEthernetLinkSetMac(iface_mac);
 
@@ -136,11 +136,11 @@ int main(int argc,
   }
 
   /* Bring up network interface or start DHCP client ... */
-  EipStatus status = BringupNetwork(arg[1],
-                                    g_tcpip.config_control,
-                                    &g_tcpip.interface_configuration,
-                                    &g_tcpip.hostname);
-  if (status < 0) {
+  eip_status = BringupNetwork(arg[1],
+                              g_tcpip.config_control,
+                              &g_tcpip.interface_configuration,
+                              &g_tcpip.hostname);
+  if (eip_status < 0) {
     OPENER_TRACE_ERR("BringUpNetwork() failed\n");
   }
 
@@ -159,14 +159,17 @@ int main(int argc,
     OPENER_TRACE_INFO("DHCP network configuration started\n");
     /* DHCP should already have been started with BringupNetwork(). Wait
      * here for IP present (DHCP done) or abort through g_end_stack. */
-    status = IfaceWaitForIp(arg[1], -1, &g_end_stack);
-    OPENER_TRACE_INFO("DHCP wait for interface: status %d, g_end_stack=%d\n",
-                      status, g_end_stack);
-    if (kEipStatusOk == status && 0 == g_end_stack) {
+    eip_status = IfaceWaitForIp(arg[1], -1, &g_end_stack);
+    OPENER_TRACE_INFO(
+      "DHCP wait for interface: eip_status %d, g_end_stack=%d\n",
+      eip_status,
+      g_end_stack);
+    if (kEipStatusOk == eip_status && 0 == g_end_stack) {
       /* Read IP configuration received via DHCP from interface and store in
        *  the TCP/IP object.*/
-      status = IfaceGetConfiguration(arg[1], &g_tcpip.interface_configuration);
-      if (status < 0) {
+      eip_status = IfaceGetConfiguration(arg[1],
+                                         &g_tcpip.interface_configuration);
+      if (eip_status < 0) {
         OPENER_TRACE_WARN("Problems getting interface configuration\n");
       }
     }

+ 52 - 229
source/tests/cip/cipcommontests.cpp

@@ -10,257 +10,80 @@
 
 extern "C" {
 
-#include "cipcommon.h"
+#include "opener_api.h"
 
 }
 
-TEST_GROUP(CipCommon) {
-
-};
-
-TEST(CipCommon, GetSizeOfAttributeCipBool) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipBool;
-  CHECK_EQUAL(sizeof(CipBool), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipSint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipSint;
-  CHECK_EQUAL(sizeof(CipSint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipInt) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipInt;
-  CHECK_EQUAL(sizeof(CipInt), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipDint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipDint;
-  CHECK_EQUAL(sizeof(CipDint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipUsint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipUsint;
-  CHECK_EQUAL(sizeof(CipUsint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipUint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipUint;
-  CHECK_EQUAL(sizeof(CipUint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipUdint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipUdint;
-  CHECK_EQUAL(sizeof(CipUdint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipReal) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipReal;
-  CHECK_EQUAL(sizeof(CipReal), GetSizeOfAttribute(&attribute) );
-}
-
-#ifdef OPENER_SUPPORT_64BIT_DATATYPES
-TEST(CipCommon, GetSizeOfAttributeCipLreal) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipLreal;
-  CHECK_EQUAL(sizeof(CipLreal), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipUlint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipUlint;
-  CHECK_EQUAL(sizeof(CipUlint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipLint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipLint;
-  CHECK_EQUAL(sizeof(CipLint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipLword) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipLword;
-  CHECK_EQUAL(sizeof(CipLword), GetSizeOfAttribute(&attribute) );
-}
+ENIPMessage message; /**< Test variable holds ENIP message*/
 
-TEST(CipCommon, GetSizeOfAttributeCipLtime) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipLtime;
-  CHECK_EQUAL(sizeof(CipLint), GetSizeOfAttribute(&attribute) );
-}
-#endif /* OPENER_SUPPORT_64BIT_DATATYPES */
-
-TEST(CipCommon, GetSizeOfAttributeCipStime) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipStime;
-  CHECK_EQUAL(sizeof(CipDint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipData) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipDate;
-  CHECK_EQUAL(sizeof(CipUint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipTimeOfDay) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipTimeOfDay;
-  CHECK_EQUAL(sizeof(CipUdint), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipDateAndTime) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipDateAndTime;
-  CHECK_EQUAL(sizeof(CipUdint) + sizeof(CipUint),
-              GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipString) {
-  CipAttributeStruct attribute;
-  char demo_string[] = "Hello World!";
-  CipString test_string =
-  { .length = sizeof(demo_string), .string = (EipByte *)demo_string };
-  attribute.type = kCipString;
-  attribute.data = (void *)&test_string;
-
-  CHECK_EQUAL(
-    sizeof(test_string.length) + test_string.length * sizeof(CipOctet),
-    GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipByte) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipByte;
-  CHECK_EQUAL(sizeof(CipByte), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipWord) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipWord;
-  CHECK_EQUAL(sizeof(CipWord), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipDword) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipDword;
-  CHECK_EQUAL(sizeof(CipDword), GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipString2) {
-  CipAttributeStruct attribute;
-  char demo_string[] = "H e l l o   W o r l d !"; /* \0 termination symbol is seen as second byte for ! */
-  CipString test_string =
-  { .length = sizeof(demo_string) / 2, .string = (EipByte *)demo_string };
-  attribute.type = kCipString;
-  attribute.data = (void *)&test_string;
-
-  CHECK_EQUAL(
-    sizeof(test_string.length) + test_string.length * sizeof(CipOctet),
-    GetSizeOfAttribute(&attribute) );
-}
-
-TEST(CipCommon, GetSizeOfAttributeCipFtime) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipFtime;
-  CHECK_EQUAL(sizeof(CipDint), GetSizeOfAttribute(&attribute) );
-}
+TEST_GROUP(CipCommon) {
 
-TEST(CipCommon, GetSizeOfAttributeCipItime) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipItime;
-  CHECK_EQUAL(sizeof(CipInt), GetSizeOfAttribute(&attribute) );
-}
+  void setup() {
+    InitializeENIPMessage(&message);
+  }
 
-TEST(CipCommon, GetSizeOfAttributeCipStringN) {
-  CipAttributeStruct attribute;
-  char demo_string[] = "Hello World!";
-  CipStringN test_string =
-  { .size = 1, .length = sizeof(demo_string),
-    .string = (EipByte *) demo_string };
-  attribute.type = kCipStringN;
-  attribute.data = (void *) &test_string;
+};
 
-  CHECK_EQUAL(
-    sizeof(test_string.size) + sizeof(test_string.length) + test_string.size * test_string.length *
-    sizeof(CipOctet),
-    GetSizeOfAttribute(
-      &attribute) );
+TEST(CipCommon, EncodeCipBool) {
+  const CipBool value = false;
+  EncodeCipBool(&value, &message);
+  CHECK_EQUAL(0, *(CipBool *)message.message_buffer);
+  POINTERS_EQUAL(message.message_buffer + 1, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipTime) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipTime;
-  CHECK_EQUAL(sizeof(CipDint), GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipByte) {
+  const CipByte value = 173U;
+  EncodeCipBool(&value, &message);
+  CHECK_EQUAL(value, *(CipByte *)message.message_buffer);
+  POINTERS_EQUAL(message.message_buffer + 1, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipEpath) {
-  /* TODO: Fix me */
-  CipAttributeStruct attribute;
-  attribute.type = kCipItime;
-  CHECK_EQUAL(sizeof(CipInt), GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipWord) {
+  const CipWord value = 53678U;
+  EncodeCipWord(&value, &message);
+  CHECK_EQUAL(value, *(CipWord *)(message.message_buffer) );
+  POINTERS_EQUAL(message.message_buffer + 2, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipEngUnit) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipEngUnit;
-  CHECK_EQUAL(sizeof(CipUint), GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipDword) {
+  const CipDword value = 5357678U;
+  EncodeCipDword(&value, &message);
+  CHECK_EQUAL(value, *(CipDword *)(message.message_buffer) );
+  POINTERS_EQUAL(message.message_buffer + 4, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipUsintUsint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipUsintUsint;
-  CHECK_EQUAL(2 * sizeof(CipUsint), GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipLword) {
+  const CipLword value = 8353457678U;
+  EncodeCipLword(&value, &message);
+  CHECK_EQUAL(value, *(CipLword *)(message.message_buffer) );
+  POINTERS_EQUAL(message.message_buffer + 8, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipUdintUdintUdintUdintUdintString) {
-  CipTcpIpInterfaceConfiguration config;
-  char domain_name[] = "www.github.com/EIPStackGroup/OpENer";
-  config.domain_name.length = sizeof(domain_name);
-  config.domain_name.string = (EipByte *)domain_name;
-  CipAttributeStruct attribute;
-  attribute.type = kCipUdintUdintUdintUdintUdintString;
-  attribute.data = (void *)&config;
-  CHECK_EQUAL(
-    5 * sizeof(CipUdint) + sizeof(CipUint) + sizeof(domain_name) *
-    sizeof(EipByte),
-    GetSizeOfAttribute(&attribute) );
-}
 
-TEST(CipCommon, GetSizeOfAttributeCip6Usint) {
-  CipAttributeStruct attribute;
-  attribute.type = kCip6Usint;
-  CHECK_EQUAL(6 * sizeof(CipUsint), GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipUsint) {
+  const CipUsint value = 212U;
+  EncodeCipBool(&value, &message);
+  CHECK_EQUAL(value, *(CipUsint *)message.message_buffer);
+  POINTERS_EQUAL(message.message_buffer + 1, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipMemberList) {
-  CipAttributeStruct attribute;
-  attribute.type = kCipMemberList;
-  CHECK_EQUAL(0, GetSizeOfAttribute(&attribute) );
-  /* Currently not implemented */
+TEST(CipCommon, EncodeCipUint) {
+  const CipUint value = 42568U;
+  EncodeCipUint(&value, &message);
+  CHECK_EQUAL(value, *(CipUint *)(message.message_buffer) );
+  POINTERS_EQUAL(message.message_buffer + 2, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeCipByteArray) {
-  CipByte data_array[] = {1,2,3,4,5,6,7,8,9};
-  CipByteArray array;
-  array.data = (EipByte *)&data_array;
-  array.length = sizeof(data_array);
-  CipAttributeStruct attribute;
-  attribute.type = kCipByteArray;
-  attribute.data = (void *)&array;
-  CHECK_EQUAL(sizeof(CipUint) + array.length * sizeof(CipByte),
-              GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipUdint) {
+  const CipUdint value = 1653245U;
+  EncodeCipUdint(&value, &message);
+  CHECK_EQUAL(value, *(CipUdint *)(message.message_buffer) );
+  POINTERS_EQUAL(message.message_buffer + 4, message.current_message_position);
 }
 
-TEST(CipCommon, GetSizeOfAttributeInternalUint6) {
-  CipAttributeStruct attribute;
-  attribute.type = kInternalUint6;
-  CHECK_EQUAL(6 * sizeof(CipUint), GetSizeOfAttribute(&attribute) );
+TEST(CipCommon, EncodeCipUlint) {
+  const CipUlint value = 5357678U;
+  EncodeCipUlint(&value, &message);
+  CHECK_EQUAL(value, *(CipUlint *)(message.message_buffer) );
+  POINTERS_EQUAL(message.message_buffer + 8, message.current_message_position);
 }

+ 8 - 8
source/tests/enet_encap/endianconvtest.cpp

@@ -99,14 +99,14 @@ TEST(EndianConversion, AddLintToMessage) {
   AddLintToMessage(value_to_add_to_message, &message);
 
   /* Expected message from highest to lowest byte [30][52][09][84][0B][EF][2A][2D] */
-  BYTES_EQUAL(0x2D, message.message_buffer[0]);
-  BYTES_EQUAL(0x2A, message.message_buffer[1]);
-  BYTES_EQUAL(0xEF, message.message_buffer[2]);
-  BYTES_EQUAL(0x0B, message.message_buffer[3]);
-  BYTES_EQUAL(0x84, message.message_buffer[4]);
-  BYTES_EQUAL(0x09, message.message_buffer[5]);
-  BYTES_EQUAL(0x52, message.message_buffer[6]);
-  BYTES_EQUAL(0x30, message.message_buffer[7]);
+  BYTES_EQUAL(0x30, message.message_buffer[0]);
+  BYTES_EQUAL(0x52, message.message_buffer[1]);
+  BYTES_EQUAL(0x09, message.message_buffer[2]);
+  BYTES_EQUAL(0x84, message.message_buffer[3]);
+  BYTES_EQUAL(0x0B, message.message_buffer[4]);
+  BYTES_EQUAL(0xEF, message.message_buffer[5]);
+  BYTES_EQUAL(0x2A, message.message_buffer[6]);
+  BYTES_EQUAL(0x2D, message.message_buffer[7]);
 
   POINTERS_EQUAL(message.message_buffer + 8, message.current_message_position)
 }

+ 10 - 0
source/tests/ports/socket_timer_tests.cpp

@@ -30,6 +30,16 @@ TEST(SocketTimer, NoEmptySocketTimerAvailable) {
   POINTERS_EQUAL( NULL, SocketTimerArrayGetEmptySocketTimer(timers, 10) );
 }
 
+TEST(SocketTimer, SetSocket) {
+  SocketTimer timer = {
+    socket : -1,
+    last_update : 0
+  };
+  SocketTimerSetSocket(&timer, 1);
+  CHECK_EQUAL( 1, timer.socket );
+}
+
+
 TEST(SocketTimer, UpdateSocketTimer) {
   SocketTimer timer = {
     socket : -1,