* bootstrap.conf (gnulib_modules): Add rawmemchr.
* src/csplit.c: Include idx.h.
* src/csplit.c (record_line_starts):
* src/head.c (elide_tail_lines_pipe):
* src/shuf.c (next_line):
* src/split.c (lines_split):
* src/tail.c (pipe_lines):
* src/wc.c (wc_lines):
Prefer rawmemchr to memchr when rawmemchr is easy.
* src/csplit.c (load_buffer):
* src/head.c (struct linebuffer):
Make room for a 1-byte sentinel.
quotearg
randint
randperm
+ rawmemchr
read-file
readlink
readtokens
#include "die.h"
#include "error.h"
#include "fd-reopen.h"
+#include "idx.h"
#include "quote.h"
#include "safe-read.h"
#include "stdio--.h"
record_line_starts (struct buffer_record *b)
{
char *line_start; /* Start of current line. */
- char *line_end; /* End of each line found. */
- size_t bytes_left; /* Length of incomplete last line. */
size_t lines; /* Number of lines found. */
size_t line_length; /* Length of each line found. */
lines = 0;
line_start = b->buffer;
- bytes_left = b->bytes_used;
+ char *buffer_end = line_start + b->bytes_used;
+ *buffer_end = '\n';
while (true)
{
- line_end = memchr (line_start, '\n', bytes_left);
- if (line_end == NULL)
+ char *line_end = rawmemchr (line_start, '\n');
+ if (line_end == buffer_end)
break;
line_length = line_end - line_start + 1;
keep_new_line (b, line_start, line_length);
- bytes_left -= line_length;
line_start = line_end + 1;
lines++;
}
/* Check for an incomplete last line. */
+ idx_t bytes_left = buffer_end - line_start;
if (bytes_left)
{
if (have_read_eof)
return false;
/* We must make the buffer at least as large as the amount of data
- in the partial line left over from the last call. */
- if (bytes_wanted < hold_count)
- bytes_wanted = hold_count;
+ in the partial line left over from the last call,
+ plus room for a sentinel '\n'. */
+ if (bytes_wanted <= hold_count)
+ bytes_wanted = hold_count + 1;
while (true)
{
hold_count = 0;
}
- b->bytes_used += read_input (p, bytes_avail);
+ b->bytes_used += read_input (p, bytes_avail - 1);
lines_found = record_line_starts (b);
{
struct linebuffer
{
- char buffer[BUFSIZ];
+ char buffer[BUFSIZ + 1];
size_t nbytes;
size_t nlines;
struct linebuffer *next;
/* Count the number of newlines just read. */
{
- char const *buffer_end = tmp->buffer + n_read;
+ char *buffer_end = tmp->buffer + n_read;
+ *buffer_end = line_end;
char const *p = tmp->buffer;
- while ((p = memchr (p, line_end, buffer_end - p)))
+ while ((p = rawmemchr (p, line_end)) < buffer_end)
{
++p;
++tmp->nlines;
operand[n_operands] = p;
}
-/* Return the start of the next line after LINE. The current line
- ends in EOLBYTE, and is guaranteed to end before LINE + N. */
+/* Return the start of the next line after LINE, which is guaranteed
+ to end in EOLBYTE. */
static char *
-next_line (char *line, char eolbyte, size_t n)
+next_line (char *line, char eolbyte)
{
- char *p = memchr (line, eolbyte, n);
+ char *p = rawmemchr (line, eolbyte);
return p + 1;
}
lim = buf + used;
n_lines = 0;
- for (p = buf; p < lim; p = next_line (p, eolbyte, lim - p))
+ for (p = buf; p < lim; p = next_line (p, eolbyte))
n_lines++;
*pline = line = xnmalloc (n_lines + 1, sizeof *line);
line[0] = p = buf;
for (size_t i = 1; i <= n_lines; i++)
- line[i] = p = next_line (p, eolbyte, lim - p);
+ line[i] = p = next_line (p, eolbyte);
return n_lines;
}
*eob = eolchar;
while (true)
{
- bp = memchr (bp, eolchar, eob - bp + 1);
+ bp = rawmemchr (bp, eolchar);
if (bp == eob)
{
if (eob != bp_out) /* do not write 0 bytes! */
size_t j;
for (j = total_lines - n_lines; j; --j)
{
- beg = memchr (beg, line_end, buffer_end - beg);
- assert (beg);
+ beg = rawmemchr (beg, line_end);
++beg;
}
}
}
else
{
- /* memchr is more efficient with longer lines. */
- while ((p = memchr (p, '\n', end - p)))
+ /* rawmemchr is more efficient with longer lines. */
+ *end = '\n';
+ while ((p = rawmemchr (p, '\n')) < end)
{
++p;
++lines;