9 changed files with 328 additions and 299 deletions
			
			
		@ -0,0 +1,143 @@ | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2022 Riyyi | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * SPDX-License-Identifier: MIT | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdio>  // FILE, fputs | 
				
			||||||
 | 
					#include <iomanip> // setprecision | 
				
			||||||
 | 
					#include <ios>     // defaultfloat, fixed | 
				
			||||||
 | 
					#include <sstream> // stringstream | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					#include <string_view> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "util/format/print.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Util::Format { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printTimeElapsedAndTypePrefix(std::stringstream& stream, Type type, bool bold) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						stream << std::fixed << std::setprecision(3) | 
				
			||||||
 | 
							   << s_timer.elapsedNanoseconds() / 1000000000.0 << "s " | 
				
			||||||
 | 
							   << std::defaultfloat << std::setprecision(6); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream << "[\033["; | 
				
			||||||
 | 
						if (bold) { | 
				
			||||||
 | 
							stream << "1"; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						switch (type) { | 
				
			||||||
 | 
						case Type::None: | 
				
			||||||
 | 
							stream << ";35mdebug"; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						case Type::Info: | 
				
			||||||
 | 
							stream << ";34minfo"; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						case Type::Warn: | 
				
			||||||
 | 
							stream << ";33mwarn"; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						case Type::Critical: | 
				
			||||||
 | 
							stream << ";31mcritical"; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						case Type::Success: | 
				
			||||||
 | 
							stream << ";32msuccess"; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						case Type::Comment: | 
				
			||||||
 | 
							stream << "mcomment"; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						default: | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
						stream << "\033[0m] "; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void prettyVariadicFormat(FILE* file, Type type, bool bold, std::string_view format, TypeErasedParameters& parameters) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						std::stringstream stream; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printTimeElapsedAndTypePrefix(stream, type, bold); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						variadicFormat(stream, format, parameters); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string string = stream.str(); | 
				
			||||||
 | 
						fputs(string.c_str(), file); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint::FormatPrint(FILE* file, Type type, bool bold) | 
				
			||||||
 | 
						: m_file(file) | 
				
			||||||
 | 
						, m_type(type) | 
				
			||||||
 | 
						, m_bold(bold) | 
				
			||||||
 | 
						, m_stream() | 
				
			||||||
 | 
						, m_builder(m_stream) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						printTimeElapsedAndTypePrefix(m_stream, type, bold); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint::~FormatPrint() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						std::string string = m_stream.str(); | 
				
			||||||
 | 
						fputs(string.c_str(), stdout); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint dbg() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::None, false); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint dbgb() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::None, true); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint info() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Info, false); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint infob() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Info, true); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint warn() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Warn, false); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint warnb() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Warn, true); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint critical() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stderr, Type::Critical, false); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint criticalb() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stderr, Type::Critical, true); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint success() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Success, false); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint successb() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Success, true); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint comment() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Comment, false); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint commentb() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return FormatPrint(stdout, Type::Comment, true); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Util::Format
 | 
				
			||||||
