From: git Date: Fri, 1 May 2026 12:44:57 +0000 (-0400) Subject: add strdup X-Git-Url: https://git.datadissipation.net/?a=commitdiff_plain;h=0cad277d2ed33b008dea56a24a3acb49259c7131;p=single-header-libcext.git add strdup --- diff --git a/README.md b/README.md index a5126fd..a10245f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -A (WIP) collection of portable, strict C99, single-header implementations of common libc extensions. +A collection of portable, strict C99, single-header implementations of common libc extensions. All functions are implemented as macros expanding to an internal function reference, this allows to use the headers with no meta build system - it compiles even if the extensions are already present, see _How to_ on disabling this behaviour. @@ -59,3 +59,9 @@ permuting, defining those enables it per function (GNU behaviour, can still be d includes `strlcat()` and `strlcpy()` --- + +### strdup + +includes `strdup()` and `strndup()` + +`strndup()` follows the latest standard, meaning that it copies at most _n_ chars, not _n_ + 1. diff --git a/strdup.h b/strdup.h new file mode 100644 index 0000000..34617ea --- /dev/null +++ b/strdup.h @@ -0,0 +1,71 @@ +/* + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to + */ + +/* https://git.datadissipation.net */ +#ifndef STRDUP_H_ + #define STRDUP_H_ 1 + + #ifdef STRDUP_INCLUDE_LIBC + #include + #include + #endif /* STRDUP_INCLUDE_LIBC */ + + #ifndef HAVE_STRDUP + #define HAVE_STRDUP 1 + #define strdup i_strdup_ + #define strndup i_strndup_ +char *i_strdup_(const char *s); +char *i_strndup_(const char *s, size_t n); + #endif /* !HAVE_STRDUP */ + + #ifdef STRDUP_IMPLEMENTATION +char * +i_strdup_(const char *s) +{ + char *t = s; + + /* avoid calling strlen twice by passing the maximum */ + return i_strndup_(s, ~(size_t) 0); +} + +char * +i_strndup_(const char *s, size_t n) +{ + char *d; + size_t t; + + t = strlen(s) + 1; + t = t < n ? t : n; + d = malloc(t); + + if (!d) return NULL; + *(d + t) = '\0'; + + return memcpy(d, s, t - 1); +} + #endif /* STRDUP_IMPLEMENTATION */ +#endif /* !STRDUP_H_ */