mirror of
https://github.com/uutils/coreutils
synced 2024-12-13 14:52:41 +00:00
starting work on stty
This commit is contained in:
parent
87e3899477
commit
600cab0bd8
7 changed files with 610 additions and 0 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -445,6 +445,7 @@ dependencies = [
|
||||||
"uu_split",
|
"uu_split",
|
||||||
"uu_stat",
|
"uu_stat",
|
||||||
"uu_stdbuf",
|
"uu_stdbuf",
|
||||||
|
"uu_stty",
|
||||||
"uu_sum",
|
"uu_sum",
|
||||||
"uu_sync",
|
"uu_sync",
|
||||||
"uu_tac",
|
"uu_tac",
|
||||||
|
@ -2908,6 +2909,15 @@ dependencies = [
|
||||||
"uucore",
|
"uucore",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uu_stty"
|
||||||
|
version = "0.0.14"
|
||||||
|
dependencies = [
|
||||||
|
"clap 3.1.18",
|
||||||
|
"nix",
|
||||||
|
"uucore",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uu_sum"
|
name = "uu_sum"
|
||||||
version = "0.0.14"
|
version = "0.0.14"
|
||||||
|
|
|
@ -190,6 +190,7 @@ feat_require_unix = [
|
||||||
"nohup",
|
"nohup",
|
||||||
"pathchk",
|
"pathchk",
|
||||||
"stat",
|
"stat",
|
||||||
|
"stty",
|
||||||
"timeout",
|
"timeout",
|
||||||
"tty",
|
"tty",
|
||||||
"uname",
|
"uname",
|
||||||
|
@ -348,6 +349,7 @@ sort = { optional=true, version="0.0.14", package="uu_sort", path="src/uu/so
|
||||||
split = { optional=true, version="0.0.14", package="uu_split", path="src/uu/split" }
|
split = { optional=true, version="0.0.14", package="uu_split", path="src/uu/split" }
|
||||||
stat = { optional=true, version="0.0.14", package="uu_stat", path="src/uu/stat" }
|
stat = { optional=true, version="0.0.14", package="uu_stat", path="src/uu/stat" }
|
||||||
stdbuf = { optional=true, version="0.0.14", package="uu_stdbuf", path="src/uu/stdbuf" }
|
stdbuf = { optional=true, version="0.0.14", package="uu_stdbuf", path="src/uu/stdbuf" }
|
||||||
|
stty = { optional=true, version="0.0.14", package="uu_stty", path="src/uu/stty" }
|
||||||
sum = { optional=true, version="0.0.14", package="uu_sum", path="src/uu/sum" }
|
sum = { optional=true, version="0.0.14", package="uu_sum", path="src/uu/sum" }
|
||||||
sync = { optional=true, version="0.0.14", package="uu_sync", path="src/uu/sync" }
|
sync = { optional=true, version="0.0.14", package="uu_sync", path="src/uu/sync" }
|
||||||
tac = { optional=true, version="0.0.14", package="uu_tac", path="src/uu/tac" }
|
tac = { optional=true, version="0.0.14", package="uu_tac", path="src/uu/tac" }
|
||||||
|
|
24
src/uu/stty/Cargo.toml
Normal file
24
src/uu/stty/Cargo.toml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[package]
|
||||||
|
name = "uu_stty"
|
||||||
|
version = "0.0.14"
|
||||||
|
authors = ["uutils developers"]
|
||||||
|
license = "MIT"
|
||||||
|
description = "stty ~ (uutils) print or change terminal characteristics"
|
||||||
|
|
||||||
|
homepage = "https://github.com/uutils/coreutils"
|
||||||
|
repository = "https://github.com/uutils/coreutils/tree/main/src/uu/stty"
|
||||||
|
keywords = ["coreutils", "uutils", "cross-platform", "cli", "utility"]
|
||||||
|
categories = ["command-line-utilities"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/stty.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
|
||||||
|
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
|
||||||
|
nix = { version="0.24.1", features = ["term"] }
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "stty"
|
||||||
|
path = "src/main.rs"
|
1
src/uu/stty/LICENSE
Symbolic link
1
src/uu/stty/LICENSE
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../LICENSE
|
332
src/uu/stty/src/flags.rs
Normal file
332
src/uu/stty/src/flags.rs
Normal file
|
@ -0,0 +1,332 @@
|
||||||
|
// * This file is part of the uutils coreutils package.
|
||||||
|
// *
|
||||||
|
// * For the full copyright and license information, please view the LICENSE file
|
||||||
|
// * that was distributed with this source code.
|
||||||
|
|
||||||
|
// spell-checker:ignore parenb parodd cmspar hupcl cstopb cread clocal crtscts
|
||||||
|
// spell-checker:ignore ignbrk brkint ignpar parmrk inpck istrip inlcr igncr icrnl ixoff ixon iuclc ixany imaxbel iutf
|
||||||
|
// spell-checker:ignore opost olcuc ocrnl onlcr onocr onlret ofill ofdel
|
||||||
|
// spell-checker:ignore isig icanon iexten echoe crterase echok echonl noflsh xcase tostop echoprt prterase echoctl ctlecho echoke crtkill flusho extproc
|
||||||
|
|
||||||
|
use crate::Flag;
|
||||||
|
use nix::sys::termios::{ControlFlags, InputFlags, LocalFlags, OutputFlags};
|
||||||
|
|
||||||
|
pub const CONTROL_FLAGS: [Flag<ControlFlags>; 8] = [
|
||||||
|
Flag {
|
||||||
|
name: "parenb",
|
||||||
|
flag: ControlFlags::PARENB,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "parodd",
|
||||||
|
flag: ControlFlags::PARODD,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "cmspar",
|
||||||
|
flag: ControlFlags::CMSPAR,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "hupcl",
|
||||||
|
flag: ControlFlags::HUPCL,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "cstopb",
|
||||||
|
flag: ControlFlags::CSTOPB,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "cread",
|
||||||
|
flag: ControlFlags::CREAD,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "clocal",
|
||||||
|
flag: ControlFlags::CLOCAL,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "crtscts",
|
||||||
|
flag: ControlFlags::CRTSCTS,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const INPUT_FLAGS: [Flag<InputFlags>; 15] = [
|
||||||
|
Flag {
|
||||||
|
name: "ignbrk",
|
||||||
|
flag: InputFlags::IGNBRK,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "brkint",
|
||||||
|
flag: InputFlags::BRKINT,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ignpar",
|
||||||
|
flag: InputFlags::IGNPAR,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "parmrk",
|
||||||
|
flag: InputFlags::PARMRK,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "inpck",
|
||||||
|
flag: InputFlags::INPCK,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "istrip",
|
||||||
|
flag: InputFlags::ISTRIP,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "inlcr",
|
||||||
|
flag: InputFlags::INLCR,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "igncr",
|
||||||
|
flag: InputFlags::IGNCR,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "icrnl",
|
||||||
|
flag: InputFlags::ICRNL,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ixoff",
|
||||||
|
flag: InputFlags::IXOFF,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "tandem",
|
||||||
|
flag: InputFlags::IXOFF,
|
||||||
|
show: false,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ixon",
|
||||||
|
flag: InputFlags::IXON,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
// not supported by nix
|
||||||
|
// Flag {
|
||||||
|
// name: "iuclc",
|
||||||
|
// flag: InputFlags::IUCLC,
|
||||||
|
// show: true,
|
||||||
|
// default: false,
|
||||||
|
// },
|
||||||
|
Flag {
|
||||||
|
name: "ixany",
|
||||||
|
flag: InputFlags::IXANY,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "imaxbel",
|
||||||
|
flag: InputFlags::IMAXBEL,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "iutf8",
|
||||||
|
flag: InputFlags::IUTF8,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const OUTPUT_FLAGS: [Flag<OutputFlags>; 8] = [
|
||||||
|
Flag {
|
||||||
|
name: "opost",
|
||||||
|
flag: OutputFlags::OPOST,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "olcuc",
|
||||||
|
flag: OutputFlags::OLCUC,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ocrnl",
|
||||||
|
flag: OutputFlags::OCRNL,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "onlcr",
|
||||||
|
flag: OutputFlags::ONLCR,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "onocr",
|
||||||
|
flag: OutputFlags::ONOCR,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "onlret",
|
||||||
|
flag: OutputFlags::ONLRET,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ofill",
|
||||||
|
flag: OutputFlags::OFILL,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ofdel",
|
||||||
|
flag: OutputFlags::OFDEL,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const LOCAL_FLAGS: [Flag<LocalFlags>; 18] = [
|
||||||
|
Flag {
|
||||||
|
name: "isig",
|
||||||
|
flag: LocalFlags::ISIG,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "icanon",
|
||||||
|
flag: LocalFlags::ICANON,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "iexten",
|
||||||
|
flag: LocalFlags::IEXTEN,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echo",
|
||||||
|
flag: LocalFlags::ECHO,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echoe",
|
||||||
|
flag: LocalFlags::ECHOE,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "crterase",
|
||||||
|
flag: LocalFlags::ECHOE,
|
||||||
|
show: false,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echok",
|
||||||
|
flag: LocalFlags::ECHOK,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echonl",
|
||||||
|
flag: LocalFlags::ECHONL,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "noflsh",
|
||||||
|
flag: LocalFlags::NOFLSH,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
// Not supported by nix
|
||||||
|
// Flag {
|
||||||
|
// name: "xcase",
|
||||||
|
// flag: LocalFlags::XCASE,
|
||||||
|
// show: true,
|
||||||
|
// sane: false,
|
||||||
|
// },
|
||||||
|
Flag {
|
||||||
|
name: "tostop",
|
||||||
|
flag: LocalFlags::TOSTOP,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echoprt",
|
||||||
|
flag: LocalFlags::ECHOPRT,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "prterase",
|
||||||
|
flag: LocalFlags::ECHOPRT,
|
||||||
|
show: false,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echoctl",
|
||||||
|
flag: LocalFlags::ECHOCTL,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "ctlecho",
|
||||||
|
flag: LocalFlags::ECHOCTL,
|
||||||
|
show: false,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "echoke",
|
||||||
|
flag: LocalFlags::ECHOKE,
|
||||||
|
show: true,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "crtkill",
|
||||||
|
flag: LocalFlags::ECHOKE,
|
||||||
|
show: false,
|
||||||
|
sane: true,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "flusho",
|
||||||
|
flag: LocalFlags::FLUSHO,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
Flag {
|
||||||
|
name: "extproc",
|
||||||
|
flag: LocalFlags::EXTPROC,
|
||||||
|
show: true,
|
||||||
|
sane: false,
|
||||||
|
},
|
||||||
|
];
|
1
src/uu/stty/src/main.rs
Normal file
1
src/uu/stty/src/main.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uucore::bin!(uu_stty);
|
240
src/uu/stty/src/stty.rs
Normal file
240
src/uu/stty/src/stty.rs
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
// * This file is part of the uutils coreutils package.
|
||||||
|
// *
|
||||||
|
// * For the full copyright and license information, please view the LICENSE file
|
||||||
|
// * that was distributed with this source code.
|
||||||
|
|
||||||
|
// spell-checker:ignore tcgetattr tcsetattr tcsanow
|
||||||
|
|
||||||
|
mod flags;
|
||||||
|
|
||||||
|
use clap::{crate_version, Arg, ArgMatches, Command};
|
||||||
|
use nix::sys::termios::{
|
||||||
|
tcgetattr, tcsetattr, ControlFlags, InputFlags, LocalFlags, OutputFlags, Termios,
|
||||||
|
};
|
||||||
|
use std::io::{self, stdout};
|
||||||
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
|
use uucore::error::UResult;
|
||||||
|
use uucore::{format_usage, InvalidEncodingHandling};
|
||||||
|
|
||||||
|
use flags::{CONTROL_FLAGS, INPUT_FLAGS, LOCAL_FLAGS, OUTPUT_FLAGS};
|
||||||
|
|
||||||
|
const NAME: &str = "stty";
|
||||||
|
const USAGE: &str = "\
|
||||||
|
{} [-F DEVICE | --file=DEVICE] [SETTING]...
|
||||||
|
{} [-F DEVICE | --file=DEVICE] [-a|--all]
|
||||||
|
{} [-F DEVICE | --file=DEVICE] [-g|--save]";
|
||||||
|
const SUMMARY: &str = "Print or change terminal characteristics.";
|
||||||
|
|
||||||
|
pub struct Flag<T> {
|
||||||
|
name: &'static str,
|
||||||
|
flag: T,
|
||||||
|
show: bool,
|
||||||
|
sane: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
trait TermiosFlag {
|
||||||
|
fn is_in(&self, termios: &Termios) -> bool;
|
||||||
|
fn apply(&self, termios: &mut Termios, val: bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod options {
|
||||||
|
pub const ALL: &str = "all";
|
||||||
|
pub const SAVE: &str = "save";
|
||||||
|
pub const FILE: &str = "file";
|
||||||
|
pub const SETTINGS: &str = "settings";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Options<'a> {
|
||||||
|
all: bool,
|
||||||
|
_save: bool,
|
||||||
|
file: RawFd,
|
||||||
|
settings: Option<Vec<&'a str>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Options<'a> {
|
||||||
|
fn from(matches: &'a ArgMatches) -> io::Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
all: matches.is_present(options::ALL),
|
||||||
|
_save: matches.is_present(options::SAVE),
|
||||||
|
file: match matches.value_of(options::FILE) {
|
||||||
|
Some(_f) => todo!(),
|
||||||
|
None => stdout().as_raw_fd(),
|
||||||
|
},
|
||||||
|
settings: matches.values_of(options::SETTINGS).map(|v| v.collect()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[uucore::main]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
let args = args
|
||||||
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
|
.accept_any();
|
||||||
|
|
||||||
|
let matches = uu_app().get_matches_from(args);
|
||||||
|
|
||||||
|
let opts = Options::from(&matches)?;
|
||||||
|
|
||||||
|
stty(&opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stty(opts: &Options) -> UResult<()> {
|
||||||
|
// TODO: Figure out the right error message
|
||||||
|
let mut termios = tcgetattr(opts.file).expect("Could not get terminal attributes");
|
||||||
|
if let Some(settings) = &opts.settings {
|
||||||
|
for setting in settings {
|
||||||
|
apply_setting(&mut termios, setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
tcsetattr(opts.file, nix::sys::termios::SetArg::TCSANOW, &termios)
|
||||||
|
.expect("Could not write terminal attributes");
|
||||||
|
} else {
|
||||||
|
print_settings(&termios, opts);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_settings(termios: &Termios, opts: &Options) {
|
||||||
|
if print_flags(termios, opts, &CONTROL_FLAGS) {
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
if print_flags(termios, opts, &INPUT_FLAGS) {
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
if print_flags(termios, opts, &OUTPUT_FLAGS) {
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
if print_flags(termios, opts, &LOCAL_FLAGS) {
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_flags<T>(termios: &Termios, opts: &Options, flags: &[Flag<T>]) -> bool
|
||||||
|
where
|
||||||
|
Flag<T>: TermiosFlag,
|
||||||
|
{
|
||||||
|
let mut printed = false;
|
||||||
|
for flag in flags {
|
||||||
|
if !flag.show {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let val = flag.is_in(termios);
|
||||||
|
if opts.all || val != flag.sane {
|
||||||
|
if !val {
|
||||||
|
print!("-");
|
||||||
|
}
|
||||||
|
print!("{} ", flag.name);
|
||||||
|
printed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printed
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_setting(termios: &mut Termios, s: &str) -> Option<()> {
|
||||||
|
if let Some(()) = apply_flag(termios, &CONTROL_FLAGS, s) {
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
|
if let Some(()) = apply_flag(termios, &INPUT_FLAGS, s) {
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
|
if let Some(()) = apply_flag(termios, &OUTPUT_FLAGS, s) {
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
|
if let Some(()) = apply_flag(termios, &LOCAL_FLAGS, s) {
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_flag<T>(termios: &mut Termios, flags: &[Flag<T>], name: &str) -> Option<()>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
Flag<T>: TermiosFlag,
|
||||||
|
{
|
||||||
|
let (remove, name) = strip_hyphen(name);
|
||||||
|
find(flags, name)?.apply(termios, !remove);
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn strip_hyphen(s: &str) -> (bool, &str) {
|
||||||
|
match s.strip_prefix('-') {
|
||||||
|
Some(s) => (true, s),
|
||||||
|
None => (false, s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uu_app<'a>() -> Command<'a> {
|
||||||
|
Command::new(uucore::util_name())
|
||||||
|
.name(NAME)
|
||||||
|
.version(crate_version!())
|
||||||
|
.override_usage(format_usage(USAGE))
|
||||||
|
.about(SUMMARY)
|
||||||
|
.infer_long_args(true)
|
||||||
|
.arg(Arg::new(options::ALL).short('a').long(options::ALL))
|
||||||
|
.arg(Arg::new(options::SAVE).short('g').long(options::SAVE))
|
||||||
|
.arg(
|
||||||
|
Arg::new(options::FILE)
|
||||||
|
.short('F')
|
||||||
|
.long(options::FILE)
|
||||||
|
.takes_value(true)
|
||||||
|
.value_hint(clap::ValueHint::FilePath),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new(options::SETTINGS)
|
||||||
|
.takes_value(true)
|
||||||
|
.multiple_values(true),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermiosFlag for Flag<ControlFlags> {
|
||||||
|
fn is_in(&self, termios: &Termios) -> bool {
|
||||||
|
termios.control_flags.contains(self.flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, termios: &mut Termios, val: bool) {
|
||||||
|
termios.control_flags.set(self.flag, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermiosFlag for Flag<InputFlags> {
|
||||||
|
fn is_in(&self, termios: &Termios) -> bool {
|
||||||
|
termios.input_flags.contains(self.flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, termios: &mut Termios, val: bool) {
|
||||||
|
termios.input_flags.set(self.flag, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermiosFlag for Flag<OutputFlags> {
|
||||||
|
fn is_in(&self, termios: &Termios) -> bool {
|
||||||
|
termios.output_flags.contains(self.flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, termios: &mut Termios, val: bool) {
|
||||||
|
termios.output_flags.set(self.flag, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermiosFlag for Flag<LocalFlags> {
|
||||||
|
fn is_in(&self, termios: &Termios) -> bool {
|
||||||
|
termios.local_flags.contains(self.flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, termios: &mut Termios, val: bool) {
|
||||||
|
termios.local_flags.set(self.flag, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find<'a, T>(flags: &'a [Flag<T>], flag_name: &str) -> Option<&'a Flag<T>>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
|
flags.iter().find_map(|flag| {
|
||||||
|
if flag.name == flag_name {
|
||||||
|
Some(flag)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue