[2/4] os/xprintf: add Xvscnprintf and Xscnprintf

Submitted by Daniel Kurtz on April 18, 2012, 9:51 a.m.

Details

Message ID 1334742713-26570-3-git-send-email-djkurtz@chromium.org
State Accepted
Commit 5c2e2a164d615ab06be28a663734e782614b5cc7
Headers show

Commit Message

Daniel Kurtz April 18, 2012, 9:51 a.m.
Normal snprintf() usually returns the number of bytes that would have been
written into a buffer had the buffer been long enough.

The scnprintf() variants return the actual number of bytes written,
excluding the trailing '\0'.

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
---
 include/Xprintf.h |   12 ++++++++++++
 os/xprintf.c      |   44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 0 deletions(-)

Patch hide | download patch | download mbox

diff --git a/include/Xprintf.h b/include/Xprintf.h
index 414fd46..9e8cdc5 100644
--- a/include/Xprintf.h
+++ b/include/Xprintf.h
@@ -66,4 +66,16 @@  _X_ATTRIBUTE_PRINTF(2, 0);
 #define vasprintf Xvasprintf
 #endif
 
+/*
+ * These functions provide a portable implementation of the linux kernel
+ * scnprintf & vscnprintf routines that return the number of bytes actually
+ * copied during a snprintf, (excluding the final '\0').
+ */
+extern _X_EXPORT int
+Xscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, ...)
+_X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT int
+Xvscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, va_list va)
+_X_ATTRIBUTE_PRINTF(3,0);
+
 #endif                          /* XPRINTF_H */
diff --git a/os/xprintf.c b/os/xprintf.c
index 17fea2e..80caa57 100644
--- a/os/xprintf.c
+++ b/os/xprintf.c
@@ -186,6 +186,50 @@  XNFasprintf(char **ret, const char *_X_RESTRICT_KYWD format, ...)
     return size;
 }
 
+/**
+ * Varargs snprintf that returns the actual number of bytes (excluding final
+ * '\0') that were copied into the buffer.
+ * This is opposed to the normal sprintf() usually returns the number of bytes
+ * that would have been written.
+ *
+ * @param s       buffer to copy into
+ * @param n       size of buffer s
+ * @param format  printf style format string
+ * @param va      variable argument list
+ * @return        number of bytes actually copied, excluding final '\0'
+ */
+int
+Xvscnprintf(char *s, int n, const char *format, va_list args)
+{
+    int x;
+    if (n == 0)
+        return 0;
+    x = vsnprintf(s, n , format, args);
+    return (x >= n) ? (n - 1) : x;
+}
+
+/**
+ * snprintf that returns the actual number of bytes (excluding final '\0') that
+ * were copied into the buffer.
+ * This is opposed to the normal sprintf() usually returns the number of bytes
+ * that would have been written.
+ *
+ * @param s       buffer to copy into
+ * @param n       size of buffer s
+ * @param format  printf style format string
+ * @param ...     arguments for specified format
+ * @return        number of bytes actually copied, excluding final '\0'
+ */
+int Xscnprintf(char *s, int n, const char *format, ...)
+{
+    int x;
+    va_list ap;
+    va_start(ap, format);
+    x = Xvscnprintf(s, n, format, ap);
+    va_end(ap);
+    return x;
+}
+
 /* Old api, now deprecated, may be removed in the future */
 char *
 Xvprintf(const char *format, va_list va)