diff --git a/lix/libutil/logging.cc b/lix/libutil/logging.cc index b0b656908..38e7f92d9 100644 --- a/lix/libutil/logging.cc +++ b/lix/libutil/logging.cc @@ -1,4 +1,6 @@ #include "c-calls.hh" +#include "libutil/error.hh" +#include "lix-rs/utils.hh" #include "lix/libutil/config-impl.hh" #include "lix/libutil/environment-variables.hh" #include "lix/libutil/file-descriptor.hh" @@ -7,6 +9,7 @@ #include "lix/libutil/json.hh" #include "lix/libutil/position.hh" #include "lix/libutil/terminal.hh" +#include "main.gen.hh" #include "manually-drop.hh" #include @@ -138,9 +141,21 @@ public: Verbosity detail::verbosity = lvlInfo; +namespace { +struct InitRustVerbosity +{ + InitRustVerbosity(Verbosity v) + { + rust::lix::log::ffi::set_verbosity(v); + } +}; +static InitRustVerbosity _initRustVerbosity{detail::verbosity}; +} + void setVerbosity(Verbosity v) { detail::verbosity = v; + log::ffi::set_verbosity(v); } Verbosity verbosityFromIntClamped(int val) @@ -459,3 +474,11 @@ std::string LogLineSplitter::finish() return std::move(line); } } + +namespace rust::exported_functions { +Unit log_message(int lvl, Ref str) +{ + printMsg(nix::Verbosity(lvl), "%s", nix::Uncolored(to_std_string_view(str))); + return {}; +} +} diff --git a/lix/lix-rs/src/lib.rs b/lix/lix-rs/src/lib.rs index b1619ae55..f45ba2b79 100644 --- a/lix/lix-rs/src/lib.rs +++ b/lix/lix-rs/src/lib.rs @@ -32,4 +32,117 @@ mod ffi { impl error::Error for Error {} } +#[macro_use] +pub(crate) mod log { + use std::fmt::{Debug, Display}; + + static mut VERBOSITY: i32 = 99; + + // these MUST match the c++ struct exactly or log messages will be filtered incorrectly + #[allow(unused)] + pub const LVL_ERROR: i32 = 0; + #[allow(unused)] + pub const LVL_WARN: i32 = 1; + #[allow(unused)] + pub const LVL_NOTICE: i32 = 2; + #[allow(unused)] + pub const LVL_INFO: i32 = 3; + #[allow(unused)] + pub const LVL_TALKATIVE: i32 = 4; + #[allow(unused)] + pub const LVL_CHATTY: i32 = 5; + #[allow(unused)] + pub const LVL_DEBUG: i32 = 6; + #[allow(unused)] + pub const LVL_VOMIT: i32 = 7; + + pub struct Colorize(pub T); + + impl Display for Colorize { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("\x1b[35;1m")?; + Display::fmt(&self.0, f)?; + f.write_str("\x1b[0m") + } + } + + impl Debug for Colorize { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("\x1b[35;1m")?; + Debug::fmt(&self.0, f)?; + f.write_str("\x1b[0m") + } + } + + macro_rules! log_message { + ( __format plain: $e:expr ) => { + $e + }; + ( __format: $e:expr ) => { + crate::log::Colorize($e) + }; + ( $level:expr, $str:expr $(, $(plain)? $item:tt)* $(,)? ) => { + crate::generated::log_message( + $level, + &format!( + $str, + $( log_message!( __format: $item ) ),* + ) + ); + }; + } + + #[macro_export] + macro_rules! print_error { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_ERROR, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_warning { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_WARN, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_notice { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_NOTICE, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_info { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_INFO, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_talkative { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_TALKATIVE, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_chatty { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_CHATTY, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_debug { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_DEBUG, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_vomit { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_VOMIT, $str $($($rest)*)*) } + } + + #[macro_export] + macro_rules! log_error { + ( $str:literal $($rest:tt)* ) => { + print_error!(concat!("\x1b[31;1merror:\x1b[0m ", $str), $($rest)*) + } + } + #[macro_export] + macro_rules! log_warning { + ( $str:literal $($rest:tt)* ) => { + print_warning!(concat!("\x1b[35;1mwarning:\x1b[0m ", $str), $($rest)*) + } + } + + pub(crate) mod ffi { + pub unsafe fn set_verbosity(level: i32) { + super::VERBOSITY = level; + } + } +} + mod ffi_test; diff --git a/lix/lix-rs/src/lib.zng b/lix/lix-rs/src/lib.zng index 7f1c6a4c3..3e163f92b 100644 --- a/lix/lix-rs/src/lib.zng +++ b/lix/lix-rs/src/lib.zng @@ -28,3 +28,11 @@ mod crate::ffi { #layout_conservative(size = 16, align = 8); } } + +mod crate::log::ffi { + fn set_verbosity(i32); + + extern "C++" { + safe fn log_message(i32, &str); + } +}