aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/memory.c')
-rw-r--r--src/nvim/memory.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 92ead873ae..25fa2f150e 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -364,29 +364,58 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
}
}
-/// xstrlcpy - Copy a %NUL terminated string into a sized buffer
-///
-/// Compatible with *BSD strlcpy: the result is always a valid
-/// NUL-terminated string that fits in the buffer (unless,
-/// of course, the buffer size is zero). It does not pad
-/// out the result like strncpy() does.
-///
-/// @param dst Where to copy the string to
-/// @param src Where to copy the string from
-/// @param size Size of destination buffer
-/// @return Length of the source string (i.e.: strlen(src))
-size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size)
+/// xstrlcpy - Copy a NUL-terminated string into a sized buffer
+///
+/// Compatible with *BSD strlcpy: the result is always a valid NUL-terminated
+/// string that fits in the buffer (unless, of course, the buffer size is
+/// zero). It does not pad out the result like strncpy() does.
+///
+/// @param dst Buffer to store the result
+/// @param src String to be copied
+/// @param dsize Size of `dst`
+/// @return strlen(src). If retval >= dstsize, truncation occurs.
+size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t dsize)
FUNC_ATTR_NONNULL_ALL
{
- size_t ret = strlen(src);
+ size_t slen = strlen(src);
- if (size) {
- size_t len = (ret >= size) ? size - 1 : ret;
+ if (dsize) {
+ size_t len = MIN(slen, dsize - 1);
memcpy(dst, src, len);
dst[len] = '\0';
}
- return ret;
+ return slen; // Does not include NUL.
+}
+
+/// Appends `src` to string `dst` of size `dsize` (unlike strncat, dsize is the
+/// full size of `dst`, not space left). At most dsize-1 characters
+/// will be copied. Always NUL terminates. `src` and `dst` may overlap.
+///
+/// @see vim_strcat from Vim.
+/// @see strlcat from OpenBSD.
+///
+/// @param dst Buffer to be appended-to. Must have a NUL byte.
+/// @param src String to put at the end of `dst`
+/// @param dsize Size of `dst` including NUL byte. Must be greater than 0.
+/// @return strlen(src) + strlen(initial dst)
+/// If retval >= dsize, truncation occurs.
+size_t xstrlcat(char *const dst, const char *const src, const size_t dsize)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(dsize > 0);
+ const size_t dlen = strlen(dst);
+ assert(dlen < dsize);
+ const size_t slen = strlen(src);
+
+ if (slen > dsize - dlen - 1) {
+ memmove(dst + dlen, src, dsize - dlen - 1);
+ dst[dsize - 1] = '\0';
+ } else {
+ memmove(dst + dlen, src, slen + 1);
+ }
+
+ return slen + dlen; // Does not include NUL.
}
/// strdup() wrapper