mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
parent
acb57ecbd0
commit
ab5b6dd844
3 changed files with 62 additions and 47 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -1325,9 +1325,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.65"
|
||||
version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
|
||||
checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
|
@ -2334,8 +2334,8 @@ name = "uu_tr"
|
|||
version = "0.0.4"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"clap",
|
||||
"fnv",
|
||||
"getopts",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
]
|
||||
|
|
|
@ -17,7 +17,7 @@ path = "src/tr.rs"
|
|||
[dependencies]
|
||||
bit-set = "0.5.0"
|
||||
fnv = "1.0.5"
|
||||
getopts = "0.2.18"
|
||||
clap = "2.33"
|
||||
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
||||
|
|
|
@ -16,16 +16,27 @@ extern crate uucore;
|
|||
mod expand;
|
||||
|
||||
use bit_set::BitSet;
|
||||
use clap::{App, Arg};
|
||||
use fnv::FnvHashMap;
|
||||
use getopts::Options;
|
||||
use std::io::{stdin, stdout, BufRead, BufWriter, Write};
|
||||
|
||||
use crate::expand::ExpandSet;
|
||||
|
||||
static NAME: &str = "tr";
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
static ABOUT: &str = "translate or delete characters";
|
||||
static LONG_HELP: &str = "Translate, squeeze, and/or delete characters from standard input,
|
||||
writing to standard output.";
|
||||
const BUFFER_LEN: usize = 1024;
|
||||
|
||||
mod options {
|
||||
pub const COMPLEMENT: &str = "complement";
|
||||
pub const DELETE: &str = "delete";
|
||||
pub const SQUEEZE: &str = "squeeze-repeats";
|
||||
pub const TRUNCATE: &str = "truncate";
|
||||
pub const SETS: &str = "sets";
|
||||
}
|
||||
|
||||
trait SymbolTranslator {
|
||||
fn translate(&self, c: char, prev_c: char) -> Option<char>;
|
||||
}
|
||||
|
@ -170,56 +181,60 @@ fn translate_input<T: SymbolTranslator>(
|
|||
}
|
||||
}
|
||||
|
||||
fn usage(opts: &Options) {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
println!();
|
||||
println!("Usage:");
|
||||
println!(" {} [OPTIONS] SET1 [SET2]", NAME);
|
||||
println!();
|
||||
println!("{}", opts.usage("Translate or delete characters."));
|
||||
fn get_usage() -> String {
|
||||
format!("{} [OPTION]... SET1 [SET2]", executable!())
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let args = args.collect_str();
|
||||
let usage = get_usage();
|
||||
|
||||
let mut opts = Options::new();
|
||||
let matches = App::new(executable!())
|
||||
.version(VERSION)
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::COMPLEMENT)
|
||||
.short("C")
|
||||
.short("c")
|
||||
.long(options::COMPLEMENT)
|
||||
.help("use the complement of SET1"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DELETE)
|
||||
.short("d")
|
||||
.long(options::DELETE)
|
||||
.help("delete characters in SET1, do not translate"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SQUEEZE)
|
||||
.long(options::SQUEEZE)
|
||||
.short("s")
|
||||
.help(
|
||||
"replace each sequence of a repeated character that is
|
||||
listed in the last specified SET, with a single occurrence
|
||||
of that character",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TRUNCATE)
|
||||
.long(options::TRUNCATE)
|
||||
.short("t")
|
||||
.help("first truncate SET1 to length of SET2"),
|
||||
)
|
||||
.arg(Arg::with_name(options::SETS).multiple(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
opts.optflag("c", "complement", "use the complement of SET1");
|
||||
opts.optflag("C", "", "same as -c");
|
||||
opts.optflag("d", "delete", "delete characters in SET1");
|
||||
opts.optflag("h", "help", "display this help and exit");
|
||||
opts.optflag("s", "squeeze", "replace each sequence of a repeated character that is listed in the last specified SET, with a single occurrence of that character");
|
||||
opts.optflag(
|
||||
"t",
|
||||
"truncate-set1",
|
||||
"first truncate SET1 to length of SET2",
|
||||
);
|
||||
opts.optflag("V", "version", "output version information and exit");
|
||||
let dflag = matches.is_present(options::DELETE);
|
||||
let cflag = matches.is_present(options::COMPLEMENT);
|
||||
let sflag = matches.is_present(options::SQUEEZE);
|
||||
let tflag = matches.is_present(options::TRUNCATE);
|
||||
|
||||
let matches = match opts.parse(&args[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(err) => {
|
||||
show_error!("{}", err);
|
||||
return 1;
|
||||
}
|
||||
let sets: Vec<String> = match matches.values_of(options::SETS) {
|
||||
Some(v) => v.map(|v| v.to_string()).collect(),
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
if matches.opt_present("help") {
|
||||
usage(&opts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if matches.opt_present("version") {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
let dflag = matches.opt_present("d");
|
||||
let cflag = matches.opts_present(&["c".to_owned(), "C".to_owned()]);
|
||||
let sflag = matches.opt_present("s");
|
||||
let tflag = matches.opt_present("t");
|
||||
let sets = matches.free;
|
||||
|
||||
if sets.is_empty() {
|
||||
show_error!(
|
||||
"missing operand\nTry `{} --help` for more information.",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue