Skip to content

Commit bb83fa9

Browse files
committed
Merge branch 'dev'
2 parents 8d7a85c + 4456623 commit bb83fa9

File tree

3 files changed

+47
-82
lines changed

3 files changed

+47
-82
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ if(NOT WIN32 OR MINGW)
9393
endif()
9494

9595
if(UNIX AND NOT APPLE)
96-
check_support(HAS_DL_FIND_OBJECT has_dl_find_object.cpp "" "" "")
96+
check_support(HAS_DL_FIND_OBJECT has_dl_find_object.cpp "" "dl" "")
9797
if(NOT HAS_DL_FIND_OBJECT)
98-
check_support(HAS_DLADDR1 has_dladdr1.cpp "" "" "")
98+
check_support(HAS_DLADDR1 has_dladdr1.cpp "" "dl" "")
9999
endif()
100100
endif()
101101

cmake/has_dladdr1.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <dlfcn.h>
2+
#include <link.h>
23

34
int main() {
45
Dl_info info;

src/utils/microfmt.hpp

Lines changed: 44 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
11
#ifndef MICROFMT_HPP
22
#define MICROFMT_HPP
33

4-
// Copyright (c) 2024 Jeremy Rifkin; MIT License
5-
64
#include <algorithm>
75
#include <array>
86
#include <cstdint>
9-
#include <cstdio>
107
#include <cstring>
118
#include <iostream>
129
#include <string>
1310
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
14-
#include <string_view>
11+
#include <string_view>
1512
#endif
1613
#ifdef _MSC_VER
17-
#include <intrin.h>
14+
#include <intrin.h>
1815
#endif
1916

20-
// {[[align][width]:[fill][base]]}
21-
// width: number or {}
17+
// https://github.com/jeremy-rifkin/microfmt
18+
// Format: {[align][width][:[fill][base]]} # width: number or {}
2219

2320
namespace microfmt {
2421
namespace detail {
25-
#define STR2(x) #x
26-
#define STR(x) STR2(x)
27-
#define MICROFMT_ASSERT(expr) if(!(expr)) { \
28-
throw std::runtime_error("Microfmt check failed" __FILE__ ":" STR(__LINE__) ": " #expr); \
29-
}
30-
3122
inline std::uint64_t clz(std::uint64_t value) {
3223
#ifdef _MSC_VER
3324
unsigned long out = 0;
@@ -60,7 +51,6 @@ namespace microfmt {
6051

6152
template<typename It> void do_write(std::string& out, It begin, It end, const format_options& options) {
6253
auto size = end - begin;
63-
MICROFMT_ASSERT(size >= 0);
6454
if(static_cast<std::size_t>(size) >= options.width) {
6555
out.append(begin, end);
6656
} else {
@@ -100,13 +90,11 @@ namespace microfmt {
10090

10191
inline std::string to_string(std::uint64_t value, const format_options& options) {
10292
switch(options.base) {
103-
case 'd': return std::to_string(value);
10493
case 'H': return to_string<4, 0xf>(value, "0123456789ABCDEF");
10594
case 'h': return to_string<4, 0xf>(value);
10695
case 'o': return to_string<3, 0x7>(value);
10796
case 'b': return to_string<1, 0x1>(value);
108-
default:
109-
MICROFMT_ASSERT(false);
97+
default: return std::to_string(value); // failure: decimal
11098
}
11199
}
112100

@@ -154,7 +142,7 @@ namespace microfmt {
154142
switch(value) {
155143
case value_type::int64_value: return static_cast<int>(int64_value);
156144
case value_type::uint64_value: return static_cast<int>(uint64_value);
157-
default: MICROFMT_ASSERT(false);
145+
default: return 0; // failure: just 0
158146
}
159147
}
160148

@@ -193,108 +181,84 @@ namespace microfmt {
193181
case value_type::c_string_value:
194182
do_write(out, c_string_value, c_string_value + std::strlen(c_string_value), options);
195183
break;
196-
default:
197-
MICROFMT_ASSERT(false);
198-
}
184+
} // failure: nop
199185
}
200186
};
201187

202-
inline int parse_int(const char* begin, const char* end) {
203-
int x = 0;
204-
for(auto it = begin; it != end; it++) {
205-
MICROFMT_ASSERT(isdigit(*it));
206-
x *= 10;
207-
x += *it - '0';
208-
}
209-
return x;
210-
}
211-
212-
template<std::size_t N>
213-
std::string format(const char* fmt_begin, const char* fmt_end, std::array<format_value, N> args) {
188+
template<std::size_t N, typename It>
189+
std::string format(It fmt_begin, It fmt_end, std::array<format_value, N> args) {
214190
std::string str;
215191
std::size_t arg_i = 0;
216192
auto it = fmt_begin;
217193
auto peek = [&] (std::size_t dist) -> char { // 0 on failure
218-
if(it != fmt_end) {
219-
return *(it + dist);
220-
} else {
221-
return 0;
222-
}
194+
return fmt_end - it > signed(dist) ? *(it + dist) : 0;
223195
};
224196
auto read_number = [&] () -> int { // -1 on failure
225197
auto scan = it;
198+
int num = 0;
226199
while(scan != fmt_end && isdigit(*scan)) {
200+
num *= 10;
201+
num += *scan - '0';
227202
scan++;
228203
}
229204
if(scan != it) {
230-
int val = parse_int(it, scan);
231205
it = scan;
232-
return val;
206+
return num;
233207
} else {
234208
return -1;
235209
}
236210
};
237-
while(it != fmt_end) {
238-
if(*it == '{') {
239-
if(peek(1) == '{') {
240-
// try to handle escape
241-
str += '{';
242-
it++;
243-
} else {
244-
// parse format string
211+
for(; it != fmt_end; it++) {
212+
if((*it == '{' || *it == '}') && peek(1) == *it) { // parse {{ and }} escapes
213+
it++;
214+
} else if(*it == '{' && it + 1 != fmt_end) {
215+
auto saved_it = it;
216+
auto handle_formatter = [&] () {
245217
it++;
246-
MICROFMT_ASSERT(it != fmt_end);
247218
format_options options;
248219
// try to parse alignment
249220
if(*it == '<' || *it == '>') {
250-
options.align = *it == '<' ? alignment::left : alignment::right;
251-
it++;
221+
options.align = *it++ == '<' ? alignment::left : alignment::right;
252222
}
253223
// try to parse width
254-
auto width = read_number();
224+
auto width = read_number(); // handles fmt_end check
255225
if(width != -1) {
256226
options.width = width;
257-
} else if(*it == '{') { // try to parse variable width
258-
MICROFMT_ASSERT(peek(1) == '}');
227+
} else if(it != fmt_end && *it == '{') { // try to parse variable width
228+
if(peek(1) != '}') {
229+
return false;
230+
}
259231
it += 2;
260-
MICROFMT_ASSERT(arg_i < args.size());
261-
options.width = args[arg_i++].unwrap_int();
232+
options.width = arg_i < args.size() ? args[arg_i++].unwrap_int() : 0;
262233
}
263234
// try to parse fill/base
264-
if(*it == ':') {
235+
if(it != fmt_end && *it == ':') {
265236
it++;
266-
// try to parse fill
267-
if(*it != '}' && peek(1) != '}') {
268-
// two chars before the }, treat as fill+base
237+
if(fmt_end - it > 1 && *it != '}' && peek(1) != '}') { // two chars before the }, fill+base
269238
options.fill = *it++;
270239
options.base = *it++;
271-
} else if(*it != '}') {
272-
// one char before the }, treat as base if possible
240+
} else if(it != fmt_end && *it != '}') { // one char before the }, just base
273241
if(*it == 'd' || *it == 'h' || *it == 'H' || *it == 'o' || *it == 'b') {
274242
options.base = *it++;
275243
} else {
276244
options.fill = *it++;
277245
}
278-
} else {
279-
MICROFMT_ASSERT(false);
280246
}
281247
}
282-
MICROFMT_ASSERT(*it == '}');
283-
MICROFMT_ASSERT(arg_i < args.size());
284-
args[arg_i++].write(str, options);
285-
}
286-
} else if(*it == '}') {
287-
// parse }} escape
288-
if(peek(1) == '}') {
289-
str += '}';
290-
it++;
291-
} else {
292-
MICROFMT_ASSERT(false);
248+
if(it == fmt_end || *it != '}') {
249+
return false;
250+
}
251+
if(arg_i < args.size()) {
252+
args[arg_i++].write(str, options);
253+
}
254+
return true;
255+
};
256+
if(handle_formatter()) {
257+
continue; // If reached here, successfully parsed and wrote a formatter. Don't write *it.
293258
}
294-
} else {
295-
str += *it;
259+
it = saved_it; // go back
296260
}
297-
it++;
261+
str += *it;
298262
}
299263
return str;
300264
}
@@ -306,8 +270,9 @@ namespace microfmt {
306270
return detail::format<sizeof...(args)>(fmt.begin(), fmt.end(), {detail::format_value(args)...});
307271
}
308272

273+
// working around an old msvc bug https://godbolt.org/z/88T8hrzzq mre: https://godbolt.org/z/drd8echbP
309274
inline std::string format(std::string_view fmt) {
310-
return std::string(fmt);
275+
return detail::format<1>(fmt.begin(), fmt.end(), {detail::format_value(1)});
311276
}
312277
#endif
313278

@@ -316,7 +281,6 @@ namespace microfmt {
316281
return detail::format<sizeof...(args)>(fmt, fmt + std::strlen(fmt), {detail::format_value(args)...});
317282
}
318283

319-
// working around an old msvc bug https://godbolt.org/z/88T8hrzzq mre: https://godbolt.org/z/drd8echbP
320284
inline std::string format(const char* fmt) {
321285
return detail::format<1>(fmt, fmt + std::strlen(fmt), {detail::format_value(1)});
322286
}

0 commit comments

Comments
 (0)