]> diplodocus.org Git - nmh/commitdiff
Add trunccpy(), and the convenience TRUNCCPY().
authorRalph Corderoy <ralph@inputplus.co.uk>
Sun, 30 Oct 2016 13:45:40 +0000 (13:45 +0000)
committerRalph Corderoy <ralph@inputplus.co.uk>
Sun, 30 Oct 2016 15:17:27 +0000 (15:17 +0000)
truncpy copies at most size - 1 chars from non-NULL src to non-NULL
dst, and ensures dst is NUL terminated.  If size is zero then it
aborts as dst cannot be NUL terminated.

It's to be used when truncation is intended and correct, e.g.
reporting a possibly very long external string back to the user.  One
of its advantages over strncpy(3) is it doesn't pad in the common
case of no truncation.

h/utils.h
sbr/utils.c

index fe05493..939bd80 100644 (file)
--- a/h/utils.h
+++ b/h/utils.h
@@ -63,6 +63,10 @@ char *find_str (const char [], size_t, const char *);
 char *rfind_str (const char [], size_t, const char *);
 char *nmh_strcasestr (const char *, const char *);
 
 char *rfind_str (const char [], size_t, const char *);
 char *nmh_strcasestr (const char *, const char *);
 
+void trunccpy(char *dst, const char *src, size_t size);
+/* A convenience for the common case of dst being an array. */
+#define TRUNCCPY(dst, src) trunccpy(dst, src, sizeof (dst))
+
 bool HasPrefix(const char *s, const char *prefix);
 bool HasSuffix(const char *s, const char *suffix);
 bool HasSuffixC(const char *s, int c);
 bool HasPrefix(const char *s, const char *prefix);
 bool HasSuffix(const char *s, const char *suffix);
 bool HasSuffixC(const char *s, int c);
index ff14467..ca80943 100644 (file)
@@ -346,6 +346,31 @@ nmh_strcasestr (const char *s1, const char *s2) {
 }
 
 
 }
 
 
+/* truncpy copies at most size - 1 chars from non-NULL src to non-NULL
+ * dst, and ensures dst is NUL terminated.  If size is zero then it
+ * aborts as dst cannot be NUL terminated.
+ *
+ * It's to be used when truncation is intended and correct, e.g.
+ * reporting a possibly very long external string back to the user.  One
+ * of its advantages over strncpy(3) is it doesn't pad in the common
+ * case of no truncation. */
+void trunccpy(char *dst, const char *src, size_t size)
+{
+    if (!size) {
+        advise(NULL, "trunccpy: zero-length destination: \"%.20s\"",
+            src ? src : "null");
+        abort();
+    }
+
+    if (strnlen(src, size) < size) {
+        strcpy(dst, src);
+    } else {
+        memcpy(dst, src, size - 1);
+        dst[size - 1] = '\0';
+    }
+}
+
+
 /* HasPrefix returns true if non-NULL s starts with non-NULL prefix. */
 bool HasPrefix(const char *s, const char *prefix)
 {
 /* HasPrefix returns true if non-NULL s starts with non-NULL prefix. */
 bool HasPrefix(const char *s, const char *prefix)
 {