mirror of
https://github.com/uutils/coreutils
synced 2024-11-17 02:08:09 +00:00
nl: move from getopts to clap (#1921)
This commit is contained in:
parent
955c547adf
commit
3ca21940f8
3 changed files with 119 additions and 111 deletions
|
@ -15,8 +15,8 @@ edition = "2018"
|
|||
path = "src/nl.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
aho-corasick = "0.7.3"
|
||||
getopts = "0.2.18"
|
||||
libc = "0.2.42"
|
||||
memchr = "2.2.0"
|
||||
regex = "1.0.1"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// spell-checker:ignore (ToDO) conv
|
||||
|
||||
use crate::options;
|
||||
|
||||
// parse_style parses a style string into a NumberingStyle.
|
||||
fn parse_style(chars: &[char]) -> Result<crate::NumberingStyle, String> {
|
||||
if chars.len() == 1 && chars[0] == 'a' {
|
||||
|
@ -23,17 +25,17 @@ fn parse_style(chars: &[char]) -> Result<crate::NumberingStyle, String> {
|
|||
|
||||
// parse_options loads the options into the settings, returning an array of
|
||||
// error messages.
|
||||
pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) -> Vec<String> {
|
||||
pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> Vec<String> {
|
||||
// This vector holds error messages encountered.
|
||||
let mut errs: Vec<String> = vec![];
|
||||
settings.renumber = !opts.opt_present("p");
|
||||
match opts.opt_str("s") {
|
||||
settings.renumber = !opts.is_present(options::NO_RENUMBER);
|
||||
match opts.value_of(options::NUMER_SEPARATOR) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
settings.number_separator = val;
|
||||
settings.number_separator = val.to_owned();
|
||||
}
|
||||
}
|
||||
match opts.opt_str("n") {
|
||||
match opts.value_of(options::NUMBER_FORMAT) {
|
||||
None => {}
|
||||
Some(val) => match val.as_ref() {
|
||||
"ln" => {
|
||||
|
@ -50,7 +52,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
},
|
||||
}
|
||||
match opts.opt_str("b") {
|
||||
match opts.value_of(options::BODY_NUMBERING) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let chars: Vec<char> = val.chars().collect();
|
||||
|
@ -64,7 +66,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
match opts.opt_str("f") {
|
||||
match opts.value_of(options::FOOTER_NUMBERING) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let chars: Vec<char> = val.chars().collect();
|
||||
|
@ -78,7 +80,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
match opts.opt_str("h") {
|
||||
match opts.value_of(options::HEADER_NUMBERING) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let chars: Vec<char> = val.chars().collect();
|
||||
|
@ -92,7 +94,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
match opts.opt_str("i") {
|
||||
match opts.value_of(options::LINE_INCREMENT) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let conv: Option<u64> = val.parse().ok();
|
||||
|
@ -104,7 +106,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
match opts.opt_str("w") {
|
||||
match opts.value_of(options::NUMBER_WIDTH) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let conv: Option<usize> = val.parse().ok();
|
||||
|
@ -116,7 +118,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
match opts.opt_str("v") {
|
||||
match opts.value_of(options::STARTING_LINE_NUMER) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let conv: Option<u64> = val.parse().ok();
|
||||
|
@ -128,7 +130,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &getopts::Matches) ->
|
|||
}
|
||||
}
|
||||
}
|
||||
match opts.opt_str("l") {
|
||||
match opts.value_of(options::JOIN_BLANK_LINES) {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
let conv: Option<u64> = val.parse().ok();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Read};
|
||||
use std::iter::repeat;
|
||||
|
@ -67,78 +68,106 @@ enum NumberFormat {
|
|||
RightZero,
|
||||
}
|
||||
|
||||
pub mod options {
|
||||
pub const FILE: &str = "file";
|
||||
pub const BODY_NUMBERING: &str = "body-numbering";
|
||||
pub const SECTION_DELIMITER: &str = "section-delimiter";
|
||||
pub const FOOTER_NUMBERING: &str = "footer-numbering";
|
||||
pub const HEADER_NUMBERING: &str = "header-numbering";
|
||||
pub const LINE_INCREMENT: &str = "line-increment";
|
||||
pub const JOIN_BLANK_LINES: &str = "join-blank-lines";
|
||||
pub const NUMBER_FORMAT: &str = "number-format";
|
||||
pub const NO_RENUMBER: &str = "no-renumber";
|
||||
pub const NUMER_SEPARATOR: &str = "number-separator";
|
||||
pub const STARTING_LINE_NUMER: &str = "starting-line-number";
|
||||
pub const NUMBER_WIDTH: &str = "number-width";
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let args = args.collect_str();
|
||||
|
||||
let mut opts = getopts::Options::new();
|
||||
|
||||
opts.optopt(
|
||||
"b",
|
||||
"body-numbering",
|
||||
"use STYLE for numbering body lines",
|
||||
"STYLE",
|
||||
);
|
||||
opts.optopt(
|
||||
"d",
|
||||
"section-delimiter",
|
||||
"use CC for separating logical pages",
|
||||
"CC",
|
||||
);
|
||||
opts.optopt(
|
||||
"f",
|
||||
"footer-numbering",
|
||||
"use STYLE for numbering footer lines",
|
||||
"STYLE",
|
||||
);
|
||||
opts.optopt(
|
||||
"h",
|
||||
"header-numbering",
|
||||
"use STYLE for numbering header lines",
|
||||
"STYLE",
|
||||
);
|
||||
opts.optopt(
|
||||
"i",
|
||||
"line-increment",
|
||||
"line number increment at each line",
|
||||
"",
|
||||
);
|
||||
opts.optopt(
|
||||
"l",
|
||||
"join-blank-lines",
|
||||
"group of NUMBER empty lines counted as one",
|
||||
"NUMBER",
|
||||
);
|
||||
opts.optopt(
|
||||
"n",
|
||||
"number-format",
|
||||
"insert line numbers according to FORMAT",
|
||||
"FORMAT",
|
||||
);
|
||||
opts.optflag(
|
||||
"p",
|
||||
"no-renumber",
|
||||
"do not reset line numbers at logical pages",
|
||||
);
|
||||
opts.optopt(
|
||||
"s",
|
||||
"number-separator",
|
||||
"add STRING after (possible) line number",
|
||||
"STRING",
|
||||
);
|
||||
opts.optopt(
|
||||
"v",
|
||||
"starting-line-number",
|
||||
"first line number on each logical page",
|
||||
"NUMBER",
|
||||
);
|
||||
opts.optopt(
|
||||
"w",
|
||||
"number-width",
|
||||
"use NUMBER columns for line numbers",
|
||||
"NUMBER",
|
||||
);
|
||||
opts.optflag("", "help", "display this help and exit");
|
||||
opts.optflag("V", "version", "version");
|
||||
let matches = App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(VERSION)
|
||||
.usage(USAGE)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
.arg(
|
||||
Arg::with_name(options::BODY_NUMBERING)
|
||||
.short("b")
|
||||
.long(options::BODY_NUMBERING)
|
||||
.help("use STYLE for numbering body lines")
|
||||
.value_name("SYNTAX"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SECTION_DELIMITER)
|
||||
.short("d")
|
||||
.long(options::SECTION_DELIMITER)
|
||||
.help("use CC for separating logical pages")
|
||||
.value_name("CC"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FOOTER_NUMBERING)
|
||||
.short("f")
|
||||
.long(options::FOOTER_NUMBERING)
|
||||
.help("use STYLE for numbering footer lines")
|
||||
.value_name("STYLE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::HEADER_NUMBERING)
|
||||
.short("h")
|
||||
.long(options::HEADER_NUMBERING)
|
||||
.help("use STYLE for numbering header lines")
|
||||
.value_name("STYLE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::LINE_INCREMENT)
|
||||
.short("i")
|
||||
.long(options::LINE_INCREMENT)
|
||||
.help("line number increment at each line")
|
||||
.value_name("NUMBER"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::JOIN_BLANK_LINES)
|
||||
.short("l")
|
||||
.long(options::JOIN_BLANK_LINES)
|
||||
.help("group of NUMBER empty lines counted as one")
|
||||
.value_name("NUMBER"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NUMBER_FORMAT)
|
||||
.short("n")
|
||||
.long(options::NUMBER_FORMAT)
|
||||
.help("insert line numbers according to FORMAT")
|
||||
.value_name("FORMAT"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_RENUMBER)
|
||||
.short("p")
|
||||
.long(options::NO_RENUMBER)
|
||||
.help("do not reset line numbers at logical pages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NUMER_SEPARATOR)
|
||||
.short("s")
|
||||
.long(options::NUMER_SEPARATOR)
|
||||
.help("add STRING after (possible) line number")
|
||||
.value_name("STRING"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::STARTING_LINE_NUMER)
|
||||
.short("v")
|
||||
.long(options::STARTING_LINE_NUMER)
|
||||
.help("first line number on each logical page")
|
||||
.value_name("NUMBER"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NUMBER_WIDTH)
|
||||
.short("w")
|
||||
.long(options::NUMBER_WIDTH)
|
||||
.help("use NUMBER columns for line numbers")
|
||||
.value_name("NUMBER"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
// A mutable settings object, initialized with the defaults.
|
||||
let mut settings = Settings {
|
||||
|
@ -155,27 +184,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
number_separator: String::from("\t"),
|
||||
};
|
||||
|
||||
let given_options = match opts.parse(&args[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
show_error!("{}", f);
|
||||
print_usage(&opts);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
if given_options.opt_present("help") {
|
||||
print_usage(&opts);
|
||||
return 0;
|
||||
}
|
||||
if given_options.opt_present("version") {
|
||||
version();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update the settings from the command line options, and terminate the
|
||||
// program if some options could not successfully be parsed.
|
||||
let parse_errors = helper::parse_options(&mut settings, &given_options);
|
||||
let parse_errors = helper::parse_options(&mut settings, &matches);
|
||||
if !parse_errors.is_empty() {
|
||||
show_error!("Invalid arguments supplied.");
|
||||
for message in &parse_errors {
|
||||
|
@ -184,8 +195,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
return 1;
|
||||
}
|
||||
|
||||
let files = given_options.free;
|
||||
let mut read_stdin = files.is_empty();
|
||||
let mut read_stdin = false;
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
for file in &files {
|
||||
if file == "-" {
|
||||
|
@ -370,11 +384,3 @@ fn pass_none(_: &str, _: ®ex::Regex) -> bool {
|
|||
fn pass_all(_: &str, _: ®ex::Regex) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn print_usage(opts: &getopts::Options) {
|
||||
println!("{}", opts.usage(USAGE));
|
||||
}
|
||||
|
||||
fn version() {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue