1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Merge branch 'main' into 2884-time-0.3

This commit is contained in:
Sylvestre Ledru 2022-05-02 18:14:14 +02:00 committed by GitHub
commit 9b69e6fd47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 340 additions and 53 deletions

View file

@ -198,7 +198,7 @@ jobs:
do do
if ! grep -Fxq ${LINE}<<<"${REF_ERROR}" if ! grep -Fxq ${LINE}<<<"${REF_ERROR}"
then then
echo "::error ::GNU test failed: ${LINE}. ${LINE} is passing on '${{ steps.vars.outputs.repo_default_branch }}'. Maybe you have to rebase?" echo "::error ::GNU test error: ${LINE}. ${LINE} is passing on '${{ steps.vars.outputs.repo_default_branch }}'. Maybe you have to rebase?"
have_new_failures="true" have_new_failures="true"
fi fi
done done

12
Cargo.lock generated
View file

@ -273,9 +273,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_complete" name = "clap_complete"
version = "3.1.2" version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1506b87ee866f7a53a5131f7b31fba656170d797e873d0609884cfd56b8bbda8" checksum = "1d7ca9141e27e6ebc52e3c378b0c07f3cea52db46ed1cc5861735fb697b56356"
dependencies = [ dependencies = [
"clap 3.1.12", "clap 3.1.12",
] ]
@ -1021,9 +1021,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.124" version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -1623,9 +1623,9 @@ dependencies = [
[[package]] [[package]]
name = "retain_mut" name = "retain_mut"
version = "0.1.2" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53552c6c49e1e13f1a203ef0080ab3bbef0beb570a528993e83df057a9d9bba1" checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086"
[[package]] [[package]]
name = "rlimit" name = "rlimit"

View file

@ -16,7 +16,7 @@ path = "src/chmod.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs", "mode"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs", "mode"] }
[[bin]] [[bin]]

View file

@ -21,7 +21,7 @@ path = "src/cp.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
filetime = "0.2" filetime = "0.2"
libc = "0.2.124" libc = "0.2.125"
quick-error = "2.0.1" quick-error = "2.0.1"
selinux = { version="0.2", optional=true } selinux = { version="0.2", optional=true }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs", "perms", "mode"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs", "perms", "mode"] }

View file

@ -16,7 +16,7 @@ path = "src/hostid.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]] [[bin]]

View file

@ -16,7 +16,7 @@ path = "src/kill.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["signals"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["signals"] }
[[bin]] [[bin]]

View file

@ -15,7 +15,7 @@ edition = "2021"
path = "src/logname.rs" path = "src/logname.rs"
[dependencies] [dependencies]
libc = "0.2.124" libc = "0.2.125"
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -16,7 +16,7 @@ path = "src/mkfifo.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]] [[bin]]

View file

@ -17,7 +17,7 @@ path = "src/mknod.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "^0.2.124" libc = "^0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["mode"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["mode"] }
[[bin]] [[bin]]

View file

@ -79,7 +79,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let template = matches.value_of(ARG_TEMPLATE).unwrap(); let template = matches.value_of(ARG_TEMPLATE).unwrap();
let tmpdir = matches.value_of(OPT_TMPDIR).unwrap_or_default(); let tmpdir = matches.value_of(OPT_TMPDIR).unwrap_or_default();
let (template, mut tmpdir) = if matches.is_present(OPT_TMPDIR) // Treat the template string as a path to get the directory
// containing the last component.
let path = PathBuf::from(template);
let (template, tmpdir) = if matches.is_present(OPT_TMPDIR)
&& !PathBuf::from(tmpdir).is_dir() // if a temp dir is provided, it must be an actual path && !PathBuf::from(tmpdir).is_dir() // if a temp dir is provided, it must be an actual path
&& tmpdir.contains("XXX") && tmpdir.contains("XXX")
// If this is a template, it has to contain at least 3 X // If this is a template, it has to contain at least 3 X
@ -97,8 +101,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let tmp = env::temp_dir(); let tmp = env::temp_dir();
(tmpdir, tmp) (tmpdir, tmp)
} else if !matches.is_present(OPT_TMPDIR) { } else if !matches.is_present(OPT_TMPDIR) {
let tmp = env::temp_dir(); // In this case, the command line was `mktemp -t XXX`, so we
(template, tmp) // treat the argument `XXX` as though it were a filename
// regardless of whether it has path separators in it.
if matches.is_present(OPT_T) {
let tmp = env::temp_dir();
(template, tmp)
// In this case, the command line was `mktemp XXX`, so we need
// to parse out the parent directory and the filename from the
// argument `XXX`, since it may be include path separators.
} else {
let tmp = match path.parent() {
None => PathBuf::from("."),
Some(d) => PathBuf::from(d),
};
let filename = path.file_name();
let template = filename.unwrap().to_str().unwrap();
(template, tmp)
}
} else { } else {
(template, PathBuf::from(tmpdir)) (template, PathBuf::from(tmpdir))
}; };
@ -113,10 +133,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
return Err(MkTempError::InvalidTemplate(template.into()).into()); return Err(MkTempError::InvalidTemplate(template.into()).into());
} }
if matches.is_present(OPT_T) {
tmpdir = env::temp_dir();
}
let res = if dry_run { let res = if dry_run {
dry_exec(tmpdir, prefix, rand, suffix) dry_exec(tmpdir, prefix, rand, suffix)
} else { } else {
@ -272,5 +288,19 @@ fn exec(dir: &Path, prefix: &str, rand: usize, suffix: &str, make_dir: bool) ->
.map_err(|e| MkTempError::PersistError(e.file.path().to_path_buf()))? .map_err(|e| MkTempError::PersistError(e.file.path().to_path_buf()))?
.1 .1
}; };
// Get just the last component of the path to the created
// temporary file or directory.
let filename = path.file_name();
let filename = filename.unwrap().to_str().unwrap();
// Join the directory to the path to get the path to print. We
// cannot use the path returned by the `Builder` because it gives
// the absolute path and we need to return a filename that matches
// the template given on the command-line which might be a
// relative path.
let mut path = dir.to_path_buf();
path.push(filename);
println_verbatim(path).map_err_context(|| "failed to print directory name".to_owned()) println_verbatim(path).map_err_context(|| "failed to print directory name".to_owned())
} }

View file

@ -16,7 +16,7 @@ path = "src/nice.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
nix = { version = "0.24.1", default-features = false } nix = { version = "0.24.1", default-features = false }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -16,7 +16,7 @@ path = "src/nohup.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
atty = "0.2" atty = "0.2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }

View file

@ -15,7 +15,7 @@ edition = "2021"
path = "src/nproc.rs" path = "src/nproc.rs"
[dependencies] [dependencies]
libc = "0.2.124" libc = "0.2.125"
num_cpus = "1.10" num_cpus = "1.10"
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }

View file

@ -16,7 +16,7 @@ path = "src/pathchk.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]] [[bin]]

View file

