Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 19 additions & 58 deletions bin/clice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@ cl::opt<unsigned int> port{
cl::desc("The port to connect to"),
};

cl::opt<std::string> resource_dir{
"resource-dir",
cl::cat(category),
cl::value_desc("path"),
cl::desc(R"(The path of the clang resource directory, default is "../../lib/clang/version")"),
};

cl::opt<logging::ColorMode> log_color{
"log-color",
cl::cat(category),
Expand All @@ -69,75 +62,43 @@ cl::opt<logging::ColorMode> log_color{
cl::opt<logging::Level> log_level{
"log-level",
cl::cat(category),
cl::value_desc("trace|debug|info|warn|fatal"),
cl::value_desc("trace|debug|info|warn|error"),
cl::init(logging::Level::info),
cl::values(clEnumValN(logging::Level::trace, "trace", ""),
clEnumValN(logging::Level::debug, "debug", ""),
clEnumValN(logging::Level::info, "info", ""),
clEnumValN(logging::Level::warn, "warn", ""),
clEnumValN(logging::Level::err, "fatal", "")),
clEnumValN(logging::Level::err, "error", ""),
clEnumValN(logging::Level::off, "off", "")),
cl::desc("The log level, default is info"),
};

void init_log() {
using namespace logging;
options.color = log_color;
options.level = log_level;
logging::create_stderr_logger("clice", logging::options);
}

/// Check the command line arguments and initialize the clice.
bool check_arguments(int argc, const char** argv) {
/// Hide unrelated options.
cl::HideUnrelatedOptions(category);
} // namespace

// Set version printer and parse command line options
int main(int argc, const char** argv) {
llvm::InitLLVM guard(argc, argv);
llvm::setBugReportMsg(
"Please report bugs to https://github.com/clice-io/clice/issues and include the crash backtrace");
cl::SetVersionPrinter([](llvm::raw_ostream& os) {
os << std::format("clice version: {}\nllvm version: {}\n",
clice::config::version,
clice::config::llvm_version);
});
cl::HideUnrelatedOptions(category);
cl::ParseCommandLineOptions(argc,
argv,
"clice is a new generation of language server for C/C++");

init_log();
logging::options.color = log_color;
logging::options.level = log_level;
logging::stderr_logger("clice", logging::options);

for(int i = 0; i < argc; ++i) {
logging::info("argv[{}] = {}", i, argv[i]);
if(auto result = fs::init_resource_dir(argv[0]); !result) {
LOGGING_FATAL("Cannot find default resource directory, because {}", result.error());
}

// Initialize resource directory
if(resource_dir.empty()) {
logging::info("No resource directory specified, using default resource directory");
// Try to initialize default resource directory
if(auto result = fs::init_resource_dir(argv[0]); !result) {
logging::warn("Cannot find default resource directory, because {}", result.error());
return false;
}
} else {
// Set and check the specified resource directory
fs::resource_dir = resource_dir.getValue();
if(fs::exists(fs::resource_dir)) {
logging::info("Resource directory found: {}", fs::resource_dir);
} else {
logging::warn("Resource directory not found: {}", fs::resource_dir);
return false;
}
}

return true;
}

} // namespace

int main(int argc, const char** argv) {
llvm::InitLLVM guard(argc, argv);
llvm::setBugReportMsg(
"Please report bugs to https://github.com/clice-io/clice/issues and include the crash backtrace");

if(!check_arguments(argc, argv)) {
return 1;
for(int i = 0; i < argc; ++i) {
LOGGING_INFO("argv[{}] = {}", i, argv[i]);
}

async::init();
Expand All @@ -151,13 +112,13 @@ int main(int argc, const char** argv) {
switch(mode) {
case Mode::Pipe: {
async::net::listen(loop);
logging::info("Server starts listening on stdin/stdout");
LOGGING_INFO("Server starts listening on stdin/stdout");
break;
}

case Mode::Socket: {
async::net::listen(host.c_str(), port, loop);
logging::info("Server starts listening on {}:{}", host.getValue(), port.getValue());
LOGGING_INFO("Server starts listening on {}:{}", host.getValue(), port.getValue());
break;
}

Expand All @@ -169,7 +130,7 @@ int main(int argc, const char** argv) {

async::run();

logging::info("clice exit normally!");
LOGGING_INFO("clice exit normally!");

return 0;
}
20 changes: 5 additions & 15 deletions bin/unit_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace {

namespace cl = llvm::cl;

cl::OptionCategory unittest_category("Clice Unittest Options");
cl::OptionCategory unittest_category("clice Unittest Options");

cl::opt<std::string> test_dir{
"test-dir",
Expand All @@ -28,12 +28,6 @@ cl::opt<std::string> test_dir{
cl::cat(unittest_category),
};

cl::opt<std::string> resource_dir{
"resource-dir",
cl::desc("Resource dir path"),
cl::cat(unittest_category),
};

cl::opt<std::string> test_filter{
"test-filter",
cl::desc("A glob pattern to run subset of tests"),
Expand Down Expand Up @@ -190,21 +184,17 @@ int main(int argc, const char* argv[]) {
llvm::cl::HideUnrelatedOptions(unittest_category);
llvm::cl::ParseCommandLineOptions(argc, argv, "clice test\n");

logging::create_stderr_logger("clice", logging::options);
logging::stderr_logger("clice", logging::options);

if(!test_filter.empty()) {
if(auto result = GlobPattern::create(test_filter)) {
pattern.emplace(std::move(*result));
}
}

if(!resource_dir.empty()) {
fs::resource_dir = resource_dir;
} else {
if(auto result = fs::init_resource_dir(argv[0]); !result) {
std::println("Failed to get resource directory, because {}", result.error());
return 1;
}
if(auto result = fs::init_resource_dir(argv[0]); !result) {
std::println("Failed to get resource directory, because {}", result.error());
return 1;
}

using namespace clice::testing;
Expand Down
19 changes: 17 additions & 2 deletions include/Support/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,31 @@ template <>
struct std::formatter<clice::json::Value> : std::formatter<llvm::StringRef> {
using Base = std::formatter<llvm::StringRef>;

int indent = 0;

template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return Base::parse(ctx);
auto it = ctx.begin();
auto end = ctx.end();
if(it == end) {
return it;
}

int parsed_indent = 0;
while(it != end && *it >= '0' && *it <= '9') {
parsed_indent = parsed_indent * 10 + (*it - '0');
++it;
}
indent = parsed_indent;

return it;
}

template <typename FormatContext>
auto format(const clice::json::Value& value, FormatContext& ctx) const {
llvm::SmallString<128> buffer;
llvm::raw_svector_ostream os{buffer};
os << value;
llvm::json::OStream(os, indent).value(value);
return Base::format(buffer, ctx);
}
};
Expand Down
30 changes: 27 additions & 3 deletions include/Support/Logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,22 @@ using Level = spdlog::level::level_enum;
using ColorMode = spdlog::color_mode;

struct Options {
/// The logging level.
Level level = Level::info;

/// The logging color.
ColorMode color = ColorMode::automatic;

/// If enable, we will record the logs of console sink and replay it
/// when create a new sink,
bool replay_console = true;
};

extern Options options;

void create_stderr_logger(std::string_view name, const Options& options);
void stderr_logger(std::string_view name, const Options& options);

void create_file_loggger(std::string_view name, std::string_view dir, const Options& options);
void file_loggger(std::string_view name, std::string_view dir, const Options& options);

template <typename... Args>
struct logging_rformat {
Expand Down Expand Up @@ -72,10 +79,27 @@ void warn(logging_format<Args...> fmt, Args&&... args) {
}

template <typename... Args>
void fatal [[noreturn]] (logging_format<Args...> fmt, Args&&... args) {
void err(logging_format<Args...> fmt, Args&&... args) {
logging::log(spdlog::level::err, fmt.location, fmt.str, std::forward<Args>(args)...);
}

template <typename... Args>
void critical [[noreturn]] (logging_format<Args...> fmt, Args&&... args) {
logging::log(spdlog::level::critical, fmt.location, fmt.str, std::forward<Args>(args)...);
spdlog::shutdown();
std::exit(1);
}

} // namespace clice::logging

#define LOGGING_MESSAGE(name, fmt, ...) \
if(clice::logging::options.level <= clice::logging::Level::name) { \
clice::logging::name(fmt __VA_OPT__(, ) __VA_ARGS__); \
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

#define LOGGING_TRACE(fmt, ...) LOGGING_MESSAGE(trace, fmt, __VA_ARGS__)
#define LOGGING_DEBUG(fmt, ...) LOGGING_MESSAGE(debug, fmt, __VA_ARGS__)
#define LOGGING_INFO(fmt, ...) LOGGING_MESSAGE(info, fmt, __VA_ARGS__)
#define LOGGING_WARN(fmt, ...) LOGGING_MESSAGE(warn, fmt, __VA_ARGS__)
#define LOGGING_ERROR(fmt, ...) LOGGING_MESSAGE(err, fmt, __VA_ARGS__)
#define LOGGING_FATAL(fmt, ...) clice::logging::critical(fmt __VA_OPT__(, ) __VA_ARGS__);
6 changes: 0 additions & 6 deletions src/AST/Selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@

namespace clice {

#ifdef NDEBUG
#define LOGGING_DEBUG(...)
#else
#define LOGGING_DEBUG(...) logging::debug(__VA_ARGS__)
#endif

namespace {

using Node = SelectionTree::Node;
Expand Down
2 changes: 1 addition & 1 deletion src/Async/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ handle::~handle() {
uv_fs_t request;
int error = uv_fs_close(async::loop, &request, file, nullptr);
if(error < 0) {
logging::warn("Failed to close file: {}", uv_strerror(error));
LOGGING_WARN("Failed to close file: {}", uv_strerror(error));
}
uv_fs_req_cleanup(&request);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Async/Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {

/// If an error occurred while reading, we can't continue.
if(nread < 0) [[unlikely]] {
logging::fatal("An error occurred while reading: {0}", uv_strerror(nread));
LOGGING_FATAL("An error occurred while reading: {0}", uv_strerror(nread));
}

/// We have at most one connection and use default event loop. So there is no data race
Expand All @@ -57,7 +57,7 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
task.dispose();
} else {
/// If the message is invalid, we can't continue.
logging::fatal("Unexpected JSON input: {0}", result);
LOGGING_FATAL("Unexpected JSON input: {0}", result);
}

/// Remove the processed message from the buffer.
Expand Down Expand Up @@ -130,7 +130,7 @@ struct write {

uv_write(&req, writer, buf, 2, [](uv_write_t* req, int status) {
if(status < 0) {
logging::fatal("An error occurred while writing: {0}", uv_strerror(status));
LOGGING_FATAL("An error occurred while writing: {0}", uv_strerror(status));
}

auto& awaiter = uv_cast<struct write>(req);
Expand Down
10 changes: 5 additions & 5 deletions src/Async/libuv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ const std::error_category& category() {
/// Use source_location to log the file, line, and function name where the error occurred.
void uv_check_result(const int result, const std::source_location location) {
if(result < 0) {
logging::warn("libuv error: {}", uv_strerror(result));
logging::warn("At {}:{}:{}",
location.file_name(),
location.line(),
location.function_name());
LOGGING_WARN("libuv error: {}", uv_strerror(result));
LOGGING_WARN("At {}:{}:{}",
location.file_name(),
location.line(),
location.function_name());
}
}

Expand Down
Loading