mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #2502 from hbina/hbina-tr-reimplement-expansion
`tr`: Expanding expansion module
This commit is contained in:
commit
d2fe245192
8 changed files with 1606 additions and 510 deletions
246
Cargo.lock
generated
246
Cargo.lock
generated
|
@ -110,21 +110,6 @@ dependencies = [
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bit-set"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
|
|
||||||
dependencies = [
|
|
||||||
"bit-vec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bit-vec"
|
|
||||||
version = "0.6.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -258,9 +243,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.0.9"
|
version = "3.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c506244a13c87262f84bf16369740d0b7c3850901b6a642aa41b031a710c473"
|
checksum = "7a30c3bf9ff12dfe5dae53f0a96e0febcd18420d1c0e7fad77796d9d5c4b5375"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -279,7 +264,7 @@ version = "3.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d044e9db8cd0f68191becdeb5246b7462e4cf0c069b19ae00d1bf3fa9889498d"
|
checksum = "d044e9db8cd0f68191becdeb5246b7462e4cf0c069b19ae00d1bf3fa9889498d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -318,7 +303,7 @@ version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"conv",
|
"conv",
|
||||||
"filetime",
|
"filetime",
|
||||||
|
@ -1004,9 +989,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.112"
|
version = "0.2.113"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
|
@ -1785,18 +1770,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.133"
|
version = "1.0.134"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
|
checksum = "96b3c34c1690edf8174f5b289a336ab03f568a4460d8c6df75f2f3a692b3bc6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.133"
|
version = "1.0.134"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
|
checksum = "784ed1fbfa13fe191077537b0d70ec8ad1e903cfe04831da608aa36457cb653d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote 1.0.14",
|
"quote 1.0.14",
|
||||||
|
@ -1893,9 +1878,9 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516"
|
checksum = "0f82496b90c36d70af5fcd482edaa2e0bd16fade569de1330405fecbbdac736b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
|
@ -1939,9 +1924,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.85"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
|
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote 1.0.14",
|
"quote 1.0.14",
|
||||||
|
@ -2156,7 +2141,7 @@ checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b"
|
||||||
name = "uu_arch"
|
name = "uu_arch"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"platform-info",
|
"platform-info",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2166,7 +2151,7 @@ dependencies = [
|
||||||
name = "uu_base32"
|
name = "uu_base32"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2184,7 +2169,7 @@ dependencies = [
|
||||||
name = "uu_basename"
|
name = "uu_basename"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2193,7 +2178,7 @@ dependencies = [
|
||||||
name = "uu_basenc"
|
name = "uu_basenc"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uu_base32",
|
"uu_base32",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2204,7 +2189,7 @@ name = "uu_cat"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"unix_socket",
|
"unix_socket",
|
||||||
|
@ -2217,7 +2202,7 @@ dependencies = [
|
||||||
name = "uu_chcon"
|
name = "uu_chcon"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"fts-sys",
|
"fts-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"selinux",
|
"selinux",
|
||||||
|
@ -2230,7 +2215,7 @@ dependencies = [
|
||||||
name = "uu_chgrp"
|
name = "uu_chgrp"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2239,7 +2224,7 @@ dependencies = [
|
||||||
name = "uu_chmod"
|
name = "uu_chmod"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2250,7 +2235,7 @@ dependencies = [
|
||||||
name = "uu_chown"
|
name = "uu_chown"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2259,7 +2244,7 @@ dependencies = [
|
||||||
name = "uu_chroot"
|
name = "uu_chroot"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2268,7 +2253,7 @@ dependencies = [
|
||||||
name = "uu_cksum"
|
name = "uu_cksum"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2278,7 +2263,7 @@ dependencies = [
|
||||||
name = "uu_comm"
|
name = "uu_comm"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2288,7 +2273,7 @@ dependencies = [
|
||||||
name = "uu_cp"
|
name = "uu_cp"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"exacl",
|
"exacl",
|
||||||
"filetime",
|
"filetime",
|
||||||
"ioctl-sys",
|
"ioctl-sys",
|
||||||
|
@ -2306,7 +2291,7 @@ dependencies = [
|
||||||
name = "uu_csplit"
|
name = "uu_csplit"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"regex",
|
"regex",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2319,7 +2304,7 @@ version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bstr",
|
"bstr",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"memchr 2.4.1",
|
"memchr 2.4.1",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2330,7 +2315,7 @@ name = "uu_date"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2342,7 +2327,7 @@ name = "uu_dd"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byte-unit",
|
"byte-unit",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"gcd",
|
"gcd",
|
||||||
"libc",
|
"libc",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
|
@ -2355,7 +2340,7 @@ dependencies = [
|
||||||
name = "uu_df"
|
name = "uu_df"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2365,7 +2350,7 @@ dependencies = [
|
||||||
name = "uu_dircolors"
|
name = "uu_dircolors"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"glob",
|
"glob",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2375,7 +2360,7 @@ dependencies = [
|
||||||
name = "uu_dirname"
|
name = "uu_dirname"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2386,7 +2371,7 @@ name = "uu_du"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
|
@ -2396,7 +2381,7 @@ dependencies = [
|
||||||
name = "uu_echo"
|
name = "uu_echo"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2405,7 +2390,7 @@ dependencies = [
|
||||||
name = "uu_env"
|
name = "uu_env"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"rust-ini",
|
"rust-ini",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2416,7 +2401,7 @@ dependencies = [
|
||||||
name = "uu_expand"
|
name = "uu_expand"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2426,7 +2411,7 @@ dependencies = [
|
||||||
name = "uu_expr"
|
name = "uu_expr"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
@ -2439,7 +2424,7 @@ dependencies = [
|
||||||
name = "uu_factor"
|
name = "uu_factor"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"coz",
|
"coz",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"paste 0.1.18",
|
"paste 0.1.18",
|
||||||
|
@ -2454,7 +2439,7 @@ dependencies = [
|
||||||
name = "uu_false"
|
name = "uu_false"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2463,7 +2448,7 @@ dependencies = [
|
||||||
name = "uu_fmt"
|
name = "uu_fmt"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2474,7 +2459,7 @@ dependencies = [
|
||||||
name = "uu_fold"
|
name = "uu_fold"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2483,7 +2468,7 @@ dependencies = [
|
||||||
name = "uu_groups"
|
name = "uu_groups"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2493,7 +2478,7 @@ name = "uu_hashsum"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"digest",
|
"digest",
|
||||||
"hex",
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -2512,7 +2497,7 @@ dependencies = [
|
||||||
name = "uu_head"
|
name = "uu_head"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"memchr 2.4.1",
|
"memchr 2.4.1",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2522,7 +2507,7 @@ dependencies = [
|
||||||
name = "uu_hostid"
|
name = "uu_hostid"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2532,7 +2517,7 @@ dependencies = [
|
||||||
name = "uu_hostname"
|
name = "uu_hostname"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"hostname",
|
"hostname",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2544,7 +2529,7 @@ dependencies = [
|
||||||
name = "uu_id"
|
name = "uu_id"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"selinux",
|
"selinux",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2554,7 +2539,7 @@ dependencies = [
|
||||||
name = "uu_install"
|
name = "uu_install"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"file_diff",
|
"file_diff",
|
||||||
"filetime",
|
"filetime",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -2567,7 +2552,7 @@ dependencies = [
|
||||||
name = "uu_join"
|
name = "uu_join"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2576,7 +2561,7 @@ dependencies = [
|
||||||
name = "uu_kill"
|
name = "uu_kill"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2586,7 +2571,7 @@ dependencies = [
|
||||||
name = "uu_link"
|
name = "uu_link"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2596,7 +2581,7 @@ dependencies = [
|
||||||
name = "uu_ln"
|
name = "uu_ln"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2606,7 +2591,7 @@ dependencies = [
|
||||||
name = "uu_logname"
|
name = "uu_logname"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2618,7 +2603,7 @@ version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"glob",
|
"glob",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lscolors",
|
"lscolors",
|
||||||
|
@ -2636,7 +2621,7 @@ dependencies = [
|
||||||
name = "uu_mkdir"
|
name = "uu_mkdir"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2646,7 +2631,7 @@ dependencies = [
|
||||||
name = "uu_mkfifo"
|
name = "uu_mkfifo"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2656,7 +2641,7 @@ dependencies = [
|
||||||
name = "uu_mknod"
|
name = "uu_mknod"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2666,7 +2651,7 @@ dependencies = [
|
||||||
name = "uu_mktemp"
|
name = "uu_mktemp"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"rand 0.5.6",
|
"rand 0.5.6",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2678,7 +2663,7 @@ name = "uu_more"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
|
@ -2693,7 +2678,7 @@ dependencies = [
|
||||||
name = "uu_mv"
|
name = "uu_mv"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2703,7 +2688,7 @@ dependencies = [
|
||||||
name = "uu_nice"
|
name = "uu_nice"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2715,7 +2700,7 @@ name = "uu_nl"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr 2.4.1",
|
"memchr 2.4.1",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -2729,7 +2714,7 @@ name = "uu_nohup"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2739,7 +2724,7 @@ dependencies = [
|
||||||
name = "uu_nproc"
|
name = "uu_nproc"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2750,7 +2735,7 @@ dependencies = [
|
||||||
name = "uu_numfmt"
|
name = "uu_numfmt"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2760,7 +2745,7 @@ name = "uu_od"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"half",
|
"half",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2771,7 +2756,7 @@ dependencies = [
|
||||||
name = "uu_paste"
|
name = "uu_paste"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2780,7 +2765,7 @@ dependencies = [
|
||||||
name = "uu_pathchk"
|
name = "uu_pathchk"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2790,7 +2775,7 @@ dependencies = [
|
||||||
name = "uu_pinky"
|
name = "uu_pinky"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2800,7 +2785,7 @@ name = "uu_pr"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"getopts",
|
"getopts",
|
||||||
"itertools 0.10.3",
|
"itertools 0.10.3",
|
||||||
"quick-error 2.0.1",
|
"quick-error 2.0.1",
|
||||||
|
@ -2813,7 +2798,7 @@ dependencies = [
|
||||||
name = "uu_printenv"
|
name = "uu_printenv"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2822,7 +2807,7 @@ dependencies = [
|
||||||
name = "uu_printf"
|
name = "uu_printf"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"itertools 0.8.2",
|
"itertools 0.8.2",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2833,7 +2818,7 @@ name = "uu_ptx"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr 2.4.1",
|
"memchr 2.4.1",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -2846,7 +2831,7 @@ dependencies = [
|
||||||
name = "uu_pwd"
|
name = "uu_pwd"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2855,7 +2840,7 @@ dependencies = [
|
||||||
name = "uu_readlink"
|
name = "uu_readlink"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2865,7 +2850,7 @@ dependencies = [
|
||||||
name = "uu_realpath"
|
name = "uu_realpath"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2874,7 +2859,7 @@ dependencies = [
|
||||||
name = "uu_relpath"
|
name = "uu_relpath"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2883,7 +2868,7 @@ dependencies = [
|
||||||
name = "uu_rm"
|
name = "uu_rm"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2895,7 +2880,7 @@ dependencies = [
|
||||||
name = "uu_rmdir"
|
name = "uu_rmdir"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2905,7 +2890,7 @@ dependencies = [
|
||||||
name = "uu_runcon"
|
name = "uu_runcon"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"fts-sys",
|
"fts-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"selinux",
|
"selinux",
|
||||||
|
@ -2919,7 +2904,7 @@ name = "uu_seq"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bigdecimal",
|
"bigdecimal",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2930,7 +2915,7 @@ dependencies = [
|
||||||
name = "uu_shred"
|
name = "uu_shred"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -2941,7 +2926,7 @@ dependencies = [
|
||||||
name = "uu_shuf"
|
name = "uu_shuf"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"rand 0.5.6",
|
"rand 0.5.6",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -2951,7 +2936,7 @@ dependencies = [
|
||||||
name = "uu_sleep"
|
name = "uu_sleep"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2961,7 +2946,7 @@ name = "uu_sort"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"binary-heap-plus",
|
"binary-heap-plus",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"compare",
|
"compare",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"fnv",
|
"fnv",
|
||||||
|
@ -2980,7 +2965,7 @@ dependencies = [
|
||||||
name = "uu_split"
|
name = "uu_split"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2989,7 +2974,7 @@ dependencies = [
|
||||||
name = "uu_stat"
|
name = "uu_stat"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -2998,7 +2983,7 @@ dependencies = [
|
||||||
name = "uu_stdbuf"
|
name = "uu_stdbuf"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"uu_stdbuf_libstdbuf",
|
"uu_stdbuf_libstdbuf",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -3020,7 +3005,7 @@ dependencies = [
|
||||||
name = "uu_sum"
|
name = "uu_sum"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3029,7 +3014,7 @@ dependencies = [
|
||||||
name = "uu_sync"
|
name = "uu_sync"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -3040,7 +3025,7 @@ dependencies = [
|
||||||
name = "uu_tac"
|
name = "uu_tac"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"memchr 2.4.1",
|
"memchr 2.4.1",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -3052,7 +3037,7 @@ dependencies = [
|
||||||
name = "uu_tail"
|
name = "uu_tail"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
|
@ -3065,7 +3050,7 @@ dependencies = [
|
||||||
name = "uu_tee"
|
name = "uu_tee"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"retain_mut",
|
"retain_mut",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -3076,7 +3061,7 @@ dependencies = [
|
||||||
name = "uu_test"
|
name = "uu_test"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -3087,7 +3072,7 @@ dependencies = [
|
||||||
name = "uu_timeout"
|
name = "uu_timeout"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -3098,7 +3083,7 @@ dependencies = [
|
||||||
name = "uu_touch"
|
name = "uu_touch"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"filetime",
|
"filetime",
|
||||||
"time",
|
"time",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -3109,9 +3094,8 @@ dependencies = [
|
||||||
name = "uu_tr"
|
name = "uu_tr"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"clap 3.0.10",
|
||||||
"clap 3.0.9",
|
"nom",
|
||||||
"fnv",
|
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3120,7 +3104,7 @@ dependencies = [
|
||||||
name = "uu_true"
|
name = "uu_true"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3129,7 +3113,7 @@ dependencies = [
|
||||||
name = "uu_truncate"
|
name = "uu_truncate"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3138,7 +3122,7 @@ dependencies = [
|
||||||
name = "uu_tsort"
|
name = "uu_tsort"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3148,7 +3132,7 @@ name = "uu_tty"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -3158,7 +3142,7 @@ dependencies = [
|
||||||
name = "uu_uname"
|
name = "uu_uname"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"platform-info",
|
"platform-info",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -3168,7 +3152,7 @@ dependencies = [
|
||||||
name = "uu_unexpand"
|
name = "uu_unexpand"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -3178,7 +3162,7 @@ dependencies = [
|
||||||
name = "uu_uniq"
|
name = "uu_uniq"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
@ -3189,7 +3173,7 @@ dependencies = [
|
||||||
name = "uu_unlink"
|
name = "uu_unlink"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3199,7 +3183,7 @@ name = "uu_uptime"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3208,7 +3192,7 @@ dependencies = [
|
||||||
name = "uu_users"
|
name = "uu_users"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3218,7 +3202,7 @@ name = "uu_wc"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytecount",
|
"bytecount",
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
|
@ -3231,7 +3215,7 @@ dependencies = [
|
||||||
name = "uu_who"
|
name = "uu_who"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -3240,7 +3224,7 @@ dependencies = [
|
||||||
name = "uu_whoami"
|
name = "uu_whoami"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"libc",
|
"libc",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -3251,7 +3235,7 @@ dependencies = [
|
||||||
name = "uu_yes"
|
name = "uu_yes"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -3261,7 +3245,7 @@ dependencies = [
|
||||||
name = "uucore"
|
name = "uucore"
|
||||||
version = "0.0.12"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.0.9",
|
"clap 3.0.10",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"data-encoding-macro",
|
"data-encoding-macro",
|
||||||
"dns-lookup",
|
"dns-lookup",
|
||||||
|
|
|
@ -15,8 +15,7 @@ edition = "2018"
|
||||||
path = "src/tr.rs"
|
path = "src/tr.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bit-set = "0.5.0"
|
nom = "7.1.0"
|
||||||
fnv = "1.0.5"
|
|
||||||
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
|
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
|
||||||
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.8", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.8", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
37
src/uu/tr/src/convert.rs
Normal file
37
src/uu/tr/src/convert.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// * 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 (strings) anychar combinator
|
||||||
|
|
||||||
|
use nom::{
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete::{anychar, one_of},
|
||||||
|
combinator::{map_opt, recognize},
|
||||||
|
multi::{many0, many_m_n},
|
||||||
|
sequence::preceded,
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn parse_octal(input: &str) -> IResult<&str, char> {
|
||||||
|
map_opt(
|
||||||
|
preceded(tag("\\"), recognize(many_m_n(1, 3, one_of("01234567")))),
|
||||||
|
|out: &str| {
|
||||||
|
u32::from_str_radix(out, 8)
|
||||||
|
.map(std::char::from_u32)
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
},
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_octal_to_char(input: String) -> String {
|
||||||
|
let result = many0(alt((parse_octal, anychar)))(input.as_str())
|
||||||
|
.map(|(_, r)| r)
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
|
result
|
||||||
|
}
|
|
@ -1,146 +0,0 @@
|
||||||
// * This file is part of the uutils coreutils package.
|
|
||||||
// *
|
|
||||||
// * (c) Michael Gehring <mg@ebfe.org>
|
|
||||||
// * (c) kwantam <kwantam@gmail.com>
|
|
||||||
// * * 2015-04-28 ~ created `expand` module to eliminate most allocs during setup
|
|
||||||
// *
|
|
||||||
// * For the full copyright and license information, please view the LICENSE
|
|
||||||
// * file that was distributed with this source code.
|
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) allocs slen unesc
|
|
||||||
|
|
||||||
use std::char::from_u32;
|
|
||||||
use std::cmp::min;
|
|
||||||
use std::iter::Peekable;
|
|
||||||
use std::ops::RangeInclusive;
|
|
||||||
|
|
||||||
/// Parse a backslash escape sequence to the corresponding character. Assumes
|
|
||||||
/// the string starts from the character _after_ the `\` and is not empty.
|
|
||||||
///
|
|
||||||
/// Returns a tuple containing the character and the number of characters
|
|
||||||
/// consumed from the input. The alphabetic escape sequences consume 1
|
|
||||||
/// character; octal escape sequences consume 1 to 3 octal digits.
|
|
||||||
#[inline]
|
|
||||||
fn parse_sequence(s: &str) -> (char, usize) {
|
|
||||||
let mut s = s.chars();
|
|
||||||
let c = s.next().expect("invalid escape: empty string");
|
|
||||||
|
|
||||||
if ('0'..='7').contains(&c) {
|
|
||||||
let mut v = c.to_digit(8).unwrap();
|
|
||||||
let mut consumed = 1;
|
|
||||||
let bits_per_digit = 3;
|
|
||||||
|
|
||||||
for c in s.take(2) {
|
|
||||||
match c.to_digit(8) {
|
|
||||||
Some(c) => {
|
|
||||||
v = (v << bits_per_digit) | c;
|
|
||||||
consumed += 1;
|
|
||||||
}
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(from_u32(v).expect("invalid octal escape"), consumed)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
match c {
|
|
||||||
'a' => 0x07u8 as char,
|
|
||||||
'b' => 0x08u8 as char,
|
|
||||||
'f' => 0x0cu8 as char,
|
|
||||||
'v' => 0x0bu8 as char,
|
|
||||||
'n' => '\n',
|
|
||||||
'r' => '\r',
|
|
||||||
't' => '\t',
|
|
||||||
c => c,
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Unescape<'a> {
|
|
||||||
string: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for Unescape<'a> {
|
|
||||||
type Item = char;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
let slen = self.string.len();
|
|
||||||
(min(slen, 1), None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.string.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is the next character an escape?
|
|
||||||
let (ret, idx) = match self.string.chars().next().unwrap() {
|
|
||||||
'\\' if self.string.len() > 1 => {
|
|
||||||
// yes---it's \ and it's not the last char in a string
|
|
||||||
// we know that \ is 1 byte long so we can index into the string safely
|
|
||||||
let (c, consumed) = parse_sequence(&self.string[1..]);
|
|
||||||
|
|
||||||
(Some(c), 1 + consumed)
|
|
||||||
}
|
|
||||||
c => (Some(c), c.len_utf8()), // not an escape char
|
|
||||||
};
|
|
||||||
|
|
||||||
self.string = &self.string[idx..]; // advance the pointer to the next char
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ExpandSet<'a> {
|
|
||||||
range: RangeInclusive<u32>,
|
|
||||||
unesc: Peekable<Unescape<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for ExpandSet<'a> {
|
|
||||||
type Item = char;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.unesc.size_hint()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
// while the Range has elements, try to return chars from it
|
|
||||||
// but make sure that they actually turn out to be Chars!
|
|
||||||
for n in &mut self.range {
|
|
||||||
if let Some(c) = from_u32(n) {
|
|
||||||
return Some(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(first) = self.unesc.next() {
|
|
||||||
// peek ahead
|
|
||||||
if self.unesc.peek() == Some(&'-') && self.unesc.size_hint().0 > 1 {
|
|
||||||
self.unesc.next(); // this is the '-'
|
|
||||||
let last = self.unesc.next().unwrap(); // this is the end of the range
|
|
||||||
|
|
||||||
{
|
|
||||||
self.range = first as u32 + 1..=last as u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(first); // in any case, return the next char
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ExpandSet<'a> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(s: &'a str) -> ExpandSet<'a> {
|
|
||||||
ExpandSet {
|
|
||||||
range: 0..=0,
|
|
||||||
unesc: Unescape { string: s }.peekable(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
556
src/uu/tr/src/operation.rs
Normal file
556
src/uu/tr/src/operation.rs
Normal file
|
@ -0,0 +1,556 @@
|
||||||
|
// * 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 (strings) anychar combinator Alnum Punct Xdigit alnum punct xdigit cntrl
|
||||||
|
|
||||||
|
use nom::{
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete::{anychar, digit1},
|
||||||
|
combinator::{map, peek, value},
|
||||||
|
multi::many0,
|
||||||
|
sequence::{delimited, preceded, separated_pair},
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
error::Error,
|
||||||
|
fmt::{Debug, Display},
|
||||||
|
io::{BufRead, Write},
|
||||||
|
};
|
||||||
|
use uucore::error::UError;
|
||||||
|
|
||||||
|
use crate::unicode_table;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum BadSequence {
|
||||||
|
MissingCharClassName,
|
||||||
|
MissingEquivalentClassChar,
|
||||||
|
MultipleCharRepeatInSet2,
|
||||||
|
CharRepeatInSet1,
|
||||||
|
InvalidRepeatCount(String),
|
||||||
|
EmptySet2WhenNotTruncatingSet1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for BadSequence {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
BadSequence::MissingCharClassName => writeln!(f, "missing character class name '[::]'"),
|
||||||
|
BadSequence::MissingEquivalentClassChar => {
|
||||||
|
writeln!(f, "missing equivalence class character '[==]'")
|
||||||
|
}
|
||||||
|
BadSequence::MultipleCharRepeatInSet2 => {
|
||||||
|
writeln!(f, "only one [c*] repeat construct may appear in string2")
|
||||||
|
}
|
||||||
|
BadSequence::CharRepeatInSet1 => {
|
||||||
|
writeln!(f, "the [c*] repeat construct may not appear in string1")
|
||||||
|
}
|
||||||
|
BadSequence::InvalidRepeatCount(count) => {
|
||||||
|
writeln!(f, "invalid repeat count '{}' in [c*n] construct", count)
|
||||||
|
}
|
||||||
|
BadSequence::EmptySet2WhenNotTruncatingSet1 => {
|
||||||
|
writeln!(f, "when not truncating set1, string2 must be non-empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for BadSequence {}
|
||||||
|
impl UError for BadSequence {}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Sequence {
|
||||||
|
Char(char),
|
||||||
|
CharRange(u32, u32),
|
||||||
|
CharStar(char),
|
||||||
|
CharRepeat(char, usize),
|
||||||
|
Alnum,
|
||||||
|
Alpha,
|
||||||
|
Blank,
|
||||||
|
Control,
|
||||||
|
Digit,
|
||||||
|
Graph,
|
||||||
|
Lower,
|
||||||
|
Print,
|
||||||
|
Punct,
|
||||||
|
Space,
|
||||||
|
Upper,
|
||||||
|
Xdigit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sequence {
|
||||||
|
pub fn flatten(&self) -> Box<dyn Iterator<Item = char>> {
|
||||||
|
match self {
|
||||||
|
Sequence::Char(c) => Box::new(std::iter::once(*c)),
|
||||||
|
Sequence::CharRange(l, r) => Box::new((*l..=*r).flat_map(std::char::from_u32)),
|
||||||
|
Sequence::CharStar(c) => Box::new(std::iter::repeat(*c)),
|
||||||
|
Sequence::CharRepeat(c, n) => Box::new(std::iter::repeat(*c).take(*n)),
|
||||||
|
Sequence::Alnum => Box::new(('0'..='9').chain('A'..='Z').chain('a'..='z')),
|
||||||
|
Sequence::Alpha => Box::new(('A'..='Z').chain('a'..='z')),
|
||||||
|
Sequence::Blank => Box::new(unicode_table::BLANK.iter().cloned()),
|
||||||
|
Sequence::Control => Box::new(
|
||||||
|
(0..=31)
|
||||||
|
.chain(std::iter::once(127))
|
||||||
|
.flat_map(std::char::from_u32),
|
||||||
|
),
|
||||||
|
Sequence::Digit => Box::new('0'..='9'),
|
||||||
|
Sequence::Graph => Box::new(
|
||||||
|
(48..=57) // digit
|
||||||
|
.chain(65..=90) // uppercase
|
||||||
|
.chain(97..=122) // lowercase
|
||||||
|
// punctuations
|
||||||
|
.chain(33..=47)
|
||||||
|
.chain(58..=64)
|
||||||
|
.chain(91..=96)
|
||||||
|
.chain(123..=126)
|
||||||
|
.chain(std::iter::once(32)) // space
|
||||||
|
.flat_map(std::char::from_u32),
|
||||||
|
),
|
||||||
|
Sequence::Lower => Box::new('a'..='z'),
|
||||||
|
Sequence::Print => Box::new(
|
||||||
|
(48..=57) // digit
|
||||||
|
.chain(65..=90) // uppercase
|
||||||
|
.chain(97..=122) // lowercase
|
||||||
|
// punctuations
|
||||||
|
.chain(33..=47)
|
||||||
|
.chain(58..=64)
|
||||||
|
.chain(91..=96)
|
||||||
|
.chain(123..=126)
|
||||||
|
.flat_map(std::char::from_u32),
|
||||||
|
),
|
||||||
|
Sequence::Punct => Box::new(
|
||||||
|
(33..=47)
|
||||||
|
.chain(58..=64)
|
||||||
|
.chain(91..=96)
|
||||||
|
.chain(123..=126)
|
||||||
|
.flat_map(std::char::from_u32),
|
||||||
|
),
|
||||||
|
Sequence::Space => Box::new(unicode_table::SPACES.iter().cloned()),
|
||||||
|
Sequence::Upper => Box::new('A'..='Z'),
|
||||||
|
Sequence::Xdigit => Box::new(('0'..='9').chain('A'..='F').chain('a'..='f')),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide all the nasty sh*t in here
|
||||||
|
// TODO: Make the 2 set lazily generate the character mapping as necessary.
|
||||||
|
pub fn solve_set_characters(
|
||||||
|
set1_str: &str,
|
||||||
|
set2_str: &str,
|
||||||
|
truncate_set1_flag: bool,
|
||||||
|
) -> Result<(Vec<char>, Vec<char>), BadSequence> {
|
||||||
|
let set1 = Sequence::from_str(set1_str)?;
|
||||||
|
let set2 = Sequence::from_str(set2_str)?;
|
||||||
|
|
||||||
|
let is_char_star = |s: &&Sequence| -> bool { matches!(s, Sequence::CharStar(_)) };
|
||||||
|
let set1_star_count = set1.iter().filter(is_char_star).count();
|
||||||
|
if set1_star_count == 0 {
|
||||||
|
let set2_star_count = set2.iter().filter(is_char_star).count();
|
||||||
|
if set2_star_count < 2 {
|
||||||
|
let char_star = set2.iter().find_map(|s| match s {
|
||||||
|
Sequence::CharStar(c) => Some(c),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
let mut partition = set2
|
||||||
|
.as_slice()
|
||||||
|
.split(|s| matches!(s, Sequence::CharStar(_)));
|
||||||
|
let set1_len = set1.iter().flat_map(Sequence::flatten).count();
|
||||||
|
let set2_len = set2
|
||||||
|
.iter()
|
||||||
|
.filter_map(|s| match s {
|
||||||
|
Sequence::CharStar(_) => None,
|
||||||
|
r => Some(r),
|
||||||
|
})
|
||||||
|
.flat_map(Sequence::flatten)
|
||||||
|
.count();
|
||||||
|
let star_compensate_len = set1_len.saturating_sub(set2_len);
|
||||||
|
let (left, right) = (partition.next(), partition.next());
|
||||||
|
let set2_solved: Vec<char> = match (left, right) {
|
||||||
|
(None, None) => match char_star {
|
||||||
|
Some(c) => std::iter::repeat(*c).take(star_compensate_len).collect(),
|
||||||
|
None => std::iter::empty().collect(),
|
||||||
|
},
|
||||||
|
(None, Some(set2_b)) => {
|
||||||
|
if let Some(c) = char_star {
|
||||||
|
std::iter::repeat(*c)
|
||||||
|
.take(star_compensate_len)
|
||||||
|
.chain(set2_b.iter().flat_map(Sequence::flatten))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
set2_b.iter().flat_map(Sequence::flatten).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some(set2_a), None) => match char_star {
|
||||||
|
Some(c) => set2_a
|
||||||
|
.iter()
|
||||||
|
.flat_map(Sequence::flatten)
|
||||||
|
.chain(std::iter::repeat(*c).take(star_compensate_len))
|
||||||
|
.collect(),
|
||||||
|
None => set2_a.iter().flat_map(Sequence::flatten).collect(),
|
||||||
|
},
|
||||||
|
(Some(set2_a), Some(set2_b)) => match char_star {
|
||||||
|
Some(c) => set2_a
|
||||||
|
.iter()
|
||||||
|
.flat_map(Sequence::flatten)
|
||||||
|
.chain(std::iter::repeat(*c).take(star_compensate_len))
|
||||||
|
.chain(set2_b.iter().flat_map(Sequence::flatten))
|
||||||
|
.collect(),
|
||||||
|
None => set2_a
|
||||||
|
.iter()
|
||||||
|
.chain(set2_b.iter())
|
||||||
|
.flat_map(Sequence::flatten)
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mut set1_solved: Vec<char> = set1.iter().flat_map(Sequence::flatten).collect();
|
||||||
|
if truncate_set1_flag {
|
||||||
|
set1_solved.truncate(set2_solved.len());
|
||||||
|
}
|
||||||
|
Ok((set1_solved, set2_solved))
|
||||||
|
} else {
|
||||||
|
Err(BadSequence::MultipleCharRepeatInSet2)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(BadSequence::CharRepeatInSet1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sequence {
|
||||||
|
pub fn from_str(input: &str) -> Result<Vec<Sequence>, BadSequence> {
|
||||||
|
many0(alt((
|
||||||
|
Sequence::parse_char_range,
|
||||||
|
Sequence::parse_char_star,
|
||||||
|
Sequence::parse_char_repeat,
|
||||||
|
Sequence::parse_class,
|
||||||
|
Sequence::parse_char_equal,
|
||||||
|
// NOTE: This must be the last one
|
||||||
|
map(Sequence::parse_backslash_or_char, |s| Ok(Sequence::Char(s))),
|
||||||
|
)))(input)
|
||||||
|
.map(|(_, r)| r)
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_backslash(input: &str) -> IResult<&str, char> {
|
||||||
|
preceded(tag("\\"), anychar)(input).map(|(l, a)| {
|
||||||
|
let c = match a {
|
||||||
|
'a' => unicode_table::BEL,
|
||||||
|
'b' => unicode_table::BS,
|
||||||
|
'f' => unicode_table::FF,
|
||||||
|
'n' => unicode_table::LF,
|
||||||
|
'r' => unicode_table::CR,
|
||||||
|
't' => unicode_table::HT,
|
||||||
|
'v' => unicode_table::VT,
|
||||||
|
x => x,
|
||||||
|
};
|
||||||
|
(l, c)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_backslash_or_char(input: &str) -> IResult<&str, char> {
|
||||||
|
alt((Sequence::parse_backslash, anychar))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_char_range(input: &str) -> IResult<&str, Result<Sequence, BadSequence>> {
|
||||||
|
separated_pair(
|
||||||
|
Sequence::parse_backslash_or_char,
|
||||||
|
tag("-"),
|
||||||
|
Sequence::parse_backslash_or_char,
|
||||||
|
)(input)
|
||||||
|
.map(|(l, (a, b))| {
|
||||||
|
(l, {
|
||||||
|
let (start, end) = (u32::from(a), u32::from(b));
|
||||||
|
Ok(Sequence::CharRange(start, end))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_char_star(input: &str) -> IResult<&str, Result<Sequence, BadSequence>> {
|
||||||
|
delimited(tag("["), Sequence::parse_backslash_or_char, tag("*]"))(input)
|
||||||
|
.map(|(l, a)| (l, Ok(Sequence::CharStar(a))))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_char_repeat(input: &str) -> IResult<&str, Result<Sequence, BadSequence>> {
|
||||||
|
delimited(
|
||||||
|
tag("["),
|
||||||
|
separated_pair(Sequence::parse_backslash_or_char, tag("*"), digit1),
|
||||||
|
tag("]"),
|
||||||
|
)(input)
|
||||||
|
.map(|(l, (c, str))| {
|
||||||
|
(
|
||||||
|
l,
|
||||||
|
match usize::from_str_radix(str, 8) {
|
||||||
|
Ok(0) => Ok(Sequence::CharStar(c)),
|
||||||
|
Ok(count) => Ok(Sequence::CharRepeat(c, count)),
|
||||||
|
Err(_) => Err(BadSequence::InvalidRepeatCount(str.to_string())),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_class(input: &str) -> IResult<&str, Result<Sequence, BadSequence>> {
|
||||||
|
delimited(
|
||||||
|
tag("[:"),
|
||||||
|
alt((
|
||||||
|
map(
|
||||||
|
alt((
|
||||||
|
value(Sequence::Alnum, tag("alnum")),
|
||||||
|
value(Sequence::Alpha, tag("alpha")),
|
||||||
|
value(Sequence::Blank, tag("blank")),
|
||||||
|
value(Sequence::Control, tag("cntrl")),
|
||||||
|
value(Sequence::Digit, tag("digit")),
|
||||||
|
value(Sequence::Graph, tag("graph")),
|
||||||
|
value(Sequence::Lower, tag("lower")),
|
||||||
|
value(Sequence::Print, tag("print")),
|
||||||
|
value(Sequence::Punct, tag("punct")),
|
||||||
|
value(Sequence::Space, tag("space")),
|
||||||
|
value(Sequence::Upper, tag("upper")),
|
||||||
|
value(Sequence::Xdigit, tag("xdigit")),
|
||||||
|
)),
|
||||||
|
Ok,
|
||||||
|
),
|
||||||
|
value(Err(BadSequence::MissingCharClassName), tag("")),
|
||||||
|
)),
|
||||||
|
tag(":]"),
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_char_equal(input: &str) -> IResult<&str, Result<Sequence, BadSequence>> {
|
||||||
|
delimited(
|
||||||
|
tag("[="),
|
||||||
|
alt((
|
||||||
|
value(
|
||||||
|
Err(BadSequence::MissingEquivalentClassChar),
|
||||||
|
peek(tag("=]")),
|
||||||
|
),
|
||||||
|
map(Sequence::parse_backslash_or_char, |c| Ok(Sequence::Char(c))),
|
||||||
|
)),
|
||||||
|
tag("=]"),
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SymbolTranslator {
|
||||||
|
fn translate(&mut self, current: char) -> Option<char>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DeleteOperation {
|
||||||
|
set: Vec<char>,
|
||||||
|
complement_flag: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeleteOperation {
|
||||||
|
pub fn new(set: Vec<char>, complement_flag: bool) -> DeleteOperation {
|
||||||
|
DeleteOperation {
|
||||||
|
set,
|
||||||
|
complement_flag,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymbolTranslator for DeleteOperation {
|
||||||
|
fn translate(&mut self, current: char) -> Option<char> {
|
||||||
|
let found = self.set.iter().any(|sequence| sequence.eq(¤t));
|
||||||
|
if self.complement_flag == found {
|
||||||
|
Some(current)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TranslateOperationComplement {
|
||||||
|
iter: u32,
|
||||||
|
set2_iter: usize,
|
||||||
|
set1: Vec<char>,
|
||||||
|
set2: Vec<char>,
|
||||||
|
translation_map: HashMap<char, char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TranslateOperationComplement {
|
||||||
|
fn new(set1: Vec<char>, set2: Vec<char>) -> TranslateOperationComplement {
|
||||||
|
TranslateOperationComplement {
|
||||||
|
iter: 0,
|
||||||
|
set2_iter: 0,
|
||||||
|
set1,
|
||||||
|
set2,
|
||||||
|
translation_map: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TranslateOperationStandard {
|
||||||
|
translation_map: HashMap<char, char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TranslateOperationStandard {
|
||||||
|
fn new(set1: Vec<char>, set2: Vec<char>) -> Result<TranslateOperationStandard, BadSequence> {
|
||||||
|
if let Some(fallback) = set2.last().copied() {
|
||||||
|
Ok(TranslateOperationStandard {
|
||||||
|
translation_map: set1
|
||||||
|
.into_iter()
|
||||||
|
.zip(set2.into_iter().chain(std::iter::repeat(fallback)))
|
||||||
|
.collect::<HashMap<_, _>>(),
|
||||||
|
})
|
||||||
|
} else if set1.is_empty() && set2.is_empty() {
|
||||||
|
Ok(TranslateOperationStandard {
|
||||||
|
translation_map: HashMap::new(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(BadSequence::EmptySet2WhenNotTruncatingSet1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum TranslateOperation {
|
||||||
|
Standard(TranslateOperationStandard),
|
||||||
|
Complement(TranslateOperationComplement),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TranslateOperation {
|
||||||
|
fn next_complement_char(iter: u32, ignore_list: &[char]) -> (u32, char) {
|
||||||
|
(iter..)
|
||||||
|
.filter_map(std::char::from_u32)
|
||||||
|
.filter(|c| !ignore_list.iter().any(|s| s.eq(c)))
|
||||||
|
.map(|c| (u32::from(c) + 1, c))
|
||||||
|
.next()
|
||||||
|
.expect("exhausted all possible characters")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TranslateOperation {
|
||||||
|
pub fn new(
|
||||||
|
set1: Vec<char>,
|
||||||
|
set2: Vec<char>,
|
||||||
|
complement: bool,
|
||||||
|
) -> Result<TranslateOperation, BadSequence> {
|
||||||
|
if complement {
|
||||||
|
Ok(TranslateOperation::Complement(
|
||||||
|
TranslateOperationComplement::new(set1, set2),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(TranslateOperation::Standard(
|
||||||
|
TranslateOperationStandard::new(set1, set2)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymbolTranslator for TranslateOperation {
|
||||||
|
fn translate(&mut self, current: char) -> Option<char> {
|
||||||
|
match self {
|
||||||
|
TranslateOperation::Standard(TranslateOperationStandard { translation_map }) => Some(
|
||||||
|
translation_map
|
||||||
|
.iter()
|
||||||
|
.find_map(|(l, r)| if l.eq(¤t) { Some(*r) } else { None })
|
||||||
|
.unwrap_or(current),
|
||||||
|
),
|
||||||
|
TranslateOperation::Complement(TranslateOperationComplement {
|
||||||
|
iter,
|
||||||
|
set2_iter,
|
||||||
|
set1,
|
||||||
|
set2,
|
||||||
|
translation_map,
|
||||||
|
}) => {
|
||||||
|
// First, try to see if current char is already mapped
|
||||||
|
// If so, return the mapped char
|
||||||
|
// Else, pop from set2
|
||||||
|
// If we popped something, map the next complement character to this value
|
||||||
|
// If set2 is empty, we just map the current char directly to fallback --- to avoid looping unnecessarily
|
||||||
|
if let Some(c) = set1.iter().find(|c| c.eq(&¤t)) {
|
||||||
|
Some(*c)
|
||||||
|
} else {
|
||||||
|
while translation_map.get(¤t).is_none() {
|
||||||
|
if let Some(value) = set2.get(*set2_iter) {
|
||||||
|
let (next_iter, next_key) =
|
||||||
|
TranslateOperation::next_complement_char(*iter, &*set1);
|
||||||
|
*iter = next_iter;
|
||||||
|
*set2_iter = set2_iter.saturating_add(1);
|
||||||
|
translation_map.insert(next_key, *value);
|
||||||
|
} else {
|
||||||
|
translation_map.insert(current, *set2.last().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(*translation_map.get(¤t).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SqueezeOperation {
|
||||||
|
set1: HashSet<char>,
|
||||||
|
complement: bool,
|
||||||
|
previous: Option<char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqueezeOperation {
|
||||||
|
pub fn new(set1: Vec<char>, complement: bool) -> SqueezeOperation {
|
||||||
|
SqueezeOperation {
|
||||||
|
set1: set1.into_iter().collect(),
|
||||||
|
complement,
|
||||||
|
previous: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymbolTranslator for SqueezeOperation {
|
||||||
|
fn translate(&mut self, current: char) -> Option<char> {
|
||||||
|
if self.complement {
|
||||||
|
let next = if self.set1.contains(¤t) {
|
||||||
|
Some(current)
|
||||||
|
} else {
|
||||||
|
match self.previous {
|
||||||
|
Some(v) => {
|
||||||
|
if v.eq(¤t) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Some(current),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.previous = Some(current);
|
||||||
|
next
|
||||||
|
} else {
|
||||||
|
let next = if self.set1.contains(¤t) {
|
||||||
|
match self.previous {
|
||||||
|
Some(v) if v == current => None,
|
||||||
|
_ => Some(current),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(current)
|
||||||
|
};
|
||||||
|
self.previous = Some(current);
|
||||||
|
next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn translate_input<T, R, W>(input: &mut R, output: &mut W, mut translator: T)
|
||||||
|
where
|
||||||
|
T: SymbolTranslator,
|
||||||
|
R: BufRead,
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
let mut buf = String::new();
|
||||||
|
let mut output_buf = String::new();
|
||||||
|
while let Ok(length) = input.read_line(&mut buf) {
|
||||||
|
if length == 0 {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
let filtered = buf.chars().filter_map(|c| translator.translate(c));
|
||||||
|
output_buf.extend(filtered);
|
||||||
|
output.write_all(output_buf.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
buf.clear();
|
||||||
|
output_buf.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,238 +1,43 @@
|
||||||
// * This file is part of the uutils coreutils package.
|
// * This file is part of the uutils coreutils package.
|
||||||
// *
|
// *
|
||||||
// * (c) Michael Gehring <mg@ebfe.org>
|
|
||||||
// * (c) kwantam <kwantam@gmail.com>
|
|
||||||
// * * 2015-04-28 ~ created `expand` module to eliminate most allocs during setup
|
|
||||||
// * (c) Sergey "Shnatsel" Davidoff <shnatsel@gmail.com>
|
|
||||||
// *
|
|
||||||
// * 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) allocs bset dflag cflag sflag tflag
|
// spell-checker:ignore (ToDO) allocs bset dflag cflag sflag tflag
|
||||||
|
|
||||||
mod expand;
|
extern crate nom;
|
||||||
|
|
||||||
|
mod convert;
|
||||||
|
mod operation;
|
||||||
|
mod unicode_table;
|
||||||
|
|
||||||
use bit_set::BitSet;
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use fnv::FnvHashMap;
|
use nom::AsBytes;
|
||||||
use std::io::{stdin, stdout, BufRead, BufWriter, Write};
|
use operation::{translate_input, Sequence, SqueezeOperation, TranslateOperation};
|
||||||
|
use std::io::{stdin, stdout, BufReader, BufWriter};
|
||||||
|
use uucore::show;
|
||||||
|
|
||||||
use crate::expand::ExpandSet;
|
use crate::operation::DeleteOperation;
|
||||||
use uucore::error::{UResult, UUsageError};
|
use uucore::error::{UResult, USimpleError, UUsageError};
|
||||||
use uucore::{display::Quotable, InvalidEncodingHandling};
|
use uucore::{display::Quotable, InvalidEncodingHandling};
|
||||||
|
|
||||||
static ABOUT: &str = "translate or delete characters";
|
static ABOUT: &str = "translate or delete characters";
|
||||||
|
|
||||||
const BUFFER_LEN: usize = 1024;
|
|
||||||
|
|
||||||
mod options {
|
mod options {
|
||||||
pub const COMPLEMENT: &str = "complement";
|
pub const COMPLEMENT: &str = "complement";
|
||||||
pub const DELETE: &str = "delete";
|
pub const DELETE: &str = "delete";
|
||||||
pub const SQUEEZE: &str = "squeeze-repeats";
|
pub const SQUEEZE: &str = "squeeze-repeats";
|
||||||
pub const TRUNCATE: &str = "truncate";
|
pub const TRUNCATE_SET1: &str = "truncate-set1";
|
||||||
pub const SETS: &str = "sets";
|
pub const SETS: &str = "sets";
|
||||||
}
|
}
|
||||||
|
|
||||||
trait SymbolTranslator {
|
fn get_usage() -> String {
|
||||||
fn translate(&self, c: char, prev_c: char) -> Option<char>;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DeleteOperation {
|
|
||||||
bset: BitSet,
|
|
||||||
complement: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeleteOperation {
|
|
||||||
fn new(set: ExpandSet, complement: bool) -> DeleteOperation {
|
|
||||||
DeleteOperation {
|
|
||||||
bset: set.map(|c| c as usize).collect(),
|
|
||||||
complement,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolTranslator for DeleteOperation {
|
|
||||||
fn translate(&self, c: char, _prev_c: char) -> Option<char> {
|
|
||||||
let uc = c as usize;
|
|
||||||
if self.complement == self.bset.contains(uc) {
|
|
||||||
Some(c)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SqueezeOperation {
|
|
||||||
squeeze_set: BitSet,
|
|
||||||
complement: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SqueezeOperation {
|
|
||||||
fn new(squeeze_set: ExpandSet, complement: bool) -> SqueezeOperation {
|
|
||||||
SqueezeOperation {
|
|
||||||
squeeze_set: squeeze_set.map(|c| c as usize).collect(),
|
|
||||||
complement,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolTranslator for SqueezeOperation {
|
|
||||||
fn translate(&self, c: char, prev_c: char) -> Option<char> {
|
|
||||||
if prev_c == c && self.complement != self.squeeze_set.contains(c as usize) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DeleteAndSqueezeOperation {
|
|
||||||
delete_set: BitSet,
|
|
||||||
squeeze_set: BitSet,
|
|
||||||
complement: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeleteAndSqueezeOperation {
|
|
||||||
fn new(
|
|
||||||
delete_set: ExpandSet,
|
|
||||||
squeeze_set: ExpandSet,
|
|
||||||
complement: bool,
|
|
||||||
) -> DeleteAndSqueezeOperation {
|
|
||||||
DeleteAndSqueezeOperation {
|
|
||||||
delete_set: delete_set.map(|c| c as usize).collect(),
|
|
||||||
squeeze_set: squeeze_set.map(|c| c as usize).collect(),
|
|
||||||
complement,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolTranslator for DeleteAndSqueezeOperation {
|
|
||||||
fn translate(&self, c: char, prev_c: char) -> Option<char> {
|
|
||||||
if self.complement != self.delete_set.contains(c as usize)
|
|
||||||
|| prev_c == c && self.squeeze_set.contains(c as usize)
|
|
||||||
{
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TranslateOperation {
|
|
||||||
translate_map: FnvHashMap<usize, char>,
|
|
||||||
complement: bool,
|
|
||||||
s2_last: char,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TranslateOperation {
|
|
||||||
fn new(
|
|
||||||
set1: ExpandSet,
|
|
||||||
set2: &mut ExpandSet,
|
|
||||||
truncate: bool,
|
|
||||||
complement: bool,
|
|
||||||
) -> TranslateOperation {
|
|
||||||
let mut map = FnvHashMap::default();
|
|
||||||
let mut s2_prev = '_';
|
|
||||||
for i in set1 {
|
|
||||||
let s2_next = set2.next();
|
|
||||||
|
|
||||||
if s2_next.is_none() && truncate {
|
|
||||||
map.insert(i as usize, i);
|
|
||||||
} else {
|
|
||||||
s2_prev = s2_next.unwrap_or(s2_prev);
|
|
||||||
map.insert(i as usize, s2_prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TranslateOperation {
|
|
||||||
translate_map: map,
|
|
||||||
complement,
|
|
||||||
s2_last: set2.last().unwrap_or(s2_prev),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolTranslator for TranslateOperation {
|
|
||||||
fn translate(&self, c: char, _prev_c: char) -> Option<char> {
|
|
||||||
if self.complement {
|
|
||||||
Some(if self.translate_map.contains_key(&(c as usize)) {
|
|
||||||
c
|
|
||||||
} else {
|
|
||||||
self.s2_last
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Some(*self.translate_map.get(&(c as usize)).unwrap_or(&c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TranslateAndSqueezeOperation {
|
|
||||||
translate: TranslateOperation,
|
|
||||||
squeeze: SqueezeOperation,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TranslateAndSqueezeOperation {
|
|
||||||
fn new(sets: Vec<String>, truncate: bool, complement: bool) -> TranslateAndSqueezeOperation {
|
|
||||||
let set1 = ExpandSet::new(sets[0].as_ref());
|
|
||||||
let set1_ = ExpandSet::new(sets[0].as_ref());
|
|
||||||
let mut set2 = ExpandSet::new(sets[1].as_ref());
|
|
||||||
let set2_ = ExpandSet::new(sets[1].as_ref());
|
|
||||||
TranslateAndSqueezeOperation {
|
|
||||||
translate: TranslateOperation::new(set1, &mut set2, truncate, complement),
|
|
||||||
squeeze: SqueezeOperation::new(if complement { set1_ } else { set2_ }, complement),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolTranslator for TranslateAndSqueezeOperation {
|
|
||||||
fn translate(&self, c: char, prev_c: char) -> Option<char> {
|
|
||||||
// `unwrap()` will never panic because `Translate.translate()`
|
|
||||||
// always returns `Some`.
|
|
||||||
self.squeeze
|
|
||||||
.translate(self.translate.translate(c, 0 as char).unwrap(), prev_c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn translate_input<T: SymbolTranslator>(
|
|
||||||
input: &mut dyn BufRead,
|
|
||||||
output: &mut dyn Write,
|
|
||||||
translator: T,
|
|
||||||
) {
|
|
||||||
let mut buf = String::with_capacity(BUFFER_LEN + 4);
|
|
||||||
let mut output_buf = String::with_capacity(BUFFER_LEN + 4);
|
|
||||||
|
|
||||||
while let Ok(length) = input.read_line(&mut buf) {
|
|
||||||
let mut prev_c = 0 as char;
|
|
||||||
if length == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// isolation to make borrow checker happy
|
|
||||||
let filtered = buf.chars().filter_map(|c| {
|
|
||||||
let res = translator.translate(c, prev_c);
|
|
||||||
// Set `prev_c` to the post-translate character. This
|
|
||||||
// allows the squeeze operation to correctly function
|
|
||||||
// after the translate operation.
|
|
||||||
if let Some(rc) = res {
|
|
||||||
prev_c = rc;
|
|
||||||
}
|
|
||||||
res
|
|
||||||
});
|
|
||||||
|
|
||||||
output_buf.extend(filtered);
|
|
||||||
output.write_all(output_buf.as_bytes()).unwrap();
|
|
||||||
}
|
|
||||||
buf.clear();
|
|
||||||
output_buf.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn usage() -> String {
|
|
||||||
format!("{} [OPTION]... SET1 [SET2]", uucore::execution_phrase())
|
format!("{} [OPTION]... SET1 [SET2]", uucore::execution_phrase())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_long_usage() -> String {
|
fn get_long_usage() -> String {
|
||||||
"Translate, squeeze, and/or delete characters from standard input,
|
"Translate, squeeze, and/or delete characters from standard input, \
|
||||||
writing to standard output."
|
writing to standard output."
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +47,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
.accept_any();
|
.accept_any();
|
||||||
|
|
||||||
let usage = usage();
|
let usage = get_usage();
|
||||||
let after_help = get_long_usage();
|
let after_help = get_long_usage();
|
||||||
|
|
||||||
let matches = uu_app()
|
let matches = uu_app()
|
||||||
|
@ -253,51 +58,87 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let delete_flag = matches.is_present(options::DELETE);
|
let delete_flag = matches.is_present(options::DELETE);
|
||||||
let complement_flag = matches.is_present(options::COMPLEMENT) || matches.is_present("C");
|
let complement_flag = matches.is_present(options::COMPLEMENT) || matches.is_present("C");
|
||||||
let squeeze_flag = matches.is_present(options::SQUEEZE);
|
let squeeze_flag = matches.is_present(options::SQUEEZE);
|
||||||
let truncate_flag = matches.is_present(options::TRUNCATE);
|
let truncate_set1_flag = matches.is_present(options::TRUNCATE_SET1);
|
||||||
|
|
||||||
let sets = matches
|
let sets = matches
|
||||||
.values_of(options::SETS)
|
.values_of(options::SETS)
|
||||||
.map(|v| v.map(ToString::to_string).collect::<Vec<_>>())
|
.map(|v| {
|
||||||
|
v.map(ToString::to_string)
|
||||||
|
.map(convert::reduce_octal_to_char)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
let sets_len = sets.len();
|
||||||
|
|
||||||
if sets.is_empty() {
|
if sets.is_empty() {
|
||||||
return Err(UUsageError::new(1, "missing operand"));
|
return Err(UUsageError::new(1, "missing operand"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(delete_flag || squeeze_flag) && sets.len() < 2 {
|
if !(delete_flag || squeeze_flag) && sets_len < 2 {
|
||||||
return Err(UUsageError::new(
|
return Err(UUsageError::new(
|
||||||
1,
|
1,
|
||||||
format!("missing operand after {}", sets[0].quote()),
|
format!("missing operand after {}", sets[0].quote()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(first) = sets.get(0) {
|
||||||
|
if first.ends_with('\\') {
|
||||||
|
show!(USimpleError::new(
|
||||||
|
0,
|
||||||
|
"warning: an unescaped backslash at end of string is not portable"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let stdin = stdin();
|
let stdin = stdin();
|
||||||
let mut locked_stdin = stdin.lock();
|
let mut locked_stdin = stdin.lock();
|
||||||
let stdout = stdout();
|
let stdout = stdout();
|
||||||
let locked_stdout = stdout.lock();
|
let locked_stdout = stdout.lock();
|
||||||
let mut buffered_stdout = BufWriter::new(locked_stdout);
|
let mut buffered_stdout = BufWriter::new(locked_stdout);
|
||||||
|
|
||||||
let set1 = ExpandSet::new(sets[0].as_ref());
|
let mut sets_iter = sets.iter().map(|c| c.as_str());
|
||||||
|
let (set1, set2) = Sequence::solve_set_characters(
|
||||||
|
sets_iter.next().unwrap_or_default(),
|
||||||
|
sets_iter.next().unwrap_or_default(),
|
||||||
|
truncate_set1_flag,
|
||||||
|
)?;
|
||||||
|
|
||||||
if delete_flag {
|
if delete_flag {
|
||||||
if squeeze_flag {
|
if squeeze_flag {
|
||||||
let set2 = ExpandSet::new(sets[1].as_ref());
|
let mut delete_buffer = vec![];
|
||||||
let op = DeleteAndSqueezeOperation::new(set1, set2, complement_flag);
|
{
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
let mut delete_writer = BufWriter::new(&mut delete_buffer);
|
||||||
|
let delete_op = DeleteOperation::new(set1, complement_flag);
|
||||||
|
translate_input(&mut locked_stdin, &mut delete_writer, delete_op);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut squeeze_reader = BufReader::new(delete_buffer.as_bytes());
|
||||||
|
let op = SqueezeOperation::new(set2, complement_flag);
|
||||||
|
translate_input(&mut squeeze_reader, &mut buffered_stdout, op);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let op = DeleteOperation::new(set1, complement_flag);
|
let op = DeleteOperation::new(set1, complement_flag);
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
}
|
}
|
||||||
} else if squeeze_flag {
|
} else if squeeze_flag {
|
||||||
if sets.len() < 2 {
|
if sets_len < 2 {
|
||||||
let op = SqueezeOperation::new(set1, complement_flag);
|
let op = SqueezeOperation::new(set1, complement_flag);
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
} else {
|
} else {
|
||||||
let op = TranslateAndSqueezeOperation::new(sets, truncate_flag, complement_flag);
|
let mut translate_buffer = vec![];
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
{
|
||||||
|
let mut writer = BufWriter::new(&mut translate_buffer);
|
||||||
|
let op = TranslateOperation::new(set1, set2.clone(), complement_flag)?;
|
||||||
|
translate_input(&mut locked_stdin, &mut writer, op);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let mut reader = BufReader::new(translate_buffer.as_bytes());
|
||||||
|
let squeeze_op = SqueezeOperation::new(set2, false);
|
||||||
|
translate_input(&mut reader, &mut buffered_stdout, squeeze_op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut set2 = ExpandSet::new(sets[1].as_ref());
|
let op = TranslateOperation::new(set1, set2, complement_flag)?;
|
||||||
let op = TranslateOperation::new(set1, &mut set2, truncate_flag, complement_flag);
|
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -330,14 +171,14 @@ pub fn uu_app<'a>() -> App<'a> {
|
||||||
.long(options::SQUEEZE)
|
.long(options::SQUEEZE)
|
||||||
.short('s')
|
.short('s')
|
||||||
.help(
|
.help(
|
||||||
"replace each sequence of a repeated character that is
|
"replace each sequence of a repeated character that is \
|
||||||
listed in the last specified SET, with a single occurrence
|
listed in the last specified SET, with a single occurrence \
|
||||||
of that character",
|
of that character",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::TRUNCATE)
|
Arg::new(options::TRUNCATE_SET1)
|
||||||
.long(options::TRUNCATE)
|
.long(options::TRUNCATE_SET1)
|
||||||
.short('t')
|
.short('t')
|
||||||
.help("first truncate SET1 to length of SET2"),
|
.help("first truncate SET1 to length of SET2"),
|
||||||
)
|
)
|
||||||
|
|
15
src/uu/tr/src/unicode_table.rs
Normal file
15
src/uu/tr/src/unicode_table.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// * 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.
|
||||||
|
|
||||||
|
pub static BEL: char = '\u{0007}';
|
||||||
|
pub static BS: char = '\u{0008}';
|
||||||
|
pub static HT: char = '\u{0009}';
|
||||||
|
pub static LF: char = '\u{000A}';
|
||||||
|
pub static VT: char = '\u{000B}';
|
||||||
|
pub static FF: char = '\u{000C}';
|
||||||
|
pub static CR: char = '\u{000D}';
|
||||||
|
pub static SPACE: char = '\u{0020}';
|
||||||
|
pub static SPACES: &[char] = &[HT, LF, VT, FF, CR, SPACE];
|
||||||
|
pub static BLANK: &[char] = &[SPACE, HT];
|
|
@ -1,3 +1,4 @@
|
||||||
|
// spell-checker:ignore aabbaa aabbcc aabc abbb abcc abcdefabcdef abcdefghijk abcdefghijklmn abcdefghijklmnop ABCDEFGHIJKLMNOPQRS abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFZZ abcxyz ABCXYZ abcxyzabcxyz ABCXYZABCXYZ acbdef alnum amzamz AMZXAMZ bbbd cclass cefgm cntrl compl dabcdef dncase Gzabcdefg PQRST upcase wxyzz xdigit xycde xyyye xyyz xyzzzzxyzzzz ZABCDEF Zamz
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -98,12 +99,11 @@ fn test_complement4() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "fixme: GNU tr returns '0a1b2c3' instead of '0~1~2~3', see #2158"]
|
|
||||||
fn test_complement5() {
|
fn test_complement5() {
|
||||||
// $ echo '0x1y2z3' | tr -c '\0-@' '*-~'
|
// $ echo -n '0x1y2z3' | tr -c '\0-@' '*-~'
|
||||||
// 0a1b2c3
|
// 0a1b2c3
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&["-c", "\\0-@", "*-~"])
|
.args(&["-c", r"\0-@", "*-~"])
|
||||||
.pipe_in("0x1y2z3")
|
.pipe_in("0x1y2z3")
|
||||||
.run()
|
.run()
|
||||||
.stdout_is("0a1b2c3");
|
.stdout_is("0a1b2c3");
|
||||||
|
@ -192,6 +192,7 @@ fn test_set1_shorter_than_set2() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_truncate() {
|
fn test_truncate() {
|
||||||
|
// echo -n "abcde" | tr -t "abc" "xy"
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&["-t", "abc", "xy"])
|
.args(&["-t", "abc", "xy"])
|
||||||
.pipe_in("abcde")
|
.pipe_in("abcde")
|
||||||
|
@ -289,3 +290,812 @@ fn test_interpret_backslash_at_eol_literally() {
|
||||||
fn test_more_than_2_sets() {
|
fn test_more_than_2_sets() {
|
||||||
new_ucmd!().args(&["'abcdef'", "'a'", "'b'"]).fails();
|
new_ucmd!().args(&["'abcdef'", "'a'", "'b'"]).fails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_translation_works() {
|
||||||
|
// echo -n "abcdefabcdef" | tr "dabcdef" "xyz"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abcdef", "xyz"])
|
||||||
|
.pipe_in("abcdefabcdef")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("xyzzzzxyzzzz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alnum_overrides_translation_to_fallback_1() {
|
||||||
|
// echo -n "abcdefghijklmnopqrstuvwxyz" | tr "abc[:alpha:]" "xyz"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abc[:alpha:]", "xyz"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("zzzzzzzzzzzzzzzzzzzzzzzzzz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alnum_overrides_translation_to_fallback_2() {
|
||||||
|
// echo -n "abcdefghijklmnopqrstuvwxyz" | tr "[:alpha:]abc" "xyz"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:alpha:]abc", "xyz"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("zzzzzzzzzzzzzzzzzzzzzzzzzz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overrides_translation_pair_if_repeats() {
|
||||||
|
// echo -n 'aaa' | tr "aaa" "xyz"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["aaa", "xyz"])
|
||||||
|
.pipe_in("aaa")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("zzz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn uppercase_conversion_works_1() {
|
||||||
|
// echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn uppercase_conversion_works_2() {
|
||||||
|
// echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "a-z" "A-Z"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a-z", "A-Z"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn uppercase_conversion_works_3() {
|
||||||
|
// echo -n 'abcdefghijklmnopqrstuvwxyz' | tr "[:lower:]" "[:upper:]"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:lower:]", "[:upper:]"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn translate_complement_set_in_order() {
|
||||||
|
// echo -n '01234' | tr -c '@-~' ' -^'
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-c", "@-~", " -^"])
|
||||||
|
.pipe_in("01234")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("PQRST");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alpha_expands_uppercase_lowercase() {
|
||||||
|
// echo -n "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alpha:]" " -_"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:alpha:]", " -_"])
|
||||||
|
.pipe_in("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(r##" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS"##);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alnum_expands_number_uppercase_lowercase() {
|
||||||
|
// echo -n "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | tr "[:alnum:]" " -_"
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:alnum:]", " -_"])
|
||||||
|
.pipe_in("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(r##" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"##);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests() {
|
||||||
|
// ['1', qw(abcd '[]*]'), {IN=>'abcd'}, {OUT=>']]]]'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abcd", "[]*]"])
|
||||||
|
.pipe_in("abcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("]]]]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_2() {
|
||||||
|
// ['2', qw(abc '[%*]xyz'), {IN=>'abc'}, {OUT=>'xyz'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abc", "[%*]xyz"])
|
||||||
|
.pipe_in("abc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("xyz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_3() {
|
||||||
|
// ['3', qw('' '[.*]'), {IN=>'abc'}, {OUT=>'abc'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["", "[.*]"])
|
||||||
|
.pipe_in("abc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_4() {
|
||||||
|
// # Test --truncate-set1 behavior when string1 is longer than string2
|
||||||
|
// ['4', qw(-t abcd xy), {IN=>'abcde'}, {OUT=>'xycde'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-t", "abcd", "xy"])
|
||||||
|
.pipe_in("abcde")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("xycde");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_5() {
|
||||||
|
// # Test bsd behavior (the default) when string1 is longer than string2
|
||||||
|
// ['5', qw(abcd xy), {IN=>'abcde'}, {OUT=>'xyyye'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abcd", "xy"])
|
||||||
|
.pipe_in("abcde")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("xyyye");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_6() {
|
||||||
|
// # Do it the posix way
|
||||||
|
// ['6', qw(abcd 'x[y*]'), {IN=>'abcde'}, {OUT=>'xyyye'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abcd", "x[y*]"])
|
||||||
|
.pipe_in("abcde")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("xyyye");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_7() {
|
||||||
|
// ['7', qw(-s a-p '%[.*]$'), {IN=>'abcdefghijklmnop'}, {OUT=>'%.$'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "a-p", "%[.*]$"])
|
||||||
|
.pipe_in("abcdefghijklmnop")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("%.$");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_8() {
|
||||||
|
// ['8', qw(-s a-p '[.*]$'), {IN=>'abcdefghijklmnop'}, {OUT=>'.$'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "a-p", "[.*]$"])
|
||||||
|
.pipe_in("abcdefghijklmnop")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(".$");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_9() {
|
||||||
|
// ['9', qw(-s a-p '%[.*]'), {IN=>'abcdefghijklmnop'}, {OUT=>'%.'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "a-p", "%[.*]"])
|
||||||
|
.pipe_in("abcdefghijklmnop")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("%.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_a() {
|
||||||
|
// ['a', qw(-s '[a-z]'), {IN=>'aabbcc'}, {OUT=>'abc'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "[a-z]"])
|
||||||
|
.pipe_in("aabbcc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_b() {
|
||||||
|
// ['b', qw(-s '[a-c]'), {IN=>'aabbcc'}, {OUT=>'abc'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "[a-c]"])
|
||||||
|
.pipe_in("aabbcc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_c() {
|
||||||
|
// ['c', qw(-s '[a-b]'), {IN=>'aabbcc'}, {OUT=>'abcc'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "[a-b]"])
|
||||||
|
.pipe_in("aabbcc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abcc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_d() {
|
||||||
|
// ['d', qw(-s '[b-c]'), {IN=>'aabbcc'}, {OUT=>'aabc'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "[b-c]"])
|
||||||
|
.pipe_in("aabbcc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("aabc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "I cannot tell if this means that tr preserve the octal representation?"]
|
||||||
|
fn check_against_gnu_tr_tests_e() {
|
||||||
|
// ['e', qw(-s '[\0-\5]'), {IN=>"\0\0a\1\1b\2\2\2c\3\3\3d\4\4\4\4e\5\5"}, {OUT=>"\0a\1b\2c\3d\4e\5"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", r"[\0-\5]"])
|
||||||
|
.pipe_in(
|
||||||
|
"\u{0}\u{0}a\u{1}\u{1}b\u{2}\u{2}\u{2}c\u{3}\u{3}\u{3}d\u{4}\u{4}\u{4}\u{4}e\u{5}\u{5}",
|
||||||
|
)
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("\u{0}a\u{1}b\u{2}c\u{3}d\u{4}e\u{5}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_f() {
|
||||||
|
// # tests of delete
|
||||||
|
// ['f', qw(-d '[=[=]'), {IN=>'[[[[[[[]]]]]]]]'}, {OUT=>']]]]]]]]'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[=[=]"])
|
||||||
|
.pipe_in("[[[[[[[]]]]]]]]")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("]]]]]]]]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_g() {
|
||||||
|
// ['g', qw(-d '[=]=]'), {IN=>'[[[[[[[]]]]]]]]'}, {OUT=>'[[[[[[['}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[=]=]"])
|
||||||
|
.pipe_in("[[[[[[[]]]]]]]]")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("[[[[[[[");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_h() {
|
||||||
|
// ['h', qw(-d '[:xdigit:]'), {IN=>'0123456789acbdefABCDEF'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:xdigit:]"])
|
||||||
|
.pipe_in("0123456789acbdefABCDEF")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_i() {
|
||||||
|
// ['i', qw(-d '[:xdigit:]'), {IN=>'w0x1y2z3456789acbdefABCDEFz'}, {OUT=>'wxyzz'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:xdigit:]"])
|
||||||
|
.pipe_in("w0x1y2z3456789acbdefABCDEFz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("wxyzz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_j() {
|
||||||
|
// ['j', qw(-d '[:digit:]'), {IN=>'0123456789'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:digit:]"])
|
||||||
|
.pipe_in("0123456789")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_k() {
|
||||||
|
// ['k', qw(-d '[:digit:]'), {IN=>'a0b1c2d3e4f5g6h7i8j9k'}, {OUT=>'abcdefghijk'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:digit:]"])
|
||||||
|
.pipe_in("a0b1c2d3e4f5g6h7i8j9k")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abcdefghijk");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_l() {
|
||||||
|
// ['l', qw(-d '[:lower:]'), {IN=>'abcdefghijklmnopqrstuvwxyz'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:lower:]"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_m() {
|
||||||
|
// ['m', qw(-d '[:upper:]'), {IN=>'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:upper:]"])
|
||||||
|
.pipe_in("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_n() {
|
||||||
|
// ['n', qw(-d '[:lower:][:upper:]'), {IN=>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:lower:][:upper:]"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_o() {
|
||||||
|
// ['o', qw(-d '[:alpha:]'), {IN=>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:alpha:]"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_p() {
|
||||||
|
// ['p', qw(-d '[:alnum:]'), {IN=>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:alnum:]"])
|
||||||
|
.pipe_in("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_q() {
|
||||||
|
// ['q', qw(-d '[:alnum:]'), {IN=>'.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.'}, {OUT=>'..'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "[:alnum:]"])
|
||||||
|
.pipe_in(".abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("..");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_r() {
|
||||||
|
// ['r', qw(-ds '[:alnum:]' .),
|
||||||
|
// {IN=>'.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.'},
|
||||||
|
// {OUT=>'.'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-ds", "[:alnum:]", "."])
|
||||||
|
.pipe_in(".abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_s() {
|
||||||
|
// # The classic example, with string2 BSD-style
|
||||||
|
// ['s', qw(-cs '[:alnum:]' '\n'),
|
||||||
|
// {IN=>'The big black fox jumped over the fence.'},
|
||||||
|
// {OUT=>"The\nbig\nblack\nfox\njumped\nover\nthe\nfence\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-cs", "[:alnum:]", "\n"])
|
||||||
|
.pipe_in("The big black fox jumped over the fence.")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("The\nbig\nblack\nfox\njumped\nover\nthe\nfence\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_t() {
|
||||||
|
// # The classic example, POSIX-style
|
||||||
|
// ['t', qw(-cs '[:alnum:]' '[\n*]'),
|
||||||
|
// {IN=>'The big black fox jumped over the fence.'},
|
||||||
|
// {OUT=>"The\nbig\nblack\nfox\njumped\nover\nthe\nfence\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-cs", "[:alnum:]", "[\n*]"])
|
||||||
|
.pipe_in("The big black fox jumped over the fence.")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("The\nbig\nblack\nfox\njumped\nover\nthe\nfence\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_u() {
|
||||||
|
// ['u', qw(-ds b a), {IN=>'aabbaa'}, {OUT=>'a'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-ds", "b", "a"])
|
||||||
|
.pipe_in("aabbaa")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("a");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_v() {
|
||||||
|
// ['v', qw(-ds '[:xdigit:]' Z), {IN=>'ZZ0123456789acbdefABCDEFZZ'}, {OUT=>'Z'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-ds", "[:xdigit:]", "Z"])
|
||||||
|
.pipe_in("ZZ0123456789acbdefABCDEFZZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("Z");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_w() {
|
||||||
|
// # Try some data with 8th bit set in case something is mistakenly
|
||||||
|
// # sign-extended.
|
||||||
|
// ['w', qw(-ds '\350' '\345'),
|
||||||
|
// {IN=>"\300\301\377\345\345\350\345"},
|
||||||
|
// {OUT=>"\300\301\377\345"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-ds", "\u{350}", "\u{345}"])
|
||||||
|
.pipe_in("\u{300}\u{301}\u{377}\u{345}\u{345}\u{350}\u{345}")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("\u{300}\u{301}\u{377}\u{345}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_x() {
|
||||||
|
// ['x', qw(-s abcdefghijklmn '[:*016]'),
|
||||||
|
// {IN=>'abcdefghijklmnop'}, {OUT=>':op'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "abcdefghijklmn", "[:*016]"])
|
||||||
|
.pipe_in("abcdefghijklmnop")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(":op");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_y() {
|
||||||
|
// ['y', qw(-d a-z), {IN=>'abc $code'}, {OUT=>' $'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-d", "a-z"])
|
||||||
|
.pipe_in("abc $code")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(" $");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_z() {
|
||||||
|
// ['z', qw(-ds a-z '$.'), {IN=>'a.b.c $$$$code\\'}, {OUT=>'. $\\'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-ds", "a-z", "$."])
|
||||||
|
.pipe_in("a.b.c $$$$code\\")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(". $\\");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_range_a_a() {
|
||||||
|
// # Make sure that a-a is accepted.
|
||||||
|
// ['range-a-a', qw(a-a z), {IN=>'abc'}, {OUT=>'zbc'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a-a", "z"])
|
||||||
|
.pipe_in("abc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("zbc");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_null() {
|
||||||
|
// ['null', qw(a ''), {IN=>''}, {OUT=>''}, {EXIT=>1},
|
||||||
|
// {ERR=>"$prog: when not truncating set1, string2 must be non-empty\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a", ""])
|
||||||
|
.pipe_in("")
|
||||||
|
.fails()
|
||||||
|
.stderr_is("tr: when not truncating set1, string2 must be non-empty\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_upcase() {
|
||||||
|
// ['upcase', qw('[:lower:]' '[:upper:]'),
|
||||||
|
// {IN=>'abcxyzABCXYZ'},
|
||||||
|
// {OUT=>'ABCXYZABCXYZ'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:lower:]", "[:upper:]"])
|
||||||
|
.pipe_in("abcxyzABCXYZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("ABCXYZABCXYZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_dncase() {
|
||||||
|
// ['dncase', qw('[:upper:]' '[:lower:]'),
|
||||||
|
// {IN=>'abcxyzABCXYZ'},
|
||||||
|
// {OUT=>'abcxyzabcxyz'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:upper:]", "[:lower:]"])
|
||||||
|
.pipe_in("abcxyzABCXYZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abcxyzabcxyz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_rep_cclass() {
|
||||||
|
// ['rep-cclass', qw('a[=*2][=c=]' xyyz), {IN=>'a=c'}, {OUT=>'xyz'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a[=*2][=c=]", "xyyz"])
|
||||||
|
.pipe_in("a=c")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("xyz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_rep_1() {
|
||||||
|
// ['rep-1', qw('[:*3][:digit:]' a-m), {IN=>':1239'}, {OUT=>'cefgm'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[:*3][:digit:]", "a-m"])
|
||||||
|
.pipe_in(":1239")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("cefgm");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_rep_2() {
|
||||||
|
// ['rep-2', qw('a[b*512]c' '1[x*]2'), {IN=>'abc'}, {OUT=>'1x2'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a[b*512]c", "1[x*]2"])
|
||||||
|
.pipe_in("abc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("1x2");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_rep_3() {
|
||||||
|
// ['rep-3', qw('a[b*513]c' '1[x*]2'), {IN=>'abc'}, {OUT=>'1x2'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a[b*513]c", "1[x*]2"])
|
||||||
|
.pipe_in("abc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("1x2");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_o_rep_1() {
|
||||||
|
// # Another couple octal repeat count tests.
|
||||||
|
// ['o-rep-1', qw('[b*08]' '[x*]'), {IN=>''}, {OUT=>''}, {EXIT=>1},
|
||||||
|
// {ERR=>"$prog: invalid repeat count '08' in [c*n] construct\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[b*08]", "[x*]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.fails()
|
||||||
|
.stderr_is("tr: invalid repeat count '08' in [c*n] construct\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_o_rep_2() {
|
||||||
|
// ['o-rep-2', qw('[b*010]cd' '[a*7]BC[x*]'), {IN=>'bcd'}, {OUT=>'BCx'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[b*010]cd", "[a*7]BC[x*]"])
|
||||||
|
.pipe_in("bcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("BCx");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_esc() {
|
||||||
|
// ['esc', qw('a\-z' A-Z), {IN=>'abc-z'}, {OUT=>'AbcBC'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[r"a\-z", "A-Z"])
|
||||||
|
.pipe_in("abc-z")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("AbcBC");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_bs_055() {
|
||||||
|
// ['bs-055', qw('a\055b' def), {IN=>"a\055b"}, {OUT=>'def'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["a\u{055}b", "def"])
|
||||||
|
.pipe_in("a\u{055}b")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("def");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "Failing in Windows because it will not separate '\' and 'x' as separate arguments"]
|
||||||
|
fn check_against_gnu_tr_tests_bs_at_end() {
|
||||||
|
// ['bs-at-end', qw('\\' x), {IN=>"\\"}, {OUT=>'x'},
|
||||||
|
// {ERR=>"$prog: warning: an unescaped backslash at end of "
|
||||||
|
// . "string is not portable\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[r"\", "x"])
|
||||||
|
.pipe_in(r"\")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("x")
|
||||||
|
.stderr_is("tr: warning: an unescaped backslash at end of string is not portable");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "not sure why GNU bails here. `[Y*]` should be able to generate all the mapping"]
|
||||||
|
fn check_against_gnu_tr_tests_ross_0a() {
|
||||||
|
// # From Ross
|
||||||
|
// ['ross-0a', qw(-cs '[:upper:]' 'X[Y*]'), {IN=>''}, {OUT=>''}, {EXIT=>1},
|
||||||
|
// {ERR=>$map_all_to_1}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-cs", "[:upper:]", "X[Y*]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.fails()
|
||||||
|
.stderr_is("tr: when translating with complemented character classes,\nstring2 must map all characters in the domain to one");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "not sure why GNU bails here. `[Y*]` should be able to generate all the mapping"]
|
||||||
|
fn check_against_gnu_tr_tests_ross_0b() {
|
||||||
|
// ['ross-0b', qw(-cs '[:cntrl:]' 'X[Y*]'), {IN=>''}, {OUT=>''}, {EXIT=>1},
|
||||||
|
// {ERR=>$map_all_to_1}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-cs", "[:cntrl:]", "X[Y*]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.fails()
|
||||||
|
.stderr_is("tr: when translating with complemented character classes,\nstring2 must map all characters in the domain to one");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_1a() {
|
||||||
|
// ['ross-1a', qw(-cs '[:upper:]' '[X*]'),
|
||||||
|
// {IN=>'AMZamz123.-+AMZ'}, {OUT=>'AMZXAMZ'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-cs", "[:upper:]", "[X*]"])
|
||||||
|
.pipe_in("AMZamz123.-+AMZ")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("AMZXAMZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_1b() {
|
||||||
|
// ['ross-1b', qw(-cs '[:upper:][:digit:]' '[Z*]'), {IN=>''}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-cs", "[:upper:][:digit:]", "[Z*]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_2() {
|
||||||
|
// ['ross-2', qw(-dcs '[:lower:]' n-rs-z),
|
||||||
|
// {IN=>'amzAMZ123.-+amz'}, {OUT=>'amzamz'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-dcs", "[:lower:]", "n-rs-z"])
|
||||||
|
.pipe_in("amzAMZ123.-+amz")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("amzamz");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_3() {
|
||||||
|
// ['ross-3', qw(-ds '[:xdigit:]' '[:alnum:]'),
|
||||||
|
// {IN=>'.ZABCDEFGzabcdefg.0123456788899.GG'}, {OUT=>'.ZGzg..G'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-ds", "[:xdigit:]", "[:alnum:]"])
|
||||||
|
.pipe_in(".ZABCDEFGzabcdefg.0123456788899.GG")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(".ZGzg..G");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_4() {
|
||||||
|
// ['ross-4', qw(-dcs '[:alnum:]' '[:digit:]'), {IN=>''}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-dcs", "[:alnum:]", "[:digit:]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_5() {
|
||||||
|
// ['ross-5', qw(-dc '[:lower:]'), {IN=>''}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-dc", "[:lower:]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_ross_6() {
|
||||||
|
// ['ross-6', qw(-dc '[:upper:]'), {IN=>''}, {OUT=>''}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-dc", "[:upper:]"])
|
||||||
|
.pipe_in("")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_empty_eq() {
|
||||||
|
// # Ensure that these fail.
|
||||||
|
// # Prior to 2.0.20, each would evoke a failed assertion.
|
||||||
|
// ['empty-eq', qw('[==]' x), {IN=>''}, {OUT=>''}, {EXIT=>1},
|
||||||
|
// {ERR=>"$prog: missing equivalence class character '[==]'\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[==]", "x"])
|
||||||
|
.pipe_in("")
|
||||||
|
.fails()
|
||||||
|
.stderr_is("tr: missing equivalence class character '[==]'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_empty_cc() {
|
||||||
|
// ['empty-cc', qw('[::]' x), {IN=>''}, {OUT=>''}, {EXIT=>1},
|
||||||
|
// {ERR=>"$prog: missing character class name '[::]'\n"}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["[::]", "x"])
|
||||||
|
.pipe_in("")
|
||||||
|
.fails()
|
||||||
|
.stderr_is("tr: missing character class name '[::]'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_repeat_bs_9() {
|
||||||
|
// # Weird repeat counts.
|
||||||
|
// ['repeat-bs-9', qw(abc '[b*\9]'), {IN=>'abcd'}, {OUT=>'[b*d'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abc", r"[b*\9]"])
|
||||||
|
.pipe_in("abcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("[b*d");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_repeat_0() {
|
||||||
|
// ['repeat-0', qw(abc '[b*0]'), {IN=>'abcd'}, {OUT=>'bbbd'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abc", "[b*0]"])
|
||||||
|
.pipe_in("abcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("bbbd");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_repeat_zeros() {
|
||||||
|
// ['repeat-zeros', qw(abc '[b*00000000000000000000]'),
|
||||||
|
// {IN=>'abcd'}, {OUT=>'bbbd'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["abc", "[b*00000000000000000000]"])
|
||||||
|
.pipe_in("abcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("bbbd");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_repeat_compl() {
|
||||||
|
// ['repeat-compl', qw(-c '[a*65536]\n' '[b*]'), {IN=>'abcd'}, {OUT=>'abbb'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-c", "[a*65536]\n", "[b*]"])
|
||||||
|
.pipe_in("abcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abbb");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_repeat_x_c() {
|
||||||
|
// ['repeat-xC', qw(-C '[a*65536]\n' '[b*]'), {IN=>'abcd'}, {OUT=>'abbb'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-C", "[a*65536]\n", "[b*]"])
|
||||||
|
.pipe_in("abcd")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abbb");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "I think either clap-rs or uutils is parsing the '-H' as an argument..."]
|
||||||
|
fn check_against_gnu_tr_tests_fowler_1() {
|
||||||
|
// # From Glenn Fowler.
|
||||||
|
// ['fowler-1', qw(ah -H), {IN=>'aha'}, {OUT=>'-H-'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["ah", "-H"])
|
||||||
|
.pipe_in("aha")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("-H-");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_against_gnu_tr_tests_no_abort_1() {
|
||||||
|
// # Up to coreutils-6.9, this would provoke a failed assertion.
|
||||||
|
// ['no-abort-1', qw(-c a '[b*256]'), {IN=>'abc'}, {OUT=>'abb'}],
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-c", "a", "[b*256]"])
|
||||||
|
.pipe_in("abc")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("abb");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue