this repo has no description
at trunk 49 lines 1.3 kB view raw
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); }