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

Merge pull request #7765 from aaron-ang/more-mem-constant

more: constant memory initialization overhead
This commit is contained in:
Sylvestre Ledru 2025-05-19 09:14:04 +02:00 committed by GitHub
commit 9fbb6aca3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 850 additions and 653 deletions

1
Cargo.lock generated
View file

@ -3031,6 +3031,7 @@ dependencies = [
"clap", "clap",
"crossterm", "crossterm",
"nix", "nix",
"tempfile",
"unicode-segmentation", "unicode-segmentation",
"unicode-width 0.2.0", "unicode-width 0.2.0",
"uucore", "uucore",

View file

@ -342,7 +342,6 @@ thiserror = "2.0.3"
time = { version = "0.3.36" } time = { version = "0.3.36" }
unicode-segmentation = "1.11.0" unicode-segmentation = "1.11.0"
unicode-width = "0.2.0" unicode-width = "0.2.0"
utf-8 = "0.7.6"
utmp-classic = "0.1.6" utmp-classic = "0.1.6"
uutils_term_grid = "0.7" uutils_term_grid = "0.7"
walkdir = "2.5" walkdir = "2.5"

View file

@ -33,3 +33,6 @@ crossterm = { workspace = true, features = ["use-dev-tty"] }
[[bin]] [[bin]]
name = "more" name = "more"
path = "src/main.rs" path = "src/main.rs"
[dev-dependencies]
tempfile = { workspace = true }

File diff suppressed because it is too large Load diff

View file

@ -2,56 +2,58 @@
// //
// For the full copyright and license information, please view the LICENSE // For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code. // file that was distributed with this source code.
use std::io::IsTerminal;
#[cfg(target_family = "unix")]
use uutests::at_and_ucmd;
use uutests::new_ucmd;
use uutests::util::TestScenario;
use uutests::util_name;
use std::io::IsTerminal;
use uutests::{at_and_ucmd, new_ucmd, util::TestScenario, util_name};
#[cfg(unix)]
#[test] #[test]
fn test_more_no_arg() { fn test_no_arg() {
if std::io::stdout().is_terminal() { if std::io::stdout().is_terminal() {
new_ucmd!().fails().stderr_contains("more: bad usage"); new_ucmd!()
.terminal_simulation(true)
.fails()
.stderr_contains("more: bad usage");
} }
} }
#[test] #[test]
fn test_valid_arg() { fn test_valid_arg() {
if std::io::stdout().is_terminal() { if std::io::stdout().is_terminal() {
let scene = TestScenario::new(util_name!()); let args_list: Vec<&[&str]> = vec![
let at = &scene.fixtures; &["-c"],
&["--clean-print"],
&["-p"],
&["--print-over"],
&["-s"],
&["--squeeze"],
&["-u"],
&["--plain"],
&["-n", "10"],
&["--lines", "0"],
&["--number", "0"],
&["-F", "10"],
&["--from-line", "0"],
&["-P", "something"],
&["--pattern", "-1"],
];
for args in args_list {
test_alive(args);
}
}
}
fn test_alive(args: &[&str]) {
let (at, mut ucmd) = at_and_ucmd!();
let file = "test_file"; let file = "test_file";
at.touch(file); at.touch(file);
scene.ucmd().arg(file).arg("-c").succeeds(); ucmd.args(args)
scene.ucmd().arg(file).arg("--print-over").succeeds();
scene.ucmd().arg(file).arg("-p").succeeds();
scene.ucmd().arg(file).arg("--clean-print").succeeds();
scene.ucmd().arg(file).arg("-s").succeeds();
scene.ucmd().arg(file).arg("--squeeze").succeeds();
scene.ucmd().arg(file).arg("-u").succeeds();
scene.ucmd().arg(file).arg("--plain").succeeds();
scene.ucmd().arg(file).arg("-n").arg("10").succeeds();
scene.ucmd().arg(file).arg("--lines").arg("0").succeeds();
scene.ucmd().arg(file).arg("--number").arg("0").succeeds();
scene.ucmd().arg(file).arg("-F").arg("10").succeeds();
scene
.ucmd()
.arg(file) .arg(file)
.arg("--from-line") .run_no_wait()
.arg("0") .make_assertion()
.succeeds(); .is_alive();
scene.ucmd().arg(file).arg("-P").arg("something").succeeds();
scene.ucmd().arg(file).arg("--pattern").arg("-1").succeeds();
}
} }
#[test] #[test]
@ -67,59 +69,46 @@ fn test_invalid_arg() {
} }
#[test] #[test]
fn test_argument_from_file() { fn test_file_arg() {
if std::io::stdout().is_terminal() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let file = "test_file";
at.write(file, "1\n2");
// output all lines
scene
.ucmd()
.arg("-F")
.arg("0")
.arg(file)
.succeeds()
.no_stderr()
.stdout_contains("1")
.stdout_contains("2");
// output only the second line
scene
.ucmd()
.arg("-F")
.arg("2")
.arg(file)
.succeeds()
.no_stderr()
.stdout_contains("2")
.stdout_does_not_contain("1");
}
}
#[test]
fn test_more_dir_arg() {
// Run the test only if there's a valid terminal, else do nothing // Run the test only if there's a valid terminal, else do nothing
// Maybe we could capture the error, i.e. "Device not found" in that case // Maybe we could capture the error, i.e. "Device not found" in that case
// but I am leaving this for later // but I am leaving this for later
if std::io::stdout().is_terminal() { if std::io::stdout().is_terminal() {
new_ucmd!() // Directory as argument
.arg(".") let mut ucmd = TestScenario::new(util_name!()).ucmd();
ucmd.arg(".")
.succeeds() .succeeds()
.stderr_contains("'.' is a directory."); .stderr_contains("'.' is a directory.");
// Single argument errors
let (at, mut ucmd) = at_and_ucmd!();
at.mkdir_all("folder");
ucmd.arg("folder")
.succeeds()
.stderr_contains("is a directory");
ucmd = TestScenario::new(util_name!()).ucmd();
ucmd.arg("nonexistent_file")
.succeeds()
.stderr_contains("No such file or directory");
// Multiple nonexistent files
ucmd = TestScenario::new(util_name!()).ucmd();
ucmd.arg("file2")
.arg("file3")
.succeeds()
.stderr_contains("file2")
.stderr_contains("file3");
} }
} }
#[test] #[test]
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
fn test_more_invalid_file_perms() { fn test_invalid_file_perms() {
if std::io::stdout().is_terminal() {
use std::fs::{Permissions, set_permissions}; use std::fs::{Permissions, set_permissions};
use std::os::unix::fs::PermissionsExt; use std::os::unix::fs::PermissionsExt;
if std::io::stdout().is_terminal() {
let (at, mut ucmd) = at_and_ucmd!(); let (at, mut ucmd) = at_and_ucmd!();
let permissions = Permissions::from_mode(0o244); let permissions = Permissions::from_mode(0o244);
at.make_file("invalid-perms.txt"); at.make_file("invalid-perms.txt");
@ -129,89 +118,3 @@ fn test_more_invalid_file_perms() {
.stderr_contains("permission denied"); .stderr_contains("permission denied");
} }
} }
#[test]
fn test_more_error_on_single_arg() {
if std::io::stdout().is_terminal() {
let ts = TestScenario::new("more");
ts.fixtures.mkdir_all("folder");
ts.ucmd()
.arg("folder")
.succeeds()
.stderr_contains("is a directory");
ts.ucmd()
.arg("file1")
.succeeds()
.stderr_contains("No such file or directory");
}
}
#[test]
fn test_more_error_on_multiple_files() {
if std::io::stdout().is_terminal() {
let ts = TestScenario::new("more");
ts.fixtures.mkdir_all("folder");
ts.fixtures.make_file("file1");
ts.ucmd()
.arg("folder")
.arg("file2")
.arg("file1")
.succeeds()
.stderr_contains("folder")
.stderr_contains("file2")
.stdout_contains("file1");
ts.ucmd()
.arg("file2")
.arg("file3")
.succeeds()
.stderr_contains("file2")
.stderr_contains("file3");
}
}
#[test]
fn test_more_pattern_found() {
if std::io::stdout().is_terminal() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let file = "test_file";
at.write(file, "line1\nline2");
// output only the second line "line2"
scene
.ucmd()
.arg("-P")
.arg("line2")
.arg(file)
.succeeds()
.no_stderr()
.stdout_does_not_contain("line1")
.stdout_contains("line2");
}
}
#[test]
fn test_more_pattern_not_found() {
if std::io::stdout().is_terminal() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let file = "test_file";
let file_content = "line1\nline2";
at.write(file, file_content);
scene
.ucmd()
.arg("-P")
.arg("something")
.arg(file)
.succeeds()
.no_stderr()
.stdout_contains("Pattern not found")
.stdout_contains("line1")
.stdout_contains("line2");
}
}