this repo has no description
1#pragma once
2
3#include <stdarg.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8// NUL-terminated string and length. Length does not include NUL.
9typedef struct str_size {
10 char *str;
11 size_t length;
12} str_size;
13
14#if defined(__STRICT_ANSI__) && __STDC_VERSION__ + 0 <= 199900L && \
15 __cplusplus + 0 <= 201103L
16#define va_copy(d, s) __builtin_va_copy(d, s)
17#endif
18
19// Returns NULL str if allocation or formatting fails.
20static str_size formatv(const char *fmt, va_list args) {
21 va_list args_copy;
22 va_copy(args_copy, args);
23 str_size result = (str_size){.str = NULL, .length = 0};
24 int size = vsnprintf(result.str, /*size=*/0, fmt, args);
25 if (size < 0) {
26 return result;
27 }
28 result.length = (size_t)size;
29 // +1 to include NUL
30 result.str = (char *)malloc(size + 1);
31 if (result.str == NULL) {
32 return result;
33 }
34 vsnprintf(result.str, size + 1, fmt, args_copy);
35 va_end(args_copy);
36 return result;
37}
38
39// Returns NULL str if allocation or formatting fails.
40__attribute__((format(printf, 1, 2))) static str_size format(const char *fmt,
41 ...) {
42 va_list args;
43 va_start(args, fmt);
44 str_size result = formatv(fmt, args);
45 va_end(args);
46 return result;
47}
48
49static void str_size_free(str_size str) { free(str.str); }