diff --git a/hal/src/main/native/cpp/ErrorHandling.cpp b/hal/src/main/native/cpp/ErrorHandling.cpp index 35aef02241..f32ab12980 100644 --- a/hal/src/main/native/cpp/ErrorHandling.cpp +++ b/hal/src/main/native/cpp/ErrorHandling.cpp @@ -2,6 +2,8 @@ // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. +#include "wpi/hal/ErrorHandling.hpp" + #include #include "wpi/hal/Errors.h" @@ -21,35 +23,36 @@ static LastErrorStorage& GetThreadLastError() { } namespace wpi::hal { -void SetLastError(int32_t* status, std::string_view value) { +HAL_Status MakeError(HAL_Status status, std::string_view value) { LastErrorStorage& lastError = GetThreadLastError(); lastError.message = value; - lastError.status = *status; - *status = HAL_USE_LAST_ERROR; + lastError.status = status; + return HAL_USE_LAST_ERROR; } -void SetLastErrorIndexOutOfRange(int32_t* status, std::string_view message, - int32_t minimum, int32_t maximum, - int32_t requested) { - SetLastError( +HAL_Status MakeErrorIndexOutOfRange(HAL_Status status, std::string_view message, + int32_t minimum, int32_t maximum, + int32_t requested) { + return MakeError( status, fmt::format("{}\n Status: {}\n Minimum: {} Maximum: {} Requested: {}", - message, *status, minimum, maximum, requested)); + message, status, minimum, maximum, requested)); } -void SetLastErrorPreviouslyAllocated(int32_t* status, std::string_view message, - int32_t channel, - std::string_view previousAllocation) { - wpi::hal::SetLastError( - status, fmt::format("{} {} previously allocated.\n" - "Location of the previous allocation:\n{}\n" - "Location of the current allocation:", - message, channel, previousAllocation)); +HAL_Status MakeErrorPreviouslyAllocated(HAL_Status status, + std::string_view message, + int32_t channel, + std::string_view previousAllocation) { + return MakeError(status, + fmt::format("{} {} previously allocated.\n" + "Location of the previous allocation:\n{}\n" + "Location of the current allocation:", + message, channel, previousAllocation)); } } // namespace wpi::hal extern "C" { -const char* HAL_GetLastError(int32_t* status) { +const char* HAL_GetLastError(HAL_Status* status) { if (*status == HAL_USE_LAST_ERROR) { LastErrorStorage& lastError = GetThreadLastError(); *status = lastError.status; diff --git a/hal/src/main/native/include/wpi/hal/ErrorHandling.hpp b/hal/src/main/native/include/wpi/hal/ErrorHandling.hpp new file mode 100644 index 0000000000..0a81af3980 --- /dev/null +++ b/hal/src/main/native/include/wpi/hal/ErrorHandling.hpp @@ -0,0 +1,27 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#include + +#include "wpi/hal/Types.h" + +namespace wpi::hal { +[[nodiscard]] +HAL_Status MakeError(HAL_Status status, std::string_view value); + +[[nodiscard]] +HAL_Status MakeErrorIndexOutOfRange(HAL_Status status, std::string_view message, + int32_t minimum, int32_t maximum, + int32_t channel); + +[[nodiscard]] +HAL_Status MakeErrorPreviouslyAllocated(HAL_Status status, + std::string_view message, + int32_t channel, + std::string_view previousAllocation); +} // namespace wpi::hal diff --git a/hal/src/main/native/include/wpi/hal/HAL.h b/hal/src/main/native/include/wpi/hal/HAL.h index 59acf610b5..ff538396f2 100644 --- a/hal/src/main/native/include/wpi/hal/HAL.h +++ b/hal/src/main/native/include/wpi/hal/HAL.h @@ -46,7 +46,7 @@ extern "C" { * @return the error message for the code. This does not need to be freed, * but can be overwritten by another hal call on the same thread. */ -const char* HAL_GetLastError(int32_t* status); +const char* HAL_GetLastError(HAL_Status* status); /** * Gets the error message for a specific status code. diff --git a/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp b/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp index ff7b511729..0cdde01d0e 100644 --- a/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/DigitalHandleResource.hpp @@ -8,10 +8,14 @@ #include #include +#include +#include +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/Types.h" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/util/expected" #include "wpi/util/mutex.hpp" namespace wpi::hal { @@ -37,8 +41,8 @@ class DigitalHandleResource : public HandleBase { DigitalHandleResource(const DigitalHandleResource&) = delete; DigitalHandleResource& operator=(const DigitalHandleResource&) = delete; - std::shared_ptr Allocate(int16_t index, HAL_HandleEnum enumValue, - THandle* handle, int32_t* status); + wpi::util::expected>, HAL_Status> + Allocate(int16_t index, HAL_HandleEnum enumValue, std::string_view name); int16_t GetIndex(THandle handle, HAL_HandleEnum enumValue) { return getHandleTypedIndex(handle, enumValue, m_version); } @@ -52,27 +56,30 @@ class DigitalHandleResource : public HandleBase { }; template -std::shared_ptr +wpi::util::expected>, HAL_Status> DigitalHandleResource::Allocate( - int16_t index, HAL_HandleEnum enumValue, THandle* handle, int32_t* status) { + int16_t index, HAL_HandleEnum enumValue, std::string_view name) { // don't acquire the lock if we can fail early. if (index < 0 || index >= size) { - *handle = HAL_INVALID_HANDLE; - *status = RESOURCE_OUT_OF_RANGE; - return nullptr; + return wpi::util::unexpected( + MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, name, 0, size, index)); } std::scoped_lock lock(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { - *handle = HAL_INVALID_HANDLE; - *status = RESOURCE_IS_ALLOCATED; - return m_structures[index]; + if constexpr (detail::HasPreviousAllocation) { + return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + RESOURCE_IS_ALLOCATED, name, index, + m_structures[index]->previousAllocation)); + } else { + return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + RESOURCE_IS_ALLOCATED, name, index, "unknown")); + } } m_structures[index] = std::make_shared(); - *handle = + THandle handle = static_cast(wpi::hal::createHandle(index, enumValue, m_version)); - *status = HAL_SUCCESS; - return m_structures[index]; + return std::pair{handle, m_structures[index]}; } template diff --git a/hal/src/main/native/include/wpi/hal/handles/HandlesInternal.hpp b/hal/src/main/native/include/wpi/hal/handles/HandlesInternal.hpp index dc2408fa9b..f287ad9293 100644 --- a/hal/src/main/native/include/wpi/hal/handles/HandlesInternal.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/HandlesInternal.hpp @@ -6,6 +6,9 @@ #include +#include +#include + #include "wpi/hal/Types.h" #include "wpi/util/Synchronization.hpp" @@ -21,6 +24,13 @@ namespace wpi::hal { +namespace detail { +template +concept HasPreviousAllocation = requires(T a) { + { a.previousAllocation } -> std::convertible_to; +}; +} // namespace detail + /** * Base for all HAL Handles. */ diff --git a/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp b/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp index e8282ead06..5f78f63485 100644 --- a/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/IndexedClassedHandleResource.hpp @@ -9,9 +9,11 @@ #include #include +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/Types.h" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/util/expected" #include "wpi/util/mutex.hpp" namespace wpi::hal { @@ -40,8 +42,9 @@ class IndexedClassedHandleResource : public HandleBase { IndexedClassedHandleResource& operator=(const IndexedClassedHandleResource&) = delete; - THandle Allocate(int16_t index, std::shared_ptr toSet, - int32_t* status); + wpi::util::expected Allocate( + int16_t index, std::shared_ptr toSet, std::string_view name, + int offset = 0); int16_t GetIndex(THandle handle) { return getHandleTypedIndex(handle, enumValue, m_version); } @@ -56,19 +59,26 @@ class IndexedClassedHandleResource : public HandleBase { template -THandle +wpi::util::expected IndexedClassedHandleResource::Allocate( - int16_t index, std::shared_ptr toSet, int32_t* status) { + int16_t index, std::shared_ptr toSet, std::string_view name, + int offset) { // don't acquire the lock if we can fail early. if (index < 0 || index >= size) { - *status = RESOURCE_OUT_OF_RANGE; - return HAL_INVALID_HANDLE; + return wpi::util::unexpected(MakeErrorIndexOutOfRange( + RESOURCE_OUT_OF_RANGE, name, offset, size + offset, index + offset)); } std::scoped_lock lock(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { - *status = RESOURCE_IS_ALLOCATED; - return HAL_INVALID_HANDLE; + if constexpr (detail::HasPreviousAllocation) { + return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + RESOURCE_IS_ALLOCATED, name, index + offset, + m_structures[index]->previousAllocation)); + } else { + return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + RESOURCE_IS_ALLOCATED, name, index + offset, "unknown")); + } } m_structures[index] = toSet; return static_cast( diff --git a/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp b/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp index ad263565e2..ee7db0cec5 100644 --- a/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp +++ b/hal/src/main/native/include/wpi/hal/handles/IndexedHandleResource.hpp @@ -8,10 +8,14 @@ #include #include +#include +#include +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/Types.h" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/util/expected" #include "wpi/util/mutex.hpp" namespace wpi::hal { @@ -38,8 +42,8 @@ class IndexedHandleResource : public HandleBase { IndexedHandleResource(const IndexedHandleResource&) = delete; IndexedHandleResource& operator=(const IndexedHandleResource&) = delete; - std::shared_ptr Allocate(int16_t index, THandle* handle, - int32_t* status); + wpi::util::expected>, HAL_Status> + Allocate(int16_t index, std::string_view name, int offset = 0); int16_t GetIndex(THandle handle) { return getHandleTypedIndex(handle, enumValue, m_version); } @@ -54,27 +58,30 @@ class IndexedHandleResource : public HandleBase { template -std::shared_ptr +wpi::util::expected>, HAL_Status> IndexedHandleResource::Allocate( - int16_t index, THandle* handle, int32_t* status) { + int16_t index, std::string_view name, int offset) { // don't acquire the lock if we can fail early. if (index < 0 || index >= size) { - *status = RESOURCE_OUT_OF_RANGE; - *handle = HAL_INVALID_HANDLE; - return nullptr; + return wpi::util::unexpected(MakeErrorIndexOutOfRange( + RESOURCE_OUT_OF_RANGE, name, offset, size + offset, index + offset)); } std::scoped_lock lock(m_handleMutexes[index]); // check for allocation, otherwise allocate and return a valid handle if (m_structures[index] != nullptr) { - *status = RESOURCE_IS_ALLOCATED; - *handle = HAL_INVALID_HANDLE; - return m_structures[index]; + if constexpr (detail::HasPreviousAllocation) { + return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + RESOURCE_IS_ALLOCATED, name, index + offset, + m_structures[index]->previousAllocation)); + } else { + return wpi::util::unexpected(MakeErrorPreviouslyAllocated( + RESOURCE_IS_ALLOCATED, name, index + offset, "unknown")); + } } m_structures[index] = std::make_shared(); - *handle = + auto handle = static_cast(wpi::hal::createHandle(index, enumValue, m_version)); - *status = HAL_SUCCESS; - return m_structures[index]; + return std::pair{handle, m_structures[index]}; } template = kNumAddressableLEDs) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for AddressableLED", 0, - kNumAddressableLEDs, channel); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for AddressableLED", 0, + kNumAddressableLEDs, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = digitalChannelHandles->Allocate( + channel, HAL_HandleEnum::ADDRESSABLE_LED, "AddressableLED"); - auto port = digitalChannelHandles->Allocate( - channel, HAL_HandleEnum::ADDRESSABLE_LED, &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "PWM or DIO", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for AddressableLED", - 0, kNumAddressableLEDs, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = static_cast(channel); SimAddressableLEDData[channel].start = 0; @@ -80,9 +71,8 @@ void HAL_SetAddressableLEDStart(HAL_AddressableLEDHandle handle, int32_t start, return; } if (start > HAL_ADDRESSABLE_LED_MAX_LEN || start < 0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format( "LED start must be less than or equal to {}. {} was requested", HAL_ADDRESSABLE_LED_MAX_LEN, start)); @@ -100,9 +90,8 @@ void HAL_SetAddressableLEDLength(HAL_AddressableLEDHandle handle, return; } if (length > HAL_ADDRESSABLE_LED_MAX_LEN || length < 0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format( "LED length must be less than or equal to {}. {} was requested", HAL_ADDRESSABLE_LED_MAX_LEN, length)); diff --git a/hal/src/main/native/sim/AnalogInput.cpp b/hal/src/main/native/sim/AnalogInput.cpp index 07a414727e..9f86d57f0b 100644 --- a/hal/src/main/native/sim/AnalogInput.cpp +++ b/hal/src/main/native/sim/AnalogInput.cpp @@ -6,9 +6,9 @@ #include "AnalogInternal.hpp" #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/AnalogInDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" using namespace wpi::hal; @@ -21,27 +21,20 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort( int32_t channel, const char* allocationLocation, int32_t* status) { wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumAnalogInputs) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange( - status, "Invalid Index for Analog Input", 0, kNumAnalogInputs, channel); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for Analog Input", 0, + kNumAnalogInputs, channel); return HAL_INVALID_HANDLE; } - HAL_AnalogInputHandle handle; - auto analog_port = analogInputHandles->Allocate(channel, &handle, status); + auto resource = analogInputHandles->Allocate(channel, "Analog"); - if (*status != 0) { - if (analog_port) { - wpi::hal::SetLastErrorPreviouslyAllocated( - status, "Analog Input", channel, analog_port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for Analog Input", 0, - kNumAnalogInputs, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, analog_port] = *resource; analog_port->channel = static_cast(channel); SimAnalogInData[channel].initialized = true; diff --git a/hal/src/main/native/sim/CTREPCM.cpp b/hal/src/main/native/sim/CTREPCM.cpp index 9a26f21cf9..0bb04f30c7 100644 --- a/hal/src/main/native/sim/CTREPCM.cpp +++ b/hal/src/main/native/sim/CTREPCM.cpp @@ -7,9 +7,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/CTREPCMDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -40,21 +40,14 @@ HAL_CTREPCMHandle HAL_InitializeCTREPCM(int32_t busId, int32_t module, int32_t* status) { wpi::hal::init::CheckInit(); - HAL_CTREPCMHandle handle; - auto pcm = pcmHandles->Allocate(module, &handle, status); + auto resource = pcmHandles->Allocate(module, "CTRE PCM"); - if (*status != 0) { - if (pcm) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "CTRE PCM", module, - pcm->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for CTRE PCM", 0, - kNumCTREPCMModules - 1, module); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, pcm] = *resource; pcm->previousAllocation = allocationLocation ? allocationLocation : ""; pcm->module = module; diff --git a/hal/src/main/native/sim/DIO.cpp b/hal/src/main/native/sim/DIO.cpp index 8bf3a24d8e..b6cad07986 100644 --- a/hal/src/main/native/sim/DIO.cpp +++ b/hal/src/main/native/sim/DIO.cpp @@ -6,10 +6,11 @@ #include "DigitalInternal.hpp" #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/DIODataInternal.hpp" #include "mockdata/DigitalPWMDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" +#include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/handles/LimitedHandleResource.hpp" @@ -37,28 +38,21 @@ HAL_DigitalHandle HAL_InitializeDIOPort(int32_t channel, HAL_Bool input, wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumDigitalChannels) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DIO", 0, - kNumDigitalChannels, channel); + *status = + MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, "Invalid Index for DIO", + 0, kNumDigitalChannels, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = + digitalChannelHandles->Allocate(channel, HAL_HandleEnum::DIO, "DIO"); - auto port = digitalChannelHandles->Allocate(channel, HAL_HandleEnum::DIO, - &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "PWM or DIO", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DIO", 0, - kNumDigitalChannels, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = static_cast(channel); SimDIOData[channel].initialized = true; @@ -189,8 +183,8 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value, } } if (SimDIOData[port->channel].isInput) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError(status, "Cannot set output of an input channel"); + *status = MakeError(PARAMETER_OUT_OF_RANGE, + "Cannot set output of an input channel"); return; } SimDIOData[port->channel].value = value; diff --git a/hal/src/main/native/sim/DutyCycle.cpp b/hal/src/main/native/sim/DutyCycle.cpp index 5be29264c7..96dbeff7d6 100644 --- a/hal/src/main/native/sim/DutyCycle.cpp +++ b/hal/src/main/native/sim/DutyCycle.cpp @@ -7,9 +7,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/DutyCycleDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -42,20 +42,14 @@ HAL_DutyCycleHandle HAL_InitializeDutyCycle(int32_t channel, int32_t* status) { wpi::hal::init::CheckInit(); - HAL_DutyCycleHandle handle = HAL_INVALID_HANDLE; - auto dutyCycle = dutyCycleHandles->Allocate(channel, &handle, status); + auto resource = dutyCycleHandles->Allocate(channel, "Duty Cycle"); - if (*status != 0) { - if (dutyCycle) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - dutyCycle->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange( - status, "Invalid Index for Duty Cycle", 0, kNumDutyCycles, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, dutyCycle] = *resource; int16_t index = getHandleIndex(handle); SimDutyCycleData[index].initialized = true; SimDutyCycleData[index].simDevice = 0; diff --git a/hal/src/main/native/sim/Encoder.cpp b/hal/src/main/native/sim/Encoder.cpp index 4bbc3e05d1..a40d10f045 100644 --- a/hal/src/main/native/sim/Encoder.cpp +++ b/hal/src/main/native/sim/Encoder.cpp @@ -8,9 +8,9 @@ #include "CounterInternal.hpp" #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/EncoderDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/handles/LimitedHandleResource.hpp" @@ -271,8 +271,7 @@ void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate, } if (minRate == 0.0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError(status, "minRate must not be 0"); + *status = MakeError(PARAMETER_OUT_OF_RANGE, "minRate must not be 0"); return; } @@ -288,8 +287,8 @@ void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle, } if (distancePerPulse == 0.0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError(status, "distancePerPulse must not be 0"); + *status = + MakeError(PARAMETER_OUT_OF_RANGE, "distancePerPulse must not be 0"); return; } encoder->distancePerPulse = distancePerPulse; diff --git a/hal/src/main/native/sim/HALInternal.hpp b/hal/src/main/native/sim/HALInternal.hpp deleted file mode 100644 index 0023442999..0000000000 --- a/hal/src/main/native/sim/HALInternal.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#pragma once - -#include - -#include - -namespace wpi::hal { -void SetLastError(int32_t* status, std::string_view value); -void SetLastErrorIndexOutOfRange(int32_t* status, std::string_view message, - int32_t minimum, int32_t maximum, - int32_t channel); -void SetLastErrorPreviouslyAllocated(int32_t* status, std::string_view message, - int32_t channel, - std::string_view previousAllocation); -} // namespace wpi::hal diff --git a/hal/src/main/native/sim/PWM.cpp b/hal/src/main/native/sim/PWM.cpp index baa8bd0648..6ecb9efc27 100644 --- a/hal/src/main/native/sim/PWM.cpp +++ b/hal/src/main/native/sim/PWM.cpp @@ -6,9 +6,9 @@ #include "DigitalInternal.hpp" #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/PWMDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/handles/HandlesInternal.hpp" using namespace wpi::hal; @@ -25,9 +25,9 @@ HAL_DigitalHandle HAL_InitializePWMPort(int32_t channel, wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumPWMChannels) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for PWM", 0, - kNumPWMChannels, channel); + *status = + MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, "Invalid Index for PWM", + 0, kNumPWMChannels, channel); return HAL_INVALID_HANDLE; } @@ -39,22 +39,15 @@ HAL_DigitalHandle HAL_InitializePWMPort(int32_t channel, channel = remapMXPPWMChannel(channel) + 10; // remap MXP to proper channel } - HAL_DigitalHandle handle; + auto resource = + digitalChannelHandles->Allocate(channel, HAL_HandleEnum::PWM, "PWM"); - auto port = digitalChannelHandles->Allocate(channel, HAL_HandleEnum::PWM, - &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "PWM or DIO", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for PWM", 0, - kNumPWMChannels, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = origChannel; SimPWMData[origChannel].initialized = true; diff --git a/hal/src/main/native/sim/PowerDistribution.cpp b/hal/src/main/native/sim/PowerDistribution.cpp index 94f8bb5cbb..6379f312d0 100644 --- a/hal/src/main/native/sim/PowerDistribution.cpp +++ b/hal/src/main/native/sim/PowerDistribution.cpp @@ -8,10 +8,10 @@ #include "CANAPIInternal.hpp" #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/PowerDistributionDataInternal.hpp" #include "wpi/hal/CANAPI.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" using namespace wpi::hal; @@ -32,9 +32,9 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution( const char* allocationLocation, int32_t* status) { if (type == HAL_POWER_DISTRIBUTION_AUTOMATIC) { if (module != HAL_DEFAULT_POWER_DISTRIBUTION_MODULE) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, "Automatic PowerDistributionType must have default module"); + *status = + MakeError(PARAMETER_OUT_OF_RANGE, + "Automatic PowerDistributionType must have default module"); return HAL_INVALID_HANDLE; } @@ -44,14 +44,14 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution( } if (!HAL_CheckPowerDistributionModule(module, type)) { - *status = RESOURCE_OUT_OF_RANGE; if (type == HAL_PowerDistributionType::HAL_POWER_DISTRIBUTION_CTRE) { - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for CTRE PDP", 0, - kNumCTREPDPModules - 1, module); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for CTRE PDP", 0, + kNumCTREPDPModules - 1, module); } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PDH", - 1, kNumREVPDHModules, module); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for REV PDH", 1, + kNumREVPDHModules, module); } return HAL_INVALID_HANDLE; } diff --git a/hal/src/main/native/sim/REVPH.cpp b/hal/src/main/native/sim/REVPH.cpp index 52eb0f7441..4bf0b4ea35 100644 --- a/hal/src/main/native/sim/REVPH.cpp +++ b/hal/src/main/native/sim/REVPH.cpp @@ -7,9 +7,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "mockdata/REVPHDataInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -41,27 +41,21 @@ HAL_REVPHHandle HAL_InitializeREVPH(int32_t busId, int32_t module, wpi::hal::init::CheckInit(); if (!HAL_CheckREVPHModuleNumber(module)) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PH", 1, - kNumREVPHModules, module); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for REV PH", 1, + kNumREVPHModules, module); return HAL_INVALID_HANDLE; } - HAL_REVPHHandle handle; // Module starts at 1 - auto pcm = pcmHandles->Allocate(module - 1, &handle, status); + auto resource = pcmHandles->Allocate(module - 1, "REV PH", 1); - if (*status != 0) { - if (pcm) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "REV PH", module, - pcm->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PH", - 1, kNumREVPHModules, module); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, pcm] = *resource; pcm->previousAllocation = allocationLocation ? allocationLocation : ""; pcm->module = module; diff --git a/hal/src/main/native/systemcore/AddressableLED.cpp b/hal/src/main/native/systemcore/AddressableLED.cpp index fb687c2331..faebaff94e 100644 --- a/hal/src/main/native/systemcore/AddressableLED.cpp +++ b/hal/src/main/native/systemcore/AddressableLED.cpp @@ -14,11 +14,11 @@ #include "AddressableLEDSimd.hpp" #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" #include "SystemServerInternal.hpp" #include "wpi/hal/AddressableLEDTypes.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/monotonic_clock.hpp" @@ -89,28 +89,21 @@ HAL_AddressableLEDHandle HAL_InitializeAddressableLED( wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumSmartIo) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange( - status, "Invalid Index for AddressableLED", 0, kNumSmartIo, channel); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for AddressableLED", 0, + kNumSmartIo, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = smartIoHandles->Allocate( + channel, HAL_HandleEnum::ADDRESSABLE_LED, "AddressableLED"); - auto port = smartIoHandles->Allocate(channel, HAL_HandleEnum::ADDRESSABLE_LED, - &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange( - status, "Invalid Index for AddressableLED", 0, kNumSmartIo, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = channel; *status = port->InitializeMode(SmartIoMode::AddressableLED); diff --git a/hal/src/main/native/systemcore/AnalogInput.cpp b/hal/src/main/native/systemcore/AnalogInput.cpp index 30f1bbea72..498b3d01f9 100644 --- a/hal/src/main/native/systemcore/AnalogInput.cpp +++ b/hal/src/main/native/systemcore/AnalogInput.cpp @@ -8,9 +8,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/monotonic_clock.hpp" @@ -28,28 +28,21 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort( wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumSmartIo) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for Analog", 0, - kNumSmartIo, channel); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for Analog", 0, + kNumSmartIo, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = + smartIoHandles->Allocate(channel, HAL_HandleEnum::ANALOG_INPUT, "Analog"); - auto port = smartIoHandles->Allocate(channel, HAL_HandleEnum::ANALOG_INPUT, - &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for Analog", - 0, kNumSmartIo, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = channel; *status = port->InitializeMode(SmartIoMode::AnalogInput); diff --git a/hal/src/main/native/systemcore/CTREPCM.cpp b/hal/src/main/native/systemcore/CTREPCM.cpp index 556da4a5b0..1b4b0ce786 100644 --- a/hal/src/main/native/systemcore/CTREPCM.cpp +++ b/hal/src/main/native/systemcore/CTREPCM.cpp @@ -9,9 +9,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "wpi/hal/CANAPI.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -180,21 +180,14 @@ HAL_CTREPCMHandle HAL_InitializeCTREPCM(int32_t busId, int32_t module, int32_t* status) { wpi::hal::init::CheckInit(); - HAL_CTREPCMHandle handle; - auto pcm = pcmHandles->Allocate(module, &handle, status); + auto resource = pcmHandles->Allocate(module, "CTRE PCM"); - if (*status != 0) { - if (pcm) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "CTRE PCM", module, - pcm->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for CTRE PCM", 0, - kNumCTREPCMModules - 1, module); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, pcm] = *resource; pcm->canHandle = HAL_InitializeCAN(busId, manufacturer, module, deviceType, status); if (*status != 0) { @@ -360,9 +353,8 @@ void HAL_ClearAllCTREPCMStickyFaults(HAL_CTREPCMHandle handle, void HAL_FireCTREPCMOneShot(HAL_CTREPCMHandle handle, int32_t index, int32_t* status) { if (index > 7 || index < 0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format("Only [0-7] are valid index values. Requested {}", index)); return; } @@ -392,9 +384,8 @@ void HAL_FireCTREPCMOneShot(HAL_CTREPCMHandle handle, int32_t index, void HAL_SetCTREPCMOneShotDuration(HAL_CTREPCMHandle handle, int32_t index, int32_t durMs, int32_t* status) { if (index > 7 || index < 0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format("Only [0-7] are valid index values. Requested {}", index)); return; } diff --git a/hal/src/main/native/systemcore/CTREPDP.cpp b/hal/src/main/native/systemcore/CTREPDP.cpp index 4b6e0c9af9..c3c5835345 100644 --- a/hal/src/main/native/systemcore/CTREPDP.cpp +++ b/hal/src/main/native/systemcore/CTREPDP.cpp @@ -9,10 +9,10 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "wpi/hal/CAN.h" #include "wpi/hal/CANAPI.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -133,27 +133,20 @@ HAL_PDPHandle HAL_InitializePDP(int32_t busId, int32_t module, int32_t* status) { wpi::hal::init::CheckInit(); if (!HAL_CheckPDPModule(module)) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for CTRE PDP", - 0, kNumCTREPDPModules - 1, module); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for CTRE PDP", 0, + kNumCTREPDPModules - 1, module); return HAL_INVALID_HANDLE; } - HAL_PDPHandle handle; - auto pdp = pdpHandles->Allocate(module, &handle, status); + auto resource = pdpHandles->Allocate(module, "CTRE PDP"); - if (*status != 0) { - if (pdp) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "CTRE PDP", module, - pdp->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, - "Invalid Index for CTRE PDP", 0, - kNumCTREPDPModules - 1, module); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, pdp] = *resource; pdp->canHandle = HAL_InitializeCAN(busId, manufacturer, module, deviceType, status); if (*status != 0) { @@ -231,9 +224,8 @@ double HAL_GetPDPVoltage(HAL_PDPHandle handle, int32_t* status) { double HAL_GetPDPChannelCurrent(HAL_PDPHandle handle, int32_t channel, int32_t* status) { if (!HAL_CheckPDPChannel(channel)) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError(status, - fmt::format("Invalid pdp channel {}", channel)); + *status = MakeError(PARAMETER_OUT_OF_RANGE, + fmt::format("Invalid pdp channel {}", channel)); return 0; } diff --git a/hal/src/main/native/systemcore/Counter.cpp b/hal/src/main/native/systemcore/Counter.cpp index e8fbfb5039..18c7207523 100644 --- a/hal/src/main/native/systemcore/Counter.cpp +++ b/hal/src/main/native/systemcore/Counter.cpp @@ -10,9 +10,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/monotonic_clock.hpp" using namespace wpi::hal; @@ -28,28 +28,21 @@ HAL_CounterHandle HAL_InitializeCounter(int channel, HAL_Bool risingEdge, int32_t* status) { wpi::hal::init::CheckInit(); if (channel == INVALID_HANDLE_INDEX || channel >= kNumSmartIo) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for Counter", - 0, kNumSmartIo, channel); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for Counter", 0, + kNumSmartIo, channel); return HAL_INVALID_HANDLE; } - HAL_CounterHandle handle; + auto resource = + smartIoHandles->Allocate(channel, HAL_HandleEnum::COUNTER, "Counter"); - auto port = smartIoHandles->Allocate(channel, HAL_HandleEnum::COUNTER, - &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for Counter", - 0, kNumSmartIo, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = channel; *status = diff --git a/hal/src/main/native/systemcore/DIO.cpp b/hal/src/main/native/systemcore/DIO.cpp index 07ee2348c9..de9adad034 100644 --- a/hal/src/main/native/systemcore/DIO.cpp +++ b/hal/src/main/native/systemcore/DIO.cpp @@ -9,9 +9,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/monotonic_clock.hpp" @@ -30,28 +30,20 @@ HAL_DigitalHandle HAL_InitializeDIOPort(int32_t channel, HAL_Bool input, wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumSmartIo) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DIO", 0, - kNumSmartIo, channel); + *status = + MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, "Invalid Index for DIO", + 0, kNumSmartIo, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = smartIoHandles->Allocate(channel, HAL_HandleEnum::DIO, "DIO"); - auto port = - smartIoHandles->Allocate(channel, HAL_HandleEnum::DIO, &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DIO", 0, - kNumSmartIo, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = channel; *status = port->InitializeMode(input ? SmartIoMode::DigitalInput diff --git a/hal/src/main/native/systemcore/DutyCycle.cpp b/hal/src/main/native/systemcore/DutyCycle.cpp index 4647d6cce6..86714d0bdf 100644 --- a/hal/src/main/native/systemcore/DutyCycle.cpp +++ b/hal/src/main/native/systemcore/DutyCycle.cpp @@ -8,9 +8,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/monotonic_clock.hpp" @@ -28,28 +28,21 @@ HAL_DutyCycleHandle HAL_InitializeDutyCycle(int32_t channel, wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumSmartIo) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DutyCycle", - 0, kNumSmartIo, channel); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for DutyCycle", 0, + kNumSmartIo, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = smartIoHandles->Allocate(channel, HAL_HandleEnum::DUTY_CYCLE, + "DutyCycle"); - auto port = smartIoHandles->Allocate(channel, HAL_HandleEnum::DUTY_CYCLE, - &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange( - status, "Invalid Index for DutyCycle", 0, kNumSmartIo, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = channel; *status = port->InitializeMode(SmartIoMode::PwmInput); diff --git a/hal/src/main/native/systemcore/HALInternal.hpp b/hal/src/main/native/systemcore/HALInternal.hpp index 628763c9ed..db84145b8c 100644 --- a/hal/src/main/native/systemcore/HALInternal.hpp +++ b/hal/src/main/native/systemcore/HALInternal.hpp @@ -6,15 +6,6 @@ #include -#include - namespace wpi::hal { -void SetLastError(int32_t* status, std::string_view value); -void SetLastErrorIndexOutOfRange(int32_t* status, std::string_view message, - int32_t minimum, int32_t maximum, - int32_t channel); -void SetLastErrorPreviouslyAllocated(int32_t* status, std::string_view message, - int32_t channel, - std::string_view previousAllocation); uint64_t GetDSInitializeTime(); } // namespace wpi::hal diff --git a/hal/src/main/native/systemcore/I2C.cpp b/hal/src/main/native/systemcore/I2C.cpp index 6b10841713..66c3381509 100644 --- a/hal/src/main/native/systemcore/I2C.cpp +++ b/hal/src/main/native/systemcore/I2C.cpp @@ -15,8 +15,8 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/util/mutex.hpp" #include "wpi/util/print.hpp" @@ -45,9 +45,8 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) { wpi::hal::init::CheckInit(); if (port < 0 || port > 2) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for I2C", 0, 1, - port); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for I2C", 0, 1, port); return; } @@ -59,9 +58,8 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) { int handle = open(physicalPorts[port], O_RDWR); if (handle < 0) { int err = errno; - *status = NO_AVAILABLE_RESOURCES; - wpi::hal::SetLastError( - status, + *status = MakeError( + NO_AVAILABLE_RESOURCES, fmt::format("Failed to open onboard i2c bus: {}", std::strerror(err))); wpi::util::print("Failed to open onboard i2c bus: {}\n", std::strerror(err)); @@ -76,9 +74,8 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress, const uint8_t* dataToSend, int32_t sendSize, uint8_t* dataReceived, int32_t receiveSize) { if (port < 0 || port > 2) { - int32_t status = 0; - wpi::hal::SetLastErrorIndexOutOfRange(&status, "Invalid Index for I2C", 0, - 1, port); + (void)MakeErrorIndexOutOfRange(PARAMETER_OUT_OF_RANGE, + "Invalid Index for I2C", 0, 1, port); return -1; } @@ -103,9 +100,8 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress, int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress, const uint8_t* dataToSend, int32_t sendSize) { if (port < 0 || port > 2) { - int32_t status = 0; - wpi::hal::SetLastErrorIndexOutOfRange(&status, "Invalid Index for I2C", 0, - 2, port); + (void)MakeErrorIndexOutOfRange(PARAMETER_OUT_OF_RANGE, + "Invalid Index for I2C", 0, 2, port); return -1; } @@ -126,9 +122,8 @@ int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress, int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer, int32_t count) { if (port < 0 || port > 2) { - int32_t status = 0; - wpi::hal::SetLastErrorIndexOutOfRange(&status, "Invalid Index for I2C", 0, - 1, port); + (void)MakeErrorIndexOutOfRange(PARAMETER_OUT_OF_RANGE, + "Invalid Index for I2C", 0, 1, port); return -1; } @@ -148,9 +143,8 @@ int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer, void HAL_CloseI2C(HAL_I2CPort port) { if (port < 0 || port > 2) { - int32_t status = 0; - wpi::hal::SetLastErrorIndexOutOfRange(&status, "Invalid Index for I2C", 0, - 1, port); + (void)MakeErrorIndexOutOfRange(PARAMETER_OUT_OF_RANGE, + "Invalid Index for I2C", 0, 1, port); return; } diff --git a/hal/src/main/native/systemcore/PWM.cpp b/hal/src/main/native/systemcore/PWM.cpp index d20b940e0a..b51fc44d2f 100644 --- a/hal/src/main/native/systemcore/PWM.cpp +++ b/hal/src/main/native/systemcore/PWM.cpp @@ -11,9 +11,9 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/monotonic_clock.hpp" @@ -32,28 +32,20 @@ HAL_DigitalHandle HAL_InitializePWMPort(int32_t channel, wpi::hal::init::CheckInit(); if (channel < 0 || channel >= kNumSmartIo) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for PWM", 0, - kNumSmartIo, channel); + *status = + MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, "Invalid Index for PWM", + 0, kNumSmartIo, channel); return HAL_INVALID_HANDLE; } - HAL_DigitalHandle handle; + auto resource = smartIoHandles->Allocate(channel, HAL_HandleEnum::PWM, "PWM"); - auto port = - smartIoHandles->Allocate(channel, HAL_HandleEnum::PWM, &handle, status); - - if (*status != 0) { - if (port) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel, - port->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for PWM", 0, - kNumSmartIo, channel); - } + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, port] = *resource; port->channel = channel; *status = port->InitializeMode(SmartIoMode::PwmOutput); @@ -113,9 +105,8 @@ void HAL_SetPWMPulseTimeMicroseconds(HAL_DigitalHandle pwmPortHandle, if (microsecondPulseTime < 0 || (microsecondPulseTime != 0xFFFF && microsecondPulseTime >= 4096)) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format("Pulse time {} out of range. Expect [0-4096) or 0xFFFF", microsecondPulseTime)); return; diff --git a/hal/src/main/native/systemcore/PowerDistribution.cpp b/hal/src/main/native/systemcore/PowerDistribution.cpp index 05a94651ca..d4c9249a33 100644 --- a/hal/src/main/native/systemcore/PowerDistribution.cpp +++ b/hal/src/main/native/systemcore/PowerDistribution.cpp @@ -11,6 +11,7 @@ #include "HALInternal.hpp" #include "PortsInternal.hpp" #include "REVPDH.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/HAL.h" #include "wpi/hal/handles/HandlesInternal.hpp" @@ -24,9 +25,9 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution( const char* allocationLocation, int32_t* status) { if (type == HAL_PowerDistributionType::HAL_POWER_DISTRIBUTION_AUTOMATIC) { if (moduleNumber != HAL_DEFAULT_POWER_DISTRIBUTION_MODULE) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, "Automatic PowerDistributionType must have default module"); + *status = + MakeError(PARAMETER_OUT_OF_RANGE, + "Automatic PowerDistributionType must have default module"); return HAL_INVALID_HANDLE; } @@ -158,15 +159,15 @@ void HAL_GetPowerDistributionAllChannelCurrents( int32_t currentsLength, int32_t* status) { if (IsCtre(handle)) { if (currentsLength < kNumCTREPDPChannels) { - *status = PARAMETER_OUT_OF_RANGE; - SetLastError(status, "Output array not large enough"); + *status = + MakeError(PARAMETER_OUT_OF_RANGE, "Output array not large enough"); return; } return HAL_GetPDPAllChannelCurrents(handle, currents, status); } else { if (currentsLength < kNumREVPDHChannels) { - *status = PARAMETER_OUT_OF_RANGE; - SetLastError(status, "Output array not large enough"); + *status = + MakeError(PARAMETER_OUT_OF_RANGE, "Output array not large enough"); return; } return HAL_GetREVPDHAllChannelCurrents(handle, currents, status); diff --git a/hal/src/main/native/systemcore/REVPDH.cpp b/hal/src/main/native/systemcore/REVPDH.cpp index 6688a79f52..95cc493446 100644 --- a/hal/src/main/native/systemcore/REVPDH.cpp +++ b/hal/src/main/native/systemcore/REVPDH.cpp @@ -11,12 +11,12 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "rev/PDHFrames.h" #include "wpi/hal/CAN.h" #include "wpi/hal/CANAPI.h" #include "wpi/hal/CANAPITypes.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/HandlesInternal.hpp" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -193,26 +193,20 @@ HAL_REVPDHHandle HAL_InitializeREVPDH(int32_t busId, int32_t module, int32_t* status) { wpi::hal::init::CheckInit(); if (!HAL_CheckREVPDHModuleNumber(module)) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PDH", - 1, kNumREVPDHModules, module); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for REV PDH", 1, + kNumREVPDHModules, module); return HAL_INVALID_HANDLE; } - HAL_REVPDHHandle handle; // Module starts at 1 - auto hpdh = REVPDHHandles->Allocate(module - 1, &handle, status); - if (*status != 0) { - if (hpdh) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "REV PDH", module, - hpdh->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PDH", - 1, kNumREVPDHModules, module); - } + auto resource = REVPDHHandles->Allocate(module - 1, "REV PDH", 1); + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, hpdh] = *resource; HAL_CANHandle hcan = HAL_InitializeCAN(busId, manufacturer, module, deviceType, status); diff --git a/hal/src/main/native/systemcore/REVPH.cpp b/hal/src/main/native/systemcore/REVPH.cpp index 33433978bd..fe4a7afbab 100644 --- a/hal/src/main/native/systemcore/REVPH.cpp +++ b/hal/src/main/native/systemcore/REVPH.cpp @@ -10,10 +10,10 @@ #include #include "HALInitializer.hpp" -#include "HALInternal.hpp" #include "PortsInternal.hpp" #include "rev/PHFrames.h" #include "wpi/hal/CANAPI.h" +#include "wpi/hal/ErrorHandling.hpp" #include "wpi/hal/Errors.h" #include "wpi/hal/handles/IndexedHandleResource.hpp" @@ -196,26 +196,20 @@ HAL_REVPHHandle HAL_InitializeREVPH(int32_t busId, int32_t module, int32_t* status) { wpi::hal::init::CheckInit(); if (!HAL_CheckREVPHModuleNumber(module)) { - *status = RESOURCE_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PH", 1, - kNumREVPHModules, module); + *status = MakeErrorIndexOutOfRange(RESOURCE_OUT_OF_RANGE, + "Invalid Index for REV PH", 1, + kNumREVPHModules, module); return HAL_INVALID_HANDLE; } - HAL_REVPHHandle handle; // Module starts at 1 - auto hph = REVPHHandles->Allocate(module - 1, &handle, status); - if (*status != 0) { - if (hph) { - wpi::hal::SetLastErrorPreviouslyAllocated(status, "REV PH", module, - hph->previousAllocation); - } else { - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for REV PH", - 1, kNumREVPHModules, module); - } + auto resource = REVPHHandles->Allocate(module - 1, "REV PH", 1); + if (!resource) { + *status = resource.error(); return HAL_INVALID_HANDLE; // failed to allocate. Pass error back. } + auto [handle, hph] = *resource; HAL_CANHandle hcan = HAL_InitializeCAN(busId, manufacturer, module, deviceType, status); @@ -397,9 +391,8 @@ double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel, } if (channel < 0 || channel > 1) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastErrorIndexOutOfRange(status, "Invalid REV Analog Index", 0, - 2, channel); + *status = MakeErrorIndexOutOfRange( + PARAMETER_OUT_OF_RANGE, "Invalid REV Analog Index", 0, 2, channel); return 0; } @@ -600,17 +593,15 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs, } if (index >= kNumREVPHChannels || index < 0) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format("Only [0-15] are valid index values. Requested {}", index)); return; } if (!HAL_CheckREVPHPulseTime(durMs)) { - *status = PARAMETER_OUT_OF_RANGE; - wpi::hal::SetLastError( - status, + *status = MakeError( + PARAMETER_OUT_OF_RANGE, fmt::format("Time not within expected range [0-65534]. Requested {}", durMs)); return; diff --git a/hal/src/test/native/cpp/handles/HandleTest.cpp b/hal/src/test/native/cpp/handles/HandleTest.cpp index 32684cc0e1..f5b59a312a 100644 --- a/hal/src/test/native/cpp/handles/HandleTest.cpp +++ b/hal/src/test/native/cpp/handles/HandleTest.cpp @@ -19,9 +19,9 @@ TEST(HandleTest, ClassedHandle) { wpi::hal::IndexedClassedHandleResource testClass; - int32_t status = 0; - testClass.Allocate(0, std::make_unique(), &status); - EXPECT_EQ(0, status); + auto resource = + testClass.Allocate(0, std::make_shared(), "TestResource"); + EXPECT_TRUE(resource.has_value()); } } // namespace wpi::hal