+2006-10-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Avoid some C++ diagnostics reported by Bruno Haible.
+ * lib/quotearg.c (clone_quoting_options): Use xmemdup rather than
+ xmalloc.
+ (quotearg_alloc): Use xcharalloc rather than xmalloc.
+ (struct slotvec): Move to top level.
+ (quotearg_n_options): Rewrite to avoid xmalloc.
+ * lib/xalloc.h (xcharalloc): New function.
+ * (xrealloc, xnrealloc, x2realloc, x2nrealloc, xmemdup):
+ [defined __cplusplus]: Add function template that provides result
+ type propagation. This part of the change is from Bruno Haible.
+
2006-10-29 Bruno Haible <bruno@clisp.org>
Make it compile in C++ mode.
clone_quoting_options (struct quoting_options *o)
{
int e = errno;
- struct quoting_options *p = xmalloc (sizeof *p);
- *p = *(o ? o : &default_quoting_options);
+ struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
+ sizeof *o);
errno = e;
return p;
}
{
int e = errno;
size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1;
- char *buf = xmalloc (bufsize);
+ char *buf = xcharalloc (bufsize);
quotearg_buffer (buf, bufsize, arg, argsize, o);
errno = e;
return buf;
}
+/* A storage slot with size and pointer to a value. */
+struct slotvec
+{
+ size_t size;
+ char *val;
+};
+
/* Use storage slot N to return a quoted version of argument ARG.
ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
null-terminated string.
static char slot0[256];
static unsigned int nslots = 1;
unsigned int n0 = n;
- struct slotvec
- {
- size_t size;
- char *val;
- };
static struct slotvec slotvec0 = {sizeof slot0, slot0};
static struct slotvec *slotvec = &slotvec0;
+ struct slotvec *sv = slotvec;
if (n < 0)
abort ();
revert to the original type, so that the test in xalloc_oversized
is once again performed only at compile time. */
size_t n1 = n0 + 1;
+ bool preallocated = (sv == &slotvec0);
- if (xalloc_oversized (n1, sizeof *slotvec))
+ if (xalloc_oversized (n1, sizeof *sv))
xalloc_die ();
- if (slotvec == &slotvec0)
- {
- slotvec = xmalloc (sizeof *slotvec);
- *slotvec = slotvec0;
- }
- slotvec = xrealloc (slotvec, n1 * sizeof *slotvec);
- memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec);
+ slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
+ if (preallocated)
+ *sv = slotvec0;
+ memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
nslots = n1;
}
{
- size_t size = slotvec[n].size;
- char *val = slotvec[n].val;
+ size_t size = sv[n].size;
+ char *val = sv[n].val;
size_t qsize = quotearg_buffer (val, size, arg, argsize, options);
if (size <= qsize)
{
- slotvec[n].size = size = qsize + 1;
+ sv[n].size = size = qsize + 1;
if (val != slot0)
free (val);
- slotvec[n].val = val = xmalloc (size);
+ sv[n].val = val = xcharalloc (size);
quotearg_buffer (val, size, arg, argsize, options);
}
# define xalloc_oversized(n, s) \
((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
+/* Return a pointer to a new buffer of S bytes. This is like xmalloc,
+ except it returns char *. */
+static inline char *
+xcharalloc (size_t s)
+{
+ return (char *) xmalloc (s);
+}
+
# ifdef __cplusplus
}
+
+/* C++ does not allow conversions from void * to other pointer types
+ without a cast. Use templates to work around the problem when
+ possible. */
+
+template <typename T> inline T *
+xrealloc (T *p, size_t s)
+{
+ return (T *) xrealloc ((void *) p, s);
+}
+
+template <typename T> inline T *
+xnrealloc (T *p, size_t n, size_t s)
+{
+ return (T *) xnrealloc ((void *) p, n, s);
+}
+
+template <typename T> inline T *
+x2realloc (T *p, size_t *pn)
+{
+ return (T *) x2realloc ((void *) p, pn);
+}
+
+template <typename T> inline T *
+x2nrealloc (T *p, size_t *pn, size_t s)
+{
+ return (T *) x2nrealloc ((void *) p, pn, s);
+}
+
+template <typename T> inline T *
+xmemdup (T const *p, size_t s)
+{
+ return (T *) xmemdup ((void const *) p, s);
+}
+
# endif