@ -5,7 +5,7 @@
// * For the full copyright and license information, please view the LICENSE // * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code. // * file that was distributed with this source code.
// spell-checker:ignore (ToDOs) corasick memchr Roff trunc oset iset // spell-checker:ignore (ToDOs) corasick memchr Roff trunc oset iset CHARCLASS
use clap::{crate_version, Arg, Command}; use clap::{crate_version, Arg, Command};
use regex::Regex; use regex::Regex;
@ -31,6 +31,8 @@ const ABOUT: &str = "\
Mandatory arguments to long options are mandatory for short options too.\n\ Mandatory arguments to long options are mandatory for short options too.\n\
With no FILE, or when FILE is -, read standard input. Default is '-F /'."; With no FILE, or when FILE is -, read standard input. Default is '-F /'.";
const REGEX_CHARCLASS: &str = "^-]\\";
#[derive(Debug)] #[derive(Debug)]
enum OutFormat { enum OutFormat {
Dumb, Dumb,
@ -88,6 +90,18 @@ fn read_word_filter_file(
Ok(words) Ok(words)
} }
/// reads contents of file as unique set of characters to be used with the break-file option
fn read_char_filter_file(
matches: &clap::ArgMatches,
option: &str,
) -> std::io::Result<HashSet<char>> {
let filename = matches.value_of(option).expect("parsing options failed!");
let mut reader = File::open(filename)?;
let mut buffer = String::new();
reader.read_to_string(&mut buffer)?;
Ok(buffer.chars().collect())
}
#[derive(Debug)] #[derive(Debug)]
struct WordFilter { struct WordFilter {
only_specified: bool, only_specified: bool,
@ -113,9 +127,23 @@ impl WordFilter {
} else { } else {
(false, HashSet::new()) (false, HashSet::new())
}; };
if matches.is_present(options::BREAK_FILE) { let break_set: Option<HashSet<char>> = if matches.is_present(options::BREAK_FILE)
return Err(PtxError::NotImplemented("-b").into()); && !matches.is_present(options::WORD_REGEXP)
} {
let chars =
read_char_filter_file(matches, options::BREAK_FILE).map_err_context(String::new)?;
let mut hs: HashSet<char> = if config.gnu_ext {
HashSet::new() // really only chars found in file
} else {
// GNU off means at least these are considered
[' ', '\t', '\n'].iter().cloned().collect()
};
hs.extend(chars);
Some(hs)
} else {
// if -W takes precedence or default
None
};
// Ignore empty string regex from cmd-line-args // Ignore empty string regex from cmd-line-args
let arg_reg: Option<String> = if matches.is_present(options::WORD_REGEXP) { let arg_reg: Option<String> = if matches.is_present(options::WORD_REGEXP) {
match matches.value_of(options::WORD_REGEXP) { match matches.value_of(options::WORD_REGEXP) {
@ -134,7 +162,21 @@ impl WordFilter {
let reg = match arg_reg { let reg = match arg_reg {
Some(arg_reg) => arg_reg, Some(arg_reg) => arg_reg,
None => { None => {
if config.gnu_ext { if break_set.is_some() {
format!(
"[^{}]+",
break_set
.unwrap()
.into_iter()
.map(|c| if REGEX_CHARCLASS.contains(c) {
format!("\\{}", c)
} else {
c.to_string()
})
.collect::<Vec<String>>()
.join("")
)
} else if config.gnu_ext {
"\\w+".to_owned() "\\w+".to_owned()
} else { } else {
"[^ \t\n]+".to_owned() "[^ \t\n]+".to_owned()

View file

@ -17,7 +17,7 @@ path = "src/rmdir.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
libc = "0.2.124" libc = "0.2.125"
[[bin]] [[bin]]
name = "rmdir" name = "rmdir"

View file

@ -16,7 +16,7 @@ path = "src/sync.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["wide"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["wide"] }
winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] } winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] }

View file

@ -16,7 +16,7 @@ path = "src/tail.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] }
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]

View file

@ -16,8 +16,8 @@ path = "src/tee.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
retain_mut = "=0.1.2" # ToDO: [2021-01-01; rivy; maint/MinSRV] ~ v0.1.5 uses const generics which aren't stabilized until rust v1.51.0 retain_mut = "=0.1.7" # ToDO: [2021-01-01; rivy; maint/MinSRV] ~ v0.1.5 uses const generics which aren't stabilized until rust v1.51.0
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc"] }
[[bin]] [[bin]]

View file

@ -16,7 +16,7 @@ path = "src/test.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" } uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[target.'cfg(target_os = "redox")'.dependencies] [target.'cfg(target_os = "redox")'.dependencies]

View file

@ -16,7 +16,7 @@ path = "src/timeout.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
nix = { version = "0.24.1", default-features = false, features = ["signal"] } nix = { version = "0.24.1", default-features = false, features = ["signal"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["process", "signals"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["process", "signals"] }

View file

@ -16,7 +16,7 @@ path = "src/tty.rs"
[dependencies] [dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] } clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.124" libc = "0.2.125"
atty = "0.2" atty = "0.2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] } uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }

View file

@ -22,7 +22,7 @@ uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=[
winapi = { version = "0.3", features = ["lmcons"] } winapi = { version = "0.3", features = ["lmcons"] }
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = "0.2.124" libc = "0.2.125"
[[bin]] [[bin]]
name = "whoami" name = "whoami"

View file

@ -31,7 +31,7 @@ time = { version="<= 0.3", optional=true, features = ["formatting", "local-offse
data-encoding = { version="2.1", optional=true } data-encoding = { version="2.1", optional=true }
data-encoding-macro = { version="0.1.12", optional=true } data-encoding-macro = { version="0.1.12", optional=true }
z85 = { version="3.0.5", optional=true } z85 = { version="3.0.5", optional=true }
libc = { version="0.2.124", optional=true } libc = { version="0.2.125", optional=true }
once_cell = "1.10.0" once_cell = "1.10.0"
os_display = "0.1.3" os_display = "0.1.3"

View file

@ -152,7 +152,11 @@ impl SubParser {
if parser.min_width_is_asterisk { if parser.min_width_is_asterisk {
CanAsterisk::Asterisk CanAsterisk::Asterisk
} else { } else {
CanAsterisk::Fixed(parser.min_width_tmp.map(|x| x.parse::<isize>().unwrap())) CanAsterisk::Fixed(
parser
.min_width_tmp
.map(|x| x.parse::<isize>().unwrap_or(1)),
)
}, },
if parser.second_field_is_asterisk { if parser.second_field_is_asterisk {
CanAsterisk::Asterisk CanAsterisk::Asterisk

View file

@ -31,7 +31,7 @@ fn test_default_output() {
scene scene
.ucmd() .ucmd()
.succeeds() .succeeds()
.stdout_does_not_match(&Regex::new("[rwx][^some-file1]").unwrap()); .stdout_does_not_match(&Regex::new("[rwx-]{10}.*some-file1$").unwrap());
} }
#[test] #[test]
@ -51,5 +51,5 @@ fn test_long_output() {
.ucmd() .ucmd()
.arg("-l") .arg("-l")
.succeeds() .succeeds()
.stdout_matches(&Regex::new("[rwx][^some-file1]").unwrap()); .stdout_matches(&Regex::new("[rwx-]{10}.*some-file1$").unwrap());
} }

View file

@ -411,3 +411,74 @@ fn test_mktemp_directory_tmpdir() {
result.no_stderr().stdout_contains("apt-key-gpghome."); result.no_stderr().stdout_contains("apt-key-gpghome.");
assert!(PathBuf::from(result.stdout_str().trim()).is_dir()); assert!(PathBuf::from(result.stdout_str().trim()).is_dir());
} }
/// Decide whether a string matches a given template.
///
/// In the template, the character `'X'` is treated as a wildcard,
/// that is, it matches anything. All other characters in `template`
/// and `s` must match exactly.
///
/// # Examples
///
/// ```rust,ignore
/// # These all match.
/// assert!(matches_template("abc", "abc"));
/// assert!(matches_template("aXc", "abc"));
/// assert!(matches_template("XXX", "abc"));
///
/// # None of these match
/// assert!(matches_template("abc", "abcd"));
/// assert!(matches_template("abc", "ab"));
/// assert!(matches_template("aXc", "abd"));
/// assert!(matches_template("XXX", "abcd"));
/// ```
///
fn matches_template(template: &str, s: &str) -> bool {
if template.len() != s.len() {
return false;
}
for (a, b) in template.chars().zip(s.chars()) {
if !(a == 'X' || a == b) {
return false;
}
}
true
}
/// An assertion that uses [`matches_template`] and adds a helpful error message.
macro_rules! assert_matches_template {
($template:expr, $s:expr) => {{
assert!(
matches_template($template, $s),
"\"{}\" != \"{}\"",
$template,
$s
);
}};
}
/// Test that the file is created in the directory given by the template.
#[test]
fn test_respect_template() {
let (at, mut ucmd) = at_and_ucmd!();
let template = "XXX";
let result = ucmd.arg(template).succeeds();
let filename = result.no_stderr().stdout_str().trim_end();
assert_matches_template!(template, filename);
assert!(at.file_exists(filename));
}
/// Test that the file is created in the directory given by the template.
#[test]
fn test_respect_template_directory() {
let (at, mut ucmd) = at_and_ucmd!();
at.mkdir("d");
#[cfg(not(windows))]
let template = "d/XXX";
#[cfg(windows)]
let template = r"d\XXX";
let result = ucmd.arg(template).succeeds();
let filename = result.no_stderr().stdout_str().trim_end();
assert_matches_template!(template, filename);
assert!(at.file_exists(filename));
}

View file

@ -446,6 +446,14 @@ fn sub_any_specifiers_after_period() {
.stdout_only("3"); .stdout_only("3");
} }
#[test]
fn unspecified_left_justify_is_1_width() {
new_ucmd!()
.args(&["%-o"]) //spell-checker:disable-line
.succeeds()
.stdout_only("0");
}
#[test] #[test]
fn sub_any_specifiers_after_second_param() { fn sub_any_specifiers_after_second_param() {
new_ucmd!() new_ucmd!()

View file

@ -71,3 +71,35 @@ fn gnu_ext_disabled_ignore_and_only_file() {
.succeeds() .succeeds()
.stdout_only_fixture("gnu_ext_disabled_ignore_and_only_file.expected"); .stdout_only_fixture("gnu_ext_disabled_ignore_and_only_file.expected");
} }
#[test]
fn gnu_ext_disabled_output_width_50() {
new_ucmd!()
.args(&["-G", "-w", "50", "input"])
.succeeds()
.stdout_only_fixture("gnu_ext_disabled_output_width_50.expected");
}
#[test]
fn gnu_ext_disabled_output_width_70() {
new_ucmd!()
.args(&["-G", "-w", "70", "input"])
.succeeds()
.stdout_only_fixture("gnu_ext_disabled_output_width_70.expected");
}
#[test]
fn gnu_ext_disabled_break_file() {
new_ucmd!()
.args(&["-G", "-b", "break_file", "input"])
.succeeds()
.stdout_only_fixture("gnu_ext_disabled_break_file.expected");
}
#[test]
fn gnu_ext_disabled_empty_word_regexp_ignores_break_file() {
new_ucmd!()
.args(&["-G", "-b", "break_file", "-R", "-W", "", "input"])
.succeeds()
.stdout_only_fixture("gnu_ext_disabled_rightward_no_ref.expected");
}

View file

@ -31,7 +31,7 @@ fn test_default_output() {
scene scene
.ucmd() .ucmd()
.succeeds() .succeeds()
.stdout_matches(&Regex::new("[rwx][^some-file1]").unwrap()); .stdout_matches(&Regex::new("[rwx-]{10}.*some-file1$").unwrap());
} }
#[test] #[test]
@ -51,5 +51,5 @@ fn test_column_output() {
.ucmd() .ucmd()
.arg("-C") .arg("-C")
.succeeds() .succeeds()
.stdout_does_not_match(&Regex::new("[rwx][^some-file1]").unwrap()); .stdout_does_not_match(&Regex::new("[rwx-]{10}.*some-file1$").unwrap());
} }

1
tests/fixtures/ptx/break_file vendored Normal file
View file

@ -0,0 +1 @@
abc_e^-]\

View file

@ -0,0 +1,42 @@
.xx "" "" """quotes"", for roff" ""
.xx "" "and some other like %a, b" "#, c$c" ""
.xx "" "and some other like %a, b#, c" "$c" ""
.xx "" "and some other like" "%a, b#, c$c" ""
.xx "" "and some other like %a" ", b#, c$c" ""
.xx "" """quotes""," "for roff" ""
.xx "" "{brackets}" "for tex" ""
.xx "" "" "hello world!" ""
.xx "" "let's c" "heck special characters:" ""
.xx "" "let's check special c" "haracters:" ""
.xx "" "let's check spec" "ial characters:" ""
.xx "" "let's chec" "k special characters:" ""
.xx "" "{brac" "kets} for tex" ""
.xx "" "oh, and bac" "k\slash" ""
.xx "" "" "let's check special characters:" ""
.xx "" "let's check specia" "l characters:" ""
.xx "" "and some other" "like %a, b#, c$c" ""
.xx "" "he" "llo world!" ""
.xx "" "maybe a" "lso~or^" ""
.xx "" "" "maybe also~or^" ""
.xx "" "a" "nd some other like %a, b#, c$c" ""
.xx "" "oh, a" "nd back\slash" ""
.xx "" "" "oh, and back\slash" ""
.xx "" "and some" "other like %a, b#, c$c" ""
.xx "" "let's check special cha" "racters:" ""
.xx "" "{b" "rackets} for tex" ""
.xx "" "and some othe" "r like %a, b#, c$c" ""
.xx "" """quotes"", for" "roff" ""
.xx "" "let's check special characte" "rs:" ""
.xx "" """quote" "s"", for roff" ""
.xx "" "oh, and back\sla" "sh" ""
.xx "" "oh, and back\" "slash" ""
.xx "" "and" "some other like %a, b#, c$c" ""
.xx "" "let's check" "special characters:" ""
.xx "" "let's check special charac" "ters:" ""
.xx "" "{brackets} for" "tex" ""
.xx "" "le" "t's check special characters:" ""
.xx "" "{bracke" "ts} for tex" ""
.xx "" "hello" "world!" ""
.xx "" "{brackets} for te" "x" ""
.xx "" "ma" "ybe also~or^" ""
.xx "" "" "{brackets} for tex" ""

View file

@ -0,0 +1,24 @@
.xx "" "" """quotes"", for roff" ""
.xx "" "and some other like" "%a, b#, c$c" ""
.xx "" "maybe" "also~or^" ""
.xx "%a, b#, c$c" "" "and some other like" ""
.xx "" "oh," "and back\slash" ""
.xx "" "some other like %a," "b#, c$c" "and"
.xx "" "oh, and" "back\slash" ""
.xx "" "other like %a, b#," "c$c" "and some"
.xx "" "let's check special" "characters:" ""
.xx "characters:" "let's" "check special" ""
.xx "" """quotes""," "for roff" ""
.xx "" "{brackets}" "for tex" ""
.xx "" "" "hello world!" ""
.xx "characters:" "" "let's check special" ""
.xx "" "and some other" "like %a, b#, c$c" ""
.xx "" "" "maybe also~or^" ""
.xx "" "" "oh, and back\slash" ""
.xx "" "and some" "other like %a, b#, c$c" ""
.xx "" """quotes"", for" "roff" ""
.xx "b#, c$c" "and" "some other like %a," ""
.xx "" "let's check" "special characters:" ""
.xx "" "{brackets} for" "tex" ""
.xx "" "hello" "world!" ""
.xx "" "" "{brackets} for tex" ""

View file

@ -0,0 +1,24 @@
.xx "" "" """quotes"", for roff" ""
.xx "" "and some other like" "%a, b#, c$c" ""
.xx "" "maybe" "also~or^" ""
.xx "" "" "and some other like %a, b#, c$c" ""
.xx "" "oh," "and back\slash" ""
.xx "" "and some other like %a," "b#, c$c" ""
.xx "" "oh, and" "back\slash" ""
.xx "" "and some other like %a, b#," "c$c" ""
.xx "" "let's check special" "characters:" ""
.xx "" "let's" "check special characters:" ""
.xx "" """quotes""," "for roff" ""
.xx "" "{brackets}" "for tex" ""
.xx "" "" "hello world!" ""
.xx "" "" "let's check special characters:" ""
.xx "" "and some other" "like %a, b#, c$c" ""
.xx "" "" "maybe also~or^" ""
.xx "" "" "oh, and back\slash" ""
.xx "" "and some" "other like %a, b#, c$c" ""
.xx "" """quotes"", for" "roff" ""
.xx "" "and" "some other like %a, b#, c$c" ""
.xx "" "let's check" "special characters:" ""
.xx "" "{brackets} for" "tex" ""
.xx "" "hello" "world!" ""
.xx "" "" "{brackets} for tex" ""

View file

@ -62,14 +62,23 @@ for binary in $(./build-aux/gen-lists-of-programs.sh --list-progs); do
} }
done done
./bootstrap if test -f gnu-built; then
./configure --quiet --disable-gcc-warnings echo "GNU build already found. Skip"
#Add timeout to to protect against hangs echo "'rm -f $(pwd)/gnu-built' to force the build"
sed -i 's|^"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver echo "Note: the customization of the tests will still happen"
# Change the PATH in the Makefile to test the uutils coreutils instead of the GNU coreutils exit 0
sed -i "s/^[[:blank:]]*PATH=.*/ PATH='${UU_BUILD_DIR//\//\\/}\$(PATH_SEPARATOR)'\"\$\$PATH\" \\\/" Makefile else
sed -i 's| tr | /usr/bin/tr |' tests/init.sh ./bootstrap
make -j "$(nproc)" ./configure --quiet --disable-gcc-warnings
#Add timeout to to protect against hangs
sed -i 's|^"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver
# Change the PATH in the Makefile to test the uutils coreutils instead of the GNU coreutils
sed -i "s/^[[:blank:]]*PATH=.*/ PATH='${UU_BUILD_DIR//\//\\/}\$(PATH_SEPARATOR)'\"\$\$PATH\" \\\/" Makefile
sed -i 's| tr | /usr/bin/tr |' tests/init.sh
make -j "$(nproc)"
touch gnu-built
fi
# Handle generated factor tests # Handle generated factor tests
t_first=00 t_first=00
t_max=36 t_max=36