mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-05 07:27:46 +00:00
docs/uucore_macros ~ improve commentary/documentation
This commit is contained in:
parent
c32ff9e8bb
commit
cf2fcd8dc1
1 changed files with 24 additions and 24 deletions
|
@ -1,9 +1,10 @@
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
// spell-checker:ignore () sigpipe uucore uumain
|
// spell-checker:ignore () SIGPIPE uucore uumain uutils
|
||||||
|
|
||||||
// ref: <https://dev.to/naufraghi/procedural-macro-in-rust-101-k3f> @@ <http://archive.is/Vbr5e>
|
//## rust proc-macro background info
|
||||||
// ref: [path construction from LitStr](https://oschwald.github.io/maxminddb-rust/syn/struct.LitStr.html) @@ <http://archive.is/8YDua>
|
//* ref: <https://dev.to/naufraghi/procedural-macro-in-rust-101-k3f> @@ <http://archive.is/Vbr5e>
|
||||||
|
//* ref: [path construction from LitStr](https://oschwald.github.io/maxminddb-rust/syn/struct.LitStr.html) @@ <http://archive.is/8YDua>
|
||||||
|
|
||||||
struct Tokens {
|
struct Tokens {
|
||||||
expr: syn::Expr,
|
expr: syn::Expr,
|
||||||
|
@ -17,14 +18,17 @@ impl syn::parse::Parse for Tokens {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// main!( EXPR )
|
||||||
|
// generates a `main()` function for utilities within the uutils group
|
||||||
|
// EXPR == syn::Expr::Lit::String | syn::Expr::Path::Ident ~ EXPR contains the location of the utility `uumain()` function
|
||||||
|
//* for future use of "eager" macros and more generic use, EXPR may be in either STRING or IDENT form
|
||||||
|
//* for ease-of-use, the trailing "::uumain" is optional and will be added if needed
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn main(stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn main(stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let Tokens { expr } = syn::parse_macro_input!(stream as Tokens);
|
let Tokens { expr } = syn::parse_macro_input!(stream as Tokens);
|
||||||
// eprintln!("expr={:?}", expr);
|
// match EXPR as a string literal or an ident path, o/w panic!()
|
||||||
let expr = match expr {
|
let expr = match expr {
|
||||||
syn::Expr::Lit(expr) => {
|
syn::Expr::Lit(expr) => match expr.lit {
|
||||||
// eprintln!("found Expr::Lit => {:?}", expr);
|
|
||||||
match expr.lit {
|
|
||||||
syn::Lit::Str(ref lit) => {
|
syn::Lit::Str(ref lit) => {
|
||||||
let mut s = lit.value();
|
let mut s = lit.value();
|
||||||
if !s.ends_with("::uumain") {
|
if !s.ends_with("::uumain") {
|
||||||
|
@ -35,12 +39,8 @@ pub fn main(stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
syn::Expr::Path(expr) => {
|
syn::Expr::Path(expr) => {
|
||||||
// eprintln!("found Expr::Path => {:?}", expr);
|
|
||||||
// let i = &expr.path.segments.last().unwrap().ident;
|
|
||||||
// eprintln!("... i => {:?}", i);
|
|
||||||
if &expr.path.segments.last().unwrap().ident.to_string() != "uumain" {
|
if &expr.path.segments.last().unwrap().ident.to_string() != "uumain" {
|
||||||
syn::parse_quote!( #expr::uumain )
|
syn::parse_quote!( #expr::uumain )
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,13 +50,13 @@ pub fn main(stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
let f = quote::quote! { #expr(uucore::args().collect()) };
|
let f = quote::quote! { #expr(uucore::args().collect()) };
|
||||||
// eprintln!("f = {:?}", f);
|
// generate a uutils utility `main()` function, tailored for the calling utility
|
||||||
let result = quote::quote! {
|
let result = quote::quote! {
|
||||||
fn main() {
|
fn main() {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
uucore::panic::mute_sigpipe_panic();
|
uucore::panic::mute_sigpipe_panic(); // suppress extraneous error output for SIGPIPE failures/panics
|
||||||
let code = #f;
|
let code = #f; // execute utility code
|
||||||
std::io::stdout().flush().expect("could not flush stdout");
|
std::io::stdout().flush().expect("could not flush stdout"); // (defensively) flush stdout for utility prior to exit; see <https://github.com/rust-lang/rust/issues/23818>
|
||||||
std::process::exit(code);
|
std::process::exit(code);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue