struct file_name
{
char *buf;
- size_t n_alloc;
+ idx_t n_alloc;
char *start;
};
{
struct file_name *p = xmalloc (sizeof *p);
- /* Start with a buffer larger than PATH_MAX, but beware of systems
+ /* Start with a buffer larger than likely file names, but beware of systems
on which PATH_MAX is very large -- e.g., INT_MAX. */
- p->n_alloc = MIN (2 * PATH_MAX, 32 * 1024);
+ int init_alloc = 2 * MIN (PATH_MAX, 16 * 1024);
+ p->n_alloc = init_alloc;
- p->buf = xmalloc (p->n_alloc);
- p->start = p->buf + (p->n_alloc - 1);
+ p->buf = xmalloc (init_alloc);
+ p->start = p->buf + init_alloc - 1;
p->start[0] = '\0';
return p;
}
static void
file_name_prepend (struct file_name *p, char const *s, size_t s_len)
{
- size_t n_free = p->start - p->buf;
+ idx_t n_free = p->start - p->buf;
if (n_free < 1 + s_len)
{
- size_t half = p->n_alloc + 1 + s_len;
- /* Use xnmalloc+free rather than xnrealloc, since with the latter
+ /* Call xpalloc with nullptr not p->buf, since with the latter
we'd end up copying the data twice: once via realloc, then again
- to align it with the end of the new buffer. With xnmalloc, we
+ to align it with the end of the new buffer. By passing nullptr we
copy it only once. */
- char *q = xnmalloc (2, half);
- size_t n_used = p->n_alloc - n_free;
- p->start = q + 2 * half - n_used;
- memcpy (p->start, p->buf + n_free, n_used);
+ idx_t n_used = p->n_alloc - n_free;
+ char *buf = xpalloc (nullptr, &p->n_alloc, 1 + s_len - n_free, -1, 1);
+ p->start = memcpy (buf + p->n_alloc - n_free, p->start, n_used);
free (p->buf);
- p->buf = q;
- p->n_alloc = 2 * half;
+ p->buf = buf;
}
p->start -= 1 + s_len;