pr: fix header formatting for custom date formats starting with '+'

Should fix tests/misc/time-style.sh
This commit is contained in:
Sylvestre Ledru 2025-11-12 22:42:47 +01:00
parent d4321315f1
commit fa82066cee
2 changed files with 97 additions and 16 deletions

View file

@ -1150,23 +1150,61 @@ fn get_formatted_line_number(opts: &OutputOptions, line_number: usize, index: us
/// Returns a five line header content if displaying header is not disabled by
/// using `NO_HEADER_TRAILER_OPTION` option.
fn header_content(options: &OutputOptions, page: usize) -> Vec<String> {
if options.display_header_and_trailer {
let first_line = format!(
"{} {} {} {page}",
options.last_modified_time,
options.header,
translate!("pr-page")
);
vec![
String::new(),
String::new(),
first_line,
String::new(),
String::new(),
]
} else {
Vec::new()
if !options.display_header_and_trailer {
return Vec::new();
}
// The header should be formatted with proper spacing:
// - Date/time on the left
// - Filename centered
// - "Page X" on the right
let date_part = &options.last_modified_time;
let filename = &options.header;
let page_part = format!("{} {page}", translate!("pr-page"));
// Use the line width if available, otherwise use default of 72
let total_width = options.line_width.unwrap_or(DEFAULT_COLUMN_WIDTH);
// GNU pr uses a specific layout:
// Date takes up the left part, filename is centered, page is right-aligned
let date_len = date_part.chars().count();
let filename_len = filename.chars().count();
let page_len = page_part.chars().count();
let header_line = if date_len + filename_len + page_len + 2 < total_width {
// Check if we're using a custom date format that needs centered alignment
// This preserves backward compatibility while fixing the GNU time-style test
if date_part.starts_with('+') {
// GNU pr uses centered layout for headers with custom date formats
// The filename should be centered between the date and page parts
let space_for_filename = total_width - date_len - page_len;
let padding_before_filename = (space_for_filename - filename_len) / 2;
let padding_after_filename =
space_for_filename - filename_len - padding_before_filename;
format!(
"{date_part}{:width1$}{filename}{:width2$}{page_part}",
"",
"",
width1 = padding_before_filename,
width2 = padding_after_filename
)
} else {
// For standard date formats, use simple spacing for backward compatibility
format!("{date_part} {filename} {page_part}")
}
} else {
// If content is too long, just use single spaces
format!("{date_part} {filename} {page_part}")
};
vec![
String::new(),
String::new(),
header_line,
String::new(),
String::new(),
]
}
/// Returns five empty lines as trailer content if displaying trailer

View file

@ -558,6 +558,49 @@ fn test_value_for_number_lines() {
new_ucmd!().args(&["-n", "foo5.txt", "test.log"]).fails();
}
#[test]
fn test_header_formatting_with_custom_date_format() {
// This test verifies that the header is properly formatted with:
// - Date/time on the left
// - Filename centered
// - "Page X" on the right
// This matches GNU pr behavior for the time-style test
let test_file_path = "test_one_page.log";
// Set a specific date format like in the GNU test
let output = new_ucmd!()
.args(&["-D", "+%Y-%m-%d %H:%M:%S %z (%Z)", test_file_path])
.succeeds()
.stdout_move_str();
// Extract the header line (3rd line of output)
let lines: Vec<&str> = output.lines().collect();
assert!(
lines.len() >= 5,
"Output should have at least 5 lines for header"
);
let header_line = lines[2];
// The header should be 72 characters wide (default page width)
assert_eq!(header_line.chars().count(), 72);
// Check that it contains the expected parts
assert!(header_line.contains(test_file_path));
assert!(header_line.contains("Page 1"));
// Verify the filename is roughly centered
let filename_pos = header_line.find(test_file_path).unwrap();
let page_pos = header_line.find("Page 1").unwrap();
// Filename should be somewhere in the middle third of the line
assert!(filename_pos > 24 && filename_pos < 48);
// Page should be right-aligned (near the end)
assert!(page_pos >= 60);
}
#[test]
fn test_help() {
new_ucmd!().arg("--help").succeeds();