Add fmt_print and fmt_println to C API

This commit is contained in:
Ferdinand Bachmann 2026-03-20 14:30:03 +01:00
parent 1899aea29f
commit 6814f1936e
2 changed files with 35 additions and 5 deletions

View File

@ -10,6 +10,7 @@
#include <stdbool.h> // bool
#include <stddef.h> // size_t
#include <stdio.h> // FILE
#ifdef __cplusplus
extern "C" {
@ -46,6 +47,8 @@ enum { fmt_error = -1, fmt_error_invalid_arg = -2 };
int fmt_vformat(char* buffer, size_t size, const char* fmt, const fmt_arg* args,
size_t num_args);
int fmt_vprint(FILE* stream, const char* fmt, const fmt_arg* args,
size_t num_args);
#ifdef __cplusplus
}
@ -190,6 +193,9 @@ typedef enum {} fmt_signed_char;
# define fmt_format(buffer, size, fmt, ...) \
fmt_vformat((buffer), (size), FMT_FORMAT_ARGS((fmt), ##__VA_ARGS__))
# define fmt_print(stream, fmt, ...) \
fmt_vprint((stream), FMT_FORMAT_ARGS((fmt), ##__VA_ARGS__))
#endif // __cplusplus
#endif // FMT_C_H_

View File

@ -9,12 +9,12 @@
#include <fmt/base.h>
extern "C" int fmt_vformat(char* buffer, size_t size, const char* fmt,
constexpr size_t max_c_format_args = 16;
static int convert_c_format_args(
fmt::basic_format_arg<fmt::format_context>* format_args,
const fmt_arg* args, size_t num_args) {
constexpr size_t max_args = 16;
if (num_args > max_args) return fmt_error_invalid_arg;
if (num_args > max_c_format_args) return fmt_error_invalid_arg;
fmt::basic_format_arg<fmt::format_context> format_args[max_args];
for (size_t i = 0; i < num_args; ++i) {
switch (args[i].type) {
case fmt_int: format_args[i] = args[i].value.int_value; break;
@ -31,6 +31,15 @@ extern "C" int fmt_vformat(char* buffer, size_t size, const char* fmt,
default: return fmt_error_invalid_arg;
}
}
return 0;
}
extern "C" int fmt_vformat(char* buffer, size_t size, const char* fmt,
const fmt_arg* args, size_t num_args) {
fmt::basic_format_arg<fmt::format_context> format_args[max_c_format_args];
int error = convert_c_format_args(format_args, args, num_args);
if (error != 0) return error;
FMT_TRY {
auto result = fmt::vformat_to_n(
buffer, size, fmt,
@ -40,3 +49,18 @@ extern "C" int fmt_vformat(char* buffer, size_t size, const char* fmt,
FMT_CATCH(...) {}
return fmt_error;
}
extern "C" int fmt_vprint(FILE* stream, const char* fmt, const fmt_arg* args,
size_t num_args) {
fmt::basic_format_arg<fmt::format_context> format_args[max_c_format_args];
int error = convert_c_format_args(format_args, args, num_args);
if (error != 0) return error;
FMT_TRY {
fmt::vprint(stream, fmt,
fmt::format_args(format_args, static_cast<int>(num_args)));
return 0;
}
FMT_CATCH(...) {}
return fmt_error;
}