new deps (termcolor, magic enum), log fixes

This commit is contained in:
programsnail 2024-07-28 18:53:25 +03:00
parent 49edbfb60c
commit 831cfa36f3
14 changed files with 1452 additions and 24 deletions

View file

@ -1 +1 @@
deps/
deps/tree-sitter-lang

2
deps/termcolor/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.xmake
compile_commands.json

31
deps/termcolor/LICENSE vendored Normal file
View file

@ -0,0 +1,31 @@
Copyright (c) 2013, Ihor Kalnytskyi.
All rights reserved.
Redistribution and use in source and binary forms of the software as well
as documentation, with or without modification, are permitted provided
that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

939
deps/termcolor/termcolor.hpp vendored Normal file
View file

@ -0,0 +1,939 @@
//!
//! termcolor
//! ~~~~~~~~~
//!
//! termcolor is a header-only c++ library for printing colored messages
//! to the terminal. Written just for fun with a help of the Force.
//!
//! :copyright: (c) 2013 by Ihor Kalnytskyi
//! :license: BSD, see LICENSE for details
//!
#ifndef TERMCOLOR_HPP_
#define TERMCOLOR_HPP_
#include <iostream>
// Detect target's platform and set some macros in order to wrap platform
// specific code this library depends on.
#if defined(_WIN32) || defined(_WIN64)
# define TERMCOLOR_TARGET_WINDOWS
#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
# define TERMCOLOR_TARGET_POSIX
#endif
// If implementation has not been explicitly set, try to choose one based on
// target platform.
#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP)
# if defined(TERMCOLOR_TARGET_POSIX)
# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES
# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION
# elif defined(TERMCOLOR_TARGET_WINDOWS)
# define TERMCOLOR_USE_WINDOWS_API
# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION
# endif
#endif
// These headers provide isatty()/fileno() functions, which are used for
// testing whether a standard stream refers to the terminal.
#if defined(TERMCOLOR_TARGET_POSIX)
# include <unistd.h>
#elif defined(TERMCOLOR_TARGET_WINDOWS)
# include <io.h>
# include <windows.h>
#endif
namespace termcolor
{
// Forward declaration of the `_internal` namespace.
// All comments are below.
namespace _internal
{
inline int colorize_index();
inline FILE* get_standard_stream(const std::ostream& stream);
inline FILE* get_standard_stream(const std::wostream& stream);
template <typename CharT>
bool is_colorized(std::basic_ostream<CharT>& stream);
template <typename CharT>
bool is_atty(const std::basic_ostream<CharT>& stream);
#if defined(TERMCOLOR_TARGET_WINDOWS)
template <typename CharT>
void win_change_attributes(std::basic_ostream<CharT>& stream, int foreground, int background = -1);
#endif
}
template <typename CharT>
std::basic_ostream<CharT>& colorize(std::basic_ostream<CharT>& stream)
{
stream.iword(_internal::colorize_index()) = 1L;
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& nocolorize(std::basic_ostream<CharT>& stream)
{
stream.iword(_internal::colorize_index()) = 0L;
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& reset(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[00m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1, -1);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bold(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[1m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& dark(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[2m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& italic(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[3m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& underline(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[4m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& blink(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[5m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& reverse(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[7m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& concealed(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[8m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& crossed(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[9m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t code, typename CharT>
std::basic_ostream<CharT>& color(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[38;5;" << +code << "m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t code, typename CharT>
std::basic_ostream<CharT>& on_color(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[48;5;" << +code << "m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t r, uint8_t g, uint8_t b, typename CharT>
std::basic_ostream<CharT>& color(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[38;2;" << +r << ";" << +g << ";" << +b << "m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t r, uint8_t g, uint8_t b, typename CharT>
std::basic_ostream<CharT>& on_color(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[48;2;" << +r << ";" << +g << ";" << +b << "m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& grey(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[30m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
0 // grey (black)
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& red(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[31m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& green(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[32m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& yellow(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[33m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& blue(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[34m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& magenta(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[35m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& cyan(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[36m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& white(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[37m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_grey(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[90m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
0 | FOREGROUND_INTENSITY // grey (black)
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_red(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[91m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_green(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[92m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_yellow(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[93m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_blue(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[94m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_magenta(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[95m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_cyan(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[96m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& bright_white(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[97m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_grey(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[40m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
0 // grey (black)
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_red(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[41m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_green(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[42m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_yellow(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[43m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_blue(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[44m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_magenta(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[45m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_cyan(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[46m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_white(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[47m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_grey(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[100m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
0 | BACKGROUND_INTENSITY // grey (black)
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_red(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[101m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_green(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[102m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_yellow(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[103m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_blue(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[104m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_magenta(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[105m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_cyan(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[106m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
template <typename CharT>
std::basic_ostream<CharT>& on_bright_white(std::basic_ostream<CharT>& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[107m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
//! Since C++ hasn't a way to hide something in the header from
//! the outer access, I have to introduce this namespace which
//! is used for internal purpose and should't be access from
//! the user code.
namespace _internal
{
// An index to be used to access a private storage of I/O streams. See
// colorize / nocolorize I/O manipulators for details. Due to the fact
// that static variables ain't shared between translation units, inline
// function with local static variable is used to do the trick and share
// the variable value between translation units.
inline int colorize_index()
{
static int colorize_index = std::ios_base::xalloc();
return colorize_index;
}
//! Since C++ hasn't a true way to extract stream handler
//! from the a given `std::ostream` object, I have to write
//! this kind of hack.
inline
FILE* get_standard_stream(const std::ostream& stream)
{
if (&stream == &std::cout)
return stdout;
else if (&stream == &std::cerr || &stream == &std::clog)
return stderr;
return nullptr;
}
//! Since C++ hasn't a true way to extract stream handler
//! from the a given `std::wostream` object, I have to write
//! this kind of hack.
inline
FILE* get_standard_stream(const std::wostream& stream)
{
if (&stream == &std::wcout)
return stdout;
else if (&stream == &std::wcerr || &stream == &std::wclog)
return stderr;
return nullptr;
}
// Say whether a given stream should be colorized or not. It's always
// true for ATTY streams and may be true for streams marked with
// colorize flag.
template <typename CharT>
bool is_colorized(std::basic_ostream<CharT>& stream)
{
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index()));
}
//! Test whether a given `std::ostream` object refers to
//! a terminal.
template <typename CharT>
bool is_atty(const std::basic_ostream<CharT>& stream)
{
FILE* std_stream = get_standard_stream(stream);
// Unfortunately, fileno() ends with segmentation fault
// if invalid file descriptor is passed. So we need to
// handle this case gracefully and assume it's not a tty
// if standard stream is not detected, and 0 is returned.
if (!std_stream)
return false;
#if defined(TERMCOLOR_TARGET_POSIX)
return ::isatty(fileno(std_stream));
#elif defined(TERMCOLOR_TARGET_WINDOWS)
return ::_isatty(_fileno(std_stream));
#else
return false;
#endif
}
#if defined(TERMCOLOR_TARGET_WINDOWS)
//! same hack as used in get_standard_stream function, but for Windows with `std::ostream`
inline HANDLE get_terminal_handle(std::ostream& stream)
{
if (&stream == &std::cout)
return GetStdHandle(STD_OUTPUT_HANDLE);
else if (&stream == &std::cerr || &stream == &std::clog)
return GetStdHandle(STD_ERROR_HANDLE);
return nullptr;
}
//! same hack as used in get_standard_stream function, but for Windows with `std::wostream`
inline HANDLE get_terminal_handle(std::wostream& stream)
{
if (&stream == &std::wcout)
return GetStdHandle(STD_OUTPUT_HANDLE);
else if (&stream == &std::wcerr || &stream == &std::wclog)
return GetStdHandle(STD_ERROR_HANDLE);
return nullptr;
}
//! Change Windows Terminal colors attribute. If some
//! parameter is `-1` then attribute won't changed.
template <typename CharT>
void win_change_attributes(std::basic_ostream<CharT>& stream, int foreground, int background)
{
// yeah, i know.. it's ugly, it's windows.
static WORD defaultAttributes = 0;
// Windows doesn't have ANSI escape sequences and so we use special
// API to change Terminal output color. That means we can't
// manipulate colors by means of "std::stringstream" and hence
// should do nothing in this case.
if (!_internal::is_atty(stream))
return;
// get terminal handle
HANDLE hTerminal = INVALID_HANDLE_VALUE;
hTerminal = get_terminal_handle(stream);
// save default terminal attributes if it unsaved
if (!defaultAttributes)
{
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
return;
defaultAttributes = info.wAttributes;
}
// restore all default settings
if (foreground == -1 && background == -1)
{
SetConsoleTextAttribute(hTerminal, defaultAttributes);
return;
}
// get current settings
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
return;
if (foreground != -1)
{
info.wAttributes &= ~(info.wAttributes & 0x0F);
info.wAttributes |= static_cast<WORD>(foreground);
}
if (background != -1)
{
info.wAttributes &= ~(info.wAttributes & 0xF0);
info.wAttributes |= static_cast<WORD>(background);
}
SetConsoleTextAttribute(hTerminal, info.wAttributes);
}
#endif // TERMCOLOR_TARGET_WINDOWS
} // namespace _internal
} // namespace termcolor
#undef TERMCOLOR_TARGET_POSIX
#undef TERMCOLOR_TARGET_WINDOWS
#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION)
# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES
# undef TERMCOLOR_USE_WINDOWS_API
#endif
#endif // TERMCOLOR_HPP_

7
deps/termcolor/xmake.lua vendored Normal file
View file

@ -0,0 +1,7 @@
set_languages("c++20")
target("termcolor")
set_kind("headeronly")
add_headerfiles("termcolor.hpp")
set_warnings("all", "error")
set_rundir("$(projectdir)")

View file

@ -11,8 +11,8 @@ int main(int argc, char **argv) {
//
SourcesManager sources_manager;
SourcesManager sources_manager(Log({}, {}));
sources_manager.add_file(filename);
sources_manager.print(std::cout);
sources_manager.AddFile(filename);
sources_manager.Print(std::cout);
}

View file

@ -2,8 +2,8 @@
#include "basic_printers.hpp"
#include "error_handling.hpp"
#include "error_log.hpp"
#include "expression_nodes.hpp"
#include "log.hpp"
#include "name_tree.hpp"
#include "statement_builders.hpp"
#include "statement_nodes.hpp"
@ -17,7 +17,11 @@
class SourcesManager {
public:
void add_file(const std::string &filename) {
SourcesManager(Log &&log) : log_(std::move(log)) {}
void AddFile(const std::string &filename) {
Log::Context logc(log_, utils::Log::Area::kParse);
std::ifstream in;
in.open(filename);
@ -32,8 +36,8 @@ public:
parser::ParseTree parse_tree(source);
if (!parse_tree.is_properly_parsed()) {
error_handling::handle_parsing_error(
"There are some parsing errors in file", parse_tree.get_root());
logc.Fatal<Log::kProc>(
{{"There are some parsing errors in file"}} /*,parse_tree.get_root()*/);
}
auto new_statements = builders::build_source_file(
@ -47,36 +51,36 @@ public:
new_statements.clear();
}
void print(std::ostream &out) {
void Print(std::ostream &out) {
printers::Printer printer(out, 2, 80, true);
printers::print(statements_, printer);
}
//
nodes::ExpressionStorage *expressions() { return &expression_storage_; }
nodes::ExpressionStorage &expressions() { return expression_storage_; }
const nodes::ExpressionStorage *expressions() const {
return &expression_storage_;
const nodes::ExpressionStorage &expressions() const {
return expression_storage_;
}
//
nodes::TypeStorage *types() { return &type_storage_; }
nodes::TypeStorage &types() { return type_storage_; }
const nodes::TypeStorage *types() const { return &type_storage_; }
const nodes::TypeStorage &types() const { return type_storage_; }
//
names::NameTree *names() { return &name_tree_; }
names::NameTree &names() { return name_tree_; }
const names::NameTree *names() const { return &name_tree_; }
const names::NameTree &names() const { return name_tree_; }
//
error_handling::ErrorLog *errors() { return &error_log_; }
utils::Log &log() { return log_; }
const error_handling::ErrorLog *errors() const { return &error_log_; }
const utils::Log &log() const { return log_; }
//
@ -89,9 +93,9 @@ public:
}
private:
nodes::ExpressionStorage expression_storage_;
nodes::TypeStorage type_storage_;
names::NameTree name_tree_;
error_handling::ErrorLog error_log_;
std::vector<nodes::Statement> statements_;
Log log_;
nodes::ExpressionStorage expression_storage_ = {};
nodes::TypeStorage type_storage_ = {};
names::NameTree name_tree_ = {};
std::vector<nodes::Statement> statements_ = {};
};

View file

@ -2,7 +2,6 @@
#include "basic_nodes.hpp"
#include "basic_type_check.hpp"
#include "builtin_types.hpp"
#include "error_log.hpp"
#include "sources_manager.hpp"
#include "type_nodes.hpp"
#include "utils.hpp"

View file

@ -3,6 +3,7 @@
#include "basic_nodes.hpp"
#include "basic_printers.hpp"
#include <string>
#include <vector>
namespace error_handling {

View file

@ -0,0 +1,79 @@
#pragma once
#include <memory>
#include <vector>
#include "log.hpp"
namespace utils {
template <typename... States> class Task;
template <typename State> class ExecutorState {
public:
struct Tag {};
ExecutorState(State &&state) : state_(std::move(state)) {}
//
State &state(Tag) { return state; }
const State &state(Tag) const { return state; }
protected:
State state_;
};
template <typename... States> class Executor : public ExecutorState<States>... {
friend class Task<States...>;
public:
Executor(Log &&log, States &&...states)
: ExecutorState<States>(std::move(states))..., log_(std::move(log)) {}
//
template <typename T, typename... Args> T New(Args... args) {
return T(*this, args...);
}
//
Log &log() { return log_; }
const Log &log() const { return log_; }
private:
Log log_;
};
template <typename... States> class Task {
public:
Task(Executor<States...> &executor) : executor(executor) {}
virtual ~Task() {}
//
virtual void operator()() = 0;
template <typename T, typename... Args> T New(Args... args) {
return executor.template New<T>(std::move(args)...);
}
//
template <typename T> T &state() {
return executor.state(ExecutorState<T>::Tag);
}
template <typename T> const T &state() const {
return executor.state(ExecutorState<T>::Tag);
}
Log &log() { return executor.log_; }
const Log &log() const { return executor.log_; }
public:
Executor<States...> &executor;
};
} // namespace utils

304
lang/utils/include/log.hpp Normal file
View file

@ -0,0 +1,304 @@
#include <format>
#include <functional>
#include <iostream>
#include <optional>
#include <source_location>
#include <string>
#include <vector>
// Expect
#define EXPECT_EQ(context, left, right) \
(context).Expect((left) == (right), "#left == #right");
#define EXPECT_NE(context, left, right) \
(context).Expect((left) != (right), "#left != #right");
#define EXPECT_LE(context, left, right) \
(context).Expect((left) <= (right), "#left <= #right");
#define EXPECT_GE(context, left, right) \
(context).Expect((left) >= (right), "#left >= #right");
#define EXPECT_LT(context, left, right) \
(context).Expect((left) < (right), "#left < #right");
#define EXPECT_GT(context, left, right) \
(context).Expect((left) > (right), "#left > #right");
// Require
#define REQUIRE_EQ(context, left, right) \
(context).Require((left) == (right), "#left == #right");
#define REQUIRE_NE(context, left, right) \
(context).Require((left) != (right), "#left != #right");
#define REQUIRE_LE(context, left, right) \
(context).Require((left) <= (right), "#left <= #right");
#define REQUIRE_GE(context, left, right) \
(context).Require((left) >= (right), "#left >= #right");
#define REQUIRE_LT(context, left, right) \
(context).Require((left) < (right), "#left < #right");
#define REQUIRE_GT(context, left, right) \
(context).Require((left) > (right), "#left > #right");
//
namespace utils {
std::string to_string(const std::source_location &source_location);
struct Pos {
public:
struct Point {
size_t line;
size_t position;
};
public:
Point start;
Point end;
};
class Log {
friend class Context;
public:
enum Kind {
kSys,
kProc,
};
enum class Level : uint32_t { // NOTE: change to_string(Log::Level level) on
// change
kDebug = 1,
kInfo = 3,
kImportant = 5,
kWarning = 7,
kError = 9,
kFatal = 11,
};
enum class Area {
kDefault,
kParse,
kIntepret,
// ...
};
struct Fragment {
// Fragment(std::string fragment) : fragment(fragment), color(kNone) {}
enum Color {
kNone,
kDebug,
kInfo,
kImportant,
kWarning,
kError,
kFatal,
};
std::string fragment;
Color color = kNone;
explicit operator std::string() {
return fragment; // TODO: +color
}
};
using Fragments = std::vector<Fragment>;
struct Message {
Fragments message;
Level level;
Area area = Area::kDefault;
std::optional<Pos> pos = {};
std::source_location source_location = std::source_location::current();
};
class Context {
public:
Context(
Log &log, Area area, Level default_level = Level::kInfo,
std::source_location source_location = std::source_location::current())
: log_(log), area_(area), default_level_(default_level),
function_(to_string(source_location)) {
log_.PushLog<kSys>({
.message = {{"Enter ", Fragment::kInfo}, {function_}},
.level = default_level_,
});
}
~Context() {
log_.PushLog<kSys>({
.message = {{"Leave ", Fragment::kInfo}, {function_}},
.level = default_level_,
});
}
Context(const Context &log) = delete;
Context(Context &&log) = delete;
//
template <Kind K>
void LogWithLevel(Fragments message, Level level,
std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
log_.PushLog<K>({
.message = std::move(message),
.level = level,
.area = area_,
.pos = pos,
.source_location = source_location,
});
}
template <Kind K>
void Default(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
LogWithLevel<K>(std::move(message), default_level_, pos, source_location);
}
template <Kind K>
void Debug(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
LogWithLevel<K>(std::move(message), Level::kDebug, pos, source_location);
}
template <Kind K>
void Info(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
LogWithLevel<K>(std::move(message), Level::kInfo, pos, source_location);
}
template <Kind K>
void Important(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
LogWithLevel<K>(std::move(message), Level::kImportant, pos,
source_location);
}
template <Kind K>
void Warning(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
LogWithLevel<K>(std::move(message), Level::kWarning, pos,
source_location);
}
template <Kind K>
void Error(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
LogWithLevel<K>(std::move(message), Level::kError, pos, source_location);
}
template <Kind K>
void Fatal(Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
auto entity = Message{
.message = std::move(message),
.level = Level::kFatal,
.area = area_,
.pos = pos,
.source_location = source_location,
};
log_.PushLog<K>(entity);
throw entity;
}
//
template <Kind K>
bool Expect(bool condition, Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
message.insert(message.begin(),
{.fragment = "Expected: ", .color = Fragment::kError});
if (condition) {
Error<K>(std::move(message), pos, source_location);
}
return condition;
}
template <Kind K>
bool Require(bool condition, Fragments message, std::optional<Pos> pos = {},
std::source_location source_location =
std::source_location::current()) {
message.insert(message.begin(),
{.fragment = "Required: ", .color = Fragment::kError});
if (condition) {
Error<K>(std::move(message), pos, source_location);
}
return condition;
}
private:
Log &log_;
Area area_;
Level default_level_;
std::string function_;
};
public:
Log(std::function<void(const Message &)> sys_hook,
std::function<void(const Message &)> proc_hook)
: sys{}, proc{}, sys_hook_(sys_hook), proc_hook_(proc_hook) {}
// TODO: proc logs
private:
template <Kind K> void PushLog(Message message) {
static_assert(K == kSys or K == kProc);
switch (K) {
case kSys:
sys_hook_(message);
sys.push_back(std::move(message));
break;
case kProc:
proc_hook_(message);
proc.push_back(std::move(message));
break;
}
}
private:
std::vector<Message> sys; // logs for runing code
std::vector<Message>
proc; // logs for code parsing / type check / interpretation / ...
std::function<void(const Message &)> sys_hook_;
std::function<void(const Message &)> proc_hook_;
};
//
std::string to_string(const std::source_location &source_location);
std::string to_string(Pos::Point point);
std::string to_string(Pos pos);
std::string to_string(Log::Fragments fragments);
std::string to_string(Log::Level level);
std::string to_string(Log::Message message);
//
Log BuildPrintLog(std::ostream &out, Log::Level min_level = Log::Level::kInfo);
} // namespace utils
using utils::Log;

View file

@ -0,0 +1 @@
#include "executor.hpp"

54
lang/utils/src/log.cpp Normal file
View file

@ -0,0 +1,54 @@
#include "log.hpp"
#include "magic_enum.hpp"
#include <numeric>
namespace utils {
std::string to_string(const std::source_location &source_location) {
return std::format("{}:{} {}", source_location.file_name(),
source_location.line(), source_location.function_name());
}
std::string to_string(Pos::Point point) {
return std::format("{},{}", point.line, point.position);
}
std::string to_string(Pos pos) {
return std::format("{} - {}", to_string(pos.start), to_string(pos.end));
}
std::string to_string(Log::Fragments fragments) {
return std::accumulate( //
std::move_iterator(fragments.begin()),
std::move_iterator(fragments.end()), std::string{},
[](auto &&acc, Log::Fragment &&fragment) {
acc += static_cast<std::string>(fragment);
return acc;
});
}
std::string to_string(Log::Level level) {
return std::string{magic_enum::enum_name(level).substr(1)}; // k... -> ...
}
std::string to_string(Log::Message message) {
return std::format(
"{}: {}{} ({})", to_string(message.level), to_string(message.message),
message.pos ? (" at " + to_string(*message.pos)) : std::string{},
to_string(message.source_location));
}
//
inline Log BuildPrintLog(std::ostream &out, Log::Level min_level) {
auto const print = [&out, min_level](const Log::Message &message) {
if (message.level >= min_level) {
out << to_string(message);
}
};
return Log(print, print);
}
} // namespace utils

View file

@ -1,8 +1,15 @@
set_languages("c++20")
add_requires("magic_enum")
-- TODO:
-- includes("../../deps/termcolor")
target("lang.utils")
set_kind("static")
add_includedirs("include", {public = true})
add_files("src/**.cpp")
add_packages("magic_enum")
-- add_deps("termcolor")
set_warnings("allextra", "error")
set_rundir("$(projectdir)")