4 #ifndef LEXY_VISUALIZE_HPP_INCLUDED
5 #define LEXY_VISUALIZE_HPP_INCLUDED
72 lhs.
flags = lhs.flags | rhs;
81 template <
typename Encoding>
86 using encoding = Encoding;
93 template <
typename OutIt>
94 constexpr OutIt
write_str(OutIt out,
const char* str)
100 template <
typename OutIt>
104 *out++ =
static_cast<char>(*str++);
108 template <
int N = 16,
typename OutIt,
typename... Args>
109 constexpr OutIt
write_format(OutIt out,
const char* fmt,
const Args&... args)
111 char buffer[std::size_t(N + 1)];
112 auto count = std::snprintf(
buffer, N, fmt, args...);
115 for (
auto i = 0; i !=
count; ++i)
137 template <
color CodeHead,
color... CodeTail,
typename OutIt>
145 auto write_code = [](OutIt out,
int code) {
148 *out++ =
static_cast<char>((code / 10) +
'0');
149 *out++ =
static_cast<char>((code % 10) +
'0');
153 *out++ =
static_cast<char>(code +
'0');
157 out = write_code(out,
int(CodeHead));
158 ((*out++ =
';', write_code(out,
int(CodeTail))), ...);
164 template <
typename OutIt>
173 template <
typename OutIt,
typename Fn>
176 out = _detail::write_color<_detail::color::cyan, _detail::color::faint>(out, opts);
186 out = _detail::write_color<_detail::color::reset>(out, opts);
193 template <
typename OutputIt>
208 auto c =
static_cast<int>(cp.
value());
231 out = _detail::write_color<_detail::color::faint>(out, opts);
233 out = _detail::write_color<_detail::color::reset>(out, opts);
249 if (opts.tab_width > 0)
253 for (
auto i = 0u; i < opts.tab_width; ++i)
258 out = _detail::write_color<_detail::color::faint>(out, opts);
260 out = _detail::write_color<_detail::color::reset>(out, opts);
287 else if (cp.
value() ==
' ')
293 out = _detail::write_color<_detail::color::faint>(out, opts);
295 out = _detail::write_color<_detail::color::reset>(out, opts);
317 else if (cp.
value() ==
'\\')
330 *out++ =
static_cast<char>(cp.
value());
336 auto c =
static_cast<int>(cp.
value());
348 template <
typename OutputIt,
typename Reader>
356 [[maybe_unused]]
auto write_escaped_byte = [opts](OutputIt out,
unsigned char byte) {
365 using encoding =
typename Reader::encoding;
366 if constexpr (std::is_same_v<encoding, lexy::ascii_encoding>
367 || std::is_same_v<encoding, lexy::default_encoding>)
377 out = write_escaped_byte(out,
static_cast<unsigned char>(c));
380 if (
count == opts.max_lexeme_width)
388 else if constexpr (std::is_same_v<encoding, lexy::utf8_encoding>
389 || std::is_same_v<encoding, lexy::utf8_char_encoding>
390 || std::is_same_v<encoding, lexy::utf16_encoding>
391 || std::is_same_v<encoding, lexy::utf32_encoding>)
395 auto reader = input.reader();
409 reader.set_position(result.end);
415 auto begin = reader.position();
417 auto end = reader.position();
420 for (
auto cur =
begin; cur !=
end; ++cur)
422 if constexpr (std::is_same_v<encoding,
424 || std::is_same_v<encoding, lexy::utf8_char_encoding>)
426 out = write_escaped_byte(out,
static_cast<unsigned char>(*cur & 0xFF));
428 else if constexpr (std::is_same_v<encoding, lexy::utf16_encoding>)
430 auto first =
static_cast<unsigned char>((*cur >> 8) & 0xFF);
431 auto second =
static_cast<unsigned char>(*cur & 0xFF);
434 out = write_escaped_byte(out, first);
435 out = write_escaped_byte(out, second);
437 else if constexpr (std::is_same_v<encoding, lexy::utf32_encoding>)
439 auto first =
static_cast<unsigned char>((*cur >> 24) & 0xFF);
440 auto second =
static_cast<unsigned char>((*cur >> 16) & 0xFF);
441 auto third =
static_cast<unsigned char>((*cur >> 8) & 0xFF);
442 auto fourth =
static_cast<unsigned char>(*cur & 0xFF);
445 out = write_escaped_byte(out, first);
446 if (first != 0 || second != 0)
447 out = write_escaped_byte(out, second);
448 if (first != 0 || second != 0 || third != 0)
449 out = write_escaped_byte(out, third);
450 out = write_escaped_byte(out, fourth);
456 if (
count == opts.max_lexeme_width)
464 else if constexpr (std::is_same_v<encoding, lexy::byte_encoding>)
467 for (
auto iter =
lexeme.begin(); iter !=
lexeme.end(); ++iter)
475 if (
count == opts.max_lexeme_width)
485 static_assert(lexy::_detail::error<encoding>,
"unknown encoding");
490 template <
typename OutputIt,
typename Tree,
typename = decltype(
LEXY_DECLVAL(Tree&).traverse())>
501 : label_t{u8
" ", u8
" ", u8
"- ", u8
"- "};
510 = [opts, label, &is_last_child](OutputIt out, std::size_t cur_depth,
bool cur_is_last) {
515 out = _detail::write_color<_detail::color::faint>(out, opts);
518 for (
auto i = 1u; i < cur_depth; ++i)
519 if (is_last_child[i])
532 out = _detail::write_color<_detail::color::reset>(out, opts);
537 std::size_t cur_depth = 0;
538 for (
auto [event, node] : tree.traverse())
540 auto last_child = node.is_last_child();
542 using event_t =
typename decltype(tree.traverse())::event;
546 if (cur_depth <= opts.max_tree_depth)
548 out = write_prefix(out, cur_depth, last_child);
550 out = _detail::write_color<_detail::color::bold>(out, opts);
552 out = _detail::write_color<_detail::color::reset>(out, opts);
554 if (cur_depth == opts.max_tree_depth)
565 is_last_child[cur_depth] = last_child;
576 if (cur_depth <= opts.max_tree_depth)
578 out = write_prefix(out, cur_depth, last_child);
580 out = _detail::write_color<_detail::color::bold>(out, opts);
582 out = _detail::write_color<_detail::color::reset>(out, opts);
584 if (!node.lexeme().empty())
620 std::fputc(c,
_file);
626 template <
typename T>
636 template <
typename T>
643 iterator& operator*() noexcept
647 iterator& operator++(
int) noexcept
652 iterator& operator=(
char c)
657 auto value =
static_cast<unsigned char>(c);
658 if ((value & 0b1100
'0000) != 0b1000'0000)
669 #endif // LEXY_VISUALIZE_HPP_INCLUDED