mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 20:17:45 +00:00
Merge branch 'master' into polish-gnu-tests
This commit is contained in:
commit
c804ec3ba3
199 changed files with 3134 additions and 1824 deletions
27
.github/workflows/CICD.yml
vendored
27
.github/workflows/CICD.yml
vendored
|
@ -154,6 +154,33 @@ jobs:
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: '-Awarnings'
|
RUSTFLAGS: '-Awarnings'
|
||||||
|
|
||||||
|
busybox_test:
|
||||||
|
name: Busybox test suite
|
||||||
|
runs-on: ${{ matrix.job.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { os: ubuntu-latest }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Install `rust` toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
default: true
|
||||||
|
profile: minimal # minimal component installation (ie, no documentation)
|
||||||
|
- name: "prepare busytest"
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
make prepare-busytest
|
||||||
|
- name: "run busybox testsuite"
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
bindir=$(pwd)/target/debug
|
||||||
|
cd tmp/busybox-*/testsuite
|
||||||
|
S=$(bindir=$bindir ./runtest) && printf "%s\n" "$S" || { printf "%s\n" "$S" | grep "FAIL:" | sed -e "s/FAIL: /::warning ::Test failure:/g" ; }
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Build
|
||||||
runs-on: ${{ matrix.job.os }}
|
runs-on: ${{ matrix.job.os }}
|
||||||
|
|
|
@ -18,7 +18,7 @@ matrix:
|
||||||
- rust: nightly
|
- rust: nightly
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
- rust: 1.32.0
|
- rust: 1.33.0
|
||||||
env: FEATURES=unix
|
env: FEATURES=unix
|
||||||
# - rust: stable
|
# - rust: stable
|
||||||
# os: linux
|
# os: linux
|
||||||
|
|
841
Cargo.lock
generated
841
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
196
Cargo.toml
196
Cargo.toml
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "coreutils"
|
name = "coreutils"
|
||||||
version = "0.0.3" # "0.0.3.1"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust"
|
description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust"
|
||||||
|
@ -226,104 +226,104 @@ test = [ "uu_test" ]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = { version="1.3" }
|
lazy_static = { version="1.3" }
|
||||||
textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review
|
textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="src/uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="src/uucore" }
|
||||||
# * uutils
|
# * uutils
|
||||||
uu_test = { optional=true, version="0.0.3", package="uu_test", path="src/uu/test" }
|
uu_test = { optional=true, version="0.0.4", package="uu_test", path="src/uu/test" }
|
||||||
#
|
#
|
||||||
arch = { optional=true, version="0.0.3", package="uu_arch", path="src/uu/arch" }
|
arch = { optional=true, version="0.0.4", package="uu_arch", path="src/uu/arch" }
|
||||||
base32 = { optional=true, version="0.0.3", package="uu_base32", path="src/uu/base32" }
|
base32 = { optional=true, version="0.0.4", package="uu_base32", path="src/uu/base32" }
|
||||||
base64 = { optional=true, version="0.0.3", package="uu_base64", path="src/uu/base64" }
|
base64 = { optional=true, version="0.0.4", package="uu_base64", path="src/uu/base64" }
|
||||||
basename = { optional=true, version="0.0.3", package="uu_basename", path="src/uu/basename" }
|
basename = { optional=true, version="0.0.4", package="uu_basename", path="src/uu/basename" }
|
||||||
cat = { optional=true, version="0.0.3", package="uu_cat", path="src/uu/cat" }
|
cat = { optional=true, version="0.0.4", package="uu_cat", path="src/uu/cat" }
|
||||||
chgrp = { optional=true, version="0.0.3", package="uu_chgrp", path="src/uu/chgrp" }
|
chgrp = { optional=true, version="0.0.4", package="uu_chgrp", path="src/uu/chgrp" }
|
||||||
chmod = { optional=true, version="0.0.3", package="uu_chmod", path="src/uu/chmod" }
|
chmod = { optional=true, version="0.0.4", package="uu_chmod", path="src/uu/chmod" }
|
||||||
chown = { optional=true, version="0.0.3", package="uu_chown", path="src/uu/chown" }
|
chown = { optional=true, version="0.0.4", package="uu_chown", path="src/uu/chown" }
|
||||||
chroot = { optional=true, version="0.0.3", package="uu_chroot", path="src/uu/chroot" }
|
chroot = { optional=true, version="0.0.4", package="uu_chroot", path="src/uu/chroot" }
|
||||||
cksum = { optional=true, version="0.0.3", package="uu_cksum", path="src/uu/cksum" }
|
cksum = { optional=true, version="0.0.4", package="uu_cksum", path="src/uu/cksum" }
|
||||||
comm = { optional=true, version="0.0.3", package="uu_comm", path="src/uu/comm" }
|
comm = { optional=true, version="0.0.4", package="uu_comm", path="src/uu/comm" }
|
||||||
cp = { optional=true, version="0.0.3", package="uu_cp", path="src/uu/cp" }
|
cp = { optional=true, version="0.0.4", package="uu_cp", path="src/uu/cp" }
|
||||||
csplit = { optional=true, version="0.0.3", package="uu_csplit", path="src/uu/csplit" }
|
csplit = { optional=true, version="0.0.4", package="uu_csplit", path="src/uu/csplit" }
|
||||||
cut = { optional=true, version="0.0.3", package="uu_cut", path="src/uu/cut" }
|
cut = { optional=true, version="0.0.4", package="uu_cut", path="src/uu/cut" }
|
||||||
date = { optional=true, version="0.0.3", package="uu_date", path="src/uu/date" }
|
date = { optional=true, version="0.0.4", package="uu_date", path="src/uu/date" }
|
||||||
df = { optional=true, version="0.0.3", package="uu_df", path="src/uu/df" }
|
df = { optional=true, version="0.0.4", package="uu_df", path="src/uu/df" }
|
||||||
dircolors= { optional=true, version="0.0.3", package="uu_dircolors", path="src/uu/dircolors" }
|
dircolors= { optional=true, version="0.0.4", package="uu_dircolors", path="src/uu/dircolors" }
|
||||||
dirname = { optional=true, version="0.0.3", package="uu_dirname", path="src/uu/dirname" }
|
dirname = { optional=true, version="0.0.4", package="uu_dirname", path="src/uu/dirname" }
|
||||||
du = { optional=true, version="0.0.3", package="uu_du", path="src/uu/du" }
|
du = { optional=true, version="0.0.4", package="uu_du", path="src/uu/du" }
|
||||||
echo = { optional=true, version="0.0.3", package="uu_echo", path="src/uu/echo" }
|
echo = { optional=true, version="0.0.4", package="uu_echo", path="src/uu/echo" }
|
||||||
env = { optional=true, version="0.0.3", package="uu_env", path="src/uu/env" }
|
env = { optional=true, version="0.0.4", package="uu_env", path="src/uu/env" }
|
||||||
expand = { optional=true, version="0.0.3", package="uu_expand", path="src/uu/expand" }
|
expand = { optional=true, version="0.0.4", package="uu_expand", path="src/uu/expand" }
|
||||||
expr = { optional=true, version="0.0.3", package="uu_expr", path="src/uu/expr" }
|
expr = { optional=true, version="0.0.4", package="uu_expr", path="src/uu/expr" }
|
||||||
factor = { optional=true, version="0.0.3", package="uu_factor", path="src/uu/factor" }
|
factor = { optional=true, version="0.0.4", package="uu_factor", path="src/uu/factor" }
|
||||||
false = { optional=true, version="0.0.3", package="uu_false", path="src/uu/false" }
|
false = { optional=true, version="0.0.4", package="uu_false", path="src/uu/false" }
|
||||||
fmt = { optional=true, version="0.0.3", package="uu_fmt", path="src/uu/fmt" }
|
fmt = { optional=true, version="0.0.4", package="uu_fmt", path="src/uu/fmt" }
|
||||||
fold = { optional=true, version="0.0.3", package="uu_fold", path="src/uu/fold" }
|
fold = { optional=true, version="0.0.4", package="uu_fold", path="src/uu/fold" }
|
||||||
groups = { optional=true, version="0.0.3", package="uu_groups", path="src/uu/groups" }
|
groups = { optional=true, version="0.0.4", package="uu_groups", path="src/uu/groups" }
|
||||||
hashsum = { optional=true, version="0.0.3", package="uu_hashsum", path="src/uu/hashsum" }
|
hashsum = { optional=true, version="0.0.4", package="uu_hashsum", path="src/uu/hashsum" }
|
||||||
head = { optional=true, version="0.0.3", package="uu_head", path="src/uu/head" }
|
head = { optional=true, version="0.0.4", package="uu_head", path="src/uu/head" }
|
||||||
hostid = { optional=true, version="0.0.3", package="uu_hostid", path="src/uu/hostid" }
|
hostid = { optional=true, version="0.0.4", package="uu_hostid", path="src/uu/hostid" }
|
||||||
hostname = { optional=true, version="0.0.3", package="uu_hostname", path="src/uu/hostname" }
|
hostname = { optional=true, version="0.0.4", package="uu_hostname", path="src/uu/hostname" }
|
||||||
id = { optional=true, version="0.0.3", package="uu_id", path="src/uu/id" }
|
id = { optional=true, version="0.0.4", package="uu_id", path="src/uu/id" }
|
||||||
install = { optional=true, version="0.0.3", package="uu_install", path="src/uu/install" }
|
install = { optional=true, version="0.0.4", package="uu_install", path="src/uu/install" }
|
||||||
join = { optional=true, version="0.0.3", package="uu_join", path="src/uu/join" }
|
join = { optional=true, version="0.0.4", package="uu_join", path="src/uu/join" }
|
||||||
kill = { optional=true, version="0.0.3", package="uu_kill", path="src/uu/kill" }
|
kill = { optional=true, version="0.0.4", package="uu_kill", path="src/uu/kill" }
|
||||||
link = { optional=true, version="0.0.3", package="uu_link", path="src/uu/link" }
|
link = { optional=true, version="0.0.4", package="uu_link", path="src/uu/link" }
|
||||||
ln = { optional=true, version="0.0.3", package="uu_ln", path="src/uu/ln" }
|
ln = { optional=true, version="0.0.4", package="uu_ln", path="src/uu/ln" }
|
||||||
ls = { optional=true, version="0.0.3", package="uu_ls", path="src/uu/ls" }
|
ls = { optional=true, version="0.0.4", package="uu_ls", path="src/uu/ls" }
|
||||||
logname = { optional=true, version="0.0.3", package="uu_logname", path="src/uu/logname" }
|
logname = { optional=true, version="0.0.4", package="uu_logname", path="src/uu/logname" }
|
||||||
mkdir = { optional=true, version="0.0.3", package="uu_mkdir", path="src/uu/mkdir" }
|
mkdir = { optional=true, version="0.0.4", package="uu_mkdir", path="src/uu/mkdir" }
|
||||||
mkfifo = { optional=true, version="0.0.3", package="uu_mkfifo", path="src/uu/mkfifo" }
|
mkfifo = { optional=true, version="0.0.4", package="uu_mkfifo", path="src/uu/mkfifo" }
|
||||||
mknod = { optional=true, version="0.0.3", package="uu_mknod", path="src/uu/mknod" }
|
mknod = { optional=true, version="0.0.4", package="uu_mknod", path="src/uu/mknod" }
|
||||||
mktemp = { optional=true, version="0.0.3", package="uu_mktemp", path="src/uu/mktemp" }
|
mktemp = { optional=true, version="0.0.4", package="uu_mktemp", path="src/uu/mktemp" }
|
||||||
more = { optional=true, version="0.0.3", package="uu_more", path="src/uu/more" }
|
more = { optional=true, version="0.0.4", package="uu_more", path="src/uu/more" }
|
||||||
mv = { optional=true, version="0.0.3", package="uu_mv", path="src/uu/mv" }
|
mv = { optional=true, version="0.0.4", package="uu_mv", path="src/uu/mv" }
|
||||||
nice = { optional=true, version="0.0.3", package="uu_nice", path="src/uu/nice" }
|
nice = { optional=true, version="0.0.4", package="uu_nice", path="src/uu/nice" }
|
||||||
nl = { optional=true, version="0.0.3", package="uu_nl", path="src/uu/nl" }
|
nl = { optional=true, version="0.0.4", package="uu_nl", path="src/uu/nl" }
|
||||||
nohup = { optional=true, version="0.0.3", package="uu_nohup", path="src/uu/nohup" }
|
nohup = { optional=true, version="0.0.4", package="uu_nohup", path="src/uu/nohup" }
|
||||||
nproc = { optional=true, version="0.0.3", package="uu_nproc", path="src/uu/nproc" }
|
nproc = { optional=true, version="0.0.4", package="uu_nproc", path="src/uu/nproc" }
|
||||||
numfmt = { optional=true, version="0.0.3", package="uu_numfmt", path="src/uu/numfmt" }
|
numfmt = { optional=true, version="0.0.4", package="uu_numfmt", path="src/uu/numfmt" }
|
||||||
od = { optional=true, version="0.0.3", package="uu_od", path="src/uu/od" }
|
od = { optional=true, version="0.0.4", package="uu_od", path="src/uu/od" }
|
||||||
paste = { optional=true, version="0.0.3", package="uu_paste", path="src/uu/paste" }
|
paste = { optional=true, version="0.0.4", package="uu_paste", path="src/uu/paste" }
|
||||||
pathchk = { optional=true, version="0.0.3", package="uu_pathchk", path="src/uu/pathchk" }
|
pathchk = { optional=true, version="0.0.4", package="uu_pathchk", path="src/uu/pathchk" }
|
||||||
pinky = { optional=true, version="0.0.3", package="uu_pinky", path="src/uu/pinky" }
|
pinky = { optional=true, version="0.0.4", package="uu_pinky", path="src/uu/pinky" }
|
||||||
printenv = { optional=true, version="0.0.3", package="uu_printenv", path="src/uu/printenv" }
|
printenv = { optional=true, version="0.0.4", package="uu_printenv", path="src/uu/printenv" }
|
||||||
printf = { optional=true, version="0.0.3", package="uu_printf", path="src/uu/printf" }
|
printf = { optional=true, version="0.0.4", package="uu_printf", path="src/uu/printf" }
|
||||||
ptx = { optional=true, version="0.0.3", package="uu_ptx", path="src/uu/ptx" }
|
ptx = { optional=true, version="0.0.4", package="uu_ptx", path="src/uu/ptx" }
|
||||||
pwd = { optional=true, version="0.0.3", package="uu_pwd", path="src/uu/pwd" }
|
pwd = { optional=true, version="0.0.4", package="uu_pwd", path="src/uu/pwd" }
|
||||||
readlink = { optional=true, version="0.0.3", package="uu_readlink", path="src/uu/readlink" }
|
readlink = { optional=true, version="0.0.4", package="uu_readlink", path="src/uu/readlink" }
|
||||||
realpath = { optional=true, version="0.0.3", package="uu_realpath", path="src/uu/realpath" }
|
realpath = { optional=true, version="0.0.4", package="uu_realpath", path="src/uu/realpath" }
|
||||||
relpath = { optional=true, version="0.0.3", package="uu_relpath", path="src/uu/relpath" }
|
relpath = { optional=true, version="0.0.4", package="uu_relpath", path="src/uu/relpath" }
|
||||||
rm = { optional=true, version="0.0.3", package="uu_rm", path="src/uu/rm" }
|
rm = { optional=true, version="0.0.4", package="uu_rm", path="src/uu/rm" }
|
||||||
rmdir = { optional=true, version="0.0.3", package="uu_rmdir", path="src/uu/rmdir" }
|
rmdir = { optional=true, version="0.0.4", package="uu_rmdir", path="src/uu/rmdir" }
|
||||||
seq = { optional=true, version="0.0.3", package="uu_seq", path="src/uu/seq" }
|
seq = { optional=true, version="0.0.4", package="uu_seq", path="src/uu/seq" }
|
||||||
shred = { optional=true, version="0.0.3", package="uu_shred", path="src/uu/shred" }
|
shred = { optional=true, version="0.0.4", package="uu_shred", path="src/uu/shred" }
|
||||||
shuf = { optional=true, version="0.0.3", package="uu_shuf", path="src/uu/shuf" }
|
shuf = { optional=true, version="0.0.4", package="uu_shuf", path="src/uu/shuf" }
|
||||||
sleep = { optional=true, version="0.0.3", package="uu_sleep", path="src/uu/sleep" }
|
sleep = { optional=true, version="0.0.4", package="uu_sleep", path="src/uu/sleep" }
|
||||||
sort = { optional=true, version="0.0.3", package="uu_sort", path="src/uu/sort" }
|
sort = { optional=true, version="0.0.4", package="uu_sort", path="src/uu/sort" }
|
||||||
split = { optional=true, version="0.0.3", package="uu_split", path="src/uu/split" }
|
split = { optional=true, version="0.0.4", package="uu_split", path="src/uu/split" }
|
||||||
stat = { optional=true, version="0.0.3", package="uu_stat", path="src/uu/stat" }
|
stat = { optional=true, version="0.0.4", package="uu_stat", path="src/uu/stat" }
|
||||||
stdbuf = { optional=true, version="0.0.3", package="uu_stdbuf", path="src/uu/stdbuf" }
|
stdbuf = { optional=true, version="0.0.4", package="uu_stdbuf", path="src/uu/stdbuf" }
|
||||||
sum = { optional=true, version="0.0.3", package="uu_sum", path="src/uu/sum" }
|
sum = { optional=true, version="0.0.4", package="uu_sum", path="src/uu/sum" }
|
||||||
sync = { optional=true, version="0.0.3", package="uu_sync", path="src/uu/sync" }
|
sync = { optional=true, version="0.0.4", package="uu_sync", path="src/uu/sync" }
|
||||||
tac = { optional=true, version="0.0.3", package="uu_tac", path="src/uu/tac" }
|
tac = { optional=true, version="0.0.4", package="uu_tac", path="src/uu/tac" }
|
||||||
tail = { optional=true, version="0.0.3", package="uu_tail", path="src/uu/tail" }
|
tail = { optional=true, version="0.0.4", package="uu_tail", path="src/uu/tail" }
|
||||||
tee = { optional=true, version="0.0.3", package="uu_tee", path="src/uu/tee" }
|
tee = { optional=true, version="0.0.4", package="uu_tee", path="src/uu/tee" }
|
||||||
timeout = { optional=true, version="0.0.3", package="uu_timeout", path="src/uu/timeout" }
|
timeout = { optional=true, version="0.0.4", package="uu_timeout", path="src/uu/timeout" }
|
||||||
touch = { optional=true, version="0.0.3", package="uu_touch", path="src/uu/touch" }
|
touch = { optional=true, version="0.0.4", package="uu_touch", path="src/uu/touch" }
|
||||||
tr = { optional=true, version="0.0.3", package="uu_tr", path="src/uu/tr" }
|
tr = { optional=true, version="0.0.4", package="uu_tr", path="src/uu/tr" }
|
||||||
true = { optional=true, version="0.0.3", package="uu_true", path="src/uu/true" }
|
true = { optional=true, version="0.0.4", package="uu_true", path="src/uu/true" }
|
||||||
truncate = { optional=true, version="0.0.3", package="uu_truncate", path="src/uu/truncate" }
|
truncate = { optional=true, version="0.0.4", package="uu_truncate", path="src/uu/truncate" }
|
||||||
tsort = { optional=true, version="0.0.3", package="uu_tsort", path="src/uu/tsort" }
|
tsort = { optional=true, version="0.0.4", package="uu_tsort", path="src/uu/tsort" }
|
||||||
tty = { optional=true, version="0.0.3", package="uu_tty", path="src/uu/tty" }
|
tty = { optional=true, version="0.0.4", package="uu_tty", path="src/uu/tty" }
|
||||||
uname = { optional=true, version="0.0.3", package="uu_uname", path="src/uu/uname" }
|
uname = { optional=true, version="0.0.4", package="uu_uname", path="src/uu/uname" }
|
||||||
unexpand = { optional=true, version="0.0.3", package="uu_unexpand", path="src/uu/unexpand" }
|
unexpand = { optional=true, version="0.0.4", package="uu_unexpand", path="src/uu/unexpand" }
|
||||||
uniq = { optional=true, version="0.0.3", package="uu_uniq", path="src/uu/uniq" }
|
uniq = { optional=true, version="0.0.4", package="uu_uniq", path="src/uu/uniq" }
|
||||||
unlink = { optional=true, version="0.0.3", package="uu_unlink", path="src/uu/unlink" }
|
unlink = { optional=true, version="0.0.4", package="uu_unlink", path="src/uu/unlink" }
|
||||||
uptime = { optional=true, version="0.0.3", package="uu_uptime", path="src/uu/uptime" }
|
uptime = { optional=true, version="0.0.4", package="uu_uptime", path="src/uu/uptime" }
|
||||||
users = { optional=true, version="0.0.3", package="uu_users", path="src/uu/users" }
|
users = { optional=true, version="0.0.4", package="uu_users", path="src/uu/users" }
|
||||||
wc = { optional=true, version="0.0.3", package="uu_wc", path="src/uu/wc" }
|
wc = { optional=true, version="0.0.4", package="uu_wc", path="src/uu/wc" }
|
||||||
who = { optional=true, version="0.0.3", package="uu_who", path="src/uu/who" }
|
who = { optional=true, version="0.0.4", package="uu_who", path="src/uu/who" }
|
||||||
whoami = { optional=true, version="0.0.3", package="uu_whoami", path="src/uu/whoami" }
|
whoami = { optional=true, version="0.0.4", package="uu_whoami", path="src/uu/whoami" }
|
||||||
yes = { optional=true, version="0.0.3", package="uu_yes", path="src/uu/yes" }
|
yes = { optional=true, version="0.0.4", package="uu_yes", path="src/uu/yes" }
|
||||||
#
|
#
|
||||||
# * pinned transitive dependencies
|
# * pinned transitive dependencies
|
||||||
pin_cc = { version="1.0.61, < 1.0.62", package="cc" } ## cc v1.0.62 has compiler errors for MinRustV v1.32.0, requires 1.34 (for `std::str::split_ascii_whitespace()`)
|
pin_cc = { version="1.0.61, < 1.0.62", package="cc" } ## cc v1.0.62 has compiler errors for MinRustV v1.32.0, requires 1.34 (for `std::str::split_ascii_whitespace()`)
|
||||||
|
@ -346,7 +346,7 @@ sha1 = { version="0.6", features=["std"] }
|
||||||
tempfile = "= 3.1.0"
|
tempfile = "= 3.1.0"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
unindent = "0.1"
|
unindent = "0.1"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="src/uucore", features=["entries"] }
|
uucore = { version=">=0.0.7", package="uucore", path="src/uucore", features=["entries"] }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dev-dependencies]
|
[target.'cfg(unix)'.dev-dependencies]
|
||||||
rust-users = { version="0.10", package="users" }
|
rust-users = { version="0.10", package="users" }
|
||||||
|
|
|
@ -41,7 +41,7 @@ PKG_BUILDDIR := $(BUILDDIR)/deps
|
||||||
DOCSDIR := $(BASEDIR)/docs
|
DOCSDIR := $(BASEDIR)/docs
|
||||||
|
|
||||||
BUSYBOX_ROOT := $(BASEDIR)/tmp
|
BUSYBOX_ROOT := $(BASEDIR)/tmp
|
||||||
BUSYBOX_VER := 1.24.1
|
BUSYBOX_VER := 1.32.1
|
||||||
BUSYBOX_SRC := $(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER)
|
BUSYBOX_SRC := $(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER)
|
||||||
|
|
||||||
# Possible programs
|
# Possible programs
|
||||||
|
@ -228,7 +228,7 @@ endif
|
||||||
|
|
||||||
define TEST_BUSYBOX
|
define TEST_BUSYBOX
|
||||||
test_busybox_$(1):
|
test_busybox_$(1):
|
||||||
(cd $(BUSYBOX_SRC)/testsuite && bindir=$(BUILDDIR) ./runtest $(RUNTEST_ARGS) $(1) )
|
-(cd $(BUSYBOX_SRC)/testsuite && bindir=$(BUILDDIR) ./runtest $(RUNTEST_ARGS) $(1))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
# Output names
|
# Output names
|
||||||
|
@ -276,9 +276,11 @@ $(BUILDDIR)/.config: $(BASEDIR)/.busybox-config
|
||||||
|
|
||||||
# Test under the busybox testsuite
|
# Test under the busybox testsuite
|
||||||
$(BUILDDIR)/busybox: busybox-src build-uutils $(BUILDDIR)/.config
|
$(BUILDDIR)/busybox: busybox-src build-uutils $(BUILDDIR)/.config
|
||||||
cp $(BUILDDIR)/uutils $(BUILDDIR)/busybox; \
|
cp $(BUILDDIR)/coreutils $(BUILDDIR)/busybox; \
|
||||||
chmod +x $@;
|
chmod +x $@;
|
||||||
|
|
||||||
|
prepare-busytest: $(BUILDDIR)/busybox
|
||||||
|
|
||||||
ifeq ($(EXES),)
|
ifeq ($(EXES),)
|
||||||
busytest:
|
busytest:
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
uutils coreutils
|
uutils coreutils
|
||||||
================
|
================
|
||||||
|
|
||||||
|
[](https://crates.io/crates/coreutils)
|
||||||
[](https://discord.gg/wQVJbvJ)
|
[](https://discord.gg/wQVJbvJ)
|
||||||
[](https://github.com/uutils/coreutils/blob/master/LICENSE)
|
[](https://github.com/uutils/coreutils/blob/master/LICENSE)
|
||||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fuutils%2Fcoreutils?ref=badge_shield)
|
|
||||||
[](https://github.com/Aaronepower/tokei)
|
[](https://github.com/Aaronepower/tokei)
|
||||||
[](https://deps.rs/repo/github/uutils/coreutils)
|
[](https://deps.rs/repo/github/uutils/coreutils)
|
||||||
|
|
||||||
[](https://travis-ci.org/uutils/coreutils)
|
[](https://travis-ci.org/uutils/coreutils)
|
||||||
[](https://ci.appveyor.com/project/Arcterus/coreutils)
|
|
||||||
[](https://cirrus-ci.com/github/uutils/coreutils/master)
|
[](https://cirrus-ci.com/github/uutils/coreutils/master)
|
||||||
[](https://codecov.io/gh/uutils/coreutils)
|
[](https://codecov.io/gh/uutils/coreutils)
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ Installation Instructions
|
||||||
|
|
||||||
Likewise, installing can simply be done using:
|
Likewise, installing can simply be done using:
|
||||||
```bash
|
```bash
|
||||||
$ cargo install
|
$ cargo install --path .
|
||||||
```
|
```
|
||||||
|
|
||||||
This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo/bin`).
|
This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo/bin`).
|
||||||
|
@ -380,4 +379,4 @@ License
|
||||||
|
|
||||||
uutils is licensed under the MIT License - see the `LICENSE` file for details
|
uutils is licensed under the MIT License - see the `LICENSE` file for details
|
||||||
|
|
||||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fuutils%2Fcoreutils?ref=badge_large)
|
GNU Coreutils is licensed under the GPL 3.0 or later.
|
||||||
|
|
|
@ -19,7 +19,7 @@ include!(concat!(env!("OUT_DIR"), "/uutils_map.rs"));
|
||||||
fn usage<T>(utils: &UtilityMap<T>, name: &str) {
|
fn usage<T>(utils: &UtilityMap<T>, name: &str) {
|
||||||
println!("{} {} (multi-call binary)\n", name, VERSION);
|
println!("{} {} (multi-call binary)\n", name, VERSION);
|
||||||
println!("Usage: {} [function [arguments...]]\n", name);
|
println!("Usage: {} [function [arguments...]]\n", name);
|
||||||
println!("Currently defined functions/utilities:\n");
|
println!("Currently defined functions:\n");
|
||||||
#[allow(clippy::map_clone)]
|
#[allow(clippy::map_clone)]
|
||||||
let mut utils: Vec<&str> = utils.keys().map(|&s| s).collect();
|
let mut utils: Vec<&str> = utils.keys().map(|&s| s).collect();
|
||||||
utils.sort_unstable();
|
utils.sort_unstable();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_arch"
|
name = "uu_arch"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "arch ~ (uutils) display machine architecture"
|
description = "arch ~ (uutils) display machine architecture"
|
||||||
|
@ -15,8 +15,8 @@ edition = "2018"
|
||||||
path = "src/arch.rs"
|
path = "src/arch.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
platform-info = "0.0.1"
|
platform-info = "0.1"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_base32"
|
name = "uu_base32"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "base32 ~ (uutils) decode/encode input (base32-encoding)"
|
description = "base32 ~ (uutils) decode/encode input (base32-encoding)"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/base32.rs"
|
path = "src/base32.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features = ["encoding"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_base64"
|
name = "uu_base64"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "base64 ~ (uutils) decode/encode input (base64-encoding)"
|
description = "base64 ~ (uutils) decode/encode input (base64-encoding)"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/base64.rs"
|
path = "src/base64.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features = ["encoding"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_basename"
|
name = "uu_basename"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "basename ~ (uutils) display PATHNAME with leading directory components removed"
|
description = "basename ~ (uutils) display PATHNAME with leading directory components removed"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/basename.rs"
|
path = "src/basename.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_cat"
|
name = "uu_cat"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "cat ~ (uutils) concatenate and display input"
|
description = "cat ~ (uutils) concatenate and display input"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/cat.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quick-error = "1.2.3"
|
quick-error = "1.2.3"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_chgrp"
|
name = "uu_chgrp"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "chgrp ~ (uutils) change the group ownership of FILE"
|
description = "chgrp ~ (uutils) change the group ownership of FILE"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/chgrp.rs"
|
path = "src/chgrp.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_chmod"
|
name = "uu_chmod"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "chmod ~ (uutils) change mode of FILE"
|
description = "chmod ~ (uutils) change mode of FILE"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/chmod.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs", "mode"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs", "mode"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_chown"
|
name = "uu_chown"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "chown ~ (uutils) change the ownership of FILE"
|
description = "chown ~ (uutils) change the ownership of FILE"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/chown.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
|
|
||||||
|
|
|
@ -27,20 +27,30 @@ use std::path::Path;
|
||||||
static ABOUT: &str = "change file owner and group";
|
static ABOUT: &str = "change file owner and group";
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
static OPT_CHANGES: &str = "changes";
|
pub mod options {
|
||||||
static OPT_DEREFERENCE: &str = "dereference";
|
pub mod verbosity {
|
||||||
static OPT_NO_DEREFERENCE: &str = "no-dereference";
|
pub static CHANGES: &str = "changes";
|
||||||
static OPT_FROM: &str = "from";
|
pub static QUIET: &str = "quiet";
|
||||||
static OPT_PRESERVE_ROOT: &str = "preserve-root";
|
pub static SILENT: &str = "silent";
|
||||||
static OPT_NO_PRESERVE_ROOT: &str = "no-preserve-root";
|
pub static VERBOSE: &str = "verbose";
|
||||||
static OPT_QUIET: &str = "quiet";
|
}
|
||||||
static OPT_RECURSIVE: &str = "recursive";
|
pub mod preserve_root {
|
||||||
static OPT_REFERENCE: &str = "reference";
|
pub static PRESERVE: &str = "preserve-root";
|
||||||
static OPT_SILENT: &str = "silent";
|
pub static NO_PRESERVE: &str = "no-preserve-root";
|
||||||
static OPT_TRAVERSE: &str = "H";
|
}
|
||||||
static OPT_NO_TRAVERSE: &str = "P";
|
pub mod dereference {
|
||||||
static OPT_TRAVERSE_EVERY: &str = "L";
|
pub static DEREFERENCE: &str = "dereference";
|
||||||
static OPT_VERBOSE: &str = "verbose";
|
pub static NO_DEREFERENCE: &str = "no-dereference";
|
||||||
|
}
|
||||||
|
pub static FROM: &str = "from";
|
||||||
|
pub static RECURSIVE: &str = "recursive";
|
||||||
|
pub mod traverse {
|
||||||
|
pub static TRAVERSE: &str = "H";
|
||||||
|
pub static NO_TRAVERSE: &str = "P";
|
||||||
|
pub static EVERY: &str = "L";
|
||||||
|
}
|
||||||
|
pub static REFERENCE: &str = "reference";
|
||||||
|
}
|
||||||
|
|
||||||
static ARG_OWNER: &str = "owner";
|
static ARG_OWNER: &str = "owner";
|
||||||
static ARG_FILES: &str = "files";
|
static ARG_FILES: &str = "files";
|
||||||
|
@ -66,80 +76,80 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.about(ABOUT)
|
.about(ABOUT)
|
||||||
.usage(&usage[..])
|
.usage(&usage[..])
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_CHANGES)
|
Arg::with_name(options::verbosity::CHANGES)
|
||||||
.short("c")
|
.short("c")
|
||||||
.long(OPT_CHANGES)
|
.long(options::verbosity::CHANGES)
|
||||||
.help("like verbose but report only when a change is made"),
|
.help("like verbose but report only when a change is made"),
|
||||||
)
|
)
|
||||||
.arg(Arg::with_name(OPT_DEREFERENCE).long(OPT_DEREFERENCE).help(
|
.arg(Arg::with_name(options::dereference::DEREFERENCE).long(options::dereference::DEREFERENCE).help(
|
||||||
"affect the referent of each symbolic link (this is the default), rather than the symbolic link itself",
|
"affect the referent of each symbolic link (this is the default), rather than the symbolic link itself",
|
||||||
))
|
))
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_NO_DEREFERENCE)
|
Arg::with_name(options::dereference::NO_DEREFERENCE)
|
||||||
.short("h")
|
.short("h")
|
||||||
.long(OPT_NO_DEREFERENCE)
|
.long(options::dereference::NO_DEREFERENCE)
|
||||||
.help(
|
.help(
|
||||||
"affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)",
|
"affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_FROM)
|
Arg::with_name(options::FROM)
|
||||||
.long(OPT_FROM)
|
.long(options::FROM)
|
||||||
.help(
|
.help(
|
||||||
"change the owner and/or group of each file only if its current owner and/or group match those specified here. Either may be omitted, in which case a match is not required for the omitted attribute",
|
"change the owner and/or group of each file only if its current owner and/or group match those specified here. Either may be omitted, in which case a match is not required for the omitted attribute",
|
||||||
)
|
)
|
||||||
.value_name("CURRENT_OWNER:CURRENT_GROUP"),
|
.value_name("CURRENT_OWNER:CURRENT_GROUP"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_PRESERVE_ROOT)
|
Arg::with_name(options::preserve_root::PRESERVE)
|
||||||
.long(OPT_PRESERVE_ROOT)
|
.long(options::preserve_root::PRESERVE)
|
||||||
.help("fail to operate recursively on '/'"),
|
.help("fail to operate recursively on '/'"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_NO_PRESERVE_ROOT)
|
Arg::with_name(options::preserve_root::NO_PRESERVE)
|
||||||
.long(OPT_NO_PRESERVE_ROOT)
|
.long(options::preserve_root::NO_PRESERVE)
|
||||||
.help("do not treat '/' specially (the default)"),
|
.help("do not treat '/' specially (the default)"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_QUIET)
|
Arg::with_name(options::verbosity::QUIET)
|
||||||
.long(OPT_QUIET)
|
.long(options::verbosity::QUIET)
|
||||||
.help("suppress most error messages"),
|
.help("suppress most error messages"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_RECURSIVE)
|
Arg::with_name(options::RECURSIVE)
|
||||||
.short("R")
|
.short("R")
|
||||||
.long(OPT_RECURSIVE)
|
.long(options::RECURSIVE)
|
||||||
.help("operate on files and directories recursively"),
|
.help("operate on files and directories recursively"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_REFERENCE)
|
Arg::with_name(options::REFERENCE)
|
||||||
.long(OPT_REFERENCE)
|
.long(options::REFERENCE)
|
||||||
.help("use RFILE's owner and group rather than specifying OWNER:GROUP values")
|
.help("use RFILE's owner and group rather than specifying OWNER:GROUP values")
|
||||||
.value_name("RFILE")
|
.value_name("RFILE")
|
||||||
.min_values(1),
|
.min_values(1),
|
||||||
)
|
)
|
||||||
.arg(Arg::with_name(OPT_SILENT).short("f").long(OPT_SILENT))
|
.arg(Arg::with_name(options::verbosity::SILENT).short("f").long(options::verbosity::SILENT))
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_TRAVERSE)
|
Arg::with_name(options::traverse::TRAVERSE)
|
||||||
.short(OPT_TRAVERSE)
|
.short(options::traverse::TRAVERSE)
|
||||||
.help("if a command line argument is a symbolic link to a directory, traverse it")
|
.help("if a command line argument is a symbolic link to a directory, traverse it")
|
||||||
.overrides_with_all(&[OPT_TRAVERSE_EVERY, OPT_NO_TRAVERSE]),
|
.overrides_with_all(&[options::traverse::EVERY, options::traverse::NO_TRAVERSE]),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_TRAVERSE_EVERY)
|
Arg::with_name(options::traverse::EVERY)
|
||||||
.short(OPT_TRAVERSE_EVERY)
|
.short(options::traverse::EVERY)
|
||||||
.help("traverse every symbolic link to a directory encountered")
|
.help("traverse every symbolic link to a directory encountered")
|
||||||
.overrides_with_all(&[OPT_TRAVERSE, OPT_NO_TRAVERSE]),
|
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::NO_TRAVERSE]),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_NO_TRAVERSE)
|
Arg::with_name(options::traverse::NO_TRAVERSE)
|
||||||
.short(OPT_NO_TRAVERSE)
|
.short(options::traverse::NO_TRAVERSE)
|
||||||
.help("do not traverse any symbolic links (default)")
|
.help("do not traverse any symbolic links (default)")
|
||||||
.overrides_with_all(&[OPT_TRAVERSE, OPT_TRAVERSE_EVERY]),
|
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::EVERY]),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(OPT_VERBOSE)
|
Arg::with_name(options::verbosity::VERBOSE)
|
||||||
.long(OPT_VERBOSE)
|
.long(options::verbosity::VERBOSE)
|
||||||
.help("output a diagnostic for every file processed"),
|
.help("output a diagnostic for every file processed"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -166,23 +176,23 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.map(|v| v.map(ToString::to_string).collect())
|
.map(|v| v.map(ToString::to_string).collect())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let preserve_root = matches.is_present(OPT_PRESERVE_ROOT);
|
let preserve_root = matches.is_present(options::preserve_root::PRESERVE);
|
||||||
|
|
||||||
let mut derefer = if matches.is_present(OPT_NO_DEREFERENCE) {
|
let mut derefer = if matches.is_present(options::dereference::NO_DEREFERENCE) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut bit_flag = if matches.is_present(OPT_TRAVERSE) {
|
let mut bit_flag = if matches.is_present(options::traverse::TRAVERSE) {
|
||||||
FTS_COMFOLLOW | FTS_PHYSICAL
|
FTS_COMFOLLOW | FTS_PHYSICAL
|
||||||
} else if matches.is_present(OPT_TRAVERSE_EVERY) {
|
} else if matches.is_present(options::traverse::EVERY) {
|
||||||
FTS_LOGICAL
|
FTS_LOGICAL
|
||||||
} else {
|
} else {
|
||||||
FTS_PHYSICAL
|
FTS_PHYSICAL
|
||||||
};
|
};
|
||||||
|
|
||||||
let recursive = matches.is_present(OPT_RECURSIVE);
|
let recursive = matches.is_present(options::RECURSIVE);
|
||||||
if recursive {
|
if recursive {
|
||||||
if bit_flag == FTS_PHYSICAL {
|
if bit_flag == FTS_PHYSICAL {
|
||||||
if derefer == 1 {
|
if derefer == 1 {
|
||||||
|
@ -195,17 +205,19 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
bit_flag = FTS_PHYSICAL;
|
bit_flag = FTS_PHYSICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
let verbosity = if matches.is_present(OPT_CHANGES) {
|
let verbosity = if matches.is_present(options::verbosity::CHANGES) {
|
||||||
Verbosity::Changes
|
Verbosity::Changes
|
||||||
} else if matches.is_present(OPT_SILENT) || matches.is_present(OPT_QUIET) {
|
} else if matches.is_present(options::verbosity::SILENT)
|
||||||
|
|| matches.is_present(options::verbosity::QUIET)
|
||||||
|
{
|
||||||
Verbosity::Silent
|
Verbosity::Silent
|
||||||
} else if matches.is_present(OPT_VERBOSE) {
|
} else if matches.is_present(options::verbosity::VERBOSE) {
|
||||||
Verbosity::Verbose
|
Verbosity::Verbose
|
||||||
} else {
|
} else {
|
||||||
Verbosity::Normal
|
Verbosity::Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
let filter = if let Some(spec) = matches.value_of(OPT_FROM) {
|
let filter = if let Some(spec) = matches.value_of(options::FROM) {
|
||||||
match parse_spec(&spec) {
|
match parse_spec(&spec) {
|
||||||
Ok((Some(uid), None)) => IfFrom::User(uid),
|
Ok((Some(uid), None)) => IfFrom::User(uid),
|
||||||
Ok((None, Some(gid))) => IfFrom::Group(gid),
|
Ok((None, Some(gid))) => IfFrom::Group(gid),
|
||||||
|
@ -222,7 +234,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
let dest_uid: Option<u32>;
|
let dest_uid: Option<u32>;
|
||||||
let dest_gid: Option<u32>;
|
let dest_gid: Option<u32>;
|
||||||
if let Some(file) = matches.value_of(OPT_REFERENCE) {
|
if let Some(file) = matches.value_of(options::REFERENCE) {
|
||||||
match fs::metadata(&file) {
|
match fs::metadata(&file) {
|
||||||
Ok(meta) => {
|
Ok(meta) => {
|
||||||
dest_gid = Some(meta.gid());
|
dest_gid = Some(meta.gid());
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_chroot"
|
name = "uu_chroot"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "chroot ~ (uutils) run COMMAND under a new root directory"
|
description = "chroot ~ (uutils) run COMMAND under a new root directory"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/chroot.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -164,7 +164,7 @@ fn set_main_group(group: &str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
|
||||||
fn set_groups(groups: Vec<libc::gid_t>) -> libc::c_int {
|
fn set_groups(groups: Vec<libc::gid_t>) -> libc::c_int {
|
||||||
unsafe { setgroups(groups.len() as libc::c_int, groups.as_ptr()) }
|
unsafe { setgroups(groups.len() as libc::c_int, groups.as_ptr()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_cksum"
|
name = "uu_cksum"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "cksum ~ (uutils) display CRC and size of input"
|
description = "cksum ~ (uutils) display CRC and size of input"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/cksum.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_comm"
|
name = "uu_comm"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "comm ~ (uutils) compare sorted inputs"
|
description = "comm ~ (uutils) compare sorted inputs"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/comm.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_cp"
|
name = "uu_cp"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = [
|
authors = [
|
||||||
"Jordy Dickinson <jordy.dickinson@gmail.com>",
|
"Jordy Dickinson <jordy.dickinson@gmail.com>",
|
||||||
"Joshua S. Miller <jsmiller@uchicago.edu>",
|
"Joshua S. Miller <jsmiller@uchicago.edu>",
|
||||||
|
@ -23,7 +23,7 @@ clap = "2.33"
|
||||||
filetime = "0.2"
|
filetime = "0.2"
|
||||||
libc = "0.2.85"
|
libc = "0.2.85"
|
||||||
quick-error = "1.2.3"
|
quick-error = "1.2.3"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,7 @@ pub struct Options {
|
||||||
one_file_system: bool,
|
one_file_system: bool,
|
||||||
overwrite: OverwriteMode,
|
overwrite: OverwriteMode,
|
||||||
parents: bool,
|
parents: bool,
|
||||||
|
strip_trailing_slashes: bool,
|
||||||
reflink: bool,
|
reflink: bool,
|
||||||
reflink_mode: ReflinkMode,
|
reflink_mode: ReflinkMode,
|
||||||
preserve_attributes: Vec<Attribute>,
|
preserve_attributes: Vec<Attribute>,
|
||||||
|
@ -248,6 +249,7 @@ static OPT_NO_DEREFERENCE_PRESERVE_LINKS: &str = "no-dereference-preserve-linkgs
|
||||||
static OPT_NO_PRESERVE: &str = "no-preserve";
|
static OPT_NO_PRESERVE: &str = "no-preserve";
|
||||||
static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory";
|
static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory";
|
||||||
static OPT_ONE_FILE_SYSTEM: &str = "one-file-system";
|
static OPT_ONE_FILE_SYSTEM: &str = "one-file-system";
|
||||||
|
static OPT_PARENT: &str = "parent";
|
||||||
static OPT_PARENTS: &str = "parents";
|
static OPT_PARENTS: &str = "parents";
|
||||||
static OPT_PATHS: &str = "paths";
|
static OPT_PATHS: &str = "paths";
|
||||||
static OPT_PRESERVE: &str = "preserve";
|
static OPT_PRESERVE: &str = "preserve";
|
||||||
|
@ -333,6 +335,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.arg(Arg::with_name(OPT_RECURSIVE_ALIAS)
|
.arg(Arg::with_name(OPT_RECURSIVE_ALIAS)
|
||||||
.short("R")
|
.short("R")
|
||||||
.help("same as -r"))
|
.help("same as -r"))
|
||||||
|
.arg(Arg::with_name(OPT_STRIP_TRAILING_SLASHES)
|
||||||
|
.long(OPT_STRIP_TRAILING_SLASHES)
|
||||||
|
.help("remove any trailing slashes from each SOURCE argument"))
|
||||||
.arg(Arg::with_name(OPT_VERBOSE)
|
.arg(Arg::with_name(OPT_VERBOSE)
|
||||||
.short("v")
|
.short("v")
|
||||||
.long(OPT_VERBOSE)
|
.long(OPT_VERBOSE)
|
||||||
|
@ -403,6 +408,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.value_name("ATTR_LIST")
|
.value_name("ATTR_LIST")
|
||||||
.conflicts_with_all(&[OPT_PRESERVE_DEFAULT_ATTRIBUTES, OPT_PRESERVE, OPT_ARCHIVE])
|
.conflicts_with_all(&[OPT_PRESERVE_DEFAULT_ATTRIBUTES, OPT_PRESERVE, OPT_ARCHIVE])
|
||||||
.help("don't preserve the specified attributes"))
|
.help("don't preserve the specified attributes"))
|
||||||
|
.arg(Arg::with_name(OPT_PARENTS)
|
||||||
|
.long(OPT_PARENTS)
|
||||||
|
.alias(OPT_PARENT)
|
||||||
|
.help("use full source file name under DIRECTORY"))
|
||||||
.arg(Arg::with_name(OPT_NO_DEREFERENCE)
|
.arg(Arg::with_name(OPT_NO_DEREFERENCE)
|
||||||
.short("-P")
|
.short("-P")
|
||||||
.long(OPT_NO_DEREFERENCE)
|
.long(OPT_NO_DEREFERENCE)
|
||||||
|
@ -428,17 +437,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.long(OPT_COPY_CONTENTS)
|
.long(OPT_COPY_CONTENTS)
|
||||||
.conflicts_with(OPT_ATTRIBUTES_ONLY)
|
.conflicts_with(OPT_ATTRIBUTES_ONLY)
|
||||||
.help("NotImplemented: copy contents of special files when recursive"))
|
.help("NotImplemented: copy contents of special files when recursive"))
|
||||||
.arg(Arg::with_name(OPT_PARENTS)
|
|
||||||
.long(OPT_PARENTS)
|
|
||||||
.help("NotImplemented: use full source file name under DIRECTORY"))
|
|
||||||
.arg(Arg::with_name(OPT_SPARSE)
|
.arg(Arg::with_name(OPT_SPARSE)
|
||||||
.long(OPT_SPARSE)
|
.long(OPT_SPARSE)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.value_name("WHEN")
|
.value_name("WHEN")
|
||||||
.help("NotImplemented: control creation of sparse files. See below"))
|
.help("NotImplemented: control creation of sparse files. See below"))
|
||||||
.arg(Arg::with_name(OPT_STRIP_TRAILING_SLASHES)
|
|
||||||
.long(OPT_STRIP_TRAILING_SLASHES)
|
|
||||||
.help("NotImplemented: remove any trailing slashes from each SOURCE argument"))
|
|
||||||
.arg(Arg::with_name(OPT_ONE_FILE_SYSTEM)
|
.arg(Arg::with_name(OPT_ONE_FILE_SYSTEM)
|
||||||
.short("x")
|
.short("x")
|
||||||
.long(OPT_ONE_FILE_SYSTEM)
|
.long(OPT_ONE_FILE_SYSTEM)
|
||||||
|
@ -559,9 +562,7 @@ impl Options {
|
||||||
fn from_matches(matches: &ArgMatches) -> CopyResult<Options> {
|
fn from_matches(matches: &ArgMatches) -> CopyResult<Options> {
|
||||||
let not_implemented_opts = vec![
|
let not_implemented_opts = vec![
|
||||||
OPT_COPY_CONTENTS,
|
OPT_COPY_CONTENTS,
|
||||||
OPT_PARENTS,
|
|
||||||
OPT_SPARSE,
|
OPT_SPARSE,
|
||||||
OPT_STRIP_TRAILING_SLASHES,
|
|
||||||
OPT_ONE_FILE_SYSTEM,
|
OPT_ONE_FILE_SYSTEM,
|
||||||
OPT_CONTEXT,
|
OPT_CONTEXT,
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -629,6 +630,7 @@ impl Options {
|
||||||
backup_suffix: matches.value_of(OPT_SUFFIX).unwrap().to_string(),
|
backup_suffix: matches.value_of(OPT_SUFFIX).unwrap().to_string(),
|
||||||
update: matches.is_present(OPT_UPDATE),
|
update: matches.is_present(OPT_UPDATE),
|
||||||
verbose: matches.is_present(OPT_VERBOSE),
|
verbose: matches.is_present(OPT_VERBOSE),
|
||||||
|
strip_trailing_slashes: matches.is_present(OPT_STRIP_TRAILING_SLASHES),
|
||||||
reflink: matches.is_present(OPT_REFLINK),
|
reflink: matches.is_present(OPT_REFLINK),
|
||||||
reflink_mode: {
|
reflink_mode: {
|
||||||
if let Some(reflink) = matches.value_of(OPT_REFLINK) {
|
if let Some(reflink) = matches.value_of(OPT_REFLINK) {
|
||||||
|
@ -686,7 +688,7 @@ fn parse_path_args(path_args: &[String], options: &Options) -> CopyResult<(Vec<S
|
||||||
return Err(format!("extra operand {:?}", paths[2]).into());
|
return Err(format!("extra operand {:?}", paths[2]).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sources, target) = match options.target_dir {
|
let (mut sources, target) = match options.target_dir {
|
||||||
Some(ref target) => {
|
Some(ref target) => {
|
||||||
// All path args are sources, and the target dir was
|
// All path args are sources, and the target dir was
|
||||||
// specified separately
|
// specified separately
|
||||||
|
@ -700,6 +702,12 @@ fn parse_path_args(path_args: &[String], options: &Options) -> CopyResult<(Vec<S
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if options.strip_trailing_slashes {
|
||||||
|
for source in sources.iter_mut() {
|
||||||
|
*source = source.components().as_path().to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok((sources, target))
|
Ok((sources, target))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,9 +851,17 @@ fn construct_dest_path(
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.parents && !target.is_dir() {
|
||||||
|
return Err("with --parents, the destination must be a directory".into());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(match *target_type {
|
Ok(match *target_type {
|
||||||
TargetType::Directory => {
|
TargetType::Directory => {
|
||||||
let root = source_path.parent().unwrap_or(source_path);
|
let root = if options.parents {
|
||||||
|
Path::new("")
|
||||||
|
} else {
|
||||||
|
source_path.parent().unwrap_or(source_path)
|
||||||
|
};
|
||||||
localize_to_target(root, source_path, target)?
|
localize_to_target(root, source_path, target)?
|
||||||
}
|
}
|
||||||
TargetType::File => target.to_path_buf(),
|
TargetType::File => target.to_path_buf(),
|
||||||
|
@ -938,7 +954,7 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult
|
||||||
Some(parent) => {
|
Some(parent) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
// On Windows, some pathes are starting with \\?
|
// On Windows, some paths are starting with \\?
|
||||||
// but not always, so, make sure that we are consistent for strip_prefix
|
// but not always, so, make sure that we are consistent for strip_prefix
|
||||||
// See https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file for more info
|
// See https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file for more info
|
||||||
let parent_can = adjust_canonicalization(parent);
|
let parent_can = adjust_canonicalization(parent);
|
||||||
|
@ -1231,15 +1247,17 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()>
|
||||||
dest.into()
|
dest.into()
|
||||||
};
|
};
|
||||||
symlink_file(&link, &dest, &*context_for(&link, &dest))?;
|
symlink_file(&link, &dest, &*context_for(&link, &dest))?;
|
||||||
|
} else if source.to_string_lossy() == "/dev/null" {
|
||||||
|
/* workaround a limitation of fs::copy
|
||||||
|
* https://github.com/rust-lang/rust/issues/79390
|
||||||
|
*/
|
||||||
|
File::create(dest)?;
|
||||||
} else {
|
} else {
|
||||||
if source.to_string_lossy() == "/dev/null" {
|
if options.parents {
|
||||||
/* workaround a limitation of fs::copy
|
let parent = dest.parent().unwrap_or(dest);
|
||||||
* https://github.com/rust-lang/rust/issues/79390
|
fs::create_dir_all(parent)?;
|
||||||
*/
|
|
||||||
File::create(dest)?;
|
|
||||||
} else {
|
|
||||||
fs::copy(source, dest).context(&*context_for(source, dest))?;
|
|
||||||
}
|
}
|
||||||
|
fs::copy(source, dest).context(&*context_for(source, dest))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_csplit"
|
name = "uu_csplit"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output"
|
description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output"
|
||||||
|
@ -19,7 +19,7 @@ getopts = "0.2.17"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
regex = "1.0.0"
|
regex = "1.0.0"
|
||||||
glob = "0.2.11"
|
glob = "0.2.11"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -344,7 +344,7 @@ impl<'a> SplitWriter<'a> {
|
||||||
///
|
///
|
||||||
/// In addition to errors reading/writing from/to a file, the following errors may be returned:
|
/// In addition to errors reading/writing from/to a file, the following errors may be returned:
|
||||||
/// - if no line matched, an [`::CsplitError::MatchNotFound`].
|
/// - if no line matched, an [`::CsplitError::MatchNotFound`].
|
||||||
/// - if there are not enough lines to accomodate the offset, an
|
/// - if there are not enough lines to accommodate the offset, an
|
||||||
/// [`::CsplitError::LineOutOfRange`].
|
/// [`::CsplitError::LineOutOfRange`].
|
||||||
fn do_to_match<I>(
|
fn do_to_match<I>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -471,14 +471,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rewind the iteration by outputing the buffer's content.
|
/// Rewind the iteration by outputting the buffer's content.
|
||||||
fn rewind_buffer(&mut self) {
|
fn rewind_buffer(&mut self) {
|
||||||
self.rewind = true;
|
self.rewind = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shrink the buffer so that its length is equal to the set size, returning an iterator for
|
/// Shrink the buffer so that its length is equal to the set size, returning an iterator for
|
||||||
/// the elements that were too much.
|
/// the elements that were too much.
|
||||||
fn shrink_buffer_to_size<'a>(&'a mut self) -> impl Iterator<Item = String> + 'a {
|
fn shrink_buffer_to_size(&mut self) -> impl Iterator<Item = String> + '_ {
|
||||||
let mut shrink_offset = 0;
|
let mut shrink_offset = 0;
|
||||||
if self.buffer.len() > self.size {
|
if self.buffer.len() > self.size {
|
||||||
shrink_offset = self.buffer.len() - self.size;
|
shrink_offset = self.buffer.len() - self.size;
|
||||||
|
@ -489,7 +489,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drain the content of the buffer.
|
/// Drain the content of the buffer.
|
||||||
fn drain_buffer<'a>(&'a mut self) -> impl Iterator<Item = String> + 'a {
|
fn drain_buffer(&mut self) -> impl Iterator<Item = String> + '_ {
|
||||||
self.buffer.drain(..).map(|(_, line)| line.unwrap())
|
self.buffer.drain(..).map(|(_, line)| line.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_cut"
|
name = "uu_cut"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "cut ~ (uutils) display byte/field columns of input lines"
|
description = "cut ~ (uutils) display byte/field columns of input lines"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/cut.rs"
|
path = "src/cut.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -14,11 +14,10 @@ use std::fs::File;
|
||||||
use std::io::{stdin, stdout, BufRead, BufReader, Read, Stdout, Write};
|
use std::io::{stdin, stdout, BufRead, BufReader, Read, Stdout, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use self::ranges::Range;
|
|
||||||
use self::searcher::Searcher;
|
use self::searcher::Searcher;
|
||||||
|
use uucore::ranges::Range;
|
||||||
|
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod ranges;
|
|
||||||
mod searcher;
|
mod searcher;
|
||||||
|
|
||||||
static SYNTAX: &str =
|
static SYNTAX: &str =
|
||||||
|
@ -125,7 +124,7 @@ enum Mode {
|
||||||
|
|
||||||
fn list_to_ranges(list: &str, complement: bool) -> Result<Vec<Range>, String> {
|
fn list_to_ranges(list: &str, complement: bool) -> Result<Vec<Range>, String> {
|
||||||
if complement {
|
if complement {
|
||||||
Range::from_list(list).map(|r| ranges::complement(&r))
|
Range::from_list(list).map(|r| uucore::ranges::complement(&r))
|
||||||
} else {
|
} else {
|
||||||
Range::from_list(list)
|
Range::from_list(list)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_date"
|
name = "uu_date"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "date ~ (uutils) display or set the current time"
|
description = "date ~ (uutils) display or set the current time"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/date.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4.4"
|
chrono = "0.4.4"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_df"
|
name = "uu_df"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "df ~ (uutils) display file system information"
|
description = "df ~ (uutils) display file system information"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/df.rs"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
number_prefix = "0.4"
|
number_prefix = "0.4"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
|
|
@ -32,15 +32,15 @@ use std::ffi::CString;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_vendor = "apple")]
|
||||||
use libc::statfs;
|
use libc::statfs;
|
||||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "windows"))]
|
#[cfg(any(target_vendor = "apple", target_os = "freebsd", target_os = "windows"))]
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
#[cfg(target_os = "freebsd")]
|
#[cfg(target_os = "freebsd")]
|
||||||
|
@ -137,7 +137,7 @@ struct MountInfo {
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
not(all(target_os = "macos", target_arch = "x86_64"))
|
not(all(target_vendor = "apple", target_arch = "x86_64"))
|
||||||
))]
|
))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -209,20 +209,20 @@ fn get_usage() -> String {
|
||||||
format!("{0} [OPTION]... [FILE]...", executable!())
|
format!("{0} [OPTION]... [FILE]...", executable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
|
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
|
#[cfg(all(target_vendor = "apple", target_arch = "x86_64"))]
|
||||||
#[link_name = "getmntinfo$INODE64"]
|
#[link_name = "getmntinfo$INODE64"]
|
||||||
fn getmntinfo(mntbufp: *mut *mut statfs, flags: c_int) -> c_int;
|
fn getmntinfo(mntbufp: *mut *mut statfs, flags: c_int) -> c_int;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
all(target_os = "freebsd"),
|
all(target_os = "freebsd"),
|
||||||
all(target_os = "macos", target_arch = "aarch64")
|
all(target_vendor = "apple", target_arch = "aarch64")
|
||||||
))]
|
))]
|
||||||
fn getmntinfo(mntbufp: *mut *mut statfs, flags: c_int) -> c_int;
|
fn getmntinfo(mntbufp: *mut *mut statfs, flags: c_int) -> c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
|
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
|
||||||
impl From<statfs> for MountInfo {
|
impl From<statfs> for MountInfo {
|
||||||
fn from(statfs: statfs) -> Self {
|
fn from(statfs: statfs) -> Self {
|
||||||
let mut info = MountInfo {
|
let mut info = MountInfo {
|
||||||
|
@ -585,7 +585,7 @@ fn read_fs_list() -> Vec<MountInfo> {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
|
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
|
||||||
{
|
{
|
||||||
let mut mptr: *mut statfs = ptr::null_mut();
|
let mut mptr: *mut statfs = ptr::null_mut();
|
||||||
let len = unsafe { getmntinfo(&mut mptr, 1 as c_int) };
|
let len = unsafe { getmntinfo(&mut mptr, 1 as c_int) };
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_dircolors"
|
name = "uu_dircolors"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "dircolors ~ (uutils) display commands to set LS_COLORS"
|
description = "dircolors ~ (uutils) display commands to set LS_COLORS"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/dircolors.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_dirname"
|
name = "uu_dirname"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "dirname ~ (uutils) display parent directory of PATHNAME"
|
description = "dirname ~ (uutils) display parent directory of PATHNAME"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/dirname.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_du"
|
name = "uu_du"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "du ~ (uutils) display disk usage"
|
description = "du ~ (uutils) display disk usage"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/du.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
time = "0.1.40"
|
time = "0.1.40"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_echo"
|
name = "uu_echo"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "echo ~ (uutils) display TEXT"
|
description = "echo ~ (uutils) display TEXT"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/echo.rs"
|
path = "src/echo.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
4
src/uu/env/Cargo.toml
vendored
4
src/uu/env/Cargo.toml
vendored
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_env"
|
name = "uu_env"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND"
|
description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/env.rs"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
rust-ini = "0.13.0"
|
rust-ini = "0.13.0"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_expand"
|
name = "uu_expand"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "expand ~ (uutils) convert input tabs to spaces"
|
description = "expand ~ (uutils) convert input tabs to spaces"
|
||||||
|
@ -15,9 +15,9 @@ edition = "2018"
|
||||||
path = "src/expand.rs"
|
path = "src/expand.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
clap = "2.33"
|
||||||
unicode-width = "0.1.5"
|
unicode-width = "0.1.5"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -12,19 +12,32 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
use clap::{App, Arg, ArgMatches};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
|
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use unicode_width::UnicodeWidthChar;
|
use unicode_width::UnicodeWidthChar;
|
||||||
|
|
||||||
static SYNTAX: &str = "[OPTION]... [FILE]...";
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
static SUMMARY: &str = "Convert tabs in each FILE to spaces, writing to standard output.
|
static ABOUT: &str = "Convert tabs in each FILE to spaces, writing to standard output.
|
||||||
With no FILE, or when FILE is -, read standard input.";
|
With no FILE, or when FILE is -, read standard input.";
|
||||||
|
|
||||||
|
pub mod options {
|
||||||
|
pub static TABS: &str = "tabs";
|
||||||
|
pub static INITIAL: &str = "initial";
|
||||||
|
pub static NO_UTF8: &str = "no-utf8";
|
||||||
|
pub static FILES: &str = "FILES";
|
||||||
|
}
|
||||||
|
|
||||||
static LONG_HELP: &str = "";
|
static LONG_HELP: &str = "";
|
||||||
|
|
||||||
static DEFAULT_TABSTOP: usize = 8;
|
static DEFAULT_TABSTOP: usize = 8;
|
||||||
|
|
||||||
|
fn get_usage() -> String {
|
||||||
|
format!("{0} [OPTION]... [FILE]...", executable!())
|
||||||
|
}
|
||||||
|
|
||||||
fn tabstops_parse(s: String) -> Vec<usize> {
|
fn tabstops_parse(s: String) -> Vec<usize> {
|
||||||
let words = s.split(',');
|
let words = s.split(',');
|
||||||
|
|
||||||
|
@ -58,14 +71,14 @@ struct Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
fn new(matches: getopts::Matches) -> Options {
|
fn new(matches: &ArgMatches) -> Options {
|
||||||
let tabstops = match matches.opt_str("t") {
|
let tabstops = match matches.value_of(options::TABS) {
|
||||||
|
Some(s) => tabstops_parse(s.to_string()),
|
||||||
None => vec![DEFAULT_TABSTOP],
|
None => vec![DEFAULT_TABSTOP],
|
||||||
Some(s) => tabstops_parse(s),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let iflag = matches.opt_present("i");
|
let iflag = matches.is_present(options::INITIAL);
|
||||||
let uflag = !matches.opt_present("U");
|
let uflag = !matches.is_present(options::NO_UTF8);
|
||||||
|
|
||||||
// avoid allocations when dumping out long sequences of spaces
|
// avoid allocations when dumping out long sequences of spaces
|
||||||
// by precomputing the longest string of spaces we will ever need
|
// by precomputing the longest string of spaces we will ever need
|
||||||
|
@ -80,10 +93,9 @@ impl Options {
|
||||||
.unwrap(); // length of tabstops is guaranteed >= 1
|
.unwrap(); // length of tabstops is guaranteed >= 1
|
||||||
let tspaces = repeat(' ').take(nspaces).collect();
|
let tspaces = repeat(' ').take(nspaces).collect();
|
||||||
|
|
||||||
let files = if matches.free.is_empty() {
|
let files: Vec<String> = match matches.values_of(options::FILES) {
|
||||||
vec!["-".to_owned()]
|
Some(s) => s.map(|v| v.to_string()).collect(),
|
||||||
} else {
|
None => vec!["-".to_owned()],
|
||||||
matches.free
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Options {
|
Options {
|
||||||
|
@ -97,31 +109,40 @@ impl Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let args = args.collect_str();
|
let usage = get_usage();
|
||||||
|
let matches = App::new(executable!())
|
||||||
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
|
.version(VERSION)
|
||||||
.optflag("i", "initial", "do not convert tabs after non blanks")
|
.about(ABOUT)
|
||||||
.optopt(
|
.usage(&usage[..])
|
||||||
"t",
|
.after_help(LONG_HELP)
|
||||||
"tabs",
|
.arg(
|
||||||
"have tabs NUMBER characters apart, not 8",
|
Arg::with_name(options::INITIAL)
|
||||||
"NUMBER",
|
.long(options::INITIAL)
|
||||||
|
.short("i")
|
||||||
|
.help("do not convert tabs after non blanks"),
|
||||||
)
|
)
|
||||||
.optopt(
|
.arg(
|
||||||
"t",
|
Arg::with_name(options::TABS)
|
||||||
"tabs",
|
.long(options::TABS)
|
||||||
"use comma separated list of explicit tab positions",
|
.short("t")
|
||||||
"LIST",
|
.value_name("N, LIST")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("have tabs N characters apart, not 8 or use comma separated list of explicit tab positions"),
|
||||||
)
|
)
|
||||||
.optflag(
|
.arg(
|
||||||
"U",
|
Arg::with_name(options::NO_UTF8)
|
||||||
"no-utf8",
|
.long(options::NO_UTF8)
|
||||||
"interpret input file as 8-bit ASCII rather than UTF-8",
|
.short("U")
|
||||||
|
.help("interpret input file as 8-bit ASCII rather than UTF-8"),
|
||||||
|
).arg(
|
||||||
|
Arg::with_name(options::FILES)
|
||||||
|
.multiple(true)
|
||||||
|
.hidden(true)
|
||||||
|
.takes_value(true)
|
||||||
)
|
)
|
||||||
.parse(args);
|
.get_matches_from(args);
|
||||||
|
|
||||||
expand(Options::new(matches));
|
|
||||||
|
|
||||||
|
expand(Options::new(&matches));
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_expr"
|
name = "uu_expr"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "expr ~ (uutils) display the value of EXPRESSION"
|
description = "expr ~ (uutils) display the value of EXPRESSION"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/expr.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
onig = "~4.3.2"
|
onig = "~4.3.2"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_factor"
|
name = "uu_factor"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "factor ~ (uutils) display the prime factors of each NUMBER"
|
description = "factor ~ (uutils) display the prime factors of each NUMBER"
|
||||||
|
@ -19,7 +19,7 @@ num-traits = "0.2.13" # used in src/numerics.rs, which is included by build.rs
|
||||||
num-traits = "0.2.13" # Needs at least version 0.2.13 for "OverflowingAdd"
|
num-traits = "0.2.13" # Needs at least version 0.2.13 for "OverflowingAdd"
|
||||||
rand = { version="0.7", features=["small_rng"] }
|
rand = { version="0.7", features=["small_rng"] }
|
||||||
smallvec = { version="0.6.14, < 1.0" }
|
smallvec = { version="0.6.14, < 1.0" }
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -225,20 +225,19 @@ pub fn factor(num: u64) -> Factors {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{factor, Factors};
|
use super::{factor, Decomposition, Exponent, Factors};
|
||||||
use quickcheck::quickcheck;
|
use quickcheck::quickcheck;
|
||||||
|
use smallvec::smallvec;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn factor_correctly_recombines_prior_test_failures() {
|
fn factor_2044854919485649() {
|
||||||
let prior_failures = [
|
let f = Factors(RefCell::new(Decomposition(smallvec![
|
||||||
// * integers with duplicate factors (ie, N.pow(M))
|
(503, 1),
|
||||||
4566769_u64, // == 2137.pow(2)
|
(2423, 1),
|
||||||
2044854919485649_u64,
|
(40961, 2)
|
||||||
18446739546814299361_u64,
|
])));
|
||||||
18446738440860217487_u64,
|
assert_eq!(factor(f.product()), f);
|
||||||
18446736729316206481_u64,
|
|
||||||
];
|
|
||||||
assert!(prior_failures.iter().all(|i| factor(*i).product() == *i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -248,15 +247,6 @@ mod tests {
|
||||||
.all(|i| factor(i).product() == i));
|
.all(|i| factor(i).product() == i));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn factor_recombines_small_squares() {
|
|
||||||
// factor(18446736729316206481) == 4294966441 ** 2 ; causes debug_assert fault for repeated decomposition factor in add()
|
|
||||||
// ToDO: explain/combine with factor_18446736729316206481 and factor_18446739546814299361 tests
|
|
||||||
assert!((1..10_000)
|
|
||||||
.map(|i| (2 * i + 1) * (2 * i + 1))
|
|
||||||
.all(|i| factor(i).product() == i));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn factor_recombines_overflowing() {
|
fn factor_recombines_overflowing() {
|
||||||
assert!((0..250)
|
assert!((0..250)
|
||||||
|
@ -282,9 +272,15 @@ mod tests {
|
||||||
i == 0 || factor(i).product() == i
|
i == 0 || factor(i).product() == i
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recombines_factors(f: Factors) -> bool {
|
fn recombines_factors(f: Factors) -> () {
|
||||||
assert_eq!(factor(f.product()), f);
|
assert_eq!(factor(f.product()), f);
|
||||||
true
|
}
|
||||||
|
|
||||||
|
fn exponentiate_factors(f: Factors, e: Exponent) -> () {
|
||||||
|
if e == 0 { return; }
|
||||||
|
if let Some(fe) = f.product().checked_pow(e.into()) {
|
||||||
|
assert_eq!(factor(fe), f ^ e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,3 +315,19 @@ impl quickcheck::Arbitrary for Factors {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl std::ops::BitXor<Exponent> for Factors {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn bitxor(self, rhs: Exponent) -> Factors {
|
||||||
|
debug_assert_ne!(rhs, 0);
|
||||||
|
let mut r = Factors::one();
|
||||||
|
for (p, e) in self.0.borrow().0.iter() {
|
||||||
|
r.add(*p, rhs * e);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert_eq!(r.product(), self.product().pow(rhs.into()));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_false"
|
name = "uu_false"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "false ~ (uutils) do nothing and fail"
|
description = "false ~ (uutils) do nothing and fail"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/false.rs"
|
path = "src/false.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_fmt"
|
name = "uu_fmt"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "fmt ~ (uutils) reformat each paragraph of input"
|
description = "fmt ~ (uutils) reformat each paragraph of input"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/fmt.rs"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
unicode-width = "0.1.5"
|
unicode-width = "0.1.5"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_fold"
|
name = "uu_fold"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "fold ~ (uutils) wrap each line of input"
|
description = "fold ~ (uutils) wrap each line of input"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/fold.rs"
|
path = "src/fold.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_groups"
|
name = "uu_groups"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "groups ~ (uutils) display group memberships for USERNAME"
|
description = "groups ~ (uutils) display group memberships for USERNAME"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/groups.rs"
|
path = "src/groups.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_hashsum"
|
name = "uu_hashsum"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "hashsum ~ (uutils) display or check input digests"
|
description = "hashsum ~ (uutils) display or check input digests"
|
||||||
|
@ -26,7 +26,7 @@ sha1 = "0.6.0"
|
||||||
sha2 = "0.6.0"
|
sha2 = "0.6.0"
|
||||||
sha3 = "0.6.0"
|
sha3 = "0.6.0"
|
||||||
blake2-rfc = "0.2.18"
|
blake2-rfc = "0.2.18"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_head"
|
name = "uu_head"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "head ~ (uutils) display the first lines of input"
|
description = "head ~ (uutils) display the first lines of input"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/head.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -29,6 +29,7 @@ enum FilterMode {
|
||||||
struct Settings {
|
struct Settings {
|
||||||
mode: FilterMode,
|
mode: FilterMode,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
|
zero_terminated: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
|
@ -36,6 +37,7 @@ impl Default for Settings {
|
||||||
Settings {
|
Settings {
|
||||||
mode: FilterMode::Lines(10),
|
mode: FilterMode::Lines(10),
|
||||||
verbose: false,
|
verbose: false,
|
||||||
|
zero_terminated: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +71,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
)
|
)
|
||||||
.optflag("q", "quiet", "never print headers giving file names")
|
.optflag("q", "quiet", "never print headers giving file names")
|
||||||
.optflag("v", "verbose", "always print headers giving file names")
|
.optflag("v", "verbose", "always print headers giving file names")
|
||||||
|
.optflag("z", "zero-terminated", "line delimiter is NUL, not newline")
|
||||||
.optflag("h", "help", "display this help and exit")
|
.optflag("h", "help", "display this help and exit")
|
||||||
.optflag("V", "version", "output version information and exit")
|
.optflag("V", "version", "output version information and exit")
|
||||||
.parse(new_args);
|
.parse(new_args);
|
||||||
|
@ -113,6 +116,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
let quiet = matches.opt_present("q");
|
let quiet = matches.opt_present("q");
|
||||||
let verbose = matches.opt_present("v");
|
let verbose = matches.opt_present("v");
|
||||||
|
settings.zero_terminated = matches.opt_present("z");
|
||||||
let files = matches.free;
|
let files = matches.free;
|
||||||
|
|
||||||
// GNU implementation allows multiple declarations of "-q" and "-v" with the
|
// GNU implementation allows multiple declarations of "-q" and "-v" with the
|
||||||
|
@ -203,8 +207,14 @@ fn head<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FilterMode::Lines(count) => {
|
FilterMode::Lines(count) => {
|
||||||
for line in reader.lines().take(count) {
|
if settings.zero_terminated {
|
||||||
println!("{}", line.unwrap());
|
for line in reader.split(0).take(count) {
|
||||||
|
print!("{}\0", String::from_utf8(line.unwrap()).unwrap())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for line in reader.lines().take(count) {
|
||||||
|
println!("{}", line.unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FilterMode::NLines(count) => {
|
FilterMode::NLines(count) => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_hostid"
|
name = "uu_hostid"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "hostid ~ (uutils) display the numeric identifier of the current host"
|
description = "hostid ~ (uutils) display the numeric identifier of the current host"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/hostid.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_hostname"
|
name = "uu_hostname"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "hostname ~ (uutils) display or set the host name of the current host"
|
description = "hostname ~ (uutils) display or set the host name of the current host"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/hostname.rs"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
hostname = { version = "0.3", features = ["set"] }
|
hostname = { version = "0.3", features = ["set"] }
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["wide"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["wide"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
winapi = { version="0.3", features=["sysinfoapi", "winsock2"] }
|
winapi = { version="0.3", features=["sysinfoapi", "winsock2"] }
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_id"
|
name = "uu_id"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "id ~ (uutils) display user and group information for USER"
|
description = "id ~ (uutils) display user and group information for USER"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/id.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries", "process"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "process"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -291,7 +291,7 @@ fn pretty(possible_pw: Option<Passwd>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
#[cfg(any(target_vendor = "apple", target_os = "freebsd"))]
|
||||||
fn pline(possible_uid: Option<uid_t>) {
|
fn pline(possible_uid: Option<uid_t>) {
|
||||||
let uid = possible_uid.unwrap_or_else(getuid);
|
let uid = possible_uid.unwrap_or_else(getuid);
|
||||||
let pw = Passwd::locate(uid).unwrap();
|
let pw = Passwd::locate(uid).unwrap();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_install"
|
name = "uu_install"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = [
|
authors = [
|
||||||
"Ben Eills <ben@beneills.com>",
|
"Ben Eills <ben@beneills.com>",
|
||||||
"uutils developers",
|
"uutils developers",
|
||||||
|
@ -19,8 +19,9 @@ path = "src/install.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
|
filetime = "0.2"
|
||||||
libc = ">= 0.2"
|
libc = ">= 0.2"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -13,6 +13,7 @@ mod mode;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{App, Arg, ArgMatches};
|
||||||
|
use filetime::{set_file_times, FileTime};
|
||||||
use uucore::entries::{grp2gid, usr2uid};
|
use uucore::entries::{grp2gid, usr2uid};
|
||||||
use uucore::perms::{wrap_chgrp, wrap_chown, Verbosity};
|
use uucore::perms::{wrap_chgrp, wrap_chown, Verbosity};
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ pub struct Behavior {
|
||||||
owner: String,
|
owner: String,
|
||||||
group: String,
|
group: String,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
|
preserve_timestamps: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
|
@ -154,11 +156,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
// TODO implement flag
|
|
||||||
Arg::with_name(OPT_PRESERVE_TIMESTAMPS)
|
Arg::with_name(OPT_PRESERVE_TIMESTAMPS)
|
||||||
.short("p")
|
.short("p")
|
||||||
.long(OPT_PRESERVE_TIMESTAMPS)
|
.long(OPT_PRESERVE_TIMESTAMPS)
|
||||||
.help("(unimplemented) apply access/modification times of SOURCE files to corresponding destination files")
|
.help("apply access/modification times of SOURCE files to corresponding destination files")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
// TODO implement flag
|
// TODO implement flag
|
||||||
|
@ -265,8 +266,6 @@ fn check_unimplemented<'a>(matches: &ArgMatches) -> Result<(), &'a str> {
|
||||||
Err("--compare, -C")
|
Err("--compare, -C")
|
||||||
} else if matches.is_present(OPT_CREATED) {
|
} else if matches.is_present(OPT_CREATED) {
|
||||||
Err("-D")
|
Err("-D")
|
||||||
} else if matches.is_present(OPT_PRESERVE_TIMESTAMPS) {
|
|
||||||
Err("--preserve-timestamps, -p")
|
|
||||||
} else if matches.is_present(OPT_STRIP) {
|
} else if matches.is_present(OPT_STRIP) {
|
||||||
Err("--strip, -s")
|
Err("--strip, -s")
|
||||||
} else if matches.is_present(OPT_STRIP_PROGRAM) {
|
} else if matches.is_present(OPT_STRIP_PROGRAM) {
|
||||||
|
@ -338,6 +337,7 @@ fn behavior(matches: &ArgMatches) -> Result<Behavior, i32> {
|
||||||
owner: matches.value_of(OPT_OWNER).unwrap_or("").to_string(),
|
owner: matches.value_of(OPT_OWNER).unwrap_or("").to_string(),
|
||||||
group: matches.value_of(OPT_GROUP).unwrap_or("").to_string(),
|
group: matches.value_of(OPT_GROUP).unwrap_or("").to_string(),
|
||||||
verbose: matches.is_present(OPT_VERBOSE),
|
verbose: matches.is_present(OPT_VERBOSE),
|
||||||
|
preserve_timestamps: matches.is_present(OPT_PRESERVE_TIMESTAMPS),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,6 +555,21 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.preserve_timestamps {
|
||||||
|
let meta = match fs::metadata(from) {
|
||||||
|
Ok(meta) => meta,
|
||||||
|
Err(f) => crash!(1, "{}", f.to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let modified_time = FileTime::from_last_modification_time(&meta);
|
||||||
|
let accessed_time = FileTime::from_last_access_time(&meta);
|
||||||
|
|
||||||
|
match set_file_times(to.as_path(), accessed_time, modified_time) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => show_info!("{}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if b.verbose {
|
if b.verbose {
|
||||||
show_info!("'{}' -> '{}'", from.display(), to.display());
|
show_info!("'{}' -> '{}'", from.display(), to.display());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_join"
|
name = "uu_join"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "join ~ (uutils) merge lines from inputs with matching join fields"
|
description = "join ~ (uutils) merge lines from inputs with matching join fields"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/join.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_kill"
|
name = "uu_kill"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "kill ~ (uutils) send a signal to a process"
|
description = "kill ~ (uutils) send a signal to a process"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/kill.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["signals"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["signals"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_link"
|
name = "uu_link"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "link ~ (uutils) create a hard (file system) link to FILE"
|
description = "link ~ (uutils) create a hard (file system) link to FILE"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/link.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_ln"
|
name = "uu_ln"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "ln ~ (uutils) create a (file system) link to TARGET"
|
description = "ln ~ (uutils) create a (file system) link to TARGET"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/ln.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -207,7 +207,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let paths: Vec<PathBuf> = matches
|
let paths: Vec<PathBuf> = matches
|
||||||
.values_of(ARG_FILES)
|
.values_of(ARG_FILES)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|path| PathBuf::from(path))
|
.map(PathBuf::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let overwrite_mode = if matches.is_present(OPT_FORCE) {
|
let overwrite_mode = if matches.is_present(OPT_FORCE) {
|
||||||
|
@ -316,9 +316,8 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &PathBuf, settings: &Setting
|
||||||
// We need to clean the target
|
// We need to clean the target
|
||||||
if is_symlink(target_dir) {
|
if is_symlink(target_dir) {
|
||||||
if target_dir.is_file() {
|
if target_dir.is_file() {
|
||||||
match fs::remove_file(target_dir) {
|
if let Err(e) = fs::remove_file(target_dir) {
|
||||||
Err(e) => show_error!("Could not update {}: {}", target_dir.display(), e),
|
show_error!("Could not update {}: {}", target_dir.display(), e)
|
||||||
_ => (),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if target_dir.is_dir() {
|
if target_dir.is_dir() {
|
||||||
|
@ -423,10 +422,8 @@ fn link(src: &PathBuf, dst: &PathBuf, settings: &Settings) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.no_dereference && settings.force {
|
if settings.no_dereference && settings.force && dst.exists() {
|
||||||
if dst.exists() {
|
fs::remove_file(dst)?;
|
||||||
fs::remove_file(dst)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.symbolic {
|
if settings.symbolic {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_logname"
|
name = "uu_logname"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "logname ~ (uutils) display the login name of the current user"
|
description = "logname ~ (uutils) display the login name of the current user"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/logname.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_ls"
|
name = "uu_ls"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "ls ~ (uutils) display directory contents"
|
description = "ls ~ (uutils) display directory contents"
|
||||||
|
@ -22,7 +22,7 @@ term_grid = "0.1.5"
|
||||||
termsize = "0.1.6"
|
termsize = "0.1.6"
|
||||||
time = "0.1.40"
|
time = "0.1.40"
|
||||||
unicode-width = "0.1.5"
|
unicode-width = "0.1.5"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_mkdir"
|
name = "uu_mkdir"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "mkdir ~ (uutils) create DIRECTORY"
|
description = "mkdir ~ (uutils) create DIRECTORY"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/mkdir.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs", "mode"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs", "mode"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_mkfifo"
|
name = "uu_mkfifo"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "mkfifo ~ (uutils) create FIFOs (named pipes)"
|
description = "mkfifo ~ (uutils) create FIFOs (named pipes)"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/mkfifo.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_mknod"
|
name = "uu_mknod"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "mknod ~ (uutils) create special file NAME of TYPE"
|
description = "mknod ~ (uutils) create special file NAME of TYPE"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/mknod.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
libc = "^0.2.42"
|
libc = "^0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["mode"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["mode"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_mktemp"
|
name = "uu_mktemp"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "mktemp ~ (uutils) create and display a temporary file or directory from TEMPLATE"
|
description = "mktemp ~ (uutils) create and display a temporary file or directory from TEMPLATE"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/mktemp.rs"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
rand = "0.5"
|
rand = "0.5"
|
||||||
tempfile = "3.1"
|
tempfile = "3.1"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -25,6 +25,7 @@ mod tempdir;
|
||||||
|
|
||||||
static ABOUT: &str = "create a temporary file or directory.";
|
static ABOUT: &str = "create a temporary file or directory.";
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
static DEFAULT_TEMPLATE: &str = "tmp.XXXXXXXXXX";
|
static DEFAULT_TEMPLATE: &str = "tmp.XXXXXXXXXX";
|
||||||
|
|
||||||
static OPT_DIRECTORY: &str = "directory";
|
static OPT_DIRECTORY: &str = "directory";
|
||||||
|
@ -119,13 +120,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
// See https://github.com/clap-rs/clap/pull/1587
|
// See https://github.com/clap-rs/clap/pull/1587
|
||||||
let tmp = env::temp_dir();
|
let tmp = env::temp_dir();
|
||||||
(tmpdir, tmp)
|
(tmpdir, tmp)
|
||||||
|
} else if !matches.is_present(OPT_TMPDIR) {
|
||||||
|
let tmp = env::temp_dir();
|
||||||
|
(template, tmp)
|
||||||
} else {
|
} else {
|
||||||
if !matches.is_present(OPT_TMPDIR) {
|
(template, PathBuf::from(tmpdir))
|
||||||
let tmp = env::temp_dir();
|
|
||||||
(template, tmp)
|
|
||||||
} else {
|
|
||||||
(template, PathBuf::from(tmpdir))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let make_dir = matches.is_present(OPT_DIRECTORY);
|
let make_dir = matches.is_present(OPT_DIRECTORY);
|
||||||
|
@ -157,14 +156,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
crash!(1, "suffix cannot contain any path separators");
|
crash!(1, "suffix cannot contain any path separators");
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches.is_present(OPT_TMPDIR) {
|
if matches.is_present(OPT_TMPDIR) && PathBuf::from(prefix).is_absolute() {
|
||||||
if PathBuf::from(prefix).is_absolute() {
|
show_info!(
|
||||||
show_info!(
|
"invalid template, ‘{}’; with --tmpdir, it may not be absolute",
|
||||||
"invalid template, ‘{}’; with --tmpdir, it may not be absolute",
|
template
|
||||||
template
|
);
|
||||||
);
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if matches.is_present(OPT_T) {
|
if matches.is_present(OPT_T) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_more"
|
name = "uu_more"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "more ~ (uutils) input perusal filter"
|
description = "more ~ (uutils) input perusal filter"
|
||||||
|
@ -16,15 +16,15 @@ path = "src/more.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version = ">=0.0.7", package = "uucore", path = "../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version = ">=0.0.5", package = "uucore_procs", path = "../../uucore_procs" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "redox")'.dependencies]
|
[target.'cfg(target_os = "redox")'.dependencies]
|
||||||
redox_termios = "0.1"
|
redox_termios = "0.1"
|
||||||
redox_syscall = "0.1"
|
redox_syscall = "0.1"
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_os = "fuchsia")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os = "fuchsia")))'.dependencies]
|
||||||
nix = "0.8.1"
|
nix = "<=0.13"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "more"
|
name = "more"
|
||||||
|
|
|
@ -17,7 +17,7 @@ use std::io::{stdout, Read, Write};
|
||||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||||
extern crate nix;
|
extern crate nix;
|
||||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||||
use nix::sys::termios;
|
use nix::sys::termios::{self, LocalFlags, SetArg};
|
||||||
|
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
extern crate redox_termios;
|
extern crate redox_termios;
|
||||||
|
@ -92,10 +92,10 @@ fn help(usage: &str) {
|
||||||
fn setup_term() -> termios::Termios {
|
fn setup_term() -> termios::Termios {
|
||||||
let mut term = termios::tcgetattr(0).unwrap();
|
let mut term = termios::tcgetattr(0).unwrap();
|
||||||
// Unset canonical mode, so we get characters immediately
|
// Unset canonical mode, so we get characters immediately
|
||||||
term.c_lflag.remove(termios::ICANON);
|
term.local_flags.remove(LocalFlags::ICANON);
|
||||||
// Disable local echo
|
// Disable local echo
|
||||||
term.c_lflag.remove(termios::ECHO);
|
term.local_flags.remove(LocalFlags::ECHO);
|
||||||
termios::tcsetattr(0, termios::TCSADRAIN, &term).unwrap();
|
termios::tcsetattr(0, SetArg::TCSADRAIN, &term).unwrap();
|
||||||
term
|
term
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +110,8 @@ fn setup_term() -> redox_termios::Termios {
|
||||||
let mut term = redox_termios::Termios::default();
|
let mut term = redox_termios::Termios::default();
|
||||||
let fd = syscall::dup(0, b"termios").unwrap();
|
let fd = syscall::dup(0, b"termios").unwrap();
|
||||||
syscall::read(fd, &mut term).unwrap();
|
syscall::read(fd, &mut term).unwrap();
|
||||||
term.c_lflag &= !redox_termios::ICANON;
|
term.local_flags &= !redox_termios::ICANON;
|
||||||
term.c_lflag &= !redox_termios::ECHO;
|
term.local_flags &= !redox_termios::ECHO;
|
||||||
syscall::write(fd, &term).unwrap();
|
syscall::write(fd, &term).unwrap();
|
||||||
let _ = syscall::close(fd);
|
let _ = syscall::close(fd);
|
||||||
term
|
term
|
||||||
|
@ -119,9 +119,9 @@ fn setup_term() -> redox_termios::Termios {
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
#[cfg(all(unix, not(target_os = "fuchsia")))]
|
||||||
fn reset_term(term: &mut termios::Termios) {
|
fn reset_term(term: &mut termios::Termios) {
|
||||||
term.c_lflag.insert(termios::ICANON);
|
term.local_flags.insert(LocalFlags::ICANON);
|
||||||
term.c_lflag.insert(termios::ECHO);
|
term.local_flags.insert(LocalFlags::ECHO);
|
||||||
termios::tcsetattr(0, termios::TCSADRAIN, &term).unwrap();
|
termios::tcsetattr(0, SetArg::TCSADRAIN, &term).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(windows, target_os = "fuchsia"))]
|
#[cfg(any(windows, target_os = "fuchsia"))]
|
||||||
|
@ -132,8 +132,8 @@ fn reset_term(_: &mut usize) {}
|
||||||
fn reset_term(term: &mut redox_termios::Termios) {
|
fn reset_term(term: &mut redox_termios::Termios) {
|
||||||
let fd = syscall::dup(0, b"termios").unwrap();
|
let fd = syscall::dup(0, b"termios").unwrap();
|
||||||
syscall::read(fd, term).unwrap();
|
syscall::read(fd, term).unwrap();
|
||||||
term.c_lflag |= redox_termios::ICANON;
|
term.local_flags |= redox_termios::ICANON;
|
||||||
term.c_lflag |= redox_termios::ECHO;
|
term.local_flags |= redox_termios::ECHO;
|
||||||
syscall::write(fd, &term).unwrap();
|
syscall::write(fd, &term).unwrap();
|
||||||
let _ = syscall::close(fd);
|
let _ = syscall::close(fd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_mv"
|
name = "uu_mv"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "mv ~ (uutils) move (rename) SOURCE to DESTINATION"
|
description = "mv ~ (uutils) move (rename) SOURCE to DESTINATION"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/mv.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
fs_extra = "1.1.0"
|
fs_extra = "1.1.0"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_nice"
|
name = "uu_nice"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "nice ~ (uutils) run PROGRAM with modified scheduling priority"
|
description = "nice ~ (uutils) run PROGRAM with modified scheduling priority"
|
||||||
|
@ -15,9 +15,10 @@ edition = "2018"
|
||||||
path = "src/nice.rs"
|
path = "src/nice.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
nix = { version="<=0.13" }
|
||||||
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::ffi::CString;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
const NAME: &str = "nice";
|
use clap::{App, AppSettings, Arg};
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
// XXX: PRIO_PROCESS is 0 on at least FreeBSD and Linux. Don't know about Mac OS X.
|
// XXX: PRIO_PROCESS is 0 on at least FreeBSD and Linux. Don't know about Mac OS X.
|
||||||
|
@ -26,64 +26,57 @@ extern "C" {
|
||||||
fn setpriority(which: c_int, who: c_int, prio: c_int) -> c_int;
|
fn setpriority(which: c_int, who: c_int, prio: c_int) -> c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
pub mod options {
|
||||||
let args = args.collect_str();
|
pub static ADJUSTMENT: &str = "adjustment";
|
||||||
|
pub static COMMAND: &str = "COMMAND";
|
||||||
|
}
|
||||||
|
|
||||||
let mut opts = getopts::Options::new();
|
fn get_usage() -> String {
|
||||||
|
format!(
|
||||||
opts.optopt(
|
"
|
||||||
"n",
|
|
||||||
"adjustment",
|
|
||||||
"add N to the niceness (default is 10)",
|
|
||||||
"N",
|
|
||||||
);
|
|
||||||
opts.optflag("h", "help", "display this help and exit");
|
|
||||||
opts.optflag("V", "version", "output version information and exit");
|
|
||||||
|
|
||||||
let matches = match opts.parse(&args[1..]) {
|
|
||||||
Ok(m) => m,
|
|
||||||
Err(err) => {
|
|
||||||
show_error!("{}", err);
|
|
||||||
return 125;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if matches.opt_present("version") {
|
|
||||||
println!("{} {}", NAME, VERSION);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches.opt_present("help") {
|
|
||||||
let msg = format!(
|
|
||||||
"{0} {1}
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
{0} [OPTIONS] [COMMAND [ARGS]]
|
{0} [OPTIONS] [COMMAND [ARGS]]
|
||||||
|
|
||||||
Run COMMAND with an adjusted niceness, which affects process scheduling.
|
Run COMMAND with an adjusted niceness, which affects process scheduling.
|
||||||
With no COMMAND, print the current niceness. Niceness values range from at
|
With no COMMAND, print the current niceness. Niceness values range from at
|
||||||
least -20 (most favorable to the process) to 19 (least favorable to the
|
least -20 (most favorable to the process) to 19 (least favorable to the
|
||||||
process).",
|
process).",
|
||||||
NAME, VERSION
|
executable!()
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
|
||||||
print!("{}", opts.usage(&msg));
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
return 0;
|
let usage = get_usage();
|
||||||
}
|
|
||||||
|
|
||||||
let mut niceness = unsafe { getpriority(PRIO_PROCESS, 0) };
|
let matches = App::new(executable!())
|
||||||
|
.setting(AppSettings::TrailingVarArg)
|
||||||
|
.version(VERSION)
|
||||||
|
.usage(&usage[..])
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::ADJUSTMENT)
|
||||||
|
.short("n")
|
||||||
|
.long(options::ADJUSTMENT)
|
||||||
|
.help("add N to the niceness (default is 10)")
|
||||||
|
.takes_value(true)
|
||||||
|
.allow_hyphen_values(true),
|
||||||
|
)
|
||||||
|
.arg(Arg::with_name(options::COMMAND).multiple(true))
|
||||||
|
.get_matches_from(args);
|
||||||
|
|
||||||
|
let mut niceness = unsafe {
|
||||||
|
nix::errno::Errno::clear();
|
||||||
|
getpriority(PRIO_PROCESS, 0)
|
||||||
|
};
|
||||||
if Error::last_os_error().raw_os_error().unwrap() != 0 {
|
if Error::last_os_error().raw_os_error().unwrap() != 0 {
|
||||||
show_error!("{}", Error::last_os_error());
|
show_error!("getpriority: {}", Error::last_os_error());
|
||||||
return 125;
|
return 125;
|
||||||
}
|
}
|
||||||
|
|
||||||
let adjustment = match matches.opt_str("adjustment") {
|
let adjustment = match matches.value_of(options::ADJUSTMENT) {
|
||||||
Some(nstr) => {
|
Some(nstr) => {
|
||||||
if matches.free.is_empty() {
|
if !matches.is_present(options::COMMAND) {
|
||||||
show_error!(
|
show_error!(
|
||||||
"A command must be given with an adjustment.
|
"A command must be given with an adjustment.\nTry \"{} --help\" for more information.",
|
||||||
Try \"{} --help\" for more information.",
|
executable!()
|
||||||
args[0]
|
|
||||||
);
|
);
|
||||||
return 125;
|
return 125;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +89,7 @@ process).",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if matches.free.is_empty() {
|
if !matches.is_present(options::COMMAND) {
|
||||||
println!("{}", niceness);
|
println!("{}", niceness);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -105,25 +98,23 @@ process).",
|
||||||
};
|
};
|
||||||
|
|
||||||
niceness += adjustment;
|
niceness += adjustment;
|
||||||
unsafe {
|
if unsafe { setpriority(PRIO_PROCESS, 0, niceness) } == -1 {
|
||||||
setpriority(PRIO_PROCESS, 0, niceness);
|
show_warning!("setpriority: {}", Error::last_os_error());
|
||||||
}
|
|
||||||
if Error::last_os_error().raw_os_error().unwrap() != 0 {
|
|
||||||
show_warning!("{}", Error::last_os_error());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let cstrs: Vec<CString> = matches
|
let cstrs: Vec<CString> = matches
|
||||||
.free
|
.values_of(options::COMMAND)
|
||||||
.iter()
|
.unwrap()
|
||||||
.map(|x| CString::new(x.as_bytes()).unwrap())
|
.map(|x| CString::new(x.as_bytes()).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect();
|
let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect();
|
||||||
args.push(ptr::null::<c_char>());
|
args.push(ptr::null::<c_char>());
|
||||||
unsafe {
|
unsafe {
|
||||||
execvp(args[0], args.as_mut_ptr());
|
execvp(args[0], args.as_mut_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
show_error!("{}", Error::last_os_error());
|
show_error!("execvp: {}", Error::last_os_error());
|
||||||
if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT {
|
if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT {
|
||||||
127
|
127
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_nl"
|
name = "uu_nl"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "nl ~ (uutils) display input with added line numbers"
|
description = "nl ~ (uutils) display input with added line numbers"
|
||||||
|
@ -21,7 +21,7 @@ libc = "0.2.42"
|
||||||
memchr = "2.2.0"
|
memchr = "2.2.0"
|
||||||
regex = "1.0.1"
|
regex = "1.0.1"
|
||||||
regex-syntax = "0.6.7"
|
regex-syntax = "0.6.7"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -11,7 +11,9 @@ fn parse_style(chars: &[char]) -> Result<crate::NumberingStyle, String> {
|
||||||
} else if chars.len() > 1 && chars[0] == 'p' {
|
} else if chars.len() > 1 && chars[0] == 'p' {
|
||||||
let s: String = chars[1..].iter().cloned().collect();
|
let s: String = chars[1..].iter().cloned().collect();
|
||||||
match regex::Regex::new(&s) {
|
match regex::Regex::new(&s) {
|
||||||
Ok(re) => Ok(crate::NumberingStyle::NumberForRegularExpression(re)),
|
Ok(re) => Ok(crate::NumberingStyle::NumberForRegularExpression(Box::new(
|
||||||
|
re,
|
||||||
|
))),
|
||||||
Err(_) => Err(String::from("Illegal regular expression")),
|
Err(_) => Err(String::from("Illegal regular expression")),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -55,7 +55,7 @@ enum NumberingStyle {
|
||||||
NumberForAll,
|
NumberForAll,
|
||||||
NumberForNonEmpty,
|
NumberForNonEmpty,
|
||||||
NumberForNone,
|
NumberForNone,
|
||||||
NumberForRegularExpression(regex::Regex),
|
NumberForRegularExpression(Box<regex::Regex>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberFormat specifies how line numbers are output within their allocated
|
// NumberFormat specifies how line numbers are output within their allocated
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_nohup"
|
name = "uu_nohup"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "nohup ~ (uutils) run COMMAND, ignoring hangup signals"
|
description = "nohup ~ (uutils) run COMMAND, ignoring hangup signals"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/nohup.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -23,7 +23,7 @@ use uucore::fs::{is_stderr_interactive, is_stdin_interactive, is_stdout_interact
|
||||||
static NAME: &str = "nohup";
|
static NAME: &str = "nohup";
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_vendor = "apple")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn _vprocmgr_detach_from_console(flags: u32) -> *const libc::c_int;
|
fn _vprocmgr_detach_from_console(flags: u32) -> *const libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_nproc"
|
name = "uu_nproc"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "nproc ~ (uutils) display the number of processing units available"
|
description = "nproc ~ (uutils) display the number of processing units available"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/nproc.rs"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
num_cpus = "1.10"
|
num_cpus = "1.10"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::env;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub const _SC_NPROCESSORS_CONF: libc::c_int = 83;
|
pub const _SC_NPROCESSORS_CONF: libc::c_int = 83;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_vendor = "apple")]
|
||||||
pub const _SC_NPROCESSORS_CONF: libc::c_int = libc::_SC_NPROCESSORS_CONF;
|
pub const _SC_NPROCESSORS_CONF: libc::c_int = libc::_SC_NPROCESSORS_CONF;
|
||||||
#[cfg(target_os = "freebsd")]
|
#[cfg(target_os = "freebsd")]
|
||||||
pub const _SC_NPROCESSORS_CONF: libc::c_int = 57;
|
pub const _SC_NPROCESSORS_CONF: libc::c_int = 57;
|
||||||
|
@ -89,7 +89,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "macos",
|
target_vendor = "apple",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "netbsd"
|
target_os = "netbsd"
|
||||||
))]
|
))]
|
||||||
|
@ -109,7 +109,7 @@ fn num_cpus_all() -> usize {
|
||||||
// Other platforms (e.g., windows), num_cpus::get() directly.
|
// Other platforms (e.g., windows), num_cpus::get() directly.
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "macos",
|
target_vendor = "apple",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "netbsd"
|
target_os = "netbsd"
|
||||||
)))]
|
)))]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_numfmt"
|
name = "uu_numfmt"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "numfmt ~ (uutils) reformat NUMBER"
|
description = "numfmt ~ (uutils) reformat NUMBER"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/numfmt.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
296
src/uu/numfmt/src/format.rs
Normal file
296
src/uu/numfmt/src/format.rs
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
use crate::options::NumfmtOptions;
|
||||||
|
use crate::units::{
|
||||||
|
DisplayableSuffix, RawSuffix, Result, Suffix, Transform, Unit, IEC_BASES, SI_BASES,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Iterate over a line's fields, where each field is a contiguous sequence of
|
||||||
|
/// non-whitespace, optionally prefixed with one or more characters of leading
|
||||||
|
/// whitespace. Fields are returned as tuples of `(prefix, field)`.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut fields = uu_numfmt::format::WhitespaceSplitter { s: Some(" 1234 5") };
|
||||||
|
///
|
||||||
|
/// assert_eq!(Some((" ", "1234")), fields.next());
|
||||||
|
/// assert_eq!(Some((" ", "5")), fields.next());
|
||||||
|
/// assert_eq!(None, fields.next());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Delimiters are included in the results; `prefix` will be empty only for
|
||||||
|
/// the first field of the line (including the case where the input line is
|
||||||
|
/// empty):
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut fields = uu_numfmt::format::WhitespaceSplitter { s: Some("first second") };
|
||||||
|
///
|
||||||
|
/// assert_eq!(Some(("", "first")), fields.next());
|
||||||
|
/// assert_eq!(Some((" ", "second")), fields.next());
|
||||||
|
///
|
||||||
|
/// let mut fields = uu_numfmt::format::WhitespaceSplitter { s: Some("") };
|
||||||
|
///
|
||||||
|
/// assert_eq!(Some(("", "")), fields.next());
|
||||||
|
/// ```
|
||||||
|
pub struct WhitespaceSplitter<'a> {
|
||||||
|
pub s: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for WhitespaceSplitter<'a> {
|
||||||
|
type Item = (&'a str, &'a str);
|
||||||
|
|
||||||
|
/// Yield the next field in the input string as a tuple `(prefix, field)`.
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let haystack = self.s?;
|
||||||
|
|
||||||
|
let (prefix, field) = haystack.split_at(
|
||||||
|
haystack
|
||||||
|
.find(|c: char| !c.is_whitespace())
|
||||||
|
.unwrap_or_else(|| haystack.len()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let (field, rest) = field.split_at(
|
||||||
|
field
|
||||||
|
.find(|c: char| c.is_whitespace())
|
||||||
|
.unwrap_or_else(|| field.len()),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.s = if !rest.is_empty() { Some(rest) } else { None };
|
||||||
|
|
||||||
|
Some((prefix, field))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Err("invalid number: ‘’".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let with_i = s.ends_with('i');
|
||||||
|
let mut iter = s.chars();
|
||||||
|
if with_i {
|
||||||
|
iter.next_back();
|
||||||
|
}
|
||||||
|
let suffix: Option<Suffix> = match iter.next_back() {
|
||||||
|
Some('K') => Ok(Some((RawSuffix::K, with_i))),
|
||||||
|
Some('M') => Ok(Some((RawSuffix::M, with_i))),
|
||||||
|
Some('G') => Ok(Some((RawSuffix::G, with_i))),
|
||||||
|
Some('T') => Ok(Some((RawSuffix::T, with_i))),
|
||||||
|
Some('P') => Ok(Some((RawSuffix::P, with_i))),
|
||||||
|
Some('E') => Ok(Some((RawSuffix::E, with_i))),
|
||||||
|
Some('Z') => Ok(Some((RawSuffix::Z, with_i))),
|
||||||
|
Some('Y') => Ok(Some((RawSuffix::Y, with_i))),
|
||||||
|
Some('0'..='9') => Ok(None),
|
||||||
|
_ => Err(format!("invalid suffix in input: ‘{}’", s)),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let suffix_len = match suffix {
|
||||||
|
None => 0,
|
||||||
|
Some((_, false)) => 1,
|
||||||
|
Some((_, true)) => 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
let number = s[..s.len() - suffix_len]
|
||||||
|
.parse::<f64>()
|
||||||
|
.map_err(|_| format!("invalid number: ‘{}’", s))?;
|
||||||
|
|
||||||
|
Ok((number, suffix))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_suffix(i: f64, s: Option<Suffix>, u: &Unit) -> Result<f64> {
|
||||||
|
match (s, u) {
|
||||||
|
(None, _) => Ok(i),
|
||||||
|
(Some((raw_suffix, false)), &Unit::Auto) | (Some((raw_suffix, false)), &Unit::Si) => {
|
||||||
|
match raw_suffix {
|
||||||
|
RawSuffix::K => Ok(i * 1e3),
|
||||||
|
RawSuffix::M => Ok(i * 1e6),
|
||||||
|
RawSuffix::G => Ok(i * 1e9),
|
||||||
|
RawSuffix::T => Ok(i * 1e12),
|
||||||
|
RawSuffix::P => Ok(i * 1e15),
|
||||||
|
RawSuffix::E => Ok(i * 1e18),
|
||||||
|
RawSuffix::Z => Ok(i * 1e21),
|
||||||
|
RawSuffix::Y => Ok(i * 1e24),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some((raw_suffix, false)), &Unit::Iec(false))
|
||||||
|
| (Some((raw_suffix, true)), &Unit::Auto)
|
||||||
|
| (Some((raw_suffix, true)), &Unit::Iec(true)) => match raw_suffix {
|
||||||
|
RawSuffix::K => Ok(i * IEC_BASES[1]),
|
||||||
|
RawSuffix::M => Ok(i * IEC_BASES[2]),
|
||||||
|
RawSuffix::G => Ok(i * IEC_BASES[3]),
|
||||||
|
RawSuffix::T => Ok(i * IEC_BASES[4]),
|
||||||
|
RawSuffix::P => Ok(i * IEC_BASES[5]),
|
||||||
|
RawSuffix::E => Ok(i * IEC_BASES[6]),
|
||||||
|
RawSuffix::Z => Ok(i * IEC_BASES[7]),
|
||||||
|
RawSuffix::Y => Ok(i * IEC_BASES[8]),
|
||||||
|
},
|
||||||
|
(_, _) => Err("This suffix is unsupported for specified unit".to_owned()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_from(s: &str, opts: &Transform) -> Result<f64> {
|
||||||
|
let (i, suffix) = parse_suffix(s)?;
|
||||||
|
|
||||||
|
remove_suffix(i, suffix, &opts.unit).map(|n| if n < 0.0 { -n.abs().ceil() } else { n.ceil() })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Divide numerator by denominator, with ceiling.
|
||||||
|
///
|
||||||
|
/// If the result of the division is less than 10.0, truncate the result
|
||||||
|
/// to the next highest tenth.
|
||||||
|
///
|
||||||
|
/// Otherwise, truncate the result to the next highest whole number.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use uu_numfmt::format::div_ceil;
|
||||||
|
///
|
||||||
|
/// assert_eq!(div_ceil(1.01, 1.0), 1.1);
|
||||||
|
/// assert_eq!(div_ceil(999.1, 1000.), 1.0);
|
||||||
|
/// assert_eq!(div_ceil(1001., 10.), 101.);
|
||||||
|
/// assert_eq!(div_ceil(9991., 10.), 1000.);
|
||||||
|
/// assert_eq!(div_ceil(-12.34, 1.0), -13.0);
|
||||||
|
/// assert_eq!(div_ceil(1000.0, -3.14), -319.0);
|
||||||
|
/// assert_eq!(div_ceil(-271828.0, -271.0), 1004.0);
|
||||||
|
/// ```
|
||||||
|
pub fn div_ceil(n: f64, d: f64) -> f64 {
|
||||||
|
let v = n / (d / 10.0);
|
||||||
|
let (v, sign) = if v < 0.0 { (v.abs(), -1.0) } else { (v, 1.0) };
|
||||||
|
|
||||||
|
if v < 100.0 {
|
||||||
|
v.ceil() / 10.0 * sign
|
||||||
|
} else {
|
||||||
|
(v / 10.0).ceil() * sign
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_suffix(n: f64, u: &Unit) -> Result<(f64, Option<Suffix>)> {
|
||||||
|
use crate::units::RawSuffix::*;
|
||||||
|
|
||||||
|
let abs_n = n.abs();
|
||||||
|
let suffixes = [K, M, G, T, P, E, Z, Y];
|
||||||
|
|
||||||
|
let (bases, with_i) = match *u {
|
||||||
|
Unit::Si => (&SI_BASES, false),
|
||||||
|
Unit::Iec(with_i) => (&IEC_BASES, with_i),
|
||||||
|
Unit::Auto => return Err("Unit 'auto' isn't supported with --to options".to_owned()),
|
||||||
|
Unit::None => return Ok((n, None)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let i = match abs_n {
|
||||||
|
_ if abs_n <= bases[1] - 1.0 => return Ok((n, None)),
|
||||||
|
_ if abs_n < bases[2] => 1,
|
||||||
|
_ if abs_n < bases[3] => 2,
|
||||||
|
_ if abs_n < bases[4] => 3,
|
||||||
|
_ if abs_n < bases[5] => 4,
|
||||||
|
_ if abs_n < bases[6] => 5,
|
||||||
|
_ if abs_n < bases[7] => 6,
|
||||||
|
_ if abs_n < bases[8] => 7,
|
||||||
|
_ if abs_n < bases[9] => 8,
|
||||||
|
_ => return Err("Number is too big and unsupported".to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let v = div_ceil(n, bases[i]);
|
||||||
|
|
||||||
|
// check if rounding pushed us into the next base
|
||||||
|
if v.abs() >= bases[1] {
|
||||||
|
Ok((v / bases[1], Some((suffixes[i], with_i))))
|
||||||
|
} else {
|
||||||
|
Ok((v, Some((suffixes[i - 1], with_i))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_to(s: f64, opts: &Transform) -> Result<String> {
|
||||||
|
let (i2, s) = consider_suffix(s, &opts.unit)?;
|
||||||
|
Ok(match s {
|
||||||
|
None => format!("{}", i2),
|
||||||
|
Some(s) if i2.abs() < 10.0 => format!("{:.1}{}", i2, DisplayableSuffix(s)),
|
||||||
|
Some(s) => format!("{:.0}{}", i2, DisplayableSuffix(s)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_string(
|
||||||
|
source: &str,
|
||||||
|
options: &NumfmtOptions,
|
||||||
|
implicit_padding: Option<isize>,
|
||||||
|
) -> Result<String> {
|
||||||
|
let number = transform_to(
|
||||||
|
transform_from(source, &options.transform.from)?,
|
||||||
|
&options.transform.to,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(match implicit_padding.unwrap_or(options.padding) {
|
||||||
|
p if p == 0 => number,
|
||||||
|
p if p > 0 => format!("{:>padding$}", number, padding = p as usize),
|
||||||
|
p => format!("{:<padding$}", number, padding = p.abs() as usize),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_and_print_delimited(s: &str, options: &NumfmtOptions) -> Result<()> {
|
||||||
|
let delimiter = options.delimiter.as_ref().unwrap();
|
||||||
|
|
||||||
|
for (n, field) in (1..).zip(s.split(delimiter)) {
|
||||||
|
let field_selected = uucore::ranges::contain(&options.fields, n);
|
||||||
|
|
||||||
|
// print delimiter before second and subsequent fields
|
||||||
|
if n > 1 {
|
||||||
|
print!("{}", delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if field_selected {
|
||||||
|
print!("{}", format_string(&field.trim_start(), options, None)?);
|
||||||
|
} else {
|
||||||
|
// print unselected field without conversion
|
||||||
|
print!("{}", field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_and_print_whitespace(s: &str, options: &NumfmtOptions) -> Result<()> {
|
||||||
|
for (n, (prefix, field)) in (1..).zip(WhitespaceSplitter { s: Some(s) }) {
|
||||||
|
let field_selected = uucore::ranges::contain(&options.fields, n);
|
||||||
|
|
||||||
|
if field_selected {
|
||||||
|
let empty_prefix = prefix.is_empty();
|
||||||
|
|
||||||
|
// print delimiter before second and subsequent fields
|
||||||
|
let prefix = if n > 1 {
|
||||||
|
print!(" ");
|
||||||
|
&prefix[1..]
|
||||||
|
} else {
|
||||||
|
&prefix
|
||||||
|
};
|
||||||
|
|
||||||
|
let implicit_padding = if !empty_prefix && options.padding == 0 {
|
||||||
|
Some((prefix.len() + field.len()) as isize)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
print!("{}", format_string(&field, options, implicit_padding)?);
|
||||||
|
} else {
|
||||||
|
// print unselected field without conversion
|
||||||
|
print!("{}{}", prefix, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format a line of text according to the selected options.
|
||||||
|
///
|
||||||
|
/// Given a line of text `s`, split the line into fields, transform and format
|
||||||
|
/// any selected numeric fields, and print the result to stdout. Fields not
|
||||||
|
/// selected for conversion are passed through unmodified.
|
||||||
|
pub fn format_and_print(s: &str, options: &NumfmtOptions) -> Result<()> {
|
||||||
|
match &options.delimiter {
|
||||||
|
Some(_) => format_and_print_delimited(s, options),
|
||||||
|
None => format_and_print_whitespace(s, options),
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,19 @@
|
||||||
// * For the full copyright and license information, please view the LICENSE
|
// * For the full copyright and license information, please view the LICENSE
|
||||||
// * file that was distributed with this source code.
|
// * file that was distributed with this source code.
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::io::BufRead;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use clap::{App, Arg, ArgMatches};
|
use crate::format::format_and_print;
|
||||||
|
use crate::options::*;
|
||||||
|
use crate::units::{Result, Transform, Unit};
|
||||||
|
use clap::{App, AppSettings, Arg, ArgMatches};
|
||||||
|
use std::io::{BufRead, Write};
|
||||||
|
use uucore::ranges::Range;
|
||||||
|
|
||||||
|
pub mod format;
|
||||||
|
mod options;
|
||||||
|
mod units;
|
||||||
|
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
static ABOUT: &str = "Convert numbers from/to human-readable strings";
|
static ABOUT: &str = "Convert numbers from/to human-readable strings";
|
||||||
|
@ -33,113 +39,43 @@ static LONG_HELP: &str = "UNIT options:
|
||||||
iec-i accept optional two-letter suffix:
|
iec-i accept optional two-letter suffix:
|
||||||
|
|
||||||
1Ki = 1024, 1Mi = 1048576, ...
|
1Ki = 1024, 1Mi = 1048576, ...
|
||||||
";
|
|
||||||
|
|
||||||
mod options {
|
FIELDS supports cut(1) style field ranges:
|
||||||
pub const FROM: &str = "from";
|
N N'th field, counted from 1
|
||||||
pub const FROM_DEFAULT: &str = "none";
|
N- from N'th field, to end of line
|
||||||
pub const HEADER: &str = "header";
|
N-M from N'th to M'th field (inclusive)
|
||||||
pub const HEADER_DEFAULT: &str = "1";
|
-M from first to M'th field (inclusive)
|
||||||
pub const NUMBER: &str = "NUMBER";
|
- all fields
|
||||||
pub const PADDING: &str = "padding";
|
Multiple fields/ranges can be separated with commas
|
||||||
pub const TO: &str = "to";
|
";
|
||||||
pub const TO_DEFAULT: &str = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_usage() -> String {
|
fn get_usage() -> String {
|
||||||
format!("{0} [OPTION]... [NUMBER]...", executable!())
|
format!("{0} [OPTION]... [NUMBER]...", executable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
const IEC_BASES: [f64; 10] = [
|
fn handle_args<'a>(args: impl Iterator<Item = &'a str>, options: NumfmtOptions) -> Result<()> {
|
||||||
//premature optimization
|
for l in args {
|
||||||
1.,
|
format_and_print(l, &options)?;
|
||||||
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<T> = std::result::Result<T, String>;
|
|
||||||
|
|
||||||
type WithI = bool;
|
|
||||||
|
|
||||||
enum Unit {
|
|
||||||
Auto,
|
|
||||||
Si,
|
|
||||||
Iec(WithI),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum RawSuffix {
|
|
||||||
K,
|
|
||||||
M,
|
|
||||||
G,
|
|
||||||
T,
|
|
||||||
P,
|
|
||||||
E,
|
|
||||||
Z,
|
|
||||||
Y,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Suffix = (RawSuffix, WithI);
|
|
||||||
|
|
||||||
struct DisplayableSuffix(Suffix);
|
|
||||||
|
|
||||||
impl fmt::Display for DisplayableSuffix {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let DisplayableSuffix((ref raw_suffix, ref with_i)) = *self;
|
|
||||||
match raw_suffix {
|
|
||||||
RawSuffix::K => write!(f, "K"),
|
|
||||||
RawSuffix::M => write!(f, "M"),
|
|
||||||
RawSuffix::G => write!(f, "G"),
|
|
||||||
RawSuffix::T => write!(f, "T"),
|
|
||||||
RawSuffix::P => write!(f, "P"),
|
|
||||||
RawSuffix::E => write!(f, "E"),
|
|
||||||
RawSuffix::Z => write!(f, "Z"),
|
|
||||||
RawSuffix::Y => write!(f, "Y"),
|
|
||||||
}
|
|
||||||
.and_then(|()| match with_i {
|
|
||||||
true => write!(f, "i"),
|
|
||||||
false => Ok(()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
|
fn handle_stdin(options: NumfmtOptions) -> Result<()> {
|
||||||
let with_i = s.ends_with('i');
|
let stdin = std::io::stdin();
|
||||||
let mut iter = s.chars();
|
let locked_stdin = stdin.lock();
|
||||||
if with_i {
|
|
||||||
iter.next_back();
|
let mut lines = locked_stdin.lines();
|
||||||
|
for l in lines.by_ref().take(options.header) {
|
||||||
|
l.map(|s| println!("{}", s)).map_err(|e| e.to_string())?;
|
||||||
}
|
}
|
||||||
let suffix: Option<Suffix> = match iter.next_back() {
|
|
||||||
Some('K') => Ok(Some((RawSuffix::K, with_i))),
|
|
||||||
Some('M') => Ok(Some((RawSuffix::M, with_i))),
|
|
||||||
Some('G') => Ok(Some((RawSuffix::G, with_i))),
|
|
||||||
Some('T') => Ok(Some((RawSuffix::T, with_i))),
|
|
||||||
Some('P') => Ok(Some((RawSuffix::P, with_i))),
|
|
||||||
Some('E') => Ok(Some((RawSuffix::E, with_i))),
|
|
||||||
Some('Z') => Ok(Some((RawSuffix::Z, with_i))),
|
|
||||||
Some('Y') => Ok(Some((RawSuffix::Y, with_i))),
|
|
||||||
Some('0'..='9') => Ok(None),
|
|
||||||
_ => Err(format!("invalid suffix in input: ‘{}’", s)),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let suffix_len = match suffix {
|
for l in lines {
|
||||||
None => 0,
|
l.map_err(|e| e.to_string())
|
||||||
Some((_, false)) => 1,
|
.and_then(|l| format_and_print(&l, &options))?;
|
||||||
Some((_, true)) => 2,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let number = s[..s.len() - suffix_len]
|
Ok(())
|
||||||
.parse::<f64>()
|
|
||||||
.map_err(|_| format!("invalid number: ‘{}’", s))?;
|
|
||||||
|
|
||||||
Ok((number, suffix))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_unit(s: &str) -> Result<Unit> {
|
fn parse_unit(s: &str) -> Result<Unit> {
|
||||||
|
@ -153,128 +89,6 @@ fn parse_unit(s: &str) -> Result<Unit> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TransformOptions {
|
|
||||||
from: Transform,
|
|
||||||
to: Transform,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Transform {
|
|
||||||
unit: Unit,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NumfmtOptions {
|
|
||||||
transform: TransformOptions,
|
|
||||||
padding: isize,
|
|
||||||
header: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_suffix(i: f64, s: Option<Suffix>, u: &Unit) -> Result<f64> {
|
|
||||||
match (s, u) {
|
|
||||||
(None, _) => Ok(i),
|
|
||||||
(Some((raw_suffix, false)), &Unit::Auto) | (Some((raw_suffix, false)), &Unit::Si) => {
|
|
||||||
match raw_suffix {
|
|
||||||
RawSuffix::K => Ok(i * 1e3),
|
|
||||||
RawSuffix::M => Ok(i * 1e6),
|
|
||||||
RawSuffix::G => Ok(i * 1e9),
|
|
||||||
RawSuffix::T => Ok(i * 1e12),
|
|
||||||
RawSuffix::P => Ok(i * 1e15),
|
|
||||||
RawSuffix::E => Ok(i * 1e18),
|
|
||||||
RawSuffix::Z => Ok(i * 1e21),
|
|
||||||
RawSuffix::Y => Ok(i * 1e24),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Some((raw_suffix, false)), &Unit::Iec(false))
|
|
||||||
| (Some((raw_suffix, true)), &Unit::Auto)
|
|
||||||
| (Some((raw_suffix, true)), &Unit::Iec(true)) => match raw_suffix {
|
|
||||||
RawSuffix::K => Ok(i * IEC_BASES[1]),
|
|
||||||
RawSuffix::M => Ok(i * IEC_BASES[2]),
|
|
||||||
RawSuffix::G => Ok(i * IEC_BASES[3]),
|
|
||||||
RawSuffix::T => Ok(i * IEC_BASES[4]),
|
|
||||||
RawSuffix::P => Ok(i * IEC_BASES[5]),
|
|
||||||
RawSuffix::E => Ok(i * IEC_BASES[6]),
|
|
||||||
RawSuffix::Z => Ok(i * IEC_BASES[7]),
|
|
||||||
RawSuffix::Y => Ok(i * IEC_BASES[8]),
|
|
||||||
},
|
|
||||||
(_, _) => Err("This suffix is unsupported for specified unit".to_owned()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_from(s: &str, opts: &Transform) -> Result<f64> {
|
|
||||||
let (i, suffix) = parse_suffix(s)?;
|
|
||||||
remove_suffix(i, suffix, &opts.unit).map(|n| n.round())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn consider_suffix(i: f64, u: &Unit) -> Result<(f64, Option<Suffix>)> {
|
|
||||||
let j = i.abs();
|
|
||||||
match *u {
|
|
||||||
Unit::Si => match j {
|
|
||||||
_ if j < 1e3 => Ok((i, None)),
|
|
||||||
_ if j < 1e6 => Ok((i / 1e3, Some((RawSuffix::K, false)))),
|
|
||||||
_ if j < 1e9 => Ok((i / 1e6, Some((RawSuffix::M, false)))),
|
|
||||||
_ if j < 1e12 => Ok((i / 1e9, Some((RawSuffix::G, false)))),
|
|
||||||
_ if j < 1e15 => Ok((i / 1e12, Some((RawSuffix::T, false)))),
|
|
||||||
_ if j < 1e18 => Ok((i / 1e15, Some((RawSuffix::P, false)))),
|
|
||||||
_ if j < 1e21 => Ok((i / 1e18, Some((RawSuffix::E, false)))),
|
|
||||||
_ if j < 1e24 => Ok((i / 1e21, Some((RawSuffix::Z, false)))),
|
|
||||||
_ if j < 1e27 => Ok((i / 1e24, Some((RawSuffix::Y, false)))),
|
|
||||||
_ => Err("Number is too big and unsupported".to_owned()),
|
|
||||||
},
|
|
||||||
Unit::Iec(with_i) => match j {
|
|
||||||
_ if j < IEC_BASES[1] => Ok((i, None)),
|
|
||||||
_ if j < IEC_BASES[2] => Ok((i / IEC_BASES[1], Some((RawSuffix::K, with_i)))),
|
|
||||||
_ if j < IEC_BASES[3] => Ok((i / IEC_BASES[2], Some((RawSuffix::M, with_i)))),
|
|
||||||
_ if j < IEC_BASES[4] => Ok((i / IEC_BASES[3], Some((RawSuffix::G, with_i)))),
|
|
||||||
_ if j < IEC_BASES[5] => Ok((i / IEC_BASES[4], Some((RawSuffix::T, with_i)))),
|
|
||||||
_ if j < IEC_BASES[6] => Ok((i / IEC_BASES[5], Some((RawSuffix::P, with_i)))),
|
|
||||||
_ if j < IEC_BASES[7] => Ok((i / IEC_BASES[6], Some((RawSuffix::E, with_i)))),
|
|
||||||
_ if j < IEC_BASES[8] => Ok((i / IEC_BASES[7], Some((RawSuffix::Z, with_i)))),
|
|
||||||
_ if j < IEC_BASES[9] => Ok((i / IEC_BASES[8], Some((RawSuffix::Y, with_i)))),
|
|
||||||
_ => Err("Number is too big and unsupported".to_owned()),
|
|
||||||
},
|
|
||||||
Unit::Auto => Err("Unit 'auto' isn't supported with --to options".to_owned()),
|
|
||||||
Unit::None => Ok((i, None)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_to(s: f64, opts: &Transform) -> Result<String> {
|
|
||||||
let (i2, s) = consider_suffix(s, &opts.unit)?;
|
|
||||||
Ok(match s {
|
|
||||||
None => format!("{}", i2),
|
|
||||||
Some(s) => format!("{:.1}{}", i2, DisplayableSuffix(s)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_string(
|
|
||||||
source: &str,
|
|
||||||
options: &NumfmtOptions,
|
|
||||||
implicit_padding: Option<isize>,
|
|
||||||
) -> Result<String> {
|
|
||||||
let number = transform_to(
|
|
||||||
transform_from(source, &options.transform.from)?,
|
|
||||||
&options.transform.to,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(match implicit_padding.unwrap_or(options.padding) {
|
|
||||||
p if p == 0 => number,
|
|
||||||
p if p > 0 => format!("{:>padding$}", number, padding = p as usize),
|
|
||||||
p => format!("{:<padding$}", number, padding = p.abs() as usize),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_and_print(s: &str, options: &NumfmtOptions) -> Result<()> {
|
|
||||||
let (prefix, field, suffix) = extract_field(&s)?;
|
|
||||||
|
|
||||||
let implicit_padding = match !prefix.is_empty() && options.padding == 0 {
|
|
||||||
true => Some((prefix.len() + field.len()) as isize),
|
|
||||||
false => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let field = format_string(field, options, implicit_padding)?;
|
|
||||||
println!("{}{}", field, suffix);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
|
fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
|
||||||
let from = parse_unit(args.value_of(options::FROM).unwrap())?;
|
let from = parse_unit(args.value_of(options::FROM).unwrap())?;
|
||||||
let to = parse_unit(args.value_of(options::TO).unwrap())?;
|
let to = parse_unit(args.value_of(options::TO).unwrap())?;
|
||||||
|
@ -305,84 +119,32 @@ fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
let fields = match args.value_of(options::FIELD) {
|
||||||
|
Some("-") => vec![Range {
|
||||||
|
low: 1,
|
||||||
|
high: std::usize::MAX,
|
||||||
|
}],
|
||||||
|
Some(v) => Range::from_list(v)?,
|
||||||
|
None => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let delimiter = args.value_of(options::DELIMITER).map_or(Ok(None), |arg| {
|
||||||
|
if arg.len() == 1 {
|
||||||
|
Ok(Some(arg.to_string()))
|
||||||
|
} else {
|
||||||
|
Err("the delimiter must be a single character".to_string())
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(NumfmtOptions {
|
Ok(NumfmtOptions {
|
||||||
transform,
|
transform,
|
||||||
padding,
|
padding,
|
||||||
header,
|
header,
|
||||||
|
fields,
|
||||||
|
delimiter,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the field to convert from `line`.
|
|
||||||
///
|
|
||||||
/// The field is the first sequence of non-whitespace characters in `line`.
|
|
||||||
///
|
|
||||||
/// Returns a [`Result`] of `(prefix: &str, field: &str, suffix: &str)`, where
|
|
||||||
/// `prefix` contains any leading whitespace, `field` is the field to convert,
|
|
||||||
/// and `suffix` is everything after the field. `prefix` and `suffix` may be
|
|
||||||
/// empty.
|
|
||||||
///
|
|
||||||
/// Returns an [`Err`] if `line` is empty or consists only of whitespace.
|
|
||||||
///
|
|
||||||
/// Examples:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use uu_numfmt::extract_field;
|
|
||||||
///
|
|
||||||
/// assert_eq!("1K", extract_field("1K").unwrap().1);
|
|
||||||
///
|
|
||||||
/// let (prefix, field, suffix) = extract_field(" 1K qux").unwrap();
|
|
||||||
/// assert_eq!(" ", prefix);
|
|
||||||
/// assert_eq!("1K", field);
|
|
||||||
/// assert_eq!(" qux", suffix);
|
|
||||||
///
|
|
||||||
/// assert!(extract_field("").is_err());
|
|
||||||
/// ```
|
|
||||||
pub fn extract_field(line: &str) -> Result<(&str, &str, &str)> {
|
|
||||||
let start = line
|
|
||||||
.find(|c: char| !c.is_whitespace())
|
|
||||||
.ok_or("invalid number: ‘’")?;
|
|
||||||
|
|
||||||
let prefix = &line[..start];
|
|
||||||
|
|
||||||
let mut field = &line[start..];
|
|
||||||
|
|
||||||
let suffix = match field.find(|c: char| c.is_whitespace()) {
|
|
||||||
Some(i) => {
|
|
||||||
let suffix = &field[i..];
|
|
||||||
field = &field[..i];
|
|
||||||
suffix
|
|
||||||
}
|
|
||||||
None => "",
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((prefix, field, suffix))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_args<'a>(args: impl Iterator<Item = &'a str>, options: NumfmtOptions) -> Result<()> {
|
|
||||||
for l in args {
|
|
||||||
format_and_print(l, &options)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_stdin(options: NumfmtOptions) -> Result<()> {
|
|
||||||
let stdin = std::io::stdin();
|
|
||||||
let locked_stdin = stdin.lock();
|
|
||||||
|
|
||||||
let mut lines = locked_stdin.lines();
|
|
||||||
for l in lines.by_ref().take(options.header) {
|
|
||||||
l.map(|s| println!("{}", s)).map_err(|e| e.to_string())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for l in lines {
|
|
||||||
l.map_err(|e| e.to_string())
|
|
||||||
.and_then(|l| format_and_print(&l, &options))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let usage = get_usage();
|
let usage = get_usage();
|
||||||
|
|
||||||
|
@ -391,6 +153,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.about(ABOUT)
|
.about(ABOUT)
|
||||||
.usage(&usage[..])
|
.usage(&usage[..])
|
||||||
.after_help(LONG_HELP)
|
.after_help(LONG_HELP)
|
||||||
|
.setting(AppSettings::AllowNegativeNumbers)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::DELIMITER)
|
||||||
|
.short("d")
|
||||||
|
.long(options::DELIMITER)
|
||||||
|
.value_name("X")
|
||||||
|
.help("use X instead of whitespace for field delimiter"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::FIELD)
|
||||||
|
.long(options::FIELD)
|
||||||
|
.help("replace the numbers in these input fields (default=1) see FIELDS below")
|
||||||
|
.value_name("FIELDS")
|
||||||
|
.default_value(options::FIELD_DEFAULT),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(options::FROM)
|
Arg::with_name(options::FROM)
|
||||||
.long(options::FROM)
|
.long(options::FROM)
|
||||||
|
@ -438,6 +215,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
std::io::stdout().flush().expect("error flushing stdout");
|
||||||
show_info!("{}", e);
|
show_info!("{}", e);
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
27
src/uu/numfmt/src/options.rs
Normal file
27
src/uu/numfmt/src/options.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
use crate::units::Transform;
|
||||||
|
use uucore::ranges::Range;
|
||||||
|
|
||||||
|
pub const DELIMITER: &str = "delimiter";
|
||||||
|
pub const FIELD: &str = "field";
|
||||||
|
pub const FIELD_DEFAULT: &str = "1";
|
||||||
|
pub const FROM: &str = "from";
|
||||||
|
pub const FROM_DEFAULT: &str = "none";
|
||||||
|
pub const HEADER: &str = "header";
|
||||||
|
pub const HEADER_DEFAULT: &str = "1";
|
||||||
|
pub const NUMBER: &str = "NUMBER";
|
||||||
|
pub const PADDING: &str = "padding";
|
||||||
|
pub const TO: &str = "to";
|
||||||
|
pub const TO_DEFAULT: &str = "none";
|
||||||
|
|
||||||
|
pub struct TransformOptions {
|
||||||
|
pub from: Transform,
|
||||||
|
pub to: Transform,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NumfmtOptions {
|
||||||
|
pub transform: TransformOptions,
|
||||||
|
pub padding: isize,
|
||||||
|
pub header: usize,
|
||||||
|
pub fields: Vec<Range>,
|
||||||
|
pub delimiter: Option<String>,
|
||||||
|
}
|
67
src/uu/numfmt/src/units.rs
Normal file
67
src/uu/numfmt/src/units.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub const SI_BASES: [f64; 10] = [1., 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24, 1e27];
|
||||||
|
|
||||||
|
pub const IEC_BASES: [f64; 10] = [
|
||||||
|
1.,
|
||||||
|
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.,
|
||||||
|
];
|
||||||
|
|
||||||
|
pub type WithI = bool;
|
||||||
|
|
||||||
|
pub enum Unit {
|
||||||
|
Auto,
|
||||||
|
Si,
|
||||||
|
Iec(WithI),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Transform {
|
||||||
|
pub unit: Unit,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, String>;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum RawSuffix {
|
||||||
|
K,
|
||||||
|
M,
|
||||||
|
G,
|
||||||
|
T,
|
||||||
|
P,
|
||||||
|
E,
|
||||||
|
Z,
|
||||||
|
Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Suffix = (RawSuffix, WithI);
|
||||||
|
|
||||||
|
pub struct DisplayableSuffix(pub Suffix);
|
||||||
|
|
||||||
|
impl fmt::Display for DisplayableSuffix {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let DisplayableSuffix((ref raw_suffix, ref with_i)) = *self;
|
||||||
|
match raw_suffix {
|
||||||
|
RawSuffix::K => write!(f, "K"),
|
||||||
|
RawSuffix::M => write!(f, "M"),
|
||||||
|
RawSuffix::G => write!(f, "G"),
|
||||||
|
RawSuffix::T => write!(f, "T"),
|
||||||
|
RawSuffix::P => write!(f, "P"),
|
||||||
|
RawSuffix::E => write!(f, "E"),
|
||||||
|
RawSuffix::Z => write!(f, "Z"),
|
||||||
|
RawSuffix::Y => write!(f, "Y"),
|
||||||
|
}
|
||||||
|
.and_then(|()| match with_i {
|
||||||
|
true => write!(f, "i"),
|
||||||
|
false => Ok(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_od"
|
name = "uu_od"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "od ~ (uutils) display formatted representation of input"
|
description = "od ~ (uutils) display formatted representation of input"
|
||||||
|
@ -19,7 +19,7 @@ byteorder = "1.3.2"
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
half = "1.6"
|
half = "1.6"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub trait HasError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> MultifileReader<'b> {
|
impl<'b> MultifileReader<'b> {
|
||||||
pub fn new<'a>(fnames: Vec<InputSource<'a>>) -> MultifileReader<'a> {
|
pub fn new(fnames: Vec<InputSource>) -> MultifileReader {
|
||||||
let mut mf = MultifileReader {
|
let mut mf = MultifileReader {
|
||||||
ni: fnames,
|
ni: fnames,
|
||||||
curr_file: None, // normally this means done; call next_file()
|
curr_file: None, // normally this means done; call next_file()
|
||||||
|
|
|
@ -472,11 +472,11 @@ fn print_bytes(prefix: &str, input_decoder: &MemoryDecoder, output_info: &Output
|
||||||
///
|
///
|
||||||
/// `skip_bytes` is the number of bytes skipped from the input
|
/// `skip_bytes` is the number of bytes skipped from the input
|
||||||
/// `read_bytes` is an optional limit to the number of bytes to read
|
/// `read_bytes` is an optional limit to the number of bytes to read
|
||||||
fn open_input_peek_reader<'a>(
|
fn open_input_peek_reader(
|
||||||
input_strings: &'a [String],
|
input_strings: &[String],
|
||||||
skip_bytes: usize,
|
skip_bytes: usize,
|
||||||
read_bytes: Option<usize>,
|
read_bytes: Option<usize>,
|
||||||
) -> PeekReader<PartialReader<MultifileReader<'a>>> {
|
) -> PeekReader<PartialReader<MultifileReader>> {
|
||||||
// should return "impl PeekRead + Read + HasError" when supported in (stable) rust
|
// should return "impl PeekRead + Read + HasError" when supported in (stable) rust
|
||||||
let inputs = input_strings
|
let inputs = input_strings
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_paste"
|
name = "uu_paste"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "paste ~ (uutils) merge lines from inputs"
|
description = "paste ~ (uutils) merge lines from inputs"
|
||||||
|
@ -15,8 +15,8 @@ edition = "2018"
|
||||||
path = "src/paste.rs"
|
path = "src/paste.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
clap = "2.33.3"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -10,73 +10,82 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
use clap::{App, Arg};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, BufRead, BufReader, Read};
|
use std::io::{stdin, BufRead, BufReader, Read};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static NAME: &str = "paste";
|
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
static ABOUT: &str = "Write lines consisting of the sequentially corresponding lines from each
|
||||||
|
FILE, separated by TABs, to standard output.";
|
||||||
|
|
||||||
|
mod options {
|
||||||
|
pub const DELIMITER: &str = "delimiters";
|
||||||
|
pub const SERIAL: &str = "serial";
|
||||||
|
pub const FILE: &str = "file";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wraps BufReader and stdin
|
||||||
|
fn read_line<R: Read>(
|
||||||
|
reader: Option<&mut BufReader<R>>,
|
||||||
|
buf: &mut String,
|
||||||
|
) -> std::io::Result<usize> {
|
||||||
|
match reader {
|
||||||
|
Some(reader) => reader.read_line(buf),
|
||||||
|
None => stdin().read_line(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let args = args.collect_str();
|
let matches = App::new(executable!())
|
||||||
|
.version(VERSION)
|
||||||
|
.about(ABOUT)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::SERIAL)
|
||||||
|
.long(options::SERIAL)
|
||||||
|
.short("s")
|
||||||
|
.help("paste one file at a time instead of in parallel"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::DELIMITER)
|
||||||
|
.long(options::DELIMITER)
|
||||||
|
.short("d")
|
||||||
|
.help("reuse characters from LIST instead of TABs")
|
||||||
|
.value_name("LIST")
|
||||||
|
.default_value("\t")
|
||||||
|
.hide_default_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::FILE)
|
||||||
|
.value_name("FILE")
|
||||||
|
.multiple(true)
|
||||||
|
.default_value("-"),
|
||||||
|
)
|
||||||
|
.get_matches_from(args);
|
||||||
|
|
||||||
let mut opts = getopts::Options::new();
|
let serial = matches.is_present(options::SERIAL);
|
||||||
|
let delimiters = matches.value_of(options::DELIMITER).unwrap().to_owned();
|
||||||
opts.optflag(
|
let files = matches
|
||||||
"s",
|
.values_of(options::FILE)
|
||||||
"serial",
|
.unwrap()
|
||||||
"paste one file at a time instead of in parallel",
|
.map(|s| s.to_owned())
|
||||||
);
|
.collect();
|
||||||
opts.optopt(
|
paste(files, serial, delimiters);
|
||||||
"d",
|
|
||||||
"delimiters",
|
|
||||||
"reuse characters from LIST instead of TABs",
|
|
||||||
"LIST",
|
|
||||||
);
|
|
||||||
opts.optflag("h", "help", "display this help and exit");
|
|
||||||
opts.optflag("V", "version", "output version information and exit");
|
|
||||||
|
|
||||||
let matches = match opts.parse(&args[1..]) {
|
|
||||||
Ok(m) => m,
|
|
||||||
Err(e) => crash!(1, "{}", e),
|
|
||||||
};
|
|
||||||
|
|
||||||
if matches.opt_present("help") {
|
|
||||||
let msg = format!(
|
|
||||||
"{0} {1}
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
{0} [OPTION]... [FILE]...
|
|
||||||
|
|
||||||
Write lines consisting of the sequentially corresponding lines from each
|
|
||||||
FILE, separated by TABs, to standard output.",
|
|
||||||
NAME, VERSION
|
|
||||||
);
|
|
||||||
print!("{}", opts.usage(&msg));
|
|
||||||
} else if matches.opt_present("version") {
|
|
||||||
println!("{} {}", NAME, VERSION);
|
|
||||||
} else {
|
|
||||||
let serial = matches.opt_present("serial");
|
|
||||||
let delimiters = matches
|
|
||||||
.opt_str("delimiters")
|
|
||||||
.unwrap_or_else(|| "\t".to_owned());
|
|
||||||
paste(matches.free, serial, delimiters);
|
|
||||||
}
|
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paste(filenames: Vec<String>, serial: bool, delimiters: String) {
|
fn paste(filenames: Vec<String>, serial: bool, delimiters: String) {
|
||||||
let mut files: Vec<BufReader<Box<dyn Read>>> = filenames
|
let mut files: Vec<_> = filenames
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
BufReader::new(if name == "-" {
|
if name == "-" {
|
||||||
Box::new(stdin()) as Box<dyn Read>
|
None
|
||||||
} else {
|
} else {
|
||||||
let r = crash_if_err!(1, File::open(Path::new(&name)));
|
let r = crash_if_err!(1, File::open(Path::new(&name)));
|
||||||
Box::new(r) as Box<dyn Read>
|
Some(BufReader::new(r))
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -91,7 +100,7 @@ fn paste(filenames: Vec<String>, serial: bool, delimiters: String) {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
loop {
|
loop {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
match file.read_line(&mut line) {
|
match read_line(file.as_mut(), &mut line) {
|
||||||
Ok(0) => break,
|
Ok(0) => break,
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
output.push_str(line.trim_end());
|
output.push_str(line.trim_end());
|
||||||
|
@ -113,7 +122,7 @@ fn paste(filenames: Vec<String>, serial: bool, delimiters: String) {
|
||||||
eof_count += 1;
|
eof_count += 1;
|
||||||
} else {
|
} else {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
match file.read_line(&mut line) {
|
match read_line(file.as_mut(), &mut line) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
eof[i] = true;
|
eof[i] = true;
|
||||||
eof_count += 1;
|
eof_count += 1;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_pathchk"
|
name = "uu_pathchk"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "pathchk ~ (uutils) diagnose invalid or non-portable PATHNAME"
|
description = "pathchk ~ (uutils) diagnose invalid or non-portable PATHNAME"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/pathchk.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_pinky"
|
name = "uu_pinky"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "pinky ~ (uutils) display user information"
|
description = "pinky ~ (uutils) display user information"
|
||||||
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/pinky.rs"
|
path = "src/pinky.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["utmpx", "entries"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["utmpx", "entries"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_printenv"
|
name = "uu_printenv"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "printenv ~ (uutils) display value of environment VAR"
|
description = "printenv ~ (uutils) display value of environment VAR"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/printenv.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_printf"
|
name = "uu_printf"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = [
|
authors = [
|
||||||
"Nathan Ross",
|
"Nathan Ross",
|
||||||
"uutils developers",
|
"uutils developers",
|
||||||
|
@ -19,7 +19,7 @@ path = "src/printf.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
itertools = "0.8.0"
|
itertools = "0.8.0"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -52,8 +52,7 @@ fn get_primitive_hex(
|
||||||
last_dec_place: usize,
|
last_dec_place: usize,
|
||||||
capitalized: bool,
|
capitalized: bool,
|
||||||
) -> FormatPrimitive {
|
) -> FormatPrimitive {
|
||||||
let mut f: FormatPrimitive = Default::default();
|
let prefix = Some(String::from(if inprefix.sign == -1 { "-0x" } else { "0x" }));
|
||||||
f.prefix = Some(String::from(if inprefix.sign == -1 { "-0x" } else { "0x" }));
|
|
||||||
|
|
||||||
// assign the digits before and after the decimal points
|
// assign the digits before and after the decimal points
|
||||||
// to separate slices. If no digits after decimal point,
|
// to separate slices. If no digits after decimal point,
|
||||||
|
@ -97,7 +96,7 @@ fn get_primitive_hex(
|
||||||
// conversion. The best way to do it is to just convert the floatnum
|
// conversion. The best way to do it is to just convert the floatnum
|
||||||
// directly to base 2 and then at the end translate back to hex.
|
// directly to base 2 and then at the end translate back to hex.
|
||||||
let mantissa = 0;
|
let mantissa = 0;
|
||||||
f.suffix = Some({
|
let suffix = Some({
|
||||||
let ind = if capitalized { "P" } else { "p" };
|
let ind = if capitalized { "P" } else { "p" };
|
||||||
if mantissa >= 0 {
|
if mantissa >= 0 {
|
||||||
format!("{}+{}", ind, mantissa)
|
format!("{}+{}", ind, mantissa)
|
||||||
|
@ -105,7 +104,11 @@ fn get_primitive_hex(
|
||||||
format!("{}{}", ind, mantissa)
|
format!("{}{}", ind, mantissa)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
f
|
FormatPrimitive {
|
||||||
|
prefix,
|
||||||
|
suffix,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_hex(src: &str, before_decimal: bool) -> String {
|
fn to_hex(src: &str, before_decimal: bool) -> String {
|
||||||
|
|
|
@ -198,9 +198,10 @@ impl Formatter for Intf {
|
||||||
// We always will have a format primitive to return
|
// We always will have a format primitive to return
|
||||||
Some(if convert_hints.len_digits == 0 || convert_hints.is_zero {
|
Some(if convert_hints.len_digits == 0 || convert_hints.is_zero {
|
||||||
// if non-digit or end is reached before a non-zero digit
|
// if non-digit or end is reached before a non-zero digit
|
||||||
let mut fmt_prim: FormatPrimitive = Default::default();
|
FormatPrimitive {
|
||||||
fmt_prim.pre_decimal = Some(String::from("0"));
|
pre_decimal: Some(String::from("0")),
|
||||||
fmt_prim
|
..Default::default()
|
||||||
|
}
|
||||||
} else if !convert_hints.past_max {
|
} else if !convert_hints.past_max {
|
||||||
// if the number is or may be below the bounds limit
|
// if the number is or may be below the bounds limit
|
||||||
let radix_out = match *field.field_char {
|
let radix_out = match *field.field_char {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_ptx"
|
name = "uu_ptx"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "ptx ~ (uutils) display a permuted index of input"
|
description = "ptx ~ (uutils) display a permuted index of input"
|
||||||
|
@ -21,7 +21,7 @@ libc = "0.2.42"
|
||||||
memchr = "2.2.0"
|
memchr = "2.2.0"
|
||||||
regex = "1.0.1"
|
regex = "1.0.1"
|
||||||
regex-syntax = "0.6.7"
|
regex-syntax = "0.6.7"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -95,12 +95,21 @@ impl WordFilter {
|
||||||
if matches.opt_present("b") {
|
if matches.opt_present("b") {
|
||||||
crash!(1, "-b not implemented yet");
|
crash!(1, "-b not implemented yet");
|
||||||
}
|
}
|
||||||
let reg = if matches.opt_present("W") {
|
// Ignore empty string regex from cmd-line-args
|
||||||
matches.opt_str("W").expect("parsing options failed!")
|
let arg_reg: Option<String> = if matches.opt_present("W") {
|
||||||
} else if config.gnu_ext {
|
matches.opt_str("W").filter(|reg| !reg.is_empty())
|
||||||
"\\w+".to_owned()
|
|
||||||
} else {
|
} else {
|
||||||
"[^ \t\n]+".to_owned()
|
None
|
||||||
|
};
|
||||||
|
let reg = match arg_reg {
|
||||||
|
Some(arg_reg) => arg_reg,
|
||||||
|
None => {
|
||||||
|
if config.gnu_ext {
|
||||||
|
"\\w+".to_owned()
|
||||||
|
} else {
|
||||||
|
"[^ \t\n]+".to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
WordFilter {
|
WordFilter {
|
||||||
only_specified: o,
|
only_specified: o,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_pwd"
|
name = "uu_pwd"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "pwd ~ (uutils) display current working directory"
|
description = "pwd ~ (uutils) display current working directory"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/pwd.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_readlink"
|
name = "uu_readlink"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "readlink ~ (uutils) display resolved path of PATHNAME"
|
description = "readlink ~ (uutils) display resolved path of PATHNAME"
|
||||||
|
@ -17,7 +17,7 @@ path = "src/readlink.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
libc = "0.2.42"
|
libc = "0.2.42"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_realpath"
|
name = "uu_realpath"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "realpath ~ (uutils) display resolved absolute path of PATHNAME"
|
description = "realpath ~ (uutils) display resolved absolute path of PATHNAME"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/realpath.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let paths: Vec<PathBuf> = matches
|
let paths: Vec<PathBuf> = matches
|
||||||
.values_of(ARG_FILES)
|
.values_of(ARG_FILES)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|path| PathBuf::from(path))
|
.map(PathBuf::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let strip = matches.is_present(OPT_STRIP);
|
let strip = matches.is_present(OPT_STRIP);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_relpath"
|
name = "uu_relpath"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM"
|
description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM"
|
||||||
|
@ -16,7 +16,7 @@ path = "src/relpath.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "0.2.18"
|
getopts = "0.2.18"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore", features=["fs"] }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "uu_rm"
|
name = "uu_rm"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
authors = ["uutils developers"]
|
authors = ["uutils developers"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "rm ~ (uutils) remove PATHNAME"
|
description = "rm ~ (uutils) remove PATHNAME"
|
||||||
|
@ -18,7 +18,7 @@ path = "src/rm.rs"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
remove_dir_all = "0.5.1"
|
remove_dir_all = "0.5.1"
|
||||||
uucore = { version=">=0.0.6", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue