From 9481ff1ad8414cfebd236a87783258d70d4b9c99 Mon Sep 17 00:00:00 2001 From: Iain Chesworth Date: Fri, 9 Feb 2024 17:30:01 +1100 Subject: [PATCH] Start adding support for static analysis and closing out analysis-detected defects. --- .clang-tidy | 13 + CMakeLists.txt | 51 +- CMakePresets.json | 1 + CMakeUserPresets.json | 4 +- cmake/PVS-Studio.cmake | 629 ++++++++++++++++++ cmake/tools/FindClangTidy.cmake | 32 +- src/developer/mock_serial_port.cpp | 2 +- src/developer/mock_serial_port.h | 1 + .../exception_certificate_invalidformat.cpp | 2 + .../exception_certificate_invalidformat.h | 2 +- .../exception_certificate_notfound.cpp | 2 + .../exception_certificate_notfound.h | 2 +- .../exception_http_duplicateroute.cpp | 2 + .../exception_http_duplicateroute.h | 2 +- src/exceptions/exception_hubnotfound.cpp | 2 + src/exceptions/exception_hubnotfound.h | 2 +- src/exceptions/exception_notimplemented.cpp | 2 + src/exceptions/exception_notimplemented.h | 2 +- .../exception_optionparsingfailed.cpp | 2 + .../exception_optionparsingfailed.h | 2 +- .../exception_options_conflictingoptions.cpp | 2 + .../exception_options_conflictingoptions.h | 2 +- .../exception_options_missingdependency.cpp | 2 + .../exception_options_missingdependency.h | 2 +- .../exception_optionshelporversion.cpp | 2 + .../exception_optionshelporversion.h | 2 +- .../exception_serial_invalidmode.cpp | 2 + src/exceptions/exception_serial_invalidmode.h | 2 +- ...ption_signallingstatscounter_badaccess.cpp | 2 + ...ception_signallingstatscounter_badaccess.h | 2 +- .../exception_traits_doesnotexist.cpp | 2 + .../exception_traits_doesnotexist.h | 2 +- .../exception_traits_failedtoset.cpp | 2 + src/exceptions/exception_traits_failedtoset.h | 2 +- .../exception_traits_invalidtraitvalue.cpp | 2 + .../exception_traits_invalidtraitvalue.h | 2 +- .../exception_traits_notmutable.cpp | 2 + src/exceptions/exception_traits_notmutable.h | 2 +- src/exceptions/exception_webserver.cpp | 2 + src/exceptions/exception_webserver.h | 2 +- src/formatters/beast_stringview_formatter.cpp | 2 +- src/formatters/beast_stringview_formatter.h | 2 +- .../units_dimensionless_formatter.cpp | 2 +- .../units_dimensionless_formatter.h | 2 +- src/http/server/listener.cpp | 4 +- src/http/webroute_equipment.cpp | 2 +- src/http/webroute_equipment.h | 2 +- src/http/webroute_equipment_button.cpp | 15 +- src/http/webroute_equipment_button.h | 12 +- src/http/webroute_equipment_buttons.cpp | 6 +- src/http/webroute_equipment_buttons.h | 6 +- src/http/webroute_equipment_devices.cpp | 5 +- src/http/webroute_equipment_devices.h | 2 +- src/http/webroute_equipment_version.cpp | 2 +- src/http/webroute_equipment_version.h | 2 +- src/http/webroute_page_equipment.cpp | 3 +- src/http/webroute_version.cpp | 2 +- src/http/webroute_version.h | 2 +- src/http/websocket_equipment.cpp | 9 +- src/interfaces/idevice.cpp | 4 - src/interfaces/idevice.h | 2 +- src/interfaces/iequipment.cpp | 6 +- src/interfaces/iequipment.h | 2 +- src/interfaces/ihub.cpp | 8 +- src/interfaces/ihub.h | 4 +- src/interfaces/imessagesignal_recv.h | 6 +- src/interfaces/imessagesignal_send.h | 6 +- src/interfaces/iprofilingunit.cpp | 4 +- src/interfaces/iprofilingunit.h | 2 +- src/interfaces/iserializable.cpp | 8 +- src/interfaces/iserializable.h | 4 +- src/interfaces/iserialport.cpp | 8 +- src/interfaces/iserialport.h | 4 +- src/interfaces/istatuspublisher.cpp | 2 +- src/interfaces/iwebpageroute.h | 4 +- src/interfaces/iwebroute.h | 2 +- src/interfaces/iwebsocket.cpp | 20 +- src/interfaces/iwebsocket.h | 8 +- src/jandy/devices/aquarite_device.cpp | 12 +- src/jandy/devices/aquarite_device.h | 2 +- src/jandy/devices/iaq_device.cpp | 2 +- src/jandy/devices/jandy_device_types.cpp | 16 +- src/jandy/utility/screen_data_page.cpp | 8 +- .../timeout_duration_string_converter.cpp | 6 +- src/utility/bandwidth_utilisation.h | 2 +- test/unit/http/test_http_sessions.cpp | 71 ++ 86 files changed, 913 insertions(+), 189 deletions(-) create mode 100644 .clang-tidy create mode 100644 cmake/PVS-Studio.cmake diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..e83c75f --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,13 @@ +Checks: " + bugprone-*, + clang-diagnostic-*, + clang-analyzer-*, + modernize-*, + performance-*, + readability-* +" +WarningsAsErrors: "" +HeaderFilterRegex: "" +CheckOptions: + - key: readability-identifier-naming.PrivateMemberSuffix + value: "_" \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 99442a6..7971db6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_SOURCE_DIR}/cmake/tools/" "${CMAKE_SOURCE_DIR}/cmake/tools/coverage" "${CMAKE_SOURCE_DIR}/deps" "${CMAKE_SOURCE_DIR}/deps/sanitizers-cmake/cmake") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_SOURCE_DIR}/cmake/tools/" "${CMAKE_SOURCE_DIR}/cmake/tools/" "${CMAKE_SOURCE_DIR}/cmake/tools/coverage" "${CMAKE_SOURCE_DIR}/deps" "${CMAKE_SOURCE_DIR}/deps/sanitizers-cmake/cmake") project( aqualink-automate @@ -18,7 +18,8 @@ option(ENABLE_BENCHMARKS "Enable performance tests" ON) option(ENABLE_COVERAGE "Enable coverage of unit tests" OFF) option(ENABLE_TESTS "Enable unit tests" ON) option(ENABLE_PROFILING "DevTools: Enable profiling tooling" ON) -option(ENABLE_CLANG_TIDY "DevTools: Enable Clang-Tidy analysis" ON) +option(ENABLE_CLANG_TIDY "DevTools: Enable static analysis using clang-tidy" ON) +option(ENABLE_PVS_STUDIO "DevTools: Enable static analysis using PVS-Studio" ON) option(ENABLE_ASIO_TRACKING "DevTools: Debug using ASIO connection tracking" OFF) cmake_dependent_option(ENABLE_SANITIZERS "DevTools: Enable sanitizer tooling" ON "NOT ENABLE_PROFILING" OFF) @@ -99,19 +100,6 @@ endif(ENABLE_SANITIZERS) # #------------------------------------------------------------------------------ -if(ENABLE_CLANG_TIDY) - -find_package(ClangTidy) - -endif(ENABLE_CLANG_TIDY) - -#------------------------------------------------------------------------------ -# -# -# -# -#------------------------------------------------------------------------------ - # Template the git commit information prior to building the application. set(GIT_FAIL_IF_NONZERO_EXIT false) set(PRE_CONFIGURE_FILE "src/version/version_git.constants.cpp.in") @@ -572,6 +560,39 @@ target_link_libraries( "$" ) +#------------------------------------------------------------------------------ +# +# STATIC ANALYSIS CONFIGURATION +# ============================= +# +#------------------------------------------------------------------------------ + +if(ENABLE_CLANG_TIDY) + +find_package(ClangTidy) + +set_target_properties(aqualink-automate PROPERTIES CXX_CLANG_TIDY "${CMAKE_CXX_CLANG_TIDY}") + +endif(ENABLE_CLANG_TIDY) + +if(ENABLE_PVS_STUDIO) + +include(PVS-Studio) + +pvs_studio_add_target( + ALL + TARGET aqualink-automate.analyze + ANALYZE aqualink-automate libaqualink-automate + OUTPUT + LOG "${CMAKE_CURRENT_BINARY_DIR}/aqualink-automate.pvs-studio.log" + FORMAT fullhtml + MODE 64+GA+OP+CS+MISRA+AUTOSAR+OWASP + SOURCES "${CMAKE_SOURCE_DIR}/src" + ARGS --exclude-path "${CMAKE_SOURCE_DIR}/build" +) + +endif(ENABLE_PVS_STUDIO) + #------------------------------------------------------------------------------ # # diff --git a/CMakePresets.json b/CMakePresets.json index 8c871f7..0b373be 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -19,6 +19,7 @@ "ENABLE_COVERAGE": "OFF", "ENABLE_TESTS": "ON", "ENABLE_CLANG_TIDY": "OFF", + "ENABLE_PVS_STUDIO": "OFF", "ENABLE_PROFILING": "OFF", "ENABLE_SANITIZERS": "OFF", "ENABLE_ASIO_TRACKING": "OFF", diff --git a/CMakeUserPresets.json b/CMakeUserPresets.json index fc6d470..08e9e22 100644 --- a/CMakeUserPresets.json +++ b/CMakeUserPresets.json @@ -79,7 +79,9 @@ "rhs": "Windows" }, "cacheVariables": { - "ENABLE_ASIO_TRACKING": "OFF" + "ENABLE_ASIO_TRACKING": "OFF", + "ENABLE_CLANG_TIDY": "ON", + "ENABLE_PVS_STUDIO": "ON" } } ], diff --git a/cmake/PVS-Studio.cmake b/cmake/PVS-Studio.cmake new file mode 100644 index 0000000..f8cef76 --- /dev/null +++ b/cmake/PVS-Studio.cmake @@ -0,0 +1,629 @@ +# 2006-2008 (c) Viva64.com Team +# 2008-2020 (c) OOO "Program Verification Systems" +# 2020-2022 (c) PVS-Studio LLC +# Version 12 + +cmake_minimum_required(VERSION 3.5) +cmake_policy(SET CMP0054 NEW) + +if (PVS_STUDIO_AS_SCRIPT) + # This code runs at build time. + # It executes pvs-studio-analyzer and propagates its return value. + + set(in_cl_params FALSE) + set(additional_args) + + foreach (arg ${PVS_STUDIO_COMMAND}) + if (NOT in_cl_params) + if ("${arg}" STREQUAL "--cl-params") + set(in_cl_params TRUE) + endif() + else() + # A workaround for macOS frameworks (e.g. QtWidgets.framework) + # You can test this workaround on this project: https://github.com/easyaspi314/MidiEditor/tree/gba + if (APPLE AND "${arg}" MATCHES "^-I(.*)\\.framework$") + STRING(REGEX REPLACE "^-I(.*)\\.framework$" "\\1.framework" framework "${arg}") + if (IS_ABSOLUTE "${framework}") + get_filename_component(framework "${framework}" DIRECTORY) + list(APPEND additional_args "-iframework") + list(APPEND additional_args "${framework}") + endif() + endif() + endif() + endforeach() + + file(REMOVE "${PVS_STUDIO_LOG_FILE}") + execute_process(COMMAND ${PVS_STUDIO_COMMAND} ${additional_args} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE error) + + if (result AND NOT output MATCHES "^No compilation units were found\\.") + message(FATAL_ERROR "PVS-Studio exited with non-zero code.\nStdout:\n${output}\nStderr:\n${error}\n") + endif() + + return() +endif() + +if(__PVS_STUDIO_INCLUDED) + return() +endif() +set(__PVS_STUDIO_INCLUDED TRUE) + +set(PVS_STUDIO_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") + +function (pvs_studio_log TEXT) + if (PVS_STUDIO_DEBUG) + message("PVS-Studio: ${TEXT}") + endif() +endfunction() + +function (pvs_studio_relative_path VAR ROOT FILEPATH) + if (CMAKE_HOST_WIN32) + STRING(REGEX REPLACE "\\\\" "/" ROOT ${ROOT}) + STRING(REGEX REPLACE "\\\\" "/" FILEPATH ${FILEPATH}) + endif() + set("${VAR}" "${FILEPATH}" PARENT_SCOPE) + if (IS_ABSOLUTE "${FILEPATH}") + file(RELATIVE_PATH RPATH "${ROOT}" "${FILEPATH}") + if (NOT IS_ABSOLUTE "${RPATH}") + set("${VAR}" "${RPATH}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (pvs_studio_join_path VAR DIR1 DIR2) + if ("${DIR2}" MATCHES "^(/|~|.:/).*$" OR "${DIR1}" STREQUAL "") + set("${VAR}" "${DIR2}" PARENT_SCOPE) + else() + set("${VAR}" "${DIR1}/${DIR2}" PARENT_SCOPE) + endif() +endfunction() + +macro (pvs_studio_append_flags_from_property CXX C DIR PREFIX) + if (NOT "${PROPERTY}" STREQUAL "NOTFOUND" AND NOT "${PROPERTY}" STREQUAL "PROPERTY-NOTFOUND") + foreach (PROP ${PROPERTY}) + pvs_studio_join_path(PROP "${DIR}" "${PROP}") + + if (APPLE AND "${PREFIX}" STREQUAL "-I" AND IS_ABSOLUTE "${PROP}" AND "${PROP}" MATCHES "\\.framework$") + get_filename_component(FRAMEWORK "${PROP}" DIRECTORY) + list(APPEND "${CXX}" "-iframework") + list(APPEND "${CXX}" "${FRAMEWORK}") + list(APPEND "${C}" "-iframework") + list(APPEND "${C}" "${FRAMEWORK}") + pvs_studio_log("framework: ${FRAMEWORK}") + elseif (NOT "${PROP}" STREQUAL "") + list(APPEND "${CXX}" "${PREFIX}${PROP}") + list(APPEND "${C}" "${PREFIX}${PROP}") + endif() + endforeach() + endif() +endmacro() + +macro (pvs_studio_append_standard_flag FLAGS STANDARD) + if ("${STANDARD}" MATCHES "^(99|11|14|17|20)$") + if ("${PVS_STUDIO_PREPROCESSOR}" MATCHES "gcc|clang") + list(APPEND "${FLAGS}" "-std=c++${STANDARD}") + elseif("${PVS_STUDIO_PREPROCESSOR}" MATCHES "visualcpp") + list(APPEND "${FLAGS}" "/std:c++${STANDARD}") + endif() + endif() +endmacro() + +function (pvs_studio_set_directory_flags DIRECTORY CXX C) + set(CXX_FLAGS "${${CXX}}") + set(C_FLAGS "${${C}}") + + get_directory_property(PROPERTY DIRECTORY "${DIRECTORY}" INCLUDE_DIRECTORIES) + pvs_studio_append_flags_from_property(CXX_FLAGS C_FLAGS "${DIRECTORY}" "-I") + + get_directory_property(PROPERTY DIRECTORY "${DIRECTORY}" COMPILE_DEFINITIONS) + pvs_studio_append_flags_from_property(CXX_FLAGS C_FLAGS "" "-D") + + set("${CXX}" "${CXX_FLAGS}" PARENT_SCOPE) + set("${C}" "${C_FLAGS}" PARENT_SCOPE) +endfunction() + +function (pvs_studio_set_target_flags TARGET CXX C) + set(CXX_FLAGS "${${CXX}}") + set(C_FLAGS "${${C}}") + + if (NOT MSVC) + list(APPEND CXX_FLAGS "$<$:--sysroot=${CMAKE_SYSROOT}>") + list(APPEND C_FLAGS "$<$:--sysroot=${CMAKE_SYSROOT}>") + endif() + + set(prop_incdirs "$") + list(APPEND CXX_FLAGS "$<$:-I$-I>>") + list(APPEND C_FLAGS "$<$:-I$-I>>") + + set(prop_compdefs "$") + list(APPEND CXX_FLAGS "$<$:-D$-D>>") + list(APPEND C_FLAGS "$<$:-D$-D>>") + + set(prop_compopt "$") + list(APPEND CXX_FLAGS "$<$:$>>") + list(APPEND C_FLAGS "$<$:$>>") + + set("${CXX}" "${CXX_FLAGS}" PARENT_SCOPE) + set("${C}" "${C_FLAGS}" PARENT_SCOPE) +endfunction() + +function (pvs_studio_set_source_file_flags SOURCE) + set(LANGUAGE "") + + string(TOLOWER "${SOURCE}" SOURCE_LOWER) + if ("${LANGUAGE}" STREQUAL "" AND "${SOURCE_LOWER}" MATCHES "^.*\\.(c|cpp|cc|cx|cxx|cp|c\\+\\+)$") + if ("${SOURCE}" MATCHES "^.*\\.c$") + set(LANGUAGE C) + else() + set(LANGUAGE CXX) + endif() + endif() + + if ("${LANGUAGE}" STREQUAL "C") + set(CL_PARAMS ${PVS_STUDIO_C_FLAGS} ${PVS_STUDIO_TARGET_C_FLAGS} -DPVS_STUDIO) + elseif ("${LANGUAGE}" STREQUAL "CXX") + set(CL_PARAMS ${PVS_STUDIO_CXX_FLAGS} ${PVS_STUDIO_TARGET_CXX_FLAGS} -DPVS_STUDIO) + endif() + + set(PVS_STUDIO_LANGUAGE "${LANGUAGE}" PARENT_SCOPE) + set(PVS_STUDIO_CL_PARAMS "${CL_PARAMS}" PARENT_SCOPE) +endfunction() + +function (pvs_studio_analyze_file SOURCE SOURCE_DIR BINARY_DIR) + set(PLOGS ${PVS_STUDIO_PLOGS}) + pvs_studio_set_source_file_flags("${SOURCE}") + + get_filename_component(SOURCE "${SOURCE}" REALPATH) + + get_source_file_property(PROPERTY "${SOURCE}" HEADER_FILE_ONLY) + if (PROPERTY) + return() + endif() + + pvs_studio_relative_path(SOURCE_RELATIVE "${SOURCE_DIR}" "${SOURCE}") + pvs_studio_join_path(SOURCE "${SOURCE_DIR}" "${SOURCE}") + + set(LOG "${BINARY_DIR}/PVS-Studio/${TARGET}/${SOURCE_RELATIVE}.log") + get_filename_component(LOG "${LOG}" REALPATH) + get_filename_component(PARENT_DIR "${LOG}" DIRECTORY) + + if (EXISTS "${SOURCE}" AND NOT TARGET "${LOG}" AND NOT "${PVS_STUDIO_LANGUAGE}" STREQUAL "") + # A workaround to support implicit dependencies for ninja generators. + set(depPvsArg) + set(depCommandArg) + if (CMAKE_VERSION VERSION_GREATER 3.6 AND "${CMAKE_GENERATOR}" STREQUAL "Ninja") + pvs_studio_relative_path(relLog "${CMAKE_BINARY_DIR}" "${LOG}") + set(depPvsArg --dep-file "${LOG}.d" --dep-file-target "${relLog}") + set(depCommandArg DEPFILE "${LOG}.d") + endif() + + # https://public.kitware.com/Bug/print_bug_page.php?bug_id=14353 + # https://public.kitware.com/Bug/file/5436/expand_command.cmake + # + # It is a workaround to expand generator expressions. + set(cmdline "${PVS_STUDIO_BIN}" analyze + --output-file "${LOG}" + --source-file "${SOURCE}" + ${depPvsArg} + ${PVS_STUDIO_ARGS} + --cl-params "${PVS_STUDIO_CL_PARAMS}" "${SOURCE}") + + string(REPLACE ";" "$" cmdline "${cmdline}") + set(pvscmd "${CMAKE_COMMAND}" + -D "PVS_STUDIO_AS_SCRIPT=TRUE" + -D "PVS_STUDIO_COMMAND=${cmdline}" + -D "PVS_STUDIO_LOG_FILE=${LOG}" + -P "${PVS_STUDIO_SCRIPT}") + + add_custom_command(OUTPUT "${LOG}" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${PARENT_DIR}" + COMMAND "${CMAKE_COMMAND}" -E remove_directory "${LOG}" + COMMAND ${pvscmd} + WORKING_DIRECTORY "${BINARY_DIR}" + DEPENDS "${SOURCE}" "${PVS_STUDIO_SUPPRESS_BASE}" "${PVS_STUDIO_DEPENDS}" + IMPLICIT_DEPENDS "${PVS_STUDIO_LANGUAGE}" "${SOURCE}" + ${depCommandArg} + VERBATIM + COMMENT "Analyzing ${PVS_STUDIO_LANGUAGE} file ${SOURCE_RELATIVE}") + list(APPEND PLOGS "${LOG}") + endif() + set(PVS_STUDIO_PLOGS "${PLOGS}" PARENT_SCOPE) +endfunction() + +function (pvs_studio_analyze_target TARGET DIR) + set(PVS_STUDIO_PLOGS "${PVS_STUDIO_PLOGS}") + set(PVS_STUDIO_TARGET_CXX_FLAGS "") + set(PVS_STUDIO_TARGET_C_FLAGS "") + + get_target_property(PROPERTY "${TARGET}" SOURCES) + pvs_studio_relative_path(BINARY_DIR "${CMAKE_SOURCE_DIR}" "${DIR}") + if ("${BINARY_DIR}" MATCHES "^/.*$") + pvs_studio_join_path(BINARY_DIR "${CMAKE_BINARY_DIR}" "PVS-Studio/__${BINARY_DIR}") + else() + pvs_studio_join_path(BINARY_DIR "${CMAKE_BINARY_DIR}" "${BINARY_DIR}") + endif() + + file(MAKE_DIRECTORY "${BINARY_DIR}") + + pvs_studio_set_directory_flags("${DIR}" PVS_STUDIO_TARGET_CXX_FLAGS PVS_STUDIO_TARGET_C_FLAGS) + pvs_studio_set_target_flags("${TARGET}" PVS_STUDIO_TARGET_CXX_FLAGS PVS_STUDIO_TARGET_C_FLAGS) + + if (NOT "${PROPERTY}" STREQUAL "NOTFOUND" AND NOT "${PROPERTY}" STREQUAL "PROPERTY-NOTFOUND") + foreach (SOURCE ${PROPERTY}) + pvs_studio_join_path(SOURCE "${DIR}" "${SOURCE}") + pvs_studio_analyze_file("${SOURCE}" "${DIR}" "${BINARY_DIR}") + endforeach() + endif() + + set(PVS_STUDIO_PLOGS "${PVS_STUDIO_PLOGS}" PARENT_SCOPE) +endfunction() + +set(PVS_STUDIO_RECURSIVE_TARGETS) +set(PVS_STUDIO_RECURSIVE_TARGETS_NEW) + +macro(pvs_studio_get_recursive_targets TARGET) + get_target_property(libs "${TARGET}" LINK_LIBRARIES) + foreach (lib IN LISTS libs) + list(FIND PVS_STUDIO_RECURSIVE_TARGETS "${lib}" index) + if (TARGET "${lib}" AND "${index}" STREQUAL -1) + get_target_property(target_type "${lib}" TYPE) + if (NOT "${target_type}" STREQUAL "INTERFACE_LIBRARY") + list(APPEND PVS_STUDIO_RECURSIVE_TARGETS "${lib}") + list(APPEND PVS_STUDIO_RECURSIVE_TARGETS_NEW "${lib}") + pvs_studio_get_recursive_targets("${lib}") + endif() + endif() + endforeach() +endmacro() + +option(PVS_STUDIO_DISABLE OFF "Disable PVS-Studio targets") +option(PVS_STUDIO_DEBUG OFF "Add debug info") + +# pvs_studio_add_target +# Target options: +# ALL add PVS-Studio target to default build (default: off) +# TARGET target name of analysis target (default: pvs) +# ANALYZE targets... targets to analyze +# RECURSIVE analyze target's dependencies (requires CMake 3.5+) +# COMPILE_COMMANDS use compile_commands.json instead of targets (specified by the 'ANALYZE' option) to determine files for analysis +# (set CMAKE_EXPORT_COMPILE_COMMANDS, available only for Makefile and Ninja generators) +# +# Output options: +# OUTPUT prints report to stdout +# LOG path path to report (default: ${CMAKE_CURRENT_BINARY_DIR}/PVS-Studio.log) +# FORMAT format format of report +# MODE mode analyzers/levels filter (default: GA:1,2) +# HIDE_HELP do not print help message +# +# Analyzer options: +# PLATFORM name linux32/linux64 (default: linux64) +# PREPROCESSOR name preprocessor type: gcc/clang (default: auto detected) +# LICENSE path path to PVS-Studio.lic (default: ~/.config/PVS-Studio/PVS-Studio.lic) +# CONFIG path path to PVS-Studio.cfg +# CFG_TEXT text embedded PVS-Studio.cfg +# SUPPRESS_BASE path to suppress base file +# KEEP_COMBINED_PLOG do not delete combined plog file *.pvs.raw for further processing with plog-converter +# +# Misc options: +# DEPENDS targets.. additional target dependencies +# SOURCES path... list of source files to analyze +# BIN path path to pvs-studio-analyzer (Unix) or CompilerCommandsAnalyzer.exe (Windows) +# CONVERTER path path to plog-converter (Unix) or HtmlGenerator.exe (Windows) +# C_FLAGS flags... additional C_FLAGS +# CXX_FLAGS flags... additional CXX_FLAGS +# ARGS args... additional pvs-studio-analyzer/CompilerCommandsAnalyzer.exe flags +# CONVERTER_ARGS args... additional plog-converter/HtmlGenerator.exe flags +function (pvs_studio_add_target) + macro (default VAR VALUE) + if ("${${VAR}}" STREQUAL "") + set("${VAR}" "${VALUE}") + endif() + endmacro() + + set(PVS_STUDIO_SUPPORTED_PREPROCESSORS "gcc|clang|visualcpp") + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(DEFAULT_PREPROCESSOR "clang") + elseif (MSVC) + set(DEFAULT_PREPROCESSOR "visualcpp") + else() + set(DEFAULT_PREPROCESSOR "gcc") + endif() + + set(OPTIONAL OUTPUT ALL RECURSIVE HIDE_HELP KEEP_COMBINED_PLOG COMPILE_COMMANDS KEEP_INTERMEDIATE_FILES) + set(SINGLE LICENSE CONFIG TARGET LOG FORMAT BIN CONVERTER PLATFORM PREPROCESSOR CFG_TEXT SUPPRESS_BASE) + set(MULTI SOURCES C_FLAGS CXX_FLAGS ARGS DEPENDS ANALYZE MODE CONVERTER_ARGS) + cmake_parse_arguments(PVS_STUDIO "${OPTIONAL}" "${SINGLE}" "${MULTI}" ${ARGN}) + + + default(PVS_STUDIO_C_FLAGS "") + default(PVS_STUDIO_CXX_FLAGS "") + default(PVS_STUDIO_TARGET "pvs") + default(PVS_STUDIO_LOG "PVS-Studio.log") + + set(PATHS) + + if (CMAKE_HOST_WIN32) + # The registry value is only read when you do some cache operation on it. + # https://stackoverflow.com/questions/1762201/reading-registry-values-with-cmake + GET_FILENAME_COMPONENT(ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\ProgramVerificationSystems\\PVS-Studio;installDir]" ABSOLUTE CACHE) + + if (EXISTS "${ROOT}") + set(PATHS "${ROOT}") + else() + set(ROOT "PROGRAMFILES(X86)") + set(ROOT "$ENV{${ROOT}}/PVS-Studio") + string(REPLACE \\ / ROOT "${ROOT}") + + if (EXISTS "${ROOT}") + set(PATHS "${ROOT}") + else() + set(ROOT "PATH") + set(ROOT "$ENV{${ROOT}}") + set(PATHS "${ROOT}") + endif() + endif() + + + + default(PVS_STUDIO_BIN "CompilerCommandsAnalyzer.exe") + default(PVS_STUDIO_CONVERTER "HtmlGenerator.exe") + else() + default(PVS_STUDIO_BIN "pvs-studio-analyzer") + default(PVS_STUDIO_CONVERTER "plog-converter") + endif() + + find_program(PVS_STUDIO_BIN_PATH "${PVS_STUDIO_BIN}" ${PATHS}) + set(PVS_STUDIO_BIN "${PVS_STUDIO_BIN_PATH}") + + if (NOT EXISTS "${PVS_STUDIO_BIN}") + message(FATAL_ERROR "pvs-studio-analyzer is not found") + endif() + + find_program(PVS_STUDIO_CONVERTER_PATH "${PVS_STUDIO_CONVERTER}" ${PATHS}) + set(PVS_STUDIO_CONVERTER "${PVS_STUDIO_CONVERTER_PATH}") + + if (NOT EXISTS "${PVS_STUDIO_CONVERTER}") + message(FATAL_ERROR "plog-converter is not found") + endif() + + default(PVS_STUDIO_MODE "GA:1,2") + default(PVS_STUDIO_PREPROCESSOR "${DEFAULT_PREPROCESSOR}") + if (WIN32) + default(PVS_STUDIO_PLATFORM "x64") + else() + default(PVS_STUDIO_PLATFORM "linux64") + endif() + + string(REPLACE ";" "+" PVS_STUDIO_MODE "${PVS_STUDIO_MODE}") + + if ("${PVS_STUDIO_CONFIG}" STREQUAL "" AND NOT "${PVS_STUDIO_CFG_TEXT}" STREQUAL "") + set(PVS_STUDIO_CONFIG "${CMAKE_BINARY_DIR}/PVS-Studio.cfg") + + set(PVS_STUDIO_CONFIG_COMMAND "${CMAKE_COMMAND}" -E echo "${PVS_STUDIO_CFG_TEXT}" > "${PVS_STUDIO_CONFIG}") + + add_custom_command(OUTPUT "${PVS_STUDIO_CONFIG}" + COMMAND ${PVS_STUDIO_CONFIG_COMMAND} + WORKING_DIRECTORY "${BINARY_DIR}" + COMMENT "Generating PVS-Studio.cfg") + + list(APPEND PVS_STUDIO_DEPENDS "${PVS_STUDIO_CONFIG}") + endif() + if (NOT "${PVS_STUDIO_PREPROCESSOR}" MATCHES "^${PVS_STUDIO_SUPPORTED_PREPROCESSORS}$") + message(FATAL_ERROR "Preprocessor ${PVS_STUDIO_PREPROCESSOR} isn't supported. Available options: ${PVS_STUDIO_SUPPORTED_PREPROCESSORS}.") + endif() + + pvs_studio_append_standard_flag(PVS_STUDIO_CXX_FLAGS "${CMAKE_CXX_STANDARD}") + pvs_studio_set_directory_flags("${CMAKE_CURRENT_SOURCE_DIR}" PVS_STUDIO_CXX_FLAGS PVS_STUDIO_C_FLAGS) + + if (NOT "${PVS_STUDIO_LICENSE}" STREQUAL "") + list(APPEND PVS_STUDIO_ARGS --lic-file "${PVS_STUDIO_LICENSE}") + endif() + + if (NOT ${PVS_STUDIO_CONFIG} STREQUAL "") + list(APPEND PVS_STUDIO_ARGS --cfg "${PVS_STUDIO_CONFIG}") + endif() + + list(APPEND PVS_STUDIO_ARGS --platform "${PVS_STUDIO_PLATFORM}" + --preprocessor "${PVS_STUDIO_PREPROCESSOR}") + + if (NOT "${PVS_STUDIO_SUPPRESS_BASE}" STREQUAL "") + pvs_studio_join_path(PVS_STUDIO_SUPPRESS_BASE "${CMAKE_CURRENT_SOURCE_DIR}" "${PVS_STUDIO_SUPPRESS_BASE}") + list(APPEND PVS_STUDIO_ARGS --suppress-file "${PVS_STUDIO_SUPPRESS_BASE}") + endif() + + if (NOT "${CMAKE_CXX_COMPILER}" STREQUAL "") + list(APPEND PVS_STUDIO_ARGS --cxx "${CMAKE_CXX_COMPILER}") + endif() + + if (NOT "${CMAKE_C_COMPILER}" STREQUAL "") + list(APPEND PVS_STUDIO_ARGS --cc "${CMAKE_C_COMPILER}") + endif() + + if (PVS_STUDIO_KEEP_INTERMEDIATE_FILES) + list(APPEND PVS_STUDIO_ARGS --dump-files) + endif() + + string(REGEX REPLACE [123,:] "" ANALYZER_MODE ${PVS_STUDIO_MODE}) + if (NOT "$ANALYZER_MODE" STREQUAL "GA") + list (APPEND PVS_STUDIO_ARGS -a "${ANALYZER_MODE}") + endif() + + set(PVS_STUDIO_PLOGS "") + + set(PVS_STUDIO_RECURSIVE_TARGETS_NEW) + if (${PVS_STUDIO_RECURSIVE}) + foreach (TARGET IN LISTS PVS_STUDIO_ANALYZE) + list(APPEND PVS_STUDIO_RECURSIVE_TARGETS_NEW "${TARGET}") + pvs_studio_get_recursive_targets("${TARGET}") + endforeach() + endif() + + set(inc_path) + + foreach (TARGET ${PVS_STUDIO_ANALYZE}) + set(DIR "${CMAKE_CURRENT_SOURCE_DIR}") + string(FIND "${TARGET}" ":" DELIM) + if ("${DELIM}" GREATER "-1") + math(EXPR DELIMI "${DELIM}+1") + string(SUBSTRING "${TARGET}" "${DELIMI}" "-1" DIR) + string(SUBSTRING "${TARGET}" "0" "${DELIM}" TARGET) + pvs_studio_join_path(DIR "${CMAKE_CURRENT_SOURCE_DIR}" "${DIR}") + else() + get_target_property(TARGET_SOURCE_DIR "${TARGET}" SOURCE_DIR) + if (EXISTS "${TARGET_SOURCE_DIR}") + set(DIR "${TARGET_SOURCE_DIR}") + endif() + endif() + pvs_studio_analyze_target("${TARGET}" "${DIR}") + list(APPEND PVS_STUDIO_DEPENDS "${TARGET}") + + if ("${inc_path}" STREQUAL "") + set(inc_path "$") + else() + set(inc_path "${inc_path}$$") + endif() + endforeach() + + foreach (TARGET ${PVS_STUDIO_RECURSIVE_TARGETS_NEW}) + set(DIR "${CMAKE_CURRENT_SOURCE_DIR}") + get_target_property(TARGET_SOURCE_DIR "${TARGET}" SOURCE_DIR) + if (EXISTS "${TARGET_SOURCE_DIR}") + set(DIR "${TARGET_SOURCE_DIR}") + endif() + pvs_studio_analyze_target("${TARGET}" "${DIR}") + list(APPEND PVS_STUDIO_DEPENDS "${TARGET}") + endforeach() + + set(PVS_STUDIO_TARGET_CXX_FLAGS "") + set(PVS_STUDIO_TARGET_C_FLAGS "") + foreach (SOURCE ${PVS_STUDIO_SOURCES}) + pvs_studio_analyze_file("${SOURCE}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") + endforeach() + + if (PVS_STUDIO_COMPILE_COMMANDS) + set(COMPILE_COMMANDS_LOG "${PVS_STUDIO_LOG}.pvs.analyzer.raw") + if (NOT CMAKE_EXPORT_COMPILE_COMMANDS) + message(FATAL_ERROR "You should set CMAKE_EXPORT_COMPILE_COMMANDS to TRUE") + endif() + add_custom_command( + OUTPUT "${COMPILE_COMMANDS_LOG}" + COMMAND "${PVS_STUDIO_BIN}" analyze -i + --output-file "${COMPILE_COMMANDS_LOG}.always" + ${PVS_STUDIO_ARGS} + COMMENT "Analyzing with PVS-Studio" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + DEPENDS "${PVS_STUDIO_SUPPRESS_BASE}" "${PVS_STUDIO_DEPENDS}" + ) + list(APPEND PVS_STUDIO_PLOGS_LOGS "${COMPILE_COMMANDS_LOG}.always") + list(APPEND PVS_STUDIO_PLOGS_DEPENDENCIES "${COMPILE_COMMANDS_LOG}") + endif() + + pvs_studio_relative_path(LOG_RELATIVE "${CMAKE_BINARY_DIR}" "${PVS_STUDIO_LOG}") + if (PVS_STUDIO_PLOGS OR PVS_STUDIO_COMPILE_COMMANDS) + if (CMAKE_HOST_WIN32) + string(REPLACE / \\ PVS_STUDIO_PLOGS "${PVS_STUDIO_PLOGS}") + if (CMAKE_GENERATOR MATCHES "NMake") + set(COMMAND_TYPE_FILE "${CMAKE_BINARY_DIR}/PVSConcatAllLogs.cmd") + + # The number of files that will be merged in one call to the type command + set(STEP_SIZE 30) + set(BEGIN 0) + + list(APPEND PVS_STUDIO_PLOGS ${PVS_STUDIO_PLOGS_LOGS}) + list(LENGTH PVS_STUDIO_PLOGS END) + + # Creating a bat file to call the 'type' command + file(WRITE ${COMMAND_TYPE_FILE} "@echo off\nbreak > ${PVS_STUDIO_LOG}\n") + + while(BEGIN LESS END) + list(SUBLIST PVS_STUDIO_PLOGS ${BEGIN} ${STEP_SIZE} NEW_LIST) + file(APPEND ${COMMAND_TYPE_FILE} "type ${NEW_LIST} >> ${PVS_STUDIO_LOG} 2>nul || cd .\n") + math(EXPR BEGIN "${BEGIN} + ${STEP_SIZE}") + endwhile() + + list(APPEND COMMANDS COMMAND call ${COMMAND_TYPE_FILE}) + else() + set(COMMANDS COMMAND type ${PVS_STUDIO_PLOGS} ${PVS_STUDIO_PLOGS_LOGS} > "${PVS_STUDIO_LOG}" 2>nul || cd .) + endif() + else() + set(COMMANDS COMMAND cat ${PVS_STUDIO_PLOGS} ${PVS_STUDIO_PLOGS_LOGS} > "${PVS_STUDIO_LOG}" 2>/dev/null || true) + endif() + set(COMMENT "Generating ${LOG_RELATIVE}") + if (NOT "${PVS_STUDIO_FORMAT}" STREQUAL "" OR PVS_STUDIO_OUTPUT) + if ("${PVS_STUDIO_FORMAT}" STREQUAL "") + set(PVS_STUDIO_FORMAT "errorfile") + endif() + if (PVS_STUDIO_HIDE_HELP) + set(PVS_STUDIO_CONVERTER_ARGS ${PVS_STUDIO_CONVERTER_ARGS} --noHelpMessages) + endif() + if (PVS_STUDIO_OUTPUT) + set(PVS_STUDIO_CONVERTER_ARGS ${PVS_STUDIO_CONVERTER_ARGS} --stdout) + endif() + list(APPEND COMMANDS + COMMAND "${CMAKE_COMMAND}" -E remove -f "${PVS_STUDIO_LOG}.pvs.raw" + COMMAND "${CMAKE_COMMAND}" -E rename "${PVS_STUDIO_LOG}" "${PVS_STUDIO_LOG}.pvs.raw" + COMMAND "${PVS_STUDIO_CONVERTER}" "${PVS_STUDIO_CONVERTER_ARGS}" -t "${PVS_STUDIO_FORMAT}" "${PVS_STUDIO_LOG}.pvs.raw" -o "${PVS_STUDIO_LOG}" -a "${PVS_STUDIO_MODE}") + if (NOT PVS_STUDIO_KEEP_COMBINED_PLOG) + list(APPEND COMMANDS COMMAND "${CMAKE_COMMAND}" -E remove -f "${PVS_STUDIO_LOG}.pvs.raw") + endif() + endif() + else() + set(COMMANDS COMMAND "${CMAKE_COMMAND}" -E touch "${PVS_STUDIO_LOG}") + set(COMMENT "Generating ${LOG_RELATIVE}: no sources found") + endif() + + if (CMAKE_HOST_WIN32) + string(REPLACE / \\ PVS_STUDIO_LOG "${PVS_STUDIO_LOG}") + endif() + + if (CMAKE_GENERATOR STREQUAL "Unix Makefiles") + get_filename_component(LOG_NAME ${LOG_RELATIVE} NAME) + set(LOG_TARGET "${PVS_STUDIO_TARGET}-${LOG_NAME}-log") + add_custom_target("${LOG_TARGET}" + BYPRODUCTS "${PVS_STUDIO_LOG}" + ${COMMANDS} + COMMENT "${COMMENT}" + DEPENDS ${PVS_STUDIO_PLOGS} ${PVS_STUDIO_PLOGS_DEPENDENCIES} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") + else() + set(LOG_TARGET "${PVS_STUDIO_LOG}") + add_custom_command(OUTPUT "${LOG_TARGET}" + ${COMMANDS} + COMMENT "${COMMENT}" + DEPENDS ${PVS_STUDIO_PLOGS} ${PVS_STUDIO_PLOGS_DEPENDENCIES} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") + endif() + + if (PVS_STUDIO_ALL) + set(ALL "ALL") + else() + set(ALL "") + endif() + + add_custom_target("${PVS_STUDIO_TARGET}" ${ALL} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + DEPENDS ${PVS_STUDIO_DEPENDS} "${LOG_TARGET}") + + # A workaround to add implicit dependencies of source files from include directories + set_target_properties("${PVS_STUDIO_TARGET}" PROPERTIES INCLUDE_DIRECTORIES "${inc_path}") + + if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") + set(props_file "${CMAKE_BINARY_DIR}/${PVS_STUDIO_TARGET}.user.props") + file(WRITE "${props_file}" [=[ + + + + + + + + true + + + +]=]) + set_target_properties("${PVS_STUDIO_TARGET}" PROPERTIES VS_USER_PROPS "${props_file}") + endif() +endfunction() diff --git a/cmake/tools/FindClangTidy.cmake b/cmake/tools/FindClangTidy.cmake index 1c6a227..106b15a 100644 --- a/cmake/tools/FindClangTidy.cmake +++ b/cmake/tools/FindClangTidy.cmake @@ -1,21 +1,17 @@ -if(ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_COMMAND NAMES clang-tidy) +find_program(CLANG_TIDY_COMMAND NAMES clang-tidy) - if(NOT CLANG_TIDY_COMMAND) - message(WARNING "CMake_RUN_CLANG_TIDY is ON but clang-tidy is not found!") - set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) - else() +if(NOT CLANG_TIDY_COMMAND) + + message(WARNING "CMake_RUN_CLANG_TIDY is ON but clang-tidy is not found!") + set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) + +else() - message(STATUS "CMake_RUN_CLANG_TIDY is ON") - set(CLANGTIDY_EXTRA_ARGS "-extra-arg=-Wno-unknown-warning-option") - set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND};-p=${CMAKE_BINARY_DIR};${CLANGTIDY_EXTRA_ARGS}" CACHE STRING "" FORCE) + message(STATUS "CMake_RUN_CLANG_TIDY is ON") + + # Seems that clang-tidy fails to recognize the /EHsc after -- (the parameters given to cl.exe). + # Refer to https://gitlab.kitware.com/cmake/cmake/-/issues/20512 about the issue. + + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}" "--extra-arg=/EHsc" CACHE STRING "" FORCE) - add_custom_target( - clang-tidy - COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${CMAKE_PROJECT_NAME} - COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target clang-tidy - COMMENT "Running clang-tidy..." - ) - set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - endif() -endif(ENABLE_CLANG_TIDY) +endif() diff --git a/src/developer/mock_serial_port.cpp b/src/developer/mock_serial_port.cpp index 7c83e82..43db037 100644 --- a/src/developer/mock_serial_port.cpp +++ b/src/developer/mock_serial_port.cpp @@ -3,7 +3,7 @@ namespace AqualinkAutomate::Developer { mock_serial_port::mock_serial_port(Types::ExecutorType executor) : - m_Executor(executor), + m_Executor(std::move(executor)), m_WriteDelayTimer(m_Executor), m_RandomDevice{}, m_Distribution(32, 127), diff --git a/src/developer/mock_serial_port.h b/src/developer/mock_serial_port.h index 404cae9..b3f0b35 100644 --- a/src/developer/mock_serial_port.h +++ b/src/developer/mock_serial_port.h @@ -300,6 +300,7 @@ namespace AqualinkAutomate::Developer case FileReadErrors::ErrorFileReachedEOF: ec = boost::asio::error::eof; keep_reading = false; + break; case FileReadErrors::ErrorDuringRead: case FileReadErrors::NoDataWasRead: diff --git a/src/exceptions/exception_certificate_invalidformat.cpp b/src/exceptions/exception_certificate_invalidformat.cpp index 9dd4e09..c41f751 100644 --- a/src/exceptions/exception_certificate_invalidformat.cpp +++ b/src/exceptions/exception_certificate_invalidformat.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Certificate_InvalidFormat::CERTIFICATE_INVALID_FORMAT_MESSAGE{ "CERTIFICATE_INVALID_FORMAT_MESSAGE" }; + Certificate_InvalidFormat::Certificate_InvalidFormat() : GenericAqualinkException(CERTIFICATE_INVALID_FORMAT_MESSAGE) { diff --git a/src/exceptions/exception_certificate_invalidformat.h b/src/exceptions/exception_certificate_invalidformat.h index 50c1fa9..653a360 100644 --- a/src/exceptions/exception_certificate_invalidformat.h +++ b/src/exceptions/exception_certificate_invalidformat.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Certificate_InvalidFormat : public GenericAqualinkException { - static constexpr std::string CERTIFICATE_INVALID_FORMAT_MESSAGE{ "" }; + static const std::string CERTIFICATE_INVALID_FORMAT_MESSAGE; public: Certificate_InvalidFormat(); diff --git a/src/exceptions/exception_certificate_notfound.cpp b/src/exceptions/exception_certificate_notfound.cpp index 324660f..02206da 100644 --- a/src/exceptions/exception_certificate_notfound.cpp +++ b/src/exceptions/exception_certificate_notfound.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Certificate_NotFound::CERTIFICATE_NOT_FOUND_MESSAGE{ "CERTIFICATE_NOT_FOUND_MESSAGE" }; + Certificate_NotFound::Certificate_NotFound() : GenericAqualinkException(CERTIFICATE_NOT_FOUND_MESSAGE) { diff --git a/src/exceptions/exception_certificate_notfound.h b/src/exceptions/exception_certificate_notfound.h index 3b4683a..d76391a 100644 --- a/src/exceptions/exception_certificate_notfound.h +++ b/src/exceptions/exception_certificate_notfound.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Certificate_NotFound : public GenericAqualinkException { - static constexpr std::string CERTIFICATE_NOT_FOUND_MESSAGE{ "" }; + static const std::string CERTIFICATE_NOT_FOUND_MESSAGE; public: Certificate_NotFound(); diff --git a/src/exceptions/exception_http_duplicateroute.cpp b/src/exceptions/exception_http_duplicateroute.cpp index 7a3fb21..5d765ba 100644 --- a/src/exceptions/exception_http_duplicateroute.cpp +++ b/src/exceptions/exception_http_duplicateroute.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string HTTP_DuplicateRoute::DUPLICATE_ROUTE_MESSAGE{ "DUPLICATE_ROUTE_MESSAGE" }; + HTTP_DuplicateRoute::HTTP_DuplicateRoute() : GenericAqualinkException(DUPLICATE_ROUTE_MESSAGE) { LogTrace(Channel::Exceptions, "HTTP_DuplicateRoute exception was constructed"); diff --git a/src/exceptions/exception_http_duplicateroute.h b/src/exceptions/exception_http_duplicateroute.h index 06f621b..bd5329c 100644 --- a/src/exceptions/exception_http_duplicateroute.h +++ b/src/exceptions/exception_http_duplicateroute.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class HTTP_DuplicateRoute : public GenericAqualinkException { - static constexpr std::string DUPLICATE_ROUTE_MESSAGE{""}; + static const std::string DUPLICATE_ROUTE_MESSAGE; public: HTTP_DuplicateRoute(); diff --git a/src/exceptions/exception_hubnotfound.cpp b/src/exceptions/exception_hubnotfound.cpp index 12734b5..d53fbb5 100644 --- a/src/exceptions/exception_hubnotfound.cpp +++ b/src/exceptions/exception_hubnotfound.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Hub_NotFound::HUB_NOT_FOUND_MESSAGE{ "HUB_NOT_FOUND_MESSAGE" }; + Hub_NotFound::Hub_NotFound() : GenericAqualinkException(HUB_NOT_FOUND_MESSAGE) { diff --git a/src/exceptions/exception_hubnotfound.h b/src/exceptions/exception_hubnotfound.h index a98e344..ff08206 100644 --- a/src/exceptions/exception_hubnotfound.h +++ b/src/exceptions/exception_hubnotfound.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Hub_NotFound : public GenericAqualinkException { - static constexpr std::string HUB_NOT_FOUND_MESSAGE{ "" }; + static const std::string HUB_NOT_FOUND_MESSAGE; public: Hub_NotFound(); diff --git a/src/exceptions/exception_notimplemented.cpp b/src/exceptions/exception_notimplemented.cpp index c7dc984..bf939fe 100644 --- a/src/exceptions/exception_notimplemented.cpp +++ b/src/exceptions/exception_notimplemented.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string NotImplemented::NOT_IMPLEMENTED_MESSAGE{ "NOT_IMPLEMENTED_MESSAGE" }; + NotImplemented::NotImplemented() : GenericAqualinkException(NOT_IMPLEMENTED_MESSAGE) { diff --git a/src/exceptions/exception_notimplemented.h b/src/exceptions/exception_notimplemented.h index 6399755..2c0218f 100644 --- a/src/exceptions/exception_notimplemented.h +++ b/src/exceptions/exception_notimplemented.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class NotImplemented : public GenericAqualinkException { - static constexpr std::string NOT_IMPLEMENTED_MESSAGE{ "" }; + static const std::string NOT_IMPLEMENTED_MESSAGE; public: NotImplemented(); diff --git a/src/exceptions/exception_optionparsingfailed.cpp b/src/exceptions/exception_optionparsingfailed.cpp index 85faaf3..b08a059 100644 --- a/src/exceptions/exception_optionparsingfailed.cpp +++ b/src/exceptions/exception_optionparsingfailed.cpp @@ -8,6 +8,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string OptionParsingFailed::OPTION_PARSING_FAILED_MESSAGE{ "OPTION_PARSING_FAILED_MESSAGE" }; + OptionParsingFailed::OptionParsingFailed() : GenericAqualinkException(OPTION_PARSING_FAILED_MESSAGE) { diff --git a/src/exceptions/exception_optionparsingfailed.h b/src/exceptions/exception_optionparsingfailed.h index 64b5458..8e5a1f5 100644 --- a/src/exceptions/exception_optionparsingfailed.h +++ b/src/exceptions/exception_optionparsingfailed.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class OptionParsingFailed : public GenericAqualinkException { - static constexpr std::string OPTION_PARSING_FAILED_MESSAGE{ "" }; + static const std::string OPTION_PARSING_FAILED_MESSAGE; public: OptionParsingFailed(); diff --git a/src/exceptions/exception_options_conflictingoptions.cpp b/src/exceptions/exception_options_conflictingoptions.cpp index c40d2c9..94b4c4a 100644 --- a/src/exceptions/exception_options_conflictingoptions.cpp +++ b/src/exceptions/exception_options_conflictingoptions.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Options_ConflictingOptions::OPTION_CONFLICTING_OPTIONS_MESSAGE{ "OPTION_CONFLICTING_OPTIONS_MESSAGE" }; + Options_ConflictingOptions::Options_ConflictingOptions() : OptionParsingFailed(OPTION_CONFLICTING_OPTIONS_MESSAGE) { diff --git a/src/exceptions/exception_options_conflictingoptions.h b/src/exceptions/exception_options_conflictingoptions.h index 2e068ed..b4a1ac3 100644 --- a/src/exceptions/exception_options_conflictingoptions.h +++ b/src/exceptions/exception_options_conflictingoptions.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Options_ConflictingOptions : public OptionParsingFailed { - static constexpr std::string OPTION_CONFLICTING_OPTIONS_MESSAGE{ "" }; + static const std::string OPTION_CONFLICTING_OPTIONS_MESSAGE; public: Options_ConflictingOptions(); diff --git a/src/exceptions/exception_options_missingdependency.cpp b/src/exceptions/exception_options_missingdependency.cpp index f0faa3f..c2bfdf7 100644 --- a/src/exceptions/exception_options_missingdependency.cpp +++ b/src/exceptions/exception_options_missingdependency.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Options_MissingDependency::OPTION_MISSING_DEPENDENCY_MESSAGE{ "OPTION_MISSING_DEPENDENCY_MESSAGE" }; + Options_MissingDependency::Options_MissingDependency() : OptionParsingFailed(OPTION_MISSING_DEPENDENCY_MESSAGE) { diff --git a/src/exceptions/exception_options_missingdependency.h b/src/exceptions/exception_options_missingdependency.h index be57b69..7922083 100644 --- a/src/exceptions/exception_options_missingdependency.h +++ b/src/exceptions/exception_options_missingdependency.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Options_MissingDependency : public OptionParsingFailed { - static constexpr std::string OPTION_MISSING_DEPENDENCY_MESSAGE{ "" }; + static const std::string OPTION_MISSING_DEPENDENCY_MESSAGE; public: Options_MissingDependency(); diff --git a/src/exceptions/exception_optionshelporversion.cpp b/src/exceptions/exception_optionshelporversion.cpp index 2a9b1f4..6ce9692 100644 --- a/src/exceptions/exception_optionshelporversion.cpp +++ b/src/exceptions/exception_optionshelporversion.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string OptionsHelpOrVersion::OPTIONS_HELP_OR_VERSION_MESSAGE{ "OPTIONS_HELP_OR_VERSION_MESSAGE" }; + OptionsHelpOrVersion::OptionsHelpOrVersion() : GenericAqualinkException(OPTIONS_HELP_OR_VERSION_MESSAGE) { diff --git a/src/exceptions/exception_optionshelporversion.h b/src/exceptions/exception_optionshelporversion.h index ac081c5..fec1ea0 100644 --- a/src/exceptions/exception_optionshelporversion.h +++ b/src/exceptions/exception_optionshelporversion.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class OptionsHelpOrVersion : public GenericAqualinkException { - static constexpr std::string OPTIONS_HELP_OR_VERSION_MESSAGE{ "" }; + static const std::string OPTIONS_HELP_OR_VERSION_MESSAGE; public: OptionsHelpOrVersion(); diff --git a/src/exceptions/exception_serial_invalidmode.cpp b/src/exceptions/exception_serial_invalidmode.cpp index c321831..dd904bd 100644 --- a/src/exceptions/exception_serial_invalidmode.cpp +++ b/src/exceptions/exception_serial_invalidmode.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Serial_InvalidMode::SERIAL_INVALID_MODE_MESSAGE{ "SERIAL_INVALID_MODE_MESSAGE" }; + Serial_InvalidMode::Serial_InvalidMode() : GenericAqualinkException(SERIAL_INVALID_MODE_MESSAGE) { diff --git a/src/exceptions/exception_serial_invalidmode.h b/src/exceptions/exception_serial_invalidmode.h index 8421d6b..94deb3e 100644 --- a/src/exceptions/exception_serial_invalidmode.h +++ b/src/exceptions/exception_serial_invalidmode.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Serial_InvalidMode : public GenericAqualinkException { - static constexpr std::string SERIAL_INVALID_MODE_MESSAGE{ "" }; + static const std::string SERIAL_INVALID_MODE_MESSAGE; public: Serial_InvalidMode(); diff --git a/src/exceptions/exception_signallingstatscounter_badaccess.cpp b/src/exceptions/exception_signallingstatscounter_badaccess.cpp index e942fdd..407e093 100644 --- a/src/exceptions/exception_signallingstatscounter_badaccess.cpp +++ b/src/exceptions/exception_signallingstatscounter_badaccess.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string SignallingStatsCounter_BadAccess::BAD_ACCESS_MESSAGE{ "BAD_ACCESS_MESSAGE" }; + SignallingStatsCounter_BadAccess::SignallingStatsCounter_BadAccess() : GenericAqualinkException(BAD_ACCESS_MESSAGE) { diff --git a/src/exceptions/exception_signallingstatscounter_badaccess.h b/src/exceptions/exception_signallingstatscounter_badaccess.h index 5dde777..b02b4d6 100644 --- a/src/exceptions/exception_signallingstatscounter_badaccess.h +++ b/src/exceptions/exception_signallingstatscounter_badaccess.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class SignallingStatsCounter_BadAccess : public GenericAqualinkException { - static constexpr std::string BAD_ACCESS_MESSAGE{ "" }; + static const std::string BAD_ACCESS_MESSAGE; public: SignallingStatsCounter_BadAccess(); diff --git a/src/exceptions/exception_traits_doesnotexist.cpp b/src/exceptions/exception_traits_doesnotexist.cpp index 8bb854f..6bddee8 100644 --- a/src/exceptions/exception_traits_doesnotexist.cpp +++ b/src/exceptions/exception_traits_doesnotexist.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Traits_DoesNotExist::TRAIT_DOES_NOT_EXIST_MESSAGE{ "TRAIT_DOES_NOT_EXIST_MESSAGE" }; + Traits_DoesNotExist::Traits_DoesNotExist() : GenericAqualinkException(TRAIT_DOES_NOT_EXIST_MESSAGE) { diff --git a/src/exceptions/exception_traits_doesnotexist.h b/src/exceptions/exception_traits_doesnotexist.h index be46c30..1d41c91 100644 --- a/src/exceptions/exception_traits_doesnotexist.h +++ b/src/exceptions/exception_traits_doesnotexist.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Traits_DoesNotExist : public GenericAqualinkException { - static constexpr std::string TRAIT_DOES_NOT_EXIST_MESSAGE{ "" }; + static const std::string TRAIT_DOES_NOT_EXIST_MESSAGE; public: Traits_DoesNotExist(); diff --git a/src/exceptions/exception_traits_failedtoset.cpp b/src/exceptions/exception_traits_failedtoset.cpp index ea73190..11967e9 100644 --- a/src/exceptions/exception_traits_failedtoset.cpp +++ b/src/exceptions/exception_traits_failedtoset.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Traits_FailedToSet::TRAIT_FAILED_TO_SET_MESSAGE{ "TRAIT_FAILED_TO_SET_MESSAGE" }; + Traits_FailedToSet::Traits_FailedToSet() : GenericAqualinkException(TRAIT_FAILED_TO_SET_MESSAGE) { diff --git a/src/exceptions/exception_traits_failedtoset.h b/src/exceptions/exception_traits_failedtoset.h index afa653f..d505732 100644 --- a/src/exceptions/exception_traits_failedtoset.h +++ b/src/exceptions/exception_traits_failedtoset.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Traits_FailedToSet : public GenericAqualinkException { - static constexpr std::string TRAIT_FAILED_TO_SET_MESSAGE{ "" }; + static const std::string TRAIT_FAILED_TO_SET_MESSAGE; public: Traits_FailedToSet(); diff --git a/src/exceptions/exception_traits_invalidtraitvalue.cpp b/src/exceptions/exception_traits_invalidtraitvalue.cpp index 9b92141..9605d2b 100644 --- a/src/exceptions/exception_traits_invalidtraitvalue.cpp +++ b/src/exceptions/exception_traits_invalidtraitvalue.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Traits_InvalidTraitValue::TRAIT_INVALID_TRAIT_VALUE_MESSAGE{ "TRAIT_INVALID_TRAIT_VALUE_MESSAGE" }; + Traits_InvalidTraitValue::Traits_InvalidTraitValue() : GenericAqualinkException(TRAIT_INVALID_TRAIT_VALUE_MESSAGE) { diff --git a/src/exceptions/exception_traits_invalidtraitvalue.h b/src/exceptions/exception_traits_invalidtraitvalue.h index 0f03554..d58d216 100644 --- a/src/exceptions/exception_traits_invalidtraitvalue.h +++ b/src/exceptions/exception_traits_invalidtraitvalue.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Traits_InvalidTraitValue : public GenericAqualinkException { - static constexpr std::string TRAIT_INVALID_TRAIT_VALUE_MESSAGE{ "" }; + static const std::string TRAIT_INVALID_TRAIT_VALUE_MESSAGE; public: Traits_InvalidTraitValue(); diff --git a/src/exceptions/exception_traits_notmutable.cpp b/src/exceptions/exception_traits_notmutable.cpp index 24b65a1..55b6314 100644 --- a/src/exceptions/exception_traits_notmutable.cpp +++ b/src/exceptions/exception_traits_notmutable.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string Traits_NotMutable::TRAIT_NOT_MUTABLE_MESSAGE{ "TRAIT_NOT_MUTABLE_MESSAGE" }; + Traits_NotMutable::Traits_NotMutable() : GenericAqualinkException(TRAIT_NOT_MUTABLE_MESSAGE) { diff --git a/src/exceptions/exception_traits_notmutable.h b/src/exceptions/exception_traits_notmutable.h index f188ea7..ee019f1 100644 --- a/src/exceptions/exception_traits_notmutable.h +++ b/src/exceptions/exception_traits_notmutable.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class Traits_NotMutable : public GenericAqualinkException { - static constexpr std::string TRAIT_NOT_MUTABLE_MESSAGE{ "" }; + static const std::string TRAIT_NOT_MUTABLE_MESSAGE; public: Traits_NotMutable(); diff --git a/src/exceptions/exception_webserver.cpp b/src/exceptions/exception_webserver.cpp index 4505ca3..1b9489d 100644 --- a/src/exceptions/exception_webserver.cpp +++ b/src/exceptions/exception_webserver.cpp @@ -6,6 +6,8 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::Exceptions { + const std::string WebServerException::OPTIONS_WEBSERVER_EXCEPTION_MESSAGE{ "OPTIONS_WEBSERVER_EXCEPTION_MESSAGE" }; + WebServerException::WebServerException(const std::string& message) : GenericAqualinkException(OPTIONS_WEBSERVER_EXCEPTION_MESSAGE) { diff --git a/src/exceptions/exception_webserver.h b/src/exceptions/exception_webserver.h index 5e8c562..5f9d2bc 100644 --- a/src/exceptions/exception_webserver.h +++ b/src/exceptions/exception_webserver.h @@ -9,7 +9,7 @@ namespace AqualinkAutomate::Exceptions class WebServerException : public GenericAqualinkException { - static constexpr std::string OPTIONS_WEBSERVER_EXCEPTION_MESSAGE{ "" }; + static const std::string OPTIONS_WEBSERVER_EXCEPTION_MESSAGE; public: WebServerException(const std::string& message); diff --git a/src/formatters/beast_stringview_formatter.cpp b/src/formatters/beast_stringview_formatter.cpp index 86cffe1..bb51234 100644 --- a/src/formatters/beast_stringview_formatter.cpp +++ b/src/formatters/beast_stringview_formatter.cpp @@ -11,7 +11,7 @@ namespace AqualinkAutomate::Formatters namespace std { - std::ostream& operator<<(std::ostream& os, const boost::beast::string_view& obj) + auto operator<<(std::ostream& os, const boost::beast::string_view& obj) -> std::ostream& { os << std::format("{}", obj); return os; diff --git a/src/formatters/beast_stringview_formatter.h b/src/formatters/beast_stringview_formatter.h index 1ed012f..ebc4b92 100644 --- a/src/formatters/beast_stringview_formatter.h +++ b/src/formatters/beast_stringview_formatter.h @@ -18,7 +18,7 @@ namespace AqualinkAutomate::Formatters namespace std { - std::ostream& operator<<(std::ostream& os, const boost::beast::string_view& obj); + auto operator<<(std::ostream& os, const boost::beast::string_view& obj) -> std::ostream&; } // namespace std diff --git a/src/formatters/units_dimensionless_formatter.cpp b/src/formatters/units_dimensionless_formatter.cpp index db545a6..417feb7 100644 --- a/src/formatters/units_dimensionless_formatter.cpp +++ b/src/formatters/units_dimensionless_formatter.cpp @@ -11,7 +11,7 @@ namespace AqualinkAutomate::Formatters namespace std { - std::ostream& operator<<(std::ostream& os, const AqualinkAutomate::Units::ppm_quantity& obj) + auto operator<<(std::ostream& os, const AqualinkAutomate::Units::ppm_quantity& obj) -> std::ostream& { os << std::format("{}", obj); return os; diff --git a/src/formatters/units_dimensionless_formatter.h b/src/formatters/units_dimensionless_formatter.h index 0d34d55..0bb25a6 100644 --- a/src/formatters/units_dimensionless_formatter.h +++ b/src/formatters/units_dimensionless_formatter.h @@ -17,7 +17,7 @@ namespace AqualinkAutomate::Formatters namespace std { - std::ostream& operator<<(std::ostream& os, const AqualinkAutomate::Units::ppm_quantity& obj); + auto operator<<(std::ostream& os, const AqualinkAutomate::Units::ppm_quantity& obj) -> std::ostream&; } // namespace std diff --git a/src/http/server/listener.cpp b/src/http/server/listener.cpp index 972c45b..1888491 100644 --- a/src/http/server/listener.cpp +++ b/src/http/server/listener.cpp @@ -13,12 +13,12 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::HTTP { Listener::Listener(Types::ExecutorType executor, boost::asio::ip::tcp::endpoint endpoint) : - Listener(executor, endpoint, std::nullopt) + Listener(std::move(executor), endpoint, std::nullopt) { } Listener::Listener(Types::ExecutorType executor, boost::asio::ip::tcp::endpoint endpoint, boost::asio::ssl::context& ssl_context) : - Listener(executor, endpoint, std::make_optional(std::ref(ssl_context))) + Listener(std::move(executor), endpoint, std::make_optional(std::ref(ssl_context))) { } diff --git a/src/http/webroute_equipment.cpp b/src/http/webroute_equipment.cpp index 36ec790..52efb75 100644 --- a/src/http/webroute_equipment.cpp +++ b/src/http/webroute_equipment.cpp @@ -15,7 +15,7 @@ namespace AqualinkAutomate::HTTP m_StatisticsHub = hub_locator.Find(); } - Message WebRoute_Equipment::OnRequest(HTTP::Request req) + Message WebRoute_Equipment::OnRequest(const HTTP::Request& req) { nlohmann::json jandy_equipment_json; diff --git a/src/http/webroute_equipment.h b/src/http/webroute_equipment.h index ad5430f..25c4a7c 100644 --- a/src/http/webroute_equipment.h +++ b/src/http/webroute_equipment.h @@ -17,7 +17,7 @@ namespace AqualinkAutomate::HTTP WebRoute_Equipment(Kernel::HubLocator& hub_locator); public: - virtual HTTP::Message OnRequest(HTTP::Request req) final; + virtual HTTP::Message OnRequest(const HTTP::Request& req) final; private: std::shared_ptr m_DataHub{ nullptr }; diff --git a/src/http/webroute_equipment_button.cpp b/src/http/webroute_equipment_button.cpp index 4dc276d..56b5370 100644 --- a/src/http/webroute_equipment_button.cpp +++ b/src/http/webroute_equipment_button.cpp @@ -19,13 +19,12 @@ using namespace AqualinkAutomate::Logging; namespace AqualinkAutomate::HTTP { - WebRoute_Equipment_Button::WebRoute_Equipment_Button(Kernel::HubLocator& hub_locator) : - Interfaces::IWebRoute() + WebRoute_Equipment_Button::WebRoute_Equipment_Button(Kernel::HubLocator& hub_locator) { m_DataHub = hub_locator.Find(); } - HTTP::Message WebRoute_Equipment_Button::OnRequest(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Button::OnRequest(const HTTP::Request& req) { switch (req.method()) { @@ -40,7 +39,7 @@ namespace AqualinkAutomate::HTTP } } - HTTP::Message WebRoute_Equipment_Button::ButtonIndividual_GetHandler(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Button::ButtonIndividual_GetHandler(const HTTP::Request& req) { const std::string UNKNOWN_BUTTON_ID{ "Unknown Or Missing Button Id" }; @@ -93,7 +92,7 @@ namespace AqualinkAutomate::HTTP } } - HTTP::Message WebRoute_Equipment_Button::ButtonIndividual_PostHandler(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Button::ButtonIndividual_PostHandler(const HTTP::Request& req) { const std::string UNKNOWN_BUTTON_ID{ "Unknown Or Missing Button Id" }; @@ -133,7 +132,7 @@ namespace AqualinkAutomate::HTTP } } - HTTP::Message WebRoute_Equipment_Button::Report_ButtonDoesntExist(HTTP::Request req, const std::string& button_id) + HTTP::Message WebRoute_Equipment_Button::Report_ButtonDoesntExist(const HTTP::Request& req, const std::string& button_id) { LogInfo(Channel::Web, std::format("Received an invalid button id ('{}'); rejecting button request", button_id)); @@ -149,13 +148,13 @@ namespace AqualinkAutomate::HTTP return resp; } - HTTP::Message WebRoute_Equipment_Button::Report_ButtonIsInactive(HTTP::Request req, const std::string& button_id) + HTTP::Message WebRoute_Equipment_Button::Report_ButtonIsInactive(const HTTP::Request& req, const std::string& button_id) { ///FIXME throw; } - HTTP::Message WebRoute_Equipment_Button::Report_SystemIsInactive(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Button::Report_SystemIsInactive(const HTTP::Request& req) { LogInfo(Channel::Web, "Aqualink Automate has not yet initialised (PoolConfiguration == Unknown); rejecting button action request"); diff --git a/src/http/webroute_equipment_button.h b/src/http/webroute_equipment_button.h index 8508f1f..9a7fe9b 100644 --- a/src/http/webroute_equipment_button.h +++ b/src/http/webroute_equipment_button.h @@ -22,16 +22,16 @@ namespace AqualinkAutomate::HTTP WebRoute_Equipment_Button(Kernel::HubLocator& hub_locator); public: - virtual HTTP::Message OnRequest(HTTP::Request req) final; + virtual HTTP::Message OnRequest(const HTTP::Request& req) final; public: - HTTP::Message ButtonIndividual_GetHandler(HTTP::Request req); - HTTP::Message ButtonIndividual_PostHandler(HTTP::Request req); + HTTP::Message ButtonIndividual_GetHandler(const HTTP::Request& req); + HTTP::Message ButtonIndividual_PostHandler(const HTTP::Request& req); private: - HTTP::Message Report_ButtonDoesntExist(HTTP::Request req, const std::string& button_id); - HTTP::Message Report_ButtonIsInactive(HTTP::Request req, const std::string& button_id); - HTTP::Message Report_SystemIsInactive(HTTP::Request req); + HTTP::Message Report_ButtonDoesntExist(const HTTP::Request& req, const std::string& button_id); + HTTP::Message Report_ButtonIsInactive(const HTTP::Request& req, const std::string& button_id); + HTTP::Message Report_SystemIsInactive(const HTTP::Request& req); private: std::shared_ptr m_DataHub{ nullptr }; diff --git a/src/http/webroute_equipment_buttons.cpp b/src/http/webroute_equipment_buttons.cpp index d019701..b26633e 100644 --- a/src/http/webroute_equipment_buttons.cpp +++ b/src/http/webroute_equipment_buttons.cpp @@ -25,7 +25,7 @@ namespace AqualinkAutomate::HTTP m_DataHub = hub_locator.Find(); } - HTTP::Message WebRoute_Equipment_Buttons::OnRequest(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Buttons::OnRequest(const HTTP::Request& req) { switch (req.method()) { @@ -40,7 +40,7 @@ namespace AqualinkAutomate::HTTP } } - HTTP::Message WebRoute_Equipment_Buttons::ButtonCollection_GetHandler(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Buttons::ButtonCollection_GetHandler(const HTTP::Request& req) { nlohmann::json buttons, all_buttons; @@ -78,7 +78,7 @@ namespace AqualinkAutomate::HTTP return resp; } - HTTP::Message WebRoute_Equipment_Buttons::ButtonCollection_PostHandler(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Buttons::ButtonCollection_PostHandler(const HTTP::Request& req) { HTTP::Response resp{HTTP::Status::ok, req.version()}; diff --git a/src/http/webroute_equipment_buttons.h b/src/http/webroute_equipment_buttons.h index faadf89..adefbae 100644 --- a/src/http/webroute_equipment_buttons.h +++ b/src/http/webroute_equipment_buttons.h @@ -22,11 +22,11 @@ namespace AqualinkAutomate::HTTP WebRoute_Equipment_Buttons(Kernel::HubLocator& hub_locator); public: - virtual HTTP::Message OnRequest(HTTP::Request req) final; + virtual HTTP::Message OnRequest(const HTTP::Request& req) final; public: - HTTP::Message ButtonCollection_GetHandler(HTTP::Request req); - HTTP::Message ButtonCollection_PostHandler(HTTP::Request req); + HTTP::Message ButtonCollection_GetHandler(const HTTP::Request& req); + HTTP::Message ButtonCollection_PostHandler(const HTTP::Request& req); private: std::shared_ptr m_DataHub{ nullptr }; diff --git a/src/http/webroute_equipment_devices.cpp b/src/http/webroute_equipment_devices.cpp index ec59664..756874d 100644 --- a/src/http/webroute_equipment_devices.cpp +++ b/src/http/webroute_equipment_devices.cpp @@ -5,13 +5,12 @@ namespace AqualinkAutomate::HTTP { - WebRoute_Equipment_Devices::WebRoute_Equipment_Devices(Kernel::HubLocator& hub_locator) : - Interfaces::IWebRoute() + WebRoute_Equipment_Devices::WebRoute_Equipment_Devices(Kernel::HubLocator& hub_locator) { m_DataHub = hub_locator.Find(); } - HTTP::Message WebRoute_Equipment_Devices::OnRequest(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Devices::OnRequest(const HTTP::Request& req) { HTTP::Response resp{HTTP::Status::ok, req.version()}; diff --git a/src/http/webroute_equipment_devices.h b/src/http/webroute_equipment_devices.h index 66156fb..b8fccde 100644 --- a/src/http/webroute_equipment_devices.h +++ b/src/http/webroute_equipment_devices.h @@ -16,7 +16,7 @@ namespace AqualinkAutomate::HTTP WebRoute_Equipment_Devices(Kernel::HubLocator& hub_locator); public: - virtual HTTP::Message OnRequest(HTTP::Request req) final; + virtual HTTP::Message OnRequest(const HTTP::Request& req) final; private: std::shared_ptr m_DataHub{ nullptr }; diff --git a/src/http/webroute_equipment_version.cpp b/src/http/webroute_equipment_version.cpp index ed473a3..876df51 100644 --- a/src/http/webroute_equipment_version.cpp +++ b/src/http/webroute_equipment_version.cpp @@ -11,7 +11,7 @@ namespace AqualinkAutomate::HTTP m_DataHub = hub_locator.Find(); } - HTTP::Message WebRoute_Equipment_Version::OnRequest(HTTP::Request req) + HTTP::Message WebRoute_Equipment_Version::OnRequest(const HTTP::Request& req) { HTTP::Response resp{HTTP::Status::ok, req.version()}; diff --git a/src/http/webroute_equipment_version.h b/src/http/webroute_equipment_version.h index 12ebe89..d92138f 100644 --- a/src/http/webroute_equipment_version.h +++ b/src/http/webroute_equipment_version.h @@ -16,7 +16,7 @@ namespace AqualinkAutomate::HTTP WebRoute_Equipment_Version(Kernel::HubLocator& hub_locator); public: - virtual HTTP::Message OnRequest(HTTP::Request req) final; + virtual HTTP::Message OnRequest(const HTTP::Request& req) final; private: std::shared_ptr m_DataHub{ nullptr }; diff --git a/src/http/webroute_page_equipment.cpp b/src/http/webroute_page_equipment.cpp index 18961f2..f0f9f3b 100644 --- a/src/http/webroute_page_equipment.cpp +++ b/src/http/webroute_page_equipment.cpp @@ -7,8 +7,7 @@ namespace AqualinkAutomate::HTTP { - WebRoute_Page_Equipment::WebRoute_Page_Equipment(Kernel::HubLocator& hub_locator) : - Interfaces::IWebPageRoute() + WebRoute_Page_Equipment::WebRoute_Page_Equipment(Kernel::HubLocator& hub_locator) { m_DataHub = hub_locator.Find(); } diff --git a/src/http/webroute_version.cpp b/src/http/webroute_version.cpp index 6917a05..f0bea84 100644 --- a/src/http/webroute_version.cpp +++ b/src/http/webroute_version.cpp @@ -7,7 +7,7 @@ namespace AqualinkAutomate::HTTP { - boost::beast::http::message_generator WebRoute_Version::OnRequest(HTTP::Request req) + boost::beast::http::message_generator WebRoute_Version::OnRequest(const HTTP::Request& req) { nlohmann::json version_info; diff --git a/src/http/webroute_version.h b/src/http/webroute_version.h index 04a099e..cba9b77 100644 --- a/src/http/webroute_version.h +++ b/src/http/webroute_version.h @@ -13,7 +13,7 @@ namespace AqualinkAutomate::HTTP virtual ~WebRoute_Version() = default; public: - virtual HTTP::Message OnRequest(HTTP::Request req) final; + virtual HTTP::Message OnRequest(const HTTP::Request& req) final; }; } diff --git a/src/http/websocket_equipment.cpp b/src/http/websocket_equipment.cpp index fffbc43..257a160 100644 --- a/src/http/websocket_equipment.cpp +++ b/src/http/websocket_equipment.cpp @@ -10,7 +10,6 @@ namespace AqualinkAutomate::HTTP { WebSocket_Equipment::WebSocket_Equipment(Kernel::HubLocator& hub_locator) : - Interfaces::IWebSocket(), m_ConfigChangeSlot(), m_StatusChangeSlot() { @@ -20,8 +19,8 @@ namespace AqualinkAutomate::HTTP void WebSocket_Equipment::OnOpen() { - m_ConfigChangeSlot = m_DataHub->ConfigUpdateSignal.connect(std::bind(&WebSocket_Equipment::HandleEvent_DataHubConfigUpdate, this, std::placeholders::_1)); - m_StatusChangeSlot = m_EquipmentHub->EquipmentStatusChangeSignal.connect(std::bind(&WebSocket_Equipment::HandleEvent_DataHubSystemUpdate, this, std::placeholders::_1)); + m_ConfigChangeSlot = m_DataHub->ConfigUpdateSignal.connect([this](auto&& PH1) { HandleEvent_DataHubConfigUpdate(std::forward(PH1)); }); + m_StatusChangeSlot = m_EquipmentHub->EquipmentStatusChangeSignal.connect([this](auto&& PH1) { HandleEvent_DataHubSystemUpdate(std::forward(PH1)); }); } void WebSocket_Equipment::OnMessage(const boost::beast::flat_buffer& buffer) @@ -46,7 +45,7 @@ namespace AqualinkAutomate::HTTP } else { - BroadcastMessage(std::move(HTTP::WebSocket_Event(config_update_event).Payload())); + BroadcastMessage(HTTP::WebSocket_Event(config_update_event).Payload()); } } @@ -58,7 +57,7 @@ namespace AqualinkAutomate::HTTP } else { - BroadcastMessage(std::move(HTTP::WebSocket_Event(system_update_event).Payload())); + BroadcastMessage(HTTP::WebSocket_Event(system_update_event).Payload()); } } diff --git a/src/interfaces/idevice.cpp b/src/interfaces/idevice.cpp index 6900505..6d0e500 100644 --- a/src/interfaces/idevice.cpp +++ b/src/interfaces/idevice.cpp @@ -8,10 +8,6 @@ namespace AqualinkAutomate::Interfaces { } - IDevice::~IDevice() - { - } - IDevice::IDevice(IDevice&& other) noexcept : m_DeviceId(std::move(other.m_DeviceId)) { diff --git a/src/interfaces/idevice.h b/src/interfaces/idevice.h index f1fcf3e..ec5580d 100644 --- a/src/interfaces/idevice.h +++ b/src/interfaces/idevice.h @@ -11,7 +11,7 @@ namespace AqualinkAutomate::Interfaces { public: IDevice(std::shared_ptr device_id); - virtual ~IDevice(); + virtual ~IDevice() = default; public: IDevice(const IDevice& other) = delete; diff --git a/src/interfaces/iequipment.cpp b/src/interfaces/iequipment.cpp index 63b2803..a8b47a7 100644 --- a/src/interfaces/iequipment.cpp +++ b/src/interfaces/iequipment.cpp @@ -4,11 +4,7 @@ namespace AqualinkAutomate::Interfaces { IEquipment::IEquipment(Types::ExecutorType executor) : - m_Executor(executor) - { - } - - IEquipment::~IEquipment() + m_Executor(std::move(executor)) { } diff --git a/src/interfaces/iequipment.h b/src/interfaces/iequipment.h index 740d293..14a1695 100644 --- a/src/interfaces/iequipment.h +++ b/src/interfaces/iequipment.h @@ -8,7 +8,7 @@ namespace AqualinkAutomate::Interfaces { public: IEquipment(Types::ExecutorType executor); - virtual ~IEquipment(); + virtual ~IEquipment() = default; protected: Types::ExecutorType m_Executor; diff --git a/src/interfaces/ihub.cpp b/src/interfaces/ihub.cpp index 0f87097..9eb6529 100644 --- a/src/interfaces/ihub.cpp +++ b/src/interfaces/ihub.cpp @@ -3,13 +3,7 @@ namespace AqualinkAutomate::Interfaces { - IHub::IHub() - { - } - - IHub::~IHub() - { - } + // NOTHING HERE } // namespace AqualinkAutomate::Interfaces diff --git a/src/interfaces/ihub.h b/src/interfaces/ihub.h index e00b167..01fa166 100644 --- a/src/interfaces/ihub.h +++ b/src/interfaces/ihub.h @@ -6,8 +6,8 @@ namespace AqualinkAutomate::Interfaces class IHub { public: - IHub(); - virtual ~IHub(); + IHub() = default; + virtual ~IHub() = default; }; } diff --git a/src/interfaces/imessagesignal_recv.h b/src/interfaces/imessagesignal_recv.h index 1ccf246..7f543d7 100644 --- a/src/interfaces/imessagesignal_recv.h +++ b/src/interfaces/imessagesignal_recv.h @@ -43,10 +43,6 @@ namespace AqualinkAutomate::Interfaces { LogTrace(Channel::Messages, "Could not retrieve signal shared_ptr from IMessageSignalRecv::GetSignal()"); } - else if (auto signal = signal_ptr.get(); nullptr == signal) - { - LogTrace(Channel::Messages, "Could not get underlying pointer (nullptr) from signal shared_ptr returned from IMessageSignalRecv::GetSignal()"); - } else if (auto upcast_ptr = dynamic_cast(this); nullptr == upcast_ptr) { const std::type_info& src_type = typeid(this); @@ -56,7 +52,7 @@ namespace AqualinkAutomate::Interfaces } else { - (*signal)(*upcast_ptr); + (*signal_ptr)(*upcast_ptr); } } }; diff --git a/src/interfaces/imessagesignal_send.h b/src/interfaces/imessagesignal_send.h index 5f6bf0a..481705a 100644 --- a/src/interfaces/imessagesignal_send.h +++ b/src/interfaces/imessagesignal_send.h @@ -43,10 +43,6 @@ namespace AqualinkAutomate::Interfaces { LogTrace(Channel::Messages, "Could not retrieve signal shared_ptr from IMessageSignalSend::GetPublisher()"); } - else if (auto publisher = publisher_ptr.get(); nullptr == publisher) - { - LogTrace(Channel::Messages, "Could not get underlying pointer (nullptr) from publisher shared_ptr returned from IMessageSignalSend::GetPublisher()"); - } else if (auto upcast_ptr = dynamic_cast(this); nullptr == upcast_ptr) { const std::type_info& src_type = typeid(this); @@ -56,7 +52,7 @@ namespace AqualinkAutomate::Interfaces } else { - (*publisher)(*upcast_ptr); + (*publisher_ptr)(*upcast_ptr); } } }; diff --git a/src/interfaces/iprofilingunit.cpp b/src/interfaces/iprofilingunit.cpp index 56368d6..12b7fba 100644 --- a/src/interfaces/iprofilingunit.cpp +++ b/src/interfaces/iprofilingunit.cpp @@ -5,8 +5,8 @@ namespace AqualinkAutomate::Interfaces { - IProfilingUnit::IProfilingUnit(const std::string& name) : - m_Name(name), + IProfilingUnit::IProfilingUnit(std::string name) : + m_Name(std::move(name)), m_UUID(boost::uuids::random_generator()()) { } diff --git a/src/interfaces/iprofilingunit.h b/src/interfaces/iprofilingunit.h index 92ee020..b771c3b 100644 --- a/src/interfaces/iprofilingunit.h +++ b/src/interfaces/iprofilingunit.h @@ -10,7 +10,7 @@ namespace AqualinkAutomate::Interfaces class IProfilingUnit { public: - IProfilingUnit(const std::string& name); + IProfilingUnit(std::string name); virtual ~IProfilingUnit() = default; public: diff --git a/src/interfaces/iserializable.cpp b/src/interfaces/iserializable.cpp index b5b1fb7..10f4515 100644 --- a/src/interfaces/iserializable.cpp +++ b/src/interfaces/iserializable.cpp @@ -3,13 +3,7 @@ namespace AqualinkAutomate::Interfaces { - ISerializable::ISerializable() - { - } - - ISerializable::~ISerializable() - { - } + // NOTHING HERE } // namespace AqualinkAutomate::Interfaces diff --git a/src/interfaces/iserializable.h b/src/interfaces/iserializable.h index 695d794..d7101ca 100644 --- a/src/interfaces/iserializable.h +++ b/src/interfaces/iserializable.h @@ -11,8 +11,8 @@ namespace AqualinkAutomate::Interfaces class ISerializable { public: - ISerializable(); - virtual ~ISerializable(); + ISerializable() = default; + virtual ~ISerializable() = default; public: virtual bool Serialize(std::vector& message_bytes) const = 0; diff --git a/src/interfaces/iserialport.cpp b/src/interfaces/iserialport.cpp index 5b240be..b4a0d77 100644 --- a/src/interfaces/iserialport.cpp +++ b/src/interfaces/iserialport.cpp @@ -3,13 +3,7 @@ namespace AqualinkAutomate::Interfaces { - ISerialPort::ISerialPort() - { - } - - ISerialPort::~ISerialPort() - { - } + // NOTHING HERE } // namespace AqualinkAutomate::Interfaces diff --git a/src/interfaces/iserialport.h b/src/interfaces/iserialport.h index bbde496..4cabaa1 100644 --- a/src/interfaces/iserialport.h +++ b/src/interfaces/iserialport.h @@ -8,8 +8,8 @@ namespace AqualinkAutomate::Interfaces class ISerialPort { public: - ISerialPort(); - virtual ~ISerialPort(); + ISerialPort() = default; + virtual ~ISerialPort() = default; public: using DataType = uint8_t; diff --git a/src/interfaces/istatuspublisher.cpp b/src/interfaces/istatuspublisher.cpp index 22a3138..e9b4171 100644 --- a/src/interfaces/istatuspublisher.cpp +++ b/src/interfaces/istatuspublisher.cpp @@ -5,7 +5,7 @@ namespace AqualinkAutomate::Interfaces IStatusPublisher::StatusType IStatusPublisher::Status() const { - return StatusType(m_Status); + return { m_Status }; } } diff --git a/src/interfaces/iwebpageroute.h b/src/interfaces/iwebpageroute.h index 6faff7e..1992979 100644 --- a/src/interfaces/iwebpageroute.h +++ b/src/interfaces/iwebpageroute.h @@ -36,9 +36,9 @@ namespace AqualinkAutomate::Interfaces virtual ~IWebPageRoute() = default; public: - virtual HTTP::Message OnRequest(HTTP::Request req) final + virtual HTTP::Message OnRequest(const HTTP::Request& req) final { - auto generate_page = [this](HTTP::Request req) -> HTTP::Message + auto generate_page = [this](const HTTP::Request& req) -> HTTP::Message { try { diff --git a/src/interfaces/iwebroute.h b/src/interfaces/iwebroute.h index 607b014..8d148fd 100644 --- a/src/interfaces/iwebroute.h +++ b/src/interfaces/iwebroute.h @@ -17,7 +17,7 @@ namespace AqualinkAutomate::Interfaces virtual const std::string_view Route() const = 0; public: - virtual HTTP::Message OnRequest(HTTP::Request req) = 0; + virtual HTTP::Message OnRequest(const HTTP::Request& req) = 0; }; template diff --git a/src/interfaces/iwebsocket.cpp b/src/interfaces/iwebsocket.cpp index a26ee18..f9aa778 100644 --- a/src/interfaces/iwebsocket.cpp +++ b/src/interfaces/iwebsocket.cpp @@ -12,7 +12,7 @@ namespace AqualinkAutomate::Interfaces { IWebSocketBase::~IWebSocketBase() { - if (0 == m_ActiveSessions.size()) + if (m_ActiveSessions.empty()) { // No active sessions...do nothing. } @@ -20,7 +20,7 @@ namespace AqualinkAutomate::Interfaces { LogDebug(Channel::Web, std::format("Destroying {} active websocket sessions...", m_ActiveSessions.size())); - for (auto& session : m_ActiveSessions) + for (const auto& session : m_ActiveSessions) { LogTrace(Channel::Web, std::format("Websocket id {} has a use_count of {}", boost::uuids::to_string(session->Id()), session.use_count())); @@ -90,33 +90,33 @@ namespace AqualinkAutomate::Interfaces } } - void IWebSocketBase::BroadcastMessage(std::vector&& buffer) + void IWebSocketBase::BroadcastMessage(const std::vector& buffer) { LogTrace(Channel::Web, std::format("Broadcasting binary message to all ({}) sessions; message -> ", m_ActiveSessions.size())); std::for_each(std::execution::par, m_ActiveSessions.cbegin(), m_ActiveSessions.cend(), - [this, buffer = std::move(buffer)](const auto& session) mutable -> void + [this, &buffer](const auto& session) -> void { LogTrace(Channel::Web, std::format("Broadcasting binary message ({} bytes) to session {}", buffer.size(), boost::uuids::to_string(session->Id()))); - PublishMessage(session, std::move(buffer)); + PublishMessage(session, buffer); } ); } - void IWebSocketBase::BroadcastMessage(std::string&& buffer) + void IWebSocketBase::BroadcastMessage(const std::string& buffer) { LogTrace(Channel::Web, std::format("Broadcasting text message (copy) to all ({}) sessions; message -> {}", m_ActiveSessions.size(), buffer)); std::for_each(std::execution::par, m_ActiveSessions.cbegin(), m_ActiveSessions.cend(), - [this, buffer = std::move(buffer)](const auto& session) mutable -> void + [this, &buffer](const auto& session) -> void { LogTrace(Channel::Web, std::format("Broadcasting text message ({} bytes) to session {}", buffer.size(), boost::uuids::to_string(session->Id()))); - PublishMessage(session, std::move(buffer)); + PublishMessage(session, buffer); } ); } - void IWebSocketBase::PublishMessage(std::shared_ptr session, std::vector&& buffer) + void IWebSocketBase::PublishMessage(std::shared_ptr session, std::vector buffer) { if (nullptr == session) { @@ -129,7 +129,7 @@ namespace AqualinkAutomate::Interfaces } } - void IWebSocketBase::PublishMessage(std::shared_ptr session, std::string&& buffer) + void IWebSocketBase::PublishMessage(std::shared_ptr session, std::string buffer) { if (nullptr == session) { diff --git a/src/interfaces/iwebsocket.h b/src/interfaces/iwebsocket.h index cf132a2..48c395d 100644 --- a/src/interfaces/iwebsocket.h +++ b/src/interfaces/iwebsocket.h @@ -41,12 +41,12 @@ namespace AqualinkAutomate::Interfaces virtual void OnError() = 0; protected: - void BroadcastMessage(std::vector&& buffer); - void BroadcastMessage(std::string&& buffer); + void BroadcastMessage(const std::vector& buffer); + void BroadcastMessage(const std::string& buffer); private: - void PublishMessage(std::shared_ptr session, std::vector&& buffer); - void PublishMessage(std::shared_ptr session, std::string&& buffer); + void PublishMessage(std::shared_ptr session, std::vector buffer); + void PublishMessage(std::shared_ptr session, std::string buffer); private: std::unordered_set> m_ActiveSessions; diff --git a/src/jandy/devices/aquarite_device.cpp b/src/jandy/devices/aquarite_device.cpp index c8e158d..484f0cc 100644 --- a/src/jandy/devices/aquarite_device.cpp +++ b/src/jandy/devices/aquarite_device.cpp @@ -17,7 +17,7 @@ namespace AqualinkAutomate::Devices AquariteDevice::AquariteDevice(Types::ExecutorType executor, std::shared_ptr device_id, Percentage requested_percentage, Percentage reported_percentage, PPM salt_ppm) : JandyDevice(device_id), - Capabilities::Restartable(executor, AQUARITE_TIMEOUT_DURATION), + Capabilities::Restartable(std::move(executor), AQUARITE_TIMEOUT_DURATION), m_Requested(AQUARITE_PERCENT_DEBOUNCE_THRESHOLD), m_Reported(std::make_pair(reported_percentage, std::chrono::system_clock::now())), m_SaltPPM(std::make_pair(salt_ppm, std::chrono::system_clock::now())) @@ -25,13 +25,9 @@ namespace AqualinkAutomate::Devices // Note that this is a debounced value so is initialised differently. m_Requested = std::make_pair(requested_percentage, std::chrono::system_clock::now()); - m_SlotManager.RegisterSlot_FilterByDeviceId(std::bind(&AquariteDevice::Slot_Aquarite_GetId, this, std::placeholders::_1), (*device_id)()); - m_SlotManager.RegisterSlot_FilterByDeviceId(std::bind(&AquariteDevice::Slot_Aquarite_Percent, this, std::placeholders::_1), (*device_id)()); - m_SlotManager.RegisterSlot_FilterByDeviceId(std::bind(&AquariteDevice::Slot_Aquarite_PPM, this, std::placeholders::_1), (*device_id)()); - } - - AquariteDevice::~AquariteDevice() - { + m_SlotManager.RegisterSlot_FilterByDeviceId([this](auto&& PH1) { Slot_Aquarite_GetId(std::forward(PH1)); }, (*device_id)()); + m_SlotManager.RegisterSlot_FilterByDeviceId([this](auto&& PH1) { Slot_Aquarite_Percent(std::forward(PH1)); }, (*device_id)()); + m_SlotManager.RegisterSlot_FilterByDeviceId([this](auto&& PH1) { Slot_Aquarite_PPM(std::forward(PH1)); }, (*device_id)()); } void AquariteDevice::WatchdogTimeoutOccurred() diff --git a/src/jandy/devices/aquarite_device.h b/src/jandy/devices/aquarite_device.h index 1fca85f..bbfa080 100644 --- a/src/jandy/devices/aquarite_device.h +++ b/src/jandy/devices/aquarite_device.h @@ -41,7 +41,7 @@ namespace AqualinkAutomate::Devices public: AquariteDevice(Types::ExecutorType executor, std::shared_ptr device_id); AquariteDevice(Types::ExecutorType executor, std::shared_ptr device_id, Percentage requested_percentage, Percentage reported_percentage, PPM salt_ppm); - virtual ~AquariteDevice(); + virtual ~AquariteDevice() = default; private: virtual void WatchdogTimeoutOccurred() override; diff --git a/src/jandy/devices/iaq_device.cpp b/src/jandy/devices/iaq_device.cpp index 10657a1..074bad0 100644 --- a/src/jandy/devices/iaq_device.cpp +++ b/src/jandy/devices/iaq_device.cpp @@ -11,7 +11,7 @@ namespace AqualinkAutomate::Devices IAQDevice::IAQDevice(Types::ExecutorType executor, std::shared_ptr device_id, Kernel::HubLocator& hub_locator, bool is_emulated) : JandyController(std::move(device_id), hub_locator), - Capabilities::Restartable(executor, IAQ_TIMEOUT_DURATION), + Capabilities::Restartable(std::move(executor), IAQ_TIMEOUT_DURATION), Capabilities::Screen(IAQ_STATUS_PAGE_LINES), Capabilities::Emulated(is_emulated), m_StatusPage(IAQ_STATUS_PAGE_LINES), diff --git a/src/jandy/devices/jandy_device_types.cpp b/src/jandy/devices/jandy_device_types.cpp index ffaf1a2..baeb197 100644 --- a/src/jandy/devices/jandy_device_types.cpp +++ b/src/jandy/devices/jandy_device_types.cpp @@ -13,9 +13,9 @@ namespace AqualinkAutomate::Devices m_DeviceClass(DeviceClasses::Unknown), m_DeviceId(device_id) { - for (auto& device_class : m_KnownDeviceIdsList) + for (const auto& device_class : m_KnownDeviceIdsList) { - for (auto& id : device_class.second) + for (const auto& id : device_class.second) { if (static_cast(id) == device_id) { @@ -44,8 +44,8 @@ namespace AqualinkAutomate::Devices } JandyDeviceType::JandyDeviceType(JandyDeviceType&& other) noexcept : - m_DeviceClass(std::move(other.m_DeviceClass)), - m_DeviceId(std::move(other.m_DeviceId)) + m_DeviceClass(other.m_DeviceClass), + m_DeviceId(other.m_DeviceId) { // Reset the other instance to default "unknown" values. other.m_DeviceClass = DeviceClasses::Unknown; @@ -57,8 +57,8 @@ namespace AqualinkAutomate::Devices if (this != &other) { // "Move" the data to this instance. - m_DeviceClass = std::move(other.m_DeviceClass); - m_DeviceId = std::move(other.m_DeviceId); + m_DeviceClass =other.m_DeviceClass; + m_DeviceId = other.m_DeviceId; // Reset the other instance to default "unknown" values. other.m_DeviceClass = DeviceClasses::Unknown; @@ -80,7 +80,7 @@ namespace AqualinkAutomate::Devices bool JandyDeviceType::operator==(const Interfaces::IDeviceIdentifier& other) const { - if (auto ptr = dynamic_cast(&other); nullptr != ptr) + if (const auto ptr = dynamic_cast(&other); nullptr != ptr) { return operator==(*ptr); } @@ -91,7 +91,7 @@ namespace AqualinkAutomate::Devices bool JandyDeviceType::operator!=(const Interfaces::IDeviceIdentifier& other) const { - if (auto ptr = dynamic_cast(&other); nullptr != ptr) + if (const auto ptr = dynamic_cast(&other); nullptr != ptr) { return operator!=(*ptr); } diff --git a/src/jandy/utility/screen_data_page.cpp b/src/jandy/utility/screen_data_page.cpp index f0f3d90..7f2c5fd 100644 --- a/src/jandy/utility/screen_data_page.cpp +++ b/src/jandy/utility/screen_data_page.cpp @@ -47,9 +47,9 @@ namespace AqualinkAutomate::Utility row.HighlightRange = std::nullopt; } } - else if (m_Rows.size() < line_id) + else if (m_Rows.size() <= line_id) { - LogDebug(Channel::Devices, std::format("ScreenDataPage: Cannot toggle highlight, line id is out of range; requested line id -> {}, max line id -> {}", line_id, m_Rows.size())); + LogDebug(Channel::Devices, std::format("ScreenDataPage: Cannot toggle highlight, line id is out of range; requested line id -> {}, max line id -> {}", line_id, std::max(m_Rows.size(), static_cast(0)))); } else { @@ -60,9 +60,9 @@ namespace AqualinkAutomate::Utility void ScreenDataPage::HighlightChars(uint8_t line_id, uint8_t start_index, uint8_t stop_index) { - if (m_Rows.size() < line_id) + if (m_Rows.size() <= line_id) { - LogDebug(Channel::Devices, std::format("ScreenDataPage: Cannot toggle highlight, line id is out of range; requested line id -> {}, max line id -> {}", line_id, m_Rows.size())); + LogDebug(Channel::Devices, std::format("ScreenDataPage: Cannot toggle highlight, line id is out of range; requested line id -> {}, max line id -> {}", line_id, std::max(m_Rows.size(), static_cast(0)))); } else { diff --git a/src/jandy/utility/string_conversion/timeout_duration_string_converter.cpp b/src/jandy/utility/string_conversion/timeout_duration_string_converter.cpp index 0f16a7e..9425aac 100644 --- a/src/jandy/utility/string_conversion/timeout_duration_string_converter.cpp +++ b/src/jandy/utility/string_conversion/timeout_duration_string_converter.cpp @@ -82,15 +82,15 @@ namespace AqualinkAutomate::Utility { LogDebug(Channel::Devices, "Failed to convert timeout duration; invalid second delimiter"); } - else if (auto [p, ec] = std::from_chars(timeout_string.data() + HOURS_INDEX_START, timeout_string.data() + HOURS_INDEX_END, hours); std::errc() != ec) + else if (auto [_, ec] = std::from_chars(timeout_string.data() + HOURS_INDEX_START, timeout_string.data() + HOURS_INDEX_END, hours); std::errc() != ec) { LogDebug(Channel::Devices, std::format("Failed to convert timeout duration; could not convert hours to number: error -> {}", magic_enum::enum_name(ec))); } - else if (auto [p, ec] = std::from_chars(timeout_string.data() + MINS_INDEX_START, timeout_string.data() + MINS_INDEX_END, minutes); std::errc() != ec) + else if (auto [_, ec] = std::from_chars(timeout_string.data() + MINS_INDEX_START, timeout_string.data() + MINS_INDEX_END, minutes); std::errc() != ec) { LogDebug(Channel::Devices, std::format("Failed to convert timeout duration; could not convert minutes to number: error -> {}", magic_enum::enum_name(ec))); } - else if (auto [p, ec] = std::from_chars(timeout_string.data() + SECS_INDEX_START, timeout_string.data() + SECS_INDEX_END, seconds); std::errc() != ec) + else if (auto [_, ec] = std::from_chars(timeout_string.data() + SECS_INDEX_START, timeout_string.data() + SECS_INDEX_END, seconds); std::errc() != ec) { LogDebug(Channel::Devices, std::format("Failed to convert timeout duration; could not convert seconds to number: error -> {}", magic_enum::enum_name(ec))); } diff --git a/src/utility/bandwidth_utilisation.h b/src/utility/bandwidth_utilisation.h index d8d8d10..d658fca 100644 --- a/src/utility/bandwidth_utilisation.h +++ b/src/utility/bandwidth_utilisation.h @@ -182,7 +182,7 @@ namespace AqualinkAutomate::Utility const double temp1 = bits_start + bits_per_character + bits_parity + bits_stop; const double temp2 = bits_per_character / temp1; - const double temp3 = options.baud_rate.value() / 8; + const double temp3 = options.baud_rate.value() / 8.0f; const double byterate_useful = temp2 * temp3; return byterate_useful; diff --git a/test/unit/http/test_http_sessions.cpp b/test/unit/http/test_http_sessions.cpp index 84b6909..751862d 100644 --- a/test/unit/http/test_http_sessions.cpp +++ b/test/unit/http/test_http_sessions.cpp @@ -8,6 +8,8 @@ #include "http/server/routing/routing.h" #include "kernel/data_hub.h" #include "kernel/hub_locator.h" +#include "logging/logging.h" +#include "logging/logging_severity_filter.h" #include "support/unit_test_httprequestresponse.h" @@ -77,4 +79,73 @@ BOOST_AUTO_TEST_CASE(Test_HttpSessions_PlainWebSocket_API) } } +BOOST_AUTO_TEST_CASE(Test_MultipleConcurrent_WebSockets) +{ + Logging::SeverityFiltering::SetChannelFilterLevel(Channel::Web, Severity::Trace); + + boost::asio::io_context io_context; + boost::beast::error_code ec; + + Kernel::HubLocator hub_locator; + hub_locator + .Register(std::make_shared()) + .Register(std::make_shared()) + .Register(std::make_shared()); + + HTTP::Routing::Add(std::make_unique(hub_locator)); + + /// TEST WEBSOCKET ROUTE: /ws/equipment + + { + auto tro1 = Test::PerformHttpWsUpgradeResponse(io_context, "/ws/equipment"); + auto tro2 = Test::PerformHttpWsUpgradeResponse(io_context, "/ws/equipment"); + + { + auto data_hub = hub_locator.TryFind(); + BOOST_TEST_REQUIRE(nullptr != data_hub); + + data_hub->ORP(650); + io_context.poll(); // ASYNC_READ + io_context.poll(); // ASYNC_READ + + std::array websocket1_buffer{}, websocket2_buffer{}; + tro1->local_stream.read_size(1024); + tro2->local_stream.read_size(1024); + + auto size1 = tro1->local_stream.buffer().size(); + const auto bytes_read1 = tro1->local_stream.read_some(boost::asio::buffer(websocket1_buffer), ec); + BOOST_TEST_REQUIRE(0 == ec.value()); + BOOST_TEST_REQUIRE(0 != bytes_read1); + BOOST_TEST_REQUIRE(size1 == bytes_read1); + + auto size2 = tro2->local_stream.buffer().size(); + const auto bytes_read2 = tro2->local_stream.read_some(boost::asio::buffer(websocket2_buffer), ec); + BOOST_TEST_REQUIRE(0 == ec.value()); + BOOST_TEST_REQUIRE(0 != bytes_read2); + BOOST_TEST_REQUIRE(size2 == bytes_read2); + + nlohmann::json wse1_json, wse2_json; + + try + { + std::string ss1(websocket1_buffer.data() + 2, websocket1_buffer.data() + bytes_read1); + std::string ss2(websocket2_buffer.data() + 2, websocket2_buffer.data() + bytes_read2); + + wse1_json = nlohmann::json::parse(websocket1_buffer.data() + 2, websocket1_buffer.data() + bytes_read1); + } + catch (const nlohmann::json::exception& e) + { + LogDebug(Channel::Developer, e.what()); + } + + BOOST_REQUIRE_NO_THROW(wse1_json = nlohmann::json::parse(websocket1_buffer.data() + 2, websocket1_buffer.data() + bytes_read1)); + BOOST_REQUIRE_NO_THROW(wse2_json = nlohmann::json::parse(websocket2_buffer.data() + 2, websocket2_buffer.data() + bytes_read2)); + + BOOST_CHECK_EQUAL(bytes_read1, bytes_read2); + BOOST_CHECK_EQUAL(wse1_json, wse2_json); + } + } + +} + BOOST_AUTO_TEST_SUITE_END()