diff --git a/.github/workflows/ci-cd-esp32.yml b/.github/workflows/ci-cd-esp32.yml new file mode 100644 index 00000000..330c13a1 --- /dev/null +++ b/.github/workflows/ci-cd-esp32.yml @@ -0,0 +1,70 @@ +name: CMake + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + + #Allows you to start workflow manually from the actions tab in the interface github.com + workflow_dispatch: + +jobs: +#ESP32 Build + build-esp-idf-component: + name: ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} ${{ matrix.compile_example }} + runs-on: ubuntu-latest + strategy: + matrix: + # The version names here correspond to the versions of espressif/idf Docker image. + # See https://hub.docker.com/r/espressif/idf/tags and + # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html + # for details. + idf_ver: ["release-v5.5"] + idf_target: ["esp32"] + compile_example: ["cloud"] + platforms: + - { + name: "Optimized", + user_config: "./config/user_config_optimized.h", + } + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + submodules: "recursive" + + - name: Build Application + uses: espressif/esp-idf-ci-action@v1 + with: + esp_idf_version: ${{ matrix.idf_ver }} + target: ${{ matrix.idf_target }} + path: "projects/xtensa_lx6/vscode/aether-client-cpp" + command: idf.py + build + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -DCOMPILE_EXAMPLE=${{ matrix.compile_example }} + -DUSER_CONFIG=../../../../../${{ matrix.platforms.user_config }} + + - name: Rename artifact + run: | + ls -lah + cp projects/xtensa_lx6/vscode/aether-client-cpp/build/bootloader/bootloader.bin bootloader-${{ matrix.idf_ver }}.bin + cp projects/xtensa_lx6/vscode/aether-client-cpp/build/partition_table/partition-table.bin partition-table-${{ matrix.idf_ver }}.bin + cp projects/xtensa_lx6/vscode/aether-client-cpp/build/Aether.bin Aether-${{ matrix.compile_example }}-${{ matrix.idf_ver }}.bin + + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: Aether_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.compile_example }} + path: "*-${{ matrix.compile_example }}-${{ matrix.idf_ver }}.bin" + + release: + needs: build-esp-idf-component + runs-on: ubuntu-latest + steps: + - name: Download Firmware Files + uses: actions/download-artifact@v4 + with: + path: build diff --git a/.github/workflows/ci-cd-multi-platforms.yml b/.github/workflows/ci-cd-multi-platforms.yml index 9b9b585e..e43fd98c 100644 --- a/.github/workflows/ci-cd-multi-platforms.yml +++ b/.github/workflows/ci-cd-multi-platforms.yml @@ -108,6 +108,7 @@ jobs: cmake -B build -G "${{ matrix.config.generator }}" -A "${{ matrix.config.arch }}" + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_COMPILER=${{ matrix.config.cxx }} -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DCMAKE_BUILD_TYPE=Release @@ -119,67 +120,18 @@ jobs: # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). run: cmake --build build --config Release --parallel - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: Aether_${{ matrix.config.name }}_${{ matrix.platforms.name }} - path: "build/*" - include-hidden-files: true - overwrite: true - - name: Test # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest --test-dir build --build-config Release --output-on-failure - #ESP32 Build - build-esp-idf-component: - name: ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} ${{ matrix.compile_example }} - runs-on: ubuntu-latest - strategy: - matrix: - # The version names here correspond to the versions of espressif/idf Docker image. - # See https://hub.docker.com/r/espressif/idf/tags and - # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html - # for details. - idf_ver: ["release-v5.5"] - idf_target: ["esp32"] - compile_example: ["cloud"] - platforms: - - { - name: "Optimized", - user_config: "./config/user_config_optimized.h", - } - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - with: - submodules: "recursive" - - - name: Build Application - uses: espressif/esp-idf-ci-action@v1 - with: - esp_idf_version: ${{ matrix.idf_ver }} - target: ${{ matrix.idf_target }} - path: "projects/xtensa_lx6/vscode/aether-client-cpp" - command: idf.py build - -DCOMPILE_EXAMPLE=${{ matrix.compile_example }} - -DUSER_CONFIG=../../../../../${{ matrix.platforms.user_config }} - -DAE_DISTILLATION=Off - - - name: Rename artifact - run: | - ls -lah - cp projects/xtensa_lx6/vscode/aether-client-cpp/build/bootloader/bootloader.bin bootloader-${{ matrix.idf_ver }}.bin - cp projects/xtensa_lx6/vscode/aether-client-cpp/build/partition_table/partition-table.bin partition-table-${{ matrix.idf_ver }}.bin - cp projects/xtensa_lx6/vscode/aether-client-cpp/build/Aether.bin Aether-${{ matrix.compile_example }}-${{ matrix.idf_ver }}.bin - - name: Upload uses: actions/upload-artifact@v4 with: - name: Aether_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.compile_example }} - path: "*-${{ matrix.compile_example }}-${{ matrix.idf_ver }}.bin" + name: Aether_${{ matrix.config.name }}_${{ matrix.platforms.name }} + path: "build/*" + include-hidden-files: true + overwrite: true release: needs: build diff --git a/.github/workflows/ci-cppcheck.yml b/.github/workflows/ci-cppcheck.yml new file mode 100644 index 00000000..ba539dd8 --- /dev/null +++ b/.github/workflows/ci-cppcheck.yml @@ -0,0 +1,87 @@ +name: cppcheck + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + + #Allows you to start workflow manually from the actions tab in the interface github.com + workflow_dispatch: + +jobs: + cppcheck: + runs-on: ubuntu-latest + steps: + - name: configure system + run: | + sudo apt-get update + sudo apt-get install -y make ninja-build + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: cache cppcheck + id: cache-cppcheck + uses: actions/cache@v4 + with: + path: _cppcheck + key: ${{ runner.os }}-cppcheck-2.19.0 + restore-keys: ${{ runner.os }}-cppcheck-2.19.0 + + - if: ${{ steps.cache-cppcheck.outputs.cache-hit != 'true' }} + name: download and build cppcheck + run: | + mkdir -p _cppcheck + wget -O _cppcheck/cppcheck.tar.gz https://github.com/danmar/cppcheck/archive/refs/tags/2.19.0.tar.gz + cd _cppcheck + tar -xzf cppcheck.tar.gz + cd cppcheck-2.19.0 + make -j + pwd + ls ./cppcheck + ./cppcheck --version + cd ../.. + _cppcheck/cppcheck-2.19.0/cppcheck --version + + # we need configure cmake to get the compile_commands.json file + - name: cmake configure + run: > + cmake -B build + -G Ninja + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -DCMAKE_BUILD_TYPE=Release + -C ".github/workflows/linux_initial_cache.txt" + -S projects/cmake + + - name: cache cppcheck_build_dir + id: cache-cppcheck_build_dir + uses: actions/cache@v4 + with: + path: _cppcheck_build_dir + key: ${{ runner.os }}-cppcheck_build_dir + restore-keys: ${{ runner.os }}-cppcheck_build_dir + + # _cppcheck_build_dir is required to increase cppcheck check speed + - if: ${{ steps.cache-cppcheck_build_dir.outputs.cache-hit != 'true' }} + name: cppcheck_build_dir + run: mkdir -p _cppcheck_build_dir + + - name: cppcheck + run: > + ./_cppcheck/cppcheck-2.19.0/cppcheck --project=build/compile_commands.json + -D__GNUC__=4 + --safety + --error-exitcode=-1 + -i "third_party/*" + --enable=warning,performance,portability,missingInclude + --suppressions-list=./cppcheck_suppressions.txt + --inline-suppr + --quiet + -j $(nproc) + --cppcheck-build-dir=./_cppcheck_build_dir + --checkers-report=./checkers.txt + + - name: print checkers report + run: cat checkers.txt diff --git a/.github/workflows/cpplint.yml b/.github/workflows/cpplint.yml deleted file mode 100644 index 3da34d4d..00000000 --- a/.github/workflows/cpplint.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: cpplint - -on: - pull_request: - branches: [ "main" ] - -jobs: - cpplint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v1 - - run: pip install cpplint - - run: cpplint --recursive ./aether - - run: cpplint --recursive ./tests - diff --git a/aether/access_points/wifi_access_point.h b/aether/access_points/wifi_access_point.h index 6a49265f..dd1d5d9d 100644 --- a/aether/access_points/wifi_access_point.h +++ b/aether/access_points/wifi_access_point.h @@ -90,9 +90,9 @@ class WifiAccessPoint final : public AccessPoint { Obj::ptr adapter_; ObjPtr poller_; ObjPtr resolver_; - WiFiAp wifi_ap_; - WiFiPowerSaveParam psp_; - WiFiBaseStation base_station_; + WiFiAp wifi_ap_{}; + WiFiPowerSaveParam psp_{}; + WiFiBaseStation base_station_{}; ActionPtr connect_action_; Subscription connect_sub_; }; diff --git a/aether/adapters/parent_modem.h b/aether/adapters/parent_modem.h index 947410ce..ba824094 100644 --- a/aether/adapters/parent_modem.h +++ b/aether/adapters/parent_modem.h @@ -45,7 +45,7 @@ class ParentModemAdapter : public Adapter { Obj::ptr aether_; IPoller::ptr poller_; - ModemInit modem_init_; + ModemInit modem_init_{}; }; } // namespace ae diff --git a/aether/adapters/parent_wifi.h b/aether/adapters/parent_wifi.h index 697273b9..89f20e8d 100644 --- a/aether/adapters/parent_wifi.h +++ b/aether/adapters/parent_wifi.h @@ -47,7 +47,7 @@ class ParentWifiAdapter : public Adapter { ObjPtr poller_; ObjPtr dns_resolver_; - WiFiInit wifi_init_; + WiFiInit wifi_init_{}; }; } // namespace ae #endif diff --git a/aether/ae_actions/select_client.cpp b/aether/ae_actions/select_client.cpp index d9657bd3..a3680ed8 100644 --- a/aether/ae_actions/select_client.cpp +++ b/aether/ae_actions/select_client.cpp @@ -77,7 +77,7 @@ UpdateStatus SelectClientAction::Update() { return {}; } -Client::ptr SelectClientAction::client() const { return client_; } +Client::ptr const& SelectClientAction::client() const { return client_; } SelectClientAction::State SelectClientAction::state() const { return state_; } diff --git a/aether/ae_actions/select_client.h b/aether/ae_actions/select_client.h index 722d6738..af406482 100644 --- a/aether/ae_actions/select_client.h +++ b/aether/ae_actions/select_client.h @@ -61,7 +61,7 @@ class SelectClientAction final : public Action { UpdateStatus Update(); - Client::ptr client() const; + Client::ptr const& client() const; State state() const; private: diff --git a/aether/ae_actions/time_sync.cpp b/aether/ae_actions/time_sync.cpp index 36e724a8..b0f757ba 100644 --- a/aether/ae_actions/time_sync.cpp +++ b/aether/ae_actions/time_sync.cpp @@ -104,25 +104,25 @@ void TimeSyncAction::SyncRequest() { CloudVisit::Visit( [this](CloudServerConnection* sc) { assert((sc != nullptr) && "Server connection is null!"); - assert((sc->client_connection()->stream_info().link_state == - LinkState::kLinked) && + + auto* cc = sc->client_connection(); + assert((cc->stream_info().link_state == LinkState::kLinked) && "Client connection is not linked!"); write_action_sub_ = - sc->client_connection() - ->LoginApiCall(SubApi{[this](auto& api) { - AE_TELED_DEBUG("Make time sync request"); - ApiPromisePtr promise = api->get_time_utc(); - response_sub_ = promise->StatusEvent().Subscribe( - OnResult{[this, request_time{Clock::now()}](auto& p) { - HandleResponse( - std::chrono::milliseconds{ - static_cast(p.value())}, - request_time, Clock::now()); - // time synced, wait for next sync interval - state_ = State::kWaitInterval; - }}); - }}) + cc->LoginApiCall(SubApi{[this](auto& api) { + AE_TELED_DEBUG("Make time sync request"); + ApiPromisePtr promise = api->get_time_utc(); + response_sub_ = promise->StatusEvent().Subscribe( + OnResult{[this, request_time{Clock::now()}](auto& p) { + HandleResponse( + std::chrono::milliseconds{ + static_cast(p.value())}, + request_time, Clock::now()); + // time synced, wait for next sync interval + state_ = State::kWaitInterval; + }}); + }}) ->StatusEvent() .Subscribe(OnError{[this]() { AE_TELED_ERROR("Time sync write error, repeat"); diff --git a/aether/aether_app.cpp b/aether/aether_app.cpp index 7992f041..56b117a1 100644 --- a/aether/aether_app.cpp +++ b/aether/aether_app.cpp @@ -196,6 +196,8 @@ static IPoller::ptr PollerFactory(AetherAppContext const& context) { return WinPoller::ptr::Create(CreateWith{context.domain()} .with_id(GlobalId::kPoller) .with_flags(ObjFlags::kUnloadedByDefault)); +# else + return {}; # endif } diff --git a/aether/aether_c/aether_capi.cpp b/aether/aether_c/aether_capi.cpp index 19edc08c..d677f3c4 100644 --- a/aether/aether_c/aether_capi.cpp +++ b/aether/aether_c/aether_capi.cpp @@ -143,7 +143,7 @@ ae::ActionPtr WriteMessageImpl(AetherClient* client, return action; } -void WriteMessage(AetherClient* client, ae::Uid destination, +void WriteMessage(AetherClient* client, ae::Uid const& destination, ae::DataBuffer&& data, ActionStatusCb status_cb, void* user_data) { assert(client); @@ -151,10 +151,10 @@ void WriteMessage(AetherClient* client, ae::Uid destination, // if client still is not selected, add send message to queue if (!client->client) { client->actions_queue_->Push( - ae::Stage([client, destination, data{std::move(data)}, status_cb, + ae::Stage([client, destination, d{std::move(data)}, status_cb, user_data]() mutable { - return WriteMessageImpl(client, destination, std::move(data), - status_cb, user_data); + return WriteMessageImpl(client, destination, std::move(d), status_cb, + user_data); })); } else { WriteMessageImpl(client, destination, std::move(data), status_cb, diff --git a/aether/api_protocol/api_class_impl.h b/aether/api_protocol/api_class_impl.h index f8acb168..7ce52c4b 100644 --- a/aether/api_protocol/api_class_impl.h +++ b/aether/api_protocol/api_class_impl.h @@ -88,7 +88,7 @@ struct MethodInvoke::value>> { public: static constexpr auto kMessageCode = message_id; - using Message = GenericMessage; + using Message = GenericMessage, std::decay_t...>; static void Invoke(TApi* obj, Message&& message, ApiParser&) { std::apply( @@ -109,7 +109,7 @@ template { public: static constexpr auto kMessageCode = message_id; - using Message = GenericMessage, Args...>; + using Message = GenericMessage, std::decay_t...>; static void Invoke(TApi* obj, Message&& message, ApiParser&) { std::apply( @@ -130,7 +130,7 @@ template { public: static constexpr auto kMessageCode = message_id; - using Message = GenericMessage; + using Message = GenericMessage...>; static void Invoke(TApi* obj, Message&& message, ApiParser& parser) { std::apply( diff --git a/aether/api_protocol/api_promise_action.h b/aether/api_protocol/api_promise_action.h index 9be1dbb9..fafcd0ef 100644 --- a/aether/api_protocol/api_promise_action.h +++ b/aether/api_protocol/api_promise_action.h @@ -40,7 +40,7 @@ class ApiPromiseAction : public Action> { RequestId const& request_id() const { return request_id_; } - void SetValue(TValue value) { promise_.SetValue(value); } + void SetValue(TValue&& value) { promise_.SetValue(std::move(value)); } void Reject() { promise_.Reject(); } diff --git a/aether/api_protocol/child_data.cpp b/aether/api_protocol/child_data.cpp index 6728f50f..418ce009 100644 --- a/aether/api_protocol/child_data.cpp +++ b/aether/api_protocol/child_data.cpp @@ -29,9 +29,8 @@ std::vector ChildData::PackData( if (pack_data_.index() == 0) { return DataPackMessage(protocol_context, std::move(*std::get<0>(pack_data_))); - } else { - return std::move(std::get<1>(pack_data_)); } + return std::get<1>(pack_data_); } std::vector const& ChildData::PackData() const { diff --git a/aether/api_protocol/request_id.h b/aether/api_protocol/request_id.h index c8feac9c..45f34c92 100644 --- a/aether/api_protocol/request_id.h +++ b/aether/api_protocol/request_id.h @@ -38,7 +38,7 @@ struct RequestId { bool operator<(RequestId const& rhs) const { return id < rhs.id; } AE_REFLECT_MEMBERS(id) - std::uint32_t id; + std::uint32_t id{}; }; } // namespace ae diff --git a/aether/api_protocol/sub_api.h b/aether/api_protocol/sub_api.h index 45bb6b53..3299836a 100644 --- a/aether/api_protocol/sub_api.h +++ b/aether/api_protocol/sub_api.h @@ -49,7 +49,7 @@ class SubApi { std::vector operator()(TApi& api) const { auto api_context = ApiContext{api}; caller_(api_context); - return std::move(api_context); + return std::move(api_context).Pack(); } private: diff --git a/aether/channels/channel.h b/aether/channels/channel.h index 9155e100..ff16c74b 100644 --- a/aether/channels/channel.h +++ b/aether/channels/channel.h @@ -45,7 +45,7 @@ class Channel : public Obj { virtual Duration ResponseTimeout() const; protected: - ChannelTransportProperties transport_properties_; + ChannelTransportProperties transport_properties_{}; ChannelStatistics::ptr channel_statistics_; }; diff --git a/aether/channels/channels_types.h b/aether/channels/channels_types.h index 75d0bdba..3ec204fc 100644 --- a/aether/channels/channels_types.h +++ b/aether/channels/channels_types.h @@ -37,10 +37,10 @@ struct ChannelTransportProperties { AE_REFLECT_MEMBERS(max_packet_size, rec_packet_size, connection_type, reliability) - std::uint32_t max_packet_size; // < Maximum packet size in bytes - std::uint32_t rec_packet_size; // < Recommended packet size in bytes - ConnectionType connection_type; - Reliability reliability; + std::uint32_t max_packet_size{}; // < Maximum packet size in bytes + std::uint32_t rec_packet_size{}; // < Recommended packet size in bytes + ConnectionType connection_type{}; + Reliability reliability{}; }; } // namespace ae diff --git a/aether/channels/ethernet_channel.cpp b/aether/channels/ethernet_channel.cpp index 5e15304e..09c3e5c6 100644 --- a/aether/channels/ethernet_channel.cpp +++ b/aether/channels/ethernet_channel.cpp @@ -183,7 +183,7 @@ class EthernetTransportBuilderAction final : public TransportBuilderAction { PtrView poller_; StateMachine state_; std::vector ip_addresses_; - std::vector::iterator it_; + std::vector::iterator it_{}; std::unique_ptr transport_stream_; Subscription address_resolve_sub_; Subscription transport_stream_sub_; diff --git a/aether/channels/wifi_channel.cpp b/aether/channels/wifi_channel.cpp index 3e0bbfea..cfe72198 100644 --- a/aether/channels/wifi_channel.cpp +++ b/aether/channels/wifi_channel.cpp @@ -205,7 +205,7 @@ class WifiTransportBuilderAction final : public TransportBuilderAction { Endpoint address_; std::vector ip_addresses_; - std::vector::iterator it_; + std::vector::iterator it_{}; std::unique_ptr transport_stream_; Subscription wifi_connected_sub_; Subscription address_resolve_sub_; diff --git a/aether/client_messages/p2p_message_stream.cpp b/aether/client_messages/p2p_message_stream.cpp index 68e2bd36..037218a5 100644 --- a/aether/client_messages/p2p_message_stream.cpp +++ b/aether/client_messages/p2p_message_stream.cpp @@ -232,7 +232,7 @@ void P2pStream::WriteOut(DataBuffer const& data) { out_data_event_.Emit(data); } -Uid P2pStream::destination() const { return destination_; } +Uid const& P2pStream::destination() const { return destination_; } void P2pStream::ConnectReceive() { auto client_ptr = client_.Lock(); diff --git a/aether/client_messages/p2p_message_stream.h b/aether/client_messages/p2p_message_stream.h index cc9888ae..17cb2720 100644 --- a/aether/client_messages/p2p_message_stream.h +++ b/aether/client_messages/p2p_message_stream.h @@ -58,7 +58,7 @@ class P2pStream final : public ByteIStream { void WriteOut(DataBuffer const& data); - Uid destination() const; + Uid const& destination() const; private: void ConnectReceive(); @@ -72,7 +72,7 @@ class P2pStream final : public ByteIStream { ActionContext action_context_; PtrView client_; - Uid destination_; + Uid destination_{}; // connection manager to destination cloud std::unique_ptr dest_conn_manager_; diff --git a/aether/cloud_connections/cloud_subscription.h b/aether/cloud_connections/cloud_subscription.h index d78ba2c7..d23a8767 100644 --- a/aether/cloud_connections/cloud_subscription.h +++ b/aether/cloud_connections/cloud_subscription.h @@ -41,7 +41,7 @@ class CloudSubscription { private: void ServersUpdate(); - CloudServerConnections* cloud_connection_; + CloudServerConnections* cloud_connection_{}; ClientListener subscriber_; RequestPolicy::Variant request_policy_; Subscription server_update_sub_; diff --git a/aether/events/cumulative_event.h b/aether/events/cumulative_event.h index ae41d91b..f2b26ff0 100644 --- a/aether/events/cumulative_event.h +++ b/aether/events/cumulative_event.h @@ -38,11 +38,16 @@ class CumulativeEvent { public: explicit ValueSetter(CumulativeEvent* event) : event_(event) {} - ValueSetter& operator=(T value) { + ValueSetter& operator=(T const& value) { event_->values_[I] = value; return *this; } + ValueSetter& operator=(T&& value) { + event_->values_[I] = std::move(value); + return *this; + } + private: CumulativeEvent* event_; }; @@ -86,15 +91,14 @@ class CumulativeEvent { EventSubscribers&&... event_subscribers) { ((subscriptions_[Is] = std::forward(event_subscribers) - .Subscribe( - [this, func{std::forward(func)}](auto&&... args) { - set_map_[Is] = true; - ValueSetter vs{this}; - func(vs, std::forward(args)...); - if (IsFull()) { - res_event_.Emit(*this); - } - })), + .Subscribe([this, f{std::forward(func)}](auto&&... args) { + set_map_[Is] = true; + ValueSetter vs{this}; + f(vs, std::forward(args)...); + if (IsFull()) { + res_event_.Emit(*this); + } + })), ...); } diff --git a/aether/events/event_list.cpp b/aether/events/event_list.cpp index b931393d..59ea8e9c 100644 --- a/aether/events/event_list.cpp +++ b/aether/events/event_list.cpp @@ -32,8 +32,8 @@ EventHandlersList::IteratorAdapter::Iterator::Iterator( } EventHandlersList::IteratorAdapter::Iterator& EventHandlersList::IteratorAdapter::Iterator::operator++() { - it_++; - index_++; + ++it_; + ++index_; if (index_ == size_) { return *this; } diff --git a/aether/events/event_list.h b/aether/events/event_list.h index 819ae3d7..883d3569 100644 --- a/aether/events/event_list.h +++ b/aether/events/event_list.h @@ -83,14 +83,14 @@ class EventHandlersList { } private: - typename ListType::iterator it_; + typename ListType::iterator it_{}; /** * index and size used to control the end of the list. * using end iterator is not appropriate here because it's grow with new * elements added. */ - std::uint16_t index_; - std::uint16_t size_; + std::uint16_t index_{}; + std::uint16_t size_{}; }; using iterator = Iterator; diff --git a/aether/reflect/reflect_impl.h b/aether/reflect/reflect_impl.h index 5d5d9df3..7d32aca0 100644 --- a/aether/reflect/reflect_impl.h +++ b/aether/reflect/reflect_impl.h @@ -110,7 +110,7 @@ class ReflectionImpl { return FieldList::template get(obj_); } - constexpr std::size_t size() const { return FieldList::kSize; } + static constexpr std::size_t size() { return FieldList::kSize; } private: T obj_; diff --git a/aether/server.h b/aether/server.h index 61f4b66e..457d277f 100644 --- a/aether/server.h +++ b/aether/server.h @@ -45,7 +45,7 @@ class Server : public Obj { ChannelsChanged::Subscriber channels_changed(); - ServerId server_id; + ServerId server_id{}; std::vector endpoints; std::vector channels; @@ -57,7 +57,7 @@ class Server : public Obj { AdapterRegistry::ptr adapter_registry_; MultiSubscription access_point_added_; ChannelsChanged channels_changed_; - bool subscribed_; + bool subscribed_{false}; }; } // namespace ae #endif // AETHER_SERVER_H_ */ diff --git a/aether/stream_api/safe_stream/safe_stream_types.h b/aether/stream_api/safe_stream/safe_stream_types.h index e3d0f9db..ab48d975 100644 --- a/aether/stream_api/safe_stream/safe_stream_types.h +++ b/aether/stream_api/safe_stream/safe_stream_types.h @@ -97,8 +97,8 @@ struct DataMessage { std::uint8_t repeat_count : 5; std::uint8_t reset : 1; std::uint8_t reserved : 2; - } control; // control flags related to message - std::uint16_t delta_offset; // data offset form sender's buffer begin + } control{}; // control flags related to message + std::uint16_t delta_offset{}; // data offset form sender's buffer begin DataBuffer data; }; diff --git a/aether/tele/traps/statistics_trap.h b/aether/tele/traps/statistics_trap.h index ebffcc98..54e56f2b 100644 --- a/aether/tele/traps/statistics_trap.h +++ b/aether/tele/traps/statistics_trap.h @@ -171,8 +171,8 @@ class StatisticsStore { void Rotate(); std::uint32_t statistics_size_limit_{kMaxSize}; - EnvStore env_store_; - MetricsStore metrics_store_; + EnvStore env_store_{}; + MetricsStore metrics_store_{}; RcPtr prev_logs_; RcPtr logs_; }; diff --git a/aether/transport/data_packet_collector.cpp b/aether/transport/data_packet_collector.cpp index a1001041..adede00a 100644 --- a/aether/transport/data_packet_collector.cpp +++ b/aether/transport/data_packet_collector.cpp @@ -53,7 +53,7 @@ void StreamDataPacketCollector::AddData(std::uint8_t const* data, } } -void StreamDataPacketCollector::AddData(DataBuffer data_buffer) { +void StreamDataPacketCollector::AddData(DataBuffer const& data_buffer) { AddData(data_buffer.data(), data_buffer.size()); } diff --git a/aether/transport/data_packet_collector.h b/aether/transport/data_packet_collector.h index d5da82f6..4eeec1e3 100644 --- a/aether/transport/data_packet_collector.h +++ b/aether/transport/data_packet_collector.h @@ -45,7 +45,7 @@ class StreamDataPacketCollector { public: // fill packets in queue with provided stream data_buffer void AddData(std::uint8_t const* data, std::size_t size); - void AddData(DataBuffer data_buffer); + void AddData(DataBuffer const& data_buffer); // pops a packet data if any, else return empty std::vector PopPacket(); diff --git a/aether/types/aligned_storage.h b/aether/types/aligned_storage.h index 22d2416d..caefac7b 100644 --- a/aether/types/aligned_storage.h +++ b/aether/types/aligned_storage.h @@ -128,7 +128,8 @@ class ManagedStorage { explicit ManagedStorage(T&& value) : vtable_{&MSVTableForT>} { static_assert(sizeof(T) <= Size, "T should fit into storage"); static_assert(Align % alignof(T) == 0, "T should be aligned like Align"); - new (storage_.data()) T{std::forward(value)}; + auto* p = storage_.data(); + new (p) T{std::forward(value)}; } // Create instance of T with arguments in place @@ -137,7 +138,8 @@ class ManagedStorage { : vtable_{&MSVTableForT} { static_assert(sizeof(T) <= Size, "T should fit into storage"); static_assert(Align % alignof(T) == 0, "T should be aligned like Align"); - new (storage_.data()) T{std::forward(args)...}; + auto* p = storage_.data(); + new (p) T{std::forward(args)...}; } // assign instance of T diff --git a/aether/types/static_map.h b/aether/types/static_map.h index 742f267d..5dac0cb8 100644 --- a/aether/types/static_map.h +++ b/aether/types/static_map.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace ae { template @@ -72,14 +73,12 @@ class StaticMap { constexpr size_type size() const { return Size; } [[nodiscard]] constexpr decltype(auto) find(key_type const& key) const { - for (std::size_t i = 0; i < Size; ++i) { - if (storage_[i].first == key) { - return std::next( - std::begin(storage_), - static_cast(i)); - } + auto it = std::find_if(std::begin(storage_), std::end(storage_), + [&key](auto const& s) { return s.first == key; }); + if (it == std::end(storage_)) { + return std::end(storage_); } - return std::end(storage_); + return it; } private: diff --git a/aether/types/uid.h b/aether/types/uid.h index 8af4fb4a..495cebcd 100644 --- a/aether/types/uid.h +++ b/aether/types/uid.h @@ -69,7 +69,7 @@ struct Uid { * \brief Get UID from string. * The https://www.ietf.org/rfc/rfc4122.txt format recognized only. */ - static constexpr Uid FromString(UidString str) { + static constexpr Uid FromString(UidString const& str) { if (!str.valid) { return {}; } diff --git a/aether/work_cloud.cpp b/aether/work_cloud.cpp index dd6c7748..6c159167 100644 --- a/aether/work_cloud.cpp +++ b/aether/work_cloud.cpp @@ -17,6 +17,6 @@ #include "aether/work_cloud.h" namespace ae { -WorkCloud::WorkCloud(ObjProp prop, Uid client_uid) +WorkCloud::WorkCloud(ObjProp prop, Uid const& client_uid) : Cloud{prop}, client_uid{client_uid} {} } // namespace ae diff --git a/aether/work_cloud.h b/aether/work_cloud.h index 75a31b12..853873b4 100644 --- a/aether/work_cloud.h +++ b/aether/work_cloud.h @@ -29,7 +29,7 @@ class WorkCloud : public Cloud { WorkCloud() = default; public: - WorkCloud(ObjProp prop, Uid client_uid); + WorkCloud(ObjProp prop, Uid const& client_uid); AE_OBJECT_REFLECT(AE_MMBRS(client_uid)) Uid client_uid; diff --git a/aether/work_cloud_api/client_api/client_api_safe.cpp b/aether/work_cloud_api/client_api/client_api_safe.cpp index 41e6febf..840999cb 100644 --- a/aether/work_cloud_api/client_api/client_api_safe.cpp +++ b/aether/work_cloud_api/client_api/client_api_safe.cpp @@ -26,29 +26,31 @@ namespace ae { ClientApiSafe::ClientApiSafe(ProtocolContext& protocol_context) : ApiClassImpl{protocol_context}, return_result{protocol_context} {} -void ClientApiSafe::SendMessages(std::vector messages) { +void ClientApiSafe::SendMessages(std::vector const& messages) { for (auto const& msg : messages) { AE_TELED_DEBUG("Received message uid:{}", msg.uid); send_message_event_.Emit(msg); } } -void ClientApiSafe::SendServerDescriptor(ServerDescriptor server_descriptor) { +void ClientApiSafe::SendServerDescriptor( + ServerDescriptor const& server_descriptor) { send_server_descriptor_event_.Emit(server_descriptor); } void ClientApiSafe::SendServerDescriptors( - std::vector server_descriptors) { + std::vector const& server_descriptors) { for (auto const& sd : server_descriptors) { send_server_descriptor_event_.Emit(sd); } } -void ClientApiSafe::SendCloud(Uid uid, CloudDescriptor cloud) { +void ClientApiSafe::SendCloud(Uid const& uid, CloudDescriptor const& cloud) { send_cloud_event_.Emit(uid, cloud); } -void ClientApiSafe::SendClouds(std::vector clouds) { +void ClientApiSafe::SendClouds( + std::vector const& clouds) { for (auto const& cloud : clouds) { send_cloud_event_.Emit(cloud.uid, cloud.cloud); } diff --git a/aether/work_cloud_api/client_api/client_api_safe.h b/aether/work_cloud_api/client_api/client_api_safe.h index af169168..e01474f3 100644 --- a/aether/work_cloud_api/client_api/client_api_safe.h +++ b/aether/work_cloud_api/client_api/client_api_safe.h @@ -32,12 +32,13 @@ class ClientApiSafe : public ApiClassImpl { public: explicit ClientApiSafe(ProtocolContext& protocol_context); - void SendMessages(std::vector messages); + void SendMessages(std::vector const& messages); - void SendServerDescriptor(ServerDescriptor server_descriptor); - void SendServerDescriptors(std::vector server_descriptors); - void SendCloud(Uid uid, CloudDescriptor cloud); - void SendClouds(std::vector clouds); + void SendServerDescriptor(ServerDescriptor const& server_descriptor); + void SendServerDescriptors( + std::vector const& server_descriptors); + void SendCloud(Uid const& uid, CloudDescriptor const& cloud); + void SendClouds(std::vector const& clouds); void RequestTelemetry(); diff --git a/cppcheck_suppressions.txt b/cppcheck_suppressions.txt new file mode 100644 index 00000000..491c86a1 --- /dev/null +++ b/cppcheck_suppressions.txt @@ -0,0 +1,24 @@ +missingIncludeSystem +functionStatic +unusedFunction +duplInheritedMember + + +*:third_party/* +*:esp-idf/* + +useInitializationList:tests/* +returnDanglingLifetime:tests/* +accessMoved:tests/* // sometimes it's specially checked if var is moved +cstyleCast:tests/* // c-style cast is heavily used in tests +dangerousTypeCast:tests/* // c-style cast is heavily used in tests +unusedStructMember:tests/test-reflect/* // there is a lot of members that looks unused + +constParameterCallback:capi/* +uninitMemberVar:aligned_storage.h +unreadVariable:aligned_storage.h +uninitMemberVar:ptr.h +uninitMemberVar:ptr_view.h + +noExplicitConstructor:crc.h +noExplicitConstructor:small_function.h diff --git a/examples/benches/send_messages_bandwidth/sender/sender_main.cpp b/examples/benches/send_messages_bandwidth/sender/sender_main.cpp index 1efb9c20..51787311 100644 --- a/examples/benches/send_messages_bandwidth/sender/sender_main.cpp +++ b/examples/benches/send_messages_bandwidth/sender/sender_main.cpp @@ -22,7 +22,7 @@ #include "aether/tele/tele.h" namespace ae::bench { -int test_sender_bandwidth(Uid receiver_uid) { +int test_sender_bandwidth(Uid const& receiver_uid) { auto aether_app = ae::AetherApp::Construct(AetherAppContext{}); ae::Client::ptr client; diff --git a/tests/test-object-system/objects/foo.h b/tests/test-object-system/objects/foo.h index abb0b611..f9d77b31 100644 --- a/tests/test-object-system/objects/foo.h +++ b/tests/test-object-system/objects/foo.h @@ -28,7 +28,7 @@ class Foo : public Obj { Foo() = default; public: - explicit Foo(ObjProp prop) : Obj{prop} { bar = Bar::ptr::Create(domain); } + explicit Foo(ObjProp prop) : Obj{prop}, bar{Bar::ptr::Create(domain)} {} AE_OBJECT_REFLECT(AE_MMBR(a), AE_MMBR(b), AE_MMBR(bar)) diff --git a/tests/test-object-system/objects/seven_fridays.h b/tests/test-object-system/objects/seven_fridays.h index 7d1c9d90..4eebafc5 100644 --- a/tests/test-object-system/objects/seven_fridays.h +++ b/tests/test-object-system/objects/seven_fridays.h @@ -67,8 +67,8 @@ class Friday1 : public Obj { dnv(a, b); } - int a; - int b; + int a{}; + int b{}; }; // change one field type and remove another @@ -126,7 +126,7 @@ class Friday2 : public Obj { } // default value provided if there is no saved state to load data - float a; + float a{}; }; class Hoopa : public Obj { @@ -207,7 +207,7 @@ class Friday3 : public Hoopa { void Save(Version<3>, Dnv& dnv) const {} // default value provided if there is no saved state to load data - float a; + float a{}; }; } // namespace ae diff --git a/tests/test-object-system/test-version-iterator.cpp b/tests/test-object-system/test-version-iterator.cpp index d895f926..79384167 100644 --- a/tests/test-object-system/test-version-iterator.cpp +++ b/tests/test-object-system/test-version-iterator.cpp @@ -28,8 +28,11 @@ struct VersionAllowed{})>> : std::true_type { }; void test_MaxVersion() { - Version<0> v; // ok! - Version max_version; // ok! + // test if possible to create a Version objects + // cppcheck-suppress-begin unreadVariable + Version<0> v{}; // ok! + Version max_version{}; // ok! + // cppcheck-suppress-end unreadVariable // Version to_big_version; // not ok! static_assert(VersionAllowed<0>::value, "Version<0> must be allowed"); @@ -149,7 +152,7 @@ void VersionIteratorLoadTestFunc(TFactory factory) { constexpr auto version_bounds = VersionedLoadMinMax::value; IterateVersions( - obj, [&visit_count](auto version, auto& obj) { ++visit_count; }); + obj, [&visit_count](auto, auto const&) { ++visit_count; }); TEST_ASSERT_EQUAL(expected_count, visit_count); } @@ -164,7 +167,7 @@ void VersionIteratorSaveTestFunc(TFactory factory) { constexpr auto version_bounds = VersionedSaveMinMax::value; IterateVersions( - obj, [&visit_count](auto version, auto& obj) { ++visit_count; }); + obj, [&visit_count](auto, auto const&) { ++visit_count; }); TEST_ASSERT_EQUAL(expected_count, visit_count); } diff --git a/tests/test-ptr/pipe_there_they_are_sitting.h b/tests/test-ptr/pipe_there_they_are_sitting.h index 9a7c0cf1..ba21b478 100644 --- a/tests/test-ptr/pipe_there_they_are_sitting.h +++ b/tests/test-ptr/pipe_there_they_are_sitting.h @@ -25,7 +25,7 @@ struct A { virtual ~A() { ++a_destroyed; } static inline int a_destroyed = 0; - int x; + int x{}; AE_REFLECT_MEMBERS(x) }; @@ -34,7 +34,7 @@ struct B : public A { ~B() override { ++b_destroyed; } static inline int b_destroyed = 0; - int y; + int y{}; AE_REFLECT_MEMBERS(y) }; } // namespace ae::test_ptr diff --git a/tests/test-ptr/test-shared-ptr-bench.cpp b/tests/test-ptr/test-shared-ptr-bench.cpp index e612740a..5c18819c 100644 --- a/tests/test-ptr/test-shared-ptr-bench.cpp +++ b/tests/test-ptr/test-shared-ptr-bench.cpp @@ -29,8 +29,8 @@ static constexpr std::size_t kBenchCount = 100'000'000; #endif struct Rabbit { - Rabbit(int y) { x = y * y; } - ~Rabbit() { x = x - x / 2; } + explicit Rabbit(int y) : x{y * y} {} + ~Rabbit() { x = x - (x / 2); } volatile int x{0}; }; @@ -79,7 +79,7 @@ void test_shared_ptr_CopyingBench() { tests::BenchmarkFunc( [&](auto i) { auto copy_rabbits = rabbits3; - for (auto& r : copy_rabbits) { + for (auto const& r : copy_rabbits) { r->x += i % 100; } }, diff --git a/tests/test-stream/safe-stream/test_safe_stream_send_recv.cpp b/tests/test-stream/safe-stream/test_safe_stream_send_recv.cpp index 78745e2d..1f24886d 100644 --- a/tests/test-stream/safe-stream/test_safe_stream_send_recv.cpp +++ b/tests/test-stream/safe-stream/test_safe_stream_send_recv.cpp @@ -120,7 +120,7 @@ class MockSendDataPush : public ISendDataPush { } ActionContext action_context_; - TestSafeStreamActionsTransport* transport_; + TestSafeStreamActionsTransport* transport_{}; }; class MockSendAckRepeat : public ISendAckRepeat { @@ -136,7 +136,7 @@ class MockSendAckRepeat : public ISendAckRepeat { transport_->SendRepeatRequest(offset); } - TestSafeStreamActionsTransport* transport_; + TestSafeStreamActionsTransport* transport_{}; }; static constexpr std::string_view test_data = diff --git a/tests/test-tele-statistics/test-tele-statistics.cpp b/tests/test-tele-statistics/test-tele-statistics.cpp index b5a97c83..dd096205 100644 --- a/tests/test-tele-statistics/test-tele-statistics.cpp +++ b/tests/test-tele-statistics/test-tele-statistics.cpp @@ -118,8 +118,24 @@ void test_SaveLoadTeleStatistics() { tele_statistics2->trap()->statistics_store.metrics_store().metrics; TEST_ASSERT_EQUAL(metrics1.size(), metrics2.size()); - if constexpr (_AE_MODULE_CONFIG(MLog.id, AE_TELE_METRICS_MODULES) && - _AE_MODULE_CONFIG(MLog.id, AE_TELE_METRICS_DURATION)) { + // simple check with _AE_MODULE_CONFIG leads here to AST broken error for + // cppcheck + constexpr bool all_and_not_excluded_duration = + IsAll(AE_TELE_METRICS_DURATION) && + !IsEnabled(AE_TELE_METRICS_DURATION_EXCLUDE); + + constexpr bool duration_enabled = + all_and_not_excluded_duration || + IsEnabled(AE_TELE_METRICS_DURATION); + + constexpr bool all_and_not_excluded_metrics = + (IsAll(AE_TELE_METRICS_MODULES) && + !IsEnabled(AE_TELE_METRICS_MODULES_EXCLUDE)); + + constexpr bool metrics_enabled = all_and_not_excluded_metrics || + IsEnabled(AE_TELE_METRICS_MODULES); + + if constexpr (duration_enabled && metrics_enabled) { auto log_index = kLog.offset; TEST_ASSERT_EQUAL(metrics1[log_index].invocations_count, metrics2[log_index].invocations_count); diff --git a/tests/test-types/test-aligned-storage.cpp b/tests/test-types/test-aligned-storage.cpp index e06e5628..400585ce 100644 --- a/tests/test-types/test-aligned-storage.cpp +++ b/tests/test-types/test-aligned-storage.cpp @@ -405,7 +405,7 @@ void test_ManagedStorageEdgeCases() { InPlace{}}; auto* managed_inner_ptr = managed_outer.ptr()->ptr(); - int* managed_value_ptr = managed_inner_ptr->ptr(); + int const* managed_value_ptr = managed_inner_ptr->ptr(); TEST_ASSERT_NOT_NULL(managed_value_ptr); } diff --git a/tests/test-types/test-small-function.cpp b/tests/test-types/test-small-function.cpp index b303b63f..2b4491fd 100644 --- a/tests/test-types/test-small-function.cpp +++ b/tests/test-types/test-small-function.cpp @@ -138,7 +138,7 @@ void test_DestructableCallableInVector() { funcs.emplace_back(DestructableCallable{}); } - for (auto& func : funcs) { + for (auto const& func : funcs) { func(); } } @@ -151,7 +151,7 @@ class Worker { static inline int invoke_count; static inline int const_invoke_count; - Worker(int expected) : expected(expected) {} + explicit Worker(int expected) : expected(expected) {} void Foo(int x) { invoke_count++; diff --git a/tests/test-types/test-type-list.cpp b/tests/test-types/test-type-list.cpp index c6c30a9c..75ff4eb5 100644 --- a/tests/test-types/test-type-list.cpp +++ b/tests/test-types/test-type-list.cpp @@ -36,9 +36,7 @@ constexpr auto MakeIndexSequenceWithStep() { } template -struct NType { - static constexpr std::size_t value = I; -}; +struct NType {}; template static constexpr auto MakeTypeListImpl(std::index_sequence) diff --git a/tools/registrator/main.cpp b/tools/registrator/main.cpp index 35f809c6..08e6e60a 100644 --- a/tools/registrator/main.cpp +++ b/tools/registrator/main.cpp @@ -18,10 +18,10 @@ #include #include -extern int AetherRegistrator(const std::string &ini_file, - const std::string &header_file); +extern int AetherRegistrator(const std::string& ini_file, + const std::string& header_file); -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { std::string ini_file{}; std::string header_file{}; @@ -30,9 +30,7 @@ int main(int argc, char *argv[]) { return -5; } - if (argc > 1) { - ini_file = std::string(argv[1]); - } + ini_file = std::string(argv[1]); if (!std::filesystem::exists(ini_file)) { std::cerr << "The configuration file was not found!\n"; return -4; diff --git a/tools/registrator/registrator_config.cpp b/tools/registrator/registrator_config.cpp index bcbb28d0..f75f0820 100644 --- a/tools/registrator/registrator_config.cpp +++ b/tools/registrator/registrator_config.cpp @@ -84,7 +84,7 @@ void RegistratorConfig::ParseWifiAdapter(ini::Section const& wifi_adapter) { void RegistratorConfig::ParseRegServer(ini::Section const& reg_server, std::string const& name) { - RegServer server; + RegServer server{}; // parse name and get id auto pos = name.find('_');