mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 09:40:22 -07:00
core: lock stdout before printing an error message to stderr
Adds a new eprintln_locked macro which locks STDOUT before logging to STDERR. This patch also replaces instances of eprintln with eprintln_locked to avoid interleaving lines. Fixes #1941, Closes #1968
This commit is contained in:
parent
4993d29a16
commit
4782ebd5e0
@ -33,7 +33,7 @@ impl Log for Logger {
|
|||||||
fn log(&self, record: &log::Record<'_>) {
|
fn log(&self, record: &log::Record<'_>) {
|
||||||
match (record.file(), record.line()) {
|
match (record.file(), record.line()) {
|
||||||
(Some(file), Some(line)) => {
|
(Some(file), Some(line)) => {
|
||||||
eprintln!(
|
eprintln_locked!(
|
||||||
"{}|{}|{}:{}: {}",
|
"{}|{}|{}:{}: {}",
|
||||||
record.level(),
|
record.level(),
|
||||||
record.target(),
|
record.target(),
|
||||||
@ -43,7 +43,7 @@ impl Log for Logger {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
(Some(file), None) => {
|
(Some(file), None) => {
|
||||||
eprintln!(
|
eprintln_locked!(
|
||||||
"{}|{}|{}: {}",
|
"{}|{}|{}: {}",
|
||||||
record.level(),
|
record.level(),
|
||||||
record.target(),
|
record.target(),
|
||||||
@ -52,7 +52,7 @@ impl Log for Logger {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!(
|
eprintln_locked!(
|
||||||
"{}|{}: {}",
|
"{}|{}: {}",
|
||||||
record.level(),
|
record.level(),
|
||||||
record.target(),
|
record.target(),
|
||||||
@ -63,6 +63,6 @@ impl Log for Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) {
|
fn flush(&self) {
|
||||||
// We use eprintln! which is flushed on every call.
|
// We use eprintln_locked! which is flushed on every call.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ type Result<T> = ::std::result::Result<T, Box<dyn error::Error>>;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if let Err(err) = Args::parse().and_then(try_main) {
|
if let Err(err) = Args::parse().and_then(try_main) {
|
||||||
eprintln!("{}", err);
|
eprintln_locked!("{}", err);
|
||||||
process::exit(2);
|
process::exit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,28 @@ static MESSAGES: AtomicBool = AtomicBool::new(false);
|
|||||||
static IGNORE_MESSAGES: AtomicBool = AtomicBool::new(false);
|
static IGNORE_MESSAGES: AtomicBool = AtomicBool::new(false);
|
||||||
static ERRORED: AtomicBool = AtomicBool::new(false);
|
static ERRORED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
/// Like eprintln, but locks STDOUT to prevent interleaving lines.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! eprintln_locked {
|
||||||
|
($($tt:tt)*) => {{
|
||||||
|
{
|
||||||
|
// This is a bit of an abstraction violation because we explicitly
|
||||||
|
// lock STDOUT before printing to STDERR. This avoids interleaving
|
||||||
|
// lines within ripgrep because `search_parallel` uses `termcolor`,
|
||||||
|
// which accesses the same STDOUT lock when writing lines.
|
||||||
|
let stdout = std::io::stdout();
|
||||||
|
let _handle = stdout.lock();
|
||||||
|
eprintln!($($tt)*);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
/// Emit a non-fatal error message, unless messages were disabled.
|
/// Emit a non-fatal error message, unless messages were disabled.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! message {
|
macro_rules! message {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
if crate::messages::messages() {
|
if crate::messages::messages() {
|
||||||
eprintln!($($tt)*);
|
eprintln_locked!($($tt)*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +46,7 @@ macro_rules! err_message {
|
|||||||
macro_rules! ignore_message {
|
macro_rules! ignore_message {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
if crate::messages::messages() && crate::messages::ignore_messages() {
|
if crate::messages::messages() && crate::messages::ignore_messages() {
|
||||||
eprintln!($($tt)*);
|
eprintln_locked!($($tt)*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user