diff --git a/.appveyor.yml b/.appveyor.yml index eb43e18358f..440a47f39d6 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,5 +1,5 @@ -# spell-checker:words POSIX repo SDK SDKs toolchain toolchains -# spell-checker:ignore uutils ARCH ABI BACKTRACE BINDIR cl COMNTOOLS dllcrt findstr maint MINGW MINGWDIR mkdir MSVC MSYS rustc rustlib rustup USERPROFILE vcvarsall +# spell-checker:words POSIX SDK SDKs repo toolchain toolchains +# spell-checker:ignore ABI ARCH BACKTRACE BINDIR COMNTOOLS MINGW MINGWDIR MSVC MSYS USERPROFILE cl dllcrt findstr maint mkdir rustc rustlib rustup targetting uutils vcvarsall version: "{build} ~ {branch}" @@ -21,8 +21,8 @@ matrix: environment: global: FEATURES: "windows" - BUILD_OPTIONS: "--no-default-features" - TEST_OPTIONS: "--no-default-features --no-fail-fast" + BUILD_OPTIONS: "" + TEST_OPTIONS: "--no-fail-fast" matrix: # minimum version @@ -69,6 +69,7 @@ environment: # - CHANNEL: nightly # ARCH: x86_64 # ABI: gnu +# FEATURES: "windows nightly" # * specific gnu compilers - CHANNEL: stable ARCH: i686 @@ -83,8 +84,8 @@ environment: install: # force branch checkout (if knowable), then reset to the specific commit ## (can be needed for accurate code coverage info) # * this allows later apps to see the branch name using standard `git branch` operations, yet always builds the correct specific commit - # * ref: [`@`](https://archive.is/RVpnF) - - if DEFINED APPVEYOR_REPO_BRANCH if /I "%APPVEYOR_REPO_SCM%"=="git" ( git checkout "%APPVEYOR_REPO_BRANCH%" 2>NUL & git reset --hard "%APPVEYOR_REPO_COMMIT%" ) + # * ref: [`@`](https://archive.is/RVpnF) ; note: `git branch -a` may be helpful for debugging edge cases + - if DEFINED APPVEYOR_REPO_BRANCH if /I "%APPVEYOR_REPO_SCM%"=="git" ( git checkout "%APPVEYOR_REPO_BRANCH%" 2>NUL & git reset --hard FETCH_HEAD 2>NUL || git reset --hard "%APPVEYOR_REPO_COMMIT%" ) # ensure CWD is project main directory - cd "%APPVEYOR_BUILD_FOLDER%" # create a working area diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml new file mode 100644 index 00000000000..ad4542ff50f --- /dev/null +++ b/.github/workflows/CICD.yml @@ -0,0 +1,361 @@ +name: CICD + +# spell-checker:ignore (acronyms) CICD MSVC musl +# spell-checker:ignore (env/flags) Ccodegen Cinline Coverflow RUSTFLAGS +# spell-checker:ignore (jargon) SHAs deps softprops toolchain +# spell-checker:ignore (names) CodeCOV MacOS MinGW Peltoche rivy +# spell-checker:ignore (shell/tools) choco clippy dmake esac fakeroot gmake grcov halium libssl mkdir popd printf pushd rustc rustfmt rustup shopt +# spell-checker:ignore (misc) alnum gnueabihf issuecomment maint nullglob onexitbegin onexitend uutils + + +env: + PROJECT_NAME: uutils + PROJECT_DESC: "'Universal' (cross-platform) CLI utilities" + PROJECT_AUTH: "uutils" + RUST_MIN_SRV: "1.31.0" + +on: [push, pull_request] + +jobs: + style: + name: Style + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest , features: unix } + - { os: macos-latest , features: unix } + - { os: windows-latest , features: windows } + steps: + - uses: actions/checkout@v1 + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + # #maint: [rivy; 2020-02-08] 'windows-latest' `cargo fmt` is bugged for this project (see reasons @ GH:rust-lang/rustfmt #3324, #3590, #3688 ; waiting for repair) + JOB_DO_FORMAT_TESTING="true" + case '${{ matrix.job.os }}' in windows-latest) unset JOB_DO_FORMAT_TESTING ;; esac; + echo set-output name=JOB_DO_FORMAT_TESTING::${JOB_DO_FORMAT_TESTING:-/false} + echo ::set-output name=JOB_DO_FORMAT_TESTING::${JOB_DO_FORMAT_TESTING} + # target-specific options + # * CARGO_FEATURES_OPTION + CARGO_FEATURES_OPTION='' ; + if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi + echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} + echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} + - name: Install `rust` toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + profile: minimal # minimal component installation (ie, no documentation) + components: rustfmt, clippy + - name: "`fmt` testing" + if: steps.vars.outputs.JOB_DO_FORMAT_TESTING + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + - name: "`clippy` testing" + if: success() || failure() # run regardless of prior step ("`fmt` testing") success/failure + uses: actions-rs/cargo@v1 + with: + command: clippy + args: ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -- -D warnings + + min_version: + name: MinSRV # Minimum supported rust version + runs-on: ${{ matrix.job.os }} + strategy: + matrix: + job: + - { os: ubuntu-latest , features: feat_os_unix } + steps: + - uses: actions/checkout@v1 + - name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.RUST_MIN_SRV }} + default: true + profile: minimal # minimal component installation (ie, no documentation) + - name: Install `cargo-tree` # for dependency information + uses: actions-rs/install@v0.1 + with: + crate: cargo-tree + version: latest + use-tool-cache: true + env: + RUSTUP_TOOLCHAIN: stable + - name: Info + shell: bash + run: | + # Info + ## tooling info display + echo "## tooling" + which gcc >/dev/null 2>&1 && (gcc --version | head -1) || true + rustup -V + rustup show active-toolchain + cargo -V + rustc -V + ## dependencies + echo "## dependency list" + cargo +stable fetch --quiet + cargo +stable tree --all --no-dev-dependencies --no-indent --features ${{ matrix.job.features }} | grep -vE "$PWD" | sort --unique + - name: Test + uses: actions-rs/cargo@v1 + with: + command: test + args: --features "feat_os_unix" + + build: + name: Build + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + job: + # { os, target, cargo-options, features, use-cross, toolchain } + - { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , features: feat_os_unix_gnueabihf , use-cross: use-cross } + - { os: ubuntu-16.04 , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } + - { os: ubuntu-18.04 , target: i686-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } + - { os: ubuntu-18.04 , target: i686-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross } + - { os: ubuntu-18.04 , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } + - { os: ubuntu-18.04 , target: x86_64-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross } + - { os: macos-latest , target: x86_64-apple-darwin , features: feat_os_unix } + - { os: windows-latest , target: i686-pc-windows-gnu , features: feat_os_windows } + - { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows } + - { os: windows-latest , target: x86_64-pc-windows-gnu , features: feat_os_windows , toolchain: nightly-x86_64-pc-windows-gnu } ## !maint: [rivy; due 2020-21-03] disable/remove when rust beta >= v1.43.0 is available (~mid-March) + # - { os: windows-latest , target: x86_64-pc-windows-gnu , features: feat_os_windows , toolchain: beta-x86_64-pc-windows-gnu } ## maint: [rivy; due 2020-21-03; due 2020-01-05] enable when rust beta >= v1.43.0 is available (~mid-March); disable when rust stable >= 1.43.0 is available (~early-May) + # - { os: windows-latest , target: x86_64-pc-windows-gnu , features: feat_os_windows } ## note: requires rust >= 1.43.0 to link correctly # ! maint: [rivy; due 2020-01-05] enable when rust stable >= 1.43.0 is available + - { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows } + steps: + - uses: actions/checkout@v1 + - name: Install/setup prerequisites + shell: bash + run: | + ## install/setup prerequisites + case '${{ matrix.job.target }}' in + arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; + x86_64-pc-windows-gnu) + # hack: move interfering 'gcc' to head of PATH; fixes linking errors, but only works for rust >= v1.43.0; see GH:rust-lang/rust#68872 (after potential fix GH:rust-lang/rust#67429) for further discussion/repairs; follow issue/solutions? via PR GH:rust-lang/rust#67429 (from GH:rust-lang/rust#47048#issuecomment-437409270); refs: GH:rust-lang/cargo#6754, GH:rust-lang/rust#47048 , GH:rust-lang/rust#53454 , GH:bike-barn/hermit#172 + echo "::add-path::C:\\ProgramData\\Chocolatey\\lib\\mingw\\tools\\install\\mingw64\\bin" + ;; + esac + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + # toolchain + TOOLCHAIN="stable" ## default to "stable" toolchain + # * specify alternate/non-default TOOLCHAIN for *-pc-windows-gnu targets; gnu targets on Windows are broken for the standard *-pc-windows-msvc toolchain (refs: GH:rust-lang/rust#47048, GH:rust-lang/rust#53454, GH:rust-lang/cargo#6754) + case ${{ matrix.job.target }} in *-pc-windows-gnu) TOOLCHAIN="stable-${{ matrix.job.target }}" ;; esac; + # * use requested TOOLCHAIN if specified + if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi + echo set-output name=TOOLCHAIN::${TOOLCHAIN:-/false} + echo ::set-output name=TOOLCHAIN::${TOOLCHAIN} + # staging directory + STAGING='_staging' + echo set-output name=STAGING::${STAGING} + echo ::set-output name=STAGING::${STAGING} + # determine EXE suffix + EXE_suffix="" ; case '${{ matrix.job.target }}' in *-pc-windows-*) EXE_suffix=".exe" ;; esac; + echo set-output name=EXE_suffix::${EXE_suffix} + echo ::set-output name=EXE_suffix::${EXE_suffix} + # parse commit reference info + echo GITHUB_REF=${GITHUB_REF} + echo GITHUB_SHA=${GITHUB_SHA} + REF_NAME=${GITHUB_REF#refs/*/} + unset REF_BRANCH ; case "${GITHUB_REF}" in refs/heads/*) REF_BRANCH=${GITHUB_REF#refs/heads/} ;; esac; + unset REF_TAG ; case "${GITHUB_REF}" in refs/tags/*) REF_TAG=${GITHUB_REF#refs/tags/} ;; esac; + REF_SHAS=${GITHUB_SHA:0:8} + echo set-output name=REF_NAME::${REF_NAME} + echo set-output name=REF_BRANCH::${REF_BRANCH} + echo set-output name=REF_TAG::${REF_TAG} + echo set-output name=REF_SHAS::${REF_SHAS} + echo ::set-output name=REF_NAME::${REF_NAME} + echo ::set-output name=REF_BRANCH::${REF_BRANCH} + echo ::set-output name=REF_TAG::${REF_TAG} + echo ::set-output name=REF_SHAS::${REF_SHAS} + # parse target + unset TARGET_ARCH ; case '${{ matrix.job.target }}' in arm-unknown-linux-gnueabihf) TARGET_ARCH=arm ;; i686-*) TARGET_ARCH=i686 ;; x86_64-*) TARGET_ARCH=x86_64 ;; esac; + echo set-output name=TARGET_ARCH::${TARGET_ARCH} + echo ::set-output name=TARGET_ARCH::${TARGET_ARCH} + unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac; + echo set-output name=TARGET_OS::${TARGET_OS} + echo ::set-output name=TARGET_OS::${TARGET_OS} + # package name + PKG_suffix=".tar.gz" ; case '${{ matrix.job.target }}' in *-pc-windows-*) PKG_suffix=".zip" ;; esac; + PKG_BASENAME=${PROJECT_NAME}-${REF_TAG:-$REF_SHAS}-${{ matrix.job.target }} + PKG_NAME=${PKG_BASENAME}${PKG_suffix} + echo set-output name=PKG_suffix::${PKG_suffix} + echo set-output name=PKG_BASENAME::${PKG_BASENAME} + echo set-output name=PKG_NAME::${PKG_NAME} + echo ::set-output name=PKG_suffix::${PKG_suffix} + echo ::set-output name=PKG_BASENAME::${PKG_BASENAME} + echo ::set-output name=PKG_NAME::${PKG_NAME} + # deployable tag? (ie, leading "vM" or "M"; M == version number) + unset DEPLOYABLE ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOYABLE='true' ; fi + echo set-output name=DEPLOYABLE::${DEPLOYABLE:-/false} + echo ::set-output name=DEPLOYABLE::${DEPLOYABLE} + # target-specific options + # * CARGO_FEATURES_OPTION + CARGO_FEATURES_OPTION='' ; + if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi + echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} + echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} + # * CARGO_USE_CROSS (truthy) + CARGO_USE_CROSS='true' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) unset CARGO_USE_CROSS ;; esac; + echo set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS:-/false} + echo ::set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS} + # # * `arm` cannot be tested on ubuntu-* hosts (b/c testing is currently primarily done via comparison of target outputs with built-in outputs and the `arm` target is not executable on the host) + JOB_DO_TESTING="true" + case '${{ matrix.job.target }}' in arm-*) unset JOB_DO_TESTING ;; esac; + echo set-output name=JOB_DO_TESTING::${JOB_DO_TESTING:-/false} + echo ::set-output name=JOB_DO_TESTING::${JOB_DO_TESTING} + # # * test only binary for arm-type targets + unset CARGO_TEST_OPTIONS + unset CARGO_TEST_OPTIONS ; case '${{ matrix.job.target }}' in arm-*) CARGO_TEST_OPTIONS="--bin ${PROJECT_NAME}" ;; esac; + echo set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} + echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} + # * strip executable? + STRIP="strip" ; case '${{ matrix.job.target }}' in arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;; *-pc-windows-msvc) STRIP="" ;; esac; + echo set-output name=STRIP::${STRIP:-/false} + echo ::set-output name=STRIP::${STRIP} + - name: Create all needed build/work directories + shell: bash + run: | + ## create build/work space + mkdir -p '${{ steps.vars.outputs.STAGING }}' + mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}' + - name: rust toolchain ~ install + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ steps.vars.outputs.TOOLCHAIN }} + target: ${{ matrix.job.target }} + default: true + profile: minimal # minimal component installation (ie, no documentation) + - name: Install `cargo-tree` # for dependency information + uses: actions-rs/install@v0.1 + with: + crate: cargo-tree + version: latest + use-tool-cache: true + env: + RUSTUP_TOOLCHAIN: stable + - name: Info + shell: bash + run: | + # Info + ## tooling info display + echo "## tooling" + which gcc >/dev/null 2>&1 && (gcc --version | head -1) || true + rustup -V + rustup show active-toolchain + cargo -V + rustc -V + ## dependencies + echo "## dependency list" + cargo fetch --quiet + cargo tree --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --all --no-dev-dependencies --no-indent | grep -vE "$PWD" | sort --unique + - name: Build + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} + command: build + args: --release --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} + - name: Test + uses: actions-rs/cargo@v1 + with: + use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} + command: test + args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} + - name: Archive executable artifacts + uses: actions/upload-artifact@master + with: + name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }} + path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }} + - name: Package + shell: bash + run: | + ## package artifact(s) + # binary + cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' + # `strip` binary (if needed) + if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' ; fi + # README and LICENSE + # * spell-checker:ignore EADME ICENSE + (shopt -s nullglob; for f in [R]"EADME"{,.*}; do cp $f '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' ; done) + (shopt -s nullglob; for f in [L]"ICENSE"{-*,}{,.*}; do cp $f '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' ; done) + # core compressed package + pushd '${{ steps.vars.outputs.STAGING }}/' >/dev/null + case '${{ matrix.job.target }}' in + *-pc-windows-*) 7z -y a '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* | tail -2 ;; + *) tar czf '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* ;; + esac + popd >/dev/null + - name: Publish + uses: softprops/action-gh-release@v1 + if: steps.vars.outputs.DEPLOYABLE + with: + files: | + ${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_NAME }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + coverage: + name: Code Coverage + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: true + matrix: + # job: [ { os: ubuntu-latest }, { os: macos-latest }, { os: windows-latest } ] + job: [ { os: ubuntu-latest } ] ## cargo-tarpaulin is currently only available on linux + steps: + - uses: actions/checkout@v1 + # - name: Reattach HEAD ## may be needed for accurate code coverage info + # run: git checkout ${{ github.head_ref }} + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + # staging directory + STAGING='_staging' + echo set-output name=STAGING::${STAGING} + echo ::set-output name=STAGING::${STAGING} + # check for CODECOV_TOKEN availability (work-around for inaccessible 'secrets' object for 'if'; see ) + unset HAS_CODECOV_TOKEN + if [ -n $CODECOV_TOKEN ]; then HAS_CODECOV_TOKEN='true' ; fi + echo set-output name=HAS_CODECOV_TOKEN::${HAS_CODECOV_TOKEN} + echo ::set-output name=HAS_CODECOV_TOKEN::${HAS_CODECOV_TOKEN} + env: + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}" + - name: Create all needed build/work directories + shell: bash + run: | + ## create build/work space + mkdir -p '${{ steps.vars.outputs.STAGING }}/work' + - name: Install required packages + run: | + sudo apt-get -y install libssl-dev + pushd '${{ steps.vars.outputs.STAGING }}/work' >/dev/null + wget --no-verbose https://github.com/xd009642/tarpaulin/releases/download/0.9.3/cargo-tarpaulin-0.9.3-travis.tar.gz + tar xf cargo-tarpaulin-0.9.3-travis.tar.gz + cp cargo-tarpaulin "$(dirname -- "$(which cargo)")"/ + popd >/dev/null + - name: Generate coverage + run: | + cargo tarpaulin --out Xml + - name: Upload coverage results (CodeCov.io) + # CODECOV_TOKEN (aka, "Repository Upload Token" for REPO from CodeCov.io) ## set via REPO/Settings/Secrets + # if: secrets.CODECOV_TOKEN (not supported {yet?}; see ) + if: steps.vars.outputs.HAS_CODECOV_TOKEN + run: | + # CodeCov.io + cargo tarpaulin --out Xml + bash <(curl -s https://codecov.io/bash) + env: + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}" diff --git a/.travis.yml b/.travis.yml index 68d83bf0076..0aad7574b53 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,21 +19,22 @@ matrix: fast_finish: true include: - rust: 1.31.0 + env: FEATURES=unix - rust: stable os: linux - env: TEST_INSTALL=true + env: FEATURES=unix TEST_INSTALL=true - rust: stable os: osx - env: TEST_INSTALL=true + env: FEATURES=macos TEST_INSTALL=true - rust: nightly os: linux - env: FEATURES=nightly + env: FEATURES=nightly,unix - rust: nightly os: osx - env: FEATURES=nightly + env: FEATURES=nightly,macos - rust: nightly os: linux - env: FEATURES=nightly,redox CC=x86_64-unknown-redox-gcc CARGO_ARGS='--no-default-features --target=x86_64-unknown-redox' REDOX=1 + env: FEATURES=nightly,feat_os_unix_redox CC=x86_64-unknown-redox-gcc CARGO_ARGS='--no-default-features --target=x86_64-unknown-redox' REDOX=1 cache: directories: diff --git a/Cargo.lock b/Cargo.lock index 2583168dbb1..4879ed258d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,7 +57,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "backtrace" -version = "0.3.15" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -894,7 +894,7 @@ dependencies = [ [[package]] name = "nix" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1904,7 +1904,7 @@ dependencies = [ "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "platform-info 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2194,7 +2194,7 @@ dependencies = [ "checksum md5 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" +"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" "checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" diff --git a/Cargo.toml b/Cargo.toml index c4507d9f7d7..2b53fbddd37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,92 +6,122 @@ build = "build.rs" autotests = false [features] -unix = [ +default = [ "feat_common_core" ] +## OS feature shortcodes +macos = [ "feat_os_unix" ] +unix = [ "feat_os_unix" ] +windows = [ "feat_os_windows" ] +## project-specific feature shortcodes +nightly = [] +test_unimplemented = [] +## feature sets +# "feat_os_unix" == set of utilities which can be built/run on modern/usual *nix platforms +feat_os_unix = [ + "feat_common", + "feat_os_unix_musl", + "feat_os_unix_utmpx_required", + # + "stdbuf", +] +# "feat_os_unix_fuchsia" == set of utilities which can be built/run on the "Fuschia" OS (refs: ; ) +feat_os_unix_fuchsia = [ + "feat_common_core", + # "chgrp", "chmod", "chown", - "chroot", "du", "groups", "hostid", - "id", "install", - "kill", "logname", "mkfifo", "mknod", "nice", - "numfmt", - "nohup", "pathchk", - "pinky", - "stat", "stdbuf", - "timeout", - "touch", "tty", "uname", "unlink", - "uptime", - "users", - "who", - - "generic" ] -windows = ["generic"] -windows_legacy = [ - "arch", - "nproc", - "sync", - "touch", - "whoami", - - "redox_generic" - ] -# Feature "fuchsia" contains the exclusive list of utilities -# that can be compiled and run on Fuchsia. Should be built -# with --no-default-features when selecting this feature. -# TODO: merge with "unix" to avoid duplication once we support -# all utilities in that feature. -fuchsia = [ - # unix utilities +# "feat_os_unix_gnueabihf" == set of utilities which can be built/run on the "arm-unknown-linux-gnueabihf" target (ARMv6 Linux [hardfloat]) +feat_os_unix_gnueabihf = [ + "feat_common", + "feat_os_unix_musl", + "feat_os_unix_utmpx_required", +] +# "feat_os_unix_musl" == set of utilities which can be built/run on targets binding to the "musl" library (ref: ) +feat_os_unix_musl = [ + "feat_common", + # "chgrp", "chmod", "chown", + "chroot", "du", "groups", "hostid", + "id", "install", + "kill", "logname", "mkfifo", "mknod", "nice", + "numfmt", + "nohup", "pathchk", - "stdbuf", + "stat", + "timeout", + "touch", "tty", "uname", "unlink", - - # All generic utilities - "generic" ] -generic = [ +# "feat_os_unix_redox" == set of utilities which can be built/run on "Redox OS" (refs: ; ) +feat_os_unix_redox = [ + "feat_common_core", + # + "uname", + "chmod", + "install", +] +# "feat_os_unix_utmpx_required" == set of utilites requiring utmp/utmpx support +# * ref: +feat_os_unix_utmpx_required = [ + "pinky", + "uptime", + "users", + "who", +] +# "feat_os_windows" == set of utilities which can be built/run on modern/usual windows platforms +feat_os_windows = [ + "feat_common", ## == "feat_os_windows_legacy" + "hostname" + ] +# "feat_os_windows_legacy" == slightly restricted set of utilities which can be built/run on early windows platforms (eg, "WinXP") +feat_os_windows_legacy = [ + "feat_common_core", + # + "arch", + "nproc", + "sync", + "touch", + "whoami", + ] +## (common/core) feature sets +# "feat_common" == expanded set of utilities which can be built/run on the usual rust "tier 1" target platforms (ref: ) +feat_common = [ + "feat_common_core", + # "arch", "hostname", "nproc", "sync", "touch", "whoami", - "redox_generic" ] -# Feature "redox"/"redox_generic" contains the exclusive list of utilities -# that can be compiled and run on redox. Should be built -# with --no-default-features when selecting this feature. -# TODO: merge with "generic" to avoid duplication once we support -# all utilities in that feature. -redox_generic = [ - - # And maybe all generic utilities +# "feat_common_core" == baseline core set of utilities which can be built/run on most targets +feat_common_core = [ "base32", "base64", "basename", @@ -153,20 +183,11 @@ redox_generic = [ "wc", "yes", ] -redox = [ - "uname", - "chmod", - "install", - "redox_generic" -] -test_unimplemented = [] -nightly = [] -default = ["unix"] [workspace] [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" arch = { optional=true, path="src/arch" } base32 = { optional=true, path="src/base32" } base64 = { optional=true, path="src/base64" } @@ -260,16 +281,19 @@ wc = { optional=true, path="src/wc" } who = { optional=true, path="src/who" } whoami = { optional=true, path="src/whoami" } yes = { optional=true, path="src/yes" } +# +# * transitive dependency via 'failure'; pin to <= v0.3.30 to avoid increasing MinSRV to v1.33.0 +backtrace = ">= 0.3.3, <= 0.3.30" [dev-dependencies] -time = "0.1.42" filetime = "0.2.5" +lazy_static = "1.3.0" libc = "0.2.62" -regex = "1.0.3" rand = "0.6.5" +regex = "1.0.3" tempdir = "0.3.7" +time = "0.1.42" unindent = "0.1.3" -lazy_static = "1.3.0" [target.'cfg(unix)'.dev-dependencies] # FIXME: this should use the normal users crate, but it conflicts with the users utility @@ -282,3 +306,6 @@ path = "src/uutils/uutils.rs" [[test]] name = "tests" + +[patch.crates-io] +uucore = { git = "https://github.com/rivy/rust.uucore", tag = "0.0.2" } diff --git a/Makefile.toml b/Makefile.toml index 0da0b7af482..f2d06372016 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -1,17 +1,88 @@ +# spell-checker:ignore (cargo-make) duckscript macos +# spell-checker:ignore (rust) clippy + [config] +min_version = "0.26.2" default_to_workspace = false +init_task = "_init" [config.modify_core_tasks] namespace = "core" -[env] -CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = { source = "${CARGO_MAKE_RUST_TARGET_OS}", default_value = "", mapping = { "linux" = "--no-default-features --features unix", "windows" = "--no-default-features --features windows" } } +### initialization + +[tasks._init] +private = true +run_task = "_init_" + +[tasks._init_] +private = true +dependencies = [ + "_init-vars", +] + +[tasks._init-vars] +private = true +script_runner = "@duckscript" +script = [ +''' +# reset build/test flags +set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "" +# determine features +env_features = get_env CARGO_FEATURES +if is_empty "${env_features}" + env_features = get_env FEATURES +end_if +if is_empty "${env_features}" + if eq "${CARGO_MAKE_RUST_TARGET_OS}" "macos" + features = set "unix" + else + if eq "${CARGO_MAKE_RUST_TARGET_OS}" "linux" + features = set "unix" + else + if eq "${CARGO_MAKE_RUST_TARGET_OS}" "windows" + features = set "windows" + end_if + end_if + end_if +end_if +if is_empty "${features}" + features = set "${env_features}" +else + if not is_empty "${env_features}" + features = set "${features},${env_features}" + end_if +end_if +# set build flags from features +if not is_empty "${features}" + set_env CARGO_MAKE_VAR_BUILD_TEST_FEATURES "${features}" + set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "--features ${features}" +end_if +# determine show-utils helper script +show_utils = set "util/show-utils.sh" +if eq "${CARGO_MAKE_RUST_TARGET_OS}" "windows" + show_utils = set "util/show-utils.BAT" +end_if +set_env CARGO_MAKE_VAR_SHOW_UTILS "${show_utils}" +# rebuild TASK_ARGS for "--features" and package-build compatibility (using "," instead of ";") +args = set ${CARGO_MAKE_TASK_ARGS} +args = replace ${args} ";" "," +set_env CARGO_MAKE_TASK_BUILD_FEATURES_ARGS "${args}" +args = replace ${args} "," " -p" +if not is_empty "${args}" + args = set "-p${args}" +end_if +set_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS "${args}" +''' +] + +### tasks [tasks.default] description = "Build and Test" category = "[project]" dependencies = [ - "build", + "action-build-debug", "test-terse", ] @@ -20,15 +91,27 @@ description = "Build" category = "[project]" dependencies = [ "core::pre-build", - "core::build", + "action-build", + "core::post-build", +] + +[tasks.build-features] +description = "Build (with features); usage: `cargo make (build-features | features) FEATURE..`" +category = "[project]" +dependencies = [ + "core::pre-build", + "action-build-features", "core::post-build", ] +[tasks.features] +alias = "build-features" + [tasks.format] description = "Format" category = "[project]" dependencies = [ - "action.format", + "action-format", ] [tasks.help] @@ -45,6 +128,11 @@ dependencies = [ "action-fmt_report", ] +[tasks.release] +alias = "build" +description = "Build" +category = "[project]" + [tasks.test] description = "Test" category = "[project]" @@ -63,13 +151,66 @@ dependencies = [ "core::post-test", ] +[tasks.util] +alias = "utils" + +[tasks.utils] +description = "Build (individual) utilities; usage: `cargo make (util | utils) [UTIL_NAME..]`" +category = "[project]" +dependencies = [ + "core::pre-build", + "action-determine-utils", + "action-build-utils", + "core::post-build", +] + ### actions +[tasks.action-build] +description = "`cargo build --release`" +command = "cargo" +args = ["build", "--release", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )" ] + +[tasks.action-build-debug] +description = "`cargo build`" +command = "cargo" +args = ["build", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )" ] + +[tasks.action-build-features] +description = "`cargo build --release --features FEATURES`" +command = "cargo" +args = ["build", "--release", "--no-default-features", "--features", "${CARGO_MAKE_TASK_BUILD_FEATURES_ARGS}" ] + +[tasks.action-build-utils] +description = "Build individual utilities" +command = "cargo" +# args = ["build", "@@remove-empty(CARGO_MAKE_TASK_BUILD_UTILS_ARGS)" ] +args = ["build", "--release", "@@split(CARGO_MAKE_TASK_BUILD_UTILS_ARGS, )" ] + [tasks.action-clippy] description = "`cargo clippy` lint report" command = "cargo" args = ["clippy", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )"] +[tasks.action-determine-utils] +script_runner = "@duckscript" +script = [ +''' +package_options = get_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS +if is_empty "${package_options}" + show_utils = get_env CARGO_MAKE_VAR_SHOW_UTILS + result = exec "${show_utils}" + set_env CARGO_MAKE_VAR_UTILS ${result.stdout} + utils = array %{result.stdout} + for util in ${utils} + package_options = set "${package_options} -p${util}" + end + package_options = trim "${package_options}" +end_if +set_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS "${package_options}" +''' +] + [tasks.action-format] description = "`cargo fmt`" command = "cargo" diff --git a/build.rs b/build.rs index 12418983912..833c911126c 100644 --- a/build.rs +++ b/build.rs @@ -16,8 +16,9 @@ pub fn main() { if val == "1" && key.starts_with(feature_prefix) { let krate = key[feature_prefix.len()..].to_lowercase(); match krate.as_ref() { - "default" | "unix" | "redox" | "redox_generic" | "fuchsia" | "generic" | "windows" | "windows_legacy" - | "nightly" | "test_unimplemented" => continue, + "default" | "macos" | "unix" | "windows" => continue, + "nightly" | "test_unimplemented" => continue, + s if s.starts_with("feat_") => continue, _ => {} } crates.push(krate.to_string()); @@ -35,7 +36,8 @@ pub fn main() { fn util_map() -> UtilityMap { let mut map: UtilityMap = HashMap::new();\n" .as_bytes(), - ).unwrap(); + ) + .unwrap(); for krate in crates { cf.write_all(format!("extern crate uu_{krate};\n", krate = krate).as_bytes()) @@ -59,18 +61,22 @@ pub fn main() { map.insert(\"shake128sum\", uu_hashsum::uumain); map.insert(\"shake256sum\", uu_hashsum::uumain);\n" .as_bytes(), - ).unwrap(); + ) + .unwrap(); } - _ => mf.write_all( - format!( - "map.insert(\"{krate}\", uu_{krate}::uumain);\n", - krate = krate - ).as_bytes(), - ).unwrap(), + _ => mf + .write_all( + format!( + "map.insert(\"{krate}\", uu_{krate}::uumain);\n", + krate = krate + ) + .as_bytes(), + ) + .unwrap(), } } - mf.write_all("map\n}\n".as_bytes()).unwrap(); + mf.write_all(b"map\n}\n").unwrap(); cf.flush().unwrap(); mf.flush().unwrap(); diff --git a/mkmain.rs b/src/#common/mkmain.rs similarity index 96% rename from mkmain.rs rename to src/#common/mkmain.rs index f065ea8b2dc..4ae471c4177 100644 --- a/mkmain.rs +++ b/src/#common/mkmain.rs @@ -1,9 +1,9 @@ use std::env; -use std::io::Write; use std::fs::File; +use std::io::Write; use std::path::Path; -static TEMPLATE: &'static str = "\ +static TEMPLATE: &str = "\ extern crate uu_@UTIL_CRATE@; extern crate uucore; diff --git a/uumain.rs b/src/#common/uumain.rs similarity index 100% rename from uumain.rs rename to src/#common/uumain.rs diff --git a/src/arch/Cargo.toml b/src/arch/Cargo.toml index d009a09c44f..5c316495ffc 100644 --- a/src/arch/Cargo.toml +++ b/src/arch/Cargo.toml @@ -2,7 +2,8 @@ name = "arch" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_arch" @@ -10,8 +11,8 @@ path = "arch.rs" [dependencies] platform-info = "0.0.1" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "arch" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/base32/Cargo.toml b/src/base32/Cargo.toml index 75b25454bfd..eaddeaa6b49 100644 --- a/src/base32/Cargo.toml +++ b/src/base32/Cargo.toml @@ -2,20 +2,18 @@ name = "base32" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_base32" path = "base32.rs" -[dependencies.uucore] -version = "0.0.1" -features = ["encoding"] - -[dependencies.clippy] -version = "0.0.212" -optional = true +[dependencies] +uucore = { version = "0.0.2", features = ["encoding"] } +## optional +clippy = { version = "0.0.212", optional = true } [[bin]] name = "base32" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/base32/base32.rs b/src/base32/base32.rs index 5487842982d..feb7bc38429 100644 --- a/src/base32/base32.rs +++ b/src/base32/base32.rs @@ -16,8 +16,7 @@ use uucore::encoding::Format; mod base_common; static SYNTAX: &str = "[OPTION]... [FILE]"; -static SUMMARY: &str = - "Base32 encode or decode FILE, or standard input, to standard output."; +static SUMMARY: &str = "Base32 encode or decode FILE, or standard input, to standard output."; static LONG_HELP: &str = " With no FILE, or when FILE is -, read standard input. diff --git a/src/base64/Cargo.toml b/src/base64/Cargo.toml index 63b82b4ec23..bb8b17e78cd 100644 --- a/src/base64/Cargo.toml +++ b/src/base64/Cargo.toml @@ -2,16 +2,16 @@ name = "base64" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_base64" path = "base64.rs" -[dependencies.uucore] -version = "0.0.1" -features = ["encoding"] +[dependencies] +uucore = { version = "0.0.2", features = ["encoding"] } [[bin]] name = "base64" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/base64/base64.rs b/src/base64/base64.rs index 9072fecb03d..effd4598b43 100644 --- a/src/base64/base64.rs +++ b/src/base64/base64.rs @@ -16,8 +16,7 @@ use uucore::encoding::Format; mod base_common; static SYNTAX: &str = "[OPTION]... [FILE]"; -static SUMMARY: &str = - "Base64 encode or decode FILE, or standard input, to standard output."; +static SUMMARY: &str = "Base64 encode or decode FILE, or standard input, to standard output."; static LONG_HELP: &str = " With no FILE, or when FILE is -, read standard input. diff --git a/src/base64/base_common.rs b/src/base64/base_common.rs index 040b91608e7..1bb09ace16e 100644 --- a/src/base64/base_common.rs +++ b/src/base64/base_common.rs @@ -36,13 +36,11 @@ pub fn execute( "COLS", ) .parse(args); - - let line_wrap = matches.opt_str("wrap").map(|s| { - match s.parse() { - Ok(n) => n, - Err(e) => { - crash!(1, "invalid wrap size: ‘{}’: {}", s, e); - } + + let line_wrap = matches.opt_str("wrap").map(|s| match s.parse() { + Ok(n) => n, + Err(e) => { + crash!(1, "invalid wrap size: ‘{}’: {}", s, e); } }); let ignore_garbage = matches.opt_present("ignore-garbage"); @@ -55,7 +53,13 @@ pub fn execute( if matches.free.is_empty() || &matches.free[0][..] == "-" { let stdin_raw = stdin(); - handle_input(&mut stdin_raw.lock(), format, line_wrap, ignore_garbage, decode); + handle_input( + &mut stdin_raw.lock(), + format, + line_wrap, + ignore_garbage, + decode, + ); } else { let path = Path::new(matches.free[0].as_str()); let file_buf = safe_unwrap!(File::open(&path)); @@ -73,8 +77,7 @@ fn handle_input( ignore_garbage: bool, decode: bool, ) { - let mut data = Data::new(input, format) - .ignore_garbage(ignore_garbage); + let mut data = Data::new(input, format).ignore_garbage(ignore_garbage); if let Some(wrap) = line_wrap { data = data.line_wrap(wrap); } @@ -88,4 +91,4 @@ fn handle_input( Err(_) => crash!(1, "invalid input"), } } -} \ No newline at end of file +} diff --git a/src/basename/Cargo.toml b/src/basename/Cargo.toml index 1e3cb7adc42..9edb409f1cc 100644 --- a/src/basename/Cargo.toml +++ b/src/basename/Cargo.toml @@ -2,15 +2,16 @@ name = "basename" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_basename" path = "basename.rs" [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "basename" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/cat/Cargo.toml b/src/cat/Cargo.toml index e4a37d1f779..0e561b7fb02 100644 --- a/src/cat/Cargo.toml +++ b/src/cat/Cargo.toml @@ -2,22 +2,20 @@ name = "cat" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_cat" path = "cat.rs" [dependencies] -quick-error = "1.2.2" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +quick-error = "1.2.3" +uucore = { version = "0.0.2", features = ["fs"] } [target.'cfg(unix)'.dependencies] unix_socket = "0.5.0" [[bin]] name = "cat" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/cat/cat.rs b/src/cat/cat.rs index 97399b977d5..477db9599d0 100755 --- a/src/cat/cat.rs +++ b/src/cat/cat.rs @@ -38,9 +38,9 @@ static LONG_HELP: &str = ""; #[derive(PartialEq)] enum NumberingMode { - NumberNone, - NumberNonEmpty, - NumberAll, + None, + NonEmpty, + All, } quick_error! { @@ -147,11 +147,11 @@ pub fn uumain(args: Vec) -> i32 { .parse(args); let number_mode = if matches.opt_present("b") { - NumberingMode::NumberNonEmpty + NumberingMode::NonEmpty } else if matches.opt_present("n") { - NumberingMode::NumberAll + NumberingMode::All } else { - NumberingMode::NumberNone + NumberingMode::None }; let show_nonprint = matches.opts_present(&[ @@ -168,8 +168,11 @@ pub fn uumain(args: Vec) -> i32 { files.push("-".to_owned()); } - let can_write_fast = !(show_tabs || show_nonprint || show_ends || squeeze_blank - || number_mode != NumberingMode::NumberNone); + let can_write_fast = !(show_tabs + || show_nonprint + || show_ends + || squeeze_blank + || number_mode != NumberingMode::None); let success = if can_write_fast { write_fast(files).is_ok() @@ -190,7 +193,11 @@ pub fn uumain(args: Vec) -> i32 { write_lines(files, &options).is_ok() }; - if success { 0 } else { 1 } + if success { + 0 + } else { + 1 + } } /// Classifies the `InputType` of file at `path` if possible @@ -205,25 +212,13 @@ fn get_input_type(path: &str) -> CatResult { match metadata(path).context(path)?.file_type() { #[cfg(unix)] - ft if ft.is_block_device() => - { - Ok(InputType::BlockDevice) - } + ft if ft.is_block_device() => Ok(InputType::BlockDevice), #[cfg(unix)] - ft if ft.is_char_device() => - { - Ok(InputType::CharacterDevice) - } + ft if ft.is_char_device() => Ok(InputType::CharacterDevice), #[cfg(unix)] - ft if ft.is_fifo() => - { - Ok(InputType::Fifo) - } + ft if ft.is_fifo() => Ok(InputType::Fifo), #[cfg(unix)] - ft if ft.is_socket() => - { - Ok(InputType::Socket) - } + ft if ft.is_socket() => Ok(InputType::Socket), ft if ft.is_dir() => Ok(InputType::Directory), ft if ft.is_file() => Ok(InputType::File), ft if ft.is_symlink() => Ok(InputType::SymLink), @@ -282,12 +277,14 @@ fn write_fast(files: Vec) -> CatResult<()> { for file in files { match open(&file[..]) { - Ok(mut handle) => while let Ok(n) = handle.reader.read(&mut in_buf) { - if n == 0 { - break; + Ok(mut handle) => { + while let Ok(n) = handle.reader.read(&mut in_buf) { + if n == 0 { + break; + } + writer.write_all(&in_buf[..n]).context(&file[..])?; } - writer.write_all(&in_buf[..n]).context(&file[..])?; - }, + } Err(error) => { writeln!(&mut stderr(), "{}", error)?; error_count += 1; @@ -357,7 +354,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState if in_buf[pos] == b'\n' { if !state.at_line_start || !options.squeeze_blank || !one_blank_kept { one_blank_kept = true; - if state.at_line_start && options.number == NumberingMode::NumberAll { + if state.at_line_start && options.number == NumberingMode::All { write!(&mut writer, "{0:6}\t", state.line_number)?; state.line_number += 1; } @@ -371,7 +368,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState continue; } one_blank_kept = false; - if state.at_line_start && options.number != NumberingMode::NumberNone { + if state.at_line_start && options.number != NumberingMode::None { write!(&mut writer, "{0:6}\t", state.line_number)?; state.line_number += 1; } @@ -421,10 +418,7 @@ fn write_to_end(in_buf: &[u8], writer: &mut W) -> usize { fn write_tab_to_end(mut in_buf: &[u8], writer: &mut W) -> usize { let mut count = 0; loop { - match in_buf - .iter() - .position(|c| *c == b'\n' || *c == b'\t') - { + match in_buf.iter().position(|c| *c == b'\n' || *c == b'\t') { Some(p) => { writer.write_all(&in_buf[..p]).unwrap(); if in_buf[p] == b'\n' { @@ -458,7 +452,8 @@ fn write_nonprint_to_end(in_buf: &[u8], writer: &mut W, tab: &[u8]) -> 128..=159 => writer.write_all(&[b'M', b'-', b'^', byte - 64]), 160..=254 => writer.write_all(&[b'M', b'-', byte - 128]), _ => writer.write_all(&[b'M', b'-', b'^', 63]), - }.unwrap(); + } + .unwrap(); count += 1; } if count != in_buf.len() { diff --git a/src/chgrp/Cargo.toml b/src/chgrp/Cargo.toml index caea10ccff1..301f081df1a 100644 --- a/src/chgrp/Cargo.toml +++ b/src/chgrp/Cargo.toml @@ -2,19 +2,17 @@ name = "chgrp" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_chgrp" path = "chgrp.rs" [dependencies] +uucore = { version = "0.0.2", features = ["entries", "fs"] } walkdir = "2.2.8" -[dependencies.uucore] -version = "0.0.1" -features = ["entries", "fs"] - [[bin]] name = "chgrp" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/chgrp/chgrp.rs b/src/chgrp/chgrp.rs index ed50432d3eb..fac36f67219 100644 --- a/src/chgrp/chgrp.rs +++ b/src/chgrp/chgrp.rs @@ -10,15 +10,15 @@ #[macro_use] extern crate uucore; -use uucore::libc::{self, gid_t, lchown}; pub use uucore::entries; use uucore::fs::resolve_relative_path; +use uucore::libc::{self, gid_t, lchown}; extern crate walkdir; use walkdir::WalkDir; -use std::io::Result as IOResult; use std::io::Error as IOError; +use std::io::Result as IOResult; use std::fs; use std::fs::Metadata; @@ -183,12 +183,12 @@ struct Chgrper { } macro_rules! unwrap { - ($m:expr, $e:ident, $err:block) => ( + ($m:expr, $e:ident, $err:block) => { match $m { Ok(meta) => meta, Err($e) => $err, } - ) + }; } impl Chgrper { diff --git a/src/chmod/Cargo.toml b/src/chmod/Cargo.toml index 0df9d54a8fe..596adee4175 100644 --- a/src/chmod/Cargo.toml +++ b/src/chmod/Cargo.toml @@ -2,7 +2,8 @@ name = "chmod" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_chmod" @@ -10,12 +11,9 @@ path = "chmod.rs" [dependencies] libc = "0.2.42" +uucore = { version = "0.0.2", features = ["mode"] } walker = "1.0.0" -[dependencies.uucore] -version = "0.0.1" -features = ["mode"] - [[bin]] name = "chmod" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/chmod/chmod.rs b/src/chmod/chmod.rs index 17e111063f6..71cd1b82f5a 100644 --- a/src/chmod/chmod.rs +++ b/src/chmod/chmod.rs @@ -19,10 +19,10 @@ extern crate uucore; use std::fs; use std::os::unix::fs::{MetadataExt, PermissionsExt}; use std::path::Path; -use walker::Walker; +use uucore::fs::display_permissions_unix; #[cfg(not(windows))] use uucore::mode; -use uucore::fs::display_permissions_unix; +use walker::Walker; const NAME: &str = "chmod"; static SUMMARY: &str = "Change the mode of each FILE to MODE. @@ -39,14 +39,31 @@ pub fn uumain(mut args: Vec) -> i32 { NAME ); let mut opts = new_coreopts!(&syntax, SUMMARY, LONG_HELP); - opts.optflag("c", "changes", "like verbose but report only when a change is made") - // TODO: support --silent (can be done using clap) - .optflag("f", "quiet", "suppress most error messages") - .optflag("v", "verbose", "output a diagnostic for every file processed") - .optflag("", "no-preserve-root", "do not treat '/' specially (the default)") - .optflag("", "preserve-root", "fail to operate recursively on '/'") - .optopt("", "reference", "use RFILE's mode instead of MODE values", "RFILE") - .optflag("R", "recursive", "change files and directories recursively"); + opts.optflag( + "c", + "changes", + "like verbose but report only when a change is made", + ) + // TODO: support --silent (can be done using clap) + .optflag("f", "quiet", "suppress most error messages") + .optflag( + "v", + "verbose", + "output a diagnostic for every file processed", + ) + .optflag( + "", + "no-preserve-root", + "do not treat '/' specially (the default)", + ) + .optflag("", "preserve-root", "fail to operate recursively on '/'") + .optopt( + "", + "reference", + "use RFILE's mode instead of MODE values", + "RFILE", + ) + .optflag("R", "recursive", "change files and directories recursively"); // sanitize input for - at beginning (e.g. chmod -x testfile). Remove // the option and save it for later, after parsing is finished. @@ -100,7 +117,7 @@ pub fn uumain(mut args: Vec) -> i32 { fn sanitize_input(args: &mut Vec) -> Option { for i in 0..args.len() { - let first = args[i].chars().nth(0).unwrap(); + let first = args[i].chars().next().unwrap(); if first != '-' { continue; } @@ -148,17 +165,19 @@ impl Chmoder { // on Windows OsStrings cannot be built out of non-UTF-8 chars. One // possible fix is to use CStrings rather than Strings in the args // to chmod() and chmod_file(). - r = self.chmod( - walk_dir - .filter_map(|x| match x { - Ok(o) => match o.path().into_os_string().to_str() { - Some(s) => Some(s.to_owned()), - None => None, - }, - Err(_) => None, - }) - .collect(), - ).and(r); + r = self + .chmod( + walk_dir + .filter_map(|x| match x { + Ok(o) => match o.path().into_os_string().to_str() { + Some(s) => Some(s.to_owned()), + None => None, + }, + Err(_) => None, + }) + .collect(), + ) + .and(r); r = self.chmod_file(&file, filename).and(r); } } else { @@ -230,7 +249,12 @@ impl Chmoder { fn change_file(&self, fperm: u32, mode: u32, file: &Path, path: &str) -> Result<(), i32> { if fperm == mode { if self.verbose && !self.changes { - show_info!("mode of '{}' retained as {:o} ({})", file.display(), fperm, display_permissions_unix(fperm)); + show_info!( + "mode of '{}' retained as {:o} ({})", + file.display(), + fperm, + display_permissions_unix(fperm) + ); } Ok(()) } else if let Err(err) = diff --git a/src/chown/Cargo.toml b/src/chown/Cargo.toml index 1e6ec9e368f..9b56872f59d 100644 --- a/src/chown/Cargo.toml +++ b/src/chown/Cargo.toml @@ -2,7 +2,8 @@ name = "chown" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_chown" @@ -10,16 +11,13 @@ path = "chown.rs" [dependencies] glob = "0.3.0" +uucore = { version = "0.0.2", features = ["entries", "fs"] } walkdir = "2.2" -[dependencies.uucore] -version = "0.0.1" -features = ["entries", "fs"] - [dependencies.clippy] version = "0.0.212" optional = true [[bin]] name = "chown" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/chown/chown.rs b/src/chown/chown.rs index ef6086c2ce4..7b737849223 100644 --- a/src/chown/chown.rs +++ b/src/chown/chown.rs @@ -11,9 +11,9 @@ #[macro_use] extern crate uucore; -use uucore::libc::{self, gid_t, lchown, uid_t}; pub use uucore::entries::{self, Group, Locate, Passwd}; use uucore::fs::resolve_relative_path; +use uucore::libc::{self, gid_t, lchown, uid_t}; extern crate walkdir; use walkdir::WalkDir; @@ -24,8 +24,8 @@ use std::os::unix::fs::MetadataExt; use std::io; use std::io::Result as IOResult; -use std::path::Path; use std::convert::AsRef; +use std::path::Path; use std::ffi::CString; use std::os::unix::ffi::OsStrExt; @@ -253,12 +253,12 @@ struct Chowner { } macro_rules! unwrap { - ($m:expr, $e:ident, $err:block) => ( + ($m:expr, $e:ident, $err:block) => { match $m { Ok(meta) => meta, Err($e) => $err, } - ) + }; } impl Chowner { @@ -395,8 +395,8 @@ impl Chowner { fn wrap_chown>(&self, path: P, meta: &Metadata, follow: bool) -> i32 { use self::Verbosity::*; let mut ret = 0; - let dest_uid = self.dest_uid.unwrap_or(meta.uid()); - let dest_gid = self.dest_gid.unwrap_or(meta.gid()); + let dest_uid = self.dest_uid.unwrap_or_else(|| meta.uid()); + let dest_gid = self.dest_gid.unwrap_or_else(|| meta.gid()); let path = path.as_ref(); if let Err(e) = self.chown(path, dest_uid, dest_gid, follow) { match self.verbosity { diff --git a/src/chroot/Cargo.toml b/src/chroot/Cargo.toml index 6fd89327769..b450fe570c7 100644 --- a/src/chroot/Cargo.toml +++ b/src/chroot/Cargo.toml @@ -2,7 +2,8 @@ name = "chroot" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_chroot" @@ -10,11 +11,8 @@ path = "chroot.rs" [dependencies] getopts = "0.2.18" - -[dependencies.uucore] -version = "0.0.1" -features = ["entries"] +uucore = { version = "0.0.2", features = ["entries"] } [[bin]] name = "chroot" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/chroot/chroot.rs b/src/chroot/chroot.rs index a7973e8fe2a..140d2f18b4d 100644 --- a/src/chroot/chroot.rs +++ b/src/chroot/chroot.rs @@ -14,8 +14,8 @@ extern crate getopts; #[macro_use] extern crate uucore; -use uucore::libc::{self, chroot, setgid, setgroups, setuid}; use uucore::entries; +use uucore::libc::{self, chroot, setgid, setgroups, setuid}; use std::ffi::CString; use std::io::Error; @@ -140,10 +140,7 @@ fn enter_chroot(root: &Path) { let root_str = root.display(); std::env::set_current_dir(root).unwrap(); let err = unsafe { - chroot(CString::new(".") - .unwrap() - .as_bytes_with_nul() - .as_ptr() as *const libc::c_char) + chroot(CString::new(".").unwrap().as_bytes_with_nul().as_ptr() as *const libc::c_char) }; if err != 0 { crash!( diff --git a/src/cksum/Cargo.toml b/src/cksum/Cargo.toml index f608e4396da..4052b436e57 100644 --- a/src/cksum/Cargo.toml +++ b/src/cksum/Cargo.toml @@ -2,6 +2,7 @@ name = "cksum" version = "0.0.1" authors = [] +license = "MIT" [lib] name = "uu_cksum" @@ -9,8 +10,8 @@ path = "cksum.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "cksum" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/cksum/build.rs b/src/cksum/build.rs index 37c48db5c6f..e918a744285 100644 --- a/src/cksum/build.rs +++ b/src/cksum/build.rs @@ -15,7 +15,7 @@ use std::path::Path; const CRC_TABLE_LEN: usize = 256; -#[path = "../../mkmain.rs"] +#[path = "../#common/mkmain.rs"] mod mkmain; fn main() { @@ -30,9 +30,10 @@ fn main() { let file = File::create(&Path::new(&out_dir).join("crc_table.rs")).unwrap(); write!( &file, - "const CRC_TABLE: [u32; {}] = {:?};", + "#[allow(clippy::unreadable_literal)]\nconst CRC_TABLE: [u32; {}] = {:?};", CRC_TABLE_LEN, table - ).unwrap(); + ) + .unwrap(); } #[inline] @@ -40,9 +41,9 @@ fn crc_entry(input: u8) -> u32 { let mut crc = (input as u32) << 24; for _ in 0..8 { - if crc & 0x80000000 != 0 { + if crc & 0x8000_0000 != 0 { crc <<= 1; - crc ^= 0x04c11db7; + crc ^= 0x04c1_1db7; } else { crc <<= 1; } diff --git a/src/cksum/cksum.rs b/src/cksum/cksum.rs index e03cea4e750..22ebabf2e85 100644 --- a/src/cksum/cksum.rs +++ b/src/cksum/cksum.rs @@ -14,8 +14,6 @@ extern crate uucore; use std::fs::File; use std::io::{self, stdin, BufReader, Read}; -#[cfg(not(windows))] -use std::mem; use std::path::Path; include!(concat!(env!("OUT_DIR"), "/crc_table.rs")); @@ -39,16 +37,10 @@ fn crc_final(mut crc: u32, mut length: usize) -> u32 { !crc } -#[cfg(windows)] fn init_byte_array() -> Vec { vec![0; 1024 * 1024] } -#[cfg(not(windows))] -fn init_byte_array() -> [u8; 1024 * 1024] { - unsafe { mem::uninitialized() } -} - #[inline] fn cksum(fname: &str) -> io::Result<(u32, usize)> { let mut crc = 0u32; diff --git a/src/comm/Cargo.toml b/src/comm/Cargo.toml index 6ddb78f3ed2..533c96ebe3e 100644 --- a/src/comm/Cargo.toml +++ b/src/comm/Cargo.toml @@ -2,17 +2,18 @@ name = "comm" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_comm" path = "comm.rs" [dependencies] -libc = "0.2.42" getopts = "0.2.18" -uucore = "0.0.1" +libc = "0.2.42" +uucore = "0.0.2" [[bin]] name = "comm" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/comm/comm.rs b/src/comm/comm.rs index f9381826bca..1997c27e64a 100644 --- a/src/comm/comm.rs +++ b/src/comm/comm.rs @@ -26,7 +26,7 @@ static LONG_HELP: &str = ""; fn mkdelim(col: usize, opts: &getopts::Matches) -> String { let mut s = String::new(); let delim = match opts.opt_str("output-delimiter") { - Some(d) => d.clone(), + Some(d) => d, None => "\t".to_owned(), }; diff --git a/src/cp/Cargo.toml b/src/cp/Cargo.toml index cabe80bcdb3..6474bb06a90 100644 --- a/src/cp/Cargo.toml +++ b/src/cp/Cargo.toml @@ -5,23 +5,21 @@ authors = [ "Jordy Dickinson ", "Joshua S. Miller ", ] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_cp" path = "cp.rs" [dependencies] +clap = "2.32.0" +filetime = "0.2" getopts = "0.2.18" libc = "0.2.42" +quick-error = "1.2.3" +uucore = { version = "0.0.2", features = ["fs"] } walkdir = "2.2.8" -clap = "2.32.0" -quick-error = "1.2.2" -filetime = "0.2" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] [target.'cfg(target_os = "linux")'.dependencies] ioctl-sys = "0.5.2" @@ -35,4 +33,4 @@ xattr="0.2.1" [[bin]] name = "cp" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/cp/cp.rs b/src/cp/cp.rs index 6b08a8e24f0..baf1a9cd82d 100644 --- a/src/cp/cp.rs +++ b/src/cp/cp.rs @@ -1,4 +1,5 @@ #![crate_name = "uu_cp"] +#![allow(clippy::missing_safety_doc)] /* * This file is part of the uutils coreutils package. @@ -27,35 +28,42 @@ extern crate xattr; #[cfg(windows)] extern crate kernel32; #[cfg(windows)] -use kernel32::GetFileInformationByHandle; -#[cfg(windows)] use kernel32::CreateFileW; #[cfg(windows)] +use kernel32::GetFileInformationByHandle; +#[cfg(windows)] extern crate winapi; -use std::mem; -use std::ffi::CString; use clap::{App, Arg, ArgMatches}; +use filetime::FileTime; use quick_error::ResultExt; use std::collections::HashSet; +#[cfg(not(windows))] +use std::ffi::CString; +#[cfg(windows)] +use std::ffi::OsStr; use std::fs; -use std::io::{stdin, stdout, Write}; +#[cfg(target_os = "linux")] +use std::fs::File; +use std::fs::OpenOptions; use std::io; +use std::io::{stdin, stdout, Write}; +use std::mem; +#[cfg(target_os = "linux")] +use std::os::unix::io::IntoRawFd; +#[cfg(windows)] +use std::os::windows::ffi::OsStrExt; use std::path::{Path, PathBuf, StripPrefixError}; use std::str::FromStr; +use std::string::ToString; use uucore::fs::{canonicalize, CanonicalizeMode}; use walkdir::WalkDir; -#[cfg(target_os = "linux")] -use std::os::unix::io::IntoRawFd; -#[cfg(target_os = "linux")] -use std::fs::File; -use std::fs::OpenOptions; -use filetime::FileTime; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; #[cfg(target_os = "linux")] +#[allow(clippy::missing_safety_doc)] ioctl!(write ficlone with 0x94, 9; std::os::raw::c_int); quick_error! { @@ -121,7 +129,7 @@ macro_rules! prompt_yes( crash_if_err!(1, stdout().flush()); let mut s = String::new(); match stdin().read_line(&mut s) { - Ok(_) => match s.char_indices().nth(0) { + Ok(_) => match s.char_indices().next() { Some((_, x)) => x == 'y' || x == 'Y', _ => false }, @@ -470,7 +478,7 @@ pub fn uumain(args: Vec) -> i32 { let options = crash_if_err!(EXIT_ERR, Options::from_matches(&matches)); let paths: Vec = matches .values_of("paths") - .map(|v| v.map(|p| p.to_string()).collect()) + .map(|v| v.map(ToString::to_string).collect()) .unwrap_or_default(); let (sources, target) = crash_if_err!(EXIT_ERR, parse_path_args(&paths, &options)); @@ -576,7 +584,8 @@ impl Options { } } - let recursive = matches.is_present(OPT_RECURSIVE) || matches.is_present(OPT_RECURSIVE_ALIAS) + let recursive = matches.is_present(OPT_RECURSIVE) + || matches.is_present(OPT_RECURSIVE_ALIAS) || matches.is_present(OPT_ARCHIVE); let backup = matches.is_present(OPT_BACKUP) || (matches.occurrences_of(OPT_SUFFIX) > 0); @@ -585,7 +594,7 @@ impl Options { let no_target_dir = matches.is_present(OPT_NO_TARGET_DIRECTORY); let target_dir = matches .value_of(OPT_TARGET_DIRECTORY) - .map(|v| v.to_string()); + .map(ToString::to_string); // Parse attributes to preserve let preserve_attributes: Vec = if matches.is_present(OPT_PRESERVE) { @@ -712,27 +721,30 @@ fn preserve_hardlinks( { if !source.is_dir() { unsafe { - let src_path = CString::new(source.as_os_str().to_str().unwrap()).unwrap(); let inode: u64; let nlinks: u64; #[cfg(unix)] { + let src_path = CString::new(source.as_os_str().to_str().unwrap()).unwrap(); let mut stat = mem::zeroed(); if libc::lstat(src_path.as_ptr(), &mut stat) < 0 { return Err(format!( "cannot stat {:?}: {}", src_path, std::io::Error::last_os_error() - ).into()); + ) + .into()); } inode = stat.st_ino as u64; nlinks = stat.st_nlink as u64; } #[cfg(windows)] { + let src_path: Vec = OsStr::new(source).encode_wide().collect(); + #[allow(deprecated)] let stat = mem::uninitialized(); let handle = CreateFileW( - src_path.as_ptr() as *const u16, + src_path.as_ptr(), winapi::um::winnt::GENERIC_READ, winapi::um::winnt::FILE_SHARE_READ, std::ptr::null_mut(), @@ -745,7 +757,8 @@ fn preserve_hardlinks( "cannot get file information {:?}: {}", source, std::io::Error::last_os_error() - ).into()); + ) + .into()); } inode = ((*stat).nFileIndexHigh as u64) << 32 | (*stat).nFileIndexLow as u64; nlinks = (*stat).nNumberOfLinks as u64; @@ -758,7 +771,7 @@ fn preserve_hardlinks( } } if !(*found_hard_link) && nlinks > 1 { - hard_links.push((dest.clone().to_str().unwrap().to_string(), inode)); + hard_links.push((dest.to_str().unwrap().to_string(), inode)); } } } @@ -826,7 +839,8 @@ fn construct_dest_path( return Err(format!( "cannot overwrite directory '{}' with non-directory", target.display() - ).into()); + ) + .into()); } Ok(match *target_type { @@ -940,7 +954,7 @@ impl OverwriteMode { fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResult<()> { let context = &*format!("'{}' -> '{}'", source.display().to_string(), dest.display()); - Ok(match *attribute { + match *attribute { #[cfg(unix)] Attribute::Mode => { let mode = fs::metadata(source).context(context)?.permissions().mode(); @@ -973,10 +987,11 @@ fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResu } #[cfg(not(unix))] { - return Err(format!("XAttrs are only supported on unix.").into()); + return Err("XAttrs are only supported on unix.".to_string().into()); } } - }) + }; + Ok(()) } #[cfg(not(windows))] @@ -1072,8 +1087,8 @@ fn copy_file(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> { CopyMode::Sparse => return Err(Error::NotImplemented(OPT_SPARSE.to_string())), CopyMode::Update => { if dest.exists() { - let src_metadata = fs::metadata(source.clone())?; - let dest_metadata = fs::metadata(dest.clone())?; + let src_metadata = fs::metadata(source)?; + let dest_metadata = fs::metadata(dest)?; let src_time = src_metadata.modified()?; let dest_time = dest_metadata.modified()?; @@ -1108,7 +1123,7 @@ fn copy_file(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> { fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> { if options.reflink { #[cfg(not(target_os = "linux"))] - return Err(format!("--reflink is only supported on linux").into()); + return Err("--reflink is only supported on linux".to_string().into()); #[cfg(target_os = "linux")] { @@ -1129,7 +1144,8 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> source, dest, std::io::Error::last_os_error() - ).into()); + ) + .into()); } else { return Ok(()); } @@ -1158,7 +1174,8 @@ pub fn verify_target_type(target: &Path, target_type: &TargetType) -> CopyResult (&TargetType::File, true) => Err(format!( "cannot overwrite directory '{}' with non-directory", target.display() - ).into()), + ) + .into()), _ => Ok(()), } } @@ -1194,6 +1211,8 @@ fn test_cp_localize_to_target() { &Path::new("a/source/"), &Path::new("a/source/c.txt"), &Path::new("target/") - ).unwrap() == Path::new("target/c.txt") + ) + .unwrap() + == Path::new("target/c.txt") ) } diff --git a/src/cut/Cargo.toml b/src/cut/Cargo.toml index 97d4ade2b2d..c22d4fd43d8 100644 --- a/src/cut/Cargo.toml +++ b/src/cut/Cargo.toml @@ -2,15 +2,16 @@ name = "cut" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_cut" path = "cut.rs" [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "cut" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/cut/buffer.rs b/src/cut/buffer.rs index 733244a54a4..54003f2748b 100644 --- a/src/cut/buffer.rs +++ b/src/cut/buffer.rs @@ -10,8 +10,8 @@ * file that was distributed with this source code. */ -use std::io::{BufRead, BufReader, Read, Write}; use std::io::Result as IoResult; +use std::io::{BufRead, BufReader, Read, Write}; #[allow(non_snake_case)] pub mod Bytes { diff --git a/src/cut/cut.rs b/src/cut/cut.rs index 85b6b89ff2e..5578713e012 100644 --- a/src/cut/cut.rs +++ b/src/cut/cut.rs @@ -203,6 +203,7 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { 0 } +#[allow(clippy::cognitive_complexity)] fn cut_fields_delimiter( reader: R, ranges: &[Range], @@ -288,6 +289,7 @@ fn cut_fields_delimiter( 0 } +#[allow(clippy::cognitive_complexity)] fn cut_fields(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32 { let newline_char = if opts.zero_terminated { b'\0' } else { b'\n' }; if let Some(ref o_delim) = opts.out_delimeter { @@ -464,8 +466,8 @@ pub fn uumain(args: Vec) -> i32 { ) }) } - (None, None, Some(field_ranges)) => list_to_ranges(&field_ranges[..], complement) - .and_then(|ranges| { + (None, None, Some(field_ranges)) => { + list_to_ranges(&field_ranges[..], complement).and_then(|ranges| { let out_delim = match matches.opt_str("output-delimiter") { Some(s) => { if s.is_empty() { @@ -488,7 +490,7 @@ pub fn uumain(args: Vec) -> i32 { "a value 2 characters or longer", "--delimiter", "-d" - ).to_owned()) + )) } else { let delim = if delim.is_empty() { "\0".to_owned() @@ -517,27 +519,30 @@ pub fn uumain(args: Vec) -> i32 { }, )), } - }), + }) + } (ref b, ref c, ref f) if b.is_some() || c.is_some() || f.is_some() => Err( - msg_expects_no_more_than_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)") - .to_owned(), + msg_expects_no_more_than_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)"), ), - _ => Err(msg_expects_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)").to_owned()), + _ => Err(msg_expects_one_of!( + "--fields (-f)", + "--chars (-c)", + "--bytes (-b)" + )), }; let mode_parse = match mode_parse { Err(_) => mode_parse, Ok(mode) => match mode { Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("delimiter") => Err( - msg_opt_only_usable_if!("printing a sequence of fields", "--delimiter", "-d") - .to_owned(), + msg_opt_only_usable_if!("printing a sequence of fields", "--delimiter", "-d"), ), Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("only-delimited") => { Err(msg_opt_only_usable_if!( "printing a sequence of fields", "--only-delimited", "-s" - ).to_owned()) + )) } _ => Ok(mode), }, diff --git a/src/cut/ranges.rs b/src/cut/ranges.rs index 44edcb9434e..85b20fe38f6 100644 --- a/src/cut/ranges.rs +++ b/src/cut/ranges.rs @@ -42,10 +42,7 @@ impl FromStr for Range { (Some(n), Some(m)) if m.is_empty() => { if let Ok(low) = n.parse::() { if low > 0 { - Ok(Range { - low, - high: MAX - 1, - }) + Ok(Range { low, high: MAX - 1 }) } else { Err(field) } @@ -53,7 +50,7 @@ impl FromStr for Range { Err(inval) } } - (Some(n), Some(m)) if n.len() == 0 => { + (Some(n), Some(m)) if n.is_empty() => { if let Ok(high) = m.parse::() { if high > 0 { Ok(Range { low: 1, high }) @@ -67,10 +64,7 @@ impl FromStr for Range { (Some(n), Some(m)) => match (n.parse::(), m.parse::()) { (Ok(low), Ok(high)) => { if low > 0 && low <= high { - Ok(Range { - low, - high, - }) + Ok(Range { low, high }) } else if low == 0 { Err(field) } else { diff --git a/src/date/Cargo.toml b/src/date/Cargo.toml index 29b66ded3da..5b5fe81047a 100644 --- a/src/date/Cargo.toml +++ b/src/date/Cargo.toml @@ -2,7 +2,8 @@ name = "date" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_date" @@ -11,8 +12,8 @@ path = "date.rs" [dependencies] chrono = "0.4.4" clap = "2.32.0" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "date" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/date/date.rs b/src/date/date.rs index f07a5e756ee..adb9726a853 100644 --- a/src/date/date.rs +++ b/src/date/date.rs @@ -14,8 +14,8 @@ extern crate chrono; extern crate clap; extern crate uucore; -use chrono::{DateTime, FixedOffset, Local, Offset}; use chrono::offset::Utc; +use chrono::{DateTime, FixedOffset, Local, Offset}; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::PathBuf; @@ -210,12 +210,11 @@ fn parse_cli(args: Vec) -> Settings { "set time described by STRING") (@arg utc: -u --utc --universal "print or set Coordinated Universal Time (UTC)")) - // TODO: Decide whether this is appropriate. // The GNU date command has an explanation of all formatting options, // but the `chrono` crate has a few differences (most notably, the %Z option) // (after_help: include_str!("usage.txt"))) - .get_matches_from(args); + .get_matches_from(args); let format = if let Some(form) = matches.value_of("custom_format") { let form = form[1..].into(); diff --git a/src/dircolors/Cargo.toml b/src/dircolors/Cargo.toml index f80e8c941bd..58d618f7976 100644 --- a/src/dircolors/Cargo.toml +++ b/src/dircolors/Cargo.toml @@ -2,7 +2,8 @@ name = "dircolors" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_dircolors" @@ -10,8 +11,8 @@ path = "dircolors.rs" [dependencies] glob = "0.3.0" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "dircolors" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/dircolors/colors.rs b/src/dircolors/colors.rs index c19920508f0..e9cea624fcd 100644 --- a/src/dircolors/colors.rs +++ b/src/dircolors/colors.rs @@ -1,5 +1,4 @@ -pub const INTERNAL_DB: &str = - r#"# Configuration file for dircolors, a utility to help you set the +pub const INTERNAL_DB: &str = r#"# Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. # Copyright (C) 1996-2016 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, diff --git a/src/dircolors/dircolors.rs b/src/dircolors/dircolors.rs index 864438500b4..2a485e1da9e 100644 --- a/src/dircolors/dircolors.rs +++ b/src/dircolors/dircolors.rs @@ -13,10 +13,10 @@ extern crate glob; #[macro_use] extern crate uucore; -use std::fs::File; -use std::io::{BufRead, BufReader}; use std::borrow::Borrow; use std::env; +use std::fs::File; +use std::io::{BufRead, BufReader}; static SYNTAX: &str = "[OPTION]... [FILE]"; static SUMMARY: &str = "Output commands to set the LS_COLORS environment variable."; @@ -68,8 +68,11 @@ pub fn uumain(args: Vec) -> i32 { .optflag("p", "print-database", "print the byte counts") .parse(args); - if (matches.opt_present("csh") || matches.opt_present("c-shell") || matches.opt_present("sh") - || matches.opt_present("bourne-shell")) && matches.opt_present("print-database") + if (matches.opt_present("csh") + || matches.opt_present("c-shell") + || matches.opt_present("sh") + || matches.opt_present("bourne-shell")) + && matches.opt_present("print-database") { disp_err!( "the options to output dircolors' internal database and\nto select a shell \ @@ -120,7 +123,7 @@ pub fn uumain(args: Vec) -> i32 { Ok(f) => { let fin = BufReader::new(f); result = parse( - fin.lines().filter_map(|l| l.ok()), + fin.lines().filter_map(Result::ok), out_format, matches.free[0].as_str(), ) @@ -291,7 +294,7 @@ where } else if key.starts_with('*') { result.push_str(format!("{}={}:", key, val).as_str()); } else if lower == "options" || lower == "color" || lower == "eightbit" { - // Slackware only. Ignore + // Slackware only. Ignore } else if let Some(s) = table.get(lower.as_str()) { result.push_str(format!("{}={}:", s, val).as_str()); } else { diff --git a/src/dirname/Cargo.toml b/src/dirname/Cargo.toml index 746757b48ce..853a4d91adb 100644 --- a/src/dirname/Cargo.toml +++ b/src/dirname/Cargo.toml @@ -2,7 +2,8 @@ name = "dirname" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_dirname" @@ -10,8 +11,8 @@ path = "dirname.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "dirname" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/du/Cargo.toml b/src/du/Cargo.toml index 8bbbfc869f5..51d8a6467f3 100644 --- a/src/du/Cargo.toml +++ b/src/du/Cargo.toml @@ -2,7 +2,8 @@ name = "du" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_du" @@ -10,8 +11,8 @@ path = "du.rs" [dependencies] time = "0.1.40" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "du" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/du/du.rs b/src/du/du.rs index fad2df37199..7b4ff4f0a81 100644 --- a/src/du/du.rs +++ b/src/du/du.rs @@ -163,44 +163,36 @@ fn du( for f in read { match f { - Ok(entry) => { - match Stat::new(entry.path()) { - Ok(this_stat) => { - if this_stat.is_dir { - futures.push(du(this_stat, options, depth + 1, inodes)); - } else { - if inodes.contains(&this_stat.inode) { - continue; - } - inodes.insert(this_stat.inode); - my_stat.size += this_stat.size; - my_stat.blocks += this_stat.blocks; - if options.all { - stats.push(this_stat); - } + Ok(entry) => match Stat::new(entry.path()) { + Ok(this_stat) => { + if this_stat.is_dir { + futures.push(du(this_stat, options, depth + 1, inodes)); + } else { + if inodes.contains(&this_stat.inode) { + continue; + } + inodes.insert(this_stat.inode); + my_stat.size += this_stat.size; + my_stat.blocks += this_stat.blocks; + if options.all { + stats.push(this_stat); } } - Err(error) => show_error!("{}", error), } - } + Err(error) => show_error!("{}", error), + }, Err(error) => show_error!("{}", error), } } } - stats.extend(futures.into_iter().flat_map(|val| val).rev().filter_map( - |stat| { - if !options.separate_dirs && stat.path.parent().unwrap() == my_stat.path { - my_stat.size += stat.size; - my_stat.blocks += stat.blocks; - } - if options.max_depth == None || depth < options.max_depth.unwrap() { - Some(stat) - } else { - None - } - }, - )); + stats.extend(futures.into_iter().flatten().rev().filter(|stat| { + if !options.separate_dirs && stat.path.parent().unwrap() == my_stat.path { + my_stat.size += stat.size; + my_stat.blocks += stat.blocks; + } + options.max_depth == None || depth < options.max_depth.unwrap() + })); stats.push(my_stat); Box::new(stats.into_iter()) } @@ -216,7 +208,7 @@ fn convert_size_human(size: u64, multiplier: u64, _block_size: u64) -> String { } fn convert_size_b(size: u64, _multiplier: u64, _block_size: u64) -> String { - format!("{}", ((size as f64) / (1 as f64)).ceil()) + format!("{}", ((size as f64) / (1_f64)).ceil()) } fn convert_size_k(size: u64, multiplier: u64, _block_size: u64) -> String { @@ -224,13 +216,17 @@ fn convert_size_k(size: u64, multiplier: u64, _block_size: u64) -> String { } fn convert_size_m(size: u64, multiplier: u64, _block_size: u64) -> String { - format!("{}", ((size as f64) / ((multiplier * multiplier) as f64)).ceil()) + format!( + "{}", + ((size as f64) / ((multiplier * multiplier) as f64)).ceil() + ) } fn convert_size_other(size: u64, _multiplier: u64, block_size: u64) -> String { format!("{}", ((size as f64) / (block_size as f64)).ceil()) } +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: Vec) -> i32 { let syntax = format!( "[OPTION]... [FILE]... @@ -238,66 +234,109 @@ pub fn uumain(args: Vec) -> i32 { NAME ); let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP) - // In task - .optflag("a", "all", " write counts for all files, not just directories") - // In main - .optflag("", "apparent-size", "print apparent sizes, rather than disk usage + // In task + .optflag( + "a", + "all", + " write counts for all files, not just directories", + ) + // In main + .optflag( + "", + "apparent-size", + "print apparent sizes, rather than disk usage although the apparent size is usually smaller, it may be larger due to holes - in ('sparse') files, internal fragmentation, indirect blocks, and the like") - // In main - .optopt("B", "block-size", "scale sizes by SIZE before printing them. + in ('sparse') files, internal fragmentation, indirect blocks, and the like", + ) + // In main + .optopt( + "B", + "block-size", + "scale sizes by SIZE before printing them. E.g., '-BM' prints sizes in units of 1,048,576 bytes. See SIZE format below.", - "SIZE") - // In main - .optflag("b", "bytes", "equivalent to '--apparent-size --block-size=1'") - // In main + "SIZE", + ) + // In main + .optflag( + "b", + "bytes", + "equivalent to '--apparent-size --block-size=1'", + ) + // In main .optflag("c", "total", "produce a grand total") - // In task - // opts.optflag("D", "dereference-args", "dereference only symlinks that are listed - // on the command line"), - // In main - // opts.optopt("", "files0-from", "summarize disk usage of the NUL-terminated file - // names specified in file F; - // If F is - then read names from standard input", "F"), - // // In task - // opts.optflag("H", "", "equivalent to --dereference-args (-D)"), - // In main - .optflag("h", "human-readable", "print sizes in human readable format (e.g., 1K 234M 2G)") - // In main + // In task + // opts.optflag("D", "dereference-args", "dereference only symlinks that are listed + // on the command line"), + // In main + // opts.optopt("", "files0-from", "summarize disk usage of the NUL-terminated file + // names specified in file F; + // If F is - then read names from standard input", "F"), + // // In task + // opts.optflag("H", "", "equivalent to --dereference-args (-D)"), + // In main + .optflag( + "h", + "human-readable", + "print sizes in human readable format (e.g., 1K 234M 2G)", + ) + // In main .optflag("", "si", "like -h, but use powers of 1000 not 1024") - // In main + // In main .optflag("k", "", "like --block-size=1K") - // In task + // In task .optflag("l", "count-links", "count sizes many times if hard linked") - // // In main + // // In main .optflag("m", "", "like --block-size=1M") - // // In task - // opts.optflag("L", "dereference", "dereference all symbolic links"), - // // In task - // opts.optflag("P", "no-dereference", "don't follow any symbolic links (this is the default)"), - // // In main - .optflag("0", "null", "end each output line with 0 byte rather than newline") - // In main - .optflag("S", "separate-dirs", "do not include size of subdirectories") - // In main + // // In task + // opts.optflag("L", "dereference", "dereference all symbolic links"), + // // In task + // opts.optflag("P", "no-dereference", "don't follow any symbolic links (this is the default)"), + // // In main + .optflag( + "0", + "null", + "end each output line with 0 byte rather than newline", + ) + // In main + .optflag( + "S", + "separate-dirs", + "do not include size of subdirectories", + ) + // In main .optflag("s", "summarize", "display only a total for each argument") - // // In task - // opts.optflag("x", "one-file-system", "skip directories on different file systems"), - // // In task - // opts.optopt("X", "exclude-from", "exclude files that match any pattern in FILE", "FILE"), - // // In task - // opts.optopt("", "exclude", "exclude files that match PATTERN", "PATTERN"), - // In main - .optopt("d", "max-depth", "print the total for a directory (or file, with --all) + // // In task + // opts.optflag("x", "one-file-system", "skip directories on different file systems"), + // // In task + // opts.optopt("X", "exclude-from", "exclude files that match any pattern in FILE", "FILE"), + // // In task + // opts.optopt("", "exclude", "exclude files that match PATTERN", "PATTERN"), + // In main + .optopt( + "d", + "max-depth", + "print the total for a directory (or file, with --all) only if it is N or fewer levels below the command - line argument; --max-depth=0 is the same as --summarize", "N") - // In main - .optflagopt("", "time", "show time of the last modification of any file in the + line argument; --max-depth=0 is the same as --summarize", + "N", + ) + // In main + .optflagopt( + "", + "time", + "show time of the last modification of any file in the directory, or any of its subdirectories. If WORD is given, show time as WORD instead - of modification time: atime, access, use, ctime or status", "WORD") - // In main - .optopt("", "time-style", "show times using style STYLE: - full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'", "STYLE") + of modification time: atime, access, use, ctime or status", + "WORD", + ) + // In main + .optopt( + "", + "time-style", + "show times using style STYLE: + full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'", + "STYLE", + ) .parse(args); let summarize = matches.opt_present("summarize"); @@ -339,7 +378,7 @@ pub fn uumain(args: Vec) -> i32 { }; let convert_size_fn = { if matches.opt_present("human-readable") || matches.opt_present("si") { - convert_size_human + convert_size_human } else if matches.opt_present("b") { convert_size_b } else if matches.opt_present("k") { @@ -353,26 +392,24 @@ pub fn uumain(args: Vec) -> i32 { let convert_size = |size| convert_size_fn(size, multiplier, block_size); let time_format_str = match matches.opt_str("time-style") { - Some(s) => { - match &s[..] { - "full-iso" => "%Y-%m-%d %H:%M:%S.%f %z", - "long-iso" => "%Y-%m-%d %H:%M", - "iso" => "%Y-%m-%d", - _ => { - show_error!( - "invalid argument '{}' for 'time style' + Some(s) => match &s[..] { + "full-iso" => "%Y-%m-%d %H:%M:%S.%f %z", + "long-iso" => "%Y-%m-%d %H:%M", + "iso" => "%Y-%m-%d", + _ => { + show_error!( + "invalid argument '{}' for 'time style' Valid arguments are: - 'full-iso' - 'long-iso' - 'iso' Try '{} --help' for more information.", - s, - NAME - ); - return 1; - } + s, + NAME + ); + return 1; } - } + }, None => "%Y-%m-%d %H:%M", }; @@ -389,9 +426,7 @@ Try '{} --help' for more information.", let (_, len) = iter.size_hint(); let len = len.unwrap(); for (index, stat) in iter.enumerate() { - let size = if matches.opt_present("apparent-size") { - stat.size - } else if matches.opt_present("b") { + let size = if matches.opt_present("apparent-size") || matches.opt_present("b") { stat.size } else { // C's stat is such that each block is assume to be 512 bytes @@ -402,23 +437,21 @@ Try '{} --help' for more information.", let tm = { let (secs, nsecs) = { let time = match matches.opt_str("time") { - Some(s) => { - match &s[..] { - "accessed" => stat.accessed, - "created" => stat.created, - "modified" => stat.modified, - _ => { - show_error!( - "invalid argument 'modified' for '--time' + Some(s) => match &s[..] { + "accessed" => stat.accessed, + "created" => stat.created, + "modified" => stat.modified, + _ => { + show_error!( + "invalid argument 'modified' for '--time' Valid arguments are: - 'accessed', 'created', 'modified' Try '{} --help' for more information.", - NAME - ); - return 1; - } + NAME + ); + return 1; } - } + }, None => stat.modified, }; ((time / 1000) as i64, (time % 1000 * 1_000_000) as i32) diff --git a/src/echo/Cargo.toml b/src/echo/Cargo.toml index 2c63c342727..2144f8ba590 100644 --- a/src/echo/Cargo.toml +++ b/src/echo/Cargo.toml @@ -2,15 +2,16 @@ name = "echo" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_echo" path = "echo.rs" [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "echo" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/echo/echo.rs b/src/echo/echo.rs index 1178652e1a2..28b5a91f9c7 100644 --- a/src/echo/echo.rs +++ b/src/echo/echo.rs @@ -43,7 +43,7 @@ fn parse_code( max_digits: u32, bits_per_digit: u32, ) -> Option { - let mut ret = 0x80000000; + let mut ret = 0x8000_0000; for _ in 0..max_digits { match input.peek().and_then(|c| c.to_digit(base)) { Some(n) => ret = (ret << bits_per_digit) | n, @@ -71,8 +71,8 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result { 'b' => '\x08', 'c' => { should_stop = true; - break - }, + break; + } 'e' => '\x1b', 'f' => '\x0c', 'n' => '\n', @@ -90,7 +90,7 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result { _ => { start = 0; next - }, + } }; } } @@ -110,7 +110,11 @@ pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, HELP) .optflag("n", "", "do not output the trailing newline") .optflag("e", "", "enable interpretation of backslash escapes") - .optflag("E", "", "disable interpretation of backslash escapes (default)") + .optflag( + "E", + "", + "disable interpretation of backslash escapes (default)", + ) .parse(args); let no_newline = matches.opt_present("n"); diff --git a/src/env/Cargo.toml b/src/env/Cargo.toml index 5f8527b24d8..e0e5d336fa1 100644 --- a/src/env/Cargo.toml +++ b/src/env/Cargo.toml @@ -3,7 +3,8 @@ name = "env" version = "0.0.1" authors = ["uutils developers"] description = "Set each NAME to VALUE in the environment and run COMMAND" -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" edition = "2018" [lib] @@ -13,9 +14,9 @@ path = "env.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = "0.0.1" rust-ini = "0.13.0" +uucore = "0.0.2" [[bin]] name = "env" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/env/env.rs b/src/env/env.rs index 1d03137a40f..9b552165f6d 100644 --- a/src/env/env.rs +++ b/src/env/env.rs @@ -18,6 +18,7 @@ use ini::Ini; use std::borrow::Cow; use std::env; use std::io::{self, Write}; +use std::iter::Iterator; use std::process::Command; const USAGE: &str = "env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]"; @@ -89,7 +90,8 @@ fn load_config_file(opts: &mut Options) -> Result<(), i32> { } }; - for (_, prop) in &conf { // ignore all INI section lines (treat them as comments) + for (_, prop) in &conf { + // ignore all INI section lines (treat them as comments) for (key, value) in prop { env::set_var(key, value); } @@ -159,11 +161,11 @@ fn run_env(args: Vec) -> Result<(), i32> { let null = matches.is_present("null"); let files = matches .values_of("file") - .map(|v| v.collect()) + .map(Iterator::collect) .unwrap_or_else(|| Vec::with_capacity(0)); let unsets = matches .values_of("unset") - .map(|v| v.collect()) + .map(Iterator::collect) .unwrap_or_else(|| Vec::with_capacity(0)); let mut opts = Options { diff --git a/src/expand/Cargo.toml b/src/expand/Cargo.toml index ba8f38c5984..c93868399bb 100644 --- a/src/expand/Cargo.toml +++ b/src/expand/Cargo.toml @@ -2,17 +2,18 @@ name = "expand" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_expand" path = "expand.rs" [dependencies] -unicode-width = "0.1.5" getopts = "0.2.18" -uucore = "0.0.1" +unicode-width = "0.1.5" +uucore = "0.0.2" [[bin]] name = "expand" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/expand/expand.rs b/src/expand/expand.rs index b117ecfc322..d0b13f6cf22 100644 --- a/src/expand/expand.rs +++ b/src/expand/expand.rs @@ -45,7 +45,8 @@ fn tabstops_parse(s: String) -> Vec { crash!(1, "{}\n", "tab size cannot be 0"); } - if let (false, _) = nums.iter() + if let (false, _) = nums + .iter() .fold((true, 0), |(acc, last), &n| (acc && last <= n, n)) { crash!(1, "{}\n", "tab sizes must be ascending"); @@ -145,7 +146,7 @@ fn next_tabstop(tabstops: &[usize], col: usize) -> usize { if tabstops.len() == 1 { tabstops[0] - col % tabstops[0] } else { - match tabstops.iter().skip_while(|&&t| t <= col).next() { + match tabstops.iter().find(|&&t| t > col) { Some(t) => t - col, None => 1, } @@ -169,7 +170,7 @@ fn expand(options: Options) { for file in options.files.into_iter() { let mut fh = open(file); - while match fh.read_until('\n' as u8, &mut buf) { + while match fh.read_until(b'\n', &mut buf) { Ok(s) => s > 0, Err(_) => buf.is_empty(), } { diff --git a/src/expr/Cargo.toml b/src/expr/Cargo.toml index 36529665fc4..00609aade52 100644 --- a/src/expr/Cargo.toml +++ b/src/expr/Cargo.toml @@ -2,7 +2,8 @@ name = "expr" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_expr" @@ -11,8 +12,8 @@ path = "expr.rs" [dependencies] libc = "0.2.42" onig = "~4.3.2" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "expr" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/expr/expr.rs b/src/expr/expr.rs index f0e124d428c..a3b61f1fd7d 100644 --- a/src/expr/expr.rs +++ b/src/expr/expr.rs @@ -13,8 +13,8 @@ extern crate onig; #[macro_use] extern crate uucore; -mod tokens; mod syntax_tree; +mod tokens; static NAME: &str = "expr"; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -80,7 +80,7 @@ fn maybe_handle_help_or_version(args: &[String]) -> bool { fn print_help() { //! The following is taken from GNU coreutils' "expr --help" output. - print!( + println!( r#"Usage: expr EXPRESSION or: expr OPTION @@ -131,8 +131,7 @@ Environment variables: * EXPR_DEBUG_TOKENS=1 dump expression's tokens * EXPR_DEBUG_RPN=1 dump expression represented in reverse polish notation * EXPR_DEBUG_SYA_STEP=1 dump each parser step - * EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree -"# + * EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree"# ); } diff --git a/src/expr/syntax_tree.rs b/src/expr/syntax_tree.rs index 66b467bf6ea..914c0ec9c9b 100644 --- a/src/expr/syntax_tree.rs +++ b/src/expr/syntax_tree.rs @@ -12,8 +12,8 @@ //! * https://en.wikipedia.org/wiki/Shunting-yard_algorithm //! -use tokens::Token; use onig::{Regex, RegexOptions, Syntax}; +use tokens::Token; type TokenStack = Vec<(usize, Token)>; pub type OperandsList = Vec>; @@ -68,9 +68,9 @@ impl ASTNode { fn new_node(token_idx: usize, op_type: &str, operands: OperandsList) -> Box { Box::new(ASTNode::Node { - token_idx: token_idx, + token_idx, op_type: op_type.into(), - operands: operands, + operands, }) } fn new_leaf(token_idx: usize, value: &str) -> Box { @@ -85,25 +85,27 @@ impl ASTNode { ASTNode::Node { ref 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_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_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: i64, b: i64| checked_binop(|| a.checked_mul(b), "*"), + &operand_values, ), - "/" => infix_operator_two_ints(|a: i64, b: i64| { + "/" => infix_operator_two_ints( + |a: i64, b: i64| { if b == 0 { Err("division by zero".to_owned()) } else { checked_binop(|| a.checked_div(b), "/") } - }, &operand_values + }, + &operand_values, ), "%" => infix_operator_two_ints( |a: i64, b: i64| { @@ -158,7 +160,7 @@ impl ASTNode { } } pub fn operand_values(&self) -> Result, String> { - if let &ASTNode::Node { ref operands, .. } = self { + if let ASTNode::Node { ref operands, .. } = *self { let mut out = Vec::with_capacity(operands.len()); for operand in operands { match operand.evaluate() { @@ -219,6 +221,7 @@ fn maybe_dump_ast(result: &Result, String>) { } } +#[allow(clippy::ptr_arg)] fn maybe_dump_rpn(rpn: &TokenStack) { use std::env; if let Ok(debug_var) = env::var("EXPR_DEBUG_RPN") { @@ -298,17 +301,29 @@ fn push_token_to_either_stack( op_stack: &mut TokenStack, ) -> Result<(), String> { let result = match *token { - Token::Value { .. } => Ok(out_stack.push((token_idx, token.clone()))), + Token::Value { .. } => { + out_stack.push((token_idx, token.clone())); + Ok(()) + } - Token::InfixOp { .. } => if op_stack.is_empty() { - Ok(op_stack.push((token_idx, token.clone()))) - } else { - push_op_to_stack(token_idx, token, out_stack, op_stack) - }, + Token::InfixOp { .. } => { + if op_stack.is_empty() { + op_stack.push((token_idx, token.clone())); + Ok(()) + } else { + push_op_to_stack(token_idx, token, out_stack, op_stack) + } + } - Token::PrefixOp { .. } => Ok(op_stack.push((token_idx, token.clone()))), + Token::PrefixOp { .. } => { + op_stack.push((token_idx, token.clone())); + Ok(()) + } - Token::ParOpen => Ok(op_stack.push((token_idx, token.clone()))), + Token::ParOpen => { + op_stack.push((token_idx, token.clone())); + Ok(()) + } Token::ParClose => move_till_match_paren(out_stack, op_stack), }; @@ -316,6 +331,7 @@ fn push_token_to_either_stack( result } +#[allow(clippy::ptr_arg)] fn maybe_dump_shunting_yard_step( token_idx: usize, token: &Token, @@ -341,15 +357,18 @@ fn push_op_to_stack( out_stack: &mut TokenStack, op_stack: &mut TokenStack, ) -> Result<(), String> { - if let &Token::InfixOp { + if let Token::InfixOp { precedence: prec, left_assoc: la, .. - } = token + } = *token { loop { match op_stack.last() { - None => return Ok(op_stack.push((token_idx, token.clone()))), + None => { + op_stack.push((token_idx, token.clone())); + return Ok(()); + } Some(&(_, Token::ParOpen)) => { op_stack.push((token_idx, token.clone())); @@ -362,12 +381,14 @@ fn push_op_to_stack( precedence: prev_prec, .. }, - )) => if la && prev_prec >= prec || !la && prev_prec > prec { - out_stack.push(op_stack.pop().unwrap()) - } else { - op_stack.push((token_idx, token.clone())); - return Ok(()); - }, + )) => { + if la && prev_prec >= prec || !la && prev_prec > prec { + out_stack.push(op_stack.pop().unwrap()) + } else { + op_stack.push((token_idx, token.clone())); + return Ok(()); + } + } Some(&(_, Token::PrefixOp { .. })) => { op_stack.push((token_idx, token.clone())); @@ -487,10 +508,7 @@ fn prefix_operator_index(values: &[String]) -> Result { let haystack = &values[0]; let needles = &values[1]; - let mut current_idx = 0; - for ch_h in haystack.chars() { - current_idx += 1; - + for (current_idx, ch_h) in haystack.chars().enumerate() { for ch_n in needles.chars() { if ch_n == ch_h { return Ok(current_idx.to_string()); diff --git a/src/expr/tokens.rs b/src/expr/tokens.rs index 5684b0bed10..5ea6e17eeff 100644 --- a/src/expr/tokens.rs +++ b/src/expr/tokens.rs @@ -58,10 +58,7 @@ impl Token { } fn is_a_number(&self) -> bool { match *self { - Token::Value { ref value, .. } => match value.parse::() { - Ok(_) => true, - Err(_) => false, - }, + Token::Value { ref value, .. } => value.parse::().is_ok(), _ => false, } } @@ -144,12 +141,7 @@ fn maybe_dump_tokens_acc(tokens_acc: &[(usize, Token)]) { } } -fn push_token_if_not_escaped( - acc: &mut Vec<(usize, Token)>, - tok_idx: usize, - token: Token, - s: &str, -) { +fn push_token_if_not_escaped(acc: &mut Vec<(usize, Token)>, tok_idx: usize, token: Token, s: &str) { // Smells heuristics... :( let prev_is_plus = match acc.last() { None => false, diff --git a/src/factor/Cargo.toml b/src/factor/Cargo.toml index e7ba407b510..59dfbc5dbcc 100644 --- a/src/factor/Cargo.toml +++ b/src/factor/Cargo.toml @@ -2,6 +2,7 @@ name = "factor" version = "0.0.1" authors = [] +license = "MIT" [lib] name = "uu_factor" @@ -9,8 +10,8 @@ path = "factor.rs" [dependencies] rand = "0.5" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "factor" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/factor/build.rs b/src/factor/build.rs index 6e336841561..42845ecb7bf 100644 --- a/src/factor/build.rs +++ b/src/factor/build.rs @@ -33,7 +33,7 @@ mod numeric; mod sieve; -#[path = "../../mkmain.rs"] +#[path = "../#common/mkmain.rs"] mod mkmain; // extended Euclid algorithm @@ -80,9 +80,8 @@ fn main() { // By default, we print the multiplicative inverses mod 2^64 of the first 1k primes let n = args() - .skip(1) - .next() - .unwrap_or("1027".to_string()) + .nth(1) + .unwrap_or_else(|| "1027".to_string()) .parse::() .ok() .unwrap_or(1027); @@ -115,7 +114,8 @@ fn main() { file, "\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n", x - ).unwrap(); + ) + .unwrap(); } #[test] @@ -131,12 +131,12 @@ fn test_inverter() { #[test] fn test_generator() { - let prime_10001 = Sieve::primes().skip(10000).next(); - assert_eq!(prime_10001, Some(104743)); + let prime_10001 = Sieve::primes().skip(10_000).next(); + assert_eq!(prime_10001, Some(104_743)); } const MAX_WIDTH: usize = 102; -const PREAMBLE: &'static str = r##"/* +const PREAMBLE: &str = r##"/* * This file is part of the uutils coreutils package. * * (c) kwantam @@ -149,5 +149,6 @@ const PREAMBLE: &'static str = r##"/* // Please do not edit by hand. Instead, modify and // re-run src/factor/gen_tables.rs. -pub const P_INVS_U64: &'static [(u64, u64, u64)] = &[ +#[allow(clippy::unreadable_literal)] +pub const P_INVS_U64: &[(u64, u64, u64)] = &[ "##; diff --git a/src/factor/factor.rs b/src/factor/factor.rs index 2f5d5bb2f7f..81f655eb74d 100644 --- a/src/factor/factor.rs +++ b/src/factor/factor.rs @@ -20,12 +20,12 @@ extern crate uucore; use numeric::*; use rand::distributions::{Distribution, Uniform}; -use rand::{SeedableRng, thread_rng}; use rand::rngs::SmallRng; +use rand::{thread_rng, SeedableRng}; use std::cmp::{max, min}; use std::io::{stdin, BufRead}; -use std::num::Wrapping; use std::mem::swap; +use std::num::Wrapping; mod numeric; @@ -53,6 +53,7 @@ fn gcd(mut a: u64, mut b: u64) -> u64 { } fn rho_pollard_find_divisor(num: u64) -> u64 { + #![allow(clippy::many_single_char_names)] let range = Uniform::new(1, num); let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap(); let mut x = range.sample(&mut rng); @@ -154,7 +155,10 @@ fn print_factors(num: u64) { } fn print_factors_str(num_str: &str) { - if let Err(e) = num_str.parse::().and_then(|x| Ok(print_factors(x))) { + if let Err(e) = num_str.parse::().and_then(|x| { + print_factors(x); + Ok(()) + }) { show_warning!("{}: {}", num_str, e); } } diff --git a/src/factor/numeric.rs b/src/factor/numeric.rs index 0cce6093a8f..474c8061310 100644 --- a/src/factor/numeric.rs +++ b/src/factor/numeric.rs @@ -9,8 +9,8 @@ * that was distributed with this source code. */ -use std::u64::MAX as MAX_U64; use std::num::Wrapping; +use std::u64::MAX as MAX_U64; pub fn big_add(a: u64, b: u64, m: u64) -> u64 { let Wrapping(msb_mod_m) = Wrapping(MAX_U64) - Wrapping(m) + Wrapping(1); @@ -125,7 +125,7 @@ pub fn is_prime(num: u64) -> bool { // These witnesses detect all composites up to at least 2^64. // Discovered by Jim Sinclair, according to http://miller-rabin.appspot.com - let witnesses = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; + let witnesses = [2, 325, 9_375, 28_178, 450_775, 9_780_504, 1_795_265_022]; !witnesses .iter() .any(|&wit| witness(wit % num, exponent, num)) diff --git a/src/factor/sieve.rs b/src/factor/sieve.rs index d0a2711f25c..6ae2cac1b30 100644 --- a/src/factor/sieve.rs +++ b/src/factor/sieve.rs @@ -68,6 +68,7 @@ impl Sieve { #[allow(dead_code)] #[inline] pub fn primes() -> PrimeSieve { + #[allow(clippy::trivially_copy_pass_by_ref)] fn deref(x: &u64) -> u64 { *x } @@ -78,6 +79,7 @@ impl Sieve { #[allow(dead_code)] #[inline] pub fn odd_primes() -> PrimeSieve { + #[allow(clippy::trivially_copy_pass_by_ref)] fn deref(x: &u64) -> u64 { *x } @@ -124,11 +126,11 @@ impl Wheel { /// The increments of a wheel of circumference 210 /// (i.e., a wheel that skips all multiples of 2, 3, 5, 7) -const WHEEL_INCS: &'static [u64] = &[ +const WHEEL_INCS: &[u64] = &[ 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10, ]; -const INIT_PRIMES: &'static [u64] = &[2, 3, 5, 7]; +const INIT_PRIMES: &[u64] = &[2, 3, 5, 7]; /// A min-heap of "infinite lists" of prime multiples, where a list is /// represented as (head, increment). diff --git a/src/false/Cargo.toml b/src/false/Cargo.toml index 9ae60084025..78894a29116 100644 --- a/src/false/Cargo.toml +++ b/src/false/Cargo.toml @@ -2,15 +2,16 @@ name = "false" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_false" path = "false.rs" [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "false" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/fmt/Cargo.toml b/src/fmt/Cargo.toml index ce50a902989..e17bcb70fe1 100644 --- a/src/fmt/Cargo.toml +++ b/src/fmt/Cargo.toml @@ -2,7 +2,8 @@ name = "fmt" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_fmt" @@ -11,8 +12,8 @@ path = "fmt.rs" [dependencies] libc = "0.2.42" unicode-width = "0.1.5" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "fmt" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/fmt/fmt.rs b/src/fmt/fmt.rs index a81ad2cf545..d078d20a23e 100644 --- a/src/fmt/fmt.rs +++ b/src/fmt/fmt.rs @@ -14,12 +14,12 @@ extern crate unicode_width; #[macro_use] extern crate uucore; +use linebreak::break_lines; +use parasplit::ParagraphStream; use std::cmp; -use std::io::{BufReader, BufWriter, Read}; use std::fs::File; use std::io::{stdin, stdout, Write}; -use linebreak::break_lines; -use parasplit::ParagraphStream; +use std::io::{BufReader, BufWriter, Read}; macro_rules! silent_unwrap( ($exp:expr) => ( @@ -57,6 +57,7 @@ pub struct FmtOptions { tabwidth: usize, } +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("c", "crown-margin", "First and second line of paragraph may have different indentations, in which case the first line's indentation is preserved, and each subsequent line's indentation matches the second line.") diff --git a/src/fmt/linebreak.rs b/src/fmt/linebreak.rs index 2bf7b0ef963..7f1097cdc77 100644 --- a/src/fmt/linebreak.rs +++ b/src/fmt/linebreak.rs @@ -7,12 +7,12 @@ * file that was distributed with this source code. */ -use FmtOptions; use parasplit::{ParaWords, Paragraph, WordInfo}; -use std::io::{BufWriter, Stdout, Write}; -use std::i64; use std::cmp; +use std::i64; +use std::io::{BufWriter, Stdout, Write}; use std::mem; +use FmtOptions; struct BreakArgs<'a> { opts: &'a FmtOptions, @@ -58,18 +58,19 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut BufWriter< } }; // print the init, if it exists, and get its length - let p_init_len = w_len + if opts.crown || opts.tagged { - // handle "init" portion - silent_unwrap!(ostream.write_all(para.init_str.as_bytes())); - para.init_len - } else if !para.mail_header { - // for non-(crown, tagged) that's the same as a normal indent - silent_unwrap!(ostream.write_all(p_indent.as_bytes())); - p_indent_len - } else { - // except that mail headers get no indent at all - 0 - }; + let p_init_len = w_len + + if opts.crown || opts.tagged { + // handle "init" portion + silent_unwrap!(ostream.write_all(para.init_str.as_bytes())); + para.init_len + } else if !para.mail_header { + // for non-(crown, tagged) that's the same as a normal indent + silent_unwrap!(ostream.write_all(p_indent.as_bytes())); + p_indent_len + } else { + // except that mail headers get no indent at all + 0 + }; // write first word after writing init silent_unwrap!(ostream.write_all(w.as_bytes())); @@ -218,17 +219,15 @@ fn find_kp_breakpoints<'a, T: Iterator>>( ) -> Vec<(&'a WordInfo<'a>, bool)> { let mut iter = iter.peekable(); // set up the initial null linebreak - let mut linebreaks = vec![ - LineBreak { - prev: 0, - linebreak: None, - break_before: false, - demerits: 0, - prev_rat: 0.0f32, - length: args.init_len, - fresh: false, - }, - ]; + let mut linebreaks = vec![LineBreak { + prev: 0, + linebreak: None, + break_before: false, + demerits: 0, + prev_rat: 0.0f32, + length: args.init_len, + fresh: false, + }]; // this vec holds the current active linebreaks; next_ holds the breaks that will be active for // the next word let active_breaks = &mut vec![0]; @@ -275,7 +274,9 @@ fn find_kp_breakpoints<'a, T: Iterator>>( } // get the new length - let tlen = w.word_nchars + args.compute_width(w, active.length, active.fresh) + slen + let tlen = w.word_nchars + + args.compute_width(w, active.length, active.fresh) + + slen + active.length; // if tlen is longer than args.opts.width, we drop this break from the active list @@ -304,7 +305,8 @@ fn find_kp_breakpoints<'a, T: Iterator>>( // do not even consider adding a line that has too many demerits // also, try to detect overflow by checking signum let total_demerits = new_demerits + active.demerits; - if new_demerits < BAD_INFTY_SQ && total_demerits < ld_new + if new_demerits < BAD_INFTY_SQ + && total_demerits < ld_new && active.demerits.signum() <= new_demerits.signum() { ld_new = total_demerits; diff --git a/src/fmt/parasplit.rs b/src/fmt/parasplit.rs index 499b3b04a63..f3f49e8a14f 100644 --- a/src/fmt/parasplit.rs +++ b/src/fmt/parasplit.rs @@ -7,8 +7,8 @@ * file that was distributed with this source code. */ -use std::iter::Peekable; use std::io::{BufRead, Lines}; +use std::iter::Peekable; use std::slice::Iter; use unicode_width::UnicodeWidthChar; use FileOrStdReader; @@ -72,10 +72,7 @@ pub struct FileLines<'a> { impl<'a> FileLines<'a> { fn new<'b>(opts: &'b FmtOptions, lines: Lines<&'b mut FileOrStdReader>) -> FileLines<'b> { - FileLines { - opts, - lines, - } + FileLines { opts, lines } } // returns true if this line should be formatted @@ -164,24 +161,28 @@ impl<'a> Iterator for FileLines<'a> { // emit a blank line // Err(true) indicates that this was a linebreak, // which is important to know when detecting mail headers - if n.chars().all(|c| c.is_whitespace()) { + if n.chars().all(char::is_whitespace) { return Some(Line::NoFormatLine("".to_owned(), true)); } + let (pmatch, poffset) = self.match_prefix(&n[..]); + // if this line does not match the prefix, // emit the line unprocessed and iterate again - let (pmatch, poffset) = self.match_prefix(&n[..]); if !pmatch { return Some(Line::NoFormatLine(n, false)); - } else if n[poffset + self.opts.prefix.len()..] - .chars() - .all(|c| c.is_whitespace()) + } + + // if the line matches the prefix, but is blank after, + // don't allow lines to be combined through it (that is, + // treat it like a blank line, except that since it's + // not truly blank we will not allow mail headers on the + // following line) + if pmatch + && n[poffset + self.opts.prefix.len()..] + .chars() + .all(char::is_whitespace) { - // if the line matches the prefix, but is blank after, - // don't allow lines to be combined through it (that is, - // treat it like a blank line, except that since it's - // not truly blank we will not allow mail headers on the - // following line) return Some(Line::NoFormatLine(n, false)); } @@ -363,25 +364,31 @@ impl<'a> Iterator for ParagraphStream<'a> { } } else if !second_done { // now we have enough info to handle crown margin and tagged mode + + // in both crown and tagged modes we require that prefix_len is the same if prefix_len != fl.prefix_len || pfxind_end != fl.pfxind_end { - // in both crown and tagged modes we require that prefix_len is the same break; - } else if self.opts.tagged && indent_len - 4 == fl.indent_len + } + + // in tagged mode, indent has to be *different* on following lines + if self.opts.tagged + && indent_len - 4 == fl.indent_len && indent_end == fl.indent_end { - // in tagged mode, indent has to be *different* on following lines break; - } else { - // this is part of the same paragraph, get the indent info from this line - indent_str.clear(); - indent_str.push_str(&fl.line[..fl.indent_end]); - indent_len = fl.indent_len; - indent_end = fl.indent_end; } + + // this is part of the same paragraph, get the indent info from this line + indent_str.clear(); + indent_str.push_str(&fl.line[..fl.indent_end]); + indent_len = fl.indent_len; + indent_end = fl.indent_end; + second_done = true; } else { // detect mismatch - if indent_end != fl.indent_end || pfxind_end != fl.pfxind_end + if indent_end != fl.indent_end + || pfxind_end != fl.pfxind_end || indent_len != fl.indent_len || prefix_len != fl.prefix_len { diff --git a/src/fold/Cargo.toml b/src/fold/Cargo.toml index fb004cc1641..a79465d4b44 100644 --- a/src/fold/Cargo.toml +++ b/src/fold/Cargo.toml @@ -2,15 +2,16 @@ name = "fold" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_fold" path = "fold.rs" [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "fold" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/fold/fold.rs b/src/fold/fold.rs index 7ff9dd16353..20decdb3868 100644 --- a/src/fold/fold.rs +++ b/src/fold/fold.rs @@ -70,9 +70,7 @@ pub fn uumain(args: Vec) -> i32 { fn handle_obsolete(args: &[String]) -> (Vec, Option) { for (i, arg) in args.iter().enumerate() { let slice = &arg; - if slice.starts_with('-') && slice.len() > 1 - && slice.chars().nth(1).unwrap().is_digit(10) - { + if slice.starts_with('-') && slice.len() > 1 && slice.chars().nth(1).unwrap().is_digit(10) { let mut v = args.to_vec(); v.remove(i); return (v, Some(slice[1..].to_owned())); @@ -110,7 +108,7 @@ fn fold_file(mut file: BufReader, bytes: bool, spaces: bool, width: let slice = { let slice = &line[i..i + width]; if spaces && i + width < len { - match slice.rfind(|ch: char| ch.is_whitespace()) { + match slice.rfind(char::is_whitespace) { Some(m) => &slice[..=m], None => slice, } @@ -145,11 +143,13 @@ fn fold_file(mut file: BufReader, bytes: bool, spaces: bool, width: let ncount = routput.chars().fold(0, |out, ch: char| { out + match ch { '\t' => 8, - '\x08' => if out > 0 { - !0 - } else { - 0 - }, + '\x08' => { + if out > 0 { + !0 + } else { + 0 + } + } '\r' => return 0, _ => 1, } diff --git a/src/groups/Cargo.toml b/src/groups/Cargo.toml index 3bef6484eb5..39821c10133 100644 --- a/src/groups/Cargo.toml +++ b/src/groups/Cargo.toml @@ -2,16 +2,16 @@ name = "groups" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_groups" path = "groups.rs" -[dependencies.uucore] -version = "0.0.1" -features = ["entries"] +[dependencies] +uucore = { version = "0.0.2", features = ["entries"] } [[bin]] name = "groups" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/groups/groups.rs b/src/groups/groups.rs index 406429eeae1..d320382d4c9 100644 --- a/src/groups/groups.rs +++ b/src/groups/groups.rs @@ -12,7 +12,7 @@ #[macro_use] extern crate uucore; -use uucore::entries::{get_groups, Locate, Passwd, gid2grp}; +use uucore::entries::{get_groups, gid2grp, Locate, Passwd}; static SYNTAX: &str = "[user]"; static SUMMARY: &str = "display current group names"; diff --git a/src/hashsum/Cargo.toml b/src/hashsum/Cargo.toml index 7b9662435eb..74634d5b2d7 100644 --- a/src/hashsum/Cargo.toml +++ b/src/hashsum/Cargo.toml @@ -2,7 +2,8 @@ name = "hashsum" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_hashsum" @@ -19,8 +20,8 @@ regex-syntax = "0.6.7" sha1 = "0.6.0" sha2 = "0.6.0" sha3 = "0.6.0" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "hashsum" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/hashsum/digest.rs b/src/hashsum/digest.rs index d85403ee68d..d9b885e002b 100644 --- a/src/hashsum/digest.rs +++ b/src/hashsum/digest.rs @@ -71,7 +71,7 @@ impl Digest for sha1::Sha1 { // Implements the Digest trait for sha2 / sha3 algorithms with fixed ouput macro_rules! impl_digest_sha { - ($type: ty, $size: expr) => ( + ($type: ty, $size: expr) => { impl Digest for $type { fn new() -> Self { Self::default() @@ -89,14 +89,16 @@ macro_rules! impl_digest_sha { *self = Self::new(); } - fn output_bits(&self) -> usize { $size } + fn output_bits(&self) -> usize { + $size + } } - ) + }; } // Implements the Digest trait for sha2 / sha3 algorithms with variable ouput macro_rules! impl_digest_shake { - ($type: ty) => ( + ($type: ty) => { impl Digest for $type { fn new() -> Self { Self::default() @@ -114,9 +116,11 @@ macro_rules! impl_digest_shake { *self = Self::new(); } - fn output_bits(&self) -> usize { 0 } + fn output_bits(&self) -> usize { + 0 + } } - ) + }; } impl_digest_sha!(sha2::Sha224, 224); diff --git a/src/hashsum/hashsum.rs b/src/hashsum/hashsum.rs index f32f3e3076c..259f6eb2e53 100644 --- a/src/hashsum/hashsum.rs +++ b/src/hashsum/hashsum.rs @@ -32,6 +32,7 @@ use regex::Regex; use sha1::Sha1; use sha2::{Sha224, Sha256, Sha384, Sha512}; use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; +use std::cmp::Ordering; use std::fs::File; use std::io::{self, stdin, BufRead, BufReader, Read}; use std::path::Path; @@ -48,6 +49,7 @@ fn is_custom_binary(program: &str) -> bool { } } +#[allow(clippy::cognitive_complexity)] fn detect_algo( program: &str, matches: &getopts::Matches, @@ -64,10 +66,26 @@ fn detect_algo( "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), "sha3sum" => match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(224) => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), - Ok(256) => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), - Ok(384) => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), - Ok(512) => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), + Ok(224) => ( + "SHA3-224", + Box::new(Sha3_224::new()) as Box, + 224, + ), + Ok(256) => ( + "SHA3-256", + Box::new(Sha3_256::new()) as Box, + 256, + ), + Ok(384) => ( + "SHA3-384", + Box::new(Sha3_384::new()) as Box, + 384, + ), + Ok(512) => ( + "SHA3-512", + Box::new(Sha3_512::new()) as Box, + 512, + ), Ok(_) => crash!( 1, "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" @@ -76,27 +94,51 @@ fn detect_algo( }, None => crash!(1, "--bits required for SHA3"), }, - "sha3-224sum" => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), - "sha3-256sum" => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), - "sha3-384sum" => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), - "sha3-512sum" => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), + "sha3-224sum" => ( + "SHA3-224", + Box::new(Sha3_224::new()) as Box, + 224, + ), + "sha3-256sum" => ( + "SHA3-256", + Box::new(Sha3_256::new()) as Box, + 256, + ), + "sha3-384sum" => ( + "SHA3-384", + Box::new(Sha3_384::new()) as Box, + 384, + ), + "sha3-512sum" => ( + "SHA3-512", + Box::new(Sha3_512::new()) as Box, + 512, + ), "shake128sum" => match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => ("SHAKE128", Box::new(Shake128::new()) as Box, bits), + Ok(bits) => ( + "SHAKE128", + Box::new(Shake128::new()) as Box, + bits, + ), Err(err) => crash!(1, "{}", err), }, None => crash!(1, "--bits required for SHAKE-128"), }, "shake256sum" => match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => ("SHAKE256", Box::new(Shake256::new()) as Box, bits), + Ok(bits) => ( + "SHAKE256", + Box::new(Shake256::new()) as Box, + bits, + ), Err(err) => crash!(1, "{}", err), }, None => crash!(1, "--bits required for SHAKE-256"), }, _ => { { - let mut set_or_crash = |n, val, bits| -> () { + let mut set_or_crash = |n, val, bits| { if alg.is_some() { crash!(1, "You cannot combine multiple hash algorithms!") }; @@ -318,17 +360,7 @@ pub fn uumain(args: Vec) -> i32 { matches.free }; match hashsum( - name, - algo, - files, - binary, - check, - tag, - status, - quiet, - strict, - warn, - bits, + name, algo, files, binary, check, tag, status, quiet, strict, warn, bits, ) { Ok(()) => return 0, Err(e) => return e, @@ -367,6 +399,8 @@ Compute and check message digests.", print!("{}", opts.usage(&msg)); } +#[allow(clippy::cognitive_complexity)] +#[allow(clippy::too_many_arguments)] fn hashsum( algoname: &str, mut digest: Box, @@ -442,11 +476,12 @@ fn hashsum( let f = safe_unwrap!(File::open(ck_filename)); let mut ckf = BufReader::new(Box::new(f) as Box); let real_sum = safe_unwrap!(digest_reader( - &mut digest, + &mut *digest, &mut ckf, binary_check, output_bits - )).to_ascii_lowercase(); + )) + .to_ascii_lowercase(); if sum == real_sum { if !quiet { println!("{}: OK", ck_filename); @@ -459,7 +494,7 @@ fn hashsum( } } } else { - let sum = safe_unwrap!(digest_reader(&mut digest, &mut file, binary, output_bits)); + let sum = safe_unwrap!(digest_reader(&mut *digest, &mut file, binary, output_bits)); if tag { println!("{} ({}) = {}", algoname, filename, sum); } else { @@ -468,11 +503,11 @@ fn hashsum( } } if !status { - if bad_format == 1 { - show_warning!("{} line is improperly formatted", bad_format); - } else if bad_format > 1 { - show_warning!("{} lines are improperly formatted", bad_format); - } + match bad_format.cmp(&1) { + Ordering::Equal => show_warning!("{} line is improperly formatted", bad_format), + Ordering::Greater => show_warning!("{} lines are improperly formatted", bad_format), + _ => {} + }; if failed > 0 { show_warning!("{} computed checksum did NOT match", failed); } @@ -482,7 +517,7 @@ fn hashsum( } fn digest_reader<'a, T: Read>( - digest: &mut Box, + digest: &mut (dyn Digest + 'a), reader: &mut BufReader, binary: bool, output_bits: usize, diff --git a/src/head/Cargo.toml b/src/head/Cargo.toml index 75d6046088d..9e5dafb30e1 100644 --- a/src/head/Cargo.toml +++ b/src/head/Cargo.toml @@ -2,7 +2,8 @@ name = "head" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_head" @@ -10,8 +11,8 @@ path = "head.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "head" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/head/head.rs b/src/head/head.rs index efc0ab8db54..c9542d1083d 100644 --- a/src/head/head.rs +++ b/src/head/head.rs @@ -14,8 +14,8 @@ #[macro_use] extern crate uucore; -use std::io::{stdin, BufRead, BufReader, Read}; use std::fs::File; +use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; use std::str::from_utf8; @@ -90,12 +90,14 @@ pub fn uumain(args: Vec) -> i32 { } } } - None => if let Some(count) = matches.opt_str("c") { - match count.parse::() { - Ok(m) => settings.mode = FilterMode::Bytes(m), - Err(e) => { - show_error!("invalid byte count '{}': {}", count, e); - return 1; + None => { + if let Some(count) = matches.opt_str("c") { + match count.parse::() { + Ok(m) => settings.mode = FilterMode::Bytes(m), + Err(e) => { + show_error!("invalid byte count '{}': {}", count, e); + return 1; + } } } } @@ -186,12 +188,16 @@ fn obsolete(options: &[String]) -> (Vec, Option) { // TODO: handle errors on read fn head(reader: &mut BufReader, settings: &Settings) -> bool { match settings.mode { - FilterMode::Bytes(count) => for byte in reader.bytes().take(count) { - print!("{}", byte.unwrap() as char); - }, - FilterMode::Lines(count) => for line in reader.lines().take(count) { - println!("{}", line.unwrap()); - }, + FilterMode::Bytes(count) => { + for byte in reader.bytes().take(count) { + print!("{}", byte.unwrap() as char); + } + } + FilterMode::Lines(count) => { + for line in reader.lines().take(count) { + println!("{}", line.unwrap()); + } + } } true } diff --git a/src/hostid/Cargo.toml b/src/hostid/Cargo.toml index 8414c740b2f..17a6ae3c069 100644 --- a/src/hostid/Cargo.toml +++ b/src/hostid/Cargo.toml @@ -2,7 +2,8 @@ name = "hostid" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_hostid" @@ -10,8 +11,8 @@ path = "hostid.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "hostid" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/hostid/hostid.rs b/src/hostid/hostid.rs index 955868aeaf6..c4460b8edf2 100644 --- a/src/hostid/hostid.rs +++ b/src/hostid/hostid.rs @@ -43,6 +43,9 @@ fn hostid() { result = gethostid(); } - result &= 0xffff_ffff; + #[allow(overflowing_literals)] + let mask = 0xffff_ffff; + + result &= mask; println!("{:0>8x}", result); } diff --git a/src/hostname/Cargo.toml b/src/hostname/Cargo.toml index 7b1497245b8..e8640eb99b8 100644 --- a/src/hostname/Cargo.toml +++ b/src/hostname/Cargo.toml @@ -2,18 +2,19 @@ name = "hostname" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_hostname" path = "hostname.rs" [dependencies] +getopts = "0.2" libc = "0.2.42" +uucore = "0.0.2" winapi = { version = "0.3", features = ["sysinfoapi", "winsock2"] } -getopts = "0.2" -uucore = "0.0.1" [[bin]] name = "hostname" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/hostname/hostname.rs b/src/hostname/hostname.rs index d3b8bd92c1e..81e7eb6a8dd 100644 --- a/src/hostname/hostname.rs +++ b/src/hostname/hostname.rs @@ -17,21 +17,21 @@ extern crate winapi; #[macro_use] extern crate uucore; +use getopts::Matches; use std::collections::hash_set::HashSet; -use std::iter::repeat; use std::io; -use std::str; +use std::iter::repeat; use std::net::ToSocketAddrs; -use getopts::Matches; +use std::str; #[cfg(windows)] -use winapi::um::winsock2::{GetHostNameW, WSACleanup, WSAStartup}; -#[cfg(windows)] -use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, SetComputerNameExW}; +use uucore::wide::*; #[cfg(windows)] use winapi::shared::minwindef::MAKEWORD; #[cfg(windows)] -use uucore::wide::*; +use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, SetComputerNameExW}; +#[cfg(windows)] +use winapi::um::winsock2::{GetHostNameW, WSACleanup, WSAStartup}; #[cfg(not(windows))] use libc::gethostname; @@ -43,8 +43,10 @@ const SUMMARY: &str = "Print or set the system's host name."; const LONG_HELP: &str = ""; pub fn uumain(args: Vec) -> i32 { + #![allow(clippy::let_and_return)] #[cfg(windows)] unsafe { + #[allow(deprecated)] let mut data = std::mem::uninitialized(); if WSAStartup(MAKEWORD(2, 2), &mut data as *mut _) != 0 { eprintln!("Failed to start Winsock 2.2"); @@ -61,12 +63,28 @@ pub fn uumain(args: Vec) -> i32 { fn execute(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .optflag("d", "domain", "Display the name of the DNS domain if possible") - .optflag("i", "ip-address", "Display the network address(es) of the host") + .optflag( + "d", + "domain", + "Display the name of the DNS domain if possible", + ) + .optflag( + "i", + "ip-address", + "Display the network address(es) of the host", + ) // TODO: support --long - .optflag("f", "fqdn", "Display the FQDN (Fully Qualified Domain Name) (default)") - .optflag("s", "short", "Display the short hostname (the portion before the first dot) if \ - possible") + .optflag( + "f", + "fqdn", + "Display the FQDN (Fully Qualified Domain Name) (default)", + ) + .optflag( + "s", + "short", + "Display the short hostname (the portion before the first dot) if \ + possible", + ) .parse(args); match matches.free.len() { diff --git a/src/id/Cargo.toml b/src/id/Cargo.toml index f9aef3e3027..ada18752f46 100644 --- a/src/id/Cargo.toml +++ b/src/id/Cargo.toml @@ -2,16 +2,16 @@ name = "id" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_id" path = "id.rs" -[dependencies.uucore] -version = "0.0.1" -features = ["entries", "process"] +[dependencies] +uucore = { version = "0.0.2", features = ["entries", "process"] } [[bin]] name = "id" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/id/id.rs b/src/id/id.rs index 0b87fb5ec79..a32d955a3cb 100644 --- a/src/id/id.rs +++ b/src/id/id.rs @@ -16,28 +16,28 @@ #[macro_use] extern crate uucore; +use std::ffi::CStr; +use uucore::entries::{self, Group, Locate, Passwd}; pub use uucore::libc; use uucore::libc::{getlogin, uid_t}; -use uucore::entries::{self, Group, Locate, Passwd}; use uucore::process::{getegid, geteuid, getgid, getuid}; -use std::ffi::CStr; macro_rules! cstr2cow { - ($v:expr) => ( + ($v:expr) => { unsafe { CStr::from_ptr($v).to_string_lossy() } - ) + }; } #[cfg(not(target_os = "linux"))] mod audit { - pub use std::mem::uninitialized; - use super::libc::{c_int, c_uint, dev_t, pid_t, uid_t, uint64_t}; + use super::libc::{c_int, c_uint, dev_t, pid_t, uid_t}; pub type au_id_t = uid_t; pub type au_asid_t = pid_t; pub type au_event_t = c_uint; pub type au_emod_t = c_uint; pub type au_class_t = c_int; + pub type au_flag_t = u64; #[repr(C)] pub struct au_mask { @@ -58,7 +58,7 @@ mod audit { pub ai_mask: au_mask_t, // Audit masks. pub ai_termid: au_tid_addr_t, // Terminal ID. pub ai_asid: au_asid_t, // Audit session ID. - pub ai_flags: uint64_t, // Audit session flags + pub ai_flags: au_flag_t, // Audit session flags } pub type c_auditinfo_addr_t = c_auditinfo_addr; @@ -67,8 +67,8 @@ mod audit { } } -static SYNTAX: &'static str = "[OPTION]... [USER]"; -static SUMMARY: &'static str = "Print user and group information for the specified USER,\n or (when USER omitted) for the current user."; +static SYNTAX: &str = "[OPTION]... [USER]"; +static SUMMARY: &str = "Print user and group information for the specified USER,\n or (when USER omitted) for the current user."; pub fn uumain(args: Vec) -> i32 { let mut opts = new_coreopts!(SYNTAX, SUMMARY, ""); @@ -117,7 +117,7 @@ pub fn uumain(args: Vec) -> i32 { println!( "{}", if nflag { - entries::gid2grp(id).unwrap_or(id.to_string()) + entries::gid2grp(id).unwrap_or_else(|_| id.to_string()) } else { id.to_string() } @@ -132,7 +132,7 @@ pub fn uumain(args: Vec) -> i32 { println!( "{}", if nflag { - entries::uid2usr(id).unwrap_or(id.to_string()) + entries::uid2usr(id).unwrap_or_else(|_| id.to_string()) } else { id.to_string() } @@ -146,7 +146,7 @@ pub fn uumain(args: Vec) -> i32 { if nflag { possible_pw .map(|p| p.belongs_to()) - .unwrap_or(entries::get_groups().unwrap()) + .unwrap_or_else(|| entries::get_groups().unwrap()) .iter() .map(|&id| entries::gid2grp(id).unwrap()) .collect::>() @@ -154,7 +154,7 @@ pub fn uumain(args: Vec) -> i32 { } else { possible_pw .map(|p| p.belongs_to()) - .unwrap_or(entries::get_groups().unwrap()) + .unwrap_or_else(|| entries::get_groups().unwrap()) .iter() .map(|&id| id.to_string()) .collect::>() @@ -238,7 +238,7 @@ fn pretty(possible_pw: Option) { #[cfg(any(target_os = "macos", target_os = "freebsd"))] fn pline(possible_uid: Option) { - let uid = possible_uid.unwrap_or(getuid()); + let uid = possible_uid.unwrap_or_else(getuid); let pw = Passwd::locate(uid).unwrap(); println!( @@ -258,7 +258,7 @@ fn pline(possible_uid: Option) { #[cfg(target_os = "linux")] fn pline(possible_uid: Option) { - let uid = possible_uid.unwrap_or(getuid()); + let uid = possible_uid.unwrap_or_else(getuid); let pw = Passwd::locate(uid).unwrap(); println!( @@ -278,7 +278,8 @@ fn auditid() {} #[cfg(not(target_os = "linux"))] fn auditid() { - let mut auditinfo: audit::c_auditinfo_addr_t = unsafe { audit::uninitialized() }; + #[allow(deprecated)] + let mut auditinfo: audit::c_auditinfo_addr_t = unsafe { std::mem::uninitialized() }; let address = &mut auditinfo as *mut audit::c_auditinfo_addr_t; if unsafe { audit::getaudit(address) } < 0 { println!("couldn't retrieve information"); diff --git a/src/install/Cargo.toml b/src/install/Cargo.toml index d2f8caac08f..fb93ae8b9f2 100644 --- a/src/install/Cargo.toml +++ b/src/install/Cargo.toml @@ -2,7 +2,8 @@ name = "install" version = "0.0.1" authors = ["Ben Eills "] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_install" @@ -11,11 +12,11 @@ path = "install.rs" [dependencies] getopts = "0.2.18" libc = ">= 0.2" -uucore = "0.0.1" +uucore = "0.0.2" [dev-dependencies] time = "0.1.40" [[bin]] name = "install" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/install/install.rs b/src/install/install.rs index 4d7aeb61184..3e91ae1dbb6 100644 --- a/src/install/install.rs +++ b/src/install/install.rs @@ -74,7 +74,8 @@ pub fn uumain(args: Vec) -> i32 { }; let paths: Vec = { - fn string_to_path<'a>(s: &'a String) -> &'a Path { + #[allow(clippy::ptr_arg)] + fn string_to_path(s: &String) -> &Path { Path::new(s) }; let to_owned = |p: &Path| p.to_owned(); @@ -100,49 +101,115 @@ fn parse_opts(args: Vec) -> getopts::Matches { NAME ); new_coreopts!(&syntax, SUMMARY, LONG_HELP) - // TODO implement flag - .optflagopt("", "backup", "(unimplemented) make a backup of each existing destination\n \ - file", "CONTROL") - // TODO implement flag - .optflag("b", "", "(unimplemented) like --backup but does not accept an argument") + // TODO implement flag + .optflagopt( + "", + "backup", + "(unimplemented) make a backup of each existing destination\n \ + file", + "CONTROL", + ) + // TODO implement flag + .optflag( + "b", + "", + "(unimplemented) like --backup but does not accept an argument", + ) .optflag("c", "", "ignored") - // TODO implement flag - .optflag("C", "compare", "(unimplemented) compare each pair of source and destination\n \ - files, and in some cases, do not modify the destination at all") - .optflag("d", "directory", "treat all arguments as directory names.\n \ - create all components of the specified directories") - // TODO implement flag - .optflag("D", "", "(unimplemented) create all leading components of DEST except the\n \ - last, then copy SOURCE to DEST") - // TODO implement flag - .optflagopt("g", "group", "(unimplemented) set group ownership, instead of process'\n \ - current group", "GROUP") - .optflagopt("m", "mode", "set permission mode (as in chmod), instead\n \ - of rwxr-xr-x", "MODE") - // TODO implement flag - .optflagopt("o", "owner", "(unimplemented) set ownership (super-user only)", - "OWNER") - // TODO implement flag - .optflag("p", "preserve-timestamps", "(unimplemented) apply access/modification times\n \ - of SOURCE files to corresponding destination files") - // TODO implement flag + // TODO implement flag + .optflag( + "C", + "compare", + "(unimplemented) compare each pair of source and destination\n \ + files, and in some cases, do not modify the destination at all", + ) + .optflag( + "d", + "directory", + "treat all arguments as directory names.\n \ + create all components of the specified directories", + ) + // TODO implement flag + .optflag( + "D", + "", + "(unimplemented) create all leading components of DEST except the\n \ + last, then copy SOURCE to DEST", + ) + // TODO implement flag + .optflagopt( + "g", + "group", + "(unimplemented) set group ownership, instead of process'\n \ + current group", + "GROUP", + ) + .optflagopt( + "m", + "mode", + "set permission mode (as in chmod), instead\n \ + of rwxr-xr-x", + "MODE", + ) + // TODO implement flag + .optflagopt( + "o", + "owner", + "(unimplemented) set ownership (super-user only)", + "OWNER", + ) + // TODO implement flag + .optflag( + "p", + "preserve-timestamps", + "(unimplemented) apply access/modification times\n \ + of SOURCE files to corresponding destination files", + ) + // TODO implement flag .optflag("s", "strip", "(unimplemented) strip symbol tables") - // TODO implement flag - .optflagopt("", "strip-program", "(unimplemented) program used to strip binaries", - "PROGRAM") - // TODO implement flag - .optopt("S", "suffix", "(unimplemented) override the usual backup suffix", "SUFFIX") - // TODO implement flag - .optopt("t", "target-directory", "(unimplemented) move all SOURCE arguments into\n \ - DIRECTORY", "DIRECTORY") - // TODO implement flag - .optflag("T", "no-target-directory", "(unimplemented) treat DEST as a normal file") + // TODO implement flag + .optflagopt( + "", + "strip-program", + "(unimplemented) program used to strip binaries", + "PROGRAM", + ) + // TODO implement flag + .optopt( + "S", + "suffix", + "(unimplemented) override the usual backup suffix", + "SUFFIX", + ) + // TODO implement flag + .optopt( + "t", + "target-directory", + "(unimplemented) move all SOURCE arguments into\n \ + DIRECTORY", + "DIRECTORY", + ) + // TODO implement flag + .optflag( + "T", + "no-target-directory", + "(unimplemented) treat DEST as a normal file", + ) .optflag("v", "verbose", "explain what is being done") - // TODO implement flag - .optflag("P", "preserve-context", "(unimplemented) preserve security context") - // TODO implement flag - .optflagopt("Z", "context", "(unimplemented) set security context of files and\n \ - directories", "CONTEXT") + // TODO implement flag + .optflag( + "P", + "preserve-context", + "(unimplemented) preserve security context", + ) + // TODO implement flag + .optflagopt( + "Z", + "context", + "(unimplemented) set security context of files and\n \ + directories", + "CONTEXT", + ) .parse(args) } @@ -244,8 +311,8 @@ fn behaviour(matches: &getopts::Matches) -> Result { }; Ok(Behaviour { - main_function: main_function, - specified_mode: specified_mode, + main_function, + specified_mode, suffix: backup_suffix, verbose: matches.opt_present("v"), }) @@ -259,7 +326,7 @@ fn behaviour(matches: &getopts::Matches) -> Result { /// Returns an integer intended as a program return code. /// fn directory(paths: &[PathBuf], b: Behaviour) -> i32 { - if paths.len() < 1 { + if paths.is_empty() { println!("{} with -d requires at least one argument.", NAME); 1 } else { @@ -297,7 +364,7 @@ fn directory(paths: &[PathBuf], b: Behaviour) -> i32 { /// Test if the path is a a new file path that can be /// created immediately fn is_new_file_path(path: &Path) -> bool { - path.is_file() || !path.exists() && path.parent().map(|p| p.is_dir()).unwrap_or(true) + path.is_file() || !path.exists() && path.parent().map(Path::is_dir).unwrap_or(true) } /// Perform an install, given a list of paths and behaviour. diff --git a/src/install/mode.rs b/src/install/mode.rs index 726b359df99..06f458dc77a 100644 --- a/src/install/mode.rs +++ b/src/install/mode.rs @@ -1,7 +1,7 @@ extern crate libc; -use std::path::Path; use std::fs; +use std::path::Path; #[cfg(not(windows))] use uucore::mode; diff --git a/src/join/Cargo.toml b/src/join/Cargo.toml index 01980d092f0..567d63a7955 100644 --- a/src/join/Cargo.toml +++ b/src/join/Cargo.toml @@ -2,7 +2,8 @@ name = "join" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_join" @@ -10,8 +11,8 @@ path = "join.rs" [dependencies] clap = "2.32.0" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "join" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/join/join.rs b/src/join/join.rs index 9915e51300d..d56269244ae 100755 --- a/src/join/join.rs +++ b/src/join/join.rs @@ -14,10 +14,10 @@ extern crate clap; #[macro_use] extern crate uucore; +use clap::{App, Arg}; +use std::cmp::{min, Ordering}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Lines, Stdin}; -use std::cmp::{min, Ordering}; -use clap::{App, Arg}; static NAME: &str = "join"; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -186,7 +186,7 @@ impl Spec { let file_num = match chars.next() { Some('0') => { // Must be all alone without a field specifier. - if let None = chars.next() { + if chars.next().is_none() { return Spec::Key; } @@ -260,9 +260,9 @@ impl<'a> State<'a> { }; State { - key: key, + key, file_name: name, - file_num: file_num, + file_num, print_unpaired: print_unpaired == file_num, lines: f.lines(), seq: Vec::new(), @@ -294,7 +294,7 @@ impl<'a> State<'a> { } } - return None; + None } /// Print lines in the buffers as headers. @@ -317,9 +317,9 @@ impl<'a> State<'a> { for line1 in &self.seq { for line2 in &other.seq { if repr.uses_format() { - repr.print_format(|spec| match spec { - &Spec::Key => key, - &Spec::Field(file_num, field_num) => { + repr.print_format(|spec| match *spec { + Spec::Key => key, + Spec::Field(file_num, field_num) => { if file_num == self.file_num { return line1.get_field(field_num); } @@ -423,13 +423,15 @@ impl<'a> State<'a> { fn print_line(&self, line: &Line, repr: &Repr) { if repr.uses_format() { - repr.print_format(|spec| match spec { - &Spec::Key => line.get_field(self.key), - &Spec::Field(file_num, field_num) => if file_num == self.file_num { - line.get_field(field_num) - } else { - None - }, + repr.print_format(|spec| match *spec { + Spec::Key => line.get_field(self.key), + Spec::Field(file_num, field_num) => { + if file_num == self.file_num { + line.get_field(field_num) + } else { + None + } + } }); } else { repr.print_field(line.get_field(self.key)); @@ -567,7 +569,7 @@ FILENUM is 1 or 2, corresponding to FILE1 or FILE2", if let Some(value) = matches.value_of("t") { settings.separator = match value.len() { 0 => Sep::Line, - 1 => Sep::Char(value.chars().nth(0).unwrap()), + 1 => Sep::Char(value.chars().next().unwrap()), _ => crash!(1, "multi-character tab {}", value), }; } diff --git a/src/kill/Cargo.toml b/src/kill/Cargo.toml index 1b1ebda7b18..c9dc99cac53 100644 --- a/src/kill/Cargo.toml +++ b/src/kill/Cargo.toml @@ -2,7 +2,8 @@ name = "kill" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_kill" @@ -10,11 +11,8 @@ path = "kill.rs" [dependencies] libc = "0.2.42" - -[dependencies.uucore] -version = "0.0.1" -features = ["signals"] +uucore = { version = "0.0.2", features = ["signals"] } [[bin]] name = "kill" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/kill/kill.rs b/src/kill/kill.rs index 739efb8df8a..f38fbc0fb9a 100644 --- a/src/kill/kill.rs +++ b/src/kill/kill.rs @@ -58,7 +58,7 @@ pub fn uumain(args: Vec) -> i32 { return kill( &matches .opt_str("signal") - .unwrap_or(obs_signal.unwrap_or("9".to_owned())), + .unwrap_or_else(|| obs_signal.unwrap_or_else(|| "9".to_owned())), matches.free, ) } @@ -74,9 +74,7 @@ fn handle_obsolete(mut args: Vec) -> (Vec, Option) { while i < args.len() { // this is safe because slice is valid when it is referenced let slice = &args[i].clone(); - if slice.chars().next().unwrap() == '-' && slice.len() > 1 - && slice.chars().nth(1).unwrap().is_digit(10) - { + if slice.starts_with('-') && slice.len() > 1 && slice.chars().nth(1).unwrap().is_digit(10) { let val = &slice[1..]; match val.parse() { Ok(num) => { @@ -107,7 +105,7 @@ fn table() { //TODO: obtain max signal width here if (idx + 1) % 7 == 0 { - println!(""); + println!(); } } } @@ -133,7 +131,7 @@ fn print_signals() { pos += signal.name.len(); print!("{}", signal.name); if idx > 0 && pos > 73 { - println!(""); + println!(); pos = 0; } else { pos += 1; diff --git a/src/link/Cargo.toml b/src/link/Cargo.toml index ff523cfdcd7..7da8cc27129 100644 --- a/src/link/Cargo.toml +++ b/src/link/Cargo.toml @@ -2,7 +2,8 @@ name = "link" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_link" @@ -10,8 +11,8 @@ path = "link.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "link" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/link/link.rs b/src/link/link.rs index 4ff654f4be8..ae5993d52d4 100644 --- a/src/link/link.rs +++ b/src/link/link.rs @@ -13,8 +13,8 @@ extern crate uucore; use std::fs::hard_link; -use std::path::Path; use std::io::Error; +use std::path::Path; static SYNTAX: &str = "[OPTIONS] FILE1 FILE2"; static SUMMARY: &str = "Create a link named FILE2 to FILE1"; diff --git a/src/ln/Cargo.toml b/src/ln/Cargo.toml index c9fe57a13a4..49f164afab3 100644 --- a/src/ln/Cargo.toml +++ b/src/ln/Cargo.toml @@ -2,7 +2,8 @@ name = "ln" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_ln" @@ -10,8 +11,8 @@ path = "ln.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "ln" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/ln/ln.rs b/src/ln/ln.rs index 263c4de10af..4aabc758c44 100644 --- a/src/ln/ln.rs +++ b/src/ln/ln.rs @@ -67,24 +67,45 @@ pub fn uumain(args: Vec) -> i32 { NAME ); let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP) - .optflag("b", "", "make a backup of each file that would otherwise be overwritten or \ - removed") - .optflagopt("", "backup", "make a backup of each file that would otherwise be overwritten \ - or removed", "METHOD") - // TODO: opts.optflag("d", "directory", "allow users with appropriate privileges to attempt \ - // to make hard links to directories"); + .optflag( + "b", + "", + "make a backup of each file that would otherwise be overwritten or \ + removed", + ) + .optflagopt( + "", + "backup", + "make a backup of each file that would otherwise be overwritten \ + or removed", + "METHOD", + ) + // TODO: opts.optflag("d", "directory", "allow users with appropriate privileges to attempt \ + // to make hard links to directories"); .optflag("f", "force", "remove existing destination files") - .optflag("i", "interactive", "prompt whether to remove existing destination files") - // TODO: opts.optflag("L", "logical", "dereference TARGETs that are symbolic links"); - // TODO: opts.optflag("n", "no-dereference", "treat LINK_NAME as a normal file if it is a \ - // symbolic link to a directory"); - // TODO: opts.optflag("P", "physical", "make hard links directly to symbolic links"); - // TODO: opts.optflag("r", "relative", "create symbolic links relative to link location"); + .optflag( + "i", + "interactive", + "prompt whether to remove existing destination files", + ) + // TODO: opts.optflag("L", "logical", "dereference TARGETs that are symbolic links"); + // TODO: opts.optflag("n", "no-dereference", "treat LINK_NAME as a normal file if it is a \ + // symbolic link to a directory"); + // TODO: opts.optflag("P", "physical", "make hard links directly to symbolic links"); + // TODO: opts.optflag("r", "relative", "create symbolic links relative to link location"); .optflag("s", "symbolic", "make symbolic links instead of hard links") .optopt("S", "suffix", "override the usual backup suffix", "SUFFIX") - .optopt("t", "target-directory", "specify the DIRECTORY in which to create the links", - "DIRECTORY") - .optflag("T", "no-target-directory", "treat LINK_NAME as a normal file always") + .optopt( + "t", + "target-directory", + "specify the DIRECTORY in which to create the links", + "DIRECTORY", + ) + .optflag( + "T", + "no-target-directory", + "treat LINK_NAME as a normal file always", + ) .optflag("v", "verbose", "print name of each linked file") .parse(args); @@ -159,7 +180,7 @@ pub fn uumain(args: Vec) -> i32 { } fn exec(files: &[PathBuf], settings: &Settings) -> i32 { - if files.len() == 0 { + if files.is_empty() { show_error!( "missing file operand\nTry '{} --help' for more information.", NAME @@ -201,7 +222,7 @@ fn exec(files: &[PathBuf], settings: &Settings) -> i32 { ); return 1; } - assert!(files.len() != 0); + assert!(!files.is_empty()); match link(&files[0], &files[1], settings) { Ok(_) => 0, @@ -295,7 +316,7 @@ fn link(src: &PathBuf, dst: &PathBuf, settings: &Settings) -> Result<()> { print!("'{}' -> '{}'", dst.display(), src.display()); match backup_path { Some(path) => println!(" (backup: '{}')", path.display()), - None => println!(""), + None => println!(), } } Ok(()) @@ -304,7 +325,7 @@ fn link(src: &PathBuf, dst: &PathBuf, settings: &Settings) -> Result<()> { fn read_yes() -> bool { let mut s = String::new(); match stdin().read_line(&mut s) { - Ok(_) => match s.char_indices().nth(0) { + Ok(_) => match s.char_indices().next() { Some((_, x)) => x == 'y' || x == 'Y', _ => false, }, diff --git a/src/logname/Cargo.toml b/src/logname/Cargo.toml index f81e10fa30c..f8a72f5f5e5 100644 --- a/src/logname/Cargo.toml +++ b/src/logname/Cargo.toml @@ -2,7 +2,8 @@ name = "logname" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_logname" @@ -10,8 +11,8 @@ path = "logname.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "logname" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/ls/Cargo.toml b/src/ls/Cargo.toml index 37bb85a8388..3fd35204489 100644 --- a/src/ls/Cargo.toml +++ b/src/ls/Cargo.toml @@ -2,7 +2,8 @@ name = "ls" version = "0.0.1" authors = ["Jeremiah Peschka "] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_ls" @@ -11,17 +12,14 @@ path = "ls.rs" [dependencies] getopts = "0.2.18" isatty = "0.1" +lazy_static = "1.0.1" number_prefix = "0.2.8" term_grid = "0.1.5" termsize = "0.1.6" time = "0.1.40" -lazy_static = "1.0.1" unicode-width = "0.1.5" - -[dependencies.uucore] -version = "0.0.1" -features = ["entries", "fs"] +uucore = { version = "0.0.2", features = ["entries", "fs"] } [[bin]] name = "ls" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/ls/ls.rs b/src/ls/ls.rs index 1d9de943c86..d429dd2d3c9 100644 --- a/src/ls/ls.rs +++ b/src/ls/ls.rs @@ -9,43 +9,41 @@ // extern crate getopts; +#[cfg(unix)] +extern crate isatty; +extern crate number_prefix; extern crate term_grid; extern crate termsize; extern crate time; extern crate unicode_width; -extern crate number_prefix; -extern crate isatty; -use isatty::stdout_isatty; -use number_prefix::{Standalone, Prefixed, decimal_prefix}; -use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; -use time::{strftime, Timespec}; #[cfg(unix)] #[macro_use] extern crate lazy_static; - #[macro_use] extern crate uucore; -#[cfg(unix)] -use uucore::libc::{mode_t, S_ISGID, S_ISUID, S_ISVTX, S_IWOTH, - S_IXGRP, S_IXOTH, S_IXUSR}; -use std::fs; -use std::fs::{DirEntry, FileType, Metadata}; -use std::path::{Path, PathBuf}; +#[cfg(unix)] +use isatty::stdout_isatty; +use number_prefix::{decimal_prefix, Prefixed, Standalone}; use std::cmp::Reverse; #[cfg(unix)] use std::collections::HashMap; - -#[cfg(any(unix, target_os = "redox"))] -use std::os::unix::fs::MetadataExt; +use std::fs; +use std::fs::{DirEntry, FileType, Metadata}; #[cfg(unix)] use std::os::unix::fs::FileTypeExt; -#[cfg(unix)] -use unicode_width::UnicodeWidthStr; - +#[cfg(any(unix, target_os = "redox"))] +use std::os::unix::fs::MetadataExt; #[cfg(windows)] use std::os::windows::fs::MetadataExt; +use std::path::{Path, PathBuf}; +use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; +use time::{strftime, Timespec}; +#[cfg(unix)] +use unicode_width::UnicodeWidthStr; +#[cfg(unix)] +use uucore::libc::{mode_t, S_ISGID, S_ISUID, S_ISVTX, S_IWOTH, S_IXGRP, S_IXOTH, S_IXUSR}; static NAME: &str = "ls"; static SUMMARY: &str = ""; @@ -60,12 +58,13 @@ static DEFAULT_COLORS: &str = "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do #[cfg(unix)] lazy_static! { - static ref LS_COLORS: String = std::env::var("LS_COLORS").unwrap_or(DEFAULT_COLORS.to_string()); + static ref LS_COLORS: String = + std::env::var("LS_COLORS").unwrap_or_else(|_| DEFAULT_COLORS.to_string()); static ref COLOR_MAP: HashMap<&'static str, &'static str> = { - let codes = LS_COLORS.split(":"); + let codes = LS_COLORS.split(':'); let mut map = HashMap::new(); for c in codes { - let p: Vec<_> = c.split("=").collect(); + let p: Vec<_> = c.split('=').collect(); if p.len() == 2 { map.insert(p[0], p[1]); } @@ -160,7 +159,12 @@ pub fn uumain(args: Vec) -> i32 { directory. This is especially useful when listing very large directories, \ since not doing any sorting can be noticeably faster.", ) - .optflagopt("", "color", "Color output based on file type.", "always|auto|never") + .optflagopt( + "", + "color", + "Color output based on file type.", + "always|auto|never", + ) .parse(args); list(matches); @@ -171,7 +175,7 @@ fn list(options: getopts::Matches) { let locs: Vec = if options.free.is_empty() { vec![String::from(".")] } else { - options.free.iter().cloned().collect() + options.free.to_vec() }; let mut files = Vec::::new(); @@ -277,20 +281,17 @@ fn max(lhs: usize, rhs: usize) -> usize { fn should_display(entry: &DirEntry, options: &getopts::Matches) -> bool { let ffi_name = entry.file_name(); let name = ffi_name.to_string_lossy(); - if !options.opt_present("a") && !options.opt_present("A") { - if name.starts_with('.') { - return false; - } + if !options.opt_present("a") && !options.opt_present("A") && name.starts_with('.') { + return false; } if options.opt_present("B") && name.ends_with('~') { return false; } - return true; + true } fn enter_directory(dir: &PathBuf, options: &getopts::Matches) { - let mut entries = - safe_unwrap!(fs::read_dir(dir).and_then(|e| e.collect::, _>>())); + let mut entries: Vec<_> = safe_unwrap!(fs::read_dir(dir).and_then(Iterator::collect)); entries.retain(|e| should_display(e, options)); @@ -316,7 +317,7 @@ fn enter_directory(dir: &PathBuf, options: &getopts::Matches) { fn get_metadata(entry: &PathBuf, options: &getopts::Matches) -> std::io::Result { if options.opt_present("L") { - entry.metadata().or(entry.symlink_metadata()) + entry.metadata().or_else(|_| entry.symlink_metadata()) } else { entry.symlink_metadata() } @@ -336,14 +337,14 @@ fn display_dir_entry_size(entry: &PathBuf, options: &getopts::Matches) -> (usize fn pad_left(string: String, count: usize) -> String { if count > string.len() { let pad = count - string.len(); - let pad = String::from_utf8(vec![' ' as u8; pad]).unwrap(); + let pad = String::from_utf8(vec![b' '; pad]).unwrap(); format!("{}{}", pad, string) } else { string } } -fn display_items(items: &Vec, strip: Option<&Path>, options: &getopts::Matches) { +fn display_items(items: &[PathBuf], strip: Option<&Path>, options: &getopts::Matches) { if options.opt_present("long") || options.opt_present("numeric-uid-gid") { let (mut max_links, mut max_size) = (1, 1); for item in items { @@ -356,19 +357,17 @@ fn display_items(items: &Vec, strip: Option<&Path>, options: &getopts:: } } else { if !options.opt_present("1") { - let names = items - .iter() - .filter_map(|i| { - let md = get_metadata(i, options); - match md { - Err(e) => { - let filename = get_file_name(i, strip); - show_error!("{}: {}", filename, e); - None - } - Ok(md) => Some(display_file_name(&i, strip, &md, options)), + let names = items.iter().filter_map(|i| { + let md = get_metadata(i, options); + match md { + Err(e) => { + let filename = get_file_name(i, strip); + show_error!("{}: {}", filename, e); + None } - }); + Ok(md) => Some(display_file_name(&i, strip, &md, options)), + } + }); if let Some(size) = termsize::get() { let mut grid = Grid::new(GridOptions { @@ -454,7 +453,7 @@ fn display_uname(metadata: &Metadata, options: &getopts::Matches) -> String { if options.opt_present("numeric-uid-gid") { metadata.uid().to_string() } else { - entries::uid2usr(metadata.uid()).unwrap_or(metadata.uid().to_string()) + entries::uid2usr(metadata.uid()).unwrap_or_else(|_| metadata.uid().to_string()) } } @@ -463,7 +462,7 @@ fn display_group(metadata: &Metadata, options: &getopts::Matches) -> String { if options.opt_present("numeric-uid-gid") { metadata.gid().to_string() } else { - entries::gid2grp(metadata.gid()).unwrap_or(metadata.gid().to_string()) + entries::gid2grp(metadata.gid()).unwrap_or_else(|_| metadata.gid().to_string()) } } @@ -511,7 +510,7 @@ fn display_file_size(metadata: &Metadata, options: &getopts::Matches) -> String if options.opt_present("human-readable") { match decimal_prefix(metadata.len() as f64) { Standalone(bytes) => bytes.to_string(), - Prefixed(prefix, bytes) => format!("{:.2}{}", bytes, prefix).to_uppercase() + Prefixed(prefix, bytes) => format!("{:.2}{}", bytes, prefix).to_uppercase(), } } else { metadata.len().to_string() @@ -533,7 +532,7 @@ fn get_file_name(name: &Path, strip: Option<&Path>) -> String { Some(prefix) => name.strip_prefix(prefix).unwrap_or(name), None => name, }; - if name.as_os_str().len() == 0 { + if name.as_os_str().is_empty() { name = Path::new("."); } name.to_string_lossy().into_owned() @@ -595,12 +594,13 @@ fn color_name(name: String, typ: &str) -> String { #[cfg(unix)] macro_rules! has { - ($mode:expr, $perm:expr) => ( + ($mode:expr, $perm:expr) => { $mode & ($perm as mode_t) != 0 - ) + }; } #[cfg(unix)] +#[allow(clippy::cognitive_complexity)] fn display_file_name( path: &Path, strip: Option<&Path>, @@ -618,7 +618,7 @@ fn display_file_name( Some(val) => match val.as_ref() { "always" | "yes" | "force" => true, "auto" | "tty" | "if-tty" => stdout_isatty(), - "never" | "no" | "none" | _ => false, + /* "never" | "no" | "none" | */ _ => false, }, }; let classify = options.opt_present("classify"); @@ -697,7 +697,7 @@ fn display_file_name( Cell { contents: name, - width: width, + width, } } diff --git a/src/mkdir/Cargo.toml b/src/mkdir/Cargo.toml index 9bbabbe4341..a9e6726d407 100644 --- a/src/mkdir/Cargo.toml +++ b/src/mkdir/Cargo.toml @@ -2,7 +2,8 @@ name = "mkdir" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_mkdir" @@ -11,8 +12,8 @@ path = "mkdir.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "mkdir" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/mkdir/mkdir.rs b/src/mkdir/mkdir.rs index c3bc0107e3e..85ab67c4857 100644 --- a/src/mkdir/mkdir.rs +++ b/src/mkdir/mkdir.rs @@ -55,16 +55,15 @@ pub fn uumain(args: Vec) -> i32 { // Translate a ~str in octal form to u16, default to 755 // Not tested on Windows let mode_match = matches.opts_str(&["mode".to_owned()]); - let mode: u16 = if mode_match.is_some() { - let m = mode_match.unwrap(); - let res: Option = u16::from_str_radix(&m, 8).ok(); - if res.is_some() { - res.unwrap() - } else { - crash!(1, "no mode given"); + let mode: u16 = match mode_match { + Some(m) => { + let res: Option = u16::from_str_radix(&m, 8).ok(); + match res { + Some(r) => r, + _ => crash!(1, "no mode given"), + } } - } else { - 0o755 as u16 + _ => 0o755 as u16, }; let dirs = matches.free; @@ -76,7 +75,7 @@ pub fn uumain(args: Vec) -> i32 { fn print_help(opts: &getopts::Options) { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); print!( "{}", @@ -113,7 +112,11 @@ fn exec(dirs: Vec, recursive: bool, mode: u16, verbose: bool) -> i32 { * Wrapper to catch errors, return 1 if failed */ fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> i32 { - let create_dir = if recursive { fs::create_dir_all } else { fs::create_dir }; + let create_dir = if recursive { + fs::create_dir_all + } else { + fs::create_dir + }; if let Err(e) = create_dir(path) { show_info!("{}: {}", path.display(), e.to_string()); return 1; @@ -125,17 +128,13 @@ fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> i32 { #[cfg(any(unix, target_os = "redox"))] fn chmod(path: &Path, mode: u16) -> i32 { - use fs::{Permissions, set_permissions}; - use std::os::unix::fs::{PermissionsExt}; + use fs::{set_permissions, Permissions}; + use std::os::unix::fs::PermissionsExt; - let mode = Permissions::from_mode(mode as u32); + let mode = Permissions::from_mode(u32::from(mode)); if let Err(err) = set_permissions(path, mode) { - show_error!( - "{}: {}", - path.display(), - err - ); + show_error!("{}: {}", path.display(), err); return 1; } 0 diff --git a/src/mkfifo/Cargo.toml b/src/mkfifo/Cargo.toml index 555799cf650..9fe02b2f85e 100644 --- a/src/mkfifo/Cargo.toml +++ b/src/mkfifo/Cargo.toml @@ -2,7 +2,8 @@ name = "mkfifo" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_mkfifo" @@ -11,8 +12,8 @@ path = "mkfifo.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "mkfifo" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/mkfifo/mkfifo.rs b/src/mkfifo/mkfifo.rs index df101278715..5c510711273 100644 --- a/src/mkfifo/mkfifo.rs +++ b/src/mkfifo/mkfifo.rs @@ -76,10 +76,8 @@ Create a FIFO with the given name.", let mut exit_status = 0; for f in &matches.free { let err = unsafe { - mkfifo( - CString::new(f.as_bytes()).unwrap().as_ptr(), - mode as libc::mode_t, - ) + let name = CString::new(f.as_bytes()).unwrap(); + mkfifo(name.as_ptr(), mode as libc::mode_t) }; if err == -1 { show_error!( diff --git a/src/mknod/Cargo.toml b/src/mknod/Cargo.toml index 5d45c76211f..f1baa14461d 100644 --- a/src/mknod/Cargo.toml +++ b/src/mknod/Cargo.toml @@ -2,7 +2,8 @@ name = "mknod" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_mknod" @@ -11,8 +12,8 @@ path = "mknod.rs" [dependencies] getopts = "0.2.18" libc = "^0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "mknod" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/mknod/mknod.rs b/src/mknod/mknod.rs index 0efd7cc92e7..172be48925b 100644 --- a/src/mknod/mknod.rs +++ b/src/mknod/mknod.rs @@ -31,8 +31,7 @@ const MODE_RW_UGO: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_ #[inline(always)] fn makedev(maj: u64, min: u64) -> dev_t { // pick up from - ((min & 0xff) | ((maj & 0xfff) << 8) | (((min & !0xff)) << 12) | (((maj & !0xfff)) << 32)) - as dev_t + ((min & 0xff) | ((maj & 0xfff) << 8) | ((min & !0xff) << 12) | ((maj & !0xfff) << 32)) as dev_t } #[cfg(windows)] @@ -45,6 +44,7 @@ fn _makenod(path: CString, mode: mode_t, dev: dev_t) -> i32 { unsafe { libc::mknod(path.as_ptr(), mode, dev) } } +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: Vec) -> i32 { let mut opts = Options::new(); @@ -130,7 +130,7 @@ for details about the options it supports.", // 'mknod /dev/rst0 character 18 0'. let ch = args[1] .chars() - .nth(0) + .next() .expect("Failed to get the first char"); if ch == 'p' { diff --git a/src/mktemp/Cargo.toml b/src/mktemp/Cargo.toml index f2b98733b01..9ab5406c618 100644 --- a/src/mktemp/Cargo.toml +++ b/src/mktemp/Cargo.toml @@ -2,18 +2,19 @@ name = "mktemp" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_mktemp" path = "mktemp.rs" [dependencies] -uucore = "0.0.1" getopts = "0.2.18" rand = "0.5" tempfile = "2.1.5" +uucore = "0.0.2" [[bin]] name = "mktemp" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/mktemp/mktemp.rs b/src/mktemp/mktemp.rs index c5747385a6e..5e200dbee25 100644 --- a/src/mktemp/mktemp.rs +++ b/src/mktemp/mktemp.rs @@ -17,9 +17,9 @@ extern crate tempfile; extern crate uucore; use std::env; -use std::path::{is_separator, PathBuf}; -use std::mem::forget; use std::iter; +use std::mem::forget; +use std::path::{is_separator, PathBuf}; use rand::Rng; use tempfile::NamedTempFileOptions; @@ -179,14 +179,14 @@ pub fn dry_exec(mut tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str) -> rand::thread_rng().fill(bytes); for byte in bytes.iter_mut() { *byte = match *byte % 62 { - v @ 0..=9 => (v + '0' as u8), - v @ 10..=35 => (v - 10 + 'a' as u8), - v @ 36..=61 => (v - 36 + 'A' as u8), + v @ 0..=9 => (v + b'0'), + v @ 10..=35 => (v - 10 + b'a'), + v @ 36..=61 => (v - 36 + b'A'), _ => unreachable!(), } } } - tmpdir.push(String::from(buf)); + tmpdir.push(buf); println!("{}", tmpdir.display()); 0 } diff --git a/src/mktemp/tempdir.rs b/src/mktemp/tempdir.rs index b3f2e60e1a1..187ade2692d 100644 --- a/src/mktemp/tempdir.rs +++ b/src/mktemp/tempdir.rs @@ -1,8 +1,8 @@ // Mainly taken from crate `tempdir` extern crate rand; -use rand::{thread_rng, Rng}; use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng}; use std::io::Result as IOResult; use std::io::{Error, ErrorKind}; diff --git a/src/more/Cargo.toml b/src/more/Cargo.toml index 315d8f52d19..75503c78872 100644 --- a/src/more/Cargo.toml +++ b/src/more/Cargo.toml @@ -2,7 +2,8 @@ name = "more" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_more" @@ -10,7 +11,7 @@ path = "more.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_termios = "0.1" @@ -21,4 +22,4 @@ nix = "0.8.1" [[bin]] name = "more" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/more/more.rs b/src/more/more.rs index 3a121fada75..44a61dc201c 100644 --- a/src/more/more.rs +++ b/src/more/more.rs @@ -15,8 +15,8 @@ extern crate getopts; extern crate uucore; use getopts::Options; -use std::io::{stdout, Read, Write}; use std::fs::File; +use std::io::{stdout, Read, Write}; #[cfg(all(unix, not(target_os = "fuchsia")))] extern crate nix; @@ -146,7 +146,7 @@ fn more(matches: getopts::Matches) { if sz == 0 { break; } - stdout().write(&buffer[0..sz]).unwrap(); + stdout().write_all(&buffer[0..sz]).unwrap(); for byte in std::io::stdin().bytes() { match byte.unwrap() { b' ' => break, @@ -164,5 +164,5 @@ fn more(matches: getopts::Matches) { } reset_term(&mut term); - println!(""); + println!(); } diff --git a/src/mv/Cargo.toml b/src/mv/Cargo.toml index 5b60e457995..d3a759a8c11 100644 --- a/src/mv/Cargo.toml +++ b/src/mv/Cargo.toml @@ -2,7 +2,8 @@ name = "mv" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_mv" @@ -10,8 +11,8 @@ path = "mv.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "mv" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/mv/mv.rs b/src/mv/mv.rs index b6e6b6870a3..807acedee76 100644 --- a/src/mv/mv.rs +++ b/src/mv/mv.rs @@ -14,8 +14,8 @@ extern crate getopts; #[macro_use] extern crate uucore; -use std::fs; use std::env; +use std::fs; use std::io::{stdin, Result}; use std::path::{Path, PathBuf}; @@ -124,7 +124,7 @@ pub fn uumain(args: Vec) -> i32 { }; let paths: Vec = { - fn strip_slashes<'a>(p: &'a Path) -> &'a Path { + fn strip_slashes(p: &Path) -> &Path { p.components().as_path() } let to_owned = |p: &Path| p.to_owned(); @@ -202,12 +202,12 @@ fn determine_backup_suffix(backup_mode: BackupMode, matches: &getopts::Matches) ); } } + } else if let (Ok(s), BackupMode::SimpleBackup) = + (env::var("SIMPLE_BACKUP_SUFFIX"), backup_mode) + { + s } else { - if let (Ok(s), BackupMode::SimpleBackup) = (env::var("SIMPLE_BACKUP_SUFFIX"), backup_mode) { - s - } else { - "~".to_owned() - } + "~".to_owned() } } @@ -259,7 +259,9 @@ fn exec(files: &[PathBuf], b: Behaviour) -> i32 { Err(e) => { show_error!( "cannot move ‘{}’ to ‘{}’: {}", - source.display(), target.display(), e + source.display(), + target.display(), + e ); 1 } @@ -271,7 +273,8 @@ fn exec(files: &[PathBuf], b: Behaviour) -> i32 { } else if target.exists() && source.is_dir() { show_error!( "cannot overwrite non-directory ‘{}’ with directory ‘{}’", - target.display(), source.display() + target.display(), + source.display() ); return 1; } @@ -361,11 +364,8 @@ fn rename(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<()> { fs::rename(to, p)?; } - if b.update { - if fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? - { - return Ok(()); - } + if b.update && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? { + return Ok(()); } } @@ -376,7 +376,10 @@ fn rename(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<()> { if is_empty_dir(to) { fs::remove_dir(to)? } else { - return Err(std::io::Error::new(std::io::ErrorKind::Other, "Directory not empty")); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "Directory not empty", + )); } } } @@ -387,7 +390,7 @@ fn rename(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<()> { print!("‘{}’ -> ‘{}’", from.display(), to.display()); match backup_path { Some(path) => println!(" (backup: ‘{}’)", path.display()), - None => println!(""), + None => println!(), } } Ok(()) @@ -396,7 +399,7 @@ fn rename(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<()> { fn read_yes() -> bool { let mut s = String::new(); match stdin().read_line(&mut s) { - Ok(_) => match s.chars().nth(0) { + Ok(_) => match s.chars().next() { Some(x) => x == 'y' || x == 'Y', _ => false, }, @@ -413,8 +416,7 @@ fn simple_backup_path(path: &PathBuf, suffix: &str) -> PathBuf { fn numbered_backup_path(path: &PathBuf) -> PathBuf { (1_u64..) .map(|i| path.with_extension(format!("~{}~", i))) - .skip_while(|p| p.exists()) - .next() + .find(|p| !p.exists()) .expect("cannot create backup") } @@ -429,9 +431,7 @@ fn existing_backup_path(path: &PathBuf, suffix: &str) -> PathBuf { fn is_empty_dir(path: &PathBuf) -> bool { match fs::read_dir(path) { - Ok(contents) => { - return contents.peekable().peek().is_none(); - }, - Err(_e) => { return false; } + Ok(contents) => contents.peekable().peek().is_none(), + Err(_e) => false, } } diff --git a/src/nice/Cargo.toml b/src/nice/Cargo.toml index 8401f1032ec..44f67735865 100644 --- a/src/nice/Cargo.toml +++ b/src/nice/Cargo.toml @@ -2,7 +2,8 @@ name = "nice" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_nice" @@ -11,8 +12,8 @@ path = "nice.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "nice" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/nice/nice.rs b/src/nice/nice.rs index e76165a8e0e..50826a60cb8 100644 --- a/src/nice/nice.rs +++ b/src/nice/nice.rs @@ -18,6 +18,7 @@ extern crate uucore; use libc::{c_char, c_int, execvp}; use std::ffi::CString; use std::io::Error; +use std::ptr; const NAME: &str = "nice"; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -120,7 +121,7 @@ process).", .map(|x| CString::new(x.as_bytes()).unwrap()) .collect(); let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect(); - args.push(0 as *const c_char); + args.push(ptr::null::()); unsafe { execvp(args[0], args.as_mut_ptr()); } diff --git a/src/nl/Cargo.toml b/src/nl/Cargo.toml index 5959c8bd57a..358cffc5a5f 100644 --- a/src/nl/Cargo.toml +++ b/src/nl/Cargo.toml @@ -2,21 +2,22 @@ name = "nl" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_nl" path = "nl.rs" [dependencies] +aho-corasick = "0.7.3" getopts = "0.2.18" libc = "0.2.42" -aho-corasick = "0.7.3" memchr = "2.2.0" regex = "1.0.1" regex-syntax = "0.6.7" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "nl" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/nl/nl.rs b/src/nl/nl.rs index 6359b4b93a6..be43101e189 100644 --- a/src/nl/nl.rs +++ b/src/nl/nl.rs @@ -58,6 +58,7 @@ pub struct Settings { // 2. Number only nonempty lines // 3. Don't number any lines at all // 4. Number all lines that match a basic regular expression. +#[allow(clippy::enum_variant_names)] enum NumberingStyle { NumberForAll, NumberForNonEmpty, @@ -272,7 +273,7 @@ fn nl(reader: &mut BufReader, settings: &Settings) { if matched_groups > 0 { // The current line is a section delimiter, so we output // a blank line. - println!(""); + println!(); // However the line does not count as a blank line, so we // reset the counter used for --join-blank-lines. empty_line_count = 0; @@ -333,10 +334,11 @@ fn nl(reader: &mut BufReader, settings: &Settings) { // way, start counting empties from zero once more. empty_line_count = 0; // A line number is to be printed. - let mut w: usize = 0; - if settings.number_width > line_no_width { - w = settings.number_width - line_no_width; - } + let w = if settings.number_width > line_no_width { + settings.number_width - line_no_width + } else { + 0 + }; let fill: String = repeat(fill_char).take(w).collect(); match settings.number_format { NumberFormat::Left => println!( @@ -364,7 +366,7 @@ fn pass_regex(line: &str, re: ®ex::Regex) -> bool { } fn pass_nonempty(line: &str, _: ®ex::Regex) -> bool { - line.len() > 0 + !line.is_empty() } fn pass_none(_: &str, _: ®ex::Regex) -> bool { diff --git a/src/nohup/Cargo.toml b/src/nohup/Cargo.toml index 0302fa8d717..d18442af04a 100644 --- a/src/nohup/Cargo.toml +++ b/src/nohup/Cargo.toml @@ -2,7 +2,8 @@ name = "nohup" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_nohup" @@ -11,11 +12,8 @@ path = "nohup.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +uucore = { version = "0.0.2", features = ["fs"] } [[bin]] name = "nohup" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/nohup/nohup.rs b/src/nohup/nohup.rs index d9d7de6a376..574cd82fbe3 100644 --- a/src/nohup/nohup.rs +++ b/src/nohup/nohup.rs @@ -15,14 +15,14 @@ extern crate libc; #[macro_use] extern crate uucore; -use libc::{c_char, execvp, signal, dup2}; +use libc::{c_char, dup2, execvp, signal}; use libc::{SIGHUP, SIG_IGN}; +use std::env; use std::ffi::CString; use std::fs::{File, OpenOptions}; use std::io::Error; use std::os::unix::prelude::*; use std::path::{Path, PathBuf}; -use std::env; use uucore::fs::{is_stderr_interactive, is_stdin_interactive, is_stdout_interactive}; static NAME: &str = "nohup"; @@ -71,7 +71,7 @@ pub fn uumain(args: Vec) -> i32 { unsafe { signal(SIGHUP, SIG_IGN) }; - if unsafe { _vprocmgr_detach_from_console(0) } != std::ptr::null() { + if unsafe { !_vprocmgr_detach_from_console(0).is_null() } { crash!(2, "Cannot detach from console") }; @@ -105,10 +105,8 @@ fn replace_fds() { } } - if is_stderr_interactive() { - if unsafe { dup2(1, 2) } != 2 { - crash!(2, "Cannot replace STDERR: {}", Error::last_os_error()) - } + if is_stderr_interactive() && unsafe { dup2(1, 2) } != 2 { + crash!(2, "Cannot replace STDERR: {}", Error::last_os_error()) } } diff --git a/src/nproc/Cargo.toml b/src/nproc/Cargo.toml index c622e3a2ecc..5055a64809a 100644 --- a/src/nproc/Cargo.toml +++ b/src/nproc/Cargo.toml @@ -2,7 +2,8 @@ name = "nproc" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_nproc" @@ -12,8 +13,8 @@ path = "nproc.rs" getopts = "0.2.18" libc = "0.2.42" num_cpus = "1.10" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "nproc" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/nproc/nproc.rs b/src/nproc/nproc.rs index 6a35520cd87..3d6b9151c29 100644 --- a/src/nproc/nproc.rs +++ b/src/nproc/nproc.rs @@ -108,25 +108,32 @@ Print the number of cores available to the current process.", 0 } -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "netbsd"))] +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd" +))] fn num_cpus_all() -> usize { let nprocs = unsafe { libc::sysconf(_SC_NPROCESSORS_CONF) }; if nprocs == 1 { // In some situation, /proc and /sys are not mounted, and sysconf returns 1. // However, we want to guarantee that `nproc --all` >= `nproc`. num_cpus::get() + } else if nprocs > 0 { + nprocs as usize } else { - if nprocs > 0 { - nprocs as usize - } else { - 1 - } + 1 } } // Other platform(e.g., windows), num_cpus::get() directly. -#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd", - target_os = "netbsd")))] +#[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd" +)))] fn num_cpus_all() -> usize { num_cpus::get() } diff --git a/src/numfmt/Cargo.toml b/src/numfmt/Cargo.toml index c56d040f579..0a782f565cd 100644 --- a/src/numfmt/Cargo.toml +++ b/src/numfmt/Cargo.toml @@ -2,7 +2,8 @@ name = "numfmt" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_numfmt" @@ -10,8 +11,8 @@ path = "numfmt.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "numfmt" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/numfmt/numfmt.rs b/src/numfmt/numfmt.rs index 604f35b2b37..8a639a37f29 100644 --- a/src/numfmt/numfmt.rs +++ b/src/numfmt/numfmt.rs @@ -21,15 +21,15 @@ static VERSION: &str = env!("CARGO_PKG_VERSION"); const IEC_BASES: [f64; 10] = [ //premature optimization 1., - 1024., - 1048576., - 1073741824., - 1099511627776., - 1125899906842624., - 1152921504606846976., - 1180591620717411303424., - 1208925819614629174706176., - 1237940039285380274899124224., + 1_024., + 1_048_576., + 1_073_741_824., + 1_099_511_627_776., + 1_125_899_906_842_624., + 1_152_921_504_606_846_976., + 1_180_591_620_717_411_303_424., + 1_208_925_819_614_629_174_706_176., + 1_237_940_039_285_380_274_899_124_224., ]; type Result = std::result::Result; @@ -70,7 +70,8 @@ impl fmt::Display for DisplayableSuffix { RawSuffix::E => write!(f, "E"), RawSuffix::Z => write!(f, "Z"), RawSuffix::Y => write!(f, "Y"), - }.and_then(|()| match with_i { + } + .and_then(|()| match with_i { true => write!(f, "i"), false => Ok(()), }) @@ -78,7 +79,7 @@ impl fmt::Display for DisplayableSuffix { } fn parse_suffix(s: String) -> Result<(f64, Option)> { - let with_i = s.ends_with("i"); + let with_i = s.ends_with('i'); let mut iter = s.chars(); if with_i { iter.next_back(); @@ -251,13 +252,13 @@ fn parse_options(args: &Matches) -> Result { }?; Ok(NumfmtOptions { - transform: transform, - padding: padding, - header: header, + transform, + padding, + header, }) } -fn handle_args(args: &Vec, options: NumfmtOptions) -> Result<()> { +fn handle_args(args: &[String], options: NumfmtOptions) -> Result<()> { for l in args { println!("{}", format_string(l.clone(), &options)?) } @@ -276,7 +277,8 @@ fn handle_stdin(options: NumfmtOptions) -> Result<()> { for l in lines { l.map_err(|e| e.to_string()).and_then(|l| { let l = format_string(l, &options)?; - Ok(println!("{}", l)) + println!("{}", l); + Ok(()) })? } Ok(()) @@ -315,10 +317,10 @@ pub fn uumain(args: Vec) -> i32 { let matches = opts.parse(&args[1..]).unwrap(); if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {0} [STRING]... [OPTION]...", NAME); - println!(""); + println!(); print!( "{}", opts.usage("Convert numbers from/to human-readable strings") @@ -353,7 +355,7 @@ pub fn uumain(args: Vec) -> i32 { let options = parse_options(&matches).unwrap(); - if matches.free.len() == 0 { + if matches.free.is_empty() { handle_stdin(options).unwrap() } else { handle_args(&matches.free, options).unwrap() diff --git a/src/od/Cargo.toml b/src/od/Cargo.toml index 66fa397f181..7636daa7eba 100644 --- a/src/od/Cargo.toml +++ b/src/od/Cargo.toml @@ -2,19 +2,20 @@ name = "od" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_od" path = "od.rs" [dependencies] -getopts = "0.2.18" -libc = "0.2.42" byteorder = "1.3.2" +getopts = "0.2.18" half = "1.1.1" -uucore = "0.0.1" +libc = "0.2.42" +uucore = "0.0.2" [[bin]] name = "od" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/od/byteorder_io.rs b/src/od/byteorder_io.rs index 33f6179100c..5d7ad4cabc0 100644 --- a/src/od/byteorder_io.rs +++ b/src/od/byteorder_io.rs @@ -1,8 +1,8 @@ // workaround until https://github.com/BurntSushi/byteorder/issues/41 has been fixed // based on: https://github.com/netvl/immeta/blob/4460ee/src/utils.rs#L76 -use byteorder::{BigEndian, LittleEndian, NativeEndian}; use byteorder::ByteOrder as ByteOrderTrait; +use byteorder::{BigEndian, LittleEndian, NativeEndian}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum ByteOrder { diff --git a/src/od/formatteriteminfo.rs b/src/od/formatteriteminfo.rs index 29d5cb6d9c0..946106fc7ce 100644 --- a/src/od/formatteriteminfo.rs +++ b/src/od/formatteriteminfo.rs @@ -31,16 +31,16 @@ impl Eq for FormatWriter {} impl fmt::Debug for FormatWriter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &FormatWriter::IntWriter(ref p) => { + match *self { + FormatWriter::IntWriter(ref p) => { f.write_str("IntWriter:")?; fmt::Pointer::fmt(p, f) } - &FormatWriter::FloatWriter(ref p) => { + FormatWriter::FloatWriter(ref p) => { f.write_str("FloatWriter:")?; fmt::Pointer::fmt(p, f) } - &FormatWriter::MultibyteWriter(ref p) => { + FormatWriter::MultibyteWriter(ref p) => { f.write_str("MultibyteWriter:")?; fmt::Pointer::fmt(&(*p as *const ()), f) } diff --git a/src/od/inputdecoder.rs b/src/od/inputdecoder.rs index cd4a0feecc6..ea75ef23709 100644 --- a/src/od/inputdecoder.rs +++ b/src/od/inputdecoder.rs @@ -1,8 +1,8 @@ -use std::io; use byteorder_io::ByteOrder; +use half::f16; use multifilereader::HasError; use peekreader::PeekRead; -use half::f16; +use std::io; /// Processes an input and provides access to the data read in various formats /// @@ -43,12 +43,12 @@ impl<'a, I> InputDecoder<'a, I> { } // fast but uninitialized InputDecoder { - input: input, + input, data: bytes, reserved_peek_length: peek_length, used_normal_length: 0, used_peek_length: 0, - byte_order: byte_order, + byte_order, } } } @@ -60,7 +60,8 @@ where /// calls `peek_read` on the internal stream to (re)fill the buffer. Returns a /// MemoryDecoder providing access to the result or returns an i/o error. pub fn peek_read(&mut self) -> io::Result { - match self.input + match self + .input .peek_read(self.data.as_mut_slice(), self.reserved_peek_length) { Ok((n, p)) => { @@ -133,9 +134,9 @@ impl<'a> MemoryDecoder<'a> { /// Returns a u8/u16/u32/u64 from the internal buffer at position `start`. pub fn read_uint(&self, start: usize, byte_size: usize) -> u64 { match byte_size { - 1 => self.data[start] as u64, - 2 => self.byte_order.read_u16(&self.data[start..start + 2]) as u64, - 4 => self.byte_order.read_u32(&self.data[start..start + 4]) as u64, + 1 => u64::from(self.data[start]), + 2 => u64::from(self.byte_order.read_u16(&self.data[start..start + 2])), + 4 => u64::from(self.byte_order.read_u32(&self.data[start..start + 4])), 8 => self.byte_order.read_u64(&self.data[start..start + 8]), _ => panic!("Invalid byte_size: {}", byte_size), } @@ -147,7 +148,7 @@ impl<'a> MemoryDecoder<'a> { 2 => f64::from(f16::from_bits( self.byte_order.read_u16(&self.data[start..start + 2]), )), - 4 => self.byte_order.read_f32(&self.data[start..start + 4]) as f64, + 4 => f64::from(self.byte_order.read_f32(&self.data[start..start + 4])), 8 => self.byte_order.read_f64(&self.data[start..start + 8]), _ => panic!("Invalid byte_size: {}", byte_size), } @@ -157,9 +158,9 @@ impl<'a> MemoryDecoder<'a> { #[cfg(test)] mod tests { use super::*; - use std::io::Cursor; - use peekreader::PeekReader; use byteorder_io::ByteOrder; + use peekreader::PeekReader; + use std::io::Cursor; #[test] fn smoke_test() { diff --git a/src/od/inputoffset.rs b/src/od/inputoffset.rs index 102f1656b84..8f3030edfce 100644 --- a/src/od/inputoffset.rs +++ b/src/od/inputoffset.rs @@ -21,9 +21,9 @@ impl InputOffset { /// creates a new `InputOffset` using the provided values. pub fn new(radix: Radix, byte_pos: usize, label: Option) -> InputOffset { InputOffset { - radix: radix, - byte_pos: byte_pos, - label: label, + radix, + byte_pos, + label, } } @@ -58,7 +58,7 @@ impl InputOffset { /// both `Radix::NoPrefix` was set and no label (--traditional) is used. pub fn print_final_offset(&self) { if self.radix != Radix::NoPrefix || self.label.is_some() { - print!("{}\n", self.format_byte_offset()); + println!("{}", self.format_byte_offset()); } } } diff --git a/src/od/mockstream.rs b/src/od/mockstream.rs index 3523caf5860..f66f1dec71a 100644 --- a/src/od/mockstream.rs +++ b/src/od/mockstream.rs @@ -1,7 +1,7 @@ // https://github.com/lazy-bitfield/rust-mockstream/pull/2 -use std::io::{Cursor, Error, ErrorKind, Read, Result}; use std::error::Error as errorError; +use std::io::{Cursor, Error, ErrorKind, Read, Result}; /// `FailingMockStream` mocks a stream which will fail upon read or write /// diff --git a/src/od/multifilereader.rs b/src/od/multifilereader.rs index b53216cabb9..48951db94d0 100644 --- a/src/od/multifilereader.rs +++ b/src/od/multifilereader.rs @@ -1,7 +1,7 @@ use std; +use std::fs::File; use std::io; use std::io::BufReader; -use std::fs::File; use std::vec::Vec; pub enum InputSource<'a> { @@ -36,7 +36,7 @@ impl<'b> MultifileReader<'b> { fn next_file(&mut self) { // loop retries with subsequent files if err - normally 'loops' once loop { - if self.ni.len() == 0 { + if self.ni.is_empty() { self.curr_file = None; break; } @@ -125,8 +125,8 @@ impl<'b> HasError for MultifileReader<'b> { #[cfg(test)] mod tests { use super::*; - use std::io::{Cursor, ErrorKind, Read}; use mockstream::*; + use std::io::{Cursor, ErrorKind, Read}; #[test] fn test_multi_file_reader_one_read() { diff --git a/src/od/od.rs b/src/od/od.rs index 03fd0d55ab4..c8982c63016 100644 --- a/src/od/od.rs +++ b/src/od/od.rs @@ -16,36 +16,36 @@ extern crate half; #[macro_use] extern crate uucore; -mod multifilereader; -mod partialreader; -mod peekreader; mod byteorder_io; mod formatteriteminfo; -mod prn_int; -mod prn_char; -mod prn_float; -mod parse_nrofbytes; -mod parse_formats; -mod parse_inputs; -mod inputoffset; mod inputdecoder; -mod output_info; +mod inputoffset; #[cfg(test)] mod mockstream; +mod multifilereader; +mod output_info; +mod parse_formats; +mod parse_inputs; +mod parse_nrofbytes; +mod partialreader; +mod peekreader; +mod prn_char; +mod prn_float; +mod prn_int; -use std::cmp; use byteorder_io::*; +use formatteriteminfo::*; +use inputdecoder::{InputDecoder, MemoryDecoder}; +use inputoffset::{InputOffset, Radix}; use multifilereader::*; +use output_info::OutputInfo; +use parse_formats::{parse_format_flags, ParsedFormatterItemInfo}; +use parse_inputs::{parse_inputs, CommandLineInputs}; +use parse_nrofbytes::parse_number_of_bytes; use partialreader::*; use peekreader::*; -use formatteriteminfo::*; -use parse_nrofbytes::parse_number_of_bytes; -use parse_formats::{parse_format_flags, ParsedFormatterItemInfo}; use prn_char::format_ascii_dump; -use parse_inputs::{parse_inputs, CommandLineInputs}; -use inputoffset::{InputOffset, Radix}; -use inputdecoder::{InputDecoder, MemoryDecoder}; -use output_info::OutputInfo; +use std::cmp; static VERSION: &str = env!("CARGO_PKG_VERSION"); const PEEK_BUFFER_SIZE: usize = 4; // utf-8 can be 4 bytes @@ -224,7 +224,7 @@ impl OdOptions { let formats = match parse_format_flags(&args) { Ok(f) => f, Err(e) => { - return Err(format!("{}", e)); + return Err(e); } }; @@ -260,7 +260,7 @@ impl OdOptions { Some(s) => { let st = s.into_bytes(); if st.len() != 1 { - return Err(format!("Radix must be one of [d, o, n, x]")); + return Err("Radix must be one of [d, o, n, x]".to_string()); } else { let radix: char = *(st.get(0).expect("byte string of length 1 lacks a 0th elem")) as char; @@ -269,22 +269,22 @@ impl OdOptions { 'x' => Radix::Hexadecimal, 'o' => Radix::Octal, 'n' => Radix::NoPrefix, - _ => return Err(format!("Radix must be one of [d, o, n, x]")), + _ => return Err("Radix must be one of [d, o, n, x]".to_string()), } } } }; Ok(OdOptions { - byte_order: byte_order, - skip_bytes: skip_bytes, - read_bytes: read_bytes, - label: label, - input_strings: input_strings, - formats: formats, - line_bytes: line_bytes, - output_duplicates: output_duplicates, - radix: radix, + byte_order, + skip_bytes, + read_bytes, + label, + input_strings, + formats, + line_bytes, + output_duplicates, + radix, }) } } @@ -379,7 +379,8 @@ where memory_decoder.zero_out_buffer(length, max_used); } - if !output_info.output_duplicates && length == line_bytes + if !output_info.output_duplicates + && length == line_bytes && memory_decoder.get_buffer(0) == &previous_bytes[..] { if !duplicate_line { @@ -469,7 +470,7 @@ fn print_bytes(prefix: &str, input_decoder: &MemoryDecoder, output_info: &Output // lines of multi-format rasters. print!("{:>width$}", "", width = prefix.chars().count()); } - print!("{}\n", output_text); + println!("{}", output_text); } } @@ -478,7 +479,7 @@ fn print_bytes(prefix: &str, input_decoder: &MemoryDecoder, output_info: &Output /// `skip_bytes` is the number of bytes skipped from the input /// `read_bytes` is an optional limit to the number of bytes to read fn open_input_peek_reader<'a>( - input_strings: &'a Vec, + input_strings: &'a [String], skip_bytes: usize, read_bytes: Option, ) -> PeekReader>> { @@ -493,6 +494,5 @@ fn open_input_peek_reader<'a>( let mf = MultifileReader::new(inputs); let pr = PartialReader::new(mf, skip_bytes, read_bytes); - let input = PeekReader::new(pr); - input + PeekReader::new(pr) } diff --git a/src/od/output_info.rs b/src/od/output_info.rs index eaf46296ce0..01e48c002d5 100644 --- a/src/od/output_info.rs +++ b/src/od/output_info.rs @@ -1,7 +1,7 @@ +use formatteriteminfo::FormatterItemInfo; +use parse_formats::ParsedFormatterItemInfo; use std::cmp; use std::slice::Iter; -use parse_formats::ParsedFormatterItemInfo; -use formatteriteminfo::FormatterItemInfo; /// Size in bytes of the max datatype. ie set to 16 for 128-bit numbers. const MAX_BYTES_PER_UNIT: usize = 8; @@ -69,11 +69,11 @@ impl OutputInfo { OutputInfo { byte_size_line: line_bytes, - print_width_line: print_width_line, - byte_size_block: byte_size_block, - print_width_block: print_width_block, - spaced_formatters: spaced_formatters, - output_duplicates: output_duplicates, + print_width_line, + byte_size_block, + print_width_block, + spaced_formatters, + output_duplicates, } } diff --git a/src/od/parse_formats.rs b/src/od/parse_formats.rs index f8c3659f000..872e5840c4c 100644 --- a/src/od/parse_formats.rs +++ b/src/od/parse_formats.rs @@ -1,7 +1,7 @@ use formatteriteminfo::FormatterItemInfo; -use prn_int::*; use prn_char::*; use prn_float::*; +use prn_int::*; #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct ParsedFormatterItemInfo { @@ -15,8 +15,8 @@ impl ParsedFormatterItemInfo { add_ascii_dump: bool, ) -> ParsedFormatterItemInfo { ParsedFormatterItemInfo { - formatter_item_info: formatter_item_info, - add_ascii_dump: add_ascii_dump, + formatter_item_info, + add_ascii_dump, } } } @@ -100,14 +100,14 @@ fn od_argument_with_option(ch: char) -> bool { /// arguments with parameters like -w16 can only appear at the end: -fvoxw16 /// parameters of -t/--format specify 1 or more formats. /// if -- appears on the commandline, parsing should stop. -pub fn parse_format_flags(args: &Vec) -> Result, String> { +pub fn parse_format_flags(args: &[String]) -> Result, String> { let mut formats = Vec::new(); // args[0] is the name of the binary - let mut arg_iter = args.iter().skip(1); + let arg_iter = args.iter().skip(1); let mut expect_type_string = false; - while let Some(arg) = arg_iter.next() { + for arg in arg_iter { if expect_type_string { match parse_type_string(arg) { Ok(v) => formats.extend(v.into_iter()), @@ -128,10 +128,10 @@ pub fn parse_format_flags(args: &Vec) -> Result) -> Result { decimal_size.push(d); - return true; + true } _ => false, } @@ -266,13 +264,13 @@ fn is_format_dump_char(ch: Option, show_ascii_dump: &mut bool) -> bool { match ch { Some('z') => { *show_ascii_dump = true; - return true; + true } _ => false, } } -fn parse_type_string(params: &String) -> Result, String> { +fn parse_type_string(params: &str) -> Result, String> { let mut formats = Vec::new(); let mut chars = params.chars(); @@ -541,7 +539,8 @@ fn test_mixed_formats() { "--".to_string(), "-h".to_string(), "--format=f8".to_string(), - ]).unwrap(), + ]) + .unwrap(), vec![ ParsedFormatterItemInfo::new(FORMAT_ITEM_DEC64S, false), // I ParsedFormatterItemInfo::new(FORMAT_ITEM_DEC8U, true), // tu1z diff --git a/src/od/parse_inputs.rs b/src/od/parse_inputs.rs index b1ab1742770..21da091e1eb 100644 --- a/src/od/parse_inputs.rs +++ b/src/od/parse_inputs.rs @@ -14,7 +14,7 @@ impl CommandLineOpts for Matches { self.free.clone() } fn opts_present(&self, opts: &[&str]) -> bool { - self.opts_present(&opts.iter().map(|s| s.to_string()).collect::>()) + self.opts_present(&opts.iter().map(|s| (*s).to_string()).collect::>()) } } @@ -52,28 +52,23 @@ pub fn parse_inputs(matches: &dyn CommandLineOpts) -> Result { - // if there is just 1 input (stdin), an offset must start with '+' - if input_strings.len() == 1 && input_strings[0].starts_with("+") { - return Ok(CommandLineInputs::FileAndOffset(("-".to_string(), n, None))); - } - if input_strings.len() == 2 { - return Ok(CommandLineInputs::FileAndOffset(( - input_strings[0].clone(), - n, - None, - ))); - } + if let Ok(n) = offset { + // if there is just 1 input (stdin), an offset must start with '+' + if input_strings.len() == 1 && input_strings[0].starts_with('+') { + return Ok(CommandLineInputs::FileAndOffset(("-".to_string(), n, None))); } - _ => { - // if it cannot be parsed, it is considered a filename + if input_strings.len() == 2 { + return Ok(CommandLineInputs::FileAndOffset(( + input_strings[0].clone(), + n, + None, + ))); } } } } - if input_strings.len() == 0 { + if input_strings.is_empty() { input_strings.push("-".to_string()); } Ok(CommandLineInputs::FileNames(input_strings)) @@ -131,13 +126,13 @@ pub fn parse_inputs_traditional(input_strings: Vec) -> Result Result { +pub fn parse_offset_operand(s: &str) -> Result { let mut start = 0; let mut len = s.len(); let mut radix = 8; let mut multiply = 1; - if s.starts_with("+") { + if s.starts_with('+') { start += 1; } @@ -145,11 +140,11 @@ pub fn parse_offset_operand(s: &String) -> Result { start += 2; radix = 16; } else { - if s[start..len].ends_with("b") { + if s[start..len].ends_with('b') { len -= 1; multiply = 512; } - if s[start..len].ends_with(".") { + if s[start..len].ends_with('.') { len -= 1; radix = 10; } @@ -177,7 +172,7 @@ mod tests { fn new(inputs: Vec<&'a str>, option_names: Vec<&'a str>) -> MockOptions<'a> { MockOptions { inputs: inputs.iter().map(|s| s.to_string()).collect::>(), - option_names: option_names, + option_names, } } } @@ -328,23 +323,27 @@ mod tests { parse_inputs(&MockOptions::new( vec!["file1", "10", "10"], vec!["traditional"] - )).unwrap() + )) + .unwrap() ); parse_inputs(&MockOptions::new( vec!["10", "file1", "10"], vec!["traditional"], - )).unwrap_err(); + )) + .unwrap_err(); parse_inputs(&MockOptions::new( vec!["10", "10", "file1"], vec!["traditional"], - )).unwrap_err(); + )) + .unwrap_err(); parse_inputs(&MockOptions::new( vec!["10", "10", "10", "10"], vec!["traditional"], - )).unwrap_err(); + )) + .unwrap_err(); } fn parse_offset_operand_str(s: &str) -> Result { diff --git a/src/od/parse_nrofbytes.rs b/src/od/parse_nrofbytes.rs index c934de9c5b7..d2ba1527bea 100644 --- a/src/od/parse_nrofbytes.rs +++ b/src/od/parse_nrofbytes.rs @@ -1,4 +1,4 @@ -pub fn parse_number_of_bytes(s: &String) -> Result { +pub fn parse_number_of_bytes(s: &str) -> Result { let mut start = 0; let mut len = s.len(); let mut radix = 10; @@ -7,7 +7,7 @@ pub fn parse_number_of_bytes(s: &String) -> Result { if s.starts_with("0x") || s.starts_with("0X") { start = 2; radix = 16; - } else if s.starts_with("0") { + } else if s.starts_with('0') { radix = 8; } diff --git a/src/od/partialreader.rs b/src/od/partialreader.rs index 42bca6428f0..265f13daea7 100644 --- a/src/od/partialreader.rs +++ b/src/od/partialreader.rs @@ -1,7 +1,7 @@ +use multifilereader::HasError; use std::cmp; use std::io; use std::io::Read; -use multifilereader::HasError; /// When a large number of bytes must be skipped, it will be read into a /// dynamically allocated buffer. The buffer will be limited to this size. @@ -21,11 +21,7 @@ impl PartialReader { /// `skip` bytes, and limits the output to `limit` bytes. Set `limit` /// to `None` if there should be no limit. pub fn new(inner: R, skip: usize, limit: Option) -> Self { - PartialReader { - inner: inner, - skip: skip, - limit: limit, - } + PartialReader { inner, skip, limit } } } @@ -77,9 +73,9 @@ impl HasError for PartialReader { #[cfg(test)] mod tests { use super::*; - use std::io::{Cursor, ErrorKind, Read}; - use std::error::Error; use mockstream::*; + use std::error::Error; + use std::io::{Cursor, ErrorKind, Read}; #[test] fn test_read_without_limits() { diff --git a/src/od/peekreader.rs b/src/od/peekreader.rs index 825335f20fd..be82e126601 100644 --- a/src/od/peekreader.rs +++ b/src/od/peekreader.rs @@ -1,8 +1,8 @@ //! Contains the trait `PeekRead` and type `PeekReader` implementing it. +use multifilereader::HasError; use std::io; use std::io::{Read, Write}; -use multifilereader::HasError; /// A trait which supplies a function to peek into a stream without /// actually reading it. @@ -41,7 +41,7 @@ impl PeekReader { /// Create a new `PeekReader` wrapping `inner` pub fn new(inner: R) -> Self { PeekReader { - inner: inner, + inner, temp_buffer: Vec::new(), } } @@ -61,7 +61,7 @@ impl PeekReader { fn write_to_tempbuffer(&mut self, bytes: &[u8]) { // if temp_buffer is not empty, data has to be inserted in front let org_buffer: Vec<_> = self.temp_buffer.drain(..).collect(); - self.temp_buffer.write(bytes).unwrap(); + self.temp_buffer.write_all(bytes).unwrap(); self.temp_buffer.extend(org_buffer); } } diff --git a/src/od/prn_char.rs b/src/od/prn_char.rs index 4caf068fa13..fadc2d11b31 100644 --- a/src/od/prn_char.rs +++ b/src/od/prn_char.rs @@ -1,5 +1,5 @@ -use std::str::from_utf8; use formatteriteminfo::*; +use std::str::from_utf8; pub static FORMAT_ITEM_A: FormatterItemInfo = FormatterItemInfo { byte_size: 1, @@ -30,7 +30,7 @@ fn format_item_a(p: u64) -> String { format!("{:>4}", A_CHRS.get(b as usize).unwrap_or(&"??")) } -static C_CHRS: [&'static str; 128] = [ +static C_CHRS: [&str; 128] = [ "\\0", "001", "002", "003", "004", "005", "006", "\\a", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "016", "017", "020", "021", "022", "023", "024", "025", "026", "027", "030", "031", "032", "033", "034", "035", "036", "037", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", diff --git a/src/od/prn_float.rs b/src/od/prn_float.rs index 19ba3cca396..109ce041a62 100644 --- a/src/od/prn_float.rs +++ b/src/od/prn_float.rs @@ -1,8 +1,8 @@ -use std::num::FpCategory; +use formatteriteminfo::*; use half::f16; use std::f32; use std::f64; -use formatteriteminfo::*; +use std::num::FpCategory; pub static FORMAT_ITEM_F16: FormatterItemInfo = FormatterItemInfo { byte_size: 2, @@ -48,7 +48,7 @@ fn format_flo32(f: f32) -> String { // subnormal numbers will be normal as f64, so will print with a wrong precision format!("{:width$e}", f, width = width) // subnormal numbers } else { - format_float(f as f64, width, precision) + format_float(f64::from(f), width, precision) } } @@ -72,7 +72,7 @@ fn format_float(f: f64, width: usize, precision: usize) -> String { let r = 10f64.powi(l); if (f > 0.0 && r > f) || (f < 0.0 && -r < f) { // fix precision error - l = l - 1; + l -= 1; } if l >= 0 && l <= (precision as i32 - 1) { diff --git a/src/od/prn_int.rs b/src/od/prn_int.rs index cc47a16e79b..0de65611725 100644 --- a/src/od/prn_int.rs +++ b/src/od/prn_int.rs @@ -1,11 +1,23 @@ use formatteriteminfo::*; /// format string to print octal using `int_writer_unsigned` -macro_rules! OCT { () => { " {:0width$o}" }} +macro_rules! OCT { + () => { + " {:0width$o}" + }; +} /// format string to print hexadecimal using `int_writer_unsigned` -macro_rules! HEX { () => { " {:0width$x}" }} +macro_rules! HEX { + () => { + " {:0width$x}" + }; +} /// format string to print decimal using `int_writer_unsigned` or `int_writer_signed` -macro_rules! DEC { () => { " {:width$}" }} +macro_rules! DEC { + () => { + " {:width$}" + }; +} /// defines a static struct of type `FormatterItemInfo` called `$NAME` /// @@ -15,9 +27,7 @@ macro_rules! DEC { () => { " {:width$}" }} macro_rules! int_writer_unsigned { ($NAME:ident, $byte_size:expr, $print_width:expr, $function:ident, $format_str:expr) => { fn $function(p: u64) -> String { - format!($format_str, - p, - width = $print_width - 1) + format!($format_str, p, width = $print_width - 1) } pub static $NAME: FormatterItemInfo = FormatterItemInfo { @@ -25,7 +35,7 @@ macro_rules! int_writer_unsigned { print_width: $print_width, formatter: FormatWriter::IntWriter($function), }; - } + }; } /// defines a static struct of type `FormatterItemInfo` called `$NAME` @@ -37,9 +47,7 @@ macro_rules! int_writer_signed { ($NAME:ident, $byte_size:expr, $print_width:expr, $function:ident, $format_str:expr) => { fn $function(p: u64) -> String { let s = sign_extend(p, $byte_size); - format!($format_str, - s, - width = $print_width - 1) + format!($format_str, s, width = $print_width - 1) } pub static $NAME: FormatterItemInfo = FormatterItemInfo { @@ -47,7 +55,7 @@ macro_rules! int_writer_signed { print_width: $print_width, formatter: FormatWriter::IntWriter($function), }; - } + }; } /// Extends a signed number in `item` of `itembytes` bytes into a (signed) i64 diff --git a/src/paste/Cargo.toml b/src/paste/Cargo.toml index fb0d70cd29c..47054357c9a 100644 --- a/src/paste/Cargo.toml +++ b/src/paste/Cargo.toml @@ -2,7 +2,8 @@ name = "paste" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_paste" @@ -10,8 +11,8 @@ path = "paste.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "paste" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/paste/paste.rs b/src/paste/paste.rs index bffe0b96fee..3a1e209b806 100644 --- a/src/paste/paste.rs +++ b/src/paste/paste.rs @@ -14,9 +14,9 @@ extern crate getopts; #[macro_use] extern crate uucore; +use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::iter::repeat; -use std::fs::File; use std::path::Path; static NAME: &str = "paste"; @@ -60,7 +60,9 @@ FILE, separated by TABs, to standard output.", println!("{} {}", NAME, VERSION); } else { let serial = matches.opt_present("serial"); - let delimiters = matches.opt_str("delimiters").unwrap_or("\t".to_owned()); + let delimiters = matches + .opt_str("delimiters") + .unwrap_or_else(|| "\t".to_owned()); paste(matches.free, serial, delimiters); } diff --git a/src/pathchk/Cargo.toml b/src/pathchk/Cargo.toml index c6303a9cc52..117daa30718 100644 --- a/src/pathchk/Cargo.toml +++ b/src/pathchk/Cargo.toml @@ -2,7 +2,8 @@ name = "pathchk" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_pathchk" @@ -11,8 +12,8 @@ path = "pathchk.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "pathchk" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/pathchk/pathchk.rs b/src/pathchk/pathchk.rs index 8159c24c931..36bb591b1df 100644 --- a/src/pathchk/pathchk.rs +++ b/src/pathchk/pathchk.rs @@ -86,11 +86,12 @@ pub fn uumain(args: Vec) -> i32 { 0 } _ => { - let mut res = true; - if matches.free.len() == 0 { + let mut res = if matches.free.is_empty() { show_error!("missing operand\nTry {} --help for more information", NAME); - res = false; - } + false + } else { + true + }; // free strings are path operands // FIXME: TCS, seems inefficient and overly verbose (?) for p in matches.free { @@ -189,7 +190,7 @@ fn check_extra(path: &[String]) -> bool { } } // path length - if path.join("/").len() == 0 { + if path.join("/").is_empty() { writeln!(&mut std::io::stderr(), "empty file name"); return false; } @@ -230,26 +231,28 @@ fn check_default(path: &[String]) -> bool { } // check whether a path is or if other problems arise -fn check_searchable(path: &String) -> bool { +fn check_searchable(path: &str) -> bool { // we use lstat, just like the original implementation match fs::symlink_metadata(path) { Ok(_) => true, - Err(e) => if e.kind() == ErrorKind::NotFound { - true - } else { - writeln!(&mut std::io::stderr(), "{}", e); - false - }, + Err(e) => { + if e.kind() == ErrorKind::NotFound { + true + } else { + writeln!(&mut std::io::stderr(), "{}", e); + false + } + } } } // check for a hyphen at the beginning of a path segment -fn no_leading_hyphen(path_segment: &String) -> bool { +fn no_leading_hyphen(path_segment: &str) -> bool { !path_segment.starts_with('-') } // check whether a path segment contains only valid (read: portable) characters -fn check_portable_chars(path_segment: &String) -> bool { +fn check_portable_chars(path_segment: &str) -> bool { let valid_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-".to_string(); for ch in path_segment.chars() { if !valid_str.contains(ch) { diff --git a/src/pinky/Cargo.toml b/src/pinky/Cargo.toml index 56c60aecf49..4e7735216af 100644 --- a/src/pinky/Cargo.toml +++ b/src/pinky/Cargo.toml @@ -2,16 +2,16 @@ name = "pinky" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_pinky" path = "pinky.rs" -[dependencies.uucore] -version = "0.0.1" -features = ["utmpx", "entries"] +[dependencies] +uucore = { version = "0.0.2", features = ["utmpx", "entries"] } [[bin]] name = "pinky" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/pinky/pinky.rs b/src/pinky/pinky.rs index 0edf3e0f2a8..a3e506ad771 100644 --- a/src/pinky/pinky.rs +++ b/src/pinky/pinky.rs @@ -11,9 +11,9 @@ #[macro_use] extern crate uucore; -use uucore::utmpx::{self, time, Utmpx}; -use uucore::libc::S_IWGRP; use uucore::entries::{Locate, Passwd}; +use uucore::libc::S_IWGRP; +use uucore::utmpx::{self, time, Utmpx}; use std::io::prelude::*; use std::io::BufReader; @@ -125,13 +125,13 @@ The utmp file will be {}", } let pk = Pinky { - include_idle: include_idle, - include_heading: include_heading, - include_fullname: include_fullname, - include_project: include_project, - include_plan: include_plan, - include_home_and_shell: include_home_and_shell, - include_where: include_where, + include_idle, + include_heading, + include_fullname, + include_project, + include_plan, + include_home_and_shell, + include_where, names: matches.free, }; @@ -254,7 +254,7 @@ impl Pinky { let ut_host = ut.host(); let mut res = ut_host.splitn(2, ':'); let host = match res.next() { - Some(_) => ut.canon_host().unwrap_or(ut_host.clone()), + Some(_) => ut.canon_host().unwrap_or_else(|_| ut_host.clone()), None => ut_host.clone(), }; match res.next() { @@ -263,7 +263,7 @@ impl Pinky { } } - println!(""); + println!(); } fn print_heading(&self) { @@ -279,7 +279,7 @@ impl Pinky { if self.include_where { print!(" Where"); } - println!(""); + println!(); } fn short_pinky(&self) -> IOResult<()> { @@ -290,10 +290,8 @@ impl Pinky { if ut.is_user_process() { if self.names.is_empty() { self.print_entry(&ut) - } else { - if self.names.iter().any(|n| n.as_str() == ut.user()) { - self.print_entry(&ut); - } + } else if self.names.iter().any(|n| n.as_str() == ut.user()) { + self.print_entry(&ut); } } } @@ -325,7 +323,7 @@ impl Pinky { read_to_console(f); } } - println!(""); + println!(); } else { println!(" ???"); } diff --git a/src/printenv/Cargo.toml b/src/printenv/Cargo.toml index 36476dbd4d1..f7505199c40 100644 --- a/src/printenv/Cargo.toml +++ b/src/printenv/Cargo.toml @@ -2,7 +2,8 @@ name = "printenv" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_printenv" @@ -10,8 +11,8 @@ path = "printenv.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "printenv" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/printf/Cargo.toml b/src/printf/Cargo.toml index bf1ab0b8f8c..f05387dd3d1 100644 --- a/src/printf/Cargo.toml +++ b/src/printf/Cargo.toml @@ -2,7 +2,8 @@ name = "printf" version = "0.0.1" authors = ["Nathan Ross"] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_printf" @@ -10,8 +11,8 @@ path = "printf.rs" [dependencies] itertools = "0.8.0" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "printf" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/printf/cli.rs b/src/printf/cli.rs index e69cdf3c9f5..62aeb8a7cbf 100644 --- a/src/printf/cli.rs +++ b/src/printf/cli.rs @@ -1,8 +1,7 @@ //! stdio convenience fns -#[allow(unused_must_use)] -use std::io::{stderr, stdout, Write}; use std::env; +use std::io::{stderr, stdout, Write}; pub const EXIT_OK: i32 = 0; pub const EXIT_ERR: i32 = 1; @@ -18,7 +17,7 @@ pub fn err_msg(msg: &str) { // by default stdout only flushes // to console when a newline is passed. #[allow(unused_must_use)] -pub fn flush_char(c: &char) { +pub fn flush_char(c: char) { print!("{}", c); stdout().flush(); } diff --git a/src/printf/memo.rs b/src/printf/memo.rs index e006f22b5b8..5f3eee482c3 100644 --- a/src/printf/memo.rs +++ b/src/printf/memo.rs @@ -5,13 +5,13 @@ //! 2. feeds remaining arguments into function //! that prints tokens. +use cli; +use itertools::put_back_n; use std::iter::Peekable; use std::slice::Iter; -use itertools::put_back_n; -use cli; +use tokenize::sub::Sub; use tokenize::token::{Token, Tokenizer}; use tokenize::unescaped_text::UnescapedText; -use tokenize::sub::Sub; pub struct Memo { tokens: Vec>, @@ -25,26 +25,22 @@ fn warn_excess_args(first_arg: &str) { } impl Memo { - pub fn new(pf_string: &String, pf_args_it: &mut Peekable>) -> Memo { + pub fn new(pf_string: &str, pf_args_it: &mut Peekable>) -> Memo { let mut pm = Memo { tokens: Vec::new() }; let mut tmp_token: Option>; let mut it = put_back_n(pf_string.chars()); let mut has_sub = false; loop { tmp_token = UnescapedText::from_it(&mut it, pf_args_it); - match tmp_token { - Some(x) => pm.tokens.push(x), - None => {} + if let Some(x) = tmp_token { + pm.tokens.push(x); } tmp_token = Sub::from_it(&mut it, pf_args_it); - match tmp_token { - Some(x) => { - if !has_sub { - has_sub = true; - } - pm.tokens.push(x); + if let Some(x) = tmp_token { + if !has_sub { + has_sub = true; } - None => {} + pm.tokens.push(x); } if let Some(x) = it.next() { it.put_back(x); @@ -74,7 +70,7 @@ impl Memo { tkn.print(pf_args_it); } } - pub fn run_all(pf_string: &String, pf_args: &[String]) { + pub fn run_all(pf_string: &str, pf_args: &[String]) { let mut arg_it = pf_args.iter().peekable(); let pm = Memo::new(pf_string, &mut arg_it); loop { diff --git a/src/printf/printf.rs b/src/printf/printf.rs index 1842f883128..05b4b94640a 100644 --- a/src/printf/printf.rs +++ b/src/printf/printf.rs @@ -282,7 +282,7 @@ pub fn uumain(args: Vec) -> i32 { ); return 1; } - let ref formatstr = args[1]; + let formatstr = &args[1]; if formatstr == "--help" { print!("{} {}", LONGHELP_LEAD, LONGHELP_BODY); @@ -292,5 +292,5 @@ pub fn uumain(args: Vec) -> i32 { let printf_args = &args[2..]; memo::Memo::run_all(formatstr, printf_args); } - return 0; + 0 } diff --git a/src/printf/tokenize/mod.rs b/src/printf/tokenize/mod.rs index 0570b74896d..dfe44a0e56b 100644 --- a/src/printf/tokenize/mod.rs +++ b/src/printf/tokenize/mod.rs @@ -1,4 +1,5 @@ -pub mod token; +#[allow(clippy::module_inception)] +mod num_format; pub mod sub; +pub mod token; pub mod unescaped_text; -mod num_format; diff --git a/src/printf/tokenize/num_format/formatter.rs b/src/printf/tokenize/num_format/formatter.rs index aa5cf18a7f0..f770823de1c 100644 --- a/src/printf/tokenize/num_format/formatter.rs +++ b/src/printf/tokenize/num_format/formatter.rs @@ -1,10 +1,10 @@ //! Primitives used by num_format and sub_modules. //! never dealt with above (e.g. Sub Tokenizer never uses these) -use std::str::Chars; -use itertools::{put_back_n, PutBackN}; -use cli; use super::format_field::FormatField; +use cli; +use itertools::{put_back_n, PutBackN}; +use std::str::Chars; // contains the rough ingredients to final // output for a number, organized together diff --git a/src/printf/tokenize/num_format/formatters/base_conv/mod.rs b/src/printf/tokenize/num_format/formatters/base_conv/mod.rs index af18044f951..f288e95cc82 100644 --- a/src/printf/tokenize/num_format/formatters/base_conv/mod.rs +++ b/src/printf/tokenize/num_format/formatters/base_conv/mod.rs @@ -1,9 +1,9 @@ -pub fn arrnum_int_mult(arr_num: &Vec, basenum: u8, base_ten_int_fact: u8) -> Vec { +pub fn arrnum_int_mult(arr_num: &[u8], basenum: u8, base_ten_int_fact: u8) -> Vec { let mut carry: u16 = 0; let mut rem: u16; let mut new_amount: u16; - let fact: u16 = base_ten_int_fact as u16; - let base: u16 = basenum as u16; + let fact: u16 = u16::from(base_ten_int_fact); + let base: u16 = u16::from(basenum); let mut ret_rev: Vec = Vec::new(); let mut it = arr_num.iter().rev(); @@ -11,7 +11,7 @@ pub fn arrnum_int_mult(arr_num: &Vec, basenum: u8, base_ten_int_fact: u8) -> let i = it.next(); match i { Some(u) => { - new_amount = ((u.clone() as u16) * fact) + carry; + new_amount = (u16::from(*u) * fact) + carry; rem = new_amount % base; carry = (new_amount - rem) / base; ret_rev.push(rem as u8) @@ -26,7 +26,8 @@ pub fn arrnum_int_mult(arr_num: &Vec, basenum: u8, base_ten_int_fact: u8) -> } } } - let ret: Vec = ret_rev.iter().rev().map(|x| x.clone()).collect(); + #[allow(clippy::map_clone)] + let ret: Vec = ret_rev.iter().rev().map(|x| *x).collect(); ret } @@ -41,12 +42,12 @@ pub struct DivOut<'a> { pub remainder: Remainder<'a>, } -pub fn arrnum_int_div_step<'a>( - rem_in: Remainder<'a>, +pub fn arrnum_int_div_step( + rem_in: Remainder, radix_in: u8, base_ten_int_divisor: u8, after_decimal: bool, -) -> DivOut<'a> { +) -> DivOut { let mut rem_out = Remainder { position: rem_in.position, replace: Vec::new(), @@ -54,8 +55,8 @@ pub fn arrnum_int_div_step<'a>( }; let mut bufferval: u16 = 0; - let base: u16 = radix_in as u16; - let divisor: u16 = base_ten_int_divisor as u16; + let base: u16 = u16::from(radix_in); + let divisor: u16 = u16::from(base_ten_int_divisor); let mut traversed = 0; let mut quotient = 0; @@ -64,9 +65,9 @@ pub fn arrnum_int_div_step<'a>( let mut it_f = refd_vals.iter(); loop { let u = match it_replace.next() { - Some(u_rep) => u_rep.clone() as u16, + Some(u_rep) => u16::from(*u_rep), None => match it_f.next() { - Some(u_orig) => u_orig.clone() as u16, + Some(u_orig) => u16::from(*u_orig), None => { if !after_decimal { break; @@ -86,8 +87,7 @@ pub fn arrnum_int_div_step<'a>( Vec::new() } else { let remainder_as_arrnum = unsigned_to_arrnum(bufferval); - let remainder_as_base_arrnum = base_conv_vec(&remainder_as_arrnum, 10, radix_in); - remainder_as_base_arrnum + base_conv_vec(&remainder_as_arrnum, 10, radix_in) }; rem_out.position += 1 + (traversed - rem_out.replace.len()); break; @@ -96,7 +96,7 @@ pub fn arrnum_int_div_step<'a>( } } DivOut { - quotient: quotient, + quotient, remainder: rem_out, } } @@ -164,11 +164,11 @@ pub fn arrnum_int_div_step<'a>( // ArrFloatDivOut { quotient: quotient, remainder: remainder } // } // -pub fn arrnum_int_add(arrnum: &Vec, basenum: u8, base_ten_int_term: u8) -> Vec { - let mut carry: u16 = base_ten_int_term as u16; +pub fn arrnum_int_add(arrnum: &[u8], basenum: u8, base_ten_int_term: u8) -> Vec { + let mut carry: u16 = u16::from(base_ten_int_term); let mut rem: u16; let mut new_amount: u16; - let base: u16 = basenum as u16; + let base: u16 = u16::from(basenum); let mut ret_rev: Vec = Vec::new(); let mut it = arrnum.iter().rev(); @@ -176,7 +176,7 @@ pub fn arrnum_int_add(arrnum: &Vec, basenum: u8, base_ten_int_term: u8) -> V let i = it.next(); match i { Some(u) => { - new_amount = (u.clone() as u16) + carry; + new_amount = u16::from(*u) + carry; rem = new_amount % base; carry = (new_amount - rem) / base; ret_rev.push(rem as u8) @@ -191,23 +191,24 @@ pub fn arrnum_int_add(arrnum: &Vec, basenum: u8, base_ten_int_term: u8) -> V } } } - let ret: Vec = ret_rev.iter().rev().map(|x| x.clone()).collect(); + #[allow(clippy::map_clone)] + let ret: Vec = ret_rev.iter().rev().map(|x| *x).collect(); ret } -pub fn base_conv_vec(src: &Vec, radix_src: u8, radix_dest: u8) -> Vec { +pub fn base_conv_vec(src: &[u8], radix_src: u8, radix_dest: u8) -> Vec { let mut result: Vec = Vec::new(); result.push(0); for i in src { result = arrnum_int_mult(&result, radix_dest, radix_src); - result = arrnum_int_add(&result, radix_dest, i.clone()); + result = arrnum_int_add(&result, radix_dest, *i); } result } pub fn unsigned_to_arrnum(src: u16) -> Vec { let mut result: Vec = Vec::new(); - let mut src_tmp: u16 = src.clone(); + let mut src_tmp: u16 = src; while src_tmp > 0 { result.push((src_tmp % 10) as u8); src_tmp /= 10; @@ -218,24 +219,22 @@ pub fn unsigned_to_arrnum(src: u16) -> Vec { // temporary needs-improvement-function #[allow(unused_variables)] -pub fn base_conv_float(src: &Vec, radix_src: u8, radix_dest: u8) -> f64 { +pub fn base_conv_float(src: &[u8], radix_src: u8, radix_dest: u8) -> f64 { // it would require a lot of addl code // to implement this for arbitrary string input. // until then, the below operates as an outline // of how it would work. let mut result: Vec = Vec::new(); result.push(0); - let mut factor: f64 = 1.; - let radix_src_float: f64 = radix_src as f64; - let mut i = 0; - let mut r: f64 = 0 as f64; - for u in src { + let mut factor: f64 = 1_f64; + let radix_src_float: f64 = f64::from(radix_src); + let mut r: f64 = 0_f64; + for (i, u) in src.iter().enumerate() { if i > 15 { break; } - i += 1; factor /= radix_src_float; - r += factor * (u.clone() as f64) + r += factor * f64::from(*u) } r } @@ -243,6 +242,7 @@ pub fn base_conv_float(src: &Vec, radix_src: u8, radix_dest: u8) -> f64 { pub fn str_to_arrnum(src: &str, radix_def_src: &dyn RadixDef) -> Vec { let mut intermed_in: Vec = Vec::new(); for c in src.chars() { + #[allow(clippy::single_match)] match radix_def_src.from_char(c) { Some(u) => { intermed_in.push(u); @@ -253,9 +253,10 @@ pub fn str_to_arrnum(src: &str, radix_def_src: &dyn RadixDef) -> Vec { intermed_in } -pub fn arrnum_to_str(src: &Vec, radix_def_dest: &dyn RadixDef) -> String { +pub fn arrnum_to_str(src: &[u8], radix_def_dest: &dyn RadixDef) -> String { let mut str_out = String::new(); for u in src.iter() { + #[allow(clippy::single_match)] match radix_def_dest.from_u8(u.clone()) { Some(c) => { str_out.push(c); @@ -288,9 +289,9 @@ pub trait RadixDef { } pub struct RadixTen; -const ZERO_ASC: u8 = '0' as u8; -const UPPER_A_ASC: u8 = 'A' as u8; -const LOWER_A_ASC: u8 = 'a' as u8; +const ZERO_ASC: u8 = b'0'; +const UPPER_A_ASC: u8 = b'A'; +const LOWER_A_ASC: u8 = b'a'; impl RadixDef for RadixTen { fn get_max(&self) -> u8 { diff --git a/src/printf/tokenize/num_format/formatters/base_conv/tests.rs b/src/printf/tokenize/num_format/formatters/base_conv/tests.rs index b69dcdb653d..55e7fdfca9c 100644 --- a/src/printf/tokenize/num_format/formatters/base_conv/tests.rs +++ b/src/printf/tokenize/num_format/formatters/base_conv/tests.rs @@ -1,5 +1,4 @@ #[cfg(test)] - use super::*; #[test] diff --git a/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs b/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs index 9d226818ce3..6e9cdc75741 100644 --- a/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs +++ b/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs @@ -1,9 +1,9 @@ //! formatter for %a %F C99 Hex-floating-point subs use super::super::format_field::FormatField; use super::super::formatter::{FormatPrimitive, Formatter, InPrefix}; -use super::float_common::{primitive_to_str_common, FloatAnalysis}; use super::base_conv; use super::base_conv::RadixDef; +use super::float_common::{primitive_to_str_common, FloatAnalysis}; pub struct CninetyNineHexFloatf { as_num: f64, @@ -60,7 +60,7 @@ fn get_primitive_hex( Some(pos) => (&str_in[..pos], &str_in[pos + 1..]), None => (&str_in[..], "0"), }; - if first_segment_raw.len() == 0 { + if first_segment_raw.is_empty() { first_segment_raw = "0"; } // convert to string, hexifying if input is in dec. diff --git a/src/printf/tokenize/num_format/formatters/decf.rs b/src/printf/tokenize/num_format/formatters/decf.rs index 46de17290ad..2cbb3f69600 100644 --- a/src/printf/tokenize/num_format/formatters/decf.rs +++ b/src/printf/tokenize/num_format/formatters/decf.rs @@ -53,23 +53,20 @@ impl Formatter for Decf { Some(*field.field_char == 'G'), ); // strip trailing zeroes - match f_sci.post_decimal.clone() { - Some(ref post_dec) => { - let mut i = post_dec.len(); - { - let mut it = post_dec.chars(); - while let Some(c) = it.next_back() { - if c != '0' { - break; - } - i -= 1; + if let Some(ref post_dec) = f_sci.post_decimal.clone() { + let mut i = post_dec.len(); + { + let mut it = post_dec.chars(); + while let Some(c) = it.next_back() { + if c != '0' { + break; } + i -= 1; } - if i != post_dec.len() { - f_sci.post_decimal = Some(String::from(&post_dec[0..i])); - } } - None => {} + if i != post_dec.len() { + f_sci.post_decimal = Some(String::from(&post_dec[0..i])); + } } let f_fl = get_primitive_dec( inprefix, diff --git a/src/printf/tokenize/num_format/formatters/float_common.rs b/src/printf/tokenize/num_format/formatters/float_common.rs index 6af7b0a6a3b..430af334792 100644 --- a/src/printf/tokenize/num_format/formatters/float_common.rs +++ b/src/printf/tokenize/num_format/formatters/float_common.rs @@ -23,16 +23,14 @@ fn has_enough_digits( // -1s are for rounding if hex_output { if hex_input { - ((string_position - 1) - starting_position >= limit) + (string_position - 1) - starting_position >= limit } else { false //undecidable without converting } + } else if hex_input { + (((string_position - 1) - starting_position) * 9) / 8 >= limit } else { - if hex_input { - ((((string_position - 1) - starting_position) * 9) / 8 >= limit) - } else { - ((string_position - 1) - starting_position >= limit) - } + (string_position - 1) - starting_position >= limit } } @@ -47,7 +45,7 @@ impl FloatAnalysis { // this fn assumes // the input string // has no leading spaces or 0s - let mut str_it = get_it_at(inprefix.offset, str_in); + let str_it = get_it_at(inprefix.offset, str_in); let mut ret = FloatAnalysis { len_important: 0, decimal_pos: None, @@ -62,7 +60,7 @@ impl FloatAnalysis { }; let mut i = 0; let mut pos_before_first_nonzero_after_decimal: Option = None; - while let Some(c) = str_it.next() { + for c in str_it { match c { e @ '0'..='9' | e @ 'A'..='F' | e @ 'a'..='f' => { if !hex_input { @@ -74,7 +72,8 @@ impl FloatAnalysis { } } } - if ret.decimal_pos.is_some() && pos_before_first_nonzero_after_decimal.is_none() + if ret.decimal_pos.is_some() + && pos_before_first_nonzero_after_decimal.is_none() && e != '0' { pos_before_first_nonzero_after_decimal = Some(i - 1); @@ -160,7 +159,7 @@ fn _round_str_from(in_str: &str, position: usize) -> (String, bool) { '9' => { rev.push('0'); } - e @ _ => { + e => { rev.push(((e as u8) + 1) as char); finished_in_dec = true; break; @@ -182,23 +181,17 @@ fn round_terminal_digit( if position < after_dec.len() { let digit_at_pos: char; { - digit_at_pos = (&after_dec[position..=position]) - .chars() - .next() - .expect(""); + digit_at_pos = (&after_dec[position..=position]).chars().next().expect(""); } - match digit_at_pos { - '5'..='9' => { - let (new_after_dec, finished_in_dec) = _round_str_from(&after_dec, position); - if finished_in_dec { - return (before_dec, new_after_dec); - } else { - let (new_before_dec, _) = _round_str_from(&before_dec, before_dec.len()); - return (new_before_dec, new_after_dec); - } - // TODO + if let '5'..='9' = digit_at_pos { + let (new_after_dec, finished_in_dec) = _round_str_from(&after_dec, position); + if finished_in_dec { + return (before_dec, new_after_dec); + } else { + let (new_before_dec, _) = _round_str_from(&before_dec, before_dec.len()); + return (new_before_dec, new_after_dec); } - _ => {} + // TODO } } (before_dec, after_dec) @@ -225,7 +218,7 @@ pub fn get_primitive_dec( Some(pos) => (&str_in[..pos], &str_in[pos + 1..]), None => (&str_in[..], "0"), }; - if first_segment_raw.len() == 0 { + if first_segment_raw.is_empty() { first_segment_raw = "0"; } // convert to string, de_hexifying if input is in hex. @@ -251,15 +244,15 @@ pub fn get_primitive_dec( } else { match first_segment.chars().next() { Some('0') => { - let mut it = second_segment.chars().enumerate(); + let it = second_segment.chars().enumerate(); let mut m: isize = 0; let mut pre = String::from("0"); let mut post = String::from("0"); - while let Some((i, c)) = it.next() { + for (i, c) in it { match c { '0' => {} _ => { - m = ((i as isize) + 1) * -1; + m = -((i as isize) + 1); pre = String::from(&second_segment[i..=i]); post = String::from(&second_segment[i + 1..]); break; @@ -299,11 +292,8 @@ pub fn get_primitive_dec( pub fn primitive_to_str_common(prim: &FormatPrimitive, field: &FormatField) -> String { let mut final_str = String::new(); - match prim.prefix { - Some(ref prefix) => { - final_str.push_str(&prefix); - } - None => {} + if let Some(ref prefix) = prim.prefix { + final_str.push_str(&prefix); } match prim.pre_decimal { Some(ref pre_decimal) => { @@ -319,7 +309,7 @@ pub fn primitive_to_str_common(prim: &FormatPrimitive, field: &FormatField) -> S let decimal_places = field.second_field.unwrap_or(6); match prim.post_decimal { Some(ref post_decimal) => { - if post_decimal.len() > 0 && decimal_places > 0 { + if !post_decimal.is_empty() && decimal_places > 0 { final_str.push('.'); let len_avail = post_decimal.len() as u32; @@ -346,11 +336,8 @@ pub fn primitive_to_str_common(prim: &FormatPrimitive, field: &FormatField) -> S ); } } - match prim.suffix { - Some(ref suffix) => { - final_str.push_str(suffix); - } - None => {} + if let Some(ref suffix) = prim.suffix { + final_str.push_str(suffix); } final_str diff --git a/src/printf/tokenize/num_format/formatters/intf.rs b/src/printf/tokenize/num_format/formatters/intf.rs index c5e517e3970..5b524897f61 100644 --- a/src/printf/tokenize/num_format/formatters/intf.rs +++ b/src/printf/tokenize/num_format/formatters/intf.rs @@ -1,11 +1,12 @@ //! formatter for unsigned and signed int subs //! unsigned ints: %X %x (hex u64) %o (octal u64) %u (base ten u64) //! signed ints: %i %d (both base ten i64) -use std::u64; -use std::i64; use super::super::format_field::FormatField; -use super::super::formatter::{get_it_at, warn_incomplete_conv, Base, FormatPrimitive, Formatter, - InPrefix}; +use super::super::formatter::{ + get_it_at, warn_incomplete_conv, Base, FormatPrimitive, Formatter, InPrefix, +}; +use std::i64; +use std::u64; pub struct Intf { a: u32, @@ -127,7 +128,7 @@ impl Intf { }, 'x' | 'X' => "ffffffffffffffff", 'o' => "1777777777777777777777", - 'u' | _ => "18446744073709551615", + /* 'u' | */ _ => "18446744073709551615", })); fmt_prim } @@ -203,7 +204,7 @@ impl Formatter for Intf { let radix_out = match *field.field_char { 'd' | 'i' | 'u' => Base::Ten, 'x' | 'X' => Base::Hex, - 'o' | _ => Base::Octal, + /* 'o' | */ _ => Base::Octal, }; let radix_mismatch = !radix_out.eq(&inprefix.radix_in); let decr_from_max: bool = inprefix.sign == -1 && *field.field_char != 'i'; @@ -216,13 +217,12 @@ impl Formatter for Intf { if convert_hints.check_past_max || decr_from_max || radix_mismatch { // radix of in and out is the same. let segment = String::from(&str_in[begin..end]); - let m = Intf::conv_from_segment( + Intf::conv_from_segment( &segment, inprefix.radix_in.clone(), *field.field_char, inprefix.sign, - ); - m + ) } else { // otherwise just do a straight string copy. let mut fmt_prim: FormatPrimitive = Default::default(); @@ -242,26 +242,20 @@ impl Formatter for Intf { } fn primitive_to_str(&self, prim: &FormatPrimitive, field: FormatField) -> String { let mut finalstr: String = String::new(); - match prim.prefix { - Some(ref prefix) => { - finalstr.push_str(&prefix); - } - None => {} + if let Some(ref prefix) = prim.prefix { + finalstr.push_str(&prefix); } // integral second fields is zero-padded minimum-width // which gets handled before general minimum-width match prim.pre_decimal { Some(ref pre_decimal) => { - match field.second_field { - Some(min) => { - let mut i = min; - let len = pre_decimal.len() as u32; - while i > len { - finalstr.push('0'); - i -= 1; - } + if let Some(min) = field.second_field { + let mut i = min; + let len = pre_decimal.len() as u32; + while i > len { + finalstr.push('0'); + i -= 1; } - None => {} } finalstr.push_str(&pre_decimal); } diff --git a/src/printf/tokenize/num_format/formatters/mod.rs b/src/printf/tokenize/num_format/formatters/mod.rs index 329e36d87f3..f6e2e7389cb 100644 --- a/src/printf/tokenize/num_format/formatters/mod.rs +++ b/src/printf/tokenize/num_format/formatters/mod.rs @@ -1,7 +1,7 @@ -pub mod intf; -pub mod floatf; +mod base_conv; pub mod cninetyninehexfloatf; -pub mod scif; pub mod decf; mod float_common; -mod base_conv; +pub mod floatf; +pub mod intf; +pub mod scif; diff --git a/src/printf/tokenize/num_format/num_format.rs b/src/printf/tokenize/num_format/num_format.rs index 23ca72936e7..e84116bfcc0 100644 --- a/src/printf/tokenize/num_format/num_format.rs +++ b/src/printf/tokenize/num_format/num_format.rs @@ -1,17 +1,17 @@ //! handles creating printed output for numeric substitutions -use std::env; -use std::vec::Vec; -use cli; use super::format_field::{FieldType, FormatField}; use super::formatter::{Base, FormatPrimitive, Formatter, InPrefix}; -use super::formatters::intf::Intf; -use super::formatters::floatf::Floatf; use super::formatters::cninetyninehexfloatf::CninetyNineHexFloatf; -use super::formatters::scif::Scif; use super::formatters::decf::Decf; +use super::formatters::floatf::Floatf; +use super::formatters::intf::Intf; +use super::formatters::scif::Scif; +use cli; +use std::env; +use std::vec::Vec; -pub fn warn_expected_numeric(pf_arg: &String) { +pub fn warn_expected_numeric(pf_arg: &str) { // important: keep println here not print cli::err_msg(&format!("{}: expected a numeric value", pf_arg)); } @@ -21,16 +21,15 @@ pub fn warn_expected_numeric(pf_arg: &String) { fn warn_char_constant_ign(remaining_bytes: Vec) { match env::var("POSIXLY_CORRECT") { Ok(_) => {} - Err(e) => match e { - env::VarError::NotPresent => { + Err(e) => { + if let env::VarError::NotPresent = e { cli::err_msg(&format!( "warning: {:?}: character(s) following character \ constant have been ignored", &*remaining_bytes )); } - _ => {} - }, + } } } @@ -46,13 +45,13 @@ fn get_provided(str_in_opt: Option<&String>) -> Option { if let Some(qchar) = byte_it.next() { match qchar { C_S_QUOTE | C_D_QUOTE => { - return Some(match byte_it.next() { + Some(match byte_it.next() { Some(second_byte) => { let mut ignored: Vec = Vec::new(); - while let Some(cont) = byte_it.next() { + for cont in byte_it { ignored.push(cont); } - if ignored.len() > 0 { + if !ignored.is_empty() { warn_char_constant_ign(ignored); } second_byte as u8 @@ -63,12 +62,10 @@ fn get_provided(str_in_opt: Option<&String>) -> Option { warn_expected_numeric(&so_far); 0 as u8 } - }); + }) } // first byte is not quote - _ => { - return None; - } // no first byte + _ => None, // no first byte } } else { Some(0 as u8) @@ -83,26 +80,19 @@ fn get_provided(str_in_opt: Option<&String>) -> Option { // a base, // and an offset for index after all // initial spacing, sign, base prefix, and leading zeroes -fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { +fn get_inprefix(str_in: &str, field_type: &FieldType) -> InPrefix { let mut str_it = str_in.chars(); let mut ret = InPrefix { radix_in: Base::Ten, sign: 1, offset: 0, }; - let mut topchar = str_it.next().clone(); + let mut topchar = str_it.next(); // skip spaces and ensure topchar is the first non-space char // (or None if none exists) - loop { - match topchar { - Some(' ') => { - ret.offset += 1; - topchar = str_it.next(); - } - _ => { - break; - } - } + while let Some(' ') = topchar { + ret.offset += 1; + topchar = str_it.next(); } // parse sign match topchar { @@ -145,11 +135,8 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { } e @ '0'..='9' => { ret.offset += 1; - match *field_type { - FieldType::Intf => { - ret.radix_in = Base::Octal; - } - _ => {} + if let FieldType::Intf = *field_type { + ret.radix_in = Base::Octal; } if e == '0' { do_clean_lead_zeroes = true; @@ -159,7 +146,7 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { } if do_clean_lead_zeroes { let mut first = true; - while let Some(ch_zero) = str_it.next() { + for ch_zero in str_it { // see notes on offset above: // this is why the offset for octals and decimals // that reach this branch is 1 even though @@ -203,7 +190,7 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { // if it is a numeric field, passing the field details // and an iterator to the argument pub fn num_format(field: &FormatField, in_str_opt: Option<&String>) -> Option { - let fchar = field.field_char.clone(); + let fchar = field.field_char; // num format mainly operates by further delegating to one of // several Formatter structs depending on the field diff --git a/src/printf/tokenize/sub.rs b/src/printf/tokenize/sub.rs index 6e5311bf16b..6e460268c85 100644 --- a/src/printf/tokenize/sub.rs +++ b/src/printf/tokenize/sub.rs @@ -3,24 +3,24 @@ //! it is created by Sub's implementation of the Tokenizer trait //! Subs which have numeric field chars make use of the num_format //! submodule -use std::slice::Iter; -use std::iter::Peekable; -use std::str::Chars; -use std::process::exit; -use cli; -use itertools::{put_back_n, PutBackN}; -use super::token; -use super::unescaped_text::UnescapedText; use super::num_format::format_field::{FieldType, FormatField}; use super::num_format::num_format; +use super::token; +use super::unescaped_text::UnescapedText; +use cli; +use itertools::{put_back_n, PutBackN}; +use std::iter::Peekable; +use std::process::exit; +use std::slice::Iter; +use std::str::Chars; // use std::collections::HashSet; -fn err_conv(sofar: &String) { +fn err_conv(sofar: &str) { cli::err_msg(&format!("%{}: invalid conversion specification", sofar)); exit(cli::EXIT_ERR); } -fn convert_asterisk_arg_int(asterisk_arg: &String) -> isize { +fn convert_asterisk_arg_int(asterisk_arg: &str) -> isize { // this is a costly way to parse the // args used for asterisk values into integers // from various bases. Actually doing it correctly @@ -32,11 +32,11 @@ fn convert_asterisk_arg_int(asterisk_arg: &String) -> isize { let field_info = FormatField { min_width: Some(0), second_field: Some(0), - orig: asterisk_arg, + orig: &asterisk_arg.to_string(), field_type: &field_type, field_char: &field_char, }; - num_format::num_format(&field_info, Some(asterisk_arg)) + num_format::num_format(&field_info, Some(&asterisk_arg.to_string())) .unwrap() .parse::() .unwrap() @@ -80,11 +80,11 @@ impl Sub { } }; Sub { - min_width: min_width, - second_field: second_field, - field_char: field_char, - field_type: field_type, - orig: orig, + min_width, + second_field, + field_char, + field_type, + orig, } } } @@ -155,29 +155,17 @@ impl SubParser { // though, as we want to mimic the original behavior of printing // the field as interpreted up until the error in the field. - let mut legal_fields = vec![// 'a', 'A', //c99 hex float implementation not yet complete - 'b', - 'c', - 'd', - 'e', - 'E', - 'f', - 'F', - 'g', - 'G', - 'i', - 'o', - 's', - 'u', - 'x', - 'X']; + let mut legal_fields = vec![ + // 'a', 'A', //c99 hex float implementation not yet complete + 'b', 'c', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'i', 'o', 's', 'u', 'x', 'X', + ]; let mut specifiers = vec!['h', 'j', 'l', 'L', 't', 'z']; legal_fields.sort(); specifiers.sort(); // divide substitution from %([0-9]+)?(.[0-9+])?([a-zA-Z]) // into min_width, second_field, field_char - while let Some(ch) = it.next() { + for ch in it { self.text_so_far.push(ch); match ch as char { '-' | '*' | '0'..='9' => { @@ -190,7 +178,7 @@ impl SubParser { } match self.min_width_tmp.as_mut() { Some(x) => { - if (ch == '-' || ch == '*') && x.len() > 0 { + if (ch == '-' || ch == '*') && !x.is_empty() { err_conv(&self.text_so_far); } if ch == '*' { @@ -213,7 +201,7 @@ impl SubParser { } match self.second_field_tmp.as_mut() { Some(x) => { - if ch == '*' && x.len() > 0 { + if ch == '*' && !x.is_empty() { err_conv(&self.text_so_far); } if ch == '*' { @@ -252,7 +240,7 @@ impl SubParser { } } } - if !self.field_char.is_some() { + if self.field_char.is_none() { err_conv(&self.text_so_far); } let field_char_retrieved = self.field_char.unwrap(); @@ -262,13 +250,10 @@ impl SubParser { self.validate_field_params(field_char_retrieved); // if the dot is provided without a second field // printf interprets it as 0. - match self.second_field_tmp.as_mut() { - Some(x) => { - if x.len() == 0 { - self.min_width_tmp = Some(String::from("0")); - } + if let Some(x) = self.second_field_tmp.as_mut() { + if x.is_empty() { + self.min_width_tmp = Some(String::from("0")); } - _ => {} } true @@ -292,8 +277,12 @@ impl SubParser { } } } else { - n_ch.map(|x| it.put_back(x)); - preface.map(|x| it.put_back(x)); + if let Some(x) = n_ch { + it.put_back(x) + }; + if let Some(x) = preface { + it.put_back(x) + }; false } } @@ -305,7 +294,8 @@ impl SubParser { || (field_char == 'c' && (self.min_width_tmp == Some(String::from("0")) || self.past_decimal)) || (field_char == 'b' - && (self.min_width_tmp.is_some() || self.past_decimal + && (self.min_width_tmp.is_some() + || self.past_decimal || self.second_field_tmp.is_some())) { err_conv(&self.text_so_far); @@ -379,7 +369,8 @@ impl token::Token for Sub { // for 'c': get iter of string vals, // get opt of first val // and map it to opt - 'c' | _ => arg_string.chars().next().map(|x| x.to_string()), + /* 'c' | */ + _ => arg_string.chars().next().map(|x| x.to_string()), } } None => None, @@ -390,39 +381,35 @@ impl token::Token for Sub { num_format::num_format(&field, pf_arg) } }; - match pre_min_width_opt { + if let Some(pre_min_width) = pre_min_width_opt { // if have a string, print it, ensuring minimum width is met. - Some(pre_min_width) => { - print!( - "{}", - match field.min_width { - Some(min_width) => { - let diff: isize = - min_width.abs() as isize - pre_min_width.len() as isize; - if diff > 0 { - let mut final_str = String::new(); - // definitely more efficient ways - // to do this. - let pad_before = min_width > 0; - if !pad_before { - final_str.push_str(&pre_min_width); - } - for _ in 0..diff { - final_str.push(' '); - } - if pad_before { - final_str.push_str(&pre_min_width); - } - final_str - } else { - pre_min_width + print!( + "{}", + match field.min_width { + Some(min_width) => { + let diff: isize = min_width.abs() as isize - pre_min_width.len() as isize; + if diff > 0 { + let mut final_str = String::new(); + // definitely more efficient ways + // to do this. + let pad_before = min_width > 0; + if !pad_before { + final_str.push_str(&pre_min_width); + } + for _ in 0..diff { + final_str.push(' '); } + if pad_before { + final_str.push_str(&pre_min_width); + } + final_str + } else { + pre_min_width } - None => pre_min_width, } - ); - } - None => {} + None => pre_min_width, + } + ); } } } diff --git a/src/printf/tokenize/token.rs b/src/printf/tokenize/token.rs index 78009dd91de..2e0cdd81283 100644 --- a/src/printf/tokenize/token.rs +++ b/src/printf/tokenize/token.rs @@ -1,6 +1,5 @@ //! Traits and enums dealing with Tokenization of printf Format String use itertools::PutBackN; -#[allow(unused_must_use)] use std::iter::Peekable; use std::slice::Iter; use std::str::Chars; diff --git a/src/printf/tokenize/unescaped_text.rs b/src/printf/tokenize/unescaped_text.rs index 93b1b229db2..5c7ee603bf9 100644 --- a/src/printf/tokenize/unescaped_text.rs +++ b/src/printf/tokenize/unescaped_text.rs @@ -60,11 +60,12 @@ impl UnescapedText { // dropped-in as a replacement. fn validate_iec(val: u32, eight_word: bool) { let mut preface = 'u'; - let mut leading_zeros = 4; - if eight_word { + let leading_zeros = if eight_word { preface = 'U'; - leading_zeros = 8; - } + 8 + } else { + 4 + }; let err_msg = format!( "invalid universal character name {0}{1:02$x}", preface, val, leading_zeros @@ -120,7 +121,7 @@ impl UnescapedText { byte_vec.push(ch as u8); } } - e @ _ => { + e => { // only for hex and octal // is byte encoding specified. // otherwise, why not leave the door open @@ -147,7 +148,7 @@ impl UnescapedText { 'u' | 'U' => { let len = match e { 'u' => 4, - 'U' | _ => 8, + /* 'U' | */ _ => 8, }; let val = UnescapedText::base_to_u32(len, len, 16, it); UnescapedText::validate_iec(val, false); @@ -191,7 +192,7 @@ impl UnescapedText { // lazy branch eval // remember this fn could be called // many times in a single exec through %b - cli::flush_char(&ch); + cli::flush_char(ch); tmp_str.push(ch); } '\\' => { @@ -202,7 +203,7 @@ impl UnescapedText { // on non hex or octal escapes is costly // then we can make it faster/more complex // with as-necessary draining. - if tmp_str.len() > 0 { + if !tmp_str.is_empty() { new_vec.extend(tmp_str.bytes()); tmp_str = String::new(); } @@ -211,7 +212,7 @@ impl UnescapedText { x if x == '%' && !subs_mode => { if let Some(follow) = it.next() { if follow == '%' { - cli::flush_char(&ch); + cli::flush_char(ch); tmp_str.push(ch); } else { it.put_back(follow); @@ -224,18 +225,19 @@ impl UnescapedText { } } _ => { - cli::flush_char(&ch); + cli::flush_char(ch); tmp_str.push(ch); } } } - if tmp_str.len() > 0 { + if !tmp_str.is_empty() { new_vec.extend(tmp_str.bytes()); } } - match addchar { - true => Some(Box::new(new_text)), - false => None, + if addchar { + Some(Box::new(new_text)) + } else { + None } } } diff --git a/src/ptx/Cargo.toml b/src/ptx/Cargo.toml index 6a7ad255c5f..700e150bd1b 100644 --- a/src/ptx/Cargo.toml +++ b/src/ptx/Cargo.toml @@ -2,21 +2,22 @@ name = "ptx" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_ptx" path = "ptx.rs" [dependencies] +aho-corasick = "0.7.3" getopts = "0.2.18" libc = "0.2.42" -aho-corasick = "0.7.3" memchr = "2.2.0" -regex-syntax = "0.6.7" regex = "1.0.1" -uucore = "0.0.1" +regex-syntax = "0.6.7" +uucore = "0.0.2" [[bin]] name = "ptx" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/ptx/ptx.rs b/src/ptx/ptx.rs index 8573b65ab7f..9e7573c253f 100644 --- a/src/ptx/ptx.rs +++ b/src/ptx/ptx.rs @@ -189,14 +189,12 @@ fn read_input(input_files: &[String], config: &Config) -> HashMap String { Some(x) => (x.start(), x.end()), None => (0, 0), }; - format!("{}", &line[beg..end]) + line[beg..end].to_string() } else { String::new() } diff --git a/src/pwd/Cargo.toml b/src/pwd/Cargo.toml index a6e29640b2f..8466713c9f3 100644 --- a/src/pwd/Cargo.toml +++ b/src/pwd/Cargo.toml @@ -2,7 +2,8 @@ name = "pwd" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_pwd" @@ -10,8 +11,8 @@ path = "pwd.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "pwd" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/pwd/pwd.rs b/src/pwd/pwd.rs index c43fcf3869f..2eff91fa63c 100644 --- a/src/pwd/pwd.rs +++ b/src/pwd/pwd.rs @@ -15,8 +15,8 @@ extern crate getopts; extern crate uucore; use std::env; -use std::path::{Path, PathBuf}; use std::io; +use std::path::{Path, PathBuf}; static NAME: &str = "pwd"; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -30,7 +30,8 @@ pub fn absolute_path(path: &Path) -> io::Result { .as_path() .to_string_lossy() .trim_start_matches(r"\\?\"), - ).to_path_buf(); + ) + .to_path_buf(); Ok(path_buf) } diff --git a/src/readlink/Cargo.toml b/src/readlink/Cargo.toml index 580d0b8051e..b2185789ec0 100644 --- a/src/readlink/Cargo.toml +++ b/src/readlink/Cargo.toml @@ -2,7 +2,8 @@ name = "readlink" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_readlink" @@ -11,11 +12,8 @@ path = "readlink.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +uucore = { version = "0.0.2", features = ["fs"] } [[bin]] name = "readlink" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/readlink/readlink.rs b/src/readlink/readlink.rs index b4971e27fe0..47bea285c6e 100644 --- a/src/readlink/readlink.rs +++ b/src/readlink/readlink.rs @@ -70,18 +70,15 @@ pub fn uumain(args: Vec) -> i32 { let silent = matches.opt_present("silent") || matches.opt_present("quiet"); let verbose = matches.opt_present("verbose"); - let mut can_mode = CanonicalizeMode::None; - if matches.opt_present("canonicalize") { - can_mode = CanonicalizeMode::Normal; - } - - if matches.opt_present("canonicalize-existing") { - can_mode = CanonicalizeMode::Existing; - } - - if matches.opt_present("canonicalize-missing") { - can_mode = CanonicalizeMode::Missing; - } + let can_mode = if matches.opt_present("canonicalize") { + CanonicalizeMode::Normal + } else if matches.opt_present("canonicalize-existing") { + CanonicalizeMode::Existing + } else if matches.opt_present("canonicalize-missing") { + CanonicalizeMode::Missing + } else { + CanonicalizeMode::None + }; let files = matches.free; if files.is_empty() { @@ -139,7 +136,7 @@ fn show(path: &PathBuf, no_newline: bool, use_zero: bool) { fn show_usage(opts: &getopts::Options) { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage: {0} [OPTION]... [FILE]...", NAME); print!("Print value of a symbolic link or canonical file name"); print!("{}", opts.usage("")); diff --git a/src/realpath/Cargo.toml b/src/realpath/Cargo.toml index 2b1c16a4556..f574d8852f9 100644 --- a/src/realpath/Cargo.toml +++ b/src/realpath/Cargo.toml @@ -2,7 +2,8 @@ name = "realpath" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_realpath" @@ -10,11 +11,8 @@ path = "realpath.rs" [dependencies] getopts = "0.2.18" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +uucore = { version = "0.0.2", features = ["fs"] } [[bin]] name = "realpath" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/realpath/realpath.rs b/src/realpath/realpath.rs index 80e6052daef..5238040221b 100644 --- a/src/realpath/realpath.rs +++ b/src/realpath/realpath.rs @@ -136,12 +136,12 @@ fn version() { fn show_usage(opts: &getopts::Options) { version(); - println!(""); + println!(); println!("Usage:"); println!(" {} [-s|--strip] [-z|--zero] FILENAME...", NAME); println!(" {} -V|--version", NAME); println!(" {} -h|--help", NAME); - println!(""); + println!(); print!("{}", opts.usage( "Convert each FILENAME to the absolute path.\n\ All the symbolic links will be resolved, resulting path will contain no special components like '.' or '..'.\n\ diff --git a/src/relpath/Cargo.toml b/src/relpath/Cargo.toml index 0855e0c0ff0..799732eae75 100644 --- a/src/relpath/Cargo.toml +++ b/src/relpath/Cargo.toml @@ -2,7 +2,8 @@ name = "relpath" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_relpath" @@ -10,11 +11,8 @@ path = "relpath.rs" [dependencies] getopts = "0.2.18" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +uucore = { version = "0.0.2", features = ["fs"] } [[bin]] name = "relpath" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/relpath/relpath.rs b/src/relpath/relpath.rs index 8e0bb401217..b2ed8c251bd 100644 --- a/src/relpath/relpath.rs +++ b/src/relpath/relpath.rs @@ -108,12 +108,12 @@ fn version() { fn show_usage(opts: &getopts::Options) { version(); - println!(""); + println!(); println!("Usage:"); println!(" {} [-d DIR] TO [FROM]", NAME); println!(" {} -V|--version", NAME); println!(" {} -h|--help", NAME); - println!(""); + println!(); print!( "{}", opts.usage( diff --git a/src/rm/Cargo.toml b/src/rm/Cargo.toml index 45c9b72b9ca..418e3fdf2b2 100644 --- a/src/rm/Cargo.toml +++ b/src/rm/Cargo.toml @@ -2,7 +2,8 @@ name = "rm" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_rm" @@ -12,8 +13,8 @@ path = "rm.rs" getopts = "0.2.18" walkdir = "2.2.8" remove_dir_all = "0.5.1" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "rm" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/rm/rm.rs b/src/rm/rm.rs index 8c2fc08ba18..b3c241a8d83 100644 --- a/src/rm/rm.rs +++ b/src/rm/rm.rs @@ -16,19 +16,19 @@ extern crate walkdir; #[macro_use] extern crate uucore; +use remove_dir_all::remove_dir_all; use std::collections::VecDeque; use std::fs; use std::io::{stderr, stdin, BufRead, Write}; use std::ops::BitOr; use std::path::Path; -use remove_dir_all::remove_dir_all; use walkdir::{DirEntry, WalkDir}; #[derive(Eq, PartialEq, Clone, Copy)] enum InteractiveMode { - InteractiveNone, - InteractiveOnce, - InteractiveAlways, + None, + Once, + Always, } struct Options { @@ -84,20 +84,20 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {0} [OPTION]... [FILE]...", NAME); - println!(""); + println!(); println!("{}", opts.usage("Remove (unlink) the FILE(s).")); println!("By default, rm does not remove directories. Use the --recursive (-r)"); println!("option to remove each listed directory, too, along with all of its contents"); - println!(""); + println!(); println!("To remove a file whose name starts with a '-', for example '-foo',"); println!("use one of these commands:"); println!("rm -- -foo"); - println!(""); + println!(); println!("rm ./-foo"); - println!(""); + println!(); println!("Note that if you use rm to remove a file, it might be possible to recover"); println!("some of its contents, given sufficient expertise and/or time. For greater"); println!("assurance that the contents are truly unrecoverable, consider using shred."); @@ -109,21 +109,21 @@ pub fn uumain(args: Vec) -> i32 { return 1; } else { let options = Options { - force: force, + force, interactive: { if matches.opt_present("i") { - InteractiveMode::InteractiveAlways + InteractiveMode::Always } else if matches.opt_present("I") { - InteractiveMode::InteractiveOnce + InteractiveMode::Once } else if matches.opt_present("interactive") { match &matches.opt_str("interactive").unwrap()[..] { - "none" => InteractiveMode::InteractiveNone, - "once" => InteractiveMode::InteractiveOnce, - "always" => InteractiveMode::InteractiveAlways, + "none" => InteractiveMode::None, + "once" => InteractiveMode::Once, + "always" => InteractiveMode::Always, val => crash!(1, "Invalid argument to interactive ({})", val), } } else { - InteractiveMode::InteractiveNone + InteractiveMode::None } }, one_fs: matches.opt_present("one-file-system"), @@ -132,7 +132,7 @@ pub fn uumain(args: Vec) -> i32 { dir: matches.opt_present("dir"), verbose: matches.opt_present("verbose"), }; - if options.interactive == InteractiveMode::InteractiveOnce + if options.interactive == InteractiveMode::Once && (options.recursive || matches.free.len() > 3) { let msg = if options.recursive { @@ -181,7 +181,8 @@ fn remove(files: Vec, options: Options) -> bool { false } } - }.bitor(had_err); + } + .bitor(had_err); } had_err @@ -192,7 +193,7 @@ fn handle_dir(path: &Path, options: &Options) -> bool { let is_root = path.has_root() && path.parent().is_none(); if options.recursive && (!is_root || !options.preserve_root) { - if options.interactive != InteractiveMode::InteractiveAlways { + if options.interactive != InteractiveMode::Always { // we need the extra crate because apparently fs::remove_dir_all() does not function // correctly on Windows if let Err(e) = remove_dir_all(path) { @@ -225,33 +226,33 @@ fn handle_dir(path: &Path, options: &Options) -> bool { } } else if options.dir && (!is_root || !options.preserve_root) { had_err = remove_dir(path, options).bitor(had_err); + } else if options.recursive { + show_error!("could not remove directory '{}'", path.display()); + had_err = true; } else { - if options.recursive { - show_error!("could not remove directory '{}'", path.display()); - had_err = true; - } else { - show_error!( - "could not remove directory '{}' (did you mean to pass '-r'?)", - path.display() - ); - had_err = true; - } + show_error!( + "could not remove directory '{}' (did you mean to pass '-r'?)", + path.display() + ); + had_err = true; } had_err } fn remove_dir(path: &Path, options: &Options) -> bool { - let response = if options.interactive == InteractiveMode::InteractiveAlways { + let response = if options.interactive == InteractiveMode::Always { prompt_file(path, true) } else { true }; if response { match fs::remove_dir(path) { - Ok(_) => if options.verbose { - println!("removed '{}'", path.display()); - }, + Ok(_) => { + if options.verbose { + println!("removed '{}'", path.display()); + } + } Err(e) => { show_error!("removing '{}': {}", path.display(), e); return true; @@ -263,16 +264,18 @@ fn remove_dir(path: &Path, options: &Options) -> bool { } fn remove_file(path: &Path, options: &Options) -> bool { - let response = if options.interactive == InteractiveMode::InteractiveAlways { + let response = if options.interactive == InteractiveMode::Always { prompt_file(path, false) } else { true }; if response { match fs::remove_file(path) { - Ok(_) => if options.verbose { - println!("removed '{}'", path.display()); - }, + Ok(_) => { + if options.verbose { + println!("removed '{}'", path.display()); + } + } Err(e) => { show_error!("removing '{}': {}", path.display(), e); return true; @@ -299,7 +302,7 @@ fn prompt(msg: &str) -> bool { let stdin = stdin(); let mut stdin = stdin.lock(); - match stdin.read_until('\n' as u8, &mut buf) { + match stdin.read_until(b'\n', &mut buf) { Ok(x) if x > 0 => match buf[0] { b'y' | b'Y' => true, _ => false, @@ -322,5 +325,6 @@ fn is_symlink_dir(metadata: &fs::Metadata) -> bool { pub type DWORD = c_ulong; pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10; - metadata.file_type().is_symlink() && ((metadata.file_attributes() & FILE_ATTRIBUTE_DIRECTORY) != 0) + metadata.file_type().is_symlink() + && ((metadata.file_attributes() & FILE_ATTRIBUTE_DIRECTORY) != 0) } diff --git a/src/rmdir/Cargo.toml b/src/rmdir/Cargo.toml index 6f74aae90ed..038e5365d2b 100644 --- a/src/rmdir/Cargo.toml +++ b/src/rmdir/Cargo.toml @@ -2,7 +2,8 @@ name = "rmdir" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_rmdir" @@ -10,8 +11,8 @@ path = "rmdir.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "rmdir" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/seq/Cargo.toml b/src/seq/Cargo.toml index 43ab40aba2b..608b1a41897 100644 --- a/src/seq/Cargo.toml +++ b/src/seq/Cargo.toml @@ -2,7 +2,8 @@ name = "seq" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_seq" @@ -10,8 +11,8 @@ path = "seq.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "seq" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/seq/seq.rs b/src/seq/seq.rs index 4bdbbf370a3..a8a4f6ec4e8 100644 --- a/src/seq/seq.rs +++ b/src/seq/seq.rs @@ -22,7 +22,7 @@ struct SeqOptions { } fn parse_float(mut s: &str) -> Result { - if s.starts_with("+") { + if s.starts_with('+') { s = &s[1..]; } match s.parse() { @@ -41,105 +41,96 @@ fn escape_sequences(s: &str) -> String { fn parse_options(args: Vec, options: &mut SeqOptions) -> Result, i32> { let mut seq_args = vec![]; let mut iter = args.into_iter().skip(1); - loop { - match iter.next() { - Some(arg) => match &arg[..] { - "--help" | "-h" => { - print_help(); - return Err(0); - } - "--version" | "-V" => { - print_version(); - return Err(0); + while let Some(arg) = iter.next() { + match &arg[..] { + "--help" | "-h" => { + print_help(); + return Err(0); + } + "--version" | "-V" => { + print_version(); + return Err(0); + } + "-s" | "--separator" => match iter.next() { + Some(sep) => options.separator = sep, + None => { + show_error!("expected a separator after {}", arg); + return Err(1); } - "-s" | "--separator" => match iter.next() { - Some(sep) => options.separator = sep, - None => { - show_error!("expected a separator after {}", arg); - return Err(1); - } - }, - "-t" | "--terminator" => match iter.next() { - Some(term) => options.terminator = Some(term), - None => { - show_error!("expected a terminator after '{}'", arg); - return Err(1); - } - }, - "-w" | "--widths" => options.widths = true, - "--" => { - seq_args.extend(iter); - break; + }, + "-t" | "--terminator" => match iter.next() { + Some(term) => options.terminator = Some(term), + None => { + show_error!("expected a terminator after '{}'", arg); + return Err(1); } - _ => { - if arg.len() > 1 && arg.chars().next().unwrap() == '-' { - let argptr: *const String = &arg; // escape from the borrow checker - let mut chiter = unsafe { &(*argptr)[..] }.chars().skip(1); - let mut ch = ' '; - while match chiter.next() { - Some(m) => { - ch = m; - true + }, + "-w" | "--widths" => options.widths = true, + "--" => { + seq_args.extend(iter); + break; + } + _ => { + if arg.len() > 1 && arg.starts_with('-') { + let argptr: *const String = &arg; // escape from the borrow checker + let mut chiter = unsafe { &(*argptr)[..] }.chars().skip(1); + let mut ch = ' '; + while match chiter.next() { + Some(m) => { + ch = m; + true + } + None => false, + } { + match ch { + 'h' => { + print_help(); + return Err(0); } - None => false, - } { - match ch { - 'h' => { - print_help(); - return Err(0); - } - 'V' => { - print_version(); - return Err(0); - } - 's' => match iter.next() { - Some(sep) => { - options.separator = sep; - let next = chiter.next(); - if next.is_some() { - show_error!( - "unexpected character ('{}')", - next.unwrap() - ); - return Err(1); - } - } - None => { - show_error!("expected a separator after {}", arg); + 'V' => { + print_version(); + return Err(0); + } + 's' => match iter.next() { + Some(sep) => { + options.separator = sep; + let next = chiter.next(); + if let Some(n) = next { + show_error!("unexpected character ('{}')", n); return Err(1); } - }, - 't' => match iter.next() { - Some(term) => { - options.terminator = Some(term); - let next = chiter.next(); - if next.is_some() { - show_error!( - "unexpected character ('{}')", - next.unwrap() - ); - return Err(1); - } - } - None => { - show_error!("expected a terminator after {}", arg); + } + None => { + show_error!("expected a separator after {}", arg); + return Err(1); + } + }, + 't' => match iter.next() { + Some(term) => { + options.terminator = Some(term); + let next = chiter.next(); + if let Some(n) = next { + show_error!("unexpected character ('{}')", n); return Err(1); } - }, - 'w' => options.widths = true, - _ => { - seq_args.push(arg); - break; } + None => { + show_error!("expected a terminator after {}", arg); + return Err(1); + } + }, + 'w' => options.widths = true, + _ => { + seq_args.push(arg); + break; } } - } else { - seq_args.push(arg); } + } else { + seq_args.push(arg); } - }, - None => break, - } + } + }; } Ok(seq_args) } @@ -189,11 +180,11 @@ pub fn uumain(args: Vec) -> i32 { Ok(m) => m, Err(f) => return f, }; - if free.len() < 1 || free.len() > 3 { + if free.is_empty() || free.len() > 3 { crash!( 1, "too {} operands.\nTry '{} --help' for more information.", - if free.len() < 1 { "few" } else { "many" }, + if free.is_empty() { "few" } else { "many" }, NAME ); } @@ -233,7 +224,7 @@ pub fn uumain(args: Vec) -> i32 { }; let last = { let slice = &free[free.len() - 1][..]; - padding = cmp::max(padding, slice.find('.').unwrap_or(slice.len())); + padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len())); match parse_float(slice) { Ok(n) => n, Err(s) => { @@ -272,6 +263,7 @@ fn done_printing(next: f64, step: f64, last: f64) -> bool { } } +#[allow(clippy::too_many_arguments)] fn print_seq( first: f64, step: f64, diff --git a/src/shred/Cargo.toml b/src/shred/Cargo.toml index 634c3ee6319..3a1ee6da750 100644 --- a/src/shred/Cargo.toml +++ b/src/shred/Cargo.toml @@ -2,20 +2,21 @@ name = "shred" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_shred" path = "shred.rs" [dependencies] -rand = "0.5" filetime = "0.2.1" getopts = "0.2.18" libc = "0.2.42" +rand = "0.5" time = "0.1.40" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "shred" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/shred/shred.rs b/src/shred/shred.rs index c62b0e179c4..80b040539c6 100644 --- a/src/shred/shred.rs +++ b/src/shred/shred.rs @@ -18,8 +18,8 @@ use std::cell::{Cell, RefCell}; use std::fs; use std::fs::{File, OpenOptions}; use std::io; -use std::io::SeekFrom; use std::io::prelude::*; +use std::io::SeekFrom; use std::path::{Path, PathBuf}; #[macro_use] @@ -31,7 +31,7 @@ const BLOCK_SIZE: usize = 512; const NAMESET: &str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_."; // Patterns as shown in the GNU coreutils shred implementation -const PATTERNS: [&'static [u8]; 22] = [ +const PATTERNS: [&[u8]; 22] = [ b"\x00", b"\xFF", b"\x55", @@ -76,7 +76,7 @@ impl FilenameGenerator { indices.push(0); } FilenameGenerator { - name_len: name_len, + name_len, nameset_indices: RefCell::new(indices), exhausted: Cell::new(false), } @@ -137,12 +137,12 @@ impl<'a> BytesGenerator<'a> { }; BytesGenerator { - total_bytes: total_bytes, + total_bytes, bytes_generated: Cell::new(0u64), block_size: BLOCK_SIZE, - exact: exact, - gen_type: gen_type, - rng: rng, + exact, + gen_type, + rng, } } } @@ -290,7 +290,7 @@ fn show_help(opts: &getopts::Options) { println!("Delete FILE(s) if --remove (-u) is specified. The default is not to remove"); println!("the files because it is common to operate on device files like /dev/hda,"); println!("and those files usually should not be removed."); - println!(""); + println!(); println!( "CAUTION: Note that {} relies on a very important assumption:", NAME @@ -302,20 +302,20 @@ fn show_help(opts: &getopts::Options) { NAME ); println!("not effective, or is not guaranteed to be effective in all file system modes:"); - println!(""); + println!(); println!("* log-structured or journaled file systems, such as those supplied with"); println!("AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)"); - println!(""); + println!(); println!("* file systems that write redundant data and carry on even if some writes"); println!("fail, such as RAID-based file systems"); - println!(""); + println!(); println!("* file systems that make snapshots, such as Network Appliance's NFS server"); - println!(""); + println!(); println!("* file systems that cache in temporary locations, such as NFS"); println!("version 3 clients"); - println!(""); + println!(); println!("* compressed file systems"); - println!(""); + println!(); println!("In the case of ext3 file systems, the above disclaimer applies"); println!( "(and {} is thus of limited effectiveness) only in data=journal mode,", @@ -329,7 +329,7 @@ fn show_help(opts: &getopts::Options) { println!("Ext3 journaling modes can be changed by adding the data=something option"); println!("to the mount options for a particular file system in the /etc/fstab file,"); println!("as documented in the mount man page (man mount)."); - println!(""); + println!(); println!("In addition, file system backups and remote mirrors may contain copies"); println!("of the file that cannot be removed, and that will allow a shredded file"); println!("to be recovered later."); @@ -338,9 +338,7 @@ fn show_help(opts: &getopts::Options) { // TODO: Add support for all postfixes here up to and including EiB // http://www.gnu.org/software/coreutils/manual/coreutils.html#Block-size fn get_size(size_str_opt: Option) -> Option { - if size_str_opt.is_none() { - return None; - } + size_str_opt.as_ref()?; let mut size_str = size_str_opt.as_ref().unwrap().clone(); // Immutably look at last character of size string @@ -371,8 +369,8 @@ fn get_size(size_str_opt: Option) -> Option { Some(coeff * unit) } -fn pass_name(pass_type: &PassType) -> String { - match *pass_type { +fn pass_name(pass_type: PassType) -> String { + match pass_type { PassType::Random => String::from("random"), PassType::Pattern(bytes) => { let mut s: String = String::new(); @@ -426,8 +424,8 @@ fn wipe_file( pass_sequence.push(PassType::Pattern(*p)); } } - for i in 0..remainder { - pass_sequence.push(PassType::Pattern(PATTERNS[i])); + for pattern in PATTERNS.iter().take(remainder) { + pass_sequence.push(PassType::Pattern(pattern)); } rand::thread_rng().shuffle(&mut pass_sequence[..]); // randomize the order of application @@ -453,7 +451,7 @@ fn wipe_file( for (i, pass_type) in pass_sequence.iter().enumerate() { if verbose { - let pass_name: String = pass_name(pass_type); + let pass_name: String = pass_name(*pass_type); if total_passes.to_string().len() == 1 { println!( "{}: {}: pass {}/{} ({})... ", @@ -475,7 +473,8 @@ fn wipe_file( } } // size is an optional argument for exactly how many bytes we want to shred - do_pass(&mut file, path, *pass_type, size, exact).expect("File write pass failed"); // Ignore failed writes; just keep trying + do_pass(&mut file, path, *pass_type, size, exact).expect("File write pass failed"); + // Ignore failed writes; just keep trying } } @@ -572,11 +571,8 @@ fn do_remove(path: &Path, orig_filename: &str, verbose: bool) -> Result<(), io:: } let renamed_path: Option = wipe_name(&path, verbose); - match renamed_path { - Some(rp) => { - fs::remove_file(rp)?; - } - None => (), + if let Some(rp) = renamed_path { + fs::remove_file(rp)?; } if verbose { diff --git a/src/shuf/Cargo.toml b/src/shuf/Cargo.toml index 9e04c2046b1..66cee9e9831 100644 --- a/src/shuf/Cargo.toml +++ b/src/shuf/Cargo.toml @@ -2,7 +2,8 @@ name = "shuf" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_shuf" @@ -11,8 +12,8 @@ path = "shuf.rs" [dependencies] getopts = "0.2.18" rand = "0.5" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "shuf" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/shuf/shuf.rs b/src/shuf/shuf.rs index ee0d1c91c7b..7843ff565e3 100644 --- a/src/shuf/shuf.rs +++ b/src/shuf/shuf.rs @@ -123,14 +123,14 @@ With no FILE, or when FILE is -, read standard input.", let mut evec = matches .free .iter() - .map(|a| a.as_bytes()) + .map(String::as_bytes) .collect::>(); find_seps(&mut evec, sep); shuf_bytes(&mut evec, repeat, count, sep, output, random); } Mode::InputRange((b, e)) => { let rvec = (b..e).map(|x| format!("{}", x)).collect::>(); - let mut rvec = rvec.iter().map(|a| a.as_bytes()).collect::>(); + let mut rvec = rvec.iter().map(String::as_bytes).collect::>(); shuf_bytes(&mut rvec, repeat, count, sep, output, random); } Mode::Default => { @@ -156,9 +156,8 @@ fn read_input_file(filename: &str) -> Vec { }); let mut data = Vec::new(); - match file.read_to_end(&mut data) { - Err(e) => crash!(1, "failed reading '{}': {}", filename, e), - Ok(_) => (), + if let Err(e) = file.read_to_end(&mut data) { + crash!(1, "failed reading '{}': {}", filename, e) }; data @@ -228,7 +227,6 @@ fn shuf_bytes( len >>= 1; len_mod <<= 1; } - drop(len); let mut count = count; while count > 0 && !input.is_empty() { diff --git a/src/sleep/Cargo.toml b/src/sleep/Cargo.toml index 5dff8703aeb..825dc92a266 100644 --- a/src/sleep/Cargo.toml +++ b/src/sleep/Cargo.toml @@ -2,7 +2,8 @@ name = "sleep" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_sleep" @@ -10,11 +11,8 @@ path = "sleep.rs" [dependencies] getopts = "0.2.18" - -[dependencies.uucore] -version = "0.0.1" -features = ["parse_time"] +uucore = { version = "0.0.2", features = ["parse_time"] } [[bin]] name = "sleep" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/sleep/sleep.rs b/src/sleep/sleep.rs index f27c42be5a4..ca05560b7e7 100644 --- a/src/sleep/sleep.rs +++ b/src/sleep/sleep.rs @@ -63,12 +63,14 @@ specified by the sum of their values.", } fn sleep(args: Vec) { - let sleep_dur = args.iter().fold(Duration::new(0, 0), |result, arg| { - match uucore::parse_time::from_str(&arg[..]) { - Ok(m) => m + result, - Err(f) => crash!(1, "{}", f), - } - }); + let sleep_dur = + args.iter().fold( + Duration::new(0, 0), + |result, arg| match uucore::parse_time::from_str(&arg[..]) { + Ok(m) => m + result, + Err(f) => crash!(1, "{}", f), + }, + ); thread::sleep(sleep_dur); } diff --git a/src/sort/Cargo.toml b/src/sort/Cargo.toml index f221ec05411..22f0d0fdcdc 100644 --- a/src/sort/Cargo.toml +++ b/src/sort/Cargo.toml @@ -2,7 +2,8 @@ name = "sort" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_sort" @@ -10,13 +11,10 @@ path = "sort.rs" [dependencies] getopts = "0.2.18" -semver = "0.9.0" itertools = "0.8.0" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +semver = "0.9.0" +uucore = { version = "0.0.2", features = ["fs"] } [[bin]] name = "sort" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/sort/sort.rs b/src/sort/sort.rs index 81ea58a26f4..8340778b05b 100644 --- a/src/sort/sort.rs +++ b/src/sort/sort.rs @@ -16,15 +16,15 @@ extern crate itertools; #[macro_use] extern crate uucore; +use itertools::Itertools; +use semver::Version; use std::cmp::Ordering; use std::collections::BinaryHeap; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Lines, Read, Write}; use std::mem::replace; use std::path::Path; -use uucore::fs::is_stdin_interactive; -use semver::Version; -use itertools::Itertools; // for Iterator::dedup() +use uucore::fs::is_stdin_interactive; // for Iterator::dedup() static NAME: &str = "sort"; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -49,7 +49,7 @@ struct Settings { unique: bool, check: bool, ignore_case: bool, - compare_fns: Vec Ordering>, + compare_fns: Vec Ordering>, } impl Default for Settings { @@ -106,20 +106,17 @@ impl<'a> FileMerger<'a> { fn new(settings: &'a Settings) -> FileMerger<'a> { FileMerger { heap: BinaryHeap::new(), - settings: settings, + settings, } } fn push_file(&mut self, mut lines: Lines>>) { - match lines.next() { - Some(Ok(next_line)) => { - let mergeable_file = MergeableFile { - lines: lines, - current_line: next_line, - settings: &self.settings, - }; - self.heap.push(mergeable_file); - } - _ => {} + if let Some(Ok(next_line)) = lines.next() { + let mergeable_file = MergeableFile { + lines, + current_line: next_line, + settings: &self.settings, + }; + self.heap.push(mergeable_file); } } } @@ -254,13 +251,13 @@ With no FILE, or when FILE is -, read standard input.", SortMode::HumanNumeric => human_numeric_size_compare, SortMode::Month => month_compare, SortMode::Version => version_compare, - SortMode::Default => String::cmp, + SortMode::Default => default_compare, }); if !settings.stable { match settings.mode { SortMode::Default => {} - _ => settings.compare_fns.push(String::cmp), + _ => settings.compare_fns.push(default_compare), } } @@ -302,12 +299,10 @@ fn exec(files: Vec, settings: &Settings) -> i32 { } else { print_sorted(file_merger, &settings.outfile) } + } else if settings.unique { + print_sorted(lines.iter().dedup(), &settings.outfile) } else { - if settings.unique { - print_sorted(lines.iter().dedup(), &settings.outfile) - } else { - print_sorted(lines.iter(), &settings.outfile) - } + print_sorted(lines.iter(), &settings.outfile) } 0 @@ -337,14 +332,14 @@ fn exec_check_file(lines: Lines>>, settings: &Settings) // line, no matter what our merging function does. if let Some(_last_line_or_next_error) = errors.next() { println!("sort: disorder in line {}", first_error_index); - return 1; + 1 } else { // first "error" was actually the last line. - return 0; + 0 } } else { // unwrapped_lines was empty. Empty files are defined to be sorted. - return 0; + 0 } } @@ -352,13 +347,13 @@ fn sort_by(lines: &mut Vec, settings: &Settings) { lines.sort_by(|a, b| compare_by(a, b, &settings)) } -fn compare_by(a: &String, b: &String, settings: &Settings) -> Ordering { +fn compare_by(a: &str, b: &str, settings: &Settings) -> Ordering { // Convert to uppercase if necessary let (a_upper, b_upper): (String, String); let (a, b) = if settings.ignore_case { a_upper = a.to_uppercase(); b_upper = b.to_uppercase(); - (&a_upper, &b_upper) + (&*a_upper, &*b_upper) } else { (a, b) }; @@ -373,7 +368,7 @@ fn compare_by(a: &String, b: &String, settings: &Settings) -> Ordering { } } } - return Ordering::Equal; + Ordering::Equal } /// Parse the beginning string into an f64, returning -inf instead of NaN on errors. @@ -385,20 +380,23 @@ fn permissive_f64_parse(a: &str) -> f64 { // GNU sort treats "NaN" as non-number in numeric, so it needs special care. match a.split_whitespace().next() { None => std::f64::NEG_INFINITY, - Some(sa) => { - match sa.parse::() { - Ok(a) if a.is_nan() => std::f64::NEG_INFINITY, - Ok(a) => a, - Err(_) => std::f64::NEG_INFINITY, - } - } + Some(sa) => match sa.parse::() { + Ok(a) if a.is_nan() => std::f64::NEG_INFINITY, + Ok(a) => a, + Err(_) => std::f64::NEG_INFINITY, + }, } } +fn default_compare(a: &str, b: &str) -> Ordering { + a.cmp(b) +} + /// Compares two floating point numbers, with errors being assumed to be -inf. /// Stops coercing at the first whitespace char, so 1e2 will parse as 100 but /// 1,000 will parse as -inf. -fn numeric_compare(a: &String, b: &String) -> Ordering { +fn numeric_compare(a: &str, b: &str) -> Ordering { + #![allow(clippy::comparison_chain)] let fa = permissive_f64_parse(a); let fb = permissive_f64_parse(b); // f64::cmp isn't implemented because NaN messes with it @@ -412,11 +410,9 @@ fn numeric_compare(a: &String, b: &String) -> Ordering { } } -fn human_numeric_convert(a: &String) -> f64 { - let int_iter = a.chars(); - let suffix_iter = a.chars(); - let int_str: String = int_iter.take_while(|c| c.is_numeric()).collect(); - let suffix = suffix_iter.skip_while(|c| c.is_numeric()).next(); +fn human_numeric_convert(a: &str) -> f64 { + let int_str: String = a.chars().take_while(|c| c.is_numeric()).collect(); + let suffix = a.chars().find(|c| !c.is_numeric()); let int_part = match int_str.parse::() { Ok(i) => i, Err(_) => -1f64, @@ -434,9 +430,11 @@ fn human_numeric_convert(a: &String) -> f64 { /// Compare two strings as if they are human readable sizes. /// AKA 1M > 100k -fn human_numeric_size_compare(a: &String, b: &String) -> Ordering { +fn human_numeric_size_compare(a: &str, b: &str) -> Ordering { + #![allow(clippy::comparison_chain)] let fa = human_numeric_convert(a); let fb = human_numeric_convert(b); + // f64::cmp isn't implemented (due to NaN issues); implement directly instead if fa > fb { Ordering::Greater } else if fa < fb { @@ -464,8 +462,9 @@ enum Month { } /// Parse the beginning string into a Month, returning Month::Unknown on errors. -fn month_parse(line: &String) -> Month { - match line.split_whitespace() +fn month_parse(line: &str) -> Month { + match line + .split_whitespace() .next() .unwrap() .to_uppercase() @@ -487,13 +486,15 @@ fn month_parse(line: &String) -> Month { } } -fn month_compare(a: &String, b: &String) -> Ordering { +fn month_compare(a: &str, b: &str) -> Ordering { month_parse(a).cmp(&month_parse(b)) } -fn version_compare(a: &String, b: &String) -> Ordering { +fn version_compare(a: &str, b: &str) -> Ordering { + #![allow(clippy::comparison_chain)] let ver_a = Version::parse(a); let ver_b = Version::parse(b); + // Version::cmp is not implemented; implement comparison directly if ver_a > ver_b { Ordering::Greater } else if ver_a < ver_b { @@ -520,12 +521,9 @@ where for line in iter { let str = format!("{}\n", line); - match file.write_all(str.as_bytes()) { - Err(e) => { - show_error!("sort: {0}", e.to_string()); - panic!("Write failed"); - } - Ok(_) => (), + if let Err(e) = file.write_all(str.as_bytes()) { + show_error!("sort: {0}", e.to_string()); + panic!("Write failed"); } } } diff --git a/src/split/Cargo.toml b/src/split/Cargo.toml index 8bf0d202257..ece2eca1ff2 100644 --- a/src/split/Cargo.toml +++ b/src/split/Cargo.toml @@ -2,7 +2,8 @@ name = "split" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_split" @@ -10,8 +11,8 @@ path = "split.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "split" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/split/split.rs b/src/split/split.rs index ff57e52a28f..e06bb33f8e8 100644 --- a/src/split/split.rs +++ b/src/split/split.rs @@ -108,16 +108,13 @@ size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is settings.strategy_param = "1000".to_owned(); let strategies = vec!["b", "C", "l"]; for e in &strategies { - match matches.opt_str(*e) { - Some(a) => { - if settings.strategy == "l" { - settings.strategy = (*e).to_owned(); - settings.strategy_param = a; - } else { - crash!(1, "{}: cannot split in more than one way", NAME) - } + if let Some(a) = matches.opt_str(*e) { + if settings.strategy == "l" { + settings.strategy = (*e).to_owned(); + settings.strategy_param = a; + } else { + crash!(1, "{}: cannot split in more than one way", NAME) } - None => {} } } @@ -159,15 +156,15 @@ struct LineSplitter { } impl LineSplitter { - fn new(settings: &Settings) -> Box { + fn new(settings: &Settings) -> LineSplitter { let n = match settings.strategy_param.parse() { Ok(a) => a, Err(e) => crash!(1, "invalid number of lines: {}", e), }; - Box::new(LineSplitter { + LineSplitter { saved_lines_to_write: n, lines_to_write: n, - }) as Box + } } } @@ -190,7 +187,7 @@ struct ByteSplitter { } impl ByteSplitter { - fn new(settings: &Settings) -> Box { + fn new(settings: &Settings) -> ByteSplitter { let mut strategy_param: Vec = settings.strategy_param.chars().collect(); let suffix = strategy_param.pop().unwrap(); let multiplier = match suffix { @@ -216,12 +213,12 @@ impl ByteSplitter { Err(e) => crash!(1, "invalid number of bytes: {}", e), } }; - Box::new(ByteSplitter { + ByteSplitter { saved_bytes_to_write: n * multiplier, bytes_to_write: n * multiplier, break_on_line_end: settings.strategy == "b", require_whole_line: false, - }) as Box + } } } @@ -248,6 +245,7 @@ impl Splitter for ByteSplitter { } // (1, 3) -> "aab" +#[allow(clippy::many_single_char_names)] fn str_prefix(i: usize, width: usize) -> String { let mut c = "".to_owned(); let mut n = i; @@ -263,6 +261,7 @@ fn str_prefix(i: usize, width: usize) -> String { } // (1, 3) -> "001" +#[allow(clippy::many_single_char_names)] fn num_prefix(i: usize, width: usize) -> String { let mut c = "".to_owned(); let mut n = i; @@ -293,8 +292,8 @@ fn split(settings: &Settings) -> i32 { }); let mut splitter: Box = match settings.strategy.as_ref() { - "l" => LineSplitter::new(settings), - "b" | "C" => ByteSplitter::new(settings), + "l" => Box::new(LineSplitter::new(settings)), + "b" | "C" => Box::new(ByteSplitter::new(settings)), a => crash!(1, "strategy {} not supported", a), }; @@ -320,7 +319,8 @@ fn split(settings: &Settings) -> i32 { num_prefix(fileno, settings.suffix_length) } else { str_prefix(fileno, settings.suffix_length) - }.as_ref(), + } + .as_ref(), ); if fileno != 0 { diff --git a/src/stat/Cargo.toml b/src/stat/Cargo.toml index 992ca7f8842..df7700e715a 100644 --- a/src/stat/Cargo.toml +++ b/src/stat/Cargo.toml @@ -2,7 +2,8 @@ name = "stat" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_stat" @@ -11,11 +12,8 @@ path = "stat.rs" [dependencies] getopts = "0.2.18" time = "0.1.40" - -[dependencies.uucore] -version = "0.0.1" -features = ["entries"] +uucore = { version = "0.0.2", features = ["entries"] } [[bin]] name = "stat" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/stat/fsext.rs b/src/stat/fsext.rs index 851361b090b..3a36c92961b 100644 --- a/src/stat/fsext.rs +++ b/src/stat/fsext.rs @@ -10,9 +10,12 @@ pub use super::uucore::libc; extern crate time; use self::time::Timespec; -pub use libc::{c_int, mode_t, strerror, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, - S_IFREG, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, - S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR}; +pub use libc::{ + c_int, mode_t, strerror, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, + S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, + S_IXGRP, S_IXOTH, S_IXUSR, +}; +use std::time::UNIX_EPOCH; pub trait BirthTime { fn pretty_birth(&self) -> String; @@ -24,25 +27,25 @@ impl BirthTime for Metadata { fn pretty_birth(&self) -> String { self.created() .ok() - .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok()) - .map(|e| pretty_time(e.as_secs() as i64, e.subsec_nanos() as i64)) - .unwrap_or("-".to_owned()) + .and_then(|t| t.duration_since(UNIX_EPOCH).ok()) + .map(|e| pretty_time(e.as_secs() as i64, i64::from(e.subsec_nanos()))) + .unwrap_or_else(|| "-".to_owned()) } fn birth(&self) -> String { self.created() .ok() - .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok()) + .and_then(|t| t.duration_since(UNIX_EPOCH).ok()) .map(|e| format!("{}", e.as_secs())) - .unwrap_or("0".to_owned()) + .unwrap_or_else(|| "0".to_owned()) } } #[macro_export] macro_rules! has { - ($mode:expr, $perm:expr) => ( + ($mode:expr, $perm:expr) => { $mode & $perm != 0 - ) + }; } pub fn pretty_time(sec: i64, nsec: i64) -> String { @@ -137,22 +140,43 @@ pub fn pretty_access(mode: mode_t) -> String { result } -use std::mem::{self, transmute}; -use std::path::Path; use std::borrow::Cow; -use std::ffi::CString; use std::convert::{AsRef, From}; -use std::error::Error; +use std::ffi::CString; use std::io::Error as IOError; +use std::mem; +use std::path::Path; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "android", target_os = "freebsd"))] +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "android", + target_os = "freebsd" +))] use libc::statfs as Sstatfs; -#[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "bitrig", target_os = "dragonfly"))] +#[cfg(any( + target_os = "openbsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "bitrig", + target_os = "dragonfly" +))] use libc::statvfs as Sstatfs; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "android", target_os = "freebsd"))] +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "android", + target_os = "freebsd" +))] use libc::statfs as statfs_fn; -#[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "openbsd", target_os = "bitrig", target_os = "dragonfly"))] +#[cfg(any( + target_os = "openbsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "bitrig", + target_os = "dragonfly" +))] use libc::statvfs as statfs_fn; pub trait FsMeta { @@ -219,8 +243,9 @@ impl FsMeta for Sstatfs { // struct statvfs, containing an unsigned long f_fsid #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "linux"))] fn fsid(&self) -> u64 { - let f_fsid: &[u32; 2] = unsafe { transmute(&self.f_fsid) }; - (f_fsid[0] as u64) << 32 | f_fsid[1] as u64 + let f_fsid: &[u32; 2] = + unsafe { &*(&self.f_fsid as *const uucore::libc::fsid_t as *const [u32; 2]) }; + (u64::from(f_fsid[0])) << 32 | u64::from(f_fsid[1]) } #[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "linux")))] fn fsid(&self) -> u64 { @@ -260,131 +285,131 @@ where let errno = IOError::last_os_error().raw_os_error().unwrap_or(0); Err(CString::from_raw(strerror(errno)) .into_string() - .unwrap_or("Unknown Error".to_owned())) + .unwrap_or_else(|_| "Unknown Error".to_owned())) } } } } - Err(e) => Err(e.description().to_owned()), + Err(e) => Err(e.to_string()), } } pub fn pretty_fstype<'a>(fstype: i64) -> Cow<'a, str> { match fstype { - 0x61636673 => "acfs".into(), + 0x6163_6673 => "acfs".into(), 0xADF5 => "adfs".into(), 0xADFF => "affs".into(), - 0x5346414F => "afs".into(), - 0x09041934 => "anon-inode FS".into(), - 0x61756673 => "aufs".into(), + 0x5346_414F => "afs".into(), + 0x0904_1934 => "anon-inode FS".into(), + 0x6175_6673 => "aufs".into(), 0x0187 => "autofs".into(), - 0x42465331 => "befs".into(), - 0x62646576 => "bdevfs".into(), - 0x1BADFACE => "bfs".into(), - 0xCAFE4A11 => "bpf_fs".into(), - 0x42494E4D => "binfmt_misc".into(), - 0x9123683E => "btrfs".into(), - 0x73727279 => "btrfs_test".into(), - 0x00C36400 => "ceph".into(), - 0x0027E0EB => "cgroupfs".into(), - 0xFF534D42 => "cifs".into(), - 0x73757245 => "coda".into(), - 0x012FF7B7 => "coh".into(), - 0x62656570 => "configfs".into(), - 0x28CD3D45 => "cramfs".into(), - 0x453DCD28 => "cramfs-wend".into(), - 0x64626720 => "debugfs".into(), + 0x4246_5331 => "befs".into(), + 0x6264_6576 => "bdevfs".into(), + 0x1BAD_FACE => "bfs".into(), + 0xCAFE_4A11 => "bpf_fs".into(), + 0x4249_4E4D => "binfmt_misc".into(), + 0x9123_683E => "btrfs".into(), + 0x7372_7279 => "btrfs_test".into(), + 0x00C3_6400 => "ceph".into(), + 0x0027_E0EB => "cgroupfs".into(), + 0xFF53_4D42 => "cifs".into(), + 0x7375_7245 => "coda".into(), + 0x012F_F7B7 => "coh".into(), + 0x6265_6570 => "configfs".into(), + 0x28CD_3D45 => "cramfs".into(), + 0x453D_CD28 => "cramfs-wend".into(), + 0x6462_6720 => "debugfs".into(), 0x1373 => "devfs".into(), 0x1CD1 => "devpts".into(), 0xF15F => "ecryptfs".into(), - 0xDE5E81E4 => "efivarfs".into(), - 0x00414A53 => "efs".into(), + 0xDE5E_81E4 => "efivarfs".into(), + 0x0041_4A53 => "efs".into(), 0x5DF5 => "exofs".into(), 0x137D => "ext".into(), 0xEF53 => "ext2/ext3".into(), 0xEF51 => "ext2".into(), - 0xF2F52010 => "f2fs".into(), + 0xF2F5_2010 => "f2fs".into(), 0x4006 => "fat".into(), - 0x19830326 => "fhgfs".into(), - 0x65735546 => "fuseblk".into(), - 0x65735543 => "fusectl".into(), - 0x0BAD1DEA => "futexfs".into(), - 0x01161970 => "gfs/gfs2".into(), - 0x47504653 => "gpfs".into(), + 0x1983_0326 => "fhgfs".into(), + 0x6573_5546 => "fuseblk".into(), + 0x6573_5543 => "fusectl".into(), + 0x0BAD_1DEA => "futexfs".into(), + 0x0116_1970 => "gfs/gfs2".into(), + 0x4750_4653 => "gpfs".into(), 0x4244 => "hfs".into(), 0x482B => "hfs+".into(), 0x4858 => "hfsx".into(), - 0x00C0FFEE => "hostfs".into(), - 0xF995E849 => "hpfs".into(), - 0x958458F6 => "hugetlbfs".into(), - 0x11307854 => "inodefs".into(), - 0x013111A8 => "ibrix".into(), - 0x2BAD1DEA => "inotifyfs".into(), + 0x00C0_FFEE => "hostfs".into(), + 0xF995_E849 => "hpfs".into(), + 0x9584_58F6 => "hugetlbfs".into(), + 0x1130_7854 => "inodefs".into(), + 0x0131_11A8 => "ibrix".into(), + 0x2BAD_1DEA => "inotifyfs".into(), 0x9660 => "isofs".into(), 0x4004 => "isofs".into(), 0x4000 => "isofs".into(), 0x07C0 => "jffs".into(), 0x72B6 => "jffs2".into(), - 0x3153464A => "jfs".into(), - 0x6B414653 => "k-afs".into(), - 0xC97E8168 => "logfs".into(), - 0x0BD00BD0 => "lustre".into(), - 0x5346314D => "m1fs".into(), + 0x3153_464A => "jfs".into(), + 0x6B41_4653 => "k-afs".into(), + 0xC97E_8168 => "logfs".into(), + 0x0BD0_0BD0 => "lustre".into(), + 0x5346_314D => "m1fs".into(), 0x137F => "minix".into(), 0x138F => "minix (30 char.)".into(), 0x2468 => "minix v2".into(), 0x2478 => "minix v2 (30 char.)".into(), 0x4D5A => "minix3".into(), - 0x19800202 => "mqueue".into(), + 0x1980_0202 => "mqueue".into(), 0x4D44 => "msdos".into(), 0x564C => "novell".into(), 0x6969 => "nfs".into(), - 0x6E667364 => "nfsd".into(), + 0x6E66_7364 => "nfsd".into(), 0x3434 => "nilfs".into(), - 0x6E736673 => "nsfs".into(), - 0x5346544E => "ntfs".into(), + 0x6E73_6673 => "nsfs".into(), + 0x5346_544E => "ntfs".into(), 0x9FA1 => "openprom".into(), - 0x7461636F => "ocfs2".into(), - 0x794C7630 => "overlayfs".into(), - 0xAAD7AAEA => "panfs".into(), - 0x50495045 => "pipefs".into(), - 0x7C7C6673 => "prl_fs".into(), + 0x7461_636F => "ocfs2".into(), + 0x794C_7630 => "overlayfs".into(), + 0xAAD7_AAEA => "panfs".into(), + 0x5049_5045 => "pipefs".into(), + 0x7C7C_6673 => "prl_fs".into(), 0x9FA0 => "proc".into(), - 0x6165676C => "pstorefs".into(), + 0x6165_676C => "pstorefs".into(), 0x002F => "qnx4".into(), - 0x68191122 => "qnx6".into(), - 0x858458F6 => "ramfs".into(), - 0x52654973 => "reiserfs".into(), + 0x6819_1122 => "qnx6".into(), + 0x8584_58F6 => "ramfs".into(), + 0x5265_4973 => "reiserfs".into(), 0x7275 => "romfs".into(), - 0x67596969 => "rpc_pipefs".into(), - 0x73636673 => "securityfs".into(), - 0xF97CFF8C => "selinux".into(), - 0x43415D53 => "smackfs".into(), + 0x6759_6969 => "rpc_pipefs".into(), + 0x7363_6673 => "securityfs".into(), + 0xF97C_FF8C => "selinux".into(), + 0x4341_5D53 => "smackfs".into(), 0x517B => "smb".into(), - 0xFE534D42 => "smb2".into(), - 0xBEEFDEAD => "snfs".into(), - 0x534F434B => "sockfs".into(), - 0x73717368 => "squashfs".into(), - 0x62656572 => "sysfs".into(), - 0x012FF7B6 => "sysv2".into(), - 0x012FF7B5 => "sysv4".into(), - 0x01021994 => "tmpfs".into(), - 0x74726163 => "tracefs".into(), - 0x24051905 => "ubifs".into(), - 0x15013346 => "udf".into(), - 0x00011954 => "ufs".into(), - 0x54190100 => "ufs".into(), + 0xFE53_4D42 => "smb2".into(), + 0xBEEF_DEAD => "snfs".into(), + 0x534F_434B => "sockfs".into(), + 0x7371_7368 => "squashfs".into(), + 0x6265_6572 => "sysfs".into(), + 0x012F_F7B6 => "sysv2".into(), + 0x012F_F7B5 => "sysv4".into(), + 0x0102_1994 => "tmpfs".into(), + 0x7472_6163 => "tracefs".into(), + 0x2405_1905 => "ubifs".into(), + 0x1501_3346 => "udf".into(), + 0x0001_1954 => "ufs".into(), + 0x5419_0100 => "ufs".into(), 0x9FA2 => "usbdevfs".into(), - 0x01021997 => "v9fs".into(), - 0xBACBACBC => "vmhgfs".into(), - 0xA501FCF5 => "vxfs".into(), - 0x565A4653 => "vzfs".into(), - 0x53464846 => "wslfs".into(), - 0xABBA1974 => "xenfs".into(), - 0x012FF7B4 => "xenix".into(), - 0x58465342 => "xfs".into(), - 0x012FD16D => "xia".into(), - 0x2FC12FC1 => "zfs".into(), + 0x0102_1997 => "v9fs".into(), + 0xBACB_ACBC => "vmhgfs".into(), + 0xA501_FCF5 => "vxfs".into(), + 0x565A_4653 => "vzfs".into(), + 0x5346_4846 => "wslfs".into(), + 0xABBA_1974 => "xenfs".into(), + 0x012F_F7B4 => "xenix".into(), + 0x5846_5342 => "xfs".into(), + 0x012F_D16D => "xia".into(), + 0x2FC1_2FC1 => "zfs".into(), other => format!("UNKNOWN ({:#x})", other).into(), } } diff --git a/src/stat/stat.rs b/src/stat/stat.rs index e8fd4165c7a..3493452fddb 100644 --- a/src/stat/stat.rs +++ b/src/stat/stat.rs @@ -19,29 +19,31 @@ pub use fsext::*; extern crate uucore; use uucore::entries; -use std::{cmp, fs, iter}; +use std::borrow::Cow; +use std::convert::AsRef; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::borrow::Cow; use std::os::unix::fs::{FileTypeExt, MetadataExt}; use std::path::Path; -use std::convert::AsRef; +use std::{cmp, fs, iter}; macro_rules! check_bound { - ($str: ident, $bound:expr, $beg: expr, $end: expr) => ( + ($str: ident, $bound:expr, $beg: expr, $end: expr) => { if $end >= $bound { return Err(format!("‘{}’: invalid directive", &$str[$beg..$end])); } - - ) + }; } macro_rules! fill_string { - ($str: ident, $c: expr, $cnt: expr) => ( - iter::repeat($c).take($cnt).map(|c| $str.push(c)).all(|_| true) - ) + ($str: ident, $c: expr, $cnt: expr) => { + iter::repeat($c) + .take($cnt) + .map(|c| $str.push(c)) + .all(|_| true) + }; } macro_rules! extend_digits { - ($str: expr, $min: expr) => ( + ($str: expr, $min: expr) => { if $min > $str.len() { let mut pad = String::with_capacity($min); fill_string!(pad, '0', $min - $str.len()); @@ -50,10 +52,10 @@ macro_rules! extend_digits { } else { $str.into() } - ) + }; } macro_rules! pad_and_print { - ($result: ident, $str: ident, $left: expr, $width: expr, $padding: expr) => ( + ($result: ident, $str: ident, $left: expr, $width: expr, $padding: expr) => { if $str.len() < $width { if $left { $result.push_str($str.as_ref()); @@ -66,7 +68,7 @@ macro_rules! pad_and_print { $result.push_str($str.as_ref()); } print!("{}", $result); - ) + }; } macro_rules! print_adjusted { ($str: ident, $left: expr, $width: expr, $padding: expr) => { @@ -82,13 +84,13 @@ macro_rules! print_adjusted { field_width -= $prefix.len(); } pad_and_print!(result, $str, $left, field_width, $padding); - } + }; } -static NAME: &'static str = "stat"; -static VERSION: &'static str = env!("CARGO_PKG_VERSION"); +static NAME: &str = "stat"; +static VERSION: &str = env!("CARGO_PKG_VERSION"); -const MOUNT_INFO: &'static str = "/etc/mtab"; +const MOUNT_INFO: &str = "/etc/mtab"; pub const F_ALTER: u8 = 1; pub const F_ZERO: u8 = 1 << 1; pub const F_LEFT: u8 = 1 << 2; @@ -136,7 +138,7 @@ impl ScanUtil for str { Some('-') | Some('+') | Some('0'..='9') => i += 1, _ => return None, } - while let Some(c) = chars.next() { + for c in chars { match c { '0'..='9' => i += 1, _ => break, @@ -155,10 +157,10 @@ impl ScanUtil for str { 16 => 2, _ => return None, }; - let mut chars = self.chars().enumerate(); + let chars = self.chars().enumerate(); let mut res = 0_u32; let mut offset = 0_usize; - while let Some((i, c)) = chars.next() { + for (i, c) in chars { if i >= count { break; } @@ -183,7 +185,7 @@ impl ScanUtil for str { } } -pub fn group_num<'a>(s: &'a str) -> Cow<'a, str> { +pub fn group_num(s: &str) -> Cow { assert!(s.chars().all(char::is_numeric)); if s.len() < 4 { return s.into(); @@ -209,6 +211,7 @@ pub struct Stater { default_dev_tokens: Vec, } +#[allow(clippy::cognitive_complexity)] fn print_it(arg: &str, otype: OutputType, flag: u8, width: usize, precision: i32) { // If the precision is given as just '.', the precision is taken to be zero. // A negative precision is taken as if the precision were omitted. @@ -369,12 +372,9 @@ impl Stater { let mut precision = -1_i32; let mut j = i; - match fmtstr[j..].scan_num::() { - Some((field_width, offset)) => { - width = field_width; - j += offset; - } - None => (), + if let Some((field_width, offset)) = fmtstr[j..].scan_num::() { + width = field_width; + j += offset; } check_bound!(fmtstr, bound, old, j); @@ -396,9 +396,9 @@ impl Stater { i = j; tokens.push(Token::Directive { - width: width, - flag: flag, - precision: precision, + width, + flag, + precision, format: chars[i], }) } @@ -458,7 +458,7 @@ impl Stater { let fmtstr = if matches.opt_present("printf") { matches.opt_str("printf").expect("Invalid format string") } else { - matches.opt_str("format").unwrap_or("".to_owned()) + matches.opt_str("format").unwrap_or_else(|| "".to_owned()) }; let use_printf = matches.opt_present("printf"); @@ -478,12 +478,12 @@ impl Stater { None } else { let reader = BufReader::new( - File::open(MOUNT_INFO).expect(&format!("Failed to read {}", MOUNT_INFO)), + File::open(MOUNT_INFO).unwrap_or_else(|_| panic!("Failed to read {}", MOUNT_INFO)), ); let mut mount_list = reader .lines() - .filter_map(|s| s.ok()) - .filter_map(|line| line.split_whitespace().nth(1).map(|s| s.to_owned())) + .filter_map(Result::ok) + .filter_map(|line| line.split_whitespace().nth(1).map(ToOwned::to_owned)) .collect::>(); // Reverse sort. The longer comes first. mount_list.sort_by(|a, b| b.cmp(a)); @@ -492,12 +492,12 @@ impl Stater { Ok(Stater { follow: matches.opt_present("dereference"), - showfs: showfs, + showfs, from_user: !fmtstr.is_empty(), files: matches.free, - default_tokens: default_tokens, - default_dev_tokens: default_dev_tokens, - mount_list: mount_list, + default_tokens, + default_dev_tokens, + mount_list, }) } @@ -507,7 +507,7 @@ impl Stater { Err(_) => return None, }; if let Some(ref mount_list) = self.mount_list { - for root in mount_list.into_iter() { + for root in mount_list.iter() { if path.starts_with(root) { return Some(root.clone()); } @@ -541,10 +541,10 @@ impl Stater { &self.default_dev_tokens }; - for t in tokens.into_iter() { - match t { - &Token::Char(c) => print!("{}", c), - &Token::Directive { + for t in tokens.iter() { + match *t { + Token::Char(c) => print!("{}", c), + Token::Directive { flag, width, precision, @@ -608,7 +608,7 @@ impl Stater { // group name of owner 'G' => { arg = entries::gid2grp(meta.gid()) - .unwrap_or("UNKNOWN".to_owned()); + .unwrap_or_else(|_| "UNKNOWN".to_owned()); otype = OutputType::Str; } // number of hard links @@ -683,7 +683,7 @@ impl Stater { // user name of owner 'U' => { arg = entries::uid2usr(meta.uid()) - .unwrap_or("UNKNOWN".to_owned()); + .unwrap_or_else(|_| "UNKNOWN".to_owned()); otype = OutputType::Str; } @@ -750,10 +750,10 @@ impl Stater { Ok(meta) => { let tokens = &self.default_tokens; - for t in tokens.into_iter() { - match t { - &Token::Char(c) => print!("{}", c), - &Token::Directive { + for t in tokens.iter() { + match *t { + Token::Char(c) => print!("{}", c), + Token::Directive { flag, width, precision, diff --git a/src/stdbuf/Cargo.toml b/src/stdbuf/Cargo.toml index d31e175b19d..037750b0589 100644 --- a/src/stdbuf/Cargo.toml +++ b/src/stdbuf/Cargo.toml @@ -2,6 +2,7 @@ name = "stdbuf" version = "0.0.1" authors = [] +license = "MIT" build = "build.rs" [lib] @@ -11,11 +12,11 @@ path = "stdbuf.rs" [dependencies] getopts = "0.2.18" tempdir = "0.3.7" -uucore = "0.0.1" +uucore = "0.0.2" [build-dependencies] libstdbuf = { path="libstdbuf" } [[bin]] name = "stdbuf" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/stdbuf/build.rs b/src/stdbuf/build.rs index 25659230180..90b16c908fc 100644 --- a/src/stdbuf/build.rs +++ b/src/stdbuf/build.rs @@ -2,7 +2,7 @@ use std::env; use std::fs; use std::path::Path; -#[path = "../../mkmain.rs"] +#[path = "../#common/mkmain.rs"] mod mkmain; #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))] @@ -30,7 +30,7 @@ fn main() { let libstdbuf = format!( "{}/../../{}/{}/deps/liblibstdbuf{}", manifest_dir, - env::var("CARGO_TARGET_DIR").unwrap_or("target".to_string()), + env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".to_string()), profile, platform::DYLIB_EXT ); diff --git a/src/stdbuf/libstdbuf/Cargo.toml b/src/stdbuf/libstdbuf/Cargo.toml index 3ee7ef0bd3b..425905f2b97 100644 --- a/src/stdbuf/libstdbuf/Cargo.toml +++ b/src/stdbuf/libstdbuf/Cargo.toml @@ -2,6 +2,7 @@ name = "libstdbuf" version = "0.0.1" authors = [] +license = "MIT" [lib] name = "libstdbuf" @@ -10,9 +11,9 @@ path = "libstdbuf.rs" crate-type = ["cdylib", "rlib"] [dependencies] -uucore = "0.0.1" -libc = "0.2" cpp = "0.4" +libc = "0.2" +uucore = "0.0.2" [build-dependencies] cpp_build = "0.4" diff --git a/src/stdbuf/libstdbuf/libstdbuf.rs b/src/stdbuf/libstdbuf/libstdbuf.rs index 1e290d00574..3b8423114e7 100644 --- a/src/stdbuf/libstdbuf/libstdbuf.rs +++ b/src/stdbuf/libstdbuf/libstdbuf.rs @@ -9,7 +9,7 @@ use libc::{c_char, c_int, size_t, FILE, _IOFBF, _IOLBF, _IONBF}; use std::env; use std::ptr; -cpp!{{ +cpp! {{ #include extern "C" { @@ -55,6 +55,8 @@ fn set_buffer(stream: *mut FILE, value: &str) { } } +/// # Safety +/// ToDO ... (safety note) #[no_mangle] pub unsafe extern "C" fn __stdbuf() { if let Ok(val) = env::var("_STDBUF_E") { diff --git a/src/stdbuf/stdbuf.rs b/src/stdbuf/stdbuf.rs index 516672d831e..b91f86bb558 100644 --- a/src/stdbuf/stdbuf.rs +++ b/src/stdbuf/stdbuf.rs @@ -16,12 +16,12 @@ extern crate tempdir; extern crate uucore; use getopts::{Matches, Options}; -use tempdir::TempDir; use std::fs::File; use std::io::{self, Write}; use std::os::unix::process::ExitStatusExt; use std::path::PathBuf; use std::process::Command; +use tempdir::TempDir; static NAME: &str = "stdbuf"; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -51,7 +51,12 @@ enum OkMsg { Version, } -#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd", target_os = "dragonflybsd"))] +#[cfg(any( + target_os = "linux", + target_os = "freebsd", + target_os = "netbsd", + target_os = "dragonflybsd" +))] fn preload_strings() -> (&'static str, &'static str) { ("LD_PRELOAD", "so") } @@ -61,7 +66,13 @@ fn preload_strings() -> (&'static str, &'static str) { ("DYLD_LIBRARY_PATH", "dylib") } -#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd", target_os = "dragonflybsd", target_os = "macos")))] +#[cfg(not(any( + target_os = "linux", + target_os = "freebsd", + target_os = "netbsd", + target_os = "dragonflybsd", + target_os = "macos" +)))] fn preload_strings() -> (&'static str, &'static str) { crash!(1, "Command not supported for this operating system!") } @@ -73,8 +84,7 @@ fn print_version() { fn print_usage(opts: &Options) { let brief = "Run COMMAND, with modified buffering operations for its standard streams\n \ Mandatory arguments to long options are mandatory for short options too."; - let explanation = - "If MODE is 'L' the corresponding stream will be line buffered.\n \ + let explanation = "If MODE is 'L' the corresponding stream will be line buffered.\n \ This option is invalid with standard input.\n\n \ If MODE is '0' the corresponding stream will be unbuffered.\n\n \ Otherwise MODE is a number which may be followed by one of the following:\n\n \ @@ -86,15 +96,15 @@ fn print_usage(opts: &Options) { Also some filters (like 'dd' and 'cat' etc.) don't use streams for I/O, \ and are thus unaffected by 'stdbuf' settings.\n"; println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage: stdbuf OPTION... COMMAND"); - println!(""); + println!(); println!("{}\n{}", opts.usage(brief), explanation); } fn parse_size(size: &str) -> Option { let ext = size.trim_start_matches(|c: char| c.is_digit(10)); - let num = size.trim_end_matches(|c: char| c.is_alphabetic()); + let num = size.trim_end_matches(char::is_alphabetic); let mut recovered = num.to_owned(); recovered.push_str(ext); if recovered != size { @@ -279,9 +289,9 @@ pub fn uumain(args: Vec) -> i32 { }; match process.wait() { Ok(status) => match status.code() { - Some(i) => return i, + Some(i) => i, None => crash!(1, "process killed by signal {}", status.signal().unwrap()), }, Err(e) => crash!(1, "{}", e), - }; + } } diff --git a/src/sum/Cargo.toml b/src/sum/Cargo.toml index 572f49e2b22..5203a05a059 100644 --- a/src/sum/Cargo.toml +++ b/src/sum/Cargo.toml @@ -2,7 +2,8 @@ name = "sum" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_sum" @@ -10,8 +11,8 @@ path = "sum.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "sum" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/sum/sum.rs b/src/sum/sum.rs index 1fd7a6202f7..797cbae046b 100644 --- a/src/sum/sum.rs +++ b/src/sum/sum.rs @@ -31,7 +31,7 @@ fn bsd_sum(mut reader: Box) -> (usize, u16) { blocks_read += 1; for &byte in buf[..n].iter() { checksum = (checksum >> 1) + ((checksum & 1) << 15); - checksum = checksum.wrapping_add(byte as u16); + checksum = checksum.wrapping_add(u16::from(byte)); } } _ => break, @@ -51,7 +51,7 @@ fn sysv_sum(mut reader: Box) -> (usize, u16) { Ok(n) if n != 0 => { blocks_read += 1; for &byte in buf[..n].iter() { - ret = ret.wrapping_add(byte as u32); + ret = ret.wrapping_add(u32::from(byte)); } } _ => break, diff --git a/src/sync/Cargo.toml b/src/sync/Cargo.toml index 361a570ded5..b1fa5632902 100644 --- a/src/sync/Cargo.toml +++ b/src/sync/Cargo.toml @@ -2,7 +2,8 @@ name = "sync" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_sync" @@ -10,14 +11,11 @@ path = "sync.rs" [dependencies] getopts = "0.2.18" +kernel32-sys = "0.2.2" libc = "0.2.42" +uucore = { version = "0.0.2", features = ["wide"] } winapi = { version = "0.3", features = ["handleapi", "winerror"] } -kernel32-sys = "0.2.2" - -[dependencies.uucore] -version = "0.0.1" -features = ["wide"] [[bin]] name = "sync" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/sync/sync.rs b/src/sync/sync.rs index c9608e519b4..2b976d5db6b 100644 --- a/src/sync/sync.rs +++ b/src/sync/sync.rs @@ -42,27 +42,29 @@ mod platform { mod platform { extern crate kernel32; extern crate winapi; - use std::mem; + use self::winapi::shared::minwindef; + use self::winapi::shared::winerror; + use self::winapi::um::handleapi; + use self::winapi::um::winbase; + use self::winapi::um::winnt; use std::fs::OpenOptions; + use std::mem; use std::os::windows::prelude::*; use uucore::wide::{FromWide, ToWide}; - use self::winapi::um::winbase; - use self::winapi::um::winnt; - use self::winapi::shared::minwindef; - use self::winapi::um::handleapi; - use self::winapi::shared::winerror; unsafe fn flush_volume(name: &str) { let name_wide = name.to_wide_null(); if kernel32::GetDriveTypeW(name_wide.as_ptr()) == winbase::DRIVE_FIXED { let sliced_name = &name[..name.len() - 1]; // eliminate trailing backslash match OpenOptions::new().write(true).open(sliced_name) { - Ok(file) => if kernel32::FlushFileBuffers(file.as_raw_handle()) == 0 { - crash!( - kernel32::GetLastError() as i32, - "failed to flush file buffer" - ); - }, + Ok(file) => { + if kernel32::FlushFileBuffers(file.as_raw_handle()) == 0 { + crash!( + kernel32::GetLastError() as i32, + "failed to flush file buffer" + ); + } + } Err(e) => crash!( e.raw_os_error().unwrap_or(1), "failed to create volume handle" @@ -72,6 +74,7 @@ mod platform { } unsafe fn find_first_volume() -> (String, winnt::HANDLE) { + #[allow(deprecated)] let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized(); let handle = kernel32::FindFirstVolumeW(name.as_mut_ptr(), name.len() as minwindef::DWORD); if handle == handleapi::INVALID_HANDLE_VALUE { @@ -87,6 +90,7 @@ mod platform { let (first_volume, next_volume_handle) = find_first_volume(); let mut volumes = vec![first_volume]; loop { + #[allow(deprecated)] let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized(); if kernel32::FindNextVolumeW( next_volume_handle, @@ -147,7 +151,7 @@ pub fn uumain(args: Vec) -> i32 { fn version() { println!("{} (uutils) {}", NAME, VERSION); println!("The MIT License"); - println!(""); + println!(); println!("Author -- Alexander Fomin."); } diff --git a/src/tac/Cargo.toml b/src/tac/Cargo.toml index 0f09e1a9bfd..1094b113f9e 100644 --- a/src/tac/Cargo.toml +++ b/src/tac/Cargo.toml @@ -2,7 +2,8 @@ name = "tac" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_tac" @@ -10,8 +11,8 @@ path = "tac.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "tac" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/tac/tac.rs b/src/tac/tac.rs index eb6786359e2..61bff94a79b 100644 --- a/src/tac/tac.rs +++ b/src/tac/tac.rs @@ -103,12 +103,9 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { }); let mut data = Vec::new(); - match file.read_to_end(&mut data) { - Err(e) => { - show_warning!("failed to read '{}': {}", filename, e); - continue; - } - Ok(_) => (), + if let Err(e) = file.read_to_end(&mut data) { + show_warning!("failed to read '{}': {}", filename, e); + continue; }; // find offsets in string of all separators @@ -126,7 +123,6 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { i += 1; } } - drop(i); // if there isn't a separator at the end of the file, fake it if offsets.is_empty() || *offsets.last().unwrap() < data.len() - slen { diff --git a/src/tail/Cargo.toml b/src/tail/Cargo.toml index 337ea34362a..f3290471b4d 100644 --- a/src/tail/Cargo.toml +++ b/src/tail/Cargo.toml @@ -2,7 +2,8 @@ name = "tail" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_tail" @@ -13,11 +14,11 @@ getopts = "0.2.18" kernel32-sys = "0.2.2" libc = "0.2.42" winapi = "0.3" -uucore = "0.0.1" +uucore = "0.0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" [[bin]] name = "tail" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/tail/platform/redox.rs b/src/tail/platform/redox.rs index c0d43cb1cd9..a3a8c5fa039 100644 --- a/src/tail/platform/redox.rs +++ b/src/tail/platform/redox.rs @@ -1,6 +1,6 @@ extern crate syscall; -use self::syscall::{Error, EPERM, ENOSYS}; +use self::syscall::{Error, ENOSYS, EPERM}; pub type Pid = usize; diff --git a/src/tail/platform/windows.rs b/src/tail/platform/windows.rs index ebab7d32bed..fbf9351d4b5 100644 --- a/src/tail/platform/windows.rs +++ b/src/tail/platform/windows.rs @@ -12,7 +12,7 @@ extern crate winapi; use self::kernel32::{CloseHandle, OpenProcess, WaitForSingleObject}; use self::winapi::shared::minwindef::DWORD; -use self::winapi::um::winbase::{WAIT_OBJECT_0, WAIT_FAILED}; +use self::winapi::um::winbase::{WAIT_FAILED, WAIT_OBJECT_0}; use self::winapi::um::winnt::{HANDLE, SYNCHRONIZE}; pub type Pid = DWORD; diff --git a/src/tail/tail.rs b/src/tail/tail.rs index c6bbbfdf22c..fa21691eacb 100755 --- a/src/tail/tail.rs +++ b/src/tail/tail.rs @@ -48,7 +48,7 @@ struct Settings { impl Default for Settings { fn default() -> Settings { Settings { - mode: FilterMode::Lines(10, '\n' as u8), + mode: FilterMode::Lines(10, b'\n'), sleep_msec: 1000, beginning: false, follow: false, @@ -57,13 +57,14 @@ impl Default for Settings { } } +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: Vec) -> i32 { let mut settings: Settings = Default::default(); // handle obsolete -number syntax let options = match obsolete(&args[1..]) { (args, Some(n)) => { - settings.mode = FilterMode::Lines(n, '\n' as u8); + settings.mode = FilterMode::Lines(n, b'\n'); args } (args, None) => args, @@ -114,16 +115,12 @@ pub fn uumain(args: Vec) -> i32 { settings.follow = given_options.opt_present("f"); if settings.follow { - match given_options.opt_str("s") { - Some(n) => { - let parsed: Option = n.parse().ok(); - match parsed { - Some(m) => settings.sleep_msec = m * 1000, - None => {} - } + if let Some(n) = given_options.opt_str("s") { + let parsed: Option = n.parse().ok(); + if let Some(m) = parsed { + settings.sleep_msec = m * 1000 } - None => {} - }; + } } if let Some(pid_str) = given_options.opt_str("pid") { @@ -150,15 +147,15 @@ pub fn uumain(args: Vec) -> i32 { slice = &slice[1..]; } match parse_size(slice) { - Ok(m) => settings.mode = FilterMode::Lines(m, '\n' as u8), + Ok(m) => settings.mode = FilterMode::Lines(m, b'\n'), Err(e) => { - show_error!("{}", e.description()); + show_error!("{}", e.to_string()); return 1; } } } - None => match given_options.opt_str("c") { - Some(n) => { + None => { + if let Some(n) = given_options.opt_str("c") { let mut slice: &str = n.as_ref(); if slice.chars().next().unwrap_or('_') == '+' { settings.beginning = true; @@ -167,13 +164,12 @@ pub fn uumain(args: Vec) -> i32 { match parse_size(slice) { Ok(m) => settings.mode = FilterMode::Bytes(m), Err(e) => { - show_error!("{}", e.description()); + show_error!("{}", e.to_string()); return 1; } } } - None => {} - }, + } }; if given_options.opt_present("z") { @@ -249,7 +245,7 @@ impl Error for ParseSizeErr { impl fmt::Display for ParseSizeErr { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "{}", Error::description(self)) + write!(f, "{}", self.to_string()) } } @@ -276,7 +272,7 @@ pub fn parse_size(mut size_slice: &str) -> Result { 1024u64 }; - let exponent = if size_slice.len() > 0 { + let exponent = if !size_slice.is_empty() { let mut has_suffix = true; let exp = match size_slice.chars().last().unwrap_or('_') { 'K' | 'k' => 1u64, @@ -316,7 +312,7 @@ pub fn parse_size(mut size_slice: &str) -> Result { let value: Option = size_slice.parse().ok(); value .map(|v| Ok(multiplier * v)) - .unwrap_or(Err(ParseSizeErr::parse_failure(size_slice))) + .unwrap_or_else(|| Err(ParseSizeErr::parse_failure(size_slice))) } } @@ -333,7 +329,7 @@ fn obsolete(options: &[String]) -> (Vec, Option) { let current = options[a].clone(); let current = current.as_bytes(); - if current.len() > 1 && current[0] == '-' as u8 { + if current.len() > 1 && current[0] == b'-' { let len = current.len(); for pos in 1..len { // Ensure that the argument is only made out of digits @@ -456,7 +452,7 @@ fn bounded_tail(mut file: &File, settings: &Settings) { // Find the position in the file to start printing from. match settings.mode { FilterMode::Lines(mut count, delimiter) => { - backwards_thru_file(&mut file, size, &mut buf, delimiter, &mut |byte| { + backwards_thru_file(&file, size, &mut buf, delimiter, &mut |byte| { if byte == delimiter { count -= 1; count == 0 @@ -476,7 +472,7 @@ fn bounded_tail(mut file: &File, settings: &Settings) { let mut stdout = stdout(); for b in &buf[0..bytes_read] { - print_byte(&mut stdout, b); + print_byte(&mut stdout, *b); } if bytes_read == 0 { @@ -549,7 +545,7 @@ fn unbounded_tail(reader: &mut BufReader, settings: &Settings) { } let mut stdout = stdout(); for datum in &ringbuf { - print_byte(&mut stdout, datum); + print_byte(&mut stdout, *datum); } } } @@ -560,8 +556,8 @@ fn is_seekable(file: &mut T) -> bool { } #[inline] -fn print_byte(stdout: &mut T, ch: &u8) { - if let Err(err) = stdout.write(&[*ch]) { +fn print_byte(stdout: &mut T, ch: u8) { + if let Err(err) = stdout.write(&[ch]) { crash!(1, "{}", err); } } diff --git a/src/tee/Cargo.toml b/src/tee/Cargo.toml index d1d86612a8b..c688b9bdcb6 100644 --- a/src/tee/Cargo.toml +++ b/src/tee/Cargo.toml @@ -2,7 +2,8 @@ name = "tee" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_tee" @@ -11,8 +12,8 @@ path = "tee.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "tee" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/tee/tee.rs b/src/tee/tee.rs index de77d855575..c2cfc1ac012 100644 --- a/src/tee/tee.rs +++ b/src/tee/tee.rs @@ -80,7 +80,10 @@ fn options(args: &[String]) -> Result { fn exec(options: Options) -> Result<()> { match options.print_and_exit { - Some(text) => Ok(println!("{}", text)), + Some(text) => { + println!("{}", text); + Ok(()) + } None => tee(options), } } @@ -118,10 +121,7 @@ fn open(name: String, append: bool) -> Box { Err(_) => Box::new(sink()), } }; - Box::new(NamedWriter { - inner: inner, - path: path, - }) as Box + Box::new(NamedWriter { inner, path }) as Box } struct MultiWriter { diff --git a/src/test/Cargo.toml b/src/test/Cargo.toml index 92a4dd14112..4dc6877e8bc 100644 --- a/src/test/Cargo.toml +++ b/src/test/Cargo.toml @@ -2,7 +2,8 @@ name = "test" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_test" @@ -10,11 +11,11 @@ path = "test.rs" [dependencies] libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" [[bin]] name = "test" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/test/test.rs b/src/test/test.rs index 907b4488810..0631d292e90 100644 --- a/src/test/test.rs +++ b/src/test/test.rs @@ -14,8 +14,8 @@ extern crate libc; extern crate syscall; use std::collections::HashMap; -use std::ffi::OsString; use std::env::args_os; +use std::ffi::OsString; use std::str::from_utf8; static NAME: &str = "test"; @@ -25,7 +25,8 @@ static NAME: &str = "test"; pub fn uumain(_: Vec) -> i32 { let args = args_os().collect::>(); // This is completely disregarding valid windows paths that aren't valid unicode - let args = args.iter() + let args = args + .iter() .map(|a| a.to_str().unwrap().as_bytes()) .collect::>(); if args.is_empty() { @@ -53,7 +54,7 @@ pub fn uumain(_: Vec) -> i32 { } fn one(args: &[&[u8]]) -> bool { - args[0].len() > 0 + !args[0].is_empty() } fn two(args: &[&[u8]], error: &mut bool) -> bool { @@ -149,7 +150,9 @@ fn isatty(fd: &[u8]) -> bool { .and_then(|s| s.parse().ok()) .map_or(false, |i| { #[cfg(not(target_os = "redox"))] - unsafe { libc::isatty(i) == 1 } + unsafe { + libc::isatty(i) == 1 + } #[cfg(target_os = "redox")] syscall::dup(i, b"termios").map(syscall::close).is_ok() }) @@ -212,13 +215,13 @@ enum Precedence { } fn parse_expr(mut args: &[&[u8]], error: &mut bool) -> bool { - if args.len() == 0 { + if args.is_empty() { false } else { let hashmap = setup_hashmap(); let lhs = dispatch(&mut args, error); - if args.len() > 0 { + if !args.is_empty() { parse_expr_helper(&hashmap, &mut args, lhs, Precedence::Unknown, error) } else { lhs @@ -237,11 +240,11 @@ fn parse_expr_helper<'a>( *error = true; &min_prec }); - while !*error && args.len() > 0 && prec as usize >= min_prec as usize { + while !*error && !args.is_empty() && prec as usize >= min_prec as usize { let op = args[0]; *args = &(*args)[1..]; let mut rhs = dispatch(args, error); - while args.len() > 0 { + while !args.is_empty() { let subprec = *hashmap.get(&args[0]).unwrap_or_else(|| { *error = true; &min_prec @@ -269,7 +272,7 @@ fn parse_expr_helper<'a>( Precedence::Paren => unimplemented!(), // TODO: implement parentheses _ => unreachable!(), }; - if args.len() > 0 { + if !args.is_empty() { prec = *hashmap.get(&args[0]).unwrap_or_else(|| { *error = true; &min_prec @@ -342,10 +345,10 @@ enum PathCondition { #[cfg(not(windows))] fn path(path: &[u8], cond: PathCondition) -> bool { - use std::os::unix::fs::{MetadataExt, FileTypeExt}; - use std::os::unix::ffi::OsStrExt; - use std::fs::{self, Metadata}; use std::ffi::OsStr; + use std::fs::{self, Metadata}; + use std::os::unix::ffi::OsStrExt; + use std::os::unix::fs::{FileTypeExt, MetadataExt}; let path = OsStr::from_bytes(path); @@ -362,15 +365,17 @@ fn path(path: &[u8], cond: PathCondition) -> bool { #[cfg(not(target_os = "redox"))] let (uid, gid) = unsafe { (libc::getuid(), libc::getgid()) }; #[cfg(target_os = "redox")] - let (uid, gid) = (syscall::getuid().unwrap() as u32, - syscall::getgid().unwrap() as u32); + let (uid, gid) = ( + syscall::getuid().unwrap() as u32, + syscall::getgid().unwrap() as u32, + ); if uid == metadata.uid() { metadata.mode() & ((p as u32) << 6) != 0 } else if gid == metadata.gid() { metadata.mode() & ((p as u32) << 3) != 0 } else { - metadata.mode() & ((p as u32)) != 0 + metadata.mode() & (p as u32) != 0 } }; @@ -382,7 +387,9 @@ fn path(path: &[u8], cond: PathCondition) -> bool { let metadata = match metadata { Ok(metadata) => metadata, - Err(_) => { return false; } + Err(_) => { + return false; + } }; let file_type = metadata.file_type(); diff --git a/src/timeout/Cargo.toml b/src/timeout/Cargo.toml index 69fd52e4fa0..1169d87eb68 100644 --- a/src/timeout/Cargo.toml +++ b/src/timeout/Cargo.toml @@ -2,7 +2,8 @@ name = "timeout" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_timeout" @@ -12,11 +13,8 @@ path = "timeout.rs" getopts = "0.2.18" libc = "0.2.42" time = "0.1.40" - -[dependencies.uucore] -version = "0.0.1" -features = ["parse_time", "process"] +uucore = { version = "0.0.2", features = ["parse_time", "process"] } [[bin]] name = "timeout" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/touch/Cargo.toml b/src/touch/Cargo.toml index d2930378062..2b78a33f34b 100644 --- a/src/touch/Cargo.toml +++ b/src/touch/Cargo.toml @@ -2,7 +2,8 @@ name = "touch" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_touch" @@ -12,11 +13,8 @@ path = "touch.rs" filetime = "0.2.1" getopts = "0.2.18" time = "0.1.40" - -[dependencies.uucore] -version = "0.0.1" -features = ["libc"] +uucore = { version = "0.0.2", features = ["libc"] } [[bin]] name = "touch" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/touch/touch.rs b/src/touch/touch.rs index ed75a767651..a129f6db87d 100644 --- a/src/touch/touch.rs +++ b/src/touch/touch.rs @@ -95,9 +95,9 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") || matches.free.is_empty() { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage: {} [OPTION]... FILE...", NAME); - println!(""); + println!(); println!( "{}", opts.usage( @@ -164,14 +164,16 @@ pub fn uumain(args: Vec) -> i32 { let st = stat(path, !matches.opt_present("no-dereference")); let time = matches.opt_strs("time"); - if !(matches.opt_present("a") || time.contains(&"access".to_owned()) + if !(matches.opt_present("a") + || time.contains(&"access".to_owned()) || time.contains(&"atime".to_owned()) || time.contains(&"use".to_owned())) { atime = st.0; } - if !(matches.opt_present("m") || time.contains(&"modify".to_owned()) + if !(matches.opt_present("m") + || time.contains(&"modify".to_owned()) || time.contains(&"mtime".to_owned())) { mtime = st.1; @@ -182,10 +184,8 @@ pub fn uumain(args: Vec) -> i32 { if let Err(e) = set_symlink_file_times(path, atime, mtime) { show_warning!("cannot touch '{}': {}", path, e); } - } else { - if let Err(e) = filetime::set_file_times(path, atime, mtime) { - show_warning!("cannot touch '{}': {}", path, e); - } + } else if let Err(e) = filetime::set_file_times(path, atime, mtime) { + show_warning!("cannot touch '{}': {}", path, e); } } diff --git a/src/tr/Cargo.toml b/src/tr/Cargo.toml index 4c3421b74cb..2c4cc01326a 100644 --- a/src/tr/Cargo.toml +++ b/src/tr/Cargo.toml @@ -2,18 +2,19 @@ name = "tr" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_tr" path = "tr.rs" [dependencies] -getopts = "0.2.18" bit-set = "0.5.0" fnv = "1.0.5" -uucore = "0.0.1" +getopts = "0.2.18" +uucore = "0.0.2" [[bin]] name = "tr" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/tr/expand.rs b/src/tr/expand.rs index d9d38688ab5..a10fb43c891 100644 --- a/src/tr/expand.rs +++ b/src/tr/expand.rs @@ -12,7 +12,7 @@ use std::char::from_u32; use std::cmp::min; use std::iter::Peekable; -use std::ops::Range; +use std::ops::RangeInclusive; #[inline] fn unescape_char(c: char) -> char { @@ -43,7 +43,7 @@ impl<'a> Iterator for Unescape<'a> { #[inline] fn next(&mut self) -> Option { - if self.string.len() == 0 { + if self.string.is_empty() { return None; } @@ -64,7 +64,7 @@ impl<'a> Iterator for Unescape<'a> { } pub struct ExpandSet<'a> { - range: Range, + range: RangeInclusive, unesc: Peekable>, } @@ -88,14 +88,13 @@ impl<'a> Iterator for ExpandSet<'a> { if let Some(first) = self.unesc.next() { // peek ahead - if self.unesc.peek() == Some(&'-') && match self.unesc.size_hint() { - (x, _) if x > 1 => true, // there's a range here; record it in our internal Range struct - _ => false, - } { + if self.unesc.peek() == Some(&'-') && self.unesc.size_hint().0 > 1 { self.unesc.next(); // this is the '-' let last = self.unesc.next().unwrap(); // this is the end of the range - self.range = first as u32 + 1..last as u32 + 1; + { + self.range = first as u32 + 1..=last as u32; + } } return Some(first); // in any case, return the next char @@ -109,7 +108,7 @@ impl<'a> ExpandSet<'a> { #[inline] pub fn new(s: &'a str) -> ExpandSet<'a> { ExpandSet { - range: 0..0, + range: 0..=0, unesc: Unescape { string: s }.peekable(), } } diff --git a/src/tr/tr.rs b/src/tr/tr.rs index c8e28c774b5..069d0fbc45e 100644 --- a/src/tr/tr.rs +++ b/src/tr/tr.rs @@ -33,7 +33,7 @@ static VERSION: &str = env!("CARGO_PKG_VERSION"); const BUFFER_LEN: usize = 1024; trait SymbolTranslator { - fn translate(&self, c: &char, prev_c: &char) -> Option; + fn translate(&self, c: char, prev_c: char) -> Option; } struct DeleteOperation { @@ -45,16 +45,16 @@ impl DeleteOperation { fn new(set: ExpandSet, complement: bool) -> DeleteOperation { DeleteOperation { bset: set.map(|c| c as usize).collect(), - complement: complement, + complement, } } } impl SymbolTranslator for DeleteOperation { - fn translate(&self, c: &char, _prev_c: &char) -> Option { - let uc = *c as usize; + fn translate(&self, c: char, _prev_c: char) -> Option { + let uc = c as usize; if self.complement == self.bset.contains(uc) { - Some(*c) + Some(c) } else { None } @@ -70,17 +70,17 @@ impl SqueezeOperation { fn new(squeeze_set: ExpandSet, complement: bool) -> SqueezeOperation { SqueezeOperation { squeeze_set: squeeze_set.map(|c| c as usize).collect(), - complement: complement, + complement, } } } impl SymbolTranslator for SqueezeOperation { - fn translate(&self, c: &char, prev_c: &char) -> Option { - if *prev_c == *c && self.complement != self.squeeze_set.contains(*c as usize) { + fn translate(&self, c: char, prev_c: char) -> Option { + if prev_c == c && self.complement != self.squeeze_set.contains(c as usize) { None } else { - Some(*c) + Some(c) } } } @@ -100,19 +100,19 @@ impl DeleteAndSqueezeOperation { DeleteAndSqueezeOperation { delete_set: delete_set.map(|c| c as usize).collect(), squeeze_set: squeeze_set.map(|c| c as usize).collect(), - complement: complement, + complement, } } } impl SymbolTranslator for DeleteAndSqueezeOperation { - fn translate(&self, c: &char, prev_c: &char) -> Option { - if self.complement != self.delete_set.contains(*c as usize) - || *prev_c == *c && self.squeeze_set.contains(*c as usize) + fn translate(&self, c: char, prev_c: char) -> Option { + if self.complement != self.delete_set.contains(c as usize) + || prev_c == c && self.squeeze_set.contains(c as usize) { None } else { - Some(*c) + Some(c) } } } @@ -140,8 +140,8 @@ impl TranslateOperation { } impl SymbolTranslator for TranslateOperation { - fn translate(&self, c: &char, _prev_c: &char) -> Option { - Some(*self.translate_map.get(&(*c as usize)).unwrap_or(c)) + fn translate(&self, c: char, _prev_c: char) -> Option { + Some(*self.translate_map.get(&(c as usize)).unwrap_or(&c)) } } @@ -161,7 +161,7 @@ fn translate_input( { // isolation to make borrow checker happy let filtered = buf.chars().filter_map(|c| { - let res = translator.translate(&c, &prev_c); + let res = translator.translate(c, prev_c); if res.is_some() { prev_c = c; } @@ -178,10 +178,10 @@ fn translate_input( fn usage(opts: &Options) { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [OPTIONS] SET1 [SET2]", NAME); - println!(""); + println!(); println!("{}", opts.usage("Translate or delete characters.")); } diff --git a/src/true/Cargo.toml b/src/true/Cargo.toml index 41c95aec2b9..c36c29526be 100644 --- a/src/true/Cargo.toml +++ b/src/true/Cargo.toml @@ -2,15 +2,16 @@ name = "true" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_true" path = "true.rs" [dependencies] -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "true" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/truncate/Cargo.toml b/src/truncate/Cargo.toml index a7a4cd539d6..376afafc0d7 100644 --- a/src/truncate/Cargo.toml +++ b/src/truncate/Cargo.toml @@ -2,7 +2,8 @@ name = "truncate" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_truncate" @@ -10,8 +11,8 @@ path = "truncate.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "truncate" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/truncate/truncate.rs b/src/truncate/truncate.rs index 47070d9a7bf..0358b438253 100644 --- a/src/truncate/truncate.rs +++ b/src/truncate/truncate.rs @@ -58,15 +58,15 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [OPTION]... FILE...", NAME); - println!(""); + println!(); print!( "{}", opts.usage("Shrink or extend the size of each file to the specified size.") ); - print!( + println!( " SIZE is an integer with an optional prefix and optional unit. The available units (K, M, G, T, P, E, Z, and Y) use the following format: @@ -83,8 +83,7 @@ file based on its current size: '<' => at most '>' => at least '/' => round down to multiple of - '%' => round up to multiple of -" + '%' => round up to multiple of" ); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -149,16 +148,20 @@ fn truncate( TruncateMode::Reference => refsize, TruncateMode::Extend => fsize + refsize, TruncateMode::Reduce => fsize - refsize, - TruncateMode::AtMost => if fsize > refsize { - refsize - } else { - fsize - }, - TruncateMode::AtLeast => if fsize < refsize { - refsize - } else { - fsize - }, + TruncateMode::AtMost => { + if fsize > refsize { + refsize + } else { + fsize + } + } + TruncateMode::AtLeast => { + if fsize < refsize { + refsize + } else { + fsize + } + } TruncateMode::RoundDown => fsize - fsize % refsize, TruncateMode::RoundUp => fsize + fsize % refsize, }; @@ -191,19 +194,21 @@ fn parse_size(size: &str) -> (u64, TruncateMode) { }; if slice.chars().last().unwrap().is_alphabetic() { slice = &slice[..slice.len() - 1]; - if slice.len() > 0 && slice.chars().last().unwrap().is_alphabetic() { + if !slice.is_empty() && slice.chars().last().unwrap().is_alphabetic() { slice = &slice[..slice.len() - 1]; } } slice - }.to_owned(); + } + .to_owned(); let mut number: u64 = match bytes.parse() { Ok(num) => num, Err(e) => crash!(1, "'{}' is not a valid number: {}", size, e), }; if size.chars().last().unwrap().is_alphabetic() { number *= match size.chars().last().unwrap().to_ascii_uppercase() { - 'B' => match size.chars() + 'B' => match size + .chars() .nth(size.len() - 2) .unwrap() .to_ascii_uppercase() diff --git a/src/tsort/Cargo.toml b/src/tsort/Cargo.toml index b2c3fe4dca8..096ba2e2e7c 100644 --- a/src/tsort/Cargo.toml +++ b/src/tsort/Cargo.toml @@ -2,7 +2,8 @@ name = "tsort" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_tsort" @@ -10,8 +11,8 @@ path = "tsort.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "tsort" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/tsort/tsort.rs b/src/tsort/tsort.rs index 72a96229da8..9a01b0cc386 100644 --- a/src/tsort/tsort.rs +++ b/src/tsort/tsort.rs @@ -36,10 +36,10 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("h") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [OPTIONS] FILE", NAME); - println!(""); + println!(); println!("{}", opts.usage("Topological sort the strings in FILE. Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline). If FILE is not passed in, stdin is used instead.")); return 0; } @@ -79,7 +79,8 @@ pub fn uumain(args: Vec) -> i32 { let mut line = String::new(); match reader.read_line(&mut line) { Ok(_) => { - let tokens: Vec = line.trim_end() + let tokens: Vec = line + .trim_end() .split_whitespace() .map(|s| s.to_owned()) .collect(); @@ -135,12 +136,12 @@ impl Graph { self.in_edges.get(to).unwrap().contains(from) } - fn init_node(&mut self, n: &String) { - self.in_edges.insert(n.clone(), HashSet::new()); - self.out_edges.insert(n.clone(), vec![]); + fn init_node(&mut self, n: &str) { + self.in_edges.insert(n.to_string(), HashSet::new()); + self.out_edges.insert(n.to_string(), vec![]); } - fn add_edge(&mut self, from: &String, to: &String) { + fn add_edge(&mut self, from: &str, to: &str) { if !self.has_node(to) { self.init_node(to); } @@ -150,8 +151,8 @@ impl Graph { } if from != to && !self.has_edge(from, to) { - self.in_edges.get_mut(to).unwrap().insert(from.clone()); - self.out_edges.get_mut(from).unwrap().push(to.clone()); + self.in_edges.get_mut(to).unwrap().insert(from.to_string()); + self.out_edges.get_mut(from).unwrap().push(to.to_string()); } } @@ -185,7 +186,7 @@ impl Graph { } fn is_acyclic(&self) -> bool { - for (_, edges) in &self.out_edges { + for edges in self.out_edges.values() { if !edges.is_empty() { return false; } diff --git a/src/tty/Cargo.toml b/src/tty/Cargo.toml index 57185ce869c..0e8a07039ff 100644 --- a/src/tty/Cargo.toml +++ b/src/tty/Cargo.toml @@ -2,7 +2,8 @@ name = "tty" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_tty" @@ -11,11 +12,8 @@ path = "tty.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" - -[dependencies.uucore] -version = "0.0.1" -features = ["fs"] +uucore = { version = "0.0.2", features = ["fs"] } [[bin]] name = "tty" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/tty/tty.rs b/src/tty/tty.rs index eaff78c964b..033f4fbcce3 100644 --- a/src/tty/tty.rs +++ b/src/tty/tty.rs @@ -41,10 +41,10 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [OPTION]...", NAME); - println!(""); + println!(); print!( "{}", opts.usage("Print the file name of the terminal connected to standard input.") diff --git a/src/uname/Cargo.toml b/src/uname/Cargo.toml index 3129adac239..8f8025a3e71 100644 --- a/src/uname/Cargo.toml +++ b/src/uname/Cargo.toml @@ -2,7 +2,8 @@ name = "uname" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_uname" @@ -11,8 +12,8 @@ path = "uname.rs" [dependencies] clap = "2.32.0" platform-info = "0.0.1" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "uname" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/unexpand/Cargo.toml b/src/unexpand/Cargo.toml index 1521a922576..c408c98d326 100644 --- a/src/unexpand/Cargo.toml +++ b/src/unexpand/Cargo.toml @@ -2,7 +2,8 @@ name = "unexpand" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_unexpand" @@ -11,8 +12,8 @@ path = "unexpand.rs" [dependencies] getopts = "0.2.18" unicode-width = "0.1.5" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "unexpand" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/unexpand/unexpand.rs b/src/unexpand/unexpand.rs index 076a68fee7f..3c680f8c480 100644 --- a/src/unexpand/unexpand.rs +++ b/src/unexpand/unexpand.rs @@ -42,7 +42,8 @@ fn tabstops_parse(s: String) -> Vec { crash!(1, "{}\n", "tab size cannot be 0"); } - if let (false, _) = nums.iter() + if let (false, _) = nums + .iter() .fold((true, 0), |(acc, last), &n| (acc && last <= n, n)) { crash!(1, "{}\n", "tab sizes must be ascending"); @@ -76,10 +77,10 @@ impl Options { }; Options { - files: files, - tabstops: tabstops, - aflag: aflag, - uflag: uflag, + files, + tabstops, + aflag, + uflag, } } } @@ -163,7 +164,7 @@ fn next_tabstop(tabstops: &[usize], col: usize) -> Option { Some(tabstops[0] - col % tabstops[0]) } else { // find next larger tab - match tabstops.iter().skip_while(|&&t| t <= col).next() { + match tabstops.iter().find(|&&t| t > col) { Some(t) => Some(t - col), None => None, // if there isn't one in the list, tab becomes a single space } @@ -189,13 +190,13 @@ fn write_tabs( break; } - safe_unwrap!(output.write_all("\t".as_bytes())); + safe_unwrap!(output.write_all(b"\t")); scol += nts; } } while col > scol { - safe_unwrap!(output.write_all(" ".as_bytes())); + safe_unwrap!(output.write_all(b" ")); scol += 1; } } @@ -219,7 +220,7 @@ fn unexpand(options: Options) { for file in options.files.into_iter() { let mut fh = open(file); - while match fh.read_until('\n' as u8, &mut buf) { + while match fh.read_until(b'\n', &mut buf) { Ok(s) => s > 0, Err(_) => !buf.is_empty(), } { diff --git a/src/uniq/Cargo.toml b/src/uniq/Cargo.toml index 17b014f56a9..de02b220d09 100644 --- a/src/uniq/Cargo.toml +++ b/src/uniq/Cargo.toml @@ -2,7 +2,8 @@ name = "uniq" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_uniq" @@ -10,8 +11,8 @@ path = "uniq.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "uniq" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/uniq/uniq.rs b/src/uniq/uniq.rs index ed73a278509..0b64bc08470 100644 --- a/src/uniq/uniq.rs +++ b/src/uniq/uniq.rs @@ -79,12 +79,12 @@ impl Uniq { let mut i = 0; while field < skip_fields && i < line.len() { while i < line.len() && line.chars().nth(i).unwrap().is_whitespace() { - i = i + 1; + i += 1; } while i < line.len() && !line.chars().nth(i).unwrap().is_whitespace() { - i = i + 1; + i += 1; } - field = field + 1; + field += 1; } &line[i..] } else { @@ -99,7 +99,7 @@ impl Uniq { if self.zero_terminated { 0 } else { - '\n' as u8 + b'\n' } } @@ -252,10 +252,10 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {0} [OPTION]... [FILE]...", NAME); - println!(""); + println!(); print!( "{}", opts.usage( @@ -263,7 +263,7 @@ pub fn uumain(args: Vec) -> i32 { writing to OUTPUT (or standard output)." ) ); - println!(""); + println!(); println!( "Note: '{0}' does not detect repeated lines unless they are adjacent.\n\ You may want to sort the input first, or use 'sort -u' without '{0}'.\n", diff --git a/src/unlink/Cargo.toml b/src/unlink/Cargo.toml index 2606d66c77e..de564f360de 100644 --- a/src/unlink/Cargo.toml +++ b/src/unlink/Cargo.toml @@ -2,7 +2,8 @@ name = "unlink" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_unlink" @@ -11,8 +12,8 @@ path = "unlink.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "unlink" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/unlink/unlink.rs b/src/unlink/unlink.rs index 9bca5e585bf..3c8bc71da87 100644 --- a/src/unlink/unlink.rs +++ b/src/unlink/unlink.rs @@ -18,11 +18,10 @@ extern crate libc; extern crate uucore; use getopts::Options; -use libc::{S_IFLNK, S_IFMT, S_IFREG}; use libc::{lstat, stat, unlink}; -use std::io::{Error, ErrorKind}; -use std::mem::uninitialized; +use libc::{S_IFLNK, S_IFMT, S_IFREG}; use std::ffi::CString; +use std::io::{Error, ErrorKind}; static NAME: &str = "unlink"; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -40,10 +39,10 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [FILE]... [OPTION]...", NAME); - println!(""); + println!(); println!("{}", opts.usage("Unlink the file at [FILE].")); return 0; } @@ -71,13 +70,9 @@ pub fn uumain(args: Vec) -> i32 { let c_string = CString::new(matches.free[0].clone()).unwrap(); // unwrap() cannot fail, the string comes from argv so it cannot contain a \0. let st_mode = { - let mut buf: stat = unsafe { uninitialized() }; - let result = unsafe { - lstat( - c_string.as_ptr(), - &mut buf as *mut stat, - ) - }; + #[allow(deprecated)] + let mut buf: stat = unsafe { std::mem::uninitialized() }; + let result = unsafe { lstat(c_string.as_ptr(), &mut buf as *mut stat) }; if result < 0 { crash!( diff --git a/src/uptime/Cargo.toml b/src/uptime/Cargo.toml index cf86a2e66ee..94333bf6e64 100644 --- a/src/uptime/Cargo.toml +++ b/src/uptime/Cargo.toml @@ -2,7 +2,8 @@ name = "uptime" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_uptime" @@ -11,11 +12,8 @@ path = "uptime.rs" [dependencies] getopts = "0.2.18" time = "0.1.40" - -[dependencies.uucore] -version = "0.0.1" -features = ["utmpx"] +uucore = { version = "0.0.2", features = ["utmpx"] } [[bin]] name = "uptime" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/uptime/uptime.rs b/src/uptime/uptime.rs index b2d97ee650f..186de7593e5 100644 --- a/src/uptime/uptime.rs +++ b/src/uptime/uptime.rs @@ -18,8 +18,8 @@ extern crate time; #[macro_use] extern crate uucore; // import crate time from utmpx -use uucore::libc::time_t; pub use uucore::libc; +use uucore::libc::time_t; use getopts::Options; @@ -50,10 +50,10 @@ pub fn uumain(args: Vec) -> i32 { } if matches.opt_present("help") || !matches.free.is_empty() { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {0} [OPTION]", NAME); - println!(""); + println!(); println!( "{}", opts.usage( @@ -85,13 +85,12 @@ pub fn uumain(args: Vec) -> i32 { #[cfg(unix)] fn print_loadavg() { use libc::c_double; - use std::mem::transmute; let mut avg: [c_double; 3] = [0.0; 3]; - let loads: i32 = unsafe { transmute(getloadavg(avg.as_mut_ptr(), 3)) }; + let loads: i32 = unsafe { getloadavg(avg.as_mut_ptr(), 3) }; if loads == -1 { - print!("\n"); + println!(); } else { print!("load average: "); for n in 0..loads { @@ -138,11 +137,11 @@ fn process_utmpx() -> (Option, usize) { } fn print_nusers(nusers: usize) { - if nusers == 1 { - print!("1 user, "); - } else if nusers > 1 { - print!("{} users, ", nusers); - } + match nusers.cmp(&1) { + std::cmp::Ordering::Equal => print!("1 user, "), + std::cmp::Ordering::Greater => print!("{} users, ", nusers), + _ => {} + }; } fn print_time() { @@ -173,7 +172,7 @@ fn get_uptime(boot_time: Option) -> i64 { Some(t) => { let now = time::get_time().sec; let boottime = t as i64; - ((now - boottime) * 100) + (now - boottime) * 100 } _ => -1, } @@ -189,11 +188,11 @@ fn print_uptime(upsecs: i64) { let updays = upsecs / 86400; let uphours = (upsecs - (updays * 86400)) / 3600; let upmins = (upsecs - (updays * 86400) - (uphours * 3600)) / 60; - if updays == 1 { - print!("up {:1} day, {:2}:{:02}, ", updays, uphours, upmins); - } else if updays > 1 { - print!("up {:1} days, {:2}:{:02}, ", updays, uphours, upmins); - } else { - print!("up {:2}:{:02}, ", uphours, upmins); - } + match updays.cmp(&1) { + std::cmp::Ordering::Equal => print!("up {:1} day, {:2}:{:02}, ", updays, uphours, upmins), + std::cmp::Ordering::Greater => { + print!("up {:1} days, {:2}:{:02}, ", updays, uphours, upmins) + } + _ => print!("up {:2}:{:02}, ", uphours, upmins), + }; } diff --git a/src/users/Cargo.toml b/src/users/Cargo.toml index 4ef0603736d..5ba2cc7d469 100644 --- a/src/users/Cargo.toml +++ b/src/users/Cargo.toml @@ -2,7 +2,8 @@ name = "users" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_users" @@ -10,11 +11,8 @@ path = "users.rs" [dependencies] getopts = "0.2.18" - -[dependencies.uucore] -features = ["utmpx"] -version = "0.0.1" +uucore = { version = "0.0.2", features = ["utmpx"] } [[bin]] name = "users" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/users/users.rs b/src/users/users.rs index 10fb5eca5ca..3d4311c4d04 100644 --- a/src/users/users.rs +++ b/src/users/users.rs @@ -10,7 +10,6 @@ */ /* last synced with: whoami (GNU coreutils) 8.22 */ - // Allow dead code here in order to keep all fields, constants here, for consistency. #![allow(dead_code)] @@ -37,10 +36,10 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [OPTION]... [FILE]", NAME); - println!(""); + println!(); println!( "{}", opts.usage("Output who is currently logged in according to FILE.") @@ -67,7 +66,7 @@ pub fn uumain(args: Vec) -> i32 { fn exec(filename: &str) { let mut users = Utmpx::iter_all_records() .read_from(filename) - .filter(|ut| ut.is_user_process()) + .filter(Utmpx::is_user_process) .map(|ut| ut.user()) .collect::>(); diff --git a/src/uutils/uutils.rs b/src/uutils/uutils.rs index a2481bcf73e..c90c73d02a0 100644 --- a/src/uutils/uutils.rs +++ b/src/uutils/uutils.rs @@ -12,8 +12,8 @@ include!(concat!(env!("OUT_DIR"), "/uutils_crates.rs")); use std::collections::hash_map::HashMap; -use std::path::Path; use std::io::Write; +use std::path::Path; extern crate uucore; @@ -24,10 +24,11 @@ include!(concat!(env!("OUT_DIR"), "/uutils_map.rs")); fn usage(cmap: &UtilityMap) { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {} [util [arguments...]]\n", NAME); println!("Currently defined functions:"); + #[allow(clippy::map_clone)] let mut utils: Vec<&str> = cmap.keys().map(|&s| s).collect(); utils.sort(); for util in utils { @@ -50,8 +51,10 @@ fn main() { std::process::exit(uumain(args)); } - if binary_as_util.ends_with("uutils") || binary_as_util.starts_with("uutils") - || binary_as_util.ends_with("busybox") || binary_as_util.starts_with("busybox") + if binary_as_util.ends_with("uutils") + || binary_as_util.starts_with("uutils") + || binary_as_util.ends_with("busybox") + || binary_as_util.starts_with("busybox") { args.remove(0); } else { @@ -70,7 +73,7 @@ fn main() { } // try first arg as util name. - if args.len() >= 1 { + if !args.is_empty() { let util = &args[0][..]; match umap.get(util) { diff --git a/src/wc/Cargo.toml b/src/wc/Cargo.toml index 51c59590f66..35d1f0cbfd2 100644 --- a/src/wc/Cargo.toml +++ b/src/wc/Cargo.toml @@ -2,7 +2,8 @@ name = "wc" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_wc" @@ -10,8 +11,8 @@ path = "wc.rs" [dependencies] getopts = "0.2.18" -uucore = "0.0.1" +uucore = "0.0.2" [[bin]] name = "wc" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/wc/wc.rs b/src/wc/wc.rs index 67c120e9313..8c70ff9f421 100644 --- a/src/wc/wc.rs +++ b/src/wc/wc.rs @@ -40,7 +40,10 @@ impl Settings { show_max_line_length: matches.opt_present("L"), }; - if settings.show_bytes || settings.show_chars || settings.show_lines || settings.show_words + if settings.show_bytes + || settings.show_chars + || settings.show_lines + || settings.show_words || settings.show_max_line_length { return settings; @@ -90,10 +93,10 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!("{} {}", NAME, VERSION); - println!(""); + println!(); println!("Usage:"); println!(" {0} [OPTION]... [FILE]...", NAME); - println!(""); + println!(); println!( "{}", opts.usage("Print newline, word and byte counts for each FILE") @@ -121,10 +124,10 @@ pub fn uumain(args: Vec) -> i32 { 0 } -const CR: u8 = '\r' as u8; -const LF: u8 = '\n' as u8; -const SPACE: u8 = ' ' as u8; -const TAB: u8 = '\t' as u8; +const CR: u8 = b'\r'; +const LF: u8 = b'\n'; +const SPACE: u8 = b' '; +const TAB: u8 = b'\t'; const SYN: u8 = 0x16 as u8; const FF: u8 = 0x0C as u8; @@ -254,7 +257,7 @@ fn print_stats(settings: &Settings, result: &Result, max_width: usize) { if result.title != "-" { println!(" {}", result.title); } else { - println!(""); + println!(); } } diff --git a/src/who/Cargo.toml b/src/who/Cargo.toml index 036ba672b87..3f3b3431e65 100644 --- a/src/who/Cargo.toml +++ b/src/who/Cargo.toml @@ -2,20 +2,18 @@ name = "who" version = "0.0.1" authors = [] -build = "../../mkmain.rs" +license = "MIT" +build = "../#common/mkmain.rs" [lib] name = "uu_who" path = "who.rs" -[dependencies.uucore] -version = "0.0.1" -features = ["utmpx"] - -[dependencies.clippy] -version = "0.0.212" -optional = true +[dependencies] +uucore = { version = "0.0.2", features = ["utmpx"] } +## optional +clippy = { version = "0.0.212", optional = true } [[bin]] name = "who" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/who/who.rs b/src/who/who.rs index b8fe3eb820f..a83457f1845 100644 --- a/src/who/who.rs +++ b/src/who/who.rs @@ -11,13 +11,13 @@ #[macro_use] extern crate uucore; -use uucore::utmpx::{self, time, Utmpx}; use uucore::libc::{ttyname, STDIN_FILENO, S_IWGRP}; +use uucore::utmpx::{self, time, Utmpx}; use std::borrow::Cow; use std::ffi::CStr; -use std::path::PathBuf; use std::os::unix::fs::MetadataExt; +use std::path::PathBuf; static SYNTAX: &str = "[OPTION]... [ FILE | ARG1 ARG2 ]"; static SUMMARY: &str = "Print information about users who are currently logged in."; @@ -60,7 +60,12 @@ pub fn uumain(args: Vec) -> i32 { "count", "all login names and number of users logged on", ); - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "linux", target_os = "android"))] + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "linux", + target_os = "android" + ))] opts.optflag("r", "runlevel", "print current runlevel"); opts.optflag("s", "short", "print only name, line, and time (default)"); opts.optflag("t", "time", "print last system clock change"); @@ -128,97 +133,100 @@ pub fn uumain(args: Vec) -> i32 { let mut assumptions = true; - if matches.opt_present("a") { - need_boottime = true; - need_deadprocs = true; - need_login = true; - need_initspawn = true; - need_runlevel = true; - need_clockchange = true; - need_users = true; - include_idle = true; - include_exit = true; - assumptions = false; - } + #[allow(clippy::useless_let_if_seq)] + { + if matches.opt_present("a") { + need_boottime = true; + need_deadprocs = true; + need_login = true; + need_initspawn = true; + need_runlevel = true; + need_clockchange = true; + need_users = true; + include_idle = true; + include_exit = true; + assumptions = false; + } - if matches.opt_present("b") { - need_boottime = true; - assumptions = false; - } + if matches.opt_present("b") { + need_boottime = true; + assumptions = false; + } - if matches.opt_present("d") { - need_deadprocs = true; - include_idle = true; - include_exit = true; - assumptions = false; - } + if matches.opt_present("d") { + need_deadprocs = true; + include_idle = true; + include_exit = true; + assumptions = false; + } - if matches.opt_present("l") { - need_login = true; - include_idle = true; - assumptions = false; - } + if matches.opt_present("l") { + need_login = true; + include_idle = true; + assumptions = false; + } - if matches.opt_present("m") || matches.free.len() == 2 { - my_line_only = true; - } + if matches.opt_present("m") || matches.free.len() == 2 { + my_line_only = true; + } - if matches.opt_present("p") { - need_initspawn = true; - assumptions = false; - } + if matches.opt_present("p") { + need_initspawn = true; + assumptions = false; + } - if matches.opt_present("r") { - need_runlevel = true; - include_idle = true; - assumptions = false; - } + if matches.opt_present("r") { + need_runlevel = true; + include_idle = true; + assumptions = false; + } - if matches.opt_present("s") { - short_output = true; - } + if matches.opt_present("s") { + short_output = true; + } - if matches.opt_present("t") { - need_clockchange = true; - assumptions = false; - } + if matches.opt_present("t") { + need_clockchange = true; + assumptions = false; + } - if matches.opt_present("u") { - need_users = true; - include_idle = true; - assumptions = false; - } + if matches.opt_present("u") { + need_users = true; + include_idle = true; + assumptions = false; + } - if assumptions { - need_users = true; - short_output = true; - } + if assumptions { + need_users = true; + short_output = true; + } - if include_exit { - short_output = false; - } + if include_exit { + short_output = false; + } - if matches.free.len() > 2 { - disp_err!("{}", msg_wrong_number_of_arguments!()); - exit!(1); + if matches.free.len() > 2 { + disp_err!("{}", msg_wrong_number_of_arguments!()); + exit!(1); + } } let mut who = Who { - do_lookup: do_lookup, - short_list: short_list, - short_output: short_output, - include_idle: include_idle, - include_heading: include_heading, - include_mesg: include_mesg, - include_exit: include_exit, - need_boottime: need_boottime, - need_deadprocs: need_deadprocs, - need_login: need_login, - need_initspawn: need_initspawn, - need_clockchange: need_clockchange, - need_runlevel: need_runlevel, - need_users: need_users, - my_line_only: my_line_only, + do_lookup, + short_list, + short_output, + include_idle, + include_heading, + include_mesg, + include_exit, + need_boottime, + need_deadprocs, + need_login, + need_initspawn, + need_clockchange, + need_runlevel, + need_users, + my_line_only, has_records: false, args: matches.free, }; @@ -263,7 +271,8 @@ fn idle_string<'a>(when: i64, boottime: i64) -> Cow<'a, str> { "{:02}:{:02}", seconds_idle / 3600, (seconds_idle % 3600) / 60 - ).into() + ) + .into() } } else { " old ".into() @@ -296,7 +305,12 @@ impl Who { #[allow(unused_assignments)] let mut res = false; - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "linux", target_os = "android"))] + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "linux", + target_os = "android" + ))] { res = record == utmpx::RUN_LVL; } @@ -311,7 +325,7 @@ impl Who { if self.short_list { let users = Utmpx::iter_all_records() .read_from(f) - .filter(|ut| ut.is_user_process()) + .filter(Utmpx::is_user_process) .map(|ut| ut.user()) .collect::>(); println!("{}", users.join(" ")); @@ -463,7 +477,7 @@ impl Who { let mut res = ut_host.splitn(2, ':'); if let Some(h) = res.next() { if self.do_lookup { - buf.push(ut.canon_host().unwrap_or(h.to_owned())); + buf.push(ut.canon_host().unwrap_or_else(|_| h.to_owned())); } else { buf.push(h.to_owned()); } @@ -486,6 +500,7 @@ impl Who { ); } + #[allow(clippy::too_many_arguments)] fn print_line( &self, user: &str, @@ -525,14 +540,7 @@ impl Who { #[inline] fn print_heading(&self) { self.print_line( - "NAME", - ' ', - "LINE", - "TIME", - "IDLE", - "PID", - "COMMENT", - "EXIT", + "NAME", ' ', "LINE", "TIME", "IDLE", "PID", "COMMENT", "EXIT", ); } } diff --git a/src/whoami/Cargo.toml b/src/whoami/Cargo.toml index 32d7771b9a6..36a3f5f70c9 100644 --- a/src/whoami/Cargo.toml +++ b/src/whoami/Cargo.toml @@ -2,22 +2,20 @@ name = "whoami" version = "0.0.1" authors = [] +license = "MIT" description = "Print effective user ID." -build = "../../mkmain.rs" +build = "../#common/mkmain.rs" [lib] name = "uu_whoami" path = "whoami.rs" [dependencies] +advapi32-sys = "0.2.0" clap = "2.32" +uucore = { version = "0.0.2", features = ["entries", "wide"] } winapi = { version = "0.3", features = ["lmcons"] } -advapi32-sys = "0.2.0" - -[dependencies.uucore] -version = "0.0.1" -features = ["entries", "wide"] [[bin]] name = "whoami" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/whoami/platform/unix.rs b/src/whoami/platform/unix.rs index ab7c42ff639..259f806ef56 100644 --- a/src/whoami/platform/unix.rs +++ b/src/whoami/platform/unix.rs @@ -9,8 +9,8 @@ */ use std::io::Result; -use uucore::libc::geteuid; use uucore::entries::uid2usr; +use uucore::libc::geteuid; pub unsafe fn getusername() -> Result { // Get effective user id diff --git a/src/whoami/platform/windows.rs b/src/whoami/platform/windows.rs index b321b93befa..6ae9027f090 100644 --- a/src/whoami/platform/windows.rs +++ b/src/whoami/platform/windows.rs @@ -11,14 +11,15 @@ extern crate advapi32; extern crate uucore; extern crate winapi; +use self::winapi::shared::lmcons; +use self::winapi::shared::minwindef; +use self::winapi::um::winnt; use std::io::{Error, Result}; use std::mem; use uucore::wide::FromWide; -use self::winapi::um::winnt; -use self::winapi::shared::lmcons; -use self::winapi::shared::minwindef; pub unsafe fn getusername() -> Result { + #[allow(deprecated)] let mut buffer: [winnt::WCHAR; lmcons::UNLEN as usize + 1] = mem::uninitialized(); let mut len = buffer.len() as minwindef::DWORD; if advapi32::GetUserNameW(buffer.as_mut_ptr(), &mut len) == 0 { diff --git a/src/yes/Cargo.toml b/src/yes/Cargo.toml index 736c5ee6433..d1b9605b2a7 100644 --- a/src/yes/Cargo.toml +++ b/src/yes/Cargo.toml @@ -2,8 +2,9 @@ name = "yes" version = "0.0.1" authors = [] +license = "MIT" description = "Repeatedly output a line with all specified STRING(s), or 'y'." -build = "../../mkmain.rs" +build = "../#common/mkmain.rs" [lib] name = "uu_yes" @@ -11,7 +12,7 @@ path = "yes.rs" [dependencies] clap = "2.32" -uucore = { version = "0.0.1", features = ["zero-copy"] } +uucore = { version = "0.0.2", features = ["zero-copy"] } [features] latency = [] @@ -19,4 +20,4 @@ default = [] [[bin]] name = "yes" -path = "../../uumain.rs" +path = "../#common/uumain.rs" diff --git a/src/yes/yes.rs b/src/yes/yes.rs index b8e7971fd13..6a46d61bafe 100644 --- a/src/yes/yes.rs +++ b/src/yes/yes.rs @@ -17,9 +17,9 @@ extern crate clap; extern crate uucore; use clap::Arg; -use uucore::zero_copy::ZeroCopyWriter; use std::borrow::Cow; use std::io::{self, Write}; +use uucore::zero_copy::ZeroCopyWriter; // force a re-build whenever Cargo.toml changes const _CARGO_TOML: &str = include_str!("Cargo.toml"); diff --git a/tests/common/macros.rs b/tests/common/macros.rs index e36fdffdc5b..645cfcc67be 100644 --- a/tests/common/macros.rs +++ b/tests/common/macros.rs @@ -49,18 +49,22 @@ macro_rules! path_concat { #[macro_export] macro_rules! util_name { - () => ( module_path!().split("_").nth(1).expect("no test name") ) + () => { + module_path!().split("_").nth(1).expect("no test name") + }; } #[macro_export] macro_rules! new_ucmd { - () => ( TestScenario::new(util_name!()).ucmd() ) + () => { + TestScenario::new(util_name!()).ucmd() + }; } #[macro_export] macro_rules! at_and_ucmd { - () => ({ - let ts = TestScenario::new(util_name!()); - (ts.fixtures.clone(), ts.ucmd()) - }) + () => {{ + let ts = TestScenario::new(util_name!()); + (ts.fixtures.clone(), ts.ucmd()) + }}; } diff --git a/tests/common/util.rs b/tests/common/util.rs index abae40826a4..7ac373c8b29 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -1,7 +1,9 @@ #![allow(dead_code)] extern crate tempdir; +use self::tempdir::TempDir; use std::env; +use std::ffi::OsStr; use std::fs::{self, File, OpenOptions}; use std::io::{Read, Result, Write}; #[cfg(unix)] @@ -10,26 +12,23 @@ use std::os::unix::fs::{symlink as symlink_dir, symlink as symlink_file}; use std::os::windows::fs::{symlink_dir, symlink_file}; use std::path::{Path, PathBuf}; use std::process::{Child, Command, Stdio}; -use std::str::from_utf8; -use std::ffi::OsStr; use std::rc::Rc; +use std::str::from_utf8; use std::thread::sleep; use std::time::Duration; -use self::tempdir::TempDir; #[cfg(windows)] -static PROGNAME: &'static str = "uutils.exe"; +static PROGNAME: &str = "uutils.exe"; #[cfg(not(windows))] -static PROGNAME: &'static str = "uutils"; +static PROGNAME: &str = "uutils"; -static TESTS_DIR: &'static str = "tests"; -static FIXTURES_DIR: &'static str = "fixtures"; +static TESTS_DIR: &str = "tests"; +static FIXTURES_DIR: &str = "fixtures"; -static ALREADY_RUN: &'static str = - " you have already run this UCommand, if you want to run \ +static ALREADY_RUN: &str = " you have already run this UCommand, if you want to run \ another command in the same test, use TestScenario::new instead of \ testing();"; -static MULTIPLE_STDIN_MEANINGLESS: &'static str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly."; +static MULTIPLE_STDIN_MEANINGLESS: &str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly."; /// Test if the program is running under WSL // ref: @@ @@ -37,13 +36,13 @@ static MULTIPLE_STDIN_MEANINGLESS: &'static str = "Ucommand is designed around a pub fn is_wsl() -> bool { #[cfg(target_os = "linux")] { - if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") { - if let Ok(s) = std::str::from_utf8(&b) { - let a = s.to_ascii_lowercase(); - return a.contains("microsoft") || a.contains("wsl"); + if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") { + if let Ok(s) = std::str::from_utf8(&b) { + let a = s.to_ascii_lowercase(); + return a.contains("microsoft") || a.contains("wsl"); + } } } - } false } @@ -108,10 +107,7 @@ impl CmdResult { /// passed in value, trailing whitespace are kept to force strict comparison (#1235) /// stdout_only is a better choice unless stderr may or will be non-empty pub fn stdout_is>(&self, msg: T) -> Box<&CmdResult> { - assert_eq!( - self.stdout, - String::from(msg.as_ref()) - ); + assert_eq!(self.stdout, String::from(msg.as_ref())); Box::new(self) } @@ -373,7 +369,8 @@ impl AtPath { pub fn root_dir_resolved(&self) -> String { log_info("current_directory_resolved", ""); - let s = self.subdir + let s = self + .subdir .canonicalize() .unwrap() .to_str() @@ -573,7 +570,8 @@ impl UCommand { } self.has_run = true; log_info("run", &self.comm_string); - let mut result = self.raw + let mut result = self + .raw .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) diff --git a/tests/test_du.rs b/tests/test_du.rs index d63c70cc1cc..8189fa2c5ed 100644 --- a/tests/test_du.rs +++ b/tests/test_du.rs @@ -82,7 +82,8 @@ fn test_du_soft_link() { #[cfg(target_os = "macos")] fn _du_soft_link(s: String) { - assert_eq!(s, "16\tsubdir/links\n"); + // 'macos' host variants may have `du` output variation for soft links + assert!((s == "12\tsubdir/links\n") || (s == "16\tsubdir/links\n")); } #[cfg(not(target_os = "macos"))] fn _du_soft_link(s: String) { diff --git a/tests/test_pinky.rs b/tests/test_pinky.rs index 377abe74da1..45c1ccc0a4d 100644 --- a/tests/test_pinky.rs +++ b/tests/test_pinky.rs @@ -36,14 +36,32 @@ fn test_long_format() { #[cfg(target_os = "linux")] #[test] -fn test_short_format() { - let scene = TestScenario::new(util_name!()); - +fn test_short_format_i() { + // allow whitespace variation + // * minor whitespace differences occur between platform built-in outputs; specifically, the number of trailing TABs may be variant let args = ["-i"]; - scene.ucmd().args(&args).run().stdout_is(expected_result(&args)); + let actual = TestScenario::new(util_name!()).ucmd().args(&args).run().stdout; + let expect = expected_result(&args); + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + let v_actual: Vec<&str> = actual.split_whitespace().collect(); + let v_expect: Vec<&str> = expect.split_whitespace().collect(); + assert_eq!(v_actual, v_expect); +} +#[cfg(target_os = "linux")] +#[test] +fn test_short_format_q() { + // allow whitespace variation + // * minor whitespace differences occur between platform built-in outputs; specifically, the number of trailing TABs may be variant let args = ["-q"]; - scene.ucmd().args(&args).run().stdout_is(expected_result(&args)); + let actual = TestScenario::new(util_name!()).ucmd().args(&args).run().stdout; + let expect = expected_result(&args); + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + let v_actual: Vec<&str> = actual.split_whitespace().collect(); + let v_expect: Vec<&str> = expect.split_whitespace().collect(); + assert_eq!(v_actual, v_expect); } #[cfg(target_os = "linux")] diff --git a/tests/test_readlink.rs b/tests/test_readlink.rs index e8088dcd691..d4eceb1dcee 100644 --- a/tests/test_readlink.rs +++ b/tests/test_readlink.rs @@ -6,29 +6,31 @@ static GIBBERISH: &'static str = "supercalifragilisticexpialidocious"; #[test] fn test_canonicalize() { let (at, mut ucmd) = at_and_ucmd!(); - ucmd.arg("-f") - .arg(".") - .run() - .stdout_is(at.root_dir_resolved() + "\n"); + let actual = ucmd.arg("-f").arg(".").run().stdout; + let expect = at.root_dir_resolved() + "\n"; + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } #[test] fn test_canonicalize_existing() { let (at, mut ucmd) = at_and_ucmd!(); - ucmd.arg("-e") - .arg(".") - .run() - .stdout_is(at.root_dir_resolved() + "\n"); + let actual = ucmd.arg("-e").arg(".").run().stdout; + let expect = at.root_dir_resolved() + "\n"; + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } #[test] fn test_canonicalize_missing() { let (at, mut ucmd) = at_and_ucmd!(); - let expected = path_concat!(at.root_dir_resolved(), GIBBERISH); - ucmd.arg("-m") - .arg(GIBBERISH) - .run() - .stdout_is(expected + "\n"); + let actual = ucmd.arg("-m").arg(GIBBERISH).run().stdout; + let expect = path_concat!(at.root_dir_resolved(), GIBBERISH) + "\n"; + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } #[test] @@ -36,21 +38,20 @@ fn test_long_redirection_to_current_dir() { let (at, mut ucmd) = at_and_ucmd!(); // Create a 256-character path to current directory let dir = path_concat!(".", ..128); - ucmd.arg("-n") - .arg("-m") - .arg(dir) - .run() - .stdout_is(at.root_dir_resolved()); + let actual = ucmd.arg("-n").arg("-m").arg(dir).run().stdout; + let expect = at.root_dir_resolved(); + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } #[test] fn test_long_redirection_to_root() { // Create a 255-character path to root let dir = path_concat!("..", ..85); - new_ucmd!() - .arg("-n") - .arg("-m") - .arg(dir) - .run() - .stdout_is(get_root_path()); + let actual = new_ucmd!().arg("-n").arg("-m").arg(dir).run().stdout; + let expect = get_root_path(); + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } diff --git a/tests/test_realpath.rs b/tests/test_realpath.rs index efe263a54a8..3ee5ea63803 100644 --- a/tests/test_realpath.rs +++ b/tests/test_realpath.rs @@ -4,7 +4,11 @@ use common::util::*; #[test] fn test_current_directory() { let (at, mut ucmd) = at_and_ucmd!(); - ucmd.arg(".").run().stdout_is(at.root_dir_resolved() + "\n"); + let actual = ucmd.arg(".").run().stdout; + let expect = at.root_dir_resolved() + "\n"; + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } #[test] @@ -12,12 +16,20 @@ fn test_long_redirection_to_current_dir() { let (at, mut ucmd) = at_and_ucmd!(); // Create a 256-character path to current directory let dir = path_concat!(".", ..128); - ucmd.arg(dir).run().stdout_is(at.root_dir_resolved() + "\n"); + let actual = ucmd.arg(dir).run().stdout; + let expect = at.root_dir_resolved() + "\n"; + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } #[test] fn test_long_redirection_to_root() { // Create a 255-character path to root let dir = path_concat!("..", ..85); - new_ucmd!().arg(dir).run().stdout_is(get_root_path().to_owned() + "\n"); + let actual = new_ucmd!().arg(dir).run().stdout; + let expect = get_root_path().to_owned() + "\n"; + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + assert_eq!(actual, expect); } diff --git a/tests/test_who.rs b/tests/test_who.rs index 039f2e86cc3..32f5230a0c4 100644 --- a/tests/test_who.rs +++ b/tests/test_who.rs @@ -1,7 +1,7 @@ +#[cfg(target_os = "linux")] use common::util::*; - #[cfg(target_os = "linux")] #[test] fn test_count() { @@ -22,7 +22,15 @@ fn test_boot() { #[test] fn test_heading() { for opt in vec!["-H"] { - new_ucmd!().arg(opt).run().stdout_is(expected_result(opt)); + // allow whitespace variation + // * minor whitespace differences occur between platform built-in outputs; specfically number of TABs between "TIME" and "COMMENT" may be variant + let actual = new_ucmd!().arg(opt).run().stdout; + let expect = expected_result(opt); + println!("actual: {:?}", actual); + println!("expect: {:?}", expect); + let v_actual: Vec<&str> = actual.split_whitespace().collect(); + let v_expect: Vec<&str> = expect.split_whitespace().collect(); + assert_eq!(v_actual, v_expect); } } diff --git a/tests/tests.rs b/tests/tests.rs index f74d8e326a6..d63cee442cd 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,6 +1,9 @@ #[macro_use] mod common; +// [warning fix]; from ref: +#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))] +#[allow(unused_imports)] #[cfg(unix)] #[macro_use] extern crate lazy_static; diff --git a/util/show-utils.BAT b/util/show-utils.BAT new file mode 100644 index 00000000000..be7400d3c01 --- /dev/null +++ b/util/show-utils.BAT @@ -0,0 +1,24 @@ +@setLocal +@echo off + +@rem ::# spell-checker:ignore (CMD) ERRORLEVEL +@rem ::# spell-checker:ignore (utils) cksum dircolors hashsum mkdir mktemp printenv printf readlink realpath relpath rmdir shuf tsort unexpand uutils +@rem ::# spell-checker:ignore (jq) deps startswith + +@rem refs: , + +@rem :: default ("Tier 1" cross-platform) utility list +set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath relpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" + +@:: `jq` available? +set "JQ=" +set "ERRORLEVEL=" +jq --version 1>NUL 2>&1 +if NOT ERRORLEVEL 1 ( set "JQ=jq" ) + +if NOT DEFINED JQ ( + echo WARN: missing `jq` ^(install with `scoop install jq`^)^; falling back to default ^(only fully cross-platform^) util list 1>&2 + echo %default_utils% +) else ( + cargo metadata %* --format-version 1 | jq -r "[.resolve.nodes[] | {id: .id, deps: [.deps[].name]}] | .[] | select(.id|startswith(\"uutils\")) | [.deps[] | select(startswith(\"uu_\"))] | [.[] | sub(\"^uu_\"; \"\")] | join(\" \")" +) diff --git a/util/show-utils.sh b/util/show-utils.sh new file mode 100644 index 00000000000..f8f2ac9da76 --- /dev/null +++ b/util/show-utils.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# spell-checker:ignore (utils) cksum dircolors hashsum mkdir mktemp printenv printf readlink realpath relpath rmdir shuf tsort unexpand uutils +# spell-checker:ignore (jq) deps startswith + +# refs: , + +# default ("Tier 1" cross-platform) utility list +default_utils="base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath relpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" + +# `jq` available? +unset JQ +jq --version 1>/dev/null 2>&1 +if [ $? -eq 0 ]; then export JQ="jq"; fi + +if [ -z "${JQ}" ]; then + echo 'WARN: missing `jq` (install with `sudo apt install jq`); falling back to default (only fully cross-platform) utility list' 1>&2 + echo $default_utils +else + cargo metadata $* --format-version 1 | jq -r "[.resolve.nodes[] | {id: .id, deps: [.deps[].name]}] | .[] | select(.id|startswith(\"uutils\")) | [.deps[] | select(startswith(\"uu_\"))] | [.[] | sub(\"^uu_\"; \"\")] | join(\" \")" +fi