Skip to content

pr: write all characters in each row in a single loop - #10475

Open
jfinkels wants to merge 5 commits into
uutils:mainfrom
jfinkels:pr-format-row
Open

pr: write all characters in each row in a single loop#10475
jfinkels wants to merge 5 commits into
uutils:mainfrom
jfinkels:pr-format-row

Conversation

@jfinkels

Copy link
Copy Markdown
Collaborator

Depends on #10474

Write the contents of the entire row to a single String before writing the full row to stdout. Before this commit, each cell was put in its own String and then that String was written to stdout before moving on to the next cell in the row. After this commit, the contents of each cell in a row is appended to a single String, and that String is written to stdout only after all cells in the row have been processed.

This change will make it much easier to make improvements to the logic of which characters to write at each point in the row, since the current logic does not match the output GNU pr very well. For example, the decision about whether to write a tab or multiple spaces requires knowing how many characters have been written in the current row, which was not easily accessible before.

Remove some unneeded parameters from the `get_line_for_printing()`
helper function since the values are already contained in the
`OutputOptions` parameter.
Write the contents of the entire row to a single String before writing
the full row to stdout. Before this commit, each cell was put in its own
String and then that String was written to stdout before moving on to
the next cell in the row. After this commit, the contents of each cell
in a row is appended to a single String, and that String is written to
stdout only after all cells in the row have been processed.

This change will make it much easier to make improvements to the logic
of which characters to write at each point in the row, since the current
logic does not match the output GNU `pr` very well. For example, the
decision about whether to write a tab or multiple spaces requires
knowing how many characters have been written in the current row, which
was not easily accessible before.
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/follow-name (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tty/tty-eof (passes in this run but fails in the 'main' branch)

@jfinkels
jfinkels marked this pull request as ready for review January 25, 2026 16:40
Comment thread src/uu/pr/src/pr.rs
if cell.is_none() && !merge {
out.write_all(result.as_bytes())?;
out.write_all(options.content_line_separator.as_bytes())?;
return Ok(false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the docs it says that "A bool indicating whether printing terminated early due to a" and here its false instead of true I think this is swapped

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'll try to cook up the missing test case to cover this.

Comment thread src/uu/pr/src/pr.rs

// Finally, terminate the line with the specified separator.
out.write_all(options.content_line_separator.as_bytes())?;
Ok(true)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for swapping this

Comment thread src/uu/pr/src/pr.rs
// If the cell is None, terminate the line early.
if cell.is_none() && !merge {
out.write_all(result.as_bytes())?;
out.write_all(options.content_line_separator.as_bytes())?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can determine if the content_line_seperator is written here, because that depends on the terminated_early variable used by the caller of this method since it should only be printed if "feed_line_present" is not equal to true

Comment thread src/uu/pr/src/pr.rs
result.push(' ');
}
}
result.truncate(col_start + min_width);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here its truncating by bytes not by characters:

let prefix: String = result[..col_start].to_string();
let cell_truncated: String = result[col_start..].chars().take(min_width).collect();
result = prefix + &cell_truncated;

@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Congrats! The gnu test tests/pr/bounded-memory is no longer failing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants