xref: /freebsd/lib/libutil++/stringf.cc (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2025 Chelsio Communications, Inc.
5  * Written by: John Baldwin <jhb@FreeBSD.org>
6  */
7 
8 #include <cstdarg>
9 #include <cstdio>
10 #include <string>
11 
12 #include "libutil++.hh"
13 
14 static int
15 stringf_write(void *cookie, const char *buf, int len)
16 {
17 	std::string *str = reinterpret_cast<std::string *>(cookie);
18 	try {
19 		str->append(buf, len);
20 	} catch (std::bad_alloc) {
21 		errno = ENOMEM;
22 		return (-1);
23 	} catch (std::length_error) {
24 		errno = EFBIG;
25 		return (-1);
26 	}
27 	return (len);
28 }
29 
30 std::string
31 freebsd::stringf(const char *fmt, va_list ap)
32 {
33 	std::string str;
34 	freebsd::FILE_up fp(fwopen(reinterpret_cast<void *>(&str),
35 	    stringf_write));
36 
37 	vfprintf(fp.get(), fmt, ap);
38 
39 	if (ferror(fp.get()))
40 		throw std::bad_alloc();
41 	fp.reset(nullptr);
42 
43 	return str;
44 }
45 
46 std::string
47 freebsd::stringf(const char *fmt, ...)
48 {
49 	std::va_list ap;
50 	std::string str;
51 
52 	va_start(ap, fmt);
53 	str = freebsd::stringf(fmt, ap);
54 	va_end(ap);
55 
56 	return str;
57 }
58