Skip to content

Commit 530e66a

Browse files
Katze719Mqxx
andauthored
Add some helpers (#15)
* Enhance error handling and serial configuration support - Added new headers for error handling, result management, and scope guard utilities. - Introduced strong types for serial parameters and compile-time validated serial configuration. - Updated CMakeLists.txt to use cmake-git-versioning version 1.1.0. - Configured clangd for C++23 support and improved clang-tidy checks for better code quality. * Refine documentation and formatting across multiple files - Updated comments in Doxyfile, cpp_core.h, and various serial interface headers to standardize punctuation and formatting. - Adjusted README.md to use consistent comparison operators for clarity. - These changes enhance readability and maintain consistency in documentation style. * Refactor ScopeGuard constructor for improved readability * Remove deprecated helpers.hpp file, consolidating utility headers for cpp-core implementors. * Update comments for consistency and clarity across multiple headers - Changed documentation comments to use consistent formatting and punctuation in error_handling.hpp, result.hpp, scope_guard.hpp, serial_config.hpp, status_codes.hpp, strong_types.hpp, and unique_resource.hpp. - These updates enhance readability and maintain a uniform style throughout the codebase. * Add validation utilities for handle and parameter checks - Introduced new header file validation.hpp containing functions to validate handles, open parameters, and buffers. - Added clamping function for timeout values to ensure non-negative timeouts. - These utilities enhance error handling and improve the robustness of the cpp_core library. * Remove unnecessary blank lines in result.hpp, status_codes.hpp, and validation.hpp for improved code clarity and consistency. * Enhance documentation comments across multiple headers - Updated comments in error_handling.hpp, result.hpp, scope_guard.hpp, serial_config.hpp, status_codes.hpp, unique_resource.hpp, and validation.hpp to use consistent formatting and punctuation. - These changes improve readability and maintain a uniform style throughout the codebase. * Create block_pr_check_labels.yml * Update block_pr_check_labels.yml --------- Co-authored-by: Mqxx <62719703+Mqxx@users.noreply.github.com>
1 parent c336616 commit 530e66a

18 files changed

Lines changed: 901 additions & 9 deletions

.clang-tidy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ Checks: '*,
1616
-boost-use-ranges,
1717
-google-objc-function-naming,
1818
-google-objc-global-variable-declaration,
19-
-performance-enum-size'
19+
-performance-enum-size,
20+
-llvm-header-guard,
21+
-portability-avoid-pragma-once'
2022
WarningsAsErrors: ''
2123
HeaderFilterRegex: '^(?!magic_enum).*$'
2224
FormatStyle: Microsoft

.clangd

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# clangd configuration for cpp-core (C++23)
2+
# CMake generates compile_commands.json; the project copies it to the repo root
3+
# via the copy-compile-commands target. Run: cmake -B build && cmake --build build
4+
# clangd automatically uses compile_commands.json in the project root when present.
5+
6+
CompileFlags:
7+
Add:
8+
- -std=c++23
9+
- -Wno-c++98-compat-pedantic
10+
- -Wno-pre-c++20-compat-pedantic
11+
- -Wno-switch-default
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: 'Block PR Check Labels'
2+
description: |
3+
This workflow checks for specific labels and if a forbidden label exists, fails the pipeline,
4+
thus preventing the merge.
5+
6+
on:
7+
pull_request:
8+
types:
9+
- opened
10+
- labeled
11+
- unlabeled
12+
- synchronize
13+
14+
jobs:
15+
check-labels:
16+
name: 'Check Labels'
17+
if: contains(github.event.pull_request.labels.*.name, 'Blocked')
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: 'Fail if forbidden label exists'
21+
run: |
22+
echo "PR still has the 'Blocked' label"
23+
exit 1

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ include(cmake/CPM.cmake)
88
CPMAddPackage(
99
NAME cmake-git-versioning
1010
GITHUB_REPOSITORY Katze719/cmake-git-versioning
11-
GIT_TAG v1.0.1
11+
GIT_TAG v1.1.0
1212
)
1313

1414
# Include the cmake-git-versioning module

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#--------------------------------------------------------------------------
2-
# Doxyfile generated for cpp-core
2+
# Doxyfile - generated for cpp-core
33
#--------------------------------------------------------------------------
44

55
# Project related --------------------------------------------------------

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Header-only API definition library for cross-platform serial communication. Defi
1919

2020
## Requirements
2121

22-
* CMake 3.30
22+
* CMake >= 3.30
2323
* A C++23 compatible compiler (GCC 13+, Clang 16+, MSVC 2022+)
2424
* Git (for automatic version detection)
2525

include/cpp_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
/*
4-
* cpp_core.h Umbrella header for the cpp_core library
4+
* cpp_core.h - Umbrella header for the cpp_core library
55
*
66
* Include this single file to gain access to the complete public C/C++ API
77
* of the cpp_core runtime. Internally it forwards to the individual header
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#pragma once
2+
3+
#include "status_codes.h"
4+
5+
#include <concepts>
6+
#include <string>
7+
#include <string_view>
8+
#include <type_traits>
9+
10+
namespace cpp_core
11+
{
12+
13+
// Concepts
14+
15+
// Matches any callable that can receive (int, const char*).
16+
// clang-format off
17+
template <typename F>
18+
concept ErrorCallback = std::is_null_pointer_v<std::remove_cvref_t<F>>
19+
|| std::is_same_v<std::remove_cvref_t<F>, std::nullptr_t>
20+
|| requires(F &&func, int code, const char *msg) {
21+
{ func(code, msg) } -> std::same_as<void>;
22+
};
23+
// clang-format on
24+
25+
// Matches anything implicitly convertible to a C-style function pointer (ErrorCallbackT).
26+
template <typename F>
27+
concept LegacyErrorCallback = std::is_convertible_v<F, void (*)(int, const char *)>;
28+
29+
// Matches any type whose value can be returned as a status/result code.
30+
template <typename T>
31+
concept StatusConvertible = std::is_arithmetic_v<T> && requires(StatusCodes code) { static_cast<T>(code); };
32+
33+
// Error invocation
34+
35+
// Safely invoke an error callback, does nothing if callback is nullptr.
36+
template <ErrorCallback Callback>
37+
constexpr auto invokeError(Callback &&callback, StatusCodes code, std::string_view message) noexcept -> void
38+
{
39+
if constexpr (std::is_null_pointer_v<std::remove_cvref_t<Callback>>)
40+
{
41+
(void)callback;
42+
(void)code;
43+
(void)message;
44+
return;
45+
}
46+
else
47+
{
48+
if (callback != nullptr)
49+
{
50+
const std::string term(message);
51+
callback(static_cast<int>(code), term.c_str());
52+
}
53+
}
54+
}
55+
56+
// Fail helpers (concept-constrained)
57+
58+
// Report failure through callback and return the status code cast to Ret.
59+
template <StatusConvertible Ret, ErrorCallback Callback>
60+
constexpr auto failMsg(Callback &&callback, StatusCodes code, std::string_view message) -> Ret
61+
{
62+
invokeError(std::forward<Callback>(callback), code, message);
63+
return static_cast<Ret>(code);
64+
}
65+
66+
// Overload that builds the message by concatenating a prefix and a detail string.
67+
template <StatusConvertible Ret, ErrorCallback Callback>
68+
auto failMsg(Callback &&callback, StatusCodes code, std::string_view prefix, std::string_view detail) -> Ret
69+
{
70+
std::string full;
71+
full.reserve(prefix.size() + 2 + detail.size());
72+
full.append(prefix);
73+
full.append(": ");
74+
full.append(detail);
75+
invokeError(std::forward<Callback>(callback), code, full);
76+
return static_cast<Ret>(code);
77+
}
78+
79+
// Pipe-style error chaining
80+
81+
/**
82+
* Chain operations that return a status-code integer.
83+
* Stops at the first non-success result and returns it.
84+
* auto result = chainStatus(
85+
* [&] { return configureBaudrate(h, 9600); },
86+
* [&] { return configureParity(h, 0); },
87+
* [&] { return configureStopBits(h, 1); }
88+
* );
89+
*/
90+
template <std::invocable... Fns>
91+
requires(std::is_convertible_v<std::invoke_result_t<Fns>, int> && ...)
92+
constexpr auto chainStatus(Fns &&...fns) -> int
93+
{
94+
int result = 0;
95+
((static_cast<void>(result = static_cast<int>(std::forward<Fns>(fns)())), result < 0) || ...);
96+
return result;
97+
}
98+
99+
} // namespace cpp_core

include/cpp_core/interface/serial_close.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extern "C"
1212
* @brief Close a previously opened serial port.
1313
*
1414
* The handle becomes invalid after the call. Passing an already invalid
15-
* ( 0) handle is a no-op.
15+
* (<= 0) handle is a no-op.
1616
*
1717
* @param handle Handle obtained from serialOpen().
1818
* @param error_callback [optional] Callback to invoke on error. Defined in error_callback.h. Default is `nullptr`.

include/cpp_core/interface/serial_drain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extern "C"
1212
* @brief Wait until the operating-system driver has physically sent every queued byte.
1313
*
1414
* The function blocks the *calling thread* until the device driver reports
15-
* that the transmit FIFO is **empty** i.e. all bytes handed to previous
15+
* that the transmit FIFO is **empty** - i.e. all bytes handed to previous
1616
* `serialWrite*` calls have been shifted out on the wire. It does *not*
1717
* flush higher-level protocol buffers you may have implemented yourself.
1818
*

0 commit comments

Comments
 (0)