mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
Fix spelling, update comments, and add documentation for improved code clarity
fixes #5066
This commit is contained in:
parent
33a04bed2f
commit
fb48e7d280
23 changed files with 173 additions and 59 deletions
4
src/uu/env/src/split_iterator.rs
vendored
4
src/uu/env/src/split_iterator.rs
vendored
|
@ -370,6 +370,6 @@ impl<'a> SplitIterator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split(s: &NativeIntStr) -> Result<Vec<NativeIntString>, ParseError> {
|
pub fn split(s: &NativeIntStr) -> Result<Vec<NativeIntString>, ParseError> {
|
||||||
let splitted_args = SplitIterator::new(s).split()?;
|
let split_args = SplitIterator::new(s).split()?;
|
||||||
Ok(splitted_args)
|
Ok(split_args)
|
||||||
}
|
}
|
||||||
|
|
4
src/uu/env/src/string_parser.rs
vendored
4
src/uu/env/src/string_parser.rs
vendored
|
@ -3,7 +3,7 @@
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
//
|
//
|
||||||
// spell-checker:ignore (words) splitted FFFD
|
// spell-checker:ignore (words) FFFD
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
use std::{borrow::Cow, ffi::OsStr};
|
use std::{borrow::Cow, ffi::OsStr};
|
||||||
|
@ -27,7 +27,7 @@ pub enum ErrorType {
|
||||||
|
|
||||||
/// Provides a valid char or a invalid sequence of bytes.
|
/// Provides a valid char or a invalid sequence of bytes.
|
||||||
///
|
///
|
||||||
/// Invalid byte sequences can't be splitted in any meaningful way.
|
/// Invalid byte sequences can't be split in any meaningful way.
|
||||||
/// Thus, they need to be consumed as one piece.
|
/// Thus, they need to be consumed as one piece.
|
||||||
pub enum Chunk<'a> {
|
pub enum Chunk<'a> {
|
||||||
InvalidEncoding(&'a NativeIntStr),
|
InvalidEncoding(&'a NativeIntStr),
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
// cSpell:disable
|
// cSpell:disable
|
||||||
|
|
||||||
|
//! Provides color handling for `ls` and other utilities.
|
||||||
|
|
||||||
/// The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
|
/// The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
|
||||||
/// slackware version of dircolors) are recognized but ignored.
|
/// slackware version of dircolors) are recognized but ignored.
|
||||||
/// Global config options can be specified before TERM or COLORTERM entries
|
/// Global config options can be specified before TERM or COLORTERM entries
|
||||||
|
@ -223,6 +225,7 @@ pub static FILE_COLORS: &[(&str, &str)] = &[
|
||||||
(".rpmsave", "00;90"),
|
(".rpmsave", "00;90"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Below are the terminal color capabilities
|
||||||
pub static FILE_ATTRIBUTE_CODES: &[(&str, &str)] = &[
|
pub static FILE_ATTRIBUTE_CODES: &[(&str, &str)] = &[
|
||||||
("normal", "no"),
|
("normal", "no"),
|
||||||
("norm", "no"),
|
("norm", "no"),
|
||||||
|
|
|
@ -7,15 +7,24 @@
|
||||||
|
|
||||||
// spell-checker:ignore powf copysign prec inity
|
// spell-checker:ignore powf copysign prec inity
|
||||||
|
|
||||||
|
/// Base for number parsing
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum Base {
|
pub enum Base {
|
||||||
|
/// Binary base
|
||||||
Binary = 2,
|
Binary = 2,
|
||||||
|
|
||||||
|
/// Octal base
|
||||||
Octal = 8,
|
Octal = 8,
|
||||||
|
|
||||||
|
/// Decimal base
|
||||||
Decimal = 10,
|
Decimal = 10,
|
||||||
|
|
||||||
|
/// Hexadecimal base
|
||||||
Hexadecimal = 16,
|
Hexadecimal = 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Base {
|
impl Base {
|
||||||
|
/// Return the digit value of a character in the given base
|
||||||
pub fn digit(&self, c: char) -> Option<u64> {
|
pub fn digit(&self, c: char) -> Option<u64> {
|
||||||
fn from_decimal(c: char) -> u64 {
|
fn from_decimal(c: char) -> u64 {
|
||||||
u64::from(c) - u64::from('0')
|
u64::from(c) - u64::from('0')
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
/// Thin pipe-related wrappers around functions from the `nix` crate.
|
|
||||||
|
//! Thin pipe-related wrappers around functions from the `nix` crate.
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
use std::io::IoSlice;
|
use std::io::IoSlice;
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
//! Set of functions for escaping names according to different quoting styles.
|
||||||
|
|
||||||
use std::char::from_digit;
|
use std::char::from_digit;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -11,25 +14,44 @@ use std::fmt;
|
||||||
const SPECIAL_SHELL_CHARS_START: &[char] = &['~', '#'];
|
const SPECIAL_SHELL_CHARS_START: &[char] = &['~', '#'];
|
||||||
const SPECIAL_SHELL_CHARS: &str = "`$&*()|[]{};\\'\"<>?! ";
|
const SPECIAL_SHELL_CHARS: &str = "`$&*()|[]{};\\'\"<>?! ";
|
||||||
|
|
||||||
|
/// The quoting style to use when escaping a name.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum QuotingStyle {
|
pub enum QuotingStyle {
|
||||||
|
/// Escape the name as a literal string.
|
||||||
Shell {
|
Shell {
|
||||||
|
/// Whether to escape characters in the name.
|
||||||
escape: bool,
|
escape: bool,
|
||||||
|
|
||||||
|
/// Whether to always quote the name.
|
||||||
always_quote: bool,
|
always_quote: bool,
|
||||||
|
|
||||||
|
/// Whether to show control characters.
|
||||||
show_control: bool,
|
show_control: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Escape the name as a C string.
|
||||||
C {
|
C {
|
||||||
|
/// The type of quotes to use.
|
||||||
quotes: Quotes,
|
quotes: Quotes,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Escape the name as a literal string.
|
||||||
Literal {
|
Literal {
|
||||||
|
/// Whether to show control characters.
|
||||||
show_control: bool,
|
show_control: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The type of quotes to use when escaping a name as a C string.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum Quotes {
|
pub enum Quotes {
|
||||||
|
/// Do not use quotes.
|
||||||
None,
|
None,
|
||||||
|
|
||||||
|
/// Use single quotes.
|
||||||
Single,
|
Single,
|
||||||
|
|
||||||
|
/// Use double quotes.
|
||||||
Double,
|
Double,
|
||||||
// TODO: Locale
|
// TODO: Locale
|
||||||
}
|
}
|
||||||
|
@ -262,6 +284,7 @@ fn shell_with_escape(name: &str, quotes: Quotes) -> (String, bool) {
|
||||||
(escaped_str, must_quote)
|
(escaped_str, must_quote)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Escape a name according to the given quoting style.
|
||||||
pub fn escape_name(name: &OsStr, style: &QuotingStyle) -> String {
|
pub fn escape_name(name: &OsStr, style: &QuotingStyle) -> String {
|
||||||
match style {
|
match style {
|
||||||
QuotingStyle::Literal { show_control } => {
|
QuotingStyle::Literal { show_control } => {
|
||||||
|
|
|
@ -5,14 +5,20 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) inval
|
// spell-checker:ignore (ToDO) inval
|
||||||
|
|
||||||
|
//! A module for handling ranges of values.
|
||||||
|
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::display::Quotable;
|
use crate::display::Quotable;
|
||||||
|
|
||||||
|
/// A range of values
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
|
/// The lower bound of the range
|
||||||
pub low: usize,
|
pub low: usize,
|
||||||
|
|
||||||
|
/// The upper bound of the range
|
||||||
pub high: usize,
|
pub high: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +78,7 @@ impl FromStr for Range {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Range {
|
impl Range {
|
||||||
|
/// Parse a list of ranges separated by commas and/or spaces
|
||||||
pub fn from_list(list: &str) -> Result<Vec<Self>, String> {
|
pub fn from_list(list: &str) -> Result<Vec<Self>, String> {
|
||||||
let mut ranges = Vec::new();
|
let mut ranges = Vec::new();
|
||||||
|
|
||||||
|
@ -106,6 +113,7 @@ impl Range {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the complement of the given ranges.
|
||||||
pub fn complement(ranges: &[Range]) -> Vec<Range> {
|
pub fn complement(ranges: &[Range]) -> Vec<Range> {
|
||||||
let mut prev_high = 0;
|
let mut prev_high = 0;
|
||||||
let mut complements = Vec::with_capacity(ranges.len() + 1);
|
let mut complements = Vec::with_capacity(ranges.len() + 1);
|
||||||
|
|
|
@ -41,11 +41,15 @@ use std::collections::VecDeque;
|
||||||
/// [`push_back`]: struct.RingBuffer.html#method.push_back
|
/// [`push_back`]: struct.RingBuffer.html#method.push_back
|
||||||
/// [`from_iter`]: struct.RingBuffer.html#method.from_iter
|
/// [`from_iter`]: struct.RingBuffer.html#method.from_iter
|
||||||
pub struct RingBuffer<T> {
|
pub struct RingBuffer<T> {
|
||||||
|
/// The data stored in the ring buffer.
|
||||||
pub data: VecDeque<T>,
|
pub data: VecDeque<T>,
|
||||||
|
|
||||||
|
/// The maximum number of elements that the ring buffer can hold.
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RingBuffer<T> {
|
impl<T> RingBuffer<T> {
|
||||||
|
/// Create a new ring buffer with a maximum size of `size`.
|
||||||
pub fn new(size: usize) -> Self {
|
pub fn new(size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data: VecDeque::new(),
|
data: VecDeque::new(),
|
||||||
|
@ -53,6 +57,7 @@ impl<T> RingBuffer<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new ring buffer from an iterator.
|
||||||
pub fn from_iter(iter: impl Iterator<Item = T>, size: usize) -> Self {
|
pub fn from_iter(iter: impl Iterator<Item = T>, size: usize) -> Self {
|
||||||
let mut ring_buffer = Self::new(size);
|
let mut ring_buffer = Self::new(size);
|
||||||
for value in iter {
|
for value in iter {
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
|
|
||||||
// spell-checker:ignore (vars/api) fcntl setrlimit setitimer rubout pollable sysconf
|
// spell-checker:ignore (vars/api) fcntl setrlimit setitimer rubout pollable sysconf
|
||||||
// spell-checker:ignore (vars/signals) ABRT ALRM CHLD SEGV SIGABRT SIGALRM SIGBUS SIGCHLD SIGCONT SIGDANGER SIGEMT SIGFPE SIGHUP SIGILL SIGINFO SIGINT SIGIO SIGIOT SIGKILL SIGMIGRATE SIGMSG SIGPIPE SIGPRE SIGPROF SIGPWR SIGQUIT SIGSEGV SIGSTOP SIGSYS SIGTALRM SIGTERM SIGTRAP SIGTSTP SIGTHR SIGTTIN SIGTTOU SIGURG SIGUSR SIGVIRT SIGVTALRM SIGWINCH SIGXCPU SIGXFSZ STKFLT PWR THR TSTP TTIN TTOU VIRT VTALRM XCPU XFSZ SIGCLD SIGPOLL SIGWAITING SIGAIOCANCEL SIGLWP SIGFREEZE SIGTHAW SIGCANCEL SIGLOST SIGXRES SIGJVM SIGRTMIN SIGRT SIGRTMAX TALRM AIOCANCEL XRES RTMIN RTMAX
|
// spell-checker:ignore (vars/signals) ABRT ALRM CHLD SEGV SIGABRT SIGALRM SIGBUS SIGCHLD SIGCONT SIGDANGER SIGEMT SIGFPE SIGHUP SIGILL SIGINFO SIGINT SIGIO SIGIOT SIGKILL SIGMIGRATE SIGMSG SIGPIPE SIGPRE SIGPROF SIGPWR SIGQUIT SIGSEGV SIGSTOP SIGSYS SIGTALRM SIGTERM SIGTRAP SIGTSTP SIGTHR SIGTTIN SIGTTOU SIGURG SIGUSR SIGVIRT SIGVTALRM SIGWINCH SIGXCPU SIGXFSZ STKFLT PWR THR TSTP TTIN TTOU VIRT VTALRM XCPU XFSZ SIGCLD SIGPOLL SIGWAITING SIGAIOCANCEL SIGLWP SIGFREEZE SIGTHAW SIGCANCEL SIGLOST SIGXRES SIGJVM SIGRTMIN SIGRT SIGRTMAX TALRM AIOCANCEL XRES RTMIN RTMAX
|
||||||
|
|
||||||
|
//! This module provides a way to handle signals in a platform-independent way.
|
||||||
|
//! It provides a way to convert signal names to their corresponding values and vice versa.
|
||||||
|
//! It also provides a way to ignore the SIGINT signal and enable pipe errors.
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -12,6 +17,7 @@ use nix::sys::signal::{
|
||||||
signal, SigHandler::SigDfl, SigHandler::SigIgn, Signal::SIGINT, Signal::SIGPIPE,
|
signal, SigHandler::SigDfl, SigHandler::SigIgn, Signal::SIGINT, Signal::SIGPIPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The default signal value.
|
||||||
pub static DEFAULT_SIGNAL: usize = 15;
|
pub static DEFAULT_SIGNAL: usize = 15;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -27,6 +33,7 @@ Linux Programmer's Manual
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// The list of all signals.
|
||||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
|
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
|
||||||
pub static ALL_SIGNALS: [&str; 32] = [
|
pub static ALL_SIGNALS: [&str; 32] = [
|
||||||
"EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV",
|
"EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV",
|
||||||
|
@ -339,6 +346,7 @@ pub static ALL_SIGNALS: [&str; 37] = [
|
||||||
"VIRT", "TALRM",
|
"VIRT", "TALRM",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Returns the signal number for a given signal name or value.
|
||||||
pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<usize> {
|
pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<usize> {
|
||||||
if let Ok(value) = signal_name_or_value.parse() {
|
if let Ok(value) = signal_name_or_value.parse() {
|
||||||
if is_signal(value) {
|
if is_signal(value) {
|
||||||
|
@ -352,20 +360,25 @@ pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<usize> {
|
||||||
ALL_SIGNALS.iter().position(|&s| s == signal_name)
|
ALL_SIGNALS.iter().position(|&s| s == signal_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the given number is a valid signal number.
|
||||||
pub fn is_signal(num: usize) -> bool {
|
pub fn is_signal(num: usize) -> bool {
|
||||||
num < ALL_SIGNALS.len()
|
num < ALL_SIGNALS.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the signal name for a given signal value.
|
||||||
pub fn signal_name_by_value(signal_value: usize) -> Option<&'static str> {
|
pub fn signal_name_by_value(signal_value: usize) -> Option<&'static str> {
|
||||||
ALL_SIGNALS.get(signal_value).copied()
|
ALL_SIGNALS.get(signal_value).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the default signal value.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn enable_pipe_errors() -> Result<(), Errno> {
|
pub fn enable_pipe_errors() -> Result<(), Errno> {
|
||||||
// We pass the error as is, the return value would just be Ok(SigDfl), so we can safely ignore it.
|
// We pass the error as is, the return value would just be Ok(SigDfl), so we can safely ignore it.
|
||||||
// SAFETY: this function is safe as long as we do not use a custom SigHandler -- we use the default one.
|
// SAFETY: this function is safe as long as we do not use a custom SigHandler -- we use the default one.
|
||||||
unsafe { signal(SIGPIPE, SigDfl) }.map(|_| ())
|
unsafe { signal(SIGPIPE, SigDfl) }.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ignores the SIGINT signal.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn ignore_interrupts() -> Result<(), Errno> {
|
pub fn ignore_interrupts() -> Result<(), Errno> {
|
||||||
// We pass the error as is, the return value would just be Ok(SigIgn), so we can safely ignore it.
|
// We pass the error as is, the return value would just be Ok(SigIgn), so we can safely ignore it.
|
||||||
|
|
|
@ -48,26 +48,30 @@
|
||||||
//! ```
|
//! ```
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
|
|
||||||
// Available update mode
|
/// Available update mode
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum UpdateMode {
|
pub enum UpdateMode {
|
||||||
// --update=`all`, ``
|
/// --update=`all`, ``
|
||||||
ReplaceAll,
|
ReplaceAll,
|
||||||
// --update=`none`
|
/// --update=`none`
|
||||||
ReplaceNone,
|
ReplaceNone,
|
||||||
// --update=`older`
|
|
||||||
// -u
|
/// --update=`older`
|
||||||
|
/// -u
|
||||||
ReplaceIfOlder,
|
ReplaceIfOlder,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod arguments {
|
pub mod arguments {
|
||||||
|
//! Pre-defined arguments for update functionality.
|
||||||
use crate::shortcut_value_parser::ShortcutValueParser;
|
use crate::shortcut_value_parser::ShortcutValueParser;
|
||||||
use clap::ArgAction;
|
use clap::ArgAction;
|
||||||
|
|
||||||
|
/// `--update` argument
|
||||||
pub static OPT_UPDATE: &str = "update";
|
pub static OPT_UPDATE: &str = "update";
|
||||||
|
/// `-u` argument
|
||||||
pub static OPT_UPDATE_NO_ARG: &str = "u";
|
pub static OPT_UPDATE_NO_ARG: &str = "u";
|
||||||
|
|
||||||
// `--update` argument, defaults to `older` if no values are provided
|
/// `--update` argument, defaults to `older` if no values are provided
|
||||||
pub fn update() -> clap::Arg {
|
pub fn update() -> clap::Arg {
|
||||||
clap::Arg::new(OPT_UPDATE)
|
clap::Arg::new(OPT_UPDATE)
|
||||||
.long("update")
|
.long("update")
|
||||||
|
@ -80,7 +84,7 @@ pub mod arguments {
|
||||||
.action(clap::ArgAction::Set)
|
.action(clap::ArgAction::Set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// `-u` argument
|
/// `-u` argument
|
||||||
pub fn update_no_args() -> clap::Arg {
|
pub fn update_no_args() -> clap::Arg {
|
||||||
clap::Arg::new(OPT_UPDATE_NO_ARG)
|
clap::Arg::new(OPT_UPDATE_NO_ARG)
|
||||||
.short('u')
|
.short('u')
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
//! Compare two version strings.
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
/// Compares the non-digit parts of a version.
|
/// Compares the non-digit parts of a version.
|
||||||
|
@ -58,6 +61,7 @@ fn remove_file_ending(a: &str) -> &str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compare two version strings.
|
||||||
pub fn version_cmp(mut a: &str, mut b: &str) -> Ordering {
|
pub fn version_cmp(mut a: &str, mut b: &str) -> Ordering {
|
||||||
let str_cmp = a.cmp(b);
|
let str_cmp = a.cmp(b);
|
||||||
if str_cmp == Ordering::Equal {
|
if str_cmp == Ordering::Equal {
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
// library ~ (core/bundler file)
|
//! library ~ (core/bundler file)
|
||||||
|
// #![deny(missing_docs)] //TODO: enable this
|
||||||
|
|
||||||
// * feature-gated external crates (re-shared as public internal modules)
|
// * feature-gated external crates (re-shared as public internal modules)
|
||||||
#[cfg(feature = "libc")]
|
#[cfg(feature = "libc")]
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
// TODO fix broken links
|
|
||||||
#![allow(rustdoc::broken_intra_doc_links)]
|
|
||||||
//! Macros for the uucore utilities.
|
//! Macros for the uucore utilities.
|
||||||
//!
|
//!
|
||||||
//! This module bundles all macros used across the uucore utilities. These
|
//! This module bundles all macros used across the uucore utilities. These
|
||||||
|
@ -183,6 +181,7 @@ macro_rules! show_warning(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Print a warning message to stderr, prepending the utility name.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! show_warning_caps(
|
macro_rules! show_warning_caps(
|
||||||
($($args:tt)+) => ({
|
($($args:tt)+) => ({
|
||||||
|
|
|
@ -2,27 +2,28 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
/// Utilities for printing paths, with special attention paid to special
|
//! Utilities for printing paths, with special attention paid to special
|
||||||
/// characters and invalid unicode.
|
//! characters and invalid unicode.
|
||||||
///
|
//!
|
||||||
/// For displaying paths in informational messages use `Quotable::quote`. This
|
//! For displaying paths in informational messages use `Quotable::quote`. This
|
||||||
/// will wrap quotes around the filename and add the necessary escapes to make
|
//! will wrap quotes around the filename and add the necessary escapes to make
|
||||||
/// it copy/paste-able into a shell.
|
//! it copy/paste-able into a shell.
|
||||||
///
|
//!
|
||||||
/// For writing raw paths to stdout when the output should not be quoted or escaped,
|
//! For writing raw paths to stdout when the output should not be quoted or escaped,
|
||||||
/// use `println_verbatim`. This will preserve invalid unicode.
|
//! use `println_verbatim`. This will preserve invalid unicode.
|
||||||
///
|
//!
|
||||||
/// # Examples
|
//! # Examples
|
||||||
/// ```
|
//! ```rust
|
||||||
/// use std::path::Path;
|
//! use std::path::Path;
|
||||||
/// use uucore::display::{Quotable, println_verbatim};
|
//! use uucore::display::{Quotable, println_verbatim};
|
||||||
///
|
//!
|
||||||
/// let path = Path::new("foo/bar.baz");
|
//! let path = Path::new("foo/bar.baz");
|
||||||
///
|
//!
|
||||||
/// println!("Found file {}", path.quote()); // Prints "Found file 'foo/bar.baz'"
|
//! println!("Found file {}", path.quote()); // Prints "Found file 'foo/bar.baz'"
|
||||||
/// println_verbatim(path)?; // Prints "foo/bar.baz"
|
//! println_verbatim(path)?; // Prints "foo/bar.baz"
|
||||||
/// # Ok::<(), std::io::Error>(())
|
//! # Ok::<(), std::io::Error>(())
|
||||||
/// ```
|
//! ```
|
||||||
|
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::io::{self, Write as IoWrite};
|
use std::io::{self, Write as IoWrite};
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
// TODO fix broken links
|
|
||||||
#![allow(rustdoc::broken_intra_doc_links)]
|
|
||||||
//! All utils return exit with an exit code. Usually, the following scheme is used:
|
//! All utils return exit with an exit code. Usually, the following scheme is used:
|
||||||
//! * `0`: succeeded
|
//! * `0`: succeeded
|
||||||
//! * `1`: minor problems
|
//! * `1`: minor problems
|
||||||
|
@ -287,11 +285,15 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct USimpleError {
|
pub struct USimpleError {
|
||||||
|
/// Exit code of the error.
|
||||||
pub code: i32,
|
pub code: i32,
|
||||||
|
|
||||||
|
/// Error message.
|
||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl USimpleError {
|
impl USimpleError {
|
||||||
|
/// Create a new `USimpleError` with a given exit code and message.
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
pub fn new<S: Into<String>>(code: i32, message: S) -> Box<dyn UError> {
|
pub fn new<S: Into<String>>(code: i32, message: S) -> Box<dyn UError> {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
|
@ -315,14 +317,19 @@ impl UError for USimpleError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper type around [`std::io::Error`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UUsageError {
|
pub struct UUsageError {
|
||||||
|
/// Exit code of the error.
|
||||||
pub code: i32,
|
pub code: i32,
|
||||||
|
|
||||||
|
/// Error message.
|
||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UUsageError {
|
impl UUsageError {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
|
/// Create a new `UUsageError` with a given exit code and message.
|
||||||
pub fn new<S: Into<String>>(code: i32, message: S) -> Box<dyn UError> {
|
pub fn new<S: Into<String>>(code: i32, message: S) -> Box<dyn UError> {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
code,
|
code,
|
||||||
|
@ -383,6 +390,7 @@ pub struct UIoError {
|
||||||
|
|
||||||
impl UIoError {
|
impl UIoError {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
|
/// Create a new `UIoError` with a given exit code and message.
|
||||||
pub fn new<S: Into<String>>(kind: std::io::ErrorKind, context: S) -> Box<dyn UError> {
|
pub fn new<S: Into<String>>(kind: std::io::ErrorKind, context: S) -> Box<dyn UError> {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
context: Some(context.into()),
|
context: Some(context.into()),
|
||||||
|
@ -459,6 +467,7 @@ pub fn strip_errno(err: &std::io::Error) -> String {
|
||||||
/// Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to
|
/// Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to
|
||||||
/// [`UResult`].
|
/// [`UResult`].
|
||||||
pub trait FromIo<T> {
|
pub trait FromIo<T> {
|
||||||
|
/// Map the error context of an [`std::io::Error`] or [`std::io::Result`] to a custom error
|
||||||
fn map_err_context(self, context: impl FnOnce() -> String) -> T;
|
fn map_err_context(self, context: impl FnOnce() -> String) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,6 +651,7 @@ pub struct ExitCode(pub i32);
|
||||||
|
|
||||||
impl ExitCode {
|
impl ExitCode {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
|
/// Create a new `ExitCode` with a given exit code.
|
||||||
pub fn new(code: i32) -> Box<dyn UError> {
|
pub fn new(code: i32) -> Box<dyn UError> {
|
||||||
Box::new(Self(code))
|
Box::new(Self(code))
|
||||||
}
|
}
|
||||||
|
@ -694,6 +704,7 @@ pub struct ClapErrorWrapper {
|
||||||
|
|
||||||
/// Extension trait for `clap::Error` to adjust the exit code.
|
/// Extension trait for `clap::Error` to adjust the exit code.
|
||||||
pub trait UClapError<T> {
|
pub trait UClapError<T> {
|
||||||
|
/// Set the exit code for the program if `uumain` returns `Ok(())`.
|
||||||
fn with_exit_code(self, code: i32) -> T;
|
fn with_exit_code(self, code: i32) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
/// Encapsulates differences between OSs regarding the access to
|
//! Encapsulates differences between OSs regarding the access to
|
||||||
/// file handles / descriptors.
|
//! file handles / descriptors.
|
||||||
/// This is useful when dealing with lower level stdin/stdout access.
|
//! This is useful when dealing with lower level stdin/stdout access.
|
||||||
///
|
//!
|
||||||
/// In detail:
|
//! In detail:
|
||||||
/// On unix like OSs, file _descriptors_ are used in this context.
|
//! On unix like OSs, file _descriptors_ are used in this context.
|
||||||
/// On windows OSs, file _handles_ are used.
|
//! On windows OSs, file _handles_ are used.
|
||||||
///
|
//!
|
||||||
/// Even though they are distinct classes, they share common functionality.
|
//! Even though they are distinct classes, they share common functionality.
|
||||||
/// Access to this common functionality is provided in `OwnedFileDescriptorOrHandle`.
|
//! Access to this common functionality is provided in `OwnedFileDescriptorOrHandle`.
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use std::os::fd::{AsFd, OwnedFd};
|
use std::os::fd::{AsFd, OwnedFd};
|
||||||
|
|
|
@ -19,7 +19,10 @@ use std::fmt::Display;
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
pub enum LineEnding {
|
pub enum LineEnding {
|
||||||
#[default]
|
#[default]
|
||||||
|
/// Newline character (`\n`)
|
||||||
Newline = b'\n',
|
Newline = b'\n',
|
||||||
|
|
||||||
|
/// Null character (`\0`)
|
||||||
Nul = 0,
|
Nul = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
/// Test if the program is running under WSL
|
|
||||||
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
|
||||||
|
|
||||||
// spell-checker:ignore (path) osrelease
|
// spell-checker:ignore (path) osrelease
|
||||||
|
|
||||||
|
//! Test if the program is running under WSL
|
||||||
|
//! ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
||||||
|
|
||||||
|
/// Test if the program is running under WSL version 1
|
||||||
pub fn is_wsl_1() -> bool {
|
pub fn is_wsl_1() -> bool {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
|
@ -23,6 +24,7 @@ pub fn is_wsl_1() -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test if the program is running under WSL version 2
|
||||||
pub fn is_wsl_2() -> bool {
|
pub fn is_wsl_2() -> bool {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,10 +10,7 @@
|
||||||
//! and has value that can be parsed.
|
//! and has value that can be parsed.
|
||||||
//! Otherwise returns None, so the calling utility would assume default behavior.
|
//! Otherwise returns None, so the calling utility would assume default behavior.
|
||||||
//!
|
//!
|
||||||
//! NOTE: GNU (as of v9.4) recognizes three distinct values for POSIX version:
|
//! NOTE: GNU (as of v9.4) recognizes three distinct values for POSIX version
|
||||||
//! '199209' for POSIX 1003.2-1992, which would define Obsolete mode
|
|
||||||
//! '200112' for POSIX 1003.1-2001, which is the minimum version for Traditional mode
|
|
||||||
//! '200809' for POSIX 1003.1-2008, which is the minimum version for Modern mode
|
|
||||||
//!
|
//!
|
||||||
//! Utilities that rely on this module:
|
//! Utilities that rely on this module:
|
||||||
//! `sort` (TBD)
|
//! `sort` (TBD)
|
||||||
|
@ -23,10 +20,16 @@
|
||||||
//!
|
//!
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
/// '199209' for POSIX 1003.2-1992, which would define Obsolete mode
|
||||||
pub const OBSOLETE: usize = 199209;
|
pub const OBSOLETE: usize = 199209;
|
||||||
|
|
||||||
|
/// '200112' for POSIX 1003.1-2001, which is the minimum version for Traditional mode
|
||||||
pub const TRADITIONAL: usize = 200112;
|
pub const TRADITIONAL: usize = 200112;
|
||||||
|
|
||||||
|
/// '200809' for POSIX 1003.1-2008, which is the minimum version for Modern mode
|
||||||
pub const MODERN: usize = 200809;
|
pub const MODERN: usize = 200809;
|
||||||
|
|
||||||
|
/// Returns the value of the `_POSIX2_VERSION` environment variable if it is defined
|
||||||
pub fn posix_version() -> Option<usize> {
|
pub fn posix_version() -> Option<usize> {
|
||||||
env::var("_POSIX2_VERSION")
|
env::var("_POSIX2_VERSION")
|
||||||
.ok()
|
.ok()
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) hdsf ghead gtail ACDBK hexdigit
|
// spell-checker:ignore (ToDO) hdsf ghead gtail ACDBK hexdigit
|
||||||
|
|
||||||
|
//! Parser for sizes in SI or IEC units (multiples of 1000 or 1024 bytes).
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::IntErrorKind;
|
use std::num::IntErrorKind;
|
||||||
|
@ -35,21 +36,25 @@ enum NumberSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'parser> Parser<'parser> {
|
impl<'parser> Parser<'parser> {
|
||||||
|
/// Change allow_list of the parser - whitelist for the suffix
|
||||||
pub fn with_allow_list(&mut self, allow_list: &'parser [&str]) -> &mut Self {
|
pub fn with_allow_list(&mut self, allow_list: &'parser [&str]) -> &mut Self {
|
||||||
self.allow_list = Some(allow_list);
|
self.allow_list = Some(allow_list);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change default_unit of the parser - when no suffix is provided
|
||||||
pub fn with_default_unit(&mut self, default_unit: &'parser str) -> &mut Self {
|
pub fn with_default_unit(&mut self, default_unit: &'parser str) -> &mut Self {
|
||||||
self.default_unit = Some(default_unit);
|
self.default_unit = Some(default_unit);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change b_byte_count of the parser - to treat "b" as a "byte count" instead of "block"
|
||||||
pub fn with_b_byte_count(&mut self, value: bool) -> &mut Self {
|
pub fn with_b_byte_count(&mut self, value: bool) -> &mut Self {
|
||||||
self.b_byte_count = value;
|
self.b_byte_count = value;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change no_empty_numeric of the parser - to allow empty numeric strings
|
||||||
pub fn with_allow_empty_numeric(&mut self, value: bool) -> &mut Self {
|
pub fn with_allow_empty_numeric(&mut self, value: bool) -> &mut Self {
|
||||||
self.no_empty_numeric = value;
|
self.no_empty_numeric = value;
|
||||||
self
|
self
|
||||||
|
@ -293,6 +298,7 @@ pub fn parse_size_u64(size: &str) -> Result<u64, ParseSizeError> {
|
||||||
Parser::default().parse_u64(size)
|
Parser::default().parse_u64(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as `parse_size_u64()` - deprecated
|
||||||
#[deprecated = "Please use parse_size_u64(size: &str) -> Result<u64, ParseSizeError> OR parse_size_u128(size: &str) -> Result<u128, ParseSizeError> instead."]
|
#[deprecated = "Please use parse_size_u64(size: &str) -> Result<u64, ParseSizeError> OR parse_size_u128(size: &str) -> Result<u128, ParseSizeError> instead."]
|
||||||
pub fn parse_size(size: &str) -> Result<u64, ParseSizeError> {
|
pub fn parse_size(size: &str) -> Result<u64, ParseSizeError> {
|
||||||
parse_size_u64(size)
|
parse_size_u64(size)
|
||||||
|
@ -310,11 +316,17 @@ pub fn parse_size_u128_max(size: &str) -> Result<u128, ParseSizeError> {
|
||||||
Parser::default().parse_u128_max(size)
|
Parser::default().parse_u128_max(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error type for parse_size
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ParseSizeError {
|
pub enum ParseSizeError {
|
||||||
InvalidSuffix(String), // Suffix
|
/// Suffix
|
||||||
ParseFailure(String), // Syntax
|
InvalidSuffix(String),
|
||||||
SizeTooBig(String), // Overflow
|
|
||||||
|
/// Syntax
|
||||||
|
ParseFailure(String),
|
||||||
|
|
||||||
|
/// Overflow
|
||||||
|
SizeTooBig(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ParseSizeError {
|
impl Error for ParseSizeError {
|
||||||
|
|
|
@ -3,11 +3,16 @@
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
// spell-checker:ignore abcdefgh abef
|
// spell-checker:ignore abcdefgh abef
|
||||||
|
|
||||||
|
//! A parser that accepts shortcuts for values.
|
||||||
|
//! `ShortcutValueParser` is similar to clap's `PossibleValuesParser`
|
||||||
|
|
||||||
use clap::{
|
use clap::{
|
||||||
builder::{PossibleValue, TypedValueParser},
|
builder::{PossibleValue, TypedValueParser},
|
||||||
error::{ContextKind, ContextValue, ErrorKind},
|
error::{ContextKind, ContextValue, ErrorKind},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A parser that accepts shortcuts for values.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ShortcutValueParser(Vec<PossibleValue>);
|
pub struct ShortcutValueParser(Vec<PossibleValue>);
|
||||||
|
|
||||||
|
@ -17,6 +22,7 @@ pub struct ShortcutValueParser(Vec<PossibleValue>);
|
||||||
/// Whereas `PossibleValuesParser` only accepts exact matches, `ShortcutValueParser` also accepts
|
/// Whereas `PossibleValuesParser` only accepts exact matches, `ShortcutValueParser` also accepts
|
||||||
/// shortcuts as long as they are unambiguous.
|
/// shortcuts as long as they are unambiguous.
|
||||||
impl ShortcutValueParser {
|
impl ShortcutValueParser {
|
||||||
|
/// Create a new `ShortcutValueParser` from a list of `PossibleValue`.
|
||||||
pub fn new(values: impl Into<Self>) -> Self {
|
pub fn new(values: impl Into<Self>) -> Self {
|
||||||
values.into()
|
values.into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
//
|
//
|
||||||
// spell-checker:ignore backticks uuhelp
|
// spell-checker:ignore backticks uuhelp
|
||||||
|
|
||||||
|
//! A collection of procedural macros for uutils.
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use std::{fs::File, io::Read, path::PathBuf};
|
use std::{fs::File, io::Read, path::PathBuf};
|
||||||
|
|
||||||
use proc_macro::{Literal, TokenStream, TokenTree};
|
use proc_macro::{Literal, TokenStream, TokenTree};
|
||||||
|
@ -14,6 +17,7 @@ use quote::quote;
|
||||||
//* ref: <https://dev.to/naufraghi/procedural-macro-in-rust-101-k3f> @@ <http://archive.is/Vbr5e>
|
//* 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>
|
//* ref: [path construction from LitStr](https://oschwald.github.io/maxminddb-rust/syn/struct.LitStr.html) @@ <http://archive.is/8YDua>
|
||||||
|
|
||||||
|
/// A procedural macro to define the main function of a uutils binary.
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {
|
pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {
|
||||||
let stream = proc_macro2::TokenStream::from(stream);
|
let stream = proc_macro2::TokenStream::from(stream);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
//! A collection of functions to parse the markdown code of help files.
|
//! A collection of functions to parse the markdown code of help files.
|
||||||
//!
|
//!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue