Skip to content

Commit 9e5bb7e

Browse files
committed
Cleanup the C API
1 parent 1dc644e commit 9e5bb7e

File tree

2 files changed

+95
-106
lines changed

2 files changed

+95
-106
lines changed

include/fmt/fmt-c.h

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,112 @@
1-
#ifndef FMT_C_H
2-
#define FMT_C_H
3-
#include <stddef.h>
4-
#ifdef __cplusplus
5-
# define _Bool bool
6-
#endif
1+
// Formatting library for C++ - the C API
2+
//
3+
// Copyright (c) 2012 - present, Victor Zverovich
4+
// All rights reserved.
5+
//
6+
// For the license information refer to format.h.
77

8-
void fmt_error_unsupported_type_detected(void);
8+
#ifndef FMT_C_H_
9+
#define FMT_C_H_
910

10-
enum { fmt_c_max_args = 16 };
11-
12-
typedef enum {
13-
fmt_err_exception = -1,
14-
fmt_err_memory = -2,
15-
fmt_err_invalid_arg = -3
16-
} fmt_error;
11+
#include <stdbool.h> // bool
12+
#include <stddef.h> // size_t
1713

1814
#ifdef __cplusplus
1915
extern "C" {
2016
#endif
2117

2218
typedef enum {
23-
fmt_int,
19+
fmt_int = 1,
2420
fmt_uint,
21+
fmt_bool = 7,
22+
fmt_char,
2523
fmt_float,
2624
fmt_double,
2725
fmt_long_double,
28-
fmt_string,
29-
fmt_ptr,
30-
fmt_bool,
31-
fmt_char
26+
fmt_cstring,
27+
fmt_pointer = 14
3228
} fmt_type;
3329

3430
typedef struct {
3531
fmt_type type;
3632
union {
37-
long long i64;
38-
unsigned long long u64;
39-
float f32;
40-
double f64;
41-
long double f128;
42-
const char* str;
43-
const void* ptr; // Used for FMT_PTR and custom data
44-
_Bool bool_val;
45-
char char_val;
33+
long long int_value;
34+
unsigned long long uint_value; // Used for FMT_PTR and custom data
35+
bool bool_value;
36+
char char_value;
37+
float float_value;
38+
double double_value;
39+
long double long_double_value;
40+
const char* cstring;
41+
const void* pointer;
4642
} value;
4743
} fmt_arg;
4844

49-
int fmt_vformat(char* buffer, size_t capacity, const char* format_str,
50-
const fmt_arg* args, size_t arg_count);
45+
enum { fmt_error = -1, fmt_error_invalid_arg = -2 };
46+
47+
int fmt_vformat(char* buffer, size_t size, const char* fmt,
48+
const fmt_arg* args, size_t num_args);
5149

5250
static inline fmt_arg fmt_from_int(long long x) {
5351
fmt_arg arg;
5452
arg.type = fmt_int;
55-
arg.value.i64 = x;
53+
arg.value.int_value = x;
5654
return arg;
5755
}
5856

5957
static inline fmt_arg fmt_from_uint(unsigned long long x) {
6058
fmt_arg arg;
6159
arg.type = fmt_uint;
62-
arg.value.u64 = x;
60+
arg.value.uint_value = x;
6361
return arg;
6462
}
6563

66-
static inline fmt_arg fmt_from_float(float x) {
64+
static inline fmt_arg fmt_from_bool(bool x) {
6765
fmt_arg arg;
68-
arg.type = fmt_float;
69-
arg.value.f32 = x;
66+
arg.type = fmt_bool;
67+
arg.value.bool_value = x;
7068
return arg;
7169
}
7270

73-
static inline fmt_arg fmt_from_double(double x) {
71+
static inline fmt_arg fmt_from_char(int x) {
7472
fmt_arg arg;
75-
arg.type = fmt_double;
76-
arg.value.f64 = x;
73+
arg.type = fmt_char;
74+
arg.value.char_value = x;
7775
return arg;
7876
}
7977

80-
static inline fmt_arg fmt_from_long_double(long double x) {
78+
static inline fmt_arg fmt_from_float(float x) {
8179
fmt_arg arg;
82-
arg.type = fmt_long_double;
83-
arg.value.f128 = x;
80+
arg.type = fmt_float;
81+
arg.value.float_value = x;
8482
return arg;
8583
}
8684

87-
static inline fmt_arg fmt_from_str(const char* x) {
85+
static inline fmt_arg fmt_from_double(double x) {
8886
fmt_arg arg;
89-
arg.type = fmt_string;
90-
arg.value.str = x;
87+
arg.type = fmt_double;
88+
arg.value.double_value = x;
9189
return arg;
9290
}
9391

94-
static inline fmt_arg fmt_from_ptr(const void* x) {
92+
static inline fmt_arg fmt_from_long_double(long double x) {
9593
fmt_arg arg;
96-
arg.type = fmt_ptr;
97-
arg.value.ptr = x;
94+
arg.type = fmt_long_double;
95+
arg.value.long_double_value = x;
9896
return arg;
9997
}
10098

101-
static inline fmt_arg fmt_from_bool(_Bool x) {
99+
static inline fmt_arg fmt_from_str(const char* x) {
102100
fmt_arg arg;
103-
arg.type = fmt_bool;
104-
arg.value.bool_val = x;
101+
arg.type = fmt_cstring;
102+
arg.value.cstring = x;
105103
return arg;
106104
}
107105

108-
static inline fmt_arg fmt_from_char(int x) {
106+
static inline fmt_arg fmt_from_ptr(const void* x) {
109107
fmt_arg arg;
110-
arg.type = fmt_char;
111-
arg.value.char_val = x;
108+
arg.type = fmt_pointer;
109+
arg.value.pointer = x;
112110
return arg;
113111
}
114112

@@ -118,15 +116,15 @@ static inline fmt_arg fmt_from_char(int x) {
118116

119117
#ifndef __cplusplus
120118

119+
void fmt_unsupported_type(void);
120+
121121
// Require modern MSVC with conformant preprocessor
122122
# if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
123123
# error "C API requires MSVC 2019+ with /Zc:preprocessor flag."
124124
# endif
125125

126126
# define FMT_MAKE_ARG(x) \
127127
_Generic((x), \
128-
_Bool: fmt_from_bool, \
129-
char: fmt_from_char, \
130128
unsigned char: fmt_from_uint, \
131129
short: fmt_from_int, \
132130
unsigned short: fmt_from_uint, \
@@ -136,14 +134,16 @@ static inline fmt_arg fmt_from_char(int x) {
136134
unsigned long: fmt_from_uint, \
137135
long long: fmt_from_int, \
138136
unsigned long long: fmt_from_uint, \
137+
bool: fmt_from_bool, \
138+
char: fmt_from_char, \
139139
float: fmt_from_float, \
140140
double: fmt_from_double, \
141141
long double: fmt_from_long_double, \
142142
char*: fmt_from_str, \
143143
const char*: fmt_from_str, \
144144
void*: fmt_from_ptr, \
145145
const void*: fmt_from_ptr, \
146-
default: fmt_error_unsupported_type_detected)(x)
146+
default: fmt_unsupported_type)(x)
147147

148148
# define FMT_CAT(a, b) FMT_CAT_(a, b)
149149
# define FMT_CAT_(a, b) a##b
@@ -189,12 +189,12 @@ static inline fmt_arg fmt_from_char(int x) {
189189
# define FMT_MAP(f, ...) \
190190
FMT_CAT(FMT_MAP_, FMT_NARG(__VA_ARGS__))(f, ##__VA_ARGS__)
191191

192-
# define fmt_format(buf, cap, fmt, ...) \
192+
# define fmt_format(buffer, size, fmt, ...) \
193193
fmt_vformat( \
194-
buf, cap, fmt, \
194+
buffer, size, fmt, \
195195
(fmt_arg[]){{fmt_int}, FMT_MAP(FMT_MAKE_ARG, ##__VA_ARGS__)} + 1, \
196196
FMT_NARG(__VA_ARGS__))
197197

198198
#endif // __cplusplus
199199

200-
#endif // FMT_C_H
200+
#endif // FMT_C_H_

src/fmt-c.cc

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,44 @@
1-
#include "fmt/fmt-c.h"
2-
3-
#include <fmt/core.h>
4-
5-
#include <cassert>
6-
7-
extern "C" {
1+
// Formatting library for C++ - the C API
2+
//
3+
// Copyright (c) 2012 - present, Victor Zverovich
4+
// All rights reserved.
5+
//
6+
// For the license information refer to format.h.
87

9-
using format_arg = fmt::basic_format_arg<fmt::format_context>;
10-
11-
static bool populate_store(format_arg* out, const fmt_arg* c_args,
12-
size_t arg_count) {
13-
if (arg_count > fmt_c_max_args) {
14-
return false;
15-
}
16-
17-
for (size_t i = 0; i < arg_count; ++i) {
18-
switch (c_args[i].type) {
19-
case fmt_int: out[i] = c_args[i].value.i64; break;
20-
case fmt_uint: out[i] = c_args[i].value.u64; break;
21-
case fmt_float: out[i] = c_args[i].value.f32; break;
22-
case fmt_double: out[i] = c_args[i].value.f64; break;
23-
case fmt_long_double: out[i] = c_args[i].value.f128; break;
24-
case fmt_ptr: out[i] = c_args[i].value.ptr; break;
25-
case fmt_char: out[i] = c_args[i].value.char_val; break;
26-
case fmt_bool: out[i] = c_args[i].value.bool_val; break;
27-
case fmt_string: out[i] = c_args[i].value.str; break;
28-
default: return false;
29-
}
30-
}
31-
return true;
32-
}
33-
34-
int fmt_vformat(char* buffer, size_t capacity, const char* format_str,
35-
const fmt_arg* args, size_t arg_count) {
36-
assert(format_str);
37-
38-
format_arg format_args[fmt_c_max_args];
8+
#include "fmt/fmt-c.h"
399

40-
if (arg_count > 0) {
41-
assert(args);
42-
if (!populate_store(format_args, args, arg_count)) {
43-
return fmt_err_invalid_arg;
10+
#include <fmt/base.h>
11+
12+
extern "C" int fmt_vformat(char* buffer, size_t size, const char* fmt,
13+
const fmt_arg* args, size_t num_args) {
14+
constexpr size_t max_args = 16;
15+
if (num_args > max_args) return fmt_error_invalid_arg;
16+
17+
fmt::basic_format_arg<fmt::format_context> format_args[max_args];
18+
for (size_t i = 0; i < num_args; ++i) {
19+
switch (args[i].type) {
20+
case fmt_int: format_args[i] = args[i].value.int_value; break;
21+
case fmt_uint: format_args[i] = args[i].value.uint_value; break;
22+
case fmt_float: format_args[i] = args[i].value.float_value; break;
23+
case fmt_double: format_args[i] = args[i].value.double_value; break;
24+
case fmt_long_double:
25+
format_args[i] = args[i].value.long_double_value;
26+
break;
27+
case fmt_pointer: format_args[i] = args[i].value.pointer; break;
28+
case fmt_char: format_args[i] = args[i].value.char_value; break;
29+
case fmt_bool: format_args[i] = args[i].value.bool_value; break;
30+
case fmt_cstring: format_args[i] = args[i].value.cstring; break;
31+
default: return fmt_error_invalid_arg;
4432
}
4533
}
4634

4735
auto format_args_view = fmt::basic_format_args<fmt::format_context>(
48-
format_args, static_cast<int>(arg_count));
36+
format_args, static_cast<int>(num_args));
4937

50-
auto result =
51-
fmt::vformat_to_n(buffer, capacity, format_str, format_args_view);
52-
return static_cast<int>(result.size);
38+
try {
39+
auto result = fmt::vformat_to_n(buffer, size, fmt, format_args_view);
40+
return static_cast<int>(result.size);
41+
} catch (...) {
42+
}
43+
return fmt_error;
5344
}
54-
55-
} // extern "C"

0 commit comments

Comments
 (0)