summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2021-06-09 14:31:15 -0400
committerJune McEnroe <june@causal.agency>2021-06-09 17:56:42 -0400
commite295e8f98f9c59aae6b1b511bad9979715a0fe7d (patch)
tree8e954e0244888b0eb649f527b21d2854e27e3ff6
parentAdd pounce-notify to README (diff)
downloadpounce-e295e8f98f9c59aae6b1b511bad9979715a0fe7d.tar.gz
pounce-e295e8f98f9c59aae6b1b511bad9979715a0fe7d.zip
Add seprintf
Based on seprint(2) from Plan 9. I'm not sure if my return value
exactly matches Plan 9's in the case of truncation. seprint(2) is
described only as returning a pointer to the terminating '\0', but
if it does so even in the case of truncation, it is awkward for the
caller to detect. This implementation returns end in the truncation
case, so that (ptr == end) indicates truncation.
-rw-r--r--bounce.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/bounce.h b/bounce.h
index a2265c8..2010d45 100644
--- a/bounce.h
+++ b/bounce.h
@@ -26,6 +26,7 @@
  */
 
 #include <limits.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -49,6 +50,18 @@
 
 typedef unsigned char byte;
 
+static inline char *seprintf(char *ptr, char *end, const char *fmt, ...)
+	__attribute__((format(printf, 3, 4)));
+static inline char *seprintf(char *ptr, char *end, const char *fmt, ...) {
+	va_list ap;
+	va_start(ap, fmt);
+	int n = vsnprintf(ptr, end - ptr, fmt, ap);
+	va_end(ap);
+	if (n < 0) return NULL;
+	if (n > end - ptr) return end;
+	return ptr + n;
+}
+
 enum { MessageCap = 8191 + 512 };
 
 enum { ParamCap = 15 };