From 880a4973c13fd1333253781e58b0cd33fa3f7bc2 Mon Sep 17 00:00:00 2001 From: Alex Lyon Date: Mon, 12 Mar 2018 01:20:58 -0700 Subject: [PATCH] Format everything using rustfmt --- Cargo.lock | 166 ++++++ Cargo.toml | 2 + build.rs | 32 +- src/arch/arch.rs | 2 +- src/base32/base32.rs | 37 +- src/base64/base64.rs | 38 +- src/basename/basename.rs | 27 +- src/cat/cat.rs | 133 +++-- src/chgrp/chgrp.rs | 31 +- src/chmod/chmod.rs | 108 ++-- src/chown/chown.rs | 97 ++-- src/chroot/chroot.rs | 96 ++-- src/cksum/build.rs | 6 +- src/cksum/cksum.rs | 16 +- src/comm/comm.rs | 37 +- src/cp/cp.rs | 412 ++++++++------ src/cut/buffer.rs | 26 +- src/cut/cut.rs | 241 ++++---- src/cut/ranges.rs | 75 ++- src/cut/searcher.rs | 4 +- src/date/date.rs | 53 +- src/dircolors/dircolors.rs | 46 +- src/dirname/dirname.rs | 14 +- src/du/du.rs | 160 ++++-- src/echo/echo.rs | 42 +- src/env/env.rs | 45 +- src/expand/expand.rs | 114 ++-- src/expr/expr.rs | 86 +-- src/expr/syntax_tree.rs | 536 +++++++++++------- src/expr/tokens.rs | 160 +++--- src/factor/build.rs | 26 +- src/factor/factor.rs | 15 +- src/factor/numeric.rs | 8 +- src/factor/sieve.rs | 31 +- src/fmt/fmt.rs | 154 ++--- src/fmt/linebreak.rs | 330 ++++++----- src/fmt/parasplit.rs | 358 +++++++----- src/fold/fold.rs | 104 ++-- src/groups/groups.rs | 24 +- src/hashsum/digest.rs | 14 +- src/hashsum/hashsum.rs | 394 ++++++++----- src/head/head.rs | 58 +- src/hostid/hostid.rs | 25 +- src/hostname/hostname.rs | 32 +- src/id/id.rs | 197 ++++--- src/install/install.rs | 86 +-- src/join/join.rs | 139 +++-- src/kill/kill.rs | 46 +- src/link/link.rs | 9 +- src/ln/ln.rs | 119 ++-- src/logname/logname.rs | 4 +- src/ls/ls.rs | 311 +++++----- src/mkdir/mkdir.rs | 23 +- src/mkfifo/mkfifo.rs | 29 +- src/mknod/mknod.rs | 31 +- src/mknod/parsemode.rs | 2 +- src/mktemp/mktemp.rs | 84 ++- src/mktemp/tempdir.rs | 16 +- src/more/more.rs | 34 +- src/mv/mv.rs | 161 +++--- src/nice/nice.rs | 47 +- src/nl/helper.rs | 92 +-- src/nl/nl.rs | 136 +++-- src/nohup/nohup.rs | 69 ++- src/nproc/nproc.rs | 35 +- src/numfmt/numfmt.rs | 157 +++-- src/od/byteorder_io.rs | 2 +- src/od/formatteriteminfo.rs | 12 +- src/od/inputdecoder.rs | 48 +- src/od/inputoffset.rs | 8 +- src/od/mockstream.rs | 18 +- src/od/multifilereader.rs | 36 +- src/od/od.rs | 211 ++++--- src/od/output_info.rs | 328 +++++++++-- src/od/parse_formats.rs | 323 ++++++----- src/od/parse_inputs.rs | 229 ++++---- src/od/parse_nrofbytes.rs | 17 +- src/od/partialreader.rs | 19 +- src/od/peekreader.rs | 10 +- src/od/prn_char.rs | 82 ++- src/od/prn_float.rs | 220 +++---- src/od/prn_int.rs | 81 ++- src/paste/paste.rs | 56 +- src/pathchk/pathchk.rs | 107 ++-- src/pinky/pinky.rs | 63 +- src/printenv/printenv.rs | 17 +- src/printf/memo.rs | 6 +- src/printf/printf.rs | 31 +- src/printf/tokenize/num_format/formatter.rs | 16 +- .../num_format/formatters/base_conv/mod.rs | 39 +- .../formatters/cninetyninehexfloatf.rs | 67 +-- .../tokenize/num_format/formatters/decf.rs | 51 +- .../num_format/formatters/float_common.rs | 122 ++-- .../tokenize/num_format/formatters/floatf.rs | 34 +- .../tokenize/num_format/formatters/intf.rs | 108 ++-- .../tokenize/num_format/formatters/scif.rs | 39 +- src/printf/tokenize/num_format/num_format.rs | 34 +- src/printf/tokenize/sub.rs | 143 ++--- src/printf/tokenize/unescaped_text.rs | 18 +- src/ptx/ptx.rs | 394 +++++++------ src/pwd/pwd.rs | 30 +- src/readlink/readlink.rs | 41 +- src/realpath/realpath.rs | 42 +- src/relpath/relpath.rs | 46 +- src/rm/rm.rs | 93 +-- src/rmdir/rmdir.rs | 23 +- src/seq/seq.rs | 119 +++- src/shred/shred.rs | 287 ++++++---- src/shuf/shuf.rs | 94 +-- src/sleep/sleep.rs | 12 +- src/sort/sort.rs | 180 +++--- src/split/split.rs | 125 ++-- src/stat/fsext.rs | 45 +- src/stat/stat.rs | 136 +++-- src/stdbuf/build.rs | 10 +- src/stdbuf/libstdbuf/build.rs | 3 +- src/stdbuf/libstdbuf/libstdbuf.rs | 8 +- src/stdbuf/stdbuf.rs | 123 ++-- src/sum/sum.rs | 22 +- src/sync/sync.rs | 56 +- src/tac/tac.rs | 72 ++- src/tail/platform/mod.rs | 4 +- src/tail/platform/unix.rs | 15 +- src/tail/platform/windows.rs | 15 +- src/tail/tail.rs | 157 ++--- src/tee/tee.rs | 96 ++-- src/test/test.rs | 134 +++-- src/timeout/timeout.rs | 68 ++- src/touch/touch.rs | 106 ++-- src/tr/expand.rs | 18 +- src/tr/tr.rs | 35 +- src/true/true.rs | 2 +- src/truncate/truncate.rs | 112 ++-- src/tsort/tsort.rs | 57 +- src/tty/tty.rs | 9 +- src/uname/uname.rs | 7 +- src/unexpand/unexpand.rs | 179 ++++-- src/uniq/uniq.rs | 123 ++-- src/unlink/unlink.rs | 38 +- src/uptime/uptime.rs | 56 +- src/users/users.rs | 6 +- src/uucore/coreopts.rs | 86 ++- src/uucore/encoding.rs | 10 +- src/uucore/entries.rs | 29 +- src/uucore/fs.rs | 24 +- src/uucore/mode.rs | 45 +- src/uucore/panic.rs | 2 +- src/uucore/parse_time.rs | 6 +- src/uucore/process.rs | 23 +- src/uucore/signals.rs | 327 ++++++++--- src/uucore/utf8.rs | 1 - src/uucore/utmpx.rs | 30 +- src/uucore/wide.rs | 11 +- src/uutils/uutils.rs | 10 +- src/wc/wc.rs | 36 +- src/who/who.rs | 181 +++--- src/whoami/platform/windows.rs | 4 +- src/whoami/whoami.rs | 2 +- src/yes/yes.rs | 11 +- tests/common/util.rs | 75 ++- tests/tests.rs | 1 - uumain.rs | 2 +- 162 files changed, 7895 insertions(+), 5056 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77faeaa69..db334658a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,6 +45,7 @@ dependencies = [ name = "base32" version = "0.0.1" dependencies = [ + "clippy 0.0.143 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.1", ] @@ -109,6 +110,16 @@ name = "byteorder" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cargo_metadata" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cat" version = "0.0.1" @@ -149,6 +160,7 @@ dependencies = [ name = "chown" version = "0.0.1" dependencies = [ + "clippy 0.0.143 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.1", "walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -193,6 +205,32 @@ dependencies = [ "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "clippy" +version = "0.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.143 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clippy_lints" +version = "0.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cmake" version = "0.1.29" @@ -345,6 +383,11 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "dtoa" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "du" version = "0.0.1" @@ -564,6 +607,7 @@ version = "0.0.1" dependencies = [ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.1", ] @@ -580,6 +624,11 @@ dependencies = [ "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itoa" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "join" version = "0.0.1" @@ -673,6 +722,11 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "matches" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "md5" version = "0.3.7" @@ -970,6 +1024,14 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "proc-macro2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ptx" version = "0.0.1" @@ -996,11 +1058,24 @@ name = "quick-error" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quine-mc_cluskey" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.22" @@ -1137,6 +1212,14 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "semver" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "semver" version = "0.7.0" @@ -1158,6 +1241,42 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "serde" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sha1" version = "0.2.0" @@ -1275,6 +1394,16 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "syn" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sync" version = "0.0.1" @@ -1410,6 +1539,14 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "toml" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "touch" version = "0.0.1" @@ -1490,6 +1627,11 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "unicode-normalization" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.4" @@ -1500,6 +1642,11 @@ name = "unicode-xid" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unindent" version = "0.1.2" @@ -1726,6 +1873,7 @@ dependencies = [ name = "who" version = "0.0.1" dependencies = [ + "clippy 0.0.143 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.1", ] @@ -1797,10 +1945,13 @@ dependencies = [ "checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" +"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200" +"checksum clippy 0.0.143 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba494d48c1022ff0ded833291488c399a24cf4b3ca42c90870a4e354f73482b" +"checksum clippy_lints 0.0.143 (registry+https://github.com/rust-lang/crates.io-index)" = "305d52f00df613fc9078dddbd820f03242a2682d57d9f7e7628891bdc041dbf5" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum cpp 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b244cf36c028e27227d6e7f9963c768dff5a1c06d5e01ff97f12ef4e05afd57c" "checksum cpp_build 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9aebc7c97550a8c6a1f48dbaf078b033dc546e1b5badde300767099d4cace8f" @@ -1811,6 +1962,7 @@ dependencies = [ "checksum cpp_synom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc8da5694233b646150c785118f77835ad0a49680c7f312a10ef30957c67b6d" "checksum data-encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867ddbf09de0b73e09ec798972fb7f870495a0893f6f736c1855448c5a56789" "checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" +"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum duct 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8c553d79f40e74f7f611e49bf3429b6760cff79596b61818291c27cc0b18549d" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" @@ -1826,11 +1978,13 @@ dependencies = [ "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2c4b26352496eaaa8ca7cfa9bd99e93419d3f7983dc6e99c2a35fe9e33504a" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" +"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" +"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum md5 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "daa1004633f76cdcd5a9d83ffcfe615e30ca7a2a638fcc8b8039a2dac21289d7" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" @@ -1848,8 +2002,11 @@ dependencies = [ "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum platform-info 0.1.0 (git+https://github.com/uutils/platform-info)" = "" "checksum pretty-bytes 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "009d6edd2c1dbf2e1c0cd48a2f7766e03498d49ada7109a01c6911815c685316" +"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" +"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" @@ -1861,13 +2018,19 @@ dependencies = [ "checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" "checksum rust-users 0.6.0 (git+https://github.com/uutils/rust-users)" = "" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" +"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdd61b85a0fa777f7fb7c454b9189b2941b110d1385ce84d7f76efdf1606a85" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406" +"checksum serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab31f00ae5574bb643c196d5e302961c122da1c768604c6d16a35c5d551948a" +"checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8" +"checksum serde_json 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fab6c4d75bedcf880711c85e39ebf8ccc70d0eba259899047ec5d7436643ee17" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" "checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0" "checksum shared_child 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd5e483b3475af9bc2a35311c2f3bbf0bd98fde91410ab15a0d4ba3c3127b4e" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd" "checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e" "checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0" "checksum term_grid 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "230d3e804faaed5a39b08319efb797783df2fd9671b39b7596490cb486d702cf" @@ -1876,10 +2039,13 @@ dependencies = [ "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" +"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unindent 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "10743f62eafa8863b3dbb35cd6abbb609c963dd98940142a85bc530b753e33a4" "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" diff --git a/Cargo.toml b/Cargo.toml index 5c1a80b34..02bb94d33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -148,6 +148,8 @@ test_unimplemented = [] nightly = [] default = ["generic", "unix"] +[workspace] + [dependencies] uucore = { path="src/uucore" } arch = { optional=true, path="src/arch" } diff --git a/build.rs b/build.rs index 9468b06eb..778562b0a 100644 --- a/build.rs +++ b/build.rs @@ -16,8 +16,9 @@ pub fn main() { if val == "1" && key.starts_with(feature_prefix) { let krate = key[feature_prefix.len()..].to_lowercase(); match krate.as_ref() { - "default" | "unix" | "redox" | "redox_generic" | "fuchsia" | "generic" | "nightly" | "test_unimplemented" => continue, - _ => {}, + "default" | "unix" | "redox" | "redox_generic" | "fuchsia" | "generic" + | "nightly" | "test_unimplemented" => continue, + _ => {} } crates.push(krate.to_string()); } @@ -27,18 +28,23 @@ pub fn main() { let mut cf = File::create(Path::new(&out_dir).join("uutils_crates.rs")).unwrap(); let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap(); - mf.write_all(" + mf.write_all( + " type UtilityMap = HashMap<&'static str, fn(Vec) -> i32>; fn util_map() -> UtilityMap { - let mut map: UtilityMap = HashMap::new();\n".as_bytes()).unwrap(); + let mut map: UtilityMap = HashMap::new();\n" + .as_bytes(), + ).unwrap(); for krate in crates { - cf.write_all(format!("extern crate uu_{krate};\n", krate=krate).as_bytes()).unwrap(); + cf.write_all(format!("extern crate uu_{krate};\n", krate = krate).as_bytes()) + .unwrap(); match krate.as_ref() { "hashsum" => { - mf.write_all("map.insert(\"hashsum\", uu_hashsum::uumain); + mf.write_all( + "map.insert(\"hashsum\", uu_hashsum::uumain); map.insert(\"md5sum\", uu_hashsum::uumain); map.insert(\"sha1sum\", uu_hashsum::uumain); map.insert(\"sha224sum\", uu_hashsum::uumain); @@ -51,10 +57,16 @@ pub fn main() { map.insert(\"sha3-384sum\", uu_hashsum::uumain); map.insert(\"sha3-512sum\", uu_hashsum::uumain); map.insert(\"shake128sum\", uu_hashsum::uumain); - map.insert(\"shake256sum\", uu_hashsum::uumain);\n".as_bytes()).unwrap(); - }, - _ => - mf.write_all(format!("map.insert(\"{krate}\", uu_{krate}::uumain);\n", krate=krate).as_bytes()).unwrap(), + map.insert(\"shake256sum\", uu_hashsum::uumain);\n" + .as_bytes(), + ).unwrap(); + } + _ => mf.write_all( + format!( + "map.insert(\"{krate}\", uu_{krate}::uumain);\n", + krate = krate + ).as_bytes(), + ).unwrap(), } } diff --git a/src/arch/arch.rs b/src/arch/arch.rs index 20da6c64d..17a6e9f53 100644 --- a/src/arch/arch.rs +++ b/src/arch/arch.rs @@ -9,9 +9,9 @@ // file that was distributed with this source code. // +extern crate platform_info; #[macro_use] extern crate uucore; -extern crate platform_info; use platform_info::*; diff --git a/src/base32/base32.rs b/src/base32/base32.rs index 9f19c44c5..c0dc5e613 100644 --- a/src/base32/base32.rs +++ b/src/base32/base32.rs @@ -10,14 +10,15 @@ #[macro_use] extern crate uucore; -use uucore::encoding::{Data, Format, wrap_print}; +use uucore::encoding::{wrap_print, Data, Format}; use std::fs::File; -use std::io::{BufReader, Read, stdin}; +use std::io::{stdin, BufReader, Read}; use std::path::Path; static SYNTAX: &'static str = "[OPTION]... [FILE]"; -static SUMMARY: &'static str = "Base32 encode or decode FILE, or standard input, to standard output."; +static SUMMARY: &'static str = + "Base32 encode or decode FILE, or standard input, to standard output."; static LONG_HELP: &'static str = " With no FILE, or when FILE is -, read standard input. @@ -31,24 +32,26 @@ static LONG_HELP: &'static str = " pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("d", "decode", "decode data") - .optflag("i", - "ignore-garbage", - "when decoding, ignore non-alphabetic characters") - .optopt("w", - "wrap", - "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", - "COLS") + .optflag( + "i", + "ignore-garbage", + "when decoding, ignore non-alphabetic characters", + ) + .optopt( + "w", + "wrap", + "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", + "COLS", + ) .parse(args); let line_wrap = match matches.opt_str("wrap") { - Some(s) => { - match s.parse() { - Ok(n) => n, - Err(e) => { - crash!(1, "invalid wrap size: ‘{}’: {}", s, e); - } + Some(s) => match s.parse() { + Ok(n) => n, + Err(e) => { + crash!(1, "invalid wrap size: ‘{}’: {}", s, e); } - } + }, None => 76, }; diff --git a/src/base64/base64.rs b/src/base64/base64.rs index 2f9459680..ac7e350b8 100644 --- a/src/base64/base64.rs +++ b/src/base64/base64.rs @@ -9,17 +9,17 @@ // that was distributed with this source code. // - #[macro_use] extern crate uucore; -use uucore::encoding::{Data, Format, wrap_print}; +use uucore::encoding::{wrap_print, Data, Format}; use std::fs::File; -use std::io::{BufReader, Read, stdin}; +use std::io::{stdin, BufReader, Read}; use std::path::Path; static SYNTAX: &'static str = "[OPTION]... [FILE]"; -static SUMMARY: &'static str = "Base64 encode or decode FILE, or standard input, to standard output."; +static SUMMARY: &'static str = + "Base64 encode or decode FILE, or standard input, to standard output."; static LONG_HELP: &'static str = " With no FILE, or when FILE is -, read standard input. @@ -33,24 +33,26 @@ static LONG_HELP: &'static str = " pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("d", "decode", "decode data") - .optflag("i", - "ignore-garbage", - "when decoding, ignore non-alphabetic characters") - .optopt("w", - "wrap", - "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", - "COLS") + .optflag( + "i", + "ignore-garbage", + "when decoding, ignore non-alphabetic characters", + ) + .optopt( + "w", + "wrap", + "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", + "COLS", + ) .parse(args); let line_wrap = match matches.opt_str("wrap") { - Some(s) => { - match s.parse() { - Ok(n) => n, - Err(e) => { - crash!(1, "invalid wrap size: ‘{}’: {}", s, e); - } + Some(s) => match s.parse() { + Ok(n) => n, + Err(e) => { + crash!(1, "invalid wrap size: ‘{}’: {}", s, e); } - } + }, None => 76, }; diff --git a/src/basename/basename.rs b/src/basename/basename.rs index a40c7bf3f..719a6addf 100644 --- a/src/basename/basename.rs +++ b/src/basename/basename.rs @@ -25,9 +25,22 @@ pub fn uumain(args: Vec) -> i32 { // Argument parsing // let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .optflag("a", "multiple", "Support more than one argument. Treat every argument as a name.") - .optopt("s", "suffix", "Remove a trailing suffix. This option implies the -a option.", "SUFFIX") - .optflag("z", "zero", "Output a zero byte (ASCII NUL) at the end of each line, rather than a newline.") + .optflag( + "a", + "multiple", + "Support more than one argument. Treat every argument as a name.", + ) + .optopt( + "s", + "suffix", + "Remove a trailing suffix. This option implies the -a option.", + "SUFFIX", + ) + .optflag( + "z", + "zero", + "Output a zero byte (ASCII NUL) at the end of each line, rather than a newline.", + ) .parse(args); // too few arguments @@ -81,7 +94,11 @@ pub fn uumain(args: Vec) -> i32 { fn basename(fullname: &str, suffix: &str) -> String { // Remove all platform-specific path separators from the end - let mut path: String = fullname.chars().rev().skip_while(|&ch| is_separator(ch)).collect(); + let mut path: String = fullname + .chars() + .rev() + .skip_while(|&ch| is_separator(ch)) + .collect(); // Undo reverse path = path.chars().rev().collect(); @@ -90,7 +107,7 @@ fn basename(fullname: &str, suffix: &str) -> String { let pb = PathBuf::from(path); match pb.components().last() { Some(c) => strip_suffix(c.as_os_str().to_str().unwrap(), suffix), - None => "".to_owned() + None => "".to_owned(), } } diff --git a/src/cat/cat.rs b/src/cat/cat.rs index 9b0a763f0..9aef7114e 100644 --- a/src/cat/cat.rs +++ b/src/cat/cat.rs @@ -20,20 +20,22 @@ extern crate uucore; // last synced with: cat (GNU coreutils) 8.13 use quick_error::ResultExt; use std::fs::{metadata, File}; -use std::io::{self, stdout, stdin, stderr, Write, Read, BufWriter}; +use std::io::{self, stderr, stdin, stdout, BufWriter, Read, Write}; use uucore::fs::is_stdin_interactive; /// Unix domain socket support -#[cfg(unix)] use std::net::Shutdown; -#[cfg(unix)] use std::os::unix::fs::FileTypeExt; -#[cfg(unix)] use unix_socket::UnixStream; +#[cfg(unix)] +use std::net::Shutdown; +#[cfg(unix)] +use std::os::unix::fs::FileTypeExt; +#[cfg(unix)] +use unix_socket::UnixStream; static SYNTAX: &'static str = "[OPTION]... [FILE]..."; static SUMMARY: &'static str = "Concatenate FILE(s), or standard input, to standard output With no FILE, or when FILE is -, read standard input."; static LONG_HELP: &'static str = ""; - #[derive(PartialEq)] enum NumberingMode { NumberNone, @@ -41,7 +43,6 @@ enum NumberingMode { NumberAll, } - quick_error! { #[derive(Debug)] enum CatError { @@ -75,7 +76,6 @@ quick_error! { } } - struct OutputOptions { /// Line numbering mode number: NumberingMode, @@ -98,14 +98,12 @@ struct OutputOptions { show_nonprint: bool, } - /// Represents an open file handle, stream, or other device struct InputHandle { reader: Box, is_interactive: bool, } - /// Concrete enum of recognized file types. /// /// *Note*: `cat`-ing a directory should result in an @@ -115,31 +113,37 @@ enum InputType { File, StdIn, SymLink, - #[cfg(unix)] BlockDevice, - #[cfg(unix)] CharacterDevice, - #[cfg(unix)] Fifo, - #[cfg(unix)] Socket, - } - + #[cfg(unix)] + BlockDevice, + #[cfg(unix)] + CharacterDevice, + #[cfg(unix)] + Fifo, + #[cfg(unix)] + Socket, +} type CatResult = Result; - pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("A", "show-all", "equivalent to -vET") - .optflag("b", - "number-nonblank", - "number nonempty output lines, overrides -n") + .optflag( + "b", + "number-nonblank", + "number nonempty output lines, overrides -n", + ) .optflag("e", "", "equivalent to -vE") .optflag("E", "show-ends", "display $ at end of each line") .optflag("n", "number", "number all output lines") .optflag("s", "squeeze-blank", "suppress repeated empty output lines") .optflag("t", "", "equivalent to -vT") .optflag("T", "show-tabs", "display TAB characters as ^I") - .optflag("v", - "show-nonprinting", - "use ^ and M- notation, except for LF (\\n) and TAB (\\t)") + .optflag( + "v", + "show-nonprinting", + "use ^ and M- notation, except for LF (\\n) and TAB (\\t)", + ) .parse(args); let number_mode = if matches.opt_present("b") { @@ -150,8 +154,12 @@ pub fn uumain(args: Vec) -> i32 { NumberingMode::NumberNone }; - let show_nonprint = - matches.opts_present(&["A".to_owned(), "e".to_owned(), "t".to_owned(), "v".to_owned()]); + let show_nonprint = matches.opts_present(&[ + "A".to_owned(), + "e".to_owned(), + "t".to_owned(), + "v".to_owned(), + ]); let show_ends = matches.opts_present(&["E".to_owned(), "A".to_owned(), "e".to_owned()]); let show_tabs = matches.opts_present(&["A".to_owned(), "T".to_owned(), "t".to_owned()]); let squeeze_blank = matches.opt_present("s"); @@ -160,15 +168,11 @@ pub fn uumain(args: Vec) -> i32 { files.push("-".to_owned()); } - let can_write_fast = !(show_tabs - || show_nonprint - || show_ends - || squeeze_blank - || number_mode != NumberingMode::NumberNone); + let can_write_fast = !(show_tabs || show_nonprint || show_ends || squeeze_blank + || number_mode != NumberingMode::NumberNone); let success = if can_write_fast { write_fast(files).is_ok() - } else { let tab = match show_tabs { true => "^I", @@ -198,7 +202,6 @@ pub fn uumain(args: Vec) -> i32 { } } - /// Classifies the `InputType` of file at `path` if possible /// /// # Arguments @@ -206,18 +209,34 @@ pub fn uumain(args: Vec) -> i32 { /// * `path` - Path on a file system to classify metadata fn get_input_type(path: &str) -> CatResult { if path == "-" { - return Ok(InputType::StdIn) + return Ok(InputType::StdIn); } match metadata(path).context(path)?.file_type() { - #[cfg(unix)] ft if ft.is_block_device() => Ok(InputType::BlockDevice), - #[cfg(unix)] ft if ft.is_char_device() => Ok(InputType::CharacterDevice), - #[cfg(unix)] ft if ft.is_fifo() => Ok(InputType::Fifo), - #[cfg(unix)] ft if ft.is_socket() => Ok(InputType::Socket), - ft if ft.is_dir() => Ok(InputType::Directory), - ft if ft.is_file() => Ok(InputType::File), - ft if ft.is_symlink() => Ok(InputType::SymLink), - _ => Err(CatError::UnknownFiletype(path.to_owned())) + #[cfg(unix)] + ft if ft.is_block_device() => + { + Ok(InputType::BlockDevice) + } + #[cfg(unix)] + ft if ft.is_char_device() => + { + Ok(InputType::CharacterDevice) + } + #[cfg(unix)] + ft if ft.is_fifo() => + { + Ok(InputType::Fifo) + } + #[cfg(unix)] + ft if ft.is_socket() => + { + Ok(InputType::Socket) + } + ft if ft.is_dir() => Ok(InputType::Directory), + ft if ft.is_file() => Ok(InputType::File), + ft if ft.is_symlink() => Ok(InputType::SymLink), + _ => Err(CatError::UnknownFiletype(path.to_owned())), } } @@ -238,21 +257,22 @@ fn open(path: &str) -> CatResult { match get_input_type(path)? { InputType::Directory => Err(CatError::IsDirectory(path.to_owned())), - #[cfg(unix)] InputType::Socket => { + #[cfg(unix)] + InputType::Socket => { let socket = UnixStream::connect(path).context(path)?; socket.shutdown(Shutdown::Write).context(path)?; Ok(InputHandle { reader: Box::new(socket) as Box, is_interactive: false, }) - }, + } _ => { let file = File::open(path).context(path)?; Ok(InputHandle { reader: Box::new(file) as Box, is_interactive: false, }) - }, + } } } @@ -271,18 +291,16 @@ fn write_fast(files: Vec) -> CatResult<()> { for file in files { match open(&file[..]) { - Ok(mut handle) => { - while let Ok(n) = handle.reader.read(&mut in_buf) { - if n == 0 { - break; - } - writer.write_all(&in_buf[..n]).context(&file[..])?; + Ok(mut handle) => while let Ok(n) = handle.reader.read(&mut in_buf) { + if n == 0 { + break; } + writer.write_all(&in_buf[..n]).context(&file[..])?; }, Err(error) => { writeln!(&mut stderr(), "{}", error)?; error_count += 1; - }, + } } } @@ -331,9 +349,7 @@ fn write_lines(files: Vec, options: &OutputOptions) -> CatResult<()> { /// Outputs file contents to stdout in a linewise fashion, /// propagating any errors that might occur. -fn write_file_lines(file: &str, - options: &OutputOptions, - state: &mut OutputState) -> CatResult<()> { +fn write_file_lines(file: &str, options: &OutputOptions, state: &mut OutputState) -> CatResult<()> { let mut handle = open(file)?; let mut in_buf = [0; 1024 * 31]; let mut writer = BufWriter::with_capacity(1024 * 64, stdout()); @@ -413,7 +429,10 @@ fn write_to_end(in_buf: &[u8], writer: &mut W) -> usize { fn write_tab_to_end(mut in_buf: &[u8], writer: &mut W) -> usize { loop { - match in_buf.iter().position(|c| *c == '\n' as u8 || *c == '\t' as u8) { + match in_buf + .iter() + .position(|c| *c == '\n' as u8 || *c == '\t' as u8) + { Some(p) => { writer.write_all(&in_buf[..p]).unwrap(); if in_buf[p] == '\n' as u8 { @@ -449,5 +468,9 @@ fn write_nonprint_to_end(in_buf: &[u8], writer: &mut W, tab: &[u8]) -> }.unwrap(); count += 1; } - if count != in_buf.len() { count + 1 } else { 0 } + if count != in_buf.len() { + count + 1 + } else { + 0 + } } diff --git a/src/chgrp/chgrp.rs b/src/chgrp/chgrp.rs index d76824fbe..a312c45f2 100644 --- a/src/chgrp/chgrp.rs +++ b/src/chgrp/chgrp.rs @@ -29,7 +29,8 @@ use std::path::Path; use std::ffi::CString; use std::os::unix::ffi::OsStrExt; -static SYNTAX: &'static str = "chgrp [OPTION]... GROUP FILE...\n or : chgrp [OPTION]... --reference=RFILE FILE..."; +static SYNTAX: &'static str = + "chgrp [OPTION]... GROUP FILE...\n or : chgrp [OPTION]... --reference=RFILE FILE..."; static SUMMARY: &'static str = "Change the group of each FILE to GROUP."; const FTS_COMFOLLOW: u8 = 1; @@ -334,10 +335,12 @@ impl Chgrper { _ => { show_info!("changing group of '{}': {}", path.display(), e); if self.verbosity == Verbose { - println!("failed to change group of {} from {} to {}", - path.display(), - entries::gid2grp(meta.gid()).unwrap(), - entries::gid2grp(dest_gid).unwrap()); + println!( + "failed to change group of {} from {} to {}", + path.display(), + entries::gid2grp(meta.gid()).unwrap(), + entries::gid2grp(dest_gid).unwrap() + ); }; } } @@ -347,17 +350,21 @@ impl Chgrper { if changed { match self.verbosity { Changes | Verbose => { - println!("changed group of {} from {} to {}", - path.display(), - entries::gid2grp(meta.gid()).unwrap(), - entries::gid2grp(dest_gid).unwrap()); + println!( + "changed group of {} from {} to {}", + path.display(), + entries::gid2grp(meta.gid()).unwrap(), + entries::gid2grp(dest_gid).unwrap() + ); } _ => (), }; } else if self.verbosity == Verbose { - println!("group of {} retained as {}", - path.display(), - entries::gid2grp(dest_gid).unwrap()); + println!( + "group of {} retained as {}", + path.display(), + entries::gid2grp(dest_gid).unwrap() + ); } } ret diff --git a/src/chmod/chmod.rs b/src/chmod/chmod.rs index 032ac926c..4fb6457c7 100644 --- a/src/chmod/chmod.rs +++ b/src/chmod/chmod.rs @@ -31,12 +31,17 @@ static LONG_HELP: &'static str = " "; pub fn uumain(mut args: Vec) -> i32 { - let syntax = format!("[OPTION]... MODE[,MODE]... FILE... + let syntax = format!( + "[OPTION]... MODE[,MODE]... FILE... {0} [OPTION]... OCTAL-MODE FILE... - {0} [OPTION]... --reference=RFILE FILE...", NAME); + {0} [OPTION]... --reference=RFILE FILE...", + NAME + ); let mut opts = new_coreopts!(&syntax, SUMMARY, LONG_HELP); - opts.optflag("c", "changes", "like verbose but report only when a change is made (unimplemented)") - .optflag("f", "quiet", "suppress most error messages (unimplemented)") // TODO: support --silent + opts.optflag("c", "changes", "like verbose but report only when a change is made \ + (unimplemented)") + // TODO: support --silent (can be done using clap) + .optflag("f", "quiet", "suppress most error messages (unimplemented)") .optflag("v", "verbose", "output a diagnostic for every file processed (unimplemented)") .optflag("", "no-preserve-root", "do not treat '/' specially (the default)") .optflag("", "preserve-root", "fail to operate recursively on '/'") @@ -58,25 +63,24 @@ pub fn uumain(mut args: Vec) -> i32 { let verbose = matches.opt_present("verbose"); let preserve_root = matches.opt_present("preserve-root"); let recursive = matches.opt_present("recursive"); - let fmode = matches.opt_str("reference").and_then(|ref fref| { - match fs::metadata(fref) { + let fmode = matches + .opt_str("reference") + .and_then(|ref fref| match fs::metadata(fref) { Ok(meta) => Some(meta.mode()), - Err(err) => crash!(1, "cannot stat attribues of '{}': {}", fref, err) - } - }); - let cmode = - if fmode.is_none() { - // If there was a negative option, now it's a good time to - // use it. - if negative_option.is_some() { - negative_option - } else { - Some(matches.free.remove(0)) - } + Err(err) => crash!(1, "cannot stat attribues of '{}': {}", fref, err), + }); + let cmode = if fmode.is_none() { + // If there was a negative option, now it's a good time to + // use it. + if negative_option.is_some() { + negative_option } else { - None - }; - let chmoder = Chmoder{ + Some(matches.free.remove(0)) + } + } else { + None + }; + let chmoder = Chmoder { changes: changes, quiet: quiet, verbose: verbose, @@ -87,7 +91,7 @@ pub fn uumain(mut args: Vec) -> i32 { }; match chmoder.chmod(matches.free) { Ok(()) => {} - Err(e) => return e + Err(e) => return e, } } @@ -102,9 +106,9 @@ fn sanitize_input(args: &mut Vec) -> Option { } if let Some(second) = args[i].chars().nth(1) { match second { - 'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0' ... '7' => { + 'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0'...'7' => { return Some(args.remove(i)); - }, + } _ => {} } } @@ -123,7 +127,6 @@ struct Chmoder { } impl Chmoder { - fn chmod(&self, files: Vec) -> Result<(), i32> { let mut r = Ok(()); @@ -145,18 +148,21 @@ impl Chmoder { // on Windows OsStrings cannot be built out of non-UTF-8 chars. One // possible fix is to use CStrings rather than Strings in the args // to chmod() and chmod_file(). - r = self.chmod(walk_dir.filter_map(|x| match x { - Ok(o) => match o.path().into_os_string().to_str() { - Some(s) => Some(s.to_owned()), - None => None, - }, - Err(_) => None, - }).collect()).and(r); + r = self.chmod( + walk_dir + .filter_map(|x| match x { + Ok(o) => match o.path().into_os_string().to_str() { + Some(s) => Some(s.to_owned()), + None => None, + }, + Err(_) => None, + }) + .collect(), + ).and(r); r = self.chmod_file(&file, filename).and(r); } } else { - show_error!("could not change permissions of directory '{}'", - filename); + show_error!("could not change permissions of directory '{}'", filename); r = Err(1); } } else { @@ -193,14 +199,14 @@ impl Chmoder { Some(mode) => try!(self.change_file(fperm, mode, file, name)), None => { let cmode_unwrapped = self.cmode.clone().unwrap(); - for mode in cmode_unwrapped.split(',') { // cmode is guaranteed to be Some in this case + for mode in cmode_unwrapped.split(',') { + // cmode is guaranteed to be Some in this case let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; - let result = - if mode.contains(arr) { - mode::parse_numeric(fperm, mode) - } else { - mode::parse_symbolic(fperm, mode, file.is_dir()) - }; + let result = if mode.contains(arr) { + mode::parse_numeric(fperm, mode) + } else { + mode::parse_symbolic(fperm, mode, file.is_dir()) + }; match result { Ok(mode) => { try!(self.change_file(fperm, mode, file, name)); @@ -226,19 +232,31 @@ impl Chmoder { show_info!("mode of '{}' retained as {:o}", file.display(), fperm); } Ok(()) - } else if let Err(err) = fs::set_permissions(Path::new(path), fs::Permissions::from_mode(mode)) { + } else if let Err(err) = + fs::set_permissions(Path::new(path), fs::Permissions::from_mode(mode)) + { if !self.quiet { show_error!("{}", err); } if self.verbose { - show_info!("failed to change mode of file '{}' from {:o} to {:o}", file.display(), fperm, mode); + show_info!( + "failed to change mode of file '{}' from {:o} to {:o}", + file.display(), + fperm, + mode + ); } Err(1) } else { if self.verbose || self.changes { - show_info!("mode of '{}' changed from {:o} to {:o}", file.display(), fperm, mode); + show_info!( + "mode of '{}' changed from {:o} to {:o}", + file.display(), + fperm, + mode + ); } Ok(()) } } -} \ No newline at end of file +} diff --git a/src/chown/chown.rs b/src/chown/chown.rs index 293220bbd..d1787b48e 100644 --- a/src/chown/chown.rs +++ b/src/chown/chown.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_chown"] - // This file is part of the uutils coreutils package. // // (c) Jian Zeng @@ -7,14 +6,13 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // - -#![cfg_attr(feature="clippy", feature(plugin))] -#![cfg_attr(feature="clippy", plugin(clippy))] +#![cfg_attr(feature = "clippy", feature(plugin))] +#![cfg_attr(feature = "clippy", plugin(clippy))] #[macro_use] extern crate uucore; -use uucore::libc::{self, uid_t, gid_t, lchown}; -pub use uucore::entries::{self, Locate, Passwd, Group}; +use uucore::libc::{self, gid_t, lchown, uid_t}; +pub use uucore::entries::{self, Group, Locate, Passwd}; use uucore::fs::resolve_relative_path; extern crate walkdir; @@ -32,7 +30,8 @@ use std::convert::AsRef; use std::ffi::CString; use std::os::unix::ffi::OsStrExt; -static SYNTAX: &'static str = "[OPTION]... [OWNER][:[GROUP]] FILE...\n chown [OPTION]... --reference=RFILE FILE..."; +static SYNTAX: &'static str = + "[OPTION]... [OWNER][:[GROUP]] FILE...\n chown [OPTION]... --reference=RFILE FILE..."; static SUMMARY: &'static str = "change file owner and group"; const FTS_COMFOLLOW: u8 = 1; @@ -193,26 +192,32 @@ fn parse_spec(spec: &str) -> Result<(Option, Option), String> { let usr_grp = args.len() == 2 && !args[0].is_empty() && !args[1].is_empty(); if usr_only { - Ok((Some(match Passwd::locate(args[0]) { - Ok(v) => v.uid(), - _ => return Err(format!("invalid user: ‘{}’", spec)), - }), - None)) + Ok(( + Some(match Passwd::locate(args[0]) { + Ok(v) => v.uid(), + _ => return Err(format!("invalid user: ‘{}’", spec)), + }), + None, + )) } else if grp_only { - Ok((None, + Ok(( + None, Some(match Group::locate(args[1]) { - Ok(v) => v.gid(), - _ => return Err(format!("invalid group: ‘{}’", spec)), - }))) + Ok(v) => v.gid(), + _ => return Err(format!("invalid group: ‘{}’", spec)), + }), + )) } else if usr_grp { - Ok((Some(match Passwd::locate(args[0]) { - Ok(v) => v.uid(), - _ => return Err(format!("invalid user: ‘{}’", spec)), - }), + Ok(( + Some(match Passwd::locate(args[0]) { + Ok(v) => v.uid(), + _ => return Err(format!("invalid user: ‘{}’", spec)), + }), Some(match Group::locate(args[1]) { - Ok(v) => v.gid(), - _ => return Err(format!("invalid group: ‘{}’", spec)), - }))) + Ok(v) => v.gid(), + _ => return Err(format!("invalid group: ‘{}’", spec)), + }), + )) } else { Ok((None, None)) } @@ -263,7 +268,13 @@ impl Chowner { ret } - fn chown>(&self, path: P, duid: uid_t, dgid: gid_t, follow: bool) -> IOResult<()> { + fn chown>( + &self, + path: P, + duid: uid_t, + dgid: gid_t, + follow: bool, + ) -> IOResult<()> { let path = path.as_ref(); let s = CString::new(path.as_os_str().as_bytes()).unwrap(); let ret = unsafe { @@ -391,12 +402,14 @@ impl Chowner { _ => { show_info!("changing ownership of '{}': {}", path.display(), e); if self.verbosity == Verbose { - println!("failed to change ownership of {} from {}:{} to {}:{}", - path.display(), - entries::uid2usr(meta.uid()).unwrap(), - entries::gid2grp(meta.gid()).unwrap(), - entries::uid2usr(dest_uid).unwrap(), - entries::gid2grp(dest_gid).unwrap()); + println!( + "failed to change ownership of {} from {}:{} to {}:{}", + path.display(), + entries::uid2usr(meta.uid()).unwrap(), + entries::gid2grp(meta.gid()).unwrap(), + entries::uid2usr(dest_uid).unwrap(), + entries::gid2grp(dest_gid).unwrap() + ); }; } } @@ -406,20 +419,24 @@ impl Chowner { if changed { match self.verbosity { Changes | Verbose => { - println!("changed ownership of {} from {}:{} to {}:{}", - path.display(), - entries::uid2usr(meta.uid()).unwrap(), - entries::gid2grp(meta.gid()).unwrap(), - entries::uid2usr(dest_uid).unwrap(), - entries::gid2grp(dest_gid).unwrap()); + println!( + "changed ownership of {} from {}:{} to {}:{}", + path.display(), + entries::uid2usr(meta.uid()).unwrap(), + entries::gid2grp(meta.gid()).unwrap(), + entries::uid2usr(dest_uid).unwrap(), + entries::gid2grp(dest_gid).unwrap() + ); } _ => (), }; } else if self.verbosity == Verbose { - println!("ownership of {} retained as {}:{}", - path.display(), - entries::uid2usr(dest_uid).unwrap(), - entries::gid2grp(dest_gid).unwrap()); + println!( + "ownership of {} retained as {}:{}", + path.display(), + entries::uid2usr(dest_uid).unwrap(), + entries::gid2grp(dest_gid).unwrap() + ); } } ret diff --git a/src/chroot/chroot.rs b/src/chroot/chroot.rs index ddb01e280..ab4072e86 100644 --- a/src/chroot/chroot.rs +++ b/src/chroot/chroot.rs @@ -14,7 +14,7 @@ extern crate getopts; #[macro_use] extern crate uucore; -use uucore::libc::{self, setgid, setuid, chroot, setgroups}; +use uucore::libc::{self, chroot, setgid, setgroups, setuid}; use uucore::entries; use std::ffi::CString; @@ -33,18 +33,33 @@ static LONG_HELP: &'static str = " pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .optopt("u", "user", "User (ID or name) to switch before running the program", "USER") + .optopt( + "u", + "user", + "User (ID or name) to switch before running the program", + "USER", + ) .optopt("g", "group", "Group (ID or name) to switch to", "GROUP") - .optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2...") - .optopt("", "userspec", "Colon-separated user and group to switch to. \ - Same as -u USER -g GROUP. \ - Userspec has higher preference than -u and/or -g", "USER:GROUP") + .optopt( + "G", + "groups", + "Comma-separated list of groups to switch to", + "GROUP1,GROUP2...", + ) + .optopt( + "", + "userspec", + "Colon-separated user and group to switch to. \ + Same as -u USER -g GROUP. \ + Userspec has higher preference than -u and/or -g", + "USER:GROUP", + ) .parse(args); if matches.free.is_empty() { println!("Missing operand: NEWROOT"); println!("Try `{} --help` for more information.", NAME); - return 1 + return 1; } let default_shell: &'static str = "/bin/sh"; @@ -53,7 +68,11 @@ pub fn uumain(args: Vec) -> i32 { let newroot = Path::new(&matches.free[0][..]); if !newroot.is_dir() { - crash!(1, "cannot change root directory to `{}`: no such directory", newroot.display()); + crash!( + 1, + "cannot change root directory to `{}`: no such directory", + newroot.display() + ); } let command: Vec<&str> = match matches.free.len() { @@ -62,9 +81,9 @@ pub fn uumain(args: Vec) -> i32 { Err(_) => default_shell, Ok(ref s) => s.as_ref(), }; - vec!(shell, default_option) - }, - _ => matches.free[1..].iter().map(|x| &x[..]).collect() + vec![shell, default_option] + } + _ => matches.free[1..].iter().map(|x| &x[..]).collect(), }; set_context(&newroot, &matches); @@ -97,10 +116,18 @@ fn set_context(root: &Path, options: &getopts::Matches) { }; s } - None => Vec::new() + None => Vec::new(), + }; + let user = if userspec.is_empty() { + &user_str[..] + } else { + &userspec[0][..] + }; + let group = if userspec.is_empty() { + &group_str[..] + } else { + &userspec[1][..] }; - let user = if userspec.is_empty() { &user_str[..] } else { &userspec[0][..] }; - let group = if userspec.is_empty() { &group_str[..] } else { &userspec[1][..] }; enter_chroot(root); @@ -113,10 +140,18 @@ fn enter_chroot(root: &Path) { let root_str = root.display(); std::env::set_current_dir(root).unwrap(); let err = unsafe { - chroot(CString::new(".".as_bytes()).unwrap().as_bytes_with_nul().as_ptr() as *const libc::c_char) + chroot(CString::new(".".as_bytes()) + .unwrap() + .as_bytes_with_nul() + .as_ptr() as *const libc::c_char) }; if err != 0 { - crash!(1, "cannot chroot to {}: {}", root_str, Error::last_os_error()) + crash!( + 1, + "cannot chroot to {}: {}", + root_str, + Error::last_os_error() + ) }; } @@ -128,36 +163,33 @@ fn set_main_group(group: &str) { }; let err = unsafe { setgid(group_id) }; if err != 0 { - crash!(1, "cannot set gid to {}: {}", group_id, Error::last_os_error()) + crash!( + 1, + "cannot set gid to {}: {}", + group_id, + Error::last_os_error() + ) } } } #[cfg(any(target_os = "macos", target_os = "freebsd"))] fn set_groups(groups: Vec) -> 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()) } } #[cfg(target_os = "linux")] fn set_groups(groups: Vec) -> libc::c_int { - unsafe { - setgroups(groups.len() as libc::size_t, - groups.as_ptr()) - } + unsafe { setgroups(groups.len() as libc::size_t, groups.as_ptr()) } } fn set_groups_from_str(groups: &str) { if !groups.is_empty() { - let groups_vec: Vec = FromIterator::from_iter( - groups.split(',').map( - |x| match entries::grp2gid(x) { - Ok(g) => g, - _ => crash!(1, "no such group: {}", x), - }) - ); + let groups_vec: Vec = + FromIterator::from_iter(groups.split(',').map(|x| match entries::grp2gid(x) { + Ok(g) => g, + _ => crash!(1, "no such group: {}", x), + })); let err = set_groups(groups_vec); if err != 0 { crash!(1, "cannot set groups: {}", Error::last_os_error()) diff --git a/src/cksum/build.rs b/src/cksum/build.rs index 3819d74c8..98736424d 100644 --- a/src/cksum/build.rs +++ b/src/cksum/build.rs @@ -28,7 +28,11 @@ fn main() { table.push(crc_entry(num as u8) as u32); } let file = File::create(&Path::new(&out_dir).join("crc_table.rs")).unwrap(); - write!(&file, "const CRC_TABLE: [u32; {}] = {:?};", CRC_TABLE_LEN, table).unwrap(); + write!( + &file, + "const CRC_TABLE: [u32; {}] = {:?};", + CRC_TABLE_LEN, table + ).unwrap(); } #[inline] diff --git a/src/cksum/cksum.rs b/src/cksum/cksum.rs index dd49f6fa8..cfb4ca955 100644 --- a/src/cksum/cksum.rs +++ b/src/cksum/cksum.rs @@ -9,12 +9,11 @@ * file that was distributed with this source code. */ - #[macro_use] extern crate uucore; use std::fs::File; -use std::io::{self, stdin, Read, BufReader}; +use std::io::{self, stdin, BufReader, Read}; #[cfg(not(windows))] use std::mem; use std::path::Path; @@ -46,7 +45,7 @@ fn init_byte_array() -> Vec { } #[cfg(not(windows))] -fn init_byte_array() -> [u8; 1024*1024] { +fn init_byte_array() -> [u8; 1024 * 1024] { unsafe { mem::uninitialized() } } @@ -56,10 +55,8 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> { let mut size = 0usize; let file; - let mut rd : Box = match fname { - "-" => { - Box::new(stdin()) - } + let mut rd: Box = match fname { + "-" => Box::new(stdin()), _ => { file = try!(File::open(&Path::new(fname))); Box::new(BufReader::new(file)) @@ -78,15 +75,14 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> { } size += num_bytes; } - Err(err) => return Err(err) + Err(err) => return Err(err), } } //Ok((0 as u32,0 as usize)) } pub fn uumain(args: Vec) -> i32 { - let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .parse(args); + let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP).parse(args); let files = matches.free; diff --git a/src/comm/comm.rs b/src/comm/comm.rs index 98f5b742b..139c3d79a 100644 --- a/src/comm/comm.rs +++ b/src/comm/comm.rs @@ -16,12 +16,12 @@ extern crate uucore; use std::cmp::Ordering; use std::fs::File; -use std::io::{self, BufRead, BufReader, stdin, Stdin}; +use std::io::{self, stdin, BufRead, BufReader, Stdin}; use std::path::Path; -static SYNTAX: &'static str = "[OPTIONS] FILE1 FILE2"; -static SUMMARY: &'static str = "Compare sorted files line by line"; -static LONG_HELP: &'static str = ""; +static SYNTAX: &'static str = "[OPTIONS] FILE1 FILE2"; +static SUMMARY: &'static str = "Compare sorted files line by line"; +static LONG_HELP: &'static str = ""; fn mkdelim(col: usize, opts: &getopts::Matches) -> String { let mut s = String::new(); @@ -43,27 +43,26 @@ fn mkdelim(col: usize, opts: &getopts::Matches) -> String { fn ensure_nl(line: &mut String) { match line.chars().last() { Some('\n') => (), - _ => line.push_str("\n") + _ => line.push_str("\n"), } } enum LineReader { Stdin(Stdin), - FileIn(BufReader) + FileIn(BufReader), } impl LineReader { fn read_line(&mut self, buf: &mut String) -> io::Result { match *self { - LineReader::Stdin(ref mut r) => r.read_line(buf), + LineReader::Stdin(ref mut r) => r.read_line(buf), LineReader::FileIn(ref mut r) => r.read_line(buf), } } } fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { - - let delim : Vec = (0 .. 4).map(|col| mkdelim(col, opts)).collect(); + let delim: Vec = (0..4).map(|col| mkdelim(col, opts)).collect(); let ra = &mut String::new(); let mut na = a.read_line(ra); @@ -72,13 +71,13 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { while na.is_ok() || nb.is_ok() { let ord = match (na.is_ok(), nb.is_ok()) { - (false, true) => Ordering::Greater, - (true , false) => Ordering::Less, - (true , true) => match(&na, &nb) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + (true, true) => match (&na, &nb) { (&Ok(0), &Ok(0)) => break, (&Ok(0), _) => Ordering::Greater, (_, &Ok(0)) => Ordering::Less, - _ => ra.cmp(&rb), + _ => ra.cmp(&rb), }, _ => unreachable!(), }; @@ -91,7 +90,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { } ra.clear(); na = a.read_line(ra); - }, + } Ordering::Greater => { if !opts.opt_present("2") { ensure_nl(rb); @@ -99,7 +98,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { } rb.clear(); nb = b.read_line(rb); - }, + } Ordering::Equal => { if !opts.opt_present("3") { ensure_nl(ra); @@ -117,7 +116,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) { fn open_file(name: &str) -> io::Result { match name { "-" => Ok(LineReader::Stdin(stdin())), - _ => { + _ => { let f = try!(File::open(&Path::new(name))); Ok(LineReader::FileIn(BufReader::new(f))) } @@ -128,7 +127,11 @@ pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("1", "", "suppress column 1 (lines uniq to FILE1)") .optflag("2", "", "suppress column 2 (lines uniq to FILE2)") - .optflag("3", "", "suppress column 3 (lines that appear in both files)") + .optflag( + "3", + "", + "suppress column 3 (lines that appear in both files)", + ) .optopt("", "output-delimiter", "separate columns with STR", "STR") .parse(args); diff --git a/src/cp/cp.rs b/src/cp/cp.rs index a1a4aa77c..d8147f6ba 100644 --- a/src/cp/cp.rs +++ b/src/cp/cp.rs @@ -10,14 +10,17 @@ * that was distributed with this source code. */ -extern crate libc; extern crate clap; -extern crate walkdir; extern crate filetime; #[cfg(target_os = "linux")] -#[macro_use] extern crate ioctl_sys; -#[macro_use] extern crate uucore; -#[macro_use] extern crate quick_error; +#[macro_use] +extern crate ioctl_sys; +extern crate libc; +#[macro_use] +extern crate quick_error; +#[macro_use] +extern crate uucore; +extern crate walkdir; #[cfg(unix)] extern crate xattr; @@ -35,24 +38,28 @@ extern crate winapi; use std::mem; use std::ffi::CString; -use clap::{Arg, App, ArgMatches}; +use clap::{App, Arg, ArgMatches}; use quick_error::ResultExt; use std::collections::HashSet; use std::fs; -use std::io::{BufReader, BufRead, stdin, stdout, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, Write}; use std::io; use std::path::{Path, PathBuf, StripPrefixError}; use std::str::FromStr; use uucore::fs::{canonicalize, CanonicalizeMode}; use walkdir::WalkDir; -#[cfg(target_os = "linux")] use std::os::unix::io::IntoRawFd; -#[cfg(target_os = "linux")] use std::fs::File; +#[cfg(target_os = "linux")] +use std::os::unix::io::IntoRawFd; +#[cfg(target_os = "linux")] +use std::fs::File; use std::fs::OpenOptions; use filetime::FileTime; -#[cfg(unix)] use std::os::unix::fs::PermissionsExt; +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; -#[cfg(target_os = "linux")] ioctl!(write ficlone with 0x94, 9; std::os::raw::c_int); +#[cfg(target_os = "linux")] +ioctl!(write ficlone with 0x94, 9; std::os::raw::c_int); quick_error! { #[derive(Debug)] @@ -97,7 +104,6 @@ quick_error! { } } - /// Continue next iteration of loop if result of expression is error macro_rules! or_continue( ($expr:expr) => (match $expr { @@ -109,7 +115,6 @@ macro_rules! or_continue( }) ); - /// Prompts the user yes/no and returns `true` they if successfully /// answered yes. macro_rules! prompt_yes( @@ -133,7 +138,7 @@ pub type Source = PathBuf; pub type Target = PathBuf; /// Specifies whether when overwrite files -#[derive (Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub enum ClobberMode { Force, RemoveDestination, @@ -141,7 +146,7 @@ pub enum ClobberMode { } /// Specifies whether when overwrite files -#[derive (Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub enum OverwriteMode { /// [Default] Always overwrite existing files Clobber(ClobberMode), @@ -151,9 +156,11 @@ pub enum OverwriteMode { NoClobber, } -#[derive (Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub enum ReflinkMode { - Always, Auto, Never + Always, + Auto, + Never, } /// Specifies the expected file type of copy target @@ -176,12 +183,13 @@ pub enum CopyMode { Sparse, Copy, Update, - AttrOnly + AttrOnly, } #[derive(Clone, Eq, PartialEq)] pub enum Attribute { - #[cfg(unix)] Mode, + #[cfg(unix)] + Mode, Ownership, Timestamps, Context, @@ -222,59 +230,76 @@ fn print_version() { } fn get_usage() -> String { - format!("{0} [OPTION]... [-T] SOURCE DEST + format!( + "{0} [OPTION]... [-T] SOURCE DEST {0} [OPTION]... SOURCE... DIRECTORY - {0} [OPTION]... -t DIRECTORY SOURCE...", executable!()) + {0} [OPTION]... -t DIRECTORY SOURCE...", + executable!() + ) } - // Argument constants -static OPT_ARCHIVE: &str = "archive"; -static OPT_ATTRIBUTES_ONLY: &str = "attributes-only"; -static OPT_BACKUP: &str = "backup"; -static OPT_CLI_SYMBOLIC_LINKS: &str = "cli-symbolic-links"; -static OPT_CONTEXT: &str = "context"; -static OPT_COPY_CONTENTS: &str = "copy-contents"; -static OPT_DEREFERENCE: &str = "dereference"; -static OPT_FORCE: &str = "force"; -static OPT_INTERACTIVE: &str = "interactive"; -static OPT_LINK: &str = "link"; -static OPT_NO_CLOBBER: &str = "no-clobber"; -static OPT_NO_DEREFERENCE: &str = "no-dereference"; +static OPT_ARCHIVE: &str = "archive"; +static OPT_ATTRIBUTES_ONLY: &str = "attributes-only"; +static OPT_BACKUP: &str = "backup"; +static OPT_CLI_SYMBOLIC_LINKS: &str = "cli-symbolic-links"; +static OPT_CONTEXT: &str = "context"; +static OPT_COPY_CONTENTS: &str = "copy-contents"; +static OPT_DEREFERENCE: &str = "dereference"; +static OPT_FORCE: &str = "force"; +static OPT_INTERACTIVE: &str = "interactive"; +static OPT_LINK: &str = "link"; +static OPT_NO_CLOBBER: &str = "no-clobber"; +static OPT_NO_DEREFERENCE: &str = "no-dereference"; static OPT_NO_DEREFERENCE_PRESERVE_LINKS: &str = "no-dereference-preserve-linkgs"; -static OPT_NO_PRESERVE: &str = "no-preserve"; -static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory"; -static OPT_ONE_FILE_SYSTEM: &str = "one-file-system"; -static OPT_PARENTS: &str = "parents"; -static OPT_PATHS: &str = "paths"; -static OPT_PRESERVE: &str = "preserve"; -static OPT_PRESERVE_DEFAULT_ATTRIBUTES: &str = "preserve-default-attributes"; -static OPT_RECURSIVE: &str = "recursive"; -static OPT_RECURSIVE_ALIAS: &str = "recursive_alias"; -static OPT_REFLINK: &str = "reflink"; -static OPT_REMOVE_DESTINATION: &str = "remove-destination"; -static OPT_SPARSE: &str = "sparse"; -static OPT_STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes"; -static OPT_SUFFIX: &str = "suffix"; -static OPT_SYMBOLIC_LINK: &str = "symbolic-link"; -static OPT_TARGET_DIRECTORY: &str = "target-directory"; -static OPT_UPDATE: &str = "update"; -static OPT_VERBOSE: &str = "verbose"; -static OPT_VERSION: &str = "version"; +static OPT_NO_PRESERVE: &str = "no-preserve"; +static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory"; +static OPT_ONE_FILE_SYSTEM: &str = "one-file-system"; +static OPT_PARENTS: &str = "parents"; +static OPT_PATHS: &str = "paths"; +static OPT_PRESERVE: &str = "preserve"; +static OPT_PRESERVE_DEFAULT_ATTRIBUTES: &str = "preserve-default-attributes"; +static OPT_RECURSIVE: &str = "recursive"; +static OPT_RECURSIVE_ALIAS: &str = "recursive_alias"; +static OPT_REFLINK: &str = "reflink"; +static OPT_REMOVE_DESTINATION: &str = "remove-destination"; +static OPT_SPARSE: &str = "sparse"; +static OPT_STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes"; +static OPT_SUFFIX: &str = "suffix"; +static OPT_SYMBOLIC_LINK: &str = "symbolic-link"; +static OPT_TARGET_DIRECTORY: &str = "target-directory"; +static OPT_UPDATE: &str = "update"; +static OPT_VERBOSE: &str = "verbose"; +static OPT_VERSION: &str = "version"; #[cfg(unix)] -static PRESERVABLE_ATTRIBUTES: &[&str] = &["mode", "ownership", "timestamps", "context", "links", "xattr", "all"]; +static PRESERVABLE_ATTRIBUTES: &[&str] = &[ + "mode", + "ownership", + "timestamps", + "context", + "links", + "xattr", + "all", +]; #[cfg(not(unix))] -static PRESERVABLE_ATTRIBUTES: &[&str] = &["ownership", "timestamps", "context", "links", "xattr", "all"]; +static PRESERVABLE_ATTRIBUTES: &[&str] = &[ + "ownership", + "timestamps", + "context", + "links", + "xattr", + "all", +]; static DEFAULT_ATTRIBUTES: &[Attribute] = &[ - #[cfg(unix)] Attribute::Mode, + #[cfg(unix)] + Attribute::Mode, Attribute::Ownership, Attribute::Timestamps, ]; - pub fn uumain(args: Vec) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) @@ -446,7 +471,8 @@ pub fn uumain(args: Vec) -> i32 { } let options = crash_if_err!(EXIT_ERR, Options::from_matches(&matches)); - let paths: Vec = matches.values_of("paths") + let paths: Vec = matches + .values_of("paths") .map(|v| v.map(|p| p.to_string()).collect()) .unwrap_or_default(); @@ -513,20 +539,26 @@ impl FromStr for Attribute { fn from_str(value: &str) -> CopyResult { Ok(match &*value.to_lowercase() { - #[cfg(unix)] "mode" => Attribute::Mode, + #[cfg(unix)] + "mode" => Attribute::Mode, "ownership" => Attribute::Ownership, "timestamps" => Attribute::Timestamps, "context" => Attribute::Context, "links" => Attribute::Links, "xattr" => Attribute::Xattr, - _ => return Err(Error::InvalidArgument(format!("invalid attribute '{}'", value))) + _ => { + return Err(Error::InvalidArgument(format!( + "invalid attribute '{}'", + value + ))) + } }) } } impl Options { fn from_matches(matches: &ArgMatches) -> CopyResult { - let not_implemented_opts = vec![ + let not_implemented_opts = vec![ OPT_ARCHIVE, OPT_COPY_CONTENTS, OPT_NO_DEREFERENCE_PRESERVE_LINKS, @@ -537,25 +569,26 @@ impl Options { OPT_STRIP_TRAILING_SLASHES, OPT_ONE_FILE_SYSTEM, OPT_CONTEXT, - #[cfg(windows)] OPT_FORCE, + #[cfg(windows)] + OPT_FORCE, ]; for not_implemented_opt in not_implemented_opts { if matches.is_present(not_implemented_opt) { - return Err(Error::NotImplemented(not_implemented_opt.to_string())) + return Err(Error::NotImplemented(not_implemented_opt.to_string())); } } - let recursive = matches.is_present(OPT_RECURSIVE) - || matches.is_present(OPT_RECURSIVE_ALIAS) + let recursive = matches.is_present(OPT_RECURSIVE) || matches.is_present(OPT_RECURSIVE_ALIAS) || matches.is_present(OPT_ARCHIVE); - let backup = matches.is_present(OPT_BACKUP) - || matches.is_present(OPT_SUFFIX); + let backup = matches.is_present(OPT_BACKUP) || matches.is_present(OPT_SUFFIX); // Parse target directory options let no_target_dir = matches.is_present(OPT_NO_TARGET_DIRECTORY); - let target_dir = matches.value_of(OPT_TARGET_DIRECTORY).map(|v| v.to_string()); + let target_dir = matches + .value_of(OPT_TARGET_DIRECTORY) + .map(|v| v.to_string()); // Parse attributes to preserve let preserve_attributes: Vec = if matches.is_present(OPT_PRESERVE) { @@ -565,14 +598,14 @@ impl Options { let mut attributes = Vec::new(); for attribute_str in attribute_strs { if attribute_str == "all" { - #[cfg(unix)] - attributes.push(Attribute::Mode); - attributes.push(Attribute::Ownership); - attributes.push(Attribute::Timestamps); - attributes.push(Attribute::Context); - attributes.push(Attribute::Xattr); - attributes.push(Attribute::Links); - break; + #[cfg(unix)] + attributes.push(Attribute::Mode); + attributes.push(Attribute::Ownership); + attributes.push(Attribute::Timestamps); + attributes.push(Attribute::Context); + attributes.push(Attribute::Xattr); + attributes.push(Attribute::Links); + break; } else { attributes.push(Attribute::from_str(attribute_str)?); } @@ -601,14 +634,13 @@ impl Options { reflink_mode: { if let Some(reflink) = matches.value_of(OPT_REFLINK) { match reflink { - "always" => { - ReflinkMode::Always - }, - "auto" => { - ReflinkMode::Auto - }, + "always" => ReflinkMode::Always, + "auto" => ReflinkMode::Auto, value => { - return Err(Error::InvalidArgument(format!("invalid argument '{}' for \'reflink\'", value))) + return Err(Error::InvalidArgument(format!( + "invalid argument '{}' for \'reflink\'", + value + ))) } } } else { @@ -640,7 +672,6 @@ impl TargetType { } } - /// Returns tuple of (Source paths, Target) fn parse_path_args(path_args: &[String], options: &Options) -> CopyResult<(Vec, Target)> { let mut paths = path_args.iter().map(PathBuf::from).collect::>(); @@ -673,51 +704,66 @@ fn parse_path_args(path_args: &[String], options: &Options) -> CopyResult<(Vec, source: &std::path::PathBuf, dest: std::path::PathBuf, found_hard_link: &mut bool) -> CopyResult<()> { +fn preserve_hardlinks( + hard_links: &mut Vec<(String, u64)>, + source: &std::path::PathBuf, + dest: std::path::PathBuf, + found_hard_link: &mut bool, +) -> CopyResult<()> { // Redox does not currently support hard links #[cfg(not(target_os = "redox"))] { - if !source.is_dir() { - unsafe { - let src_path = CString::new(source.as_os_str().to_str().unwrap()).unwrap(); - let inode: u64; - let nlinks: u64; - #[cfg(unix)] - { - let mut stat = mem::zeroed(); - if libc::lstat(src_path.as_ptr(), &mut stat) < 0 { - return Err(format!("cannot stat {:?}: {}", src_path, std::io::Error::last_os_error()).into()); + if !source.is_dir() { + unsafe { + let src_path = CString::new(source.as_os_str().to_str().unwrap()).unwrap(); + let inode: u64; + let nlinks: u64; + #[cfg(unix)] + { + let mut stat = mem::zeroed(); + if libc::lstat(src_path.as_ptr(), &mut stat) < 0 { + return Err(format!( + "cannot stat {:?}: {}", + src_path, + std::io::Error::last_os_error() + ).into()); + } + inode = stat.st_ino as u64; + nlinks = stat.st_nlink as u64; } - inode = stat.st_ino as u64; - nlinks = stat.st_nlink as u64; - } - #[cfg(windows)] - { - let mut stat = mem::uninitialized(); - let handle = CreateFile2(src_path.as_ptr() as *const u16, - winapi::um::winnt::GENERIC_READ, - winapi::um::winnt::FILE_SHARE_READ, - 0, - std::ptr::null_mut()); - if GetFileInformationByHandle(handle, stat) != 0 { - return Err(format!("cannot get file information {:?}: {}", source, std::io::Error::last_os_error()).into()); + #[cfg(windows)] + { + let mut stat = mem::uninitialized(); + let handle = CreateFile2( + src_path.as_ptr() as *const u16, + winapi::um::winnt::GENERIC_READ, + winapi::um::winnt::FILE_SHARE_READ, + 0, + std::ptr::null_mut(), + ); + if GetFileInformationByHandle(handle, stat) != 0 { + return Err(format!( + "cannot get file information {:?}: {}", + source, + std::io::Error::last_os_error() + ).into()); + } + inode = (((*stat).nFileIndexHigh as u64) << 32 | (*stat).nFileIndexLow as u64); + nlinks = (*stat).nNumberOfLinks as u64; } - inode = (((*stat).nFileIndexHigh as u64) << 32 | (*stat).nFileIndexLow as u64); - nlinks = (*stat).nNumberOfLinks as u64; - } - for hard_link in hard_links.iter() { - if hard_link.1 == inode { - std::fs::hard_link(hard_link.0.clone(), dest.clone()).unwrap(); - *found_hard_link = true; + for hard_link in hard_links.iter() { + if hard_link.1 == inode { + std::fs::hard_link(hard_link.0.clone(), dest.clone()).unwrap(); + *found_hard_link = true; + } + } + if !(*found_hard_link) && nlinks > 1 { + hard_links.push((dest.clone().to_str().unwrap().to_string(), inode)); } - } - if !(*found_hard_link) && nlinks > 1 { - hard_links.push((dest.clone().to_str().unwrap().to_string(), inode)); } } } - } Ok(()) } @@ -749,9 +795,9 @@ fn copy(sources: &[Source], target: &Target, options: &Options) -> CopyResult<() } else { let mut found_hard_link = false; if preserve_hard_links { - let dest = construct_dest_path(source, target, &target_type, options)?; - preserve_hardlinks(&mut hard_links, source, dest, &mut found_hard_link).unwrap(); - } + let dest = construct_dest_path(source, target, &target_type, options)?; + preserve_hardlinks(&mut hard_links, source, dest, &mut found_hard_link).unwrap(); + } if !found_hard_link { if let Err(error) = copy_source(source, target, &target_type, options) { show_error!("{}", error); @@ -767,30 +813,38 @@ fn copy(sources: &[Source], target: &Target, options: &Options) -> CopyResult<() if non_fatal_errors { Err(Error::NotAllFilesCopied) } else { - Ok(()) + Ok(()) } } - -fn construct_dest_path(source_path: &Path, target: &Target, target_type: &TargetType, options: &Options) - -> CopyResult -{ +fn construct_dest_path( + source_path: &Path, + target: &Target, + target_type: &TargetType, + options: &Options, +) -> CopyResult { if options.no_target_dir && target.is_dir() { - return Err(format!("cannot overwrite directory '{}' with non-directory", target.display()).into()) + return Err(format!( + "cannot overwrite directory '{}' with non-directory", + target.display() + ).into()); } Ok(match *target_type { TargetType::Directory => { let root = source_path.parent().unwrap_or(source_path); localize_to_target(root, source_path, target)? - }, + } TargetType::File => target.to_path_buf(), }) } -fn copy_source(source: &Source, target: &Target, target_type: &TargetType, options: &Options) - -> CopyResult<()> -{ +fn copy_source( + source: &Source, + target: &Target, + target_type: &TargetType, + options: &Options, +) -> CopyResult<()> { let source_path = Path::new(&source); if source_path.is_dir() { // Copy as directory @@ -802,7 +856,6 @@ fn copy_source(source: &Source, target: &Target, target_type: &TargetType, optio } } - /// Read the contents of the directory `root` and recursively copy the /// contents to `target`. /// @@ -823,12 +876,12 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult #[cfg(unix)] let mut hard_links: Vec<(String, u64)> = vec![]; - let mut preserve_hard_links = false; - for attribute in &options.preserve_attributes { - if *attribute == Attribute::Links { - preserve_hard_links = true; - } + let mut preserve_hard_links = false; + for attribute in &options.preserve_attributes { + if *attribute == Attribute::Links { + preserve_hard_links = true; } + } // This should be changed once Redox supports hardlinks #[cfg(any(windows, target_os = "redox"))] @@ -838,7 +891,7 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult let path = or_continue!(or_continue!(path).path().canonicalize()); let local_to_root_parent = match root_parent { Some(parent) => or_continue!(path.strip_prefix(&parent)).to_path_buf(), - None => path.clone(), + None => path.clone(), }; let local_to_target = target.join(&local_to_root_parent); @@ -852,7 +905,7 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult let dest = local_to_target.as_path().to_path_buf(); preserve_hardlinks(&mut hard_links, &source, dest, &mut found_hard_link).unwrap(); if !found_hard_link { - copy_file(path.as_path(), local_to_target.as_path(), options)?; + copy_file(path.as_path(), local_to_target.as_path(), options)?; } } else { copy_file(path.as_path(), local_to_target.as_path(), options)?; @@ -866,22 +919,26 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult impl OverwriteMode { fn verify(&self, path: &Path) -> CopyResult<()> { match *self { - OverwriteMode::NoClobber => { - Err(Error::Skipped(format!("Not overwriting {} because of option '{}'", path.display(), OPT_NO_CLOBBER))) - }, + OverwriteMode::NoClobber => Err(Error::Skipped(format!( + "Not overwriting {} because of option '{}'", + path.display(), + OPT_NO_CLOBBER + ))), OverwriteMode::Interactive(_) => { if prompt_yes!("{}: overwrite {}? ", executable!(), path.display()) { Ok(()) } else { - Err(Error::Skipped(format!("Not overwriting {} at user request", path.display()))) + Err(Error::Skipped(format!( + "Not overwriting {} at user request", + path.display() + ))) } - }, + } OverwriteMode::Clobber(_) => Ok(()), } } } - fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResult<()> { let context = &*format!("'{}' -> '{}'", source.display().to_string(), dest.display()); Ok(match *attribute { @@ -890,32 +947,36 @@ fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResu let mode = fs::metadata(source).context(context)?.permissions().mode(); let mut dest_metadata = fs::metadata(source).context(context)?.permissions(); dest_metadata.set_mode(mode); - }, + } Attribute::Ownership => { let metadata = fs::metadata(source).context(context)?; fs::set_permissions(dest, metadata.permissions()).context(context)?; - }, + } Attribute::Timestamps => { let metadata = fs::metadata(source)?; - filetime::set_file_times(Path::new(dest), FileTime::from_last_access_time(&metadata), FileTime::from_last_modification_time(&metadata))?; - }, - Attribute::Context => {}, - Attribute::Links => {}, - Attribute::Xattr => { + filetime::set_file_times( + Path::new(dest), + FileTime::from_last_access_time(&metadata), + FileTime::from_last_modification_time(&metadata), + )?; + } + Attribute::Context => {} + Attribute::Links => {} + Attribute::Xattr => { #[cfg(unix)] { - let xattrs = xattr::list(source)?; - for attr in xattrs { + let xattrs = xattr::list(source)?; + for attr in xattrs { if let Some(attr_value) = xattr::get(source, attr.clone())? { crash_if_err!(EXIT_ERR, xattr::set(dest, attr, &attr_value[..])); } - } + } } #[cfg(not(unix))] { return Err(format!("XAttrs are only supported on unix.").into()); } - }, + } }) } @@ -960,10 +1021,10 @@ fn handle_existing_dest(source: &Path, dest: &Path, options: &Options) -> CopyRe if fs::metadata(dest)?.permissions().readonly() { fs::remove_file(dest)?; } - }, + } OverwriteMode::Clobber(ClobberMode::RemoveDestination) => { fs::remove_file(dest)?; - }, + } _ => (), }; @@ -1025,7 +1086,7 @@ fn copy_file(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> { } else { copy_helper(source, dest, options)?; } - }, + } CopyMode::AttrOnly => { OpenOptions::new() .write(true) @@ -1064,9 +1125,14 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> ReflinkMode::Always => unsafe { let result = ficlone(dst_file, src_file as *const i32); if result != 0 { - return Err(format!("failed to clone {:?} from {:?}: {}", source, dest, std::io::Error::last_os_error()).into()); + return Err(format!( + "failed to clone {:?} from {:?}: {}", + source, + dest, + std::io::Error::last_os_error() + ).into()); } else { - return Ok(()) + return Ok(()); } }, ReflinkMode::Auto => unsafe { @@ -1090,14 +1156,14 @@ pub fn verify_target_type(target: &Path, target_type: &TargetType) -> CopyResult (&TargetType::Directory, false) => { Err(format!("target: '{}' is not a directory", target.display()).into()) } - (&TargetType::File, true) => { - Err(format!("cannot overwrite directory '{}' with non-directory", target.display()).into()) - } + (&TargetType::File, true) => Err(format!( + "cannot overwrite directory '{}' with non-directory", + target.display() + ).into()), _ => Ok(()), } } - /// Remove the `root` prefix from `source` and prefix it with `target` /// to create a file that is local to `target` /// # Examples @@ -1114,7 +1180,6 @@ pub fn localize_to_target(root: &Path, source: &Path, target: &Path) -> CopyResu Ok(target.join(&local_to_root)) } - pub fn paths_refer_to_same_file(p1: &Path, p2: &Path) -> io::Result { // We have to take symlinks and relative paths into account. let pathbuf1 = try!(canonicalize(p1, CanonicalizeMode::Normal)); @@ -1123,12 +1188,13 @@ pub fn paths_refer_to_same_file(p1: &Path, p2: &Path) -> io::Result { Ok(pathbuf1 == pathbuf2) } - #[test] fn test_cp_localize_to_target() { - assert!(localize_to_target( - &Path::new("a/source/"), - &Path::new("a/source/c.txt"), - &Path::new("target/") - ).unwrap() == Path::new("target/c.txt")) + assert!( + localize_to_target( + &Path::new("a/source/"), + &Path::new("a/source/c.txt"), + &Path::new("target/") + ).unwrap() == Path::new("target/c.txt") + ) } diff --git a/src/cut/buffer.rs b/src/cut/buffer.rs index 33067116f..77955171a 100644 --- a/src/cut/buffer.rs +++ b/src/cut/buffer.rs @@ -31,7 +31,10 @@ pub mod Bytes { } #[derive(Debug)] -pub struct ByteReader where R: Read { +pub struct ByteReader +where + R: Read, +{ inner: BufReader, newline_char: u8, } @@ -40,7 +43,7 @@ impl ByteReader { pub fn new(read: R, newline_char: u8) -> ByteReader { ByteReader { inner: BufReader::with_capacity(4096, read), - newline_char: newline_char + newline_char: newline_char, } } } @@ -68,15 +71,16 @@ impl ByteReader { let newline_char = self.newline_char; loop { - { // need filled_buf to go out of scope + { + // need filled_buf to go out of scope let filled_buf = match self.fill_buf() { Ok(b) => { if b.len() == 0 { - return bytes_consumed + return bytes_consumed; } else { b } - }, + } Err(e) => crash!(1, "read error: {}", e), }; @@ -123,15 +127,13 @@ impl self::Bytes::Select for ByteReader { let buf_slice = &buffer[0..bytes + 1]; match buf_slice.iter().position(|byte| *byte == newline_char) { - Some(idx) => (SRes::Newl, idx+1), + Some(idx) => (SRes::Newl, idx + 1), None => (SRes::Comp, bytes), } - }, - _ => { - match buffer.iter().position(|byte| *byte == newline_char) { - Some(idx) => (SRes::Newl, idx+1), - None => (SRes::Part, buffer.len()), - } + } + _ => match buffer.iter().position(|byte| *byte == newline_char) { + Some(idx) => (SRes::Newl, idx + 1), + None => (SRes::Part, buffer.len()), }, }; diff --git a/src/cut/cut.rs b/src/cut/cut.rs index 64315c864..d1221656d 100644 --- a/src/cut/cut.rs +++ b/src/cut/cut.rs @@ -13,7 +13,7 @@ extern crate uucore; use std::fs::File; -use std::io::{stdout, stdin, BufRead, BufReader, Read, Stdout, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, Read, Stdout, Write}; use std::path::Path; use ranges::Range; @@ -23,8 +23,10 @@ mod buffer; mod ranges; mod searcher; -static SYNTAX: &'static str = "[-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+"; -static SUMMARY: &'static str = "Prints specified byte or field columns from each line of stdin or the input files"; +static SYNTAX: &'static str = + "[-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+"; +static SUMMARY: &'static str = + "Prints specified byte or field columns from each line of stdin or the input files"; static LONG_HELP: &'static str = " Each call must specify a mode (what to use for columns), a sequence (which columns to print), and provide a data source @@ -111,7 +113,7 @@ struct Options { } struct FieldOptions { - delimiter: String, // one char long, String because of UTF8 representation + delimiter: String, // one char long, String because of UTF8 representation out_delimeter: Option, only_delimited: bool, zero_terminated: bool, @@ -135,8 +137,7 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { use buffer::Bytes::Select; use buffer::Bytes::Selected::*; - let newline_char = - if opts.zero_terminated { b'\0' } else { b'\n' }; + let newline_char = if opts.zero_terminated { b'\0' } else { b'\n' }; let mut buf_read = buffer::ByteReader::new(reader, newline_char); let mut out = stdout(); @@ -151,11 +152,11 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { match buf_read.select(low - cur_pos, None::<&mut Stdout>) { NewlineFound => { crash_if_err!(1, out.write_all(&[newline_char])); - continue 'newline + continue 'newline; } Complete(len) => { cur_pos += len; - break + break; } Partial(len) => cur_pos += len, EndOfFile => { @@ -163,7 +164,7 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { crash_if_err!(1, out.write_all(&[newline_char])); } - break 'newline + break 'newline; } } } @@ -175,7 +176,7 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { } print_delim = true; } - None => () + None => (), } // write out from low to high @@ -185,14 +186,14 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { Partial(len) => cur_pos += len, Complete(_) => { cur_pos = high + 1; - break + break; } EndOfFile => { if cur_pos != low || low == high { crash_if_err!(1, out.write_all(&[newline_char])); } - break 'newline + break 'newline; } } } @@ -205,7 +206,14 @@ fn cut_bytes(reader: R, ranges: &[Range], opts: &Options) -> i32 { 0 } -fn cut_fields_delimiter(reader: R, ranges: &[Range], delim: &str, only_delimited: bool, newline_char: u8, out_delim: &str) -> i32 { +fn cut_fields_delimiter( + reader: R, + ranges: &[Range], + delim: &str, + only_delimited: bool, + newline_char: u8, + out_delim: &str, +) -> i32 { let mut buf_in = BufReader::new(reader); let mut out = stdout(); let mut buffer = Vec::new(); @@ -218,7 +226,7 @@ fn cut_fields_delimiter(reader: R, ranges: &[Range], delim: &str, only_ if buffer.is_empty() { crash!(1, "read error: {}", e); } - }, + } _ => (), } @@ -229,21 +237,21 @@ fn cut_fields_delimiter(reader: R, ranges: &[Range], delim: &str, only_ let mut print_delim = false; if delim_search.peek().is_none() { - if ! only_delimited { + if !only_delimited { crash_if_err!(1, out.write_all(line)); if line[line.len() - 1] != newline_char { crash_if_err!(1, out.write_all(&[newline_char])); } } - continue + continue; } for &Range { low, high } in ranges.iter() { if low - fields_pos > 0 { low_idx = match delim_search.nth(low - fields_pos - 1) { Some((_, beyond_delim)) => beyond_delim, - None => break + None => break, }; } @@ -269,9 +277,9 @@ fn cut_fields_delimiter(reader: R, ranges: &[Range], delim: &str, only_ crash_if_err!(1, out.write_all(segment)); if line[line.len() - 1] == newline_char { - continue 'newline + continue 'newline; } - break + break; } } } @@ -284,14 +292,19 @@ fn cut_fields_delimiter(reader: R, ranges: &[Range], delim: &str, only_ } fn cut_fields(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32 { - let newline_char = - if opts.zero_terminated { b'\0' } else { b'\n' }; + let newline_char = if opts.zero_terminated { b'\0' } else { b'\n' }; match opts.out_delimeter { Some(ref o_delim) => { - return cut_fields_delimiter(reader, ranges, &opts.delimiter, - opts.only_delimited, newline_char, o_delim) + return cut_fields_delimiter( + reader, + ranges, + &opts.delimiter, + opts.only_delimited, + newline_char, + o_delim, + ) } - None => () + None => (), } let mut buf_in = BufReader::new(reader); @@ -306,7 +319,7 @@ fn cut_fields(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32 if buffer.is_empty() { crash!(1, "read error: {}", e); } - }, + } _ => (), } @@ -317,21 +330,21 @@ fn cut_fields(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32 let mut print_delim = false; if delim_search.peek().is_none() { - if ! opts.only_delimited { + if !opts.only_delimited { crash_if_err!(1, out.write_all(line)); if line[line.len() - 1] != newline_char { crash_if_err!(1, out.write_all(&[newline_char])); } } - continue + continue; } for &Range { low, high } in ranges.iter() { if low - fields_pos > 0 { low_idx = match delim_search.nth(low - fields_pos - 1) { Some((_, beyond_delim)) => beyond_delim, - None => break + None => break, }; } @@ -357,9 +370,9 @@ fn cut_fields(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32 crash_if_err!(1, out.write_all(segment)); if line[line.len() - 1] == newline_char { - continue 'newline + continue 'newline; } - break + break; } } } @@ -374,11 +387,15 @@ fn cut_files(mut filenames: Vec, mode: Mode) -> i32 { let mut stdin_read = false; let mut exit_code = 0; - if filenames.is_empty() { filenames.push("-".to_owned()); } + if filenames.is_empty() { + filenames.push("-".to_owned()); + } for filename in &filenames { if filename == "-" { - if stdin_read { continue } + if stdin_read { + continue; + } exit_code |= match mode { Mode::Bytes(ref ranges, ref opts) => cut_bytes(stdin(), ranges, opts), @@ -392,14 +409,14 @@ fn cut_files(mut filenames: Vec, mode: Mode) -> i32 { if !path.exists() { show_error!("{}", msg_args_nonexistent_file!(filename)); - continue + continue; } let file = match File::open(&path) { Ok(f) => f, Err(e) => { show_error!("opening '{}': {}", &filename[..], e); - continue + continue; } }; @@ -428,82 +445,110 @@ pub fn uumain(args: Vec) -> i32 { .parse(args); let complement = matches.opt_present("complement"); - let mode_parse = match (matches.opt_str("bytes"), - matches.opt_str("characters"), - matches.opt_str("fields")) { + let mode_parse = match ( + matches.opt_str("bytes"), + matches.opt_str("characters"), + matches.opt_str("fields"), + ) { (Some(byte_ranges), None, None) => { - list_to_ranges(&byte_ranges[..], complement) - .map(|ranges| Mode::Bytes(ranges, Options { out_delim: matches.opt_str("output-delimiter"), zero_terminated : matches.opt_present("zero-terminated") })) + list_to_ranges(&byte_ranges[..], complement).map(|ranges| { + Mode::Bytes( + ranges, + Options { + out_delim: matches.opt_str("output-delimiter"), + zero_terminated: matches.opt_present("zero-terminated"), + }, + ) + }) } (None, Some(char_ranges), None) => { - list_to_ranges(&char_ranges[..], complement) - .map(|ranges| Mode::Characters(ranges, Options { out_delim: matches.opt_str("output-delimiter"), zero_terminated : matches.opt_present("zero-terminated") })) + list_to_ranges(&char_ranges[..], complement).map(|ranges| { + Mode::Characters( + ranges, + Options { + out_delim: matches.opt_str("output-delimiter"), + zero_terminated: matches.opt_present("zero-terminated"), + }, + ) + }) } - (None, None, Some(field_ranges)) => { - list_to_ranges(&field_ranges[..], complement).and_then(|ranges| - { - let out_delim = match matches.opt_str("output-delimiter") { - Some(s) => { - if s.is_empty() { - Some("\0".to_owned()) - } else { - Some(s) - } - }, - None => None, - }; - - let only_delimited = matches.opt_present("only-delimited"); - let zero_terminated = matches.opt_present("zero-terminated"); - - match matches.opt_str("delimiter") { - Some(delim) => { - if delim.chars().count() > 1 { - Err(msg_opt_invalid_should_be!("empty or 1 character long", "a value 2 characters or longer", "--delimiter", "-d").to_owned()) - } else { - let delim = if delim.is_empty() { - "\0".to_owned() - } else { - delim - }; - - Ok(Mode::Fields(ranges, - FieldOptions { - delimiter: delim, - out_delimeter: out_delim, - only_delimited: only_delimited, - zero_terminated: zero_terminated - })) - } + (None, None, Some(field_ranges)) => list_to_ranges(&field_ranges[..], complement) + .and_then(|ranges| { + let out_delim = match matches.opt_str("output-delimiter") { + Some(s) => { + if s.is_empty() { + Some("\0".to_owned()) + } else { + Some(s) } - None => Ok(Mode::Fields(ranges, - FieldOptions { - delimiter: "\t".to_owned(), - out_delimeter: out_delim, - only_delimited: only_delimited, - zero_terminated: zero_terminated - })) } + None => None, + }; + + let only_delimited = matches.opt_present("only-delimited"); + let zero_terminated = matches.opt_present("zero-terminated"); + + match matches.opt_str("delimiter") { + Some(delim) => { + if delim.chars().count() > 1 { + Err(msg_opt_invalid_should_be!( + "empty or 1 character long", + "a value 2 characters or longer", + "--delimiter", + "-d" + ).to_owned()) + } else { + let delim = if delim.is_empty() { + "\0".to_owned() + } else { + delim + }; + + Ok(Mode::Fields( + ranges, + FieldOptions { + delimiter: delim, + out_delimeter: out_delim, + only_delimited: only_delimited, + zero_terminated: zero_terminated, + }, + )) + } + } + None => Ok(Mode::Fields( + ranges, + FieldOptions { + delimiter: "\t".to_owned(), + out_delimeter: out_delim, + only_delimited: only_delimited, + zero_terminated: zero_terminated, + }, + )), } - ) - } - (ref b, ref c, ref f) if b.is_some() || c.is_some() || f.is_some() => { - Err(msg_expects_no_more_than_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)").to_owned()) - } - _ => Err(msg_expects_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)").to_owned()) + }), + (ref b, ref c, ref f) if b.is_some() || c.is_some() || f.is_some() => Err( + msg_expects_no_more_than_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)") + .to_owned(), + ), + _ => Err(msg_expects_one_of!("--fields (-f)", "--chars (-c)", "--bytes (-b)").to_owned()), }; let mode_parse = match mode_parse { Err(_) => mode_parse, - Ok(mode) => { - match mode { - Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("delimiter") => - Err(msg_opt_only_usable_if!("printing a sequence of fields", "--delimiter", "-d").to_owned()), - Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("only-delimited") => - Err(msg_opt_only_usable_if!("printing a sequence of fields", "--only-delimited", "-s").to_owned()), - _ => Ok(mode), + Ok(mode) => match mode { + Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("delimiter") => Err( + msg_opt_only_usable_if!("printing a sequence of fields", "--delimiter", "-d") + .to_owned(), + ), + Mode::Bytes(_, _) | Mode::Characters(_, _) if matches.opt_present("only-delimited") => { + Err(msg_opt_only_usable_if!( + "printing a sequence of fields", + "--only-delimited", + "-s" + ).to_owned()) } - } + _ => Ok(mode), + }, }; match mode_parse { diff --git a/src/cut/ranges.rs b/src/cut/ranges.rs index 528e54959..ad8735ea9 100644 --- a/src/cut/ranges.rs +++ b/src/cut/ranges.rs @@ -9,7 +9,7 @@ use std::str::FromStr; -#[derive(PartialEq,Eq,PartialOrd,Ord,Debug)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct Range { pub low: usize, pub high: usize, @@ -30,40 +30,56 @@ impl FromStr for Range { match (parts.next(), parts.next()) { (Some(nm), None) => { if let Ok(nm) = nm.parse::() { - if nm > 0 { Ok(Range{ low: nm, high: nm}) } else { Err(field) } + if nm > 0 { + Ok(Range { low: nm, high: nm }) + } else { + Err(field) + } } else { Err(inval) } } (Some(n), Some(m)) if m.len() == 0 => { if let Ok(low) = n.parse::() { - if low > 0 { Ok(Range{ low: low, high: MAX - 1}) } else { Err(field) } + if low > 0 { + Ok(Range { + low: low, + high: MAX - 1, + }) + } else { + Err(field) + } } else { Err(inval) } } (Some(n), Some(m)) if n.len() == 0 => { if let Ok(high) = m.parse::() { - if high > 0 { Ok(Range{ low: 1, high: high}) } else { Err(field) } + if high > 0 { + Ok(Range { low: 1, high: high }) + } else { + Err(field) + } } else { Err(inval) } } - (Some(n), Some(m)) => { - match (n.parse::(), m.parse::()) { - (Ok(low), Ok(high)) => { - if low > 0 && low <= high { - Ok(Range { low: low, high: high }) - } else if low == 0 { - Err(field) - } else { - Err(order) - } - }, - _ => Err(inval), + (Some(n), Some(m)) => match (n.parse::(), m.parse::()) { + (Ok(low), Ok(high)) => { + if low > 0 && low <= high { + Ok(Range { + low: low, + high: high, + }) + } else if low == 0 { + Err(field) + } else { + Err(order) + } } - } - _ => unreachable!() + _ => Err(inval), + }, + _ => unreachable!(), } } } @@ -72,12 +88,12 @@ impl Range { pub fn from_list(list: &str) -> Result, String> { use std::cmp::max; - let mut ranges : Vec = vec!(); + let mut ranges: Vec = vec![]; for item in list.split(',') { match FromStr::from_str(item) { Ok(range_item) => ranges.push(range_item), - Err(e)=> return Err(format!("range '{}' was invalid: {}", item, e)) + Err(e) => return Err(format!("range '{}' was invalid: {}", item, e)), } } @@ -103,7 +119,10 @@ pub fn complement(ranges: &[Range]) -> Vec { let mut complements = Vec::with_capacity(ranges.len() + 1); if ranges.len() > 0 && ranges[0].low > 1 { - complements.push(Range { low: 1, high: ranges[0].low - 1 }); + complements.push(Range { + low: 1, + high: ranges[0].low - 1, + }); } let mut ranges_iter = ranges.iter().peekable(); @@ -112,20 +131,20 @@ pub fn complement(ranges: &[Range]) -> Vec { (Some(left), Some(right)) => { if left.high + 1 != right.low { complements.push(Range { - low: left.high + 1, - high: right.low - 1 - }); + low: left.high + 1, + high: right.low - 1, + }); } } (Some(last), None) => { if last.high < usize::MAX - 1 { complements.push(Range { - low: last.high + 1, - high: usize::MAX - 1 - }); + low: last.high + 1, + high: usize::MAX - 1, + }); } } - _ => break + _ => break, } } diff --git a/src/cut/searcher.rs b/src/cut/searcher.rs index 707a97f3a..e5d761551 100644 --- a/src/cut/searcher.rs +++ b/src/cut/searcher.rs @@ -11,7 +11,7 @@ pub struct Searcher<'a> { haystack: &'a [u8], needle: &'a [u8], - position: usize + position: usize, } impl<'a> Searcher<'a> { @@ -19,7 +19,7 @@ impl<'a> Searcher<'a> { Searcher { haystack: haystack, needle: needle, - position: 0 + position: 0, } } } diff --git a/src/date/date.rs b/src/date/date.rs index 369d1eaba..9e6bad796 100644 --- a/src/date/date.rs +++ b/src/date/date.rs @@ -14,7 +14,7 @@ extern crate chrono; extern crate clap; extern crate uucore; -use chrono::{DateTime, FixedOffset, Offset, Local}; +use chrono::{DateTime, FixedOffset, Local, Offset}; use chrono::offset::Utc; use std::fs::File; use std::io::{BufRead, BufReader}; @@ -108,14 +108,12 @@ impl<'a> From<&'a str> for Rfc3339Format { } pub fn uumain(args: Vec) -> i32 { - let settings = parse_cli(args); if let Some(_time) = settings.set_to { unimplemented!(); - // Probably need to use this syscall: - // https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html - + // Probably need to use this syscall: + // https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html } else { // Declare a file here because it needs to outlive the `dates` iterator. let file: File; @@ -134,8 +132,9 @@ pub fn uumain(args: Vec) -> i32 { /// Parse a `String` into a `DateTime`. /// If it fails, return a tuple of the `String` along with its `ParseError`. - fn parse_date(s: String) - -> Result, (String, chrono::format::ParseError)> { + fn parse_date( + s: String, + ) -> Result, (String, chrono::format::ParseError)> { // TODO: The GNU date command can parse a wide variety of inputs. s.parse().map_err(|e| (s, e)) } @@ -178,7 +177,6 @@ pub fn uumain(args: Vec) -> i32 { 0 } - /// Handle command line arguments. fn parse_cli(args: Vec) -> Settings { let matches = clap_app!( @@ -221,15 +219,13 @@ fn parse_cli(args: Vec) -> Settings { // (after_help: include_str!("usage.txt"))) .get_matches_from(args); - let format = if let Some(form) = matches.value_of("custom_format") { let form = form[1..].into(); Format::Custom(form) - } else if let Some(fmt) = matches.values_of("iso_8601").map(|mut iter| { - iter.next() - .unwrap_or(DATE) - .into() - }) { + } else if let Some(fmt) = matches + .values_of("iso_8601") + .map(|mut iter| iter.next().unwrap_or(DATE).into()) + { Format::Iso8601(fmt) } else if matches.is_present("rfc_2822") { Format::Rfc2822 @@ -256,27 +252,22 @@ fn parse_cli(args: Vec) -> Settings { } } - /// Return the appropriate format string for the given settings. fn make_format_string(settings: &Settings) -> &str { match settings.format { - Format::Iso8601(ref fmt) => { - match fmt { - &Iso8601Format::Date => "%F", - &Iso8601Format::Hours => "%FT%H%:z", - &Iso8601Format::Minutes => "%FT%H:%M%:z", - &Iso8601Format::Seconds => "%FT%T%:z", - &Iso8601Format::Ns => "%FT%T,%f%:z", - } - } + Format::Iso8601(ref fmt) => match fmt { + &Iso8601Format::Date => "%F", + &Iso8601Format::Hours => "%FT%H%:z", + &Iso8601Format::Minutes => "%FT%H:%M%:z", + &Iso8601Format::Seconds => "%FT%T%:z", + &Iso8601Format::Ns => "%FT%T,%f%:z", + }, Format::Rfc2822 => "%a, %d %h %Y %T %z", - Format::Rfc3339(ref fmt) => { - match fmt { - &Rfc3339Format::Date => "%F", - &Rfc3339Format::Seconds => "%F %T%:z", - &Rfc3339Format::Ns => "%F %T.%f%:z", - } - } + Format::Rfc3339(ref fmt) => match fmt { + &Rfc3339Format::Date => "%F", + &Rfc3339Format::Seconds => "%F %T%:z", + &Rfc3339Format::Ns => "%F %T.%f%:z", + }, Format::Custom(ref fmt) => fmt, Format::Default => "%c", } diff --git a/src/dircolors/dircolors.rs b/src/dircolors/dircolors.rs index 0e603bc7d..6bdc6bda3 100644 --- a/src/dircolors/dircolors.rs +++ b/src/dircolors/dircolors.rs @@ -58,27 +58,33 @@ pub fn guess_syntax() -> OutputFmt { pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("b", "sh", "output Bourne shell code to set LS_COLORS") - .optflag("", - "bourne-shell", - "output Bourne shell code to set LS_COLORS") + .optflag( + "", + "bourne-shell", + "output Bourne shell code to set LS_COLORS", + ) .optflag("c", "csh", "output C shell code to set LS_COLORS") .optflag("", "c-shell", "output C shell code to set LS_COLORS") .optflag("p", "print-database", "print the byte counts") .parse(args); - if (matches.opt_present("csh") || matches.opt_present("c-shell") || - matches.opt_present("sh") || matches.opt_present("bourne-shell")) && - matches.opt_present("print-database") { - disp_err!("the options to output dircolors' internal database and\nto select a shell \ - syntax are mutually exclusive"); + if (matches.opt_present("csh") || matches.opt_present("c-shell") || matches.opt_present("sh") + || matches.opt_present("bourne-shell")) && matches.opt_present("print-database") + { + disp_err!( + "the options to output dircolors' internal database and\nto select a shell \ + syntax are mutually exclusive" + ); return 1; } if matches.opt_present("print-database") { if !matches.free.is_empty() { - disp_err!("extra operand ‘{}’\nfile operands cannot be combined with \ - --print-database (-p)", - matches.free[0]); + disp_err!( + "extra operand ‘{}’\nfile operands cannot be combined with \ + --print-database (-p)", + matches.free[0] + ); return 1; } println!("{}", INTERNAL_DB); @@ -113,9 +119,11 @@ pub fn uumain(args: Vec) -> i32 { match File::open(matches.free[0].as_str()) { Ok(f) => { let fin = BufReader::new(f); - result = parse(fin.lines().filter_map(|l| l.ok()), - out_format, - matches.free[0].as_str()) + result = parse( + fin.lines().filter_map(|l| l.ok()), + out_format, + matches.free[0].as_str(), + ) } Err(e) => { show_info!("{}: {}", matches.free[0], e); @@ -193,8 +201,9 @@ enum ParseState { } use std::collections::HashMap; fn parse(lines: T, fmt: OutputFmt, fp: &str) -> Result - where T: IntoIterator, - T::Item: Borrow +where + T: IntoIterator, + T::Item: Borrow, { // 1440 > $(dircolors | wc -m) let mut result = String::with_capacity(1440); @@ -257,7 +266,10 @@ fn parse(lines: T, fmt: OutputFmt, fp: &str) -> Result let (key, val) = line.split_two(); if val.is_empty() { - return Err(format!("{}:{}: invalid line; missing second token", fp, num)); + return Err(format!( + "{}:{}: invalid line; missing second token", + fp, num + )); } let lower = key.to_lowercase(); diff --git a/src/dirname/dirname.rs b/src/dirname/dirname.rs index db5b2f095..e9b773ad0 100644 --- a/src/dirname/dirname.rs +++ b/src/dirname/dirname.rs @@ -14,21 +14,25 @@ extern crate uucore; use std::path::Path; -static NAME: &'static str = "dirname"; -static SYNTAX: &'static str = "[OPTION] NAME..."; -static SUMMARY: &'static str = "strip last component from file name"; +static NAME: &'static str = "dirname"; +static SYNTAX: &'static str = "[OPTION] NAME..."; +static SUMMARY: &'static str = "strip last component from file name"; static LONG_HELP: &'static str = " Output each NAME with its last non-slash component and trailing slashes removed; if NAME contains no /'s, output '.' (meaning the current directory). -"; +"; pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("z", "zero", "separate output with NUL rather than newline") .parse(args); - let separator = if matches.opt_present("zero") {"\0"} else {"\n"}; + let separator = if matches.opt_present("zero") { + "\0" + } else { + "\n" + }; if !matches.free.is_empty() { for path in &matches.free { diff --git a/src/du/du.rs b/src/du/du.rs index 1e630e9de..eda6755eb 100644 --- a/src/du/du.rs +++ b/src/du/du.rs @@ -64,26 +64,29 @@ impl Stat { nlink: metadata.nlink() as u64, created: metadata.mtime() as u64, accessed: metadata.atime() as u64, - modified: metadata.mtime() as u64 + modified: metadata.mtime() as u64, } } } // this takes `my_stat` to avoid having to stat files multiple times. // XXX: this should use the impl Trait return type when it is stabilized -fn du(mut my_stat: Stat, options: &Options, depth: usize) - -> Box> -{ - let mut stats = vec!(); - let mut futures = vec!(); +fn du(mut my_stat: Stat, options: &Options, depth: usize) -> Box> { + let mut stats = vec![]; + let mut futures = vec![]; if my_stat.is_dir { let read = match fs::read_dir(&my_stat.path) { Ok(read) => read, Err(e) => { - safe_writeln!(stderr(), "{}: cannot read directory ‘{}‘: {}", - options.program_name, my_stat.path.display(), e); - return Box::new(iter::once(my_stat)) + safe_writeln!( + stderr(), + "{}: cannot read directory ‘{}‘: {}", + options.program_name, + my_stat.path.display(), + e + ); + return Box::new(iter::once(my_stat)); } }; @@ -102,24 +105,33 @@ fn du(mut my_stat: Stat, options: &Options, depth: usize) } } - stats.extend(futures.into_iter().flat_map(|val| val).rev().filter_map(|stat| { - if !options.separate_dirs && stat.path.parent().unwrap() == my_stat.path { - my_stat.size += stat.size; - my_stat.blocks += stat.blocks; - } - if options.max_depth == None || depth < options.max_depth.unwrap() { - Some(stat) - } else { - None - } - })); + stats.extend( + futures + .into_iter() + .flat_map(|val| val) + .rev() + .filter_map(|stat| { + if !options.separate_dirs && stat.path.parent().unwrap() == my_stat.path { + my_stat.size += stat.size; + my_stat.blocks += stat.blocks; + } + if options.max_depth == None || depth < options.max_depth.unwrap() { + Some(stat) + } else { + None + } + }), + ); stats.push(my_stat); Box::new(stats.into_iter()) } pub fn uumain(args: Vec) -> i32 { - let syntax = format!("[OPTION]... [FILE]... - {0} [OPTION]... --files0-from=F", NAME); + let syntax = format!( + "[OPTION]... [FILE]... + {0} [OPTION]... --files0-from=F", + NAME + ); let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP) // In task .optflag("a", "all", " write counts for all files, not just directories") @@ -176,8 +188,8 @@ pub fn uumain(args: Vec) -> i32 { line argument; --max-depth=0 is the same as --summarize", "N") // In main .optflagopt("", "time", "show time of the last modification of any file in the - directory, or any of its subdirectories. If WORD is given, show time as WORD instead of modification time: - atime, access, use, ctime or status", "WORD") + directory, or any of its subdirectories. If WORD is given, show time as WORD instead + of modification time: atime, access, use, ctime or status", "WORD") // In main .optopt("", "time-style", "show times using style STYLE: full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'", "STYLE") @@ -207,10 +219,22 @@ pub fn uumain(args: Vec) -> i32 { separate_dirs: matches.opt_present("S"), }; - let strs = if matches.free.is_empty() {vec!("./".to_owned())} else {matches.free.clone()}; + let strs = if matches.free.is_empty() { + vec!["./".to_owned()] + } else { + matches.free.clone() + }; - let mb = if matches.opt_present("si") {1000 * 1000} else {1024 * 1024}; - let kb = if matches.opt_present("si") {1000} else {1024}; + let mb = if matches.opt_present("si") { + 1000 * 1000 + } else { + 1024 * 1024 + }; + let kb = if matches.opt_present("si") { + 1000 + } else { + 1024 + }; let block_size = match matches.opt_str("block-size") { Some(s) => { @@ -232,22 +256,30 @@ pub fn uumain(args: Vec) -> i32 { } let number = numbers.parse::().unwrap(); let multiple = match &letters[..] { - "K" => 1024u64.pow(1), "M" => 1024u64.pow(2), - "G" => 1024u64.pow(3), "T" => 1024u64.pow(4), - "P" => 1024u64.pow(5), "E" => 1024u64.pow(6), - "Z" => 1024u64.pow(7), "Y" => 1024u64.pow(8), - "KB" => 1000u64.pow(1), "MB" => 1000u64.pow(2), - "GB" => 1000u64.pow(3), "TB" => 1000u64.pow(4), - "PB" => 1000u64.pow(5), "EB" => 1000u64.pow(6), - "ZB" => 1000u64.pow(7), "YB" => 1000u64.pow(8), + "K" => 1024u64.pow(1), + "M" => 1024u64.pow(2), + "G" => 1024u64.pow(3), + "T" => 1024u64.pow(4), + "P" => 1024u64.pow(5), + "E" => 1024u64.pow(6), + "Z" => 1024u64.pow(7), + "Y" => 1024u64.pow(8), + "KB" => 1000u64.pow(1), + "MB" => 1000u64.pow(2), + "GB" => 1000u64.pow(3), + "TB" => 1000u64.pow(4), + "PB" => 1000u64.pow(5), + "EB" => 1000u64.pow(6), + "ZB" => 1000u64.pow(7), + "YB" => 1000u64.pow(8), _ => { show_error!("invalid --block-size argument '{}'", s); return 1; } }; number * multiple - }, - None => 1024 + } + None => 1024, }; let convert_size = |size: u64| -> String { @@ -269,26 +301,28 @@ pub fn uumain(args: Vec) -> i32 { }; let time_format_str = match matches.opt_str("time-style") { - Some(s) => { - match &s[..] { - "full-iso" => "%Y-%m-%d %H:%M:%S.%f %z", - "long-iso" => "%Y-%m-%d %H:%M", - "iso" => "%Y-%m-%d", - _ => { - show_error!("invalid argument '{}' for 'time style' + Some(s) => match &s[..] { + "full-iso" => "%Y-%m-%d %H:%M:%S.%f %z", + "long-iso" => "%Y-%m-%d %H:%M", + "iso" => "%Y-%m-%d", + _ => { + show_error!( + "invalid argument '{}' for 'time style' Valid arguments are: - 'full-iso' - 'long-iso' - 'iso' -Try '{} --help' for more information.", s, NAME); - return 1; - } +Try '{} --help' for more information.", + s, + NAME + ); + return 1; } }, - None => "%Y-%m-%d %H:%M" + None => "%Y-%m-%d %H:%M", }; - let line_separator = if matches.opt_present("0") {"\0"} else {"\n"}; + let line_separator = if matches.opt_present("0") { "\0" } else { "\n" }; let mut grand_total = 0; for path_str in strs.into_iter() { @@ -313,26 +347,40 @@ Try '{} --help' for more information.", s, NAME); "created" => stat.created, "modified" => stat.modified, _ => { - show_error!("invalid argument 'modified' for '--time' + show_error!( + "invalid argument 'modified' for '--time' Valid arguments are: - 'accessed', 'created', 'modified' - Try '{} --help' for more information.", NAME); + Try '{} --help' for more information.", + NAME + ); return 1; } }, - None => stat.modified + None => stat.modified, }; ((time / 1000) as i64, (time % 1000 * 1000000) as i32) }; time::at(Timespec::new(secs, nsecs)) }; - if !summarize || (summarize && index == len-1) { + if !summarize || (summarize && index == len - 1) { let time_str = tm.strftime(time_format_str).unwrap(); - print!("{}\t{}\t{}{}", convert_size(size), time_str, stat.path.display(), line_separator); + print!( + "{}\t{}\t{}{}", + convert_size(size), + time_str, + stat.path.display(), + line_separator + ); } } else { - if !summarize || (summarize && index == len-1) { - print!("{}\t{}{}", convert_size(size), stat.path.display(), line_separator); + if !summarize || (summarize && index == len - 1) { + print!( + "{}\t{}{}", + convert_size(size), + stat.path.display(), + line_separator + ); } } if options.total && index == (len - 1) { diff --git a/src/echo/echo.rs b/src/echo/echo.rs index cc39f37ac..ef6d9dae2 100644 --- a/src/echo/echo.rs +++ b/src/echo/echo.rs @@ -12,7 +12,7 @@ #[macro_use] extern crate uucore; -use std::io::{Write, stdout}; +use std::io::{stdout, Write}; use std::str::from_utf8; #[allow(dead_code)] @@ -43,13 +43,13 @@ enum Base { struct Opts { newline: bool, - escape: bool + escape: bool, } fn convert_str(string: &[u8], index: usize, base: Base) -> (char, usize) { let (max_digits, is_legal_digit): (usize, fn(u8) -> bool) = match base { - Base::B8 => (3, |c| { (c as char).is_digit(8) }), - Base::B16 => (2, |c| { (c as char).is_digit(16) }), + Base::B8 => (3, |c| (c as char).is_digit(8)), + Base::B16 => (2, |c| (c as char).is_digit(16)), }; let mut bytes = vec![]; @@ -68,10 +68,11 @@ fn convert_str(string: &[u8], index: usize, base: Base) -> (char, usize) { if bytes.is_empty() { (' ', 0) } else { - (usize::from_str_radix( - from_utf8(bytes.as_ref()).unwrap(), - base as u32 - ).unwrap() as u8 as char, bytes.len()) + ( + usize::from_str_radix(from_utf8(bytes.as_ref()).unwrap(), base as u32).unwrap() as u8 + as char, + bytes.len(), + ) } } @@ -79,7 +80,11 @@ pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, HELP) .optflag("n", "", "do not output the trailing newline") .optflag("e", "", "enable interpretation of backslash escapes") - .optflag("E", "", "disable interpretation of backslash escapes (default)") + .optflag( + "E", + "", + "disable interpretation of backslash escapes (default)", + ) .parse(args); let options = Opts { @@ -112,20 +117,15 @@ pub fn uumain(args: Vec) -> i32 { 'c' => break, 'e' => print!("\x1B"), 'f' => print!("\x0C"), - ch => { // 'x' or '0' or _ - idx = if ch == 'x' || ch == '0' { - idx + 1 - } else { - idx - }; + ch => { + // 'x' or '0' or _ + idx = if ch == 'x' || ch == '0' { idx + 1 } else { idx }; let base = if ch == 'x' { Base::B16 } else { Base::B8 }; match convert_str(string.as_bytes(), idx, base) { - (_, 0) => { - match ch { - 'x' => print!("\\x"), - '0' => print!("\0"), - _ => print!("\\{}", c), - } + (_, 0) => match ch { + 'x' => print!("\\x"), + '0' => print!("\0"), + _ => print!("\\{}", c), }, (c, num_char_used) => { print!("{}", c); diff --git a/src/env/env.rs b/src/env/env.rs index bcdcdb917..1aa8520ff 100644 --- a/src/env/env.rs +++ b/src/env/env.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_env"] - /* * This file is part of the uutils coreutils package. * @@ -10,14 +9,13 @@ */ /* last synced with: env (GNU coreutils) 8.13 */ - #![allow(non_camel_case_types)] #[macro_use] extern crate uucore; use std::env; -use std::io::{Write, stdout}; +use std::io::{stdout, Write}; use std::process::Command; static NAME: &'static str = "env"; @@ -32,7 +30,7 @@ struct options { null: bool, unsets: Vec, sets: Vec<(String, String)>, - program: Vec + program: Vec, } // print name=value env pairs on screen @@ -45,16 +43,21 @@ fn print_env(null: bool) { pub fn uumain(args: Vec) -> i32 { let mut core_opts = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP); - core_opts.optflag("i", "ignore-environment", "start with an empty environment") - .optflag("0", "null", "end each output line with a 0 byte rather than newline") + core_opts + .optflag("i", "ignore-environment", "start with an empty environment") + .optflag( + "0", + "null", + "end each output line with a 0 byte rather than newline", + ) .optopt("u", "unset", "remove variable from the environment", "NAME"); let mut opts = Box::new(options { ignore_env: false, null: false, - unsets: vec!(), - sets: vec!(), - program: vec!() + unsets: vec![], + sets: vec![], + program: vec![], }); let mut wait_cmd = false; @@ -86,8 +89,14 @@ pub fn uumain(args: Vec) -> i32 { } } else if opt.starts_with("--") { match opt.as_ref() { - "--help" => { core_opts.parse(vec![String::new(), String::from("--help")]); return 0; } - "--version" => { core_opts.parse(vec![String::new(), String::from("--version")]); return 0; } + "--help" => { + core_opts.parse(vec![String::new(), String::from("--help")]); + return 0; + } + "--version" => { + core_opts.parse(vec![String::new(), String::from("--version")]); + return 0; + } "--ignore-environment" => opts.ignore_env = true, "--null" => opts.null = true, @@ -96,7 +105,7 @@ pub fn uumain(args: Vec) -> i32 { match var { None => println!("{}: this option requires an argument: {}", NAME, opt), - Some(s) => opts.unsets.push(s.to_owned()) + Some(s) => opts.unsets.push(s.to_owned()), } } @@ -127,7 +136,7 @@ pub fn uumain(args: Vec) -> i32 { match var { None => println!("{}: this option requires an argument: {}", NAME, opt), - Some(s) => opts.unsets.push(s.to_owned()) + Some(s) => opts.unsets.push(s.to_owned()), } } _ => { @@ -183,8 +192,14 @@ pub fn uumain(args: Vec) -> i32 { let prog = opts.program[0].clone(); let args = &opts.program[1..]; match Command::new(prog).args(args).status() { - Ok(exit) => return if exit.success() { 0 } else { exit.code().unwrap() }, - Err(_) => return 1 + Ok(exit) => { + return if exit.success() { + 0 + } else { + exit.code().unwrap() + } + } + Err(_) => return 1, } } else { // no program provided diff --git a/src/expand/expand.rs b/src/expand/expand.rs index 4624b21e8..3821f4870 100644 --- a/src/expand/expand.rs +++ b/src/expand/expand.rs @@ -11,8 +11,8 @@ * file that was distributed with this source code. */ -extern crate unicode_width; extern crate getopts; +extern crate unicode_width; #[macro_use] extern crate uucore; @@ -23,9 +23,9 @@ use std::iter::repeat; use std::str::from_utf8; use unicode_width::UnicodeWidthChar; -static SYNTAX: &'static str = "[OPTION]... [FILE]..."; +static SYNTAX: &'static str = "[OPTION]... [FILE]..."; static SUMMARY: &'static 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."; static LONG_HELP: &'static str = ""; static DEFAULT_TABSTOP: usize = 8; @@ -33,18 +33,21 @@ static DEFAULT_TABSTOP: usize = 8; fn tabstops_parse(s: String) -> Vec { let words = s.split(',').collect::>(); - let nums = words.into_iter() - .map(|sn| sn.parse::() - .unwrap_or_else( - |_| crash!(1, "{}\n", "tab size contains invalid character(s)")) - ) + let nums = words + .into_iter() + .map(|sn| { + sn.parse::() + .unwrap_or_else(|_| crash!(1, "{}\n", "tab size contains invalid character(s)")) + }) .collect::>(); if nums.iter().any(|&n| n == 0) { crash!(1, "{}\n", "tab size cannot be 0"); } - if let (false, _) = nums.iter().fold((true, 0), |(acc, last), &n| (acc && last <= n, n)) { + if let (false, _) = nums.iter() + .fold((true, 0), |(acc, last), &n| (acc && last <= n, n)) + { crash!(1, "{}\n", "tab sizes must be ascending"); } @@ -62,8 +65,8 @@ struct Options { impl Options { fn new(matches: getopts::Matches) -> Options { let tabstops = match matches.opt_str("t") { - None => vec!(DEFAULT_TABSTOP), - Some(s) => tabstops_parse(s) + None => vec![DEFAULT_TABSTOP], + Some(s) => tabstops_parse(s), }; let iflag = matches.opt_present("i"); @@ -71,30 +74,53 @@ impl Options { // avoid allocations when dumping out long sequences of spaces // by precomputing the longest string of spaces we will ever need - let nspaces = tabstops.iter().scan(0, |pr,&it| { - let ret = Some(it - *pr); - *pr = it; - ret - }).max().unwrap(); // length of tabstops is guaranteed >= 1 + let nspaces = tabstops + .iter() + .scan(0, |pr, &it| { + let ret = Some(it - *pr); + *pr = it; + ret + }) + .max() + .unwrap(); // length of tabstops is guaranteed >= 1 let tspaces = repeat(' ').take(nspaces).collect(); - let files = - if matches.free.is_empty() { - vec!("-".to_owned()) - } else { - matches.free - }; + let files = if matches.free.is_empty() { + vec!["-".to_owned()] + } else { + matches.free + }; - Options { files: files, tabstops: tabstops, tspaces: tspaces, iflag: iflag, uflag: uflag } + Options { + files: files, + tabstops: tabstops, + tspaces: tspaces, + iflag: iflag, + uflag: uflag, + } } } pub fn uumain(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("i", "initial", "do not convert tabs after non blanks") - .optopt("t", "tabs", "have tabs NUMBER characters apart, not 8", "NUMBER") - .optopt("t", "tabs", "use comma separated list of explicit tab positions", "LIST") - .optflag("U", "no-utf8", "interpret input file as 8-bit ASCII rather than UTF-8") + .optopt( + "t", + "tabs", + "have tabs NUMBER characters apart, not 8", + "NUMBER", + ) + .optopt( + "t", + "tabs", + "use comma separated list of explicit tab positions", + "LIST", + ) + .optflag( + "U", + "no-utf8", + "interpret input file as 8-bit ASCII rather than UTF-8", + ) .parse(args); expand(Options::new(matches)); @@ -102,7 +128,7 @@ pub fn uumain(args: Vec) -> i32 { 0 } -fn open(path: String) -> BufReader> { +fn open(path: String) -> BufReader> { let file_buf; if path == "-" { BufReader::new(Box::new(stdin()) as Box) @@ -158,24 +184,30 @@ fn expand(options: Options) { if byte + nbytes > buf.len() { // don't overrun buffer because of invalid UTF-8 (Other, 1, 1) - } else if let Ok(t) = from_utf8(&buf[byte..byte+nbytes]) { + } else if let Ok(t) = from_utf8(&buf[byte..byte + nbytes]) { match t.chars().next() { Some('\t') => (Tab, 0, nbytes), Some('\x08') => (Backspace, 0, nbytes), Some(c) => (Other, UnicodeWidthChar::width(c).unwrap_or(0), nbytes), - None => { // no valid char at start of t, so take 1 byte + None => { + // no valid char at start of t, so take 1 byte (Other, 1, 1) - }, + } } } else { - (Other, 1, 1) // implicit assumption: non-UTF-8 char is 1 col wide + (Other, 1, 1) // implicit assumption: non-UTF-8 char is 1 col wide } } else { - (match buf[byte] { // always take exactly 1 byte in strict ASCII mode - 0x09 => Tab, - 0x08 => Backspace, - _ => Other, - }, 1, 1) + ( + match buf[byte] { + // always take exactly 1 byte in strict ASCII mode + 0x09 => Tab, + 0x08 => Backspace, + _ => Other, + }, + 1, + 1, + ) }; // figure out how many columns this char takes up @@ -189,9 +221,9 @@ fn expand(options: Options) { if init || !options.iflag { safe_unwrap!(output.write_all(&options.tspaces[..nts].as_bytes())); } else { - safe_unwrap!(output.write_all(&buf[byte..byte+nbytes])); + safe_unwrap!(output.write_all(&buf[byte..byte + nbytes])); } - }, + } _ => { col = if ctype == Other { col + cwidth @@ -207,14 +239,14 @@ fn expand(options: Options) { init = false; } - safe_unwrap!(output.write_all(&buf[byte..byte+nbytes])); - }, + safe_unwrap!(output.write_all(&buf[byte..byte + nbytes])); + } } byte += nbytes; // advance the pointer } - buf.truncate(0); // clear the buffer + buf.truncate(0); // clear the buffer } } } diff --git a/src/expr/expr.rs b/src/expr/expr.rs index b6e98a114..c1fdceb22 100644 --- a/src/expr/expr.rs +++ b/src/expr/expr.rs @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ +extern crate onig; #[macro_use] extern crate uucore; -extern crate onig; mod tokens; mod syntax_tree; @@ -20,54 +20,68 @@ static NAME: &'static str = "expr"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { - // For expr utility we do not want getopts. - // The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)` + // For expr utility we do not want getopts. + // The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)` - if maybe_handle_help_or_version( &args ) { 0 } - else { - let token_strings = args[1..].to_vec(); + if maybe_handle_help_or_version(&args) { + 0 + } else { + let token_strings = args[1..].to_vec(); - match process_expr( &token_strings ) { - Ok( expr_result ) => print_expr_ok( &expr_result ), - Err( expr_error ) => print_expr_error( &expr_error ) - } - } + match process_expr(&token_strings) { + Ok(expr_result) => print_expr_ok(&expr_result), + Err(expr_error) => print_expr_error(&expr_error), + } + } } -fn process_expr( token_strings: &Vec ) -> Result< String, String > { - let maybe_tokens = tokens::strings_to_tokens( &token_strings ); - let maybe_ast = syntax_tree::tokens_to_ast( maybe_tokens ); - evaluate_ast( maybe_ast ) +fn process_expr(token_strings: &Vec) -> Result { + let maybe_tokens = tokens::strings_to_tokens(&token_strings); + let maybe_ast = syntax_tree::tokens_to_ast(maybe_tokens); + evaluate_ast(maybe_ast) } -fn print_expr_ok( expr_result: &String ) -> i32 { - println!("{}", expr_result); - if expr_result == "0" || expr_result == "" { 1 } - else { 0 } +fn print_expr_ok(expr_result: &String) -> i32 { + println!("{}", expr_result); + if expr_result == "0" || expr_result == "" { + 1 + } else { + 0 + } } -fn print_expr_error( expr_error: &String ) -> ! { - crash!(2, "{}", expr_error) +fn print_expr_error(expr_error: &String) -> ! { + crash!(2, "{}", expr_error) } -fn evaluate_ast( maybe_ast: Result, String> ) -> Result { - if maybe_ast.is_err() { Err( maybe_ast.err().unwrap() ) } - else { maybe_ast.ok().unwrap().evaluate() } +fn evaluate_ast(maybe_ast: Result, String>) -> Result { + if maybe_ast.is_err() { + Err(maybe_ast.err().unwrap()) + } else { + maybe_ast.ok().unwrap().evaluate() + } } -fn maybe_handle_help_or_version( args: &Vec ) -> bool { - if args.len() == 2 { - if args[1] == "--help" { print_help(); true } - else if args[1] == "--version" { print_version(); true } - else { false } - } - else { false } +fn maybe_handle_help_or_version(args: &Vec) -> bool { + if args.len() == 2 { + if args[1] == "--help" { + print_help(); + true + } else if args[1] == "--version" { + print_version(); + true + } else { + false + } + } else { + false + } } fn print_help() { - //! The following is taken from GNU coreutils' "expr --help" output. - print!( -r#"Usage: expr EXPRESSION + //! The following is taken from GNU coreutils' "expr --help" output. + print!( + r#"Usage: expr EXPRESSION or: expr OPTION --help display this help and exit @@ -119,9 +133,9 @@ Environment variables: * EXPR_DEBUG_SYA_STEP=1 dump each parser step * EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree "# - ); + ); } fn print_version() { - println!("{} {}", NAME, VERSION); + println!("{} {}", NAME, VERSION); } diff --git a/src/expr/syntax_tree.rs b/src/expr/syntax_tree.rs index 904980360..f705feedd 100644 --- a/src/expr/syntax_tree.rs +++ b/src/expr/syntax_tree.rs @@ -12,170 +12,210 @@ //! * https://en.wikipedia.org/wiki/Shunting-yard_algorithm //! -use tokens::{Token}; +use tokens::Token; use onig::{Regex, RegexOptions, Syntax}; type TokenStack = Vec<(usize, Token)>; -pub type OperandsList = Vec< Box >; +pub type OperandsList = Vec>; #[derive(Debug)] pub enum ASTNode { - Leaf { token_idx: usize, value: String }, - Node { token_idx: usize, op_type: String, operands: OperandsList } + Leaf { + token_idx: usize, + value: String, + }, + Node { + token_idx: usize, + op_type: String, + operands: OperandsList, + }, } impl ASTNode { - fn debug_dump( &self ) { - self.debug_dump_impl( 1 ); + fn debug_dump(&self) { + self.debug_dump_impl(1); } - fn debug_dump_impl( &self, depth: usize ) { + fn debug_dump_impl(&self, depth: usize) { for _ in 0..depth { - print!("\t", ); + print!("\t",); } match *self { - ASTNode::Leaf{ ref token_idx, ref value } => println!("Leaf( {} ) at #{} ( evaluate -> {:?} )", value, token_idx, self.evaluate()), - ASTNode::Node{ ref token_idx, ref op_type, ref operands } => { - println!("Node( {} ) at #{} (evaluate -> {:?})", op_type, token_idx, self.evaluate()); + ASTNode::Leaf { + ref token_idx, + ref value, + } => println!( + "Leaf( {} ) at #{} ( evaluate -> {:?} )", + value, + token_idx, + self.evaluate() + ), + ASTNode::Node { + ref token_idx, + ref op_type, + ref operands, + } => { + println!( + "Node( {} ) at #{} (evaluate -> {:?})", + op_type, + token_idx, + self.evaluate() + ); for operand in operands { - operand.debug_dump_impl( depth + 1 ); + operand.debug_dump_impl(depth + 1); } } } } - fn new_node( token_idx: usize, op_type: &String, operands: OperandsList ) -> Box { - Box::new( ASTNode::Node{ - token_idx: token_idx, - op_type: op_type.clone(), - operands: operands - } ) + fn new_node(token_idx: usize, op_type: &String, operands: OperandsList) -> Box { + Box::new(ASTNode::Node { + token_idx: token_idx, + op_type: op_type.clone(), + operands: operands, + }) } - fn new_leaf( token_idx: usize, value: &String ) -> Box { - Box::new( ASTNode::Leaf{ token_idx: token_idx, value: value.clone() } ) + fn new_leaf(token_idx: usize, value: &String) -> Box { + Box::new(ASTNode::Leaf { + token_idx: token_idx, + value: value.clone(), + }) } - pub fn evaluate( &self ) -> Result { + pub fn evaluate(&self) -> Result { match *self { - ASTNode::Leaf{ ref value, .. } => Ok( value.clone() ), - ASTNode::Node{ ref op_type, .. } => - match self.operand_values() { - Err( reason ) => Err( reason ), - Ok( operand_values ) => - match op_type.as_ref() { - "+" => infix_operator_two_ints( |a: i64, b: i64| Ok( a + b ), &operand_values ), - "-" => infix_operator_two_ints( |a: i64, b: i64| Ok( a - b ), &operand_values ), - "*" => infix_operator_two_ints( |a: i64, b: i64| Ok( a * b ), &operand_values ), - "/" => infix_operator_two_ints( - |a: i64, b: i64| - if b == 0 { Err("division by zero".to_owned()) } - else { Ok( a / b ) }, - &operand_values ), - "%" => infix_operator_two_ints( - |a: i64, b: i64| - if b == 0 { Err("division by zero".to_owned()) } - else { Ok( a % b ) }, - &operand_values ), + ASTNode::Leaf { ref value, .. } => Ok(value.clone()), + ASTNode::Node { ref op_type, .. } => match self.operand_values() { + Err(reason) => Err(reason), + Ok(operand_values) => match op_type.as_ref() { + "+" => infix_operator_two_ints(|a: i64, b: i64| Ok(a + b), &operand_values), + "-" => infix_operator_two_ints(|a: i64, b: i64| Ok(a - b), &operand_values), + "*" => infix_operator_two_ints(|a: i64, b: i64| Ok(a * b), &operand_values), + "/" => infix_operator_two_ints( + |a: i64, b: i64| { + if b == 0 { + Err("division by zero".to_owned()) + } else { + Ok(a / b) + } + }, + &operand_values, + ), + "%" => infix_operator_two_ints( + |a: i64, b: i64| { + if b == 0 { + Err("division by zero".to_owned()) + } else { + Ok(a % b) + } + }, + &operand_values, + ), - "=" => infix_operator_two_ints_or_two_strings( - |a: i64, b: i64| Ok( bool_as_int(a == b) ), - |a: &String, b: &String| Ok( bool_as_string(a == b) ), - &operand_values - ), - "!=" => infix_operator_two_ints_or_two_strings( - |a: i64, b: i64| Ok( bool_as_int(a != b) ), - |a: &String, b: &String| Ok( bool_as_string(a != b) ), - &operand_values - ), - "<" => infix_operator_two_ints_or_two_strings( - |a: i64, b: i64| Ok( bool_as_int(a < b) ), - |a: &String, b: &String| Ok( bool_as_string(a < b) ), - &operand_values - ), - ">" => infix_operator_two_ints_or_two_strings( - |a: i64, b: i64| Ok( bool_as_int(a > b) ), - |a: &String, b: &String| Ok( bool_as_string(a > b) ), - &operand_values - ), - "<=" => infix_operator_two_ints_or_two_strings( - |a: i64, b: i64| Ok( bool_as_int(a <= b) ), - |a: &String, b: &String| Ok( bool_as_string(a <= b) ), - &operand_values - ), - ">=" => infix_operator_two_ints_or_two_strings( - |a: i64, b: i64| Ok( bool_as_int(a >= b) ), - |a: &String, b: &String| Ok( bool_as_string(a >= b) ), - &operand_values - ), - "|" => infix_operator_or(&operand_values), - "&" => infix_operator_and(&operand_values), - ":" | "match" => operator_match(&operand_values), - "length" => prefix_operator_length( &operand_values ), - "index" => prefix_operator_index( &operand_values ), - "substr" => prefix_operator_substr( &operand_values ), + "=" => infix_operator_two_ints_or_two_strings( + |a: i64, b: i64| Ok(bool_as_int(a == b)), + |a: &String, b: &String| Ok(bool_as_string(a == b)), + &operand_values, + ), + "!=" => infix_operator_two_ints_or_two_strings( + |a: i64, b: i64| Ok(bool_as_int(a != b)), + |a: &String, b: &String| Ok(bool_as_string(a != b)), + &operand_values, + ), + "<" => infix_operator_two_ints_or_two_strings( + |a: i64, b: i64| Ok(bool_as_int(a < b)), + |a: &String, b: &String| Ok(bool_as_string(a < b)), + &operand_values, + ), + ">" => infix_operator_two_ints_or_two_strings( + |a: i64, b: i64| Ok(bool_as_int(a > b)), + |a: &String, b: &String| Ok(bool_as_string(a > b)), + &operand_values, + ), + "<=" => infix_operator_two_ints_or_two_strings( + |a: i64, b: i64| Ok(bool_as_int(a <= b)), + |a: &String, b: &String| Ok(bool_as_string(a <= b)), + &operand_values, + ), + ">=" => infix_operator_two_ints_or_two_strings( + |a: i64, b: i64| Ok(bool_as_int(a >= b)), + |a: &String, b: &String| Ok(bool_as_string(a >= b)), + &operand_values, + ), + "|" => infix_operator_or(&operand_values), + "&" => infix_operator_and(&operand_values), + ":" | "match" => operator_match(&operand_values), + "length" => prefix_operator_length(&operand_values), + "index" => prefix_operator_index(&operand_values), + "substr" => prefix_operator_substr(&operand_values), - _ => Err(format!("operation not implemented: {}", op_type)) - } - } + _ => Err(format!("operation not implemented: {}", op_type)), + }, + }, } } - pub fn operand_values( &self ) -> Result, String> { - if let &ASTNode::Node{ ref operands, .. } = self { - let mut out = Vec::with_capacity( operands.len() ); + pub fn operand_values(&self) -> Result, String> { + if let &ASTNode::Node { ref operands, .. } = self { + let mut out = Vec::with_capacity(operands.len()); for operand in operands { match operand.evaluate() { - Ok( value ) => out.push( value ), - Err( reason ) => return Err( reason ), + Ok(value) => out.push(value), + Err(reason) => return Err(reason), } } - Ok( out ) + Ok(out) + } else { + panic!("Invoked .operand_values(&self) not with ASTNode::Node") } - else { panic!("Invoked .operand_values(&self) not with ASTNode::Node") } } } -pub fn tokens_to_ast( maybe_tokens: Result< Vec<(usize, Token)>, String > ) -> Result, String> { - if maybe_tokens.is_err() { Err( maybe_tokens.err().unwrap() ) } - else { +pub fn tokens_to_ast( + maybe_tokens: Result, String>, +) -> Result, String> { + if maybe_tokens.is_err() { + Err(maybe_tokens.err().unwrap()) + } else { let tokens = maybe_tokens.ok().unwrap(); let mut out_stack: TokenStack = Vec::new(); let mut op_stack: TokenStack = Vec::new(); for (token_idx, token) in tokens { - if let Err( reason ) = push_token_to_either_stack( token_idx, &token, &mut out_stack, &mut op_stack ) { - return Err( reason ) + if let Err(reason) = + push_token_to_either_stack(token_idx, &token, &mut out_stack, &mut op_stack) + { + return Err(reason); } } - if let Err( reason ) = move_rest_of_ops_to_out( &mut out_stack, &mut op_stack ) { - return Err( reason ) + if let Err(reason) = move_rest_of_ops_to_out(&mut out_stack, &mut op_stack) { + return Err(reason); } - assert!( op_stack.is_empty() ); + assert!(op_stack.is_empty()); - maybe_dump_rpn( &out_stack ); - let result = ast_from_rpn( &mut out_stack ); + maybe_dump_rpn(&out_stack); + let result = ast_from_rpn(&mut out_stack); if !out_stack.is_empty() { - Err( "syntax error (fist RPN token does not represent expression AST's root)".to_owned() ) - } - else { - maybe_dump_ast( &result ); + Err("syntax error (fist RPN token does not represent expression AST's root)".to_owned()) + } else { + maybe_dump_ast(&result); result } } } -fn maybe_dump_ast( result: &Result< Box, String > ) { +fn maybe_dump_ast(result: &Result, String>) { use std::env; - if let Ok( debug_var ) = env::var( "EXPR_DEBUG_AST" ) { + if let Ok(debug_var) = env::var("EXPR_DEBUG_AST") { if debug_var == "1" { println!("EXPR_DEBUG_AST"); match *result { - Ok( ref ast ) => ast.debug_dump(), - Err( ref reason ) => println!("\terr: {:?}", reason), - } + Ok(ref ast) => ast.debug_dump(), + Err(ref reason) => println!("\terr: {:?}", reason), + } } } } -fn maybe_dump_rpn( rpn: &TokenStack ) { +fn maybe_dump_rpn(rpn: &TokenStack) { use std::env; - if let Ok( debug_var ) = env::var( "EXPR_DEBUG_RPN" ) { + if let Ok(debug_var) = env::var("EXPR_DEBUG_RPN") { if debug_var == "1" { println!("EXPR_DEBUG_RPN"); for token in rpn { @@ -185,68 +225,100 @@ fn maybe_dump_rpn( rpn: &TokenStack ) { } } -fn ast_from_rpn( rpn: &mut TokenStack ) -> Result, String> { +fn ast_from_rpn(rpn: &mut TokenStack) -> Result, String> { match rpn.pop() { - None => Err( "syntax error (premature end of expression)".to_owned() ), + None => Err("syntax error (premature end of expression)".to_owned()), - Some( (token_idx, Token::Value{ value }) ) => - Ok( ASTNode::new_leaf( token_idx, &value ) ), + Some((token_idx, Token::Value { value })) => Ok(ASTNode::new_leaf(token_idx, &value)), - Some( (token_idx, Token::InfixOp{ value, .. }) ) => - maybe_ast_node( token_idx, &value, 2, rpn ), + Some((token_idx, Token::InfixOp { value, .. })) => { + maybe_ast_node(token_idx, &value, 2, rpn) + } - Some( (token_idx, Token::PrefixOp{ value, arity }) ) => - maybe_ast_node( token_idx, &value, arity, rpn ), + Some((token_idx, Token::PrefixOp { value, arity })) => { + maybe_ast_node(token_idx, &value, arity, rpn) + } - Some( (token_idx, unexpected_token) ) => - panic!("unexpected token at #{} {:?}", token_idx, unexpected_token), + Some((token_idx, unexpected_token)) => { + panic!("unexpected token at #{} {:?}", token_idx, unexpected_token) + } } } -fn maybe_ast_node( token_idx: usize, op_type: &String, arity: usize, rpn: &mut TokenStack ) -> Result< Box, String > { - let mut operands = Vec::with_capacity( arity ); +fn maybe_ast_node( + token_idx: usize, + op_type: &String, + arity: usize, + rpn: &mut TokenStack, +) -> Result, String> { + let mut operands = Vec::with_capacity(arity); for _ in 0..arity { - match ast_from_rpn( rpn ) { - Err( reason ) => return Err( reason ), - Ok( operand ) => operands.push( operand ), + match ast_from_rpn(rpn) { + Err(reason) => return Err(reason), + Ok(operand) => operands.push(operand), } } operands.reverse(); - Ok( ASTNode::new_node( token_idx, op_type, operands ) ) + Ok(ASTNode::new_node(token_idx, op_type, operands)) } -fn move_rest_of_ops_to_out( out_stack: &mut TokenStack, op_stack: &mut TokenStack ) -> Result<(), String> { +fn move_rest_of_ops_to_out( + out_stack: &mut TokenStack, + op_stack: &mut TokenStack, +) -> Result<(), String> { loop { match op_stack.pop() { - None => return Ok( () ), - Some( (token_idx, Token::ParOpen) ) => return Err( format!( "syntax error (Mismatched open-parenthesis at #{})", token_idx ) ), - Some( (token_idx, Token::ParClose) ) => return Err( format!( "syntax error (Mismatched close-parenthesis at #{})", token_idx ) ), - Some( other ) => out_stack.push( other ) + None => return Ok(()), + Some((token_idx, Token::ParOpen)) => { + return Err(format!( + "syntax error (Mismatched open-parenthesis at #{})", + token_idx + )) + } + Some((token_idx, Token::ParClose)) => { + return Err(format!( + "syntax error (Mismatched close-parenthesis at #{})", + token_idx + )) + } + Some(other) => out_stack.push(other), } } } -fn push_token_to_either_stack( token_idx: usize, token: &Token, out_stack: &mut TokenStack, op_stack: &mut TokenStack ) -> Result<(), String> { - let result = - match *token { - Token::Value{ .. } => Ok( out_stack.push( (token_idx, token.clone()) ) ), +fn push_token_to_either_stack( + token_idx: usize, + token: &Token, + out_stack: &mut TokenStack, + op_stack: &mut TokenStack, +) -> Result<(), String> { + let result = match *token { + Token::Value { .. } => Ok(out_stack.push((token_idx, token.clone()))), - Token::InfixOp{ .. } => - if op_stack.is_empty() { Ok( op_stack.push( (token_idx, token.clone()) ) ) } - else { push_op_to_stack( token_idx, token, out_stack, op_stack ) }, + Token::InfixOp { .. } => if op_stack.is_empty() { + Ok(op_stack.push((token_idx, token.clone()))) + } else { + push_op_to_stack(token_idx, token, out_stack, op_stack) + }, - Token::PrefixOp{ .. } => Ok( op_stack.push( (token_idx, token.clone()) ) ), + Token::PrefixOp { .. } => Ok(op_stack.push((token_idx, token.clone()))), - Token::ParOpen => Ok( op_stack.push( (token_idx, token.clone()) ) ), + Token::ParOpen => Ok(op_stack.push((token_idx, token.clone()))), - Token::ParClose => move_till_match_paren( out_stack, op_stack ) - }; - maybe_dump_shunting_yard_step( token_idx, token, out_stack, op_stack, &result ); + Token::ParClose => move_till_match_paren(out_stack, op_stack), + }; + maybe_dump_shunting_yard_step(token_idx, token, out_stack, op_stack, &result); result } -fn maybe_dump_shunting_yard_step( token_idx: usize, token: &Token, out_stack: &TokenStack, op_stack: &TokenStack, result: &Result<(), String> ) { +fn maybe_dump_shunting_yard_step( + token_idx: usize, + token: &Token, + out_stack: &TokenStack, + op_stack: &TokenStack, + result: &Result<(), String>, +) { use std::env; - if let Ok( debug_var ) = env::var( "EXPR_DEBUG_SYA_STEP" ) { + if let Ok(debug_var) = env::var("EXPR_DEBUG_SYA_STEP") { if debug_var == "1" { println!("EXPR_DEBUG_SYA_STEP"); println!("\t{} => {:?}", token_idx, token); @@ -257,85 +329,100 @@ fn maybe_dump_shunting_yard_step( token_idx: usize, token: &Token, out_stack: &T } } -fn push_op_to_stack( token_idx: usize, token: &Token, out_stack: &mut TokenStack, op_stack: &mut TokenStack ) -> Result<(), String> { - if let &Token::InfixOp{ precedence: prec, left_assoc: la, .. } = token { +fn push_op_to_stack( + token_idx: usize, + token: &Token, + out_stack: &mut TokenStack, + op_stack: &mut TokenStack, +) -> Result<(), String> { + if let &Token::InfixOp { + precedence: prec, + left_assoc: la, + .. + } = token + { loop { match op_stack.last() { - None => - return Ok( op_stack.push( (token_idx, token.clone()) ) ), + None => return Ok(op_stack.push((token_idx, token.clone()))), - Some( &(_, Token::ParOpen) ) => - return Ok( op_stack.push( (token_idx, token.clone()) ) ), + Some(&(_, Token::ParOpen)) => return Ok(op_stack.push((token_idx, token.clone()))), - Some( &(_, Token::InfixOp{ precedence: prev_prec, .. }) ) => - if la && prev_prec >= prec - || !la && prev_prec > prec { - out_stack.push( op_stack.pop().unwrap() ) - } - else { - return Ok( op_stack.push( (token_idx, token.clone()) ) ) + Some(&( + _, + Token::InfixOp { + precedence: prev_prec, + .. }, + )) => if la && prev_prec >= prec || !la && prev_prec > prec { + out_stack.push(op_stack.pop().unwrap()) + } else { + return Ok(op_stack.push((token_idx, token.clone()))); + }, - Some( &(_, Token::PrefixOp{ .. }) ) => - return Ok( op_stack.push( (token_idx, token.clone()) ) ), + Some(&(_, Token::PrefixOp { .. })) => { + return Ok(op_stack.push((token_idx, token.clone()))) + } - Some( _ ) => panic!("Non-operator on op_stack") + Some(_) => panic!("Non-operator on op_stack"), } } - } - else { + } else { panic!("Expected infix-op") } } -fn move_till_match_paren( out_stack: &mut TokenStack, op_stack: &mut TokenStack ) -> Result<(), String> { +fn move_till_match_paren( + out_stack: &mut TokenStack, + op_stack: &mut TokenStack, +) -> Result<(), String> { loop { match op_stack.pop() { - None => return Err( "syntax error (Mismatched close-parenthesis)".to_string() ), - Some( (_, Token::ParOpen) ) => return Ok( () ), - Some( other ) => out_stack.push( other ) + None => return Err("syntax error (Mismatched close-parenthesis)".to_string()), + Some((_, Token::ParOpen)) => return Ok(()), + Some(other) => out_stack.push(other), } } } - -fn infix_operator_two_ints( f: F, values: &Vec ) -> Result - where F : Fn( i64, i64 ) -> Result +fn infix_operator_two_ints(f: F, values: &Vec) -> Result +where + F: Fn(i64, i64) -> Result, { - assert!( values.len() == 2 ); - if let Some( left ) = values[0].parse::().ok() { - if let Some( right ) = values[1].parse::().ok() { - return match f( left, right ) { + assert!(values.len() == 2); + if let Some(left) = values[0].parse::().ok() { + if let Some(right) = values[1].parse::().ok() { + return match f(left, right) { Ok(result) => Ok(result.to_string()), Err(reason) => Err(reason), - } + }; } } - Err( "Expected an integer operand".to_string() ) + Err("Expected an integer operand".to_string()) } - -fn infix_operator_two_ints_or_two_strings( fi: FI, fs: FS, values: &Vec ) -> Result - where FI : Fn( i64, i64 ) -> Result, - FS : Fn( &String, &String ) -> Result +fn infix_operator_two_ints_or_two_strings( + fi: FI, + fs: FS, + values: &Vec, +) -> Result +where + FI: Fn(i64, i64) -> Result, + FS: Fn(&String, &String) -> Result, { - assert!( values.len() == 2 ); - if let ( Some( a_int ), Some( b_int ) ) = - ( - values[0].parse::().ok(), - values[1].parse::().ok() - ) { - match fi( a_int, b_int ) { - Ok( result ) => Ok(result.to_string()), - Err( reason ) => Err(reason) - } + assert!(values.len() == 2); + if let (Some(a_int), Some(b_int)) = + (values[0].parse::().ok(), values[1].parse::().ok()) + { + match fi(a_int, b_int) { + Ok(result) => Ok(result.to_string()), + Err(reason) => Err(reason), } - else { - fs( &values[0], &values[1] ) + } else { + fs(&values[0], &values[1]) } } -fn infix_operator_or( values: &Vec ) -> Result { +fn infix_operator_or(values: &Vec) -> Result { assert!(values.len() == 2); if value_as_bool(&values[0]) { Ok(values[0].clone()) @@ -344,7 +431,7 @@ fn infix_operator_or( values: &Vec ) -> Result { } } -fn infix_operator_and( values: &Vec ) -> Result { +fn infix_operator_and(values: &Vec) -> Result { if value_as_bool(&values[0]) && value_as_bool(&values[1]) { Ok(values[0].clone()) } else { @@ -354,30 +441,31 @@ fn infix_operator_and( values: &Vec ) -> Result { fn operator_match(values: &Vec) -> Result { assert!(values.len() == 2); - let re = match Regex::with_options(&values[1], RegexOptions::REGEX_OPTION_NONE, Syntax::grep()) { + let re = match Regex::with_options(&values[1], RegexOptions::REGEX_OPTION_NONE, Syntax::grep()) + { Ok(m) => m, - Err(err) => return Err(err.description().to_string()) + Err(err) => return Err(err.description().to_string()), }; if re.captures_len() > 0 { Ok(match re.captures(&values[0]) { Some(captures) => captures.at(1).unwrap().to_string(), - None => "".to_string() + None => "".to_string(), }) } else { Ok(match re.find(&values[0]) { Some((start, end)) => (end - start).to_string(), - None => "0".to_string() + None => "0".to_string(), }) } } -fn prefix_operator_length( values: &Vec ) -> Result { - assert!( values.len() == 1 ); - Ok( values[0].len().to_string() ) +fn prefix_operator_length(values: &Vec) -> Result { + assert!(values.len() == 1); + Ok(values[0].len().to_string()) } -fn prefix_operator_index( values: &Vec ) -> Result { - assert!( values.len() == 2 ); +fn prefix_operator_index(values: &Vec) -> Result { + assert!(values.len() == 2); let haystack = &values[0]; let needles = &values[1]; @@ -387,45 +475,61 @@ fn prefix_operator_index( values: &Vec ) -> Result { for ch_n in needles.chars() { if ch_n == ch_h { - return Ok( current_idx.to_string() ) + return Ok(current_idx.to_string()); } } } - Ok( "0".to_string() ) + Ok("0".to_string()) } -fn prefix_operator_substr( values: &Vec ) -> Result { - assert!( values.len() == 3 ); +fn prefix_operator_substr(values: &Vec) -> Result { + assert!(values.len() == 3); let subj = &values[0]; let mut idx = match values[1].parse::() { - Ok( i ) => i, - Err( _ ) => return Err( "expected integer as POS arg to 'substr'".to_string() ), + Ok(i) => i, + Err(_) => return Err("expected integer as POS arg to 'substr'".to_string()), }; let mut len = match values[2].parse::() { - Ok( i ) => i, - Err( _ ) => return Err( "expected integer as LENGTH arg to 'substr'".to_string() ), + Ok(i) => i, + Err(_) => return Err("expected integer as LENGTH arg to 'substr'".to_string()), }; - if idx <= 0 || len <= 0 { return Ok( "".to_string() ) } + if idx <= 0 || len <= 0 { + return Ok("".to_string()); + } let mut out_str = String::new(); for ch in subj.chars() { idx -= 1; if idx <= 0 { - if len <= 0 { break; } + if len <= 0 { + break; + } len -= 1; - out_str.push( ch ); + out_str.push(ch); } } - Ok( out_str ) + Ok(out_str) } -fn bool_as_int( b: bool ) -> i64 { if b { 1 } else { 0 } } -fn bool_as_string( b: bool ) -> String { if b { "1".to_string() } else { "0".to_string() } } -fn value_as_bool( s: &str ) -> bool { +fn bool_as_int(b: bool) -> i64 { + if b { + 1 + } else { + 0 + } +} +fn bool_as_string(b: bool) -> String { + if b { + "1".to_string() + } else { + "0".to_string() + } +} +fn value_as_bool(s: &str) -> bool { if s.len() == 0 { - return false + return false; } match s.parse::() { Ok(n) => n != 0, diff --git a/src/expr/tokens.rs b/src/expr/tokens.rs index 48c341e1c..23bf985df 100644 --- a/src/expr/tokens.rs +++ b/src/expr/tokens.rs @@ -18,10 +18,11 @@ //! Hence all we need is to map the strings into the Token structures, except for some ugly fiddling with +-escaping. //! -#[derive(Debug)] -#[derive(Clone)] +#[derive(Debug, Clone)] pub enum Token { - Value{ value: String }, + Value { + value: String, + }, ParOpen, ParClose, @@ -29,45 +30,42 @@ pub enum Token { InfixOp { precedence: u8, left_assoc: bool, - value: String + value: String, }, PrefixOp { arity: usize, - value: String + value: String, }, } impl Token { - fn new_infix_op( v: &String, left_assoc: bool, precedence: u8 ) -> Self { - Token::InfixOp{ + fn new_infix_op(v: &String, left_assoc: bool, precedence: u8) -> Self { + Token::InfixOp { left_assoc: left_assoc, precedence: precedence, - value: v.clone() + value: v.clone(), } } - fn new_value( v: &String ) -> Self { - Token::Value{ - value: v.clone() - } + fn new_value(v: &String) -> Self { + Token::Value { value: v.clone() } } - fn is_infix_plus( &self ) -> bool { + fn is_infix_plus(&self) -> bool { match *self { - Token::InfixOp{ ref value, .. } => value == "+", - _ => false - } - } - fn is_a_number( &self ) -> bool { - match *self { - Token::Value{ ref value, .. } => - match value.parse::() { - Ok( _ ) => true, - Err( _ ) => false - }, + Token::InfixOp { ref value, .. } => value == "+", _ => false, } } - fn is_a_close_paren( &self ) -> bool { + fn is_a_number(&self) -> bool { + match *self { + Token::Value { ref value, .. } => match value.parse::() { + Ok(_) => true, + Err(_) => false, + }, + _ => false, + } + } + fn is_a_close_paren(&self) -> bool { match *self { Token::ParClose => true, _ => false, @@ -75,57 +73,68 @@ impl Token { } } -pub fn strings_to_tokens( strings: &[String] ) -> Result< Vec<(usize, Token)>, String > { - let mut tokens_acc = Vec::with_capacity( strings.len() ); +pub fn strings_to_tokens(strings: &[String]) -> Result, String> { + let mut tokens_acc = Vec::with_capacity(strings.len()); let mut tok_idx = 1; for s in strings { - let token_if_not_escaped = - match s.as_ref() { - "(" => Token::ParOpen, - ")" => Token::ParClose, + let token_if_not_escaped = match s.as_ref() { + "(" => Token::ParOpen, + ")" => Token::ParClose, - "^" => Token::new_infix_op( &s, false, 7 ), + "^" => Token::new_infix_op(&s, false, 7), - ":" => Token::new_infix_op( &s, true, 6 ), + ":" => Token::new_infix_op(&s, true, 6), - "*" => Token::new_infix_op( &s, true, 5 ), - "/" => Token::new_infix_op( &s, true, 5 ), - "%" => Token::new_infix_op( &s, true, 5 ), + "*" => Token::new_infix_op(&s, true, 5), + "/" => Token::new_infix_op(&s, true, 5), + "%" => Token::new_infix_op(&s, true, 5), - "+" => Token::new_infix_op( &s, true, 4 ), - "-" => Token::new_infix_op( &s, true, 4 ), + "+" => Token::new_infix_op(&s, true, 4), + "-" => Token::new_infix_op(&s, true, 4), - "=" => Token::new_infix_op( &s, true, 3 ), - "!=" => Token::new_infix_op( &s, true, 3 ), - "<" => Token::new_infix_op( &s, true, 3 ), - ">" => Token::new_infix_op( &s, true, 3 ), - "<=" => Token::new_infix_op( &s, true, 3 ), - ">=" => Token::new_infix_op( &s, true, 3 ), + "=" => Token::new_infix_op(&s, true, 3), + "!=" => Token::new_infix_op(&s, true, 3), + "<" => Token::new_infix_op(&s, true, 3), + ">" => Token::new_infix_op(&s, true, 3), + "<=" => Token::new_infix_op(&s, true, 3), + ">=" => Token::new_infix_op(&s, true, 3), - "&" => Token::new_infix_op( &s, true, 2 ), + "&" => Token::new_infix_op(&s, true, 2), - "|" => Token::new_infix_op( &s, true, 1 ), + "|" => Token::new_infix_op(&s, true, 1), - "match" => Token::PrefixOp{ arity: 2, value: s.clone() }, - "substr" => Token::PrefixOp{ arity: 3, value: s.clone() }, - "index" => Token::PrefixOp{ arity: 2, value: s.clone() }, - "length" => Token::PrefixOp{ arity: 1, value: s.clone() }, + "match" => Token::PrefixOp { + arity: 2, + value: s.clone(), + }, + "substr" => Token::PrefixOp { + arity: 3, + value: s.clone(), + }, + "index" => Token::PrefixOp { + arity: 2, + value: s.clone(), + }, + "length" => Token::PrefixOp { + arity: 1, + value: s.clone(), + }, - _ => Token::new_value( &s ), - }; - push_token_if_not_escaped( &mut tokens_acc, tok_idx, token_if_not_escaped, &s ); + _ => Token::new_value(&s), + }; + push_token_if_not_escaped(&mut tokens_acc, tok_idx, token_if_not_escaped, &s); tok_idx += 1; } - maybe_dump_tokens_acc( &tokens_acc ); + maybe_dump_tokens_acc(&tokens_acc); - Ok( tokens_acc ) + Ok(tokens_acc) } -fn maybe_dump_tokens_acc( tokens_acc: &[(usize, Token)] ) { +fn maybe_dump_tokens_acc(tokens_acc: &[(usize, Token)]) { use std::env; - if let Ok(debug_var) = env::var( "EXPR_DEBUG_TOKENS" ) { + if let Ok(debug_var) = env::var("EXPR_DEBUG_TOKENS") { if debug_var == "1" { println!("EXPR_DEBUG_TOKENS"); for token in tokens_acc { @@ -135,27 +144,28 @@ fn maybe_dump_tokens_acc( tokens_acc: &[(usize, Token)] ) { } } -fn push_token_if_not_escaped( acc: &mut Vec<(usize, Token)>, tok_idx: usize, token: Token, s: &String ) { +fn push_token_if_not_escaped( + acc: &mut Vec<(usize, Token)>, + tok_idx: usize, + token: Token, + s: &String, +) { // Smells heuristics... :( - let prev_is_plus = - match acc.last() { - None => false, - Some( ref t ) => t.1.is_infix_plus(), - }; - let should_use_as_escaped = - if prev_is_plus && acc.len() >= 2 { - let pre_prev = &acc[acc.len() - 2]; - ! ( pre_prev.1.is_a_number() || pre_prev.1.is_a_close_paren() ) - } - else { - prev_is_plus - }; + let prev_is_plus = match acc.last() { + None => false, + Some(ref t) => t.1.is_infix_plus(), + }; + let should_use_as_escaped = if prev_is_plus && acc.len() >= 2 { + let pre_prev = &acc[acc.len() - 2]; + !(pre_prev.1.is_a_number() || pre_prev.1.is_a_close_paren()) + } else { + prev_is_plus + }; if should_use_as_escaped { acc.pop(); - acc.push( (tok_idx, Token::new_value( s )) ) - } - else { - acc.push( (tok_idx, token) ) + acc.push((tok_idx, Token::new_value(s))) + } else { + acc.push((tok_idx, token)) } } diff --git a/src/factor/build.rs b/src/factor/build.rs index 16076d2d7..6e3368415 100644 --- a/src/factor/build.rs +++ b/src/factor/build.rs @@ -54,18 +54,17 @@ fn inv_mod_u64(a: u64) -> Option { r } / newr; - let (tp, Wrapping(newtp)) = - (newt, Wrapping(t) - (Wrapping(quot) * Wrapping(newt))); + let (tp, Wrapping(newtp)) = (newt, Wrapping(t) - (Wrapping(quot) * Wrapping(newt))); t = tp; newt = newtp; - let (rp, Wrapping(newrp)) = - (newr, Wrapping(r) - (Wrapping(quot) * Wrapping(newr))); + let (rp, Wrapping(newrp)) = (newr, Wrapping(r) - (Wrapping(quot) * Wrapping(newr))); r = rp; newr = newrp; } - if r > 1 { // not invertible + if r > 1 { + // not invertible return None; } @@ -80,7 +79,13 @@ fn main() { let mut file = File::create(&Path::new(&out_dir).join("prime_table.rs")).unwrap(); // By default, we print the multiplicative inverses mod 2^64 of the first 1k primes - let n = args().skip(1).next().unwrap_or("1027".to_string()).parse::().ok().unwrap_or(1027); + let n = args() + .skip(1) + .next() + .unwrap_or("1027".to_string()) + .parse::() + .ok() + .unwrap_or(1027); write!(file, "{}", PREAMBLE).unwrap(); let mut cols = 3; @@ -106,7 +111,11 @@ fn main() { x = next; } - write!(file, "\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n", x).unwrap(); + write!( + file, + "\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n", + x + ).unwrap(); } #[test] @@ -127,8 +136,7 @@ fn test_generator() { } const MAX_WIDTH: usize = 102; -const PREAMBLE: &'static str = -r##"/* +const PREAMBLE: &'static str = r##"/* * This file is part of the uutils coreutils package. * * (c) kwantam diff --git a/src/factor/factor.rs b/src/factor/factor.rs index 26eca7ab3..72224377d 100644 --- a/src/factor/factor.rs +++ b/src/factor/factor.rs @@ -19,7 +19,7 @@ extern crate rand; extern crate uucore; use numeric::*; -use rand::distributions::{Range, IndependentSample}; +use rand::distributions::{IndependentSample, Range}; use std::cmp::{max, min}; use std::io::{stdin, BufRead, BufReader}; use std::num::Wrapping; @@ -111,7 +111,7 @@ fn table_division(mut num: u64, factors: &mut Vec) { // See http://math.stackexchange.com/questions/1251327/ // for a nice explanation. loop { - let Wrapping(x) = Wrapping(num) * Wrapping(inv); // x = num * inv mod 2^64 + let Wrapping(x) = Wrapping(num) * Wrapping(inv); // x = num * inv mod 2^64 if x <= ceil { num = x; factors.push(prime); @@ -129,11 +129,11 @@ fn table_division(mut num: u64, factors: &mut Vec) { // Decide whether to use Pollard Rho or slow divisibility based on // number's size: //if num >= 1 << 63 { - // number is too big to use rho pollard without overflowing - //trial_division_slow(num, factors); + // number is too big to use rho pollard without overflowing + //trial_division_slow(num, factors); //} else if num > 1 { - // number is still greater than 1, but not so big that we have to worry - rho_pollard_factor(num, factors); + // number is still greater than 1, but not so big that we have to worry + rho_pollard_factor(num, factors); //} } @@ -158,8 +158,7 @@ fn print_factors_str(num_str: &str) { } pub fn uumain(args: Vec) -> i32 { - let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .parse(args); + let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP).parse(args); if matches.free.is_empty() { for line in BufReader::new(stdin()).lines() { diff --git a/src/factor/numeric.rs b/src/factor/numeric.rs index 4915a189f..0cce6093a 100644 --- a/src/factor/numeric.rs +++ b/src/factor/numeric.rs @@ -92,7 +92,7 @@ fn witness(mut a: u64, exponent: u64, m: u64) -> bool { big_mul as fn(u64, u64, u64) -> u64 }; - if pow(a, m-1, m, mul) != 1 { + if pow(a, m - 1, m, mul) != 1 { return true; } a = pow(a, exponent, m, mul); @@ -103,7 +103,7 @@ fn witness(mut a: u64, exponent: u64, m: u64) -> bool { if a == 1 { return true; } - if a == m-1 { + if a == m - 1 { return false; } a = mul(a, a, m); @@ -126,5 +126,7 @@ pub fn is_prime(num: u64) -> bool { // These witnesses detect all composites up to at least 2^64. // Discovered by Jim Sinclair, according to http://miller-rabin.appspot.com let witnesses = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; - ! witnesses.iter().any(|&wit| witness(wit % num, exponent, num)) + !witnesses + .iter() + .any(|&wit| witness(wit % num, exponent, num)) } diff --git a/src/factor/sieve.rs b/src/factor/sieve.rs index 6b389ec39..d0a2711f2 100644 --- a/src/factor/sieve.rs +++ b/src/factor/sieve.rs @@ -36,7 +36,7 @@ impl Iterator for Sieve { // need to keep checking the min element of the heap // until we've found an element that's greater than n if next > n { - break; // next heap element is bigger than n + break; // next heap element is bigger than n } if next == n { @@ -59,13 +59,18 @@ impl Iterator for Sieve { impl Sieve { fn new() -> Sieve { - Sieve { inner: Wheel::new(), filts: PrimeHeap::new() } + Sieve { + inner: Wheel::new(), + filts: PrimeHeap::new(), + } } #[allow(dead_code)] #[inline] pub fn primes() -> PrimeSieve { - fn deref(x: &u64) -> u64 { *x } + fn deref(x: &u64) -> u64 { + *x + } let deref = deref as fn(&u64) -> u64; INIT_PRIMES.iter().map(deref).chain(Sieve::new()) } @@ -73,7 +78,9 @@ impl Sieve { #[allow(dead_code)] #[inline] pub fn odd_primes() -> PrimeSieve { - fn deref(x: &u64) -> u64 { *x } + fn deref(x: &u64) -> u64 { + *x + } let deref = deref as fn(&u64) -> u64; (&INIT_PRIMES[1..]).iter().map(deref).chain(Sieve::new()) } @@ -97,7 +104,7 @@ impl Iterator for Wheel { } #[inline] - fn next (&mut self) -> Option { + fn next(&mut self) -> Option { let increment = self.increment.next().unwrap(); // infinite iterator, no check necessary let ret = self.next; self.next = ret + increment; @@ -108,13 +115,19 @@ impl Iterator for Wheel { impl Wheel { #[inline] fn new() -> Wheel { - Wheel { next: 11u64, increment: WHEEL_INCS.iter().cycle() } + Wheel { + next: 11u64, + increment: WHEEL_INCS.iter().cycle(), + } } } /// The increments of a wheel of circumference 210 /// (i.e., a wheel that skips all multiples of 2, 3, 5, 7) -const WHEEL_INCS: &'static [u64] = &[2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10]; +const WHEEL_INCS: &'static [u64] = &[ + 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, + 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10, +]; const INIT_PRIMES: &'static [u64] = &[2, 3, 5, 7]; /// A min-heap of "infinite lists" of prime multiples, where a list is @@ -169,8 +182,8 @@ impl PrimeHeap { let len = self.data.len(); let (key, _) = self.data[0]; loop { - let child1 = 2*idx + 1; - let child2 = 2*idx + 2; + let child1 = 2 * idx + 1; + let child2 = 2 * idx + 2; // no more children if child1 >= len { diff --git a/src/fmt/fmt.rs b/src/fmt/fmt.rs index d2be2c105..45e1e885f 100644 --- a/src/fmt/fmt.rs +++ b/src/fmt/fmt.rs @@ -15,7 +15,7 @@ extern crate unicode_width; extern crate uucore; use std::cmp; -use std::io::{Read, BufReader, BufWriter}; +use std::io::{BufReader, BufWriter, Read}; use std::fs::File; use std::io::{stdin, stdout, Write}; use linebreak::break_lines; @@ -34,27 +34,27 @@ mod linebreak; mod parasplit; // program's NAME and VERSION are used for -V and -h -static SYNTAX: &'static str = "[OPTION]... [FILE]..."; +static SYNTAX: &'static str = "[OPTION]... [FILE]..."; static SUMMARY: &'static str = "Reformat paragraphs from input files (or stdin) to stdout."; static LONG_HELP: &'static str = ""; -pub type FileOrStdReader = BufReader>; +pub type FileOrStdReader = BufReader>; pub struct FmtOptions { - crown : bool, - tagged : bool, - mail : bool, - split_only : bool, - use_prefix : bool, - prefix : String, - xprefix : bool, - use_anti_prefix : bool, - anti_prefix : String, - xanti_prefix : bool, - uniform : bool, - quick : bool, - width : usize, - goal : usize, - tabwidth : usize, + crown: bool, + tagged: bool, + mail: bool, + split_only: bool, + use_prefix: bool, + prefix: String, + xprefix: bool, + use_anti_prefix: bool, + anti_prefix: String, + xanti_prefix: bool, + uniform: bool, + quick: bool, + width: usize, + goal: usize, + tabwidth: usize, } pub fn uumain(args: Vec) -> i32 { @@ -75,38 +75,57 @@ pub fn uumain(args: Vec) -> i32 { .parse(args); let mut fmt_opts = FmtOptions { - crown : false, - tagged : false, - mail : false, - uniform : false, - quick : false, - split_only : false, - use_prefix : false, - prefix : String::new(), - xprefix : false, - use_anti_prefix : false, - anti_prefix : String::new(), - xanti_prefix : false, - width : 79, - goal : 74, - tabwidth : 8, + crown: false, + tagged: false, + mail: false, + uniform: false, + quick: false, + split_only: false, + use_prefix: false, + prefix: String::new(), + xprefix: false, + use_anti_prefix: false, + anti_prefix: String::new(), + xanti_prefix: false, + width: 79, + goal: 74, + tabwidth: 8, }; - if matches.opt_present("t") { fmt_opts.tagged = true; } - if matches.opt_present("c") { fmt_opts.crown = true; fmt_opts.tagged = false; } - if matches.opt_present("m") { fmt_opts.mail = true; } - if matches.opt_present("u") { fmt_opts.uniform = true; } - if matches.opt_present("q") { fmt_opts.quick = true; } - if matches.opt_present("s") { fmt_opts.split_only = true; fmt_opts.crown = false; fmt_opts.tagged = false; } - if matches.opt_present("x") { fmt_opts.xprefix = true; } - if matches.opt_present("X") { fmt_opts.xanti_prefix = true; } + if matches.opt_present("t") { + fmt_opts.tagged = true; + } + if matches.opt_present("c") { + fmt_opts.crown = true; + fmt_opts.tagged = false; + } + if matches.opt_present("m") { + fmt_opts.mail = true; + } + if matches.opt_present("u") { + fmt_opts.uniform = true; + } + if matches.opt_present("q") { + fmt_opts.quick = true; + } + if matches.opt_present("s") { + fmt_opts.split_only = true; + fmt_opts.crown = false; + fmt_opts.tagged = false; + } + if matches.opt_present("x") { + fmt_opts.xprefix = true; + } + if matches.opt_present("X") { + fmt_opts.xanti_prefix = true; + } match matches.opt_str("p") { Some(s) => { fmt_opts.prefix = s; fmt_opts.use_prefix = true; } - None => () + None => (), }; match matches.opt_str("P") { @@ -114,46 +133,49 @@ pub fn uumain(args: Vec) -> i32 { fmt_opts.anti_prefix = s; fmt_opts.use_anti_prefix = true; } - None => () + None => (), }; match matches.opt_str("w") { Some(s) => { - fmt_opts.width = - match s.parse::() { - Ok(t) => t, - Err(e) => { crash!(1, "Invalid WIDTH specification: `{}': {}", s, e); } - }; + fmt_opts.width = match s.parse::() { + Ok(t) => t, + Err(e) => { + crash!(1, "Invalid WIDTH specification: `{}': {}", s, e); + } + }; fmt_opts.goal = cmp::min(fmt_opts.width * 94 / 100, fmt_opts.width - 3); } - None => () + None => (), }; match matches.opt_str("g") { Some(s) => { - fmt_opts.goal = - match s.parse::() { - Ok(t) => t, - Err(e) => { crash!(1, "Invalid GOAL specification: `{}': {}", s, e); } - }; + fmt_opts.goal = match s.parse::() { + Ok(t) => t, + Err(e) => { + crash!(1, "Invalid GOAL specification: `{}': {}", s, e); + } + }; if !matches.opt_present("w") { fmt_opts.width = cmp::max(fmt_opts.goal * 100 / 94, fmt_opts.goal + 3); } else if fmt_opts.goal > fmt_opts.width { crash!(1, "GOAL cannot be greater than WIDTH."); } } - None => () + None => (), }; match matches.opt_str("T") { Some(s) => { - fmt_opts.tabwidth = - match s.parse::() { - Ok(t) => t, - Err(e) => { crash!(1, "Invalid TABWIDTH specification: `{}': {}", s, e); } - }; + fmt_opts.tabwidth = match s.parse::() { + Ok(t) => t, + Err(e) => { + crash!(1, "Invalid TABWIDTH specification: `{}': {}", s, e); + } + }; } - None => () + None => (), }; if fmt_opts.tabwidth < 1 { @@ -172,13 +194,13 @@ pub fn uumain(args: Vec) -> i32 { for i in files.iter().map(|x| &x[..]) { let mut fp = match i { - "-" => BufReader::new(Box::new(stdin()) as Box), + "-" => BufReader::new(Box::new(stdin()) as Box), _ => match File::open(i) { - Ok(f) => BufReader::new(Box::new(f) as Box), + Ok(f) => BufReader::new(Box::new(f) as Box), Err(e) => { show_warning!("{}: {}", i, e); continue; - }, + } }, }; let p_stream = ParagraphStream::new(&fmt_opts, &mut fp); @@ -187,8 +209,8 @@ pub fn uumain(args: Vec) -> i32 { Err(s) => { silent_unwrap!(ostream.write_all(s.as_bytes())); silent_unwrap!(ostream.write_all("\n".as_bytes())); - }, - Ok(para) => break_lines(¶, &fmt_opts, &mut ostream) + } + Ok(para) => break_lines(¶, &fmt_opts, &mut ostream), } } diff --git a/src/fmt/linebreak.rs b/src/fmt/linebreak.rs index f43fb8022..1c47c5c64 100644 --- a/src/fmt/linebreak.rs +++ b/src/fmt/linebreak.rs @@ -8,19 +8,19 @@ */ use FmtOptions; -use parasplit::{Paragraph, ParaWords, WordInfo}; -use std::io::{Write, BufWriter, Stdout}; +use parasplit::{ParaWords, Paragraph, WordInfo}; +use std::io::{BufWriter, Stdout, Write}; use std::i64; use std::cmp; use std::mem; struct BreakArgs<'a> { - opts : &'a FmtOptions, - init_len : usize, - indent_str : &'a str, - indent_len : usize, - uniform : bool, - ostream : &'a mut BufWriter + opts: &'a FmtOptions, + init_len: usize, + indent_str: &'a str, + indent_len: usize, + uniform: bool, + ostream: &'a mut BufWriter, } impl<'a> BreakArgs<'a> { @@ -31,7 +31,9 @@ impl<'a> BreakArgs<'a> { let post = winfo.after_tab; match winfo.before_tab { None => post, - Some(pre) => post + ((pre + posn) / self.opts.tabwidth + 1) * self.opts.tabwidth - posn + Some(pre) => { + post + ((pre + posn) / self.opts.tabwidth + 1) * self.opts.tabwidth - posn + } } } } @@ -56,19 +58,18 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut BufWriter< } }; // print the init, if it exists, and get its length - let p_init_len = w_len + - if opts.crown || opts.tagged { - // handle "init" portion - silent_unwrap!(ostream.write_all(para.init_str.as_bytes())); - para.init_len - } else if !para.mail_header { - // for non-(crown, tagged) that's the same as a normal indent - silent_unwrap!(ostream.write_all(p_indent.as_bytes())); - p_indent_len - } else { - // except that mail headers get no indent at all - 0 - }; + let p_init_len = w_len + if opts.crown || opts.tagged { + // handle "init" portion + silent_unwrap!(ostream.write_all(para.init_str.as_bytes())); + para.init_len + } else if !para.mail_header { + // for non-(crown, tagged) that's the same as a normal indent + silent_unwrap!(ostream.write_all(p_indent.as_bytes())); + p_indent_len + } else { + // except that mail headers get no indent at all + 0 + }; // write first word after writing init silent_unwrap!(ostream.write_all(w.as_bytes())); @@ -76,12 +77,12 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut BufWriter< let uniform = para.mail_header || opts.uniform; let mut break_args = BreakArgs { - opts : opts, - init_len : p_init_len, - indent_str : &p_indent[..], - indent_len : p_indent_len, - uniform : uniform, - ostream : ostream + opts: opts, + init_len: p_init_len, + indent_str: &p_indent[..], + indent_len: p_indent_len, + uniform: uniform, + ostream: ostream, }; if opts.quick || para.mail_header { @@ -93,16 +94,27 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut BufWriter< // break_simple implements a "greedy" breaking algorithm: print words until // maxlength would be exceeded, then print a linebreak and indent and continue. -fn break_simple<'a, T: Iterator>>(iter: T, args: &mut BreakArgs<'a>) { - iter.fold((args.init_len, false), |l, winfo| accum_words_simple(args, l, winfo)); +fn break_simple<'a, T: Iterator>>(iter: T, args: &mut BreakArgs<'a>) { + iter.fold((args.init_len, false), |l, winfo| { + accum_words_simple(args, l, winfo) + }); silent_unwrap!(args.ostream.write_all("\n".as_bytes())); } -fn accum_words_simple<'a>(args: &mut BreakArgs<'a>, (l, prev_punct): (usize, bool), winfo: &'a WordInfo<'a>) -> (usize, bool) { +fn accum_words_simple<'a>( + args: &mut BreakArgs<'a>, + (l, prev_punct): (usize, bool), + winfo: &'a WordInfo<'a>, +) -> (usize, bool) { // compute the length of this word, considering how tabs will expand at this position on the line let wlen = winfo.word_nchars + args.compute_width(winfo, l, false); - let slen = compute_slen(args.uniform, winfo.new_line, winfo.sentence_start, prev_punct); + let slen = compute_slen( + args.uniform, + winfo.new_line, + winfo.sentence_start, + prev_punct, + ); if l + wlen + slen > args.opts.width { write_newline(args.indent_str, args.ostream); @@ -118,20 +130,31 @@ fn accum_words_simple<'a>(args: &mut BreakArgs<'a>, (l, prev_punct): (usize, boo // Knuth, D.E., and Plass, M.F. "Breaking Paragraphs into Lines." in Software, // Practice and Experience. Vol. 11, No. 11, November 1981. // http://onlinelibrary.wiley.com/doi/10.1002/spe.4380111102/pdf -fn break_knuth_plass<'a, T: Clone + Iterator>>(mut iter: T, args: &mut BreakArgs<'a>) { +fn break_knuth_plass<'a, T: Clone + Iterator>>( + mut iter: T, + args: &mut BreakArgs<'a>, +) { // run the algorithm to get the breakpoints let breakpoints = find_kp_breakpoints(iter.clone(), args); // iterate through the breakpoints (note that breakpoints is in reverse break order, so we .rev() it - let (mut prev_punct, mut fresh) = - breakpoints.iter().rev().fold((false, false), |(mut prev_punct, mut fresh), &(next_break, break_before)| { + let (mut prev_punct, mut fresh) = breakpoints.iter().rev().fold( + (false, false), + |(mut prev_punct, mut fresh), &(next_break, break_before)| { if fresh { write_newline(args.indent_str, args.ostream); } // at each breakpoint, keep emitting words until we find the word matching this breakpoint for winfo in &mut iter { - let (slen, word) = slice_if_fresh(fresh, winfo.word, winfo.word_start, args.uniform, - winfo.new_line, winfo.sentence_start, prev_punct); + let (slen, word) = slice_if_fresh( + fresh, + winfo.word, + winfo.word_start, + args.uniform, + winfo.new_line, + winfo.sentence_start, + prev_punct, + ); fresh = false; prev_punct = winfo.ends_punct; @@ -155,15 +178,23 @@ fn break_knuth_plass<'a, T: Clone + Iterator>>(mut iter: T } } (prev_punct, fresh) - }); + }, + ); // after the last linebreak, write out the rest of the final line. for winfo in iter { if fresh { write_newline(args.indent_str, args.ostream); } - let (slen, word) = slice_if_fresh(fresh, winfo.word, winfo.word_start, args.uniform, - winfo.new_line, winfo.sentence_start, prev_punct); + let (slen, word) = slice_if_fresh( + fresh, + winfo.word, + winfo.word_start, + args.uniform, + winfo.new_line, + winfo.sentence_start, + prev_punct, + ); prev_punct = winfo.ends_punct; fresh = false; write_with_spaces(word, slen, args.ostream); @@ -172,49 +203,57 @@ fn break_knuth_plass<'a, T: Clone + Iterator>>(mut iter: T } struct LineBreak<'a> { - prev : usize, - linebreak : Option<&'a WordInfo<'a>>, - break_before : bool, - demerits : i64, - prev_rat : f32, - length : usize, - fresh : bool + prev: usize, + linebreak: Option<&'a WordInfo<'a>>, + break_before: bool, + demerits: i64, + prev_rat: f32, + length: usize, + fresh: bool, } -fn find_kp_breakpoints<'a, T: Iterator>>(iter: T, args: &BreakArgs<'a>) -> Vec<(&'a WordInfo<'a>, bool)> { +fn find_kp_breakpoints<'a, T: Iterator>>( + iter: T, + args: &BreakArgs<'a>, +) -> Vec<(&'a WordInfo<'a>, bool)> { let mut iter = iter.peekable(); // set up the initial null linebreak - let mut linebreaks = vec!(LineBreak { - prev : 0, - linebreak : None, - break_before : false, - demerits : 0, - prev_rat : 0.0f32, - length : args.init_len, - fresh : false - }); - // this vec holds the current active linebreaks; next_ holds the breaks that will be active for the next word - let active_breaks = &mut vec!(0); - let next_active_breaks = &mut vec!(); + let mut linebreaks = vec![ + LineBreak { + prev: 0, + linebreak: None, + break_before: false, + demerits: 0, + prev_rat: 0.0f32, + length: args.init_len, + fresh: false, + }, + ]; + // this vec holds the current active linebreaks; next_ holds the breaks that will be active for + // the next word + let active_breaks = &mut vec![0]; + let next_active_breaks = &mut vec![]; let stretch = (args.opts.width - args.opts.goal) as isize; let minlength = args.opts.goal - stretch as usize; - let mut new_linebreaks = vec!(); + let mut new_linebreaks = vec![]; let mut is_sentence_start = false; let mut least_demerits = 0; loop { - let w = - match iter.next() { - None => break, - Some(w) => w - }; + let w = match iter.next() { + None => break, + Some(w) => w, + }; // if this is the last word, we don't add additional demerits for this break - let (is_last_word, is_sentence_end) = - match iter.peek() { - None => (true, true), - Some(&&WordInfo { sentence_start: st, new_line: nl, .. }) => (false, st || (nl && w.ends_punct)) - }; + let (is_last_word, is_sentence_end) = match iter.peek() { + None => (true, true), + Some(&&WordInfo { + sentence_start: st, + new_line: nl, + .. + }) => (false, st || (nl && w.ends_punct)), + }; // should we be adding extra space at the beginning of the next sentence? let slen = compute_slen(args.uniform, w.new_line, is_sentence_start, false); @@ -236,7 +275,8 @@ fn find_kp_breakpoints<'a, T: Iterator>>(iter: T, args: &B } // get the new length - let tlen = w.word_nchars + args.compute_width(w, active.length, active.fresh) + slen + active.length; + let tlen = w.word_nchars + args.compute_width(w, active.length, active.fresh) + slen + + active.length; // if tlen is longer than args.opts.width, we drop this break from the active list // otherwise, we extend the break, and possibly add a new break at this point @@ -249,27 +289,33 @@ fn find_kp_breakpoints<'a, T: Iterator>>(iter: T, args: &B // if we're above the minlength, we can also consider breaking here if tlen >= minlength { - let (new_demerits, new_ratio) = - if is_last_word { - // there is no penalty for the final line's length - (0, 0.0) - } else { - compute_demerits((args.opts.goal - tlen) as isize, stretch, w.word_nchars as isize, active.prev_rat) - }; + let (new_demerits, new_ratio) = if is_last_word { + // there is no penalty for the final line's length + (0, 0.0) + } else { + compute_demerits( + (args.opts.goal - tlen) as isize, + stretch, + w.word_nchars as isize, + active.prev_rat, + ) + }; // do not even consider adding a line that has too many demerits // also, try to detect overflow by checking signum let total_demerits = new_demerits + active.demerits; - if new_demerits < BAD_INFTY_SQ && total_demerits < ld_new && active.demerits.signum() <= new_demerits.signum() { + if new_demerits < BAD_INFTY_SQ && total_demerits < ld_new + && active.demerits.signum() <= new_demerits.signum() + { ld_new = total_demerits; new_linebreaks.push(LineBreak { - prev : i, - linebreak : Some(w), - break_before : false, - demerits : total_demerits, - prev_rat : new_ratio, - length : args.indent_len, - fresh : true + prev: i, + linebreak: Some(w), + break_before: false, + demerits: total_demerits, + prev_rat: new_ratio, + length: args.indent_len, + fresh: true, }); } } @@ -289,7 +335,8 @@ fn find_kp_breakpoints<'a, T: Iterator>>(iter: T, args: &B if next_active_breaks.is_empty() { // every potential linebreak is too long! choose the linebreak with the least demerits, ld_idx - let new_break = restart_active_breaks(args, &linebreaks[ld_idx], ld_idx, w, slen, minlength); + let new_break = + restart_active_breaks(args, &linebreaks[ld_idx], ld_idx, w, slen, minlength); next_active_breaks.push(linebreaks.len()); linebreaks.push(new_break); least_demerits = 0; @@ -309,11 +356,14 @@ fn find_kp_breakpoints<'a, T: Iterator>>(iter: T, args: &B } fn build_best_path<'a>(paths: &[LineBreak<'a>], active: &[usize]) -> Vec<(&'a WordInfo<'a>, bool)> { - let mut breakwords = vec!(); + let mut breakwords = vec![]; // of the active paths, we select the one with the fewest demerits let mut best_idx = match active.iter().min_by_key(|&&a| paths[a].demerits) { - None => crash!(1, "Failed to find a k-p linebreak solution. This should never happen."), - Some(&s) => s + None => crash!( + 1, + "Failed to find a k-p linebreak solution. This should never happen." + ), + Some(&s) => s, }; // now, chase the pointers back through the break list, recording @@ -342,28 +392,28 @@ const DL_MULT: f32 = 300.0; fn compute_demerits(delta_len: isize, stretch: isize, wlen: isize, prev_rat: f32) -> (i64, f32) { // how much stretch are we using? - let ratio = - if delta_len == 0 { - 0.0f32 - } else { - delta_len as f32 / stretch as f32 - }; + let ratio = if delta_len == 0 { + 0.0f32 + } else { + delta_len as f32 / stretch as f32 + }; // compute badness given the stretch ratio - let bad_linelen = - if ratio.abs() > 1.0f32 { - BAD_INFTY - } else { - (BAD_MULT * ratio.powf(3f32).abs()) as i64 - }; + let bad_linelen = if ratio.abs() > 1.0f32 { + BAD_INFTY + } else { + (BAD_MULT * ratio.powf(3f32).abs()) as i64 + }; // we penalize lines ending in really short words - let bad_wordlen = - if wlen >= stretch { - 0 - } else { - (DL_MULT * ((stretch - wlen) as f32 / (stretch - 1) as f32).powf(3f32).abs()) as i64 - }; + let bad_wordlen = if wlen >= stretch { + 0 + } else { + (DL_MULT + * ((stretch - wlen) as f32 / (stretch - 1) as f32) + .powf(3f32) + .abs()) as i64 + }; // we penalize lines that have very different ratios from previous lines let bad_delta_r = (DR_MULT * (((ratio - prev_rat) / 2.0).powf(3f32)).abs()) as i64; @@ -373,33 +423,39 @@ fn compute_demerits(delta_len: isize, stretch: isize, wlen: isize, prev_rat: f32 (demerits, ratio) } -fn restart_active_breaks<'a>(args: &BreakArgs<'a>, active: &LineBreak<'a>, act_idx: usize, w: &'a WordInfo<'a>, slen: usize, min: usize) -> LineBreak<'a> { - let (break_before, line_length) = - if active.fresh { - // never break before a word if that word would be the first on a line - (false, args.indent_len) +fn restart_active_breaks<'a>( + args: &BreakArgs<'a>, + active: &LineBreak<'a>, + act_idx: usize, + w: &'a WordInfo<'a>, + slen: usize, + min: usize, +) -> LineBreak<'a> { + let (break_before, line_length) = if active.fresh { + // never break before a word if that word would be the first on a line + (false, args.indent_len) + } else { + // choose the lesser evil: breaking too early, or breaking too late + let wlen = w.word_nchars + args.compute_width(w, active.length, active.fresh); + let underlen = (min - active.length) as isize; + let overlen = ((wlen + slen + active.length) - args.opts.width) as isize; + if overlen > underlen { + // break early, put this word on the next line + (true, args.indent_len + w.word_nchars) } else { - // choose the lesser evil: breaking too early, or breaking too late - let wlen = w.word_nchars + args.compute_width(w, active.length, active.fresh); - let underlen = (min - active.length) as isize; - let overlen = ((wlen + slen + active.length) - args.opts.width) as isize; - if overlen > underlen { - // break early, put this word on the next line - (true, args.indent_len + w.word_nchars) - } else { - (false, args.indent_len) - } - }; + (false, args.indent_len) + } + }; // restart the linebreak. This will be our only active path. LineBreak { - prev : act_idx, - linebreak : Some(w), - break_before : break_before, - demerits : 0, // this is the only active break, so we can reset the demerit count - prev_rat : if break_before { 1.0 } else { -1.0 }, - length : line_length, - fresh : !break_before + prev: act_idx, + linebreak: Some(w), + break_before: break_before, + demerits: 0, // this is the only active break, so we can reset the demerit count + prev_rat: if break_before { 1.0 } else { -1.0 }, + length: line_length, + fresh: !break_before, } } @@ -418,7 +474,15 @@ fn compute_slen(uniform: bool, newline: bool, start: bool, punct: bool) -> usize // If we're on a fresh line, slen=0 and we slice off leading whitespace. // Otherwise, compute slen and leave whitespace alone. -fn slice_if_fresh(fresh: bool, word: &str, start: usize, uniform: bool, newline: bool, sstart: bool, punct: bool) -> (usize, &str) { +fn slice_if_fresh( + fresh: bool, + word: &str, + start: usize, + uniform: bool, + newline: bool, + sstart: bool, + punct: bool, +) -> (usize, &str) { if fresh { (0, &word[start..]) } else { diff --git a/src/fmt/parasplit.rs b/src/fmt/parasplit.rs index 68ec74d0c..208b3bf04 100644 --- a/src/fmt/parasplit.rs +++ b/src/fmt/parasplit.rs @@ -32,7 +32,7 @@ fn char_width(c: char) -> usize { #[derive(Debug)] pub enum Line { FormatLine(FileLine), - NoFormatLine(String, bool) + NoFormatLine(String, bool), } impl Line { @@ -40,7 +40,7 @@ impl Line { fn get_formatline(self) -> FileLine { match self { Line::FormatLine(fl) => fl, - Line::NoFormatLine(..) => panic!("Found NoFormatLine when expecting FormatLine") + Line::NoFormatLine(..) => panic!("Found NoFormatLine when expecting FormatLine"), } } @@ -48,7 +48,7 @@ impl Line { fn get_noformatline(self) -> (String, bool) { match self { Line::NoFormatLine(s, b) => (s, b), - Line::FormatLine(..) => panic!("Found FormatLine when expecting NoFormatLine") + Line::FormatLine(..) => panic!("Found FormatLine when expecting NoFormatLine"), } } } @@ -57,38 +57,49 @@ impl Line { // the next line or not #[derive(Debug)] pub struct FileLine { - line : String, - indent_end : usize, // the end of the indent, always the start of the text - pfxind_end : usize, // the end of the PREFIX's indent, that is, the spaces before the prefix - indent_len : usize, // display length of indent taking into account tabs - prefix_len : usize, // PREFIX indent length taking into account tabs + line: String, + indent_end: usize, // the end of the indent, always the start of the text + pfxind_end: usize, // the end of the PREFIX's indent, that is, the spaces before the prefix + indent_len: usize, // display length of indent taking into account tabs + prefix_len: usize, // PREFIX indent length taking into account tabs } // iterator that produces a stream of Lines from a file pub struct FileLines<'a> { - opts : &'a FmtOptions, - lines : Lines<&'a mut FileOrStdReader>, + opts: &'a FmtOptions, + lines: Lines<&'a mut FileOrStdReader>, } impl<'a> FileLines<'a> { fn new<'b>(opts: &'b FmtOptions, lines: Lines<&'b mut FileOrStdReader>) -> FileLines<'b> { - FileLines { opts: opts, lines: lines } + FileLines { + opts: opts, + lines: lines, + } } // returns true if this line should be formatted fn match_prefix(&self, line: &str) -> (bool, usize) { - if !self.opts.use_prefix { return (true, 0); } + if !self.opts.use_prefix { + return (true, 0); + } FileLines::match_prefix_generic(&self.opts.prefix[..], line, self.opts.xprefix) } // returns true if this line should be formatted fn match_anti_prefix(&self, line: &str) -> bool { - if !self.opts.use_anti_prefix { return true; } + if !self.opts.use_anti_prefix { + return true; + } - match FileLines::match_prefix_generic(&self.opts.anti_prefix[..], line, self.opts.xanti_prefix) { + match FileLines::match_prefix_generic( + &self.opts.anti_prefix[..], + line, + self.opts.xanti_prefix, + ) { (true, _) => false, - (_ , _) => true + (_, _) => true, } } @@ -141,14 +152,13 @@ impl<'a> Iterator for FileLines<'a> { type Item = Line; fn next(&mut self) -> Option { - let n = - match self.lines.next() { - Some(t) => match t { - Ok(tt) => tt, - Err(_) => return None - }, - None => return None - }; + let n = match self.lines.next() { + Some(t) => match t { + Ok(tt) => tt, + Err(_) => return None, + }, + None => return None, + }; // if this line is entirely whitespace, // emit a blank line @@ -163,7 +173,10 @@ impl<'a> Iterator for FileLines<'a> { let (pmatch, poffset) = self.match_prefix(&n[..]); if !pmatch { return Some(Line::NoFormatLine(n, false)); - } else if n[poffset + self.opts.prefix.len()..].chars().all(|c| c.is_whitespace()) { + } else if n[poffset + self.opts.prefix.len()..] + .chars() + .all(|c| c.is_whitespace()) + { // if the line matches the prefix, but is blank after, // don't allow lines to be combined through it (that is, // treat it like a blank line, except that since it's @@ -183,11 +196,11 @@ impl<'a> Iterator for FileLines<'a> { let (indent_end, prefix_len, indent_len) = self.compute_indent(&n[..], prefix_end); Some(Line::FormatLine(FileLine { - line : n, - indent_end : indent_end, - pfxind_end : poffset, - indent_len : indent_len, - prefix_len : prefix_len + line: n, + indent_end: indent_end, + pfxind_end: poffset, + indent_len: indent_len, + prefix_len: prefix_len, })) } } @@ -198,29 +211,33 @@ impl<'a> Iterator for FileLines<'a> { // is only there to help us in deciding how to merge lines into Paragraphs #[derive(Debug)] pub struct Paragraph { - lines : Vec, // the lines of the file - pub init_str : String, // string representing the init, that is, the first line's indent - pub init_len : usize, // printable length of the init string considering TABWIDTH - init_end : usize, // byte location of end of init in first line String - pub indent_str : String, // string representing indent - pub indent_len : usize, // length of above - indent_end : usize, // byte location of end of indent (in crown and tagged mode, only applies to 2nd line and onward) - pub mail_header : bool // we need to know if this is a mail header because we do word splitting differently in that case + lines: Vec, // the lines of the file + pub init_str: String, // string representing the init, that is, the first line's indent + pub init_len: usize, // printable length of the init string considering TABWIDTH + init_end: usize, // byte location of end of init in first line String + pub indent_str: String, // string representing indent + pub indent_len: usize, // length of above + indent_end: usize, // byte location of end of indent (in crown and tagged mode, only applies to 2nd line and onward) + pub mail_header: bool, // we need to know if this is a mail header because we do word splitting differently in that case } // an iterator producing a stream of paragraphs from a stream of lines // given a set of options. pub struct ParagraphStream<'a> { - lines : Peekable>, - next_mail : bool, - opts : &'a FmtOptions, + lines: Peekable>, + next_mail: bool, + opts: &'a FmtOptions, } impl<'a> ParagraphStream<'a> { pub fn new<'b>(opts: &'b FmtOptions, reader: &'b mut FileOrStdReader) -> ParagraphStream<'b> { let lines = FileLines::new(opts, reader.lines()).peekable(); // at the beginning of the file, we might find mail headers - ParagraphStream { lines: lines, next_mail: true, opts: opts } + ParagraphStream { + lines: lines, + next_mail: true, + opts: opts, + } } // detect RFC822 mail header @@ -235,18 +252,19 @@ impl<'a> ParagraphStream<'a> { if l_slice.starts_with("From ") { true } else { - let colon_posn = - match l_slice.find(':') { - Some(n) => n, - None => return false - }; + let colon_posn = match l_slice.find(':') { + Some(n) => n, + None => return false, + }; // header field must be nonzero length - if colon_posn == 0 { return false; } + if colon_posn == 0 { + return false; + } l_slice[..colon_posn].chars().all(|x| match x as usize { y if y < 33 || y > 126 => false, - _ => true + _ => true, }) } } @@ -258,14 +276,13 @@ impl<'a> Iterator for ParagraphStream<'a> { fn next(&mut self) -> Option> { // return a NoFormatLine in an Err; it should immediately be output - let noformat = - match self.lines.peek() { - None => return None, - Some(l) => match *l { - Line::FormatLine(_) => false, - Line::NoFormatLine(_, _) => true - } - }; + let noformat = match self.lines.peek() { + None => return None, + Some(l) => match *l { + Line::FormatLine(_) => false, + Line::NoFormatLine(_, _) => true, + }, + }; // found a NoFormatLine, immediately dump it out if noformat { @@ -286,28 +303,27 @@ impl<'a> Iterator for ParagraphStream<'a> { let mut p_lines = Vec::new(); let mut in_mail = false; - let mut second_done = false; // for when we use crown or tagged mode + let mut second_done = false; // for when we use crown or tagged mode loop { - { // peek ahead - // need to explicitly force fl out of scope before we can call self.lines.next() - let fl = - match self.lines.peek() { - None => break, - Some(l) => { - match *l { - Line::FormatLine(ref x) => x, - Line::NoFormatLine(..) => break - } - } - }; + { + // peek ahead + // need to explicitly force fl out of scope before we can call self.lines.next() + let fl = match self.lines.peek() { + None => break, + Some(l) => match *l { + Line::FormatLine(ref x) => x, + Line::NoFormatLine(..) => break, + }, + }; if p_lines.is_empty() { // first time through the loop, get things set up // detect mail header if self.opts.mail && self.next_mail && ParagraphStream::is_mail_header(fl) { in_mail = true; - // there can't be any indent or pfxind because otherwise is_mail_header would fail - // since there cannot be any whitespace before the colon in a valid header field + // there can't be any indent or pfxind because otherwise is_mail_header + // would fail since there cannot be any whitespace before the colon in a + // valid header field indent_str.push_str(" "); indent_len = 2; } else { @@ -343,14 +359,16 @@ impl<'a> Iterator for ParagraphStream<'a> { } else if in_mail { // lines following mail headers must begin with spaces if fl.indent_end == 0 || (self.opts.use_prefix && fl.pfxind_end == 0) { - break; // this line does not begin with spaces + break; // this line does not begin with spaces } } else if !second_done { // now we have enough info to handle crown margin and tagged mode if prefix_len != fl.prefix_len || pfxind_end != fl.pfxind_end { // in both crown and tagged modes we require that prefix_len is the same break; - } else if self.opts.tagged && indent_len - 4 == fl.indent_len && indent_end == fl.indent_end { + } else if self.opts.tagged && indent_len - 4 == fl.indent_len + && indent_end == fl.indent_end + { // in tagged mode, indent has to be *different* on following lines break; } else { @@ -363,7 +381,10 @@ impl<'a> Iterator for ParagraphStream<'a> { second_done = true; } else { // detect mismatch - if indent_end != fl.indent_end || pfxind_end != fl.pfxind_end || indent_len != fl.indent_len || prefix_len != fl.prefix_len { + if indent_end != fl.indent_end || pfxind_end != fl.pfxind_end + || indent_len != fl.indent_len + || prefix_len != fl.prefix_len + { break; } } @@ -383,75 +404,91 @@ impl<'a> Iterator for ParagraphStream<'a> { self.next_mail = in_mail; Some(Ok(Paragraph { - lines : p_lines, - init_str : init_str, - init_len : init_len, - init_end : init_end, - indent_str : indent_str, - indent_len : indent_len, - indent_end : indent_end, - mail_header : in_mail + lines: p_lines, + init_str: init_str, + init_len: init_len, + init_end: init_end, + indent_str: indent_str, + indent_len: indent_len, + indent_end: indent_end, + mail_header: in_mail, })) } } pub struct ParaWords<'a> { - opts : &'a FmtOptions, - para : &'a Paragraph, - words : Vec> + opts: &'a FmtOptions, + para: &'a Paragraph, + words: Vec>, } impl<'a> ParaWords<'a> { pub fn new<'b>(opts: &'b FmtOptions, para: &'b Paragraph) -> ParaWords<'b> { - let mut pw = ParaWords { opts: opts, para: para, words: Vec::new() }; + let mut pw = ParaWords { + opts: opts, + para: para, + words: Vec::new(), + }; pw.create_words(); pw } - fn create_words(& mut self) { + fn create_words(&mut self) { if self.para.mail_header { // no extra spacing for mail headers; always exactly 1 space // safe to trim_left on every line of a mail header, since the // first line is guaranteed not to have any spaces - self.words.extend(self.para.lines.iter().flat_map(|x| x.split_whitespace()).map(|x| WordInfo { - word : x, - word_start : 0, - word_nchars : x.len(), // OK for mail headers; only ASCII allowed (unicode is escaped) - before_tab : None, - after_tab : 0, - sentence_start : false, - ends_punct : false, - new_line : false - })); + self.words.extend( + self.para + .lines + .iter() + .flat_map(|x| x.split_whitespace()) + .map(|x| WordInfo { + word: x, + word_start: 0, + word_nchars: x.len(), // OK for mail headers; only ASCII allowed (unicode is escaped) + before_tab: None, + after_tab: 0, + sentence_start: false, + ends_punct: false, + new_line: false, + }), + ); } else { // first line - self.words.extend( - if self.opts.crown || self.opts.tagged { - // crown and tagged mode has the "init" in the first line, so slice from there - WordSplit::new(self.opts, &self.para.lines[0][self.para.init_end..]) - } else { - // otherwise we slice from the indent - WordSplit::new(self.opts, &self.para.lines[0][self.para.indent_end..]) - }); + self.words.extend(if self.opts.crown || self.opts.tagged { + // crown and tagged mode has the "init" in the first line, so slice from there + WordSplit::new(self.opts, &self.para.lines[0][self.para.init_end..]) + } else { + // otherwise we slice from the indent + WordSplit::new(self.opts, &self.para.lines[0][self.para.indent_end..]) + }); if self.para.lines.len() > 1 { let indent_end = self.para.indent_end; let opts = self.opts; self.words.extend( - self.para.lines.iter().skip(1).flat_map(|x| WordSplit::new(opts, &x[indent_end..]))); + self.para + .lines + .iter() + .skip(1) + .flat_map(|x| WordSplit::new(opts, &x[indent_end..])), + ); } } } - pub fn words(&'a self) -> Iter<'a, WordInfo<'a>> { self.words.iter() } + pub fn words(&'a self) -> Iter<'a, WordInfo<'a>> { + self.words.iter() + } } struct WordSplit<'a> { - opts : &'a FmtOptions, - string : &'a str, - length : usize, - position : usize, - prev_punct : bool + opts: &'a FmtOptions, + string: &'a str, + length: usize, + position: usize, + prev_punct: bool, } impl<'a> WordSplit<'a> { @@ -484,26 +521,32 @@ impl<'a> WordSplit<'a> { fn new<'b>(opts: &'b FmtOptions, string: &'b str) -> WordSplit<'b> { // wordsplits *must* start at a non-whitespace character let trim_string = string.trim_left(); - WordSplit { opts: opts, string: trim_string, length: string.len(), position: 0, prev_punct: false } + WordSplit { + opts: opts, + string: trim_string, + length: string.len(), + position: 0, + prev_punct: false, + } } fn is_punctuation(c: char) -> bool { match c { '!' | '.' | '?' => true, - _ => false + _ => false, } } } pub struct WordInfo<'a> { - pub word : &'a str, - pub word_start : usize, - pub word_nchars : usize, - pub before_tab : Option, - pub after_tab : usize, - pub sentence_start : bool, - pub ends_punct : bool, - pub new_line : bool + pub word: &'a str, + pub word_start: usize, + pub word_nchars: usize, + pub before_tab: Option, + pub after_tab: usize, + pub sentence_start: bool, + pub ends_punct: bool, + pub new_line: bool, } // returns (&str, is_start_of_sentence) @@ -512,58 +555,69 @@ impl<'a> Iterator for WordSplit<'a> { fn next(&mut self) -> Option> { if self.position >= self.length { - return None + return None; } let old_position = self.position; let new_line = old_position == 0; // find the start of the next word, and record if we find a tab character - let (before_tab, after_tab, word_start) = match self.analyze_tabs(&self.string[old_position..]) { - (b, a, Some(s)) => (b, a, s + old_position), - (_, _, None) => { - self.position = self.length; - return None; - } - }; + let (before_tab, after_tab, word_start) = + match self.analyze_tabs(&self.string[old_position..]) { + (b, a, Some(s)) => (b, a, s + old_position), + (_, _, None) => { + self.position = self.length; + return None; + } + }; // find the beginning of the next whitespace // note that this preserves the invariant that self.position // points to whitespace character OR end of string let mut word_nchars = 0; - self.position = - match self.string[word_start..] - .find(|x: char| if !x.is_whitespace() { word_nchars += char_width(x); false } else { true }) { - None => self.length, - Some(s) => s + word_start - }; + self.position = match self.string[word_start..].find(|x: char| { + if !x.is_whitespace() { + word_nchars += char_width(x); + false + } else { + true + } + }) { + None => self.length, + Some(s) => s + word_start, + }; let word_start_relative = word_start - old_position; // if the previous sentence was punctuation and this sentence has >2 whitespace or one tab, is a new sentence. - let is_start_of_sentence = self.prev_punct && (before_tab.is_some() || word_start_relative > 1); + let is_start_of_sentence = + self.prev_punct && (before_tab.is_some() || word_start_relative > 1); // now record whether this word ends in punctuation self.prev_punct = match self.string[..self.position].chars().rev().next() { Some(ch) => WordSplit::is_punctuation(ch), - _ => panic!("fatal: expected word not to be empty") + _ => panic!("fatal: expected word not to be empty"), }; - let (word, word_start_relative, before_tab, after_tab) = - if self.opts.uniform { - (&self.string[word_start..self.position], 0, None, 0) - } else { - (&self.string[old_position..self.position], word_start_relative, before_tab, after_tab) - }; + let (word, word_start_relative, before_tab, after_tab) = if self.opts.uniform { + (&self.string[word_start..self.position], 0, None, 0) + } else { + ( + &self.string[old_position..self.position], + word_start_relative, + before_tab, + after_tab, + ) + }; Some(WordInfo { - word : word, - word_start : word_start_relative, - word_nchars : word_nchars, - before_tab : before_tab, - after_tab : after_tab, - sentence_start : is_start_of_sentence, - ends_punct : self.prev_punct, - new_line : new_line + word: word, + word_start: word_start_relative, + word_nchars: word_nchars, + before_tab: before_tab, + after_tab: after_tab, + sentence_start: is_start_of_sentence, + ends_punct: self.prev_punct, + new_line: new_line, }) } } diff --git a/src/fold/fold.rs b/src/fold/fold.rs index 2c538d86d..d2d33fecc 100644 --- a/src/fold/fold.rs +++ b/src/fold/fold.rs @@ -13,7 +13,7 @@ extern crate uucore; use std::fs::File; -use std::io::{BufRead, BufReader, Read, stdin}; +use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; static SYNTAX: &'static str = "[OPTION]... [FILE]..."; @@ -24,28 +24,41 @@ static LONG_HELP: &'static str = ""; pub fn uumain(args: Vec) -> i32 { let (args, obs_width) = handle_obsolete(&args[..]); let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .optflag("b", "bytes", "count using bytes rather than columns (meaning control characters such as newline are not treated specially)") - .optflag("s", "spaces", "break lines at word boundaries rather than a hard cut-off") - .optopt("w", "width", "set WIDTH as the maximum line width rather than 80", "WIDTH") + .optflag( + "b", + "bytes", + "count using bytes rather than columns (meaning control characters \ + such as newline are not treated specially)", + ) + .optflag( + "s", + "spaces", + "break lines at word boundaries rather than a hard cut-off", + ) + .optopt( + "w", + "width", + "set WIDTH as the maximum line width rather than 80", + "WIDTH", + ) .parse(args); let bytes = matches.opt_present("b"); let spaces = matches.opt_present("s"); - let poss_width = - if matches.opt_present("w") { - matches.opt_str("w") - } else { - obs_width - }; + let poss_width = if matches.opt_present("w") { + matches.opt_str("w") + } else { + obs_width + }; let width = match poss_width { Some(inp_width) => match inp_width.parse::() { Ok(width) => width, - Err(e) => crash!(1, "illegal width value (\"{}\"): {}", inp_width, e) + Err(e) => crash!(1, "illegal width value (\"{}\"): {}", inp_width, e), }, - None => 80 + None => 80, }; let files = if matches.free.is_empty() { - vec!("-".to_owned()) + vec!["-".to_owned()] } else { matches.free }; @@ -57,7 +70,9 @@ pub fn uumain(args: Vec) -> i32 { fn handle_obsolete(args: &[String]) -> (Vec, Option) { for (i, arg) in args.iter().enumerate() { let slice = &arg; - if slice.chars().next().unwrap() == '-' && slice.len() > 1 && slice.chars().nth(1).unwrap().is_digit(10) { + if slice.chars().next().unwrap() == '-' && slice.len() > 1 + && slice.chars().nth(1).unwrap().is_digit(10) + { let mut v = args.to_vec(); v.remove(i); return (v, Some(slice[1..].to_owned())); @@ -72,15 +87,13 @@ fn fold(filenames: Vec, bytes: bool, spaces: bool, width: usize) { let filename: &str = &filename; let mut stdin_buf; let mut file_buf; - let buffer = BufReader::new( - if filename == "-" { - stdin_buf = stdin(); - &mut stdin_buf as &mut Read - } else { - file_buf = safe_unwrap!(File::open(Path::new(filename))); - &mut file_buf as &mut Read - } - ); + let buffer = BufReader::new(if filename == "-" { + stdin_buf = stdin(); + &mut stdin_buf as &mut Read + } else { + file_buf = safe_unwrap!(File::open(Path::new(filename))); + &mut file_buf as &mut Read + }); fold_file(buffer, bytes, spaces, width); } } @@ -99,7 +112,7 @@ fn fold_file(mut file: BufReader, bytes: bool, spaces: bool, width: if spaces && i + width < len { match slice.rfind(|ch: char| ch.is_whitespace()) { Some(m) => &slice[..m + 1], - None => slice + None => slice, } } else { slice @@ -125,26 +138,29 @@ fn fold_file(mut file: BufReader, bytes: bool, spaces: bool, width: if count >= width { let (val, ncount) = { let slice = &output[..]; - let (out, val, ncount) = - if spaces && i + 1 < len { - match rfind_whitespace(slice) { - Some(m) => { - let routput = &slice[m + 1 .. slice.chars().count()]; - let ncount = routput.chars().fold(0, |out, ch: char| { - out + match ch { - '\t' => 8, - '\x08' => if out > 0 { !0 } else { 0 }, - '\r' => return 0, - _ => 1 - } - }); - (&slice[0 .. m + 1], routput, ncount) - }, - None => (slice, "", 0) + let (out, val, ncount) = if spaces && i + 1 < len { + match rfind_whitespace(slice) { + Some(m) => { + let routput = &slice[m + 1..slice.chars().count()]; + let ncount = routput.chars().fold(0, |out, ch: char| { + out + match ch { + '\t' => 8, + '\x08' => if out > 0 { + !0 + } else { + 0 + }, + '\r' => return 0, + _ => 1, + } + }); + (&slice[0..m + 1], routput, ncount) } - } else { - (slice, "", 0) - }; + None => (slice, "", 0), + } + } else { + (slice, "", 0) + }; println!("{}", out); (val.to_owned(), ncount) }; @@ -173,7 +189,7 @@ fn fold_file(mut file: BufReader, bytes: bool, spaces: bool, width: count = 0; continue; } - _ => count += 1 + _ => count += 1, }; output.push(ch); } diff --git a/src/groups/groups.rs b/src/groups/groups.rs index f4ba97501..a667b1a9c 100644 --- a/src/groups/groups.rs +++ b/src/groups/groups.rs @@ -12,20 +12,34 @@ #[macro_use] extern crate uucore; -use uucore::entries::{Passwd, Locate, get_groups, gid2grp}; +use uucore::entries::{get_groups, Locate, Passwd, gid2grp}; static SYNTAX: &'static str = "[user]"; static SUMMARY: &'static str = "display current group names"; pub fn uumain(args: Vec) -> i32 { - let matches = new_coreopts!(SYNTAX, SUMMARY, "") - .parse(args); + let matches = new_coreopts!(SYNTAX, SUMMARY, "").parse(args); if matches.free.is_empty() { - println!("{}", get_groups().unwrap().iter().map(|&g| gid2grp(g).unwrap()).collect::>().join(" ")); + println!( + "{}", + get_groups() + .unwrap() + .iter() + .map(|&g| gid2grp(g).unwrap()) + .collect::>() + .join(" ") + ); } else { if let Ok(p) = Passwd::locate(matches.free[0].as_str()) { - println!("{}", p.belongs_to().iter().map(|&g| gid2grp(g).unwrap()).collect::>().join(" ")); + println!( + "{}", + p.belongs_to() + .iter() + .map(|&g| gid2grp(g).unwrap()) + .collect::>() + .join(" ") + ); } else { crash!(1, "unknown user {}", matches.free[0]); } diff --git a/src/hashsum/digest.rs b/src/hashsum/digest.rs index 2f38a6278..d85403ee6 100644 --- a/src/hashsum/digest.rs +++ b/src/hashsum/digest.rs @@ -4,11 +4,13 @@ extern crate sha1; extern crate sha2; extern crate sha3; -use digest::digest::{Input, ExtendableOutput, XofReader}; +use digest::digest::{ExtendableOutput, Input, XofReader}; use hex::ToHex; pub trait Digest { - fn new() -> Self where Self: Sized; + fn new() -> Self + where + Self: Sized; fn input(&mut self, input: &[u8]); fn result(&mut self, out: &mut [u8]); fn reset(&mut self); @@ -40,7 +42,9 @@ impl Digest for md5::Context { *self = md5::Context::new(); } - fn output_bits(&self) -> usize { 128 } + fn output_bits(&self) -> usize { + 128 + } } impl Digest for sha1::Sha1 { @@ -60,7 +64,9 @@ impl Digest for sha1::Sha1 { self.reset(); } - fn output_bits(&self) -> usize { 160 } + fn output_bits(&self) -> usize { + 160 + } } // Implements the Digest trait for sha2 / sha3 algorithms with fixed ouput diff --git a/src/hashsum/hashsum.rs b/src/hashsum/hashsum.rs index 401544019..e71ed4f4e 100644 --- a/src/hashsum/hashsum.rs +++ b/src/hashsum/hashsum.rs @@ -14,8 +14,8 @@ extern crate getopts; extern crate hex; extern crate md5; -extern crate regex_syntax; extern crate regex; +extern crate regex_syntax; extern crate sha1; extern crate sha2; extern crate sha3; @@ -35,7 +35,7 @@ use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; #[allow(unused_imports)] use std::ascii::AsciiExt; use std::fs::File; -use std::io::{self, BufRead, BufReader, Read, stdin}; +use std::io::{self, stdin, BufRead, BufReader, Read}; use std::path::Path; static NAME: &'static str = "hashsum"; @@ -43,18 +43,17 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); fn is_custom_binary(program: &str) -> bool { match program { - "md5sum" | "sha1sum" - | "sha224sum" | "sha256sum" - | "sha384sum" | "sha512sum" - | "sha3sum" | "sha3-224sum" - | "sha3-256sum" | "sha3-384sum" - | "sha3-512sum" | "shake128sum" - | "shake256sum" => true, - _ => false + "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" + | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" + | "shake128sum" | "shake256sum" => true, + _ => false, } } -fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box, usize) { +fn detect_algo( + program: &str, + matches: &getopts::Matches, +) -> (&'static str, Box, usize) { let mut alg: Option> = None; let mut name: &'static str = ""; let mut output_bits = 0; @@ -65,92 +64,132 @@ fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box< "sha256sum" => ("SHA256", Box::new(Sha256::new()) as Box, 256), "sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box, 384), "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), - "sha3sum" => { - match matches.opt_str("bits") { - Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(224) => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), - Ok(256) => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), - Ok(384) => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), - Ok(512) => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), - Ok(_) => crash!(1, "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"), - Err(err) => crash!(1, "{}", err) - }, - None => crash!(1, "--bits required for SHA3") - } - } + "sha3sum" => match matches.opt_str("bits") { + Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { + Ok(224) => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), + Ok(256) => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), + Ok(384) => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), + Ok(512) => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), + Ok(_) => crash!( + 1, + "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" + ), + Err(err) => crash!(1, "{}", err), + }, + None => crash!(1, "--bits required for SHA3"), + }, "sha3-224sum" => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), "sha3-256sum" => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), "sha3-384sum" => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), "sha3-512sum" => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), - "shake128sum" => { - match matches.opt_str("bits") { - Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => ("SHAKE128", Box::new(Shake128::new()) as Box, bits), - Err(err) => crash!(1, "{}", err) - }, - None => crash!(1, "--bits required for SHAKE-128") - } - } - "shake256sum" => { - match matches.opt_str("bits") { - Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => ("SHAKE256", Box::new(Shake256::new()) as Box, bits), - Err(err) => crash!(1, "{}", err) - }, - None => crash!(1, "--bits required for SHAKE-256") - } - } + "shake128sum" => match matches.opt_str("bits") { + Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { + Ok(bits) => ("SHAKE128", Box::new(Shake128::new()) as Box, bits), + Err(err) => crash!(1, "{}", err), + }, + None => crash!(1, "--bits required for SHAKE-128"), + }, + "shake256sum" => match matches.opt_str("bits") { + Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { + Ok(bits) => ("SHAKE256", Box::new(Shake256::new()) as Box, bits), + Err(err) => crash!(1, "{}", err), + }, + None => crash!(1, "--bits required for SHAKE-256"), + }, _ => { { let mut set_or_crash = |n, val, bits| -> () { - if alg.is_some() { crash!(1, "You cannot combine multiple hash algorithms!") }; + if alg.is_some() { + crash!(1, "You cannot combine multiple hash algorithms!") + }; name = n; alg = Some(val); output_bits = bits }; - if matches.opt_present("md5") { set_or_crash("MD5", Box::new(Md5::new()), 128) } - if matches.opt_present("sha1") { set_or_crash("SHA1", Box::new(Sha1::new()), 160) } - if matches.opt_present("sha224") { set_or_crash("SHA224", Box::new(Sha224::new()), 224) } - if matches.opt_present("sha256") { set_or_crash("SHA256", Box::new(Sha256::new()), 256) } - if matches.opt_present("sha384") { set_or_crash("SHA384", Box::new(Sha384::new()), 384) } - if matches.opt_present("sha512") { set_or_crash("SHA512", Box::new(Sha512::new()), 512) } + if matches.opt_present("md5") { + set_or_crash("MD5", Box::new(Md5::new()), 128) + } + if matches.opt_present("sha1") { + set_or_crash("SHA1", Box::new(Sha1::new()), 160) + } + if matches.opt_present("sha224") { + set_or_crash("SHA224", Box::new(Sha224::new()), 224) + } + if matches.opt_present("sha256") { + set_or_crash("SHA256", Box::new(Sha256::new()), 256) + } + if matches.opt_present("sha384") { + set_or_crash("SHA384", Box::new(Sha384::new()), 384) + } + if matches.opt_present("sha512") { + set_or_crash("SHA512", Box::new(Sha512::new()), 512) + } if matches.opt_present("sha3") { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(224) => set_or_crash("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), - Ok(256) => set_or_crash("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), - Ok(384) => set_or_crash("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), - Ok(512) => set_or_crash("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), - Ok(_) => crash!(1, "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"), - Err(err) => crash!(1, "{}", err) + Ok(224) => set_or_crash( + "SHA3-224", + Box::new(Sha3_224::new()) as Box, + 224, + ), + Ok(256) => set_or_crash( + "SHA3-256", + Box::new(Sha3_256::new()) as Box, + 256, + ), + Ok(384) => set_or_crash( + "SHA3-384", + Box::new(Sha3_384::new()) as Box, + 384, + ), + Ok(512) => set_or_crash( + "SHA3-512", + Box::new(Sha3_512::new()) as Box, + 512, + ), + Ok(_) => crash!( + 1, + "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" + ), + Err(err) => crash!(1, "{}", err), }, - None => crash!(1, "--bits required for SHA3") + None => crash!(1, "--bits required for SHA3"), } } - if matches.opt_present("sha3-224") { set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224) } - if matches.opt_present("sha3-256") { set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256) } - if matches.opt_present("sha3-384") { set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384) } - if matches.opt_present("sha3-512") { set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512) } + if matches.opt_present("sha3-224") { + set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224) + } + if matches.opt_present("sha3-256") { + set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256) + } + if matches.opt_present("sha3-384") { + set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384) + } + if matches.opt_present("sha3-512") { + set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512) + } if matches.opt_present("shake128") { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { Ok(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), bits), - Err(err) => crash!(1, "{}", err) + Err(err) => crash!(1, "{}", err), }, - None => crash!(1, "--bits required for SHAKE-128") + None => crash!(1, "--bits required for SHAKE-128"), } } if matches.opt_present("shake256") { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { Ok(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), bits), - Err(err) => crash!(1, "{}", err) + Err(err) => crash!(1, "{}", err), }, - None => crash!(1, "--bits required for SHAKE-256") + None => crash!(1, "--bits required for SHAKE-256"), } } } - if alg.is_none() { crash!(1, "You must specify hash algorithm!") }; + if alg.is_none() { + crash!(1, "You must specify hash algorithm!") + }; (name, alg.unwrap(), output_bits) } } @@ -164,14 +203,52 @@ pub fn uumain(args: Vec) -> i32 { let binary_flag_default = cfg!(windows); let mut opts = getopts::Options::new(); - opts.optflag("b", "binary", &format!("read in binary mode{}", if binary_flag_default { " (default)" } else { "" })); + opts.optflag( + "b", + "binary", + &format!( + "read in binary mode{}", + if binary_flag_default { + " (default)" + } else { + "" + } + ), + ); opts.optflag("c", "check", "read hashsums from the FILEs and check them"); opts.optflag("", "tag", "create a BSD-style checksum"); - opts.optflag("t", "text", &format!("read in text mode{}", if binary_flag_default { "" } else { " (default)" })); - opts.optflag("q", "quiet", "don't print OK for each successfully verified file"); - opts.optflag("s", "status", "don't output anything, status code shows success"); - opts.optflag("", "strict", "exit non-zero for improperly formatted checksum lines"); - opts.optflag("w", "warn", "warn about improperly formatted checksum lines"); + opts.optflag( + "t", + "text", + &format!( + "read in text mode{}", + if binary_flag_default { + "" + } else { + " (default)" + } + ), + ); + opts.optflag( + "q", + "quiet", + "don't print OK for each successfully verified file", + ); + opts.optflag( + "s", + "status", + "don't output anything, status code shows success", + ); + opts.optflag( + "", + "strict", + "exit non-zero for improperly formatted checksum lines", + ); + opts.optflag( + "w", + "warn", + "warn about improperly formatted checksum lines", + ); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); @@ -187,16 +264,29 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("", "sha3-256", "work with SHA3-256"); opts.optflag("", "sha3-384", "work with SHA3-384"); opts.optflag("", "sha3-512", "work with SHA3-512"); - opts.optflag("", "shake128", "work with SHAKE128 using BITS for the output size"); - opts.optflag("", "shake256", "work with SHAKE256 using BITS for the output size"); + opts.optflag( + "", + "shake128", + "work with SHAKE128 using BITS for the output size", + ); + opts.optflag( + "", + "shake256", + "work with SHAKE256 using BITS for the output size", + ); } // Needed for variable-length output sums (e.g. SHAKE) - opts.optopt("", "bits", "set the size of the output (only for SHAKE)", "BITS"); + opts.optopt( + "", + "bits", + "set the size of the output (only for SHAKE)", + "BITS", + ); let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("help") { @@ -211,7 +301,13 @@ pub fn uumain(args: Vec) -> i32 { if binary_flag && text_flag { crash!(1, "cannot set binary and text mode at the same time"); } - let binary = if binary_flag { true } else if text_flag { false } else { binary_flag_default }; + let binary = if binary_flag { + true + } else if text_flag { + false + } else { + binary_flag_default + }; let check = matches.opt_present("check"); let tag = matches.opt_present("tag"); let status = matches.opt_present("status"); @@ -219,13 +315,25 @@ pub fn uumain(args: Vec) -> i32 { let strict = matches.opt_present("strict"); let warn = matches.opt_present("warn") && !status; let files = if matches.free.is_empty() { - vec!("-".to_owned()) + vec!["-".to_owned()] } else { matches.free }; - match hashsum(name, algo, files, binary, check, tag, status, quiet, strict, warn, bits) { + match hashsum( + name, + algo, + files, + binary, + check, + tag, + status, + quiet, + strict, + warn, + bits, + ) { Ok(()) => return 0, - Err(e) => return e + Err(e) => return e, } } @@ -240,90 +348,107 @@ fn usage(program: &str, binary_name: &str, opts: &getopts::Options) { let spec = if is_custom_binary(binary_name) { format!(" {} [OPTION]... [FILE]...", program) } else { - format!(" {} {{--md5|--sha1|--sha224|--sha256|--sha384|--sha512|\ - --sha3|--sha3-224|--sha3-256|--sha3-384|--sha3-512|\ - --shake128|--shake256}} [OPTION]... [FILE]...", program) + format!( + " {} {{--md5|--sha1|--sha224|--sha256|--sha384|--sha512|\ + --sha3|--sha3-224|--sha3-256|--sha3-384|--sha3-512|\ + --shake128|--shake256}} [OPTION]... [FILE]...", + program + ) }; - let msg = format!("{} {} + let msg = format!( + "{} {} Usage: {} -Compute and check message digests.", NAME, VERSION, spec); +Compute and check message digests.", + NAME, VERSION, spec + ); print!("{}", opts.usage(&msg)); } -fn hashsum(algoname: &str, mut digest: Box, files: Vec, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool, output_bits: usize) -> Result<(), i32> { +fn hashsum( + algoname: &str, + mut digest: Box, + files: Vec, + binary: bool, + check: bool, + tag: bool, + status: bool, + quiet: bool, + strict: bool, + warn: bool, + output_bits: usize, +) -> Result<(), i32> { let mut bad_format = 0; let mut failed = 0; - let binary_marker = if binary { - "*" - } else { - " " - }; + let binary_marker = if binary { "*" } else { " " }; for filename in &files { let filename: &str = filename; let stdin_buf; let file_buf; - let mut file = BufReader::new( - if filename == "-" { - stdin_buf = stdin(); - Box::new(stdin_buf) as Box - } else { - file_buf = safe_unwrap!(File::open(filename)); - Box::new(file_buf) as Box - } - ); + let mut file = BufReader::new(if filename == "-" { + stdin_buf = stdin(); + Box::new(stdin_buf) as Box + } else { + file_buf = safe_unwrap!(File::open(filename)); + Box::new(file_buf) as Box + }); if check { // Set up Regexes for line validation and parsing let bytes = digest.output_bits() / 4; - let gnu_re = safe_unwrap!( - Regex::new( - &format!( - r"^(?P[a-fA-F0-9]{{{}}}) (?P[ \*])(?P.*)", - bytes - ) - ) - ); - let bsd_re = safe_unwrap!( - Regex::new( - &format!( - r"^{algorithm} \((?P.*)\) = (?P[a-fA-F0-9]{{{digest_size}}})", - algorithm = algoname, - digest_size = bytes - ) - ) - ); + let gnu_re = safe_unwrap!(Regex::new(&format!( + r"^(?P[a-fA-F0-9]{{{}}}) (?P[ \*])(?P.*)", + bytes + ))); + let bsd_re = safe_unwrap!(Regex::new(&format!( + r"^{algorithm} \((?P.*)\) = (?P[a-fA-F0-9]{{{digest_size}}})", + algorithm = algoname, + digest_size = bytes + ))); let buffer = file; for (i, line) in buffer.lines().enumerate() { let line = safe_unwrap!(line); let (ck_filename, sum, binary_check) = match gnu_re.captures(&line) { - Some(caps) => (caps.name("fileName").unwrap().as_str(), - caps.name("digest").unwrap().as_str().to_ascii_lowercase(), - caps.name("binary").unwrap().as_str() == "*"), + Some(caps) => ( + caps.name("fileName").unwrap().as_str(), + caps.name("digest").unwrap().as_str().to_ascii_lowercase(), + caps.name("binary").unwrap().as_str() == "*", + ), None => match bsd_re.captures(&line) { - Some(caps) => (caps.name("fileName").unwrap().as_str(), - caps.name("digest").unwrap().as_str().to_ascii_lowercase(), - true), + Some(caps) => ( + caps.name("fileName").unwrap().as_str(), + caps.name("digest").unwrap().as_str().to_ascii_lowercase(), + true, + ), None => { bad_format += 1; if strict { return Err(1); } if warn { - show_warning!("{}: {}: improperly formatted {} checksum line", filename, i + 1, algoname); + show_warning!( + "{}: {}: improperly formatted {} checksum line", + filename, + i + 1, + algoname + ); } continue; } - } + }, }; let f = safe_unwrap!(File::open(ck_filename)); let mut ckf = BufReader::new(Box::new(f) as Box); - let real_sum = safe_unwrap!(digest_reader(&mut digest, &mut ckf, binary_check, output_bits)) - .to_ascii_lowercase(); + let real_sum = safe_unwrap!(digest_reader( + &mut digest, + &mut ckf, + binary_check, + output_bits + )).to_ascii_lowercase(); if sum == real_sum { if !quiet { println!("{}: OK", ck_filename); @@ -358,7 +483,12 @@ fn hashsum(algoname: &str, mut digest: Box, files: Vec, binary: Ok(()) } -fn digest_reader<'a, T: Read>(digest: &mut Box, reader: &mut BufReader, binary: bool, output_bits: usize) -> io::Result { +fn digest_reader<'a, T: Read>( + digest: &mut Box, + reader: &mut BufReader, + binary: bool, + output_bits: usize, +) -> io::Result { digest.reset(); // Digest file, do not hold too much in memory at any given moment @@ -368,11 +498,13 @@ fn digest_reader<'a, T: Read>(digest: &mut Box, reader: &mut BufReade let mut looking_for_newline = false; loop { match reader.read_to_end(&mut buffer) { - Ok(0) => { break; }, + Ok(0) => { + break; + } Ok(nread) => { if windows && !binary { // Windows text mode returns '\n' when reading '\r\n' - for i in 0 .. nread { + for i in 0..nread { if looking_for_newline { if buffer[i] != ('\n' as u8) { vec.push('\r' as u8); @@ -392,8 +524,8 @@ fn digest_reader<'a, T: Read>(digest: &mut Box, reader: &mut BufReade } else { digest.input(&buffer[..nread]); } - }, - Err(e) => return Err(e) + } + Err(e) => return Err(e), } } if windows && looking_for_newline { diff --git a/src/head/head.rs b/src/head/head.rs index eef3ee630..cd61e1082 100644 --- a/src/head/head.rs +++ b/src/head/head.rs @@ -14,7 +14,7 @@ #[macro_use] extern crate uucore; -use std::io::{BufRead, BufReader, Read, stdin}; +use std::io::{stdin, BufRead, BufReader, Read}; use std::fs::File; use std::path::Path; use std::str::from_utf8; @@ -47,13 +47,26 @@ pub fn uumain(args: Vec) -> i32 { // handle obsolete -number syntax let new_args = match obsolete(&args[0..]) { - (args, Some(n)) => { settings.mode = FilterMode::Lines(n); args }, - (args, None) => args + (args, Some(n)) => { + settings.mode = FilterMode::Lines(n); + args + } + (args, None) => args, }; let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .optopt("c", "bytes", "Print the first K bytes. With the leading '-', print all but the last K bytes", "[-]K") - .optopt("n", "lines", "Print the first K lines. With the leading '-', print all but the last K lines", "[-]K") + .optopt( + "c", + "bytes", + "Print the first K bytes. With the leading '-', print all but the last K bytes", + "[-]K", + ) + .optopt( + "n", + "lines", + "Print the first K lines. With the leading '-', print all but the last K lines", + "[-]K", + ) .optflag("q", "quiet", "never print headers giving file names") .optflag("v", "verbose", "always print headers giving file names") .optflag("h", "help", "display this help and exit") @@ -70,7 +83,7 @@ pub fn uumain(args: Vec) -> i32 { return 1; } match n.parse::() { - Ok(m) => { settings.mode = FilterMode::Lines(m) } + Ok(m) => settings.mode = FilterMode::Lines(m), Err(e) => { show_error!("invalid line count '{}': {}", n, e); return 1; @@ -80,13 +93,13 @@ pub fn uumain(args: Vec) -> i32 { None => match matches.opt_str("c") { Some(count) => match count.parse::() { Ok(m) => settings.mode = FilterMode::Bytes(m), - Err(e)=> { + Err(e) => { show_error!("invalid byte count '{}': {}", count, e); return 1; } }, None => {} - } + }, }; let quiet = matches.opt_present("q"); @@ -115,7 +128,9 @@ pub fn uumain(args: Vec) -> i32 { for file in &files { if settings.verbose { - if !firstime { println!(""); } + if !firstime { + println!(""); + } println!("==> {} <==", file); } firstime = false; @@ -147,21 +162,24 @@ fn obsolete(options: &[String]) -> (Vec, Option) { if current.len() > 1 && current[0] == '-' as u8 { let len = current.len(); - for pos in 1 .. len { + for pos in 1..len { // Ensure that the argument is only made out of digits - if !(current[pos] as char).is_numeric() { break; } + if !(current[pos] as char).is_numeric() { + break; + } // If this is the last number if pos == len - 1 { options.remove(a); - let number: Option = from_utf8(¤t[1..len]).unwrap().parse::().ok(); + let number: Option = + from_utf8(¤t[1..len]).unwrap().parse::().ok(); return (options, Some(number.unwrap())); } } } a += 1; - }; + } (options, None) } @@ -169,16 +187,12 @@ fn obsolete(options: &[String]) -> (Vec, Option) { // TODO: handle errors on read fn head(reader: &mut BufReader, settings: &Settings) -> bool { match settings.mode { - FilterMode::Bytes(count) => { - for byte in reader.bytes().take(count) { - print!("{}", byte.unwrap() as char); - } + FilterMode::Bytes(count) => for byte in reader.bytes().take(count) { + print!("{}", byte.unwrap() as char); + }, + FilterMode::Lines(count) => for line in reader.lines().take(count) { + println!("{}", line.unwrap()); }, - FilterMode::Lines(count) => { - for line in reader.lines().take(count) { - println!("{}", line.unwrap()); - } - } } true } diff --git a/src/hostid/hostid.rs b/src/hostid/hostid.rs index 05e31f7d4..a7c056502 100644 --- a/src/hostid/hostid.rs +++ b/src/hostid/hostid.rs @@ -16,9 +16,9 @@ extern crate uucore; use libc::c_long; -static SYNTAX: &'static str = "[options]"; -static SUMMARY: &'static str = ""; -static LONG_HELP: &'static str = ""; +static SYNTAX: &'static str = "[options]"; +static SUMMARY: &'static str = ""; +static LONG_HELP: &'static str = ""; pub enum Mode { HostId, @@ -27,29 +27,28 @@ pub enum Mode { } // currently rust libc interface doesn't include gethostid -extern { +extern "C" { pub fn gethostid() -> c_long; } pub fn uumain(args: Vec) -> i32 { - new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .parse(args); + new_coreopts!(SYNTAX, SUMMARY, LONG_HELP).parse(args); hostid(); 0 } fn hostid() { - /* - * POSIX says gethostid returns a "32-bit identifier" but is silent - * whether it's sign-extended. Turn off any sign-extension. This - * is a no-op unless unsigned int is wider than 32 bits. - */ + /* + * POSIX says gethostid returns a "32-bit identifier" but is silent + * whether it's sign-extended. Turn off any sign-extension. This + * is a no-op unless unsigned int is wider than 32 bits. + */ - let mut result:c_long; + let mut result: c_long; unsafe { result = gethostid(); } - result &= 0xffffffff; + result &= 0xffffffff; println!("{:0>8x}", result); } diff --git a/src/hostname/hostname.rs b/src/hostname/hostname.rs index 898e3c8b0..23ad3b4e9 100644 --- a/src/hostname/hostname.rs +++ b/src/hostname/hostname.rs @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ +extern crate getopts; extern crate libc; #[cfg(windows)] extern crate winapi; -extern crate getopts; #[macro_use] extern crate uucore; @@ -25,7 +25,7 @@ use std::net::ToSocketAddrs; use getopts::Matches; #[cfg(windows)] -use winapi::um::winsock2::{GetHostNameW, WSAStartup, WSACleanup}; +use winapi::um::winsock2::{GetHostNameW, WSACleanup, WSAStartup}; #[cfg(windows)] use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, SetComputerNameExW}; #[cfg(windows)] @@ -63,8 +63,10 @@ fn execute(args: Vec) -> i32 { let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optflag("d", "domain", "Display the name of the DNS domain if possible") .optflag("i", "ip-address", "Display the network address(es) of the host") - .optflag("f", "fqdn", "Display the FQDN (Fully Qualified Domain Name) (default)") // TODO: support --long - .optflag("s", "short", "Display the short hostname (the portion before the first dot) if possible") + // TODO: support --long + .optflag("f", "fqdn", "Display the FQDN (Fully Qualified Domain Name) (default)") + .optflag("s", "short", "Display the short hostname (the portion before the first dot) if \ + possible") .parse(args); match matches.free.len() { @@ -148,7 +150,10 @@ fn xgethostname() -> io::Result { let namelen = 256; let mut name: Vec = repeat(0).take(namelen).collect(); let err = unsafe { - gethostname(name.as_mut_ptr() as *mut libc::c_char, namelen as libc::size_t) + gethostname( + name.as_mut_ptr() as *mut libc::c_char, + namelen as libc::size_t, + ) }; if err == 0 { @@ -158,7 +163,10 @@ fn xgethostname() -> io::Result { last_char += 1; } - Ok(CStr::from_bytes_with_nul(&name[..last_char]).unwrap().to_string_lossy().into_owned()) + Ok(CStr::from_bytes_with_nul(&name[..last_char]) + .unwrap() + .to_string_lossy() + .into_owned()) } else { Err(io::Error::last_os_error()) } @@ -168,9 +176,7 @@ fn xgethostname() -> io::Result { fn xgethostname() -> io::Result { let namelen = 256; let mut name: Vec = repeat(0).take(namelen).collect(); - let err = unsafe { - GetHostNameW(name.as_mut_ptr(), namelen as libc::c_int) - }; + let err = unsafe { GetHostNameW(name.as_mut_ptr(), namelen as libc::c_int) }; if err == 0 { Ok(String::from_wide_null(&name)) @@ -183,9 +189,7 @@ fn xgethostname() -> io::Result { fn xsethostname(name: &str) -> io::Result<()> { let vec_name: Vec = name.bytes().map(|c| c as libc::c_char).collect(); - let err = unsafe { - sethostname(vec_name.as_ptr(), vec_name.len() as _) - }; + let err = unsafe { sethostname(vec_name.as_ptr(), vec_name.len() as _) }; if err != 0 { Err(io::Error::last_os_error()) @@ -200,9 +204,7 @@ fn xsethostname(name: &str) -> io::Result<()> { let wide_name = OsStr::new(name).to_wide_null(); - let err = unsafe { - SetComputerNameExW(ComputerNamePhysicalDnsHostname, wide_name.as_ptr()) - }; + let err = unsafe { SetComputerNameExW(ComputerNamePhysicalDnsHostname, wide_name.as_ptr()) }; if err == 0 { // NOTE: the above is correct, failure is when the function returns 0 apparently diff --git a/src/id/id.rs b/src/id/id.rs index 66eb4d8d2..0b87fb5ec 100644 --- a/src/id/id.rs +++ b/src/id/id.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_id"] - // This file is part of the uutils coreutils package. // // (c) Alan Andrade @@ -12,7 +11,6 @@ // http://ftp-archive.freebsd.org/mirror/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/id.c // http://www.opensource.apple.com/source/shell_cmds/shell_cmds-118/id/id.c // - #![allow(non_camel_case_types)] #![allow(dead_code)] @@ -20,8 +18,8 @@ extern crate uucore; pub use uucore::libc; use uucore::libc::{getlogin, uid_t}; -use uucore::entries::{self, Passwd, Group, Locate}; -use uucore::process::{getgid, getuid, getegid, geteuid}; +use uucore::entries::{self, Group, Locate, Passwd}; +use uucore::process::{getegid, geteuid, getgid, getuid}; use std::ffi::CStr; macro_rules! cstr2cow { @@ -33,7 +31,7 @@ macro_rules! cstr2cow { #[cfg(not(target_os = "linux"))] mod audit { pub use std::mem::uninitialized; - use super::libc::{uid_t, pid_t, c_int, c_uint, uint64_t, dev_t}; + use super::libc::{c_int, c_uint, dev_t, pid_t, uid_t, uint64_t}; pub type au_id_t = uid_t; pub type au_asid_t = pid_t; @@ -56,11 +54,11 @@ mod audit { #[repr(C)] pub struct c_auditinfo_addr { - pub ai_auid: au_id_t, // Audit user ID - pub ai_mask: au_mask_t, // Audit masks. + pub ai_auid: au_id_t, // Audit user ID + pub ai_mask: au_mask_t, // Audit masks. pub ai_termid: au_tid_addr_t, // Terminal ID. - pub ai_asid: au_asid_t, // Audit session ID. - pub ai_flags: uint64_t, // Audit session flags + pub ai_asid: au_asid_t, // Audit session ID. + pub ai_flags: uint64_t, // Audit session flags } pub type c_auditinfo_addr_t = c_auditinfo_addr; @@ -74,14 +72,18 @@ static SUMMARY: &'static str = "Print user and group information for the specifi pub fn uumain(args: Vec) -> i32 { let mut opts = new_coreopts!(SYNTAX, SUMMARY, ""); - opts.optflag("A", - "", - "Display the process audit (not available on Linux)"); + opts.optflag( + "A", + "", + "Display the process audit (not available on Linux)", + ); opts.optflag("G", "", "Display the different group IDs"); opts.optflag("g", "", "Display the effective group ID as a number"); - opts.optflag("n", - "", - "Display the name of the user or group ID for the -G, -g and -u options"); + opts.optflag( + "n", + "", + "Display the name of the user or group ID for the -G, -g and -u options", + ); opts.optflag("P", "", "Display the id as a password file entry"); opts.optflag("p", "", "Make the output human-readable"); opts.optflag("r", "", "Display the real ID for the -g and -u options"); @@ -109,52 +111,56 @@ pub fn uumain(args: Vec) -> i32 { let rflag = matches.opt_present("r"); if gflag { - let id = possible_pw.map(|p| p.gid()).unwrap_or(if rflag { - getgid() - } else { - getegid() - }); - println!("{}", - if nflag { - entries::gid2grp(id).unwrap_or(id.to_string()) - } else { - id.to_string() - }); + let id = possible_pw + .map(|p| p.gid()) + .unwrap_or(if rflag { getgid() } else { getegid() }); + println!( + "{}", + if nflag { + entries::gid2grp(id).unwrap_or(id.to_string()) + } else { + id.to_string() + } + ); return 0; } if uflag { - let id = possible_pw.map(|p| p.uid()).unwrap_or(if rflag { - getuid() - } else { - geteuid() - }); - println!("{}", - if nflag { - entries::uid2usr(id).unwrap_or(id.to_string()) - } else { - id.to_string() - }); + let id = possible_pw + .map(|p| p.uid()) + .unwrap_or(if rflag { getuid() } else { geteuid() }); + println!( + "{}", + if nflag { + entries::uid2usr(id).unwrap_or(id.to_string()) + } else { + id.to_string() + } + ); return 0; } if matches.opt_present("G") { - println!("{}", - if nflag { - possible_pw.map(|p| p.belongs_to()) - .unwrap_or(entries::get_groups().unwrap()) - .iter() - .map(|&id| entries::gid2grp(id).unwrap()) - .collect::>() - .join(" ") - } else { - possible_pw.map(|p| p.belongs_to()) - .unwrap_or(entries::get_groups().unwrap()) - .iter() - .map(|&id| id.to_string()) - .collect::>() - .join(" ") - }); + println!( + "{}", + if nflag { + possible_pw + .map(|p| p.belongs_to()) + .unwrap_or(entries::get_groups().unwrap()) + .iter() + .map(|&id| entries::gid2grp(id).unwrap()) + .collect::>() + .join(" ") + } else { + possible_pw + .map(|p| p.belongs_to()) + .unwrap_or(entries::get_groups().unwrap()) + .iter() + .map(|&id| id.to_string()) + .collect::>() + .join(" ") + } + ); return 0; } @@ -180,8 +186,14 @@ pub fn uumain(args: Vec) -> i32 { fn pretty(possible_pw: Option) { if let Some(p) = possible_pw { print!("uid\t{}\ngroups\t", p.name()); - println!("{}", - p.belongs_to().iter().map(|&gr| entries::gid2grp(gr).unwrap()).collect::>().join(" ")); + println!( + "{}", + p.belongs_to() + .iter() + .map(|&gr| entries::gid2grp(gr).unwrap()) + .collect::>() + .join(" ") + ); } else { let login = cstr2cow!(getlogin() as *const _); let rid = getuid(); @@ -212,13 +224,15 @@ fn pretty(possible_pw: Option) { } } - println!("groups\t{}", - entries::get_groups() - .unwrap() - .iter() - .map(|&gr| entries::gid2grp(gr).unwrap()) - .collect::>() - .join(" ")); + println!( + "groups\t{}", + entries::get_groups() + .unwrap() + .iter() + .map(|&gr| entries::gid2grp(gr).unwrap()) + .collect::>() + .join(" ") + ); } } @@ -227,17 +241,19 @@ fn pline(possible_uid: Option) { let uid = possible_uid.unwrap_or(getuid()); let pw = Passwd::locate(uid).unwrap(); - println!("{}:{}:{}:{}:{}:{}:{}:{}:{}:{}", - pw.name(), - pw.user_passwd(), - pw.uid(), - pw.gid(), - pw.user_access_class(), - pw.passwd_change_time(), - pw.expiration(), - pw.user_info(), - pw.user_dir(), - pw.user_shell()); + println!( + "{}:{}:{}:{}:{}:{}:{}:{}:{}:{}", + pw.name(), + pw.user_passwd(), + pw.uid(), + pw.gid(), + pw.user_access_class(), + pw.passwd_change_time(), + pw.expiration(), + pw.user_info(), + pw.user_dir(), + pw.user_shell() + ); } #[cfg(target_os = "linux")] @@ -245,14 +261,16 @@ fn pline(possible_uid: Option) { let uid = possible_uid.unwrap_or(getuid()); let pw = Passwd::locate(uid).unwrap(); - println!("{}:{}:{}:{}:{}:{}:{}", - pw.name(), - pw.user_passwd(), - pw.uid(), - pw.gid(), - pw.user_info(), - pw.user_dir(), - pw.user_shell()); + println!( + "{}:{}:{}:{}:{}:{}:{}", + pw.name(), + pw.user_passwd(), + pw.uid(), + pw.gid(), + pw.user_info(), + pw.user_dir(), + pw.user_shell() + ); } #[cfg(target_os = "linux")] @@ -275,7 +293,9 @@ fn auditid() { } fn id_print(possible_pw: Option, p_euid: bool, p_egid: bool) { - let (uid, gid) = possible_pw.map(|p| (p.uid(), p.gid())).unwrap_or((getuid(), getgid()));; + let (uid, gid) = possible_pw + .map(|p| (p.uid(), p.gid())) + .unwrap_or((getuid(), getgid())); let groups = Passwd::locate(uid).unwrap().belongs_to(); @@ -292,9 +312,12 @@ fn id_print(possible_pw: Option, p_euid: bool, p_egid: bool) { print!(" egid={}({})", euid, entries::gid2grp(egid).unwrap()); } - println!(" groups={}", - groups.iter() - .map(|&gr| format!("{}({})", gr, entries::gid2grp(gr).unwrap())) - .collect::>() - .join(",")); + println!( + " groups={}", + groups + .iter() + .map(|&gr| format!("{}({})", gr, entries::gid2grp(gr).unwrap())) + .collect::>() + .join(",") + ); } diff --git a/src/install/install.rs b/src/install/install.rs index fbd1b41cd..dc7b8d223 100644 --- a/src/install/install.rs +++ b/src/install/install.rs @@ -33,7 +33,7 @@ pub struct Behaviour { main_function: MainFunction, specified_mode: Option, suffix: String, - verbose: bool + verbose: bool, } #[derive(Clone, Eq, PartialEq)] @@ -41,7 +41,7 @@ pub enum MainFunction { /// Create directories Directory, /// Install files to locations (primary functionality) - Standard + Standard, } impl Behaviour { @@ -49,7 +49,7 @@ impl Behaviour { pub fn mode(&self) -> u32 { match self.specified_mode { Some(x) => x, - None => DEFAULT_MODE + None => DEFAULT_MODE, } } } @@ -84,12 +84,8 @@ pub fn uumain(args: Vec) -> i32 { }; match behaviour.main_function { - MainFunction::Directory => { - directory(&paths[..], behaviour) - }, - MainFunction::Standard => { - standard(&paths[..], behaviour) - } + MainFunction::Directory => directory(&paths[..], behaviour), + MainFunction::Standard => standard(&paths[..], behaviour), } } @@ -98,9 +94,12 @@ pub fn uumain(args: Vec) -> i32 { /// Returns a getopts::Options struct. /// fn parse_opts(args: Vec) -> getopts::Matches { - let syntax = format!("SOURCE DEST - {} SOURCE... DIRECTORY", NAME); - new_coreopts!(&syntax, SUMMARY, LONG_HELP) + let syntax = format!( + "SOURCE DEST + {} SOURCE... DIRECTORY", + NAME + ); + new_coreopts!(&syntax, SUMMARY, LONG_HELP) // TODO implement flag .optflagopt("", "backup", "(unimplemented) make a backup of each existing destination\n \ file", "CONTROL") @@ -208,18 +207,19 @@ fn behaviour(matches: &getopts::Matches) -> Result { let specified_mode: Option = if matches.opt_present("mode") { match matches.opt_str("mode") { - Some(x) => { - match mode::parse(&x[..], considering_dir) { - Ok(y) => Some(y), - Err(err) => { - show_error!("Invalid mode string: {}", err); - return Err(1); - } + Some(x) => match mode::parse(&x[..], considering_dir) { + Ok(y) => Some(y), + Err(err) => { + show_error!("Invalid mode string: {}", err); + return Err(1); } }, None => { - show_error!("option '--mode' requires an argument\n \ - Try '{} --help' for more information.", NAME); + show_error!( + "option '--mode' requires an argument\n \ + Try '{} --help' for more information.", + NAME + ); return Err(1); } } @@ -231,8 +231,11 @@ fn behaviour(matches: &getopts::Matches) -> Result { match matches.opt_str("suffix") { Some(x) => x, None => { - show_error!("option '--suffix' requires an argument\n\ - Try '{} --help' for more information.", NAME); + show_error!( + "option '--suffix' requires an argument\n\ + Try '{} --help' for more information.", + NAME + ); return Err(1); } } @@ -283,15 +286,18 @@ fn directory(paths: &[PathBuf], b: Behaviour) -> i32 { show_info!("created directory '{}'", path.display()); } } - if all_successful { 0 } else { 1 } + if all_successful { + 0 + } else { + 1 + } } } /// Test if the path is a a new file path that can be /// created immediately fn is_new_file_path(path: &Path) -> bool { - path.is_file() || - ! path.exists() && path.parent().map(|p| p.is_dir()).unwrap_or(true) + path.is_file() || !path.exists() && path.parent().map(|p| p.is_dir()).unwrap_or(true) } /// Perform an install, given a list of paths and behaviour. @@ -335,8 +341,10 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behaviour) - let targetpath = match sourcepath.as_os_str().to_str() { Some(name) => target_dir.join(name), None => { - show_error!("cannot stat ‘{}’: No such file or directory", - sourcepath.display()); + show_error!( + "cannot stat ‘{}’: No such file or directory", + sourcepath.display() + ); all_successful = false; continue; @@ -346,8 +354,12 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behaviour) - if copy(sourcepath, &targetpath, b).is_err() { all_successful = false; } - }; - if all_successful { 0 } else { 1 } + } + if all_successful { + 0 + } else { + 1 + } } /// Copy a file to another file. @@ -361,7 +373,11 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behaviour) - /// _target_ must be a non-directory /// fn copy_file_to_file(file: &PathBuf, target: &PathBuf, b: &Behaviour) -> i32 { - if copy(file, &target, b).is_err() { 1 } else { 0 } + if copy(file, &target, b).is_err() { + 1 + } else { + 0 + } } /// Copy one file to a new location, changing metadata. @@ -379,8 +395,12 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<(), ()> { let io_result = fs::copy(from, to); if let Err(err) = io_result { - show_error!("install: cannot install ‘{}’ to ‘{}’: {}", - from.display(), to.display(), err); + show_error!( + "install: cannot install ‘{}’ to ‘{}’: {}", + from.display(), + to.display(), + err + ); return Err(()); } diff --git a/src/join/join.rs b/src/join/join.rs index 30acc5d09..6cc2ed13d 100644 --- a/src/join/join.rs +++ b/src/join/join.rs @@ -410,65 +410,90 @@ pub fn uumain(args: Vec) -> i32 { "For each pair of input lines with identical join fields, write a line to standard output. The default join field is the first, delimited by blanks. -When FILE1 or FILE2 (not both) is -, read standard input.") +When FILE1 or FILE2 (not both) is -, read standard input.", + ) .help_message("display this help and exit") .version_message("display version and exit") - .arg(Arg::with_name("a") - .short("a") - .takes_value(true) - .possible_values(&["1", "2"]) - .value_name("FILENUM") - .help("also print unpairable lines from file FILENUM, where -FILENUM is 1 or 2, corresponding to FILE1 or FILE2")) - .arg(Arg::with_name("e") - .short("e") - .takes_value(true) - .value_name("EMPTY") - .help("replace missing input fields with EMPTY")) - .arg(Arg::with_name("i") - .short("i") - .long("ignore-case") - .help("ignore differences in case when comparing fields")) - .arg(Arg::with_name("j") - .short("j") - .takes_value(true) - .value_name("FIELD") - .help("equivalent to '-1 FIELD -2 FIELD'")) - .arg(Arg::with_name("o") - .short("o") - .takes_value(true) - .value_name("FORMAT") - .help("obey FORMAT while constructing output line")) - .arg(Arg::with_name("t") - .short("t") - .takes_value(true) - .value_name("CHAR") - .help("use CHAR as input and output field separator")) - .arg(Arg::with_name("1") - .short("1") - .takes_value(true) - .value_name("FIELD") - .help("join on this FIELD of file 1")) - .arg(Arg::with_name("2") - .short("2") - .takes_value(true) - .value_name("FIELD") - .help("join on this FIELD of file 2")) - .arg(Arg::with_name("check-order") - .long("check-order") - .help("check that the input is correctly sorted, \ - even if all input lines are pairable")) - .arg(Arg::with_name("nocheck-order") - .long("nocheck-order") - .help("do not check that the input is correctly sorted")) - .arg(Arg::with_name("file1") - .required(true) - .value_name("FILE1") - .hidden(true)) - .arg(Arg::with_name("file2") - .required(true) - .value_name("FILE2") - .hidden(true)) + .arg( + Arg::with_name("a") + .short("a") + .takes_value(true) + .possible_values(&["1", "2"]) + .value_name("FILENUM") + .help( + "also print unpairable lines from file FILENUM, where +FILENUM is 1 or 2, corresponding to FILE1 or FILE2", + ), + ) + .arg( + Arg::with_name("e") + .short("e") + .takes_value(true) + .value_name("EMPTY") + .help("replace missing input fields with EMPTY"), + ) + .arg( + Arg::with_name("i") + .short("i") + .long("ignore-case") + .help("ignore differences in case when comparing fields"), + ) + .arg( + Arg::with_name("j") + .short("j") + .takes_value(true) + .value_name("FIELD") + .help("equivalent to '-1 FIELD -2 FIELD'"), + ) + .arg( + Arg::with_name("o") + .short("o") + .takes_value(true) + .value_name("FORMAT") + .help("obey FORMAT while constructing output line"), + ) + .arg( + Arg::with_name("t") + .short("t") + .takes_value(true) + .value_name("CHAR") + .help("use CHAR as input and output field separator"), + ) + .arg( + Arg::with_name("1") + .short("1") + .takes_value(true) + .value_name("FIELD") + .help("join on this FIELD of file 1"), + ) + .arg( + Arg::with_name("2") + .short("2") + .takes_value(true) + .value_name("FIELD") + .help("join on this FIELD of file 2"), + ) + .arg(Arg::with_name("check-order").long("check-order").help( + "check that the input is correctly sorted, \ + even if all input lines are pairable", + )) + .arg( + Arg::with_name("nocheck-order") + .long("nocheck-order") + .help("do not check that the input is correctly sorted"), + ) + .arg( + Arg::with_name("file1") + .required(true) + .value_name("FILE1") + .hidden(true), + ) + .arg( + Arg::with_name("file2") + .required(true) + .value_name("FILE2") + .hidden(true), + ) .get_matches_from(args); let keys = parse_field_number_option(matches.value_of("j")); diff --git a/src/kill/kill.rs b/src/kill/kill.rs index 4510b1cc0..1f9a69829 100644 --- a/src/kill/kill.rs +++ b/src/kill/kill.rs @@ -22,7 +22,7 @@ static SYNTAX: &'static str = "[options] [...]"; static SUMMARY: &'static str = ""; static LONG_HELP: &'static str = ""; -static EXIT_OK: i32 = 0; +static EXIT_OK: i32 = 0; static EXIT_ERR: i32 = 1; #[derive(Clone, Copy)] @@ -36,7 +36,12 @@ pub fn uumain(args: Vec) -> i32 { let (args, obs_signal) = handle_obsolete(args); let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) .optopt("s", "signal", "specify the to be sent", "SIGNAL") - .optflagopt("l", "list", "list all signal names, or convert one to a name", "LIST") + .optflagopt( + "l", + "list", + "list all signal names, or convert one to a name", + "LIST", + ) .optflag("L", "table", "list all signal names in a nice table") .parse(args); @@ -49,9 +54,16 @@ pub fn uumain(args: Vec) -> i32 { }; match mode { - Mode::Kill => return kill(&matches.opt_str("signal").unwrap_or(obs_signal.unwrap_or("9".to_owned())), matches.free), - Mode::Table => table(), - Mode::List => list(matches.opt_str("list")), + Mode::Kill => { + return kill( + &matches + .opt_str("signal") + .unwrap_or(obs_signal.unwrap_or("9".to_owned())), + matches.free, + ) + } + Mode::Table => table(), + Mode::List => list(matches.opt_str("list")), } 0 @@ -62,7 +74,9 @@ fn handle_obsolete(mut args: Vec) -> (Vec, Option) { while i < args.len() { // this is safe because slice is valid when it is referenced let slice = &args[i].clone(); - if slice.chars().next().unwrap() == '-' && slice.len() > 1 && slice.chars().nth(1).unwrap().is_digit(10) { + if slice.chars().next().unwrap() == '-' && slice.len() > 1 + && slice.chars().nth(1).unwrap().is_digit(10) + { let val = &slice[1..]; match val.parse() { Ok(num) => { @@ -71,7 +85,7 @@ fn handle_obsolete(mut args: Vec) -> (Vec, Option) { return (args, Some(val.to_owned())); } } - Err(_)=> break /* getopts will error out for us */ + Err(_) => break, /* getopts will error out for us */ } } i += 1; @@ -89,10 +103,10 @@ fn table() { } for (idx, signal) in ALL_SIGNALS.iter().enumerate() { - print!("{0: >#2} {1: <#8}", idx+1, signal.name); + print!("{0: >#2} {1: <#8}", idx + 1, signal.name); //TODO: obtain max signal width here - if (idx+1) % 7 == 0 { + if (idx + 1) % 7 == 0 { println!(""); } } @@ -100,7 +114,9 @@ fn table() { fn print_signal(signal_name_or_value: &str) { for signal in &ALL_SIGNALS { - if signal.name == signal_name_or_value || (format!("SIG{}", signal.name)) == signal_name_or_value { + if signal.name == signal_name_or_value + || (format!("SIG{}", signal.name)) == signal_name_or_value + { println!("{}", signal.value); exit!(EXIT_OK as i32) } else if signal_name_or_value == signal.value.to_string() { @@ -128,8 +144,8 @@ fn print_signals() { fn list(arg: Option) { match arg { - Some(ref x) => print_signal(x), - None => print_signals(), + Some(ref x) => print_signal(x), + None => print_signals(), }; } @@ -138,7 +154,7 @@ fn kill(signalname: &str, pids: std::vec::Vec) -> i32 { let optional_signal_value = uucore::signals::signal_by_name_or_value(signalname); let signal_value = match optional_signal_value { Some(x) => x, - None => crash!(EXIT_ERR, "unknown signal name {}", signalname) + None => crash!(EXIT_ERR, "unknown signal name {}", signalname), }; for pid in &pids { match pid.parse::() { @@ -147,8 +163,8 @@ fn kill(signalname: &str, pids: std::vec::Vec) -> i32 { show_error!("{}", Error::last_os_error()); status = 1; } - }, - Err(e) => crash!(EXIT_ERR, "failed to parse argument {}: {}", pid, e) + } + Err(e) => crash!(EXIT_ERR, "failed to parse argument {}: {}", pid, e), }; } status diff --git a/src/link/link.rs b/src/link/link.rs index 72910866d..9a53f1106 100644 --- a/src/link/link.rs +++ b/src/link/link.rs @@ -22,14 +22,13 @@ static LONG_HELP: &'static str = ""; pub fn normalize_error_message(e: Error) -> String { match e.raw_os_error() { - Some(2) => { String::from("No such file or directory (os error 2)") } - _ => { format!("{}", e) } + Some(2) => String::from("No such file or directory (os error 2)"), + _ => format!("{}", e), } } pub fn uumain(args: Vec) -> i32 { - let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) - .parse(args); + let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP).parse(args); if matches.free.len() != 2 { crash!(1, "{}", msg_wrong_number_of_arguments!(2)); } @@ -40,7 +39,7 @@ pub fn uumain(args: Vec) -> i32 { match hard_link(old, new) { Ok(_) => 0, Err(err) => { - show_error!("{}",normalize_error_message(err)); + show_error!("{}", normalize_error_message(err)); 1 } } diff --git a/src/ln/ln.rs b/src/ln/ln.rs index 7e006bd3c..68e4d173b 100644 --- a/src/ln/ln.rs +++ b/src/ln/ln.rs @@ -9,14 +9,15 @@ * file that was distributed with this source code. */ - #[macro_use] extern crate uucore; use std::fs; -use std::io::{BufRead, BufReader, Result, stdin}; -#[cfg(unix)] use std::os::unix::fs::symlink; -#[cfg(windows)] use std::os::windows::fs::{symlink_file,symlink_dir}; +use std::io::{stdin, BufRead, BufReader, Result}; +#[cfg(unix)] +use std::os::unix::fs::symlink; +#[cfg(windows)] +use std::os::windows::fs::{symlink_dir, symlink_file}; use std::path::{Path, PathBuf}; static NAME: &'static str = "ln"; @@ -58,23 +59,31 @@ pub enum BackupMode { } pub fn uumain(args: Vec) -> i32 { - let syntax = format!("[OPTION]... [-T] TARGET LINK_NAME (1st form) + let syntax = format!( + "[OPTION]... [-T] TARGET LINK_NAME (1st form) {0} [OPTION]... TARGET (2nd form) {0} [OPTION]... TARGET... DIRECTORY (3rd form) - {0} [OPTION]... -t DIRECTORY TARGET... (4th form)", NAME); + {0} [OPTION]... -t DIRECTORY TARGET... (4th form)", + NAME + ); let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP) - .optflag("b", "", "make a backup of each file that would otherwise be overwritten or removed") - .optflagopt("", "backup", "make a backup of each file that would otherwise be overwritten or removed", "METHOD") - // TODO: opts.optflag("d", "directory", "allow users with appropriate privileges to attempt to make hard links to directories"); + .optflag("b", "", "make a backup of each file that would otherwise be overwritten or \ + removed") + .optflagopt("", "backup", "make a backup of each file that would otherwise be overwritten \ + or removed", "METHOD") + // TODO: opts.optflag("d", "directory", "allow users with appropriate privileges to attempt \ + // to make hard links to directories"); .optflag("f", "force", "remove existing destination files") .optflag("i", "interactive", "prompt whether to remove existing destination files") // TODO: opts.optflag("L", "logical", "dereference TARGETs that are symbolic links"); - // TODO: opts.optflag("n", "no-dereference", "treat LINK_NAME as a normal file if it is a symbolic link to a directory"); + // TODO: opts.optflag("n", "no-dereference", "treat LINK_NAME as a normal file if it is a \ + // symbolic link to a directory"); // TODO: opts.optflag("P", "physical", "make hard links directly to symbolic links"); // TODO: opts.optflag("r", "relative", "create symbolic links relative to link location"); .optflag("s", "symbolic", "make symbolic links instead of hard links") .optopt("S", "suffix", "override the usual backup suffix", "SUFFIX") - .optopt("t", "target-directory", "specify the DIRECTORY in which to create the links", "DIRECTORY") + .optopt("t", "target-directory", "specify the DIRECTORY in which to create the links", + "DIRECTORY") .optflag("T", "no-target-directory", "treat LINK_NAME as a normal file always") .optflag("v", "verbose", "print name of each linked file") .parse(args); @@ -94,15 +103,19 @@ pub fn uumain(args: Vec) -> i32 { None => BackupMode::ExistingBackup, Some(mode) => match &mode[..] { "simple" | "never" => BackupMode::SimpleBackup, - "numbered" | "t" => BackupMode::NumberedBackup, + "numbered" | "t" => BackupMode::NumberedBackup, "existing" | "nil" => BackupMode::ExistingBackup, - "none" | "off" => BackupMode::NoBackup, + "none" | "off" => BackupMode::NoBackup, x => { - show_error!("invalid argument '{}' for 'backup method'\n\ - Try '{} --help' for more information.", x, NAME); + show_error!( + "invalid argument '{}' for 'backup method'\n\ + Try '{} --help' for more information.", + x, + NAME + ); return 1; } - } + }, } } else { BackupMode::NoBackup @@ -112,8 +125,11 @@ pub fn uumain(args: Vec) -> i32 { match matches.opt_str("suffix") { Some(x) => x, None => { - show_error!("option '--suffix' requires an argument\n\ - Try '{} --help' for more information.", NAME); + show_error!( + "option '--suffix' requires an argument\n\ + Try '{} --help' for more information.", + NAME + ); return 1; } } @@ -136,7 +152,7 @@ pub fn uumain(args: Vec) -> i32 { verbose: matches.opt_present("v"), }; - let string_to_path = |s: &String| { PathBuf::from(s) }; + let string_to_path = |s: &String| PathBuf::from(s); let paths: Vec = matches.free.iter().map(string_to_path).collect(); exec(&paths[..], &settings) @@ -144,7 +160,10 @@ pub fn uumain(args: Vec) -> i32 { fn exec(files: &[PathBuf], settings: &Settings) -> i32 { if files.len() == 0 { - show_error!("missing file operand\nTry '{} --help' for more information.", NAME); + show_error!( + "missing file operand\nTry '{} --help' for more information.", + NAME + ); return 1; } @@ -161,18 +180,25 @@ fn exec(files: &[PathBuf], settings: &Settings) -> i32 { let last_file = &PathBuf::from(files.last().unwrap()); if files.len() > 2 || last_file.is_dir() { // 3rd form: create links in the last argument. - return link_files_in_dir(&files[0..files.len()-1], last_file, &settings); + return link_files_in_dir(&files[0..files.len() - 1], last_file, &settings); } } // 1st form. Now there should be only two operands, but if -T is // specified we may have a wrong number of operands. if files.len() == 1 { - show_error!("missing destination file operand after '{}'", files[0].to_string_lossy()); + show_error!( + "missing destination file operand after '{}'", + files[0].to_string_lossy() + ); return 1; } if files.len() > 2 { - show_error!("extra operand '{}'\nTry '{} --help' for more information.", files[2].display(), NAME); + show_error!( + "extra operand '{}'\nTry '{} --help' for more information.", + files[2].display(), + NAME + ); return 1; } assert!(files.len() != 0); @@ -206,20 +232,30 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &PathBuf, settings: &Setting } } None => { - show_error!("cannot stat '{}': No such file or directory", - srcpath.display()); + show_error!( + "cannot stat '{}': No such file or directory", + srcpath.display() + ); all_successful = false; continue; } }; if let Err(e) = link(srcpath, &targetpath, settings) { - show_error!("cannot link '{}' to '{}': {}", - targetpath.display(), srcpath.display(), e); + show_error!( + "cannot link '{}' to '{}': {}", + targetpath.display(), + srcpath.display(), + e + ); all_successful = false; } } - if all_successful { 0 } else { 1 } + if all_successful { + 0 + } else { + 1 + } } fn link(src: &PathBuf, dst: &PathBuf, settings: &Settings) -> Result<()> { @@ -227,24 +263,22 @@ fn link(src: &PathBuf, dst: &PathBuf, settings: &Settings) -> Result<()> { if is_symlink(dst) || dst.exists() { match settings.overwrite { - OverwriteMode::NoClobber => {}, + OverwriteMode::NoClobber => {} OverwriteMode::Interactive => { print!("{}: overwrite '{}'? ", NAME, dst.display()); if !read_yes() { return Ok(()); } try!(fs::remove_file(dst)) - }, - OverwriteMode::Force => { - try!(fs::remove_file(dst)) } + OverwriteMode::Force => try!(fs::remove_file(dst)), }; backup_path = match settings.backup { BackupMode::NoBackup => None, BackupMode::SimpleBackup => Some(simple_backup_path(dst, &settings.suffix)), BackupMode::NumberedBackup => Some(numbered_backup_path(dst)), - BackupMode::ExistingBackup => Some(existing_backup_path(dst, &settings.suffix)) + BackupMode::ExistingBackup => Some(existing_backup_path(dst, &settings.suffix)), }; if let Some(ref p) = backup_path { try!(fs::rename(dst, p)); @@ -261,7 +295,7 @@ fn link(src: &PathBuf, dst: &PathBuf, settings: &Settings) -> Result<()> { print!("'{}' -> '{}'", dst.display(), src.display()); match backup_path { Some(path) => println!(" (backup: '{}')", path.display()), - None => println!("") + None => println!(""), } } Ok(()) @@ -272,9 +306,9 @@ fn read_yes() -> bool { match BufReader::new(stdin()).read_line(&mut s) { Ok(_) => match s.char_indices().nth(0) { Some((_, x)) => x == 'y' || x == 'Y', - _ => false + _ => false, }, - _ => false + _ => false, } } @@ -305,19 +339,16 @@ fn existing_backup_path(path: &PathBuf, suffix: &str) -> PathBuf { #[cfg(windows)] pub fn symlink>(src: P, dst: P) -> Result<()> { - if src.as_ref().is_dir() - { - symlink_dir(src,dst) - } - else - { - symlink_file(src,dst) + if src.as_ref().is_dir() { + symlink_dir(src, dst) + } else { + symlink_file(src, dst) } } pub fn is_symlink>(path: P) -> bool { match fs::symlink_metadata(path) { Ok(m) => m.file_type().is_symlink(), - Err(_) => false + Err(_) => false, } } diff --git a/src/logname/logname.rs b/src/logname/logname.rs index 233ce2f16..d573f2cee 100644 --- a/src/logname/logname.rs +++ b/src/logname/logname.rs @@ -18,7 +18,7 @@ extern crate uucore; use std::ffi::CStr; -extern { +extern "C" { // POSIX requires using getlogin (or equivalent code) pub fn getlogin() -> *const libc::c_char; } @@ -49,6 +49,6 @@ pub fn uumain(args: Vec) -> i32 { fn exec() { match get_userlogin() { Some(userlogin) => println!("{}", userlogin), - None => show_error!("no login name") + None => show_error!("no login name"), } } diff --git a/src/ls/ls.rs b/src/ls/ls.rs index 63d77fc05..119617b7d 100644 --- a/src/ls/ls.rs +++ b/src/ls/ls.rs @@ -10,13 +10,13 @@ extern crate getopts; extern crate pretty_bytes; -extern crate termsize; extern crate term_grid; +extern crate termsize; extern crate time; extern crate unicode_width; use pretty_bytes::converter::convert; -use term_grid::{Grid, GridOptions, Direction, Filling, Cell}; -use time::{Timespec, strftime}; +use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; +use time::{strftime, Timespec}; #[macro_use] extern crate lazy_static; @@ -24,8 +24,8 @@ extern crate lazy_static; #[macro_use] extern crate uucore; #[cfg(unix)] -use uucore::libc::{S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, - S_IROTH, S_IWOTH, S_IXOTH, mode_t}; +use uucore::libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, + S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR}; use std::fs; use std::fs::{DirEntry, FileType, Metadata}; @@ -76,65 +76,86 @@ lazy_static! { } pub fn uumain(args: Vec) -> i32 { - let syntax = format!("[OPTION]... DIRECTORY - {0} [OPTION]... [FILE]...", NAME); + let syntax = format!( + "[OPTION]... DIRECTORY + {0} [OPTION]... [FILE]...", + NAME + ); let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP) - .optflag("a", - "all", - "Do not ignore hidden files (files with names that start with '.').") - .optflag("A", - "almost-all", - "In a directory, do not ignore all file names that start with '.', only ignore \ - '.' and '..'.") - .optflag("B", - "ignore-backups", - "Ignore entries which end with ~.") - .optflag("c", - "", - "If the long listing format (e.g., -l, -o) is being used, print the status \ - change time (the ‘ctime’ in the inode) instead of the modification time. When \ - explicitly sorting by time (--sort=time or -t) or when not using a long listing \ - format, sort according to the status change time.") - .optflag("d", - "directory", - "Only list the names of directories, rather than listing directory contents. \ - This will not follow symbolic links unless one of `--dereference-command-line \ - (-H)`, `--dereference (-L)`, or `--dereference-command-line-symlink-to-dir` is \ - specified.") - .optflag("F", - "classify", - "Append a character to each file name indicating the file type. Also, for \ - regular files that are executable, append '*'. The file type indicators are \ - '/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, \ - '>' for doors, and nothing for regular files.") - .optflag("h", - "human-readable", - "Print human readable file sizes (e.g. 1K 234M 56G).") - .optflag("i", - "inode", - "print the index number of each file") - .optflag("L", - "dereference", - "When showing file information for a symbolic link, show information for the \ - file the link references rather than the link itself.") + .optflag( + "a", + "all", + "Do not ignore hidden files (files with names that start with '.').", + ) + .optflag( + "A", + "almost-all", + "In a directory, do not ignore all file names that start with '.', only ignore \ + '.' and '..'.", + ) + .optflag("B", "ignore-backups", "Ignore entries which end with ~.") + .optflag( + "c", + "", + "If the long listing format (e.g., -l, -o) is being used, print the status \ + change time (the ‘ctime’ in the inode) instead of the modification time. When \ + explicitly sorting by time (--sort=time or -t) or when not using a long listing \ + format, sort according to the status change time.", + ) + .optflag( + "d", + "directory", + "Only list the names of directories, rather than listing directory contents. \ + This will not follow symbolic links unless one of `--dereference-command-line \ + (-H)`, `--dereference (-L)`, or `--dereference-command-line-symlink-to-dir` is \ + specified.", + ) + .optflag( + "F", + "classify", + "Append a character to each file name indicating the file type. Also, for \ + regular files that are executable, append '*'. The file type indicators are \ + '/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, \ + '>' for doors, and nothing for regular files.", + ) + .optflag( + "h", + "human-readable", + "Print human readable file sizes (e.g. 1K 234M 56G).", + ) + .optflag("i", "inode", "print the index number of each file") + .optflag( + "L", + "dereference", + "When showing file information for a symbolic link, show information for the \ + file the link references rather than the link itself.", + ) .optflag("l", "long", "Display detailed information.") .optflag("n", "numeric-uid-gid", "-l with numeric UIDs and GIDs.") - .optflag("r", - "reverse", - "Reverse whatever the sorting method is--e.g., list files in reverse \ - alphabetical order, youngest first, smallest first, or whatever.") - .optflag("R", - "recursive", - "List the contents of all directories recursively.") + .optflag( + "r", + "reverse", + "Reverse whatever the sorting method is--e.g., list files in reverse \ + alphabetical order, youngest first, smallest first, or whatever.", + ) + .optflag( + "R", + "recursive", + "List the contents of all directories recursively.", + ) .optflag("S", "", "Sort by file size, largest first.") - .optflag("t", - "", - "Sort by modification time (the 'mtime' in the inode), newest first.") - .optflag("U", - "", - "Do not sort; list the files in whatever order they are stored in the \ - directory. This is especially useful when listing very large directories, \ - since not doing any sorting can be noticeably faster.") + .optflag( + "t", + "", + "Sort by modification time (the 'mtime' in the inode), newest first.", + ) + .optflag( + "U", + "", + "Do not sort; list the files in whatever order they are stored in the \ + directory. This is especially useful when listing very large directories, \ + since not doing any sorting can be noticeably faster.", + ) .optflag("", "color", "Color output based on file type.") .parse(args); @@ -159,7 +180,7 @@ fn list(options: getopts::Matches) { dir = true; if options.opt_present("l") && !(options.opt_present("L")) { if let Ok(md) = p.symlink_metadata() { - if md.file_type().is_symlink() && !p.ends_with( "/" ) { + if md.file_type().is_symlink() && !p.ends_with("/") { dir = false; } } @@ -189,16 +210,16 @@ fn sort_entries(entries: &mut Vec, options: &getopts::Matches) { if options.opt_present("t") { if options.opt_present("c") { entries.sort_by_key(|k| { - Reverse(get_metadata(k, options) - .map(|md| md.ctime()) - .unwrap_or(0)) + Reverse(get_metadata(k, options).map(|md| md.ctime()).unwrap_or(0)) }); } else { entries.sort_by_key(|k| { // Newest first - Reverse(get_metadata(k, options) - .and_then(|md| md.modified()) - .unwrap_or(std::time::UNIX_EPOCH)) + Reverse( + get_metadata(k, options) + .and_then(|md| md.modified()) + .unwrap_or(std::time::UNIX_EPOCH), + ) }); } } else if options.opt_present("S") { @@ -219,12 +240,18 @@ fn sort_entries(entries: &mut Vec, options: &getopts::Matches) { if options.opt_present("t") { entries.sort_by_key(|k| { // Newest first - Reverse(get_metadata(k, options) - .and_then(|md| md.modified()) - .unwrap_or(std::time::UNIX_EPOCH)) + Reverse( + get_metadata(k, options) + .and_then(|md| md.modified()) + .unwrap_or(std::time::UNIX_EPOCH), + ) }); } else if options.opt_present("S") { - entries.sort_by_key(|k| get_metadata(k, options).map(|md| md.file_size()).unwrap_or(0)); + entries.sort_by_key(|k| { + get_metadata(k, options) + .map(|md| md.file_size()) + .unwrap_or(0) + }); reverse = !reverse; } else if !options.opt_present("U") { entries.sort(); @@ -258,28 +285,23 @@ fn should_display(entry: &DirEntry, options: &getopts::Matches) -> bool { } fn enter_directory(dir: &PathBuf, options: &getopts::Matches) { - let mut entries = safe_unwrap!(fs::read_dir(dir) - .and_then(|e| e.collect::, _>>())); + let mut entries = + safe_unwrap!(fs::read_dir(dir).and_then(|e| e.collect::, _>>())); entries.retain(|e| should_display(e, options)); let mut entries: Vec<_> = entries.iter().map(DirEntry::path).collect(); sort_entries(&mut entries, options); - - if options.opt_present("a") { let mut display_entries = entries.clone(); display_entries.insert(0, dir.join("..")); display_entries.insert(0, dir.join(".")); display_items(&display_entries, Some(dir), options); - } - else - { + } else { display_items(&entries, Some(dir), options); } - if options.opt_present("R") { for e in entries.iter().filter(|p| p.is_dir()) { println!("\n{}:", e.to_string_lossy()); @@ -298,7 +320,10 @@ fn get_metadata(entry: &PathBuf, options: &getopts::Matches) -> std::io::Result< fn display_dir_entry_size(entry: &PathBuf, options: &getopts::Matches) -> (usize, usize) { if let Ok(md) = get_metadata(entry, options) { - (display_symlink_count(&md).len(), display_file_size(&md, options).len()) + ( + display_symlink_count(&md).len(), + display_file_size(&md, options).len(), + ) } else { (0, 0) } @@ -326,7 +351,8 @@ fn display_items(items: &Vec, strip: Option<&Path>, options: &getopts:: display_item_long(item, strip, max_links, max_size, options); } } else { - let names: Vec<_> = items.iter() + let names: Vec<_> = items + .iter() .filter_map(|i| { let md = get_metadata(i, options); match md { @@ -364,11 +390,13 @@ fn display_items(items: &Vec, strip: Option<&Path>, options: &getopts:: } } -fn display_item_long(item: &PathBuf, - strip: Option<&Path>, - max_links: usize, - max_size: usize, - options: &getopts::Matches) { +fn display_item_long( + item: &PathBuf, + strip: Option<&Path>, + max_links: usize, + max_size: usize, + options: &getopts::Matches, +) { let md = match get_metadata(item, options) { Err(e) => { let filename = get_file_name(&item, strip); @@ -378,16 +406,18 @@ fn display_item_long(item: &PathBuf, Ok(md) => md, }; - println!("{}{}{} {} {} {} {} {} {}", - get_inode(&md, options), - display_file_type(md.file_type()), - display_permissions(&md), - pad_left(display_symlink_count(&md), max_links), - display_uname(&md, options), - display_group(&md, options), - pad_left(display_file_size(&md, options), max_size), - display_date(&md, options), - display_file_name(&item, strip, &md, options).contents); + println!( + "{}{}{} {} {} {} {} {} {}", + get_inode(&md, options), + display_file_type(md.file_type()), + display_permissions(&md), + pad_left(display_symlink_count(&md), max_links), + display_uname(&md, options), + display_group(&md, options), + pad_left(display_file_size(&md, options), max_size), + display_date(&md, options), + display_file_name(&item, strip, &md, options).contents + ); } #[cfg(unix)] @@ -404,7 +434,6 @@ fn get_inode(_metadata: &Metadata, _options: &getopts::Matches) -> String { "".to_string() } - // Currently getpwuid is `linux` target only. If it's broken out into // a posix-compliant attribute this can be updated... #[cfg(unix)] @@ -455,11 +484,13 @@ fn display_date(metadata: &Metadata, options: &getopts::Matches) -> String { #[allow(unused_variables)] fn display_date(metadata: &Metadata, options: &getopts::Matches) -> String { if let Ok(mtime) = metadata.modified() { - let time = - time::at(Timespec::new(mtime.duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs() as i64, - 0)); + let time = time::at(Timespec::new( + mtime + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + 0, + )); strftime("%F %R", &time).unwrap() } else { "???".to_string() @@ -496,11 +527,12 @@ fn get_file_name(name: &Path, strip: Option<&Path>) -> String { } #[cfg(not(unix))] -fn display_file_name(path: &Path, - strip: Option<&Path>, - metadata: &Metadata, - options: &getopts::Matches) - -> Cell { +fn display_file_name( + path: &Path, + strip: Option<&Path>, + metadata: &Metadata, + options: &getopts::Matches, +) -> Cell { let mut name = get_file_name(path, strip); if !options.opt_present("long") { @@ -539,15 +571,9 @@ fn color_name(name: String, typ: &str) -> String { } }; if let Some(code) = COLOR_MAP.get(typ) { - format!("{}{}{}{}{}{}{}{}", - *LEFT_CODE, - code, - *RIGHT_CODE, - name, - *END_CODE, - *LEFT_CODE, - *RESET_CODE, - *RIGHT_CODE, + format!( + "{}{}{}{}{}{}{}{}", + *LEFT_CODE, code, *RIGHT_CODE, name, *END_CODE, *LEFT_CODE, *RESET_CODE, *RIGHT_CODE, ) } else { name @@ -560,11 +586,12 @@ macro_rules! has { ) } #[cfg(unix)] -fn display_file_name(path: &Path, - strip: Option<&Path>, - metadata: &Metadata, - options: &getopts::Matches) - -> Cell { +fn display_file_name( + path: &Path, + strip: Option<&Path>, + metadata: &Metadata, + options: &getopts::Matches, +) -> Cell { let mut name = get_file_name(path, strip); if !options.opt_present("long") { name = get_inode(metadata, options) + &name; @@ -639,11 +666,7 @@ fn display_file_name(path: &Path, if options.opt_present("long") && metadata.file_type().is_symlink() { if let Ok(target) = path.read_link() { // We don't bother updating width here because it's not used for long listings - let code = if target.exists() { - "fi" - } else { - "mi" - }; + let code = if target.exists() { "fi" } else { "mi" }; let target_name = color_name(target.to_string_lossy().to_string(), code); name.push_str(" -> "); name.push_str(&target_name); @@ -679,16 +702,8 @@ fn display_permissions(metadata: &Metadata) -> String { fn display_permissions(metadata: &Metadata) -> String { let mode = metadata.mode() as mode_t; let mut result = String::with_capacity(9); - result.push(if has!(mode, S_IRUSR) { - 'r' - } else { - '-' - }); - result.push(if has!(mode, S_IWUSR) { - 'w' - } else { - '-' - }); + result.push(if has!(mode, S_IRUSR) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWUSR) { 'w' } else { '-' }); result.push(if has!(mode, S_ISUID) { if has!(mode, S_IXUSR) { 's' @@ -701,16 +716,8 @@ fn display_permissions(metadata: &Metadata) -> String { '-' }); - result.push(if has!(mode, S_IRGRP) { - 'r' - } else { - '-' - }); - result.push(if has!(mode, S_IWGRP) { - 'w' - } else { - '-' - }); + result.push(if has!(mode, S_IRGRP) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWGRP) { 'w' } else { '-' }); result.push(if has!(mode, S_ISGID) { if has!(mode, S_IXGRP) { 's' @@ -723,16 +730,8 @@ fn display_permissions(metadata: &Metadata) -> String { '-' }); - result.push(if has!(mode, S_IROTH) { - 'r' - } else { - '-' - }); - result.push(if has!(mode, S_IWOTH) { - 'w' - } else { - '-' - }); + result.push(if has!(mode, S_IROTH) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWOTH) { 'w' } else { '-' }); result.push(if has!(mode, S_ISVTX) { if has!(mode, S_IXOTH) { 't' diff --git a/src/mkdir/mkdir.rs b/src/mkdir/mkdir.rs index c8e1ed0c3..af8c3d2e9 100644 --- a/src/mkdir/mkdir.rs +++ b/src/mkdir/mkdir.rs @@ -38,7 +38,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f) + Err(f) => crash!(1, "Invalid options\n{}", f), }; if args.len() == 1 || matches.opt_present("help") { @@ -78,7 +78,10 @@ fn print_help(opts: &getopts::Options) { println!("{} {}", NAME, VERSION); println!(""); println!("Usage:"); - print!("{}", opts.usage("Create the given DIRECTORY(ies) if they do not exist")); + print!( + "{}", + opts.usage("Create the given DIRECTORY(ies) if they do not exist") + ); } /** @@ -101,12 +104,15 @@ fn exec(dirs: Vec, recursive: bool, mode: u16, verbose: bool) -> i32 { match path.parent() { Some(parent) => { if parent != empty && !parent.exists() { - show_info!("cannot create directory '{}': No such file or directory", path.display()); + show_info!( + "cannot create directory '{}': No such file or directory", + path.display() + ); status = 1; } else { status |= mkdir(path, mode, verbose); } - }, + } None => { status |= mkdir(path, mode, verbose); } @@ -134,11 +140,16 @@ fn mkdir(path: &Path, mode: u16, verbose: bool) -> i32 { use std::ffi::CString; use std::io::Error; - let directory = CString::new(path.as_os_str().to_str().unwrap()).unwrap_or_else(|e| crash!(1, "{}", e)); + let directory = + CString::new(path.as_os_str().to_str().unwrap()).unwrap_or_else(|e| crash!(1, "{}", e)); let mode = mode as libc::mode_t; if unsafe { libc::chmod(directory.as_ptr(), mode) } != 0 { - show_info!("{}: errno {}", path.display(), Error::last_os_error().raw_os_error().unwrap()); + show_info!( + "{}: errno {}", + path.display(), + Error::last_os_error().raw_os_error().unwrap() + ); return 1; } 0 diff --git a/src/mkfifo/mkfifo.rs b/src/mkfifo/mkfifo.rs index c472b1ee3..3e25e0510 100644 --- a/src/mkfifo/mkfifo.rs +++ b/src/mkfifo/mkfifo.rs @@ -25,7 +25,12 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optopt("m", "mode", "file permissions for the fifo", "(default 0666)"); + opts.optopt( + "m", + "mode", + "file permissions for the fifo", + "(default 0666)", + ); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); @@ -40,12 +45,15 @@ pub fn uumain(args: Vec) -> i32 { } if matches.opt_present("help") || matches.free.is_empty() { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTIONS] NAME... -Create a FIFO with the given name.", NAME, VERSION); +Create a FIFO with the given name.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); if matches.free.is_empty() { @@ -57,7 +65,7 @@ Create a FIFO with the given name.", NAME, VERSION); let mode = match matches.opt_str("m") { Some(m) => match usize::from_str_radix(&m, 8) { Ok(m) => m, - Err(e)=> { + Err(e) => { show_error!("invalid mode: {}", e); return 1; } @@ -67,9 +75,18 @@ Create a FIFO with the given name.", NAME, VERSION); let mut exit_status = 0; for f in &matches.free { - let err = unsafe { mkfifo(CString::new(f.as_bytes()).unwrap().as_ptr(), mode as libc::mode_t) }; + let err = unsafe { + mkfifo( + CString::new(f.as_bytes()).unwrap().as_ptr(), + mode as libc::mode_t, + ) + }; if err == -1 { - show_error!("creating '{}': {}", f, Error::last_os_error().raw_os_error().unwrap()); + show_error!( + "creating '{}': {}", + f, + Error::last_os_error().raw_os_error().unwrap() + ); exit_status = 1; } } diff --git a/src/mknod/mknod.rs b/src/mknod/mknod.rs index 108c984d6..c950a7845 100644 --- a/src/mknod/mknod.rs +++ b/src/mknod/mknod.rs @@ -16,8 +16,8 @@ mod parsemode; #[macro_use] extern crate uucore; -use libc::{mode_t, dev_t}; -use libc::{S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IFIFO, S_IFBLK, S_IFCHR}; +use libc::{dev_t, mode_t}; +use libc::{S_IFBLK, S_IFCHR, S_IFIFO, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR}; use getopts::Options; @@ -31,8 +31,8 @@ const MODE_RW_UGO: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_ #[inline(always)] fn makedev(maj: u64, min: u64) -> dev_t { // pick up from - ((min & 0xff) | ((maj & 0xfff) << 8) | (((min & !0xff)) << 12) | - (((maj & !0xfff)) << 32)) as dev_t + ((min & 0xff) | ((maj & 0xfff) << 8) | (((min & !0xff)) << 12) | (((maj & !0xfff)) << 32)) + as dev_t } #[cfg(windows)] @@ -51,10 +51,12 @@ pub fn uumain(args: Vec) -> i32 { // Linux-specific options, not implemented // opts.optflag("Z", "", "set the SELinux security context to default type"); // opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX"); - opts.optopt("m", - "mode", - "set file permission bits to MODE, not a=rw - umask", - "MODE"); + opts.optopt( + "m", + "mode", + "set file permission bits to MODE, not a=rw - umask", + "MODE", + ); opts.optflag("", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); @@ -66,7 +68,7 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("help") { println!( -"Usage: {0} [OPTION]... NAME TYPE [MAJOR MINOR] + "Usage: {0} [OPTION]... NAME TYPE [MAJOR MINOR] Mandatory arguments to long options are mandatory for short options too. -m, --mode=MODE set file permission bits to MODE, not a=rw - umask @@ -84,7 +86,9 @@ otherwise, as decimal. TYPE may be: NOTE: your shell may have its own version of mknod, which usually supersedes the version described here. Please refer to your shell's documentation -for details about the options it supports.", NAME); +for details about the options it supports.", + NAME + ); return 0; } @@ -124,7 +128,10 @@ for details about the options it supports.", NAME); // Only check the first character, to allow mnemonic usage like // 'mknod /dev/rst0 character 18 0'. - let ch = args[1].chars().nth(0).expect("Failed to get the first char"); + let ch = args[1] + .chars() + .nth(0) + .expect("Failed to get the first char"); if ch == 'p' { if args.len() > 2 { @@ -183,7 +190,7 @@ for details about the options it supports.", NAME); } if ret == -1 { let c_str = CString::new(format!("{}: {}", NAME, matches.free[0]).as_str()) - .expect("Failed to convert to CString"); + .expect("Failed to convert to CString"); unsafe { libc::perror(c_str.as_ptr()); } diff --git a/src/mknod/parsemode.rs b/src/mknod/parsemode.rs index b7e08d9a0..688b3d5c7 100644 --- a/src/mknod/parsemode.rs +++ b/src/mknod/parsemode.rs @@ -1,5 +1,5 @@ extern crate libc; -use libc::{mode_t, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IRUSR, S_IWUSR}; +use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR}; use uucore::mode; diff --git a/src/mktemp/mktemp.rs b/src/mktemp/mktemp.rs index e844f97f1..2b47fe4c6 100644 --- a/src/mktemp/mktemp.rs +++ b/src/mktemp/mktemp.rs @@ -10,14 +10,14 @@ // extern crate getopts; -extern crate tempfile; extern crate rand; +extern crate tempfile; #[macro_use] extern crate uucore; use std::env; -use std::path::{PathBuf, is_separator}; +use std::path::{is_separator, PathBuf}; use std::mem::forget; use std::iter; @@ -30,22 +30,37 @@ static NAME: &'static str = "mktemp"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); static DEFAULT_TEMPLATE: &'static str = "tmp.XXXXXXXXXX"; - pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); opts.optflag("d", "directory", "Make a directory instead of a file"); - opts.optflag("u", - "dry-run", - "do not create anything; merely print a name (unsafe)"); + opts.optflag( + "u", + "dry-run", + "do not create anything; merely print a name (unsafe)", + ); opts.optflag("q", "quiet", "Fail silently if an error occurs."); - opts.optopt("", "suffix", "append SUFF to TEMPLATE; SUFF must not contain a path separator. This option is implied if TEMPLATE does not end with X.", "SUFF"); - opts.optopt("p", "tmpdir", "interpret TEMPLATE relative to DIR; if DIR is not specified, use $TMPDIR if set, else /tmp. With this option, TEMPLATE must not be an absolute name; unlike with -t, TEMPLATE may contain slashes, but mktemp creates only the final component", "DIR"); + opts.optopt( + "", + "suffix", + "append SUFF to TEMPLATE; SUFF must not contain a path separator. \ + This option is implied if TEMPLATE does not end with X.", + "SUFF", + ); + opts.optopt( + "p", + "tmpdir", + "interpret TEMPLATE relative to DIR; if DIR is not specified, use \ + $TMPDIR if set, else /tmp. With this option, TEMPLATE must not \ + be an absolute name; unlike with -t, TEMPLATE may contain \ + slashes, but mktemp creates only the final component", + "DIR", + ); // deprecated option of GNU coreutils - // opts.optflag("t", "", "Generate a template (using the supplied prefix and TMPDIR if set) to create a filename template"); + // opts.optflag("t", "", "Generate a template (using the supplied prefix and TMPDIR if set) \ + // to create a filename template"); opts.optflag("", "help", "Print this help and exit"); opts.optflag("", "version", "print the version and exit"); - // >> early return options let matches = match opts.parse(&args[1..]) { Ok(m) => m, @@ -71,7 +86,6 @@ pub fn uumain(args: Vec) -> i32 { let suffix_opt = matches.opt_str("suffix"); let suppress_file_err = matches.opt_present("quiet"); - let template = if matches.free.is_empty() { DEFAULT_TEMPLATE } else { @@ -79,19 +93,19 @@ pub fn uumain(args: Vec) -> i32 { }; let (prefix, rand, suffix) = match parse_template(template) { - Some((p, r, s)) => { - match suffix_opt { - Some(suf) => { - if s == "" { - (p, r, suf) - } else { - crash!(1, - "Template should end with 'X' when you specify suffix option.") - } + Some((p, r, s)) => match suffix_opt { + Some(suf) => { + if s == "" { + (p, r, suf) + } else { + crash!( + 1, + "Template should end with 'X' when you specify suffix option." + ) } - None => (p, r, s.to_owned()), } - } + None => (p, r, s.to_owned()), + }, None => ("", 0, "".to_owned()), }; @@ -103,11 +117,13 @@ pub fn uumain(args: Vec) -> i32 { crash!(1, "suffix cannot contain any path separators"); } - let tmpdir = match matches.opt_str("tmpdir") { Some(s) => { if PathBuf::from(prefix).is_absolute() { - show_info!("invalid template, ‘{}’; with --tmpdir, it may not be absolute", template); + show_info!( + "invalid template, ‘{}’; with --tmpdir, it may not be absolute", + template + ); return 1; } PathBuf::from(s) @@ -120,14 +136,15 @@ pub fn uumain(args: Vec) -> i32 { } else { exec(tmpdir, prefix, rand, &suffix, make_dir, suppress_file_err) } - } fn print_help(opts: &getopts::Options) { - let usage = format!(" Create a temporary file or directory, safely, and print its name. + let usage = format!( + " Create a temporary file or directory, safely, and print its name. TEMPLATE must contain at least 3 consecutive 'X's in last component. If TEMPLATE is not specified, use {}, and --tmpdir is implied", - DEFAULT_TEMPLATE); + DEFAULT_TEMPLATE + ); println!("{} {}", NAME, VERSION); println!("SYNOPSIS"); @@ -174,7 +191,14 @@ pub fn dry_exec(mut tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str) -> 0 } -fn exec(tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str, make_dir: bool, quiet: bool) -> i32 { +fn exec( + tmpdir: PathBuf, + prefix: &str, + rand: usize, + suffix: &str, + make_dir: bool, + quiet: bool, +) -> i32 { if make_dir { match tempdir::new_in(&tmpdir, prefix, rand, suffix) { Ok(ref f) => { @@ -206,9 +230,7 @@ fn exec(tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str, make_dir: bool } }; - let tmpname = tmpfile.path() - .to_string_lossy() - .to_string(); + let tmpname = tmpfile.path().to_string_lossy().to_string(); println!("{}", tmpname); diff --git a/src/mktemp/tempdir.rs b/src/mktemp/tempdir.rs index a2b3ec86c..0dfc2d51b 100644 --- a/src/mktemp/tempdir.rs +++ b/src/mktemp/tempdir.rs @@ -1,7 +1,7 @@ // Mainly taken from crate `tempdir` extern crate rand; -use rand::{Rng, thread_rng}; +use rand::{thread_rng, Rng}; use std::io::Result as IOResult; use std::io::{Error, ErrorKind}; @@ -24,8 +24,12 @@ fn create_dir>(path: P) -> IOResult<()> { ::std::fs::create_dir(path) } -pub fn new_in>(tmpdir: P, prefix: &str, rand: usize, suffix: &str) -> IOResult { - +pub fn new_in>( + tmpdir: P, + prefix: &str, + rand: usize, + suffix: &str, +) -> IOResult { let mut rng = thread_rng(); for _ in 0..NUM_RETRIES { let rand_chars: String = rng.gen_ascii_chars().take(rand).collect(); @@ -38,6 +42,8 @@ pub fn new_in>(tmpdir: P, prefix: &str, rand: usize, suffix: &str } } - Err(Error::new(ErrorKind::AlreadyExists, - "too many temporary directories already exist")) + Err(Error::new( + ErrorKind::AlreadyExists, + "too many temporary directories already exist", + )) } diff --git a/src/more/more.rs b/src/more/more.rs index 8967fe9e4..587237200 100644 --- a/src/more/more.rs +++ b/src/more/more.rs @@ -15,7 +15,7 @@ extern crate getopts; extern crate uucore; use getopts::Options; -use std::io::{stdout, Write, Read}; +use std::io::{stdout, Read, Write}; use std::fs::File; #[cfg(all(unix, not(target_os = "fuchsia")))] @@ -44,7 +44,7 @@ pub fn uumain(args: Vec) -> i32 { Err(e) => { show_error!("{}", e); panic!() - }, + } }; let usage = opts.usage("more TARGET."); let mode = if matches.opt_present("version") { @@ -56,8 +56,8 @@ pub fn uumain(args: Vec) -> i32 { }; match mode { - Mode::More => more(matches), - Mode::Help => help(&usage), + Mode::More => more(matches), + Mode::Help => help(&usage), Mode::Version => version(), } @@ -69,10 +69,13 @@ fn version() { } fn help(usage: &str) { - let msg = format!("{0} {1}\n\n\ - Usage: {0} TARGET\n \ - \n\ - {2}", NAME, VERSION, usage); + let msg = format!( + "{0} {1}\n\n\ + Usage: {0} TARGET\n \ + \n\ + {2}", + NAME, VERSION, usage + ); println!("{}", msg); } @@ -102,8 +105,7 @@ fn reset_term(term: &mut termios::Termios) { #[cfg(any(windows, target_os = "fuchsia"))] #[inline(always)] -fn reset_term(_: &mut usize) { -} +fn reset_term(_: &mut usize) {} fn more(matches: getopts::Matches) { let files = matches.free; @@ -114,7 +116,9 @@ fn more(matches: getopts::Matches) { let mut end = false; while let Ok(sz) = f.read(&mut buffer) { - if sz == 0 { break } + if sz == 0 { + break; + } stdout().write(&buffer[0..sz]).unwrap(); for byte in std::io::stdin().bytes() { match byte.unwrap() { @@ -122,12 +126,14 @@ fn more(matches: getopts::Matches) { b'q' | 27 => { end = true; break; - }, - _ => () + } + _ => (), } } - if end { break } + if end { + break; + } } reset_term(&mut term); diff --git a/src/mv/mv.rs b/src/mv/mv.rs index 4e947c3cd..dea29e94e 100644 --- a/src/mv/mv.rs +++ b/src/mv/mv.rs @@ -16,7 +16,7 @@ extern crate uucore; use std::fs; use std::env; -use std::io::{BufRead, BufReader, Result, stdin}; +use std::io::{stdin, BufRead, BufReader, Result}; use std::path::{Path, PathBuf}; static NAME: &'static str = "mv"; @@ -50,29 +50,37 @@ pub enum BackupMode { pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflagopt("", - "backup", - "make a backup of each existing destination file", - "CONTROL"); + opts.optflagopt( + "", + "backup", + "make a backup of each existing destination file", + "CONTROL", + ); opts.optflag("b", "", "like --backup but does not accept an argument"); opts.optflag("f", "force", "do not prompt before overwriting"); opts.optflag("i", "interactive", "prompt before override"); opts.optflag("n", "no-clobber", "do not overwrite an existing file"); - opts.optflag("", - "strip-trailing-slashes", - "remove any trailing slashes from each SOURCE\n \ - argument"); + opts.optflag( + "", + "strip-trailing-slashes", + "remove any trailing slashes from each SOURCE\n \ + argument", + ); opts.optopt("S", "suffix", "override the usual backup suffix", "SUFFIX"); - opts.optopt("t", - "target-directory", - "move all SOURCE arguments into DIRECTORY", - "DIRECTORY"); + opts.optopt( + "t", + "target-directory", + "move all SOURCE arguments into DIRECTORY", + "DIRECTORY", + ); opts.optflag("T", "no-target-directory", "treat DEST as a normal file"); - opts.optflag("u", - "update", - "move only when the SOURCE file is newer\n \ - than the destination file or when the\n \ - destination file is missing"); + opts.optflag( + "u", + "update", + "move only when the SOURCE file is newer\n \ + than the destination file or when the\n \ + destination file is missing", + ); opts.optflag("v", "verbose", "explain what is being done"); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); @@ -90,9 +98,11 @@ pub fn uumain(args: Vec) -> i32 { let backup_mode = determine_backup_mode(&matches); if overwrite_mode == OverwriteMode::NoClobber && backup_mode != BackupMode::NoBackup { - show_error!("options --backup and --no-clobber are mutually exclusive\n\ - Try '{} --help' for more information.", - NAME); + show_error!( + "options --backup and --no-clobber are mutually exclusive\n\ + Try '{} --help' for more information.", + NAME + ); return 1; } @@ -158,20 +168,21 @@ fn determine_backup_mode(matches: &getopts::Matches) -> BackupMode { } else if matches.opt_present("backup") { match matches.opt_str("backup") { None => BackupMode::SimpleBackup, - Some(mode) => { - match &mode[..] { - "simple" | "never" => BackupMode::SimpleBackup, - "numbered" | "t" => BackupMode::NumberedBackup, - "existing" | "nil" => BackupMode::ExistingBackup, - "none" | "off" => BackupMode::NoBackup, - x => { - crash!(1, "invalid argument ‘{}’ for ‘backup type’\n\ - Try '{} --help' for more information.", - x, - NAME); - } + Some(mode) => match &mode[..] { + "simple" | "never" => BackupMode::SimpleBackup, + "numbered" | "t" => BackupMode::NumberedBackup, + "existing" | "nil" => BackupMode::ExistingBackup, + "none" | "off" => BackupMode::NoBackup, + x => { + crash!( + 1, + "invalid argument ‘{}’ for ‘backup type’\n\ + Try '{} --help' for more information.", + x, + NAME + ); } - } + }, } } else { BackupMode::NoBackup @@ -183,9 +194,12 @@ fn determine_backup_suffix(backup_mode: BackupMode, matches: &getopts::Matches) match matches.opt_str("suffix") { Some(x) => x, None => { - crash!(1, "option '--suffix' requires an argument\n\ - Try '{} --help' for more information.", - NAME); + crash!( + 1, + "option '--suffix' requires an argument\n\ + Try '{} --help' for more information.", + NAME + ); } } } else { @@ -198,13 +212,13 @@ fn determine_backup_suffix(backup_mode: BackupMode, matches: &getopts::Matches) } fn help(usage: &str) { - println!("{0} {1}\n\n\ - Usage: {0} SOURCE DEST\n \ - or: {0} SOURCE... DIRECTORY\n\n\ - {2}", - NAME, - VERSION, - usage); + println!( + "{0} {1}\n\n\ + Usage: {0} SOURCE DEST\n \ + or: {0} SOURCE... DIRECTORY\n\n\ + {2}", + NAME, VERSION, usage + ); } fn exec(files: &[PathBuf], b: Behaviour) -> i32 { @@ -213,25 +227,31 @@ fn exec(files: &[PathBuf], b: Behaviour) -> i32 { } match files.len() { 0 | 1 => { - show_error!("missing file operand\n\ - Try '{} --help' for more information.", - NAME); + show_error!( + "missing file operand\n\ + Try '{} --help' for more information.", + NAME + ); return 1; } 2 => { let source = &files[0]; let target = &files[1]; if !source.exists() { - show_error!("cannot stat ‘{}’: No such file or directory", - source.display()); + show_error!( + "cannot stat ‘{}’: No such file or directory", + source.display() + ); return 1; } if target.is_dir() { if b.no_target_dir { if !source.is_dir() { - show_error!("cannot overwrite directory ‘{}’ with non-directory", - target.display()); + show_error!( + "cannot overwrite directory ‘{}’ with non-directory", + target.display() + ); return 1; } @@ -254,10 +274,12 @@ fn exec(files: &[PathBuf], b: Behaviour) -> i32 { } _ => { if b.no_target_dir { - show_error!("mv: extra operand ‘{}’\n\ - Try '{} --help' for more information.", - files[2].display(), - NAME); + show_error!( + "mv: extra operand ‘{}’\n\ + Try '{} --help' for more information.", + files[2].display(), + NAME + ); return 1; } let target_dir = files.last().unwrap(); @@ -278,8 +300,10 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behaviour) - let targetpath = match sourcepath.as_os_str().to_str() { Some(name) => target_dir.join(name), None => { - show_error!("cannot stat ‘{}’: No such file or directory", - sourcepath.display()); + show_error!( + "cannot stat ‘{}’: No such file or directory", + sourcepath.display() + ); all_successful = false; continue; @@ -287,10 +311,12 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behaviour) - }; if let Err(e) = rename(sourcepath, &targetpath, b) { - show_error!("mv: cannot move ‘{}’ to ‘{}’: {}", - sourcepath.display(), - targetpath.display(), - e); + show_error!( + "mv: cannot move ‘{}’ to ‘{}’: {}", + sourcepath.display(), + targetpath.display(), + e + ); all_successful = false; } } @@ -327,7 +353,8 @@ fn rename(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<()> { } if b.update { - if try!(try!(fs::metadata(from)).modified()) <= try!(try!(fs::metadata(to)).modified()) { + if try!(try!(fs::metadata(from)).modified()) <= try!(try!(fs::metadata(to)).modified()) + { return Ok(()); } } @@ -348,12 +375,10 @@ fn rename(from: &PathBuf, to: &PathBuf, b: &Behaviour) -> Result<()> { fn read_yes() -> bool { let mut s = String::new(); match BufReader::new(stdin()).read_line(&mut s) { - Ok(_) => { - match s.chars().nth(0) { - Some(x) => x == 'y' || x == 'Y', - _ => false, - } - } + Ok(_) => match s.chars().nth(0) { + Some(x) => x == 'y' || x == 'Y', + _ => false, + }, _ => false, } } diff --git a/src/nice/nice.rs b/src/nice/nice.rs index 284dde85e..1f79983b7 100644 --- a/src/nice/nice.rs +++ b/src/nice/nice.rs @@ -25,7 +25,7 @@ const VERSION: &'static str = env!("CARGO_PKG_VERSION"); // XXX: PRIO_PROCESS is 0 on at least FreeBSD and Linux. Don't know about Mac OS X. const PRIO_PROCESS: c_int = 0; -extern { +extern "C" { fn getpriority(which: c_int, who: c_int) -> c_int; fn setpriority(which: c_int, who: c_int, prio: c_int) -> c_int; } @@ -33,7 +33,12 @@ extern { pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optopt("n", "adjustment", "add N to the niceness (default is 10)", "N"); + 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"); @@ -51,7 +56,8 @@ pub fn uumain(args: Vec) -> i32 { } if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTIONS] [COMMAND [ARGS]] @@ -59,7 +65,9 @@ Usage: Run COMMAND with an adjusted niceness, which affects process scheduling. 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 -process).", NAME, VERSION); +process).", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); return 0; @@ -74,18 +82,21 @@ process).", NAME, VERSION); let adjustment = match matches.opt_str("adjustment") { Some(nstr) => { if matches.free.is_empty() { - show_error!("A command must be given with an adjustment. - Try \"{} --help\" for more information.", args[0]); + show_error!( + "A command must be given with an adjustment. + Try \"{} --help\" for more information.", + args[0] + ); return 125; } match nstr.parse() { Ok(num) => num, - Err(e)=> { + Err(e) => { show_error!("\"{}\" is not a valid number: {}", nstr, e); return 125; } } - }, + } None => { if matches.free.is_empty() { println!("{}", niceness); @@ -96,16 +107,28 @@ process).", NAME, VERSION); }; niceness += adjustment; - unsafe { setpriority(PRIO_PROCESS, 0, niceness); } + unsafe { + setpriority(PRIO_PROCESS, 0, niceness); + } if Error::last_os_error().raw_os_error().unwrap() != 0 { show_warning!("{}", Error::last_os_error()); } - let cstrs: Vec = matches.free.iter().map(|x| CString::new(x.as_bytes()).unwrap()).collect(); + let cstrs: Vec = matches + .free + .iter() + .map(|x| CString::new(x.as_bytes()).unwrap()) + .collect(); let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect(); args.push(0 as *const c_char); - unsafe { execvp(args[0], args.as_mut_ptr()); } + unsafe { + execvp(args[0], args.as_mut_ptr()); + } show_error!("{}", Error::last_os_error()); - if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT { 127 } else { 126 } + if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT { + 127 + } else { + 126 + } } diff --git a/src/nl/helper.rs b/src/nl/helper.rs index f51308356..b34c2a1e1 100644 --- a/src/nl/helper.rs +++ b/src/nl/helper.rs @@ -27,45 +27,67 @@ pub fn parse_options(settings: &mut ::Settings, opts: &getopts::Matches) -> Vec< let mut errs: Vec = vec![]; settings.renumber = !opts.opt_present("p"); match opts.opt_str("s") { - None => {}, - Some(val) => { settings.number_separator = val; } - } - match opts.opt_str("n") { - None => {}, - Some(val) => match val.as_ref() { - "ln" => { settings.number_format = ::NumberFormat::Left; }, - "rn" => { settings.number_format = ::NumberFormat::Right; }, - "rz" => { settings.number_format = ::NumberFormat::RightZero; }, - _ => { errs.push(String::from("Illegal value for -n")); }, + None => {} + Some(val) => { + settings.number_separator = val; } } + match opts.opt_str("n") { + None => {} + Some(val) => match val.as_ref() { + "ln" => { + settings.number_format = ::NumberFormat::Left; + } + "rn" => { + settings.number_format = ::NumberFormat::Right; + } + "rz" => { + settings.number_format = ::NumberFormat::RightZero; + } + _ => { + errs.push(String::from("Illegal value for -n")); + } + }, + } match opts.opt_str("b") { - None => {}, + None => {} Some(val) => { let chars: Vec = val.chars().collect(); match parse_style(&chars) { - Ok(s) => { settings.body_numbering = s; } - Err(message) => { errs.push(message); } + Ok(s) => { + settings.body_numbering = s; + } + Err(message) => { + errs.push(message); + } } } } match opts.opt_str("f") { - None => {}, + None => {} Some(val) => { let chars: Vec = val.chars().collect(); match parse_style(&chars) { - Ok(s) => { settings.footer_numbering = s; } - Err(message) => { errs.push(message); } + Ok(s) => { + settings.footer_numbering = s; + } + Err(message) => { + errs.push(message); + } } } } match opts.opt_str("h") { - None => {}, + None => {} Some(val) => { let chars: Vec = val.chars().collect(); match parse_style(&chars) { - Ok(s) => { settings.header_numbering = s; } - Err(message) => { errs.push(message); } + Ok(s) => { + settings.header_numbering = s; + } + Err(message) => { + errs.push(message); + } } } } @@ -74,10 +96,10 @@ pub fn parse_options(settings: &mut ::Settings, opts: &getopts::Matches) -> Vec< Some(val) => { let conv: Option = val.parse().ok(); match conv { - None => { - errs.push(String::from("Illegal value for -i")); - } - Some(num) => { settings.line_increment = num } + None => { + errs.push(String::from("Illegal value for -i")); + } + Some(num) => settings.line_increment = num, } } } @@ -86,10 +108,10 @@ pub fn parse_options(settings: &mut ::Settings, opts: &getopts::Matches) -> Vec< Some(val) => { let conv: Option = val.parse().ok(); match conv { - None => { - errs.push(String::from("Illegal value for -w")); - } - Some(num) => { settings.number_width = num } + None => { + errs.push(String::from("Illegal value for -w")); + } + Some(num) => settings.number_width = num, } } } @@ -98,10 +120,10 @@ pub fn parse_options(settings: &mut ::Settings, opts: &getopts::Matches) -> Vec< Some(val) => { let conv: Option = val.parse().ok(); match conv { - None => { - errs.push(String::from("Illegal value for -v")); - } - Some(num) => { settings.starting_line_number = num } + None => { + errs.push(String::from("Illegal value for -v")); + } + Some(num) => settings.starting_line_number = num, } } } @@ -110,10 +132,10 @@ pub fn parse_options(settings: &mut ::Settings, opts: &getopts::Matches) -> Vec< Some(val) => { let conv: Option = val.parse().ok(); match conv { - None => { - errs.push(String::from("Illegal value for -l")); - } - Some(num) => { settings.join_blank_lines = num } + None => { + errs.push(String::from("Illegal value for -l")); + } + Some(num) => settings.join_blank_lines = num, } } } diff --git a/src/nl/nl.rs b/src/nl/nl.rs index b8937afd3..2fb50179b 100644 --- a/src/nl/nl.rs +++ b/src/nl/nl.rs @@ -13,14 +13,14 @@ extern crate aho_corasick; extern crate getopts; extern crate memchr; -extern crate regex_syntax; extern crate regex; +extern crate regex_syntax; #[macro_use] extern crate uucore; use std::fs::File; -use std::io::{BufRead, BufReader, Read, stdin}; +use std::io::{stdin, BufRead, BufReader, Read}; use std::iter::repeat; use std::path::Path; @@ -49,7 +49,7 @@ pub struct Settings { number_format: NumberFormat, renumber: bool, // The string appended to each line number output. - number_separator: String + number_separator: String, } // NumberingStyle stores which lines are to be numbered. @@ -62,7 +62,7 @@ enum NumberingStyle { NumberForAll, NumberForNonEmpty, NumberForNone, - NumberForRegularExpression(regex::Regex) + NumberForRegularExpression(regex::Regex), } // NumberFormat specifies how line numbers are output within their allocated @@ -77,17 +77,71 @@ enum NumberFormat { pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optopt("b", "body-numbering", "use STYLE for numbering body lines", "STYLE"); - opts.optopt("d", "section-delimiter", "use CC for separating logical pages", "CC"); - opts.optopt("f", "footer-numbering", "use STYLE for numbering footer lines", "STYLE"); - opts.optopt("h", "header-numbering", "use STYLE for numbering header lines", "STYLE"); - opts.optopt("i", "line-increment", "line number increment at each line", ""); - opts.optopt("l", "join-blank-lines", "group of NUMBER empty lines counted as one", "NUMBER"); - opts.optopt("n", "number-format", "insert line numbers according to FORMAT", "FORMAT"); - opts.optflag("p", "no-renumber", "do not reset line numbers at logical pages"); - opts.optopt("s", "number-separator", "add STRING after (possible) line number", "STRING"); - opts.optopt("v", "starting-line-number", "first line number on each logical page", "NUMBER"); - opts.optopt("w", "number-width", "use NUMBER columns for line numbers", "NUMBER"); + opts.optopt( + "b", + "body-numbering", + "use STYLE for numbering body lines", + "STYLE", + ); + opts.optopt( + "d", + "section-delimiter", + "use CC for separating logical pages", + "CC", + ); + opts.optopt( + "f", + "footer-numbering", + "use STYLE for numbering footer lines", + "STYLE", + ); + opts.optopt( + "h", + "header-numbering", + "use STYLE for numbering header lines", + "STYLE", + ); + opts.optopt( + "i", + "line-increment", + "line number increment at each line", + "", + ); + opts.optopt( + "l", + "join-blank-lines", + "group of NUMBER empty lines counted as one", + "NUMBER", + ); + opts.optopt( + "n", + "number-format", + "insert line numbers according to FORMAT", + "FORMAT", + ); + opts.optflag( + "p", + "no-renumber", + "do not reset line numbers at logical pages", + ); + opts.optopt( + "s", + "number-separator", + "add STRING after (possible) line number", + "STRING", + ); + opts.optopt( + "v", + "starting-line-number", + "first line number on each logical page", + "NUMBER", + ); + opts.optopt( + "w", + "number-width", + "use NUMBER columns for line numbers", + "NUMBER", + ); opts.optflag("", "help", "display this help and exit"); opts.optflag("V", "version", "version"); @@ -107,11 +161,11 @@ pub fn uumain(args: Vec) -> i32 { }; let given_options = match opts.parse(&args[1..]) { - Ok (m) => { m } + Ok(m) => m, Err(f) => { show_error!("{}", f); print_usage(&opts); - return 1 + return 1; } }; @@ -119,7 +173,10 @@ pub fn uumain(args: Vec) -> i32 { print_usage(&opts); return 0; } - if given_options.opt_present("version") { version(); return 0; } + if given_options.opt_present("version") { + version(); + return 0; + } // Update the settings from the command line options, and terminate the // program if some options could not successfully be parsed. @@ -140,7 +197,7 @@ pub fn uumain(args: Vec) -> i32 { // If both file names and '-' are specified, we choose to treat first all // regular files, and then read from stdin last. read_stdin = true; - continue + continue; } let path = Path::new(file); let reader = File::open(path).unwrap(); @@ -156,7 +213,7 @@ pub fn uumain(args: Vec) -> i32 { } // nl implements the main functionality for an individual buffer. -fn nl (reader: &mut BufReader, settings: &Settings) { +fn nl(reader: &mut BufReader, settings: &Settings) { let regexp: regex::Regex = regex::Regex::new(r".?").unwrap(); let mut line_no = settings.starting_line_number; // The current line number's width as a string. Using to_string is inefficient @@ -169,14 +226,14 @@ fn nl (reader: &mut BufReader, settings: &Settings) { let mut empty_line_count: u64 = 0; let fill_char = match settings.number_format { NumberFormat::RightZero => '0', - _ => ' ' + _ => ' ', }; // Initially, we use the body's line counting settings let mut regex_filter = match settings.body_numbering { NumberingStyle::NumberForRegularExpression(ref re) => re, _ => ®exp, }; - let mut line_filter : fn(&str, ®ex::Regex) -> bool = pass_regex; + let mut line_filter: fn(&str, ®ex::Regex) -> bool = pass_regex; for mut l in reader.lines().map(|r| r.unwrap()) { // Sanitize the string. We want to print the newline ourselves. if !l.is_empty() && l.chars().rev().next().unwrap() == '\n' { @@ -198,8 +255,7 @@ fn nl (reader: &mut BufReader, settings: &Settings) { // If we have already seen three groups (corresponding to // a header) or the current char does not form part of // a new group, then this line is not a segment indicator. - if matched_groups >= 3 - || settings.section_delimiter[if odd { 1 } else { 0 }] != c { + if matched_groups >= 3 || settings.section_delimiter[if odd { 1 } else { 0 }] != c { matched_groups = 0; break; } @@ -230,22 +286,18 @@ fn nl (reader: &mut BufReader, settings: &Settings) { line_no_threshold = 10u64.pow(line_no_width as u32); } &settings.header_numbering - }, - 1 => { - &settings.footer_numbering - }, + } + 1 => &settings.footer_numbering, // The only option left is 2, but rust wants // a catch-all here. - _ => { - &settings.body_numbering - } + _ => &settings.body_numbering, } { NumberingStyle::NumberForAll => { line_filter = pass_all; - }, + } NumberingStyle::NumberForNonEmpty => { line_filter = pass_nonempty; - }, + } NumberingStyle::NumberForNone => { line_filter = pass_none; } @@ -267,7 +319,8 @@ fn nl (reader: &mut BufReader, settings: &Settings) { empty_line_count = 0; } if !line_filter(&line, regex_filter) - || ( empty_line_count > 0 && empty_line_count < settings.join_blank_lines) { + || (empty_line_count > 0 && empty_line_count < settings.join_blank_lines) + { // No number is printed for this line. Either we did not // want to print one in the first place, or it is a blank // line but we are still collecting more blank lines via @@ -286,12 +339,14 @@ fn nl (reader: &mut BufReader, settings: &Settings) { } let fill: String = repeat(fill_char).take(w).collect(); match settings.number_format { - NumberFormat::Left => { - println!("{1}{0}{2}{3}", fill, line_no, settings.number_separator, line) - }, - _ => { - println!("{0}{1}{2}{3}", fill, line_no, settings.number_separator, line) - } + NumberFormat::Left => println!( + "{1}{0}{2}{3}", + fill, line_no, settings.number_separator, line + ), + _ => println!( + "{0}{1}{2}{3}", + fill, line_no, settings.number_separator, line + ), } // Now update the variables for the (potential) next // line. @@ -301,7 +356,6 @@ fn nl (reader: &mut BufReader, settings: &Settings) { line_no_threshold *= 10; line_no_width += 1; } - } } diff --git a/src/nohup/nohup.rs b/src/nohup/nohup.rs index 66e88e4a6..a54e17869 100644 --- a/src/nohup/nohup.rs +++ b/src/nohup/nohup.rs @@ -15,8 +15,8 @@ extern crate libc; #[macro_use] extern crate uucore; -use libc::{c_char, signal, dup2, execvp}; -use libc::{SIG_IGN, SIGHUP}; +use libc::{c_char, execvp, signal, dup2}; +use libc::{SIGHUP, SIG_IGN}; use std::ffi::CString; use std::fs::{File, OpenOptions}; use std::io::Error; @@ -29,12 +29,14 @@ static NAME: &'static str = "nohup"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); #[cfg(target_os = "macos")] -extern { +extern "C" { fn _vprocmgr_detach_from_console(flags: u32) -> *const libc::c_int; } #[cfg(any(target_os = "linux", target_os = "freebsd"))] -unsafe fn _vprocmgr_detach_from_console(_: u32) -> *const libc::c_int { std::ptr::null() } +unsafe fn _vprocmgr_detach_from_console(_: u32) -> *const libc::c_int { + std::ptr::null() +} pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); @@ -47,37 +49,47 @@ pub fn uumain(args: Vec) -> i32 { Err(f) => { show_error!("{}", f); show_usage(&opts); - return 1 + return 1; } }; - if matches.opt_present("V") { println!("{} {}", NAME, VERSION); return 0 } - if matches.opt_present("h") { show_usage(&opts); return 0 } + if matches.opt_present("V") { + println!("{} {}", NAME, VERSION); + return 0; + } + if matches.opt_present("h") { + show_usage(&opts); + return 0; + } if matches.free.is_empty() { show_error!("Missing operand: COMMAND"); println!("Try `{} --help` for more information.", NAME); - return 1 + return 1; } replace_fds(); unsafe { signal(SIGHUP, SIG_IGN) }; - if unsafe { _vprocmgr_detach_from_console(0) } != std::ptr::null() { crash!(2, "Cannot detach from console")}; + if unsafe { _vprocmgr_detach_from_console(0) } != std::ptr::null() { + crash!(2, "Cannot detach from console") + }; - let cstrs: Vec = matches.free.iter().map(|x| CString::new(x.as_bytes()).unwrap()).collect(); + let cstrs: Vec = matches + .free + .iter() + .map(|x| CString::new(x.as_bytes()).unwrap()) + .collect(); let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect(); args.push(std::ptr::null()); - unsafe { execvp(args[0], args.as_mut_ptr())} + unsafe { execvp(args[0], args.as_mut_ptr()) } } fn replace_fds() { if is_stdin_interactive() { let new_stdin = match File::open(Path::new("/dev/null")) { Ok(t) => t, - Err(e) => { - crash!(2, "Cannot replace STDIN: {}", e) - } + Err(e) => crash!(2, "Cannot replace STDIN: {}", e), }; if unsafe { dup2(new_stdin.as_raw_fd(), 0) } != 0 { crash!(2, "Cannot replace STDIN: {}", Error::last_os_error()) @@ -101,33 +113,42 @@ fn replace_fds() { } fn find_stdout() -> File { - match OpenOptions::new().write(true).create(true).append(true).open(Path::new("nohup.out")) { + match OpenOptions::new() + .write(true) + .create(true) + .append(true) + .open(Path::new("nohup.out")) + { Ok(t) => { show_warning!("Output is redirected to: nohup.out"); t - }, + } Err(e) => { let home = match env::var("HOME") { Err(_) => crash!(2, "Cannot replace STDOUT: {}", e), - Ok(h) => h + Ok(h) => h, }; let mut homeout = PathBuf::from(home); homeout.push("nohup.out"); - match OpenOptions::new().write(true).create(true).append(true).open(&homeout) { + match OpenOptions::new() + .write(true) + .create(true) + .append(true) + .open(&homeout) + { Ok(t) => { show_warning!("Output is redirected to: {:?}", homeout); t - }, - Err(e) => { - crash!(2, "Cannot replace STDOUT: {}", e) } + Err(e) => crash!(2, "Cannot replace STDOUT: {}", e), } } } } fn show_usage(opts: &getopts::Options) { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} COMMAND [ARG]... @@ -137,7 +158,9 @@ Run COMMAND ignoring hangup signals. If standard input is terminal, it'll be replaced with /dev/null. If standard output is terminal, it'll be appended to nohup.out instead, or $HOME/nohup.out, if nohup.out open failed. -If standard error is terminal, it'll be redirected to stdout.", NAME, VERSION); +If standard error is terminal, it'll be redirected to stdout.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } diff --git a/src/nproc/nproc.rs b/src/nproc/nproc.rs index 5e0eb24c4..d245836f7 100644 --- a/src/nproc/nproc.rs +++ b/src/nproc/nproc.rs @@ -29,14 +29,17 @@ pub const _SC_NPROCESSORS_CONF: libc::c_int = 57; #[cfg(target_os = "netbsd")] pub const _SC_NPROCESSORS_CONF: libc::c_int = 1001; - static NAME: &'static str = "nproc"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("", "all", "print the number of cores available to the system"); + opts.optflag( + "", + "all", + "print the number of cores available to the system", + ); opts.optopt("", "ignore", "ignore up to N cores", "N"); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); @@ -55,12 +58,15 @@ pub fn uumain(args: Vec) -> i32 { } if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTIONS]... -Print the number of cores available to the current process.", NAME, VERSION); +Print the number of cores available to the current process.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); return 0; @@ -74,16 +80,16 @@ Print the number of cores available to the current process.", NAME, VERSION); return 1; } }, - None => 0 + None => 0, }; if !matches.opt_present("all") { ignore += match env::var("OMP_NUM_THREADS") { Ok(threadstr) => match threadstr.parse() { Ok(num) => num, - Err(_)=> 0 + Err(_) => 0, }, - Err(_) => 0 + Err(_) => 0, }; } @@ -102,10 +108,7 @@ Print the number of cores available to the current process.", NAME, VERSION); 0 } -#[cfg(any(target_os = "linux", - target_os = "macos", - target_os = "freebsd", - target_os = "netbsd"))] +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "netbsd"))] fn num_cpus_all() -> usize { let nprocs = unsafe { libc::sysconf(_SC_NPROCESSORS_CONF) }; if nprocs == 1 { @@ -113,14 +116,16 @@ fn num_cpus_all() -> usize { // However, we want to guarantee that `nproc --all` >= `nproc`. num_cpus::get() } else { - if nprocs > 0 { nprocs as usize } else { 1 } + if nprocs > 0 { + nprocs as usize + } else { + 1 + } } } // Other platform(e.g., windows), num_cpus::get() directly. -#[cfg(not(any(target_os = "linux", - target_os = "macos", - target_os = "freebsd", +#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "netbsd")))] fn num_cpus_all() -> usize { num_cpus::get() diff --git a/src/numfmt/numfmt.rs b/src/numfmt/numfmt.rs index 6ea84f894..600cf462d 100644 --- a/src/numfmt/numfmt.rs +++ b/src/numfmt/numfmt.rs @@ -75,23 +75,21 @@ fn parse_suffix(s: String) -> Result<(f64, Option)> { Some('T') => Ok((Some(Suffix::T), 1)), Some('P') => Ok((Some(Suffix::P), 1)), Some('E') => Ok((Some(Suffix::E), 1)), - Some('i') => { - match iter.next_back() { - Some('K') => Ok((Some(Suffix::Ki), 2)), - Some('M') => Ok((Some(Suffix::Mi), 2)), - Some('G') => Ok((Some(Suffix::Gi), 2)), - Some('T') => Ok((Some(Suffix::Ti), 2)), - Some('P') => Ok((Some(Suffix::Pi), 2)), - Some('E') => Ok((Some(Suffix::Ei), 2)), - _ => Err("Failed to parse suffix"), - } - } + Some('i') => match iter.next_back() { + Some('K') => Ok((Some(Suffix::Ki), 2)), + Some('M') => Ok((Some(Suffix::Mi), 2)), + Some('G') => Ok((Some(Suffix::Gi), 2)), + Some('T') => Ok((Some(Suffix::Ti), 2)), + Some('P') => Ok((Some(Suffix::Pi), 2)), + Some('E') => Ok((Some(Suffix::Ei), 2)), + _ => Err("Failed to parse suffix"), + }, _ => Ok((None, 0)), }?; - let number = s[..s.len() - suffix_len].parse::().map_err(|err| { - err.to_string() - })?; + let number = s[..s.len() - suffix_len] + .parse::() + .map_err(|err| err.to_string())?; Ok((number, suffix)) } @@ -120,37 +118,35 @@ struct NumfmtOptions { fn remove_suffix(i: f64, s: Option, u: &Unit) -> Result { match (s, u) { (None, _) => Ok(i), - (Some(Suffix::K), &Unit::Auto) | - (Some(Suffix::K), &Unit::Si) => Ok(i * 1000.), - (Some(Suffix::M), &Unit::Auto) | - (Some(Suffix::M), &Unit::Si) => Ok(i * 1000_000.), - (Some(Suffix::G), &Unit::Auto) | - (Some(Suffix::G), &Unit::Si) => Ok(i * 1000_000_000.), - (Some(Suffix::T), &Unit::Auto) | - (Some(Suffix::T), &Unit::Si) => Ok(i * 1000_000_000_000.), - (Some(Suffix::P), &Unit::Auto) | - (Some(Suffix::P), &Unit::Si) => Ok(i * 1000_000_000_000_000.), - (Some(Suffix::E), &Unit::Auto) | - (Some(Suffix::E), &Unit::Si) => Ok(i * 1000_000_000_000_000_000.), + (Some(Suffix::K), &Unit::Auto) | (Some(Suffix::K), &Unit::Si) => Ok(i * 1000.), + (Some(Suffix::M), &Unit::Auto) | (Some(Suffix::M), &Unit::Si) => Ok(i * 1000_000.), + (Some(Suffix::G), &Unit::Auto) | (Some(Suffix::G), &Unit::Si) => Ok(i * 1000_000_000.), + (Some(Suffix::T), &Unit::Auto) | (Some(Suffix::T), &Unit::Si) => Ok(i * 1000_000_000_000.), + (Some(Suffix::P), &Unit::Auto) | (Some(Suffix::P), &Unit::Si) => { + Ok(i * 1000_000_000_000_000.) + } + (Some(Suffix::E), &Unit::Auto) | (Some(Suffix::E), &Unit::Si) => { + Ok(i * 1000_000_000_000_000_000.) + } - (Some(Suffix::Ki), &Unit::Auto) | - (Some(Suffix::Ki), &Unit::IecI) | - (Some(Suffix::K), &Unit::Iec) => Ok(i * 1024.), - (Some(Suffix::Mi), &Unit::Auto) | - (Some(Suffix::Mi), &Unit::IecI) | - (Some(Suffix::M), &Unit::Iec) => Ok(i * 1048576.), - (Some(Suffix::Gi), &Unit::Auto) | - (Some(Suffix::Gi), &Unit::IecI) | - (Some(Suffix::G), &Unit::Iec) => Ok(i * 1073741824.), - (Some(Suffix::Ti), &Unit::Auto) | - (Some(Suffix::Ti), &Unit::IecI) | - (Some(Suffix::T), &Unit::Iec) => Ok(i * 1099511627776.), - (Some(Suffix::Pi), &Unit::Auto) | - (Some(Suffix::Pi), &Unit::IecI) | - (Some(Suffix::P), &Unit::Iec) => Ok(i * 1125899906842624.), - (Some(Suffix::Ei), &Unit::Auto) | - (Some(Suffix::Ei), &Unit::IecI) | - (Some(Suffix::E), &Unit::Iec) => Ok(i * 1152921504606846976.), + (Some(Suffix::Ki), &Unit::Auto) + | (Some(Suffix::Ki), &Unit::IecI) + | (Some(Suffix::K), &Unit::Iec) => Ok(i * 1024.), + (Some(Suffix::Mi), &Unit::Auto) + | (Some(Suffix::Mi), &Unit::IecI) + | (Some(Suffix::M), &Unit::Iec) => Ok(i * 1048576.), + (Some(Suffix::Gi), &Unit::Auto) + | (Some(Suffix::Gi), &Unit::IecI) + | (Some(Suffix::G), &Unit::Iec) => Ok(i * 1073741824.), + (Some(Suffix::Ti), &Unit::Auto) + | (Some(Suffix::Ti), &Unit::IecI) + | (Some(Suffix::T), &Unit::Iec) => Ok(i * 1099511627776.), + (Some(Suffix::Pi), &Unit::Auto) + | (Some(Suffix::Pi), &Unit::IecI) + | (Some(Suffix::P), &Unit::Iec) => Ok(i * 1125899906842624.), + (Some(Suffix::Ei), &Unit::Auto) + | (Some(Suffix::Ei), &Unit::IecI) + | (Some(Suffix::E), &Unit::Iec) => Ok(i * 1152921504606846976.), (_, _) => Err("This suffix is unsupported for specified unit".to_owned()), } @@ -163,49 +159,38 @@ fn transform_from(s: String, unit: &Unit) -> Result { fn consider_suffix(i: f64, u: &Unit) -> Result<(f64, Option)> { match *u { - Unit::Si => { - match i { - _ if i < 1000. => Ok((i, None)), - _ if i < 1000_000. => Ok((i / 1000., Some(Suffix::K))), - _ if i < 1000_000_000. => Ok((i / 1000_000., Some(Suffix::M))), - _ if i < 1000_000_000_000. => Ok((i / 1000_000_000., Some(Suffix::G))), - _ if i < 1000_000_000_000_000. => Ok((i / 1000_000_000_000., Some(Suffix::T))), - _ if i < 1000_000_000_000_000_000. => Ok( - (i / 1000_000_000_000_000., Some(Suffix::P)), - ), - _ if i < 1000_000_000_000_000_000_000. => Ok(( - i / 1000_000_000_000_000_000., - Some(Suffix::E), - )), - _ => Err("Number is too big and unsupported".to_owned()), + Unit::Si => match i { + _ if i < 1000. => Ok((i, None)), + _ if i < 1000_000. => Ok((i / 1000., Some(Suffix::K))), + _ if i < 1000_000_000. => Ok((i / 1000_000., Some(Suffix::M))), + _ if i < 1000_000_000_000. => Ok((i / 1000_000_000., Some(Suffix::G))), + _ if i < 1000_000_000_000_000. => Ok((i / 1000_000_000_000., Some(Suffix::T))), + _ if i < 1000_000_000_000_000_000. => Ok((i / 1000_000_000_000_000., Some(Suffix::P))), + _ if i < 1000_000_000_000_000_000_000. => { + Ok((i / 1000_000_000_000_000_000., Some(Suffix::E))) } - } - Unit::Iec => { - match i { - _ if i < 1024. => Ok((i, None)), - _ if i < 1048576. => Ok((i / 1024., Some(Suffix::K))), - _ if i < 1073741824. => Ok((i / 1048576., Some(Suffix::M))), - _ if i < 1099511627776. => Ok((i / 1073741824., Some(Suffix::G))), - _ if i < 1125899906842624. => Ok((i / 1099511627776., Some(Suffix::T))), - _ if i < 1152921504606846976. => Ok((i / 1125899906842624., Some(Suffix::P))), - _ if i < 1180591620717411303424. => Ok((i / 1152921504606846976., Some(Suffix::E))), - _ => Err("Number is too big and unsupported".to_owned()), - } - } - Unit::IecI => { - match i { - _ if i < 1024. => Ok((i, None)), - _ if i < 1048576. => Ok((i / 1024., Some(Suffix::Ki))), - _ if i < 1073741824. => Ok((i / 1048576., Some(Suffix::Mi))), - _ if i < 1099511627776. => Ok((i / 1073741824., Some(Suffix::Gi))), - _ if i < 1125899906842624. => Ok((i / 1099511627776., Some(Suffix::Ti))), - _ if i < 1152921504606846976. => Ok((i / 1125899906842624., Some(Suffix::Pi))), - _ if i < 1180591620717411303424. => Ok( - (i / 1152921504606846976., Some(Suffix::Ei)), - ), - _ => Err("Number is too big and unsupported".to_owned()), - } - } + _ => Err("Number is too big and unsupported".to_owned()), + }, + Unit::Iec => match i { + _ if i < 1024. => Ok((i, None)), + _ if i < 1048576. => Ok((i / 1024., Some(Suffix::K))), + _ if i < 1073741824. => Ok((i / 1048576., Some(Suffix::M))), + _ if i < 1099511627776. => Ok((i / 1073741824., Some(Suffix::G))), + _ if i < 1125899906842624. => Ok((i / 1099511627776., Some(Suffix::T))), + _ if i < 1152921504606846976. => Ok((i / 1125899906842624., Some(Suffix::P))), + _ if i < 1180591620717411303424. => Ok((i / 1152921504606846976., Some(Suffix::E))), + _ => Err("Number is too big and unsupported".to_owned()), + }, + Unit::IecI => match i { + _ if i < 1024. => Ok((i, None)), + _ if i < 1048576. => Ok((i / 1024., Some(Suffix::Ki))), + _ if i < 1073741824. => Ok((i / 1048576., Some(Suffix::Mi))), + _ if i < 1099511627776. => Ok((i / 1073741824., Some(Suffix::Gi))), + _ if i < 1125899906842624. => Ok((i / 1099511627776., Some(Suffix::Ti))), + _ if i < 1152921504606846976. => Ok((i / 1125899906842624., Some(Suffix::Pi))), + _ if i < 1180591620717411303424. => Ok((i / 1152921504606846976., Some(Suffix::Ei))), + _ => Err("Number is too big and unsupported".to_owned()), + }, Unit::Auto => Err("Unit 'auto' isn't supported with --to options".to_owned()), } } diff --git a/src/od/byteorder_io.rs b/src/od/byteorder_io.rs index e72b4373b..33f617910 100644 --- a/src/od/byteorder_io.rs +++ b/src/od/byteorder_io.rs @@ -1,7 +1,7 @@ // workaround until https://github.com/BurntSushi/byteorder/issues/41 has been fixed // based on: https://github.com/netvl/immeta/blob/4460ee/src/utils.rs#L76 -use byteorder::{NativeEndian, LittleEndian, BigEndian}; +use byteorder::{BigEndian, LittleEndian, NativeEndian}; use byteorder::ByteOrder as ByteOrderTrait; #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/src/od/formatteriteminfo.rs b/src/od/formatteriteminfo.rs index 9a5c3e236..d43b1bade 100644 --- a/src/od/formatteriteminfo.rs +++ b/src/od/formatteriteminfo.rs @@ -35,22 +35,22 @@ impl fmt::Debug for FormatWriter { &FormatWriter::IntWriter(ref p) => { try!(f.write_str("IntWriter:")); fmt::Pointer::fmt(p, f) - }, + } &FormatWriter::FloatWriter(ref p) => { try!(f.write_str("FloatWriter:")); fmt::Pointer::fmt(p, f) - }, + } &FormatWriter::MultibyteWriter(ref p) => { try!(f.write_str("MultibyteWriter:")); fmt::Pointer::fmt(&(*p as *const ()), f) - }, + } } - } - } + } +} #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct FormatterItemInfo { pub byte_size: usize, - pub print_width: usize, // including a space in front of the text + pub print_width: usize, // including a space in front of the text pub formatter: FormatWriter, } diff --git a/src/od/inputdecoder.rs b/src/od/inputdecoder.rs index feec673bb..cd4a0feec 100644 --- a/src/od/inputdecoder.rs +++ b/src/od/inputdecoder.rs @@ -7,7 +7,10 @@ use half::f16; /// Processes an input and provides access to the data read in various formats /// /// Currently only useful if the input implements `PeekRead`. -pub struct InputDecoder<'a, I> where I: 'a { +pub struct InputDecoder<'a, I> +where + I: 'a, +{ /// The input from which data is read input: &'a mut I, @@ -28,9 +31,16 @@ pub struct InputDecoder<'a, I> where I: 'a { impl<'a, I> InputDecoder<'a, I> { /// Creates a new `InputDecoder` with an allocated buffer of `normal_length` + `peek_length` bytes. /// `byte_order` determines how to read multibyte formats from the buffer. - pub fn new(input: &mut I, normal_length: usize, peek_length: usize, byte_order: ByteOrder) -> InputDecoder { + pub fn new( + input: &mut I, + normal_length: usize, + peek_length: usize, + byte_order: ByteOrder, + ) -> InputDecoder { let mut bytes: Vec = Vec::with_capacity(normal_length + peek_length); - unsafe { bytes.set_len(normal_length + peek_length); } // fast but uninitialized + unsafe { + bytes.set_len(normal_length + peek_length); + } // fast but uninitialized InputDecoder { input: input, @@ -43,12 +53,16 @@ impl<'a, I> InputDecoder<'a, I> { } } - -impl<'a, I> InputDecoder<'a, I> where I: PeekRead { +impl<'a, I> InputDecoder<'a, I> +where + I: PeekRead, +{ /// calls `peek_read` on the internal stream to (re)fill the buffer. Returns a /// MemoryDecoder providing access to the result or returns an i/o error. pub fn peek_read(&mut self) -> io::Result { - match self.input.peek_read(self.data.as_mut_slice(), self.reserved_peek_length) { + match self.input + .peek_read(self.data.as_mut_slice(), self.reserved_peek_length) + { Ok((n, p)) => { self.used_normal_length = n; self.used_peek_length = p; @@ -58,14 +72,16 @@ impl<'a, I> InputDecoder<'a, I> where I: PeekRead { used_peek_length: self.used_peek_length, byte_order: self.byte_order, }) - }, + } Err(e) => Err(e), } - } } -impl<'a, I> HasError for InputDecoder<'a, I> where I: HasError { +impl<'a, I> HasError for InputDecoder<'a, I> +where + I: HasError, +{ /// calls has_error on the internal stream. fn has_error(&self) -> bool { self.input.has_error() @@ -87,7 +103,7 @@ pub struct MemoryDecoder<'a> { impl<'a> MemoryDecoder<'a> { /// Set a part of the internal buffer to zero. /// access to the whole buffer is possible, not just to the valid data. - pub fn zero_out_buffer(&mut self, start:usize, end:usize) { + pub fn zero_out_buffer(&mut self, start: usize, end: usize) { for i in start..end { self.data[i] = 0; } @@ -128,7 +144,9 @@ impl<'a> MemoryDecoder<'a> { /// Returns a f32/f64 from the internal buffer at position `start`. pub fn read_float(&self, start: usize, byte_size: usize) -> f64 { match byte_size { - 2 => f64::from(f16::from_bits(self.byte_order.read_u16(&self.data[start..start + 2]))), + 2 => f64::from(f16::from_bits( + self.byte_order.read_u16(&self.data[start..start + 2]), + )), 4 => self.byte_order.read_f32(&self.data[start..start + 4]) as f64, 8 => self.byte_order.read_f64(&self.data[start..start + 8]), _ => panic!("Invalid byte_size: {}", byte_size), @@ -169,7 +187,9 @@ mod tests { mem.zero_out_buffer(7, 8); assert_eq!(&[0, 0, 0xff, 0xff], mem.get_full_buffer(6)); } - Err(e) => { assert!(false, e); } + Err(e) => { + assert!(false, e); + } } match sut.peek_read() { @@ -177,7 +197,9 @@ mod tests { assert_eq!(2, mem.length()); assert_eq!(0xffff, mem.read_uint(0, 2)); } - Err(e) => { assert!(false, e); } + Err(e) => { + assert!(false, e); + } } } } diff --git a/src/od/inputoffset.rs b/src/od/inputoffset.rs index 9b82a214d..102f1656b 100644 --- a/src/od/inputoffset.rs +++ b/src/od/inputoffset.rs @@ -1,6 +1,10 @@ - #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Radix { Decimal, Hexadecimal, Octal, NoPrefix } +pub enum Radix { + Decimal, + Hexadecimal, + Octal, + NoPrefix, +} /// provides the byte offset printed at the left margin pub struct InputOffset { diff --git a/src/od/mockstream.rs b/src/od/mockstream.rs index 5adfce2ae..3523caf58 100644 --- a/src/od/mockstream.rs +++ b/src/od/mockstream.rs @@ -1,6 +1,6 @@ // https://github.com/lazy-bitfield/rust-mockstream/pull/2 -use std::io::{Cursor, Read, Result, Error, ErrorKind}; +use std::io::{Cursor, Error, ErrorKind, Read, Result}; use std::error::Error as errorError; /// `FailingMockStream` mocks a stream which will fail upon read or write @@ -56,12 +56,16 @@ impl FailingMockStream { /// When `read` or `write` is called, it will return an error `repeat_count` times. /// `kind` and `message` can be specified to define the exact error. pub fn new(kind: ErrorKind, message: &'static str, repeat_count: i32) -> FailingMockStream { - FailingMockStream { kind: kind, message: message, repeat_count: repeat_count, } + FailingMockStream { + kind: kind, + message: message, + repeat_count: repeat_count, + } } fn error(&mut self) -> Result { if self.repeat_count == 0 { - return Ok(0) + return Ok(0); } else { if self.repeat_count > 0 { self.repeat_count -= 1; @@ -91,8 +95,12 @@ fn test_failing_mock_stream_read() { #[test] fn test_failing_mock_stream_chain_interrupted() { let mut c = Cursor::new(&b"abcd"[..]) - .chain(FailingMockStream::new(ErrorKind::Interrupted, "Interrupted", 5)) - .chain(Cursor::new(&b"ABCD"[..])); + .chain(FailingMockStream::new( + ErrorKind::Interrupted, + "Interrupted", + 5, + )) + .chain(Cursor::new(&b"ABCD"[..])); let mut v = [0; 8]; c.read_exact(v.as_mut()).unwrap(); diff --git a/src/od/multifilereader.rs b/src/od/multifilereader.rs index 6a9fda10e..20dfa1ae1 100644 --- a/src/od/multifilereader.rs +++ b/src/od/multifilereader.rs @@ -56,9 +56,12 @@ impl<'b> MultifileReader<'b> { // print an error at the time that the file is needed, // then move on the the next file. // This matches the behavior of the original `od` - eprintln!("{}: '{}': {}", + eprintln!( + "{}: '{}': {}", executable!().split("::").next().unwrap(), // remove module - fname, e); + fname, + e + ); self.any_err = true } } @@ -91,12 +94,14 @@ impl<'b> io::Read for MultifileReader<'b> { Ok(0) => break, Ok(n) => n, Err(e) => { - eprintln!("{}: I/O: {}", + eprintln!( + "{}: I/O: {}", executable!().split("::").next().unwrap(), // remove module - e); + e + ); self.any_err = true; break; - }, + } }; if xfrd == buf.len() { // transferred all that was asked for. @@ -117,11 +122,10 @@ impl<'b> HasError for MultifileReader<'b> { } } - #[cfg(test)] mod tests { use super::*; - use std::io::{Cursor, Read, ErrorKind}; + use std::io::{Cursor, ErrorKind, Read}; use mockstream::*; #[test] @@ -176,11 +180,23 @@ mod tests { #[test] fn test_multi_file_reader_read_error_at_start() { let mut inputs = Vec::new(); - inputs.push(InputSource::Stream(Box::new(FailingMockStream::new(ErrorKind::Other, "Failing", 1)))); + inputs.push(InputSource::Stream(Box::new(FailingMockStream::new( + ErrorKind::Other, + "Failing", + 1, + )))); inputs.push(InputSource::Stream(Box::new(Cursor::new(&b"abcd"[..])))); - inputs.push(InputSource::Stream(Box::new(FailingMockStream::new(ErrorKind::Other, "Failing", 1)))); + inputs.push(InputSource::Stream(Box::new(FailingMockStream::new( + ErrorKind::Other, + "Failing", + 1, + )))); inputs.push(InputSource::Stream(Box::new(Cursor::new(&b"ABCD"[..])))); - inputs.push(InputSource::Stream(Box::new(FailingMockStream::new(ErrorKind::Other, "Failing", 1)))); + inputs.push(InputSource::Stream(Box::new(FailingMockStream::new( + ErrorKind::Other, + "Failing", + 1, + )))); let mut v = [0; 5]; let mut sut = MultifileReader::new(inputs); diff --git a/src/od/od.rs b/src/od/od.rs index 03ba6a06d..2c937e63f 100644 --- a/src/od/od.rs +++ b/src/od/od.rs @@ -9,8 +9,8 @@ * file that was distributed with this source code. */ -extern crate getopts; extern crate byteorder; +extern crate getopts; extern crate half; #[macro_use] @@ -44,14 +44,13 @@ use parse_formats::{parse_format_flags, ParsedFormatterItemInfo}; use prn_char::format_ascii_dump; use parse_inputs::{parse_inputs, CommandLineInputs}; use inputoffset::{InputOffset, Radix}; -use inputdecoder::{InputDecoder,MemoryDecoder}; +use inputdecoder::{InputDecoder, MemoryDecoder}; use output_info::OutputInfo; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); const PEEK_BUFFER_SIZE: usize = 4; // utf-8 can be 4 bytes -static USAGE: &'static str = -r#"Usage: +static USAGE: &'static str = r#"Usage: od [OPTION]... [--] [FILENAME]... od [-abcdDefFhHiIlLoOsxX] [FILENAME] [[+][0x]OFFSET[.][b]] od --traditional [OPTION]... [FILENAME] [[+][0x]OFFSET[.][b] [[+][0x]LABEL[.][b]]] @@ -97,17 +96,37 @@ exitcode will be non-zero."#; fn create_getopts_options() -> getopts::Options { let mut opts = getopts::Options::new(); - opts.optopt("A", "address-radix", - "Select the base in which file offsets are printed.", "RADIX"); - opts.optopt("j", "skip-bytes", - "Skip bytes input bytes before formatting and writing.", "BYTES"); - opts.optopt("N", "read-bytes", - "limit dump to BYTES input bytes", "BYTES"); - opts.optopt("", "endian", "byte order to use for multi-byte formats", "big|little"); - opts.optopt("S", "strings", - "output strings of at least BYTES graphic chars. 3 is assumed when \ - BYTES is not specified.", - "BYTES"); + opts.optopt( + "A", + "address-radix", + "Select the base in which file offsets are printed.", + "RADIX", + ); + opts.optopt( + "j", + "skip-bytes", + "Skip bytes input bytes before formatting and writing.", + "BYTES", + ); + opts.optopt( + "N", + "read-bytes", + "limit dump to BYTES input bytes", + "BYTES", + ); + opts.optopt( + "", + "endian", + "byte order to use for multi-byte formats", + "big|little", + ); + opts.optopt( + "S", + "strings", + "output strings of at least BYTES graphic chars. 3 is assumed when \ + BYTES is not specified.", + "BYTES", + ); opts.optflagmulti("a", "", "named characters, ignoring high-order bit"); opts.optflagmulti("b", "", "octal bytes"); opts.optflagmulti("c", "", "ASCII characters or backslash escapes"); @@ -132,14 +151,25 @@ fn create_getopts_options() -> getopts::Options { opts.optflagmulti("F", "", "floating point double precision (64-bit) units"); opts.optmulti("t", "format", "select output format or formats", "TYPE"); - opts.optflag("v", "output-duplicates", "do not use * to mark line suppression"); - opts.optflagopt("w", "width", - "output BYTES bytes per output line. 32 is implied when BYTES is not \ - specified.", - "BYTES"); + opts.optflag( + "v", + "output-duplicates", + "do not use * to mark line suppression", + ); + opts.optflagopt( + "w", + "width", + "output BYTES bytes per output line. 32 is implied when BYTES is not \ + specified.", + "BYTES", + ); opts.optflag("", "help", "display this help and exit."); opts.optflag("", "version", "output version information and exit."); - opts.optflag("", "traditional", "compatibility mode with one input, offset and label."); + opts.optflag( + "", + "traditional", + "compatibility mode with one input, offset and label.", + ); opts } @@ -159,9 +189,9 @@ struct OdOptions { impl OdOptions { fn new(matches: getopts::Matches, args: Vec) -> Result { let byte_order = match matches.opt_str("endian").as_ref().map(String::as_ref) { - None => { ByteOrder::Native }, - Some("little") => { ByteOrder::Little }, - Some("big") => { ByteOrder::Big }, + None => ByteOrder::Native, + Some("little") => ByteOrder::Little, + Some("big") => ByteOrder::Big, Some(s) => { return Err(format!("Invalid argument --endian={}", s)); } @@ -169,14 +199,12 @@ impl OdOptions { let mut skip_bytes = match matches.opt_default("skip-bytes", "0") { None => 0, - Some(s) => { - match parse_number_of_bytes(&s) { - Ok(i) => { i } - Err(_) => { - return Err(format!("Invalid argument --skip-bytes={}", s)); - } + Some(s) => match parse_number_of_bytes(&s) { + Ok(i) => i, + Err(_) => { + return Err(format!("Invalid argument --skip-bytes={}", s)); } - } + }, }; let mut label: Option = None; @@ -187,7 +215,7 @@ impl OdOptions { skip_bytes = s; label = l; vec![f] - }, + } Err(e) => { return Err(format!("Invalid inputs: {}", e)); } @@ -202,14 +230,14 @@ impl OdOptions { let mut line_bytes = match matches.opt_default("w", "32") { None => 16, - Some(s) => { - match s.parse::() { - Ok(i) => { i } - Err(_) => { 0 } - } - } + Some(s) => match s.parse::() { + Ok(i) => i, + Err(_) => 0, + }, }; - let min_bytes = formats.iter().fold(1, |max, next| cmp::max(max, next.formatter_item_info.byte_size)); + let min_bytes = formats.iter().fold(1, |max, next| { + cmp::max(max, next.formatter_item_info.byte_size) + }); if line_bytes == 0 || line_bytes % min_bytes != 0 { show_warning!("invalid width {}; using {} instead", line_bytes, min_bytes); line_bytes = min_bytes; @@ -219,14 +247,12 @@ impl OdOptions { let read_bytes = match matches.opt_str("read-bytes") { None => None, - Some(s) => { - match parse_number_of_bytes(&s) { - Ok(i) => { Some(i) } - Err(_) => { - return Err(format!("Invalid argument --read-bytes={}", s)); - } + Some(s) => match parse_number_of_bytes(&s) { + Ok(i) => Some(i), + Err(_) => { + return Err(format!("Invalid argument --read-bytes={}", s)); } - } + }, }; let radix = match matches.opt_str("A") { @@ -234,16 +260,16 @@ impl OdOptions { Some(s) => { let st = s.into_bytes(); if st.len() != 1 { - return Err(format!("Radix must be one of [d, o, n, x]")) + return Err(format!("Radix must be one of [d, o, n, x]")); } else { - let radix: char = *(st.get(0) - .expect("byte string of length 1 lacks a 0th elem")) as char; + let radix: char = + *(st.get(0).expect("byte string of length 1 lacks a 0th elem")) as char; match radix { 'd' => Radix::Decimal, 'x' => Radix::Hexadecimal, 'o' => Radix::Octal, 'n' => Radix::NoPrefix, - _ => return Err(format!("Radix must be one of [d, o, n, x]")) + _ => return Err(format!("Radix must be one of [d, o, n, x]")), } } } @@ -289,28 +315,43 @@ pub fn uumain(args: Vec) -> i32 { Err(s) => { disp_err!("{}", s); return 1; - }, + } Ok(o) => o, }; - let mut input_offset = InputOffset::new(od_options.radix, od_options.skip_bytes, - od_options.label); + let mut input_offset = + InputOffset::new(od_options.radix, od_options.skip_bytes, od_options.label); - let mut input = open_input_peek_reader(&od_options.input_strings, - od_options.skip_bytes, od_options.read_bytes); - let mut input_decoder = InputDecoder::new(&mut input, od_options.line_bytes, - PEEK_BUFFER_SIZE, od_options.byte_order); + let mut input = open_input_peek_reader( + &od_options.input_strings, + od_options.skip_bytes, + od_options.read_bytes, + ); + let mut input_decoder = InputDecoder::new( + &mut input, + od_options.line_bytes, + PEEK_BUFFER_SIZE, + od_options.byte_order, + ); - let output_info = OutputInfo::new(od_options.line_bytes, &od_options.formats[..], - od_options.output_duplicates); + let output_info = OutputInfo::new( + od_options.line_bytes, + &od_options.formats[..], + od_options.output_duplicates, + ); odfunc(&mut input_offset, &mut input_decoder, &output_info) } /// Loops through the input line by line, calling print_bytes to take care of the output. -fn odfunc(input_offset: &mut InputOffset, input_decoder: &mut InputDecoder, - output_info: &OutputInfo) -> i32 - where I: PeekRead + HasError { +fn odfunc( + input_offset: &mut InputOffset, + input_decoder: &mut InputDecoder, + output_info: &OutputInfo, +) -> i32 +where + I: PeekRead + HasError, +{ let mut duplicate_line = false; let mut previous_bytes: Vec = Vec::new(); let line_bytes = output_info.byte_size_line; @@ -338,9 +379,9 @@ fn odfunc(input_offset: &mut InputOffset, input_decoder: &mut InputDecoder memory_decoder.zero_out_buffer(length, max_used); } - if !output_info.output_duplicates - && length == line_bytes - && memory_decoder.get_buffer(0) == &previous_bytes[..] { + if !output_info.output_duplicates && length == line_bytes + && memory_decoder.get_buffer(0) == &previous_bytes[..] + { if !duplicate_line { duplicate_line = true; println!("*"); @@ -352,8 +393,11 @@ fn odfunc(input_offset: &mut InputOffset, input_decoder: &mut InputDecoder memory_decoder.clone_buffer(&mut previous_bytes); } - print_bytes(&input_offset.format_byte_offset(), &memory_decoder, - &output_info); + print_bytes( + &input_offset.format_byte_offset(), + &memory_decoder, + &output_info, + ); } input_offset.increase_position(length); @@ -381,9 +425,11 @@ fn print_bytes(prefix: &str, input_decoder: &MemoryDecoder, output_info: &Output let mut b = 0; while b < input_decoder.length() { - output_text.push_str(&format!("{:>width$}", - "", - width = f.spacing[b % output_info.byte_size_block])); + output_text.push_str(&format!( + "{:>width$}", + "", + width = f.spacing[b % output_info.byte_size_block] + )); match f.formatter_item_info.formatter { FormatWriter::IntWriter(func) => { @@ -403,21 +449,25 @@ fn print_bytes(prefix: &str, input_decoder: &MemoryDecoder, output_info: &Output } if f.add_ascii_dump { - let missing_spacing = output_info.print_width_line.saturating_sub(output_text.chars().count()); - output_text.push_str(&format!("{:>width$} {}", - "", - format_ascii_dump(input_decoder.get_buffer(0)), - width = missing_spacing)); + let missing_spacing = output_info + .print_width_line + .saturating_sub(output_text.chars().count()); + output_text.push_str(&format!( + "{:>width$} {}", + "", + format_ascii_dump(input_decoder.get_buffer(0)), + width = missing_spacing + )); } if first { print!("{}", prefix); // print offset - // if printing in multiple formats offset is printed only once + // if printing in multiple formats offset is printed only once first = false; } else { // this takes the space of the file offset on subsequent // lines of multi-format rasters. - print!("{:>width$}", "", width=prefix.chars().count()); + print!("{:>width$}", "", width = prefix.chars().count()); } print!("{}\n", output_text); } @@ -427,8 +477,11 @@ fn print_bytes(prefix: &str, input_decoder: &MemoryDecoder, output_info: &Output /// /// `skip_bytes` is the number of bytes skipped from the input /// `read_bytes` is an optional limit to the number of bytes to read -fn open_input_peek_reader<'a>(input_strings: &'a Vec, skip_bytes: usize, - read_bytes: Option) -> PeekReader>> { +fn open_input_peek_reader<'a>( + input_strings: &'a Vec, + skip_bytes: usize, + read_bytes: Option, +) -> PeekReader>> { // should return "impl PeekRead + Read + HasError" when supported in (stable) rust let inputs = input_strings .iter() diff --git a/src/od/output_info.rs b/src/od/output_info.rs index b8c464284..2ce6596d2 100644 --- a/src/od/output_info.rs +++ b/src/od/output_info.rs @@ -9,7 +9,7 @@ const MAX_BYTES_PER_UNIT: usize = 8; /// Contains information to output single output line in human readable form pub struct SpacedFormatterItemInfo { /// Contains a function pointer to output data, and information about the output format. - pub formatter_item_info: FormatterItemInfo, + pub formatter_item_info: FormatterItemInfo, /// Contains the number of spaces to add to align data with other output formats. /// /// If the corresponding data is a single byte, each entry in this array contains @@ -40,7 +40,6 @@ pub struct OutputInfo { pub output_duplicates: bool, } - impl OutputInfo { /// Returns an iterator over the `SpacedFormatterItemInfo` vector. pub fn spaced_formatters_iter(&self) -> Iter { @@ -48,16 +47,25 @@ impl OutputInfo { } /// Creates a new `OutputInfo` based on the parameters - pub fn new(line_bytes: usize, formats: &[ParsedFormatterItemInfo], output_duplicates: bool) -> OutputInfo { - let byte_size_block = formats.iter().fold(1, |max, next| cmp::max(max, next.formatter_item_info.byte_size)); - let print_width_block = formats - .iter() - .fold(1, |max, next| { - cmp::max(max, next.formatter_item_info.print_width * (byte_size_block / next.formatter_item_info.byte_size)) - }); + pub fn new( + line_bytes: usize, + formats: &[ParsedFormatterItemInfo], + output_duplicates: bool, + ) -> OutputInfo { + let byte_size_block = formats.iter().fold(1, |max, next| { + cmp::max(max, next.formatter_item_info.byte_size) + }); + let print_width_block = formats.iter().fold(1, |max, next| { + cmp::max( + max, + next.formatter_item_info.print_width + * (byte_size_block / next.formatter_item_info.byte_size), + ) + }); let print_width_line = print_width_block * (line_bytes / byte_size_block); - let spaced_formatters = OutputInfo::create_spaced_formatter_info(&formats, byte_size_block, print_width_block); + let spaced_formatters = + OutputInfo::create_spaced_formatter_info(&formats, byte_size_block, print_width_block); OutputInfo { byte_size_line: line_bytes, @@ -69,14 +77,17 @@ impl OutputInfo { } } - fn create_spaced_formatter_info(formats: &[ParsedFormatterItemInfo], - byte_size_block: usize, print_width_block: usize) -> Vec { + fn create_spaced_formatter_info( + formats: &[ParsedFormatterItemInfo], + byte_size_block: usize, + print_width_block: usize, + ) -> Vec { formats .iter() .map(|f| SpacedFormatterItemInfo { formatter_item_info: f.formatter_item_info, add_ascii_dump: f.add_ascii_dump, - spacing: OutputInfo::calculate_alignment(f, byte_size_block, print_width_block) + spacing: OutputInfo::calculate_alignment(f, byte_size_block, print_width_block), }) .collect() } @@ -126,12 +137,17 @@ impl OutputInfo { /// /// This algorithm assumes the size of all types is a power of 2 (1, 2, 4, 8, 16, ...) /// Increase MAX_BYTES_PER_UNIT to allow larger types. - fn calculate_alignment(sf: &TypeSizeInfo, byte_size_block: usize, - print_width_block: usize) -> [usize; MAX_BYTES_PER_UNIT] { + fn calculate_alignment( + sf: &TypeSizeInfo, + byte_size_block: usize, + print_width_block: usize, + ) -> [usize; MAX_BYTES_PER_UNIT] { if byte_size_block > MAX_BYTES_PER_UNIT { - panic!("{}-bits types are unsupported. Current max={}-bits.", - 8 * byte_size_block, - 8 * MAX_BYTES_PER_UNIT); + panic!( + "{}-bits types are unsupported. Current max={}-bits.", + 8 * byte_size_block, + 8 * MAX_BYTES_PER_UNIT + ); } let mut spacing = [0; MAX_BYTES_PER_UNIT]; @@ -161,8 +177,12 @@ trait TypeSizeInfo { } impl TypeSizeInfo for ParsedFormatterItemInfo { - fn byte_size(&self) -> usize { self.formatter_item_info.byte_size } - fn print_width(&self) -> usize { self.formatter_item_info.print_width } + fn byte_size(&self) -> usize { + self.formatter_item_info.byte_size + } + fn print_width(&self) -> usize { + self.formatter_item_info.print_width + } } #[cfg(test)] @@ -173,8 +193,12 @@ struct TypeInfo { #[cfg(test)] impl TypeSizeInfo for TypeInfo { - fn byte_size(&self) -> usize { self.byte_size } - fn print_width(&self) -> usize { self.print_width } + fn byte_size(&self) -> usize { + self.byte_size + } + fn print_width(&self) -> usize { + self.print_width + } } #[test] @@ -185,14 +209,41 @@ fn test_calculate_alignment() { // ffff ffff ffff ffff ffff ffff ffff ffff // the first line has no additional spacing: - assert_eq!([0, 0, 0, 0, 0, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:8, print_width:23}, 8, 23)); + assert_eq!( + [0, 0, 0, 0, 0, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 8, + print_width: 23, + }, + 8, + 23 + ) + ); // the second line a single space at the start of the block: - assert_eq!([1, 0, 0, 0, 0, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:4, print_width:11}, 8, 23)); + assert_eq!( + [1, 0, 0, 0, 0, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 4, + print_width: 11, + }, + 8, + 23 + ) + ); // the third line two spaces at pos 0, and 1 space at pos 4: - assert_eq!([2, 0, 0, 0, 1, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:2, print_width:5}, 8, 23)); + assert_eq!( + [2, 0, 0, 0, 1, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 2, + print_width: 5, + }, + 8, + 23 + ) + ); // For this example `byte_size_block` is 8 and 'print_width_block' is 28: // 18446744073709551615 18446744073709551615 @@ -200,42 +251,195 @@ fn test_calculate_alignment() { // 177777 177777 177777 177777 177777 177777 177777 177777 // ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff - assert_eq!([7, 0, 0, 0, 0, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:8, print_width:21}, 8, 28)); - assert_eq!([5, 0, 0, 0, 5, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:4, print_width:9}, 8, 28)); - assert_eq!([0, 0, 0, 0, 0, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:2, print_width:7}, 8, 28)); - assert_eq!([1, 0, 1, 0, 1, 0, 1, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:3}, 8, 28)); + assert_eq!( + [7, 0, 0, 0, 0, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 8, + print_width: 21, + }, + 8, + 28 + ) + ); + assert_eq!( + [5, 0, 0, 0, 5, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 4, + print_width: 9, + }, + 8, + 28 + ) + ); + assert_eq!( + [0, 0, 0, 0, 0, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 2, + print_width: 7, + }, + 8, + 28 + ) + ); + assert_eq!( + [1, 0, 1, 0, 1, 0, 1, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 3, + }, + 8, + 28 + ) + ); // 9 tests where 8 .. 16 spaces are spread across 8 positions - assert_eq!([1, 1, 1, 1, 1, 1, 1, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 8)); - assert_eq!([2, 1, 1, 1, 1, 1, 1, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 9)); - assert_eq!([2, 1, 1, 1, 2, 1, 1, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 10)); - assert_eq!([3, 1, 1, 1, 2, 1, 1, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 11)); - assert_eq!([2, 1, 2, 1, 2, 1, 2, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 12)); - assert_eq!([3, 1, 2, 1, 2, 1, 2, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 13)); - assert_eq!([3, 1, 2, 1, 3, 1, 2, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 14)); - assert_eq!([4, 1, 2, 1, 3, 1, 2, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 15)); - assert_eq!([2, 2, 2, 2, 2, 2, 2, 2], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 16)); + assert_eq!( + [1, 1, 1, 1, 1, 1, 1, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 8 + ) + ); + assert_eq!( + [2, 1, 1, 1, 1, 1, 1, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 9 + ) + ); + assert_eq!( + [2, 1, 1, 1, 2, 1, 1, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 10 + ) + ); + assert_eq!( + [3, 1, 1, 1, 2, 1, 1, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 11 + ) + ); + assert_eq!( + [2, 1, 2, 1, 2, 1, 2, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 12 + ) + ); + assert_eq!( + [3, 1, 2, 1, 2, 1, 2, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 13 + ) + ); + assert_eq!( + [3, 1, 2, 1, 3, 1, 2, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 14 + ) + ); + assert_eq!( + [4, 1, 2, 1, 3, 1, 2, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 15 + ) + ); + assert_eq!( + [2, 2, 2, 2, 2, 2, 2, 2], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 16 + ) + ); // 4 tests where 15 spaces are spread across 8, 4, 2 or 1 position(s) - assert_eq!([4, 1, 2, 1, 3, 1, 2, 1], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:1, print_width:2}, 8, 16 + 15)); - assert_eq!([5, 0, 3, 0, 4, 0, 3, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:2, print_width:4}, 8, 16 + 15)); - assert_eq!([8, 0, 0, 0, 7, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:4, print_width:8}, 8, 16 + 15)); - assert_eq!([15, 0, 0, 0, 0, 0, 0, 0], - OutputInfo::calculate_alignment(&TypeInfo{byte_size:8, print_width:16}, 8, 16 + 15)); + assert_eq!( + [4, 1, 2, 1, 3, 1, 2, 1], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 1, + print_width: 2, + }, + 8, + 16 + 15 + ) + ); + assert_eq!( + [5, 0, 3, 0, 4, 0, 3, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 2, + print_width: 4, + }, + 8, + 16 + 15 + ) + ); + assert_eq!( + [8, 0, 0, 0, 7, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 4, + print_width: 8, + }, + 8, + 16 + 15 + ) + ); + assert_eq!( + [15, 0, 0, 0, 0, 0, 0, 0], + OutputInfo::calculate_alignment( + &TypeInfo { + byte_size: 8, + print_width: 16, + }, + 8, + 16 + 15 + ) + ); } diff --git a/src/od/parse_formats.rs b/src/od/parse_formats.rs index 6669b09bb..f8c3659f0 100644 --- a/src/od/parse_formats.rs +++ b/src/od/parse_formats.rs @@ -5,12 +5,15 @@ use prn_float::*; #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct ParsedFormatterItemInfo { - pub formatter_item_info: FormatterItemInfo, + pub formatter_item_info: FormatterItemInfo, pub add_ascii_dump: bool, } impl ParsedFormatterItemInfo { - pub fn new(formatter_item_info: FormatterItemInfo, add_ascii_dump: bool) -> ParsedFormatterItemInfo { + pub fn new( + formatter_item_info: FormatterItemInfo, + add_ascii_dump: bool, + ) -> ParsedFormatterItemInfo { ParsedFormatterItemInfo { formatter_item_info: formatter_item_info, add_ascii_dump: add_ascii_dump, @@ -51,45 +54,41 @@ fn od_format_type(type_char: FormatType, byte_size: u8) -> Option Some(FORMAT_ITEM_DEC8S), (FormatType::DecimalInt, 2) => Some(FORMAT_ITEM_DEC16S), - (FormatType::DecimalInt, 0) | - (FormatType::DecimalInt, 4) => Some(FORMAT_ITEM_DEC32S), + (FormatType::DecimalInt, 0) | (FormatType::DecimalInt, 4) => Some(FORMAT_ITEM_DEC32S), (FormatType::DecimalInt, 8) => Some(FORMAT_ITEM_DEC64S), (FormatType::OctalInt, 1) => Some(FORMAT_ITEM_OCT8), (FormatType::OctalInt, 2) => Some(FORMAT_ITEM_OCT16), - (FormatType::OctalInt, 0) | - (FormatType::OctalInt, 4) => Some(FORMAT_ITEM_OCT32), + (FormatType::OctalInt, 0) | (FormatType::OctalInt, 4) => Some(FORMAT_ITEM_OCT32), (FormatType::OctalInt, 8) => Some(FORMAT_ITEM_OCT64), (FormatType::UnsignedInt, 1) => Some(FORMAT_ITEM_DEC8U), (FormatType::UnsignedInt, 2) => Some(FORMAT_ITEM_DEC16U), - (FormatType::UnsignedInt, 0) | - (FormatType::UnsignedInt, 4) => Some(FORMAT_ITEM_DEC32U), + (FormatType::UnsignedInt, 0) | (FormatType::UnsignedInt, 4) => Some(FORMAT_ITEM_DEC32U), (FormatType::UnsignedInt, 8) => Some(FORMAT_ITEM_DEC64U), (FormatType::HexadecimalInt, 1) => Some(FORMAT_ITEM_HEX8), (FormatType::HexadecimalInt, 2) => Some(FORMAT_ITEM_HEX16), - (FormatType::HexadecimalInt, 0) | - (FormatType::HexadecimalInt, 4) => Some(FORMAT_ITEM_HEX32), + (FormatType::HexadecimalInt, 0) | (FormatType::HexadecimalInt, 4) => { + Some(FORMAT_ITEM_HEX32) + } (FormatType::HexadecimalInt, 8) => Some(FORMAT_ITEM_HEX64), (FormatType::Float, 2) => Some(FORMAT_ITEM_F16), - (FormatType::Float, 0) | - (FormatType::Float, 4) => Some(FORMAT_ITEM_F32), + (FormatType::Float, 0) | (FormatType::Float, 4) => Some(FORMAT_ITEM_F32), (FormatType::Float, 8) => Some(FORMAT_ITEM_F64), _ => None, } } -fn od_argument_with_option(ch:char) -> bool { +fn od_argument_with_option(ch: char) -> bool { match ch { 'A' | 'j' | 'N' | 'S' | 'w' => true, _ => false, } } - /// Parses format flags from commandline /// /// getopts, docopt, clap don't seem suitable to parse the commandline @@ -156,7 +155,9 @@ pub fn parse_format_flags(args: &Vec) -> Result Option { } } - fn format_type_category(t: FormatType) -> FormatTypeCategory { match t { - FormatType::Ascii | FormatType::Char - => FormatTypeCategory::Char, - FormatType::DecimalInt | FormatType::OctalInt | FormatType::UnsignedInt | FormatType::HexadecimalInt - => FormatTypeCategory::Integer, - FormatType::Float - => FormatTypeCategory::Float, + FormatType::Ascii | FormatType::Char => FormatTypeCategory::Char, + FormatType::DecimalInt + | FormatType::OctalInt + | FormatType::UnsignedInt + | FormatType::HexadecimalInt => FormatTypeCategory::Integer, + FormatType::Float => FormatTypeCategory::Float, } } -fn is_format_size_char(ch: Option, format_type: FormatTypeCategory, byte_size: &mut u8) -> bool { +fn is_format_size_char( + ch: Option, + format_type: FormatTypeCategory, + byte_size: &mut u8, +) -> bool { match (format_type, ch) { (FormatTypeCategory::Integer, Some('C')) => { *byte_size = 1; true - }, + } (FormatTypeCategory::Integer, Some('S')) => { *byte_size = 2; true - }, + } (FormatTypeCategory::Integer, Some('I')) => { *byte_size = 4; true - }, + } (FormatTypeCategory::Integer, Some('L')) => { *byte_size = 8; true - }, + } (FormatTypeCategory::Float, Some('F')) => { *byte_size = 4; true - }, + } (FormatTypeCategory::Float, Some('D')) => { *byte_size = 8; true - }, + } // FormatTypeCategory::Float, 'L' => *byte_size = 16, // TODO support f128 - _ => false, } } -fn is_format_size_decimal(ch: Option, format_type: FormatTypeCategory, decimal_size: &mut String) -> bool { - if format_type == FormatTypeCategory::Char { return false; } +fn is_format_size_decimal( + ch: Option, + format_type: FormatTypeCategory, + decimal_size: &mut String, +) -> bool { + if format_type == FormatTypeCategory::Char { + return false; + } match ch { Some(d) if d.is_digit(10) => { decimal_size.push(d); @@ -274,7 +283,10 @@ fn parse_type_string(params: &String) -> Result, St let type_char = match format_type(type_char) { Some(t) => t, None => { - return Err(format!("unexpected char '{}' in format specification '{}'", type_char, params)); + return Err(format!( + "unexpected char '{}' in format specification '{}'", + type_char, params + )); } }; @@ -293,7 +305,12 @@ fn parse_type_string(params: &String) -> Result, St } if !decimal_size.is_empty() { byte_size = match decimal_size.parse() { - Err(_) => return Err(format!("invalid number '{}' in format specification '{}'", decimal_size, params)), + Err(_) => { + return Err(format!( + "invalid number '{}' in format specification '{}'", + decimal_size, params + )) + } Ok(n) => n, } } @@ -304,7 +321,12 @@ fn parse_type_string(params: &String) -> Result, St match od_format_type(type_char, byte_size) { Some(ft) => formats.push(ParsedFormatterItemInfo::new(ft, show_ascii_dump)), - None => return Err(format!("invalid size '{}' in format specification '{}'", byte_size, params)), + None => { + return Err(format!( + "invalid size '{}' in format specification '{}'", + byte_size, params + )) + } } } @@ -312,7 +334,9 @@ fn parse_type_string(params: &String) -> Result, St } #[cfg(test)] -pub fn parse_format_flags_str(args_str: &Vec<&'static str>) -> Result, String> { +pub fn parse_format_flags_str( + args_str: &Vec<&'static str>, +) -> Result, String> { let args = args_str.iter().map(|s| s.to_string()).collect(); match parse_format_flags(&args) { Err(e) => Err(e), @@ -322,195 +346,214 @@ pub fn parse_format_flags_str(args_str: &Vec<&'static str>) -> Result)), } - /// Interprets the commandline inputs of od. /// /// Returns either an unspecified number of filenames. @@ -52,7 +51,7 @@ pub fn parse_inputs(matches: &CommandLineOpts) -> Result { // if there is just 1 input (stdin), an offset must start with '+' @@ -60,7 +59,11 @@ pub fn parse_inputs(matches: &CommandLineOpts) -> Result { @@ -82,9 +85,7 @@ pub fn parse_inputs(matches: &CommandLineOpts) -> Result) -> Result { match input_strings.len() { - 0 => { - Ok(CommandLineInputs::FileNames(vec!["-".to_string()])) - } + 0 => Ok(CommandLineInputs::FileNames(vec!["-".to_string()])), 1 => { let offset0 = parse_offset_operand(&input_strings[0]); Ok(match offset0 { @@ -96,8 +97,16 @@ pub fn parse_inputs_traditional(input_strings: Vec) -> Result Ok(CommandLineInputs::FileAndOffset(("-".to_string(), n, Some(m)))), - (_, Ok(m)) => Ok(CommandLineInputs::FileAndOffset((input_strings[0].clone(), m, None))), + (Ok(n), Ok(m)) => Ok(CommandLineInputs::FileAndOffset(( + "-".to_string(), + n, + Some(m), + ))), + (_, Ok(m)) => Ok(CommandLineInputs::FileAndOffset(( + input_strings[0].clone(), + m, + None, + ))), _ => Err(format!("invalid offset: {}", input_strings[1])), } } @@ -105,14 +114,19 @@ pub fn parse_inputs_traditional(input_strings: Vec) -> Result Ok(CommandLineInputs::FileAndOffset((input_strings[0].clone(), n, Some(m)))), + (Ok(n), Ok(m)) => Ok(CommandLineInputs::FileAndOffset(( + input_strings[0].clone(), + n, + Some(m), + ))), (Err(_), _) => Err(format!("invalid offset: {}", input_strings[1])), (_, Err(_)) => Err(format!("invalid label: {}", input_strings[2])), } } - _ => { - Err(format!("too many inputs after --traditional: {}", input_strings[3])) - } + _ => Err(format!( + "too many inputs after --traditional: {}", + input_strings[3] + )), } } @@ -146,7 +160,6 @@ pub fn parse_offset_operand(s: &String) -> Result { } } - #[cfg(test)] mod tests { use super::*; @@ -187,143 +200,151 @@ mod tests { #[test] fn test_parse_inputs_normal() { - assert_eq!(CommandLineInputs::FileNames(vec!["-".to_string()]), - parse_inputs(&MockOptions::new( - vec![], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["-".to_string()]), + parse_inputs(&MockOptions::new(vec![], vec![])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["-".to_string()]), - parse_inputs(&MockOptions::new( - vec!["-"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["-".to_string()]), + parse_inputs(&MockOptions::new(vec!["-"], vec![])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["file1".to_string()]), - parse_inputs(&MockOptions::new( - vec!["file1"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["file1".to_string()]), + parse_inputs(&MockOptions::new(vec!["file1"], vec![])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["file1".to_string(), "file2".to_string()]), - parse_inputs(&MockOptions::new( - vec!["file1", "file2"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["file1".to_string(), "file2".to_string()]), + parse_inputs(&MockOptions::new(vec!["file1", "file2"], vec![])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["-".to_string(), "file1".to_string(), "file2".to_string()]), - parse_inputs(&MockOptions::new( - vec!["-", "file1", "file2"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec![ + "-".to_string(), + "file1".to_string(), + "file2".to_string(), + ]), + parse_inputs(&MockOptions::new(vec!["-", "file1", "file2"], vec![])).unwrap() + ); } #[test] fn test_parse_inputs_with_offset() { // offset is found without filename, so stdin will be used. - assert_eq!(CommandLineInputs::FileAndOffset(("-".to_string(), 8, None)), - parse_inputs(&MockOptions::new( - vec!["+10"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileAndOffset(("-".to_string(), 8, None)), + parse_inputs(&MockOptions::new(vec!["+10"], vec![])).unwrap() + ); // offset must start with "+" if no input is specified. - assert_eq!(CommandLineInputs::FileNames(vec!["10".to_string()]), - parse_inputs(&MockOptions::new( - vec!["10"], - vec![""])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["10".to_string()]), + parse_inputs(&MockOptions::new(vec!["10"], vec![""])).unwrap() + ); // offset is not valid, so it is considered a filename. - assert_eq!(CommandLineInputs::FileNames(vec!["+10a".to_string()]), - parse_inputs(&MockOptions::new( - vec!["+10a"], - vec![""])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["+10a".to_string()]), + parse_inputs(&MockOptions::new(vec!["+10a"], vec![""])).unwrap() + ); // if -j is included in the commandline, there cannot be an offset. - assert_eq!(CommandLineInputs::FileNames(vec!["+10".to_string()]), - parse_inputs(&MockOptions::new( - vec!["+10"], - vec!["j"])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["+10".to_string()]), + parse_inputs(&MockOptions::new(vec!["+10"], vec!["j"])).unwrap() + ); // if -v is included in the commandline, there cannot be an offset. - assert_eq!(CommandLineInputs::FileNames(vec!["+10".to_string()]), - parse_inputs(&MockOptions::new( - vec!["+10"], - vec!["o", "v"])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["+10".to_string()]), + parse_inputs(&MockOptions::new(vec!["+10"], vec!["o", "v"])).unwrap() + ); - assert_eq!(CommandLineInputs::FileAndOffset(("file1".to_string(), 8, None)), - parse_inputs(&MockOptions::new( - vec!["file1", "+10"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileAndOffset(("file1".to_string(), 8, None)), + parse_inputs(&MockOptions::new(vec!["file1", "+10"], vec![])).unwrap() + ); // offset does not need to start with "+" if a filename is included. - assert_eq!(CommandLineInputs::FileAndOffset(("file1".to_string(), 8, None)), - parse_inputs(&MockOptions::new( - vec!["file1", "10"], - vec![])).unwrap()); + assert_eq!( + CommandLineInputs::FileAndOffset(("file1".to_string(), 8, None)), + parse_inputs(&MockOptions::new(vec!["file1", "10"], vec![])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["file1".to_string(), "+10a".to_string()]), - parse_inputs(&MockOptions::new( - vec!["file1", "+10a"], - vec![""])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["file1".to_string(), "+10a".to_string()]), + parse_inputs(&MockOptions::new(vec!["file1", "+10a"], vec![""])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["file1".to_string(), "+10".to_string()]), - parse_inputs(&MockOptions::new( - vec!["file1", "+10"], - vec!["j"])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["file1".to_string(), "+10".to_string()]), + parse_inputs(&MockOptions::new(vec!["file1", "+10"], vec!["j"])).unwrap() + ); // offset must be last on the commandline - assert_eq!(CommandLineInputs::FileNames(vec!["+10".to_string(), "file1".to_string()]), - parse_inputs(&MockOptions::new( - vec!["+10", "file1"], - vec![""])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["+10".to_string(), "file1".to_string()]), + parse_inputs(&MockOptions::new(vec!["+10", "file1"], vec![""])).unwrap() + ); } #[test] fn test_parse_inputs_traditional() { // it should not return FileAndOffset to signal no offset was entered on the commandline. - assert_eq!(CommandLineInputs::FileNames(vec!["-".to_string()]), - parse_inputs(&MockOptions::new( - vec![], - vec!["traditional"])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["-".to_string()]), + parse_inputs(&MockOptions::new(vec![], vec!["traditional"])).unwrap() + ); - assert_eq!(CommandLineInputs::FileNames(vec!["file1".to_string()]), - parse_inputs(&MockOptions::new( - vec!["file1"], - vec!["traditional"])).unwrap()); + assert_eq!( + CommandLineInputs::FileNames(vec!["file1".to_string()]), + parse_inputs(&MockOptions::new(vec!["file1"], vec!["traditional"])).unwrap() + ); // offset does not need to start with a + - assert_eq!(CommandLineInputs::FileAndOffset(("-".to_string(), 8, None)), - parse_inputs(&MockOptions::new( - vec!["10"], - vec!["traditional"])).unwrap()); + assert_eq!( + CommandLineInputs::FileAndOffset(("-".to_string(), 8, None)), + parse_inputs(&MockOptions::new(vec!["10"], vec!["traditional"])).unwrap() + ); // valid offset and valid label - assert_eq!(CommandLineInputs::FileAndOffset(("-".to_string(), 8, Some(8))), - parse_inputs(&MockOptions::new( - vec!["10", "10"], - vec!["traditional"])).unwrap()); + assert_eq!( + CommandLineInputs::FileAndOffset(("-".to_string(), 8, Some(8))), + parse_inputs(&MockOptions::new(vec!["10", "10"], vec!["traditional"])).unwrap() + ); - assert_eq!(CommandLineInputs::FileAndOffset(("file1".to_string(), 8, None)), - parse_inputs(&MockOptions::new( - vec!["file1", "10"], - vec!["traditional"])).unwrap()); + assert_eq!( + CommandLineInputs::FileAndOffset(("file1".to_string(), 8, None)), + parse_inputs(&MockOptions::new(vec!["file1", "10"], vec!["traditional"])).unwrap() + ); // only one file is allowed, it must be the first - parse_inputs(&MockOptions::new( - vec!["10", "file1"], - vec!["traditional"])).unwrap_err(); + parse_inputs(&MockOptions::new(vec!["10", "file1"], vec!["traditional"])).unwrap_err(); - assert_eq!(CommandLineInputs::FileAndOffset(("file1".to_string(), 8, Some(8))), + assert_eq!( + CommandLineInputs::FileAndOffset(("file1".to_string(), 8, Some(8))), parse_inputs(&MockOptions::new( vec!["file1", "10", "10"], - vec!["traditional"])).unwrap()); + vec!["traditional"] + )).unwrap() + ); parse_inputs(&MockOptions::new( - vec!["10", "file1", "10"], - vec!["traditional"])).unwrap_err(); + vec!["10", "file1", "10"], + vec!["traditional"], + )).unwrap_err(); parse_inputs(&MockOptions::new( - vec!["10", "10", "file1"], - vec!["traditional"])).unwrap_err(); + vec!["10", "10", "file1"], + vec!["traditional"], + )).unwrap_err(); parse_inputs(&MockOptions::new( - vec!["10", "10", "10", "10"], - vec!["traditional"])).unwrap_err(); + vec!["10", "10", "10", "10"], + vec!["traditional"], + )).unwrap_err(); } fn parse_offset_operand_str(s: &str) -> Result { diff --git a/src/od/parse_nrofbytes.rs b/src/od/parse_nrofbytes.rs index be55cb7b6..c934de9c5 100644 --- a/src/od/parse_nrofbytes.rs +++ b/src/od/parse_nrofbytes.rs @@ -1,4 +1,3 @@ - pub fn parse_number_of_bytes(s: &String) -> Result { let mut start = 0; let mut len = s.len(); @@ -17,7 +16,7 @@ pub fn parse_number_of_bytes(s: &String) -> Result { Some('b') if radix != 16 => { multiply = 512; len -= 1; - }, + } Some('k') | Some('K') => { multiply = 1024; len -= 1; @@ -59,8 +58,8 @@ pub fn parse_number_of_bytes(s: &String) -> Result { Some('E') => 1000 * 1000 * 1000 * 1000 * 1000 * 1000, _ => return Err("parse failed"), } - }, - _ => {}, + } + _ => {} } match usize::from_str_radix(&s[start..len], radix) { @@ -120,9 +119,15 @@ fn test_parse_number_of_bytes() { fn test_parse_number_of_bytes_64bits() { assert_eq!(1099511627776, parse_number_of_bytes_str("1T").unwrap()); assert_eq!(1125899906842624, parse_number_of_bytes_str("1P").unwrap()); - assert_eq!(1152921504606846976, parse_number_of_bytes_str("1E").unwrap()); + assert_eq!( + 1152921504606846976, + parse_number_of_bytes_str("1E").unwrap() + ); assert_eq!(2000000000000, parse_number_of_bytes_str("2TB").unwrap()); assert_eq!(2000000000000000, parse_number_of_bytes_str("2PB").unwrap()); - assert_eq!(2000000000000000000, parse_number_of_bytes_str("2EB").unwrap()); + assert_eq!( + 2000000000000000000, + parse_number_of_bytes_str("2EB").unwrap() + ); } diff --git a/src/od/partialreader.rs b/src/od/partialreader.rs index 72a37f58b..42bca6428 100644 --- a/src/od/partialreader.rs +++ b/src/od/partialreader.rs @@ -34,7 +34,9 @@ impl Read for PartialReader { if self.skip > 0 { let buf_size = cmp::min(self.skip, MAX_SKIP_BUFFER); let mut bytes: Vec = Vec::with_capacity(buf_size); - unsafe { bytes.set_len(buf_size); } + unsafe { + bytes.set_len(buf_size); + } while self.skip > 0 { let skip_count = cmp::min(self.skip, buf_size); @@ -49,15 +51,19 @@ impl Read for PartialReader { None => self.inner.read(out), Some(0) => Ok(0), Some(ref mut limit) => { - let slice = if *limit > out.len() { out } else { &mut out[0..*limit] }; + let slice = if *limit > out.len() { + out + } else { + &mut out[0..*limit] + }; match self.inner.read(slice) { Err(e) => Err(e), Ok(r) => { *limit -= r; Ok(r) - }, + } } - }, + } } } } @@ -71,7 +77,7 @@ impl HasError for PartialReader { #[cfg(test)] mod tests { use super::*; - use std::io::{Cursor, Read, ErrorKind}; + use std::io::{Cursor, ErrorKind, Read}; use std::error::Error; use mockstream::*; @@ -127,8 +133,7 @@ mod tests { #[test] fn test_read_skipping_with_two_reads_during_skip() { let mut v = [0; 10]; - let c = Cursor::new(&b"a"[..]) - .chain(Cursor::new(&b"bcdefgh"[..])); + let c = Cursor::new(&b"a"[..]).chain(Cursor::new(&b"bcdefgh"[..])); let mut sut = PartialReader::new(c, 2, None); assert_eq!(sut.read(v.as_mut()).unwrap(), 6); diff --git a/src/od/peekreader.rs b/src/od/peekreader.rs index b6e4d53ae..825335f20 100644 --- a/src/od/peekreader.rs +++ b/src/od/peekreader.rs @@ -28,7 +28,7 @@ pub trait PeekRead { /// /// # Panics /// Might panic if `peek_size` is larger then the size of `out` - fn peek_read(&mut self, out: &mut [u8], peek_size: usize) -> io::Result<(usize,usize)>; + fn peek_read(&mut self, out: &mut [u8], peek_size: usize) -> io::Result<(usize, usize)>; } /// Wrapper for `std::io::Read` allowing to peek into the data to be read. @@ -53,7 +53,7 @@ impl PeekReader { Ok(n) => { self.temp_buffer.drain(..n); n - }, + } Err(_) => 0, } } @@ -83,7 +83,7 @@ impl PeekRead for PeekReader { /// /// # Panics /// If `peek_size` is larger then the size of `out` - fn peek_read(&mut self, out: &mut [u8], peek_size: usize) -> io::Result<(usize,usize)> { + fn peek_read(&mut self, out: &mut [u8], peek_size: usize) -> io::Result<(usize, usize)> { assert!(out.len() >= peek_size); match self.read(out) { Err(e) => Err(e), @@ -97,7 +97,7 @@ impl PeekRead for PeekReader { self.write_to_tempbuffer(&out[real_size..bytes_in_buffer]); Ok((real_size, actual_peek_size)) } - }, + } } } } @@ -127,7 +127,7 @@ mod tests { let mut sut = PeekReader::new(Cursor::new(&b"abcdefgh"[..])); let mut v = [0; 10]; - assert_eq!(sut.peek_read(v.as_mut(), 0).unwrap(), (8,0)); + assert_eq!(sut.peek_read(v.as_mut(), 0).unwrap(), (8, 0)); assert_eq!(v, [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0, 0]); } diff --git a/src/od/prn_char.rs b/src/od/prn_char.rs index 55a7c6076..1b01956ee 100644 --- a/src/od/prn_char.rs +++ b/src/od/prn_char.rs @@ -13,51 +13,33 @@ pub static FORMAT_ITEM_C: FormatterItemInfo = FormatterItemInfo { formatter: FormatWriter::MultibyteWriter(format_item_c), }; - -static A_CHRS: [&'static str; 128] = -["nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", - "bs", "ht", "nl", "vt", "ff", "cr", "so", "si", - "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", - "can", "em", "sub", "esc", "fs", "gs", "rs", "us", - "sp", "!", "\"", "#", "$", "%", "&", "'", - "(", ")", "*", "+", ",", "-", ".", "/", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", ":", ";", "<", "=", ">", "?", - "@", "A", "B", "C", "D", "E", "F", "G", - "H", "I", "J", "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", "U", "V", "W", - "X", "Y", "Z", "[", "\\", "]", "^", "_", - "`", "a", "b", "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", "m", "n", "o", - "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", "~", "del"]; +static A_CHRS: [&'static str; 128] = [ + "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs", "ht", "nl", "vt", "ff", "cr", + "so", "si", "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em", "sub", "esc", + "fs", "gs", "rs", "us", "sp", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", + ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", + "z", "{", "|", "}", "~", "del", +]; fn format_item_a(p: u64) -> String { // itembytes == 1 let b = (p & 0x7f) as u8; - format!("{:>4}", A_CHRS.get(b as usize).unwrap_or(&"??") - ) + format!("{:>4}", A_CHRS.get(b as usize).unwrap_or(&"??")) } - -static C_CHRS: [&'static str; 128] = [ -"\\0", "001", "002", "003", "004", "005", "006", "\\a", -"\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "016", "017", -"020", "021", "022", "023", "024", "025", "026", "027", -"030", "031", "032", "033", "034", "035", "036", "037", - " ", "!", "\"", "#", "$", "%", "&", "'", - "(", ")", "*", "+", ",", "-", ".", "/", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", ":", ";", "<", "=", ">", "?", - "@", "A", "B", "C", "D", "E", "F", "G", - "H", "I", "J", "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", "U", "V", "W", - "X", "Y", "Z", "[", "\\", "]", "^", "_", - "`", "a", "b", "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", "m", "n", "o", - "p", "q", "r", "s", "t", "u", "v", "w", - "x", "y", "z", "{", "|", "}", "~", "177"]; - +static C_CHRS: [&'static str; 128] = [ + "\\0", "001", "002", "003", "004", "005", "006", "\\a", "\\b", "\\t", "\\n", "\\v", "\\f", + "\\r", "016", "017", "020", "021", "022", "023", "024", "025", "026", "027", "030", "031", + "032", "033", "034", "035", "036", "037", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", + "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", + "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", + "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", + "v", "w", "x", "y", "z", "{", "|", "}", "~", "177", +]; fn format_item_c(bytes: &[u8]) -> String { // itembytes == 1 @@ -74,20 +56,20 @@ fn format_item_c(bytes: &[u8]) -> String { } else if ((b & 0xe0) == 0xc0) && (bytes.len() >= 2) { // start of a 2 octet utf-8 sequence match from_utf8(&bytes[0..2]) { - Ok(s) => { format!("{:>4}", s) }, - Err(_) => { format!(" {:03o}", b) }, + Ok(s) => format!("{:>4}", s), + Err(_) => format!(" {:03o}", b), } } else if ((b & 0xf0) == 0xe0) && (bytes.len() >= 3) { // start of a 3 octet utf-8 sequence match from_utf8(&bytes[0..3]) { - Ok(s) => { format!("{:>4}", s) }, - Err(_) => { format!(" {:03o}", b) }, + Ok(s) => format!("{:>4}", s), + Err(_) => format!(" {:03o}", b), } } else if ((b & 0xf8) == 0xf0) && (bytes.len() >= 4) { // start of a 4 octet utf-8 sequence match from_utf8(&bytes[0..4]) { - Ok(s) => { format!("{:>4}", s) }, - Err(_) => { format!(" {:03o}", b) }, + Ok(s) => format!("{:>4}", s), + Err(_) => format!(" {:03o}", b), } } else { // invalid utf-8 @@ -146,7 +128,10 @@ fn test_format_item_c() { assert_eq!(" \u{1000}", format_item_c(&[0xe1, 0x80, 0x80, 0x21])); assert_eq!(" \u{1f496}", format_item_c(&[0xf0, 0x9f, 0x92, 0x96])); - assert_eq!(" \u{1f496}", format_item_c(&[0xf0, 0x9f, 0x92, 0x96, 0x21])); + assert_eq!( + " \u{1f496}", + format_item_c(&[0xf0, 0x9f, 0x92, 0x96, 0x21]) + ); assert_eq!(" 300", format_item_c(&[0xc0, 0x80])); // invalid utf-8 (MUTF-8 null) assert_eq!(" 301", format_item_c(&[0xc1, 0xa1])); // invalid utf-8 @@ -162,5 +147,8 @@ fn test_format_item_c() { #[test] fn test_format_ascii_dump() { assert_eq!(">.<", format_ascii_dump(&[0x00])); - assert_eq!(">. A~.<", format_ascii_dump(&[0x1f, 0x20, 0x41, 0x7e, 0x7f])); + assert_eq!( + ">. A~.<", + format_ascii_dump(&[0x1f, 0x20, 0x41, 0x7e, 0x7f]) + ); } diff --git a/src/od/prn_float.rs b/src/od/prn_float.rs index 5162fbc29..19ba3cca3 100644 --- a/src/od/prn_float.rs +++ b/src/od/prn_float.rs @@ -58,9 +58,13 @@ fn format_flo64(f: f64) -> String { fn format_float(f: f64, width: usize, precision: usize) -> String { if !f.is_normal() { - if f == -0.0 && f.is_sign_negative() { return format!("{:>width$}", "-0", width = width) } - if f == 0.0 || !f.is_finite() { return format!("{:width$}", f, width = width) } - return format!("{:width$e}", f, width = width) // subnormal numbers + if f == -0.0 && f.is_sign_negative() { + return format!("{:>width$}", "-0", width = width); + } + if f == 0.0 || !f.is_finite() { + return format!("{:width$}", f, width = width); + } + return format!("{:width$e}", f, width = width); // subnormal numbers } let mut l = f.abs().log10().floor() as i32; @@ -71,115 +75,123 @@ fn format_float(f: f64, width: usize, precision: usize) -> String { l = l - 1; } - if l >= 0 && l <= (precision as i32 - 1) { - format!("{:width$.dec$}", f, + if l >= 0 && l <= (precision as i32 - 1) { + format!( + "{:width$.dec$}", + f, width = width, - dec = (precision-1) - l as usize) + dec = (precision - 1) - l as usize + ) } else if l == -1 { - format!("{:width$.dec$}", f, - width = width, - dec = precision) + format!("{:width$.dec$}", f, width = width, dec = precision) } else { - format!("{:width$.dec$e}", f, - width = width, - dec = precision - 1) + format!("{:width$.dec$e}", f, width = width, dec = precision - 1) } } #[test] fn test_format_flo32() { - assert_eq!(format_flo32(1.0), " 1.0000000"); - assert_eq!(format_flo32(9.9999990), " 9.9999990"); - assert_eq!(format_flo32(10.0), " 10.000000"); - assert_eq!(format_flo32(99.999977), " 99.999977"); - assert_eq!(format_flo32(99.999992), " 99.999992"); - assert_eq!(format_flo32(100.0), " 100.00000"); - assert_eq!(format_flo32(999.99994), " 999.99994"); - assert_eq!(format_flo32(1000.0), " 1000.0000"); - assert_eq!(format_flo32(9999.9990), " 9999.9990"); - assert_eq!(format_flo32(10000.0), " 10000.000"); - assert_eq!(format_flo32(99999.992), " 99999.992"); - assert_eq!(format_flo32(100000.0), " 100000.00"); - assert_eq!(format_flo32(999999.94), " 999999.94"); - assert_eq!(format_flo32(1000000.0), " 1000000.0"); - assert_eq!(format_flo32(9999999.0), " 9999999.0"); - assert_eq!(format_flo32(10000000.0), " 10000000"); - assert_eq!(format_flo32(99999992.0), " 99999992"); - assert_eq!(format_flo32(100000000.0), " 1.0000000e8"); - assert_eq!(format_flo32(9.9999994e8), " 9.9999994e8"); - assert_eq!(format_flo32(1.0e9), " 1.0000000e9"); - assert_eq!(format_flo32(9.9999990e9), " 9.9999990e9"); - assert_eq!(format_flo32(1.0e10), " 1.0000000e10"); + assert_eq!(format_flo32(1.0), " 1.0000000"); + assert_eq!(format_flo32(9.9999990), " 9.9999990"); + assert_eq!(format_flo32(10.0), " 10.000000"); + assert_eq!(format_flo32(99.999977), " 99.999977"); + assert_eq!(format_flo32(99.999992), " 99.999992"); + assert_eq!(format_flo32(100.0), " 100.00000"); + assert_eq!(format_flo32(999.99994), " 999.99994"); + assert_eq!(format_flo32(1000.0), " 1000.0000"); + assert_eq!(format_flo32(9999.9990), " 9999.9990"); + assert_eq!(format_flo32(10000.0), " 10000.000"); + assert_eq!(format_flo32(99999.992), " 99999.992"); + assert_eq!(format_flo32(100000.0), " 100000.00"); + assert_eq!(format_flo32(999999.94), " 999999.94"); + assert_eq!(format_flo32(1000000.0), " 1000000.0"); + assert_eq!(format_flo32(9999999.0), " 9999999.0"); + assert_eq!(format_flo32(10000000.0), " 10000000"); + assert_eq!(format_flo32(99999992.0), " 99999992"); + assert_eq!(format_flo32(100000000.0), " 1.0000000e8"); + assert_eq!(format_flo32(9.9999994e8), " 9.9999994e8"); + assert_eq!(format_flo32(1.0e9), " 1.0000000e9"); + assert_eq!(format_flo32(9.9999990e9), " 9.9999990e9"); + assert_eq!(format_flo32(1.0e10), " 1.0000000e10"); - assert_eq!(format_flo32(0.1), " 0.10000000"); - assert_eq!(format_flo32(0.99999994), " 0.99999994"); - assert_eq!(format_flo32(0.010000001), " 1.0000001e-2"); - assert_eq!(format_flo32(0.099999994), " 9.9999994e-2"); - assert_eq!(format_flo32(0.001), " 1.0000000e-3"); - assert_eq!(format_flo32(0.0099999998), " 9.9999998e-3"); + assert_eq!(format_flo32(0.1), " 0.10000000"); + assert_eq!(format_flo32(0.99999994), " 0.99999994"); + assert_eq!(format_flo32(0.010000001), " 1.0000001e-2"); + assert_eq!(format_flo32(0.099999994), " 9.9999994e-2"); + assert_eq!(format_flo32(0.001), " 1.0000000e-3"); + assert_eq!(format_flo32(0.0099999998), " 9.9999998e-3"); - assert_eq!(format_flo32(-1.0), " -1.0000000"); - assert_eq!(format_flo32(-9.9999990), " -9.9999990"); - assert_eq!(format_flo32(-10.0), " -10.000000"); - assert_eq!(format_flo32(-99.999977), " -99.999977"); - assert_eq!(format_flo32(-99.999992), " -99.999992"); - assert_eq!(format_flo32(-100.0), " -100.00000"); - assert_eq!(format_flo32(-999.99994), " -999.99994"); - assert_eq!(format_flo32(-1000.0), " -1000.0000"); - assert_eq!(format_flo32(-9999.9990), " -9999.9990"); - assert_eq!(format_flo32(-10000.0), " -10000.000"); - assert_eq!(format_flo32(-99999.992), " -99999.992"); - assert_eq!(format_flo32(-100000.0), " -100000.00"); - assert_eq!(format_flo32(-999999.94), " -999999.94"); - assert_eq!(format_flo32(-1000000.0), " -1000000.0"); - assert_eq!(format_flo32(-9999999.0), " -9999999.0"); - assert_eq!(format_flo32(-10000000.0), " -10000000"); - assert_eq!(format_flo32(-99999992.0), " -99999992"); - assert_eq!(format_flo32(-100000000.0), " -1.0000000e8"); - assert_eq!(format_flo32(-9.9999994e8), " -9.9999994e8"); - assert_eq!(format_flo32(-1.0e9), " -1.0000000e9"); - assert_eq!(format_flo32(-9.9999990e9), " -9.9999990e9"); - assert_eq!(format_flo32(-1.0e10), " -1.0000000e10"); + assert_eq!(format_flo32(-1.0), " -1.0000000"); + assert_eq!(format_flo32(-9.9999990), " -9.9999990"); + assert_eq!(format_flo32(-10.0), " -10.000000"); + assert_eq!(format_flo32(-99.999977), " -99.999977"); + assert_eq!(format_flo32(-99.999992), " -99.999992"); + assert_eq!(format_flo32(-100.0), " -100.00000"); + assert_eq!(format_flo32(-999.99994), " -999.99994"); + assert_eq!(format_flo32(-1000.0), " -1000.0000"); + assert_eq!(format_flo32(-9999.9990), " -9999.9990"); + assert_eq!(format_flo32(-10000.0), " -10000.000"); + assert_eq!(format_flo32(-99999.992), " -99999.992"); + assert_eq!(format_flo32(-100000.0), " -100000.00"); + assert_eq!(format_flo32(-999999.94), " -999999.94"); + assert_eq!(format_flo32(-1000000.0), " -1000000.0"); + assert_eq!(format_flo32(-9999999.0), " -9999999.0"); + assert_eq!(format_flo32(-10000000.0), " -10000000"); + assert_eq!(format_flo32(-99999992.0), " -99999992"); + assert_eq!(format_flo32(-100000000.0), " -1.0000000e8"); + assert_eq!(format_flo32(-9.9999994e8), " -9.9999994e8"); + assert_eq!(format_flo32(-1.0e9), " -1.0000000e9"); + assert_eq!(format_flo32(-9.9999990e9), " -9.9999990e9"); + assert_eq!(format_flo32(-1.0e10), " -1.0000000e10"); - assert_eq!(format_flo32(-0.1), " -0.10000000"); - assert_eq!(format_flo32(-0.99999994), " -0.99999994"); - assert_eq!(format_flo32(-0.010000001), " -1.0000001e-2"); - assert_eq!(format_flo32(-0.099999994), " -9.9999994e-2"); - assert_eq!(format_flo32(-0.001), " -1.0000000e-3"); + assert_eq!(format_flo32(-0.1), " -0.10000000"); + assert_eq!(format_flo32(-0.99999994), " -0.99999994"); + assert_eq!(format_flo32(-0.010000001), " -1.0000001e-2"); + assert_eq!(format_flo32(-0.099999994), " -9.9999994e-2"); + assert_eq!(format_flo32(-0.001), " -1.0000000e-3"); assert_eq!(format_flo32(-0.0099999998), " -9.9999998e-3"); - assert_eq!(format_flo32(3.4028233e38), " 3.4028233e38"); + assert_eq!(format_flo32(3.4028233e38), " 3.4028233e38"); assert_eq!(format_flo32(-3.4028233e38), " -3.4028233e38"); - assert_eq!(format_flo32(-1.1663108e-38),"-1.1663108e-38"); - assert_eq!(format_flo32(-4.7019771e-38),"-4.7019771e-38"); - assert_eq!(format_flo32(1e-45), " 1e-45"); + assert_eq!(format_flo32(-1.1663108e-38), "-1.1663108e-38"); + assert_eq!(format_flo32(-4.7019771e-38), "-4.7019771e-38"); + assert_eq!(format_flo32(1e-45), " 1e-45"); - assert_eq!(format_flo32(-3.402823466e+38), " -3.4028235e38"); - assert_eq!(format_flo32(f32::NAN), " NaN"); - assert_eq!(format_flo32(f32::INFINITY), " inf"); + assert_eq!(format_flo32(-3.402823466e+38), " -3.4028235e38"); + assert_eq!(format_flo32(f32::NAN), " NaN"); + assert_eq!(format_flo32(f32::INFINITY), " inf"); assert_eq!(format_flo32(f32::NEG_INFINITY), " -inf"); - assert_eq!(format_flo32(-0.0), " -0"); - assert_eq!(format_flo32(0.0), " 0"); + assert_eq!(format_flo32(-0.0), " -0"); + assert_eq!(format_flo32(0.0), " 0"); } #[test] fn test_format_flo64() { - assert_eq!(format_flo64(1.0), " 1.0000000000000000"); - assert_eq!(format_flo64(10.0), " 10.000000000000000"); - assert_eq!(format_flo64(1000000000000000.0), " 1000000000000000.0"); - assert_eq!(format_flo64(10000000000000000.0), " 10000000000000000"); - assert_eq!(format_flo64(100000000000000000.0), " 1.0000000000000000e17"); + assert_eq!(format_flo64(1.0), " 1.0000000000000000"); + assert_eq!(format_flo64(10.0), " 10.000000000000000"); + assert_eq!(format_flo64(1000000000000000.0), " 1000000000000000.0"); + assert_eq!( + format_flo64(10000000000000000.0), + " 10000000000000000" + ); + assert_eq!( + format_flo64(100000000000000000.0), + " 1.0000000000000000e17" + ); - assert_eq!(format_flo64(-0.1), " -0.10000000000000001"); - assert_eq!(format_flo64(-0.01), " -1.0000000000000000e-2"); + assert_eq!(format_flo64(-0.1), " -0.10000000000000001"); + assert_eq!(format_flo64(-0.01), " -1.0000000000000000e-2"); - assert_eq!(format_flo64(-2.2250738585072014e-308),"-2.2250738585072014e-308"); - assert_eq!(format_flo64(4e-320), " 4e-320"); - assert_eq!(format_flo64(f64::NAN), " NaN"); - assert_eq!(format_flo64(f64::INFINITY), " inf"); - assert_eq!(format_flo64(f64::NEG_INFINITY), " -inf"); - assert_eq!(format_flo64(-0.0), " -0"); - assert_eq!(format_flo64(0.0), " 0"); + assert_eq!( + format_flo64(-2.2250738585072014e-308), + "-2.2250738585072014e-308" + ); + assert_eq!(format_flo64(4e-320), " 4e-320"); + assert_eq!(format_flo64(f64::NAN), " NaN"); + assert_eq!(format_flo64(f64::INFINITY), " inf"); + assert_eq!(format_flo64(f64::NEG_INFINITY), " -inf"); + assert_eq!(format_flo64(-0.0), " -0"); + assert_eq!(format_flo64(0.0), " 0"); } #[test] @@ -191,20 +203,20 @@ fn test_format_flo16() { assert_eq!(format_flo16(f16::from_bits(0x8402u16)), "-6.115e-5"); assert_eq!(format_flo16(f16::from_bits(0x8403u16)), "-6.121e-5"); - assert_eq!(format_flo16(f16::from_f32(1.0)), " 1.000"); - assert_eq!(format_flo16(f16::from_f32(10.0)), " 10.00"); - assert_eq!(format_flo16(f16::from_f32(100.0)), " 100.0"); - assert_eq!(format_flo16(f16::from_f32(1000.0)), " 1000"); - assert_eq!(format_flo16(f16::from_f32(10000.0)), " 1.000e4"); + assert_eq!(format_flo16(f16::from_f32(1.0)), " 1.000"); + assert_eq!(format_flo16(f16::from_f32(10.0)), " 10.00"); + assert_eq!(format_flo16(f16::from_f32(100.0)), " 100.0"); + assert_eq!(format_flo16(f16::from_f32(1000.0)), " 1000"); + assert_eq!(format_flo16(f16::from_f32(10000.0)), " 1.000e4"); - assert_eq!(format_flo16(f16::from_f32(-0.2)), " -0.2000"); - assert_eq!(format_flo16(f16::from_f32(-0.02)), "-2.000e-2"); + assert_eq!(format_flo16(f16::from_f32(-0.2)), " -0.2000"); + assert_eq!(format_flo16(f16::from_f32(-0.02)), "-2.000e-2"); - assert_eq!(format_flo16(MIN_POSITIVE_SUBNORMAL), " 5.966e-8"); - assert_eq!(format_flo16(MIN), " -6.550e4"); - assert_eq!(format_flo16(NAN), " NaN"); - assert_eq!(format_flo16(INFINITY), " inf"); - assert_eq!(format_flo16(NEG_INFINITY), " -inf"); - assert_eq!(format_flo16(NEG_ZERO), " -0"); - assert_eq!(format_flo16(ZERO), " 0"); + assert_eq!(format_flo16(MIN_POSITIVE_SUBNORMAL), " 5.966e-8"); + assert_eq!(format_flo16(MIN), " -6.550e4"); + assert_eq!(format_flo16(NAN), " NaN"); + assert_eq!(format_flo16(INFINITY), " inf"); + assert_eq!(format_flo16(NEG_INFINITY), " -inf"); + assert_eq!(format_flo16(NEG_ZERO), " -0"); + assert_eq!(format_flo16(ZERO), " 0"); } diff --git a/src/od/prn_int.rs b/src/od/prn_int.rs index 9dd1fe58c..cc47a16e7 100644 --- a/src/od/prn_int.rs +++ b/src/od/prn_int.rs @@ -51,42 +51,65 @@ macro_rules! int_writer_signed { } /// Extends a signed number in `item` of `itembytes` bytes into a (signed) i64 -fn sign_extend(item: u64, itembytes: usize) -> i64{ +fn sign_extend(item: u64, itembytes: usize) -> i64 { let shift = 64 - itembytes * 8; (item << shift) as i64 >> shift } - -int_writer_unsigned!(FORMAT_ITEM_OCT8, 1, 4, format_item_oct8, OCT!()); // max: 377 -int_writer_unsigned!(FORMAT_ITEM_OCT16, 2, 7, format_item_oct16, OCT!()); // max: 177777 +int_writer_unsigned!(FORMAT_ITEM_OCT8, 1, 4, format_item_oct8, OCT!()); // max: 377 +int_writer_unsigned!(FORMAT_ITEM_OCT16, 2, 7, format_item_oct16, OCT!()); // max: 177777 int_writer_unsigned!(FORMAT_ITEM_OCT32, 4, 12, format_item_oct32, OCT!()); // max: 37777777777 int_writer_unsigned!(FORMAT_ITEM_OCT64, 8, 23, format_item_oct64, OCT!()); // max: 1777777777777777777777 -int_writer_unsigned!(FORMAT_ITEM_HEX8, 1, 3, format_item_hex8, HEX!()); // max: ff -int_writer_unsigned!(FORMAT_ITEM_HEX16, 2, 5, format_item_hex16, HEX!()); // max: ffff -int_writer_unsigned!(FORMAT_ITEM_HEX32, 4, 9, format_item_hex32, HEX!()); // max: ffffffff +int_writer_unsigned!(FORMAT_ITEM_HEX8, 1, 3, format_item_hex8, HEX!()); // max: ff +int_writer_unsigned!(FORMAT_ITEM_HEX16, 2, 5, format_item_hex16, HEX!()); // max: ffff +int_writer_unsigned!(FORMAT_ITEM_HEX32, 4, 9, format_item_hex32, HEX!()); // max: ffffffff int_writer_unsigned!(FORMAT_ITEM_HEX64, 8, 17, format_item_hex64, HEX!()); // max: ffffffffffffffff -int_writer_unsigned!(FORMAT_ITEM_DEC8U, 1, 4, format_item_dec_u8, DEC!()); // max: 255 -int_writer_unsigned!(FORMAT_ITEM_DEC16U, 2, 6, format_item_dec_u16, DEC!()); // max: 65535 +int_writer_unsigned!(FORMAT_ITEM_DEC8U, 1, 4, format_item_dec_u8, DEC!()); // max: 255 +int_writer_unsigned!(FORMAT_ITEM_DEC16U, 2, 6, format_item_dec_u16, DEC!()); // max: 65535 int_writer_unsigned!(FORMAT_ITEM_DEC32U, 4, 11, format_item_dec_u32, DEC!()); // max: 4294967295 int_writer_unsigned!(FORMAT_ITEM_DEC64U, 8, 21, format_item_dec_u64, DEC!()); // max: 18446744073709551615 -int_writer_signed!(FORMAT_ITEM_DEC8S, 1, 5, format_item_dec_s8, DEC!()); // max: -128 -int_writer_signed!(FORMAT_ITEM_DEC16S, 2, 7, format_item_dec_s16, DEC!()); // max: -32768 +int_writer_signed!(FORMAT_ITEM_DEC8S, 1, 5, format_item_dec_s8, DEC!()); // max: -128 +int_writer_signed!(FORMAT_ITEM_DEC16S, 2, 7, format_item_dec_s16, DEC!()); // max: -32768 int_writer_signed!(FORMAT_ITEM_DEC32S, 4, 12, format_item_dec_s32, DEC!()); // max: -2147483648 int_writer_signed!(FORMAT_ITEM_DEC64S, 8, 21, format_item_dec_s64, DEC!()); // max: -9223372036854775808 #[test] fn test_sign_extend() { - assert_eq!(0xffffffffffffff80u64 as i64, sign_extend(0x0000000000000080, 1)); - assert_eq!(0xffffffffffff8000u64 as i64, sign_extend(0x0000000000008000, 2)); - assert_eq!(0xffffffffff800000u64 as i64, sign_extend(0x0000000000800000, 3)); - assert_eq!(0xffffffff80000000u64 as i64, sign_extend(0x0000000080000000, 4)); - assert_eq!(0xffffff8000000000u64 as i64, sign_extend(0x0000008000000000, 5)); - assert_eq!(0xffff800000000000u64 as i64, sign_extend(0x0000800000000000, 6)); - assert_eq!(0xff80000000000000u64 as i64, sign_extend(0x0080000000000000, 7)); - assert_eq!(0x8000000000000000u64 as i64, sign_extend(0x8000000000000000, 8)); + assert_eq!( + 0xffffffffffffff80u64 as i64, + sign_extend(0x0000000000000080, 1) + ); + assert_eq!( + 0xffffffffffff8000u64 as i64, + sign_extend(0x0000000000008000, 2) + ); + assert_eq!( + 0xffffffffff800000u64 as i64, + sign_extend(0x0000000000800000, 3) + ); + assert_eq!( + 0xffffffff80000000u64 as i64, + sign_extend(0x0000000080000000, 4) + ); + assert_eq!( + 0xffffff8000000000u64 as i64, + sign_extend(0x0000008000000000, 5) + ); + assert_eq!( + 0xffff800000000000u64 as i64, + sign_extend(0x0000800000000000, 6) + ); + assert_eq!( + 0xff80000000000000u64 as i64, + sign_extend(0x0080000000000000, 7) + ); + assert_eq!( + 0x8000000000000000u64 as i64, + sign_extend(0x8000000000000000, 8) + ); assert_eq!(0x000000000000007f, sign_extend(0x000000000000007f, 1)); assert_eq!(0x0000000000007fff, sign_extend(0x0000000000007fff, 2)); @@ -107,7 +130,10 @@ fn test_format_item_oct() { assert_eq!(" 00000000000", format_item_oct32(0)); assert_eq!(" 37777777777", format_item_oct32(0xffffffff)); assert_eq!(" 0000000000000000000000", format_item_oct64(0)); - assert_eq!(" 1777777777777777777777", format_item_oct64(0xffffffffffffffff)); + assert_eq!( + " 1777777777777777777777", + format_item_oct64(0xffffffffffffffff) + ); } #[test] @@ -131,7 +157,10 @@ fn test_format_item_dec_u() { assert_eq!(" 0", format_item_dec_u32(0)); assert_eq!(" 4294967295", format_item_dec_u32(0xffffffff)); assert_eq!(" 0", format_item_dec_u64(0)); - assert_eq!(" 18446744073709551615", format_item_dec_u64(0xffffffffffffffff)); + assert_eq!( + " 18446744073709551615", + format_item_dec_u64(0xffffffffffffffff) + ); } #[test] @@ -146,6 +175,12 @@ fn test_format_item_dec_s() { assert_eq!(" 2147483647", format_item_dec_s32(0x7fffffff)); assert_eq!(" -2147483648", format_item_dec_s32(0x80000000)); assert_eq!(" 0", format_item_dec_s64(0)); - assert_eq!(" 9223372036854775807", format_item_dec_s64(0x7fffffffffffffff)); - assert_eq!(" -9223372036854775808", format_item_dec_s64(0x8000000000000000)); + assert_eq!( + " 9223372036854775807", + format_item_dec_s64(0x7fffffffffffffff) + ); + assert_eq!( + " -9223372036854775808", + format_item_dec_s64(0x8000000000000000) + ); } diff --git a/src/paste/paste.rs b/src/paste/paste.rs index 20237eb15..73c9aa74f 100644 --- a/src/paste/paste.rs +++ b/src/paste/paste.rs @@ -14,7 +14,7 @@ extern crate getopts; #[macro_use] extern crate uucore; -use std::io::{BufRead, BufReader, Read, stdin}; +use std::io::{stdin, BufRead, BufReader, Read}; use std::iter::repeat; use std::fs::File; use std::path::Path; @@ -25,24 +25,36 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("s", "serial", "paste one file at a time instead of in parallel"); - opts.optopt("d", "delimiters", "reuse characters from LIST instead of TABs", "LIST"); + opts.optflag( + "s", + "serial", + "paste one file at a time instead of in parallel", + ); + opts.optopt( + "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) + Err(e) => crash!(1, "{}", e), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + 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); +FILE, separated by TABs, to standard output.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -56,18 +68,22 @@ FILE, separated by TABs, to standard output.", NAME, VERSION); } fn paste(filenames: Vec, serial: bool, delimiters: String) { - let mut files: Vec>> = filenames.into_iter().map(|name| - BufReader::new( - if name == "-" { + let mut files: Vec>> = filenames + .into_iter() + .map(|name| { + BufReader::new(if name == "-" { Box::new(stdin()) as Box } else { let r = crash_if_err!(1, File::open(Path::new(&name))); Box::new(r) as Box - } - ) - ).collect(); + }) + }) + .collect(); - let delimiters: Vec = unescape(delimiters).chars().map(|x| x.to_string()).collect(); + let delimiters: Vec = unescape(delimiters) + .chars() + .map(|x| x.to_string()) + .collect(); let mut delim_count = 0; if serial { @@ -81,11 +97,11 @@ fn paste(filenames: Vec, serial: bool, delimiters: String) { output.push_str(line.trim_right()); output.push_str(&delimiters[delim_count % delimiters.len()]); } - Err(e) => crash!(1, "{}", e.to_string()) + Err(e) => crash!(1, "{}", e.to_string()), } delim_count += 1; } - println!("{}", &output[..output.len()-1]); + println!("{}", &output[..output.len() - 1]); } } else { let mut eof: Vec = repeat(false).take(files.len()).collect(); @@ -103,7 +119,7 @@ fn paste(filenames: Vec, serial: bool, delimiters: String) { eof_count += 1; } Ok(_) => output.push_str(line.trim_right()), - Err(e) => crash!(1, "{}", e.to_string()) + Err(e) => crash!(1, "{}", e.to_string()), } } output.push_str(&delimiters[delim_count % delimiters.len()]); @@ -112,7 +128,7 @@ fn paste(filenames: Vec, serial: bool, delimiters: String) { if files.len() == eof_count { break; } - println!("{}", &output[..output.len()-1]); + println!("{}", &output[..output.len() - 1]); delim_count = 0; } } @@ -122,7 +138,7 @@ fn paste(filenames: Vec, serial: bool, delimiters: String) { // TODO: this will need work to conform to GNU implementation fn unescape(s: String) -> String { s.replace("\\n", "\n") - .replace("\\t", "\t") - .replace("\\\\", "\\") - .replace("\\", "") + .replace("\\t", "\t") + .replace("\\\\", "\\") + .replace("\\", "") } diff --git a/src/pathchk/pathchk.rs b/src/pathchk/pathchk.rs index 085c92c92..dcc21b896 100644 --- a/src/pathchk/pathchk.rs +++ b/src/pathchk/pathchk.rs @@ -18,7 +18,7 @@ extern crate uucore; use getopts::Options; use std::fs; -use std::io::{Write, ErrorKind}; +use std::io::{ErrorKind, Write}; // operating mode enum Mode { @@ -27,7 +27,7 @@ enum Mode { Extra, // check for leading dashes and empty names Both, // a combination of `Basic` and `Extra` Help, // show help - Version // show version information + Version, // show version information } static NAME: &'static str = "pathchk"; @@ -41,15 +41,21 @@ pub fn uumain(args: Vec) -> i32 { // add options let mut opts = Options::new(); opts.optflag("p", "posix", "check for (most) POSIX systems"); - opts.optflag("P", - "posix-special", "check for empty names and leading \"-\""); - opts.optflag("", - "portability", "check for all POSIX systems (equivalent to -p -P)"); + opts.optflag( + "P", + "posix-special", + "check for empty names and leading \"-\"", + ); + opts.optflag( + "", + "portability", + "check for all POSIX systems (equivalent to -p -P)", + ); opts.optflag("h", "help", "display this help text 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) } + Err(e) => crash!(1, "{}", e), }; // set working mode @@ -57,9 +63,9 @@ pub fn uumain(args: Vec) -> i32 { Mode::Version } else if matches.opt_present("help") { Mode::Help - } else if (matches.opt_present("posix") && - matches.opt_present("posix-special")) || - matches.opt_present("portability") { + } else if (matches.opt_present("posix") && matches.opt_present("posix-special")) + || matches.opt_present("portability") + { Mode::Both } else if matches.opt_present("posix") { Mode::Basic @@ -71,14 +77,18 @@ pub fn uumain(args: Vec) -> i32 { // take necessary actions match mode { - Mode::Help => { help(opts); 0 } - Mode::Version => { version(); 0 } + Mode::Help => { + help(opts); + 0 + } + Mode::Version => { + version(); + 0 + } _ => { let mut res = true; if matches.free.len() == 0 { - show_error!( - "missing operand\nTry {} --help for more information", NAME - ); + show_error!("missing operand\nTry {} --help for more information", NAME); res = false; } // free strings are path operands @@ -91,15 +101,22 @@ pub fn uumain(args: Vec) -> i32 { res &= check_path(&mode, &path); } // determine error code - if res { 0 } else { 1 } + if res { + 0 + } else { + 1 + } } } } // print help fn help(opts: Options) { - let msg = format!("Usage: {} [OPTION]... NAME...\n\n\ - Diagnose invalid or unportable file names.", NAME); + let msg = format!( + "Usage: {} [OPTION]... NAME...\n\n\ + Diagnose invalid or unportable file names.", + NAME + ); print!("{}", opts.usage(&msg)); } @@ -115,7 +132,7 @@ fn check_path(mode: &Mode, path: &[String]) -> bool { Mode::Basic => check_basic(&path), Mode::Extra => check_default(&path) && check_extra(&path), Mode::Both => check_basic(&path) && check_extra(&path), - _ => check_default(&path) + _ => check_default(&path), } } @@ -125,9 +142,13 @@ fn check_basic(path: &[String]) -> bool { let total_len = joined_path.len(); // path length if total_len > POSIX_PATH_MAX { - writeln!(&mut std::io::stderr(), + writeln!( + &mut std::io::stderr(), "limit {} exceeded by length {} of file name {}", - POSIX_PATH_MAX, total_len, joined_path); + POSIX_PATH_MAX, + total_len, + joined_path + ); return false; } else if total_len == 0 { writeln!(&mut std::io::stderr(), "empty file name"); @@ -137,9 +158,13 @@ fn check_basic(path: &[String]) -> bool { for p in path { let component_len = p.len(); if component_len > POSIX_NAME_MAX { - writeln!(&mut std::io::stderr(), + writeln!( + &mut std::io::stderr(), "limit {} exceeded by length {} of file name component '{}'", - POSIX_NAME_MAX, component_len, p); + POSIX_NAME_MAX, + component_len, + p + ); return false; } if !check_portable_chars(&p) { @@ -155,8 +180,11 @@ fn check_extra(path: &[String]) -> bool { // components: leading hyphens for p in path { if !no_leading_hyphen(&p) { - writeln!(&mut std::io::stderr(), - "leading hyphen in file name component '{}'", p); + writeln!( + &mut std::io::stderr(), + "leading hyphen in file name component '{}'", + p + ); return false; } } @@ -174,18 +202,26 @@ fn check_default(path: &[String]) -> bool { let total_len = joined_path.len(); // path length if total_len > libc::PATH_MAX as usize { - writeln!(&mut std::io::stderr(), + writeln!( + &mut std::io::stderr(), "limit {} exceeded by length {} of file name '{}'", - libc::PATH_MAX, total_len, joined_path); + libc::PATH_MAX, + total_len, + joined_path + ); return false; } // components: length for p in path { let component_len = p.len(); if component_len > libc::FILENAME_MAX as usize { - writeln!(&mut std::io::stderr(), + writeln!( + &mut std::io::stderr(), "limit {} exceeded by length {} of file name component '{}'", - libc::FILENAME_MAX, component_len, p); + libc::FILENAME_MAX, + component_len, + p + ); return false; } } @@ -203,7 +239,7 @@ fn check_searchable(path: &String) -> bool { } else { writeln!(&mut std::io::stderr(), "{}", e); false - } + }, } } @@ -214,14 +250,15 @@ fn no_leading_hyphen(path_segment: &String) -> bool { // check whether a path segment contains only valid (read: portable) characters fn check_portable_chars(path_segment: &String) -> bool { - let valid_str = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-" - .to_string(); + let valid_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-".to_string(); for ch in path_segment.chars() { if !valid_str.contains(ch) { - writeln!(&mut std::io::stderr(), + writeln!( + &mut std::io::stderr(), "nonportable character '{}' in file name component '{}'", - ch, path_segment); + ch, + path_segment + ); return false; } } diff --git a/src/pinky/pinky.rs b/src/pinky/pinky.rs index 41ef0e757..e36d05f63 100644 --- a/src/pinky/pinky.rs +++ b/src/pinky/pinky.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_pinky"] - // This file is part of the uutils coreutils package. // // (c) Jian Zeng @@ -7,8 +6,8 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // -#![cfg_attr(feature="clippy", feature(plugin))] -#![cfg_attr(feature="clippy", plugin(clippy))] +#![cfg_attr(feature = "clippy", feature(plugin))] +#![cfg_attr(feature = "clippy", plugin(clippy))] #[macro_use] extern crate uucore; @@ -31,7 +30,8 @@ static SUMMARY: &'static str = "A lightweight 'finger' program; print user info const BUFSIZE: usize = 1024; pub fn uumain(args: Vec) -> i32 { - let long_help = &format!(" + let long_help = &format!( + " -l produce long format output for the specified USERs -b omit the user's home directory and shell in long format -h omit the user's project file in long format @@ -45,25 +45,35 @@ pub fn uumain(args: Vec) -> i32 { --help display this help and exit --version output version information and exit -The utmp file will be {}", utmpx::DEFAULT_FILE); +The utmp file will be {}", + utmpx::DEFAULT_FILE + ); let mut opts = new_coreopts!(SYNTAX, SUMMARY, &long_help); - opts.optflag("l", - "", - "produce long format output for the specified USERs"); - opts.optflag("b", - "", - "omit the user's home directory and shell in long format"); + opts.optflag( + "l", + "", + "produce long format output for the specified USERs", + ); + opts.optflag( + "b", + "", + "omit the user's home directory and shell in long format", + ); opts.optflag("h", "", "omit the user's project file in long format"); opts.optflag("p", "", "omit the user's plan file in long format"); opts.optflag("s", "", "do short format output, this is the default"); opts.optflag("f", "", "omit the line of column headings in short format"); opts.optflag("w", "", "omit the user's full name in short format"); - opts.optflag("i", - "", - "omit the user's full name and remote host in short format"); - opts.optflag("q", - "", - "omit the user's full name, remote host and idle time in short format"); + opts.optflag( + "i", + "", + "omit the user's full name and remote host in short format", + ); + opts.optflag( + "q", + "", + "omit the user's full name, remote host and idle time in short format", + ); opts.optflag("", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); @@ -135,7 +145,6 @@ The utmp file will be {}", utmpx::DEFAULT_FILE); } else { pk.long_pinky() } - } struct Pinky { @@ -157,14 +166,15 @@ impl Capitalize for str { fn capitalize(&self) -> String { #[allow(unused_imports)] use std::ascii::AsciiExt; - self.char_indices().fold(String::with_capacity(self.len()), |mut acc, x| { - if x.0 != 0 { - acc.push(x.1) - } else { - acc.push(x.1.to_ascii_uppercase()) - } - acc - }) + self.char_indices() + .fold(String::with_capacity(self.len()), |mut acc, x| { + if x.0 != 0 { + acc.push(x.1) + } else { + acc.push(x.1.to_ascii_uppercase()) + } + acc + }) } } @@ -228,7 +238,6 @@ impl Pinky { } else { print!(" {:19}", " ???"); } - } print!(" {}{:<8.*}", mesg, utmpx::UT_LINESIZE, ut.tty_device()); diff --git a/src/printenv/printenv.rs b/src/printenv/printenv.rs index fae5aa0b6..72e0c2056 100644 --- a/src/printenv/printenv.rs +++ b/src/printenv/printenv.rs @@ -23,22 +23,27 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("0", "null", "end each output line with 0 byte rather than newline"); + opts.optflag( + "0", + "null", + "end each output line with 0 byte rather than newline", + ); 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(f) => { - crash!(1, "Invalid options\n{}", f) - } + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [VARIABLE]... [OPTION]... -Prints the given environment VARIABLE(s), otherwise prints them all.", NAME, VERSION); +Prints the given environment VARIABLE(s), otherwise prints them all.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); return 0; } diff --git a/src/printf/memo.rs b/src/printf/memo.rs index 0472d7bf6..e5a05cf0e 100644 --- a/src/printf/memo.rs +++ b/src/printf/memo.rs @@ -18,8 +18,10 @@ pub struct Memo { } fn warn_excess_args(first_arg: &str) { - cli::err_msg(&format!("warning: ignoring excess arguments, starting with '{}'", - first_arg)); + cli::err_msg(&format!( + "warning: ignoring excess arguments, starting with '{}'", + first_arg + )); } impl Memo { diff --git a/src/printf/printf.rs b/src/printf/printf.rs index c599729b7..086bc6a88 100644 --- a/src/printf/printf.rs +++ b/src/printf/printf.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_printf"] - #![allow(dead_code)] extern crate itertools; @@ -9,7 +8,6 @@ mod cli; mod memo; mod tokenize; - static NAME: &'static str = "printf"; static VERSION: &'static str = "0.0.1"; static SHORT_USAGE: &'static str = "printf: usage: printf [-v var] format [arguments]"; @@ -179,8 +177,10 @@ static LONGHELP_BODY: &'static str = " e.g. \\n will be transformed into a newline character. One special rule about %b mode is that octal literals are intepreted differently - In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN instead of \\NNN - (Although, for legacy reasons, octal literals in the form of \\NNN will still be interpreted and not throw a warning, you will have problems if you use this for a literal whose code begins with zero, as it will be viewed as in \\0NNN form.) + In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN + instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will + still be interpreted and not throw a warning, you will have problems if you use this for a + literal whose code begins with zero, as it will be viewed as in \\0NNN form.) CHAR SUBSTITUTIONS The character field does not have a secondary parameter. @@ -206,12 +206,18 @@ static LONGHELP_BODY: &'static str = " All floating point fields have a 'max decimal places / max significant digits' parameter %.10f means a decimal floating point with 7 decimal places past 0 %.10e means a scientific notation number with 10 significant digits - %.10g means the same behavior for decimal and Sci. Note, respectively, and provides the shorter of each's output. + %.10g means the same behavior for decimal and Sci. Note, respectively, and provides the shorter + of each's output. - Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a double first before being rendered to text. For both implementations do not expect meaningful precision past the 18th decimal place. When using a number of decimal places that is 18 or higher, you can expect variation in output between GNU coreutils printf and this printf at the 18th decimal place of +/- 1 + Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a + double first before being rendered to text. For both implementations do not expect meaningful + precision past the 18th decimal place. When using a number of decimal places that is 18 or + higher, you can expect variation in output between GNU coreutils printf and this printf at the + 18th decimal place of +/- 1 - %f - floating point value presented in decimal, truncated and displayed to 6 decimal places by default. - There is not past-double behavior parity with Coreutils printf, values are not estimated or adjusted beyond input values. + %f - floating point value presented in decimal, truncated and displayed to 6 decimal places by + default. There is not past-double behavior parity with Coreutils printf, values are not + estimated or adjusted beyond input values. %e or %E - floating point value presented in scientific notation 7 significant digits by default @@ -252,7 +258,8 @@ static LONGHELP_BODY: &'static str = " Character Constant: if the argument begins with a single quote character, the first byte of the next character will be interpreted as an 8-bit unsigned integer. If there are - additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECt is set) + additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECT + is set) WRITTEN BY : Nathan E. Ross, et al. for the uutils project @@ -269,8 +276,10 @@ COPYRIGHT : pub fn uumain(args: Vec) -> i32 { let location = &args[0]; if args.len() <= 1 { - println!("{0}: missing operand\nTry '{0} --help' for more information.", - location); + println!( + "{0}: missing operand\nTry '{0} --help' for more information.", + location + ); return 1; } let ref formatstr = args[1]; diff --git a/src/printf/tokenize/num_format/formatter.rs b/src/printf/tokenize/num_format/formatter.rs index 1d9e3fbcd..aa5cf18a7 100644 --- a/src/printf/tokenize/num_format/formatter.rs +++ b/src/printf/tokenize/num_format/formatter.rs @@ -2,7 +2,7 @@ //! never dealt with above (e.g. Sub Tokenizer never uses these) use std::str::Chars; -use itertools::{PutBackN, put_back_n}; +use itertools::{put_back_n, PutBackN}; use cli; use super::format_field::FormatField; @@ -28,8 +28,7 @@ impl Default for FormatPrimitive { } } -#[derive(Clone)] -#[derive(PartialEq)] +#[derive(Clone, PartialEq)] pub enum Base { Ten = 10, Hex = 16, @@ -48,11 +47,12 @@ pub trait Formatter { // return a FormatPrimitive for // particular field char(s), given the argument // string and prefix information (sign, radix) - fn get_primitive(&self, - field: &FormatField, - inprefix: &InPrefix, - str_in: &str) - -> Option; + fn get_primitive( + &self, + field: &FormatField, + inprefix: &InPrefix, + str_in: &str, + ) -> Option; // return a string from a formatprimitive, // given information about the field fn primitive_to_str(&self, prim: &FormatPrimitive, field: FormatField) -> String; diff --git a/src/printf/tokenize/num_format/formatters/base_conv/mod.rs b/src/printf/tokenize/num_format/formatters/base_conv/mod.rs index c851ecda5..5e46a6c51 100644 --- a/src/printf/tokenize/num_format/formatters/base_conv/mod.rs +++ b/src/printf/tokenize/num_format/formatters/base_conv/mod.rs @@ -41,12 +41,12 @@ pub struct DivOut<'a> { pub remainder: Remainder<'a>, } -pub fn arrnum_int_div_step<'a>(rem_in: Remainder<'a>, - radix_in: u8, - base_ten_int_divisor: u8, - after_decimal: bool) - -> DivOut<'a> { - +pub fn arrnum_int_div_step<'a>( + rem_in: Remainder<'a>, + radix_in: u8, + base_ten_int_divisor: u8, + after_decimal: bool, +) -> DivOut<'a> { let mut rem_out = Remainder { position: rem_in.position, replace: Vec::new(), @@ -65,17 +65,15 @@ pub fn arrnum_int_div_step<'a>(rem_in: Remainder<'a>, loop { let u = match it_replace.next() { Some(u_rep) => u_rep.clone() as u16, - None => { - match it_f.next() { - Some(u_orig) => u_orig.clone() as u16, - None => { - if !after_decimal { - break; - } - 0 + None => match it_f.next() { + Some(u_orig) => u_orig.clone() as u16, + None => { + if !after_decimal { + break; } + 0 } - } + }, }; traversed += 1; bufferval += u; @@ -176,7 +174,7 @@ pub fn arrnum_int_add(arrnum: &Vec, basenum: u8, base_ten_int_term: u8) -> V let mut it = arrnum.iter().rev(); loop { let i = it.next(); - match i { + match i { Some(u) => { new_amount = (u.clone() as u16) + carry; rem = new_amount % base; @@ -218,7 +216,6 @@ pub fn unsigned_to_arrnum(src: u16) -> Vec { result } - // temporary needs-improvement-function #[allow(unused_variables)] pub fn base_conv_float(src: &Vec, radix_src: u8, radix_dest: u8) -> f64 { @@ -272,9 +269,11 @@ pub fn arrnum_to_str(src: &Vec, radix_def_dest: &RadixDef) -> String { #[allow(unused_variables)] pub fn base_conv_str(src: &str, radix_def_src: &RadixDef, radix_def_dest: &RadixDef) -> String { let intermed_in: Vec = str_to_arrnum(src, radix_def_src); - let intermed_out = base_conv_vec(&intermed_in, - radix_def_src.get_max(), - radix_def_dest.get_max()); + let intermed_out = base_conv_vec( + &intermed_in, + radix_def_src.get_max(), + radix_def_dest.get_max(), + ); arrnum_to_str(&intermed_out, radix_def_dest) } diff --git a/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs b/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs index 8dcd93187..9d226818c 100644 --- a/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs +++ b/src/printf/tokenize/num_format/formatters/cninetyninehexfloatf.rs @@ -1,11 +1,10 @@ //! formatter for %a %F C99 Hex-floating-point subs use super::super::format_field::FormatField; -use super::super::formatter::{InPrefix, FormatPrimitive, Formatter}; -use super::float_common::{FloatAnalysis, primitive_to_str_common}; +use super::super::formatter::{FormatPrimitive, Formatter, InPrefix}; +use super::float_common::{primitive_to_str_common, FloatAnalysis}; use super::base_conv; use super::base_conv::RadixDef; - pub struct CninetyNineHexFloatf { as_num: f64, } @@ -16,22 +15,22 @@ impl CninetyNineHexFloatf { } impl Formatter for CninetyNineHexFloatf { - fn get_primitive(&self, - field: &FormatField, - inprefix: &InPrefix, - str_in: &str) - -> Option { + fn get_primitive( + &self, + field: &FormatField, + inprefix: &InPrefix, + str_in: &str, + ) -> Option { let second_field = field.second_field.unwrap_or(6) + 1; - let analysis = FloatAnalysis::analyze(&str_in, - inprefix, - Some(second_field as usize), - None, - true); - let f = get_primitive_hex(inprefix, - &str_in[inprefix.offset..], - &analysis, - second_field as usize, - *field.field_char == 'A'); + let analysis = + FloatAnalysis::analyze(&str_in, inprefix, Some(second_field as usize), None, true); + let f = get_primitive_hex( + inprefix, + &str_in[inprefix.offset..], + &analysis, + second_field as usize, + *field.field_char == 'A', + ); Some(f) } fn primitive_to_str(&self, prim: &FormatPrimitive, field: FormatField) -> String { @@ -44,19 +43,15 @@ impl Formatter for CninetyNineHexFloatf { // on the todo list is to have a trait for get_primitive that is implemented by each float formatter and can override a default. when that happens we can take the parts of get_primitive_dec specific to dec and spin them out to their own functions that can be overridden. #[allow(unused_variables)] #[allow(unused_assignments)] -fn get_primitive_hex(inprefix: &InPrefix, - str_in: &str, - analysis: &FloatAnalysis, - last_dec_place: usize, - capitalized: bool) - -> FormatPrimitive { - +fn get_primitive_hex( + inprefix: &InPrefix, + str_in: &str, + analysis: &FloatAnalysis, + last_dec_place: usize, + capitalized: bool, +) -> FormatPrimitive { let mut f: FormatPrimitive = Default::default(); - f.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 // to separate slices. If no digits after decimal point, @@ -101,11 +96,7 @@ fn get_primitive_hex(inprefix: &InPrefix, // directly to base 2 and then at the end translate back to hex. let mantissa = 0; f.suffix = Some({ - let ind = if capitalized { - "P" - } else { - "p" - }; + let ind = if capitalized { "P" } else { "p" }; if mantissa >= 0 { format!("{}+{}", ind, mantissa) } else { @@ -122,8 +113,10 @@ fn to_hex(src: &str, before_decimal: bool) -> String { base_conv::base_conv_str(src, &rten, &rhex) } else { let as_arrnum_ten = base_conv::str_to_arrnum(src, &rten); - let s = format!("{}", - base_conv::base_conv_float(&as_arrnum_ten, rten.get_max(), rhex.get_max())); + let s = format!( + "{}", + base_conv::base_conv_float(&as_arrnum_ten, rten.get_max(), rhex.get_max()) + ); if s.len() > 2 { String::from(&s[2..]) } else { diff --git a/src/printf/tokenize/num_format/formatters/decf.rs b/src/printf/tokenize/num_format/formatters/decf.rs index 5567ebf91..46de17290 100644 --- a/src/printf/tokenize/num_format/formatters/decf.rs +++ b/src/printf/tokenize/num_format/formatters/decf.rs @@ -1,7 +1,7 @@ //! formatter for %g %G decimal subs use super::super::format_field::FormatField; -use super::super::formatter::{InPrefix, FormatPrimitive, Formatter}; -use super::float_common::{FloatAnalysis, get_primitive_dec, primitive_to_str_common}; +use super::super::formatter::{FormatPrimitive, Formatter, InPrefix}; +use super::float_common::{get_primitive_dec, primitive_to_str_common, FloatAnalysis}; fn get_len_fprim(fprim: &FormatPrimitive) -> usize { let mut len = 0; @@ -29,24 +29,29 @@ impl Decf { } } impl Formatter for Decf { - fn get_primitive(&self, - field: &FormatField, - inprefix: &InPrefix, - str_in: &str) - -> Option { + fn get_primitive( + &self, + field: &FormatField, + inprefix: &InPrefix, + str_in: &str, + ) -> Option { let second_field = field.second_field.unwrap_or(6) + 1; // default to scif interp. so as to not truncate input vals // (that would be displayed in scif) based on relation to decimal place - let analysis = FloatAnalysis::analyze(str_in, - inprefix, - Some(second_field as usize + 1), - None, - false); - let mut f_sci = get_primitive_dec(inprefix, - &str_in[inprefix.offset..], - &analysis, - second_field as usize, - Some(*field.field_char == 'G')); + let analysis = FloatAnalysis::analyze( + str_in, + inprefix, + Some(second_field as usize + 1), + None, + false, + ); + let mut f_sci = get_primitive_dec( + inprefix, + &str_in[inprefix.offset..], + &analysis, + second_field as usize, + Some(*field.field_char == 'G'), + ); // strip trailing zeroes match f_sci.post_decimal.clone() { Some(ref post_dec) => { @@ -66,11 +71,13 @@ impl Formatter for Decf { } None => {} } - let f_fl = get_primitive_dec(inprefix, - &str_in[inprefix.offset..], - &analysis, - second_field as usize, - None); + let f_fl = get_primitive_dec( + inprefix, + &str_in[inprefix.offset..], + &analysis, + second_field as usize, + None, + ); Some(if get_len_fprim(&f_fl) >= get_len_fprim(&f_sci) { f_sci } else { diff --git a/src/printf/tokenize/num_format/formatters/float_common.rs b/src/printf/tokenize/num_format/formatters/float_common.rs index 9da8fd907..0b4a54b30 100644 --- a/src/printf/tokenize/num_format/formatters/float_common.rs +++ b/src/printf/tokenize/num_format/formatters/float_common.rs @@ -1,5 +1,5 @@ use super::super::format_field::FormatField; -use super::super::formatter::{InPrefix, Base, FormatPrimitive, warn_incomplete_conv, get_it_at}; +use super::super::formatter::{get_it_at, warn_incomplete_conv, Base, FormatPrimitive, InPrefix}; use super::base_conv; use super::base_conv::RadixDef; @@ -13,12 +13,13 @@ pub struct FloatAnalysis { pub decimal_pos: Option, pub follow: Option, } -fn has_enough_digits(hex_input: bool, - hex_output: bool, - string_position: usize, - starting_position: usize, - limit: usize) - -> bool { +fn has_enough_digits( + hex_input: bool, + hex_output: bool, + string_position: usize, + starting_position: usize, + limit: usize, +) -> bool { // -1s are for rounding if hex_output { if hex_input { @@ -33,16 +34,16 @@ fn has_enough_digits(hex_input: bool, ((string_position - 1) - starting_position >= limit) } } - } impl FloatAnalysis { - pub fn analyze(str_in: &str, - inprefix: &InPrefix, - max_sd_opt: Option, - max_after_dec_opt: Option, - hex_output: bool) - -> FloatAnalysis { + pub fn analyze( + str_in: &str, + inprefix: &InPrefix, + max_sd_opt: Option, + max_after_dec_opt: Option, + hex_output: bool, + ) -> FloatAnalysis { // this fn assumes // the input string // has no leading spaces or 0s @@ -73,9 +74,9 @@ impl FloatAnalysis { } } } - if ret.decimal_pos.is_some() && - pos_before_first_nonzero_after_decimal.is_none() && - e != '0' { + if ret.decimal_pos.is_some() && pos_before_first_nonzero_after_decimal.is_none() + && e != '0' + { pos_before_first_nonzero_after_decimal = Some(i - 1); } if let Some(max_sd) = max_sd_opt { @@ -130,8 +131,10 @@ fn de_hex(src: &str, before_decimal: bool) -> String { base_conv::base_conv_str(src, &rhex, &rten) } else { let as_arrnum_hex = base_conv::str_to_arrnum(src, &rhex); - let s = format!("{}", - base_conv::base_conv_float(&as_arrnum_hex, rhex.get_max(), rten.get_max())); + let s = format!( + "{}", + base_conv::base_conv_float(&as_arrnum_hex, rhex.get_max(), rten.get_max()) + ); if s.len() > 2 { String::from(&s[2..]) } else { @@ -147,7 +150,6 @@ fn de_hex(src: &str, before_decimal: bool) -> String { // and if the digit was nine // propagate to the next, etc. fn _round_str_from(in_str: &str, position: usize) -> (String, bool) { - let mut it = in_str[0..position].chars(); let mut rev = String::new(); let mut i = position; @@ -162,7 +164,7 @@ fn _round_str_from(in_str: &str, position: usize) -> (String, bool) { rev.push(((e as u8) + 1) as char); finished_in_dec = true; break; - } + } } } let mut fwd = String::from(&in_str[0..i]); @@ -172,18 +174,18 @@ fn _round_str_from(in_str: &str, position: usize) -> (String, bool) { (fwd, finished_in_dec) } -fn round_terminal_digit(before_dec: String, - after_dec: String, - position: usize) - -> (String, String) { - +fn round_terminal_digit( + before_dec: String, + after_dec: String, + position: usize, +) -> (String, String) { if position < after_dec.len() { let digit_at_pos: char; { digit_at_pos = (&after_dec[position..position + 1]) - .chars() - .next() - .expect(""); + .chars() + .next() + .expect(""); } match digit_at_pos { '5'...'9' => { @@ -202,12 +204,13 @@ fn round_terminal_digit(before_dec: String, (before_dec, after_dec) } -pub fn get_primitive_dec(inprefix: &InPrefix, - str_in: &str, - analysis: &FloatAnalysis, - last_dec_place: usize, - sci_mode: Option) - -> FormatPrimitive { +pub fn get_primitive_dec( + inprefix: &InPrefix, + str_in: &str, + analysis: &FloatAnalysis, + last_dec_place: usize, + sci_mode: Option, +) -> FormatPrimitive { let mut f: FormatPrimitive = Default::default(); // add negative sign section @@ -227,22 +230,24 @@ pub fn get_primitive_dec(inprefix: &InPrefix, } // convert to string, de_hexifying if input is in hex. let (first_segment, second_segment) = match inprefix.radix_in { - Base::Hex => { - (de_hex(first_segment_raw, true), - de_hex(second_segment_raw, false)) - } - _ => { - (String::from(first_segment_raw), - String::from(second_segment_raw)) - } + Base::Hex => ( + de_hex(first_segment_raw, true), + de_hex(second_segment_raw, false), + ), + _ => ( + String::from(first_segment_raw), + String::from(second_segment_raw), + ), }; let (pre_dec_unrounded, post_dec_unrounded, mantissa) = if sci_mode.is_some() { if first_segment.len() > 1 { let mut post_dec = String::from(&first_segment[1..]); post_dec.push_str(&second_segment); - (String::from(&first_segment[0..1]), - post_dec, - first_segment.len() as isize - 1) + ( + String::from(&first_segment[0..1]), + post_dec, + first_segment.len() as isize - 1, + ) } else { match first_segment.chars().next() { Some('0') => { @@ -273,18 +278,13 @@ pub fn get_primitive_dec(inprefix: &InPrefix, (first_segment, second_segment, 0) }; - let (pre_dec_draft, post_dec_draft) = round_terminal_digit(pre_dec_unrounded, - post_dec_unrounded, - last_dec_place - 1); + let (pre_dec_draft, post_dec_draft) = + round_terminal_digit(pre_dec_unrounded, post_dec_unrounded, last_dec_place - 1); f.pre_decimal = Some(pre_dec_draft); f.post_decimal = Some(post_dec_draft); if let Some(capitalized) = sci_mode { - let si_ind = if capitalized { - 'E' - } else { - 'e' - }; + let si_ind = if capitalized { 'E' } else { 'e' }; f.suffix = Some(if mantissa >= 0 { format!("{}+{:02}", si_ind, mantissa) } else { @@ -310,9 +310,11 @@ pub fn primitive_to_str_common(prim: &FormatPrimitive, field: &FormatField) -> S final_str.push_str(&pre_decimal); } None => { - panic!("error, format primitives provided to int, will, incidentally under correct \ - behavior, always have a pre_dec value."); - } + panic!( + "error, format primitives provided to int, will, incidentally under correct \ + behavior, always have a pre_dec value." + ); + } } let decimal_places = field.second_field.unwrap_or(6); match prim.post_decimal { @@ -338,8 +340,10 @@ pub fn primitive_to_str_common(prim: &FormatPrimitive, field: &FormatField) -> S } } None => { - panic!("error, format primitives provided to int, will, incidentally under correct \ - behavior, always have a pre_dec value."); + panic!( + "error, format primitives provided to int, will, incidentally under correct \ + behavior, always have a pre_dec value." + ); } } match prim.suffix { diff --git a/src/printf/tokenize/num_format/formatters/floatf.rs b/src/printf/tokenize/num_format/formatters/floatf.rs index 648eda9a4..46d7c9682 100644 --- a/src/printf/tokenize/num_format/formatters/floatf.rs +++ b/src/printf/tokenize/num_format/formatters/floatf.rs @@ -1,7 +1,7 @@ //! formatter for %f %F common-notation floating-point subs use super::super::format_field::FormatField; -use super::super::formatter::{InPrefix, FormatPrimitive, Formatter}; -use super::float_common::{FloatAnalysis, get_primitive_dec, primitive_to_str_common}; +use super::super::formatter::{FormatPrimitive, Formatter, InPrefix}; +use super::float_common::{get_primitive_dec, primitive_to_str_common, FloatAnalysis}; pub struct Floatf { as_num: f64, @@ -12,22 +12,22 @@ impl Floatf { } } impl Formatter for Floatf { - fn get_primitive(&self, - field: &FormatField, - inprefix: &InPrefix, - str_in: &str) - -> Option { + fn get_primitive( + &self, + field: &FormatField, + inprefix: &InPrefix, + str_in: &str, + ) -> Option { let second_field = field.second_field.unwrap_or(6) + 1; - let analysis = FloatAnalysis::analyze(&str_in, - inprefix, - None, - Some(second_field as usize), - false); - let f = get_primitive_dec(inprefix, - &str_in[inprefix.offset..], - &analysis, - second_field as usize, - None); + let analysis = + FloatAnalysis::analyze(&str_in, inprefix, None, Some(second_field as usize), false); + let f = get_primitive_dec( + inprefix, + &str_in[inprefix.offset..], + &analysis, + second_field as usize, + None, + ); Some(f) } fn primitive_to_str(&self, prim: &FormatPrimitive, field: FormatField) -> String { diff --git a/src/printf/tokenize/num_format/formatters/intf.rs b/src/printf/tokenize/num_format/formatters/intf.rs index 8dddc29ac..498df3fc2 100644 --- a/src/printf/tokenize/num_format/formatters/intf.rs +++ b/src/printf/tokenize/num_format/formatters/intf.rs @@ -4,8 +4,8 @@ use std::u64; use std::i64; use super::super::format_field::FormatField; -use super::super::formatter::{InPrefix, FormatPrimitive, Base, Formatter, warn_incomplete_conv, - get_it_at}; +use super::super::formatter::{get_it_at, warn_incomplete_conv, Base, FormatPrimitive, Formatter, + InPrefix}; pub struct Intf { a: u32, @@ -118,15 +118,13 @@ impl Intf { fn get_max(fchar: char, sign: i8) -> FormatPrimitive { let mut fmt_prim: FormatPrimitive = Default::default(); fmt_prim.pre_decimal = Some(String::from(match fchar { - 'd' | 'i' => { - match sign { - 1 => "9223372036854775807", - _ => { - fmt_prim.prefix = Some(String::from("-")); - "9223372036854775808" - } + 'd' | 'i' => match sign { + 1 => "9223372036854775807", + _ => { + fmt_prim.prefix = Some(String::from("-")); + "9223372036854775808" } - } + }, 'x' | 'X' => "ffffffffffffffff", 'o' => "1777777777777777777777", 'u' | _ => "18446744073709551615", @@ -150,56 +148,50 @@ impl Intf { // for u64 output, the u64 max in the output radix fn conv_from_segment(segment: &str, radix_in: Base, fchar: char, sign: i8) -> FormatPrimitive { match fchar { - 'i' | 'd' => { - match i64::from_str_radix(segment, radix_in as u32) { - Ok(i) => { - let mut fmt_prim: FormatPrimitive = Default::default(); - if sign == -1 { - fmt_prim.prefix = Some(String::from("-")); - } - fmt_prim.pre_decimal = Some(format!("{}", i)); - fmt_prim + 'i' | 'd' => match i64::from_str_radix(segment, radix_in as u32) { + Ok(i) => { + let mut fmt_prim: FormatPrimitive = Default::default(); + if sign == -1 { + fmt_prim.prefix = Some(String::from("-")); } - Err(_) => Intf::get_max(fchar, sign), + fmt_prim.pre_decimal = Some(format!("{}", i)); + fmt_prim } - } - _ => { - match u64::from_str_radix(segment, radix_in as u32) { - Ok(u) => { - let mut fmt_prim: FormatPrimitive = Default::default(); - let u_f = if sign == -1 { - u64::MAX - (u - 1) - } else { - u - }; - fmt_prim.pre_decimal = Some(match fchar { - 'X' => format!("{:X}", u_f), - 'x' => format!("{:x}", u_f), - 'o' => format!("{:o}", u_f), - _ => format!("{}", u_f), - }); - fmt_prim - } - Err(_) => Intf::get_max(fchar, sign), + Err(_) => Intf::get_max(fchar, sign), + }, + _ => match u64::from_str_radix(segment, radix_in as u32) { + Ok(u) => { + let mut fmt_prim: FormatPrimitive = Default::default(); + let u_f = if sign == -1 { u64::MAX - (u - 1) } else { u }; + fmt_prim.pre_decimal = Some(match fchar { + 'X' => format!("{:X}", u_f), + 'x' => format!("{:x}", u_f), + 'o' => format!("{:o}", u_f), + _ => format!("{}", u_f), + }); + fmt_prim } - } + Err(_) => Intf::get_max(fchar, sign), + }, } } } impl Formatter for Intf { - fn get_primitive(&self, - field: &FormatField, - inprefix: &InPrefix, - str_in: &str) - -> Option { - + fn get_primitive( + &self, + field: &FormatField, + inprefix: &InPrefix, + str_in: &str, + ) -> Option { let begin = inprefix.offset; // get information about the string. see Intf::Analyze // def above. - let convert_hints = Intf::analyze(str_in, - *field.field_char == 'i' || *field.field_char == 'd', - inprefix); + let convert_hints = Intf::analyze( + str_in, + *field.field_char == 'i' || *field.field_char == 'd', + inprefix, + ); // We always will have a formatprimitive to return Some(if convert_hints.len_digits == 0 || convert_hints.is_zero { // if non-digit or end is reached before a non-zero digit @@ -224,10 +216,12 @@ impl Formatter for Intf { if convert_hints.check_past_max || decr_from_max || radix_mismatch { // radix of in and out is the same. let segment = String::from(&str_in[begin..end]); - let m = Intf::conv_from_segment(&segment, - inprefix.radix_in.clone(), - *field.field_char, - inprefix.sign); + let m = Intf::conv_from_segment( + &segment, + inprefix.radix_in.clone(), + *field.field_char, + inprefix.sign, + ); m } else { // otherwise just do a straight string copy. @@ -237,7 +231,6 @@ impl Formatter for Intf { // zero doesn't get a sign, and conv_from_segment // creates its format primitive separately if inprefix.sign == -1 && *field.field_char == 'i' { - fmt_prim.prefix = Some(String::from("-")); } fmt_prim.pre_decimal = Some(String::from(&str_in[begin..end])); @@ -246,7 +239,6 @@ impl Formatter for Intf { } else { Intf::get_max(*field.field_char, inprefix.sign) }) - } fn primitive_to_str(&self, prim: &FormatPrimitive, field: FormatField) -> String { let mut finalstr: String = String::new(); @@ -274,8 +266,10 @@ impl Formatter for Intf { finalstr.push_str(&pre_decimal); } None => { - panic!("error, format primitives provided to int, will, incidentally under \ - correct behavior, always have a pre_dec value."); + panic!( + "error, format primitives provided to int, will, incidentally under \ + correct behavior, always have a pre_dec value." + ); } } finalstr diff --git a/src/printf/tokenize/num_format/formatters/scif.rs b/src/printf/tokenize/num_format/formatters/scif.rs index 78d03f996..f9092d1ca 100644 --- a/src/printf/tokenize/num_format/formatters/scif.rs +++ b/src/printf/tokenize/num_format/formatters/scif.rs @@ -1,7 +1,7 @@ //! formatter for %e %E scientific notation subs use super::super::format_field::FormatField; -use super::super::formatter::{InPrefix, FormatPrimitive, Formatter}; -use super::float_common::{FloatAnalysis, get_primitive_dec, primitive_to_str_common}; +use super::super::formatter::{FormatPrimitive, Formatter, InPrefix}; +use super::float_common::{get_primitive_dec, primitive_to_str_common, FloatAnalysis}; pub struct Scif { as_num: f64, @@ -12,22 +12,27 @@ impl Scif { } } impl Formatter for Scif { - fn get_primitive(&self, - field: &FormatField, - inprefix: &InPrefix, - str_in: &str) - -> Option { + fn get_primitive( + &self, + field: &FormatField, + inprefix: &InPrefix, + str_in: &str, + ) -> Option { let second_field = field.second_field.unwrap_or(6) + 1; - let analysis = FloatAnalysis::analyze(str_in, - inprefix, - Some(second_field as usize + 1), - None, - false); - let f = get_primitive_dec(inprefix, - &str_in[inprefix.offset..], - &analysis, - second_field as usize, - Some(*field.field_char == 'E')); + let analysis = FloatAnalysis::analyze( + str_in, + inprefix, + Some(second_field as usize + 1), + None, + false, + ); + let f = get_primitive_dec( + inprefix, + &str_in[inprefix.offset..], + &analysis, + second_field as usize, + Some(*field.field_char == 'E'), + ); Some(f) } fn primitive_to_str(&self, prim: &FormatPrimitive, field: FormatField) -> String { diff --git a/src/printf/tokenize/num_format/num_format.rs b/src/printf/tokenize/num_format/num_format.rs index dd2185cb0..911fabb6a 100644 --- a/src/printf/tokenize/num_format/num_format.rs +++ b/src/printf/tokenize/num_format/num_format.rs @@ -3,8 +3,8 @@ use std::env; use std::vec::Vec; use cli; -use super::format_field::{FormatField, FieldType}; -use super::formatter::{Formatter, FormatPrimitive, InPrefix, Base}; +use super::format_field::{FieldType, FormatField}; +use super::formatter::{Base, FormatPrimitive, Formatter, InPrefix}; use super::formatters::intf::Intf; use super::formatters::floatf::Floatf; use super::formatters::cninetyninehexfloatf::CninetyNineHexFloatf; @@ -21,16 +21,16 @@ pub fn warn_expected_numeric(pf_arg: &String) { fn warn_char_constant_ign(remaining_bytes: Vec) { match env::var("POSIXLY_CORRECT") { Ok(_) => {} - Err(e) => { - match e { - env::VarError::NotPresent => { - cli::err_msg(&format!("warning: {:?}: character(s) following character \ - constant have been ignored", - &*remaining_bytes)); - } - _ => {} + Err(e) => match e { + env::VarError::NotPresent => { + cli::err_msg(&format!( + "warning: {:?}: character(s) following character \ + constant have been ignored", + &*remaining_bytes + )); } - } + _ => {} + }, } } @@ -68,8 +68,7 @@ fn get_provided(str_in_opt: Option<&String>) -> Option { // first byte is not quote _ => { return None; - } - // no first byte + } // no first byte } } else { Some(0 as u8) @@ -150,7 +149,7 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { FieldType::Intf => { ret.radix_in = Base::Octal; } - _ => {} + _ => {} } if e == '0' { do_clean_lead_zeroes = true; @@ -181,7 +180,7 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { // if decimal, keep last zero if one exists // (it's possible for last zero to // not exist at this branch if we're in hex input) - '.' => break, + '.' => break, // other digit, etc. _ => { if !(is_hex && first) { @@ -193,7 +192,6 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { if first { first = false; } - } } } @@ -205,8 +203,6 @@ fn get_inprefix(str_in: &String, field_type: &FieldType) -> InPrefix { // if it is a numeric field, passing the field details // and an iterator to the argument pub fn num_format(field: &FormatField, in_str_opt: Option<&String>) -> Option { - - let fchar = field.field_char.clone(); // num format mainly operates by further delegating to one of @@ -247,7 +243,7 @@ pub fn num_format(field: &FormatField, in_str_opt: Option<&String>) -> Option>, - second_field: CanAsterisk>, - field_char: char, - orig: String) - -> Sub { + pub fn new( + min_width: CanAsterisk>, + second_field: CanAsterisk>, + field_char: char, + orig: String, + ) -> Sub { // for more dry printing, field characters are grouped // in initialization of token. let field_type = match field_char { @@ -112,9 +113,10 @@ impl SubParser { text_so_far: String::new(), } } - fn from_it(it: &mut PutBackN, - args: &mut Peekable>) - -> Option> { + fn from_it( + it: &mut PutBackN, + args: &mut Peekable>, + ) -> Option> { let mut parser = SubParser::new(); if parser.sub_vals_retrieved(it) { let t: Box = SubParser::build_token(parser); @@ -127,22 +129,23 @@ impl SubParser { fn build_token(parser: SubParser) -> Box { // not a self method so as to allow move of subparser vals. // return new Sub struct as token - let t: Box = Box::new(Sub::new(if parser.min_width_is_asterisk { - CanAsterisk::Asterisk - } else { - CanAsterisk::Fixed(parser.min_width_tmp.map(|x| x.parse::().unwrap())) - }, - if parser.second_field_is_asterisk { - CanAsterisk::Asterisk - } else { - CanAsterisk::Fixed(parser.second_field_tmp.map(|x| x.parse::().unwrap())) - }, - parser.field_char.unwrap(), - parser.text_so_far)); + let t: Box = Box::new(Sub::new( + if parser.min_width_is_asterisk { + CanAsterisk::Asterisk + } else { + CanAsterisk::Fixed(parser.min_width_tmp.map(|x| x.parse::().unwrap())) + }, + if parser.second_field_is_asterisk { + CanAsterisk::Asterisk + } else { + CanAsterisk::Fixed(parser.second_field_tmp.map(|x| x.parse::().unwrap())) + }, + parser.field_char.unwrap(), + parser.text_so_far, + )); t } fn sub_vals_retrieved(&mut self, it: &mut PutBackN) -> bool { - if !SubParser::successfully_eat_prefix(it, &mut self.text_so_far) { return false; } @@ -197,7 +200,7 @@ impl SubParser { } None => { panic!("should be unreachable"); - } + } } } else { // second field should never have a @@ -220,7 +223,7 @@ impl SubParser { } None => { panic!("should be unreachable"); - } + } } } } @@ -298,23 +301,23 @@ impl SubParser { // check for illegal combinations here when possible vs // on each application so we check less per application // to do: move these checks to Sub::new - if (field_char == 's' && self.min_width_tmp == Some(String::from("0"))) || - (field_char == 'c' && - (self.min_width_tmp == Some(String::from("0")) || self.past_decimal)) || - (field_char == 'b' && - (self.min_width_tmp.is_some() || self.past_decimal || - self.second_field_tmp.is_some())) { + if (field_char == 's' && self.min_width_tmp == Some(String::from("0"))) + || (field_char == 'c' + && (self.min_width_tmp == Some(String::from("0")) || self.past_decimal)) + || (field_char == 'b' + && (self.min_width_tmp.is_some() || self.past_decimal + || self.second_field_tmp.is_some())) + { err_conv(&self.text_so_far); } } } - - impl token::Tokenizer for Sub { - fn from_it(it: &mut PutBackN, - args: &mut Peekable>) - -> Option> { + fn from_it( + it: &mut PutBackN, + args: &mut Peekable>, + ) -> Option> { SubParser::from_it(it, args) } } @@ -346,7 +349,7 @@ impl token::Token for Sub { } None => Some(0), } - } + } }, field_char: &self.field_char, field_type: &self.field_type, @@ -361,15 +364,13 @@ impl token::Token for Sub { // if %b use UnescapedText module's unescaping-fn // if %c return first char of arg FieldType::Strf | FieldType::Charf => { - match pf_arg { + match pf_arg { Some(arg_string) => { match *field.field_char { - 's' => { - Some(match field.second_field { - Some(max) => String::from(&arg_string[..max as usize]), - None => arg_string.clone(), - }) - } + 's' => Some(match field.second_field { + Some(max) => String::from(&arg_string[..max as usize]), + None => arg_string.clone(), + }), 'b' => { let mut a_it = put_back_n(arg_string.chars()); UnescapedText::from_it_core(&mut a_it, true); @@ -392,32 +393,34 @@ impl token::Token for Sub { match pre_min_width_opt { // if have a string, print it, ensuring minimum width is met. Some(pre_min_width) => { - print!("{}", - match field.min_width { - Some(min_width) => { - let diff: isize = min_width.abs() as isize - - pre_min_width.len() as isize; - if diff > 0 { - let mut final_str = String::new(); - // definitely more efficient ways - // to do this. - let pad_before = min_width > 0; - if !pad_before { - final_str.push_str(&pre_min_width); - } - for _ in 0..diff { - final_str.push(' '); - } - if pad_before { - final_str.push_str(&pre_min_width); - } - final_str - } else { - pre_min_width - } - } - None => pre_min_width, - }); + print!( + "{}", + match field.min_width { + Some(min_width) => { + let diff: isize = + min_width.abs() as isize - pre_min_width.len() as isize; + if diff > 0 { + let mut final_str = String::new(); + // definitely more efficient ways + // to do this. + let pad_before = min_width > 0; + if !pad_before { + final_str.push_str(&pre_min_width); + } + for _ in 0..diff { + final_str.push(' '); + } + if pad_before { + final_str.push_str(&pre_min_width); + } + final_str + } else { + pre_min_width + } + } + None => pre_min_width, + } + ); } None => {} } diff --git a/src/printf/tokenize/unescaped_text.rs b/src/printf/tokenize/unescaped_text.rs index 50eecc8ec..3ea0038b1 100644 --- a/src/printf/tokenize/unescaped_text.rs +++ b/src/printf/tokenize/unescaped_text.rs @@ -65,12 +65,12 @@ impl UnescapedText { preface = 'U'; leading_zeros = 8; } - let err_msg = format!("invalid universal character name {0}{1:02$x}", - preface, - val, - leading_zeros); + let err_msg = format!( + "invalid universal character name {0}{1:02$x}", + preface, val, leading_zeros + ); if (val < 159 && (val != 36 && val != 64 && val != 96)) || (val > 55296 && val < 57343) { - println!("{}", err_msg);//todo stderr + println!("{}", err_msg); //todo stderr exit(cli::EXIT_ERR); } } @@ -167,7 +167,6 @@ impl UnescapedText { byte_vec.extend(s.bytes()); } }; - } // take an iterator to a string, @@ -239,9 +238,10 @@ impl UnescapedText { } #[allow(unused_variables)] impl token::Tokenizer for UnescapedText { - fn from_it(it: &mut PutBackN, - args: &mut Peekable>) - -> Option> { + fn from_it( + it: &mut PutBackN, + args: &mut Peekable>, + ) -> Option> { UnescapedText::from_it_core(it, false) } } diff --git a/src/ptx/ptx.rs b/src/ptx/ptx.rs index ac9731591..b918b30f7 100644 --- a/src/ptx/ptx.rs +++ b/src/ptx/ptx.rs @@ -12,19 +12,19 @@ extern crate aho_corasick; extern crate getopts; extern crate memchr; -extern crate regex_syntax; extern crate regex; +extern crate regex_syntax; #[macro_use] extern crate uucore; -use getopts::{Options, Matches}; +use getopts::{Matches, Options}; use regex::Regex; use std::cmp; -use std::collections::{HashMap, HashSet, BTreeSet}; +use std::collections::{BTreeSet, HashMap, HashSet}; use std::default::Default; use std::fs::File; -use std::io::{stdin, stdout, BufReader, BufWriter, BufRead, Read, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; static NAME: &'static str = "ptx"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); @@ -38,33 +38,33 @@ enum OutFormat { #[derive(Debug)] struct Config { - format : OutFormat, - gnu_ext : bool, - auto_ref : bool, - input_ref : bool, - right_ref : bool, - ignore_case : bool, - macro_name : String, - trunc_str : String, - context_regex : String, - line_width : usize, - gap_size : usize, + format: OutFormat, + gnu_ext: bool, + auto_ref: bool, + input_ref: bool, + right_ref: bool, + ignore_case: bool, + macro_name: String, + trunc_str: String, + context_regex: String, + line_width: usize, + gap_size: usize, } impl Default for Config { fn default() -> Config { Config { - format : OutFormat::Dumb, - gnu_ext : true, - auto_ref : false, - input_ref : false, - right_ref : false, - ignore_case : false, - macro_name : "xx".to_owned(), - trunc_str : "/".to_owned(), - context_regex : "\\w+".to_owned(), - line_width : 72, - gap_size : 3 + format: OutFormat::Dumb, + gnu_ext: true, + auto_ref: false, + input_ref: false, + right_ref: false, + ignore_case: false, + macro_name: "xx".to_owned(), + trunc_str: "/".to_owned(), + context_regex: "\\w+".to_owned(), + line_width: 72, + gap_size: 3, } } } @@ -89,36 +89,33 @@ struct WordFilter { } impl WordFilter { - fn new(matches: &Matches, config: &Config) -> WordFilter { - let (o, oset): (bool, HashSet) = - if matches.opt_present("o") { - (true, read_word_filter_file(matches, "o")) - } else { - (false, HashSet::new()) - }; - let (i, iset): (bool, HashSet) = - if matches.opt_present("i") { - (true, read_word_filter_file(matches, "i")) - } else { - (false, HashSet::new()) - }; + fn new(matches: &Matches, config: &Config) -> WordFilter { + let (o, oset): (bool, HashSet) = if matches.opt_present("o") { + (true, read_word_filter_file(matches, "o")) + } else { + (false, HashSet::new()) + }; + let (i, iset): (bool, HashSet) = if matches.opt_present("i") { + (true, read_word_filter_file(matches, "i")) + } else { + (false, HashSet::new()) + }; if matches.opt_present("b") { crash!(1, "-b not implemented yet"); } - let reg = - if matches.opt_present("W") { - matches.opt_str("W").expect("parsing options failed!") - } else if config.gnu_ext { - "\\w+".to_owned() - } else { - "[^ \t\n]+".to_owned() - }; + let reg = if matches.opt_present("W") { + matches.opt_str("W").expect("parsing options failed!") + } else if config.gnu_ext { + "\\w+".to_owned() + } else { + "[^ \t\n]+".to_owned() + }; WordFilter { only_specified: o, ignore_specified: i, only_set: oset, ignore_set: iset, - word_regex: reg + word_regex: reg, } } } @@ -139,11 +136,11 @@ fn print_version() { fn print_usage(opts: &Options) { let brief = "Usage: ptx [OPTION]... [INPUT]... (without -G) or: \ - ptx -G [OPTION]... [INPUT [OUTPUT]] \n Output a permuted index, \ - including context, of the words in the input files. \n\n Mandatory \ - arguments to long options are mandatory for short options too."; + ptx -G [OPTION]... [INPUT [OUTPUT]] \n Output a permuted index, \ + including context, of the words in the input files. \n\n Mandatory \ + arguments to long options are mandatory for short options too."; let explaination = "With no FILE, or when FILE is -, read standard input. \ - Default is '-F /'."; + Default is '-F /'."; println!("{}\n{}", opts.usage(&brief), explaination); } @@ -165,22 +162,18 @@ fn get_config(matches: &Matches) -> Config { config.right_ref &= matches.opt_present("R"); config.ignore_case = matches.opt_present("f"); if matches.opt_present("M") { - config.macro_name = - matches.opt_str("M").expect(err_msg); + config.macro_name = matches.opt_str("M").expect(err_msg); } if matches.opt_present("F") { - config.trunc_str = - matches.opt_str("F").expect(err_msg); + config.trunc_str = matches.opt_str("F").expect(err_msg); } if matches.opt_present("w") { let width_str = matches.opt_str("w").expect(err_msg); - config.line_width = crash_if_err!( - 1, usize::from_str_radix(&width_str, 10)); + config.line_width = crash_if_err!(1, usize::from_str_radix(&width_str, 10)); } if matches.opt_present("g") { let gap_str = matches.opt_str("g").expect(err_msg); - config.gap_size = crash_if_err!( - 1, usize::from_str_radix(&gap_str, 10)); + config.gap_size = crash_if_err!(1, usize::from_str_radix(&gap_str, 10)); } if matches.opt_present("O") { config.format = OutFormat::Roff; @@ -191,10 +184,8 @@ fn get_config(matches: &Matches) -> Config { config } -fn read_input(input_files: &[String], config: &Config) -> - HashMap, usize)> { - let mut file_map : HashMap, usize)> = - HashMap::new(); +fn read_input(input_files: &[String], config: &Config) -> HashMap, usize)> { + let mut file_map: HashMap, usize)> = HashMap::new(); let mut files = Vec::new(); if input_files.is_empty() { files.push("-"); @@ -209,15 +200,13 @@ fn read_input(input_files: &[String], config: &Config) -> } let mut lines_so_far: usize = 0; for filename in files { - let reader: BufReader> = BufReader::new( - if filename == "-" { - Box::new(stdin()) - } else { - let file = crash_if_err!(1, File::open(filename)); - Box::new(file) - }); - let lines: Vec = reader.lines().map(|x| crash_if_err!(1, x)) - .collect(); + let reader: BufReader> = BufReader::new(if filename == "-" { + Box::new(stdin()) + } else { + let file = crash_if_err!(1, File::open(filename)); + Box::new(file) + }); + let lines: Vec = reader.lines().map(|x| crash_if_err!(1, x)).collect(); let size = lines.len(); file_map.insert(filename.to_owned(), (lines, lines_so_far)); lines_so_far += size @@ -225,9 +214,11 @@ fn read_input(input_files: &[String], config: &Config) -> file_map } -fn create_word_set(config: &Config, filter: &WordFilter, - file_map: &HashMap, usize)>)-> - BTreeSet { +fn create_word_set( + config: &Config, + filter: &WordFilter, + file_map: &HashMap, usize)>, +) -> BTreeSet { let reg = Regex::new(&filter.word_regex).unwrap(); let ref_reg = Regex::new(&config.context_regex).unwrap(); let mut word_set: BTreeSet = BTreeSet::new(); @@ -238,7 +229,7 @@ fn create_word_set(config: &Config, filter: &WordFilter, // if -r, exclude reference from word set let (ref_beg, ref_end) = match ref_reg.find(line) { Some(x) => (x.start(), x.end()), - None => (0, 0) + None => (0, 0), }; // match words with given regex for mat in reg.find_iter(line) { @@ -246,25 +237,23 @@ fn create_word_set(config: &Config, filter: &WordFilter, if config.input_ref && ((beg, end) == (ref_beg, ref_end)) { continue; } - let mut word = line[beg .. end].to_owned(); - if filter.only_specified && - !(filter.only_set.contains(&word)) { + let mut word = line[beg..end].to_owned(); + if filter.only_specified && !(filter.only_set.contains(&word)) { continue; } - if filter.ignore_specified && - filter.ignore_set.contains(&word) { + if filter.ignore_specified && filter.ignore_set.contains(&word) { continue; } if config.ignore_case { word = word.to_lowercase(); } - word_set.insert(WordRef{ + word_set.insert(WordRef { word: word, filename: String::from(file.clone()), global_line_nr: offs + count, local_line_nr: count, position: beg, - position_end: end + position_end: end, }); } count += 1; @@ -273,17 +262,16 @@ fn create_word_set(config: &Config, filter: &WordFilter, word_set } -fn get_reference(config: &Config, word_ref: &WordRef, line: &str) -> - String { +fn get_reference(config: &Config, word_ref: &WordRef, line: &str) -> String { if config.auto_ref { format!("{}:{}", word_ref.filename, word_ref.local_line_nr + 1) } else if config.input_ref { let reg = Regex::new(&config.context_regex).unwrap(); let (beg, end) = match reg.find(line) { Some(x) => (x.start(), x.end()), - None => (0, 0) + None => (0, 0), }; - format!("{}", &line[beg .. end]) + format!("{}", &line[beg..end]) } else { String::new() } @@ -296,8 +284,7 @@ fn assert_str_integrity(s: &[char], beg: usize, end: usize) { fn trim_broken_word_left(s: &[char], beg: usize, end: usize) -> usize { assert_str_integrity(s, beg, end); - if beg == end || beg == 0 || s[beg].is_whitespace() || - s[beg-1].is_whitespace() { + if beg == end || beg == 0 || s[beg].is_whitespace() || s[beg - 1].is_whitespace() { return beg; } let mut b = beg; @@ -309,12 +296,11 @@ fn trim_broken_word_left(s: &[char], beg: usize, end: usize) -> usize { fn trim_broken_word_right(s: &[char], beg: usize, end: usize) -> usize { assert_str_integrity(s, beg, end); - if beg == end || end == s.len() || s[end-1].is_whitespace() || - s[end].is_whitespace() { + if beg == end || end == s.len() || s[end - 1].is_whitespace() || s[end].is_whitespace() { return end; } let mut e = end; - while beg < e && !s[e-1].is_whitespace() { + while beg < e && !s[e - 1].is_whitespace() { e -= 1; } e @@ -327,14 +313,18 @@ fn trim_idx(s: &[char], beg: usize, end: usize) -> (usize, usize) { while b < e && s[b].is_whitespace() { b += 1; } - while b < e && s[e-1].is_whitespace() { + while b < e && s[e - 1].is_whitespace() { e -= 1; } - (b,e) + (b, e) } -fn get_output_chunks(all_before: &str, keyword: &str, all_after: &str, - config: &Config) -> (String, String, String, String) { +fn get_output_chunks( + all_before: &str, + keyword: &str, + all_after: &str, + config: &Config, +) -> (String, String, String, String) { assert_eq!(all_before.trim(), all_before); assert_eq!(keyword.trim(), keyword); assert_eq!(all_after.trim(), all_after); @@ -343,28 +333,27 @@ fn get_output_chunks(all_before: &str, keyword: &str, all_after: &str, let mut after = String::new(); let mut tail = String::new(); - let half_line_size = cmp::max((config.line_width/2) as isize - - (2*config.trunc_str.len()) as isize, 0) as usize; - let max_after_size = cmp::max(half_line_size as isize - - keyword.len() as isize - 1, 0) as usize; + let half_line_size = cmp::max( + (config.line_width / 2) as isize - (2 * config.trunc_str.len()) as isize, + 0, + ) as usize; + let max_after_size = cmp::max(half_line_size as isize - keyword.len() as isize - 1, 0) as usize; let max_before_size = half_line_size; let all_before_vec: Vec = all_before.chars().collect(); let all_after_vec: Vec = all_after.chars().collect(); // get before - let mut bb_tmp = - cmp::max(all_before.len() as isize - max_before_size as isize, 0) as usize; + let mut bb_tmp = cmp::max(all_before.len() as isize - max_before_size as isize, 0) as usize; bb_tmp = trim_broken_word_left(&all_before_vec, bb_tmp, all_before.len()); - let (before_beg, before_end) = - trim_idx(&all_before_vec, bb_tmp, all_before.len()); - before.push_str(&all_before[before_beg .. before_end]); + let (before_beg, before_end) = trim_idx(&all_before_vec, bb_tmp, all_before.len()); + before.push_str(&all_before[before_beg..before_end]); assert!(max_before_size >= before.len()); // get after let mut ae_tmp = cmp::min(max_after_size, all_after.len()); ae_tmp = trim_broken_word_right(&all_after_vec, 0, ae_tmp); let (after_beg, after_end) = trim_idx(&all_after_vec, 0, ae_tmp); - after.push_str(&all_after[after_beg .. after_end]); + after.push_str(&all_after[after_beg..after_end]); assert!(max_after_size >= after.len()); // get tail @@ -373,16 +362,15 @@ fn get_output_chunks(all_before: &str, keyword: &str, all_after: &str, let mut te_tmp = cmp::min(tb + max_tail_size, all_after.len()); te_tmp = trim_broken_word_right(&all_after_vec, tb, te_tmp); let (tail_beg, tail_end) = trim_idx(&all_after_vec, tb, te_tmp); - tail.push_str(&all_after[tail_beg .. tail_end]); + tail.push_str(&all_after[tail_beg..tail_end]); // get head let max_head_size = max_after_size - after.len(); let (_, he) = trim_idx(&all_before_vec, 0, before_beg); - let mut hb_tmp = - cmp::max(he as isize - max_head_size as isize, 0) as usize; + let mut hb_tmp = cmp::max(he as isize - max_head_size as isize, 0) as usize; hb_tmp = trim_broken_word_left(&all_before_vec, hb_tmp, he); let (head_beg, head_end) = trim_idx(&all_before_vec, hb_tmp, he); - head.push_str(&all_before[head_beg .. head_end]); + head.push_str(&all_before[head_beg..head_end]); // put right context truncation string if needed if after_end != all_after.len() && tail_beg == tail_end { @@ -411,7 +399,7 @@ fn tex_mapper(x: char) -> String { '\\' => "\\backslash{}".to_owned(), '$' | '%' | '#' | '&' | '_' => format!("\\{}", x), '}' | '{' => format!("$\\{}$", x), - _ => x.to_string() + _ => x.to_string(), } } @@ -423,84 +411,85 @@ fn adjust_tex_str(context: &str) -> String { fix } -fn format_tex_line(config: &Config, word_ref: &WordRef, line: &str, - reference: &str) -> String { +fn format_tex_line(config: &Config, word_ref: &WordRef, line: &str, reference: &str) -> String { let mut output = String::new(); output.push_str(&format!("\\{} ", config.macro_name)); let all_before = if config.input_ref { - let before = &line[0 .. word_ref.position]; + let before = &line[0..word_ref.position]; adjust_tex_str(before.trim().trim_left_matches(reference)) } else { - adjust_tex_str(&line[0 .. word_ref.position]) + adjust_tex_str(&line[0..word_ref.position]) }; - let keyword = adjust_tex_str( - &line[word_ref.position .. word_ref.position_end]); - let all_after = adjust_tex_str( - &line[word_ref.position_end .. line.len()]); - let (tail, before, after, head) = - get_output_chunks(&all_before, &keyword, &all_after, &config); - output.push_str(&format!("{5}{0}{6}{5}{1}{6}{5}{2}{6}{5}{3}{6}{5}{4}{6}", - tail, before, keyword, after, head, "{", "}")); + let keyword = adjust_tex_str(&line[word_ref.position..word_ref.position_end]); + let all_after = adjust_tex_str(&line[word_ref.position_end..line.len()]); + let (tail, before, after, head) = get_output_chunks(&all_before, &keyword, &all_after, &config); + output.push_str(&format!( + "{5}{0}{6}{5}{1}{6}{5}{2}{6}{5}{3}{6}{5}{4}{6}", + tail, before, keyword, after, head, "{", "}" + )); if config.auto_ref || config.input_ref { - output.push_str( - &format!("{}{}{}", "{", adjust_tex_str(&reference), "}")); + output.push_str(&format!("{}{}{}", "{", adjust_tex_str(&reference), "}")); } output } fn adjust_roff_str(context: &str) -> String { let ws_reg = Regex::new(r"[\t\n\v\f\r]").unwrap(); - ws_reg.replace_all(context, " ").replace("\"", "\"\"").trim().to_owned() + ws_reg + .replace_all(context, " ") + .replace("\"", "\"\"") + .trim() + .to_owned() } -fn format_roff_line(config: &Config, word_ref: &WordRef, line: &str, - reference: &str) -> String { +fn format_roff_line(config: &Config, word_ref: &WordRef, line: &str, reference: &str) -> String { let mut output = String::new(); output.push_str(&format!(".{}", config.macro_name)); let all_before = if config.input_ref { - let before = &line[0 .. word_ref.position]; + let before = &line[0..word_ref.position]; adjust_roff_str(before.trim().trim_left_matches(reference)) } else { - adjust_roff_str(&line[0 .. word_ref.position]) + adjust_roff_str(&line[0..word_ref.position]) }; - let keyword = adjust_roff_str( - &line[word_ref.position .. word_ref.position_end]); - let all_after = adjust_roff_str( - &line[word_ref.position_end .. line.len()]); - let (tail, before, after, head) = - get_output_chunks(&all_before, &keyword, &all_after, &config); - output.push_str(&format!(" \"{}\" \"{}\" \"{}{}\" \"{}\"", - tail, before, keyword, after, head)); + let keyword = adjust_roff_str(&line[word_ref.position..word_ref.position_end]); + let all_after = adjust_roff_str(&line[word_ref.position_end..line.len()]); + let (tail, before, after, head) = get_output_chunks(&all_before, &keyword, &all_after, &config); + output.push_str(&format!( + " \"{}\" \"{}\" \"{}{}\" \"{}\"", + tail, before, keyword, after, head + )); if config.auto_ref || config.input_ref { output.push_str(&format!(" \"{}\"", adjust_roff_str(&reference))); } output } -fn write_traditional_output(config: &Config, - file_map: &HashMap,usize)>, - words: &BTreeSet, output_filename: &str) { - let mut writer: BufWriter> = BufWriter::new( - if output_filename == "-" { +fn write_traditional_output( + config: &Config, + file_map: &HashMap, usize)>, + words: &BTreeSet, + output_filename: &str, +) { + let mut writer: BufWriter> = BufWriter::new(if output_filename == "-" { Box::new(stdout()) } else { let file = crash_if_err!(1, File::create(output_filename)); Box::new(file) }); for word_ref in words.iter() { - let file_map_value : &(Vec, usize) = - file_map.get(&(word_ref.filename)) - .expect("Missing file in file map"); + let file_map_value: &(Vec, usize) = file_map + .get(&(word_ref.filename)) + .expect("Missing file in file map"); let (ref lines, _) = *(file_map_value); - let reference = - get_reference(config, word_ref, &lines[word_ref.local_line_nr]); + let reference = get_reference(config, word_ref, &lines[word_ref.local_line_nr]); let output_line: String = match config.format { - OutFormat::Tex => format_tex_line( - config, word_ref, &lines[word_ref.local_line_nr], &reference), - OutFormat::Roff => format_roff_line( - config, word_ref, &lines[word_ref.local_line_nr], &reference), - OutFormat::Dumb => crash!( - 1, "There is no dumb format with GNU extensions disabled") + OutFormat::Tex => { + format_tex_line(config, word_ref, &lines[word_ref.local_line_nr], &reference) + } + OutFormat::Roff => { + format_roff_line(config, word_ref, &lines[word_ref.local_line_nr], &reference) + } + OutFormat::Dumb => crash!(1, "There is no dumb format with GNU extensions disabled"), }; crash_if_err!(1, writeln!(writer, "{}", output_line)); } @@ -508,33 +497,79 @@ fn write_traditional_output(config: &Config, pub fn uumain(args: Vec) -> i32 { let mut opts = Options::new(); - opts.optflag("A", "auto-reference", - "output automatically generated references"); + opts.optflag( + "A", + "auto-reference", + "output automatically generated references", + ); opts.optflag("G", "traditional", "behave more like System V 'ptx'"); - opts.optopt("F", "flag-truncation", - "use STRING for flagging line truncations", "STRING"); - opts.optopt("M", "macro-name", "macro name to use instead of 'xx'", - "STRING"); + opts.optopt( + "F", + "flag-truncation", + "use STRING for flagging line truncations", + "STRING", + ); + opts.optopt( + "M", + "macro-name", + "macro name to use instead of 'xx'", + "STRING", + ); opts.optflag("O", "format=roff", "generate output as roff directives"); - opts.optflag("R", "right-side-refs", - "put references at right, not counted in -w"); - opts.optopt("S", "sentence-regexp", "for end of lines or end of sentences", - "REGEXP"); + opts.optflag( + "R", + "right-side-refs", + "put references at right, not counted in -w", + ); + opts.optopt( + "S", + "sentence-regexp", + "for end of lines or end of sentences", + "REGEXP", + ); opts.optflag("T", "format=tex", "generate output as TeX directives"); - opts.optopt("W", "word-regexp", "use REGEXP to match each keyword", - "REGEXP"); - opts.optopt("b", "break-file", "word break characters in this FILE", - "FILE"); - opts.optflag("f", "ignore-case", - "fold lower case to upper case for sorting"); - opts.optopt("g", "gap-size", "gap size in columns between output fields", - "NUMBER"); - opts.optopt("i", "ignore-file", "read ignore word list from FILE", "FILE"); - opts.optopt("o", "only-file", "read only word list from this FILE", - "FILE"); + opts.optopt( + "W", + "word-regexp", + "use REGEXP to match each keyword", + "REGEXP", + ); + opts.optopt( + "b", + "break-file", + "word break characters in this FILE", + "FILE", + ); + opts.optflag( + "f", + "ignore-case", + "fold lower case to upper case for sorting", + ); + opts.optopt( + "g", + "gap-size", + "gap size in columns between output fields", + "NUMBER", + ); + opts.optopt( + "i", + "ignore-file", + "read ignore word list from FILE", + "FILE", + ); + opts.optopt( + "o", + "only-file", + "read only word list from this FILE", + "FILE", + ); opts.optflag("r", "references", "first field of each line is a reference"); - opts.optopt("w", "width", "output width in columns, reference excluded", - "NUMBER"); + opts.optopt( + "w", + "width", + "output width in columns, reference excluded", + "NUMBER", + ); opts.optflag("", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); @@ -550,8 +585,7 @@ pub fn uumain(args: Vec) -> i32 { } let config = get_config(&matches); let word_filter = WordFilter::new(&matches, &config); - let file_map = - read_input(&matches.free, &config); + let file_map = read_input(&matches.free, &config); let word_set = create_word_set(&config, &word_filter, &file_map); let output_file = if !config.gnu_ext && matches.free.len() == 2 { matches.free[1].clone() diff --git a/src/pwd/pwd.rs b/src/pwd/pwd.rs index 2365bdb3a..191dff488 100644 --- a/src/pwd/pwd.rs +++ b/src/pwd/pwd.rs @@ -25,7 +25,12 @@ pub fn absolute_path(path: &Path) -> io::Result { let path_buf = path.canonicalize()?; #[cfg(windows)] - let path_buf = Path::new(path_buf.as_path().to_string_lossy().trim_left_matches(r"\\?\")).to_path_buf(); + let path_buf = Path::new( + path_buf + .as_path() + .to_string_lossy() + .trim_left_matches(r"\\?\"), + ).to_path_buf(); Ok(path_buf) } @@ -35,23 +40,28 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); - opts.optflag("L", "logical", "use PWD from environment, even if it contains symlinks"); + opts.optflag( + "L", + "logical", + "use PWD from environment, even if it contains symlinks", + ); opts.optflag("P", "physical", "avoid all symlinks"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => { - crash!(1, "Invalid options\n{}", f) - } + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... -Print the full filename of the current working directory.", NAME, VERSION); +Print the full filename of the current working directory.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -63,11 +73,11 @@ Print the full filename of the current working directory.", NAME, VERSION); } else { match absolute_path(&logical_path) { Ok(physical_path) => println!("{}", physical_path.display()), - Err(e) => crash!(1, "failed to get absolute path {}", e) + Err(e) => crash!(1, "failed to get absolute path {}", e), }; } - }, - Err(e) => crash!(1, "failed to get current directory {}", e) + } + Err(e) => crash!(1, "failed to get current directory {}", e), }; } diff --git a/src/readlink/readlink.rs b/src/readlink/readlink.rs index 9242ca856..f3fab0ead 100644 --- a/src/readlink/readlink.rs +++ b/src/readlink/readlink.rs @@ -15,7 +15,7 @@ extern crate getopts; extern crate uucore; use std::fs; -use std::io::{Write, stdout}; +use std::io::{stdout, Write}; use std::path::PathBuf; use uucore::fs::{canonicalize, CanonicalizeMode}; @@ -25,15 +25,24 @@ const VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("f", "canonicalize", - "canonicalize by following every symlink in every component of the \ - given name recursively; all but the last component must exist"); - opts.optflag("e", "canonicalize-existing", - "canonicalize by following every symlink in every component of the \ - given name recursively, all components must exist"); - opts.optflag("m", "canonicalize-missing", - "canonicalize by following every symlink in every component of the \ - given name recursively, without requirements on components existence"); + opts.optflag( + "f", + "canonicalize", + "canonicalize by following every symlink in every component of the \ + given name recursively; all but the last component must exist", + ); + opts.optflag( + "e", + "canonicalize-existing", + "canonicalize by following every symlink in every component of the \ + given name recursively, all components must exist", + ); + opts.optflag( + "m", + "canonicalize-missing", + "canonicalize by following every symlink in every component of the \ + given name recursively, without requirements on components existence", + ); opts.optflag("n", "no-newline", "do not output the trailing delimiter"); opts.optflag("q", "quiet", "suppress most error messages"); opts.optflag("s", "silent", "suppress most error messages"); @@ -44,7 +53,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f) + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("help") { show_usage(&opts); @@ -76,7 +85,11 @@ pub fn uumain(args: Vec) -> i32 { let files = matches.free; if files.is_empty() { - crash!(1, "missing operand\nTry {} --help for more information", NAME); + crash!( + 1, + "missing operand\nTry {} --help for more information", + NAME + ); } if no_newline && files.len() > 1 && !silent { @@ -93,7 +106,7 @@ pub fn uumain(args: Vec) -> i32 { if verbose { eprintln!("{}: {}: errno {}", NAME, f, err.raw_os_error().unwrap()); } - return 1 + return 1; } } } else { @@ -103,7 +116,7 @@ pub fn uumain(args: Vec) -> i32 { if verbose { eprintln!("{}: {}: errno {:?}", NAME, f, err.raw_os_error().unwrap()); } - return 1 + return 1; } } } diff --git a/src/realpath/realpath.rs b/src/realpath/realpath.rs index e801efb4c..258d7caf2 100644 --- a/src/realpath/realpath.rs +++ b/src/realpath/realpath.rs @@ -1,4 +1,4 @@ -#![crate_name= "uu_realpath"] +#![crate_name = "uu_realpath"] /* * This file is part of the uutils coreutils package. @@ -26,8 +26,16 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("h", "help", "Show help and exit"); opts.optflag("V", "version", "Show version and exit"); - opts.optflag("s", "strip", "Only strip '.' and '..' components, but don't resolve symbolic links"); - opts.optflag("z", "zero", "Separate output filenames with \\0 rather than newline"); + opts.optflag( + "s", + "strip", + "Only strip '.' and '..' components, but don't resolve symbolic links", + ); + opts.optflag( + "z", + "zero", + "Separate output filenames with \\0 rather than newline", + ); opts.optflag("q", "quiet", "Do not print warnings for invalid paths"); let matches = match opts.parse(&args[1..]) { @@ -35,17 +43,23 @@ pub fn uumain(args: Vec) -> i32 { Err(f) => { show_error!("{}", f); show_usage(&opts); - return 1 + return 1; } }; - if matches.opt_present("V") { version(); return 0 } - if matches.opt_present("h") { show_usage(&opts); return 0 } + if matches.opt_present("V") { + version(); + return 0; + } + if matches.opt_present("h") { + show_usage(&opts); + return 0; + } if matches.free.is_empty() { show_error!("Missing operand: FILENAME, at least one is required"); println!("Try `{} --help` for more information.", NAME); - return 1 + return 1; } let strip = matches.opt_present("s"); @@ -70,7 +84,7 @@ fn resolve_path(path: &str, strip: bool, zero: bool, quiet: bool) -> bool { } else { println!("{}", abs.display()) } - return true + return true; } let mut result = PathBuf::new(); @@ -80,8 +94,10 @@ fn resolve_path(path: &str, strip: bool, zero: bool, quiet: bool) -> bool { result.push(part.as_os_str()); loop { if links_left == 0 { - if !quiet { show_error!("Too many symbolic links: {}", path) }; - return false + if !quiet { + show_error!("Too many symbolic links: {}", path) + }; + return false; } match fs::metadata(result.as_path()) { Err(_) => break, @@ -92,13 +108,13 @@ fn resolve_path(path: &str, strip: bool, zero: bool, quiet: bool) -> bool { Ok(x) => { result.pop(); result.push(x.as_path()); - }, + } _ => { if !quiet { show_error!("Invalid path: {}", path) }; - return false - }, + return false; + } } } } diff --git a/src/relpath/relpath.rs b/src/relpath/relpath.rs index b1bd0ac41..0138f1c0d 100644 --- a/src/relpath/relpath.rs +++ b/src/relpath/relpath.rs @@ -26,24 +26,35 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("h", "help", "Show help and exit"); opts.optflag("V", "version", "Show version and exit"); - opts.optopt("d", "", "If any of FROM and TO is not subpath of DIR, output absolute path instead of relative", "DIR"); + opts.optopt( + "d", + "", + "If any of FROM and TO is not subpath of DIR, output absolute path instead of relative", + "DIR", + ); let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(f) => { show_error!("{}", f); show_usage(&opts); - return 1 + return 1; } }; - if matches.opt_present("V") { version(); return 0 } - if matches.opt_present("h") { show_usage(&opts); return 0 } + if matches.opt_present("V") { + version(); + return 0; + } + if matches.opt_present("h") { + show_usage(&opts); + return 0; + } if matches.free.is_empty() { show_error!("Missing operand: TO"); println!("Try `{} --help` for more information.", NAME); - return 1 + return 1; } let to = Path::new(&matches.free[0]); @@ -58,9 +69,11 @@ pub fn uumain(args: Vec) -> i32 { if matches.opt_present("d") { let base = Path::new(&matches.opt_str("d").unwrap()).to_path_buf(); let absbase = canonicalize(base, CanonicalizeMode::Normal).unwrap(); - if !absto.as_path().starts_with(absbase.as_path()) || !absfrom.as_path().starts_with(absbase.as_path()) { + if !absto.as_path().starts_with(absbase.as_path()) + || !absfrom.as_path().starts_with(absbase.as_path()) + { println!("{}", absto.display()); - return 0 + return 0; } } @@ -74,8 +87,16 @@ pub fn uumain(args: Vec) -> i32 { } let mut result = PathBuf::new(); - absfrom.components().skip(suffix_pos).map(|_| result.push("..")).last(); - absto.components().skip(suffix_pos).map(|x| result.push(x.as_os_str())).last(); + absfrom + .components() + .skip(suffix_pos) + .map(|_| result.push("..")) + .last(); + absto + .components() + .skip(suffix_pos) + .map(|x| result.push(x.as_os_str())) + .last(); println!("{}", result.display()); 0 @@ -93,8 +114,11 @@ fn show_usage(opts: &getopts::Options) { println!(" {} -V|--version", NAME); println!(" {} -h|--help", NAME); println!(""); - print!("{}", opts.usage( + print!( + "{}", + opts.usage( "Convert TO destination to the relative path from the FROM dir.\n\ - If FROM path is omitted, current working dir will be used.") + If FROM path is omitted, current working dir will be used." + ) ); } diff --git a/src/rm/rm.rs b/src/rm/rm.rs index b4072b790..3664b75f9 100644 --- a/src/rm/rm.rs +++ b/src/rm/rm.rs @@ -18,7 +18,7 @@ extern crate uucore; use std::collections::VecDeque; use std::fs; -use std::io::{stdin, stderr, BufRead, Write}; +use std::io::{stderr, stdin, BufRead, Write}; use std::ops::BitOr; use std::path::Path; use remove_dir_all::remove_dir_all; @@ -28,7 +28,7 @@ use walkdir::{DirEntry, WalkDir}; enum InteractiveMode { InteractiveNone, InteractiveOnce, - InteractiveAlways + InteractiveAlways, } struct Options { @@ -39,7 +39,7 @@ struct Options { preserve_root: bool, recursive: bool, dir: bool, - verbose: bool + verbose: bool, } static NAME: &'static str = "rm"; @@ -49,14 +49,27 @@ pub fn uumain(args: Vec) -> i32 { // TODO: make getopts support -R in addition to -r let mut opts = getopts::Options::new(); - opts.optflag("f", "force", "ignore nonexistent files and arguments, never prompt"); + opts.optflag( + "f", + "force", + "ignore nonexistent files and arguments, never prompt", + ); opts.optflag("i", "", "prompt before every removal"); opts.optflag("I", "", "prompt once before removing more than three files, or when removing recursively. Less intrusive than -i, while still giving some protection against most mistakes"); - opts.optflagopt("", "interactive", "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always", "WHEN"); + opts.optflagopt( + "", + "interactive", + "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always", + "WHEN", + ); opts.optflag("", "one-file-system", "when removing a hierarchy recursively, skip any directory that is on a file system different from that of the corresponding command line argument (NOT IMPLEMENTED)"); opts.optflag("", "no-preserve-root", "do not treat '/' specially"); opts.optflag("", "preserve-root", "do not remove '/' (default)"); - opts.optflag("r", "recursive", "remove directories and their contents recursively"); + opts.optflag( + "r", + "recursive", + "remove directories and their contents recursively", + ); opts.optflag("d", "dir", "remove empty directories"); opts.optflag("v", "verbose", "explain what is being done"); opts.optflag("h", "help", "display this help and exit"); @@ -64,7 +77,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; let force = matches.opt_present("force"); @@ -107,9 +120,7 @@ pub fn uumain(args: Vec) -> i32 { "none" => InteractiveMode::InteractiveNone, "once" => InteractiveMode::InteractiveOnce, "always" => InteractiveMode::InteractiveAlways, - val => { - crash!(1, "Invalid argument to interactive ({})", val) - } + val => crash!(1, "Invalid argument to interactive ({})", val), } } else { InteractiveMode::InteractiveNone @@ -119,16 +130,16 @@ pub fn uumain(args: Vec) -> i32 { preserve_root: !matches.opt_present("no-preserve-root"), recursive: matches.opt_present("recursive"), dir: matches.opt_present("dir"), - verbose: matches.opt_present("verbose") + verbose: matches.opt_present("verbose"), }; if options.interactive == InteractiveMode::InteractiveOnce - && (options.recursive || matches.free.len() > 3) { - let msg = - if options.recursive { - "Remove all arguments recursively? " - } else { - "Remove all arguments? " - }; + && (options.recursive || matches.free.len() > 3) + { + let msg = if options.recursive { + "Remove all arguments recursively? " + } else { + "Remove all arguments? " + }; if !prompt(msg) { return 0; } @@ -217,8 +228,10 @@ fn handle_dir(path: &Path, options: &Options) -> bool { show_error!("could not remove directory '{}'", path.display()); had_err = true; } else { - show_error!("could not remove directory '{}' (did you mean to pass '-r'?)", - path.display()); + show_error!( + "could not remove directory '{}' (did you mean to pass '-r'?)", + path.display() + ); had_err = true; } } @@ -227,15 +240,16 @@ fn handle_dir(path: &Path, options: &Options) -> bool { } fn remove_dir(path: &Path, options: &Options) -> bool { - let response = - if options.interactive == InteractiveMode::InteractiveAlways { - prompt_file(path, true) - } else { - true - }; + let response = if options.interactive == InteractiveMode::InteractiveAlways { + prompt_file(path, true) + } else { + true + }; if response { match fs::remove_dir(path) { - Ok(_) => if options.verbose { println!("removed '{}'", path.display()); }, + Ok(_) => if options.verbose { + println!("removed '{}'", path.display()); + }, Err(e) => { show_error!("removing '{}': {}", path.display(), e); return true; @@ -247,15 +261,16 @@ fn remove_dir(path: &Path, options: &Options) -> bool { } fn remove_file(path: &Path, options: &Options) -> bool { - let response = - if options.interactive == InteractiveMode::InteractiveAlways { - prompt_file(path, false) - } else { - true - }; + let response = if options.interactive == InteractiveMode::InteractiveAlways { + prompt_file(path, false) + } else { + true + }; if response { match fs::remove_file(path) { - Ok(_) => if options.verbose { println!("removed '{}'", path.display()); }, + Ok(_) => if options.verbose { + println!("removed '{}'", path.display()); + }, Err(e) => { show_error!("removing '{}': {}", path.display(), e); return true; @@ -283,12 +298,10 @@ fn prompt(msg: &str) -> bool { let mut stdin = stdin.lock(); match stdin.read_until('\n' as u8, &mut buf) { - Ok(x) if x > 0 => { - match buf[0] { - b'y' | b'Y' => true, - _ => false, - } - } + Ok(x) if x > 0 => match buf[0] { + b'y' | b'Y' => true, + _ => false, + }, _ => false, } } diff --git a/src/rmdir/rmdir.rs b/src/rmdir/rmdir.rs index c1de9099e..21e514e1b 100644 --- a/src/rmdir/rmdir.rs +++ b/src/rmdir/rmdir.rs @@ -23,9 +23,17 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("", "ignore-fail-on-non-empty", "ignore each failure that is solely because a directory is non-empty"); + opts.optflag( + "", + "ignore-fail-on-non-empty", + "ignore each failure that is solely because a directory is non-empty", + ); opts.optflag("p", "parents", "remove DIRECTORY and its ancestors; e.g., 'rmdir -p a/b/c' is similar to rmdir a/b/c a/b a"); - opts.optflag("v", "verbose", "output a diagnostic for every directory processed"); + opts.optflag( + "v", + "verbose", + "output a diagnostic for every directory processed", + ); opts.optflag("h", "help", "print this help and exit"); opts.optflag("V", "version", "output version information and exit"); @@ -38,12 +46,15 @@ pub fn uumain(args: Vec) -> i32 { }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... DIRECTORY... -Remove the DIRECTORY(ies), if they are empty.", NAME, VERSION); +Remove the DIRECTORY(ies), if they are empty.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -57,7 +68,7 @@ Remove the DIRECTORY(ies), if they are empty.", NAME, VERSION); let verbose = matches.opt_present("verbose"); match remove(matches.free, ignore, parents, verbose) { Ok(()) => ( /* pass */ ), - Err(e) => return e + Err(e) => return e, } } @@ -105,7 +116,7 @@ fn remove_dir(path: &Path, ignore: bool, verbose: bool) -> Result<(), i32> { Err(e) => { show_error!("removing directory '{}': {}", path.display(), e); r = Err(1); - }, + } Ok(_) if verbose => println!("Removed directory '{}'", path.display()), _ => (), } diff --git a/src/seq/seq.rs b/src/seq/seq.rs index 8e83e3f62..48dec3796 100644 --- a/src/seq/seq.rs +++ b/src/seq/seq.rs @@ -9,7 +9,7 @@ extern crate getopts; extern crate uucore; use std::cmp; -use std::io::{Write, stdout}; +use std::io::{stdout, Write}; static NAME: &'static str = "seq"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); @@ -18,7 +18,7 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); struct SeqOptions { separator: String, terminator: Option, - widths: bool + widths: bool, } fn parse_float(mut s: &str) -> Result { @@ -27,17 +27,19 @@ fn parse_float(mut s: &str) -> Result { } match s.parse() { Ok(n) => Ok(n), - Err(e) => Err(format!("seq: invalid floating point argument `{}`: {}", s, e)) + Err(e) => Err(format!( + "seq: invalid floating point argument `{}`: {}", + s, e + )), } } fn escape_sequences(s: &str) -> String { - s.replace("\\n", "\n") - .replace("\\t", "\t") + s.replace("\\n", "\n").replace("\\t", "\t") } fn parse_options(args: Vec, options: &mut SeqOptions) -> Result, i32> { - let mut seq_args = vec!(); + let mut seq_args = vec![]; let mut iter = args.into_iter().skip(1); loop { match iter.next() { @@ -68,13 +70,19 @@ fn parse_options(args: Vec, options: &mut SeqOptions) -> Result { seq_args.extend(iter); break; - }, + } _ => { if arg.len() > 1 && arg.chars().next().unwrap() == '-' { - let argptr: *const String = &arg; // escape from the borrow checker + let argptr: *const String = &arg; // escape from the borrow checker let mut chiter = unsafe { &(*argptr)[..] }.chars().skip(1); let mut ch = ' '; - while match chiter.next() { Some(m) => { ch = m; true } None => false } { + while match chiter.next() { + Some(m) => { + ch = m; + true + } + None => false, + } { match ch { 'h' => { print_help(); @@ -89,7 +97,10 @@ fn parse_options(args: Vec, options: &mut SeqOptions) -> Result, options: &mut SeqOptions) -> Result, options: &mut SeqOptions) -> Result options.widths = true, - _ => { seq_args.push(arg); break } + _ => { + seq_args.push(arg); + break; + } } } } else { @@ -121,7 +138,7 @@ fn parse_options(args: Vec, options: &mut SeqOptions) -> Result break + None => break, } } Ok(seq_args) @@ -130,14 +147,31 @@ fn parse_options(args: Vec, options: &mut SeqOptions) -> Result) -> i32 { let mut options = SeqOptions { separator: "\n".to_owned(), terminator: None, - widths: false + widths: false, }; let free = match parse_options(args, &mut options) { Ok(m) => m, - Err(f) => return f + Err(f) => return f, }; if free.len() < 1 || free.len() > 3 { - crash!(1, "too {} operands.\nTry '{} --help' for more information.", - if free.len() < 1 { "few" } else { "many" }, NAME); + crash!( + 1, + "too {} operands.\nTry '{} --help' for more information.", + if free.len() < 1 { "few" } else { "many" }, + NAME + ); } let mut largest_dec = 0; let mut padding = 0; @@ -169,7 +207,10 @@ pub fn uumain(args: Vec) -> i32 { padding = dec; match parse_float(slice) { Ok(n) => n, - Err(s) => { show_error!("{}", s); return 1; } + Err(s) => { + show_error!("{}", s); + return 1; + } } } else { 1.0 @@ -182,7 +223,10 @@ pub fn uumain(args: Vec) -> i32 { padding = cmp::max(padding, dec); match parse_float(slice) { Ok(n) => n, - Err(s) => { show_error!("{}", s); return 1; } + Err(s) => { + show_error!("{}", s); + return 1; + } } } else { 1.0 @@ -192,7 +236,10 @@ pub fn uumain(args: Vec) -> i32 { padding = cmp::max(padding, slice.find('.').unwrap_or(slice.len())); match parse_float(slice) { Ok(n) => n, - Err(s) => { show_error!("{}", s); return 1; } + Err(s) => { + show_error!("{}", s); + return 1; + } } }; if largest_dec > 0 { @@ -201,9 +248,18 @@ pub fn uumain(args: Vec) -> i32 { let separator = escape_sequences(&options.separator[..]); let terminator = match options.terminator { Some(term) => escape_sequences(&term[..]), - None => separator.clone() + None => separator.clone(), }; - print_seq(first, step, last, largest_dec, separator, terminator, options.widths, padding); + print_seq( + first, + step, + last, + largest_dec, + separator, + terminator, + options.widths, + padding, + ); 0 } @@ -216,7 +272,16 @@ fn done_printing(next: f64, step: f64, last: f64) -> bool { } } -fn print_seq(first: f64, step: f64, last: f64, largest_dec: usize, separator: String, terminator: String, pad: bool, padding: usize) { +fn print_seq( + first: f64, + step: f64, + last: f64, + largest_dec: usize, + separator: String, + terminator: String, + pad: bool, + padding: usize, +) { let mut i = 0isize; let mut value = first + i as f64 * step; while !done_printing(value, step, last) { diff --git a/src/shred/shred.rs b/src/shred/shred.rs index 15d83f710..548d6ac87 100644 --- a/src/shred/shred.rs +++ b/src/shred/shred.rs @@ -13,7 +13,7 @@ extern crate getopts; extern crate rand; -use rand::{ThreadRng, Rng}; +use rand::{Rng, ThreadRng}; use std::cell::{Cell, RefCell}; use std::fs; use std::fs::{File, OpenOptions}; @@ -32,25 +32,41 @@ const NAMESET: &'static str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM // Patterns as shown in the GNU coreutils shred implementation const PATTERNS: [&'static [u8]; 22] = [ - b"\x00", b"\xFF", b"\x55", b"\xAA", - b"\x24\x92\x49", b"\x49\x24\x92", b"\x6D\xB6\xDB", b"\x92\x49\x24", - b"\xB6\xDB\x6D", b"\xDB\x6D\xB6", b"\x11", b"\x22", - b"\x33", b"\x44", b"\x66", b"\x77", - b"\x88", b"\x99", b"\xBB", b"\xCC", - b"\xDD", b"\xEE" + b"\x00", + b"\xFF", + b"\x55", + b"\xAA", + b"\x24\x92\x49", + b"\x49\x24\x92", + b"\x6D\xB6\xDB", + b"\x92\x49\x24", + b"\xB6\xDB\x6D", + b"\xDB\x6D\xB6", + b"\x11", + b"\x22", + b"\x33", + b"\x44", + b"\x66", + b"\x77", + b"\x88", + b"\x99", + b"\xBB", + b"\xCC", + b"\xDD", + b"\xEE", ]; #[derive(Clone, Copy)] enum PassType<'a> { Pattern(&'a [u8]), - Random + Random, } // Used to generate all possible filenames of a certain length using NAMESET as an alphabet struct FilenameGenerator { name_len: usize, nameset_indices: RefCell>, // Store the indices of the letters of our filename in NAMESET - exhausted: Cell + exhausted: Cell, } impl FilenameGenerator { @@ -62,28 +78,28 @@ impl FilenameGenerator { FilenameGenerator { name_len: name_len, nameset_indices: RefCell::new(indices), - exhausted: Cell::new(false) + exhausted: Cell::new(false), } } } impl Iterator for FilenameGenerator { type Item = String; - + fn next(&mut self) -> Option { if self.exhausted.get() { return None; } - + let mut nameset_indices = self.nameset_indices.borrow_mut(); - + // Make the return value, then increment let mut ret = String::new(); for i in nameset_indices.iter() { let c: char = NAMESET.chars().nth(*i).unwrap(); ret.push(c); } - + if nameset_indices[0] == NAMESET.len() - 1 { self.exhausted.set(true) } @@ -92,13 +108,12 @@ impl Iterator for FilenameGenerator { if nameset_indices[i] == NAMESET.len() - 1 { nameset_indices[i] = 0; // Carry the 1 continue; - } - else { + } else { nameset_indices[i] += 1; break; } } - + Some(ret) } } @@ -111,7 +126,7 @@ struct BytesGenerator<'a> { block_size: usize, exact: bool, // if false, every block's size is block_size gen_type: PassType<'a>, - rng: Option> + rng: Option>, } impl<'a> BytesGenerator<'a> { @@ -120,28 +135,28 @@ impl<'a> BytesGenerator<'a> { PassType::Random => Some(RefCell::new(rand::thread_rng())), _ => None, }; - + BytesGenerator { total_bytes: total_bytes, bytes_generated: Cell::new(0u64), block_size: BLOCK_SIZE, exact: exact, gen_type: gen_type, - rng: rng + rng: rng, } } } impl<'a> Iterator for BytesGenerator<'a> { type Item = Box<[u8]>; - + fn next(&mut self) -> Option> { // We go over the total_bytes limit when !self.exact and total_bytes isn't a multiple // of self.block_size if self.bytes_generated.get() >= self.total_bytes { return None; } - + let this_block_size: usize = { if !self.exact { self.block_size @@ -154,9 +169,9 @@ impl<'a> Iterator for BytesGenerator<'a> { } } }; - - let mut bytes : Vec = Vec::with_capacity(this_block_size); - + + let mut bytes: Vec = Vec::with_capacity(this_block_size); + match self.gen_type { PassType::Random => { // This is ok because the vector was @@ -170,9 +185,9 @@ impl<'a> Iterator for BytesGenerator<'a> { PassType::Pattern(pattern) => { let skip = { if self.bytes_generated.get() == 0 { - 0 + 0 } else { - (pattern.len() as u64 % self.bytes_generated.get()) as usize + (pattern.len() as u64 % self.bytes_generated.get()) as usize } }; // Same range as 0..this_block_size but we start with the right index @@ -182,7 +197,7 @@ impl<'a> Iterator for BytesGenerator<'a> { } } }; - + let new_bytes_generated = self.bytes_generated.get() + this_block_size as u64; self.bytes_generated.set(new_bytes_generated); @@ -194,19 +209,41 @@ pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); // TODO: Add force option - opts.optopt("n", "iterations", "overwrite N times instead of the default (3)", "N"); - opts.optopt("s", "size", "shred this many bytes (suffixes like K, M, G accepted)", "FILESIZE"); - opts.optflag("u", "remove", "truncate and remove the file after overwriting; See below"); + opts.optopt( + "n", + "iterations", + "overwrite N times instead of the default (3)", + "N", + ); + opts.optopt( + "s", + "size", + "shred this many bytes (suffixes like K, M, G accepted)", + "FILESIZE", + ); + opts.optflag( + "u", + "remove", + "truncate and remove the file after overwriting; See below", + ); opts.optflag("v", "verbose", "show progress"); - opts.optflag("x", "exact", "do not round file sizes up to the next full block; \ - this is the default for non-regular files"); - opts.optflag("z", "zero", "add a final overwrite with zeros to hide shredding"); + opts.optflag( + "x", + "exact", + "do not round file sizes up to the next full block; \ + this is the default for non-regular files", + ); + opts.optflag( + "z", + "zero", + "add a final overwrite with zeros to hide shredding", + ); opts.optflag("", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(e) => panic!("Invalid options\n{}", e) + Ok(m) => m, + Err(e) => panic!("Invalid options\n{}", e), }; if matches.opt_present("help") { @@ -222,13 +259,13 @@ pub fn uumain(args: Vec) -> i32 { } else { let iterations = match matches.opt_str("iterations") { Some(s) => match s.parse::() { - Ok(u) => u, - Err(_) => { - println!("{}: Invalid number of passes", NAME); - return 1; - } - }, - None => 3 + Ok(u) => u, + Err(_) => { + println!("{}: Invalid number of passes", NAME); + return 1; + } + }, + None => 3, }; let remove = matches.opt_present("remove"); let size = get_size(matches.opt_str("size")); @@ -236,8 +273,7 @@ pub fn uumain(args: Vec) -> i32 { let zero = matches.opt_present("zero"); let verbose = matches.opt_present("verbose"); for path_str in matches.free.into_iter() { - wipe_file(&path_str, iterations, remove, - size, exact, zero, verbose); + wipe_file(&path_str, iterations, remove, size, exact, zero, verbose); } } @@ -246,17 +282,25 @@ pub fn uumain(args: Vec) -> i32 { fn show_help(opts: &getopts::Options) { println!("Usage: {} [OPTION]... FILE...", NAME); - println!("Overwrite the specified FILE(s) repeatedly, in order to make it harder \ - for even very expensive hardware probing to recover the data."); + println!( + "Overwrite the specified FILE(s) repeatedly, in order to make it harder \ + for even very expensive hardware probing to recover the data." + ); println!("{}", opts.usage("")); println!("Delete FILE(s) if --remove (-u) is specified. The default is not to remove"); println!("the files because it is common to operate on device files like /dev/hda,"); println!("and those files usually should not be removed."); println!(""); - println!("CAUTION: Note that {} relies on a very important assumption:", NAME); + println!( + "CAUTION: Note that {} relies on a very important assumption:", + NAME + ); println!("that the file system overwrites data in place. This is the traditional"); println!("way to do things, but many modern file system designs do not satisfy this"); - println!("assumption. The following are examples of file systems on which {} is", NAME); + println!( + "assumption. The following are examples of file systems on which {} is", + NAME + ); println!("not effective, or is not guaranteed to be effective in all file system modes:"); println!(""); println!("* log-structured or journaled file systems, such as those supplied with"); @@ -273,9 +317,15 @@ fn show_help(opts: &getopts::Options) { println!("* compressed file systems"); println!(""); println!("In the case of ext3 file systems, the above disclaimer applies"); - println!("(and {} is thus of limited effectiveness) only in data=journal mode,", NAME); + println!( + "(and {} is thus of limited effectiveness) only in data=journal mode,", + NAME + ); println!("which journals file data in addition to just metadata. In both the"); - println!("data=ordered (default) and data=writeback modes, {} works as usual.", NAME); + println!( + "data=ordered (default) and data=writeback modes, {} works as usual.", + NAME + ); println!("Ext3 journaling modes can be changed by adding the data=something option"); println!("to the mount options for a particular file system in the /etc/fstab file,"); println!("as documented in the mount man page (man mount)."); @@ -291,16 +341,25 @@ fn get_size(size_str_opt: Option) -> Option { if size_str_opt.is_none() { return None; } - + let mut size_str = size_str_opt.as_ref().unwrap().clone(); // Immutably look at last character of size string let unit = match size_str.chars().last().unwrap() { - 'K' => { size_str.pop(); 1024u64 } - 'M' => { size_str.pop(); (1024 * 1024) as u64 } - 'G' => { size_str.pop(); (1024 * 1024 * 1024) as u64 } - _ => { 1u64 } + 'K' => { + size_str.pop(); + 1024u64 + } + 'M' => { + size_str.pop(); + (1024 * 1024) as u64 + } + 'G' => { + size_str.pop(); + (1024 * 1024 * 1024) as u64 + } + _ => 1u64, }; - + let coeff = match size_str.parse::() { Ok(u) => u, Err(_) => { @@ -308,7 +367,7 @@ fn get_size(size_str_opt: Option) -> Option { exit!(1); } }; - + Some(coeff * unit) } @@ -328,29 +387,40 @@ fn pass_name(pass_type: &PassType) -> String { } } -fn wipe_file(path_str: &str, n_passes: usize, remove: bool, - size: Option, exact: bool, zero: bool, verbose: bool) { - +fn wipe_file( + path_str: &str, + n_passes: usize, + remove: bool, + size: Option, + exact: bool, + zero: bool, + verbose: bool, +) { // Get these potential errors out of the way first let path: &Path = Path::new(path_str); if !path.exists() { - println!("{}: {}: No such file or directory", NAME, path.display()); return; + println!("{}: {}: No such file or directory", NAME, path.display()); + return; } if !path.is_file() { - println!("{}: {}: Not a file", NAME, path.display()); return; + println!("{}: {}: Not a file", NAME, path.display()); + return; } // Fill up our pass sequence let mut pass_sequence: Vec = Vec::new(); - - if n_passes <= 3 { // Only random passes if n_passes <= 3 - for _ in 0..n_passes { pass_sequence.push(PassType::Random) } + + if n_passes <= 3 { + // Only random passes if n_passes <= 3 + for _ in 0..n_passes { + pass_sequence.push(PassType::Random) + } } // First fill it with Patterns, shuffle it, then evenly distribute Random else { let n_full_arrays = n_passes / PATTERNS.len(); // How many times can we go through all the patterns? let remainder = n_passes % PATTERNS.len(); // How many do we get through on our last time through? - + for _ in 0..n_full_arrays { for p in &PATTERNS { pass_sequence.push(PassType::Pattern(*p)); @@ -360,14 +430,14 @@ fn wipe_file(path_str: &str, n_passes: usize, remove: bool, pass_sequence.push(PassType::Pattern(PATTERNS[i])); } rand::thread_rng().shuffle(&mut pass_sequence[..]); // randomize the order of application - - let n_random = 3 + n_passes/10; // Minimum 3 random passes; ratio of 10 after - // Evenly space random passes; ensures one at the beginning and end + + let n_random = 3 + n_passes / 10; // Minimum 3 random passes; ratio of 10 after + // Evenly space random passes; ensures one at the beginning and end for i in 0..n_random { - pass_sequence[i * (n_passes - 1)/(n_random - 1)] = PassType::Random; + pass_sequence[i * (n_passes - 1) / (n_random - 1)] = PassType::Random; } } - + // --zero specifies whether we want one final pass of 0x00 on our file if zero { pass_sequence.push(PassType::Pattern(b"\x00")); @@ -375,19 +445,33 @@ fn wipe_file(path_str: &str, n_passes: usize, remove: bool, { let total_passes: usize = pass_sequence.len(); - let mut file: File = OpenOptions::new().write(true) - .truncate(false) - .open(path) - .expect("Failed to open file for writing"); + let mut file: File = OpenOptions::new() + .write(true) + .truncate(false) + .open(path) + .expect("Failed to open file for writing"); for (i, pass_type) in pass_sequence.iter().enumerate() { if verbose { let pass_name: String = pass_name(pass_type); if total_passes.to_string().len() == 1 { - println!("{}: {}: pass {}/{} ({})... ", NAME, path.display(), i + 1, total_passes, pass_name); - } - else { - println!("{}: {}: pass {:2.0}/{:2.0} ({})... ", NAME, path.display(), i + 1, total_passes, pass_name); + println!( + "{}: {}: pass {}/{} ({})... ", + NAME, + path.display(), + i + 1, + total_passes, + pass_name + ); + } else { + println!( + "{}: {}: pass {:2.0}/{:2.0} ({})... ", + NAME, + path.display(), + i + 1, + total_passes, + pass_name + ); } } // size is an optional argument for exactly how many bytes we want to shred @@ -400,9 +484,13 @@ fn wipe_file(path_str: &str, n_passes: usize, remove: bool, } } -fn do_pass(file: &mut File, path: &Path, generator_type: PassType, - given_file_size: Option, exact: bool) -> Result<(), io::Error> { - +fn do_pass( + file: &mut File, + path: &Path, + generator_type: PassType, + given_file_size: Option, + exact: bool, +) -> Result<(), io::Error> { try!(file.seek(SeekFrom::Start(0))); // Use the given size or the whole file if not specified @@ -429,9 +517,9 @@ fn get_file_size(path: &Path) -> Result { // Return the path of the file after its last renaming or None if error fn wipe_name(orig_path: &Path, verbose: bool) -> Option { let file_name_len: usize = orig_path.file_name().unwrap().to_str().unwrap().len(); - + let mut last_path: PathBuf = PathBuf::from(orig_path); - + for length in (1..file_name_len + 1).rev() { for name in FilenameGenerator::new(length) { let new_path: PathBuf = orig_path.with_file_name(name); @@ -443,14 +531,18 @@ fn wipe_name(orig_path: &Path, verbose: bool) -> Option { match fs::rename(&last_path, &new_path) { Ok(()) => { if verbose { - println!("{}: {}: renamed to {}", NAME, - last_path.display(), - new_path.display()); + println!( + "{}: {}: renamed to {}", + NAME, + last_path.display(), + new_path.display() + ); } - + // Sync every file rename { - let new_file: File = File::open(new_path.clone()).expect("Failed to open renamed file for syncing"); + let new_file: File = File::open(new_path.clone()) + .expect("Failed to open renamed file for syncing"); new_file.sync_all().expect("Failed to sync renamed file"); } @@ -458,10 +550,13 @@ fn wipe_name(orig_path: &Path, verbose: bool) -> Option { break; } Err(e) => { - println!("{}: {}: Couldn't rename to {}: {}", NAME, - last_path.display(), - new_path.display(), - e); + println!( + "{}: {}: Couldn't rename to {}: {}", + NAME, + last_path.display(), + new_path.display(), + e + ); return None; } } @@ -480,8 +575,8 @@ fn do_remove(path: &Path, orig_filename: &str, verbose: bool) -> Result<(), io:: match renamed_path { Some(rp) => { try!(fs::remove_file(rp)); - }, - None => () + } + None => (), } if verbose { diff --git a/src/shuf/shuf.rs b/src/shuf/shuf.rs index 60d42ac27..1ac2745ee 100644 --- a/src/shuf/shuf.rs +++ b/src/shuf/shuf.rs @@ -23,7 +23,7 @@ use std::usize::MAX as MAX_USIZE; enum Mode { Default, Echo, - InputRange((usize, usize)) + InputRange((usize, usize)), } static NAME: &'static str = "shuf"; @@ -32,9 +32,19 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); opts.optflag("e", "echo", "treat each ARG as an input line"); - opts.optopt("i", "input-range", "treat each number LO through HI as an input line", "LO-HI"); + opts.optopt( + "i", + "input-range", + "treat each number LO through HI as an input line", + "LO-HI", + ); opts.optopt("n", "head-count", "output at most COUNT lines", "COUNT"); - opts.optopt("o", "output", "write result to FILE instead of standard output", "FILE"); + opts.optopt( + "o", + "output", + "write result to FILE instead of standard output", + "FILE", + ); opts.optopt("", "random-source", "get random bytes from FILE", "FILE"); opts.optflag("r", "repeat", "output lines can be repeated"); opts.optflag("z", "zero-terminated", "end lines with 0 byte, not newline"); @@ -42,12 +52,11 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("V", "version", "output version information and exit"); let mut matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => { - crash!(1, "{}", f) - } + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... [FILE] @@ -55,7 +64,9 @@ Usage: {0} -i LO-HI [OPTION]... Write a random permutation of the input lines to standard output. -With no FILE, or when FILE is -, read standard input.", NAME, VERSION); +With no FILE, or when FILE is -, read standard input.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -71,7 +82,7 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); Ok(m) => Mode::InputRange(m), Err(msg) => { crash!(1, "{}", msg); - }, + } } } None => { @@ -109,18 +120,22 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); match mode { Mode::Echo => { // XXX: this doesn't correctly handle non-UTF-8 cmdline args - let mut evec = matches.free.iter().map(|a| a.as_bytes()).collect::>(); + let mut evec = matches + .free + .iter() + .map(|a| a.as_bytes()) + .collect::>(); find_seps(&mut evec, sep); shuf_bytes(&mut evec, repeat, count, sep, output, random); - }, + } Mode::InputRange((b, e)) => { let rvec = (b..e).map(|x| format!("{}", x)).collect::>(); let mut rvec = rvec.iter().map(|a| a.as_bytes()).collect::>(); shuf_bytes(&mut rvec, repeat, count, sep, output, random); - }, + } Mode::Default => { let fdata = read_input_file(&matches.free[0][..]); - let mut fdata = vec!(&fdata[..]); + let mut fdata = vec![&fdata[..]]; find_seps(&mut fdata, sep); shuf_bytes(&mut fdata, repeat, count, sep, output, random); } @@ -131,15 +146,14 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); } fn read_input_file(filename: &str) -> Vec { - let mut file = BufReader::new( - if filename == "-" { - Box::new(stdin()) as Box - } else { - match File::open(filename) { - Ok(f) => Box::new(f) as Box, - Err(e) => crash!(1, "failed to open '{}': {}", filename, e), - } - }); + let mut file = BufReader::new(if filename == "-" { + Box::new(stdin()) as Box + } else { + match File::open(filename) { + Ok(f) => Box::new(f) as Box, + Err(e) => crash!(1, "failed to open '{}': {}", filename, e), + } + }); let mut data = Vec::new(); match file.read_to_end(&mut data) { @@ -183,15 +197,21 @@ fn find_seps(data: &mut Vec<&[u8]>, sep: u8) { } } -fn shuf_bytes(input: &mut Vec<&[u8]>, repeat: bool, count: usize, sep: u8, output: Option, random: Option) { - let mut output = BufWriter::new( - match output { - None => Box::new(stdout()) as Box, - Some(s) => match File::create(&s[..]) { - Ok(f) => Box::new(f) as Box, - Err(e) => crash!(1, "failed to open '{}' for writing: {}", &s[..], e), - }, - }); +fn shuf_bytes( + input: &mut Vec<&[u8]>, + repeat: bool, + count: usize, + sep: u8, + output: Option, + random: Option, +) { + let mut output = BufWriter::new(match output { + None => Box::new(stdout()) as Box, + Some(s) => match File::create(&s[..]) { + Ok(f) => Box::new(f) as Box, + Err(e) => crash!(1, "failed to open '{}' for writing: {}", &s[..], e), + }, + }); let mut rng = match random { Some(r) => WrappedRng::RngFile(rand::read::ReadRng::new(match File::open(&r[..]) { @@ -218,8 +238,12 @@ fn shuf_bytes(input: &mut Vec<&[u8]>, repeat: bool, count: usize, sep: u8, outpu } // write the randomly chosen value and the separator - output.write_all(input[r]).unwrap_or_else(|e| crash!(1, "write failed: {}", e)); - output.write_all(&[sep]).unwrap_or_else(|e| crash!(1, "write failed: {}", e)); + output + .write_all(input[r]) + .unwrap_or_else(|e| crash!(1, "write failed: {}", e)); + output + .write_all(&[sep]) + .unwrap_or_else(|e| crash!(1, "write failed: {}", e)); // if we do not allow repeats, remove the chosen value from the input vector if !repeat { @@ -241,11 +265,11 @@ fn parse_range(input_range: String) -> Result<(usize, usize), String> { } else { let begin = match split[0].parse::() { Ok(m) => m, - Err(e)=> return Err(format!("{} is not a valid number: {}", split[0], e)), + Err(e) => return Err(format!("{} is not a valid number: {}", split[0], e)), }; let end = match split[1].parse::() { Ok(m) => m, - Err(e)=> return Err(format!("{} is not a valid number: {}", split[1], e)), + Err(e) => return Err(format!("{} is not a valid number: {}", split[1], e)), }; Ok((begin, end + 1)) } diff --git a/src/sleep/sleep.rs b/src/sleep/sleep.rs index 113ea44a0..cda34e6b5 100644 --- a/src/sleep/sleep.rs +++ b/src/sleep/sleep.rs @@ -33,7 +33,8 @@ pub fn uumain(args: Vec) -> i32 { }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} NUMBER[SUFFIX] @@ -44,7 +45,9 @@ Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementations that require NUMBER be an integer, here NUMBER may be an arbitrary floating point number. Given two or more arguments, pause for the amount of time -specified by the sum of their values.", NAME, VERSION); +specified by the sum of their values.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -60,11 +63,12 @@ specified by the sum of their values.", NAME, VERSION); } fn sleep(args: Vec) { - let sleep_dur = args.iter().fold(Duration::new(0, 0), |result, arg| + let sleep_dur = args.iter().fold(Duration::new(0, 0), |result, arg| { match uucore::parse_time::from_str(&arg[..]) { Ok(m) => m + result, Err(f) => crash!(1, "{}", f), - }); + } + }); thread::sleep(sleep_dur); } diff --git a/src/sort/sort.rs b/src/sort/sort.rs index 39245ae34..9c25af938 100644 --- a/src/sort/sort.rs +++ b/src/sort/sort.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_sort"] - /* * This file is part of the uutils coreutils package. * @@ -8,20 +7,19 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - #![allow(dead_code)] extern crate getopts; extern crate semver; +extern crate itertools; #[macro_use] extern crate uucore; -extern crate itertools; use std::cmp::Ordering; use std::collections::BinaryHeap; use std::fs::File; -use std::io::{BufRead, BufReader, BufWriter, Lines, Read, stdin, stdout, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Lines, Read, Write}; use std::mem::replace; use std::path::Path; use uucore::fs::is_stdin_interactive; @@ -111,7 +109,7 @@ impl<'a> FileMerger<'a> { settings: settings, } } - fn push_file(&mut self, mut lines: Lines>>){ + fn push_file(&mut self, mut lines: Lines>>) { match lines.next() { Some(Ok(next_line)) => { let mergeable_file = MergeableFile { @@ -136,14 +134,14 @@ impl<'a> Iterator for FileMerger<'a> { let ret = replace(&mut current.current_line, next_line); self.heap.push(current); Some(ret) - }, + } _ => { // Don't put it back in the heap (it's empty/erroring) // but its first line is still valid. Some(current.current_line) - }, + } } - }, + } None => None, } } @@ -153,26 +151,56 @@ pub fn uumain(args: Vec) -> i32 { let mut settings: Settings = Default::default(); let mut opts = getopts::Options::new(); - opts.optflag("f", "ignore-case", "fold lower case to upper case characters"); - opts.optflag("n", "numeric-sort", "compare according to string numerical value"); - opts.optflag("h", "human-numeric-sort", "compare according to human readable sizes, eg 1M > 100k"); - opts.optflag("M", "month-sort", "compare according to month name abbreviation"); + opts.optflag( + "f", + "ignore-case", + "fold lower case to upper case characters", + ); + opts.optflag( + "n", + "numeric-sort", + "compare according to string numerical value", + ); + opts.optflag( + "h", + "human-numeric-sort", + "compare according to human readable sizes, eg 1M > 100k", + ); + opts.optflag( + "M", + "month-sort", + "compare according to month name abbreviation", + ); opts.optflag("r", "reverse", "reverse the output"); opts.optflag("h", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); opts.optflag("m", "merge", "merge already sorted files; do not sort"); - opts.optopt("o", "output", "write output to FILENAME instead of stdout", "FILENAME"); - opts.optflag("s", "stable", "stabilize sort by disabling last-resort comparison"); + opts.optopt( + "o", + "output", + "write output to FILENAME instead of stdout", + "FILENAME", + ); + opts.optflag( + "s", + "stable", + "stabilize sort by disabling last-resort comparison", + ); opts.optflag("u", "unique", "output only the first of an equal run"); - opts.optflag("V", "version-sort", "Sort by SemVer version number, eg 1.12.2 > 1.1.2"); + opts.optflag( + "V", + "version-sort", + "Sort by SemVer version number, eg 1.12.2 > 1.1.2", + ); opts.optflag("c", "check", "check for sorted input; do not sort"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f) + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... [FILE]... @@ -181,7 +209,9 @@ Write the sorted concatenation of all FILE(s) to standard output. Mandatory arguments for long options are mandatory for short options too. -With no FILE, or when FILE is -, read standard input.", NAME, VERSION); +With no FILE, or when FILE is -, read standard input.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); return 0; } @@ -215,10 +245,8 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); if files.is_empty() { /* if no file, default to stdin */ files.push("-".to_owned()); - } - else if settings.check && files.len() != 1 { + } else if settings.check && files.len() != 1 { crash!(1, "sort: extra operand `{}' not allowed with -c", files[1]) - } settings.compare_fns.push(match settings.mode { @@ -226,13 +254,13 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); SortMode::HumanNumeric => human_numeric_size_compare, SortMode::Month => month_compare, SortMode::Version => version_compare, - SortMode::Default => String::cmp + SortMode::Default => String::cmp, }); if !settings.stable { match settings.mode { SortMode::Default => {} - _ => settings.compare_fns.push(String::cmp) + _ => settings.compare_fns.push(String::cmp), } } @@ -253,16 +281,13 @@ fn exec(files: Vec, settings: &Settings) -> i32 { if settings.merge { file_merger.push_file(buf_reader.lines()); - } - else if settings.check { - return exec_check_file(buf_reader.lines(), &settings) - } - else { + } else if settings.check { + return exec_check_file(buf_reader.lines(), &settings); + } else { for line in buf_reader.lines() { if let Ok(n) = line { - lines.push(n); - } - else { + lines.push(n); + } else { break; } } @@ -274,22 +299,18 @@ fn exec(files: Vec, settings: &Settings) -> i32 { if settings.merge { if settings.unique { print_sorted(file_merger.dedup(), &settings.outfile) - } - else { + } else { print_sorted(file_merger, &settings.outfile) } - } - else { + } else { if settings.unique { print_sorted(lines.iter().dedup(), &settings.outfile) - } - else { + } else { print_sorted(lines.iter(), &settings.outfile) } } 0 - } fn exec_check_file(lines: Lines>>, settings: &Settings) -> i32 { @@ -298,42 +319,37 @@ fn exec_check_file(lines: Lines>>, settings: &Settings) -> i let unwrapped_lines = lines.filter_map(|maybe_line| { if let Ok(line) = maybe_line { Some(line) - } - else { + } else { None } }); - let mut errors = unwrapped_lines.enumerate().coalesce( - |(last_i, last_line), (i, line)| { + let mut errors = unwrapped_lines + .enumerate() + .coalesce(|(last_i, last_line), (i, line)| { if compare_by(&last_line, &line, &settings) == Ordering::Greater { Err(((last_i, last_line), (i, line))) - } - else { + } else { Ok((i, line)) } - }); + }); if let Some((first_error_index, _line)) = errors.next() { // Check for a second "error", as .coalesce() always returns the last // line, no matter what our merging function does. if let Some(_last_line_or_next_error) = errors.next() { println!("sort: disorder in line {}", first_error_index); return 1; - } - else { - // first "error" was actually the last line. + } else { + // first "error" was actually the last line. return 0; } - } - else { + } else { // unwrapped_lines was empty. Empty files are defined to be sorted. return 0; } } fn sort_by(lines: &mut Vec, settings: &Settings) { - lines.sort_by(|a, b| { - compare_by(a, b, &settings) - }) + lines.sort_by(|a, b| compare_by(a, b, &settings)) } fn compare_by(a: &String, b: &String, settings: &Settings) -> Ordering { @@ -352,8 +368,7 @@ fn compare_by(a: &String, b: &String, settings: &Settings) -> Ordering { if cmp != Ordering::Equal { if settings.reverse { return cmp.reverse(); - } - else { + } else { return cmp; } } @@ -370,7 +385,7 @@ fn permissive_f64_parse(a: &str) -> f64 { let sa: &str = a.split_whitespace().next().unwrap(); match sa.parse::() { Ok(a) => a, - Err(_) => std::f64::NEG_INFINITY + Err(_) => std::f64::NEG_INFINITY, } } @@ -384,11 +399,9 @@ fn numeric_compare(a: &String, b: &String) -> Ordering { // but we sidestep that with permissive_f64_parse so just fake it if fa > fb { Ordering::Greater - } - else if fa < fb { + } else if fa < fb { Ordering::Less - } - else { + } else { Ordering::Equal } } @@ -400,7 +413,7 @@ fn human_numeric_convert(a: &String) -> f64 { let suffix = suffix_iter.skip_while(|c| c.is_numeric()).next(); let int_part = match int_str.parse::() { Ok(i) => i, - Err(_) => -1f64 + Err(_) => -1f64, } as f64; let suffix: f64 = match suffix.unwrap_or('\0') { 'K' => 1000f64, @@ -408,7 +421,7 @@ fn human_numeric_convert(a: &String) -> f64 { 'G' => 1E9, 'T' => 1E12, 'P' => 1E15, - _ => 1f64 + _ => 1f64, }; int_part * suffix } @@ -420,11 +433,9 @@ fn human_numeric_size_compare(a: &String, b: &String) -> Ordering { let fb = human_numeric_convert(b); if fa > fb { Ordering::Greater - } - else if fa < fb { + } else if fa < fb { Ordering::Less - } - else { + } else { Ordering::Equal } } @@ -448,7 +459,12 @@ enum Month { /// Parse the beginning string into a Month, returning Month::Unknown on errors. fn month_parse(line: &String) -> Month { - match line.split_whitespace().next().unwrap().to_uppercase().as_ref() { + match line.split_whitespace() + .next() + .unwrap() + .to_uppercase() + .as_ref() + { "JAN" => Month::January, "FEB" => Month::February, "MAR" => Month::March, @@ -461,7 +477,7 @@ fn month_parse(line: &String) -> Month { "OCT" => Month::October, "NOV" => Month::November, "DEC" => Month::December, - _ => Month::Unknown, + _ => Month::Unknown, } } @@ -474,37 +490,35 @@ fn version_compare(a: &String, b: &String) -> Ordering { let ver_b = Version::parse(b); if ver_a > ver_b { Ordering::Greater - } - else if ver_a < ver_b { + } else if ver_a < ver_b { Ordering::Less - } - else { + } else { Ordering::Equal } } -fn print_sorted>(iter: T, outfile: &Option) where S: std::fmt::Display { +fn print_sorted>(iter: T, outfile: &Option) +where + S: std::fmt::Display, +{ let mut file: Box = match *outfile { - Some(ref filename) => { - match File::create(Path::new(&filename)) { - Ok(f) => Box::new(BufWriter::new(f)) as Box, - Err(e) => { - show_error!("sort: {0}: {1}", filename, e.to_string()); - panic!("Could not open output file"); - }, + Some(ref filename) => match File::create(Path::new(&filename)) { + Ok(f) => Box::new(BufWriter::new(f)) as Box, + Err(e) => { + show_error!("sort: {0}: {1}", filename, e.to_string()); + panic!("Could not open output file"); } }, None => Box::new(stdout()) as Box, }; - for line in iter { let str = format!("{}\n", line); match file.write_all(str.as_bytes()) { Err(e) => { show_error!("sort: {0}", e.to_string()); panic!("Write failed"); - }, + } Ok(_) => (), } } @@ -522,6 +536,6 @@ fn open(path: &str) -> Option<(Box, bool)> { Err(e) => { show_error!("sort: {0}: {1}", path, e.to_string()); None - }, + } } } diff --git a/src/split/split.rs b/src/split/split.rs index a652ada24..5025de6e9 100644 --- a/src/split/split.rs +++ b/src/split/split.rs @@ -16,7 +16,7 @@ extern crate uucore; use std::char; use std::fs::{File, OpenOptions}; -use std::io::{BufRead, BufReader, BufWriter, Read, stdin, stdout, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; use std::path::Path; static NAME: &'static str = "split"; @@ -25,31 +25,55 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optopt("a", "suffix-length", "use suffixes of length N (default 2)", "N"); + opts.optopt( + "a", + "suffix-length", + "use suffixes of length N (default 2)", + "N", + ); opts.optopt("b", "bytes", "put SIZE bytes per output file", "SIZE"); - opts.optopt("C", "line-bytes", "put at most SIZE bytes of lines per output file", "SIZE"); - opts.optflag("d", "numeric-suffixes", "use numeric suffixes instead of alphabetic"); + opts.optopt( + "C", + "line-bytes", + "put at most SIZE bytes of lines per output file", + "SIZE", + ); + opts.optflag( + "d", + "numeric-suffixes", + "use numeric suffixes instead of alphabetic", + ); opts.optopt("l", "lines", "put NUMBER lines per output file", "NUMBER"); - opts.optflag("", "verbose", "print a diagnostic just before each output file is opened"); + opts.optflag( + "", + "verbose", + "print a diagnostic just before each output file is opened", + ); opts.optflag("h", "help", "display help and exit"); opts.optflag("V", "version", "output version information and exit"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("h") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... [INPUT [PREFIX]] Output fixed-size pieces of INPUT to PREFIXaa, PREFIX ab, ...; default size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is --, read standard input.", NAME, VERSION); +-, read standard input.", + NAME, VERSION + ); - println!("{}\nSIZE may have a multiplier suffix: b for 512, k for 1K, m for 1 Meg.", opts.usage(&msg)); + println!( + "{}\nSIZE may have a multiplier suffix: b for 512, k for 1K, m for 1 Meg.", + opts.usage(&msg) + ); return 0; } @@ -73,9 +97,9 @@ size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is settings.suffix_length = match matches.opt_str("a") { Some(n) => match n.parse() { Ok(m) => m, - Err(e) => crash!(1, "cannot parse num: {}", e) + Err(e) => crash!(1, "cannot parse num: {}", e), }, - None => 2 + None => 2, }; settings.verbose = matches.opt_present("verbose"); @@ -92,7 +116,7 @@ size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is } else { crash!(1, "{}: cannot split in more than one way", NAME) } - }, + } None => {} } } @@ -120,7 +144,7 @@ struct Settings { } struct SplitControl { - current_line: String, // Don't touch + current_line: String, // Don't touch request_new_file: bool, // Splitter implementation requests new file } @@ -138,14 +162,13 @@ impl LineSplitter { fn new(settings: &Settings) -> Box { let n = match settings.strategy_param.parse() { Ok(a) => a, - Err(e) => crash!(1, "invalid number of lines: {}", e) + Err(e) => crash!(1, "invalid number of lines: {}", e), }; Box::new(LineSplitter { saved_lines_to_write: n, lines_to_write: n, }) as Box } - } impl Splitter for LineSplitter { @@ -168,24 +191,29 @@ struct ByteSplitter { impl ByteSplitter { fn new(settings: &Settings) -> Box { - let mut strategy_param : Vec = settings.strategy_param.chars().collect(); + let mut strategy_param: Vec = settings.strategy_param.chars().collect(); let suffix = strategy_param.pop().unwrap(); let multiplier = match suffix { '0'...'9' => 1usize, 'b' => 512usize, 'k' => 1024usize, 'm' => 1024usize * 1024usize, - _ => crash!(1, "invalid number of bytes") + _ => crash!(1, "invalid number of bytes"), }; let n = if suffix.is_alphabetic() { - match strategy_param.iter().cloned().collect::().parse::() { + match strategy_param + .iter() + .cloned() + .collect::() + .parse::() + { Ok(a) => a, - Err(e) => crash!(1, "invalid number of bytes: {}", e) + Err(e) => crash!(1, "invalid number of bytes: {}", e), } } else { match settings.strategy_param.parse::() { Ok(a) => a, - Err(e) => crash!(1, "invalid number of bytes: {}", e) + Err(e) => crash!(1, "invalid number of bytes: {}", e), } }; Box::new(ByteSplitter { @@ -250,28 +278,29 @@ fn num_prefix(i: usize, width: usize) -> String { } fn split(settings: &Settings) -> i32 { - let mut reader = BufReader::new( - if settings.input == "-" { - Box::new(stdin()) as Box - } else { - let r = match File::open(Path::new(&settings.input)) { - Ok(a) => a, - Err(_) => crash!(1, "cannot open '{}' for reading: No such file or directory", settings.input) - }; - Box::new(r) as Box - } - ); - - let mut splitter: Box = - match settings.strategy.as_ref() { - "l" => LineSplitter::new(settings), - "b" | "C" => ByteSplitter::new(settings), - a => crash!(1, "strategy {} not supported", a) + let mut reader = BufReader::new(if settings.input == "-" { + Box::new(stdin()) as Box + } else { + let r = match File::open(Path::new(&settings.input)) { + Ok(a) => a, + Err(_) => crash!( + 1, + "cannot open '{}' for reading: No such file or directory", + settings.input + ), }; + Box::new(r) as Box + }); + + let mut splitter: Box = match settings.strategy.as_ref() { + "l" => LineSplitter::new(settings), + "b" | "C" => ByteSplitter::new(settings), + a => crash!(1, "strategy {} not supported", a), + }; let mut control = SplitControl { current_line: "".to_owned(), // Request new line - request_new_file: true, // Request new file + request_new_file: true, // Request new file }; let mut writer = BufWriter::new(Box::new(stdout()) as Box); @@ -286,17 +315,25 @@ fn split(settings: &Settings) -> i32 { if control.request_new_file { let mut filename = settings.prefix.clone(); - filename.push_str(if settings.numeric_suffix { - num_prefix(fileno, settings.suffix_length) - } else { - str_prefix(fileno, settings.suffix_length) - }.as_ref()); + filename.push_str( + if settings.numeric_suffix { + num_prefix(fileno, settings.suffix_length) + } else { + str_prefix(fileno, settings.suffix_length) + }.as_ref(), + ); if fileno != 0 { crash_if_err!(1, writer.flush()); } fileno += 1; - writer = BufWriter::new(Box::new(OpenOptions::new().write(true).create(true).open(Path::new(&filename)).unwrap()) as Box); + writer = BufWriter::new(Box::new( + OpenOptions::new() + .write(true) + .create(true) + .open(Path::new(&filename)) + .unwrap(), + ) as Box); control.request_new_file = false; if settings.verbose { println!("creating file '{}'", filename); diff --git a/src/stat/fsext.rs b/src/stat/fsext.rs index b7119f635..31ca7d4c9 100644 --- a/src/stat/fsext.rs +++ b/src/stat/fsext.rs @@ -10,9 +10,9 @@ pub use super::uucore::libc; extern crate time; use self::time::Timespec; -pub use libc::{S_IFMT, S_IFDIR, S_IFCHR, S_IFBLK, S_IFREG, S_IFIFO, S_IFLNK, S_IFSOCK, S_ISUID, S_ISGID, S_ISVTX, - S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, mode_t, c_int, - strerror}; +pub use libc::{c_int, mode_t, strerror, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, + S_IFREG, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, + S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR}; pub trait BirthTime { fn pretty_birth(&self) -> String; @@ -98,16 +98,8 @@ pub fn pretty_access(mode: mode_t) -> String { _ => '?', }); - result.push(if has!(mode, S_IRUSR) { - 'r' - } else { - '-' - }); - result.push(if has!(mode, S_IWUSR) { - 'w' - } else { - '-' - }); + result.push(if has!(mode, S_IRUSR) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWUSR) { 'w' } else { '-' }); result.push(if has!(mode, S_ISUID as mode_t) { if has!(mode, S_IXUSR) { 's' @@ -120,16 +112,8 @@ pub fn pretty_access(mode: mode_t) -> String { '-' }); - result.push(if has!(mode, S_IRGRP) { - 'r' - } else { - '-' - }); - result.push(if has!(mode, S_IWGRP) { - 'w' - } else { - '-' - }); + result.push(if has!(mode, S_IRGRP) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWGRP) { 'w' } else { '-' }); result.push(if has!(mode, S_ISGID as mode_t) { if has!(mode, S_IXGRP) { 's' @@ -142,16 +126,8 @@ pub fn pretty_access(mode: mode_t) -> String { '-' }); - result.push(if has!(mode, S_IROTH) { - 'r' - } else { - '-' - }); - result.push(if has!(mode, S_IWOTH) { - 'w' - } else { - '-' - }); + result.push(if has!(mode, S_IROTH) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWOTH) { 'w' } else { '-' }); result.push(if has!(mode, S_ISVTX as mode_t) { if has!(mode, S_IXOTH) { 't' @@ -268,7 +244,8 @@ impl FsMeta for Sstatfs { } pub fn statfs>(path: P) -> Result - where Vec: From

+where + Vec: From

, { match CString::new(path) { Ok(p) => { diff --git a/src/stat/stat.rs b/src/stat/stat.rs index 7acad72fe..482d0e21a 100644 --- a/src/stat/stat.rs +++ b/src/stat/stat.rs @@ -19,9 +19,9 @@ pub use fsext::*; extern crate uucore; use uucore::entries; -use std::{fs, iter, cmp}; +use std::{cmp, fs, iter}; use std::fs::File; -use std::io::{BufReader, BufRead}; +use std::io::{BufRead, BufReader}; use std::borrow::Cow; use std::os::unix::fs::{FileTypeExt, MetadataExt}; use std::path::Path; @@ -69,12 +69,12 @@ macro_rules! pad_and_print { ) } macro_rules! print_adjusted { - ($str: ident, $left: expr, $width: expr, $padding: expr) => ({ + ($str: ident, $left: expr, $width: expr, $padding: expr) => { let field_width = cmp::max($width, $str.len()); let mut result = String::with_capacity(field_width); pad_and_print!(result, $str, $left, field_width, $padding); - }); - ($str: ident, $left: expr, $need_prefix: expr, $prefix: expr, $width: expr, $padding: expr) => ({ + }; + ($str: ident, $left: expr, $need_prefix: expr, $prefix: expr, $width: expr, $padding: expr) => { let mut field_width = cmp::max($width, $str.len()); let mut result = String::with_capacity(field_width + $prefix.len()); if $need_prefix { @@ -82,7 +82,7 @@ macro_rules! print_adjusted { field_width -= $prefix.len(); } pad_and_print!(result, $str, $left, field_width, $padding); - }) + } } static NAME: &'static str = "stat"; @@ -119,13 +119,16 @@ pub enum Token { } pub trait ScanUtil { - fn scan_num(&self) -> Option<(F, usize)> where F: std::str::FromStr; + fn scan_num(&self) -> Option<(F, usize)> + where + F: std::str::FromStr; fn scan_char(&self, radix: u32) -> Option<(char, usize)>; } impl ScanUtil for str { fn scan_num(&self) -> Option<(F, usize)> - where F: std::str::FromStr + where + F: std::str::FromStr, { let mut chars = self.chars(); let mut i = 0; @@ -196,7 +199,6 @@ pub fn group_num<'a>(s: &'a str) -> Cow<'a, str> { res.into() } - pub struct Stater { follow: bool, showfs: bool, @@ -208,7 +210,6 @@ pub struct Stater { } fn print_it(arg: &str, otype: OutputType, flag: u8, width: usize, precision: i32) { - // If the precision is given as just '.', the precision is taken to be zero. // A negative precision is taken as if the precision were omitted. // This gives the minimum number of digits to appear for d, i, o, u, x, and X conversions, @@ -299,22 +300,26 @@ fn print_it(arg: &str, otype: OutputType, flag: u8, width: usize, precision: i32 OutputType::UnsignedOct => { let min_digits = cmp::max(precision, arg.len() as i32) as usize; let extended: Cow = extend_digits!(arg, min_digits); - print_adjusted!(extended, - left_align, - should_alter, - prefix, - width, - padding_char); + print_adjusted!( + extended, + left_align, + should_alter, + prefix, + width, + padding_char + ); } OutputType::UnsignedHex => { let min_digits = cmp::max(precision, arg.len() as i32) as usize; let extended: Cow = extend_digits!(arg, min_digits); - print_adjusted!(extended, - left_align, - should_alter, - prefix, - width, - padding_char); + print_adjusted!( + extended, + left_align, + should_alter, + prefix, + width, + padding_char + ); } _ => unreachable!(), } @@ -322,14 +327,12 @@ fn print_it(arg: &str, otype: OutputType, flag: u8, width: usize, precision: i32 impl Stater { pub fn generate_tokens(fmtstr: &str, use_printf: bool) -> Result, String> { - let mut tokens = Vec::new(); let bound = fmtstr.len(); let chars = fmtstr.chars().collect::>(); let mut i = 0_usize; while i < bound { - match chars[i] { '%' => { let old = i; @@ -398,7 +401,6 @@ impl Stater { precision: precision, format: chars[i], }) - } '\\' => { if !use_printf { @@ -468,18 +470,21 @@ impl Stater { } else { try!(Stater::generate_tokens(&fmtstr, use_printf)) }; - let default_dev_tokens = Stater::generate_tokens(&Stater::default_fmt(showfs, terse, true), use_printf) - .unwrap(); + let default_dev_tokens = + Stater::generate_tokens(&Stater::default_fmt(showfs, terse, true), use_printf).unwrap(); let mount_list = if showfs { // mount points aren't displayed when showing filesystem information None } else { - let reader = BufReader::new(File::open(MOUNT_INFO).expect(&format!("Failed to read {}", MOUNT_INFO))); - let mut mount_list = reader.lines() - .filter_map(|s| s.ok()) - .filter_map(|line| line.split_whitespace().nth(1).map(|s| s.to_owned())) - .collect::>(); + let reader = BufReader::new( + File::open(MOUNT_INFO).expect(&format!("Failed to read {}", MOUNT_INFO)), + ); + let mut mount_list = reader + .lines() + .filter_map(|s| s.ok()) + .filter_map(|line| line.split_whitespace().nth(1).map(|s| s.to_owned())) + .collect::>(); // Reverse sort. The longer comes first. mount_list.sort_by(|a, b| b.cmp(a)); Some(mount_list) @@ -520,7 +525,6 @@ impl Stater { } fn do_stat(&self, file: &str) -> i32 { - if !self.showfs { let result = if self.follow { fs::metadata(file) @@ -530,17 +534,22 @@ impl Stater { match result { Ok(meta) => { let ftype = meta.file_type(); - let tokens = if self.from_user || !(ftype.is_char_device() || ftype.is_block_device()) { - &self.default_tokens - } else { - &self.default_dev_tokens - }; + let tokens = + if self.from_user || !(ftype.is_char_device() || ftype.is_block_device()) { + &self.default_tokens + } else { + &self.default_dev_tokens + }; for t in tokens.into_iter() { match t { &Token::Char(c) => print!("{}", c), - &Token::Directive { flag, width, precision, format } => { - + &Token::Directive { + flag, + width, + precision, + format, + } => { let arg: String; let otype: OutputType; @@ -587,7 +596,8 @@ impl Stater { } // file type 'F' => { - arg = pretty_filetype(meta.mode() as mode_t, meta.len()).to_owned(); + arg = pretty_filetype(meta.mode() as mode_t, meta.len()) + .to_owned(); otype = OutputType::Str; } // group ID of owner @@ -597,7 +607,8 @@ impl Stater { } // group name of owner 'G' => { - arg = entries::gid2grp(meta.gid()).unwrap_or("UNKNOWN".to_owned()); + arg = entries::gid2grp(meta.gid()) + .unwrap_or("UNKNOWN".to_owned()); otype = OutputType::Str; } // number of hard links @@ -632,7 +643,11 @@ impl Stater { return 1; } }; - arg = format!("`{}' -> `{}'", file, dst.to_string_lossy()); + arg = format!( + "`{}' -> `{}'", + file, + dst.to_string_lossy() + ); } else { arg = format!("`{}'", file); } @@ -667,7 +682,8 @@ impl Stater { } // user name of owner 'U' => { - arg = entries::uid2usr(meta.uid()).unwrap_or("UNKNOWN".to_owned()); + arg = entries::uid2usr(meta.uid()) + .unwrap_or("UNKNOWN".to_owned()); otype = OutputType::Str; } @@ -737,8 +753,12 @@ impl Stater { for t in tokens.into_iter() { match t { &Token::Char(c) => print!("{}", c), - &Token::Directive { flag, width, precision, format } => { - + &Token::Directive { + flag, + width, + precision, + format, + } => { let arg: String; let otype: OutputType; match format { @@ -824,7 +844,6 @@ impl Stater { // taken from coreutils/src/stat.c fn default_fmt(showfs: bool, terse: bool, dev: bool) -> String { - // SELinux related format is *ignored* let mut fmtstr = String::with_capacity(36); @@ -832,9 +851,11 @@ impl Stater { if terse { fmtstr.push_str("%n %i %l %t %s %S %b %f %a %c %d\n"); } else { - fmtstr.push_str(" File: \"%n\"\n ID: %-8i Namelen: %-7l Type: %T\nBlock \ - size: %-10s Fundamental block size: %S\nBlocks: Total: %-10b \ - Free: %-10f Available: %a\nInodes: Total: %-10c Free: %d\n"); + fmtstr.push_str( + " File: \"%n\"\n ID: %-8i Namelen: %-7l Type: %T\nBlock \ + size: %-10s Fundamental block size: %S\nBlocks: Total: %-10b \ + Free: %-10f Available: %a\nInodes: Total: %-10c Free: %d\n", + ); } } else if terse { fmtstr.push_str("%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o\n"); @@ -859,16 +880,17 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("", "version", "output version information and exit"); opts.optflag("L", "dereference", "follow links"); - opts.optflag("f", - "file-system", - "display file system status instead of file status"); + opts.optflag( + "f", + "file-system", + "display file system status instead of file status", + ); opts.optflag("t", "terse", "print the information in terse form"); // Omit the unused description as they are too long opts.optopt("c", "format", "", "FORMAT"); opts.optopt("", "printf", "", "FORMAT"); - let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(f) => { @@ -903,7 +925,8 @@ fn version() -> i32 { } fn help() -> i32 { - let msg = format!(r#"Usage: {} [OPTION]... FILE... + let msg = format!( + r#"Usage: {} [OPTION]... FILE... Display file or file system status. Mandatory arguments to long options are mandatory for short options too. @@ -969,7 +992,8 @@ Valid format sequences for file systems: NOTE: your shell may have its own version of stat, which usually supersedes the version described here. Please refer to your shell's documentation for details about the options it supports."#, - NAME); + NAME + ); println!("{}", msg); 0 } diff --git a/src/stdbuf/build.rs b/src/stdbuf/build.rs index 3b15b75fd..c13d8bffc 100644 --- a/src/stdbuf/build.rs +++ b/src/stdbuf/build.rs @@ -22,7 +22,13 @@ fn main() { let profile = env::var("PROFILE").expect("Could not determine profile"); let out_dir = env::var("OUT_DIR").unwrap(); - let libstdbuf = format!("{}/../../{}/{}/deps/liblibstdbuf{}", manifest_dir, env::var("CARGO_TARGET_DIR").unwrap_or("target".to_string()), profile, platform::DYLIB_EXT); - + let libstdbuf = format!( + "{}/../../{}/{}/deps/liblibstdbuf{}", + manifest_dir, + env::var("CARGO_TARGET_DIR").unwrap_or("target".to_string()), + profile, + platform::DYLIB_EXT + ); + fs::copy(libstdbuf, Path::new(&out_dir).join("libstdbuf.so")).unwrap(); } diff --git a/src/stdbuf/libstdbuf/build.rs b/src/stdbuf/libstdbuf/build.rs index 9d9896f58..c4bb007b9 100644 --- a/src/stdbuf/libstdbuf/build.rs +++ b/src/stdbuf/libstdbuf/build.rs @@ -3,6 +3,5 @@ extern crate cpp_build; use cpp_build::Config; fn main() { - Config::new().pic(true) - .build("libstdbuf.rs"); + Config::new().pic(true).build("libstdbuf.rs"); } diff --git a/src/stdbuf/libstdbuf/libstdbuf.rs b/src/stdbuf/libstdbuf/libstdbuf.rs index 464731541..1e290d005 100644 --- a/src/stdbuf/libstdbuf/libstdbuf.rs +++ b/src/stdbuf/libstdbuf/libstdbuf.rs @@ -1,11 +1,11 @@ -extern crate libc; #[macro_use] extern crate cpp; +extern crate libc; #[macro_use] extern crate uucore; -use libc::{c_int, size_t, c_char, FILE, _IOFBF, _IONBF, _IOLBF}; +use libc::{c_char, c_int, size_t, FILE, _IOFBF, _IOLBF, _IONBF}; use std::env; use std::ptr; @@ -26,7 +26,7 @@ cpp!{{ } }} -extern { +extern "C" { fn __stdbuf_get_stdin() -> *mut FILE; fn __stdbuf_get_stdout() -> *mut FILE; fn __stdbuf_get_stderr() -> *mut FILE; @@ -39,7 +39,7 @@ fn set_buffer(stream: *mut FILE, value: &str) { input => { let buff_size: usize = match input.parse() { Ok(num) => num, - Err(e) => crash!(1, "incorrect size of buffer!: {}", e) + Err(e) => crash!(1, "incorrect size of buffer!: {}", e), }; (_IOFBF, buff_size as size_t) } diff --git a/src/stdbuf/stdbuf.rs b/src/stdbuf/stdbuf.rs index c6689ab09..77629522b 100644 --- a/src/stdbuf/stdbuf.rs +++ b/src/stdbuf/stdbuf.rs @@ -31,7 +31,7 @@ const STDBUF_INJECT: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), "/l enum BufferType { Default, Line, - Size(u64) + Size(u64), } struct ProgramOptions { @@ -42,13 +42,13 @@ struct ProgramOptions { enum ErrMsg { Retry, - Fatal + Fatal, } enum OkMsg { Buffering, Help, - Version + Version, } #[cfg(target_os = "linux")] @@ -71,20 +71,20 @@ fn print_version() { } fn print_usage(opts: &Options) { - let brief = - "Run COMMAND, with modified buffering operations for its standard streams\n \ - Mandatory arguments to long options are mandatory for short options too."; + let brief = "Run COMMAND, with modified buffering operations for its standard streams\n \ + Mandatory arguments to long options are mandatory for short options too."; let explanation = "If MODE is 'L' the corresponding stream will be line buffered.\n \ - This option is invalid with standard input.\n\n \ - If MODE is '0' the corresponding stream will be unbuffered.\n\n \ - Otherwise MODE is a number which may be followed by one of the following:\n\n \ - KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n \ - In this case the corresponding stream will be fully buffered with the buffer size set to MODE bytes.\n\n \ - NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does for e.g.) then that will override \ - corresponding settings changed by 'stdbuf'.\n \ - Also some filters (like 'dd' and 'cat' etc.) don't use streams for I/O, \ - and are thus unaffected by 'stdbuf' settings.\n"; + This option is invalid with standard input.\n\n \ + If MODE is '0' the corresponding stream will be unbuffered.\n\n \ + Otherwise MODE is a number which may be followed by one of the following:\n\n \ + KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n \ + In this case the corresponding stream will be fully buffered with the buffer size set to \ + MODE bytes.\n\n \ + NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does for e.g.) then \ + that will override corresponding settings changed by 'stdbuf'.\n \ + Also some filters (like 'dd' and 'cat' etc.) don't use streams for I/O, \ + and are thus unaffected by 'stdbuf' settings.\n"; println!("{} {}", NAME, VERSION); println!(""); println!("Usage: stdbuf OPTION... COMMAND"); @@ -139,24 +139,31 @@ fn check_option(matches: &Matches, name: &str, modified: &mut bool) -> Option { let size = match parse_size(x) { Some(m) => m, - None => { show_error!("Invalid mode {}", x); return None } + None => { + show_error!("Invalid mode {}", x); + return None; + } }; Some(BufferType::Size(size)) - }, + } } - }, + } None => Some(BufferType::Default), } } -fn parse_options(args: &[String], options: &mut ProgramOptions, optgrps: &Options) -> Result { +fn parse_options( + args: &[String], + options: &mut ProgramOptions, + optgrps: &Options, +) -> Result { let matches = match optgrps.parse(args) { Ok(m) => m, - Err(_) => return Err(ErrMsg::Retry) + Err(_) => return Err(ErrMsg::Retry), }; if matches.opt_present("help") { return Ok(OkMsg::Help); @@ -181,9 +188,13 @@ fn parse_options(args: &[String], options: &mut ProgramOptions, optgrps: &Option fn set_command_env(command: &mut Command, buffer_name: &str, buffer_type: BufferType) { match buffer_type { - BufferType::Size(m) => { command.env(buffer_name, m.to_string()); }, - BufferType::Line => { command.env(buffer_name, "L"); }, - BufferType::Default => {}, + BufferType::Size(m) => { + command.env(buffer_name, m.to_string()); + } + BufferType::Line => { + command.env(buffer_name, "L"); + } + BufferType::Default => {} } } @@ -193,62 +204,84 @@ fn get_preload_env(tmp_dir: &mut TempDir) -> io::Result<(String, PathBuf)> { let mut file = File::create(&inject_path)?; file.write_all(STDBUF_INJECT)?; - + Ok((preload.to_owned(), inject_path)) } pub fn uumain(args: Vec) -> i32 { let mut opts = Options::new(); - opts.optopt("i", "input", "adjust standard input stream buffering", "MODE"); - opts.optopt("o", "output", "adjust standard output stream buffering", "MODE"); - opts.optopt("e", "error", "adjust standard error stream buffering", "MODE"); + opts.optopt( + "i", + "input", + "adjust standard input stream buffering", + "MODE", + ); + opts.optopt( + "o", + "output", + "adjust standard output stream buffering", + "MODE", + ); + opts.optopt( + "e", + "error", + "adjust standard error stream buffering", + "MODE", + ); opts.optflag("", "help", "display this help and exit"); opts.optflag("", "version", "output version information and exit"); - let mut options = ProgramOptions {stdin: BufferType::Default, stdout: BufferType::Default, stderr: BufferType::Default}; + let mut options = ProgramOptions { + stdin: BufferType::Default, + stdout: BufferType::Default, + stderr: BufferType::Default, + }; let mut command_idx: i32 = -1; - for i in 1 .. args.len()+1 { - match parse_options(&args[1 .. i], &mut options, &opts) { + for i in 1..args.len() + 1 { + match parse_options(&args[1..i], &mut options, &opts) { Ok(OkMsg::Buffering) => { command_idx = (i as i32) - 1; break; - }, + } Ok(OkMsg::Help) => { print_usage(&opts); return 0; - }, + } Ok(OkMsg::Version) => { print_version(); return 0; - }, + } Err(ErrMsg::Fatal) => break, Err(ErrMsg::Retry) => continue, } - }; + } if command_idx == -1 { - crash!(125, "Invalid options\nTry 'stdbuf --help' for more information."); + crash!( + 125, + "Invalid options\nTry 'stdbuf --help' for more information." + ); } let command_name = &args[command_idx as usize]; let mut command = Command::new(command_name); - + let mut tmp_dir = return_if_err!(1, TempDir::new("stdbuf")); let (preload_env, libstdbuf) = return_if_err!(1, get_preload_env(&mut tmp_dir)); - command.args(&args[(command_idx as usize) + 1 ..]).env(preload_env, libstdbuf); + command + .args(&args[(command_idx as usize) + 1..]) + .env(preload_env, libstdbuf); set_command_env(&mut command, "_STDBUF_I", options.stdin); set_command_env(&mut command, "_STDBUF_O", options.stdout); set_command_env(&mut command, "_STDBUF_E", options.stderr); let mut process = match command.spawn() { Ok(p) => p, - Err(e) => crash!(1, "failed to execute process: {}", e) + Err(e) => crash!(1, "failed to execute process: {}", e), }; match process.wait() { - Ok(status) => { - match status.code() { - Some(i) => return i, - None => crash!(1, "process killed by signal {}", status.signal().unwrap()), - } + Ok(status) => match status.code() { + Some(i) => return i, + None => crash!(1, "process killed by signal {}", status.signal().unwrap()), }, - Err(e) => crash!(1, "{}", e) + Err(e) => crash!(1, "{}", e), }; } diff --git a/src/sum/sum.rs b/src/sum/sum.rs index 602fef6bb..445bf48d6 100644 --- a/src/sum/sum.rs +++ b/src/sum/sum.rs @@ -15,7 +15,7 @@ extern crate getopts; extern crate uucore; use std::fs::File; -use std::io::{Read, Result, stdin}; +use std::io::{stdin, Read, Result}; use std::path::Path; static NAME: &'static str = "sum"; @@ -33,7 +33,7 @@ fn bsd_sum(mut reader: Box) -> (usize, u16) { checksum = (checksum >> 1) + ((checksum & 1) << 15); checksum = checksum.wrapping_add(byte as u16); } - }, + } _ => break, } } @@ -53,7 +53,7 @@ fn sysv_sum(mut reader: Box) -> (usize, u16) { for &byte in buf[..n].iter() { ret = ret.wrapping_add(byte as u32); } - }, + } _ => break, } } @@ -84,17 +84,23 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f) + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... [FILE]... -Checksum and count the blocks in a file.", NAME, VERSION); - println!("{}\nWith no FILE, or when FILE is -, read standard input.", opts.usage(&msg)); +Checksum and count the blocks in a file.", + NAME, VERSION + ); + println!( + "{}\nWith no FILE, or when FILE is -, read standard input.", + opts.usage(&msg) + ); return 0; } if matches.opt_present("version") { @@ -119,7 +125,7 @@ Checksum and count the blocks in a file.", NAME, VERSION); for file in &files { let reader = match open(file) { Ok(f) => f, - _ => crash!(1, "unable to open file") + _ => crash!(1, "unable to open file"), }; let (blocks, sum) = if sysv { sysv_sum(reader) diff --git a/src/sync/sync.rs b/src/sync/sync.rs index 0457874d5..e1bbb2401 100644 --- a/src/sync/sync.rs +++ b/src/sync/sync.rs @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ - /* Last synced with: sync (GNU coreutils) 8.13 */ +/* Last synced with: sync (GNU coreutils) 8.13 */ extern crate getopts; extern crate libc; @@ -28,7 +28,7 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); mod platform { use super::libc; - extern { + extern "C" { fn sync() -> libc::c_void; } @@ -40,9 +40,9 @@ mod platform { #[cfg(windows)] mod platform { - extern crate winapi; extern crate kernel32; - use std::{mem}; + extern crate winapi; + use std::mem; use std::fs::OpenOptions; use std::os::windows::prelude::*; use uucore::wide::{FromWide, ToWide}; @@ -58,9 +58,15 @@ mod platform { let sliced_name = &name[..name.len() - 1]; // eliminate trailing backslash match OpenOptions::new().write(true).open(sliced_name) { Ok(file) => if kernel32::FlushFileBuffers(file.as_raw_handle()) == 0 { - crash!(kernel32::GetLastError() as i32, "failed to flush file buffer"); + crash!( + kernel32::GetLastError() as i32, + "failed to flush file buffer" + ); }, - Err(e) => crash!(e.raw_os_error().unwrap_or(1), "failed to create volume handle") + Err(e) => crash!( + e.raw_os_error().unwrap_or(1), + "failed to create volume handle" + ), } } } @@ -69,7 +75,10 @@ mod platform { let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized(); let handle = kernel32::FindFirstVolumeW(name.as_mut_ptr(), name.len() as minwindef::DWORD); if handle == handleapi::INVALID_HANDLE_VALUE { - crash!(kernel32::GetLastError() as i32, "failed to find first volume"); + crash!( + kernel32::GetLastError() as i32, + "failed to find first volume" + ); } (String::from_wide_null(&name), handle) } @@ -80,13 +89,16 @@ mod platform { loop { let mut name: [winnt::WCHAR; minwindef::MAX_PATH] = mem::uninitialized(); if kernel32::FindNextVolumeW( - next_volume_handle, name.as_mut_ptr(), name.len() as minwindef::DWORD - ) == 0 { + next_volume_handle, + name.as_mut_ptr(), + name.len() as minwindef::DWORD, + ) == 0 + { match kernel32::GetLastError() { winerror::ERROR_NO_MORE_FILES => { kernel32::FindVolumeClose(next_volume_handle); - return volumes - }, + return volumes; + } err => crash!(err as i32, "failed to find next volume"), } } else { @@ -111,18 +123,21 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("V", "version", "output version information and exit"); let matches = match opts.parse(&args[1..]) { - Ok(m) => { m } - _ => { help(&opts); return 1 } + Ok(m) => m, + _ => { + help(&opts); + return 1; + } }; if matches.opt_present("h") { help(&opts); - return 0 + return 0; } if matches.opt_present("V") { version(); - return 0 + return 0; } sync(); @@ -137,18 +152,19 @@ fn version() { } fn help(opts: &getopts::Options) { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION] -Force changed blocks to disk, update the super block.", NAME, VERSION); +Force changed blocks to disk, update the super block.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } fn sync() -> isize { - unsafe { - platform::do_sync() - } + unsafe { platform::do_sync() } } diff --git a/src/tac/tac.rs b/src/tac/tac.rs index 69d241891..6da33a82c 100644 --- a/src/tac/tac.rs +++ b/src/tac/tac.rs @@ -15,7 +15,7 @@ extern crate getopts; extern crate uucore; use std::fs::File; -use std::io::{BufReader, Read, stdin, stdout, Stdout, Write}; +use std::io::{stdin, stdout, BufReader, Read, Stdout, Write}; static NAME: &'static str = "tac"; static VERSION: &'static str = env!("CARGO_PKG_VERSION"); @@ -23,23 +23,39 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("b", "before", "attach the separator before instead of after"); - opts.optflag("r", "regex", "interpret the sequence as a regular expression (NOT IMPLEMENTED)"); - opts.optopt("s", "separator", "use STRING as the separator instead of newline", "STRING"); + opts.optflag( + "b", + "before", + "attach the separator before instead of after", + ); + opts.optflag( + "r", + "regex", + "interpret the sequence as a regular expression (NOT IMPLEMENTED)", + ); + opts.optopt( + "s", + "separator", + "use STRING as the separator instead of newline", + "STRING", + ); 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(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("help") { - let msg = format!("{0} {1} + let msg = format!( + "{0} {1} Usage: {0} [OPTION]... [FILE]... -Write each file to standard output, last line first.", NAME, VERSION); +Write each file to standard output, last line first.", + NAME, VERSION + ); print!("{}", opts.usage(&msg)); } else if matches.opt_present("version") { @@ -55,10 +71,10 @@ Write each file to standard output, last line first.", NAME, VERSION); m } } - None => "\n".to_owned() + None => "\n".to_owned(), }; let files = if matches.free.is_empty() { - vec!("-".to_owned()) + vec!["-".to_owned()] } else { matches.free }; @@ -74,25 +90,24 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { let slen = sbytes.len(); for filename in &filenames { - let mut file = BufReader::new( - if filename == "-" { - Box::new(stdin()) as Box - } else { - match File::open(filename) { - Ok(f) => Box::new(f) as Box, - Err(e) => { - show_warning!("failed to open '{}' for reading: {}", filename, e); - continue; - }, + let mut file = BufReader::new(if filename == "-" { + Box::new(stdin()) as Box + } else { + match File::open(filename) { + Ok(f) => Box::new(f) as Box, + Err(e) => { + show_warning!("failed to open '{}' for reading: {}", filename, e); + continue; } - }); + } + }); let mut data = Vec::new(); match file.read_to_end(&mut data) { Err(e) => { show_warning!("failed to read '{}': {}", filename, e); continue; - }, + } Ok(_) => (), }; @@ -104,7 +119,7 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { break; } - if &data[i..i+slen] == sbytes { + if &data[i..i + slen] == sbytes { offsets.push(i); i += slen; } else { @@ -123,10 +138,10 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { for off in offsets.iter().rev().skip(1) { // correctly handle case of no final separator in file if start && prev == data.len() { - show_line(&mut out, &[], &data[*off+slen..prev], before); + show_line(&mut out, &[], &data[*off + slen..prev], before); start = false; } else { - show_line(&mut out, sbytes, &data[*off+slen..prev], before); + show_line(&mut out, sbytes, &data[*off + slen..prev], before); } prev = *off; } @@ -136,12 +151,15 @@ fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { fn show_line(out: &mut Stdout, sep: &[u8], dat: &[u8], before: bool) { if before { - out.write_all(sep).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); + out.write_all(sep) + .unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); } - out.write_all(dat).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); + out.write_all(dat) + .unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); if !before { - out.write_all(sep).unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); + out.write_all(sep) + .unwrap_or_else(|e| crash!(1, "failed to write to stdout: {}", e)); } } diff --git a/src/tail/platform/mod.rs b/src/tail/platform/mod.rs index c043bafbe..98960049d 100644 --- a/src/tail/platform/mod.rs +++ b/src/tail/platform/mod.rs @@ -8,10 +8,10 @@ */ #[cfg(unix)] -pub use self::unix::{Pid, supports_pid_checks, ProcessChecker}; +pub use self::unix::{supports_pid_checks, Pid, ProcessChecker}; #[cfg(windows)] -pub use self::windows::{Pid, supports_pid_checks, ProcessChecker}; +pub use self::windows::{supports_pid_checks, Pid, ProcessChecker}; #[cfg(unix)] mod unix; diff --git a/src/tail/platform/unix.rs b/src/tail/platform/unix.rs index c54306da1..7f64207f4 100644 --- a/src/tail/platform/unix.rs +++ b/src/tail/platform/unix.rs @@ -13,7 +13,9 @@ use std::io::Error; pub type Pid = libc::pid_t; -pub struct ProcessChecker { pid: self::Pid } +pub struct ProcessChecker { + pid: self::Pid, +} impl ProcessChecker { pub fn new(process_id: self::Pid) -> ProcessChecker { @@ -22,21 +24,16 @@ impl ProcessChecker { // Borrowing mutably to be aligned with Windows implementation pub fn is_dead(&mut self) -> bool { - unsafe { - libc::kill(self.pid, 0) != 0 && get_errno() != libc::EPERM - } + unsafe { libc::kill(self.pid, 0) != 0 && get_errno() != libc::EPERM } } } impl Drop for ProcessChecker { - fn drop(&mut self) { - } + fn drop(&mut self) {} } pub fn supports_pid_checks(pid: self::Pid) -> bool { - unsafe { - !(libc::kill(pid, 0) != 0 && get_errno() == libc::ENOSYS) - } + unsafe { !(libc::kill(pid, 0) != 0 && get_errno() == libc::ENOSYS) } } #[inline] diff --git a/src/tail/platform/windows.rs b/src/tail/platform/windows.rs index 61338fd31..ebab7d32b 100644 --- a/src/tail/platform/windows.rs +++ b/src/tail/platform/windows.rs @@ -7,10 +7,10 @@ * file that was distributed with this source code. */ -extern crate winapi; extern crate kernel32; +extern crate winapi; -use self::kernel32::{OpenProcess, CloseHandle, WaitForSingleObject}; +use self::kernel32::{CloseHandle, OpenProcess, WaitForSingleObject}; use self::winapi::shared::minwindef::DWORD; use self::winapi::um::winbase::{WAIT_OBJECT_0, WAIT_FAILED}; use self::winapi::um::winnt::{HANDLE, SYNCHRONIZE}; @@ -19,17 +19,18 @@ pub type Pid = DWORD; pub struct ProcessChecker { dead: bool, - handle: HANDLE + handle: HANDLE, } impl ProcessChecker { pub fn new(process_id: self::Pid) -> ProcessChecker { #[allow(non_snake_case)] let FALSE = 0i32; - let h = unsafe { - OpenProcess(SYNCHRONIZE, FALSE, process_id as DWORD) - }; - ProcessChecker { dead: h.is_null(), handle: h } + let h = unsafe { OpenProcess(SYNCHRONIZE, FALSE, process_id as DWORD) }; + ProcessChecker { + dead: h.is_null(), + handle: h, + } } pub fn is_dead(&mut self) -> bool { diff --git a/src/tail/tail.rs b/src/tail/tail.rs index bb0f115ea..e26d94133 100755 --- a/src/tail/tail.rs +++ b/src/tail/tail.rs @@ -23,7 +23,7 @@ use std::collections::VecDeque; use std::error::Error; use std::fmt; use std::fs::File; -use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, stdin, stdout, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, Read, Seek, SeekFrom, Write}; use std::path::Path; use std::str::from_utf8; use std::thread::sleep; @@ -62,8 +62,11 @@ pub fn uumain(args: Vec) -> i32 { // handle obsolete -number syntax let options = match obsolete(&args[1..]) { - (args, Some(n)) => { settings.mode = FilterMode::Lines(n, '\n' as u8); args }, - (args, None) => args + (args, Some(n)) => { + settings.mode = FilterMode::Lines(n, '\n' as u8); + args + } + (args, None) => args, }; let args = options; @@ -73,8 +76,18 @@ pub fn uumain(args: Vec) -> i32 { opts.optopt("c", "bytes", "Number of bytes to print", "k"); opts.optopt("n", "lines", "Number of lines to print", "k"); opts.optflag("f", "follow", "Print the file as it grows"); - opts.optopt("s", "sleep-interval", "Number or seconds to sleep between polling the file when running with -f", "n"); - opts.optopt("", "pid", "with -f, terminate after process ID, PID dies", "PID"); + opts.optopt( + "s", + "sleep-interval", + "Number or seconds to sleep between polling the file when running with -f", + "n", + ); + opts.optopt( + "", + "pid", + "with -f, terminate after process ID, PID dies", + "PID", + ); opts.optflag("z", "zero-terminated", "Line delimiter is NUL, not newline"); opts.optflag("h", "help", "help"); opts.optflag("V", "version", "version"); @@ -83,7 +96,7 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("", "silent", "synonym of --quiet"); let given_options = match opts.parse(&args) { - Ok (m) => { m } + Ok(m) => m, Err(_) => { println!("{}", opts.usage("")); return 1; @@ -94,7 +107,10 @@ pub fn uumain(args: Vec) -> i32 { println!("{}", opts.usage("")); return 0; } - if given_options.opt_present("V") { version(); return 0 } + if given_options.opt_present("V") { + version(); + return 0; + } settings.follow = given_options.opt_present("f"); if settings.follow { @@ -102,7 +118,7 @@ pub fn uumain(args: Vec) -> i32 { Some(n) => { let parsed: Option = n.parse().ok(); match parsed { - Some(m) => { settings.sleep_msec = m * 1000 } + Some(m) => settings.sleep_msec = m * 1000, None => {} } } @@ -156,8 +172,8 @@ pub fn uumain(args: Vec) -> i32 { } } } - None => { } - } + None => {} + }, }; if given_options.opt_present("z") { @@ -181,7 +197,9 @@ pub fn uumain(args: Vec) -> i32 { for filename in &files { if (multiple || verbose) && !quiet { - if !first_header { println!(); } + if !first_header { + println!(); + } println!("==> {} <==", filename); } first_header = false; @@ -241,54 +259,54 @@ impl ParseSizeErr { } fn size_too_big(s: &str) -> ParseSizeErr { - ParseSizeErr::SizeTooBig( - format!("invalid size: '{}': Value too large to be stored in data type", s)) + ParseSizeErr::SizeTooBig(format!( + "invalid size: '{}': Value too large to be stored in data type", + s + )) } } pub type ParseSizeResult = Result; pub fn parse_size(mut size_slice: &str) -> Result { - let mut base = - if size_slice.chars().last().unwrap_or('_') == 'B' { - size_slice = &size_slice[..size_slice.len() - 1]; - 1000u64 - } else { - 1024u64 - }; + let mut base = if size_slice.chars().last().unwrap_or('_') == 'B' { + size_slice = &size_slice[..size_slice.len() - 1]; + 1000u64 + } else { + 1024u64 + }; - let exponent = - if size_slice.len() > 0 { - let mut has_suffix = true; - let exp = match size_slice.chars().last().unwrap_or('_') { - 'K' | 'k' => 1u64, - 'M' => 2u64, - 'G' => 3u64, - 'T' => 4u64, - 'P' => 5u64, - 'E' => 6u64, - 'Z' | 'Y' => { - return Err(ParseSizeErr::size_too_big(size_slice)); - }, - 'b' => { - base = 512u64; - 1u64 - } - _ => { - has_suffix = false; - 0u64 - } - }; - if has_suffix { - size_slice = &size_slice[..size_slice.len() - 1]; + let exponent = if size_slice.len() > 0 { + let mut has_suffix = true; + let exp = match size_slice.chars().last().unwrap_or('_') { + 'K' | 'k' => 1u64, + 'M' => 2u64, + 'G' => 3u64, + 'T' => 4u64, + 'P' => 5u64, + 'E' => 6u64, + 'Z' | 'Y' => { + return Err(ParseSizeErr::size_too_big(size_slice)); + } + 'b' => { + base = 512u64; + 1u64 + } + _ => { + has_suffix = false; + 0u64 } - exp - } else { - 0u64 }; + if has_suffix { + size_slice = &size_slice[..size_slice.len() - 1]; + } + exp + } else { + 0u64 + }; let mut multiplier = 1u64; - for _ in 0u64 .. exponent { + for _ in 0u64..exponent { multiplier *= base; } if base == 1000u64 && exponent == 0u64 { @@ -296,8 +314,9 @@ pub fn parse_size(mut size_slice: &str) -> Result { Err(ParseSizeErr::parse_failure(size_slice)) } else { let value: Option = size_slice.parse().ok(); - value.map(|v| Ok(multiplier * v)) - .unwrap_or(Err(ParseSizeErr::parse_failure(size_slice))) + value + .map(|v| Ok(multiplier * v)) + .unwrap_or(Err(ParseSizeErr::parse_failure(size_slice))) } } @@ -316,9 +335,11 @@ fn obsolete(options: &[String]) -> (Vec, Option) { if current.len() > 1 && current[0] == '-' as u8 { let len = current.len(); - for pos in 1 .. len { + for pos in 1..len { // Ensure that the argument is only made out of digits - if !(current[pos] as char).is_numeric() { break; } + if !(current[pos] as char).is_numeric() { + break; + } // If this is the last number if pos == len - 1 { @@ -330,7 +351,7 @@ fn obsolete(options: &[String]) -> (Vec, Option) { } a += 1; - }; + } (options, None) } @@ -346,7 +367,7 @@ fn follow(readers: &mut [BufReader], filenames: &[String], settings: let mut process = platform::ProcessChecker::new(settings.pid); loop { - sleep(Duration::new(0, settings.sleep_msec*1000)); + sleep(Duration::new(0, settings.sleep_msec * 1000)); let pid_is_dead = !read_some && settings.pid != 0 && process.is_dead(); read_some = false; @@ -364,8 +385,8 @@ fn follow(readers: &mut [BufReader], filenames: &[String], settings: last = i; } print!("{}", datum); - }, - Err(err) => panic!(err) + } + Err(err) => panic!(err), } } } @@ -379,8 +400,14 @@ fn follow(readers: &mut [BufReader], filenames: &[String], settings: /// Iterate over bytes in the file, in reverse, until `should_stop` returns /// true. The `file` is left seek'd to the position just after the byte that /// `should_stop` returned true for. -fn backwards_thru_file(mut file: &File, size: u64, buf: &mut Vec, delimiter: u8, should_stop: &mut F) - where F: FnMut(u8) -> bool +fn backwards_thru_file( + mut file: &File, + size: u64, + buf: &mut Vec, + delimiter: u8, + should_stop: &mut F, +) where + F: FnMut(u8) -> bool, { assert!(buf.len() >= BLOCK_SIZE as usize); @@ -437,10 +464,10 @@ fn bounded_tail(mut file: &File, settings: &Settings) { false } }); - }, + } FilterMode::Bytes(count) => { file.seek(SeekFrom::End(-(count as i64))).unwrap(); - }, + } } // Print the target section of the file. @@ -485,15 +512,15 @@ fn unbounded_tail(reader: &mut BufReader, settings: &Settings) { } ringbuf.push_back(datum); } - }, - Err(err) => panic!(err) + } + Err(err) => panic!(err), } } let mut stdout = stdout(); for datum in &ringbuf { print_string(&mut stdout, datum); } - }, + } FilterMode::Bytes(mut count) => { let mut ringbuf: VecDeque = VecDeque::new(); let mut skip = if settings.beginning { @@ -516,8 +543,8 @@ fn unbounded_tail(reader: &mut BufReader, settings: &Settings) { } ringbuf.push_back(datum[0]); } - }, - Err(err) => panic!(err) + } + Err(err) => panic!(err), } } let mut stdout = stdout(); diff --git a/src/tee/tee.rs b/src/tee/tee.rs index 8f5f9e2f3..3198334c1 100644 --- a/src/tee/tee.rs +++ b/src/tee/tee.rs @@ -14,7 +14,7 @@ extern crate getopts; extern crate uucore; use std::fs::OpenOptions; -use std::io::{copy, Error, ErrorKind, Read, Result, sink, stdin, stdout, Write}; +use std::io::{copy, sink, stdin, stdout, Error, ErrorKind, Read, Result, Write}; use std::path::{Path, PathBuf}; static NAME: &'static str = "tee"; @@ -23,7 +23,7 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub fn uumain(args: Vec) -> i32 { match options(&args).and_then(exec) { Ok(_) => 0, - Err(_) => 1 + Err(_) => 1, } } @@ -33,7 +33,7 @@ struct Options { append: bool, ignore_interrupts: bool, print_and_exit: Option, - files: Vec + files: Vec, } fn options(args: &[String]) -> Result { @@ -44,40 +44,59 @@ fn options(args: &[String]) -> Result { opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); - opts.parse(&args[1..]).map_err(|e| Error::new(ErrorKind::Other, format!("{}", e))).and_then(|m| { - let version = format!("{} {}", NAME, VERSION); - let arguments = "[OPTION]... [FILE]..."; - let brief = "Copy standard input to each FILE, and also to standard output."; - let comment = "If a FILE is -, copy again to standard output."; - let help = format!("{}\n\nUsage:\n {} {}\n\n{}\n{}", - version, NAME, arguments, opts.usage(brief), - comment); - let mut names: Vec = m.free.clone().into_iter().collect(); - names.push("-".to_owned()); - let to_print = if m.opt_present("help") { Some(help) } - else if m.opt_present("version") { Some(version) } - else { None }; - Ok(Options { - program: NAME.to_owned(), - append: m.opt_present("append"), - ignore_interrupts: m.opt_present("ignore-interrupts"), - print_and_exit: to_print, - files: names + opts.parse(&args[1..]) + .map_err(|e| Error::new(ErrorKind::Other, format!("{}", e))) + .and_then(|m| { + let version = format!("{} {}", NAME, VERSION); + let arguments = "[OPTION]... [FILE]..."; + let brief = "Copy standard input to each FILE, and also to standard output."; + let comment = "If a FILE is -, copy again to standard output."; + let help = format!( + "{}\n\nUsage:\n {} {}\n\n{}\n{}", + version, + NAME, + arguments, + opts.usage(brief), + comment + ); + let mut names: Vec = m.free.clone().into_iter().collect(); + names.push("-".to_owned()); + let to_print = if m.opt_present("help") { + Some(help) + } else if m.opt_present("version") { + Some(version) + } else { + None + }; + Ok(Options { + program: NAME.to_owned(), + append: m.opt_present("append"), + ignore_interrupts: m.opt_present("ignore-interrupts"), + print_and_exit: to_print, + files: names, + }) }) - }).map_err(|message| warn(format!("{}", message).as_ref())) + .map_err(|message| warn(format!("{}", message).as_ref())) } fn exec(options: Options) -> Result<()> { match options.print_and_exit { Some(text) => Ok(println!("{}", text)), - None => tee(options) + None => tee(options), } } fn tee(options: Options) -> Result<()> { - let writers: Vec> = options.files.clone().into_iter().map(|file| open(file, options.append)).collect(); + let writers: Vec> = options + .files + .clone() + .into_iter() + .map(|file| open(file, options.append)) + .collect(); let output = &mut MultiWriter { writers: writers }; - let input = &mut NamedReader { inner: Box::new(stdin()) as Box }; + let input = &mut NamedReader { + inner: Box::new(stdin()) as Box, + }; if copy(input, output).is_err() || output.flush().is_err() { Err(Error::new(ErrorKind::Other, "")) } else { @@ -92,17 +111,24 @@ fn open(name: String, append: bool) -> Box { Box::new(stdout()) } else { let mut options = OpenOptions::new(); - let mode = if append { options.append(true) } else { options.truncate(true) }; + let mode = if append { + options.append(true) + } else { + options.truncate(true) + }; match mode.write(true).create(true).open(path.as_path()) { Ok(file) => Box::new(file), - Err(_) => Box::new(sink()) + Err(_) => Box::new(sink()), } }; - Box::new(NamedWriter { inner: inner, path: path }) as Box + Box::new(NamedWriter { + inner: inner, + path: path, + }) as Box } struct MultiWriter { - writers: Vec> + writers: Vec>, } impl Write for MultiWriter { @@ -123,7 +149,7 @@ impl Write for MultiWriter { struct NamedWriter { inner: Box, - path: PathBuf + path: PathBuf, } impl Write for NamedWriter { @@ -134,7 +160,7 @@ impl Write for NamedWriter { warn(format!("{}: {}", self.path.display(), f.to_string()).as_ref()); Err(f) } - okay => okay + okay => okay, } } @@ -145,13 +171,13 @@ impl Write for NamedWriter { warn(format!("{}: {}", self.path.display(), f.to_string()).as_ref()); Err(f) } - okay => okay + okay => okay, } } } struct NamedReader { - inner: Box + inner: Box, } impl Read for NamedReader { @@ -161,7 +187,7 @@ impl Read for NamedReader { warn(format!("{}: {}", Path::new("stdin").display(), f.to_string()).as_ref()); Err(f) } - okay => okay + okay => okay, } } } diff --git a/src/test/test.rs b/src/test/test.rs index 6a3488627..888961893 100644 --- a/src/test/test.rs +++ b/src/test/test.rs @@ -13,8 +13,8 @@ extern crate libc; use std::collections::HashMap; use std::ffi::OsString; -use std::env::{args_os}; -use std::str::{from_utf8}; +use std::env::args_os; +use std::str::from_utf8; static NAME: &'static str = "test"; @@ -23,16 +23,17 @@ static NAME: &'static str = "test"; pub fn uumain(_: Vec) -> i32 { let args = args_os().collect::>(); // This is completely disregarding valid windows paths that aren't valid unicode - let args = args.iter().map(|a| a.to_str().unwrap().as_bytes()).collect::>(); + let args = args.iter() + .map(|a| a.to_str().unwrap().as_bytes()) + .collect::>(); if args.is_empty() { return 2; } - let args = - if !args[0].ends_with(NAME.as_bytes()) { - &args[1..] - } else { - &args[..] - }; + let args = if !args[0].ends_with(NAME.as_bytes()) { + &args[1..] + } else { + &args[..] + }; let args = match args[0] { b"[" => match args[args.len() - 1] { b"]" => &args[1..args.len() - 1], @@ -98,15 +99,13 @@ fn three(args: &[&[u8]], error: &mut bool) -> bool { *error = true; false } - } + }, } } fn four(args: &[&[u8]], error: &mut bool) -> bool { match args[0] { - b"!" => { - !three(&args[1..], error) - } + b"!" => !three(&args[1..], error), _ => { *error = true; false @@ -133,19 +132,21 @@ fn integers(a: &[u8], b: &[u8], cond: IntegerCondition) -> bool { _ => return false, }; match cond { - IntegerCondition::Equal => a == b, - IntegerCondition::Unequal => a != b, - IntegerCondition::Greater => a > b, + IntegerCondition::Equal => a == b, + IntegerCondition::Unequal => a != b, + IntegerCondition::Greater => a > b, IntegerCondition::GreaterEqual => a >= b, - IntegerCondition::Less => a < b, - IntegerCondition::LessEqual => a <= b, + IntegerCondition::Less => a < b, + IntegerCondition::LessEqual => a <= b, } } fn isatty(fd: &[u8]) -> bool { - use libc::{isatty}; - from_utf8(fd).ok().and_then(|s| s.parse().ok()) - .map_or(false, |i| unsafe { isatty(i) == 1 }) + use libc::isatty; + from_utf8(fd) + .ok() + .and_then(|s| s.parse().ok()) + .map_or(false, |i| unsafe { isatty(i) == 1 }) } fn dispatch(args: &mut &[&[u8]], error: &mut bool) -> bool { @@ -157,7 +158,7 @@ fn dispatch(args: &mut &[&[u8]], error: &mut bool) -> bool { 1 => (one(*args), 1), 2 => dispatch_two(args, error), 3 => dispatch_three(args, error), - _ => dispatch_four(args, error) + _ => dispatch_four(args, error), }; *args = &(*args)[idx..]; val @@ -196,12 +197,12 @@ fn dispatch_four(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) { #[derive(Clone, Copy)] enum Precedence { Unknown = 0, - Paren, // FIXME: this is useless (parentheses have not been implemented) + Paren, // FIXME: this is useless (parentheses have not been implemented) Or, And, BUnOp, BinOp, - UnOp + UnOp, } fn parse_expr(mut args: &[&[u8]], error: &mut bool) -> bool { @@ -219,11 +220,13 @@ fn parse_expr(mut args: &[&[u8]], error: &mut bool) -> bool { } } -fn parse_expr_helper<'a>(hashmap: &HashMap<&'a [u8], Precedence>, - args: &mut &[&'a [u8]], - mut lhs: bool, - min_prec: Precedence, - error: &mut bool) -> bool { +fn parse_expr_helper<'a>( + hashmap: &HashMap<&'a [u8], Precedence>, + args: &mut &[&'a [u8]], + mut lhs: bool, + min_prec: Precedence, + error: &mut bool, +) -> bool { let mut prec = *hashmap.get(&args[0]).unwrap_or_else(|| { *error = true; &min_prec @@ -249,9 +252,16 @@ fn parse_expr_helper<'a>(hashmap: &HashMap<&'a [u8], Precedence>, } Precedence::And => lhs && rhs, Precedence::Or => lhs || rhs, - Precedence::BinOp => three(&[if lhs { b" " } else { b"" }, op, if rhs { b" " } else { b"" }], error), - Precedence::Paren => unimplemented!(), // TODO: implement parentheses - _ => unreachable!() + Precedence::BinOp => three( + &[ + if lhs { b" " } else { b"" }, + op, + if rhs { b" " } else { b"" }, + ], + error, + ), + Precedence::Paren => unimplemented!(), // TODO: implement parentheses + _ => unreachable!(), }; if args.len() > 0 { prec = *hashmap.get(&args[0]).unwrap_or_else(|| { @@ -326,8 +336,8 @@ enum PathCondition { #[cfg(not(windows))] fn path(path: &[u8], cond: PathCondition) -> bool { - use libc::{stat, lstat, S_IFMT, S_IFLNK, S_IFBLK, S_IFCHR, S_IFDIR, S_IFREG}; - use libc::{S_IFIFO, mode_t}; + use libc::{lstat, stat, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG}; + use libc::{mode_t, S_IFIFO}; use std::ffi::CString; static S_ISUID: mode_t = 0o4000; @@ -335,8 +345,8 @@ fn path(path: &[u8], cond: PathCondition) -> bool { static S_IFSOCK: mode_t = 0o140000; enum Permission { - Read = 0o4, - Write = 0o2, + Read = 0o4, + Write = 0o2, Execute = 0o1, } let perm = |stat: stat, p: Permission| { @@ -366,20 +376,20 @@ fn path(path: &[u8], cond: PathCondition) -> bool { } let file_type = stat.st_mode & S_IFMT; match cond { - PathCondition::BlockSpecial => file_type == S_IFBLK, + PathCondition::BlockSpecial => file_type == S_IFBLK, PathCondition::CharacterSpecial => file_type == S_IFCHR, - PathCondition::Directory => file_type == S_IFDIR, - PathCondition::Exists => true, - PathCondition::Regular => file_type == S_IFREG, - PathCondition::GroupIDFlag => stat.st_mode & S_ISGID != 0, - PathCondition::SymLink => true, - PathCondition::FIFO => file_type == S_IFIFO, - PathCondition::Readable => perm(stat, Permission::Read), - PathCondition::Socket => file_type == S_IFSOCK, - PathCondition::NonEmpty => stat.st_size > 0, - PathCondition::UserIDFlag => stat.st_mode & S_ISUID != 0, - PathCondition::Writable => perm(stat, Permission::Write), - PathCondition::Executable => perm(stat, Permission::Execute), + PathCondition::Directory => file_type == S_IFDIR, + PathCondition::Exists => true, + PathCondition::Regular => file_type == S_IFREG, + PathCondition::GroupIDFlag => stat.st_mode & S_ISGID != 0, + PathCondition::SymLink => true, + PathCondition::FIFO => file_type == S_IFIFO, + PathCondition::Readable => perm(stat, Permission::Read), + PathCondition::Socket => file_type == S_IFSOCK, + PathCondition::NonEmpty => stat.st_size > 0, + PathCondition::UserIDFlag => stat.st_mode & S_ISUID != 0, + PathCondition::Writable => perm(stat, Permission::Write), + PathCondition::Executable => perm(stat, Permission::Execute), } } @@ -392,19 +402,19 @@ fn path(path: &[u8], cond: PathCondition) -> bool { _ => return false, }; match cond { - PathCondition::BlockSpecial => false, + PathCondition::BlockSpecial => false, PathCondition::CharacterSpecial => false, - PathCondition::Directory => stat.is_dir(), - PathCondition::Exists => true, - PathCondition::Regular => stat.is_file(), - PathCondition::GroupIDFlag => false, - PathCondition::SymLink => false, - PathCondition::FIFO => false, - PathCondition::Readable => false, // TODO - PathCondition::Socket => false, - PathCondition::NonEmpty => stat.len() > 0, - PathCondition::UserIDFlag => false, - PathCondition::Writable => false, // TODO - PathCondition::Executable => false, // TODO + PathCondition::Directory => stat.is_dir(), + PathCondition::Exists => true, + PathCondition::Regular => stat.is_file(), + PathCondition::GroupIDFlag => false, + PathCondition::SymLink => false, + PathCondition::FIFO => false, + PathCondition::Readable => false, // TODO + PathCondition::Socket => false, + PathCondition::NonEmpty => stat.len() > 0, + PathCondition::UserIDFlag => false, + PathCondition::Writable => false, // TODO + PathCondition::Executable => false, // TODO } } diff --git a/src/timeout/timeout.rs b/src/timeout/timeout.rs index 3cad8fa77..1058c0f39 100644 --- a/src/timeout/timeout.rs +++ b/src/timeout/timeout.rs @@ -30,7 +30,11 @@ pub fn uumain(args: Vec) -> i32 { let program = args[0].clone(); let mut opts = getopts::Options::new(); - opts.optflag("", "preserve-status", "exit with the same status as COMMAND, even when the command times out"); + opts.optflag( + "", + "preserve-status", + "exit with the same status as COMMAND, even when the command times out", + ); opts.optflag("", "foreground", "when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out"); opts.optopt("k", "kill-after", "also send a KILL signal if COMMAND is still running this long after the initial signal was sent", "DURATION"); opts.optflag("s", "signal", "specify the signal to be sent on timeout; SIGNAL may be a name like 'HUP' or a number; see 'kill -l' for a list of signals"); @@ -38,17 +42,21 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("V", "version", "output version information and exit"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => { - crash!(ERR_EXIT_STATUS, "{}", f) - } + Err(f) => crash!(ERR_EXIT_STATUS, "{}", f), }; if matches.opt_present("help") { - print!("{} {} + print!( + "{} {} Usage: {} [OPTION] DURATION COMMAND [ARG]... -{}", NAME, VERSION, program, &opts.usage("Start COMMAND, and kill it if still running after DURATION.")); +{}", + NAME, + VERSION, + program, + &opts.usage("Start COMMAND, and kill it if still running after DURATION.") + ); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); } else if matches.free.len() < 2 { @@ -76,7 +84,7 @@ Usage: return ERR_EXIT_STATUS; } }, - None => uucore::signals::signal_by_name_or_value("TERM").unwrap() + None => uucore::signals::signal_by_name_or_value("TERM").unwrap(), }; let duration = match uucore::parse_time::from_str(&matches.free[0]) { Ok(time) => time, @@ -85,21 +93,39 @@ Usage: return ERR_EXIT_STATUS; } }; - return timeout(&matches.free[1], &matches.free[2..], duration, signal, kill_after, foreground, status); + return timeout( + &matches.free[1], + &matches.free[2..], + duration, + signal, + kill_after, + foreground, + status, + ); } 0 } -fn timeout(cmdname: &str, args: &[String], duration: Duration, signal: usize, kill_after: Duration, foreground: bool, preserve_status: bool) -> i32 { +fn timeout( + cmdname: &str, + args: &[String], + duration: Duration, + signal: usize, + kill_after: Duration, + foreground: bool, + preserve_status: bool, +) -> i32 { if !foreground { unsafe { libc::setpgid(0, 0) }; } - let mut process = match Command::new(cmdname).args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() { + let mut process = match Command::new(cmdname) + .args(args) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn() + { Ok(p) => p, Err(err) => { show_error!("failed to execute process: {}", err); @@ -123,22 +149,26 @@ fn timeout(cmdname: &str, args: &[String], duration: Duration, signal: usize, ki } else { 124 } - }, + } Ok(None) => { if kill_after == Duration::new(0, 0) { // XXX: this may not be right return 124; } - return_if_err!(ERR_EXIT_STATUS, process.send_signal(uucore::signals::signal_by_name_or_value("KILL").unwrap())); + return_if_err!( + ERR_EXIT_STATUS, + process + .send_signal(uucore::signals::signal_by_name_or_value("KILL").unwrap()) + ); return_if_err!(ERR_EXIT_STATUS, process.wait()); 137 - }, + } Err(_) => 124, } - }, + } Err(_) => { return_if_err!(ERR_EXIT_STATUS, process.send_signal(signal)); ERR_EXIT_STATUS - }, + } } } diff --git a/src/touch/touch.rs b/src/touch/touch.rs index f373b88fc..e0608f16f 100644 --- a/src/touch/touch.rs +++ b/src/touch/touch.rs @@ -9,9 +9,9 @@ // that was distributed with this source code. // +pub extern crate filetime; extern crate getopts; extern crate time; -pub extern crate filetime; #[macro_use] extern crate uucore; @@ -54,7 +54,7 @@ macro_rules! to_timeval { #[cfg(unix)] fn set_symlink_times(p: &str, atime: FileTime, mtime: FileTime) -> io::Result<()> { use std::ffi::CString; - use uucore::libc::{lutimes, timeval, time_t, suseconds_t}; + use uucore::libc::{lutimes, suseconds_t, time_t, timeval}; let times = [to_timeval!(atime), to_timeval!(mtime)]; let p = try!(CString::new(p)); @@ -72,29 +72,39 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("a", "", "change only the access time"); opts.optflag("c", "no-create", "do not create any files"); - opts.optopt("d", - "date", - "parse argument and use it instead of current time", - "STRING"); - opts.optflag("h", - "no-dereference", - "affect each symbolic link instead of any referenced file \ - (only for systems that can change the timestamps of a symlink)"); + opts.optopt( + "d", + "date", + "parse argument and use it instead of current time", + "STRING", + ); + opts.optflag( + "h", + "no-dereference", + "affect each symbolic link instead of any referenced file \ + (only for systems that can change the timestamps of a symlink)", + ); opts.optflag("m", "", "change only the modification time"); - opts.optopt("r", - "reference", - "use this file's times instead of the current time", - "FILE"); - opts.optopt("t", - "", - "use [[CC]YY]MMDDhhmm[.ss] instead of the current time", - "STAMP"); - opts.optopt("", - "time", - "change only the specified time: \"access\", \"atime\", or \ - \"use\" are equivalent to -a; \"modify\" or \"mtime\" are \ - equivalent to -m", - "WORD"); + opts.optopt( + "r", + "reference", + "use this file's times instead of the current time", + "FILE", + ); + opts.optopt( + "t", + "", + "use [[CC]YY]MMDDhhmm[.ss] instead of the current time", + "STAMP", + ); + opts.optopt( + "", + "time", + "change only the specified time: \"access\", \"atime\", or \ + \"use\" are equivalent to -a; \"modify\" or \"mtime\" are \ + equivalent to -m", + "WORD", + ); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); @@ -113,23 +123,34 @@ pub fn uumain(args: Vec) -> i32 { println!(""); println!("Usage: {} [OPTION]... FILE...", NAME); println!(""); - println!("{}", opts.usage("Update the access and modification times of \ - each FILE to the current time.")); + println!( + "{}", + opts.usage( + "Update the access and modification times of \ + each FILE to the current time." + ) + ); if matches.free.is_empty() { return 1; } return 0; } - if matches.opt_present("date") && matches.opts_present(&["reference".to_owned(), "t".to_owned()]) || - matches.opt_present("reference") && matches.opts_present(&["date".to_owned(), "t".to_owned()]) || - matches.opt_present("t") && matches.opts_present(&["date".to_owned(), "reference".to_owned()]) { + if matches.opt_present("date") + && matches.opts_present(&["reference".to_owned(), "t".to_owned()]) + || matches.opt_present("reference") + && matches.opts_present(&["date".to_owned(), "t".to_owned()]) + || matches.opt_present("t") + && matches.opts_present(&["date".to_owned(), "reference".to_owned()]) + { panic!("Invalid options: cannot specify reference time from more than one source"); } let (mut atime, mut mtime) = if matches.opt_present("reference") { - stat(&matches.opt_str("reference").unwrap()[..], - !matches.opt_present("no-dereference")) + stat( + &matches.opt_str("reference").unwrap()[..], + !matches.opt_present("no-dereference"), + ) } else if matches.opts_present(&["date".to_owned(), "t".to_owned()]) { let timestamp = if matches.opt_present("date") { parse_date(matches.opt_str("date").unwrap().as_ref()) @@ -168,13 +189,16 @@ pub fn uumain(args: Vec) -> i32 { let st = stat(path, !matches.opt_present("no-dereference")); let time = matches.opt_strs("time"); - if !(matches.opt_present("a") || time.contains(&"access".to_owned()) || - time.contains(&"atime".to_owned()) || time.contains(&"use".to_owned())) { + if !(matches.opt_present("a") || time.contains(&"access".to_owned()) + || time.contains(&"atime".to_owned()) + || time.contains(&"use".to_owned())) + { atime = st.0; } - if !(matches.opt_present("m") || time.contains(&"modify".to_owned()) || - time.contains(&"mtime".to_owned())) { + if !(matches.opt_present("m") || time.contains(&"modify".to_owned()) + || time.contains(&"mtime".to_owned())) + { mtime = st.1; } } @@ -201,8 +225,16 @@ fn stat(path: &str, follow: bool) -> (FileTime, FileTime) { }; match metadata { - Ok(m) => (FileTime::from_last_access_time(&m), FileTime::from_last_modification_time(&m)), - Err(_) => crash!(1, "failed to get attributes of '{}': {}", path, Error::last_os_error()), + Ok(m) => ( + FileTime::from_last_access_time(&m), + FileTime::from_last_modification_time(&m), + ), + Err(_) => crash!( + 1, + "failed to get attributes of '{}': {}", + path, + Error::last_os_error() + ), } } diff --git a/src/tr/expand.rs b/src/tr/expand.rs index e5d4d8da0..d9d38688a 100644 --- a/src/tr/expand.rs +++ b/src/tr/expand.rs @@ -54,11 +54,11 @@ impl<'a> Iterator for Unescape<'a> { // we know that \ is 1 byte long so we can index into the string safely let c = self.string[1..].chars().next().unwrap(); (Some(unescape_char(c)), 1 + c.len_utf8()) - }, - c => (Some(c), c.len_utf8()), // not an escape char + } + c => (Some(c), c.len_utf8()), // not an escape char }; - self.string = &self.string[idx..]; // advance the pointer to the next char + self.string = &self.string[idx..]; // advance the pointer to the next char ret } } @@ -89,16 +89,16 @@ impl<'a> Iterator for ExpandSet<'a> { if let Some(first) = self.unesc.next() { // peek ahead if self.unesc.peek() == Some(&'-') && match self.unesc.size_hint() { - (x, _) if x > 1 => true, // there's a range here; record it in our internal Range struct + (x, _) if x > 1 => true, // there's a range here; record it in our internal Range struct _ => false, } { - self.unesc.next(); // this is the '-' - let last = self.unesc.next().unwrap(); // this is the end of the range + self.unesc.next(); // this is the '-' + let last = self.unesc.next().unwrap(); // this is the end of the range - self.range = first as u32 + 1 .. last as u32 + 1; + self.range = first as u32 + 1..last as u32 + 1; } - return Some(first); // in any case, return the next char + return Some(first); // in any case, return the next char } None @@ -109,7 +109,7 @@ impl<'a> ExpandSet<'a> { #[inline] pub fn new(s: &'a str) -> ExpandSet<'a> { ExpandSet { - range: 0 .. 0, + range: 0..0, unesc: Unescape { string: s }.peekable(), } } diff --git a/src/tr/tr.rs b/src/tr/tr.rs index 0e82baa3d..86f181ee2 100644 --- a/src/tr/tr.rs +++ b/src/tr/tr.rs @@ -13,8 +13,8 @@ */ extern crate bit_set; -extern crate getopts; extern crate fnv; +extern crate getopts; #[macro_use] extern crate uucore; @@ -45,7 +45,7 @@ impl DeleteOperation { fn new(set: ExpandSet, complement: bool) -> DeleteOperation { DeleteOperation { bset: set.map(|c| c as usize).collect(), - complement: complement + complement: complement, } } } @@ -70,7 +70,7 @@ impl SqueezeOperation { fn new(squeeze_set: ExpandSet, complement: bool) -> SqueezeOperation { SqueezeOperation { squeeze_set: squeeze_set.map(|c| c as usize).collect(), - complement: complement + complement: complement, } } } @@ -92,18 +92,24 @@ struct DeleteAndSqueezeOperation { } impl DeleteAndSqueezeOperation { - fn new(delete_set: ExpandSet, squeeze_set: ExpandSet, complement: bool) -> DeleteAndSqueezeOperation { + fn new( + delete_set: ExpandSet, + squeeze_set: ExpandSet, + complement: bool, + ) -> DeleteAndSqueezeOperation { DeleteAndSqueezeOperation { delete_set: delete_set.map(|c| c as usize).collect(), squeeze_set: squeeze_set.map(|c| c as usize).collect(), - complement: complement + complement: complement, } } } impl SymbolTranslator for DeleteAndSqueezeOperation { fn translate(&self, c: &char, prev_c: &char) -> Option { - if self.complement != self.delete_set.contains(*c as usize) || *prev_c == *c && self.squeeze_set.contains(*c as usize) { + if self.complement != self.delete_set.contains(*c as usize) + || *prev_c == *c && self.squeeze_set.contains(*c as usize) + { None } else { Some(*c) @@ -129,9 +135,7 @@ impl TranslateOperation { map.insert(i as usize, s2_prev); } } - TranslateOperation { - translate_map: map, - } + TranslateOperation { translate_map: map } } } @@ -147,8 +151,11 @@ fn translate_input(input: &mut BufRead, output: &mut Write, while let Ok(length) = input.read_line(&mut buf) { let mut prev_c = 0 as char; - if length == 0 { break } - { // isolation to make borrow checker happy + if length == 0 { + break; + } + { + // isolation to make borrow checker happy let filtered = buf.chars().filter_map(|c| { let res = translator.translate(&c, &prev_c); if res.is_some() { @@ -182,7 +189,11 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("d", "delete", "delete characters in SET1"); opts.optflag("h", "help", "display this help and exit"); opts.optflag("s", "squeeze", "replace each sequence of a repeated character that is listed in the last specified SET, with a single occurrence of that character"); - opts.optflag("t", "truncate-set1", "first truncate SET1 to length of SET2"); + opts.optflag( + "t", + "truncate-set1", + "first truncate SET1 to length of SET2", + ); opts.optflag("V", "version", "output version information and exit"); let matches = match opts.parse(&args[1..]) { diff --git a/src/true/true.rs b/src/true/true.rs index 16ef23527..d1d3d70b9 100644 --- a/src/true/true.rs +++ b/src/true/true.rs @@ -1,4 +1,4 @@ -#![crate_name= "uu_true"] +#![crate_name = "uu_true"] /* * This file is part of the uutils coreutils package. diff --git a/src/truncate/truncate.rs b/src/truncate/truncate.rs index a46ecef21..ef1168daf 100644 --- a/src/truncate/truncate.rs +++ b/src/truncate/truncate.rs @@ -16,7 +16,7 @@ extern crate uucore; #[allow(unused_imports)] use std::ascii::AsciiExt; -use std::fs::{File, metadata, OpenOptions}; +use std::fs::{metadata, File, OpenOptions}; use std::io::Result; use std::path::Path; @@ -28,7 +28,7 @@ enum TruncateMode { AtMost, AtLeast, RoundDown, - RoundUp + RoundUp, } static NAME: &'static str = "truncate"; @@ -38,15 +38,24 @@ pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); opts.optflag("c", "no-create", "do not create files that do not exist"); - opts.optflag("o", "io-blocks", "treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)"); - opts.optopt("r", "reference", "base the size of each file on the size of RFILE", "RFILE"); + opts.optflag( + "o", + "io-blocks", + "treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)", + ); + opts.optopt( + "r", + "reference", + "base the size of each file on the size of RFILE", + "RFILE", + ); opts.optopt("s", "size", "set or adjust the size of each file according to SIZE, which is in bytes unless --io-blocks is specified", "SIZE"); 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(f) => { crash!(1, "{}", f) } + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("help") { @@ -55,8 +64,12 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {} [OPTION]... FILE...", NAME); println!(""); - print!("{}", opts.usage("Shrink or extend the size of each file to the specified size.")); - print!(" + print!( + "{}", + opts.usage("Shrink or extend the size of each file to the specified size.") + ); + print!( + " SIZE is an integer with an optional prefix and optional unit. The available units (K, M, G, T, P, E, Z, and Y) use the following format: 'KB' => 1000 (kilobytes) @@ -73,7 +86,8 @@ file based on its current size: '>' => at least '/' => round down to multiple of '%' => round up to multiple of -"); +" + ); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); } else if matches.free.is_empty() { @@ -89,7 +103,7 @@ file based on its current size: } else { match truncate(no_create, io_blocks, reference, size, matches.free) { Ok(()) => ( /* pass */ ), - Err(_) => return 1 + Err(_) => return 1, } } } @@ -97,27 +111,34 @@ file based on its current size: 0 } -fn truncate(no_create: bool, _: bool, reference: Option, size: Option, filenames: Vec) -> Result<()> { +fn truncate( + no_create: bool, + _: bool, + reference: Option, + size: Option, + filenames: Vec, +) -> Result<()> { let (refsize, mode) = match reference { Some(rfilename) => { let _ = match File::open(Path::new(&rfilename)) { Ok(m) => m, - Err(f) => { - crash!(1, "{}", f.to_string()) - } + Err(f) => crash!(1, "{}", f.to_string()), }; match metadata(rfilename) { Ok(meta) => (meta.len(), TruncateMode::Reference), - Err(f) => { - crash!(1, "{}", f.to_string()) - } + Err(f) => crash!(1, "{}", f.to_string()), } } - None => parse_size(size.unwrap().as_ref()) + None => parse_size(size.unwrap().as_ref()), }; for filename in &filenames { let path = Path::new(filename); - match OpenOptions::new().read(true).write(true).create(!no_create).open(path) { + match OpenOptions::new() + .read(true) + .write(true) + .create(!no_create) + .open(path) + { Ok(file) => { let fsize = match metadata(filename) { Ok(meta) => meta.len(), @@ -130,21 +151,25 @@ fn truncate(no_create: bool, _: bool, reference: Option, size: Option refsize, TruncateMode::Extend => fsize + refsize, TruncateMode::Reduce => fsize - refsize, - TruncateMode::AtMost => if fsize > refsize { refsize } else { fsize }, - TruncateMode::AtLeast => if fsize < refsize { refsize } else { fsize }, + TruncateMode::AtMost => if fsize > refsize { + refsize + } else { + fsize + }, + TruncateMode::AtLeast => if fsize < refsize { + refsize + } else { + fsize + }, TruncateMode::RoundDown => fsize - fsize % refsize, - TruncateMode::RoundUp => fsize + fsize % refsize + TruncateMode::RoundUp => fsize + fsize % refsize, }; match file.set_len(tsize) { - Ok(_) => {}, - Err(f) => { - crash!(1, "{}", f.to_string()) - } + Ok(_) => {} + Err(f) => crash!(1, "{}", f.to_string()), }; } - Err(f) => { - crash!(1, "{}", f.to_string()) - } + Err(f) => crash!(1, "{}", f.to_string()), } } Ok(()) @@ -158,15 +183,14 @@ fn parse_size(size: &str) -> (u64, TruncateMode) { '>' => TruncateMode::AtLeast, '/' => TruncateMode::RoundDown, '*' => TruncateMode::RoundUp, - _ => TruncateMode::Reference /* assume that the size is just a number */ + _ => TruncateMode::Reference, /* assume that the size is just a number */ }; let bytes = { - let mut slice = - if mode == TruncateMode::Reference { - size - } else { - &size[1..] - }; + let mut slice = if mode == TruncateMode::Reference { + size + } else { + &size[1..] + }; if slice.chars().last().unwrap().is_alphabetic() { slice = &slice[..slice.len() - 1]; if slice.len() > 0 && slice.chars().last().unwrap().is_alphabetic() { @@ -177,13 +201,15 @@ fn parse_size(size: &str) -> (u64, TruncateMode) { }.to_owned(); let mut number: u64 = match bytes.parse() { Ok(num) => num, - Err(e) => { - crash!(1, "'{}' is not a valid number: {}", size, e) - } + Err(e) => crash!(1, "'{}' is not a valid number: {}", size, e), }; if size.chars().last().unwrap().is_alphabetic() { number *= match size.chars().last().unwrap().to_ascii_uppercase() { - 'B' => match size.chars().nth(size.len() - 2).unwrap().to_ascii_uppercase() { + 'B' => match size.chars() + .nth(size.len() - 2) + .unwrap() + .to_ascii_uppercase() + { 'K' => 1000u64, 'M' => 1000u64.pow(2), 'G' => 1000u64.pow(3), @@ -192,9 +218,7 @@ fn parse_size(size: &str) -> (u64, TruncateMode) { 'E' => 1000u64.pow(6), 'Z' => 1000u64.pow(7), 'Y' => 1000u64.pow(8), - letter => { - crash!(1, "'{}B' is not a valid suffix.", letter) - } + letter => crash!(1, "'{}B' is not a valid suffix.", letter), }, 'K' => 1024u64, 'M' => 1024u64.pow(2), @@ -204,9 +228,7 @@ fn parse_size(size: &str) -> (u64, TruncateMode) { 'E' => 1024u64.pow(6), 'Z' => 1024u64.pow(7), 'Y' => 1024u64.pow(8), - letter => { - crash!(1, "'{}' is not a valid suffix.", letter) - } + letter => crash!(1, "'{}' is not a valid suffix.", letter), }; } (number, mode) diff --git a/src/tsort/tsort.rs b/src/tsort/tsort.rs index afab4a5d4..a81104c5d 100644 --- a/src/tsort/tsort.rs +++ b/src/tsort/tsort.rs @@ -17,7 +17,7 @@ extern crate uucore; use std::collections::{HashMap, HashSet}; use std::fs::File; -use std::io::{BufRead, BufReader, Read, stdin}; +use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; static NAME: &'static str = "tsort"; @@ -31,7 +31,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("h") { @@ -60,39 +60,40 @@ pub fn uumain(args: Vec) -> i32 { let mut stdin_buf; let mut file_buf; - let mut reader = BufReader::new( - if input == "-" { - stdin_buf = stdin(); - &mut stdin_buf as &mut Read - } else { - file_buf = match File::open(Path::new(&input)) { - Ok(a) => a, - _ => { - show_error!("{}: No such file or directory", input); - return 1; - } - }; - &mut file_buf as &mut Read - } - ); + let mut reader = BufReader::new(if input == "-" { + stdin_buf = stdin(); + &mut stdin_buf as &mut Read + } else { + file_buf = match File::open(Path::new(&input)) { + Ok(a) => a, + _ => { + show_error!("{}: No such file or directory", input); + return 1; + } + }; + &mut file_buf as &mut Read + }); let mut g = Graph::new(); loop { let mut line = String::new(); match reader.read_line(&mut line) { Ok(_) => { - let tokens: Vec = line.trim_right().split_whitespace().map(|s| s.to_owned()).collect(); + let tokens: Vec = line.trim_right() + .split_whitespace() + .map(|s| s.to_owned()) + .collect(); if tokens.is_empty() { - break + break; } for ab in tokens.chunks(2) { match ab.len() { 2 => g.add_edge(&ab[0], &ab[1]), - _ => crash!(1, "{}: input contains an odd number of tokens", input) + _ => crash!(1, "{}: input contains an odd number of tokens", input), } } - }, - _ => break + } + _ => break, } } @@ -114,7 +115,7 @@ pub fn uumain(args: Vec) -> i32 { struct Graph { in_edges: HashMap>, out_edges: HashMap>, - result: Vec + result: Vec, } impl Graph { @@ -122,7 +123,7 @@ impl Graph { Graph { in_edges: HashMap::new(), out_edges: HashMap::new(), - result: vec!(), + result: vec![], } } @@ -136,10 +137,10 @@ impl Graph { fn init_node(&mut self, n: &String) { self.in_edges.insert(n.clone(), HashSet::new()); - self.out_edges.insert(n.clone(), vec!()); + self.out_edges.insert(n.clone(), vec![]); } - fn add_edge(&mut self, from: &String, to: &String) { + fn add_edge(&mut self, from: &String, to: &String) { if !self.has_node(to) { self.init_node(to); } @@ -157,7 +158,7 @@ impl Graph { // Kahn's algorithm // O(|V|+|E|) fn run_tsort(&mut self) { - let mut start_nodes = vec!(); + let mut start_nodes = vec![]; for (n, edges) in &self.in_edges { if edges.is_empty() { start_nodes.push(n.clone()); @@ -186,7 +187,7 @@ impl Graph { fn is_acyclic(&self) -> bool { for (_, edges) in &self.out_edges { if !edges.is_empty() { - return false + return false; } } true diff --git a/src/tty/tty.rs b/src/tty/tty.rs index e3328c430..173d0f0ff 100644 --- a/src/tty/tty.rs +++ b/src/tty/tty.rs @@ -20,7 +20,7 @@ extern crate uucore; use std::ffi::CStr; use uucore::fs::is_stdin_interactive; -extern { +extern "C" { fn ttyname(filedesc: libc::c_int) -> *const libc::c_char; } @@ -36,7 +36,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => { crash!(2, "{}", f) } + Err(f) => crash!(2, "{}", f), }; if matches.opt_present("help") { @@ -45,7 +45,10 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {} [OPTION]...", NAME); println!(""); - print!("{}", opts.usage("Print the file name of the terminal connected to standard input.")); + print!( + "{}", + opts.usage("Print the file name of the terminal connected to standard input.") + ); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); } else { diff --git a/src/uname/uname.rs b/src/uname/uname.rs index 865cf9671..307473454 100644 --- a/src/uname/uname.rs +++ b/src/uname/uname.rs @@ -11,12 +11,12 @@ // last synced with: uname (GNU coreutils) 8.21 -#[macro_use] -extern crate uucore; extern crate clap; extern crate platform_info; +#[macro_use] +extern crate uucore; -use clap::{Arg, App}; +use clap::{App, Arg}; use platform_info::*; const VERSION: &'static str = env!("CARGO_PKG_VERSION"); @@ -50,7 +50,6 @@ const HOST_OS: &'static str = "Fuchsia"; const HOST_OS: &'static str = "Redox"; pub fn uumain(args: Vec) -> i32 { - let usage = format!("{} [OPTION]...", executable!()); let matches = App::new(executable!()) .version(VERSION) diff --git a/src/unexpand/unexpand.rs b/src/unexpand/unexpand.rs index 50ecc7ed4..e06caedc7 100644 --- a/src/unexpand/unexpand.rs +++ b/src/unexpand/unexpand.rs @@ -30,18 +30,21 @@ static DEFAULT_TABSTOP: usize = 8; fn tabstops_parse(s: String) -> Vec { let words = s.split(',').collect::>(); - let nums = words.into_iter() - .map(|sn| sn.parse() - .unwrap_or_else( - |_| crash!(1, "{}\n", "tab size contains invalid character(s)")) - ) + let nums = words + .into_iter() + .map(|sn| { + sn.parse() + .unwrap_or_else(|_| crash!(1, "{}\n", "tab size contains invalid character(s)")) + }) .collect::>(); if nums.iter().any(|&n| n == 0) { crash!(1, "{}\n", "tab size cannot be 0"); } - if let (false, _) = nums.iter().fold((true, 0), |(acc, last), &n| (acc && last <= n, n)) { + if let (false, _) = nums.iter() + .fold((true, 0), |(acc, last), &n| (acc && last <= n, n)) + { crash!(1, "{}\n", "tab sizes must be ascending"); } @@ -58,47 +61,77 @@ struct Options { impl Options { fn new(matches: getopts::Matches) -> Options { let tabstops = match matches.opt_str("t") { - None => vec!(DEFAULT_TABSTOP), - Some(s) => tabstops_parse(s) + None => vec![DEFAULT_TABSTOP], + Some(s) => tabstops_parse(s), }; let aflag = (matches.opt_present("all") || matches.opt_present("tabs")) - && !matches.opt_present("first-only"); + && !matches.opt_present("first-only"); let uflag = !matches.opt_present("U"); - let files = - if matches.free.is_empty() { - vec!("-".to_owned()) - } else { - matches.free - }; + let files = if matches.free.is_empty() { + vec!["-".to_owned()] + } else { + matches.free + }; - Options { files: files, tabstops: tabstops, aflag: aflag, uflag: uflag } + Options { + files: files, + tabstops: tabstops, + aflag: aflag, + uflag: uflag, + } } } pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optflag("a", "all", "convert all blanks, instead of just initial blanks"); - opts.optflag("", "first-only", "convert only leading sequences of blanks (overrides -a)"); - opts.optopt("t", "tabs", "have tabs N characters apart instead of 8 (enables -a)", "N"); - opts.optopt("t", "tabs", "use comma separated LIST of tab positions (enables -a)", "LIST"); - opts.optflag("U", "no-utf8", "interpret input file as 8-bit ASCII rather than UTF-8"); + opts.optflag( + "a", + "all", + "convert all blanks, instead of just initial blanks", + ); + opts.optflag( + "", + "first-only", + "convert only leading sequences of blanks (overrides -a)", + ); + opts.optopt( + "t", + "tabs", + "have tabs N characters apart instead of 8 (enables -a)", + "N", + ); + opts.optopt( + "t", + "tabs", + "use comma separated LIST of tab positions (enables -a)", + "LIST", + ); + opts.optflag( + "U", + "no-utf8", + "interpret input file as 8-bit ASCII rather than UTF-8", + ); 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(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("help") { println!("{} {}\n", NAME, VERSION); println!("Usage: {} [OPTION]... [FILE]...\n", NAME); - println!("{}", opts.usage( - "Convert blanks in each FILE to tabs, writing to standard output.\n\ - With no FILE, or when FILE is -, read standard input.")); + println!( + "{}", + opts.usage( + "Convert blanks in each FILE to tabs, writing to standard output.\n\ + With no FILE, or when FILE is -, read standard input." + ) + ); return 0; } @@ -112,7 +145,7 @@ pub fn uumain(args: Vec) -> i32 { 0 } -fn open(path: String) -> BufReader> { +fn open(path: String) -> BufReader> { let file_buf; if path == "-" { BufReader::new(Box::new(stdin()) as Box) @@ -132,19 +165,25 @@ fn next_tabstop(tabstops: &[usize], col: usize) -> Option { // find next larger tab match tabstops.iter().skip_while(|&&t| t <= col).next() { Some(t) => Some(t - col), - None => None, // if there isn't one in the list, tab becomes a single space + None => None, // if there isn't one in the list, tab becomes a single space } } } -fn write_tabs(output: &mut BufWriter, tabstops: &[usize], - mut scol: usize, col: usize, prevtab: bool, init: bool, amode: bool) { +fn write_tabs( + output: &mut BufWriter, + tabstops: &[usize], + mut scol: usize, + col: usize, + prevtab: bool, + init: bool, + amode: bool, +) { // This conditional establishes the following: // We never turn a single space before a non-blank into // a tab, unless it's at the start of the line. let ai = init || amode; - if (ai && !prevtab && col > scol + 1) || - (col > scol && (init || ai && prevtab)) { + if (ai && !prevtab && col > scol + 1) || (col > scol && (init || ai && prevtab)) { while let Some(nts) = next_tabstop(tabstops, scol) { if col < scol + nts { break; @@ -175,11 +214,7 @@ fn unexpand(options: Options) { let mut output = BufWriter::new(stdout()); let ts = &options.tabstops[..]; let mut buf = Vec::new(); - let lastcol = if ts.len() > 1 { - *ts.last().unwrap() - } else { - 0 - }; + let lastcol = if ts.len() > 1 { *ts.last().unwrap() } else { 0 }; for file in options.files.into_iter() { let mut fh = open(file); @@ -188,10 +223,10 @@ fn unexpand(options: Options) { Ok(s) => s > 0, Err(_) => !buf.is_empty(), } { - let mut byte = 0; // offset into the buffer - let mut col = 0; // the current column - let mut scol = 0; // the start col for the current span, i.e., the already-printed width - let mut init = true; // are we at the start of the line? + let mut byte = 0; // offset into the buffer + let mut col = 0; // the current column + let mut scol = 0; // the start col for the current span, i.e., the already-printed width + let mut init = true; // are we at the start of the line? let mut pctype = Other; while byte < buf.len() { @@ -210,34 +245,41 @@ fn unexpand(options: Options) { if byte + nbytes > buf.len() { // make sure we don't overrun the buffer because of invalid UTF-8 (Other, 1, 1) - } else if let Ok(t) = from_utf8(&buf[byte..byte+nbytes]) { + } else if let Ok(t) = from_utf8(&buf[byte..byte + nbytes]) { // Now that we think it's UTF-8, figure out what kind of char it is match t.chars().next() { Some(' ') => (Space, 0, 1), Some('\t') => (Tab, 0, 1), Some('\x08') => (Backspace, 0, 1), Some(c) => (Other, UnicodeWidthChar::width(c).unwrap_or(0), nbytes), - None => { // invalid char snuck past the utf8_validation_iterator somehow??? + None => { + // invalid char snuck past the utf8_validation_iterator somehow??? (Other, 1, 1) - }, + } } } else { // otherwise, it's not valid - (Other, 1, 1) // implicit assumption: non-UTF8 char has display width 1 + (Other, 1, 1) // implicit assumption: non-UTF8 char has display width 1 } } else { - (match buf[byte] { // always take exactly 1 byte in strict ASCII mode - 0x20 => Space, - 0x09 => Tab, - 0x08 => Backspace, - _ => Other, - }, 1, 1) + ( + match buf[byte] { + // always take exactly 1 byte in strict ASCII mode + 0x20 => Space, + 0x09 => Tab, + 0x08 => Backspace, + _ => Other, + }, + 1, + 1, + ) }; // now figure out how many columns this char takes up, and maybe print it let tabs_buffered = init || options.aflag; match ctype { - Space | Tab => { // compute next col, but only write space or tab chars if not buffering + Space | Tab => { + // compute next col, but only write space or tab chars if not buffering col += if ctype == Space { 1 } else { @@ -245,23 +287,34 @@ fn unexpand(options: Options) { }; if !tabs_buffered { - safe_unwrap!(output.write_all(&buf[byte..byte+nbytes])); - scol = col; // now printed up to this column + safe_unwrap!(output.write_all(&buf[byte..byte + nbytes])); + scol = col; // now printed up to this column } - }, - Other | Backspace => { // always - write_tabs(&mut output, ts, scol, col, pctype == Tab, init, options.aflag); - init = false; // no longer at the start of a line - col = if ctype == Other { // use computed width + } + Other | Backspace => { + // always + write_tabs( + &mut output, + ts, + scol, + col, + pctype == Tab, + init, + options.aflag, + ); + init = false; // no longer at the start of a line + col = if ctype == Other { + // use computed width col + cwidth - } else if col > 0 { // Backspace case, but only if col > 0 + } else if col > 0 { + // Backspace case, but only if col > 0 col - 1 } else { 0 }; - safe_unwrap!(output.write_all(&buf[byte..byte+nbytes])); - scol = col; // we've now printed up to this column - }, + safe_unwrap!(output.write_all(&buf[byte..byte + nbytes])); + scol = col; // we've now printed up to this column + } } byte += nbytes; // move on to next char @@ -270,7 +323,7 @@ fn unexpand(options: Options) { // write out anything remaining write_tabs(&mut output, ts, scol, col, pctype == Tab, init, true); - buf.truncate(0); // clear out the buffer + buf.truncate(0); // clear out the buffer } } crash_if_err!(1, output.flush()) diff --git a/src/uniq/uniq.rs b/src/uniq/uniq.rs index aa1951613..d1a79c149 100644 --- a/src/uniq/uniq.rs +++ b/src/uniq/uniq.rs @@ -17,7 +17,7 @@ extern crate uucore; use getopts::{Matches, Options}; use std::fs::File; -use std::io::{BufRead, BufReader, BufWriter, Read, stdin, stdout, Write}; +use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; use std::path::Path; use std::str::FromStr; @@ -38,8 +38,12 @@ struct Uniq { } impl Uniq { - pub fn print_uniq(&self, reader: &mut BufReader, writer: &mut BufWriter) { - let mut lines: Vec = vec!(); + pub fn print_uniq( + &self, + reader: &mut BufReader, + writer: &mut BufWriter, + ) { + let mut lines: Vec = vec![]; let mut first_line_printed = false; let delimiters = &self.delimiters[..]; let line_terminator = self.get_line_terminator(); @@ -47,14 +51,16 @@ impl Uniq { for io_line in reader.split(line_terminator) { let line = String::from_utf8(crash_if_err!(1, io_line)).unwrap(); if !lines.is_empty() && self.cmp_key(&lines[0]) != self.cmp_key(&line) { - let print_delimiter = delimiters == "prepend" || (delimiters == "separate" && first_line_printed); + let print_delimiter = + delimiters == "prepend" || (delimiters == "separate" && first_line_printed); first_line_printed |= self.print_lines(writer, &lines, print_delimiter); lines.truncate(0); } lines.push(line); } if !lines.is_empty() { - let print_delimiter = delimiters == "prepend" || (delimiters == "separate" && first_line_printed); + let print_delimiter = + delimiters == "prepend" || (delimiters == "separate" && first_line_printed); self.print_lines(writer, &lines, print_delimiter); } } @@ -94,23 +100,29 @@ impl Uniq { let fields_to_check = &self.skip_fields(line); let len = fields_to_check.len(); if len > 0 { - fields_to_check.chars() + fields_to_check + .chars() .skip(self.slice_start.unwrap_or(0)) .take(self.slice_stop.unwrap_or(len)) .map(|c| match c { - 'a' ... 'z' if self.ignore_case => ((c as u8) - 32) as char, + 'a'...'z' if self.ignore_case => ((c as u8) - 32) as char, _ => c, - }).collect() + }) + .collect() } else { fields_to_check.to_owned() } } - fn print_lines(&self, writer: &mut BufWriter, lines: &[String], print_delimiter: bool) -> bool { + fn print_lines( + &self, + writer: &mut BufWriter, + lines: &[String], + print_delimiter: bool, + ) -> bool { let mut first_line_printed = false; let mut count = if self.all_repeated { 1 } else { lines.len() }; - if lines.len() == 1 && !self.repeats_only - || lines.len() > 1 && !self.uniques_only { + if lines.len() == 1 && !self.repeats_only || lines.len() > 1 && !self.uniques_only { self.print_line(writer, &lines[0], count, print_delimiter); first_line_printed = true; count += 1; @@ -125,18 +137,27 @@ impl Uniq { first_line_printed } - fn print_line(&self, writer: &mut BufWriter, line: &str, count: usize, print_delimiter: bool) { + fn print_line( + &self, + writer: &mut BufWriter, + line: &str, + count: usize, + print_delimiter: bool, + ) { let line_terminator = self.get_line_terminator(); if print_delimiter { crash_if_err!(1, writer.write_all(&[line_terminator])); } - crash_if_err!(1, if self.show_counts { - writer.write_all(format!("{:7} {}", count, line).as_bytes()) - } else { - writer.write_all(line.as_bytes()) - }); + crash_if_err!( + 1, + if self.show_counts { + writer.write_all(format!("{:7} {}", count, line).as_bytes()) + } else { + writer.write_all(line.as_bytes()) + } + ); crash_if_err!(1, writer.write_all(&[line_terminator])); } } @@ -144,8 +165,7 @@ impl Uniq { fn opt_parsed(opt_name: &str, matches: &Matches) -> Option { matches.opt_str(opt_name).map(|arg_str| { let opt_val: Option = arg_str.parse().ok(); - opt_val.unwrap_or_else(|| - crash!(1, "Invalid argument for {}: {}", opt_name, arg_str)) + opt_val.unwrap_or_else(|| crash!(1, "Invalid argument for {}: {}", opt_name, arg_str)) }) } @@ -160,10 +180,29 @@ pub fn uumain(args: Vec) -> i32 { "print all duplicate lines delimit-method={none(default),prepend,separate} Delimiting is done with blank lines", "delimit-method" ); - opts.optopt("f", "skip-fields", "avoid comparing the first N fields", "N"); - opts.optopt("s", "skip-chars", "avoid comparing the first N characters", "N"); - opts.optopt("w", "check-chars", "compare no more than N characters in lines", "N"); - opts.optflag("i", "ignore-case", "ignore differences in case when comparing"); + opts.optopt( + "f", + "skip-fields", + "avoid comparing the first N fields", + "N", + ); + opts.optopt( + "s", + "skip-chars", + "avoid comparing the first N characters", + "N", + ); + opts.optopt( + "w", + "check-chars", + "compare no more than N characters in lines", + "N", + ); + opts.optflag( + "i", + "ignore-case", + "ignore differences in case when comparing", + ); opts.optflag("u", "unique", "only print unique lines"); opts.optflag("z", "zero-terminated", "end lines with 0 byte, not newline"); opts.optflag("h", "help", "display this help and exit"); @@ -171,7 +210,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "{}", f) + Err(f) => crash!(1, "{}", f), }; if matches.opt_present("help") { @@ -180,11 +219,19 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {0} [OPTION]... [FILE]...", NAME); println!(""); - print!("{}", opts.usage("Filter adjacent matching lines from INPUT (or standard input),\n\ - writing to OUTPUT (or standard output).")); + print!( + "{}", + opts.usage( + "Filter adjacent matching lines from INPUT (or standard input),\n\ + writing to OUTPUT (or standard output)." + ) + ); println!(""); - println!("Note: '{0}' does not detect repeated lines unless they are adjacent.\n\ - You may want to sort the input first, or use 'sort -u' without '{0}'.\n", NAME); + println!( + "Note: '{0}' does not detect repeated lines unless they are adjacent.\n\ + You may want to sort the input first, or use 'sort -u' without '{0}'.\n", + NAME + ); } else if matches.opt_present("version") { println!("{} {}", NAME, VERSION); } else { @@ -204,11 +251,15 @@ pub fn uumain(args: Vec) -> i32 { Some(ref opt_arg) if opt_arg != "none" => { let rep_args = ["prepend".to_owned(), "separate".to_owned()]; if !rep_args.contains(opt_arg) { - crash!(1, "Incorrect argument for all-repeated: {}", opt_arg.clone()); + crash!( + 1, + "Incorrect argument for all-repeated: {}", + opt_arg.clone() + ); } opt_arg.clone() - }, - _ => "".to_owned() + } + _ => "".to_owned(), }, show_counts: matches.opt_present("count"), skip_fields: opt_parsed("skip-fields", &matches), @@ -217,13 +268,15 @@ pub fn uumain(args: Vec) -> i32 { ignore_case: matches.opt_present("ignore-case"), zero_terminated: matches.opt_present("zero-terminated"), }; - uniq.print_uniq(&mut open_input_file(in_file_name), - &mut open_output_file(out_file_name)); + uniq.print_uniq( + &mut open_input_file(in_file_name), + &mut open_output_file(out_file_name), + ); } 0 } -fn open_input_file(in_file_name: String) -> BufReader> { +fn open_input_file(in_file_name: String) -> BufReader> { let in_file = if in_file_name == "-" { Box::new(stdin()) as Box } else { @@ -235,7 +288,7 @@ fn open_input_file(in_file_name: String) -> BufReader> { BufReader::new(in_file) } -fn open_output_file(out_file_name: String) -> BufWriter> { +fn open_output_file(out_file_name: String) -> BufWriter> { let out_file = if out_file_name == "-" { Box::new(stdout()) as Box } else { diff --git a/src/unlink/unlink.rs b/src/unlink/unlink.rs index e899b6a30..17e3d8d76 100644 --- a/src/unlink/unlink.rs +++ b/src/unlink/unlink.rs @@ -18,8 +18,8 @@ extern crate libc; extern crate uucore; use getopts::Options; -use libc::{S_IFMT, S_IFLNK, S_IFREG}; -use libc::{lstat, unlink, c_char, stat}; +use libc::{S_IFLNK, S_IFMT, S_IFREG}; +use libc::{c_char, lstat, stat, unlink}; use std::io::{Error, ErrorKind}; use std::mem::uninitialized; @@ -34,7 +34,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "invalid options\n{}", f) + Err(f) => crash!(1, "invalid options\n{}", f), }; if matches.opt_present("help") { @@ -53,24 +53,46 @@ pub fn uumain(args: Vec) -> i32 { } if matches.free.is_empty() { - crash!(1, "missing operand\nTry '{0} --help' for more information.", NAME); + crash!( + 1, + "missing operand\nTry '{0} --help' for more information.", + NAME + ); } else if matches.free.len() > 1 { - crash!(1, "extra operand: '{1}'\nTry '{0} --help' for more information.", NAME, matches.free[1]); + crash!( + 1, + "extra operand: '{1}'\nTry '{0} --help' for more information.", + NAME, + matches.free[1] + ); } let st_mode = { let mut buf: stat = unsafe { uninitialized() }; - let result = unsafe { lstat(matches.free[0].as_ptr() as *const c_char, &mut buf as *mut stat) }; + let result = unsafe { + lstat( + matches.free[0].as_ptr() as *const c_char, + &mut buf as *mut stat, + ) + }; if result < 0 { - crash!(1, "Cannot stat '{}': {}", matches.free[0], Error::last_os_error()); + crash!( + 1, + "Cannot stat '{}': {}", + matches.free[0], + Error::last_os_error() + ); } buf.st_mode & S_IFMT }; let result = if st_mode != S_IFREG && st_mode != S_IFLNK { - Err(Error::new(ErrorKind::Other, "Not a regular file or symlink")) + Err(Error::new( + ErrorKind::Other, + "Not a regular file or symlink", + )) } else { let result = unsafe { unlink(matches.free[0].as_ptr() as *const c_char) }; diff --git a/src/uptime/uptime.rs b/src/uptime/uptime.rs index 449846c3d..e32846ddd 100644 --- a/src/uptime/uptime.rs +++ b/src/uptime/uptime.rs @@ -18,7 +18,7 @@ extern crate getopts; extern crate uucore; // import crate time from utmpx use uucore::utmpx::*; -use uucore::libc::{time_t, c_double}; +use uucore::libc::{c_double, time_t}; pub use uucore::libc; use getopts::Options; @@ -33,7 +33,7 @@ static VERSION: &'static str = env!("CARGO_PKG_VERSION"); use libc::getloadavg; #[cfg(windows)] -extern { +extern "C" { fn GetTickCount() -> libc::uint32_t; } @@ -45,7 +45,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f) + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("version") { println!("{} {}", NAME, VERSION); @@ -57,9 +57,14 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {0} [OPTION]", NAME); println!(""); - println!("{}", opts.usage("Print the current time, the length of time the system has been up,\n\ - the number of users on the system, and the average number of jobs\n\ - in the run queue over the last 1, 5 and 15 minutes.")); + println!( + "{}", + opts.usage( + "Print the current time, the length of time the system has been up,\n\ + the number of users on the system, and the average number of jobs\n\ + in the run queue over the last 1, 5 and 15 minutes." + ) + ); return 0; } @@ -79,12 +84,14 @@ fn print_loadavg() { if loads == -1 { print!("\n"); - } - else { + } else { print!("load average: "); for n in 0..loads { - print!("{:.2}{}", avg[n as usize], if n == loads - 1 { "\n" } - else { ", " } ); + print!( + "{:.2}{}", + avg[n as usize], + if n == loads - 1 { "\n" } else { ", " } + ); } } } @@ -102,8 +109,8 @@ fn process_utmpx() -> (Option, usize) { if t.sec > 0 { boot_time = Some(t.sec as time_t); } - }, - _ => continue + } + _ => continue, } } (boot_time, nusers) @@ -125,19 +132,22 @@ fn print_nusers(nusers: usize) { fn print_time() { let local_time = time::now(); - print!(" {:02}:{:02}:{:02} ", local_time.tm_hour, - local_time.tm_min, local_time.tm_sec); + print!( + " {:02}:{:02}:{:02} ", + local_time.tm_hour, local_time.tm_min, local_time.tm_sec + ); } #[cfg(unix)] fn get_uptime(boot_time: Option) -> i64 { let mut proc_uptime = String::new(); - if let Some(n) = - File::open("/proc/uptime").ok() - .and_then(|mut f| f.read_to_string(&mut proc_uptime).ok()) - .and_then(|_| proc_uptime.split_whitespace().next()) - .and_then(|s| s.replace(".", "").parse().ok()) { + if let Some(n) = File::open("/proc/uptime") + .ok() + .and_then(|mut f| f.read_to_string(&mut proc_uptime).ok()) + .and_then(|_| proc_uptime.split_whitespace().next()) + .and_then(|s| s.replace(".", "").parse().ok()) + { n } else { match boot_time { @@ -145,7 +155,7 @@ fn get_uptime(boot_time: Option) -> i64 { let now = time::get_time().sec; let boottime = t as i64; ((now - boottime) * 100) - }, + } _ => -1, } } @@ -162,11 +172,9 @@ fn print_uptime(upsecs: i64) { let upmins = (upsecs - (updays * 86400) - (uphours * 3600)) / 60; if updays == 1 { print!("up {:1} day, {:2}:{:02}, ", updays, uphours, upmins); - } - else if updays > 1 { + } else if updays > 1 { print!("up {:1} days, {:2}:{:02}, ", updays, uphours, upmins); - } - else { + } else { print!("up {:2}:{:02}, ", uphours, upmins); } } diff --git a/src/users/users.rs b/src/users/users.rs index 28da6fe49..e6c6323ad 100644 --- a/src/users/users.rs +++ b/src/users/users.rs @@ -1,5 +1,4 @@ #![crate_name = "uu_users"] - /* * This file is part of the uutils coreutils package. * @@ -42,7 +41,10 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {} [OPTION]... [FILE]", NAME); println!(""); - println!("{}", opts.usage("Output who is currently logged in according to FILE.")); + println!( + "{}", + opts.usage("Output who is currently logged in according to FILE.") + ); return 0; } diff --git a/src/uucore/coreopts.rs b/src/uucore/coreopts.rs index 76895b612..58518540f 100644 --- a/src/uucore/coreopts.rs +++ b/src/uucore/coreopts.rs @@ -1,56 +1,84 @@ extern crate getopts; pub struct HelpText<'a> { - pub name : &'a str, - pub version : &'a str, - pub syntax : &'a str, - pub summary : &'a str, - pub long_help : &'a str, - pub display_usage : bool + pub name: &'a str, + pub version: &'a str, + pub syntax: &'a str, + pub summary: &'a str, + pub long_help: &'a str, + pub display_usage: bool, } pub struct CoreOptions<'a> { - options : getopts::Options, - help_text : HelpText<'a> + options: getopts::Options, + help_text: HelpText<'a>, } impl<'a> CoreOptions<'a> { pub fn new(help_text: HelpText<'a>) -> Self { let mut ret = CoreOptions { - options : getopts::Options::new(), - help_text : help_text + options: getopts::Options::new(), + help_text: help_text, }; ret.options .optflag("", "help", "print usage information") .optflag("", "version", "print name and version number"); ret } - pub fn optflagopt(&mut self, short_name: &str, long_name: &str, desc: &str, hint: &str) -> &mut CoreOptions<'a> { + pub fn optflagopt( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + hint: &str, + ) -> &mut CoreOptions<'a> { self.options.optflagopt(short_name, long_name, desc, hint); self } - pub fn optflag(&mut self, short_name: &str, long_name: &str, desc: &str) -> &mut CoreOptions<'a> { + pub fn optflag( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + ) -> &mut CoreOptions<'a> { self.options.optflag(short_name, long_name, desc); self } - pub fn optflagmulti(&mut self, short_name: &str, long_name: &str, desc: &str) -> &mut CoreOptions<'a> { + pub fn optflagmulti( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + ) -> &mut CoreOptions<'a> { self.options.optflagmulti(short_name, long_name, desc); self } - pub fn optopt(&mut self, short_name: &str, long_name: &str, desc: &str, hint: &str) -> &mut CoreOptions<'a> { + pub fn optopt( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + hint: &str, + ) -> &mut CoreOptions<'a> { self.options.optopt(short_name, long_name, desc, hint); self } - pub fn optmulti(&mut self, short_name: &str, long_name: &str, desc: &str, hint: &str) -> &mut CoreOptions<'a> { + pub fn optmulti( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + hint: &str, + ) -> &mut CoreOptions<'a> { self.options.optmulti(short_name, long_name, desc, hint); self } - pub fn usage(&self, summary : &str) -> String { + pub fn usage(&self, summary: &str) -> String { self.options.usage(summary) } - pub fn parse(&mut self, args : Vec) -> getopts::Matches { + pub fn parse(&mut self, args: Vec) -> getopts::Matches { let matches = match self.options.parse(&args[1..]) { - Ok(m) => { Some(m) }, + Ok(m) => Some(m), Err(f) => { eprint!("{}: error: ", self.help_text.name); eprintln!("{}", f); @@ -59,16 +87,26 @@ impl<'a> CoreOptions<'a> { }.unwrap(); if matches.opt_present("help") { let usage_str = if self.help_text.display_usage { - format!("\n {}\n\n Reference\n", - self.options.usage(self.help_text.summary) - ).replace("Options:", " Options:") - } else { String::new() }; - print!(" + format!( + "\n {}\n\n Reference\n", + self.options.usage(self.help_text.summary) + ).replace("Options:", " Options:") + } else { + String::new() + }; + print!( + " {0} {1} {0} {2} {3}{4} -", self.help_text.name, self.help_text.version, self.help_text.syntax, usage_str, self.help_text.long_help); +", + self.help_text.name, + self.help_text.version, + self.help_text.syntax, + usage_str, + self.help_text.long_help + ); exit!(0); } else if matches.opt_present("version") { println!("{} {}", self.help_text.name, self.help_text.version); diff --git a/src/uucore/encoding.rs b/src/uucore/encoding.rs index 4e2273c25..f2ff75dd2 100644 --- a/src/uucore/encoding.rs +++ b/src/uucore/encoding.rs @@ -7,7 +7,7 @@ // extern crate data_encoding; -use self::data_encoding::{base64, base32, decode}; +use self::data_encoding::{decode, base32, base64}; use std::io::Read; pub type DecodeResult = Result, decode::Error>; @@ -70,12 +70,12 @@ impl Data { self.input.read_to_string(&mut buf).unwrap(); let clean = if self.ignore_garbage { buf.chars() - .filter(|&c| self.alphabet.contains(c)) - .collect::() + .filter(|&c| self.alphabet.contains(c)) + .collect::() } else { buf.chars() - .filter(|&c| c != '\r' && c != '\n') - .collect::() + .filter(|&c| c != '\r' && c != '\n') + .collect::() }; decode(self.format, clean.as_bytes()) } diff --git a/src/uucore/entries.rs b/src/uucore/entries.rs index 5dae92dd3..3120d54e2 100644 --- a/src/uucore/entries.rs +++ b/src/uucore/entries.rs @@ -27,24 +27,29 @@ #[cfg(any(target_os = "freebsd", target_os = "macos"))] use libc::time_t; -use libc::{uid_t, gid_t, c_char, c_int}; -use libc::{passwd, group, getpwnam, getpwuid, getgrnam, getgrgid, getgroups}; +use libc::{c_char, c_int, gid_t, uid_t}; +use libc::{getgrgid, getgrnam, getgroups, getpwnam, getpwuid, group, passwd}; -use ::std::ptr; -use ::std::io::ErrorKind; -use ::std::io::Error as IOError; -use ::std::io::Result as IOResult; -use ::std::ffi::{CStr, CString}; -use ::std::borrow::Cow; +use std::ptr; +use std::io::ErrorKind; +use std::io::Error as IOError; +use std::io::Result as IOResult; +use std::ffi::{CStr, CString}; +use std::borrow::Cow; extern "C" { - fn getgrouplist(name: *const c_char, gid: gid_t, groups: *mut gid_t, ngroups: *mut c_int) -> c_int; + fn getgrouplist( + name: *const c_char, + gid: gid_t, + groups: *mut gid_t, + ngroups: *mut c_int, + ) -> c_int; } pub fn get_groups() -> IOResult> { let ngroups = unsafe { getgroups(0, ptr::null_mut()) }; if ngroups == -1 { - return Err(IOError::last_os_error()) + return Err(IOError::last_os_error()); } let mut groups = Vec::with_capacity(ngroups as usize); let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) }; @@ -173,7 +178,9 @@ impl Group { /// Fetch desired entry. pub trait Locate { - fn locate(key: K) -> IOResult where Self: ::std::marker::Sized; + fn locate(key: K) -> IOResult + where + Self: ::std::marker::Sized; } macro_rules! f { diff --git a/src/uucore/fs.rs b/src/uucore/fs.rs index 6cc0d58da..1fbf46de0 100644 --- a/src/uucore/fs.rs +++ b/src/uucore/fs.rs @@ -31,9 +31,9 @@ pub fn resolve_relative_path<'a>(path: &'a Path) -> Cow<'a, Path> { result.pop(); } Component::CurDir => (), - Component::RootDir | - Component::Normal(_) | - Component::Prefix(_) => result.push(comp.as_os_str()), + Component::RootDir | Component::Normal(_) | Component::Prefix(_) => { + result.push(comp.as_os_str()) + } } } result.into() @@ -53,7 +53,10 @@ fn resolve>(original: P) -> IOResult { let mut result = original.as_ref().to_path_buf(); loop { if followed == MAX_LINKS_FOLLOWED { - return Err(Error::new(ErrorKind::InvalidInput, "maximum links followed")); + return Err(Error::new( + ErrorKind::InvalidInput, + "maximum links followed", + )); } match fs::symlink_metadata(&result) { @@ -93,8 +96,7 @@ pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> // vector for canonicalization. for part in original.components() { match part { - Component::Prefix(_) | - Component::RootDir => { + Component::Prefix(_) | Component::RootDir => { result.push(part.as_os_str()); } Component::CurDir => (), @@ -117,12 +119,10 @@ pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> } match resolve(&result) { - Err(e) => { - match can_mode { - CanonicalizeMode::Missing => continue, - _ => return Err(e), - } - } + Err(e) => match can_mode { + CanonicalizeMode::Missing => continue, + _ => return Err(e), + }, Ok(path) => { result.pop(); result.push(path); diff --git a/src/uucore/mode.rs b/src/uucore/mode.rs index f8d2123d2..7a08652db 100644 --- a/src/uucore/mode.rs +++ b/src/uucore/mode.rs @@ -15,20 +15,22 @@ pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result { Err(format!("mode is too large ({} > 7777)", mode)) } else { match u32::from_str_radix(mode, 8) { - Ok(change) => { - Ok(match op { - '+' => fperm | change, - '-' => fperm & !change, - '=' => change, - _ => unreachable!() - }) - } - Err(err) => Err(err.description().to_owned()) + Ok(change) => Ok(match op { + '+' => fperm | change, + '-' => fperm & !change, + '=' => change, + _ => unreachable!(), + }), + Err(err) => Err(err.description().to_owned()), } } } -pub fn parse_symbolic(mut fperm: u32, mut mode: &str, considering_dir: bool) -> Result { +pub fn parse_symbolic( + mut fperm: u32, + mut mode: &str, + considering_dir: bool, +) -> Result { #[cfg(unix)] use libc::umask; @@ -43,9 +45,7 @@ pub fn parse_symbolic(mut fperm: u32, mut mode: &str, considering_dir: bool) -> return Err(format!("invalid mode ({})", mode)); } let respect_umask = pos == 0; - let last_umask = unsafe { - umask(0) - }; + let last_umask = unsafe { umask(0) }; mode = &mode[pos..]; while mode.len() > 0 { let (op, pos) = parse_op(mode, None)?; @@ -59,7 +59,7 @@ pub fn parse_symbolic(mut fperm: u32, mut mode: &str, considering_dir: bool) -> '+' => fperm |= srwx & mask, '-' => fperm &= !(srwx & mask), '=' => fperm = (fperm & !mask) | (srwx & mask), - _ => unreachable!() + _ => unreachable!(), } } unsafe { @@ -77,12 +77,12 @@ fn parse_levels(mode: &str) -> (u32, usize) { 'g' => 0o7070, 'o' => 0o7007, 'a' => 0o7777, - _ => break + _ => break, }; pos += 1; } if pos == 0 { - mask = 0o7777; // default to 'a' + mask = 0o7777; // default to 'a' } (mask, pos) } @@ -93,10 +93,13 @@ fn parse_op(mode: &str, default: Option) -> Result<(char, usize), String> '+' | '-' | '=' => Ok((ch, 1)), _ => match default { Some(ch) => Ok((ch, 0)), - None => Err(format!("invalid operator (expected +, -, or =, but found {})", ch)) - } + None => Err(format!( + "invalid operator (expected +, -, or =, but found {})", + ch + )), + }, }, - None => Err("unexpected end of mode".to_owned()) + None => Err("unexpected end of mode".to_owned()), } } @@ -118,7 +121,7 @@ fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) { 'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007), 'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007), 'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007), - _ => break + _ => break, }; pos += 1; } @@ -126,4 +129,4 @@ fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) { srwx = 0; } (srwx, pos) -} \ No newline at end of file +} diff --git a/src/uucore/panic.rs b/src/uucore/panic.rs index 765e035ab..5cccca4ba 100644 --- a/src/uucore/panic.rs +++ b/src/uucore/panic.rs @@ -1,6 +1,6 @@ use std::panic; -pub fn install_sigpipe_hook() { +pub fn install_sigpipe_hook() { let hook = panic::take_hook(); panic::set_hook(Box::new(move |info| { if let Some(res) = info.payload().downcast_ref::() { diff --git a/src/uucore/parse_time.rs b/src/uucore/parse_time.rs index 05b9f17b1..260455f7d 100644 --- a/src/uucore/parse_time.rs +++ b/src/uucore/parse_time.rs @@ -12,7 +12,7 @@ use std::time::Duration; pub fn from_str(string: &str) -> Result { let len = string.len(); if len == 0 { - return Err("empty string".to_owned()) + return Err("empty string".to_owned()); } let slice = &string[..len - 1]; let (numstr, times) = match string.chars().next_back().unwrap() { @@ -26,13 +26,13 @@ pub fn from_str(string: &str) -> Result { } else if string == "inf" || string == "infinity" { ("inf", 1) } else { - return Err(format!("invalid time interval '{}'", string)) + return Err(format!("invalid time interval '{}'", string)); } } }; let num = match numstr.parse::() { Ok(m) => m, - Err(e) => return Err(format!("invalid time interval '{}': {}", string, e)) + Err(e) => return Err(format!("invalid time interval '{}': {}", string, e)), }; const NANOS_PER_SEC: u32 = 1_000_000_000; diff --git a/src/uucore/process.rs b/src/uucore/process.rs index f6aec5166..11888ae66 100644 --- a/src/uucore/process.rs +++ b/src/uucore/process.rs @@ -8,7 +8,7 @@ // use super::libc; -use libc::{c_int, pid_t, uid_t, gid_t}; +use libc::{c_int, gid_t, pid_t, uid_t}; use std::fmt; use std::io; use std::process::Child; @@ -17,27 +17,19 @@ use std::thread; use std::time::{Duration, Instant}; pub fn geteuid() -> uid_t { - unsafe { - libc::geteuid() - } + unsafe { libc::geteuid() } } pub fn getegid() -> gid_t { - unsafe { - libc::getegid() - } + unsafe { libc::getegid() } } pub fn getgid() -> gid_t { - unsafe { - libc::getgid() - } + unsafe { libc::getgid() } } pub fn getuid() -> uid_t { - unsafe { - libc::getuid() - } + unsafe { libc::getuid() } } // This is basically sys::unix::process::ExitStatus @@ -109,7 +101,10 @@ impl ChildExt for Child { fn wait_or_timeout(&mut self, timeout: Duration) -> io::Result> { // The result will be written to that Option, protected by a Mutex // Then the Condvar will be signaled - let state = Arc::new((Mutex::new(Option::None::>), Condvar::new())); + let state = Arc::new(( + Mutex::new(Option::None::>), + Condvar::new(), + )); // Start the waiting thread let state_th = state.clone(); diff --git a/src/uucore/signals.rs b/src/uucore/signals.rs index db360975a..8887ddfe1 100644 --- a/src/uucore/signals.rs +++ b/src/uucore/signals.rs @@ -7,10 +7,12 @@ * that was distributed with this source code. */ -pub static DEFAULT_SIGNAL:usize= 15; +pub static DEFAULT_SIGNAL: usize = 15; - -pub struct Signal<'a> { pub name:&'a str, pub value: usize} +pub struct Signal<'a> { + pub name: &'a str, + pub value: usize, +} /* @@ -26,41 +28,133 @@ Linux Programmer's Manual */ #[cfg(target_os = "linux")] -pub static ALL_SIGNALS:[Signal<'static>; 31] = [ - Signal{ name: "HUP", value:1 }, - Signal{ name: "INT", value:2 }, - Signal{ name: "QUIT", value:3 }, - Signal{ name: "ILL", value:4 }, - Signal{ name: "TRAP", value:5 }, - Signal{ name: "ABRT", value:6 }, - Signal{ name: "BUS", value:7 }, - Signal{ name: "FPE", value:8 }, - Signal{ name: "KILL", value:9 }, - Signal{ name: "USR1", value:10 }, - Signal{ name: "SEGV", value:11 }, - Signal{ name: "USR2", value:12 }, - Signal{ name: "PIPE", value:13 }, - Signal{ name: "ALRM", value:14 }, - Signal{ name: "TERM", value:15 }, - Signal{ name: "STKFLT", value:16 }, - Signal{ name: "CHLD", value:17 }, - Signal{ name: "CONT", value:18 }, - Signal{ name: "STOP", value:19 }, - Signal{ name: "TSTP", value:20 }, - Signal{ name: "TTIN", value:21 }, - Signal{ name: "TTOU", value:22 }, - Signal{ name: "URG", value:23 }, - Signal{ name: "XCPU", value:24 }, - Signal{ name: "XFSZ", value:25 }, - Signal{ name: "VTALRM", value:26 }, - Signal{ name: "PROF", value:27 }, - Signal{ name: "WINCH", value:28 }, - Signal{ name: "POLL", value:29 }, - Signal{ name: "PWR", value:30 }, - Signal{ name: "SYS", value:31 }, +pub static ALL_SIGNALS: [Signal<'static>; 31] = [ + Signal { + name: "HUP", + value: 1, + }, + Signal { + name: "INT", + value: 2, + }, + Signal { + name: "QUIT", + value: 3, + }, + Signal { + name: "ILL", + value: 4, + }, + Signal { + name: "TRAP", + value: 5, + }, + Signal { + name: "ABRT", + value: 6, + }, + Signal { + name: "BUS", + value: 7, + }, + Signal { + name: "FPE", + value: 8, + }, + Signal { + name: "KILL", + value: 9, + }, + Signal { + name: "USR1", + value: 10, + }, + Signal { + name: "SEGV", + value: 11, + }, + Signal { + name: "USR2", + value: 12, + }, + Signal { + name: "PIPE", + value: 13, + }, + Signal { + name: "ALRM", + value: 14, + }, + Signal { + name: "TERM", + value: 15, + }, + Signal { + name: "STKFLT", + value: 16, + }, + Signal { + name: "CHLD", + value: 17, + }, + Signal { + name: "CONT", + value: 18, + }, + Signal { + name: "STOP", + value: 19, + }, + Signal { + name: "TSTP", + value: 20, + }, + Signal { + name: "TTIN", + value: 21, + }, + Signal { + name: "TTOU", + value: 22, + }, + Signal { + name: "URG", + value: 23, + }, + Signal { + name: "XCPU", + value: 24, + }, + Signal { + name: "XFSZ", + value: 25, + }, + Signal { + name: "VTALRM", + value: 26, + }, + Signal { + name: "PROF", + value: 27, + }, + Signal { + name: "WINCH", + value: 28, + }, + Signal { + name: "POLL", + value: 29, + }, + Signal { + name: "PWR", + value: 30, + }, + Signal { + name: "SYS", + value: 31, + }, ]; - /* @@ -103,38 +197,131 @@ No Name Default Action Description */ #[cfg(any(target_os = "macos", target_os = "freebsd"))] -pub static ALL_SIGNALS:[Signal<'static>; 31] = [ - Signal{ name: "HUP", value:1 }, - Signal{ name: "INT", value:2 }, - Signal{ name: "QUIT", value:3 }, - Signal{ name: "ILL", value:4 }, - Signal{ name: "TRAP", value:5 }, - Signal{ name: "ABRT", value:6 }, - Signal{ name: "EMT", value:7 }, - Signal{ name: "FPE", value:8 }, - Signal{ name: "KILL", value:9 }, - Signal{ name: "BUS", value:10 }, - Signal{ name: "SEGV", value:11 }, - Signal{ name: "SYS", value:12 }, - Signal{ name: "PIPE", value:13 }, - Signal{ name: "ALRM", value:14 }, - Signal{ name: "TERM", value:15 }, - Signal{ name: "URG", value:16 }, - Signal{ name: "STOP", value:17 }, - Signal{ name: "TSTP", value:18 }, - Signal{ name: "CONT", value:19 }, - Signal{ name: "CHLD", value:20 }, - Signal{ name: "TTIN", value:21 }, - Signal{ name: "TTOU", value:22 }, - Signal{ name: "IO", value:23 }, - Signal{ name: "XCPU", value:24 }, - Signal{ name: "XFSZ", value:25 }, - Signal{ name: "VTALRM", value:26 }, - Signal{ name: "PROF", value:27 }, - Signal{ name: "WINCH", value:28 }, - Signal{ name: "INFO", value:29 }, - Signal{ name: "USR1", value:30 }, - Signal{ name: "USR2", value:31 }, +pub static ALL_SIGNALS: [Signal<'static>; 31] = [ + Signal { + name: "HUP", + value: 1, + }, + Signal { + name: "INT", + value: 2, + }, + Signal { + name: "QUIT", + value: 3, + }, + Signal { + name: "ILL", + value: 4, + }, + Signal { + name: "TRAP", + value: 5, + }, + Signal { + name: "ABRT", + value: 6, + }, + Signal { + name: "EMT", + value: 7, + }, + Signal { + name: "FPE", + value: 8, + }, + Signal { + name: "KILL", + value: 9, + }, + Signal { + name: "BUS", + value: 10, + }, + Signal { + name: "SEGV", + value: 11, + }, + Signal { + name: "SYS", + value: 12, + }, + Signal { + name: "PIPE", + value: 13, + }, + Signal { + name: "ALRM", + value: 14, + }, + Signal { + name: "TERM", + value: 15, + }, + Signal { + name: "URG", + value: 16, + }, + Signal { + name: "STOP", + value: 17, + }, + Signal { + name: "TSTP", + value: 18, + }, + Signal { + name: "CONT", + value: 19, + }, + Signal { + name: "CHLD", + value: 20, + }, + Signal { + name: "TTIN", + value: 21, + }, + Signal { + name: "TTOU", + value: 22, + }, + Signal { + name: "IO", + value: 23, + }, + Signal { + name: "XCPU", + value: 24, + }, + Signal { + name: "XFSZ", + value: 25, + }, + Signal { + name: "VTALRM", + value: 26, + }, + Signal { + name: "PROF", + value: 27, + }, + Signal { + name: "WINCH", + value: 28, + }, + Signal { + name: "INFO", + value: 29, + }, + Signal { + name: "USR1", + value: 30, + }, + Signal { + name: "USR2", + value: 31, + }, ]; pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option { @@ -143,7 +330,9 @@ pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option { } for signal in &ALL_SIGNALS { let long_name = format!("SIG{}", signal.name); - if signal.name == signal_name_or_value || (signal_name_or_value == signal.value.to_string()) || (long_name == signal_name_or_value) { + if signal.name == signal_name_or_value || (signal_name_or_value == signal.value.to_string()) + || (long_name == signal_name_or_value) + { return Some(signal.value); } } diff --git a/src/uucore/utf8.rs b/src/uucore/utf8.rs index a6c48b785..f2d2137a2 100644 --- a/src/uucore/utf8.rs +++ b/src/uucore/utf8.rs @@ -25,4 +25,3 @@ static UTF8_CHAR_WIDTH: [u8; 256] = [ pub fn utf8_char_width(b: u8) -> usize { return UTF8_CHAR_WIDTH[b as usize] as usize; } - diff --git a/src/uucore/utmpx.rs b/src/uucore/utmpx.rs index ddf976ab9..db0605a4e 100644 --- a/src/uucore/utmpx.rs +++ b/src/uucore/utmpx.rs @@ -33,12 +33,12 @@ use super::libc; pub extern crate time; -use self::time::{Tm, Timespec}; +use self::time::{Timespec, Tm}; -use ::std::io::Result as IOResult; -use ::std::io::Error as IOError; -use ::std::ptr; -use ::std::ffi::CString; +use std::io::Result as IOResult; +use std::io::Error as IOError; +use std::ptr; +use std::ffi::CString; pub use self::ut::*; use libc::utmpx; @@ -159,8 +159,10 @@ impl Utmpx { } /// A.K.A. ut.ut_tv pub fn login_time(&self) -> Tm { - time::at(Timespec::new(self.inner.ut_tv.tv_sec as i64, - self.inner.ut_tv.tv_usec as i32)) + time::at(Timespec::new( + self.inner.ut_tv.tv_sec as i64, + self.inner.ut_tv.tv_usec as i32, + )) } /// A.K.A. ut.ut_exit /// @@ -202,10 +204,12 @@ impl Utmpx { let c_host = CString::new(host).unwrap(); let mut res = ptr::null_mut(); let status = unsafe { - libc::getaddrinfo(c_host.as_ptr(), - ptr::null(), - &hints as *const _, - &mut res as *mut _) + libc::getaddrinfo( + c_host.as_ptr(), + ptr::null(), + &hints as *const _, + &mut res as *mut _, + ) }; if status == 0 { let info: libc::addrinfo = unsafe { ptr::read(res as *const _) }; @@ -255,7 +259,9 @@ impl Iterator for UtmpxIter { unsafe { let res = getutxent(); if !res.is_null() { - Some(Utmpx { inner: ptr::read(res as *const _) }) + Some(Utmpx { + inner: ptr::read(res as *const _), + }) } else { endutxent(); None diff --git a/src/uucore/wide.rs b/src/uucore/wide.rs index 189e84438..23088183b 100644 --- a/src/uucore/wide.rs +++ b/src/uucore/wide.rs @@ -12,7 +12,10 @@ pub trait ToWide { fn to_wide(&self) -> Vec; fn to_wide_null(&self) -> Vec; } -impl ToWide for T where T: AsRef { +impl ToWide for T +where + T: AsRef, +{ fn to_wide(&self) -> Vec { self.as_ref().encode_wide().collect() } @@ -30,6 +33,8 @@ impl FromWide for String { } fn from_wide_null(wide: &[u16]) -> String { let len = wide.iter().take_while(|&&c| c != 0).count(); - OsString::from_wide(&wide[..len]).to_string_lossy().into_owned() + OsString::from_wide(&wide[..len]) + .to_string_lossy() + .into_owned() } -} \ No newline at end of file +} diff --git a/src/uutils/uutils.rs b/src/uutils/uutils.rs index 7ecf7a234..2bcefd6f2 100644 --- a/src/uutils/uutils.rs +++ b/src/uutils/uutils.rs @@ -40,7 +40,7 @@ fn main() { uucore::panic::install_sigpipe_hook(); let umap = util_map(); - let mut args : Vec = env::args().collect(); + let mut args: Vec = env::args().collect(); // try binary name as util name. let args0 = args[0].clone(); @@ -51,8 +51,9 @@ fn main() { std::process::exit(uumain(args)); } - if binary_as_util.ends_with("uutils") || binary_as_util.starts_with("uutils") || - binary_as_util.ends_with("busybox") || binary_as_util.starts_with("busybox") { + if binary_as_util.ends_with("uutils") || binary_as_util.starts_with("uutils") + || binary_as_util.ends_with("busybox") || binary_as_util.starts_with("busybox") + { args.remove(0); } else { let mut found = false; @@ -63,7 +64,7 @@ fn main() { break; } } - if ! found { + if !found { println!("{}: applet not found", binary_as_util); std::process::exit(1); } @@ -71,7 +72,6 @@ fn main() { // try first arg as util name. if args.len() >= 1 { - let util = &args[0][..]; match umap.get(util) { diff --git a/src/wc/wc.rs b/src/wc/wc.rs index 65426e202..c7a3857f5 100644 --- a/src/wc/wc.rs +++ b/src/wc/wc.rs @@ -42,11 +42,9 @@ impl Settings { show_max_line_length: matches.opt_present("L"), }; - if settings.show_bytes - || settings.show_chars - || settings.show_lines - || settings.show_words - || settings.show_max_line_length { + if settings.show_bytes || settings.show_chars || settings.show_lines || settings.show_words + || settings.show_max_line_length + { return settings; } @@ -78,14 +76,18 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("c", "bytes", "print the byte counts"); opts.optflag("m", "chars", "print the character counts"); opts.optflag("l", "lines", "print the newline counts"); - opts.optflag("L", "max-line-length", "print the length of the longest line"); + opts.optflag( + "L", + "max-line-length", + "print the length of the longest line", + ); opts.optflag("w", "words", "print the word counts"); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); let mut matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f) + Err(f) => crash!(1, "Invalid options\n{}", f), }; if matches.opt_present("help") { @@ -94,7 +96,10 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {0} [OPTION]... [FILE]...", NAME); println!(""); - println!("{}", opts.usage("Print newline, word and byte counts for each FILE")); + println!( + "{}", + opts.usage("Print newline, word and byte counts for each FILE") + ); println!("With no FILE, or when FILE is -, read standard input."); return 0; } @@ -112,7 +117,7 @@ pub fn uumain(args: Vec) -> i32 { match wc(matches.free, &settings) { Ok(()) => ( /* pass */ ), - Err(e) => return e + Err(e) => return e, } 0 @@ -137,7 +142,7 @@ fn wc(files: Vec, settings: &Settings) -> StdResult<(), i32> { let mut total_byte_count: usize = 0; let mut total_longest_line_length: usize = 0; - let mut results = vec!(); + let mut results = vec![]; let mut max_width: usize = 0; for path in &files { @@ -157,7 +162,7 @@ fn wc(files: Vec, settings: &Settings) -> StdResult<(), i32> { Err(ref e) if !raw_line.is_empty() => { show_warning!("Error while reading {}: {}", path, e); !raw_line.is_empty() - }, + } _ => false, } { // GNU 'wc' only counts lines that end in LF as lines @@ -173,10 +178,10 @@ fn wc(files: Vec, settings: &Settings) -> StdResult<(), i32> { Ok(line) => { word_count += line.split_whitespace().count(); current_char_count = line.chars().count(); - }, + } Err(..) => { word_count += raw_line.split(|&x| is_word_seperator(x)).count(); - current_char_count = raw_line.iter().filter(|c|c.is_ascii()).count() + current_char_count = raw_line.iter().filter(|c| c.is_ascii()).count() } } char_count += current_char_count; @@ -250,13 +255,12 @@ fn print_stats(settings: &Settings, result: &Result, max_width: usize) { if result.title != "-" { println!(" {}", result.title); - } - else { + } else { println!(""); } } -fn open(path: &str) -> StdResult>, i32> { +fn open(path: &str) -> StdResult>, i32> { if "-" == path { let reader = Box::new(stdin()) as Box; return Ok(BufReader::new(reader)); diff --git a/src/who/who.rs b/src/who/who.rs index 47214eb1a..ea32749f9 100644 --- a/src/who/who.rs +++ b/src/who/who.rs @@ -6,13 +6,13 @@ // file that was distributed with this source code. // #![crate_name = "uu_who"] -#![cfg_attr(feature="clippy", feature(plugin))] -#![cfg_attr(feature="clippy", plugin(clippy))] +#![cfg_attr(feature = "clippy", feature(plugin))] +#![cfg_attr(feature = "clippy", plugin(clippy))] #[macro_use] extern crate uucore; use uucore::utmpx::{self, time, Utmpx}; -use uucore::libc::{STDIN_FILENO, ttyname, S_IWGRP}; +use uucore::libc::{ttyname, STDIN_FILENO, S_IWGRP}; use std::borrow::Cow; use std::ffi::CStr; @@ -46,7 +46,6 @@ If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual. "; pub fn uumain(args: Vec) -> i32 { - let mut opts = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP); opts.optflag("a", "all", "same as -b -d --login -p -r -t -T -u"); opts.optflag("b", "boot", "time of last system boot"); @@ -56,9 +55,11 @@ pub fn uumain(args: Vec) -> i32 { opts.optflag("", "lookup", "attempt to canonicalize hostnames via DNS"); opts.optflag("m", "", "only hostname and user associated with stdin"); opts.optflag("p", "process", "print active processes spawned by init"); - opts.optflag("q", - "count", - "all login names and number of users logged on"); + opts.optflag( + "q", + "count", + "all login names and number of users logged on", + ); opts.optflag("r", "runlevel", "print current runlevel"); opts.optflag("s", "short", "print only name, line, and time (default)"); opts.optflag("t", "time", "print last system clock change"); @@ -94,7 +95,8 @@ pub fn uumain(args: Vec) -> i32 { // If true, display a '+' for each user if mesg y, a '-' if mesg n, // or a '?' if their tty cannot be statted. - let include_mesg = matches.opt_present("a") || matches.opt_present("T") || matches.opt_present("w"); + let include_mesg = + matches.opt_present("a") || matches.opt_present("T") || matches.opt_present("w"); // If true, display process termination & exit status. let mut include_exit = false; @@ -256,10 +258,11 @@ fn idle_string<'a>(when: i64, boottime: i64) -> Cow<'a, str> { if seconds_idle < 60 { " . ".into() } else { - format!("{:02}:{:02}", - seconds_idle / 3600, - (seconds_idle % 3600) / 60) - .into() + format!( + "{:02}:{:02}", + seconds_idle / 3600, + (seconds_idle % 3600) / 60 + ).into() } } else { " old ".into() @@ -276,7 +279,10 @@ fn current_tty() -> String { unsafe { let res = ttyname(STDIN_FILENO); if !res.is_null() { - CStr::from_ptr(res as *const _).to_string_lossy().trim_left_matches("/dev/").to_owned() + CStr::from_ptr(res as *const _) + .to_string_lossy() + .trim_left_matches("/dev/") + .to_owned() } else { "".to_owned() } @@ -330,9 +336,7 @@ impl Who { } } - if ut.record_type() == utmpx::BOOT_TIME { - - } + if ut.record_type() == utmpx::BOOT_TIME {} } } } @@ -342,25 +346,18 @@ impl Who { let last = (ut.pid() / 256) as u8 as char; let curr = (ut.pid() % 256) as u8 as char; let runlvline = format!("run-level {}", curr); - let comment = format!("last={}", - if last == 'N' { - 'S' - } else { - 'N' - }); + let comment = format!("last={}", if last == 'N' { 'S' } else { 'N' }); - self.print_line("", - ' ', - &runlvline, - &time_string(ut), - "", - "", - if !last.is_control() { - &comment - } else { - "" - }, - ""); + self.print_line( + "", + ' ', + &runlvline, + &time_string(ut), + "", + "", + if !last.is_control() { &comment } else { "" }, + "", + ); } #[inline] @@ -372,14 +369,16 @@ impl Who { fn print_login(&self, ut: &Utmpx) { let comment = format!("id={}", ut.terminal_suffix()); let pidstr = format!("{}", ut.pid()); - self.print_line("LOGIN", - ' ', - &ut.tty_device(), - &time_string(ut), - "", - &pidstr, - &comment, - ""); + self.print_line( + "LOGIN", + ' ', + &ut.tty_device(), + &time_string(ut), + "", + &pidstr, + &comment, + "", + ); } #[inline] @@ -388,28 +387,32 @@ impl Who { let pidstr = format!("{}", ut.pid()); let e = ut.exit_status(); let exitstr = format!("term={} exit={}", e.0, e.1); - self.print_line("", - ' ', - &ut.tty_device(), - &time_string(ut), - "", - &pidstr, - &comment, - &exitstr); + self.print_line( + "", + ' ', + &ut.tty_device(), + &time_string(ut), + "", + &pidstr, + &comment, + &exitstr, + ); } #[inline] fn print_initspawn(&self, ut: &Utmpx) { let comment = format!("id={}", ut.terminal_suffix()); let pidstr = format!("{}", ut.pid()); - self.print_line("", - ' ', - &ut.tty_device(), - &time_string(ut), - "", - &pidstr, - &comment, - ""); + self.print_line( + "", + ' ', + &ut.tty_device(), + &time_string(ut), + "", + &pidstr, + &comment, + "", + ); } #[inline] @@ -457,31 +460,31 @@ impl Who { buf.push(h.to_owned()); } let s = buf.join(":"); - let hoststr = if s.is_empty() { - s - } else { - format!("({})", s) - }; + let hoststr = if s.is_empty() { s } else { format!("({})", s) }; - self.print_line(ut.user().as_ref(), - mesg, - ut.tty_device().as_ref(), - time_string(ut).as_str(), - idle.as_ref(), - format!("{}", ut.pid()).as_str(), - hoststr.as_str(), - ""); + self.print_line( + ut.user().as_ref(), + mesg, + ut.tty_device().as_ref(), + time_string(ut).as_str(), + idle.as_ref(), + format!("{}", ut.pid()).as_str(), + hoststr.as_str(), + "", + ); } - fn print_line(&self, - user: &str, - state: char, - line: &str, - time: &str, - idle: &str, - pid: &str, - comment: &str, - exit: &str) { + fn print_line( + &self, + user: &str, + state: char, + line: &str, + time: &str, + idle: &str, + pid: &str, + comment: &str, + exit: &str, + ) { let mut buf = String::with_capacity(64); let msg = vec![' ', state].into_iter().collect::(); @@ -512,13 +515,15 @@ impl Who { #[inline] fn print_heading(&self) { - self.print_line("NAME", - ' ', - "LINE", - "TIME", - "IDLE", - "PID", - "COMMENT", - "EXIT"); + self.print_line( + "NAME", + ' ', + "LINE", + "TIME", + "IDLE", + "PID", + "COMMENT", + "EXIT", + ); } } diff --git a/src/whoami/platform/windows.rs b/src/whoami/platform/windows.rs index 8014047a1..b321b93be 100644 --- a/src/whoami/platform/windows.rs +++ b/src/whoami/platform/windows.rs @@ -7,9 +7,9 @@ * file that was distributed with this source code. */ -extern crate winapi; extern crate advapi32; extern crate uucore; +extern crate winapi; use std::io::{Error, Result}; use std::mem; @@ -22,7 +22,7 @@ pub unsafe fn getusername() -> Result { let mut buffer: [winnt::WCHAR; lmcons::UNLEN as usize + 1] = mem::uninitialized(); let mut len = buffer.len() as minwindef::DWORD; if advapi32::GetUserNameW(buffer.as_mut_ptr(), &mut len) == 0 { - return Err(Error::last_os_error()) + return Err(Error::last_os_error()); } let username = String::from_wide(&buffer[..len as usize - 1]); Ok(username) diff --git a/src/whoami/whoami.rs b/src/whoami/whoami.rs index 26200dfef..13bcc586a 100644 --- a/src/whoami/whoami.rs +++ b/src/whoami/whoami.rs @@ -59,7 +59,7 @@ pub fn exec() { Err(err) => match err.raw_os_error() { Some(0) | None => crash!(1, "failed to get username"), Some(_) => crash!(1, "failed to get username: {}", err), - } + }, } } } diff --git a/src/yes/yes.rs b/src/yes/yes.rs index 544e12213..99b4efb81 100644 --- a/src/yes/yes.rs +++ b/src/yes/yes.rs @@ -31,7 +31,7 @@ pub fn uumain(args: Vec) -> i32 { let matches = match opts.parse(&args[1..]) { Ok(m) => m, - Err(f) => crash!(1, "invalid options\n{}", f) + Err(f) => crash!(1, "invalid options\n{}", f), }; if matches.opt_present("help") { println!("{} {}", NAME, VERSION); @@ -39,7 +39,10 @@ pub fn uumain(args: Vec) -> i32 { println!("Usage:"); println!(" {0} [STRING]... [OPTION]...", NAME); println!(""); - print!("{}", opts.usage("Repeatedly output a line with all specified STRING(s), or 'y'.")); + print!( + "{}", + opts.usage("Repeatedly output a line with all specified STRING(s), or 'y'.") + ); return 0; } if matches.opt_present("version") { @@ -64,5 +67,7 @@ pub fn uumain(args: Vec) -> i32 { } pub fn exec(string: &str) { - loop { println!("{}", string) } + loop { + println!("{}", string) + } } diff --git a/tests/common/util.rs b/tests/common/util.rs index a727f739d..1a0e4205e 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -3,13 +3,13 @@ extern crate tempdir; use std::env; use std::fs::{self, File, OpenOptions}; -use std::io::{Read, Write, Result}; +use std::io::{Read, Result, Write}; #[cfg(unix)] use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] use std::os::windows::fs::symlink_file; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio, Child}; +use std::process::{Child, Command, Stdio}; use std::str::from_utf8; use std::ffi::OsStr; use std::rc::Rc; @@ -25,9 +25,10 @@ static PROGNAME: &'static str = "uutils"; static TESTS_DIR: &'static str = "tests"; static FIXTURES_DIR: &'static str = "fixtures"; -static ALREADY_RUN: &'static str = " you have already run this UCommand, if you want to run \ - another command in the same test, use TestScenario::new instead of \ - testing();"; +static ALREADY_RUN: &'static str = + " you have already run this UCommand, if you want to run \ + another command in the same test, use TestScenario::new instead of \ + testing();"; static MULTIPLE_STDIN_MEANINGLESS: &'static str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly."; fn read_scenario_fixture>(tmpd: &Option>, file_rel_path: S) -> String { @@ -91,7 +92,10 @@ impl CmdResult { /// passed in value, when both are trimmed of trailing whitespace /// stdout_only is a better choice unless stderr may or will be non-empty pub fn stdout_is>(&self, msg: T) -> Box<&CmdResult> { - assert_eq!(String::from(msg.as_ref()).trim_right(), self.stdout.trim_right()); + assert_eq!( + String::from(msg.as_ref()).trim_right(), + self.stdout.trim_right() + ); Box::new(self) } @@ -105,7 +109,10 @@ impl CmdResult { /// passed in value, when both are trimmed of trailing whitespace /// stderr_only is a better choice unless stdout may or will be non-empty pub fn stderr_is>(&self, msg: T) -> Box<&CmdResult> { - assert_eq!(String::from(msg.as_ref()).trim_right(), self.stderr.trim_right()); + assert_eq!( + String::from(msg.as_ref()).trim_right(), + self.stderr.trim_right() + ); Box::new(self) } @@ -188,7 +195,9 @@ pub struct AtPath { impl AtPath { pub fn new(subdir: &Path) -> AtPath { - AtPath { subdir: PathBuf::from(subdir) } + AtPath { + subdir: PathBuf::from(subdir), + } } pub fn as_string(&self) -> String { @@ -209,8 +218,7 @@ impl AtPath { let prefixed = PathBuf::from(name); if prefixed.starts_with(&self.subdir) { let mut unprefixed = PathBuf::new(); - for component in prefixed.components() - .skip(self.subdir.components().count()) { + for component in prefixed.components().skip(self.subdir.components().count()) { unprefixed.push(component.as_os_str().to_str().unwrap()); } unprefixed @@ -242,7 +250,11 @@ impl AtPath { pub fn append(&self, name: &str, contents: &str) { log_info("open(append)", self.plus_as_string(name)); - let mut f = OpenOptions::new().write(true).append(true).open(self.plus(name)).unwrap(); + let mut f = OpenOptions::new() + .write(true) + .append(true) + .open(self.plus(name)) + .unwrap(); let _ = f.write(contents.as_bytes()); } @@ -268,8 +280,10 @@ impl AtPath { } pub fn symlink(&self, src: &str, dst: &str) { - log_info("symlink", - &format!("{},{}", self.plus_as_string(src), self.plus_as_string(dst))); + log_info( + "symlink", + &format!("{},{}", self.plus_as_string(src), self.plus_as_string(dst)), + ); symlink_file(&self.plus(src), &self.plus(dst)).unwrap(); } @@ -284,9 +298,7 @@ impl AtPath { pub fn resolve_link(&self, path: &str) -> String { log_info("resolve_link", self.plus_as_string(path)); match fs::read_link(&self.plus(path)) { - Ok(p) => { - self.minus_as_string(p.to_str().unwrap()) - } + Ok(p) => self.minus_as_string(p.to_str().unwrap()), Err(_) => "".to_string(), } } @@ -337,7 +349,12 @@ impl AtPath { pub fn root_dir_resolved(&self) -> String { log_info("current_directory_resolved", ""); - let s = self.subdir.canonicalize().unwrap().to_str().unwrap().to_owned(); + let s = self.subdir + .canonicalize() + .unwrap() + .to_str() + .unwrap() + .to_owned(); // Due to canonicalize()'s use of GetFinalPathNameByHandleW() on Windows, the resolved path // starts with '\\?\' to extend the limit of a given path to 32,767 wide characters. @@ -427,7 +444,7 @@ pub struct UCommand { comm_string: String, tmpd: Option>, has_run: bool, - stdin: Option> + stdin: Option>, } impl UCommand { @@ -456,7 +473,7 @@ impl UCommand { cmd }, comm_string: String::from(arg.as_ref().to_str().unwrap()), - stdin: None + stdin: None, } } @@ -511,7 +528,11 @@ impl UCommand { self.pipe_in(contents) } - pub fn env(&mut self, key: K, val: V) -> Box<&mut UCommand> where K: AsRef, V: AsRef { + pub fn env(&mut self, key: K, val: V) -> Box<&mut UCommand> + where + K: AsRef, + V: AsRef, + { if self.has_run { panic!(ALREADY_RUN); } @@ -535,11 +556,10 @@ impl UCommand { .unwrap(); if let Some(ref input) = self.stdin { - result.stdin + result + .stdin .take() - .unwrap_or_else( - || panic!( - "Could not take child process stdin")) + .unwrap_or_else(|| panic!("Could not take child process stdin")) .write_all(input) .unwrap_or_else(|e| panic!("{}", e)); } @@ -590,6 +610,11 @@ pub fn read_size(child: &mut Child, size: usize) -> String { let mut output = Vec::new(); output.resize(size, 0); sleep(Duration::from_secs(1)); - child.stdout.as_mut().unwrap().read(output.as_mut_slice()).unwrap(); + child + .stdout + .as_mut() + .unwrap() + .read(output.as_mut_slice()) + .unwrap(); String::from_utf8(output).unwrap() } diff --git a/tests/tests.rs b/tests/tests.rs index b413a4f88..cb164a91c 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -33,7 +33,6 @@ unix_only! { "stat", test_stat } - macro_rules! generic { ($($fea:expr, $m:ident);+) => { $( diff --git a/uumain.rs b/uumain.rs index 3fa1dd87a..d3c87408c 100644 --- a/uumain.rs +++ b/uumain.rs @@ -1 +1 @@ -include!(concat!(env!("OUT_DIR"), "/main.rs")); \ No newline at end of file +include!(concat!(env!("OUT_DIR"), "/main.rs"));