mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Implements project testfing from root.
- conv=FLAG testing. (1) WIP conv=nocreat - iflag & oflag testing. - conv=CONV ascii,...,ucase,...,block,...sync tests at unit-test-level (project root is todo)
This commit is contained in:
parent
47464f50a1
commit
17cfba41cc
29 changed files with 1376 additions and 187 deletions
148
Cargo.lock
generated
148
Cargo.lock
generated
|
@ -98,16 +98,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814"
|
checksum = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byte-tools",
|
"byte-tools",
|
||||||
"generic-array 0.8.4",
|
"generic-array",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "block-buffer"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array 0.14.4",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -569,16 +560,7 @@ version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a"
|
checksum = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.8.4",
|
"generic-array",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "digest"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array 0.14.4",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -655,16 +637,6 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "generic-array"
|
|
||||||
version = "0.14.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
|
||||||
dependencies = [
|
|
||||||
"typenum",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getopts"
|
name = "getopts"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
|
@ -682,7 +654,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"libc",
|
||||||
|
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -718,12 +701,6 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
|
checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hex-literal"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hostname"
|
name = "hostname"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -832,17 +809,6 @@ version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "md-5"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
|
|
||||||
dependencies = [
|
|
||||||
"block-buffer 0.9.0",
|
|
||||||
"digest 0.9.0",
|
|
||||||
"opaque-debug",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md5"
|
name = "md5"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
@ -973,12 +939,6 @@ version = "11.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "opaque-debug"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "0.1.18"
|
version = "0.1.18"
|
||||||
|
@ -1115,14 +1075,26 @@ version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.1.16",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.2.2",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
"rand_hc",
|
"rand_hc 0.2.0",
|
||||||
"rand_pcg",
|
"rand_pcg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.3.1",
|
||||||
|
"rand_core 0.6.3",
|
||||||
|
"rand_hc 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -1133,6 +1105,16 @@ dependencies = [
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.6.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -1154,7 +1136,16 @@ version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.1.16",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1166,6 +1157,15 @@ dependencies = [
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.6.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_pcg"
|
name = "rand_pcg"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -1366,11 +1366,11 @@ version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a"
|
checksum = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer 0.2.0",
|
"block-buffer",
|
||||||
"byte-tools",
|
"byte-tools",
|
||||||
"digest 0.6.2",
|
"digest",
|
||||||
"fake-simd",
|
"fake-simd",
|
||||||
"generic-array 0.8.4",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1379,10 +1379,10 @@ version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0"
|
checksum = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer 0.2.0",
|
"block-buffer",
|
||||||
"byte-tools",
|
"byte-tools",
|
||||||
"digest 0.6.2",
|
"digest",
|
||||||
"generic-array 0.8.4",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1759,10 +1759,10 @@ dependencies = [
|
||||||
"debug_print",
|
"debug_print",
|
||||||
"gcd",
|
"gcd",
|
||||||
"getopts",
|
"getopts",
|
||||||
"hex-literal",
|
|
||||||
"libc",
|
"libc",
|
||||||
"md-5",
|
"rand 0.8.4",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
|
"tempfile",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
@ -1854,7 +1854,7 @@ dependencies = [
|
||||||
"paste",
|
"paste",
|
||||||
"quickcheck",
|
"quickcheck",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rand_chacha",
|
"rand_chacha 0.2.2",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
|
@ -1902,7 +1902,7 @@ version = "0.0.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2-rfc",
|
"blake2-rfc",
|
||||||
"clap",
|
"clap",
|
||||||
"digest 0.6.2",
|
"digest",
|
||||||
"hex",
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
"md5",
|
"md5",
|
||||||
|
@ -2621,12 +2621,6 @@ version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "void"
|
name = "void"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -2650,6 +2644,12 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.71"
|
version = "0.2.71"
|
||||||
|
|
|
@ -17,7 +17,7 @@ path = "src/dd.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byte-unit = "4.0"
|
byte-unit = "4.0"
|
||||||
debug_print = "1.0"
|
debug_print = "1.0"
|
||||||
# Probably best to keep this identical to the version of getopts in the uucore crate
|
# Probably best to keep the getopts version identical to the version of getopts in the uucore crate
|
||||||
getopts = "<= 0.2.21"
|
getopts = "<= 0.2.21"
|
||||||
gcd = "2.0"
|
gcd = "2.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
@ -26,8 +26,8 @@ uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
md-5 = "0.9"
|
rand = "0.8"
|
||||||
hex-literal = "0.3"
|
tempfile = "^3"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "dd"
|
name = "dd"
|
||||||
|
|
|
@ -361,19 +361,32 @@ impl<R: Read> Read for Input<R>
|
||||||
{
|
{
|
||||||
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize>
|
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize>
|
||||||
{
|
{
|
||||||
match self.src.read(&mut buf)
|
let mut base_idx = 0;
|
||||||
|
let tlen = buf.len();
|
||||||
|
loop
|
||||||
{
|
{
|
||||||
Ok(len) =>
|
match self.src.read(&mut buf[base_idx..])
|
||||||
Ok(len),
|
|
||||||
Err(e) =>
|
|
||||||
if !self.cflags.noerror
|
|
||||||
{
|
{
|
||||||
Err(e)
|
Ok(0) =>
|
||||||
|
return Ok(base_idx),
|
||||||
|
Ok(rlen) if self.iflags.fullblock =>
|
||||||
|
{
|
||||||
|
base_idx += rlen;
|
||||||
|
|
||||||
|
if base_idx >= tlen
|
||||||
|
{
|
||||||
|
return Ok(tlen)
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Ok(0)
|
|
||||||
},
|
},
|
||||||
|
Ok(len) =>
|
||||||
|
return Ok(len),
|
||||||
|
Err(e) if e.kind() == io::ErrorKind::Interrupted =>
|
||||||
|
continue,
|
||||||
|
Err(_) if self.cflags.noerror =>
|
||||||
|
return Ok(base_idx),
|
||||||
|
Err(e) =>
|
||||||
|
return Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,6 +542,11 @@ fn make_unix_oflags(oflags: &OFlags) -> Option<libc::c_int>
|
||||||
{
|
{
|
||||||
let mut flag = 0;
|
let mut flag = 0;
|
||||||
|
|
||||||
|
// oflag=FLAG
|
||||||
|
if oflags.append
|
||||||
|
{
|
||||||
|
flag |= libc::O_APPEND;
|
||||||
|
}
|
||||||
if oflags.direct
|
if oflags.direct
|
||||||
{
|
{
|
||||||
flag |= libc::O_DIRECT;
|
flag |= libc::O_DIRECT;
|
||||||
|
@ -585,9 +603,11 @@ impl Output<File> {
|
||||||
let mut dst = {
|
let mut dst = {
|
||||||
let mut opts = OpenOptions::new();
|
let mut opts = OpenOptions::new();
|
||||||
opts.write(true)
|
opts.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(!cflags.notrunc)
|
||||||
.append(oflags.append)
|
.append(oflags.append)
|
||||||
.create_new(cflags.excl || !cflags.nocreat)
|
// 'create_new' overrides 'create'
|
||||||
.truncate(!cflags.notrunc);
|
.create_new(cflags.excl && !cflags.nocreat);
|
||||||
|
|
||||||
if cfg!(unix)
|
if cfg!(unix)
|
||||||
{
|
{
|
||||||
|
@ -1484,47 +1504,57 @@ fn append_dashes_if_not_present(mut acc: Vec<String>, s: &String) -> Vec<String>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! unpack_or_rtn (
|
||||||
|
($i:expr, $o:expr) =>
|
||||||
|
{{
|
||||||
|
match ($i, $o)
|
||||||
|
{
|
||||||
|
(Ok(i), Ok(o)) =>
|
||||||
|
(i,o),
|
||||||
|
(Err(e), _) =>
|
||||||
|
{
|
||||||
|
eprintln!("dd Error: {}", e);
|
||||||
|
return RTN_FAILURE;
|
||||||
|
},
|
||||||
|
(_, Err(e)) =>
|
||||||
|
{
|
||||||
|
eprintln!("dd Error: {}", e);
|
||||||
|
return RTN_FAILURE;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
);
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32
|
pub fn uumain(args: impl uucore::Args) -> i32
|
||||||
{
|
{
|
||||||
let dashed_args = args.collect_str()
|
let dashed_args = args.collect_str()
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Vec::new(), append_dashes_if_not_present);
|
.fold(Vec::new(), append_dashes_if_not_present);
|
||||||
let matches = build_app!().parse(dashed_args);
|
let matches = build_app!().parse(dashed_args);
|
||||||
|
|
||||||
let result = match (matches.opt_present("if"), matches.opt_present("of"))
|
let result = match (matches.opt_present("if"), matches.opt_present("of"))
|
||||||
{
|
{
|
||||||
(true, true) =>
|
(true, true) =>
|
||||||
{
|
{
|
||||||
let i = Input::<File>::new(&matches)
|
let (i, o) = unpack_or_rtn!(Input::<File>::new(&matches), Output::<File>::new(&matches));
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
let o = Output::<File>::new(&matches)
|
dd_fileout(i,o)
|
||||||
.expect("TODO: Return correct error code");
|
},
|
||||||
|
(false, true) =>
|
||||||
|
{
|
||||||
|
let (i, o) = unpack_or_rtn!(Input::<io::Stdin>::new(&matches), Output::<File>::new(&matches));
|
||||||
|
|
||||||
dd_fileout(i,o)
|
dd_fileout(i,o)
|
||||||
},
|
},
|
||||||
(true, false) =>
|
(true, false) =>
|
||||||
{
|
{
|
||||||
let i = Input::<File>::new(&matches)
|
let (i, o) = unpack_or_rtn!(Input::<File>::new(&matches), Output::<io::Stdout>::new(&matches));
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
let o = Output::<io::Stdout>::new(&matches)
|
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
|
|
||||||
dd_stdout(i,o)
|
dd_stdout(i,o)
|
||||||
},
|
},
|
||||||
(false, true) =>
|
|
||||||
{
|
|
||||||
let i = Input::<io::Stdin>::new(&matches)
|
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
let o = Output::<File>::new(&matches)
|
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
|
|
||||||
dd_fileout(i,o)
|
|
||||||
},
|
|
||||||
(false, false) =>
|
(false, false) =>
|
||||||
{
|
{
|
||||||
let i = Input::<io::Stdin>::new(&matches)
|
let (i, o) = unpack_or_rtn!(Input::<io::Stdin>::new(&matches), Output::<io::Stdout>::new(&matches));
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
let o = Output::<io::Stdout>::new(&matches)
|
|
||||||
.expect("TODO: Return correct error code");
|
|
||||||
|
|
||||||
dd_stdout(i,o)
|
dd_stdout(i,o)
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
struct LazyReader<R: Read>
|
|
||||||
{
|
|
||||||
src: R,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: Read> Read for LazyReader<R>
|
|
||||||
{
|
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
|
|
||||||
{
|
|
||||||
let reduced = cmp::max(buf.len() / 2, 1);
|
|
||||||
self.src.read(&mut buf[..reduced])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! make_sync_test (
|
macro_rules! make_sync_test (
|
||||||
( $test_id:ident, $test_name:expr, $src:expr, $sync:expr, $ibs:expr, $obs:expr, $spec:expr ) =>
|
( $test_id:ident, $test_name:expr, $src:expr, $sync:expr, $ibs:expr, $obs:expr, $spec:expr ) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,14 +5,10 @@ mod conversion_tests;
|
||||||
mod block_unblock_tests;
|
mod block_unblock_tests;
|
||||||
mod conv_sync_tests;
|
mod conv_sync_tests;
|
||||||
|
|
||||||
|
use rand::prelude::*;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use md5::{ Md5, Digest, };
|
|
||||||
use hex_literal::hex;
|
|
||||||
|
|
||||||
// use tempfile::tempfile;
|
|
||||||
// TODO: (Maybe) Use tempfiles in the tests.
|
|
||||||
|
|
||||||
const DEFAULT_CFO: OConvFlags = OConvFlags {
|
const DEFAULT_CFO: OConvFlags = OConvFlags {
|
||||||
sparse: false,
|
sparse: false,
|
||||||
|
@ -60,6 +56,40 @@ const DEFAULT_OFLAGS: OFlags = OFlags {
|
||||||
seek_bytes: false,
|
seek_bytes: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LazyReader<R: Read>
|
||||||
|
{
|
||||||
|
src: R,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read> Read for LazyReader<R>
|
||||||
|
{
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
|
||||||
|
{
|
||||||
|
let reduced = cmp::max(buf.len() / 2, 1);
|
||||||
|
self.src.read(&mut buf[..reduced])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FickleReader<R: Read>
|
||||||
|
{
|
||||||
|
src: R,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read> Read for FickleReader<R>
|
||||||
|
{
|
||||||
|
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize>
|
||||||
|
{
|
||||||
|
if rand::random()
|
||||||
|
{
|
||||||
|
self.src.read(&mut buf)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! icf (
|
macro_rules! icf (
|
||||||
() =>
|
() =>
|
||||||
|
|
|
@ -212,6 +212,86 @@ make_io_test!(
|
||||||
File::open("./test-resources/gnudd-random-first-32k.spec").unwrap()
|
File::open("./test-resources/gnudd-random-first-32k.spec").unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
make_io_test!(
|
||||||
|
random_73k_test_lazy_fullblock,
|
||||||
|
"random-73k-test-lazy-fullblock",
|
||||||
|
Input {
|
||||||
|
src: LazyReader {
|
||||||
|
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
|
||||||
|
},
|
||||||
|
non_ascii: false,
|
||||||
|
ibs: 521,
|
||||||
|
xfer_stats: None,
|
||||||
|
count: None,
|
||||||
|
cflags: icf!(),
|
||||||
|
iflags: IFlags {
|
||||||
|
fullblock: true,
|
||||||
|
cio: false,
|
||||||
|
direct: false,
|
||||||
|
directory: false,
|
||||||
|
dsync: false,
|
||||||
|
sync: false,
|
||||||
|
nocache: false,
|
||||||
|
nonblock: false,
|
||||||
|
noatime: false,
|
||||||
|
noctty: false,
|
||||||
|
nofollow: false,
|
||||||
|
nolinks: false,
|
||||||
|
binary: false,
|
||||||
|
text: false,
|
||||||
|
count_bytes: false,
|
||||||
|
skip_bytes: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Output {
|
||||||
|
dst: DST_PLACEHOLDER,
|
||||||
|
obs: 1031,
|
||||||
|
cflags: DEFAULT_CFO,
|
||||||
|
oflags: DEFAULT_OFLAGS,
|
||||||
|
},
|
||||||
|
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
make_io_test!(
|
||||||
|
random_73k_test_fickle_fullblock,
|
||||||
|
"random-73k-test-fickle-fullblock",
|
||||||
|
Input {
|
||||||
|
src: FickleReader {
|
||||||
|
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
|
||||||
|
},
|
||||||
|
non_ascii: false,
|
||||||
|
ibs: 521,
|
||||||
|
xfer_stats: None,
|
||||||
|
count: None,
|
||||||
|
cflags: icf!(),
|
||||||
|
iflags: IFlags {
|
||||||
|
fullblock: true,
|
||||||
|
cio: false,
|
||||||
|
direct: false,
|
||||||
|
directory: false,
|
||||||
|
dsync: false,
|
||||||
|
sync: false,
|
||||||
|
nocache: false,
|
||||||
|
nonblock: false,
|
||||||
|
noatime: false,
|
||||||
|
noctty: false,
|
||||||
|
nofollow: false,
|
||||||
|
nolinks: false,
|
||||||
|
binary: false,
|
||||||
|
text: false,
|
||||||
|
count_bytes: false,
|
||||||
|
skip_bytes: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Output {
|
||||||
|
dst: DST_PLACEHOLDER,
|
||||||
|
obs: 1031,
|
||||||
|
cflags: DEFAULT_CFO,
|
||||||
|
oflags: DEFAULT_OFLAGS,
|
||||||
|
},
|
||||||
|
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
// Test internal buffer size fn
|
// Test internal buffer size fn
|
||||||
#[test]
|
#[test]
|
||||||
fn bsize_test_primes()
|
fn bsize_test_primes()
|
||||||
|
|
|
@ -33,7 +33,53 @@ pub enum ParseError
|
||||||
impl std::fmt::Display for ParseError
|
impl std::fmt::Display for ParseError
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "dd-args: Parse Error")
|
match self
|
||||||
|
{
|
||||||
|
Self::MultipleFmtTable =>
|
||||||
|
{
|
||||||
|
write!(f, "Only one of conv=ascii conv=ebcdic or conv=ibm may be specified")
|
||||||
|
},
|
||||||
|
Self::MultipleUCaseLCase =>
|
||||||
|
{
|
||||||
|
write!(f, "Only one of conv=lcase or conv=ucase may be specified")
|
||||||
|
},
|
||||||
|
Self::MultipleBlockUnblock =>
|
||||||
|
{
|
||||||
|
write!(f, "Only one of conv=block or conv=unblock may be specified")
|
||||||
|
},
|
||||||
|
Self::MultipleExclNoCreat =>
|
||||||
|
{
|
||||||
|
write!(f, "Only one ov conv=excl or conv=nocreat may be specified")
|
||||||
|
},
|
||||||
|
Self::FlagNoMatch(arg) =>
|
||||||
|
{
|
||||||
|
write!(f, "Unrecognized iflag=FLAG or oflag=FLAG -> {}", arg)
|
||||||
|
},
|
||||||
|
Self::ConvFlagNoMatch(arg) =>
|
||||||
|
{
|
||||||
|
write!(f, "Unrecognized conv=CONV -> {}", arg)
|
||||||
|
},
|
||||||
|
Self::NoMatchingMultiplier(arg) =>
|
||||||
|
{
|
||||||
|
write!(f, "Unrecognized byte multiplier -> {}", arg)
|
||||||
|
},
|
||||||
|
Self::ByteStringContainsNoValue(arg) =>
|
||||||
|
{
|
||||||
|
write!(f, "Unrecognized byte value -> {}", arg)
|
||||||
|
},
|
||||||
|
Self::MultiplierStringWouldOverflow(arg) =>
|
||||||
|
{
|
||||||
|
write!(f, "Multiplier string would overflow on current system -> {}", arg)
|
||||||
|
},
|
||||||
|
Self::BlockUnblockWithoutCBS =>
|
||||||
|
{
|
||||||
|
write!(f, "conv=block or conv=unblock specified without cbs=N")
|
||||||
|
},
|
||||||
|
Self::StatusLevelNotRecognized(arg) =>
|
||||||
|
{
|
||||||
|
write!(f, "status=LEVEL not recognized -> {}", arg)
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +316,9 @@ fn parse_bytes_only(s: &str) -> Result<usize, ParseError>
|
||||||
|
|
||||||
fn parse_bytes_with_opt_multiplier(s: String) -> Result<usize, ParseError>
|
fn parse_bytes_with_opt_multiplier(s: String) -> Result<usize, ParseError>
|
||||||
{
|
{
|
||||||
if let Some(idx) = s.find(char::is_alphabetic)
|
match s.find(char::is_alphabetic)
|
||||||
|
{
|
||||||
|
Some(idx) =>
|
||||||
{
|
{
|
||||||
let base = parse_bytes_only(&s[..idx])?;
|
let base = parse_bytes_only(&s[..idx])?;
|
||||||
let mult = parse_multiplier(&s[idx..])?;
|
let mult = parse_multiplier(&s[idx..])?;
|
||||||
|
@ -284,9 +332,8 @@ fn parse_bytes_with_opt_multiplier(s: String) -> Result<usize, ParseError>
|
||||||
Err(ParseError::MultiplierStringWouldOverflow(s))
|
Err(ParseError::MultiplierStringWouldOverflow(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
_ =>
|
||||||
{
|
parse_bytes_only(&s),
|
||||||
parse_bytes_only(&s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,107 @@
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
|
use std::io::{BufReader, Read, Write};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::fs::{self, OpenOptions, File};
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
use tempfile::tempfile;
|
||||||
|
|
||||||
|
macro_rules! inf
|
||||||
|
{
|
||||||
|
($fname:expr) =>
|
||||||
|
{{
|
||||||
|
&format!("if={}", $fname)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! of
|
||||||
|
{
|
||||||
|
($fname:expr) =>
|
||||||
|
{{
|
||||||
|
&format!("of={}", $fname)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! fixture_path
|
||||||
|
{
|
||||||
|
($fname:expr) =>
|
||||||
|
{{
|
||||||
|
PathBuf::from(format!("./tests/fixtures/dd/{}", $fname))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_fixture_exists
|
||||||
|
{
|
||||||
|
($fname:expr) =>
|
||||||
|
{{
|
||||||
|
let fpath = fixture_path!($fname);
|
||||||
|
if !fpath.exists()
|
||||||
|
{
|
||||||
|
panic!("Fixture missing: {:?}", fpath);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_fixture_not_exists
|
||||||
|
{
|
||||||
|
($fname:expr) =>
|
||||||
|
{{
|
||||||
|
let fpath = PathBuf::from(format!("./fixtures/dd/{}", $fname));
|
||||||
|
if fpath.exists()
|
||||||
|
{
|
||||||
|
panic!("Fixture present: {:?}", fpath);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! build_test_file {
|
||||||
|
($fp:expr, $data:expr) => {{
|
||||||
|
OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open($fp)
|
||||||
|
.unwrap()
|
||||||
|
.write_all($data)
|
||||||
|
.unwrap()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! cmp_file (
|
||||||
|
($spec:expr, $test:expr) =>
|
||||||
|
{
|
||||||
|
let specfile_len = $spec.metadata().unwrap().len();
|
||||||
|
let testfile_len = $test.metadata().unwrap().len();
|
||||||
|
assert_eq!(testfile_len, specfile_len);
|
||||||
|
|
||||||
|
let spec = BufReader::new($spec);
|
||||||
|
let test = BufReader::new($test);
|
||||||
|
|
||||||
|
for (b_spec, b_test) in spec.bytes().zip(test.bytes())
|
||||||
|
{
|
||||||
|
assert_eq!(b_spec.unwrap(),
|
||||||
|
b_test.unwrap());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
|
fn build_ascii_block(n: usize) -> Vec<u8>
|
||||||
|
{
|
||||||
|
(0..=127)
|
||||||
|
.cycle()
|
||||||
|
.take(n)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_ebcdic_block(n: usize) -> Vec<u8>
|
||||||
|
{
|
||||||
|
(0..=255)
|
||||||
|
.cycle()
|
||||||
|
.take(n)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity Tests
|
||||||
#[test]
|
#[test]
|
||||||
fn version()
|
fn version()
|
||||||
{
|
{
|
||||||
|
@ -16,16 +118,6 @@ fn help()
|
||||||
.succeeds();
|
.succeeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ascii_block(n: usize) -> Vec<u8>
|
|
||||||
{
|
|
||||||
vec!['a', 'b', 'c', 'd', 'e', 'f']
|
|
||||||
.into_iter()
|
|
||||||
.map(|c| c as u8)
|
|
||||||
.cycle()
|
|
||||||
.take(n)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_stdin_stdout()
|
fn test_stdin_stdout()
|
||||||
{
|
{
|
||||||
|
@ -34,10 +126,13 @@ fn test_stdin_stdout()
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&["status=none"])
|
.args(&["status=none"])
|
||||||
.pipe_in(input)
|
.pipe_in(input)
|
||||||
.succeeds()
|
.run()
|
||||||
|
.no_stderr()
|
||||||
.stdout_only(output);
|
.stdout_only(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Top-Level Items
|
||||||
|
// count=N, skip=N, status=LEVEL, conv=FLAG, *flag=FLAG
|
||||||
#[test]
|
#[test]
|
||||||
fn test_stdin_stdout_count()
|
fn test_stdin_stdout_count()
|
||||||
{
|
{
|
||||||
|
@ -51,7 +146,8 @@ fn test_stdin_stdout_count()
|
||||||
"ibs=128",
|
"ibs=128",
|
||||||
])
|
])
|
||||||
.pipe_in(input)
|
.pipe_in(input)
|
||||||
.succeeds()
|
.run()
|
||||||
|
.no_stderr()
|
||||||
.stdout_only(output);
|
.stdout_only(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +164,8 @@ fn test_stdin_stdout_count_bytes()
|
||||||
"iflag=count_bytes",
|
"iflag=count_bytes",
|
||||||
])
|
])
|
||||||
.pipe_in(input)
|
.pipe_in(input)
|
||||||
.succeeds()
|
.run()
|
||||||
|
.no_stderr()
|
||||||
.stdout_only(output);
|
.stdout_only(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +182,8 @@ fn test_stdin_stdout_skip()
|
||||||
"ibs=128",
|
"ibs=128",
|
||||||
])
|
])
|
||||||
.pipe_in(input)
|
.pipe_in(input)
|
||||||
.succeeds()
|
.run()
|
||||||
|
.no_stderr()
|
||||||
.stdout_only(output);
|
.stdout_only(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,10 +201,47 @@ fn test_stdin_stdout_skip_bytes()
|
||||||
"iflag=skip_bytes",
|
"iflag=skip_bytes",
|
||||||
])
|
])
|
||||||
.pipe_in(input)
|
.pipe_in(input)
|
||||||
.succeeds()
|
.run()
|
||||||
|
.no_stderr()
|
||||||
.stdout_only(output);
|
.stdout_only(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stdin_stdout_skip_w_multiplier()
|
||||||
|
{
|
||||||
|
let input = build_ascii_block(10*1024);
|
||||||
|
let output = String::from_utf8(input[5*1024..].to_vec()).unwrap();
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[
|
||||||
|
"status=none",
|
||||||
|
"skip=5K",
|
||||||
|
"iflag=skip_bytes"
|
||||||
|
])
|
||||||
|
.pipe_in(input)
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.stdout_is(output)
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stdin_stdout_count_w_multiplier()
|
||||||
|
{
|
||||||
|
let input = build_ascii_block(5*1024);
|
||||||
|
let output = String::from_utf8(input[..2*1024].to_vec()).unwrap();
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[
|
||||||
|
"status=none",
|
||||||
|
"count=2KiB",
|
||||||
|
"iflag=count_bytes",
|
||||||
|
])
|
||||||
|
.pipe_in(input)
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.stdout_is(output)
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_final_stats_noxfer()
|
fn test_final_stats_noxfer()
|
||||||
{
|
{
|
||||||
|
@ -133,49 +268,246 @@ fn test_final_stats_unspec()
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.succeeds()
|
.run()
|
||||||
.stderr_only(&output);
|
.stderr_only(&output)
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_self_transfer()
|
fn test_excl_causes_failure_when_present()
|
||||||
{
|
{
|
||||||
panic!();
|
let fname = "this-file-exists-excl.txt";
|
||||||
// TODO: Make new copy per-test
|
assert_fixture_exists!(&fname);
|
||||||
new_ucmd!()
|
|
||||||
.args(&[
|
let (_fix, mut ucmd) = at_and_ucmd!();
|
||||||
"conv=notruc",
|
ucmd.args(&[
|
||||||
"if=../fixtures/dd/zero-256k.copy",
|
"of=this-file-exists-excl.txt",
|
||||||
"of=../fixtures/dd/zero-256k.copy",
|
"conv=excl",
|
||||||
])
|
])
|
||||||
.succeeds();
|
.fails();
|
||||||
assert!(false/* Must check that zero256k.copy still == zero-256k.txt */)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_null()
|
fn test_atime_updated()
|
||||||
|
{
|
||||||
|
let fname = "this-file-exists-no-noatime.txt";
|
||||||
|
assert_fixture_exists!(&fname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
inf!(fname),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let pre_atime = fix.metadata(&fname).accessed().unwrap();
|
||||||
|
|
||||||
|
ucmd.pipe_in("")
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
let post_atime = fix.metadata(&fname).accessed().unwrap();
|
||||||
|
assert!(pre_atime != post_atime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_noatime_does_not_update_infile_atime()
|
||||||
|
{
|
||||||
|
let fname = "this-ifile-exists-noatime.txt";
|
||||||
|
assert_fixture_exists!(&fname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
"iflag=noatime",
|
||||||
|
inf!(fname),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let pre_atime = fix.metadata(&fname).accessed().unwrap();
|
||||||
|
|
||||||
|
ucmd.run()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
let post_atime = fix.metadata(&fname).accessed().unwrap();
|
||||||
|
assert_eq!(pre_atime, post_atime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_noatime_does_not_update_ofile_atime()
|
||||||
|
{
|
||||||
|
let fname = "this-ofile-exists-noatime.txt";
|
||||||
|
assert_fixture_exists!(&fname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
"oflag=noatime",
|
||||||
|
of!(fname),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let pre_atime = fix.metadata(&fname).accessed().unwrap();
|
||||||
|
|
||||||
|
ucmd.pipe_in("")
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
let post_atime = fix.metadata(&fname).accessed().unwrap();
|
||||||
|
assert_eq!(pre_atime, post_atime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_nocreat_causes_failure_when_not_present()
|
||||||
|
{
|
||||||
|
let fname = "this-file-does-not-exist.txt";
|
||||||
|
assert_fixture_not_exists!(&fname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"conv=nocreat",
|
||||||
|
of!(&fname),
|
||||||
|
])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
assert!(!fix.file_exists(&fname));
|
||||||
|
|
||||||
|
ucmd.fails();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_notrunc_does_not_truncate()
|
||||||
|
{
|
||||||
|
// Set up test if needed (eg. after failure)
|
||||||
|
let fname = "this-file-exists-notrunc.txt";
|
||||||
|
let fpath = fixture_path!(fname);
|
||||||
|
match fpath.metadata()
|
||||||
|
{
|
||||||
|
Ok(m) if m.len() == 256 => {},
|
||||||
|
_ =>
|
||||||
|
build_test_file!(&fpath, &build_ascii_block(256)),
|
||||||
|
}
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
"conv=notrunc",
|
||||||
|
of!(&fname),
|
||||||
|
"if=null.txt",
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stdout()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
assert_eq!(256, fix.metadata(&fname).len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_existing_file_truncated()
|
||||||
|
{
|
||||||
|
// Set up test if needed (eg. after failure)
|
||||||
|
let fname = "this-file-exists-truncated.txt";
|
||||||
|
let fpath = fixture_path!(fname);
|
||||||
|
match fpath.metadata()
|
||||||
|
{
|
||||||
|
Ok(m) if m.len() == 256 => {},
|
||||||
|
_ =>
|
||||||
|
build_test_file!(&fpath, &vec![0; 256]),
|
||||||
|
}
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
"if=null.txt",
|
||||||
|
of!(fname),
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stdout()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
assert_eq!(0, fix.metadata(&fname).len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_null_stats()
|
||||||
{
|
{
|
||||||
let stats = vec![
|
let stats = vec![
|
||||||
"0+0 records in",
|
"0+0 records in\n",
|
||||||
"0+0 records out",
|
"0+0 records out\n",
|
||||||
"0 bytes (0 B, 0 B) copied, 0.0 s, 0 B/s",
|
"0 bytes (0 B, 0 B) copied, 0.0 s, 0 B/s\n",
|
||||||
];
|
];
|
||||||
let stats = stats.into_iter()
|
let stats = stats.into_iter()
|
||||||
.fold(String::new(), | mut acc, s | {
|
.fold(String::new(), | mut acc, s | {
|
||||||
acc.push_str(s);
|
acc.push_str(s);
|
||||||
acc.push('\n');
|
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&[
|
.args(&[
|
||||||
"if=/dev/null",
|
"if=null.txt",
|
||||||
])
|
])
|
||||||
.succeeds()
|
.run()
|
||||||
.stderr_only(stats)
|
.stderr_only(stats)
|
||||||
.stdout_only("");
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_null_fullblock()
|
||||||
|
{
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[
|
||||||
|
"if=null.txt",
|
||||||
|
"status=none",
|
||||||
|
"iflag=fullblock",
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stdout()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
// #[ignore] // See note below before running this test!
|
||||||
|
#[test]
|
||||||
|
fn test_fullblock()
|
||||||
|
{
|
||||||
|
let tname = "fullblock-from-urand";
|
||||||
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
||||||
|
let stats = vec![
|
||||||
|
"1+0 records in\n",
|
||||||
|
"1+0 records out\n",
|
||||||
|
"134217728 bytes (134 MB, 128 MiB) copied,",
|
||||||
|
];
|
||||||
|
let stats = stats.into_iter()
|
||||||
|
.fold(String::new(), | mut acc, s | {
|
||||||
|
acc.push_str(s);
|
||||||
|
acc
|
||||||
|
});
|
||||||
|
|
||||||
|
let res = new_ucmd!()
|
||||||
|
.args(&[
|
||||||
|
"if=/dev/urandom",
|
||||||
|
of!(&tmp_fn),
|
||||||
|
"bs=128M",
|
||||||
|
// Note: In order for this test to actually test iflag=fullblock, the bs=VALUE
|
||||||
|
// must be big enough to 'overwhelm' urandom's store of bytes.
|
||||||
|
// Try executing 'dd if=/dev/urandom bs=128M count=1' (i.e without iflag=fullblock).
|
||||||
|
// The stats should contain the line: '0+1 records in' indicating a partial read.
|
||||||
|
// Since my system only copies 32 MiB without fullblock, I expect 128 MiB to be
|
||||||
|
// a reasonable value for testing most systems.
|
||||||
|
"count=1",
|
||||||
|
"iflag=fullblock",
|
||||||
|
])
|
||||||
|
.run();
|
||||||
|
|
||||||
|
res.success();
|
||||||
|
let res_stats = &res.stderr[..stats.len()];
|
||||||
|
assert_eq!(&stats, res_stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fileio
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ys_to_stdout()
|
fn test_ys_to_stdout()
|
||||||
{
|
{
|
||||||
|
@ -188,10 +520,13 @@ fn test_ys_to_stdout()
|
||||||
|
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&[
|
.args(&[
|
||||||
"if=../fixtures/dd/y-nl-1k.txt",
|
"status=none",
|
||||||
|
"if=y-nl-1k.txt",
|
||||||
])
|
])
|
||||||
.run()
|
.run()
|
||||||
.stdout_only(output);
|
.no_stderr()
|
||||||
|
.stdout_is(output)
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -201,9 +536,176 @@ fn test_zeros_to_stdout()
|
||||||
let output = String::from_utf8(output).unwrap();
|
let output = String::from_utf8(output).unwrap();
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&[
|
.args(&[
|
||||||
"if=../fixtures/dd/zero-256k.txt",
|
"status=none",
|
||||||
|
"if=zero-256k.txt",
|
||||||
])
|
])
|
||||||
.run()
|
.run()
|
||||||
.stdout_only(output);
|
.no_stderr()
|
||||||
|
.stdout_is(output)
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_stdout_with_ibs_obs()
|
||||||
|
{
|
||||||
|
let output: Vec<_> = String::from("y\n")
|
||||||
|
.bytes()
|
||||||
|
.cycle()
|
||||||
|
.take(1024)
|
||||||
|
.collect();
|
||||||
|
let output = String::from_utf8(output).unwrap();
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[
|
||||||
|
"status=none",
|
||||||
|
"if=y-nl-1k.txt",
|
||||||
|
"ibs=521",
|
||||||
|
"obs=1031",
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.stdout_is(output)
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ascii_10k_to_stdout()
|
||||||
|
{
|
||||||
|
let output = build_ascii_block(1024*1024);
|
||||||
|
// build_test_file!("ascii-10k.txt", &output);
|
||||||
|
let output = String::from_utf8(output).unwrap();
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[
|
||||||
|
"status=none",
|
||||||
|
"if=ascii-10k.txt",
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.stdout_is(output)
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_zeros_to_file()
|
||||||
|
{
|
||||||
|
let tname = "zero-256k";
|
||||||
|
let test_fn = format!("{}.txt", tname);
|
||||||
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
inf!(test_fn),
|
||||||
|
of!(tmp_fn),
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
cmp_file!(File::open(fixture_path!(&test_fn)).unwrap(),
|
||||||
|
fix.open(&tmp_fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_file_with_ibs_obs()
|
||||||
|
{
|
||||||
|
let tname = "zero-256k";
|
||||||
|
let test_fn = format!("{}.txt", tname);
|
||||||
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
inf!(test_fn),
|
||||||
|
of!(tmp_fn),
|
||||||
|
"ibs=222",
|
||||||
|
"obs=111",
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
cmp_file!(File::open(fixture_path!(&test_fn)).unwrap(),
|
||||||
|
fix.open(&tmp_fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ascii_521k_to_file()
|
||||||
|
{
|
||||||
|
let tname = "ascii-521k";
|
||||||
|
let input = build_ascii_block(512*1024);
|
||||||
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
of!(tmp_fn),
|
||||||
|
])
|
||||||
|
.pipe_in(input.clone())
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
assert_eq!(512*1024, fix.metadata(&tmp_fn).len());
|
||||||
|
|
||||||
|
cmp_file!({ let mut input_f = tempfile().unwrap();
|
||||||
|
input_f.write(&input).unwrap();
|
||||||
|
input_f },
|
||||||
|
fix.open(&tmp_fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn test_ascii_5_gibi_to_file()
|
||||||
|
{
|
||||||
|
let tname = "ascii-5G";
|
||||||
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
"count=5G",
|
||||||
|
"iflag=count_bytes",
|
||||||
|
"if=/dev/zero",
|
||||||
|
of!(tmp_fn),
|
||||||
|
])
|
||||||
|
.run()
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
assert_eq!(5*1024*1024*1024, fix.metadata(&tmp_fn).len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_self_transfer()
|
||||||
|
{
|
||||||
|
let fname = "self-transfer-256k.txt";
|
||||||
|
|
||||||
|
let (fix, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.args(&[
|
||||||
|
"status=none",
|
||||||
|
"conv=notrunc",
|
||||||
|
inf!(fname),
|
||||||
|
of!(fname),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert!(fix.file_exists(fname));
|
||||||
|
assert_eq!(256*1024, fix.metadata(fname).len());
|
||||||
|
|
||||||
|
ucmd.run()
|
||||||
|
.no_stdout()
|
||||||
|
.no_stderr()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
assert!(fix.file_exists(fname));
|
||||||
|
assert_eq!(256*1024, fix.metadata(fname).len());
|
||||||
|
}
|
||||||
|
|
||||||
|
// conv=[ascii,ebcdic,ibm], conv=[ucase,lcase], conv=[block,unblock], conv=sync
|
||||||
|
// TODO: Move conv tests from unit test module
|
||||||
|
|
BIN
tests/fixtures/dd/ascii-10k.txt
vendored
Normal file
BIN
tests/fixtures/dd/ascii-10k.txt
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-atoe-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-atoe-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-atoibm-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-atoibm-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-ebcdic-ltou-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-ebcdic-ltou-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-ebcdic-utol-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-ebcdic-utol-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-etoa-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-etoa-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-ibm-ltou-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-ibm-ltou-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-ibm-utol-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-ibm-utol-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-ltou-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-ltou-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/gnudd-conv-utol-seq-byte-values.spec
vendored
Normal file
BIN
tests/fixtures/dd/gnudd-conv-utol-seq-byte-values.spec
vendored
Normal file
Binary file not shown.
0
tests/fixtures/dd/null.txt
vendored
Normal file
0
tests/fixtures/dd/null.txt
vendored
Normal file
BIN
tests/fixtures/dd/self-transfer-256k.txt
vendored
Normal file
BIN
tests/fixtures/dd/self-transfer-256k.txt
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/dd/seq-byte-values.test
vendored
Normal file
BIN
tests/fixtures/dd/seq-byte-values.test
vendored
Normal file
Binary file not shown.
0
tests/fixtures/dd/this-file-exists-excl.txt
vendored
Normal file
0
tests/fixtures/dd/this-file-exists-excl.txt
vendored
Normal file
0
tests/fixtures/dd/this-file-exists-no-noatime.txt
vendored
Normal file
0
tests/fixtures/dd/this-file-exists-no-noatime.txt
vendored
Normal file
1
tests/fixtures/dd/this-file-exists-notrunc.txt
vendored
Normal file
1
tests/fixtures/dd/this-file-exists-notrunc.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd
|
1
tests/fixtures/dd/this-file-exists-truncated.txt
vendored
Normal file
1
tests/fixtures/dd/this-file-exists-truncated.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd
|
0
tests/fixtures/dd/this-ifile-exists-noatime.txt
vendored
Normal file
0
tests/fixtures/dd/this-ifile-exists-noatime.txt
vendored
Normal file
0
tests/fixtures/dd/this-ofile-exists-noatime.txt
vendored
Normal file
0
tests/fixtures/dd/this-ofile-exists-noatime.txt
vendored
Normal file
512
tests/fixtures/dd/y-nl-1k.txt
vendored
Normal file
512
tests/fixtures/dd/y-nl-1k.txt
vendored
Normal file
|
@ -0,0 +1,512 @@
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
||||||
|
y
|
BIN
tests/fixtures/dd/zero-256k.txt
vendored
Normal file
BIN
tests/fixtures/dd/zero-256k.txt
vendored
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue