mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-09-17 20:26:18 +00:00
Merge branch 'main' into openbsd-utmpx
This commit is contained in:
commit
1bfac9b25a
45 changed files with 387 additions and 257 deletions
59
.github/workflows/CICD.yml
vendored
59
.github/workflows/CICD.yml
vendored
|
@ -395,14 +395,14 @@ jobs:
|
||||||
--arg multisize "$SIZE_MULTI" \
|
--arg multisize "$SIZE_MULTI" \
|
||||||
'{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json
|
'{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json
|
||||||
- name: Download the previous individual size result
|
- name: Download the previous individual size result
|
||||||
uses: dawidd6/action-download-artifact@v2
|
uses: dawidd6/action-download-artifact@v3
|
||||||
with:
|
with:
|
||||||
workflow: CICD.yml
|
workflow: CICD.yml
|
||||||
name: individual-size-result
|
name: individual-size-result
|
||||||
repo: uutils/coreutils
|
repo: uutils/coreutils
|
||||||
path: dl
|
path: dl
|
||||||
- name: Download the previous size result
|
- name: Download the previous size result
|
||||||
uses: dawidd6/action-download-artifact@v2
|
uses: dawidd6/action-download-artifact@v3
|
||||||
with:
|
with:
|
||||||
workflow: CICD.yml
|
workflow: CICD.yml
|
||||||
name: size-result
|
name: size-result
|
||||||
|
@ -439,12 +439,12 @@ jobs:
|
||||||
previous_multisize=$(cat dl/size-result.json | jq -r '.[] | .multisize')
|
previous_multisize=$(cat dl/size-result.json | jq -r '.[] | .multisize')
|
||||||
check 'multicall binary' "$multisize" "$previous_multisize" 'size-result.json'
|
check 'multicall binary' "$multisize" "$previous_multisize" 'size-result.json'
|
||||||
- name: Upload the individual size result
|
- name: Upload the individual size result
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: individual-size-result
|
name: individual-size-result
|
||||||
path: individual-size-result.json
|
path: individual-size-result.json
|
||||||
- name: Upload the size result
|
- name: Upload the size result
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: size-result
|
name: size-result
|
||||||
path: size-result.json
|
path: size-result.json
|
||||||
|
@ -473,6 +473,7 @@ jobs:
|
||||||
- { os: ubuntu-latest , target: i686-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross }
|
- { os: ubuntu-latest , target: i686-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross }
|
||||||
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross }
|
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross }
|
||||||
- { os: ubuntu-latest , target: x86_64-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross }
|
- { os: ubuntu-latest , target: x86_64-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross }
|
||||||
|
- { os: ubuntu-latest , target: x86_64-unknown-redox , features: feat_os_unix_redox , use-cross: redoxer , skip-tests: true }
|
||||||
- { os: macos-latest , target: aarch64-apple-darwin , features: feat_os_macos , use-cross: use-cross, skip-tests: true} # Hopefully github provides free M1 runners soon...
|
- { os: macos-latest , target: aarch64-apple-darwin , features: feat_os_macos , use-cross: use-cross, skip-tests: true} # Hopefully github provides free M1 runners soon...
|
||||||
- { os: macos-latest , target: x86_64-apple-darwin , features: feat_os_macos }
|
- { os: macos-latest , target: x86_64-apple-darwin , features: feat_os_macos }
|
||||||
- { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows }
|
- { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows }
|
||||||
|
@ -525,7 +526,13 @@ jobs:
|
||||||
i686-*) TARGET_ARCH=i686 ;;
|
i686-*) TARGET_ARCH=i686 ;;
|
||||||
x86_64-*) TARGET_ARCH=x86_64 ;;
|
x86_64-*) TARGET_ARCH=x86_64 ;;
|
||||||
esac;
|
esac;
|
||||||
unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac;
|
unset TARGET_OS
|
||||||
|
case '${{ matrix.job.target }}' in
|
||||||
|
*-linux-*) TARGET_OS=linux ;;
|
||||||
|
*-apple-*) TARGET_OS=macos ;;
|
||||||
|
*-windows-*) TARGET_OS=windows ;;
|
||||||
|
*-redox*) TARGET_OS=redox ;;
|
||||||
|
esac
|
||||||
outputs TARGET_ARCH TARGET_OS
|
outputs TARGET_ARCH TARGET_OS
|
||||||
# package name
|
# package name
|
||||||
PKG_suffix=".tar.gz" ; case '${{ matrix.job.target }}' in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
|
PKG_suffix=".tar.gz" ; case '${{ matrix.job.target }}' in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
|
||||||
|
@ -560,8 +567,19 @@ jobs:
|
||||||
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features=${{ matrix.job.features }}' ; fi
|
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features=${{ matrix.job.features }}' ; fi
|
||||||
outputs CARGO_FEATURES_OPTION
|
outputs CARGO_FEATURES_OPTION
|
||||||
# * CARGO_CMD
|
# * CARGO_CMD
|
||||||
CARGO_CMD='cross' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) CARGO_CMD='cargo' ;; esac;
|
CARGO_CMD='cross'
|
||||||
|
CARGO_CMD_OPTIONS='+${{ env.RUST_MIN_SRV }}'
|
||||||
|
case '${{ matrix.job.use-cross }}' in
|
||||||
|
''|0|f|false|n|no)
|
||||||
|
CARGO_CMD='cargo'
|
||||||
|
;;
|
||||||
|
redoxer)
|
||||||
|
CARGO_CMD='redoxer'
|
||||||
|
CARGO_CMD_OPTIONS=''
|
||||||
|
;;
|
||||||
|
esac
|
||||||
outputs CARGO_CMD
|
outputs CARGO_CMD
|
||||||
|
outputs CARGO_CMD_OPTIONS
|
||||||
# ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml")
|
# ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml")
|
||||||
if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then
|
if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then
|
||||||
printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\", \"CARGO_TERM_COLOR\"]\n" > Cross.toml
|
printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\", \"CARGO_TERM_COLOR\"]\n" > Cross.toml
|
||||||
|
@ -595,6 +613,7 @@ jobs:
|
||||||
case '${{ matrix.job.target }}' in
|
case '${{ matrix.job.target }}' in
|
||||||
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
|
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
|
||||||
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
|
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
|
||||||
|
*-redox*) sudo apt-get -y update ; sudo apt-get -y install fuse3 libfuse-dev ;;
|
||||||
esac
|
esac
|
||||||
case '${{ matrix.job.os }}' in
|
case '${{ matrix.job.os }}' in
|
||||||
macos-latest) brew install coreutils ;; # needed for testing
|
macos-latest) brew install coreutils ;; # needed for testing
|
||||||
|
@ -614,6 +633,10 @@ jobs:
|
||||||
echo "foo" > /home/runner/.plan
|
echo "foo" > /home/runner/.plan
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
- uses: taiki-e/install-action@v2
|
||||||
|
if: steps.vars.outputs.CARGO_CMD == 'redoxer'
|
||||||
|
with:
|
||||||
|
tool: redoxer@0.2.37
|
||||||
- name: Initialize toolchain-dependent workflow variables
|
- name: Initialize toolchain-dependent workflow variables
|
||||||
id: dep_vars
|
id: dep_vars
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -652,14 +675,14 @@ jobs:
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
## Build
|
## Build
|
||||||
${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} build --release \
|
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} build --release \
|
||||||
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||||
- name: Test
|
- name: Test
|
||||||
if: matrix.job.skip-tests != true
|
if: matrix.job.skip-tests != true
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
## Test
|
## Test
|
||||||
${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} test --target=${{ matrix.job.target }} \
|
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} test --target=${{ matrix.job.target }} \
|
||||||
${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||||
env:
|
env:
|
||||||
RUST_BACKTRACE: "1"
|
RUST_BACKTRACE: "1"
|
||||||
|
@ -668,12 +691,12 @@ jobs:
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
## Test individual utilities
|
## Test individual utilities
|
||||||
${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} test --target=${{ matrix.job.target }} \
|
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} test --target=${{ matrix.job.target }} \
|
||||||
${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
||||||
env:
|
env:
|
||||||
RUST_BACKTRACE: "1"
|
RUST_BACKTRACE: "1"
|
||||||
- name: Archive executable artifacts
|
- name: Archive executable artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}
|
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}
|
||||||
path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}
|
path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}
|
||||||
|
@ -784,17 +807,17 @@ jobs:
|
||||||
HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1)
|
HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1)
|
||||||
echo "HASH=${HASH}" >> $GITHUB_OUTPUT
|
echo "HASH=${HASH}" >> $GITHUB_OUTPUT
|
||||||
- name: Reserve SHA1/ID of 'test-summary'
|
- name: Reserve SHA1/ID of 'test-summary'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "${{ steps.summary.outputs.HASH }}"
|
name: "${{ steps.summary.outputs.HASH }}"
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||||
- name: Reserve test results summary
|
- name: Reserve test results summary
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-summary
|
name: busybox-test-summary
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||||
- name: Upload json results
|
- name: Upload json results
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: busybox-result.json
|
name: busybox-result.json
|
||||||
path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }}
|
path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }}
|
||||||
|
@ -872,17 +895,17 @@ jobs:
|
||||||
HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1)
|
HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1)
|
||||||
echo "HASH=${HASH}" >> $GITHUB_OUTPUT
|
echo "HASH=${HASH}" >> $GITHUB_OUTPUT
|
||||||
- name: Reserve SHA1/ID of 'test-summary'
|
- name: Reserve SHA1/ID of 'test-summary'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "${{ steps.summary.outputs.HASH }}"
|
name: "${{ steps.summary.outputs.HASH }}"
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||||
- name: Reserve test results summary
|
- name: Reserve test results summary
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-summary
|
name: toybox-test-summary
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||||
- name: Upload json results
|
- name: Upload json results
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: toybox-result.json
|
name: toybox-result.json
|
||||||
path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }}
|
path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }}
|
||||||
|
|
12
.github/workflows/GnuTests.yml
vendored
12
.github/workflows/GnuTests.yml
vendored
|
@ -77,7 +77,7 @@ jobs:
|
||||||
ref: ${{ steps.vars.outputs.repo_GNU_ref }}
|
ref: ${{ steps.vars.outputs.repo_GNU_ref }}
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Retrieve reference artifacts
|
- name: Retrieve reference artifacts
|
||||||
uses: dawidd6/action-download-artifact@v2
|
uses: dawidd6/action-download-artifact@v3
|
||||||
# ref: <https://github.com/dawidd6/action-download-artifact>
|
# ref: <https://github.com/dawidd6/action-download-artifact>
|
||||||
continue-on-error: true ## don't break the build for missing reference artifacts (may be expired or just not generated yet)
|
continue-on-error: true ## don't break the build for missing reference artifacts (may be expired or just not generated yet)
|
||||||
with:
|
with:
|
||||||
|
@ -179,22 +179,22 @@ jobs:
|
||||||
# Compress logs before upload (fails otherwise)
|
# Compress logs before upload (fails otherwise)
|
||||||
gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }}
|
gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }}
|
||||||
- name: Reserve SHA1/ID of 'test-summary'
|
- name: Reserve SHA1/ID of 'test-summary'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "${{ steps.summary.outputs.HASH }}"
|
name: "${{ steps.summary.outputs.HASH }}"
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||||
- name: Reserve test results summary
|
- name: Reserve test results summary
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-summary
|
name: test-summary
|
||||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||||
- name: Reserve test logs
|
- name: Reserve test logs
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-logs
|
name: test-logs
|
||||||
path: "${{ steps.vars.outputs.TEST_LOGS_GLOB }}"
|
path: "${{ steps.vars.outputs.TEST_LOGS_GLOB }}"
|
||||||
- name: Upload full json results
|
- name: Upload full json results
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: gnu-full-result.json
|
name: gnu-full-result.json
|
||||||
path: ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}
|
path: ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}
|
||||||
|
@ -288,7 +288,7 @@ jobs:
|
||||||
if test -n "${have_new_failures}" ; then exit -1 ; fi
|
if test -n "${have_new_failures}" ; then exit -1 ; fi
|
||||||
- name: Upload comparison log (for GnuComment workflow)
|
- name: Upload comparison log (for GnuComment workflow)
|
||||||
if: success() || failure() # run regardless of prior step success/failure
|
if: success() || failure() # run regardless of prior step success/failure
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: comment
|
name: comment
|
||||||
path: ${{ steps.vars.outputs.path_reference }}/comment/
|
path: ${{ steps.vars.outputs.path_reference }}/comment/
|
||||||
|
|
98
Cargo.lock
generated
98
Cargo.lock
generated
|
@ -781,12 +781,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.5"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
|
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1215,9 +1215,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.10"
|
version = "0.4.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
|
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
|
@ -1600,7 +1600,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"procfs-core",
|
"procfs-core",
|
||||||
"rustix 0.38.21",
|
"rustix 0.38.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1842,15 +1842,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.21"
|
version = "0.38.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
|
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.0",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.4.10",
|
"linux-raw-sys 0.4.12",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2063,7 +2063,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"redox_syscall 0.4.0",
|
"redox_syscall 0.4.0",
|
||||||
"rustix 0.38.21",
|
"rustix 0.38.28",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2083,7 +2083,7 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
|
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustix 0.38.21",
|
"rustix 0.38.28",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3403,6 +3403,15 @@ dependencies = [
|
||||||
"windows-targets 0.48.0",
|
"windows-targets 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3433,6 +3442,21 @@ dependencies = [
|
||||||
"windows_x86_64_msvc 0.48.0",
|
"windows_x86_64_msvc 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.0",
|
||||||
|
"windows_aarch64_msvc 0.52.0",
|
||||||
|
"windows_i686_gnu 0.52.0",
|
||||||
|
"windows_i686_msvc 0.52.0",
|
||||||
|
"windows_x86_64_gnu 0.52.0",
|
||||||
|
"windows_x86_64_gnullvm 0.52.0",
|
||||||
|
"windows_x86_64_msvc 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3445,6 +3469,12 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3457,6 +3487,12 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3469,6 +3505,12 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3481,6 +3523,12 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3493,6 +3541,12 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3505,6 +3559,12 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@ -3518,12 +3578,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xattr"
|
name = "windows_x86_64_msvc"
|
||||||
version = "1.1.1"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbc6ab6ec1907d1a901cdbcd2bd4cb9e7d64ce5c9739cbb97d3c391acd8c7fae"
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xattr"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7dae5072fe1f8db8f8d29059189ac175196e410e40ba42d5d4684ae2f750995"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
|
"linux-raw-sys 0.4.12",
|
||||||
|
"rustix 0.38.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -331,7 +331,7 @@ utf-8 = "0.7.6"
|
||||||
walkdir = "2.4"
|
walkdir = "2.4"
|
||||||
winapi-util = "0.1.6"
|
winapi-util = "0.1.6"
|
||||||
windows-sys = { version = "0.48.0", default-features = false }
|
windows-sys = { version = "0.48.0", default-features = false }
|
||||||
xattr = "1.1.1"
|
xattr = "1.1.3"
|
||||||
zip = { version = "0.6.6", default-features = false, features = ["deflate"] }
|
zip = { version = "0.6.6", default-features = false, features = ["deflate"] }
|
||||||
|
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
|
18
deny.toml
18
deny.toml
|
@ -64,8 +64,12 @@ skip = [
|
||||||
{ name = "rustix", version = "0.37.26" },
|
{ name = "rustix", version = "0.37.26" },
|
||||||
# various crates
|
# various crates
|
||||||
{ name = "windows-sys", version = "0.45.0" },
|
{ name = "windows-sys", version = "0.45.0" },
|
||||||
|
# various crates
|
||||||
|
{ name = "windows-sys", version = "0.48.0" },
|
||||||
# windows-sys
|
# windows-sys
|
||||||
{ name = "windows-targets", version = "0.42.2" },
|
{ name = "windows-targets", version = "0.42.2" },
|
||||||
|
# windows-sys
|
||||||
|
{ name = "windows-targets", version = "0.48.0" },
|
||||||
# windows-targets
|
# windows-targets
|
||||||
{ name = "windows_aarch64_gnullvm", version = "0.42.2" },
|
{ name = "windows_aarch64_gnullvm", version = "0.42.2" },
|
||||||
# windows-targets
|
# windows-targets
|
||||||
|
@ -80,6 +84,20 @@ skip = [
|
||||||
{ name = "windows_x86_64_gnullvm", version = "0.42.2" },
|
{ name = "windows_x86_64_gnullvm", version = "0.42.2" },
|
||||||
# windows-targets
|
# windows-targets
|
||||||
{ name = "windows_x86_64_msvc", version = "0.42.2" },
|
{ name = "windows_x86_64_msvc", version = "0.42.2" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_aarch64_gnullvm", version = "0.48.0" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_aarch64_msvc", version = "0.48.0" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_i686_gnu", version = "0.48.0" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_i686_msvc", version = "0.48.0" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_x86_64_gnu", version = "0.48.0" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_x86_64_gnullvm", version = "0.48.0" },
|
||||||
|
# windows-targets
|
||||||
|
{ name = "windows_x86_64_msvc", version = "0.48.0" },
|
||||||
# various crates
|
# various crates
|
||||||
{ name = "syn", version = "1.0.109" },
|
{ name = "syn", version = "1.0.109" },
|
||||||
# various crates
|
# various crates
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- spell-checker:ignore pacman pamac nixpkgs openmandriva conda -->
|
<!-- spell-checker:ignore pacman pamac nixpkgs openmandriva conda winget -->
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ You can also [build uutils from source](build.md).
|
||||||
|
|
||||||
## Cargo
|
## Cargo
|
||||||
|
|
||||||
[](https://repology.org/project/uutils-coreutils/versions)
|
[](https://crates.io/crates/coreutils)
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Linux
|
# Linux
|
||||||
|
@ -65,9 +65,9 @@ emerge -pv sys-apps/uutils-coreutils
|
||||||
|
|
||||||
### Manjaro
|
### Manjaro
|
||||||
|
|
||||||

|
[](https://packages.manjaro.org/?query=uutils-coreutils)
|
||||||
[](https://repology.org/project/uutils-coreutils/versions)
|
[](https://packages.manjaro.org/?query=uutils-coreutils)
|
||||||
[](https://repology.org/project/uutils-coreutils/versions)
|
[](https://packages.manjaro.org/?query=uutils-coreutils)
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
pacman -S uutils-coreutils
|
pacman -S uutils-coreutils
|
||||||
|
@ -77,7 +77,7 @@ pamac install uutils-coreutils
|
||||||
|
|
||||||
### NixOS
|
### NixOS
|
||||||
|
|
||||||
[](https://repology.org/project/uutils-coreutils/versions)
|
[](https://search.nixos.org/packages?query=uutils-coreutils)
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
nix-env -iA nixos.uutils-coreutils
|
nix-env -iA nixos.uutils-coreutils
|
||||||
|
@ -131,9 +131,15 @@ pkg install rust-coreutils
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
|
### Winget
|
||||||
|
|
||||||
|
```shell
|
||||||
|
winget install uutils.coreutils
|
||||||
|
```
|
||||||
|
|
||||||
### Scoop
|
### Scoop
|
||||||
|
|
||||||
[](https://scoop.sh/#/apps?q=uutils-coreutils&s=0&d=1&o=true)
|
[Scoop package](https://scoop.sh/#/apps?q=uutils-coreutils&s=0&d=1&o=true)
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
scoop install uutils-coreutils
|
scoop install uutils-coreutils
|
||||||
|
|
|
@ -87,8 +87,7 @@ pub fn parse_base_cmd_args(
|
||||||
usage: &str,
|
usage: &str,
|
||||||
) -> UResult<Config> {
|
) -> UResult<Config> {
|
||||||
let command = base_app(about, usage);
|
let command = base_app(about, usage);
|
||||||
let arg_list = args.collect_lossy();
|
Config::from(&command.try_get_matches_from(args)?)
|
||||||
Config::from(&command.try_get_matches_from(arg_list)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn base_app(about: &'static str, usage: &str) -> Command {
|
pub fn base_app(about: &'static str, usage: &str) -> Command {
|
||||||
|
|
|
@ -174,8 +174,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let number_mode = if matches.get_flag(options::NUMBER_NONBLANK) {
|
let number_mode = if matches.get_flag(options::NUMBER_NONBLANK) {
|
||||||
|
|
|
@ -33,8 +33,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
|
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
|
||||||
|
|
||||||
let default_shell: &'static str = "/bin/sh";
|
let default_shell: &'static str = "/bin/sh";
|
||||||
|
|
|
@ -221,8 +221,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let algo_name: &str = match matches.get_one::<String>(options::ALGORITHM) {
|
let algo_name: &str = match matches.get_one::<String>(options::ALGORITHM) {
|
||||||
|
|
|
@ -145,8 +145,6 @@ fn open_file(name: &str, line_ending: LineEnding) -> io::Result<LineReader> {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO_TERMINATED));
|
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO_TERMINATED));
|
||||||
let filename1 = matches.get_one::<String>(options::FILE_1).unwrap();
|
let filename1 = matches.get_one::<String>(options::FILE_1).unwrap();
|
||||||
|
|
|
@ -552,8 +552,6 @@ where
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
// get the file to split
|
// get the file to split
|
||||||
|
|
|
@ -1267,8 +1267,6 @@ fn is_fifo(filename: &str) -> bool {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let settings: Settings = Parser::new().parse(
|
let settings: Settings = Parser::new().parse(
|
||||||
|
|
|
@ -129,8 +129,6 @@ fn generate_ls_colors(fmt: &OutputFmt, sep: &str) -> String {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let files = matches
|
let files = matches
|
||||||
|
|
|
@ -21,8 +21,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?;
|
let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?;
|
||||||
|
|
||||||
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
|
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
|
||||||
|
|
|
@ -590,8 +590,6 @@ pub fn div_ceil(a: u64, b: u64) -> u64 {
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let summarize = matches.get_flag(options::SUMMARIZE);
|
let summarize = matches.get_flag(options::SUMMARIZE);
|
||||||
|
|
|
@ -118,7 +118,6 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<ControlFlow<
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
let matches = uu_app().get_matches_from(args);
|
let matches = uu_app().get_matches_from(args);
|
||||||
|
|
||||||
let no_newline = matches.get_flag(options::NO_NEWLINE);
|
let no_newline = matches.get_flag(options::NO_NEWLINE);
|
||||||
|
|
|
@ -98,8 +98,6 @@ pub fn uu_app() -> Command {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
// For expr utility we do not want getopts.
|
// For expr utility we do not want getopts.
|
||||||
// The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)`
|
// The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)`
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
@ -108,9 +106,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
.map(|v| v.into_iter().map(|s| s.as_ref()).collect::<Vec<_>>())
|
.map(|v| v.into_iter().map(|s| s.as_ref()).collect::<Vec<_>>())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let res = AstNode::parse(&token_strings)?.eval()?;
|
let res: String = AstNode::parse(&token_strings)?.eval()?.eval_as_string();
|
||||||
println!("{res}");
|
println!("{res}");
|
||||||
if !is_truthy(&res) {
|
if !is_truthy(&res.into()) {
|
||||||
return Err(1.into());
|
return Err(1.into());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) ints paren prec multibytes
|
// spell-checker:ignore (ToDO) ints paren prec multibytes
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::{BigInt, ParseBigIntError};
|
||||||
|
use num_traits::ToPrimitive;
|
||||||
use onig::{Regex, RegexOptions, Syntax};
|
use onig::{Regex, RegexOptions, Syntax};
|
||||||
|
|
||||||
use crate::{ExprError, ExprResult};
|
use crate::{ExprError, ExprResult};
|
||||||
|
@ -45,7 +46,7 @@ pub enum StringOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinOp {
|
impl BinOp {
|
||||||
fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult<String> {
|
fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult<NumOrStr> {
|
||||||
match self {
|
match self {
|
||||||
Self::Relation(op) => op.eval(left, right),
|
Self::Relation(op) => op.eval(left, right),
|
||||||
Self::Numeric(op) => op.eval(left, right),
|
Self::Numeric(op) => op.eval(left, right),
|
||||||
|
@ -55,10 +56,10 @@ impl BinOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelationOp {
|
impl RelationOp {
|
||||||
fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult<String> {
|
fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult<NumOrStr> {
|
||||||
let a = a.eval()?;
|
let a = a.eval()?;
|
||||||
let b = b.eval()?;
|
let b = b.eval()?;
|
||||||
let b = if let (Ok(a), Ok(b)) = (a.parse::<BigInt>(), b.parse::<BigInt>()) {
|
let b = if let (Ok(a), Ok(b)) = (&a.to_bigint(), &b.to_bigint()) {
|
||||||
match self {
|
match self {
|
||||||
Self::Lt => a < b,
|
Self::Lt => a < b,
|
||||||
Self::Leq => a <= b,
|
Self::Leq => a <= b,
|
||||||
|
@ -79,24 +80,18 @@ impl RelationOp {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if b {
|
if b {
|
||||||
Ok("1".into())
|
Ok(1.into())
|
||||||
} else {
|
} else {
|
||||||
Ok("0".into())
|
Ok(0.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumericOp {
|
impl NumericOp {
|
||||||
fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult<String> {
|
fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult<NumOrStr> {
|
||||||
let a: BigInt = left
|
let a = left.eval()?.eval_as_bigint()?;
|
||||||
.eval()?
|
let b = right.eval()?.eval_as_bigint()?;
|
||||||
.parse()
|
Ok(NumOrStr::Num(match self {
|
||||||
.map_err(|_| ExprError::NonIntegerArgument)?;
|
|
||||||
let b: BigInt = right
|
|
||||||
.eval()?
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| ExprError::NonIntegerArgument)?;
|
|
||||||
Ok(match self {
|
|
||||||
Self::Add => a + b,
|
Self::Add => a + b,
|
||||||
Self::Sub => a - b,
|
Self::Sub => a - b,
|
||||||
Self::Mul => a * b,
|
Self::Mul => a * b,
|
||||||
|
@ -110,13 +105,12 @@ impl NumericOp {
|
||||||
};
|
};
|
||||||
a % b
|
a % b
|
||||||
}
|
}
|
||||||
}
|
}))
|
||||||
.to_string())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StringOp {
|
impl StringOp {
|
||||||
fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult<String> {
|
fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult<NumOrStr> {
|
||||||
match self {
|
match self {
|
||||||
Self::Or => {
|
Self::Or => {
|
||||||
let left = left.eval()?;
|
let left = left.eval()?;
|
||||||
|
@ -127,23 +121,23 @@ impl StringOp {
|
||||||
if is_truthy(&right) {
|
if is_truthy(&right) {
|
||||||
return Ok(right);
|
return Ok(right);
|
||||||
}
|
}
|
||||||
Ok("0".into())
|
Ok(0.into())
|
||||||
}
|
}
|
||||||
Self::And => {
|
Self::And => {
|
||||||
let left = left.eval()?;
|
let left = left.eval()?;
|
||||||
if !is_truthy(&left) {
|
if !is_truthy(&left) {
|
||||||
return Ok("0".into());
|
return Ok(0.into());
|
||||||
}
|
}
|
||||||
let right = right.eval()?;
|
let right = right.eval()?;
|
||||||
if !is_truthy(&right) {
|
if !is_truthy(&right) {
|
||||||
return Ok("0".into());
|
return Ok(0.into());
|
||||||
}
|
}
|
||||||
Ok(left)
|
Ok(left)
|
||||||
}
|
}
|
||||||
Self::Match => {
|
Self::Match => {
|
||||||
let left = left.eval()?;
|
let left = left.eval()?.eval_as_string();
|
||||||
let right = right.eval()?;
|
let right = right.eval()?.eval_as_string();
|
||||||
let re_string = format!("^{}", &right);
|
let re_string = format!("^{}", right);
|
||||||
let re = Regex::with_options(
|
let re = Regex::with_options(
|
||||||
&re_string,
|
&re_string,
|
||||||
RegexOptions::REGEX_OPTION_NONE,
|
RegexOptions::REGEX_OPTION_NONE,
|
||||||
|
@ -158,19 +152,20 @@ impl StringOp {
|
||||||
} else {
|
} else {
|
||||||
re.find(&left)
|
re.find(&left)
|
||||||
.map_or("0".to_string(), |(start, end)| (end - start).to_string())
|
.map_or("0".to_string(), |(start, end)| (end - start).to_string())
|
||||||
})
|
}
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
Self::Index => {
|
Self::Index => {
|
||||||
let left = left.eval()?;
|
let left = left.eval()?.eval_as_string();
|
||||||
let right = right.eval()?;
|
let right = right.eval()?.eval_as_string();
|
||||||
for (current_idx, ch_h) in left.chars().enumerate() {
|
for (current_idx, ch_h) in left.chars().enumerate() {
|
||||||
for ch_n in right.chars() {
|
for ch_n in right.to_string().chars() {
|
||||||
if ch_n == ch_h {
|
if ch_n == ch_h {
|
||||||
return Ok((current_idx + 1).to_string());
|
return Ok((current_idx + 1).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok("0".to_string())
|
Ok(0.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,6 +195,55 @@ const PRECEDENCE: &[&[(&str, BinOp)]] = &[
|
||||||
&[(":", BinOp::String(StringOp::Match))],
|
&[(":", BinOp::String(StringOp::Match))],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
|
pub enum NumOrStr {
|
||||||
|
Num(BigInt),
|
||||||
|
Str(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<usize> for NumOrStr {
|
||||||
|
fn from(num: usize) -> Self {
|
||||||
|
Self::Num(BigInt::from(num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BigInt> for NumOrStr {
|
||||||
|
fn from(num: BigInt) -> Self {
|
||||||
|
Self::Num(num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for NumOrStr {
|
||||||
|
fn from(str: String) -> Self {
|
||||||
|
Self::Str(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NumOrStr {
|
||||||
|
pub fn to_bigint(&self) -> Result<BigInt, ParseBigIntError> {
|
||||||
|
match self {
|
||||||
|
Self::Num(num) => Ok(num.clone()),
|
||||||
|
Self::Str(str) => str.parse::<BigInt>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval_as_bigint(self) -> ExprResult<BigInt> {
|
||||||
|
match self {
|
||||||
|
Self::Num(num) => Ok(num),
|
||||||
|
Self::Str(str) => str
|
||||||
|
.parse::<BigInt>()
|
||||||
|
.map_err(|_| ExprError::NonIntegerArgument),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval_as_string(self) -> String {
|
||||||
|
match self {
|
||||||
|
Self::Num(num) => num.to_string(),
|
||||||
|
Self::Str(str) => str,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum AstNode {
|
pub enum AstNode {
|
||||||
Leaf {
|
Leaf {
|
||||||
|
@ -225,9 +269,9 @@ impl AstNode {
|
||||||
Parser::new(input).parse()
|
Parser::new(input).parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval(&self) -> ExprResult<String> {
|
pub fn eval(&self) -> ExprResult<NumOrStr> {
|
||||||
match self {
|
match self {
|
||||||
Self::Leaf { value } => Ok(value.into()),
|
Self::Leaf { value } => Ok(value.to_string().into()),
|
||||||
Self::BinOp {
|
Self::BinOp {
|
||||||
op_type,
|
op_type,
|
||||||
left,
|
left,
|
||||||
|
@ -238,7 +282,7 @@ impl AstNode {
|
||||||
pos,
|
pos,
|
||||||
length,
|
length,
|
||||||
} => {
|
} => {
|
||||||
let string = string.eval()?;
|
let string: String = string.eval()?.eval_as_string();
|
||||||
|
|
||||||
// The GNU docs say:
|
// The GNU docs say:
|
||||||
//
|
//
|
||||||
|
@ -247,16 +291,31 @@ impl AstNode {
|
||||||
//
|
//
|
||||||
// So we coerce errors into 0 to make that the only case we
|
// So we coerce errors into 0 to make that the only case we
|
||||||
// have to care about.
|
// have to care about.
|
||||||
let pos: usize = pos.eval()?.parse().unwrap_or(0);
|
let pos = pos
|
||||||
let length: usize = length.eval()?.parse().unwrap_or(0);
|
.eval()?
|
||||||
|
.eval_as_bigint()
|
||||||
|
.ok()
|
||||||
|
.and_then(|n| n.to_usize())
|
||||||
|
.unwrap_or(0);
|
||||||
|
let length = length
|
||||||
|
.eval()?
|
||||||
|
.eval_as_bigint()
|
||||||
|
.ok()
|
||||||
|
.and_then(|n| n.to_usize())
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else {
|
let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else {
|
||||||
return Ok(String::new());
|
return Ok(String::new().into());
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(string.chars().skip(pos).take(length).collect())
|
Ok(string
|
||||||
|
.chars()
|
||||||
|
.skip(pos)
|
||||||
|
.take(length)
|
||||||
|
.collect::<String>()
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
Self::Length { string } => Ok(string.eval()?.chars().count().to_string()),
|
Self::Length { string } => Ok(string.eval()?.eval_as_string().chars().count().into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,21 +458,26 @@ impl<'a> Parser<'a> {
|
||||||
/// Determine whether `expr` should evaluate the string as "truthy"
|
/// Determine whether `expr` should evaluate the string as "truthy"
|
||||||
///
|
///
|
||||||
/// Truthy strings are either empty or match the regex "-?0+".
|
/// Truthy strings are either empty or match the regex "-?0+".
|
||||||
pub fn is_truthy(s: &str) -> bool {
|
pub fn is_truthy(s: &NumOrStr) -> bool {
|
||||||
// Edge case: `-` followed by nothing is truthy
|
match s {
|
||||||
if s == "-" {
|
NumOrStr::Num(num) => num != &BigInt::from(0),
|
||||||
return true;
|
NumOrStr::Str(str) => {
|
||||||
|
// Edge case: `-` followed by nothing is truthy
|
||||||
|
if str == "-" {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut bytes = str.bytes();
|
||||||
|
|
||||||
|
// Empty string is falsy
|
||||||
|
let Some(first) = bytes.next() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_zero = (first == b'-' || first == b'0') && bytes.all(|b| b == b'0');
|
||||||
|
!is_zero
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bytes = s.bytes();
|
|
||||||
|
|
||||||
// Empty string is falsy
|
|
||||||
let Some(first) = bytes.next() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
let is_zero = (first == b'-' || first == b'0') && bytes.all(|b| b == b'0');
|
|
||||||
!is_zero
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
use std::io::{BufWriter, Stdout, Write};
|
use std::io::{BufWriter, Stdout, Write};
|
||||||
use std::{cmp, i64, mem};
|
use std::{cmp, i64, mem};
|
||||||
|
|
||||||
use uucore::crash;
|
|
||||||
|
|
||||||
use crate::parasplit::{ParaWords, Paragraph, WordInfo};
|
use crate::parasplit::{ParaWords, Paragraph, WordInfo};
|
||||||
use crate::FmtOptions;
|
use crate::FmtOptions;
|
||||||
|
|
||||||
|
@ -363,28 +361,26 @@ fn find_kp_breakpoints<'a, T: Iterator<Item = &'a WordInfo<'a>>>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_best_path<'a>(paths: &[LineBreak<'a>], active: &[usize]) -> Vec<(&'a WordInfo<'a>, bool)> {
|
fn build_best_path<'a>(paths: &[LineBreak<'a>], active: &[usize]) -> Vec<(&'a WordInfo<'a>, bool)> {
|
||||||
let mut breakwords = vec![];
|
|
||||||
// of the active paths, we select the one with the fewest demerits
|
// of the active paths, we select the one with the fewest demerits
|
||||||
let mut best_idx = match active.iter().min_by_key(|&&a| paths[a].demerits) {
|
active
|
||||||
None => crash!(
|
.iter()
|
||||||
1,
|
.min_by_key(|&&a| paths[a].demerits)
|
||||||
"Failed to find a k-p linebreak solution. This should never happen."
|
.map(|&(mut best_idx)| {
|
||||||
),
|
let mut breakwords = vec![];
|
||||||
Some(&s) => s,
|
// now, chase the pointers back through the break list, recording
|
||||||
};
|
// the words at which we should break
|
||||||
|
loop {
|
||||||
// now, chase the pointers back through the break list, recording
|
let next_best = &paths[best_idx];
|
||||||
// the words at which we should break
|
match next_best.linebreak {
|
||||||
loop {
|
None => return breakwords,
|
||||||
let next_best = &paths[best_idx];
|
Some(prev) => {
|
||||||
match next_best.linebreak {
|
breakwords.push((prev, next_best.break_before));
|
||||||
None => return breakwords,
|
best_idx = next_best.prev;
|
||||||
Some(prev) => {
|
}
|
||||||
breakwords.push((prev, next_best.break_before));
|
}
|
||||||
best_idx = next_best.prev;
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
// "infinite" badness is more like (1+BAD_INFTY)^2 because of how demerits are computed
|
// "infinite" badness is more like (1+BAD_INFTY)^2 because of how demerits are computed
|
||||||
|
|
|
@ -30,8 +30,6 @@ const USAGE: &str = help_usage!("logname.md");
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let _ = uu_app().try_get_matches_from(args)?;
|
let _ = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
match get_userlogin() {
|
match get_userlogin() {
|
||||||
|
|
|
@ -1070,6 +1070,7 @@ pub fn uu_app() -> Command {
|
||||||
.about(ABOUT)
|
.about(ABOUT)
|
||||||
.infer_long_args(true)
|
.infer_long_args(true)
|
||||||
.disable_help_flag(true)
|
.disable_help_flag(true)
|
||||||
|
.args_override_self(true)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::HELP)
|
Arg::new(options::HELP)
|
||||||
.long(options::HELP)
|
.long(options::HELP)
|
||||||
|
@ -1552,7 +1553,7 @@ pub fn uu_app() -> Command {
|
||||||
.short('h')
|
.short('h')
|
||||||
.long(options::size::HUMAN_READABLE)
|
.long(options::size::HUMAN_READABLE)
|
||||||
.help("Print human readable file sizes (e.g. 1K 234M 56G).")
|
.help("Print human readable file sizes (e.g. 1K 234M 56G).")
|
||||||
.overrides_with(options::size::SI)
|
.overrides_with_all([options::size::BLOCK_SIZE, options::size::SI])
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1569,6 +1570,7 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::size::SI)
|
Arg::new(options::size::SI)
|
||||||
.long(options::size::SI)
|
.long(options::size::SI)
|
||||||
.help("Print human readable file sizes using powers of 1000 instead of 1024.")
|
.help("Print human readable file sizes using powers of 1000 instead of 1024.")
|
||||||
|
.overrides_with_all([options::size::BLOCK_SIZE, options::size::HUMAN_READABLE])
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1576,7 +1578,8 @@ pub fn uu_app() -> Command {
|
||||||
.long(options::size::BLOCK_SIZE)
|
.long(options::size::BLOCK_SIZE)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("BLOCK_SIZE")
|
.value_name("BLOCK_SIZE")
|
||||||
.help("scale sizes by BLOCK_SIZE when printing them"),
|
.help("scale sizes by BLOCK_SIZE when printing them")
|
||||||
|
.overrides_with_all([options::size::SI, options::size::HUMAN_READABLE]),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::INODE)
|
Arg::new(options::INODE)
|
||||||
|
|
|
@ -22,8 +22,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
if matches.contains_id(options::CONTEXT) {
|
if matches.contains_id(options::CONTEXT) {
|
||||||
|
|
|
@ -68,7 +68,6 @@ fn _mknod(file_name: &str, mode: mode_t, dev: dev_t) -> i32 {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
// Linux-specific options, not implemented
|
// Linux-specific options, not implemented
|
||||||
// opts.optflag("Z", "", "set the SELinux security context to default type");
|
// opts.optflag("Z", "", "set the SELinux security context to default type");
|
||||||
// opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX");
|
// opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX");
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
// This file is part of the uutils coreutils package.
|
|
||||||
//
|
|
||||||
// For the full copyright and license information, please view the LICENSE
|
|
||||||
// file that was distributed with this source code.
|
|
||||||
// spell-checker:ignore (path) osrelease
|
|
||||||
|
|
||||||
use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR};
|
|
||||||
|
|
||||||
use uucore::mode;
|
|
||||||
|
|
||||||
pub const MODE_RW_UGO: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
|
||||||
|
|
||||||
pub fn parse_mode(mode: &str) -> Result<mode_t, String> {
|
|
||||||
let result = if mode.chars().any(|c| c.is_ascii_digit()) {
|
|
||||||
mode::parse_numeric(MODE_RW_UGO as u32, mode)
|
|
||||||
} else {
|
|
||||||
mode::parse_symbolic(MODE_RW_UGO as u32, mode, true)
|
|
||||||
};
|
|
||||||
result.map(|mode| mode as mode_t)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
/// Test if the program is running under WSL
|
|
||||||
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
|
||||||
// ToDO: test on WSL2 which likely doesn't need special handling; plan change to `is_wsl_1()` if WSL2 is less needy
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn symbolic_modes() {
|
|
||||||
assert_eq!(super::parse_mode("u+x").unwrap(), 0o766);
|
|
||||||
assert_eq!(
|
|
||||||
super::parse_mode("+x").unwrap(),
|
|
||||||
if is_wsl() { 0o776 } else { 0o777 }
|
|
||||||
);
|
|
||||||
assert_eq!(super::parse_mode("a-w").unwrap(), 0o444);
|
|
||||||
assert_eq!(super::parse_mode("g-r").unwrap(), 0o626);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn numeric_modes() {
|
|
||||||
assert_eq!(super::parse_mode("644").unwrap(), 0o644);
|
|
||||||
assert_eq!(super::parse_mode("+100").unwrap(), 0o766);
|
|
||||||
assert_eq!(super::parse_mode("-4").unwrap(), 0o662);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ use uucore::{format_usage, help_about, help_usage};
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::ffi::OsStr;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -308,8 +309,7 @@ impl Params {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
let args: Vec<_> = args.collect();
|
||||||
|
|
||||||
let matches = match uu_app().try_get_matches_from(&args) {
|
let matches = match uu_app().try_get_matches_from(&args) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -333,7 +333,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
// If POSIXLY_CORRECT was set, template MUST be the last argument.
|
// If POSIXLY_CORRECT was set, template MUST be the last argument.
|
||||||
if matches.contains_id(ARG_TEMPLATE) {
|
if matches.contains_id(ARG_TEMPLATE) {
|
||||||
// Template argument was provided, check if was the last one.
|
// Template argument was provided, check if was the last one.
|
||||||
if args.last().unwrap() != &options.template {
|
if args.last().unwrap() != OsStr::new(&options.template) {
|
||||||
return Err(Box::new(MkTempError::TooManyTemplates));
|
return Err(Box::new(MkTempError::TooManyTemplates));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@ impl Options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
let matches = match uu_app().try_get_matches_from(args) {
|
let matches = match uu_app().try_get_matches_from(args) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
|
|
|
@ -178,8 +178,6 @@ pub mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let mut settings = Settings::default();
|
let mut settings = Settings::default();
|
||||||
|
|
|
@ -74,8 +74,6 @@ impl Display for NohupError {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
|
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
|
||||||
|
|
||||||
replace_fds()?;
|
replace_fds()?;
|
||||||
|
|
|
@ -36,8 +36,6 @@ const POSIX_NAME_MAX: usize = 14;
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
// set working mode
|
// set working mode
|
||||||
|
|
|
@ -27,7 +27,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
let matches = uu_app().get_matches_from(args);
|
let matches = uu_app().get_matches_from(args);
|
||||||
|
|
||||||
let format_string = matches
|
let format_string = matches
|
||||||
|
|
|
@ -715,8 +715,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let mut input_files: Vec<String> = match &matches.get_many::<String>(options::FILE) {
|
let mut input_files: Vec<String> = match &matches.get_many::<String>(options::FILE) {
|
||||||
|
|
|
@ -200,8 +200,6 @@ impl BytesWriter {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
if !matches.contains_id(options::FILE) {
|
if !matches.contains_id(options::FILE) {
|
||||||
|
|
|
@ -47,8 +47,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let mode = if let Some(args) = matches.get_many::<String>(options::ECHO) {
|
let mode = if let Some(args) = matches.get_many::<String>(options::ECHO) {
|
||||||
|
|
|
@ -1029,7 +1029,6 @@ fn make_sort_mode_arg(mode: &'static str, short: char, help: &'static str) -> Ar
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
let mut settings = GlobalSettings::default();
|
let mut settings = GlobalSettings::default();
|
||||||
|
|
||||||
let matches = match uu_app().try_get_matches_from(args) {
|
let matches = match uu_app().try_get_matches_from(args) {
|
||||||
|
|
|
@ -141,8 +141,6 @@ fn get_preload_env(tmp_dir: &TempDir) -> UResult<(String, PathBuf)> {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_ignore();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let options = ProgramOptions::try_from(&matches).map_err(|e| UUsageError::new(125, e.0))?;
|
let options = ProgramOptions::try_from(&matches).map_err(|e| UUsageError::new(125, e.0))?;
|
||||||
|
|
|
@ -176,8 +176,6 @@ ioctl_write_ptr_bad!(
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let opts = Options::from(&matches)?;
|
let opts = Options::from(&matches)?;
|
||||||
|
|
|
@ -102,8 +102,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let files: Vec<String> = match matches.get_many::<String>(options::FILE) {
|
let files: Vec<String> = match matches.get_many::<String>(options::FILE) {
|
||||||
|
|
|
@ -33,8 +33,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let before = matches.get_flag(options::BEFORE);
|
let before = matches.get_flag(options::BEFORE);
|
||||||
|
|
|
@ -107,8 +107,6 @@ impl Config {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
|
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
|
||||||
|
|
||||||
let config = Config::from(&matches)?;
|
let config = Config::from(&matches)?;
|
||||||
|
|
|
@ -33,8 +33,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?;
|
let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?;
|
||||||
|
|
||||||
let delete_flag = matches.get_flag(options::DELETE);
|
let delete_flag = matches.get_flag(options::DELETE);
|
||||||
|
|
|
@ -20,8 +20,6 @@ mod options {
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args.collect_lossy();
|
|
||||||
|
|
||||||
let matches = uu_app().try_get_matches_from(args)?;
|
let matches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let input = matches
|
let input = matches
|
||||||
|
|
|
@ -14,8 +14,8 @@ fn test_hostname() {
|
||||||
assert!(ls_default_res.stdout().len() >= ls_domain_res.stdout().len());
|
assert!(ls_default_res.stdout().len() >= ls_domain_res.stdout().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
// FixME: fails for "MacOS" and "freebsd" "failed to lookup address information: Name does not resolve"
|
// FixME: fails for "MacOS", "freebsd" and "openbsd" "failed to lookup address information: Name does not resolve"
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
|
#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hostname_ip() {
|
fn test_hostname_ip() {
|
||||||
let result = new_ucmd!().arg("-i").succeeds();
|
let result = new_ucmd!().arg("-i").succeeds();
|
||||||
|
|
|
@ -3874,6 +3874,71 @@ fn test_ls_invalid_block_size() {
|
||||||
.stderr_is("ls: invalid --block-size argument 'invalid'\n");
|
.stderr_is("ls: invalid --block-size argument 'invalid'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "dd"))]
|
||||||
|
#[test]
|
||||||
|
fn test_ls_block_size_override() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ccmd("dd")
|
||||||
|
.arg("if=/dev/zero")
|
||||||
|
.arg("of=file")
|
||||||
|
.arg("bs=1024")
|
||||||
|
.arg("count=1")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
// --si "wins"
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-s")
|
||||||
|
.arg("--block-size=512")
|
||||||
|
.arg("--si")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains_line("total 4.1k");
|
||||||
|
|
||||||
|
// --block-size "wins"
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-s")
|
||||||
|
.arg("--si")
|
||||||
|
.arg("--block-size=512")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains_line("total 8");
|
||||||
|
|
||||||
|
// --human-readable "wins"
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-s")
|
||||||
|
.arg("--block-size=512")
|
||||||
|
.arg("--human-readable")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains_line("total 4.0K");
|
||||||
|
|
||||||
|
// --block-size "wins"
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-s")
|
||||||
|
.arg("--human-readable")
|
||||||
|
.arg("--block-size=512")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains_line("total 8");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ls_block_size_override_self() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("--block-size=512")
|
||||||
|
.arg("--block-size=512")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("--human-readable")
|
||||||
|
.arg("--human-readable")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
new_ucmd!().arg("--si").arg("--si").succeeds();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ls_hyperlink() {
|
fn test_ls_hyperlink() {
|
||||||
let scene = TestScenario::new(util_name!());
|
let scene = TestScenario::new(util_name!());
|
||||||
|
|
|
@ -10,10 +10,20 @@ use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_invalid_arg() {
|
fn test_mv_invalid_arg() {
|
||||||
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mv_missing_dest() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let dir = "dir";
|
||||||
|
|
||||||
|
at.mkdir(dir);
|
||||||
|
|
||||||
|
ucmd.arg(dir).fails();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mv_rename_dir() {
|
fn test_mv_rename_dir() {
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
@ -27,16 +37,6 @@ fn test_mv_rename_dir() {
|
||||||
assert!(at.dir_exists(dir2));
|
assert!(at.dir_exists(dir2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_mv_fail() {
|
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
|
||||||
let dir1 = "test_mv_rename_dir";
|
|
||||||
|
|
||||||
at.mkdir(dir1);
|
|
||||||
|
|
||||||
ucmd.arg(dir1).fails();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mv_rename_file() {
|
fn test_mv_rename_file() {
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue