mirror of
https://github.com/uutils/coreutils
synced 2024-12-13 14:52:41 +00:00
Merge branch 'master' into pr
This commit is contained in:
commit
7690dc018f
76 changed files with 1318 additions and 938 deletions
21
.github/workflows/CICD.yml
vendored
21
.github/workflows/CICD.yml
vendored
|
@ -84,7 +84,7 @@ jobs:
|
|||
- name: Install `rust` toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: nightly
|
||||
default: true
|
||||
profile: minimal # minimal component installation (ie, no documentation)
|
||||
components: clippy
|
||||
|
@ -94,7 +94,7 @@ jobs:
|
|||
run: |
|
||||
# `clippy` testing
|
||||
# * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>
|
||||
S=$(cargo clippy ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -- -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::warning file=\2,line=\3,col=\4::WARNING: \`cargo clippy\`: \1/p;" -e '}' ; }
|
||||
S=$(cargo +nightly clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -- -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::warning file=\2,line=\3,col=\4::WARNING: \`cargo clippy\`: \1/p;" -e '}' ; }
|
||||
|
||||
min_version:
|
||||
name: MinRustV # Minimum supported rust version
|
||||
|
@ -614,3 +614,20 @@ jobs:
|
|||
flags: ${{ steps.vars.outputs.CODECOV_FLAGS }}
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
spellcheck:
|
||||
name: Spell Check
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
job:
|
||||
- { os: ubuntu-latest }
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Install/setup prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get -y update ; sudo apt-get -y install npm ; sudo npm install cspell -g;
|
||||
- name: Run `cspell`
|
||||
shell: bash
|
||||
run: |
|
||||
cspell --config .vscode/cSpell.json --no-summary --no-progress $( git ls-files | grep "\.\(rs\|md\)" ) | sed "s/\(.*\):\(.*\):\(.*\) - \(.*\)/::warning file=\1,line=\2,col=\3::cspell: \4/" || true
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
# https://pre-commit.com
|
||||
repos:
|
||||
- repo: https://github.com/doublify/pre-commit-rust
|
||||
rev: v1.0
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: cargo-check
|
||||
- id: clippy
|
||||
- id: fmt
|
||||
- id: rust-linting
|
||||
name: Rust linting
|
||||
description: Run cargo fmt on files included in the commit.
|
||||
entry: cargo +nightly fmt --
|
||||
pass_filenames: true
|
||||
types: [file, rust]
|
||||
language: system
|
||||
- id: rust-clippy
|
||||
name: Rust clippy
|
||||
description: Run cargo clippy on files included in the commit.
|
||||
entry: cargo +nightly clippy --all-targets --all-features --
|
||||
pass_filenames: false
|
||||
types: [file, rust]
|
||||
language: system
|
||||
|
|
462
Cargo.lock
generated
462
Cargo.lock
generated
|
@ -43,12 +43,6 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "array-init"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6945cc5422176fc5e602e590c2878d2c2acd9a4fe20a4baa7c28022521698ec6"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.4.12"
|
||||
|
@ -134,15 +128,8 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"memchr 2.4.0",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.2.0"
|
||||
|
@ -155,20 +142,11 @@ version = "1.4.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.67"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -244,6 +222,7 @@ dependencies = [
|
|||
name = "coreutils"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"chrono",
|
||||
"conv",
|
||||
"filetime",
|
||||
|
@ -285,7 +264,6 @@ dependencies = [
|
|||
"uu_expand",
|
||||
"uu_expr",
|
||||
"uu_factor",
|
||||
"uu_factor_benches",
|
||||
"uu_false",
|
||||
"uu_fmt",
|
||||
"uu_fold",
|
||||
|
@ -465,42 +443,6 @@ dependencies = [
|
|||
"unicode-xid 0.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"cast",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"csv",
|
||||
"itertools 0.10.0",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_cbor",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
|
@ -524,9 +466,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94"
|
||||
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
|
@ -537,35 +479,37 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
name = "crossterm"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.10"
|
||||
name = "crossterm_winapi"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||
checksum = "0da8964ace4d3e4a044fd027919b2237000b24315a37c916f61809f1ff2140b9"
|
||||
dependencies = [
|
||||
"memchr 2.4.0",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -794,6 +738,15 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46dbcb333e86939721589d25a3557e180b52778cb33c7fdfe9e0158ff790d5ec"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ioctl-sys"
|
||||
version = "0.5.2"
|
||||
|
@ -809,15 +762,6 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
|
@ -827,21 +771,6 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
|
@ -873,6 +802,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
@ -926,13 +864,35 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
|||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"ntapi",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.13.1"
|
||||
|
@ -964,6 +924,26 @@ version = "0.1.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
|
@ -1033,12 +1013,6 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "ouroboros"
|
||||
version = "0.9.3"
|
||||
|
@ -1071,6 +1045,31 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.8",
|
||||
"smallvec 1.6.1",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "0.1.18"
|
||||
|
@ -1090,15 +1089,6 @@ dependencies = [
|
|||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
|
@ -1115,34 +1105,6 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
"plotters-svg",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
|
@ -1454,21 +1416,6 @@ version = "0.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
||||
dependencies = [
|
||||
"semver 0.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
|
@ -1490,16 +1437,7 @@ version = "0.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser 0.10.2",
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1508,53 +1446,6 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
|
||||
dependencies = [
|
||||
"half",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.0"
|
||||
|
@ -1586,6 +1477,26 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.14"
|
||||
|
@ -1595,6 +1506,12 @@ dependencies = [
|
|||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.19"
|
||||
|
@ -1717,18 +1634,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.24"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.24"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
|
@ -1745,28 +1662,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.7.1"
|
||||
|
@ -2053,6 +1954,8 @@ name = "uu_expr"
|
|||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"onig",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
|
@ -2068,22 +1971,11 @@ dependencies = [
|
|||
"paste",
|
||||
"quickcheck",
|
||||
"rand 0.7.3",
|
||||
"smallvec",
|
||||
"smallvec 0.6.14",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uu_factor_benches"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"array-init",
|
||||
"criterion",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"uu_factor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uu_false"
|
||||
version = "0.0.6"
|
||||
|
@ -2306,7 +2198,9 @@ dependencies = [
|
|||
name = "uu_more"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
"crossterm",
|
||||
"nix 0.13.1",
|
||||
"redox_syscall 0.1.57",
|
||||
"redox_termios",
|
||||
|
@ -2576,7 +2470,7 @@ dependencies = [
|
|||
"ouroboros",
|
||||
"rand 0.7.3",
|
||||
"rayon",
|
||||
"semver 0.9.0",
|
||||
"semver",
|
||||
"tempfile",
|
||||
"unicode-width",
|
||||
"uucore",
|
||||
|
@ -2924,70 +2818,6 @@ version = "0.10.2+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
dependencies = [
|
||||
"quote 1.0.9",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wild"
|
||||
version = "2.0.4"
|
||||
|
|
|
@ -327,7 +327,8 @@ who = { optional=true, version="0.0.6", package="uu_who", path="src/uu/who"
|
|||
whoami = { optional=true, version="0.0.6", package="uu_whoami", path="src/uu/whoami" }
|
||||
yes = { optional=true, version="0.0.6", package="uu_yes", path="src/uu/yes" }
|
||||
|
||||
factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" }
|
||||
# this breaks clippy linting with: "tests/by-util/test_factor_benches.rs: No such file or directory (os error 2)"
|
||||
# factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" }
|
||||
|
||||
#
|
||||
# * pinned transitive dependencies
|
||||
|
@ -350,6 +351,7 @@ time = "0.1"
|
|||
unindent = "0.1"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="src/uucore", features=["entries"] }
|
||||
walkdir = "2.2"
|
||||
atty = "0.2.14"
|
||||
|
||||
[target.'cfg(unix)'.dev-dependencies]
|
||||
rust-users = { version="0.10", package="users" }
|
||||
|
|
|
@ -36,3 +36,7 @@ To use the provided hook:
|
|||
2. Run `pre-commit install` while in the repository directory
|
||||
|
||||
Your git commits will then automatically be checked. If a check fails, an error message will explain why, and your commit will be canceled. You can then make the suggested changes, and run `git commit ...` again.
|
||||
|
||||
### Using Clippy
|
||||
|
||||
The `msrv` key in the clippy configuration file `clippy.toml` is used to disable lints pertaining to newer features by specifying the minimum supported Rust version (MSRV). However, this key is only supported on `nightly`. To invoke clippy without errors, use `cargo +nightly clippy`. In order to also check tests and non-default crate features, use `cargo +nightly clippy --all-targets --all-features`.
|
||||
|
|
1
clippy.toml
Normal file
1
clippy.toml
Normal file
|
@ -0,0 +1 @@
|
|||
msrv = "1.43.1"
|
|
@ -136,7 +136,8 @@ fn basename(fullname: &str, suffix: &str) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::manual_strip)] // can be replaced with strip_suffix once the minimum rust version is 1.45
|
||||
// can be replaced with strip_suffix once MSRV is 1.45
|
||||
#[allow(clippy::manual_strip)]
|
||||
fn strip_suffix(name: &str, suffix: &str) -> String {
|
||||
if name == suffix {
|
||||
return name.to_owned();
|
||||
|
|
|
@ -669,8 +669,8 @@ impl Options {
|
|||
}
|
||||
},
|
||||
backup: backup_mode,
|
||||
backup_suffix: backup_suffix,
|
||||
overwrite: overwrite,
|
||||
backup_suffix,
|
||||
overwrite,
|
||||
no_target_dir,
|
||||
preserve_attributes,
|
||||
recursive,
|
||||
|
@ -1089,7 +1089,7 @@ fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResu
|
|||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[allow(clippy::unnecessary_wraps)] // needed for windows version
|
||||
#[allow(clippy::unnecessary_unwrap)] // needed for windows version
|
||||
fn symlink_file(source: &Path, dest: &Path, context: &str) -> CopyResult<()> {
|
||||
match std::os::unix::fs::symlink(source, dest).context(context) {
|
||||
Ok(_) => Ok(()),
|
||||
|
@ -1108,7 +1108,7 @@ fn context_for(src: &Path, dest: &Path) -> String {
|
|||
|
||||
/// Implements a simple backup copy for the destination file.
|
||||
/// TODO: for the backup, should this function be replaced by `copy_file(...)`?
|
||||
fn backup_dest(dest: &Path, backup_path: &PathBuf) -> CopyResult<PathBuf> {
|
||||
fn backup_dest(dest: &Path, backup_path: &Path) -> CopyResult<PathBuf> {
|
||||
fs::copy(dest, &backup_path)?;
|
||||
Ok(backup_path.into())
|
||||
}
|
||||
|
|
|
@ -483,10 +483,11 @@ where
|
|||
/// Shrink the buffer so that its length is equal to the set size, returning an iterator for
|
||||
/// the elements that were too much.
|
||||
fn shrink_buffer_to_size(&mut self) -> impl Iterator<Item = String> + '_ {
|
||||
let mut shrink_offset = 0;
|
||||
if self.buffer.len() > self.size {
|
||||
shrink_offset = self.buffer.len() - self.size;
|
||||
}
|
||||
let shrink_offset = if self.buffer.len() > self.size {
|
||||
self.buffer.len() - self.size
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.buffer
|
||||
.drain(..shrink_offset)
|
||||
.map(|(_, line)| line.unwrap())
|
||||
|
|
|
@ -16,6 +16,8 @@ path = "src/expr.rs"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2.42"
|
||||
num-bigint = "0.4.0"
|
||||
num-traits = "0.2.14"
|
||||
onig = "~4.3.2"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) binop binops ints paren prec
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::{One, Zero};
|
||||
use onig::{Regex, RegexOptions, Syntax};
|
||||
|
||||
use crate::tokens::Token;
|
||||
|
@ -39,20 +41,17 @@ impl AstNode {
|
|||
for _ in 0..depth {
|
||||
print!("\t",);
|
||||
}
|
||||
match *self {
|
||||
AstNode::Leaf {
|
||||
ref token_idx,
|
||||
ref value,
|
||||
} => println!(
|
||||
match self {
|
||||
AstNode::Leaf { token_idx, value } => println!(
|
||||
"Leaf( {} ) at #{} ( evaluate -> {:?} )",
|
||||
value,
|
||||
token_idx,
|
||||
self.evaluate()
|
||||
),
|
||||
AstNode::Node {
|
||||
ref token_idx,
|
||||
ref op_type,
|
||||
ref operands,
|
||||
token_idx,
|
||||
op_type,
|
||||
operands,
|
||||
} => {
|
||||
println!(
|
||||
"Node( {} ) at #{} (evaluate -> {:?})",
|
||||
|
@ -81,36 +80,33 @@ impl AstNode {
|
|||
})
|
||||
}
|
||||
pub fn evaluate(&self) -> Result<String, String> {
|
||||
match *self {
|
||||
AstNode::Leaf { ref value, .. } => Ok(value.clone()),
|
||||
AstNode::Node { ref op_type, .. } => match self.operand_values() {
|
||||
match self {
|
||||
AstNode::Leaf { value, .. } => Ok(value.clone()),
|
||||
AstNode::Node { op_type, .. } => match self.operand_values() {
|
||||
Err(reason) => Err(reason),
|
||||
Ok(operand_values) => match op_type.as_ref() {
|
||||
"+" => infix_operator_two_ints(
|
||||
|a: i64, b: i64| checked_binop(|| a.checked_add(b), "+"),
|
||||
&operand_values,
|
||||
),
|
||||
"-" => infix_operator_two_ints(
|
||||
|a: i64, b: i64| checked_binop(|| a.checked_sub(b), "-"),
|
||||
&operand_values,
|
||||
),
|
||||
"*" => infix_operator_two_ints(
|
||||
|a: i64, b: i64| checked_binop(|| a.checked_mul(b), "*"),
|
||||
&operand_values,
|
||||
),
|
||||
"+" => {
|
||||
infix_operator_two_ints(|a: BigInt, b: BigInt| Ok(a + b), &operand_values)
|
||||
}
|
||||
"-" => {
|
||||
infix_operator_two_ints(|a: BigInt, b: BigInt| Ok(a - b), &operand_values)
|
||||
}
|
||||
"*" => {
|
||||
infix_operator_two_ints(|a: BigInt, b: BigInt| Ok(a * b), &operand_values)
|
||||
}
|
||||
"/" => infix_operator_two_ints(
|
||||
|a: i64, b: i64| {
|
||||
if b == 0 {
|
||||
|a: BigInt, b: BigInt| {
|
||||
if b.is_zero() {
|
||||
Err("division by zero".to_owned())
|
||||
} else {
|
||||
checked_binop(|| a.checked_div(b), "/")
|
||||
Ok(a / b)
|
||||
}
|
||||
},
|
||||
&operand_values,
|
||||
),
|
||||
"%" => infix_operator_two_ints(
|
||||
|a: i64, b: i64| {
|
||||
if b == 0 {
|
||||
|a: BigInt, b: BigInt| {
|
||||
if b.is_zero() {
|
||||
Err("division by zero".to_owned())
|
||||
} else {
|
||||
Ok(a % b)
|
||||
|
@ -119,32 +115,32 @@ impl AstNode {
|
|||
&operand_values,
|
||||
),
|
||||
"=" => infix_operator_two_ints_or_two_strings(
|
||||
|a: i64, b: i64| Ok(bool_as_int(a == b)),
|
||||
|a: BigInt, b: BigInt| Ok(bool_as_int(a == b)),
|
||||
|a: &String, b: &String| Ok(bool_as_string(a == b)),
|
||||
&operand_values,
|
||||
),
|
||||
"!=" => infix_operator_two_ints_or_two_strings(
|
||||
|a: i64, b: i64| Ok(bool_as_int(a != b)),
|
||||
|a: BigInt, b: BigInt| Ok(bool_as_int(a != b)),
|
||||
|a: &String, b: &String| Ok(bool_as_string(a != b)),
|
||||
&operand_values,
|
||||
),
|
||||
"<" => infix_operator_two_ints_or_two_strings(
|
||||
|a: i64, b: i64| Ok(bool_as_int(a < b)),
|
||||
|a: BigInt, b: BigInt| Ok(bool_as_int(a < b)),
|
||||
|a: &String, b: &String| Ok(bool_as_string(a < b)),
|
||||
&operand_values,
|
||||
),
|
||||
">" => infix_operator_two_ints_or_two_strings(
|
||||
|a: i64, b: i64| Ok(bool_as_int(a > b)),
|
||||
|a: BigInt, b: BigInt| Ok(bool_as_int(a > b)),
|
||||
|a: &String, b: &String| Ok(bool_as_string(a > b)),
|
||||
&operand_values,
|
||||
),
|
||||
"<=" => infix_operator_two_ints_or_two_strings(
|
||||
|a: i64, b: i64| Ok(bool_as_int(a <= b)),
|
||||
|a: BigInt, b: BigInt| Ok(bool_as_int(a <= b)),
|
||||
|a: &String, b: &String| Ok(bool_as_string(a <= b)),
|
||||
&operand_values,
|
||||
),
|
||||
">=" => infix_operator_two_ints_or_two_strings(
|
||||
|a: i64, b: i64| Ok(bool_as_int(a >= b)),
|
||||
|a: BigInt, b: BigInt| Ok(bool_as_int(a >= b)),
|
||||
|a: &String, b: &String| Ok(bool_as_string(a >= b)),
|
||||
&operand_values,
|
||||
),
|
||||
|
@ -161,7 +157,7 @@ impl AstNode {
|
|||
}
|
||||
}
|
||||
pub fn operand_values(&self) -> Result<Vec<String>, String> {
|
||||
if let AstNode::Node { ref operands, .. } = *self {
|
||||
if let AstNode::Node { operands, .. } = self {
|
||||
let mut out = Vec::with_capacity(operands.len());
|
||||
for operand in operands {
|
||||
match operand.evaluate() {
|
||||
|
@ -217,9 +213,9 @@ fn maybe_dump_ast(result: &Result<Box<AstNode>, String>) {
|
|||
if let Ok(debug_var) = env::var("EXPR_DEBUG_AST") {
|
||||
if debug_var == "1" {
|
||||
println!("EXPR_DEBUG_AST");
|
||||
match *result {
|
||||
Ok(ref ast) => ast.debug_dump(),
|
||||
Err(ref reason) => println!("\terr: {:?}", reason),
|
||||
match result {
|
||||
Ok(ast) => ast.debug_dump(),
|
||||
Err(reason) => println!("\terr: {:?}", reason),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +300,7 @@ fn push_token_to_either_stack(
|
|||
out_stack: &mut TokenStack,
|
||||
op_stack: &mut TokenStack,
|
||||
) -> Result<(), String> {
|
||||
let result = match *token {
|
||||
let result = match token {
|
||||
Token::Value { .. } => {
|
||||
out_stack.push((token_idx, token.clone()));
|
||||
Ok(())
|
||||
|
@ -420,24 +416,14 @@ fn move_till_match_paren(
|
|||
}
|
||||
}
|
||||
|
||||
fn checked_binop<F: Fn() -> Option<T>, T>(cb: F, op: &str) -> Result<T, String> {
|
||||
match cb() {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(format!("{}: Numerical result out of range", op)),
|
||||
}
|
||||
}
|
||||
|
||||
fn infix_operator_two_ints<F>(f: F, values: &[String]) -> Result<String, String>
|
||||
where
|
||||
F: Fn(i64, i64) -> Result<i64, String>,
|
||||
F: Fn(BigInt, BigInt) -> Result<BigInt, String>,
|
||||
{
|
||||
assert!(values.len() == 2);
|
||||
if let Ok(left) = values[0].parse::<i64>() {
|
||||
if let Ok(right) = values[1].parse::<i64>() {
|
||||
return match f(left, right) {
|
||||
Ok(result) => Ok(result.to_string()),
|
||||
Err(reason) => Err(reason),
|
||||
};
|
||||
if let Ok(left) = values[0].parse::<BigInt>() {
|
||||
if let Ok(right) = values[1].parse::<BigInt>() {
|
||||
return f(left, right).map(|big_int| big_int.to_string());
|
||||
}
|
||||
}
|
||||
Err("Expected an integer operand".to_string())
|
||||
|
@ -449,13 +435,14 @@ fn infix_operator_two_ints_or_two_strings<FI, FS>(
|
|||
values: &[String],
|
||||
) -> Result<String, String>
|
||||
where
|
||||
FI: Fn(i64, i64) -> Result<i64, String>,
|
||||
FI: Fn(BigInt, BigInt) -> Result<u8, String>,
|
||||
FS: Fn(&String, &String) -> Result<String, String>,
|
||||
{
|
||||
assert!(values.len() == 2);
|
||||
if let (Some(a_int), Some(b_int)) =
|
||||
(values[0].parse::<i64>().ok(), values[1].parse::<i64>().ok())
|
||||
{
|
||||
if let (Some(a_int), Some(b_int)) = (
|
||||
values[0].parse::<BigInt>().ok(),
|
||||
values[1].parse::<BigInt>().ok(),
|
||||
) {
|
||||
match fi(a_int, b_int) {
|
||||
Ok(result) => Ok(result.to_string()),
|
||||
Err(reason) => Err(reason),
|
||||
|
@ -541,7 +528,7 @@ fn prefix_operator_substr(values: &[String]) -> String {
|
|||
subj.chars().skip(idx).take(len).collect()
|
||||
}
|
||||
|
||||
fn bool_as_int(b: bool) -> i64 {
|
||||
fn bool_as_int(b: bool) -> u8 {
|
||||
if b {
|
||||
1
|
||||
} else {
|
||||
|
@ -559,8 +546,8 @@ fn value_as_bool(s: &str) -> bool {
|
|||
if s.is_empty() {
|
||||
return false;
|
||||
}
|
||||
match s.parse::<i64>() {
|
||||
Ok(n) => n != 0,
|
||||
match s.parse::<BigInt>() {
|
||||
Ok(n) => n.is_one(),
|
||||
Err(_) => true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) paren
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Token {
|
||||
Value {
|
||||
|
@ -51,14 +53,14 @@ impl Token {
|
|||
}
|
||||
|
||||
fn is_infix_plus(&self) -> bool {
|
||||
match *self {
|
||||
Token::InfixOp { ref value, .. } => value == "+",
|
||||
match self {
|
||||
Token::InfixOp { value, .. } => value == "+",
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
fn is_a_number(&self) -> bool {
|
||||
match *self {
|
||||
Token::Value { ref value, .. } => value.parse::<i64>().is_ok(),
|
||||
match self {
|
||||
Token::Value { value, .. } => value.parse::<BigInt>().is_ok(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +144,7 @@ fn push_token_if_not_escaped(acc: &mut Vec<(usize, Token)>, tok_idx: usize, toke
|
|||
// Smells heuristics... :(
|
||||
let prev_is_plus = match acc.last() {
|
||||
None => false,
|
||||
Some(ref t) => t.1.is_infix_plus(),
|
||||
Some(t) => t.1.is_infix_plus(),
|
||||
};
|
||||
let should_use_as_escaped = if prev_is_plus && acc.len() >= 2 {
|
||||
let pre_prev = &acc[acc.len() - 2];
|
||||
|
|
|
@ -30,7 +30,7 @@ impl Iterator for Sieve {
|
|||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<u64> {
|
||||
while let Some(n) = self.inner.next() {
|
||||
for n in &mut self.inner {
|
||||
let mut prime = true;
|
||||
while let Some((next, inc)) = self.filts.peek() {
|
||||
// need to keep checking the min element of the heap
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn parse_obsolete(src: &str) -> Option<Result<impl Iterator<Item = OsString>
|
|||
let mut num_end = 0usize;
|
||||
let mut has_num = false;
|
||||
let mut last_char = 0 as char;
|
||||
while let Some((n, c)) = chars.next() {
|
||||
for (n, c) in &mut chars {
|
||||
if c.is_numeric() {
|
||||
has_num = true;
|
||||
num_end = n;
|
||||
|
@ -109,7 +109,7 @@ pub fn parse_num(src: &str) -> Result<(usize, bool), ParseError> {
|
|||
let mut num_end = 0usize;
|
||||
let mut last_char = 0 as char;
|
||||
let mut num_count = 0usize;
|
||||
while let Some((n, c)) = chars.next() {
|
||||
for (n, c) in &mut chars {
|
||||
if c.is_numeric() {
|
||||
num_end = n;
|
||||
num_count += 1;
|
||||
|
|
|
@ -520,6 +520,7 @@ fn copy_file_to_file(file: &Path, target: &Path, b: &Behavior) -> i32 {
|
|||
///
|
||||
/// If the copy system call fails, we print a verbose error and return an empty error value.
|
||||
///
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn copy(from: &Path, to: &Path, b: &Behavior) -> Result<(), ()> {
|
||||
if b.compare && !need_copy(from, to, b) {
|
||||
return Ok(());
|
||||
|
|
|
@ -218,6 +218,7 @@ struct LongFormat {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn from(options: clap::ArgMatches) -> Config {
|
||||
let (mut format, opt) = if let Some(format_) = options.value_of(options::FORMAT) {
|
||||
(
|
||||
|
@ -1222,7 +1223,7 @@ fn list(locs: Vec<String>, config: Config) -> i32 {
|
|||
|
||||
sort_entries(&mut dirs, &config);
|
||||
for dir in dirs {
|
||||
if locs.len() > 1 {
|
||||
if locs.len() > 1 || config.recursive {
|
||||
let _ = writeln!(out, "\n{}:", dir.p_buf.display());
|
||||
}
|
||||
enter_directory(&dir, &config, &mut out);
|
||||
|
@ -1614,7 +1615,7 @@ fn display_date(metadata: &Metadata, config: &Config) -> String {
|
|||
Some(time) => {
|
||||
//Date is recent if from past 6 months
|
||||
//According to GNU a Gregorian year has 365.2425 * 24 * 60 * 60 == 31556952 seconds on the average.
|
||||
let recent = time + chrono::Duration::seconds(31556952 / 2) > chrono::Local::now();
|
||||
let recent = time + chrono::Duration::seconds(31_556_952 / 2) > chrono::Local::now();
|
||||
|
||||
match config.time_style {
|
||||
TimeStyle::FullIso => time.format("%Y-%m-%d %H:%M:%S.%f %z"),
|
||||
|
@ -1696,7 +1697,6 @@ fn file_is_executable(md: &Metadata) -> bool {
|
|||
md.mode() & ((S_IXUSR | S_IXGRP | S_IXOTH) as u32) != 0
|
||||
}
|
||||
|
||||
#[allow(clippy::clippy::collapsible_else_if)]
|
||||
fn classify_file(path: &PathData) -> Option<char> {
|
||||
let file_type = path.file_type()?;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ path = "src/more.rs"
|
|||
clap = "2.33"
|
||||
uucore = { version = ">=0.0.7", package = "uucore", path = "../../uucore" }
|
||||
uucore_procs = { version = ">=0.0.5", package = "uucore_procs", path = "../../uucore_procs" }
|
||||
crossterm = ">=0.19"
|
||||
atty = "0.2.14"
|
||||
|
||||
[target.'cfg(target_os = "redox")'.dependencies]
|
||||
redox_termios = "0.1"
|
||||
|
|
|
@ -10,150 +10,395 @@
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, stdout, BufRead, BufReader, Read, Write};
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
fs::File,
|
||||
io::{stdin, stdout, BufReader, Read, Stdout, Write},
|
||||
path::Path,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||
extern crate nix;
|
||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||
use nix::sys::termios::{self, LocalFlags, SetArg};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
extern crate redox_termios;
|
||||
#[cfg(target_os = "redox")]
|
||||
extern crate syscall;
|
||||
use clap::{App, Arg};
|
||||
use crossterm::{
|
||||
event::{self, Event, KeyCode, KeyEvent, KeyModifiers},
|
||||
execute, queue,
|
||||
style::Attribute,
|
||||
terminal,
|
||||
};
|
||||
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
static ABOUT: &str = "A file perusal filter for CRT viewing.";
|
||||
|
||||
mod options {
|
||||
pub const FILE: &str = "file";
|
||||
pub mod options {
|
||||
pub const SILENT: &str = "silent";
|
||||
pub const LOGICAL: &str = "logical";
|
||||
pub const NO_PAUSE: &str = "no-pause";
|
||||
pub const PRINT_OVER: &str = "print-over";
|
||||
pub const CLEAN_PRINT: &str = "clean-print";
|
||||
pub const SQUEEZE: &str = "squeeze";
|
||||
pub const PLAIN: &str = "plain";
|
||||
pub const LINES: &str = "lines";
|
||||
pub const NUMBER: &str = "number";
|
||||
pub const PATTERN: &str = "pattern";
|
||||
pub const FROM_LINE: &str = "from-line";
|
||||
pub const FILES: &str = "files";
|
||||
}
|
||||
|
||||
fn get_usage() -> String {
|
||||
format!("{} [options] <file>...", executable!())
|
||||
}
|
||||
const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n";
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let args = args
|
||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(VERSION)
|
||||
.usage(usage.as_str())
|
||||
.about(ABOUT)
|
||||
.about("A file perusal filter for CRT viewing.")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
// The commented arguments below are unimplemented:
|
||||
/*
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.number_of_values(1)
|
||||
.multiple(true),
|
||||
Arg::with_name(options::SILENT)
|
||||
.short("d")
|
||||
.long(options::SILENT)
|
||||
.help("Display help instead of ringing bell"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::LOGICAL)
|
||||
.short("f")
|
||||
.long(options::LOGICAL)
|
||||
.help("Count logical rather than screen lines"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_PAUSE)
|
||||
.short("l")
|
||||
.long(options::NO_PAUSE)
|
||||
.help("Suppress pause after form feed"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PRINT_OVER)
|
||||
.short("c")
|
||||
.long(options::PRINT_OVER)
|
||||
.help("Do not scroll, display text and clean line ends"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::CLEAN_PRINT)
|
||||
.short("p")
|
||||
.long(options::CLEAN_PRINT)
|
||||
.help("Do not scroll, clean screen and display text"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SQUEEZE)
|
||||
.short("s")
|
||||
.long(options::SQUEEZE)
|
||||
.help("Squeeze multiple blank lines into one"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PLAIN)
|
||||
.short("u")
|
||||
.long(options::PLAIN)
|
||||
.help("Suppress underlining and bold"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::LINES)
|
||||
.short("n")
|
||||
.long(options::LINES)
|
||||
.value_name("number")
|
||||
.takes_value(true)
|
||||
.help("The number of lines per screenful"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NUMBER)
|
||||
.allow_hyphen_values(true)
|
||||
.long(options::NUMBER)
|
||||
.required(false)
|
||||
.takes_value(true)
|
||||
.help("Same as --lines"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FROM_LINE)
|
||||
.short("F")
|
||||
.allow_hyphen_values(true)
|
||||
.required(false)
|
||||
.takes_value(true)
|
||||
.value_name("number")
|
||||
.help("Display file beginning from line number"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PATTERN)
|
||||
.short("P")
|
||||
.allow_hyphen_values(true)
|
||||
.required(false)
|
||||
.takes_value(true)
|
||||
.help("Display file beginning from pattern match"),
|
||||
)
|
||||
*/
|
||||
.arg(
|
||||
Arg::with_name(options::FILES)
|
||||
.required(false)
|
||||
.multiple(true)
|
||||
.help("Path to the files to be read"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
// FixME: fail without panic for now; but `more` should work with no arguments (ie, for piped input)
|
||||
if let None | Some("-") = matches.value_of(options::FILE) {
|
||||
show_usage_error!("Reading from stdin isn't supported yet.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if let Some(x) = matches.value_of(options::FILE) {
|
||||
let path = std::path::Path::new(x);
|
||||
if path.is_dir() {
|
||||
show_usage_error!("'{}' is a directory.", x);
|
||||
return 1;
|
||||
let mut buff = String::new();
|
||||
if let Some(filenames) = matches.values_of(options::FILES) {
|
||||
let mut stdout = setup_term();
|
||||
let length = filenames.len();
|
||||
for (idx, fname) in filenames.enumerate() {
|
||||
let fname = Path::new(fname);
|
||||
if fname.is_dir() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_usage_error!("'{}' is a directory.", fname.display());
|
||||
return 1;
|
||||
}
|
||||
if !fname.exists() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_error!(
|
||||
"cannot open {}: No such file or directory",
|
||||
fname.display()
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
if length > 1 {
|
||||
buff.push_str(&MULTI_FILE_TOP_PROMPT.replace("{}", fname.to_str().unwrap()));
|
||||
}
|
||||
let mut reader = BufReader::new(File::open(fname).unwrap());
|
||||
reader.read_to_string(&mut buff).unwrap();
|
||||
let is_last = idx + 1 == length;
|
||||
more(&buff, &mut stdout, is_last);
|
||||
buff.clear();
|
||||
}
|
||||
reset_term(&mut stdout);
|
||||
} else if atty::isnt(atty::Stream::Stdin) {
|
||||
stdin().read_to_string(&mut buff).unwrap();
|
||||
let mut stdout = setup_term();
|
||||
more(&buff, &mut stdout, true);
|
||||
reset_term(&mut stdout);
|
||||
} else {
|
||||
show_usage_error!("bad usage");
|
||||
}
|
||||
|
||||
more(matches);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||
fn setup_term() -> termios::Termios {
|
||||
let mut term = termios::tcgetattr(0).unwrap();
|
||||
// Unset canonical mode, so we get characters immediately
|
||||
term.local_flags.remove(LocalFlags::ICANON);
|
||||
// Disable local echo
|
||||
term.local_flags.remove(LocalFlags::ECHO);
|
||||
termios::tcsetattr(0, SetArg::TCSADRAIN, &term).unwrap();
|
||||
term
|
||||
#[cfg(not(target_os = "fuchsia"))]
|
||||
fn setup_term() -> std::io::Stdout {
|
||||
let stdout = stdout();
|
||||
terminal::enable_raw_mode().unwrap();
|
||||
stdout
|
||||
}
|
||||
|
||||
#[cfg(any(windows, target_os = "fuchsia"))]
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
#[inline(always)]
|
||||
fn setup_term() -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
fn setup_term() -> redox_termios::Termios {
|
||||
let mut term = redox_termios::Termios::default();
|
||||
let fd = syscall::dup(0, b"termios").unwrap();
|
||||
syscall::read(fd, &mut term).unwrap();
|
||||
term.local_flags &= !redox_termios::ICANON;
|
||||
term.local_flags &= !redox_termios::ECHO;
|
||||
syscall::write(fd, &term).unwrap();
|
||||
let _ = syscall::close(fd);
|
||||
term
|
||||
#[cfg(not(target_os = "fuchsia"))]
|
||||
fn reset_term(stdout: &mut std::io::Stdout) {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
// Clear the prompt
|
||||
queue!(stdout, terminal::Clear(terminal::ClearType::CurrentLine)).unwrap();
|
||||
// Move cursor to the beginning without printing new line
|
||||
print!("\r");
|
||||
stdout.flush().unwrap();
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||
fn reset_term(term: &mut termios::Termios) {
|
||||
term.local_flags.insert(LocalFlags::ICANON);
|
||||
term.local_flags.insert(LocalFlags::ECHO);
|
||||
termios::tcsetattr(0, SetArg::TCSADRAIN, &term).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(any(windows, target_os = "fuchsia"))]
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
#[inline(always)]
|
||||
fn reset_term(_: &mut usize) {}
|
||||
|
||||
#[cfg(any(target_os = "redox"))]
|
||||
fn reset_term(term: &mut redox_termios::Termios) {
|
||||
let fd = syscall::dup(0, b"termios").unwrap();
|
||||
syscall::read(fd, term).unwrap();
|
||||
term.local_flags |= redox_termios::ICANON;
|
||||
term.local_flags |= redox_termios::ECHO;
|
||||
syscall::write(fd, &term).unwrap();
|
||||
let _ = syscall::close(fd);
|
||||
}
|
||||
fn more(buff: &str, mut stdout: &mut Stdout, is_last: bool) {
|
||||
let (cols, rows) = terminal::size().unwrap();
|
||||
let lines = break_buff(buff, usize::from(cols));
|
||||
let line_count: u16 = lines.len().try_into().unwrap();
|
||||
|
||||
fn more(matches: ArgMatches) {
|
||||
let mut f: Box<dyn BufRead> = match matches.value_of(options::FILE) {
|
||||
None | Some("-") => Box::new(BufReader::new(stdin())),
|
||||
Some(filename) => Box::new(BufReader::new(File::open(filename).unwrap())),
|
||||
};
|
||||
let mut buffer = [0; 1024];
|
||||
let mut upper_mark = 0;
|
||||
let mut lines_left = line_count.saturating_sub(upper_mark + rows);
|
||||
|
||||
let mut term = setup_term();
|
||||
draw(
|
||||
&mut upper_mark,
|
||||
rows,
|
||||
&mut stdout,
|
||||
lines.clone(),
|
||||
line_count,
|
||||
);
|
||||
|
||||
let mut end = false;
|
||||
while let Ok(sz) = f.read(&mut buffer) {
|
||||
if sz == 0 {
|
||||
break;
|
||||
}
|
||||
stdout().write_all(&buffer[0..sz]).unwrap();
|
||||
for byte in std::io::stdin().bytes() {
|
||||
match byte.unwrap() {
|
||||
b' ' => break,
|
||||
b'q' | 27 => {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if end {
|
||||
break;
|
||||
// Specifies whether we have reached the end of the file and should
|
||||
// return on the next keypress. However, we immediately return when
|
||||
// this is the last file.
|
||||
let mut to_be_done = false;
|
||||
if lines_left == 0 && is_last {
|
||||
if is_last {
|
||||
return;
|
||||
} else {
|
||||
to_be_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
reset_term(&mut term);
|
||||
println!();
|
||||
loop {
|
||||
if event::poll(Duration::from_millis(10)).unwrap() {
|
||||
match event::read().unwrap() {
|
||||
Event::Key(KeyEvent {
|
||||
code: KeyCode::Char('q'),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
})
|
||||
| Event::Key(KeyEvent {
|
||||
code: KeyCode::Char('c'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
}) => {
|
||||
reset_term(&mut stdout);
|
||||
std::process::exit(0);
|
||||
}
|
||||
Event::Key(KeyEvent {
|
||||
code: KeyCode::Down,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
})
|
||||
| Event::Key(KeyEvent {
|
||||
code: KeyCode::Char(' '),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
}) => {
|
||||
upper_mark = upper_mark.saturating_add(rows.saturating_sub(1));
|
||||
|
||||
}
|
||||
Event::Key(KeyEvent {
|
||||
code: KeyCode::Up,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
}) => {
|
||||
upper_mark = upper_mark.saturating_sub(rows.saturating_sub(1));
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
lines_left = line_count.saturating_sub(upper_mark + rows);
|
||||
draw(
|
||||
&mut upper_mark,
|
||||
rows,
|
||||
&mut stdout,
|
||||
lines.clone(),
|
||||
line_count,
|
||||
);
|
||||
|
||||
if lines_left == 0 {
|
||||
if to_be_done || is_last {
|
||||
return
|
||||
}
|
||||
to_be_done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(
|
||||
upper_mark: &mut u16,
|
||||
rows: u16,
|
||||
mut stdout: &mut std::io::Stdout,
|
||||
lines: Vec<String>,
|
||||
lc: u16,
|
||||
) {
|
||||
execute!(stdout, terminal::Clear(terminal::ClearType::CurrentLine)).unwrap();
|
||||
let (up_mark, lower_mark) = calc_range(*upper_mark, rows, lc);
|
||||
// Reduce the row by 1 for the prompt
|
||||
let displayed_lines = lines
|
||||
.iter()
|
||||
.skip(up_mark.into())
|
||||
.take(usize::from(rows.saturating_sub(1)));
|
||||
|
||||
for line in displayed_lines {
|
||||
stdout
|
||||
.write_all(format!("\r{}\n", line).as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
make_prompt_and_flush(&mut stdout, lower_mark, lc);
|
||||
*upper_mark = up_mark;
|
||||
}
|
||||
|
||||
// Break the lines on the cols of the terminal
|
||||
fn break_buff(buff: &str, cols: usize) -> Vec<String> {
|
||||
let mut lines = Vec::new();
|
||||
|
||||
for l in buff.lines() {
|
||||
lines.append(&mut break_line(l, cols));
|
||||
}
|
||||
lines
|
||||
}
|
||||
|
||||
fn break_line(mut line: &str, cols: usize) -> Vec<String> {
|
||||
let breaks = (line.len() / cols).saturating_add(1);
|
||||
let mut lines = Vec::with_capacity(breaks);
|
||||
// TODO: Use unicode width instead of the length in bytes.
|
||||
if line.len() < cols {
|
||||
lines.push(line.to_string());
|
||||
return lines;
|
||||
}
|
||||
|
||||
for _ in 1..=breaks {
|
||||
let (line1, line2) = line.split_at(cols);
|
||||
lines.push(line1.to_string());
|
||||
if line2.len() < cols {
|
||||
lines.push(line2.to_string());
|
||||
break;
|
||||
}
|
||||
line = line2;
|
||||
}
|
||||
lines
|
||||
}
|
||||
|
||||
// Calculate upper_mark based on certain parameters
|
||||
fn calc_range(mut upper_mark: u16, rows: u16, line_count: u16) -> (u16, u16) {
|
||||
let mut lower_mark = upper_mark.saturating_add(rows);
|
||||
|
||||
if lower_mark >= line_count {
|
||||
upper_mark = line_count.saturating_sub(rows);
|
||||
lower_mark = line_count;
|
||||
} else {
|
||||
lower_mark = lower_mark.saturating_sub(1)
|
||||
}
|
||||
(upper_mark, lower_mark)
|
||||
}
|
||||
|
||||
// Make a prompt similar to original more
|
||||
fn make_prompt_and_flush(stdout: &mut Stdout, lower_mark: u16, lc: u16) {
|
||||
write!(
|
||||
stdout,
|
||||
"\r{}--More--({}%){}",
|
||||
Attribute::Reverse,
|
||||
((lower_mark as f64 / lc as f64) * 100.0).round() as u16,
|
||||
Attribute::Reset
|
||||
)
|
||||
.unwrap();
|
||||
stdout.flush().unwrap();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{break_line, calc_range};
|
||||
|
||||
// It is good to test the above functions
|
||||
#[test]
|
||||
fn test_calc_range() {
|
||||
assert_eq!((0, 24), calc_range(0, 25, 100));
|
||||
assert_eq!((50, 74), calc_range(50, 25, 100));
|
||||
assert_eq!((75, 100), calc_range(85, 25, 100));
|
||||
}
|
||||
#[test]
|
||||
fn test_break_lines_long() {
|
||||
let mut test_string = String::with_capacity(100);
|
||||
for _ in 0..200 {
|
||||
test_string.push('#');
|
||||
}
|
||||
|
||||
let lines = break_line(&test_string, 80);
|
||||
|
||||
assert_eq!(
|
||||
(80, 80, 40),
|
||||
(lines[0].len(), lines[1].len(), lines[2].len())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_break_lines_short() {
|
||||
let mut test_string = String::with_capacity(100);
|
||||
for _ in 0..20 {
|
||||
test_string.push('#');
|
||||
}
|
||||
|
||||
let lines = break_line(&test_string, 80);
|
||||
|
||||
assert_eq!(20, lines[0].len());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ pub fn parse_inputs(matches: &dyn CommandLineOpts) -> Result<CommandLineInputs,
|
|||
input_strings.push("-");
|
||||
}
|
||||
Ok(CommandLineInputs::FileNames(
|
||||
input_strings.iter().map(|s| s.to_string()).collect(),
|
||||
input_strings.iter().map(|&s| s.to_string()).collect(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ pub fn parse_inputs_traditional(input_strings: Vec<&str>) -> Result<CommandLineI
|
|||
Ok(match offset0 {
|
||||
Ok(n) => CommandLineInputs::FileAndOffset(("-".to_string(), n, None)),
|
||||
_ => CommandLineInputs::FileNames(
|
||||
input_strings.iter().map(|s| s.to_string()).collect(),
|
||||
input_strings.iter().map(|&s| s.to_string()).collect(),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ mod tests {
|
|||
impl<'a> MockOptions<'a> {
|
||||
fn new(inputs: Vec<&'a str>, option_names: Vec<&'a str>) -> MockOptions<'a> {
|
||||
MockOptions {
|
||||
inputs: inputs.iter().map(|s| s.to_string()).collect::<Vec<_>>(),
|
||||
inputs: inputs.iter().map(|&s| s.to_string()).collect::<Vec<_>>(),
|
||||
option_names,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut separator = "\n";
|
||||
if matches.is_present(OPT_NULL) {
|
||||
separator = "\x00";
|
||||
}
|
||||
let separator = if matches.is_present(OPT_NULL) {
|
||||
"\x00"
|
||||
} else {
|
||||
"\n"
|
||||
};
|
||||
|
||||
if variables.is_empty() {
|
||||
for (env_var, value) in env::vars() {
|
||||
|
|
|
@ -108,10 +108,13 @@ impl WordFilter {
|
|||
// Ignore empty string regex from cmd-line-args
|
||||
let arg_reg: Option<String> = if matches.is_present(options::WORD_REGEXP) {
|
||||
match matches.value_of(options::WORD_REGEXP) {
|
||||
Some(v) => match v.is_empty() {
|
||||
true => None,
|
||||
false => Some(v.to_string()),
|
||||
},
|
||||
Some(v) => {
|
||||
if v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(v.to_string())
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Most of the time when sorting is spent comparing lines. The comparison functions however differ based
|
||||
on which arguments are passed to `sort`, therefore it is important to always benchmark multiple scenarios.
|
||||
This is an overwiew over what was benchmarked, and if you make changes to `sort`, you are encouraged to check
|
||||
This is an overview over what was benchmarked, and if you make changes to `sort`, you are encouraged to check
|
||||
how performance was affected for the workloads listed below. Feel free to add other workloads to the
|
||||
list that we should improve / make sure not to regress.
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ impl Chunk {
|
|||
/// * `lines`: The recycled vector to fill with lines. Must be empty.
|
||||
/// * `settings`: The global settings.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[allow(clippy::borrowed_box)]
|
||||
pub fn read(
|
||||
sender_option: &mut Option<SyncSender<Chunk>>,
|
||||
mut buffer: Vec<u8>,
|
||||
|
@ -164,6 +165,7 @@ fn parse_lines<'a>(
|
|||
/// The remaining bytes must be copied to the start of the buffer for the next invocation,
|
||||
/// if another invocation is necessary, which is determined by the other return value.
|
||||
/// * Whether this function should be called again.
|
||||
#[allow(clippy::borrowed_box)]
|
||||
fn read_to_buffer(
|
||||
file: &mut Box<dyn Read + Send>,
|
||||
next_files: &mut impl Iterator<Item = Box<dyn Read + Send>>,
|
||||
|
|
|
@ -108,7 +108,7 @@ const POSITIVE: char = '+';
|
|||
// available memory into consideration, instead of relying on this constant only.
|
||||
static DEFAULT_BUF_SIZE: usize = 1_000_000_000; // 1 GB
|
||||
|
||||
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Copy)]
|
||||
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Debug)]
|
||||
enum SortMode {
|
||||
Numeric,
|
||||
HumanNumeric,
|
||||
|
@ -118,6 +118,21 @@ enum SortMode {
|
|||
Random,
|
||||
Default,
|
||||
}
|
||||
|
||||
impl SortMode {
|
||||
fn get_short_name(&self) -> Option<char> {
|
||||
match self {
|
||||
SortMode::Numeric => Some('n'),
|
||||
SortMode::HumanNumeric => Some('h'),
|
||||
SortMode::GeneralNumeric => Some('g'),
|
||||
SortMode::Month => Some('M'),
|
||||
SortMode::Version => Some('V'),
|
||||
SortMode::Random => Some('R'),
|
||||
SortMode::Default => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GlobalSettings {
|
||||
mode: SortMode,
|
||||
|
@ -211,7 +226,7 @@ impl Default for GlobalSettings {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
struct KeySettings {
|
||||
mode: SortMode,
|
||||
ignore_blanks: bool,
|
||||
|
@ -221,6 +236,60 @@ struct KeySettings {
|
|||
reverse: bool,
|
||||
}
|
||||
|
||||
impl KeySettings {
|
||||
/// Checks if the supplied combination of `mode`, `ignore_non_printing` and `dictionary_order` is allowed.
|
||||
fn check_compatibility(
|
||||
mode: SortMode,
|
||||
ignore_non_printing: bool,
|
||||
dictionary_order: bool,
|
||||
) -> Result<(), String> {
|
||||
if matches!(
|
||||
mode,
|
||||
SortMode::Numeric | SortMode::HumanNumeric | SortMode::GeneralNumeric | SortMode::Month
|
||||
) {
|
||||
if dictionary_order {
|
||||
return Err(format!(
|
||||
"options '-{}{}' are incompatible",
|
||||
'd',
|
||||
mode.get_short_name().unwrap()
|
||||
));
|
||||
} else if ignore_non_printing {
|
||||
return Err(format!(
|
||||
"options '-{}{}' are incompatible",
|
||||
'i',
|
||||
mode.get_short_name().unwrap()
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_sort_mode(&mut self, mode: SortMode) -> Result<(), String> {
|
||||
if self.mode != SortMode::Default {
|
||||
return Err(format!(
|
||||
"options '-{}{}' are incompatible",
|
||||
self.mode.get_short_name().unwrap(),
|
||||
mode.get_short_name().unwrap()
|
||||
));
|
||||
}
|
||||
Self::check_compatibility(mode, self.ignore_non_printing, self.dictionary_order)?;
|
||||
self.mode = mode;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_dictionary_order(&mut self) -> Result<(), String> {
|
||||
Self::check_compatibility(self.mode, self.ignore_non_printing, true)?;
|
||||
self.dictionary_order = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_ignore_non_printing(&mut self) -> Result<(), String> {
|
||||
Self::check_compatibility(self.mode, true, self.dictionary_order)?;
|
||||
self.ignore_non_printing = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&GlobalSettings> for KeySettings {
|
||||
fn from(settings: &GlobalSettings) -> Self {
|
||||
Self {
|
||||
|
@ -234,6 +303,12 @@ impl From<&GlobalSettings> for KeySettings {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for KeySettings {
|
||||
fn default() -> Self {
|
||||
Self::from(&GlobalSettings::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum NumCache {
|
||||
AsF64(GeneralF64ParseResult),
|
||||
|
@ -296,10 +371,10 @@ impl<'a> Line<'a> {
|
|||
fn print(&self, writer: &mut impl Write, settings: &GlobalSettings) {
|
||||
if settings.zero_terminated && !settings.debug {
|
||||
crash_if_err!(1, writer.write_all(self.line.as_bytes()));
|
||||
crash_if_err!(1, writer.write_all("\0".as_bytes()));
|
||||
crash_if_err!(1, writer.write_all(b"\0"));
|
||||
} else if !settings.debug {
|
||||
crash_if_err!(1, writer.write_all(self.line.as_bytes()));
|
||||
crash_if_err!(1, writer.write_all("\n".as_bytes()));
|
||||
crash_if_err!(1, writer.write_all(b"\n"));
|
||||
} else {
|
||||
crash_if_err!(1, self.print_debug(settings, writer));
|
||||
}
|
||||
|
@ -412,14 +487,18 @@ impl<'a> Line<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
if !(settings.mode == SortMode::Random
|
||||
|| settings.stable
|
||||
|| settings.unique
|
||||
|| !(settings.dictionary_order
|
||||
if settings.mode != SortMode::Random
|
||||
&& !settings.stable
|
||||
&& !settings.unique
|
||||
&& (settings.dictionary_order
|
||||
|| settings.ignore_blanks
|
||||
|| settings.ignore_case
|
||||
|| settings.ignore_non_printing
|
||||
|| settings.mode != SortMode::Default))
|
||||
|| settings.mode != SortMode::Default
|
||||
|| settings
|
||||
.selectors
|
||||
.last()
|
||||
.map_or(true, |selector| selector != &Default::default()))
|
||||
{
|
||||
// A last resort comparator is in use, underline the whole line.
|
||||
if self.line.is_empty() {
|
||||
|
@ -483,7 +562,7 @@ fn tokenize_with_separator(line: &str, separator: char) -> Vec<Field> {
|
|||
tokens
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
struct KeyPosition {
|
||||
/// 1-indexed, 0 is invalid.
|
||||
field: usize,
|
||||
|
@ -493,87 +572,45 @@ struct KeyPosition {
|
|||
}
|
||||
|
||||
impl KeyPosition {
|
||||
fn parse(key: &str, default_char_index: usize, settings: &mut KeySettings) -> Self {
|
||||
fn new(key: &str, default_char_index: usize, ignore_blanks: bool) -> Result<Self, String> {
|
||||
let mut field_and_char = key.split('.');
|
||||
let mut field = field_and_char
|
||||
|
||||
let field = field_and_char
|
||||
.next()
|
||||
.unwrap_or_else(|| crash!(1, "invalid key `{}`", key));
|
||||
let mut char = field_and_char.next();
|
||||
|
||||
// If there is a char index, we expect options to appear after it. Otherwise we expect them after the field index.
|
||||
let value_with_options = char.as_mut().unwrap_or(&mut field);
|
||||
|
||||
let mut ignore_blanks = settings.ignore_blanks;
|
||||
if let Some(options_start) = value_with_options.chars().position(char::is_alphabetic) {
|
||||
for option in value_with_options[options_start..].chars() {
|
||||
// valid options: MbdfghinRrV
|
||||
match option {
|
||||
'M' => settings.mode = SortMode::Month,
|
||||
'b' => ignore_blanks = true,
|
||||
'd' => settings.dictionary_order = true,
|
||||
'f' => settings.ignore_case = true,
|
||||
'g' => settings.mode = SortMode::GeneralNumeric,
|
||||
'h' => settings.mode = SortMode::HumanNumeric,
|
||||
'i' => settings.ignore_non_printing = true,
|
||||
'n' => settings.mode = SortMode::Numeric,
|
||||
'R' => settings.mode = SortMode::Random,
|
||||
'r' => settings.reverse = true,
|
||||
'V' => settings.mode = SortMode::Version,
|
||||
c => crash!(1, "invalid option for key: `{}`", c),
|
||||
}
|
||||
// All numeric sorts and month sort conflict with dictionary_order and ignore_non_printing.
|
||||
// Instad of reporting an error, let them overwrite each other.
|
||||
|
||||
// FIXME: This should only override if the overridden flag is a global flag.
|
||||
// If conflicting flags are attached to the key, GNU sort crashes and we should probably too.
|
||||
match option {
|
||||
'h' | 'n' | 'g' | 'M' => {
|
||||
settings.dictionary_order = false;
|
||||
settings.ignore_non_printing = false;
|
||||
}
|
||||
'd' | 'i' => {
|
||||
settings.mode = match settings.mode {
|
||||
SortMode::Numeric
|
||||
| SortMode::HumanNumeric
|
||||
| SortMode::GeneralNumeric
|
||||
| SortMode::Month => SortMode::Default,
|
||||
// Only SortMode::Default and SortMode::Version work with dictionary_order and ignore_non_printing
|
||||
m @ SortMode::Default
|
||||
| m @ SortMode::Version
|
||||
| m @ SortMode::Random => m,
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// Strip away option characters from the original value so we can parse it later
|
||||
*value_with_options = &value_with_options[..options_start];
|
||||
}
|
||||
.ok_or_else(|| format!("invalid key `{}`", key))?;
|
||||
let char = field_and_char.next();
|
||||
|
||||
let field = field
|
||||
.parse()
|
||||
.unwrap_or_else(|e| crash!(1, "failed to parse field index for key `{}`: {}", key, e));
|
||||
.map_err(|e| format!("failed to parse field index `{}`: {}", field, e))?;
|
||||
if field == 0 {
|
||||
crash!(1, "field index was 0");
|
||||
return Err("field index can not be 0".to_string());
|
||||
}
|
||||
let char = char.map_or(default_char_index, |char| {
|
||||
char.parse().unwrap_or_else(|e| {
|
||||
crash!(
|
||||
1,
|
||||
"failed to parse character index for key `{}`: {}",
|
||||
key,
|
||||
e
|
||||
)
|
||||
})
|
||||
});
|
||||
Self {
|
||||
|
||||
let char = char.map_or(Ok(default_char_index), |char| {
|
||||
char.parse()
|
||||
.map_err(|e| format!("failed to parse character index `{}`: {}", char, e))
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
field,
|
||||
char,
|
||||
ignore_blanks,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for KeyPosition {
|
||||
fn default() -> Self {
|
||||
KeyPosition {
|
||||
field: 1,
|
||||
char: 1,
|
||||
ignore_blanks: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
struct FieldSelector {
|
||||
from: KeyPosition,
|
||||
to: Option<KeyPosition>,
|
||||
|
@ -583,20 +620,120 @@ struct FieldSelector {
|
|||
is_default_selection: bool,
|
||||
}
|
||||
|
||||
impl FieldSelector {
|
||||
fn new(from: KeyPosition, to: Option<KeyPosition>, settings: KeySettings) -> Self {
|
||||
impl Default for FieldSelector {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
is_default_selection: from.field == 1
|
||||
&& from.char == 1
|
||||
&& to.is_none()
|
||||
&& !matches!(
|
||||
settings.mode,
|
||||
SortMode::Numeric | SortMode::GeneralNumeric | SortMode::HumanNumeric
|
||||
),
|
||||
needs_tokens: from.field != 1 || from.char == 0 || to.is_some(),
|
||||
from,
|
||||
to,
|
||||
settings,
|
||||
from: Default::default(),
|
||||
to: None,
|
||||
settings: Default::default(),
|
||||
needs_tokens: false,
|
||||
is_default_selection: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FieldSelector {
|
||||
/// Splits this position into the actual position and the attached options.
|
||||
fn split_key_options(position: &str) -> (&str, &str) {
|
||||
if let Some((options_start, _)) = position.char_indices().find(|(_, c)| c.is_alphabetic()) {
|
||||
position.split_at(options_start)
|
||||
} else {
|
||||
(position, "")
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(key: &str, global_settings: &GlobalSettings) -> Self {
|
||||
let mut from_to = key.split(',');
|
||||
let (from, from_options) = Self::split_key_options(from_to.next().unwrap());
|
||||
let to = from_to.next().map(|to| Self::split_key_options(to));
|
||||
let options_are_empty = from_options.is_empty() && matches!(to, None | Some((_, "")));
|
||||
crash_if_err!(
|
||||
2,
|
||||
if options_are_empty {
|
||||
// Inherit the global settings if there are no options attached to this key.
|
||||
(|| {
|
||||
// This would be ideal for a try block, I think. In the meantime this closure allows
|
||||
// to use the `?` operator here.
|
||||
Self::new(
|
||||
KeyPosition::new(from, 1, global_settings.ignore_blanks)?,
|
||||
to.map(|(to, _)| KeyPosition::new(to, 0, global_settings.ignore_blanks))
|
||||
.transpose()?,
|
||||
KeySettings::from(global_settings),
|
||||
)
|
||||
})()
|
||||
} else {
|
||||
// Do not inherit from `global_settings`, as there are options attached to this key.
|
||||
Self::parse_with_options((from, from_options), to)
|
||||
}
|
||||
.map_err(|e| format!("failed to parse key `{}`: {}", key, e))
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_with_options(
|
||||
(from, from_options): (&str, &str),
|
||||
to: Option<(&str, &str)>,
|
||||
) -> Result<Self, String> {
|
||||
/// Applies `options` to `key_settings`, returning if the 'b'-flag (ignore blanks) was present.
|
||||
fn parse_key_settings(
|
||||
options: &str,
|
||||
key_settings: &mut KeySettings,
|
||||
) -> Result<bool, String> {
|
||||
let mut ignore_blanks = false;
|
||||
for option in options.chars() {
|
||||
match option {
|
||||
'M' => key_settings.set_sort_mode(SortMode::Month)?,
|
||||
'b' => ignore_blanks = true,
|
||||
'd' => key_settings.set_dictionary_order()?,
|
||||
'f' => key_settings.ignore_case = true,
|
||||
'g' => key_settings.set_sort_mode(SortMode::GeneralNumeric)?,
|
||||
'h' => key_settings.set_sort_mode(SortMode::HumanNumeric)?,
|
||||
'i' => key_settings.set_ignore_non_printing()?,
|
||||
'n' => key_settings.set_sort_mode(SortMode::Numeric)?,
|
||||
'R' => key_settings.set_sort_mode(SortMode::Random)?,
|
||||
'r' => key_settings.reverse = true,
|
||||
'V' => key_settings.set_sort_mode(SortMode::Version)?,
|
||||
c => return Err(format!("invalid option: `{}`", c)),
|
||||
}
|
||||
}
|
||||
Ok(ignore_blanks)
|
||||
}
|
||||
|
||||
let mut key_settings = KeySettings::default();
|
||||
let from = parse_key_settings(from_options, &mut key_settings)
|
||||
.map(|ignore_blanks| KeyPosition::new(from, 1, ignore_blanks))??;
|
||||
let to = if let Some((to, to_options)) = to {
|
||||
Some(
|
||||
parse_key_settings(to_options, &mut key_settings)
|
||||
.map(|ignore_blanks| KeyPosition::new(to, 0, ignore_blanks))??,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Self::new(from, to, key_settings)
|
||||
}
|
||||
|
||||
fn new(
|
||||
from: KeyPosition,
|
||||
to: Option<KeyPosition>,
|
||||
settings: KeySettings,
|
||||
) -> Result<Self, String> {
|
||||
if from.char == 0 {
|
||||
Err("invalid character index 0 for the start position of a field".to_string())
|
||||
} else {
|
||||
Ok(Self {
|
||||
is_default_selection: from.field == 1
|
||||
&& from.char == 1
|
||||
&& to.is_none()
|
||||
&& !matches!(
|
||||
settings.mode,
|
||||
SortMode::Numeric | SortMode::GeneralNumeric | SortMode::HumanNumeric
|
||||
)
|
||||
&& !from.ignore_blanks,
|
||||
needs_tokens: from.field != 1 || from.char == 0 || to.is_some(),
|
||||
from,
|
||||
to,
|
||||
settings,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -900,7 +1037,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.long(OPT_SEPARATOR)
|
||||
.help("custom separator for -k")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name(OPT_ZERO_TERMINATED)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ZERO_TERMINATED)
|
||||
.short("z")
|
||||
.long(OPT_ZERO_TERMINATED)
|
||||
.help("line delimiter is NUL, not newline"),
|
||||
|
@ -1053,43 +1191,27 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
if matches.is_present(OPT_KEY) {
|
||||
for key in &matches.args[OPT_KEY].vals {
|
||||
let key = key.to_string_lossy();
|
||||
let mut from_to = key.split(',');
|
||||
let mut key_settings = KeySettings::from(&settings);
|
||||
let from = KeyPosition::parse(
|
||||
from_to
|
||||
.next()
|
||||
.unwrap_or_else(|| crash!(1, "invalid key `{}`", key)),
|
||||
1,
|
||||
&mut key_settings,
|
||||
);
|
||||
if from.char == 0 {
|
||||
crash!(
|
||||
1,
|
||||
"invalid character index 0 in `{}` for the start position of a field",
|
||||
key
|
||||
)
|
||||
}
|
||||
let to = from_to
|
||||
.next()
|
||||
.map(|to| KeyPosition::parse(to, 0, &mut key_settings));
|
||||
let field_selector = FieldSelector::new(from, to, key_settings);
|
||||
settings.selectors.push(field_selector);
|
||||
settings
|
||||
.selectors
|
||||
.push(FieldSelector::parse(&key.to_string_lossy(), &settings));
|
||||
}
|
||||
}
|
||||
|
||||
if !settings.stable || !matches.is_present(OPT_KEY) {
|
||||
if !matches.is_present(OPT_KEY) {
|
||||
// add a default selector matching the whole line
|
||||
let key_settings = KeySettings::from(&settings);
|
||||
settings.selectors.push(FieldSelector::new(
|
||||
KeyPosition {
|
||||
field: 1,
|
||||
char: 1,
|
||||
ignore_blanks: key_settings.ignore_blanks,
|
||||
},
|
||||
None,
|
||||
key_settings,
|
||||
));
|
||||
settings.selectors.push(
|
||||
FieldSelector::new(
|
||||
KeyPosition {
|
||||
field: 1,
|
||||
char: 1,
|
||||
ignore_blanks: key_settings.ignore_blanks,
|
||||
},
|
||||
None,
|
||||
key_settings,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
exec(&files, &settings)
|
||||
|
@ -1437,7 +1559,7 @@ mod tests {
|
|||
fn test_get_hash() {
|
||||
let a = "Ted".to_string();
|
||||
|
||||
assert_eq!(2646829031758483623, get_hash(&a));
|
||||
assert_eq!(2_646_829_031_758_483_623, get_hash(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -200,6 +200,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
split(&settings)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Settings {
|
||||
prefix: String,
|
||||
numeric_suffix: bool,
|
||||
|
@ -210,7 +211,7 @@ struct Settings {
|
|||
filter: Option<String>,
|
||||
strategy: String,
|
||||
strategy_param: String,
|
||||
verbose: bool,
|
||||
verbose: bool, // TODO: warning: field is never read: `verbose`
|
||||
}
|
||||
|
||||
trait Splitter {
|
||||
|
|
|
@ -199,6 +199,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if matches.is_present(options::FILE_SYSTEM) {
|
||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||
syncfs(files);
|
||||
|
|
|
@ -265,11 +265,10 @@ impl Parser {
|
|||
fn boolop(&mut self, op: Symbol) {
|
||||
if op == Symbol::BoolOp(OsString::from("-a")) {
|
||||
self.term();
|
||||
self.stack.push(op);
|
||||
} else {
|
||||
self.expr();
|
||||
self.stack.push(op);
|
||||
}
|
||||
self.stack.push(op);
|
||||
}
|
||||
|
||||
/// Parse a (possible) unary argument test (string length or file
|
||||
|
|
|
@ -145,14 +145,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|| matches.is_present(options::sources::CURRENT)
|
||||
{
|
||||
let timestamp = if matches.is_present(options::sources::DATE) {
|
||||
parse_date(matches.value_of(options::sources::DATE).unwrap().as_ref())
|
||||
parse_date(matches.value_of(options::sources::DATE).unwrap())
|
||||
} else {
|
||||
parse_timestamp(
|
||||
matches
|
||||
.value_of(options::sources::CURRENT)
|
||||
.unwrap()
|
||||
.as_ref(),
|
||||
)
|
||||
parse_timestamp(matches.value_of(options::sources::CURRENT).unwrap())
|
||||
};
|
||||
(timestamp, timestamp)
|
||||
} else {
|
||||
|
|
|
@ -110,7 +110,7 @@ impl<'a> Iterator for ExpandSet<'a> {
|
|||
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!
|
||||
while let Some(n) = self.range.next() {
|
||||
for n in &mut self.range {
|
||||
if let Some(c) = from_u32(n) {
|
||||
return Some(c);
|
||||
}
|
||||
|
|
|
@ -551,10 +551,11 @@ impl Who {
|
|||
" ?".into()
|
||||
};
|
||||
|
||||
let mut s = ut.host();
|
||||
if self.do_lookup {
|
||||
s = safe_unwrap!(ut.canon_host());
|
||||
}
|
||||
let s = if self.do_lookup {
|
||||
safe_unwrap!(ut.canon_host())
|
||||
} else {
|
||||
ut.host()
|
||||
};
|
||||
let hoststr = if s.is_empty() { s } else { format!("({})", s) };
|
||||
|
||||
self.print_line(
|
||||
|
|
|
@ -179,7 +179,7 @@ impl MountInfo {
|
|||
/* for Irix 6.5 */
|
||||
| "ignore" => self.dummy = true,
|
||||
_ => self.dummy = self.fs_type == "none"
|
||||
&& self.mount_option.find(MOUNT_OPT_BIND).is_none(),
|
||||
&& !self.mount_option.contains(MOUNT_OPT_BIND)
|
||||
}
|
||||
// set MountInfo::remote
|
||||
#[cfg(windows)]
|
||||
|
|
|
@ -40,6 +40,7 @@ pub enum ExitStatus {
|
|||
Signal(i32),
|
||||
}
|
||||
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
impl ExitStatus {
|
||||
fn from_std_status(status: StdExitStatus) -> Self {
|
||||
#[cfg(unix)]
|
||||
|
|
|
@ -146,15 +146,16 @@ pub trait Args: Iterator<Item = OsString> + Sized {
|
|||
InvalidEncodingHandling::Ignore => s.is_ok(),
|
||||
_ => true,
|
||||
})
|
||||
.map(|s| match s.is_ok() {
|
||||
true => s.unwrap(),
|
||||
false => s.unwrap_err(),
|
||||
.map(|s| match s {
|
||||
Ok(v) => v,
|
||||
Err(e) => e,
|
||||
})
|
||||
.collect();
|
||||
|
||||
match full_conversion {
|
||||
true => ConversionResult::Complete(result_vector),
|
||||
false => ConversionResult::Lossy(result_vector),
|
||||
if full_conversion {
|
||||
ConversionResult::Complete(result_vector)
|
||||
} else {
|
||||
ConversionResult::Lossy(result_vector)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ pub fn determine_backup_suffix(supplied_suffix: Option<&str>) -> String {
|
|||
if let Some(suffix) = supplied_suffix {
|
||||
String::from(suffix)
|
||||
} else {
|
||||
env::var("SIMPLE_BACKUP_SUFFIX").unwrap_or("~".to_owned())
|
||||
env::var("SIMPLE_BACKUP_SUFFIX").unwrap_or_else(|_| "~".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ fn test_base32_encode_file() {
|
|||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
for decode_param in vec!["-d", "--decode"] {
|
||||
for decode_param in &["-d", "--decode"] {
|
||||
let input = "JBSWY3DPFQQFO33SNRSCC===\n";
|
||||
new_ucmd!()
|
||||
.arg(decode_param)
|
||||
|
@ -56,7 +56,7 @@ fn test_garbage() {
|
|||
|
||||
#[test]
|
||||
fn test_ignore_garbage() {
|
||||
for ignore_garbage_param in vec!["-i", "--ignore-garbage"] {
|
||||
for ignore_garbage_param in &["-i", "--ignore-garbage"] {
|
||||
let input = "JBSWY\x013DPFQ\x02QFO33SNRSCC===\n";
|
||||
new_ucmd!()
|
||||
.arg("-d")
|
||||
|
@ -69,7 +69,7 @@ fn test_ignore_garbage() {
|
|||
|
||||
#[test]
|
||||
fn test_wrap() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
for wrap_param in &["-w", "--wrap"] {
|
||||
let input = "The quick brown fox jumps over the lazy dog.";
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
|
@ -84,16 +84,21 @@ fn test_wrap() {
|
|||
|
||||
#[test]
|
||||
fn test_wrap_no_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
new_ucmd!().arg(wrap_param).fails().stderr_only(format!(
|
||||
"error: The argument '--wrap <wrap>\' requires a value but none was supplied\n\nUSAGE:\n base32 [OPTION]... [FILE]\n\nFor more information try --help"
|
||||
));
|
||||
for wrap_param in &["-w", "--wrap"] {
|
||||
let expected_stderr = "error: The argument '--wrap <wrap>\' requires a value but none was \
|
||||
supplied\n\nUSAGE:\n base32 [OPTION]... [FILE]\n\nFor more \
|
||||
information try --help"
|
||||
.to_string();
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.fails()
|
||||
.stderr_only(expected_stderr);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_bad_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
for wrap_param in &["-w", "--wrap"] {
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.arg("b")
|
||||
|
|
|
@ -26,7 +26,7 @@ fn test_base64_encode_file() {
|
|||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
for decode_param in vec!["-d", "--decode"] {
|
||||
for decode_param in &["-d", "--decode"] {
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==";
|
||||
new_ucmd!()
|
||||
.arg(decode_param)
|
||||
|
@ -48,7 +48,7 @@ fn test_garbage() {
|
|||
|
||||
#[test]
|
||||
fn test_ignore_garbage() {
|
||||
for ignore_garbage_param in vec!["-i", "--ignore-garbage"] {
|
||||
for ignore_garbage_param in &["-i", "--ignore-garbage"] {
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==\0";
|
||||
new_ucmd!()
|
||||
.arg("-d")
|
||||
|
@ -61,7 +61,7 @@ fn test_ignore_garbage() {
|
|||
|
||||
#[test]
|
||||
fn test_wrap() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
for wrap_param in &["-w", "--wrap"] {
|
||||
let input = "The quick brown fox jumps over the lazy dog.";
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
|
@ -74,7 +74,7 @@ fn test_wrap() {
|
|||
|
||||
#[test]
|
||||
fn test_wrap_no_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
for wrap_param in &["-w", "--wrap"] {
|
||||
new_ucmd!().arg(wrap_param).fails().stderr_contains(
|
||||
&"The argument '--wrap <wrap>' requires a value but none was supplied",
|
||||
);
|
||||
|
@ -83,7 +83,7 @@ fn test_wrap_no_arg() {
|
|||
|
||||
#[test]
|
||||
fn test_wrap_bad_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
for wrap_param in &["-w", "--wrap"] {
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.arg("b")
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::ffi::OsStr;
|
|||
|
||||
#[test]
|
||||
fn test_help() {
|
||||
for help_flg in vec!["-h", "--help"] {
|
||||
for help_flg in &["-h", "--help"] {
|
||||
new_ucmd!()
|
||||
.arg(&help_flg)
|
||||
.succeeds()
|
||||
|
@ -15,7 +15,7 @@ fn test_help() {
|
|||
|
||||
#[test]
|
||||
fn test_version() {
|
||||
for version_flg in vec!["-V", "--version"] {
|
||||
for version_flg in &["-V", "--version"] {
|
||||
assert!(new_ucmd!()
|
||||
.arg(&version_flg)
|
||||
.succeeds()
|
||||
|
@ -59,7 +59,7 @@ fn test_dont_remove_suffix() {
|
|||
|
||||
#[test]
|
||||
fn test_multiple_param() {
|
||||
for multiple_param in vec!["-a", "--multiple"] {
|
||||
for &multiple_param in &["-a", "--multiple"] {
|
||||
let path = "/foo/bar/baz";
|
||||
new_ucmd!()
|
||||
.args(&[multiple_param, path, path])
|
||||
|
@ -70,7 +70,7 @@ fn test_multiple_param() {
|
|||
|
||||
#[test]
|
||||
fn test_suffix_param() {
|
||||
for suffix_param in vec!["-s", "--suffix"] {
|
||||
for &suffix_param in &["-s", "--suffix"] {
|
||||
let path = "/foo/bar/baz.exe";
|
||||
new_ucmd!()
|
||||
.args(&[suffix_param, ".exe", path, path])
|
||||
|
@ -81,7 +81,7 @@ fn test_suffix_param() {
|
|||
|
||||
#[test]
|
||||
fn test_zero_param() {
|
||||
for zero_param in vec!["-z", "--zero"] {
|
||||
for &zero_param in &["-z", "--zero"] {
|
||||
let path = "/foo/bar/baz";
|
||||
new_ucmd!()
|
||||
.args(&[zero_param, "-a", path, path])
|
||||
|
@ -91,7 +91,12 @@ fn test_zero_param() {
|
|||
}
|
||||
|
||||
fn expect_error(input: Vec<&str>) {
|
||||
assert!(new_ucmd!().args(&input).fails().no_stdout().stderr().len() > 0);
|
||||
assert!(!new_ucmd!()
|
||||
.args(&input)
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -237,7 +237,7 @@ fn test_numbered_lines_no_trailing_newline() {
|
|||
|
||||
#[test]
|
||||
fn test_stdin_show_nonprinting() {
|
||||
for same_param in vec!["-v", "--show-nonprinting"] {
|
||||
for same_param in &["-v", "--show-nonprinting"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param])
|
||||
.pipe_in("\t\0\n")
|
||||
|
@ -248,7 +248,7 @@ fn test_stdin_show_nonprinting() {
|
|||
|
||||
#[test]
|
||||
fn test_stdin_show_tabs() {
|
||||
for same_param in vec!["-T", "--show-tabs"] {
|
||||
for same_param in &["-T", "--show-tabs"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param])
|
||||
.pipe_in("\t\0\n")
|
||||
|
@ -259,7 +259,7 @@ fn test_stdin_show_tabs() {
|
|||
|
||||
#[test]
|
||||
fn test_stdin_show_ends() {
|
||||
for same_param in vec!["-E", "--show-ends"] {
|
||||
for &same_param in &["-E", "--show-ends"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param, "-"])
|
||||
.pipe_in("\t\0\n\t")
|
||||
|
@ -270,7 +270,7 @@ fn test_stdin_show_ends() {
|
|||
|
||||
#[test]
|
||||
fn test_stdin_show_all() {
|
||||
for same_param in vec!["-A", "--show-all"] {
|
||||
for same_param in &["-A", "--show-all"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param])
|
||||
.pipe_in("\t\0\n")
|
||||
|
@ -299,7 +299,7 @@ fn test_stdin_nonprinting_and_tabs() {
|
|||
|
||||
#[test]
|
||||
fn test_stdin_squeeze_blank() {
|
||||
for same_param in vec!["-s", "--squeeze-blank"] {
|
||||
for same_param in &["-s", "--squeeze-blank"] {
|
||||
new_ucmd!()
|
||||
.arg(same_param)
|
||||
.pipe_in("\n\na\n\n\n\n\nb\n\n\n")
|
||||
|
@ -310,7 +310,7 @@ fn test_stdin_squeeze_blank() {
|
|||
|
||||
#[test]
|
||||
fn test_stdin_number_non_blank() {
|
||||
for same_param in vec!["-b", "--number-nonblank"] {
|
||||
for same_param in &["-b", "--number-nonblank"] {
|
||||
new_ucmd!()
|
||||
.arg(same_param)
|
||||
.arg("-")
|
||||
|
@ -322,7 +322,7 @@ fn test_stdin_number_non_blank() {
|
|||
|
||||
#[test]
|
||||
fn test_non_blank_overrides_number() {
|
||||
for same_param in vec!["-b", "--number-nonblank"] {
|
||||
for &same_param in &["-b", "--number-nonblank"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param, "-"])
|
||||
.pipe_in("\na\nb\n\n\nc")
|
||||
|
@ -333,7 +333,7 @@ fn test_non_blank_overrides_number() {
|
|||
|
||||
#[test]
|
||||
fn test_squeeze_blank_before_numbering() {
|
||||
for same_param in vec!["-s", "--squeeze-blank"] {
|
||||
for &same_param in &["-s", "--squeeze-blank"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param, "-n", "-"])
|
||||
.pipe_in("a\n\n\nb")
|
||||
|
@ -408,7 +408,10 @@ fn test_domain_socket() {
|
|||
use std::thread;
|
||||
use unix_socket::UnixListener;
|
||||
|
||||
let dir = tempfile::Builder::new().prefix("unix_socket").tempdir().expect("failed to create dir");
|
||||
let dir = tempfile::Builder::new()
|
||||
.prefix("unix_socket")
|
||||
.tempdir()
|
||||
.expect("failed to create dir");
|
||||
let socket_path = dir.path().join("sock");
|
||||
let listener = UnixListener::bind(&socket_path).expect("failed to create socket");
|
||||
|
||||
|
@ -426,7 +429,7 @@ fn test_domain_socket() {
|
|||
|
||||
let child = new_ucmd!().args(&[socket_path]).run_no_wait();
|
||||
barrier.wait();
|
||||
let stdout = &child.wait_with_output().unwrap().stdout.clone();
|
||||
let stdout = &child.wait_with_output().unwrap().stdout;
|
||||
let output = String::from_utf8_lossy(&stdout);
|
||||
assert_eq!("a\tb", output);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ fn test_invalid_option() {
|
|||
new_ucmd!().arg("-w").arg("/").fails();
|
||||
}
|
||||
|
||||
static DIR: &'static str = "/tmp";
|
||||
static DIR: &str = "/tmp";
|
||||
|
||||
#[test]
|
||||
fn test_invalid_group() {
|
||||
|
|
|
@ -8,8 +8,8 @@ use self::chmod::strip_minus_from_mode;
|
|||
extern crate chmod;
|
||||
use self::libc::umask;
|
||||
|
||||
static TEST_FILE: &'static str = "file";
|
||||
static REFERENCE_FILE: &'static str = "reference";
|
||||
static TEST_FILE: &str = "file";
|
||||
static REFERENCE_FILE: &str = "reference";
|
||||
static REFERENCE_PERMS: u32 = 0o247;
|
||||
lazy_static! {
|
||||
static ref UMASK_MUTEX: Mutex<()> = Mutex::new(());
|
||||
|
@ -69,6 +69,7 @@ fn run_tests(tests: Vec<TestCase>) {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_chmod_octal() {
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
|
@ -121,6 +122,7 @@ fn test_chmod_octal() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_chmod_ugoa() {
|
||||
let _guard = UMASK_MUTEX.lock();
|
||||
|
||||
|
@ -216,6 +218,7 @@ fn test_chmod_ugoa() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_chmod_ugo_copy() {
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
|
@ -248,6 +251,7 @@ fn test_chmod_ugo_copy() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_chmod_many_options() {
|
||||
let _guard = UMASK_MUTEX.lock();
|
||||
|
||||
|
@ -264,6 +268,7 @@ fn test_chmod_many_options() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_chmod_reference_file() {
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
|
@ -303,6 +308,7 @@ fn test_permission_denied() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_chmod_recursive() {
|
||||
let _guard = UMASK_MUTEX.lock();
|
||||
|
||||
|
@ -477,7 +483,7 @@ fn test_chmod_strip_minus_from_mode() {
|
|||
];
|
||||
|
||||
for test in tests {
|
||||
let mut args: Vec<String> = test.0.split(" ").map(|v| v.to_string()).collect();
|
||||
let mut args: Vec<String> = test.0.split(' ').map(|v| v.to_string()).collect();
|
||||
let _mode_had_minus_prefix = strip_minus_from_mode(&mut args);
|
||||
assert_eq!(test.1, args.join(" "));
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ mod test_passgrp {
|
|||
#[test]
|
||||
fn test_usr2uid() {
|
||||
assert_eq!(0, usr2uid("root").unwrap());
|
||||
assert!(usr2uid("88888888").is_err());
|
||||
assert!(usr2uid("88_888_888").is_err());
|
||||
assert!(usr2uid("auserthatdoesntexist").is_err());
|
||||
}
|
||||
|
||||
|
@ -50,14 +50,14 @@ mod test_passgrp {
|
|||
} else {
|
||||
assert_eq!(0, grp2gid("wheel").unwrap());
|
||||
}
|
||||
assert!(grp2gid("88888888").is_err());
|
||||
assert!(grp2gid("88_888_888").is_err());
|
||||
assert!(grp2gid("agroupthatdoesntexist").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uid2usr() {
|
||||
assert_eq!("root", uid2usr(0).unwrap());
|
||||
assert!(uid2usr(88888888).is_err());
|
||||
assert!(uid2usr(88_888_888).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -67,7 +67,7 @@ mod test_passgrp {
|
|||
} else {
|
||||
assert_eq!("wheel", gid2grp(0).unwrap());
|
||||
}
|
||||
assert!(gid2grp(88888888).is_err());
|
||||
assert!(gid2grp(88_888_888).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,12 +85,12 @@ fn test_crc_for_bigger_than_32_bytes() {
|
|||
|
||||
let result = ucmd.arg("chars.txt").succeeds();
|
||||
|
||||
let mut stdout_splitted = result.stdout_str().split(" ");
|
||||
let mut stdout_splitted = result.stdout_str().split(' ');
|
||||
|
||||
let cksum: i64 = stdout_splitted.next().unwrap().parse().unwrap();
|
||||
let bytes_cnt: i64 = stdout_splitted.next().unwrap().parse().unwrap();
|
||||
|
||||
assert_eq!(cksum, 586047089);
|
||||
assert_eq!(cksum, 586_047_089);
|
||||
assert_eq!(bytes_cnt, 16);
|
||||
}
|
||||
|
||||
|
@ -100,11 +100,11 @@ fn test_stdin_larger_than_128_bytes() {
|
|||
|
||||
let result = ucmd.arg("larger_than_2056_bytes.txt").succeeds();
|
||||
|
||||
let mut stdout_splitted = result.stdout_str().split(" ");
|
||||
let mut stdout_splitted = result.stdout_str().split(' ');
|
||||
|
||||
let cksum: i64 = stdout_splitted.next().unwrap().parse().unwrap();
|
||||
let bytes_cnt: i64 = stdout_splitted.next().unwrap().parse().unwrap();
|
||||
|
||||
assert_eq!(cksum, 945881979);
|
||||
assert_eq!(cksum, 945_881_979);
|
||||
assert_eq!(bytes_cnt, 2058);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ fn output_delimiter_require_arg() {
|
|||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn zero_terminated() {
|
||||
for param in vec!["-z", "--zero-terminated"] {
|
||||
for ¶m in &["-z", "--zero-terminated"] {
|
||||
new_ucmd!()
|
||||
.args(&[param, "a", "b"])
|
||||
.fails()
|
||||
|
|
|
@ -108,7 +108,7 @@ fn test_cp_multiple_files() {
|
|||
|
||||
#[test]
|
||||
// FixME: for MacOS, this has intermittent failures; track repair progress at GH:uutils/coreutils/issues/1590
|
||||
#[cfg(not(macos))]
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn test_cp_recurse() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.arg("-r")
|
||||
|
@ -132,7 +132,7 @@ fn test_cp_with_dirs_t() {
|
|||
|
||||
#[test]
|
||||
// FixME: for MacOS, this has intermittent failures; track repair progress at GH:uutils/coreutils/issues/1590
|
||||
#[cfg(not(macos))]
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn test_cp_with_dirs() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static INPUT: &'static str = "lists.txt";
|
||||
static INPUT: &str = "lists.txt";
|
||||
|
||||
struct TestedSequence<'b> {
|
||||
name: &'b str,
|
||||
sequence: &'b str,
|
||||
}
|
||||
|
||||
static EXAMPLE_SEQUENCES: &'static [TestedSequence<'static>] = &[
|
||||
static EXAMPLE_SEQUENCES: &[TestedSequence] = &[
|
||||
TestedSequence {
|
||||
name: "singular",
|
||||
sequence: "2",
|
||||
|
@ -34,14 +34,14 @@ static EXAMPLE_SEQUENCES: &'static [TestedSequence<'static>] = &[
|
|||
},
|
||||
];
|
||||
|
||||
static COMPLEX_SEQUENCE: &'static TestedSequence<'static> = &TestedSequence {
|
||||
static COMPLEX_SEQUENCE: &TestedSequence = &TestedSequence {
|
||||
name: "",
|
||||
sequence: "9-,6-7,-2,4",
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_byte_sequence() {
|
||||
for param in vec!["-b", "--bytes"] {
|
||||
for ¶m in &["-b", "--bytes"] {
|
||||
for example_seq in EXAMPLE_SEQUENCES {
|
||||
new_ucmd!()
|
||||
.args(&[param, example_seq.sequence, INPUT])
|
||||
|
@ -53,7 +53,7 @@ fn test_byte_sequence() {
|
|||
|
||||
#[test]
|
||||
fn test_char_sequence() {
|
||||
for param in vec!["-c", "--characters"] {
|
||||
for ¶m in &["-c", "--characters"] {
|
||||
for example_seq in EXAMPLE_SEQUENCES {
|
||||
//as of coreutils 8.25 a char range is effectively the same as a byte range; there is no distinct treatment of utf8 chars.
|
||||
new_ucmd!()
|
||||
|
@ -66,7 +66,7 @@ fn test_char_sequence() {
|
|||
|
||||
#[test]
|
||||
fn test_field_sequence() {
|
||||
for param in vec!["-f", "--fields"] {
|
||||
for ¶m in &["-f", "--fields"] {
|
||||
for example_seq in EXAMPLE_SEQUENCES {
|
||||
new_ucmd!()
|
||||
.args(&[param, example_seq.sequence, INPUT])
|
||||
|
@ -78,7 +78,7 @@ fn test_field_sequence() {
|
|||
|
||||
#[test]
|
||||
fn test_specify_delimiter() {
|
||||
for param in vec!["-d", "--delimiter"] {
|
||||
for ¶m in &["-d", "--delimiter"] {
|
||||
new_ucmd!()
|
||||
.args(&[param, ":", "-f", COMPLEX_SEQUENCE.sequence, INPUT])
|
||||
.succeeds()
|
||||
|
@ -122,7 +122,7 @@ fn test_zero_terminated() {
|
|||
|
||||
#[test]
|
||||
fn test_only_delimited() {
|
||||
for param in vec!["-s", "--only-delimited"] {
|
||||
for param in &["-s", "--only-delimited"] {
|
||||
new_ucmd!()
|
||||
.args(&["-d_", param, "-f", "1"])
|
||||
.pipe_in("91\n82\n7_3")
|
||||
|
|
|
@ -187,7 +187,7 @@ fn test_du_d_flag() {
|
|||
// TODO: gnu `du` doesn't use trailing "/" here
|
||||
// result.stdout_str(), result_reference.stdout_str()
|
||||
result.stdout_str().trim_end_matches("/\n"),
|
||||
result_reference.stdout_str().trim_end_matches("\n")
|
||||
result_reference.stdout_str().trim_end_matches('\n')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ fn test_null_delimiter() {
|
|||
|
||||
let mut vars: Vec<_> = out.split('\0').collect();
|
||||
assert_eq!(vars.len(), 3);
|
||||
vars.sort();
|
||||
vars.sort_unstable();
|
||||
assert_eq!(vars[0], "");
|
||||
assert_eq!(vars[1], "ABC=xyz");
|
||||
assert_eq!(vars[2], "FOO=bar");
|
||||
|
@ -135,7 +135,7 @@ fn test_unset_variable() {
|
|||
.succeeds()
|
||||
.stdout_move_str();
|
||||
|
||||
assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false);
|
||||
assert!(!out.lines().any(|line| line.starts_with("HOME=")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -196,7 +196,7 @@ fn test_change_directory() {
|
|||
fn test_fail_change_directory() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let some_non_existing_path = "some_nonexistent_path";
|
||||
assert_eq!(Path::new(some_non_existing_path).is_dir(), false);
|
||||
assert!(!Path::new(some_non_existing_path).is_dir());
|
||||
|
||||
let out = scene
|
||||
.ucmd()
|
||||
|
|
|
@ -2,55 +2,95 @@ use crate::common::util::*;
|
|||
|
||||
#[test]
|
||||
fn test_simple_arithmetic() {
|
||||
new_ucmd!().args(&["1", "+", "1"]).run().stdout_is("2\n");
|
||||
new_ucmd!()
|
||||
.args(&["1", "+", "1"])
|
||||
.succeeds()
|
||||
.stdout_only("2\n");
|
||||
|
||||
new_ucmd!().args(&["1", "-", "1"]).run().stdout_is("0\n");
|
||||
new_ucmd!()
|
||||
.args(&["1", "-", "1"])
|
||||
.fails()
|
||||
.status_code(1)
|
||||
.stdout_only("0\n");
|
||||
|
||||
new_ucmd!().args(&["3", "*", "2"]).run().stdout_is("6\n");
|
||||
new_ucmd!()
|
||||
.args(&["3", "*", "2"])
|
||||
.succeeds()
|
||||
.stdout_only("6\n");
|
||||
|
||||
new_ucmd!().args(&["4", "/", "2"]).run().stdout_is("2\n");
|
||||
new_ucmd!()
|
||||
.args(&["4", "/", "2"])
|
||||
.succeeds()
|
||||
.stdout_only("2\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complex_arithmetic() {
|
||||
let run = new_ucmd!()
|
||||
new_ucmd!()
|
||||
.args(&["9223372036854775807", "+", "9223372036854775807"])
|
||||
.run();
|
||||
run.stdout_is("");
|
||||
run.stderr_is("expr: +: Numerical result out of range");
|
||||
.succeeds()
|
||||
.stdout_only("18446744073709551614\n");
|
||||
|
||||
let run = new_ucmd!().args(&["9", "/", "0"]).run();
|
||||
run.stdout_is("");
|
||||
run.stderr_is("expr: division by zero");
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"92233720368547758076549841651981984981498415651",
|
||||
"%",
|
||||
"922337203685",
|
||||
])
|
||||
.succeeds()
|
||||
.stdout_only("533691697086\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"92233720368547758076549841651981984981498415651",
|
||||
"*",
|
||||
"922337203685",
|
||||
])
|
||||
.succeeds()
|
||||
.stdout_only("85070591730190566808700855121818604965830915152801178873935\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"92233720368547758076549841651981984981498415651",
|
||||
"-",
|
||||
"922337203685",
|
||||
])
|
||||
.succeeds()
|
||||
.stdout_only("92233720368547758076549841651981984059161211966\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["9", "/", "0"])
|
||||
.fails()
|
||||
.stderr_only("expr: division by zero\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parenthesis() {
|
||||
new_ucmd!()
|
||||
.args(&["(", "1", "+", "1", ")", "*", "2"])
|
||||
.run()
|
||||
.stdout_is("4\n");
|
||||
.succeeds()
|
||||
.stdout_only("4\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
new_ucmd!()
|
||||
.args(&["0", "|", "foo"])
|
||||
.run()
|
||||
.stdout_is("foo\n");
|
||||
.succeeds()
|
||||
.stdout_only("foo\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["foo", "|", "bar"])
|
||||
.run()
|
||||
.stdout_is("foo\n");
|
||||
.succeeds()
|
||||
.stdout_only("foo\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
new_ucmd!()
|
||||
.args(&["foo", "&", "1"])
|
||||
.run()
|
||||
.stdout_is("foo\n");
|
||||
.succeeds()
|
||||
.stdout_only("foo\n");
|
||||
|
||||
new_ucmd!().args(&["", "&", "1"]).run().stdout_is("0\n");
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE file
|
||||
// that was distributed with this source code.
|
||||
#![allow(clippy::unreadable_literal)]
|
||||
|
||||
use crate::common::util::*;
|
||||
use std::time::SystemTime;
|
||||
|
@ -89,7 +90,7 @@ fn test_random() {
|
|||
};
|
||||
}
|
||||
|
||||
factors.sort();
|
||||
factors.sort_unstable();
|
||||
(product, factors)
|
||||
};
|
||||
|
||||
|
@ -104,7 +105,7 @@ fn test_random() {
|
|||
for factor in factors {
|
||||
outstring.push_str(&(format!(" {}", factor))[..]);
|
||||
}
|
||||
outstring.push_str("\n");
|
||||
outstring.push('\n');
|
||||
}
|
||||
|
||||
run(instring.as_bytes(), outstring.as_bytes());
|
||||
|
@ -143,7 +144,7 @@ fn test_random_big() {
|
|||
f_bits.push(extrarange.sample(&mut rng));
|
||||
}
|
||||
f_bits.push(extrabits);
|
||||
f_bits.sort();
|
||||
f_bits.sort_unstable();
|
||||
|
||||
// compute sequential differences here. We leave off the +14 bits
|
||||
// so we can just index PRIMES_BY_BITS
|
||||
|
@ -172,7 +173,7 @@ fn test_random_big() {
|
|||
}
|
||||
assert_eq!(nbits, 64);
|
||||
|
||||
factors.sort();
|
||||
factors.sort_unstable();
|
||||
(product, factors)
|
||||
};
|
||||
|
||||
|
@ -186,7 +187,7 @@ fn test_random_big() {
|
|||
for factor in factors {
|
||||
outstring.push_str(&(format!(" {}", factor))[..]);
|
||||
}
|
||||
outstring.push_str("\n");
|
||||
outstring.push('\n');
|
||||
}
|
||||
|
||||
run(instring.as_bytes(), outstring.as_bytes());
|
||||
|
@ -214,7 +215,7 @@ fn run(instring: &[u8], outstring: &[u8]) {
|
|||
.stdout_is(String::from_utf8(outstring.to_owned()).unwrap());
|
||||
}
|
||||
|
||||
const PRIMES_BY_BITS: &'static [&'static [u64]] = &[
|
||||
const PRIMES_BY_BITS: &[&[u64]] = &[
|
||||
PRIMES14, PRIMES15, PRIMES16, PRIMES17, PRIMES18, PRIMES19, PRIMES20, PRIMES21, PRIMES22,
|
||||
PRIMES23, PRIMES24, PRIMES25, PRIMES26, PRIMES27, PRIMES28, PRIMES29, PRIMES30, PRIMES31,
|
||||
PRIMES32, PRIMES33, PRIMES34, PRIMES35, PRIMES36, PRIMES37, PRIMES38, PRIMES39, PRIMES40,
|
||||
|
@ -222,7 +223,7 @@ const PRIMES_BY_BITS: &'static [&'static [u64]] = &[
|
|||
PRIMES50,
|
||||
];
|
||||
|
||||
const PRIMES64: &'static [u64] = &[
|
||||
const PRIMES64: &[u64] = &[
|
||||
18446744073709551557,
|
||||
18446744073709551533,
|
||||
18446744073709551521,
|
||||
|
@ -274,7 +275,7 @@ const PRIMES64: &'static [u64] = &[
|
|||
18446744073709549571,
|
||||
];
|
||||
|
||||
const PRIMES14: &'static [u64] = &[
|
||||
const PRIMES14: &[u64] = &[
|
||||
16381, 16369, 16363, 16361, 16349, 16339, 16333, 16319, 16301, 16273, 16267, 16253, 16249,
|
||||
16231, 16229, 16223, 16217, 16193, 16189, 16187, 16183, 16141, 16139, 16127, 16111, 16103,
|
||||
16097, 16091, 16087, 16073, 16069, 16067, 16063, 16061, 16057, 16033, 16007, 16001, 15991,
|
||||
|
@ -286,7 +287,7 @@ const PRIMES14: &'static [u64] = &[
|
|||
15373,
|
||||
];
|
||||
|
||||
const PRIMES15: &'static [u64] = &[
|
||||
const PRIMES15: &[u64] = &[
|
||||
32749, 32719, 32717, 32713, 32707, 32693, 32687, 32653, 32647, 32633, 32621, 32611, 32609,
|
||||
32603, 32587, 32579, 32573, 32569, 32563, 32561, 32537, 32533, 32531, 32507, 32503, 32497,
|
||||
32491, 32479, 32467, 32443, 32441, 32429, 32423, 32413, 32411, 32401, 32381, 32377, 32371,
|
||||
|
@ -297,7 +298,7 @@ const PRIMES15: &'static [u64] = &[
|
|||
31847, 31817, 31799, 31793, 31771, 31769, 31751,
|
||||
];
|
||||
|
||||
const PRIMES16: &'static [u64] = &[
|
||||
const PRIMES16: &[u64] = &[
|
||||
65521, 65519, 65497, 65479, 65449, 65447, 65437, 65423, 65419, 65413, 65407, 65393, 65381,
|
||||
65371, 65357, 65353, 65327, 65323, 65309, 65293, 65287, 65269, 65267, 65257, 65239, 65213,
|
||||
65203, 65183, 65179, 65173, 65171, 65167, 65147, 65141, 65129, 65123, 65119, 65111, 65101,
|
||||
|
@ -307,7 +308,7 @@ const PRIMES16: &'static [u64] = &[
|
|||
64627, 64621, 64613, 64609, 64601, 64591, 64579, 64577, 64567, 64553,
|
||||
];
|
||||
|
||||
const PRIMES17: &'static [u64] = &[
|
||||
const PRIMES17: &[u64] = &[
|
||||
131071, 131063, 131059, 131041, 131023, 131011, 131009, 130987, 130981, 130973, 130969, 130957,
|
||||
130927, 130873, 130859, 130843, 130841, 130829, 130817, 130811, 130807, 130787, 130783, 130769,
|
||||
130729, 130699, 130693, 130687, 130681, 130657, 130651, 130649, 130643, 130639, 130633, 130631,
|
||||
|
@ -318,7 +319,7 @@ const PRIMES17: &'static [u64] = &[
|
|||
130073, 130069, 130057, 130051,
|
||||
];
|
||||
|
||||
const PRIMES18: &'static [u64] = &[
|
||||
const PRIMES18: &[u64] = &[
|
||||
262139, 262133, 262127, 262121, 262111, 262109, 262103, 262079, 262069, 262051, 262049, 262027,
|
||||
262007, 261983, 261977, 261973, 261971, 261959, 261917, 261887, 261881, 261847, 261823, 261799,
|
||||
261791, 261787, 261773, 261761, 261757, 261739, 261721, 261713, 261707, 261697, 261673, 261643,
|
||||
|
@ -328,7 +329,7 @@ const PRIMES18: &'static [u64] = &[
|
|||
261169, 261167, 261127,
|
||||
];
|
||||
|
||||
const PRIMES19: &'static [u64] = &[
|
||||
const PRIMES19: &[u64] = &[
|
||||
524287, 524269, 524261, 524257, 524243, 524231, 524221, 524219, 524203, 524201, 524197, 524189,
|
||||
524171, 524149, 524123, 524119, 524113, 524099, 524087, 524081, 524071, 524063, 524057, 524053,
|
||||
524047, 523997, 523987, 523969, 523949, 523937, 523927, 523907, 523903, 523877, 523867, 523847,
|
||||
|
@ -338,7 +339,7 @@ const PRIMES19: &'static [u64] = &[
|
|||
523403, 523387, 523357, 523351, 523349, 523333, 523307, 523297,
|
||||
];
|
||||
|
||||
const PRIMES20: &'static [u64] = &[
|
||||
const PRIMES20: &[u64] = &[
|
||||
1048573, 1048571, 1048559, 1048549, 1048517, 1048507, 1048447, 1048433, 1048423, 1048391,
|
||||
1048387, 1048367, 1048361, 1048357, 1048343, 1048309, 1048291, 1048273, 1048261, 1048219,
|
||||
1048217, 1048213, 1048193, 1048189, 1048139, 1048129, 1048127, 1048123, 1048063, 1048051,
|
||||
|
@ -348,7 +349,7 @@ const PRIMES20: &'static [u64] = &[
|
|||
1047691, 1047689, 1047671, 1047667, 1047653, 1047649, 1047647, 1047589, 1047587, 1047559,
|
||||
];
|
||||
|
||||
const PRIMES21: &'static [u64] = &[
|
||||
const PRIMES21: &[u64] = &[
|
||||
2097143, 2097133, 2097131, 2097097, 2097091, 2097083, 2097047, 2097041, 2097031, 2097023,
|
||||
2097013, 2096993, 2096987, 2096971, 2096959, 2096957, 2096947, 2096923, 2096911, 2096909,
|
||||
2096893, 2096881, 2096873, 2096867, 2096851, 2096837, 2096807, 2096791, 2096789, 2096777,
|
||||
|
@ -358,7 +359,7 @@ const PRIMES21: &'static [u64] = &[
|
|||
2096221, 2096209, 2096191, 2096183, 2096147,
|
||||
];
|
||||
|
||||
const PRIMES22: &'static [u64] = &[
|
||||
const PRIMES22: &[u64] = &[
|
||||
4194301, 4194287, 4194277, 4194271, 4194247, 4194217, 4194199, 4194191, 4194187, 4194181,
|
||||
4194173, 4194167, 4194143, 4194137, 4194131, 4194107, 4194103, 4194023, 4194011, 4194007,
|
||||
4193977, 4193971, 4193963, 4193957, 4193939, 4193929, 4193909, 4193869, 4193807, 4193803,
|
||||
|
@ -368,7 +369,7 @@ const PRIMES22: &'static [u64] = &[
|
|||
4193297,
|
||||
];
|
||||
|
||||
const PRIMES23: &'static [u64] = &[
|
||||
const PRIMES23: &[u64] = &[
|
||||
8388593, 8388587, 8388581, 8388571, 8388547, 8388539, 8388473, 8388461, 8388451, 8388449,
|
||||
8388439, 8388427, 8388421, 8388409, 8388377, 8388371, 8388319, 8388301, 8388287, 8388283,
|
||||
8388277, 8388239, 8388209, 8388187, 8388113, 8388109, 8388091, 8388071, 8388059, 8388019,
|
||||
|
@ -377,7 +378,7 @@ const PRIMES23: &'static [u64] = &[
|
|||
8387723, 8387707, 8387671, 8387611, 8387609, 8387591,
|
||||
];
|
||||
|
||||
const PRIMES24: &'static [u64] = &[
|
||||
const PRIMES24: &[u64] = &[
|
||||
16777213, 16777199, 16777183, 16777153, 16777141, 16777139, 16777127, 16777121, 16777099,
|
||||
16777049, 16777027, 16776989, 16776973, 16776971, 16776967, 16776961, 16776941, 16776937,
|
||||
16776931, 16776919, 16776901, 16776899, 16776869, 16776857, 16776839, 16776833, 16776817,
|
||||
|
@ -387,7 +388,7 @@ const PRIMES24: &'static [u64] = &[
|
|||
16776317, 16776313, 16776289, 16776217, 16776211,
|
||||
];
|
||||
|
||||
const PRIMES25: &'static [u64] = &[
|
||||
const PRIMES25: &[u64] = &[
|
||||
33554393, 33554383, 33554371, 33554347, 33554341, 33554317, 33554291, 33554273, 33554267,
|
||||
33554249, 33554239, 33554221, 33554201, 33554167, 33554159, 33554137, 33554123, 33554093,
|
||||
33554083, 33554077, 33554051, 33554021, 33554011, 33554009, 33553999, 33553991, 33553969,
|
||||
|
@ -397,7 +398,7 @@ const PRIMES25: &'static [u64] = &[
|
|||
33553519, 33553517, 33553511, 33553489, 33553463, 33553451, 33553417,
|
||||
];
|
||||
|
||||
const PRIMES26: &'static [u64] = &[
|
||||
const PRIMES26: &[u64] = &[
|
||||
67108859, 67108837, 67108819, 67108777, 67108763, 67108757, 67108753, 67108747, 67108739,
|
||||
67108729, 67108721, 67108709, 67108693, 67108669, 67108667, 67108661, 67108649, 67108633,
|
||||
67108597, 67108579, 67108529, 67108511, 67108507, 67108493, 67108471, 67108463, 67108453,
|
||||
|
@ -408,7 +409,7 @@ const PRIMES26: &'static [u64] = &[
|
|||
67107863,
|
||||
];
|
||||
|
||||
const PRIMES27: &'static [u64] = &[
|
||||
const PRIMES27: &[u64] = &[
|
||||
134217689, 134217649, 134217617, 134217613, 134217593, 134217541, 134217529, 134217509,
|
||||
134217497, 134217493, 134217487, 134217467, 134217439, 134217437, 134217409, 134217403,
|
||||
134217401, 134217367, 134217361, 134217353, 134217323, 134217301, 134217277, 134217257,
|
||||
|
@ -419,7 +420,7 @@ const PRIMES27: &'static [u64] = &[
|
|||
134216737, 134216729,
|
||||
];
|
||||
|
||||
const PRIMES28: &'static [u64] = &[
|
||||
const PRIMES28: &[u64] = &[
|
||||
268435399, 268435367, 268435361, 268435337, 268435331, 268435313, 268435291, 268435273,
|
||||
268435243, 268435183, 268435171, 268435157, 268435147, 268435133, 268435129, 268435121,
|
||||
268435109, 268435091, 268435067, 268435043, 268435039, 268435033, 268435019, 268435009,
|
||||
|
@ -430,7 +431,7 @@ const PRIMES28: &'static [u64] = &[
|
|||
268434479, 268434461,
|
||||
];
|
||||
|
||||
const PRIMES29: &'static [u64] = &[
|
||||
const PRIMES29: &[u64] = &[
|
||||
536870909, 536870879, 536870869, 536870849, 536870839, 536870837, 536870819, 536870813,
|
||||
536870791, 536870779, 536870767, 536870743, 536870729, 536870723, 536870717, 536870701,
|
||||
536870683, 536870657, 536870641, 536870627, 536870611, 536870603, 536870599, 536870573,
|
||||
|
@ -440,7 +441,7 @@ const PRIMES29: &'static [u64] = &[
|
|||
536870027, 536869999, 536869951, 536869943, 536869937, 536869919, 536869901, 536869891,
|
||||
];
|
||||
|
||||
const PRIMES30: &'static [u64] = &[
|
||||
const PRIMES30: &[u64] = &[
|
||||
1073741789, 1073741783, 1073741741, 1073741723, 1073741719, 1073741717, 1073741689, 1073741671,
|
||||
1073741663, 1073741651, 1073741621, 1073741567, 1073741561, 1073741527, 1073741503, 1073741477,
|
||||
1073741467, 1073741441, 1073741419, 1073741399, 1073741387, 1073741381, 1073741371, 1073741329,
|
||||
|
@ -449,7 +450,7 @@ const PRIMES30: &'static [u64] = &[
|
|||
1073740853, 1073740847, 1073740819, 1073740807,
|
||||
];
|
||||
|
||||
const PRIMES31: &'static [u64] = &[
|
||||
const PRIMES31: &[u64] = &[
|
||||
2147483647, 2147483629, 2147483587, 2147483579, 2147483563, 2147483549, 2147483543, 2147483497,
|
||||
2147483489, 2147483477, 2147483423, 2147483399, 2147483353, 2147483323, 2147483269, 2147483249,
|
||||
2147483237, 2147483179, 2147483171, 2147483137, 2147483123, 2147483077, 2147483069, 2147483059,
|
||||
|
@ -458,7 +459,7 @@ const PRIMES31: &'static [u64] = &[
|
|||
2147482763, 2147482739, 2147482697, 2147482693, 2147482681, 2147482663, 2147482661,
|
||||
];
|
||||
|
||||
const PRIMES32: &'static [u64] = &[
|
||||
const PRIMES32: &[u64] = &[
|
||||
4294967291, 4294967279, 4294967231, 4294967197, 4294967189, 4294967161, 4294967143, 4294967111,
|
||||
4294967087, 4294967029, 4294966997, 4294966981, 4294966943, 4294966927, 4294966909, 4294966877,
|
||||
4294966829, 4294966813, 4294966769, 4294966667, 4294966661, 4294966657, 4294966651, 4294966639,
|
||||
|
@ -466,7 +467,7 @@ const PRIMES32: &'static [u64] = &[
|
|||
4294966373, 4294966367, 4294966337, 4294966297,
|
||||
];
|
||||
|
||||
const PRIMES33: &'static [u64] = &[
|
||||
const PRIMES33: &[u64] = &[
|
||||
8589934583, 8589934567, 8589934543, 8589934513, 8589934487, 8589934307, 8589934291, 8589934289,
|
||||
8589934271, 8589934237, 8589934211, 8589934207, 8589934201, 8589934187, 8589934151, 8589934141,
|
||||
8589934139, 8589934117, 8589934103, 8589934099, 8589934091, 8589934069, 8589934049, 8589934027,
|
||||
|
@ -475,7 +476,7 @@ const PRIMES33: &'static [u64] = &[
|
|||
8589933647, 8589933641, 8589933637, 8589933631, 8589933629, 8589933619, 8589933601, 8589933581,
|
||||
];
|
||||
|
||||
const PRIMES34: &'static [u64] = &[
|
||||
const PRIMES34: &[u64] = &[
|
||||
17179869143,
|
||||
17179869107,
|
||||
17179869071,
|
||||
|
@ -526,7 +527,7 @@ const PRIMES34: &'static [u64] = &[
|
|||
17179868183,
|
||||
];
|
||||
|
||||
const PRIMES35: &'static [u64] = &[
|
||||
const PRIMES35: &[u64] = &[
|
||||
34359738337,
|
||||
34359738319,
|
||||
34359738307,
|
||||
|
@ -559,7 +560,7 @@ const PRIMES35: &'static [u64] = &[
|
|||
34359737371,
|
||||
];
|
||||
|
||||
const PRIMES36: &'static [u64] = &[
|
||||
const PRIMES36: &[u64] = &[
|
||||
68719476731,
|
||||
68719476719,
|
||||
68719476713,
|
||||
|
@ -611,7 +612,7 @@ const PRIMES36: &'static [u64] = &[
|
|||
68719475729,
|
||||
];
|
||||
|
||||
const PRIMES37: &'static [u64] = &[
|
||||
const PRIMES37: &[u64] = &[
|
||||
137438953447,
|
||||
137438953441,
|
||||
137438953427,
|
||||
|
@ -637,7 +638,7 @@ const PRIMES37: &'static [u64] = &[
|
|||
137438952491,
|
||||
];
|
||||
|
||||
const PRIMES38: &'static [u64] = &[
|
||||
const PRIMES38: &[u64] = &[
|
||||
274877906899,
|
||||
274877906857,
|
||||
274877906837,
|
||||
|
@ -677,7 +678,7 @@ const PRIMES38: &'static [u64] = &[
|
|||
274877905931,
|
||||
];
|
||||
|
||||
const PRIMES39: &'static [u64] = &[
|
||||
const PRIMES39: &[u64] = &[
|
||||
549755813881,
|
||||
549755813869,
|
||||
549755813821,
|
||||
|
@ -723,7 +724,7 @@ const PRIMES39: &'static [u64] = &[
|
|||
549755812867,
|
||||
];
|
||||
|
||||
const PRIMES40: &'static [u64] = &[
|
||||
const PRIMES40: &[u64] = &[
|
||||
1099511627689,
|
||||
1099511627609,
|
||||
1099511627581,
|
||||
|
@ -753,7 +754,7 @@ const PRIMES40: &'static [u64] = &[
|
|||
1099511626771,
|
||||
];
|
||||
|
||||
const PRIMES41: &'static [u64] = &[
|
||||
const PRIMES41: &[u64] = &[
|
||||
2199023255531,
|
||||
2199023255521,
|
||||
2199023255497,
|
||||
|
@ -792,7 +793,7 @@ const PRIMES41: &'static [u64] = &[
|
|||
2199023254567,
|
||||
];
|
||||
|
||||
const PRIMES42: &'static [u64] = &[
|
||||
const PRIMES42: &[u64] = &[
|
||||
4398046511093,
|
||||
4398046511087,
|
||||
4398046511071,
|
||||
|
@ -832,7 +833,7 @@ const PRIMES42: &'static [u64] = &[
|
|||
4398046510093,
|
||||
];
|
||||
|
||||
const PRIMES43: &'static [u64] = &[
|
||||
const PRIMES43: &[u64] = &[
|
||||
8796093022151,
|
||||
8796093022141,
|
||||
8796093022091,
|
||||
|
@ -867,7 +868,7 @@ const PRIMES43: &'static [u64] = &[
|
|||
8796093021269,
|
||||
];
|
||||
|
||||
const PRIMES44: &'static [u64] = &[
|
||||
const PRIMES44: &[u64] = &[
|
||||
17592186044399,
|
||||
17592186044299,
|
||||
17592186044297,
|
||||
|
@ -900,7 +901,7 @@ const PRIMES44: &'static [u64] = &[
|
|||
17592186043409,
|
||||
];
|
||||
|
||||
const PRIMES45: &'static [u64] = &[
|
||||
const PRIMES45: &[u64] = &[
|
||||
35184372088777,
|
||||
35184372088763,
|
||||
35184372088751,
|
||||
|
@ -941,7 +942,7 @@ const PRIMES45: &'static [u64] = &[
|
|||
35184372087869,
|
||||
];
|
||||
|
||||
const PRIMES46: &'static [u64] = &[
|
||||
const PRIMES46: &[u64] = &[
|
||||
70368744177643,
|
||||
70368744177607,
|
||||
70368744177601,
|
||||
|
@ -976,7 +977,7 @@ const PRIMES46: &'static [u64] = &[
|
|||
70368744176711,
|
||||
];
|
||||
|
||||
const PRIMES47: &'static [u64] = &[
|
||||
const PRIMES47: &[u64] = &[
|
||||
140737488355213,
|
||||
140737488355201,
|
||||
140737488355181,
|
||||
|
@ -998,7 +999,7 @@ const PRIMES47: &'static [u64] = &[
|
|||
140737488354329,
|
||||
];
|
||||
|
||||
const PRIMES48: &'static [u64] = &[
|
||||
const PRIMES48: &[u64] = &[
|
||||
281474976710597,
|
||||
281474976710591,
|
||||
281474976710567,
|
||||
|
@ -1031,7 +1032,7 @@ const PRIMES48: &'static [u64] = &[
|
|||
281474976709637,
|
||||
];
|
||||
|
||||
const PRIMES49: &'static [u64] = &[
|
||||
const PRIMES49: &[u64] = &[
|
||||
562949953421231,
|
||||
562949953421201,
|
||||
562949953421189,
|
||||
|
@ -1065,7 +1066,7 @@ const PRIMES49: &'static [u64] = &[
|
|||
562949953420297,
|
||||
];
|
||||
|
||||
const PRIMES50: &'static [u64] = &[
|
||||
const PRIMES50: &[u64] = &[
|
||||
1125899906842597,
|
||||
1125899906842589,
|
||||
1125899906842573,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static INPUT: &'static str = "lorem_ipsum.txt";
|
||||
static INPUT: &str = "lorem_ipsum.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
|
|
|
@ -116,11 +116,11 @@ fn test_install_ancestors_mode_directories() {
|
|||
assert!(at.dir_exists(ancestor2));
|
||||
assert!(at.dir_exists(target_dir));
|
||||
|
||||
assert_ne!(0o40700 as u32, at.metadata(ancestor1).permissions().mode());
|
||||
assert_ne!(0o40700 as u32, at.metadata(ancestor2).permissions().mode());
|
||||
assert_ne!(0o40_700_u32, at.metadata(ancestor1).permissions().mode());
|
||||
assert_ne!(0o40_700_u32, at.metadata(ancestor2).permissions().mode());
|
||||
|
||||
// Expected mode only on the target_dir.
|
||||
assert_eq!(0o40700 as u32, at.metadata(target_dir).permissions().mode());
|
||||
assert_eq!(0o40_700_u32, at.metadata(target_dir).permissions().mode());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -184,7 +184,7 @@ fn test_install_mode_numeric() {
|
|||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(dest_file));
|
||||
let permissions = at.metadata(dest_file).permissions();
|
||||
assert_eq!(0o100333 as u32, PermissionsExt::mode(&permissions));
|
||||
assert_eq!(0o100_333_u32, PermissionsExt::mode(&permissions));
|
||||
|
||||
let mode_arg = "-m 0333";
|
||||
at.mkdir(dir2);
|
||||
|
@ -195,7 +195,7 @@ fn test_install_mode_numeric() {
|
|||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(dest_file));
|
||||
let permissions = at.metadata(dest_file).permissions();
|
||||
assert_eq!(0o100333 as u32, PermissionsExt::mode(&permissions));
|
||||
assert_eq!(0o100_333_u32, PermissionsExt::mode(&permissions));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -213,7 +213,7 @@ fn test_install_mode_symbolic() {
|
|||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(dest_file));
|
||||
let permissions = at.metadata(dest_file).permissions();
|
||||
assert_eq!(0o100003 as u32, PermissionsExt::mode(&permissions));
|
||||
assert_eq!(0o100_003_u32, PermissionsExt::mode(&permissions));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -251,7 +251,7 @@ fn test_install_mode_directories() {
|
|||
|
||||
assert!(at.dir_exists(component));
|
||||
let permissions = at.metadata(component).permissions();
|
||||
assert_eq!(0o040333 as u32, PermissionsExt::mode(&permissions));
|
||||
assert_eq!(0o040_333_u32, PermissionsExt::mode(&permissions));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -51,6 +51,7 @@ fn test_ls_a() {
|
|||
.unwrap(),
|
||||
);
|
||||
|
||||
#[allow(clippy::trivial_regex)]
|
||||
let re_pwd = Regex::new(r"^\.\n").unwrap();
|
||||
|
||||
// Using the present working directory
|
||||
|
@ -124,7 +125,7 @@ fn test_ls_width() {
|
|||
for option in &["-w 100", "-w=100", "--width=100", "--width 100"] {
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&option.split(" ").collect::<Vec<_>>())
|
||||
.args(&option.split(' ').collect::<Vec<_>>())
|
||||
.succeeds()
|
||||
.stdout_only("test-width-1 test-width-2 test-width-3 test-width-4\n");
|
||||
}
|
||||
|
@ -132,7 +133,7 @@ fn test_ls_width() {
|
|||
for option in &["-w 50", "-w=50", "--width=50", "--width 50"] {
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&option.split(" ").collect::<Vec<_>>())
|
||||
.args(&option.split(' ').collect::<Vec<_>>())
|
||||
.succeeds()
|
||||
.stdout_only("test-width-1 test-width-3\ntest-width-2 test-width-4\n");
|
||||
}
|
||||
|
@ -149,7 +150,7 @@ fn test_ls_width() {
|
|||
] {
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&option.split(" ").collect::<Vec<_>>())
|
||||
.args(&option.split(' ').collect::<Vec<_>>())
|
||||
.succeeds()
|
||||
.stdout_only("test-width-1\ntest-width-2\ntest-width-3\ntest-width-4\n");
|
||||
}
|
||||
|
@ -163,7 +164,7 @@ fn test_ls_width() {
|
|||
for option in &["-w 1a", "-w=1a", "--width=1a", "--width 1a"] {
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&option.split(" ").collect::<Vec<_>>())
|
||||
.args(&option.split(' ').collect::<Vec<_>>())
|
||||
.fails()
|
||||
.stderr_only("ls: invalid line width: ‘1a’");
|
||||
}
|
||||
|
@ -417,7 +418,7 @@ fn test_ls_long_formats() {
|
|||
] {
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.args(&arg.split(" ").collect::<Vec<_>>())
|
||||
.args(&arg.split(' ').collect::<Vec<_>>())
|
||||
.arg("test-long-formats")
|
||||
.succeeds();
|
||||
assert!(re_two.is_match(result.stdout_str()));
|
||||
|
@ -427,7 +428,7 @@ fn test_ls_long_formats() {
|
|||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-n")
|
||||
.args(&arg.split(" ").collect::<Vec<_>>())
|
||||
.args(&arg.split(' ').collect::<Vec<_>>())
|
||||
.arg("test-long-formats")
|
||||
.succeeds();
|
||||
assert!(re_two_num.is_match(result.stdout_str()));
|
||||
|
@ -446,7 +447,7 @@ fn test_ls_long_formats() {
|
|||
] {
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.args(&arg.split(" ").collect::<Vec<_>>())
|
||||
.args(&arg.split(' ').collect::<Vec<_>>())
|
||||
.arg("test-long-formats")
|
||||
.succeeds();
|
||||
assert!(re_one.is_match(result.stdout_str()));
|
||||
|
@ -456,7 +457,7 @@ fn test_ls_long_formats() {
|
|||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-n")
|
||||
.args(&arg.split(" ").collect::<Vec<_>>())
|
||||
.args(&arg.split(' ').collect::<Vec<_>>())
|
||||
.arg("test-long-formats")
|
||||
.succeeds();
|
||||
assert!(re_one_num.is_match(result.stdout_str()));
|
||||
|
@ -478,7 +479,7 @@ fn test_ls_long_formats() {
|
|||
] {
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.args(&arg.split(" ").collect::<Vec<_>>())
|
||||
.args(&arg.split(' ').collect::<Vec<_>>())
|
||||
.arg("test-long-formats")
|
||||
.succeeds();
|
||||
assert!(re_zero.is_match(result.stdout_str()));
|
||||
|
@ -488,7 +489,7 @@ fn test_ls_long_formats() {
|
|||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-n")
|
||||
.args(&arg.split(" ").collect::<Vec<_>>())
|
||||
.args(&arg.split(' ').collect::<Vec<_>>())
|
||||
.arg("test-long-formats")
|
||||
.succeeds();
|
||||
assert!(re_zero.is_match(result.stdout_str()));
|
||||
|
@ -898,6 +899,12 @@ fn test_ls_recursive() {
|
|||
|
||||
scene.ucmd().arg("a").succeeds();
|
||||
scene.ucmd().arg("a/a").succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("z")
|
||||
.arg("-R")
|
||||
.succeeds()
|
||||
.stdout_contains(&"z:");
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.arg("--color=never")
|
||||
|
@ -1063,7 +1070,7 @@ fn test_ls_indicator_style() {
|
|||
for opt in options {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(format!("{}", opt))
|
||||
.arg(opt.to_string())
|
||||
.succeeds()
|
||||
.stdout_contains(&"/");
|
||||
}
|
||||
|
@ -1085,7 +1092,10 @@ fn test_ls_indicator_style() {
|
|||
{
|
||||
use self::unix_socket::UnixListener;
|
||||
|
||||
let dir = tempfile::Builder::new().prefix("unix_socket").tempdir().expect("failed to create dir");
|
||||
let dir = tempfile::Builder::new()
|
||||
.prefix("unix_socket")
|
||||
.tempdir()
|
||||
.expect("failed to create dir");
|
||||
let socket_path = dir.path().join("sock");
|
||||
let _listener = UnixListener::bind(&socket_path).expect("failed to create socket");
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static TEST_DIR1: &'static str = "mkdir_test1";
|
||||
static TEST_DIR2: &'static str = "mkdir_test2";
|
||||
static TEST_DIR3: &'static str = "mkdir_test3";
|
||||
static TEST_DIR4: &'static str = "mkdir_test4/mkdir_test4_1";
|
||||
static TEST_DIR5: &'static str = "mkdir_test5/mkdir_test5_1";
|
||||
static TEST_DIR6: &'static str = "mkdir_test6";
|
||||
static TEST_FILE7: &'static str = "mkdir_test7";
|
||||
static TEST_DIR1: &str = "mkdir_test1";
|
||||
static TEST_DIR2: &str = "mkdir_test2";
|
||||
static TEST_DIR3: &str = "mkdir_test3";
|
||||
static TEST_DIR4: &str = "mkdir_test4/mkdir_test4_1";
|
||||
static TEST_DIR5: &str = "mkdir_test5/mkdir_test5_1";
|
||||
static TEST_DIR6: &str = "mkdir_test6";
|
||||
static TEST_FILE7: &str = "mkdir_test7";
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_mkdir() {
|
||||
|
|
|
@ -3,19 +3,19 @@ use crate::common::util::*;
|
|||
use std::path::PathBuf;
|
||||
use tempfile::tempdir;
|
||||
|
||||
static TEST_TEMPLATE1: &'static str = "tempXXXXXX";
|
||||
static TEST_TEMPLATE2: &'static str = "temp";
|
||||
static TEST_TEMPLATE3: &'static str = "tempX";
|
||||
static TEST_TEMPLATE4: &'static str = "tempXX";
|
||||
static TEST_TEMPLATE5: &'static str = "tempXXX";
|
||||
static TEST_TEMPLATE6: &'static str = "tempXXXlate";
|
||||
static TEST_TEMPLATE7: &'static str = "XXXtemplate";
|
||||
static TEST_TEMPLATE1: &str = "tempXXXXXX";
|
||||
static TEST_TEMPLATE2: &str = "temp";
|
||||
static TEST_TEMPLATE3: &str = "tempX";
|
||||
static TEST_TEMPLATE4: &str = "tempXX";
|
||||
static TEST_TEMPLATE5: &str = "tempXXX";
|
||||
static TEST_TEMPLATE6: &str = "tempXXXlate";
|
||||
static TEST_TEMPLATE7: &str = "XXXtemplate";
|
||||
#[cfg(unix)]
|
||||
static TEST_TEMPLATE8: &'static str = "tempXXXl/ate";
|
||||
static TEST_TEMPLATE8: &str = "tempXXXl/ate";
|
||||
#[cfg(windows)]
|
||||
static TEST_TEMPLATE8: &'static str = "tempXXXl\\ate";
|
||||
static TEST_TEMPLATE8: &str = "tempXXXl\\ate";
|
||||
|
||||
const TMPDIR: &'static str = "TMPDIR";
|
||||
const TMPDIR: &str = "TMPDIR";
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_mktemp() {
|
||||
|
|
|
@ -2,15 +2,22 @@ use crate::common::util::*;
|
|||
|
||||
#[test]
|
||||
fn test_more_no_arg() {
|
||||
// stderr = more: Reading from stdin isn't supported yet.
|
||||
new_ucmd!().fails();
|
||||
// Reading from stdin is now supported, so this must succeed
|
||||
if atty::is(atty::Stream::Stdout) {
|
||||
new_ucmd!().succeeds();
|
||||
} else {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_more_dir_arg() {
|
||||
let result = new_ucmd!().arg(".").run();
|
||||
result.failure();
|
||||
const EXPECTED_ERROR_MESSAGE: &str =
|
||||
"more: '.' is a directory.\nTry 'more --help' for more information.";
|
||||
assert_eq!(result.stderr_str().trim(), EXPECTED_ERROR_MESSAGE);
|
||||
// Run the test only if there's a valud terminal, else do nothing
|
||||
// Maybe we could capture the error, i.e. "Device not found" in that case
|
||||
// but I am leaving this for later
|
||||
if atty::is(atty::Stream::Stdout) {
|
||||
let result = new_ucmd!().arg(".").run();
|
||||
result.failure();
|
||||
const EXPECTED_ERROR_MESSAGE: &str =
|
||||
"more: '.' is a directory.\nTry 'more --help' for more information.";
|
||||
assert_eq!(result.stderr_str().trim(), EXPECTED_ERROR_MESSAGE);
|
||||
} else {}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ fn test_mv_strip_slashes() {
|
|||
let dir = "test_mv_strip_slashes_dir";
|
||||
let file = "test_mv_strip_slashes_file";
|
||||
let mut source = file.to_owned();
|
||||
source.push_str("/");
|
||||
source.push('/');
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file);
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
|
||||
// octal dump of 'abcdefghijklmnopqrstuvwxyz\n'
|
||||
static ALPHA_OUT: &'static str = "
|
||||
static ALPHA_OUT: &str = "
|
||||
0000000 061141 062143 063145 064147 065151 066153 067155 070157
|
||||
0000020 071161 072163 073165 074167 075171 000012
|
||||
0000033
|
||||
|
@ -563,7 +563,7 @@ fn test_dec_offset() {
|
|||
#[test]
|
||||
fn test_no_offset() {
|
||||
let input = [0u8; 31];
|
||||
const LINE: &'static str = " 00000000 00000000 00000000 00000000\n";
|
||||
const LINE: &str = " 00000000 00000000 00000000 00000000\n";
|
||||
let expected_output = [LINE, LINE, LINE, LINE].join("");
|
||||
|
||||
new_ucmd!()
|
||||
|
|
|
@ -7,7 +7,7 @@ struct TestData<'b> {
|
|||
out: &'b str,
|
||||
}
|
||||
|
||||
static EXAMPLE_DATA: &'static [TestData<'static>] = &[
|
||||
static EXAMPLE_DATA: &[TestData] = &[
|
||||
// Ensure that paste properly handles files lacking a final newline.
|
||||
TestData {
|
||||
name: "no-nl-1",
|
||||
|
@ -64,8 +64,8 @@ static EXAMPLE_DATA: &'static [TestData<'static>] = &[
|
|||
|
||||
#[test]
|
||||
fn test_combine_pairs_of_lines() {
|
||||
for s in vec!["-s", "--serial"] {
|
||||
for d in vec!["-d", "--delimiters"] {
|
||||
for &s in &["-s", "--serial"] {
|
||||
for &d in &["-d", "--delimiters"] {
|
||||
new_ucmd!()
|
||||
.args(&[s, d, "\t\n", "html_colors.txt"])
|
||||
.run()
|
||||
|
@ -76,7 +76,7 @@ fn test_combine_pairs_of_lines() {
|
|||
|
||||
#[test]
|
||||
fn test_multi_stdin() {
|
||||
for d in vec!["-d", "--delimiters"] {
|
||||
for &d in &["-d", "--delimiters"] {
|
||||
new_ucmd!()
|
||||
.args(&[d, "\t\n", "-", "-"])
|
||||
.pipe_in_fixture("html_colors.txt")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static GIBBERISH: &'static str = "supercalifragilisticexpialidocious";
|
||||
static GIBBERISH: &str = "supercalifragilisticexpialidocious";
|
||||
|
||||
#[test]
|
||||
fn test_canonicalize() {
|
||||
|
|
|
@ -61,6 +61,7 @@ const TESTS: [TestCase; 10] = [
|
|||
},
|
||||
];
|
||||
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
fn convert_path<'a>(path: &'a str) -> Cow<'a, str> {
|
||||
#[cfg(windows)]
|
||||
return path.replace("/", "\\").into();
|
||||
|
|
|
@ -14,11 +14,11 @@ fn test_output_is_random_permutation() {
|
|||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort();
|
||||
result_seq.sort_unstable();
|
||||
assert_ne!(result.stdout_str(), input, "Output is not randomised");
|
||||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ fn test_zero_termination() {
|
|||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\0")
|
||||
.split('\0')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort();
|
||||
result_seq.sort_unstable();
|
||||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
|
@ -55,11 +55,11 @@ fn test_echo() {
|
|||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort();
|
||||
result_seq.sort_unstable();
|
||||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
|
@ -81,11 +81,11 @@ fn test_head_count() {
|
|||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort();
|
||||
result_seq.sort_unstable();
|
||||
assert_eq!(result_seq.len(), repeat_limit, "Output is not limited");
|
||||
assert!(
|
||||
result_seq.iter().all(|x| input_seq.contains(x)),
|
||||
|
@ -113,7 +113,7 @@ fn test_repeat() {
|
|||
|
||||
let result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
|
@ -141,11 +141,11 @@ fn test_file_input() {
|
|||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort();
|
||||
result_seq.sort_unstable();
|
||||
assert_eq!(result_seq, expected_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ fn test_dictionary_order() {
|
|||
|
||||
#[test]
|
||||
fn test_dictionary_order2() {
|
||||
for non_dictionary_order2_param in vec!["-d"] {
|
||||
for non_dictionary_order2_param in &["-d"] {
|
||||
new_ucmd!()
|
||||
.pipe_in("a👦🏻aa b\naaaa b")
|
||||
.arg(non_dictionary_order2_param)
|
||||
|
@ -299,7 +299,7 @@ fn test_dictionary_order2() {
|
|||
|
||||
#[test]
|
||||
fn test_non_printing_chars() {
|
||||
for non_printing_chars_param in vec!["-i"] {
|
||||
for non_printing_chars_param in &["-i"] {
|
||||
new_ucmd!()
|
||||
.pipe_in("a👦🏻aa\naaaa")
|
||||
.arg(non_printing_chars_param)
|
||||
|
@ -361,7 +361,7 @@ fn test_mixed_floats_ints_chars_numeric_stable() {
|
|||
|
||||
#[test]
|
||||
fn test_numeric_floats_and_ints2() {
|
||||
for numeric_sort_param in vec!["-n", "--numeric-sort"] {
|
||||
for numeric_sort_param in &["-n", "--numeric-sort"] {
|
||||
let input = "1.444\n8.013\n1\n-8\n1.04\n-1";
|
||||
new_ucmd!()
|
||||
.arg(numeric_sort_param)
|
||||
|
@ -373,7 +373,7 @@ fn test_numeric_floats_and_ints2() {
|
|||
|
||||
#[test]
|
||||
fn test_numeric_floats2() {
|
||||
for numeric_sort_param in vec!["-n", "--numeric-sort"] {
|
||||
for numeric_sort_param in &["-n", "--numeric-sort"] {
|
||||
let input = "1.444\n8.013\n1.58590\n-8.90880\n1.040000000\n-.05";
|
||||
new_ucmd!()
|
||||
.arg(numeric_sort_param)
|
||||
|
@ -426,7 +426,7 @@ fn test_default_unsorted_ints2() {
|
|||
|
||||
#[test]
|
||||
fn test_numeric_unique_ints2() {
|
||||
for numeric_unique_sort_param in vec!["-nu"] {
|
||||
for numeric_unique_sort_param in &["-nu"] {
|
||||
let input = "9\n9\n8\n1\n";
|
||||
new_ucmd!()
|
||||
.arg(numeric_unique_sort_param)
|
||||
|
@ -471,7 +471,7 @@ fn test_keys_invalid_field() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "1."])
|
||||
.fails()
|
||||
.stderr_only("sort: failed to parse character index for key `1.`: cannot parse integer from empty string");
|
||||
.stderr_only("sort: failed to parse key `1.`: failed to parse character index ``: cannot parse integer from empty string");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -479,7 +479,7 @@ fn test_keys_invalid_field_option() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "1.1x"])
|
||||
.fails()
|
||||
.stderr_only("sort: invalid option for key: `x`");
|
||||
.stderr_only("sort: failed to parse key `1.1x`: invalid option: `x`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -487,7 +487,7 @@ fn test_keys_invalid_field_zero() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "0.1"])
|
||||
.fails()
|
||||
.stderr_only("sort: field index was 0");
|
||||
.stderr_only("sort: failed to parse key `0.1`: field index can not be 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -495,7 +495,7 @@ fn test_keys_invalid_char_zero() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "1.0"])
|
||||
.fails()
|
||||
.stderr_only("sort: invalid character index 0 in `1.0` for the start position of a field");
|
||||
.stderr_only("sort: failed to parse key `1.0`: invalid character index 0 for the start position of a field");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -586,6 +586,47 @@ fn test_keys_negative_size_match() {
|
|||
test_helper("keys_negative_size", &["-k 3,1"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_ignore_flag() {
|
||||
test_helper("keys_ignore_flag", &["-k 1n -b"])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_doesnt_inherit_key_settings() {
|
||||
let input = " 1
|
||||
2
|
||||
10
|
||||
";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "1b", "-n"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only(
|
||||
" 1
|
||||
10
|
||||
2
|
||||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inherits_key_settings() {
|
||||
let input = " 1
|
||||
2
|
||||
10
|
||||
";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "1", "-n"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only(
|
||||
" 1
|
||||
2
|
||||
10
|
||||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_terminated() {
|
||||
test_helper("zero-terminated", &["-z"]);
|
||||
|
@ -707,10 +748,9 @@ fn test_dictionary_and_nonprinting_conflicts() {
|
|||
.succeeds();
|
||||
}
|
||||
for conflicting_arg in &conflicting_args {
|
||||
// FIXME: this should ideally fail.
|
||||
new_ucmd!()
|
||||
.args(&["-k", &format!("1{},1{}", restricted_arg, conflicting_arg)])
|
||||
.succeeds();
|
||||
.fails();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -737,3 +777,8 @@ fn test_nonexistent_file() {
|
|||
"sort: cannot read: \"nonexistent.txt\": The system cannot find the file specified. (os error 2)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_blanks() {
|
||||
test_helper("blanks", &["-b", "--ignore-blanks"]);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ impl RandomFile {
|
|||
let to_write = std::cmp::min(remaining_size, buffer.len());
|
||||
let buf = &mut buffer[..to_write];
|
||||
rng.fill(buf);
|
||||
writer.write(buf).unwrap();
|
||||
writer.write_all(buf).unwrap();
|
||||
|
||||
remaining_size -= to_write;
|
||||
}
|
||||
|
@ -179,6 +179,7 @@ fn test_split_bytes_prime_part_size() {
|
|||
let mut fns = glob.collect();
|
||||
// glob.collect() is not guaranteed to return in sorted order, so we sort.
|
||||
fns.sort();
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0..5 {
|
||||
assert_eq!(glob.directory.metadata(&fns[i]).len(), 1753);
|
||||
}
|
||||
|
@ -246,9 +247,9 @@ fn test_filter() {
|
|||
assert!(
|
||||
glob.collate().iter().find(|&&c| {
|
||||
// is not i
|
||||
c != ('i' as u8)
|
||||
c != (b'i')
|
||||
// is not newline
|
||||
&& c != ('\n' as u8)
|
||||
&& c != (b'\n')
|
||||
}) == None
|
||||
);
|
||||
}
|
||||
|
@ -271,7 +272,7 @@ fn test_filter_with_env_var_set() {
|
|||
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
assert!(env::var("FILE").unwrap_or("var was unset".to_owned()) == env_var_value);
|
||||
assert!(env::var("FILE").unwrap_or_else(|_| "var was unset".to_owned()) == env_var_value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -97,13 +97,13 @@ fn test_invalid_option() {
|
|||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
|
||||
const NORMAL_FMTSTR: &'static str =
|
||||
const NORMAL_FMTSTR: &str =
|
||||
"%a %A %b %B %d %D %f %F %g %G %h %i %m %n %o %s %u %U %x %X %y %Y %z %Z"; // avoid "%w %W" (birth/creation) due to `stat` limitations and linux kernel & rust version capability variations
|
||||
#[cfg(any(target_os = "linux"))]
|
||||
const DEV_FMTSTR: &'static str =
|
||||
const DEV_FMTSTR: &str =
|
||||
"%a %A %b %B %d %D %f %F %g %G %h %i %m %n %o %s (%t/%T) %u %U %w %W %x %X %y %Y %z %Z";
|
||||
#[cfg(target_os = "linux")]
|
||||
const FS_FMTSTR: &'static str = "%b %c %i %l %n %s %S %t %T"; // avoid "%a %d %f" which can cause test failure due to race conditions
|
||||
const FS_FMTSTR: &str = "%b %c %i %l %n %s %S %t %T"; // avoid "%a %d %f" which can cause test failure due to race conditions
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -140,7 +140,7 @@ fn test_terse_normal_format() {
|
|||
assert!(!v_expect.is_empty());
|
||||
|
||||
// uu_stat does not support selinux
|
||||
if v_actual.len() == v_expect.len() - 1 && v_expect[v_expect.len() - 1].contains(":") {
|
||||
if v_actual.len() == v_expect.len() - 1 && v_expect[v_expect.len() - 1].contains(':') {
|
||||
// assume last element contains: `SELinux security context string`
|
||||
v_expect.pop();
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ fn test_symlinks() {
|
|||
|
||||
let mut tested: bool = false;
|
||||
// arbitrarily chosen symlinks with hope that the CI environment provides at least one of them
|
||||
for file in vec![
|
||||
for file in &[
|
||||
"/bin/sh",
|
||||
"/bin/sudoedit",
|
||||
"/usr/bin/ex",
|
||||
|
|
|
@ -5,9 +5,9 @@ use crate::common::util::*;
|
|||
use std::char::from_digit;
|
||||
use std::io::Write;
|
||||
|
||||
static FOOBAR_TXT: &'static str = "foobar.txt";
|
||||
static FOOBAR_2_TXT: &'static str = "foobar2.txt";
|
||||
static FOOBAR_WITH_NULL_TXT: &'static str = "foobar_with_null.txt";
|
||||
static FOOBAR_TXT: &str = "foobar.txt";
|
||||
static FOOBAR_2_TXT: &str = "foobar2.txt";
|
||||
static FOOBAR_WITH_NULL_TXT: &str = "foobar_with_null.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
|
@ -153,8 +153,8 @@ fn test_follow_with_pid() {
|
|||
|
||||
#[test]
|
||||
fn test_single_big_args() {
|
||||
const FILE: &'static str = "single_big_args.txt";
|
||||
const EXPECTED_FILE: &'static str = "single_big_args_expected.txt";
|
||||
const FILE: &str = "single_big_args.txt";
|
||||
const EXPECTED_FILE: &str = "single_big_args_expected.txt";
|
||||
const LINES: usize = 1_000_000;
|
||||
const N_ARG: usize = 100_000;
|
||||
|
||||
|
@ -162,13 +162,13 @@ fn test_single_big_args() {
|
|||
|
||||
let mut big_input = at.make_file(FILE);
|
||||
for i in 0..LINES {
|
||||
write!(&mut big_input, "Line {}\n", i).expect("Could not write to FILE");
|
||||
writeln!(&mut big_input, "Line {}", i).expect("Could not write to FILE");
|
||||
}
|
||||
big_input.flush().expect("Could not flush FILE");
|
||||
|
||||
let mut big_expected = at.make_file(EXPECTED_FILE);
|
||||
for i in (LINES - N_ARG)..LINES {
|
||||
write!(&mut big_expected, "Line {}\n", i).expect("Could not write to EXPECTED_FILE");
|
||||
writeln!(&mut big_expected, "Line {}", i).expect("Could not write to EXPECTED_FILE");
|
||||
}
|
||||
big_expected.flush().expect("Could not flush EXPECTED_FILE");
|
||||
|
||||
|
@ -201,8 +201,8 @@ fn test_bytes_stdin() {
|
|||
|
||||
#[test]
|
||||
fn test_bytes_big() {
|
||||
const FILE: &'static str = "test_bytes_big.txt";
|
||||
const EXPECTED_FILE: &'static str = "test_bytes_big_expected.txt";
|
||||
const FILE: &str = "test_bytes_big.txt";
|
||||
const EXPECTED_FILE: &str = "test_bytes_big_expected.txt";
|
||||
const BYTES: usize = 1_000_000;
|
||||
const N_ARG: usize = 100_000;
|
||||
|
||||
|
@ -257,10 +257,10 @@ fn test_parse_size() {
|
|||
|
||||
for &(c, exp) in &suffixes {
|
||||
let s = format!("2{}B", c);
|
||||
assert_eq!(Ok(2 * (1000 as u64).pow(exp)), parse_size(&s));
|
||||
assert_eq!(Ok(2 * (1000_u64).pow(exp)), parse_size(&s));
|
||||
|
||||
let s = format!("2{}", c);
|
||||
assert_eq!(Ok(2 * (1024 as u64).pow(exp)), parse_size(&s));
|
||||
assert_eq!(Ok(2 * (1024_u64).pow(exp)), parse_size(&s));
|
||||
}
|
||||
|
||||
// Sizes that are too big.
|
||||
|
@ -273,8 +273,8 @@ fn test_parse_size() {
|
|||
|
||||
#[test]
|
||||
fn test_lines_with_size_suffix() {
|
||||
const FILE: &'static str = "test_lines_with_size_suffix.txt";
|
||||
const EXPECTED_FILE: &'static str = "test_lines_with_size_suffix_expected.txt";
|
||||
const FILE: &str = "test_lines_with_size_suffix.txt";
|
||||
const EXPECTED_FILE: &str = "test_lines_with_size_suffix_expected.txt";
|
||||
const LINES: usize = 3_000;
|
||||
const N_ARG: usize = 2 * 1024;
|
||||
|
||||
|
|
|
@ -401,8 +401,8 @@ fn get_dstswitch_hour() -> Option<String> {
|
|||
for _i in 0..(366 * 24) {
|
||||
if is_dst_switch_hour(ts) {
|
||||
let mut tm = time::at(ts);
|
||||
tm.tm_hour = tm.tm_hour + 1;
|
||||
let s = time::strftime("%Y%m%d%H%M", &tm).unwrap().to_string();
|
||||
tm.tm_hour += 1;
|
||||
let s = time::strftime("%Y%m%d%H%M", &tm).unwrap();
|
||||
return Some(s);
|
||||
}
|
||||
ts = ts + time::Duration::hours(1);
|
||||
|
@ -415,10 +415,7 @@ fn test_touch_mtime_dst_fails() {
|
|||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_mtime_dst_fails";
|
||||
|
||||
match get_dstswitch_hour() {
|
||||
Some(s) => {
|
||||
ucmd.args(&["-m", "-t", &s, file]).fails();
|
||||
}
|
||||
None => (),
|
||||
if let Some(s) = get_dstswitch_hour() {
|
||||
ucmd.args(&["-m", "-t", &s, file]).fails();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::common::util::*;
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
|
||||
static TFILE1: &'static str = "truncate_test_1";
|
||||
static TFILE2: &'static str = "truncate_test_2";
|
||||
static TFILE1: &str = "truncate_test_1";
|
||||
static TFILE2: &str = "truncate_test_2";
|
||||
|
||||
#[test]
|
||||
fn test_increase_file_size() {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static INPUT: &'static str = "sorted.txt";
|
||||
static OUTPUT: &'static str = "sorted-output.txt";
|
||||
static SKIP_CHARS: &'static str = "skip-chars.txt";
|
||||
static SKIP_FIELDS: &'static str = "skip-fields.txt";
|
||||
static SORTED_ZERO_TERMINATED: &'static str = "sorted-zero-terminated.txt";
|
||||
static INPUT: &str = "sorted.txt";
|
||||
static OUTPUT: &str = "sorted-output.txt";
|
||||
static SKIP_CHARS: &str = "skip-chars.txt";
|
||||
static SKIP_FIELDS: &str = "skip-fields.txt";
|
||||
static SORTED_ZERO_TERMINATED: &str = "sorted-zero-terminated.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::common::util::*;
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_count() {
|
||||
for opt in vec!["-q", "--count"] {
|
||||
for opt in &["-q", "--count"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -14,7 +14,7 @@ fn test_count() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_boot() {
|
||||
for opt in vec!["-b", "--boot"] {
|
||||
for opt in &["-b", "--boot"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -25,7 +25,7 @@ fn test_boot() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_heading() {
|
||||
for opt in vec!["-H", "--heading"] {
|
||||
for opt in &["-H", "--heading"] {
|
||||
// allow whitespace variation
|
||||
// * minor whitespace differences occur between platform built-in outputs;
|
||||
// specifically number of TABs between "TIME" and "COMMENT" may be variant
|
||||
|
@ -42,7 +42,7 @@ fn test_heading() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_short() {
|
||||
for opt in vec!["-s", "--short"] {
|
||||
for opt in &["-s", "--short"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -53,7 +53,7 @@ fn test_short() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_login() {
|
||||
for opt in vec!["-l", "--login"] {
|
||||
for opt in &["-l", "--login"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -64,7 +64,7 @@ fn test_login() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_m() {
|
||||
for opt in vec!["-m"] {
|
||||
for opt in &["-m"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -75,7 +75,7 @@ fn test_m() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_process() {
|
||||
for opt in vec!["-p", "--process"] {
|
||||
for opt in &["-p", "--process"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -85,7 +85,7 @@ fn test_process() {
|
|||
|
||||
#[test]
|
||||
fn test_runlevel() {
|
||||
for opt in vec!["-r", "--runlevel"] {
|
||||
for opt in &["-r", "--runlevel"] {
|
||||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
|
@ -100,7 +100,7 @@ fn test_runlevel() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_time() {
|
||||
for opt in vec!["-t", "--time"] {
|
||||
for opt in &["-t", "--time"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -117,7 +117,7 @@ fn test_mesg() {
|
|||
// same as -T
|
||||
// --writable
|
||||
// same as -T
|
||||
for opt in vec!["-T", "-w", "--mesg", "--message", "--writable"] {
|
||||
for opt in &["-T", "-w", "--mesg", "--message", "--writable"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -147,7 +147,7 @@ fn test_too_many_args() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_users() {
|
||||
for opt in vec!["-u", "--users"] {
|
||||
for opt in &["-u", "--users"] {
|
||||
let actual = new_ucmd!().arg(opt).succeeds().stdout_move_str();
|
||||
let expect = expected_result(&[opt]);
|
||||
println!("actual: {:?}", actual);
|
||||
|
@ -172,18 +172,17 @@ fn test_users() {
|
|||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_lookup() {
|
||||
for opt in vec!["--lookup"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(&[opt]));
|
||||
}
|
||||
let opt = "--lookup";
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(&[opt]));
|
||||
}
|
||||
|
||||
#[cfg(any(target_vendor = "apple", target_os = "linux"))]
|
||||
#[test]
|
||||
fn test_dead() {
|
||||
for opt in vec!["-d", "--dead"] {
|
||||
for opt in &["-d", "--dead"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
@ -222,7 +221,7 @@ fn test_all() {
|
|||
return;
|
||||
}
|
||||
|
||||
for opt in vec!["-a", "--all"] {
|
||||
for opt in &["-a", "--all"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
#[cfg(not(windows))]
|
||||
use libc;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::env;
|
||||
#[cfg(not(windows))]
|
||||
|
@ -39,7 +36,7 @@ static NO_STDIN_MEANINGLESS: &str = "Setting this flag has no effect if there is
|
|||
/// Test if the program is running under CI
|
||||
pub fn is_ci() -> bool {
|
||||
std::env::var("CI")
|
||||
.unwrap_or(String::from("false"))
|
||||
.unwrap_or_else(|_| String::from("false"))
|
||||
.eq_ignore_ascii_case("true")
|
||||
}
|
||||
|
||||
|
@ -478,7 +475,7 @@ impl AtPath {
|
|||
.append(true)
|
||||
.open(self.plus(name))
|
||||
.unwrap();
|
||||
f.write(contents.as_bytes())
|
||||
f.write_all(contents.as_bytes())
|
||||
.unwrap_or_else(|e| panic!("Couldn't write {}: {}", name, e));
|
||||
}
|
||||
|
||||
|
@ -791,7 +788,7 @@ impl UCommand {
|
|||
if self.has_run {
|
||||
panic!("{}", ALREADY_RUN);
|
||||
}
|
||||
self.comm_string.push_str(" ");
|
||||
self.comm_string.push(' ');
|
||||
self.comm_string
|
||||
.push_str(arg.as_ref().to_str().unwrap_or_default());
|
||||
self.raw.arg(arg.as_ref());
|
||||
|
@ -811,7 +808,7 @@ impl UCommand {
|
|||
.accept_any();
|
||||
|
||||
for s in strings {
|
||||
self.comm_string.push_str(" ");
|
||||
self.comm_string.push(' ');
|
||||
self.comm_string.push_str(&s);
|
||||
}
|
||||
|
||||
|
@ -867,9 +864,9 @@ impl UCommand {
|
|||
log_info("run", &self.comm_string);
|
||||
let mut child = self
|
||||
.raw
|
||||
.stdin(self.stdin.take().unwrap_or_else(|| Stdio::piped()))
|
||||
.stdout(self.stdout.take().unwrap_or_else(|| Stdio::piped()))
|
||||
.stderr(self.stderr.take().unwrap_or_else(|| Stdio::piped()))
|
||||
.stdin(self.stdin.take().unwrap_or_else(Stdio::piped))
|
||||
.stdout(self.stdout.take().unwrap_or_else(Stdio::piped))
|
||||
.stderr(self.stderr.take().unwrap_or_else(Stdio::piped))
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
|
@ -948,10 +945,7 @@ pub fn read_size(child: &mut Child, size: usize) -> String {
|
|||
}
|
||||
|
||||
pub fn vec_of_size(n: usize) -> Vec<u8> {
|
||||
let mut result = Vec::new();
|
||||
for _ in 0..n {
|
||||
result.push('a' as u8);
|
||||
}
|
||||
let result = vec![b'a'; n];
|
||||
assert_eq!(result.len(), n);
|
||||
result
|
||||
}
|
||||
|
|
5
tests/fixtures/sort/blanks.expected
vendored
Normal file
5
tests/fixtures/sort/blanks.expected
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
a
|
||||
b
|
||||
x
|
||||
x
|
||||
z
|
15
tests/fixtures/sort/blanks.expected.debug
vendored
Normal file
15
tests/fixtures/sort/blanks.expected.debug
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
a
|
||||
_
|
||||
___
|
||||
b
|
||||
_
|
||||
_
|
||||
x
|
||||
_
|
||||
__________
|
||||
x
|
||||
_
|
||||
___
|
||||
z
|
||||
_
|
||||
__
|
5
tests/fixtures/sort/blanks.txt
vendored
Normal file
5
tests/fixtures/sort/blanks.txt
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
b
|
||||
a
|
||||
z
|
||||
x
|
||||
x
|
2
tests/fixtures/sort/keys_ignore_flag.expected
vendored
Normal file
2
tests/fixtures/sort/keys_ignore_flag.expected
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
1a
|
||||
1A
|
6
tests/fixtures/sort/keys_ignore_flag.expected.debug
vendored
Normal file
6
tests/fixtures/sort/keys_ignore_flag.expected.debug
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
1a
|
||||
_
|
||||
___
|
||||
1A
|
||||
_
|
||||
__
|
2
tests/fixtures/sort/keys_ignore_flag.txt
vendored
Normal file
2
tests/fixtures/sort/keys_ignore_flag.txt
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
1a
|
||||
1A
|
Loading…
Reference in a new issue