uucore/macros.rs
1// This file is part of the uutils coreutils package.
2//
3// For the full copyright and license information, please view the LICENSE
4// file that was distributed with this source code.
5
6//! Macros for the uucore utilities.
7//!
8//! This module bundles all macros used across the uucore utilities. These
9//! include macros for reporting errors in various formats, aborting program
10//! execution and more.
11//!
12//! To make use of all macros in this module, they must be imported like so:
13//!
14//! ```ignore
15//! #[macro_use]
16//! extern crate uucore;
17//! ```
18//!
19//! Alternatively, you can import single macros by importing them through their
20//! fully qualified name like this:
21//!
22//! ```no_run
23//! use uucore::show;
24//! ```
25//!
26//! Here's an overview of the macros sorted by purpose
27//!
28//! - Print errors
29//! - From types implementing [`crate::error::UError`]: [`crate::show!`],
30//! [`crate::show_if_err!`]
31//! - From custom messages: [`crate::show_error!`]
32//! - Print warnings: [`crate::show_warning!`]
33
34// spell-checker:ignore sourcepath targetpath rustdoc
35
36use std::sync::atomic::AtomicBool;
37
38// This file is part of the uutils coreutils package.
39//
40// For the full copyright and license information, please view the LICENSE
41// file that was distributed with this source code.
42
43/// Whether we were called as a multicall binary (`coreutils <utility>`)
44pub static UTILITY_IS_SECOND_ARG: AtomicBool = AtomicBool::new(false);
45
46//====
47
48/// Display a [`crate::error::UError`] and set global exit code.
49///
50/// Prints the error message contained in an [`crate::error::UError`] to stderr
51/// and sets the exit code through [`crate::error::set_exit_code`]. The printed
52/// error message is prepended with the calling utility's name. A call to this
53/// macro will not finish program execution.
54///
55/// # Examples
56///
57/// The following example would print a message "Some error occurred" and set
58/// the utility's exit code to 2.
59///
60/// ```
61/// # #[macro_use]
62/// # extern crate uucore;
63///
64/// use uucore::error::{self, USimpleError};
65///
66/// fn main() {
67/// let err = USimpleError::new(2, "Some error occurred.");
68/// show!(err);
69/// assert_eq!(error::get_exit_code(), 2);
70/// }
71/// ```
72///
73/// If not using [`crate::error::UError`], one may achieve the same behavior
74/// like this:
75///
76/// ```
77/// # #[macro_use]
78/// # extern crate uucore;
79///
80/// use uucore::error::set_exit_code;
81///
82/// fn main() {
83/// set_exit_code(2);
84/// show_error!("Some error occurred.");
85/// }
86/// ```
87#[macro_export]
88macro_rules! show(
89 ($err:expr) => ({
90 #[allow(unused_imports)]
91 use $crate::error::UError;
92 let e = $err;
93 $crate::error::set_exit_code(e.code());
94 eprintln!("{}: {e}", $crate::util_name());
95 })
96);
97
98/// Display an error and set global exit code in error case.
99///
100/// Wraps around [`crate::show!`] and takes a [`crate::error::UResult`] instead of a
101/// [`crate::error::UError`] type. This macro invokes [`crate::show!`] if the
102/// [`crate::error::UResult`] is an `Err`-variant. This can be invoked directly
103/// on the result of a function call, like in the `install` utility:
104///
105/// ```ignore
106/// show_if_err!(copy(sourcepath, &targetpath, b));
107/// ```
108///
109/// # Examples
110///
111/// ```ignore
112/// # #[macro_use]
113/// # extern crate uucore;
114/// # use uucore::error::{UError, UIoError, UResult, USimpleError};
115///
116/// # fn main() {
117/// let is_ok = Ok(1);
118/// // This does nothing at all
119/// show_if_err!(is_ok);
120///
121/// let is_err = Err(USimpleError::new(1, "I'm an error").into());
122/// // Calls `show!` on the contained USimpleError
123/// show_if_err!(is_err);
124/// # }
125/// ```
126///
127///
128#[macro_export]
129macro_rules! show_if_err(
130 ($res:expr) => ({
131 if let Err(e) = $res {
132 $crate::show!(e);
133 }
134 })
135);
136
137/// Show an error to stderr in a similar style to GNU coreutils.
138///
139/// Takes a [`format!`]-like input and prints it to stderr. The output is
140/// prepended with the current utility's name.
141///
142/// # Examples
143///
144/// ```
145/// # #[macro_use]
146/// # extern crate uucore;
147/// # fn main() {
148/// show_error!("Couldn't apply {} to {}", "foo", "bar");
149/// # }
150/// ```
151#[macro_export]
152macro_rules! show_error(
153 ($($args:tt)+) => ({
154 eprint!("{}: ", $crate::util_name());
155 eprintln!($($args)+);
156 })
157);
158
159/// Print a warning message to stderr.
160///
161/// Takes [`format!`]-compatible input and prepends it with the current
162/// utility's name and "warning: " before printing to stderr.
163///
164/// # Examples
165///
166/// ```
167/// # #[macro_use]
168/// # extern crate uucore;
169/// # fn main() {
170/// // outputs <name>: warning: Couldn't apply foo to bar
171/// show_warning!("Couldn't apply {} to {}", "foo", "bar");
172/// # }
173/// ```
174#[macro_export]
175macro_rules! show_warning(
176 ($($args:tt)+) => ({
177 eprint!("{}: warning: ", $crate::util_name());
178 eprintln!($($args)+);
179 })
180);
181
182/// Print a warning message to stderr, prepending the utility name.
183#[macro_export]
184macro_rules! show_warning_caps(
185 ($($args:tt)+) => ({
186 eprint!("{}: WARNING: ", $crate::util_name());
187 eprintln!($($args)+);
188 })
189);