From 3615c5a1947f80cb0cb597dee5526ce7dad05c0e Mon Sep 17 00:00:00 2001 From: qingfengzl Date: Fri, 8 Aug 2025 16:06:56 +0800 Subject: [PATCH] Misc fix (#171) --- .pre-commit-config.yaml | 2 +- include/Support/Logger.h | 44 ++++++++++++++++++++++++++++++++-------- src/Driver/clice.cc | 39 ++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 27448bed..35f54cd9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ -files: '^(src|include)(/[^/]+)*/[^/]+\.(h|cpp|cc)$' repos: - repo: https://github.com/pre-commit/mirrors-clang-format rev: "v20.1.0" hooks: - id: clang-format + files: '^(src|include)(/[^/]+)*/[^/]+\.(h|cpp|cc)$' diff --git a/include/Support/Logger.h b/include/Support/Logger.h index 8daefe8a..d53dde3a 100644 --- a/include/Support/Logger.h +++ b/include/Support/Logger.h @@ -3,32 +3,58 @@ #include "Format.h" #include "FileSystem.h" +#include "llvm/Support/CommandLine.h" + namespace clice::log { enum class Level { + TRACE, + DEBUG, INFO, WARN, - DEBUG, - TRACE, FATAL, }; +struct LogOpt { + Level level = Level::INFO; + bool color = false; +}; + +inline LogOpt log_opt; + template void log(Level level, std::string_view fmt, Args&&... args) { +#define Green "\033[32m" +#define Yellow "\033[33m" +#define Cyan "\033[36m" +#define Magenta "\033[35m" +#define Red "\033[31m" +#define None "\033[0m" namespace chrono = std::chrono; auto now = chrono::floor(chrono::system_clock::now()); auto time = now; // chrono::zoned_time(chrono::current_zone(), now); auto tag = [&] { switch(level) { - case Level::INFO: return "\033[32mINFO\033[0m"; // Green - case Level::WARN: return "\033[33mWARN\033[0m"; // Yellow - case Level::DEBUG: return "\033[36mDEBUG\033[0m"; // Cyan - case Level::TRACE: return "\033[35mTRACE\033[0m"; // Magenta - case Level::FATAL: return "\033[31mFATAL ERROR\033[0m"; // Red + case Level::INFO: return log_opt.color ? Green "[INFO]" None : "[INFO]"; // Green + case Level::WARN: return log_opt.color ? Yellow "[WARN]" None : "[WARN]"; // Yellow + case Level::DEBUG: return log_opt.color ? Cyan "[DEBUG]" None : "[DEBUG]"; // Cyan + case Level::TRACE: + return log_opt.color ? Magenta "[TRACE]" None : "[TRACE]"; // Magenta + case Level::FATAL: + return log_opt.color ? Red "[FATAL ERROR]" None : "[FATAL ERROR]"; // Red + default: llvm::llvm_unreachable_internal("Illegal log level"); } }(); - llvm::errs() << std::format("[{0:%Y-%m-%d %H:%M:%S}] [{1}] ", time, tag) - << std::vformat(fmt, std::make_format_args(args...)) << "\n"; + if(level >= log_opt.level) { + llvm::errs() << std::format("[{0:%Y-%m-%d %H:%M:%S}] {1} ", time, tag) + << std::vformat(fmt, std::make_format_args(args...)) << "\n"; + } +#undef Green +#undef Yellow +#undef Cyan +#undef Magenta +#undef Red +#undef None } template diff --git a/src/Driver/clice.cc b/src/Driver/clice.cc index 00ad4bb8..4356a771 100644 --- a/src/Driver/clice.cc +++ b/src/Driver/clice.cc @@ -4,6 +4,8 @@ #include "llvm/Support/InitLLVM.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Process.h" +#include "llvm/ADT/StringSwitch.h" namespace cl = llvm::cl; using namespace clice; @@ -32,15 +34,48 @@ cl::opt resource_dir( cl::value_desc("path"), cl::desc(R"(The path of the clang resource directory, default is "../../lib/clang/version")")); +static cl::OptionCategory category_log{"clice logging options"}; + +cl::opt log_color("log-color", + cl::cat(category_log), + cl::value_desc("always|auto|never"), + cl::init("auto"), + cl::desc("When to use terminal colors, default is auto")); + +cl::opt log_level("log-level", + cl::cat(category_log), + cl::value_desc("trace|debug|info|warn|fatal"), + cl::init("info"), + cl::desc("The log level, default is info")); + void printVersion(llvm::raw_ostream& os) { os << std::format("clice version: {}\n", clice::config::version) << std::format("llvm version: {}\n", clice::config::llvm_version); } +void init_log() { + using namespace log; + if(auto color_mode = llvm::StringRef{log_color}; !color_mode.compare("never")) { + log_opt.color = false; + } else if(!color_mode.compare("always")) { + log_opt.color = true; + } else { + // Auto mode + log_opt.color = llvm::sys::Process::StandardErrIsDisplayed(); + } + log_opt.level = llvm::StringSwitch(log_level) + .Case("trace", Level::TRACE) + .Case("debug", Level::DEBUG) + .Case("warn", Level::WARN) + .Case("fatal", Level::FATAL) + .Default(Level::INFO); +} + /// Check the command line arguments and initialize the clice. bool checkArguments(int argc, const char** argv) { /// Hide unrelated options. - cl::HideUnrelatedOptions(category); + std::vector categories = {&category, &category_log}; + cl::HideUnrelatedOptions(categories); // Set version printer and parse command line options cl::SetVersionPrinter(printVersion); @@ -48,6 +83,8 @@ bool checkArguments(int argc, const char** argv) { argv, "clice is a new generation of language server for C/C++"); + init_log(); + for(int i = 0; i < argc; ++i) { log::info("argv[{}] = {}", i, argv[i]); }