diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..95dfec676 --- /dev/null +++ b/.editorconfig @@ -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 diff --git a/.gitignore b/.gitignore index 3eabba702..b1ac52506 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ target/ .idea Cargo.lock lib*.a -/docs/_build \ No newline at end of file +/docs/_build diff --git a/Cargo.toml b/Cargo.toml index ecdd024c5..bc1eeb23c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,109 +24,109 @@ test_unimplemented = [] ## (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 = [ - "base32", - "base64", - "basename", - "cat", - "cksum", - "comm", - "cp", - "cut", - "date", - "df", - "dircolors", - "dirname", - "echo", - "env", - "expand", - "expr", - "factor", - "false", - "fmt", - "fold", - "hashsum", - "head", - "join", - "link", - "ln", - "ls", - "mkdir", - "mktemp", - "more", - "mv", - "nl", - "od", - "paste", - "printenv", - "printf", - "ptx", - "pwd", - "readlink", - "realpath", - "relpath", - "rm", - "rmdir", - "seq", - "shred", - "shuf", - "sleep", - "sort", - "split", - "sum", - "tac", - "tail", - "tee", - "test", - "tr", - "true", - "truncate", - "tsort", - "unexpand", - "uniq", - "wc", - "yes", + "base32", + "base64", + "basename", + "cat", + "cksum", + "comm", + "cp", + "cut", + "date", + "df", + "dircolors", + "dirname", + "echo", + "env", + "expand", + "expr", + "factor", + "false", + "fmt", + "fold", + "hashsum", + "head", + "join", + "link", + "ln", + "ls", + "mkdir", + "mktemp", + "more", + "mv", + "nl", + "od", + "paste", + "printenv", + "printf", + "ptx", + "pwd", + "readlink", + "realpath", + "relpath", + "rm", + "rmdir", + "seq", + "shred", + "shuf", + "sleep", + "sort", + "split", + "sum", + "tac", + "tail", + "tee", + "test", + "tr", + "true", + "truncate", + "tsort", + "unexpand", + "uniq", + "wc", + "yes", ] # "feat_Tier1" == expanded set of utilities which can be built/run on the usual rust "Tier 1" target platforms (ref: ) feat_Tier1 = [ - "feat_common_core", - # - "arch", - "hostname", - "nproc", - "sync", - "touch", - "whoami", + "feat_common_core", + # + "arch", + "hostname", + "nproc", + "sync", + "touch", + "whoami", ] ## (primary platforms) feature sets # "feat_os_macos" == set of utilities which can be built/run on the MacOS platform 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 = [ - "feat_Tier1", - # - "feat_require_crate_cpp", - "feat_require_unix", - "feat_require_unix_utmpx", + "feat_Tier1", + # + "feat_require_crate_cpp", + "feat_require_unix", + "feat_require_unix_utmpx", ] # "feat_os_windows" == set of utilities which can be built/run on modern/usual windows platforms feat_os_windows = [ - "feat_Tier1", ## == "feat_os_windows_legacy" + "hostname" - ] + "feat_Tier1", ## == "feat_os_windows_legacy" + "hostname" +] ## (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 = [ - "feat_Tier1", - # - "feat_require_unix", - "feat_require_unix_utmpx", + "feat_Tier1", + # + "feat_require_unix", + "feat_require_unix_utmpx", ] # "feat_os_unix_musl" == set of utilities which can be built/run on targets binding to the "musl" library (ref: ) feat_os_unix_musl = [ - "feat_Tier1", - # - "feat_require_unix", + "feat_Tier1", + # + "feat_require_unix", ] ## 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 = [ - "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 = [ - "chgrp", - "chmod", - "chown", - "chroot", - "du", - "groups", - "hostid", - "id", - "install", - "kill", - "logname", - "mkfifo", - "mknod", - "nice", - "numfmt", - "nohup", - "pathchk", - "stat", - "timeout", - "tty", - "uname", - "unlink", + "chgrp", + "chmod", + "chown", + "chroot", + "du", + "groups", + "hostid", + "id", + "install", + "kill", + "logname", + "mkfifo", + "mknod", + "nice", + "numfmt", + "nohup", + "pathchk", + "stat", + "timeout", + "tty", + "uname", + "unlink", ] # "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support # * ref: feat_require_unix_utmpx = [ - "pinky", - "uptime", - "users", - "who", + "pinky", + "uptime", + "users", + "who", ] ## (alternate/newer/smaller platforms) feature sets # "feat_os_unix_fuchsia" == set of utilities which can be built/run on the "Fuchsia" OS (refs: ; ) feat_os_unix_fuchsia = [ - "feat_common_core", - # - "feat_require_crate_cpp", - # - "chgrp", - "chmod", - "chown", - "du", - "groups", - "hostid", - "install", - "logname", - "mkfifo", - "mknod", - "nice", - "pathchk", - "tty", - "uname", - "unlink", + "feat_common_core", + # + "feat_require_crate_cpp", + # + "chgrp", + "chmod", + "chown", + "du", + "groups", + "hostid", + "install", + "logname", + "mkfifo", + "mknod", + "nice", + "pathchk", + "tty", + "uname", + "unlink", ] # "feat_os_unix_redox" == set of utilities which can be built/run on "Redox OS" (refs: ; ) feat_os_unix_redox = [ - "feat_common_core", - # - "uname", - "chmod", - "install", + "feat_common_core", + # + "uname", + "chmod", + "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 = [ - "feat_common_core", - # - "arch", - "nproc", - "sync", - "touch", - "whoami", + "feat_common_core", + # + "arch", + "nproc", + "sync", + "touch", + "whoami", ] [workspace] [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" } base32 = { optional=true, path="src/uu/base32" } 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" } # # * 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] filetime = "0.2" -lazy_static = "1.3" libc = "0.2" rand = "0.6" regex = "1.0" @@ -324,8 +326,7 @@ time = "0.1" unindent = "0.1" [target.'cfg(unix)'.dev-dependencies] -# FIXME: this should use the normal users crate, but it conflicts with the users utility -rust-users = { git = "https://github.com/uutils/rust-users" } +rust-users = { version="0.10", package="users" } unix_socket = "0.5.0" [[bin]] diff --git a/GNUmakefile b/GNUmakefile index 64ceaa5c2..1e24d9445 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -46,101 +46,101 @@ BUSYBOX_SRC := $(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER) # Possible programs PROGS := \ - base32 \ - base64 \ - basename \ - cat \ - cksum \ - comm \ - cp \ - cut \ - df \ - dircolors \ - dirname \ - echo \ - env \ - expand \ - expr \ - factor \ - false \ - fmt \ - fold \ - hashsum \ - head \ - join \ - link \ - ln \ - ls \ - mkdir \ - mktemp \ - more \ - mv \ - nl \ - numfmt \ - nproc \ - od \ - paste \ - printenv \ - printf \ - ptx \ - pwd \ - readlink \ - realpath \ - relpath \ - rm \ - rmdir \ - seq \ - shred \ - shuf \ - sleep \ - sort \ - split \ - sum \ - sync \ - tac \ - tail \ - tee \ - test \ - tr \ - true \ - truncate \ - tsort \ - unexpand \ - uniq \ - wc \ - whoami \ - yes + base32 \ + base64 \ + basename \ + cat \ + cksum \ + comm \ + cp \ + cut \ + df \ + dircolors \ + dirname \ + echo \ + env \ + expand \ + expr \ + factor \ + false \ + fmt \ + fold \ + hashsum \ + head \ + join \ + link \ + ln \ + ls \ + mkdir \ + mktemp \ + more \ + mv \ + nl \ + numfmt \ + nproc \ + od \ + paste \ + printenv \ + printf \ + ptx \ + pwd \ + readlink \ + realpath \ + relpath \ + rm \ + rmdir \ + seq \ + shred \ + shuf \ + sleep \ + sort \ + split \ + sum \ + sync \ + tac \ + tail \ + tee \ + test \ + tr \ + true \ + truncate \ + tsort \ + unexpand \ + uniq \ + wc \ + whoami \ + yes UNIX_PROGS := \ - arch \ - chgrp \ - chmod \ - chown \ - chroot \ - du \ - groups \ - hostid \ - hostname \ - id \ - install \ - kill \ - logname \ - mkfifo \ - mknod \ - nice \ - nohup \ - pathchk \ - pinky \ - stat \ - stdbuf \ - timeout \ - touch \ - tty \ - uname \ - unlink \ - uptime \ - users \ - who + arch \ + chgrp \ + chmod \ + chown \ + chroot \ + du \ + groups \ + hostid \ + hostname \ + id \ + install \ + kill \ + logname \ + mkfifo \ + mknod \ + nice \ + nohup \ + pathchk \ + pinky \ + stat \ + stdbuf \ + timeout \ + touch \ + tty \ + uname \ + unlink \ + uptime \ + users \ + who ifneq ($(OS),Windows_NT) PROGS := $(PROGS) $(UNIX_PROGS) @@ -229,7 +229,7 @@ endef # Output names EXES := \ - $(sort $(filter $(UTILS),$(filter-out $(SKIP_UTILS),$(PROGS)))) + $(sort $(filter $(UTILS),$(filter-out $(SKIP_UTILS),$(PROGS)))) INSTALLEES := ${EXES} ifeq (${MULTICALL}, y) diff --git a/Makefile.toml b/Makefile.toml index 00345410b..fd301a925 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -36,7 +36,7 @@ set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "" # determine features env_features = get_env CARGO_FEATURES if is_empty "${env_features}" - env_features = get_env FEATURES + env_features = get_env FEATURES end_if if is_empty "${env_features}" if eq "${CARGO_MAKE_RUST_TARGET_OS}" "macos" @@ -61,7 +61,7 @@ end_if # set build flags from features if not is_empty "${features}" set_env CARGO_MAKE_VAR_BUILD_TEST_FEATURES "${features}" - set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "--features ${features}" + set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "--features ${features}" end_if # determine show-utils helper script 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" end_if 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 = replace ${args} ";" "," -set_env CARGO_MAKE_TASK_BUILD_FEATURES_ARGS "${args}" -args = replace ${args} "," " -p" -if not is_empty "${args}" - args = set "-p${args}" +# * rebuild for 'features' target +args_features = replace ${args} ";" "," +set_env CARGO_MAKE_TASK_BUILD_FEATURES_ARGS "${args_features}" +# * rebuild for 'examples' target +args_examples = replace ${args} ";" " --example " +if is_empty "${args_examples}" + args_examples = set "--examples" 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]" dependencies = [ "action-build-debug", - "test-terse", + "test-terse", ] ## @@ -98,8 +106,8 @@ description = "## Build (release-mode) project" category = "[project]" dependencies = [ "core::pre-build", - "action-build-release", - "core::post-build", + "action-build-release", + "core::post-build", ] [tasks.build-debug] @@ -109,18 +117,33 @@ dependencies = [ "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] description = "## Build (with features; release-mode) project; usage: `cargo make (build-features | features) FEATURE...`" category = "[project]" dependencies = [ "core::pre-build", - "action-build-features", - "core::post-build", + "action-build-features", + "core::post-build", ] [tasks.debug] alias = "build-debug" +[tasks.example] +alias = "build-examples" + +[tasks.examples] +alias = "build-examples" + [tasks.features] alias = "build-features" @@ -162,8 +185,8 @@ description = "## Run project tests" category = "[project]" dependencies = [ "core::pre-test", - "core::test", - "core::post-test", + "core::test", + "core::post-test", ] [tasks.test-terse] @@ -171,8 +194,8 @@ description = "## Run project tests (with terse/summary output)" category = "[project]" dependencies = [ "core::pre-test", - "action-test_quiet", - "core::post-test", + "action-test_quiet", + "core::post-test", ] [tasks.uninstall] @@ -190,8 +213,8 @@ category = "[project]" dependencies = [ "core::pre-build", "action-determine-utils", - "action-build-utils", - "core::post-build", + "action-build-utils", + "core::post-build", ] [tasks.uutil] @@ -212,6 +235,11 @@ description = "`cargo build`" command = "cargo" 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] description = "`cargo build --release --features FEATURES`" command = "cargo" diff --git a/docs/GNUmakefile b/docs/GNUmakefile index 05cef70c1..894a53be0 100644 --- a/docs/GNUmakefile +++ b/docs/GNUmakefile @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: GNUmakefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat index 0fb8a16c1..1e8ea10a0 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -5,7 +5,7 @@ pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build + set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build @@ -15,15 +15,15 @@ if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% diff --git a/examples/busybox.rs b/examples/busybox.rs new file mode 100644 index 000000000..f2516b124 --- /dev/null +++ b/examples/busybox.rs @@ -0,0 +1 @@ +include!("../src/bin/uutils.rs"); diff --git a/examples/uu.rs b/examples/uu.rs new file mode 100644 index 000000000..f2516b124 --- /dev/null +++ b/examples/uu.rs @@ -0,0 +1 @@ +include!("../src/bin/uutils.rs"); diff --git a/src/bin/uutils.rs b/src/bin/uutils.rs index c90c73d02..fe8128bb0 100644 --- a/src/bin/uutils.rs +++ b/src/bin/uutils.rs @@ -1,5 +1,3 @@ -#![crate_name = "uutils"] - /* * This file is part of the uutils coreutils package. * @@ -9,74 +7,84 @@ * 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")); -use std::collections::hash_map::HashMap; -use std::io::Write; -use std::path::Path; - +extern crate lazy_static; +extern crate textwrap; 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"); +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")); -fn usage(cmap: &UtilityMap) { - println!("{} {}", NAME, VERSION); - println!(); - println!("Usage:"); - println!(" {} [util [arguments...]]\n", NAME); - println!("Currently defined functions:"); +fn usage(utils: &UtilityMap) { + println!("{} {} (multi-call binary)\n", *NAME, VERSION); + println!("Usage: {} [function [arguments...]]\n", *NAME); + println!("Currently defined functions/utilities:\n"); #[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(); - for util in utils { - println!("\t{}", util); - } + let display_list = utils.join(", "); + 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() { uucore::panic::install_sigpipe_hook(); - let umap = util_map(); + let utils = util_map(); let mut args: Vec = uucore::args().collect(); - // try binary name as util name. - let args0 = args[0].clone(); - let binary = Path::new(&args0[..]); + let binary = &BINARY_PATH; 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)); } - 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); + // binary name equals prefixed util name? + // * prefix/stem may be any string ending in a non-alphanumeric character + if let Some(util) = utils.keys().find(|util| { + binary_as_util.ends_with(*util) + && !(&binary_as_util[..binary_as_util.len() - (*util).len()]) + .ends_with(char::is_alphanumeric) + }) { + // prefixed util => replace 0th (aka, executable name) argument + args[0] = (*util).to_owned(); } else { - let mut found = false; - for util in umap.keys() { - 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); - } + // unmatched binary name => regard as multi-binary container and advance argument list + args.remove(0); } - // try first arg as util name. + // 0th argument equals util name? if !args.is_empty() { let util = &args[0][..]; - match umap.get(util) { + match utils.get(util) { Some(&uumain) => { std::process::exit(uumain(args.clone())); } @@ -85,29 +93,29 @@ fn main() { // see if they want help on a specific util if args.len() >= 2 { let util = &args[1][..]; - match umap.get(util) { + match utils.get(util) { Some(&uumain) => { let code = uumain(vec![util.to_owned(), "--help".to_owned()]); std::io::stdout().flush().expect("could not flush stdout"); std::process::exit(code); } None => { - println!("{}: applet not found", util); + println!("{}: function/utility not found", util); std::process::exit(1); } } } - usage(&umap); + usage(&utils); std::process::exit(0); } else { - println!("{}: applet not found", util); + println!("{}: function/utility not found", util); std::process::exit(1); } } } } else { // no arguments provided - usage(&umap); + usage(&utils); std::process::exit(0); } } diff --git a/src/uu/cut/.gitignore b/src/uu/cut/.gitignore index 1de565933..eb5a316cb 100644 --- a/src/uu/cut/.gitignore +++ b/src/uu/cut/.gitignore @@ -1 +1 @@ -target \ No newline at end of file +target diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index a3b61f1fd..e2039f918 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -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. Environment variables: - * EXPR_DEBUG_TOKENS=1 dump expression's tokens - * EXPR_DEBUG_RPN=1 dump expression represented in reverse polish notation - * EXPR_DEBUG_SYA_STEP=1 dump each parser step - * EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree"# + * EXPR_DEBUG_TOKENS=1 dump expression's tokens + * EXPR_DEBUG_RPN=1 dump expression represented in reverse polish notation + * EXPR_DEBUG_SYA_STEP=1 dump each parser step + * EXPR_DEBUG_AST=1 dump expression represented abstract syntax tree"# ); } diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index 8a639a37f..164e83ff0 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -331,19 +331,19 @@ pub fn uumain(args: Vec) -> i32 { 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: - 1K = 1000, 1M = 1000000, ... + 1K = 1000, 1M = 1000000, ... iec accept optional single letter suffix: - 1K = 1024, 1M = 1048576, ... + 1K = 1024, 1M = 1048576, ... iec-i accept optional two-letter suffix: - 1Ki = 1024, 1Mi = 1048576, ..." + 1Ki = 1024, 1Mi = 1048576, ..." ); return 0; diff --git a/src/uu/printf/src/tokenize/num_format/num_format.rs b/src/uu/printf/src/tokenize/num_format/num_format.rs index e84116bfc..8b3f245fe 100644 --- a/src/uu/printf/src/tokenize/num_format/num_format.rs +++ b/src/uu/printf/src/tokenize/num_format/num_format.rs @@ -245,7 +245,7 @@ pub fn num_format(field: &FormatField, in_str_opt: Option<&String>) -> Option +:: 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 +::