Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 35 additions & 14 deletions src/uu/uniq/src/uniq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct Uniq {
slice_stop: Option<usize>,
ignore_case: bool,
zero_terminated: bool,
is_c_locale: bool,
}

#[derive(Default)]
Expand Down Expand Up @@ -87,6 +88,7 @@ impl Uniq {

let mut next_buf = Vec::with_capacity(1024);
let mut next_meta = LineMeta::default();
let mut line_out = Vec::with_capacity(1024);

loop {
if !Self::read_line(&mut reader, &mut next_buf, line_terminator)? {
Expand All @@ -97,7 +99,13 @@ impl Uniq {

if self.keys_are_equal(&current_buf, &current_meta, &next_buf, &next_meta) {
if self.all_repeated {
self.write_line(writer, &current_buf, group_count, first_line_printed)?;
self.write_line(
writer,
&mut line_out,
&current_buf,
group_count,
first_line_printed,
)?;
first_line_printed = true;
std::mem::swap(&mut current_buf, &mut next_buf);
std::mem::swap(&mut current_meta, &mut next_meta);
Expand All @@ -107,7 +115,13 @@ impl Uniq {
if (group_count == 1 && !self.repeats_only)
|| (group_count > 1 && !self.uniques_only)
{
self.write_line(writer, &current_buf, group_count, first_line_printed)?;
self.write_line(
writer,
&mut line_out,
&current_buf,
group_count,
first_line_printed,
)?;
first_line_printed = true;
}
std::mem::swap(&mut current_buf, &mut next_buf);
Expand All @@ -118,7 +132,13 @@ impl Uniq {
}

if (group_count == 1 && !self.repeats_only) || (group_count > 1 && !self.uniques_only) {
self.write_line(writer, &current_buf, group_count, first_line_printed)?;
self.write_line(
writer,
&mut line_out,
&current_buf,
group_count,
first_line_printed,
)?;
first_line_printed = true;
}
if (self.delimiters == Delimiters::Append || self.delimiters == Delimiters::Both)
Expand Down Expand Up @@ -202,7 +222,7 @@ impl Uniq {
if remainder.is_empty() {
return key_start;
}
if Self::is_c_locale() {
if self.is_c_locale {
// for C or POSIX we count bytes
key_start + remainder.len().min(limit)
} else if let Ok(valid) = std::str::from_utf8(remainder) {
Expand Down Expand Up @@ -264,6 +284,7 @@ impl Uniq {
fn write_line(
&self,
writer: &mut impl Write,
line_out: &mut Vec<u8>,
line: &[u8],
count: usize,
first_line_printed: bool,
Expand All @@ -274,21 +295,20 @@ impl Uniq {
write_line_terminator!(writer, line_terminator)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there some special reason line_terminator is written differently here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sorry, what do you mean ? :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here write_line_terminator! is used whereas on line 307 line_out.push(line_terminator); replaces the use of write_line_terminator!.

}

let mut count_buf = [0u8; Self::COUNT_PREFIX_BUF_SIZE];
line_out.clear();

if self.show_counts {
// Call the associated function (no &self) after the refactor above.
let mut count_buf = [0u8; Self::COUNT_PREFIX_BUF_SIZE];
let prefix = Self::build_count_prefix(count, &mut count_buf);
writer
.write_all(prefix)
.map_err_context(|| translate!("uniq-error-write-error"))?;
line_out.extend_from_slice(prefix);
}

writer
.write_all(line)
.map_err_context(|| translate!("uniq-error-write-error"))?;
line_out.extend_from_slice(line);
line_out.push(line_terminator);

write_line_terminator!(writer, line_terminator)
writer
.write_all(line_out)
.map_err_context(|| translate!("uniq-error-write-error"))
}

const COUNT_PREFIX_WIDTH: usize = 7;
Expand Down Expand Up @@ -680,6 +700,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
slice_stop: opt_parsed(options::CHECK_CHARS, &matches)?,
ignore_case: matches.get_flag(options::IGNORE_CASE),
zero_terminated: matches.get_flag(options::ZERO_TERMINATED),
is_c_locale: Uniq::is_c_locale(),
};

if uniq.show_counts && uniq.all_repeated {
Expand Down Expand Up @@ -825,7 +846,7 @@ fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
let in_file = File::open(path).map_err_context(
|| translate!("uniq-error-could-not-open", "path" => path.maybe_quote()),
)?;
Box::new(BufReader::new(in_file))
Box::new(BufReader::with_capacity(OUTPUT_BUFFER_CAPACITY, in_file))
}
_ => Box::new(stdin().lock()),
})
Expand Down
Loading