1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #1500 from rivy/chg.uutils-naming

Change ~ allow alternate names for `uutils`
This commit is contained in:
Roy Ivy III 2020-05-25 00:16:40 -05:00 committed by GitHub
commit 53ee25693f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 484 additions and 330 deletions

24
.editorconfig Normal file
View file

@ -0,0 +1,24 @@
# EditorConfig (is awesome): http://EditorConfig.org
# * top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{bat,cmd,[Bb][Aa][Tt],[Cc][Mm][Dd]}]
# DOS/Win requires BAT/CMD files to have CRLF EOLNs
end_of_line = crlf
[[Mm]akefile{,.*}]
# TAB-style indentation
indent_style = tab
[*.{yml,[Yy][Mm][Ll]}]
indent_size = 2

2
.gitignore vendored
View file

@ -11,4 +11,4 @@ target/
.idea .idea
Cargo.lock Cargo.lock
lib*.a lib*.a
/docs/_build /docs/_build

View file

@ -24,109 +24,109 @@ test_unimplemented = []
## (common/core and Tier1) feature sets ## (common/core and Tier1) feature sets
# "feat_common_core" == baseline core set of utilities which can be built/run on most targets # "feat_common_core" == baseline core set of utilities which can be built/run on most targets
feat_common_core = [ feat_common_core = [
"base32", "base32",
"base64", "base64",
"basename", "basename",
"cat", "cat",
"cksum", "cksum",
"comm", "comm",
"cp", "cp",
"cut", "cut",
"date", "date",
"df", "df",
"dircolors", "dircolors",
"dirname", "dirname",
"echo", "echo",
"env", "env",
"expand", "expand",
"expr", "expr",
"factor", "factor",
"false", "false",
"fmt", "fmt",
"fold", "fold",
"hashsum", "hashsum",
"head", "head",
"join", "join",
"link", "link",
"ln", "ln",
"ls", "ls",
"mkdir", "mkdir",
"mktemp", "mktemp",
"more", "more",
"mv", "mv",
"nl", "nl",
"od", "od",
"paste", "paste",
"printenv", "printenv",
"printf", "printf",
"ptx", "ptx",
"pwd", "pwd",
"readlink", "readlink",
"realpath", "realpath",
"relpath", "relpath",
"rm", "rm",
"rmdir", "rmdir",
"seq", "seq",
"shred", "shred",
"shuf", "shuf",
"sleep", "sleep",
"sort", "sort",
"split", "split",
"sum", "sum",
"tac", "tac",
"tail", "tail",
"tee", "tee",
"test", "test",
"tr", "tr",
"true", "true",
"truncate", "truncate",
"tsort", "tsort",
"unexpand", "unexpand",
"uniq", "uniq",
"wc", "wc",
"yes", "yes",
] ]
# "feat_Tier1" == expanded set of utilities which can be built/run on the usual rust "Tier 1" target platforms (ref: <https://forge.rust-lang.org/release/platform-support.html>) # "feat_Tier1" == expanded set of utilities which can be built/run on the usual rust "Tier 1" target platforms (ref: <https://forge.rust-lang.org/release/platform-support.html>)
feat_Tier1 = [ feat_Tier1 = [
"feat_common_core", "feat_common_core",
# #
"arch", "arch",
"hostname", "hostname",
"nproc", "nproc",
"sync", "sync",
"touch", "touch",
"whoami", "whoami",
] ]
## (primary platforms) feature sets ## (primary platforms) feature sets
# "feat_os_macos" == set of utilities which can be built/run on the MacOS platform # "feat_os_macos" == set of utilities which can be built/run on the MacOS platform
feat_os_macos = [ feat_os_macos = [
"feat_os_unix", ## == a modern/usual *nix platform "feat_os_unix", ## == a modern/usual *nix platform
] ]
# "feat_os_unix" == set of utilities which can be built/run on modern/usual *nix platforms # "feat_os_unix" == set of utilities which can be built/run on modern/usual *nix platforms
feat_os_unix = [ feat_os_unix = [
"feat_Tier1", "feat_Tier1",
# #
"feat_require_crate_cpp", "feat_require_crate_cpp",
"feat_require_unix", "feat_require_unix",
"feat_require_unix_utmpx", "feat_require_unix_utmpx",
] ]
# "feat_os_windows" == set of utilities which can be built/run on modern/usual windows platforms # "feat_os_windows" == set of utilities which can be built/run on modern/usual windows platforms
feat_os_windows = [ feat_os_windows = [
"feat_Tier1", ## == "feat_os_windows_legacy" + "hostname" "feat_Tier1", ## == "feat_os_windows_legacy" + "hostname"
] ]
## (secondary platforms) feature sets ## (secondary platforms) feature sets
# "feat_os_unix_gnueabihf" == set of utilities which can be built/run on the "arm-unknown-linux-gnueabihf" target (ARMv6 Linux [hardfloat]) # "feat_os_unix_gnueabihf" == set of utilities which can be built/run on the "arm-unknown-linux-gnueabihf" target (ARMv6 Linux [hardfloat])
feat_os_unix_gnueabihf = [ feat_os_unix_gnueabihf = [
"feat_Tier1", "feat_Tier1",
# #
"feat_require_unix", "feat_require_unix",
"feat_require_unix_utmpx", "feat_require_unix_utmpx",
] ]
# "feat_os_unix_musl" == set of utilities which can be built/run on targets binding to the "musl" library (ref: <https://musl.libc.org/about.html>) # "feat_os_unix_musl" == set of utilities which can be built/run on targets binding to the "musl" library (ref: <https://musl.libc.org/about.html>)
feat_os_unix_musl = [ feat_os_unix_musl = [
"feat_Tier1", "feat_Tier1",
# #
"feat_require_unix", "feat_require_unix",
] ]
## feature sets with requirements (restricting cross-platform availability) ## feature sets with requirements (restricting cross-platform availability)
# #
@ -134,87 +134,90 @@ feat_os_unix_musl = [
# #
# "feat_require_crate_cpp" == set of utilities requiring the `cpp` crate (which fail to compile on several platforms; as of 2020-04-23) # "feat_require_crate_cpp" == set of utilities requiring the `cpp` crate (which fail to compile on several platforms; as of 2020-04-23)
feat_require_crate_cpp = [ feat_require_crate_cpp = [
"stdbuf", "stdbuf",
] ]
# "feat_require_unix" == set of utilities requiring support which is only available on unix platforms (as of 2020-04-23) # "feat_require_unix" == set of utilities requiring support which is only available on unix platforms (as of 2020-04-23)
feat_require_unix = [ feat_require_unix = [
"chgrp", "chgrp",
"chmod", "chmod",
"chown", "chown",
"chroot", "chroot",
"du", "du",
"groups", "groups",
"hostid", "hostid",
"id", "id",
"install", "install",
"kill", "kill",
"logname", "logname",
"mkfifo", "mkfifo",
"mknod", "mknod",
"nice", "nice",
"numfmt", "numfmt",
"nohup", "nohup",
"pathchk", "pathchk",
"stat", "stat",
"timeout", "timeout",
"tty", "tty",
"uname", "uname",
"unlink", "unlink",
] ]
# "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support # "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support
# * ref: <https://wiki.musl-libc.org/faq.html#Q:-Why-is-the-utmp/wtmp-functionality-only-implemented-as-stubs?> # * ref: <https://wiki.musl-libc.org/faq.html#Q:-Why-is-the-utmp/wtmp-functionality-only-implemented-as-stubs?>
feat_require_unix_utmpx = [ feat_require_unix_utmpx = [
"pinky", "pinky",
"uptime", "uptime",
"users", "users",
"who", "who",
] ]
## (alternate/newer/smaller platforms) feature sets ## (alternate/newer/smaller platforms) feature sets
# "feat_os_unix_fuchsia" == set of utilities which can be built/run on the "Fuchsia" OS (refs: <https://fuchsia.dev>; <https://en.wikipedia.org/wiki/Google_Fuchsia>) # "feat_os_unix_fuchsia" == set of utilities which can be built/run on the "Fuchsia" OS (refs: <https://fuchsia.dev>; <https://en.wikipedia.org/wiki/Google_Fuchsia>)
feat_os_unix_fuchsia = [ feat_os_unix_fuchsia = [
"feat_common_core", "feat_common_core",
# #
"feat_require_crate_cpp", "feat_require_crate_cpp",
# #
"chgrp", "chgrp",
"chmod", "chmod",
"chown", "chown",
"du", "du",
"groups", "groups",
"hostid", "hostid",
"install", "install",
"logname", "logname",
"mkfifo", "mkfifo",
"mknod", "mknod",
"nice", "nice",
"pathchk", "pathchk",
"tty", "tty",
"uname", "uname",
"unlink", "unlink",
] ]
# "feat_os_unix_redox" == set of utilities which can be built/run on "Redox OS" (refs: <https://www.redox-os.org>; <https://en.wikipedia.org/wiki/Redox_(operating_system)>) # "feat_os_unix_redox" == set of utilities which can be built/run on "Redox OS" (refs: <https://www.redox-os.org>; <https://en.wikipedia.org/wiki/Redox_(operating_system)>)
feat_os_unix_redox = [ feat_os_unix_redox = [
"feat_common_core", "feat_common_core",
# #
"uname", "uname",
"chmod", "chmod",
"install", "install",
] ]
# "feat_os_windows_legacy" == slightly restricted set of utilities which can be built/run on early windows platforms (eg, "WinXP") # "feat_os_windows_legacy" == slightly restricted set of utilities which can be built/run on early windows platforms (eg, "WinXP")
feat_os_windows_legacy = [ feat_os_windows_legacy = [
"feat_common_core", "feat_common_core",
# #
"arch", "arch",
"nproc", "nproc",
"sync", "sync",
"touch", "touch",
"whoami", "whoami",
] ]
[workspace] [workspace]
[dependencies] [dependencies]
uucore = "0.0.2" lazy_static = { version="1.3" }
textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review
uucore = { version="0.0.2" }
# * uutils
arch = { optional=true, path="src/uu/arch" } arch = { optional=true, path="src/uu/arch" }
base32 = { optional=true, path="src/uu/base32" } base32 = { optional=true, path="src/uu/base32" }
base64 = { optional=true, path="src/uu/base64" } base64 = { optional=true, path="src/uu/base64" }
@ -311,11 +314,10 @@ whoami = { optional=true, path="src/uu/whoami" }
yes = { optional=true, path="src/uu/yes" } yes = { optional=true, path="src/uu/yes" }
# #
# * transitive dependency via 'failure'; pin to <= v0.3.30 to avoid increasing MinSRV to v1.33.0 # * transitive dependency via 'failure'; pin to <= v0.3.30 to avoid increasing MinSRV to v1.33.0
backtrace = ">= 0.3.3, <= 0.3.30" _backtrace = { version=">= 0.3.3, <= 0.3.30", package="backtrace" }
[dev-dependencies] [dev-dependencies]
filetime = "0.2" filetime = "0.2"
lazy_static = "1.3"
libc = "0.2" libc = "0.2"
rand = "0.6" rand = "0.6"
regex = "1.0" regex = "1.0"
@ -324,8 +326,7 @@ time = "0.1"
unindent = "0.1" unindent = "0.1"
[target.'cfg(unix)'.dev-dependencies] [target.'cfg(unix)'.dev-dependencies]
# FIXME: this should use the normal users crate, but it conflicts with the users utility rust-users = { version="0.10", package="users" }
rust-users = { git = "https://github.com/uutils/rust-users" }
unix_socket = "0.5.0" unix_socket = "0.5.0"
[[bin]] [[bin]]

View file

@ -46,101 +46,101 @@ BUSYBOX_SRC := $(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER)
# Possible programs # Possible programs
PROGS := \ PROGS := \
base32 \ base32 \
base64 \ base64 \
basename \ basename \
cat \ cat \
cksum \ cksum \
comm \ comm \
cp \ cp \
cut \ cut \
df \ df \
dircolors \ dircolors \
dirname \ dirname \
echo \ echo \
env \ env \
expand \ expand \
expr \ expr \
factor \ factor \
false \ false \
fmt \ fmt \
fold \ fold \
hashsum \ hashsum \
head \ head \
join \ join \
link \ link \
ln \ ln \
ls \ ls \
mkdir \ mkdir \
mktemp \ mktemp \
more \ more \
mv \ mv \
nl \ nl \
numfmt \ numfmt \
nproc \ nproc \
od \ od \
paste \ paste \
printenv \ printenv \
printf \ printf \
ptx \ ptx \
pwd \ pwd \
readlink \ readlink \
realpath \ realpath \
relpath \ relpath \
rm \ rm \
rmdir \ rmdir \
seq \ seq \
shred \ shred \
shuf \ shuf \
sleep \ sleep \
sort \ sort \
split \ split \
sum \ sum \
sync \ sync \
tac \ tac \
tail \ tail \
tee \ tee \
test \ test \
tr \ tr \
true \ true \
truncate \ truncate \
tsort \ tsort \
unexpand \ unexpand \
uniq \ uniq \
wc \ wc \
whoami \ whoami \
yes yes
UNIX_PROGS := \ UNIX_PROGS := \
arch \ arch \
chgrp \ chgrp \
chmod \ chmod \
chown \ chown \
chroot \ chroot \
du \ du \
groups \ groups \
hostid \ hostid \
hostname \ hostname \
id \ id \
install \ install \
kill \ kill \
logname \ logname \
mkfifo \ mkfifo \
mknod \ mknod \
nice \ nice \
nohup \ nohup \
pathchk \ pathchk \
pinky \ pinky \
stat \ stat \
stdbuf \ stdbuf \
timeout \ timeout \
touch \ touch \
tty \ tty \
uname \ uname \
unlink \ unlink \
uptime \ uptime \
users \ users \
who who
ifneq ($(OS),Windows_NT) ifneq ($(OS),Windows_NT)
PROGS := $(PROGS) $(UNIX_PROGS) PROGS := $(PROGS) $(UNIX_PROGS)
@ -229,7 +229,7 @@ endef
# Output names # Output names
EXES := \ EXES := \
$(sort $(filter $(UTILS),$(filter-out $(SKIP_UTILS),$(PROGS)))) $(sort $(filter $(UTILS),$(filter-out $(SKIP_UTILS),$(PROGS))))
INSTALLEES := ${EXES} INSTALLEES := ${EXES}
ifeq (${MULTICALL}, y) ifeq (${MULTICALL}, y)

View file

@ -36,7 +36,7 @@ set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS ""
# determine features # determine features
env_features = get_env CARGO_FEATURES env_features = get_env CARGO_FEATURES
if is_empty "${env_features}" if is_empty "${env_features}"
env_features = get_env FEATURES env_features = get_env FEATURES
end_if end_if
if is_empty "${env_features}" if is_empty "${env_features}"
if eq "${CARGO_MAKE_RUST_TARGET_OS}" "macos" if eq "${CARGO_MAKE_RUST_TARGET_OS}" "macos"
@ -61,7 +61,7 @@ end_if
# set build flags from features # set build flags from features
if not is_empty "${features}" if not is_empty "${features}"
set_env CARGO_MAKE_VAR_BUILD_TEST_FEATURES "${features}" set_env CARGO_MAKE_VAR_BUILD_TEST_FEATURES "${features}"
set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "--features ${features}" set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "--features ${features}"
end_if end_if
# determine show-utils helper script # determine show-utils helper script
show_utils = set "util/show-utils.sh" show_utils = set "util/show-utils.sh"
@ -69,15 +69,23 @@ if eq "${CARGO_MAKE_RUST_TARGET_OS}" "windows"
show_utils = set "util/show-utils.BAT" show_utils = set "util/show-utils.BAT"
end_if end_if
set_env CARGO_MAKE_VAR_SHOW_UTILS "${show_utils}" set_env CARGO_MAKE_VAR_SHOW_UTILS "${show_utils}"
# rebuild TASK_ARGS for "--features" and package-build compatibility (using "," instead of ";") # rebuild CARGO_MAKE_TASK_ARGS for various targets
args = set ${CARGO_MAKE_TASK_ARGS} args = set ${CARGO_MAKE_TASK_ARGS}
args = replace ${args} ";" "," # * rebuild for 'features' target
set_env CARGO_MAKE_TASK_BUILD_FEATURES_ARGS "${args}" args_features = replace ${args} ";" ","
args = replace ${args} "," " -p" set_env CARGO_MAKE_TASK_BUILD_FEATURES_ARGS "${args_features}"
if not is_empty "${args}" # * rebuild for 'examples' target
args = set "-p${args}" args_examples = replace ${args} ";" " --example "
if is_empty "${args_examples}"
args_examples = set "--examples"
end_if end_if
set_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS "${args}" set_env CARGO_MAKE_TASK_BUILD_EXAMPLES_ARGS "${args_examples}"
# * rebuild for 'utils' target
args_utils = replace ${args} ";" " -p"
if not is_empty "${args_utils}"
args_utils = set "-p${args_utils}"
end_if
set_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS "${args_utils}"
''' '''
] ]
@ -88,7 +96,7 @@ description = "## *DEFAULT* Build (debug-mode) and test project"
category = "[project]" category = "[project]"
dependencies = [ dependencies = [
"action-build-debug", "action-build-debug",
"test-terse", "test-terse",
] ]
## ##
@ -98,8 +106,8 @@ description = "## Build (release-mode) project"
category = "[project]" category = "[project]"
dependencies = [ dependencies = [
"core::pre-build", "core::pre-build",
"action-build-release", "action-build-release",
"core::post-build", "core::post-build",
] ]
[tasks.build-debug] [tasks.build-debug]
@ -109,18 +117,33 @@ dependencies = [
"action-build-debug", "action-build-debug",
] ]
[tasks.build-examples]
description = "## Build (release-mode) project example(s); usage: `cargo make (build-examples | examples | example) [EXAMPLE]...`"
category = "[project]"
dependencies = [
"core::pre-build",
"action-build-examples",
"core::post-build",
]
[tasks.build-features] [tasks.build-features]
description = "## Build (with features; release-mode) project; usage: `cargo make (build-features | features) FEATURE...`" description = "## Build (with features; release-mode) project; usage: `cargo make (build-features | features) FEATURE...`"
category = "[project]" category = "[project]"
dependencies = [ dependencies = [
"core::pre-build", "core::pre-build",
"action-build-features", "action-build-features",
"core::post-build", "core::post-build",
] ]
[tasks.debug] [tasks.debug]
alias = "build-debug" alias = "build-debug"
[tasks.example]
alias = "build-examples"
[tasks.examples]
alias = "build-examples"
[tasks.features] [tasks.features]
alias = "build-features" alias = "build-features"
@ -162,8 +185,8 @@ description = "## Run project tests"
category = "[project]" category = "[project]"
dependencies = [ dependencies = [
"core::pre-test", "core::pre-test",
"core::test", "core::test",
"core::post-test", "core::post-test",
] ]
[tasks.test-terse] [tasks.test-terse]
@ -171,8 +194,8 @@ description = "## Run project tests (with terse/summary output)"
category = "[project]" category = "[project]"
dependencies = [ dependencies = [
"core::pre-test", "core::pre-test",
"action-test_quiet", "action-test_quiet",
"core::post-test", "core::post-test",
] ]
[tasks.uninstall] [tasks.uninstall]
@ -190,8 +213,8 @@ category = "[project]"
dependencies = [ dependencies = [
"core::pre-build", "core::pre-build",
"action-determine-utils", "action-determine-utils",
"action-build-utils", "action-build-utils",
"core::post-build", "core::post-build",
] ]
[tasks.uutil] [tasks.uutil]
@ -212,6 +235,11 @@ description = "`cargo build`"
command = "cargo" command = "cargo"
args = ["build", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )" ] args = ["build", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )" ]
[tasks.action-build-examples]
description = "`cargo build (--examples|(--example EXAMPLE)...)`"
command = "cargo"
args = ["build", "--release", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )", "${CARGO_MAKE_TASK_BUILD_EXAMPLES_ARGS}" ]
[tasks.action-build-features] [tasks.action-build-features]
description = "`cargo build --release --features FEATURES`" description = "`cargo build --release --features FEATURES`"
command = "cargo" command = "cargo"

View file

@ -17,4 +17,4 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new # Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: GNUmakefile %: GNUmakefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View file

@ -5,7 +5,7 @@ pushd %~dp0
REM Command file for Sphinx documentation REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" ( if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build set SPHINXBUILD=sphinx-build
) )
set SOURCEDIR=. set SOURCEDIR=.
set BUILDDIR=_build set BUILDDIR=_build
@ -15,15 +15,15 @@ if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL %SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 ( if errorlevel 9009 (
echo. echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH. echo.may add the Sphinx directory to PATH.
echo. echo.
echo.If you don't have Sphinx installed, grab it from echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/ echo.http://sphinx-doc.org/
exit /b 1 exit /b 1
) )
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%

1
examples/busybox.rs Normal file
View file

@ -0,0 +1 @@
include!("../src/bin/uutils.rs");

1
examples/uu.rs Normal file
View file

@ -0,0 +1 @@
include!("../src/bin/uutils.rs");

View file

@ -1,5 +1,3 @@
#![crate_name = "uutils"]
/* /*
* This file is part of the uutils coreutils package. * This file is part of the uutils coreutils package.
* *
@ -9,74 +7,84 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
// spell-checker:ignore (acronyms/names) Gehring
// spell-checker:ignore (rustlang/crates) clippy concat rustlang termwidth textwrap
// spell-checker:ignore (uutils) coreutils sigpipe uucore uumain uutils
// spell-checker:ignore (shell) busybox symlinks
include!(concat!(env!("OUT_DIR"), "/uutils_crates.rs")); include!(concat!(env!("OUT_DIR"), "/uutils_crates.rs"));
use std::collections::hash_map::HashMap; extern crate lazy_static;
use std::io::Write; extern crate textwrap;
use std::path::Path;
extern crate uucore; extern crate uucore;
static NAME: &str = "uutils"; use lazy_static::lazy_static;
use std::collections::hash_map::HashMap;
use std::io::Write;
static VERSION: &str = env!("CARGO_PKG_VERSION"); static VERSION: &str = env!("CARGO_PKG_VERSION");
lazy_static! {
static ref BINARY_PATH: std::path::PathBuf = {
// support symlinks by using args[0], when possible, with fallback to current_exe()
match std::env::args().next() {
Some(ref s) if !s.is_empty() => std::path::PathBuf::from(s),
_ => std::env::current_exe().unwrap(),
}
};
static ref NAME: &'static str = &*BINARY_PATH.file_stem().unwrap().to_str().unwrap();
}
include!(concat!(env!("OUT_DIR"), "/uutils_map.rs")); include!(concat!(env!("OUT_DIR"), "/uutils_map.rs"));
fn usage(cmap: &UtilityMap) { fn usage(utils: &UtilityMap) {
println!("{} {}", NAME, VERSION); println!("{} {} (multi-call binary)\n", *NAME, VERSION);
println!(); println!("Usage: {} [function [arguments...]]\n", *NAME);
println!("Usage:"); println!("Currently defined functions/utilities:\n");
println!(" {} [util [arguments...]]\n", NAME);
println!("Currently defined functions:");
#[allow(clippy::map_clone)] #[allow(clippy::map_clone)]
let mut utils: Vec<&str> = cmap.keys().map(|&s| s).collect(); let mut utils: Vec<&str> = utils.keys().map(|&s| s).collect();
utils.sort(); utils.sort();
for util in utils { let display_list = utils.join(", ");
println!("\t{}", util); let width = std::cmp::min(textwrap::termwidth(), 100) - 4 * 2; // (opinion/heuristic) max 100 chars wide with 4 character side indentions
} println!(
"{}",
textwrap::indent(&textwrap::fill(&display_list, width), " ")
);
} }
fn main() { fn main() {
uucore::panic::install_sigpipe_hook(); uucore::panic::install_sigpipe_hook();
let umap = util_map(); let utils = util_map();
let mut args: Vec<String> = uucore::args().collect(); let mut args: Vec<String> = uucore::args().collect();
// try binary name as util name. let binary = &BINARY_PATH;
let args0 = args[0].clone();
let binary = Path::new(&args0[..]);
let binary_as_util = binary.file_stem().unwrap().to_str().unwrap(); let binary_as_util = binary.file_stem().unwrap().to_str().unwrap();
if let Some(&uumain) = umap.get(binary_as_util) { // binary name equals util name?
if let Some(&uumain) = utils.get(binary_as_util) {
std::process::exit(uumain(args)); std::process::exit(uumain(args));
} }
if binary_as_util.ends_with("uutils") // binary name equals prefixed util name?
|| binary_as_util.starts_with("uutils") // * prefix/stem may be any string ending in a non-alphanumeric character
|| binary_as_util.ends_with("busybox") if let Some(util) = utils.keys().find(|util| {
|| binary_as_util.starts_with("busybox") binary_as_util.ends_with(*util)
{ && !(&binary_as_util[..binary_as_util.len() - (*util).len()])
args.remove(0); .ends_with(char::is_alphanumeric)
}) {
// prefixed util => replace 0th (aka, executable name) argument
args[0] = (*util).to_owned();
} else { } else {
let mut found = false; // unmatched binary name => regard as multi-binary container and advance argument list
for util in umap.keys() { args.remove(0);
if binary_as_util.ends_with(util) {
args[0] = (*util).to_owned();
found = true;
break;
}
}
if !found {
println!("{}: applet not found", binary_as_util);
std::process::exit(1);
}
} }
// try first arg as util name. // 0th argument equals util name?
if !args.is_empty() { if !args.is_empty() {
let util = &args[0][..]; let util = &args[0][..];
match umap.get(util) { match utils.get(util) {
Some(&uumain) => { Some(&uumain) => {
std::process::exit(uumain(args.clone())); std::process::exit(uumain(args.clone()));
} }
@ -85,29 +93,29 @@ fn main() {
// see if they want help on a specific util // see if they want help on a specific util
if args.len() >= 2 { if args.len() >= 2 {
let util = &args[1][..]; let util = &args[1][..];
match umap.get(util) { match utils.get(util) {
Some(&uumain) => { Some(&uumain) => {
let code = uumain(vec![util.to_owned(), "--help".to_owned()]); let code = uumain(vec![util.to_owned(), "--help".to_owned()]);
std::io::stdout().flush().expect("could not flush stdout"); std::io::stdout().flush().expect("could not flush stdout");
std::process::exit(code); std::process::exit(code);
} }
None => { None => {
println!("{}: applet not found", util); println!("{}: function/utility not found", util);
std::process::exit(1); std::process::exit(1);
} }
} }
} }
usage(&umap); usage(&utils);
std::process::exit(0); std::process::exit(0);
} else { } else {
println!("{}: applet not found", util); println!("{}: function/utility not found", util);
std::process::exit(1); std::process::exit(1);
} }
} }
} }
} else { } else {
// no arguments provided // no arguments provided
usage(&umap); usage(&utils);
std::process::exit(0); std::process::exit(0);
} }
} }

View file

@ -1 +1 @@
target target

View file

@ -128,10 +128,10 @@ Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null
or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred. or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.
Environment variables: Environment variables:
* EXPR_DEBUG_TOKENS=1 dump expression's tokens * EXPR_DEBUG_TOKENS=1 dump expression's tokens
* EXPR_DEBUG_RPN=1 dump expression represented in reverse polish notation * EXPR_DEBUG_RPN=1 dump expression represented in reverse polish notation
* EXPR_DEBUG_SYA_STEP=1 dump each parser step * EXPR_DEBUG_SYA_STEP=1 dump each parser step
* EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree"# * EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree"#
); );
} }

View file

@ -331,19 +331,19 @@ pub fn uumain(args: Vec<String>) -> i32 {
auto accept optional single/two letter suffix: auto accept optional single/two letter suffix:
1K = 1000, 1Ki = 1024, 1M = 1000000, 1Mi = 1048576, 1K = 1000, 1Ki = 1024, 1M = 1000000, 1Mi = 1048576,
si accept optional single letter suffix: si accept optional single letter suffix:
1K = 1000, 1M = 1000000, ... 1K = 1000, 1M = 1000000, ...
iec accept optional single letter suffix: iec accept optional single letter suffix:
1K = 1024, 1M = 1048576, ... 1K = 1024, 1M = 1048576, ...
iec-i accept optional two-letter suffix: iec-i accept optional two-letter suffix:
1Ki = 1024, 1Mi = 1048576, ..." 1Ki = 1024, 1Mi = 1048576, ..."
); );
return 0; return 0;

View file

@ -245,7 +245,7 @@ pub fn num_format(field: &FormatField, in_str_opt: Option<&String>) -> Option<St
// otherwise we'll interpret the argument as a number // otherwise we'll interpret the argument as a number
// using the appropriate Formatter // using the appropriate Formatter
let in_str = in_str_opt.expect( let in_str = in_str_opt.expect(
"please send the devs this message: "please send the devs this message:
\n get_provided is failing to ret as Some(0) on no str "); \n get_provided is failing to ret as Some(0) on no str ");
// first get information about the beginning of the // first get information about the beginning of the
// numeric argument that would be useful for // numeric argument that would be useful for

View file

@ -0,0 +1,91 @@
@setLocal
@echo off
:: `test-repo-whitespace [DIR]...`
:: style inspector ~ whitespace: find nonconforming files in repository
:: Copyright (C) 2016-2020 ~ Roy Ivy III <rivy.dev@gmail.com>
:: License: MIT/Apache-2.0 (see https://opensource.org/licenses/Apache-2.0 , https://opensource.org/licenses/MIT)
:: * this software is provided for free, WITHOUT ANY EXPRESS OR IMPLIED WARRANTY (see the license for details)
:: spell-checker:ignore (shell/cmd) COMSPEC ERRORLEVEL
:: spell-checker:ignore () CTYPE POSIX Tval Tvar akefile makefile makefiles multiline
:config
set "_exclude_dir=(?i)[_.#]build|[.]git|[.]gpg|[.]vs|fixtures|vendor"
set "_exclude=(?i)[.](cache|dll|exe|gif|gz|zip)$"
:config_done
set _dp0=%~dp0.
set _nx0=%~nx0
set dirs=%*
if NOT DEFINED dirs if EXIST "%CD%\repo" ( set dirs="%CD%\repo" )
if NOT DEFINED dirs if EXIST "%_dp0%\..\.git" ( set dirs="%_dp0%\.." )
if NOT DEFINED dirs ( set "dirs=." )
set PCREGREP=pcregrep
if EXIST "%_dp0%\pcregrep.EXE" ( set "PCREGREP=%_dp0%\pcregrep.EXE" )
"%PCREGREP%" --version >NUL 2>NUL || ( echo ERR!: Missing required `pcregrep` [try `scoop install pcregrep`] 1>&2 & goto _undefined_ 2>NUL || "%COMSPEC%" /d/c exit 1 )
echo [ %dirs% ]
if /i "%LC_CTYPE%"=="posix" (set "LC_CTYPE=C") &:: `pcregrep` doesn't understand the common "POSIX", replace with the equivalent "C"
set "ERRORLEVEL="
set "ERROR="
:: 1. Test for TABs within leading whitespace (except go files makefiles)
"%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --exclude "(?i)[.]go$" --exclude "go[.](mod|sum)" --exclude "(GNU)?[Mm]akefile([.].*)?" --count --files-with-matches --recursive "^\s*\t" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with TABs within leading whitespace [file:#lines_matched])
:: 2. Test for lines with internal TABs
"%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --count --files-with-matches --recursive "^.*[^\t]\t" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with lines containing internal TABs [file:#lines_matched])
:: 3. Test that makefiles have ONLY initial-TAB leading whitespace
"%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --include "(GNU)?[Mm]akefile([.].*)?" --exclude "[.](to|y)ml$" --recursive --line-number --invert-match "^([\t]\s*\S|\S|$)" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: Makefiles found with lines having non-TAB leading whitespace [file:line_number])
:: 4. Test for non-LF line endings
set "HAVE_NonLF_ERROR="
"%PCREGREP%" --buffer-size=1M -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" -NLF --files-with-matches --multiline --recursive "\r[^\n]" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set HAVE_NonLF_ERROR=1 & echo ## files found with CR line endings)
"%PCREGREP%" --buffer-size=1M -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --exclude "(?i)\.bat$|\.cmd$" -NLF --files-with-matches --multiline --recursive "\r\n" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set HAVE_NonLF_ERROR=1 & echo ## files found with CRLF line endings)
if DEFINED HAVE_NonLF_ERROR ( set ERROR=1 & echo ERROR: files found with non-LF line endings)
:: 5. Test for files without trailing newline
:: "%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --files-without-match --multiline --recursive "\r?[\r\n]\z" %dirs%
"%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --files-with-matches --multiline --recursive "\z" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found without trailing newline)
:: 6. Test for files with lines having trailing whitespace
"%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --recursive --line-number "\s$" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with lines having trailing whitespace [file:line_number])
:: 7. Test for files with BOM
"%PCREGREP%" -I --exclude-dir "%_exclude_dir%" --exclude "%_exclude%" --files-with-matches --multiline --recursive "\A[\xEF][\xBB][\xBF]" %dirs%
if NOT "%ERRORLEVEL%" == "1" ( set ERROR=1 & echo ERROR: files found with leading BOM)
:script_done
if NOT DEFINED ERROR (
echo success: no file errors found
)
call :#exit__title __exit_title "%COMSPEC%"
set "__exit_title=" && title %__exit_title% && set "ERRORLEVEL=" & goto _undefined_ 2>NUL || "%COMSPEC%" /d/c "exit %ERROR%"
@rem::::
@rem:: FUNCTIONS
@goto :EOF
::
:#exit__title ( ref_RETURN PATH )
:: RETURN == name of PATH
setLocal
set "_RETvar=%~1"
set "_RETval=%~2"
if NOT DEFINED _RETval ( set "_RETval=cmd" & goto :#exit__title_RETURN )
set "_RETval=%~n2"
:#exit__title_RETURN
endLocal & set %_RETvar%^=%_RETval%
goto :EOF
::