@ -0,0 +1,124 @@ | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2022 Riyyi | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * SPDX-License-Identifier: MIT | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdio> // FILE | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "util/format/format.h" | 
				
			||||||
 | 
					#include "util/timer.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Util::Format { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Util::Timer s_timer; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class Type { | 
				
			||||||
 | 
						None,     // Foreground
 | 
				
			||||||
 | 
						Info,     // Blue
 | 
				
			||||||
 | 
						Warn,     // Yellow
 | 
				
			||||||
 | 
						Critical, // Red
 | 
				
			||||||
 | 
						Success,  // Green
 | 
				
			||||||
 | 
						Comment,  // White
 | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void prettyVariadicFormat(FILE* file, Type type, bool bold, std::string_view format, TypeErasedParameters& parameters); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FORMAT_FUNCTION(name, type, bold)                                                      \ | 
				
			||||||
 | 
						template<size_t N, typename... Parameters>                                                 \
 | 
				
			||||||
 | 
						void name(const char(&format)[N] = "", const Parameters&... parameters)                    \
 | 
				
			||||||
 | 
						{                                                                                          \
 | 
				
			||||||
 | 
							VariadicParameters variadicParameters { parameters... };                               \
 | 
				
			||||||
 | 
							prettyVariadicFormat(stdout, Type::type, bold, { format, N - 1 }, variadicParameters); \
 | 
				
			||||||
 | 
						}                                                                                          \
 | 
				
			||||||
 | 
						template<size_t N, typename... Parameters>                                                 \
 | 
				
			||||||
 | 
						void name(FILE* file, const char(&format)[N] = "", const Parameters&... parameters)        \
 | 
				
			||||||
 | 
						{                                                                                          \
 | 
				
			||||||
 | 
							VariadicParameters variadicParameters { parameters... };                               \
 | 
				
			||||||
 | 
							prettyVariadicFormat(file, Type::type, bold, { format, N - 1 }, variadicParameters);   \
 | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FORMAT_FUNCTION(dbgln, None, false); | 
				
			||||||
 | 
					FORMAT_FUNCTION(dbgbln, None, true); | 
				
			||||||
 | 
					FORMAT_FUNCTION(infoln, Info, false); | 
				
			||||||
 | 
					FORMAT_FUNCTION(infobln, Info, true); | 
				
			||||||
 | 
					FORMAT_FUNCTION(warnln, Warn, false); | 
				
			||||||
 | 
					FORMAT_FUNCTION(warnbln, Warn, true); | 
				
			||||||
 | 
					FORMAT_FUNCTION(criticalln, Critical, false); | 
				
			||||||
 | 
					FORMAT_FUNCTION(criticalbln, Critical, true); | 
				
			||||||
 | 
					FORMAT_FUNCTION(successln, Success, false); | 
				
			||||||
 | 
					FORMAT_FUNCTION(successbln, Success, true); | 
				
			||||||
 | 
					FORMAT_FUNCTION(commentln, Comment, false); | 
				
			||||||
 | 
					FORMAT_FUNCTION(commentbln, Comment, true); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FormatPrint { | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						FormatPrint(FILE* file, Type type, bool bold); | 
				
			||||||
 | 
						virtual ~FormatPrint(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Builder& builder() { return m_builder; } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						FILE* m_file; | 
				
			||||||
 | 
						Type m_type; | 
				
			||||||
 | 
						bool m_bold; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::stringstream m_stream; | 
				
			||||||
 | 
						Builder m_builder; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T> | 
				
			||||||
 | 
					const FormatPrint& operator<<(const FormatPrint& formatPrint, const T& value) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						_format(const_cast<FormatPrint&>(formatPrint).builder(), value); | 
				
			||||||
 | 
						return formatPrint; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatPrint dbg(); | 
				
			||||||
 | 
					FormatPrint dbgb(); | 
				
			||||||
 | 
					FormatPrint info(); | 
				
			||||||
 | 
					FormatPrint infob(); | 
				
			||||||
 | 
					FormatPrint warn(); | 
				
			||||||
 | 
					FormatPrint warnb(); | 
				
			||||||
 | 
					FormatPrint critical(); | 
				
			||||||
 | 
					FormatPrint criticalb(); | 
				
			||||||
 | 
					FormatPrint success(); | 
				
			||||||
 | 
					FormatPrint successb(); | 
				
			||||||
 | 
					FormatPrint comment(); | 
				
			||||||
 | 
					FormatPrint commentb(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Util::Format
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Util { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Util::Format::commentbln; | 
				
			||||||
 | 
					using Util::Format::commentln; | 
				
			||||||
 | 
					using Util::Format::criticalbln; | 
				
			||||||
 | 
					using Util::Format::criticalln; | 
				
			||||||
 | 
					using Util::Format::dbgbln; | 
				
			||||||
 | 
					using Util::Format::dbgln; | 
				
			||||||
 | 
					using Util::Format::infobln; | 
				
			||||||
 | 
					using Util::Format::infoln; | 
				
			||||||
 | 
					using Util::Format::successbln; | 
				
			||||||
 | 
					using Util::Format::successln; | 
				
			||||||
 | 
					using Util::Format::warnbln; | 
				
			||||||
 | 
					using Util::Format::warnln; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Util::Format::comment; | 
				
			||||||
 | 
					using Util::Format::commentb; | 
				
			||||||
 | 
					using Util::Format::critical; | 
				
			||||||
 | 
					using Util::Format::criticalb; | 
				
			||||||
 | 
					using Util::Format::dbg; | 
				
			||||||
 | 
					using Util::Format::dbgb; | 
				
			||||||
 | 
					using Util::Format::info; | 
				
			||||||
 | 
					using Util::Format::infob; | 
				
			||||||
 | 
					using Util::Format::success; | 
				
			||||||
 | 
					using Util::Format::successb; | 
				
			||||||
 | 
					using Util::Format::warn; | 
				
			||||||
 | 
					using Util::Format::warnb; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Util
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue