From 505539f1cdb51f251ef84be746e6e2154f0aece9 Mon Sep 17 00:00:00 2001 From: MechSlayer <0jcrespo1996@gmail.com> Date: Fri, 5 Sep 2025 16:52:35 +0200 Subject: [PATCH] feature: add string duplication functions with error handling --- Source/DrangPlatform/Include/drang/strings.h | 54 ++++++++++++++++++++ Source/DrangPlatform/Source/strings.c | 25 +++++++++ 2 files changed, 79 insertions(+) create mode 100644 Source/DrangPlatform/Include/drang/strings.h create mode 100644 Source/DrangPlatform/Source/strings.c diff --git a/Source/DrangPlatform/Include/drang/strings.h b/Source/DrangPlatform/Include/drang/strings.h new file mode 100644 index 0000000..e6047c3 --- /dev/null +++ b/Source/DrangPlatform/Include/drang/strings.h @@ -0,0 +1,54 @@ +#pragma once + +#include "alloc.h" +#include "platform.h" +#include + +DRANG_BEGIN_DECLS + +/** + * @brief Duplicates a null-terminated string. + * @param[in] str The null-terminated string to duplicate. + * @return Pointer to a newly allocated copy of the string, or NULL if allocation fails. + * @remarks The returned string must be freed using drang_free() when no longer needed. + * The input string must be null-terminated. If str is NULL, the behavior is undefined. + */ +DRANG_PLATFORM_API char *drang_strdup(const char *str); + +/** + * @brief Duplicates at most n characters of a string. + * @param[in] str The string to duplicate (may or may not be null-terminated). + * @param[in] n Maximum number of characters to copy. + * @return Pointer to a newly allocated copy of the string, or NULL if allocation fails. + * @remarks The returned string is always null-terminated and must be freed using drang_free(). + * If str contains fewer than n characters, only the available characters are copied. + * If str is NULL, the behavior is undefined. + */ +DRANG_PLATFORM_API char *drang_strndup(const char *str, size_t n); + +/** + * @brief Duplicates a string with automatic error handling. + * @param _Str_ The null-terminated string to duplicate. + * @return Pointer to a newly allocated copy of the string. + * @details This macro calls drang_strdup() and automatically triggers DRANG error handling + * with DRANG_ENOMEM if allocation fails. The operation will jump to the cleanup + * section if used within a DRANG_BEGIN_TRY()...DRANG_END_TRY() block. + * @remarks The returned string must be freed using drang_free() when no longer needed. + * This macro should only be used within a DRANG error handling context. + */ +#define DRANG_TRY_STRDUP(_Str_) (char*)(DRANG_ALLOC_TRY_IMPL(drang_strdup((_Str_)))) + +/** + * @brief Duplicates at most n characters of a string with automatic error handling. + * @param _Str_ The string to duplicate (may or may not be null-terminated). + * @param _N_ Maximum number of characters to copy. + * @return Pointer to a newly allocated copy of the string. + * @details This macro calls drang_strndup() and automatically triggers DRANG error handling + * with DRANG_ENOMEM if allocation fails. The operation will jump to the cleanup + * section if used within a DRANG_BEGIN_TRY()...DRANG_END_TRY() block. + * @remarks The returned string is always null-terminated and must be freed using drang_free(). + * This macro should only be used within a DRANG error handling context. + */ +#define DRANG_TRY_STRNDUP(_Str_, _N_) (char*)(DRANG_ALLOC_TRY_IMPL(drang_strndup((_Str_), (_N_)))) + +DRANG_END_DECLS diff --git a/Source/DrangPlatform/Source/strings.c b/Source/DrangPlatform/Source/strings.c new file mode 100644 index 0000000..0ef33a5 --- /dev/null +++ b/Source/DrangPlatform/Source/strings.c @@ -0,0 +1,25 @@ +#include +#include + +char *drang_strdup(const char *str) +{ + if (!str) return NULL; + const size_t len = strlen(str); + char *dup = DRANG_ALLOC_T_N(char, len + 1); + if (dup) { + memcpy(dup, str, len); + dup[len] = '\0'; + } + return dup; +} +char *drang_strndup(const char *str, size_t n) +{ + if (!str) return NULL; + const size_t len = strnlen(str, n); + char *dup = DRANG_ALLOC_T_N(char, len + 1); + if (dup) { + memcpy(dup, str, len); + dup[len] = '\0'; + } + return dup; +}