diff options
Diffstat (limited to 'libsimple/aligned_wcsdup.h')
-rw-r--r-- | libsimple/aligned_wcsdup.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libsimple/aligned_wcsdup.h b/libsimple/aligned_wcsdup.h new file mode 100644 index 0000000..3d5e96b --- /dev/null +++ b/libsimple/aligned_wcsdup.h @@ -0,0 +1,74 @@ +/* See LICENSE file for copyright and license details. */ + + +/** + * Stack allocation version of `libsimple_aligned_wcsdup` + * + * @param s:const wchar_t * The string to copy + * @param alignment:size_t The alignment of the returned pointer + * @return :wchar_t * Duplicate of `s` with automatic storage + */ +#if defined(__GNUC__) || defined(__clang__) +# define libsimple_aligned_wcsdupa(s, alignment) /* TODO test, man */\ + ({\ + const wchar_t *__s = (s);\ + size_t __n = wcslen(__s) + 1;\ + size_t __a = (alignment);\ + uintptr_t __misalignment;\ + char *__r;\ + __a += !__a;\ + __r = alloca(__n * sizeof(wchar_t) + (__a - 1));\ + __misalignment = (uintptr_t)__r % (uintptr_t)__a;\ + if (__misalignment)\ + __r += (uintptr_t)__a - __misalignment;\ + wmemcpy(__r, __s, __n);\ + }) +# ifndef aligned_wcsdupa +# define aligned_wcsdupa(s, alignment) libsimple_aligned_wcsdupa(s, alignment) +# endif +#endif + + +/** + * Version of wcsdup(3) that returns a pointer with a custom alignment + * + * @param s The string to copy + * @param alignment The alignment of the returned pointer + * @return Duplicate of `s`, `NULL` on failure + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) +static inline wchar_t *libsimple_aligned_wcsdup(const wchar_t * __s, size_t __alignment) /* TODO test, man */ +{ return libsimple_aligned_wmemdup(__s, __alignment, wcslen(__s) + 1); } +#ifndef aligned_wcsdup +# define aligned_wcsdup libsimple_aligned_wcsdup +#endif + + +/** + * Version of `libsimple_aligned_wcsdup` that calls `libsimple_enprintf` on error + * + * @param status Exit value in case of failure + * @param s The string to copy + * @param alignment The alignment of the returned pointer + * @return Duplicate of `s` + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __nonnull__, __warn_unused_result__, __returns_nonnull__))) +wchar_t *libsimple_enaligned_wcsdup(int, const wchar_t *, size_t); /* TODO man */ +#ifndef enaligned_wcsdup +# define enaligned_wcsdup libsimple_enaligned_wcsdup +#endif + + +/** + * Version of `libsimple_aligned_wcsdup` that calls `libsimple_eprintf` on error + * + * @param s The string to copy + * @param alignment The alignment of the returned pointer + * @return Duplicate of `s` + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) +static inline wchar_t *libsimple_ealigned_wcsdup(const wchar_t *__s, size_t __alignment) /* TODO test, man */ +{ return libsimple_enaligned_wcsdup(libsimple_default_failure_exit, __s, __alignment); } +#ifndef ealigned_wcsdup +# define ealigned_wcsdup libsimple_ealigned_wcsdup +#endif |