commit b3a948898f49969297d2ce5ea5e712e2fc807ca0
parent 44255b350222f624c42b4aa5ca59c72898365753
Author: Robert Russell <robertrussell.72001@gmail.com>
Date: Fri, 24 Mar 2023 17:40:42 -0700
string: printf constructors
Diffstat:
2 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/inc/string.h b/inc/string.h
@@ -1,5 +1,6 @@
#pragma once
+#include <stdarg.h>
#include <string.h>
#include "debug.h"
@@ -29,6 +30,9 @@ struct str {
.data = buf_static(s,##__VA_ARGS__) \
}
+int str_printf(Str *str, char *fmt, ...);
+int str_vprintf(Str *str, char *fmt, va_list args);
+
static inline usize
str_off(Str s) {
return s.off;
diff --git a/src/string.c b/src/string.c
@@ -1,7 +1,43 @@
+#include <stdio.h>
+
#include "debug.h"
#include "rcx.h"
#include "string.h"
+int
+str_printf(Str *str, char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ int ret = str_vprintf(str, fmt, args);
+ va_end(args);
+ return ret;
+}
+
+int
+str_vprintf(Str *str, char *fmt, va_list args) {
+ /* XXX: Using stdlib printf means we waste 1 byte for null term. */
+
+ va_list args2;
+ va_copy(args2, args);
+ int ret = vsnprintf(0, 0, fmt, args2);
+ va_end(args2);
+ if (ret < 0) return -1;
+ usize len = (usize)ret + 1u;
+
+ Buf buf = buf_alloc(len);
+ if (!buf) return -1;
+
+ ret = vsnprintf((char *)buf, len, fmt, args);
+ if (ret < 0) {
+ buf_drop(buf);
+ return -1;
+ }
+
+ *str = buf_slice(buf, 0);
+ return 0;
+
+}
+
Str
str_slice_(Str s, isize l, isize u) {
if (l < 0) l += s.len;