diff --git a/cmake.config/CMakeLists.txt b/cmake.config/CMakeLists.txt index d30c522aa2..f85cda7351 100644 --- a/cmake.config/CMakeLists.txt +++ b/cmake.config/CMakeLists.txt @@ -49,6 +49,8 @@ endif() check_function_exists(fseeko HAVE_FSEEKO) check_function_exists(readv HAVE_READV) check_function_exists(readlink HAVE_READLINK) +check_function_exists(stpcpy HAVE_STPCPY) +check_function_exists(stpncpy HAVE_STPNCPY) check_function_exists(strnlen HAVE_STRNLEN) check_function_exists(strcasecmp HAVE_STRCASECMP) check_function_exists(strncasecmp HAVE_STRNCASECMP) diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index f172646edf..aea3080009 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -918,15 +918,15 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) for (int i = 0; i < xp->xp_numfiles; i++) { if (i > 0) { if (xp->xp_prefix == XP_PREFIX_NO) { - ssp = xstpcpy(ssp, "no"); + ssp = STPCPY(ssp, "no"); } else if (xp->xp_prefix == XP_PREFIX_INV) { - ssp = xstpcpy(ssp, "inv"); + ssp = STPCPY(ssp, "inv"); } } - ssp = xstpcpy(ssp, xp->xp_files[i]); + ssp = STPCPY(ssp, xp->xp_files[i]); if (i != xp->xp_numfiles - 1) { - ssp = xstpcpy(ssp, (options & WILD_USE_NL) ? "\n" : " "); + ssp = STPCPY(ssp, (options & WILD_USE_NL) ? "\n" : " "); } } } diff --git a/src/nvim/garray.c b/src/nvim/garray.c index f87a196361..52a25b665f 100644 --- a/src/nvim/garray.c +++ b/src/nvim/garray.c @@ -156,8 +156,8 @@ char *ga_concat_strings_sep(const garray_T *gap, const char *sep) char *s = ret; for (size_t i = 0; i < nelem - 1; i++) { - s = xstpcpy(s, strings[i]); - s = xstpcpy(s, sep); + s = STPCPY(s, strings[i]); + s = STPCPY(s, sep); } strcpy(s, strings[nelem - 1]); // NOLINT(runtime/printf) diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 5acf4f0c37..27915dbf17 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -333,7 +333,7 @@ int ml_open(buf_T *buf) b0p->b0_magic_int = B0_MAGIC_INT; b0p->b0_magic_short = (int16_t)B0_MAGIC_SHORT; b0p->b0_magic_char = B0_MAGIC_CHAR; - xstrlcpy(xstpcpy(b0p->b0_version, "VIM "), Version, 6); + xstrlcpy(STPCPY(b0p->b0_version, "VIM "), Version, 6); long_to_char((long)mfp->mf_page_size, b0p->b0_page_size); if (!buf->b_spell) { diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 37e53e4453..ffa8397ab5 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -333,43 +333,16 @@ size_t memcnt(const void *data, char c, size_t len) return cnt; } -/// Copies the string pointed to by src (including the terminating NUL -/// character) into the array pointed to by dst. -/// -/// @returns pointer to the terminating NUL char copied into the dst buffer. -/// This is the only difference with strcpy(), which returns dst. -/// -/// WARNING: If copying takes place between objects that overlap, the behavior -/// is undefined. -/// -/// Nvim version of POSIX 2008 stpcpy(3). We do not require POSIX 2008, so -/// implement our own version. -/// -/// @param dst -/// @param src +#ifndef HAVE_STPCPY char *xstpcpy(char *restrict dst, const char *restrict src) FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { const size_t len = strlen(src); return (char *)memcpy(dst, src, len + 1) + len; } +#endif -/// Copies not more than n bytes (bytes that follow a NUL character are not -/// copied) from the array pointed to by src to the array pointed to by dst. -/// -/// If a NUL character is written to the destination, xstpncpy() returns the -/// address of the first such NUL character. Otherwise, it shall return -/// &dst[maxlen]. -/// -/// WARNING: If copying takes place between objects that overlap, the behavior -/// is undefined. -/// -/// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than -/// maxlen, zeroes will be written to the remaining bytes. -/// -/// @param dst -/// @param src -/// @param maxlen +#ifndef HAVE_STPNCPY char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen) FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { @@ -384,6 +357,7 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen) return dst + maxlen; } } +#endif /// xstrlcpy - Copy a NUL-terminated string into a sized buffer /// diff --git a/src/nvim/memory.h b/src/nvim/memory.h index 0788670142..c32e7cf4d1 100644 --- a/src/nvim/memory.h +++ b/src/nvim/memory.h @@ -68,6 +68,19 @@ EXTERN size_t arena_alloc_count INIT( = 0); # define strnlen xstrnlen // Older versions of SunOS may not have strnlen #endif +// MacOS doesn't have HAVE_STPCPY defined and defines its own stpcpy in Xcode. So just define STPCPY +#ifdef HAVE_STPCPY +# define STPCPY stpcpy +#else +# define STPCPY xstpcpy +#endif + +#ifdef HAVE_STPNCPY +# define STPNCPY stpncpy +#else +# define STPNCPY xstpncpy +#endif + #define STRCPY(d, s) strcpy((char *)(d), (char *)(s)) // NOLINT(runtime/printf) // Like strcpy() but allows overlapped source and destination.