mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Use estream_asprintf instead of the GNU asprintf.
This commit is contained in:
parent
edb3dc99e9
commit
5f3bca9682
25 changed files with 2413 additions and 351 deletions
|
@ -1,3 +1,20 @@
|
|||
2007-05-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* util.h: Do not include gnulib's vasprintf. Redefine asprintf
|
||||
and vasprintf.
|
||||
|
||||
* xasprintf.c (xasprintf, xtryasprintf): Use estream_vasprintf.
|
||||
|
||||
* estream-printf.h, estream-printf.c: New. Taken from current
|
||||
libestream SVN.
|
||||
* Makefile.am (common_sources): Add them.
|
||||
|
||||
2007-05-14 Werner Koch <wk@g10code.com>
|
||||
|
||||
* sexp-parse.h (smklen): New.
|
||||
* sexputil.c: Include sexp-parse.h.
|
||||
(make_simple_sexp_from_hexstr): Replace sprintf by smklen.
|
||||
|
||||
2007-05-07 Werner Koch <wk@g10code.com>
|
||||
|
||||
* signal.c (got_fatal_signal): Protect SIG from being clobbered by
|
||||
|
|
|
@ -54,7 +54,7 @@ common_sources = \
|
|||
w32reg.c \
|
||||
signal.c \
|
||||
dynload.h \
|
||||
estream.c estream.h \
|
||||
estream.c estream.h estream-printf.c estream-printf.h \
|
||||
srv.c srv.h \
|
||||
dns-cert.c dns-cert.h \
|
||||
pka.c pka.h \
|
||||
|
|
2139
common/estream-printf.c
Normal file
2139
common/estream-printf.c
Normal file
File diff suppressed because it is too large
Load diff
60
common/estream-printf.h
Normal file
60
common/estream-printf.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* estream-printf.h - Versatile C-99 compliant printf formatting.
|
||||
* Copyright (C) 2007 g10 Code GmbH
|
||||
*
|
||||
* This file is part of Libestream.
|
||||
*
|
||||
* Libestream is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* Libestream is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Libestream; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* $Id: estream-printf.h 54 2007-05-15 14:12:06Z wk $
|
||||
*/
|
||||
|
||||
#ifndef ESTREAM_PRINTF_H
|
||||
#define ESTREAM_PRINTF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
|
||||
# define ESTREAM_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a)))
|
||||
#else
|
||||
# define ESTREAM_GCC_A_PRINTF( f, a )
|
||||
#endif
|
||||
|
||||
|
||||
typedef int (*estream_printf_out_t)
|
||||
(void *outfncarg, const char *buf, size_t buflen);
|
||||
|
||||
int estream_format (estream_printf_out_t outfnc, void *outfncarg,
|
||||
const char *format, va_list vaargs)
|
||||
ESTREAM_GCC_A_PRINTF(3,0);
|
||||
int estream_printf (const char *format, ...)
|
||||
ESTREAM_GCC_A_PRINTF(1,2);
|
||||
int estream_fprintf (FILE *fp, const char *format, ... )
|
||||
ESTREAM_GCC_A_PRINTF(2,3);
|
||||
int estream_vfprintf (FILE *fp, const char *format, va_list arg_ptr)
|
||||
ESTREAM_GCC_A_PRINTF(2,0);
|
||||
int estream_snprintf (char *buf, size_t bufsize, const char *format, ...)
|
||||
ESTREAM_GCC_A_PRINTF(3,4);
|
||||
int estream_vsnprintf (char *buf,size_t bufsize,
|
||||
const char *format, va_list arg_ptr)
|
||||
ESTREAM_GCC_A_PRINTF(3,0);
|
||||
int estream_asprintf (char **bufp, const char *format, ...)
|
||||
ESTREAM_GCC_A_PRINTF(2,3);
|
||||
int estream_vasprintf (char **bufp, const char *format, va_list arg_ptr)
|
||||
ESTREAM_GCC_A_PRINTF(2,0);
|
||||
|
||||
|
||||
#endif /*ESTREAM_PRINTF_H*/
|
143
common/estream.c
143
common/estream.c
|
@ -1,5 +1,5 @@
|
|||
/* estream.c - Extended Stream I/O Library
|
||||
* Copyright (C) 2004, 2006, 2007 g10 Code GmbH
|
||||
* Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
|
||||
*
|
||||
* This file is part of Libestream.
|
||||
*
|
||||
|
@ -11,7 +11,7 @@
|
|||
* Libestream is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Libestream; if not, write to the Free Software
|
||||
|
@ -49,6 +49,7 @@
|
|||
# include <pth.h>
|
||||
#endif
|
||||
|
||||
/* This is for the special hack to use estream.c in GnuPG. */
|
||||
#ifdef GNUPG_MAJOR_VERSION
|
||||
#include "../common/util.h"
|
||||
#endif
|
||||
|
@ -62,7 +63,7 @@ void *memrchr (const void *block, int c, size_t size);
|
|||
#endif
|
||||
|
||||
#include <estream.h>
|
||||
|
||||
#include <estream-printf.h>
|
||||
|
||||
|
||||
|
||||
|
@ -747,8 +748,8 @@ static int
|
|||
es_convert_mode (const char *mode, unsigned int *flags)
|
||||
{
|
||||
|
||||
/* FIXME: We need to allow all combinations for mode flags and for
|
||||
binary we need to do a
|
||||
/* FIXME: We need to allow all mode flags permutations and for
|
||||
binary mode we need to do a
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
setmode (fd, O_BINARY);
|
||||
|
@ -1671,29 +1672,19 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length,
|
|||
}
|
||||
|
||||
|
||||
/* Helper for esprint. */
|
||||
#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN)
|
||||
static my_funopen_hook_ret_t
|
||||
print_fun_writer (void *cookie_arg, const char *buffer, size_t size)
|
||||
/* Output fucntion used for estream_format. */
|
||||
static int
|
||||
print_writer (void *outfncarg, const char *buf, size_t buflen)
|
||||
{
|
||||
estream_t stream = cookie_arg;
|
||||
estream_t stream = outfncarg;
|
||||
size_t nwritten;
|
||||
|
||||
/* We don't return an error but let es_print check whether an error
|
||||
has occured. Internally we skip everything after an error. */
|
||||
if (!stream->intern->print_err)
|
||||
{
|
||||
if (es_writen (stream, buffer, size, &nwritten))
|
||||
{
|
||||
stream->intern->print_err = 1;
|
||||
stream->intern->print_errno = errno;
|
||||
}
|
||||
else
|
||||
stream->intern->print_ntotal += nwritten;
|
||||
}
|
||||
return 0;
|
||||
int rc;
|
||||
|
||||
nwritten = 0;
|
||||
rc = es_writen (stream, buf, buflen, &nwritten);
|
||||
stream->intern->print_ntotal += nwritten;
|
||||
return rc;
|
||||
}
|
||||
#endif /* HAVE_FOPENCOOKIE || HAVE_FUNOPEN */
|
||||
|
||||
|
||||
/* The core of our printf function. This is called in locked state. */
|
||||
|
@ -1701,98 +1692,13 @@ static int
|
|||
es_print (estream_t ES__RESTRICT stream,
|
||||
const char *ES__RESTRICT format, va_list ap)
|
||||
{
|
||||
#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN)
|
||||
int rc;
|
||||
|
||||
if (!stream->intern->print_fp)
|
||||
{
|
||||
#ifdef HAVE_FOPENCOOKIE
|
||||
{
|
||||
cookie_io_functions_t io = { NULL };
|
||||
io.write = print_fun_writer;
|
||||
|
||||
stream->intern->print_fp = fopencookie (stream, "w", io);
|
||||
}
|
||||
#else /*!HAVE_FOPENCOOKIE*/
|
||||
stream->intern->print_fp = funopen (stream, NULL,
|
||||
print_fun_writer, NULL, NULL);
|
||||
#endif /*!HAVE_FOPENCOOKIE*/
|
||||
if (!stream->intern->print_fp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream->intern->print_err = 0;
|
||||
stream->intern->print_errno = 0;
|
||||
stream->intern->print_ntotal = 0;
|
||||
|
||||
if ( vfprintf (stream->intern->print_fp, format, ap) < 0
|
||||
|| fflush (stream->intern->print_fp) )
|
||||
{
|
||||
stream->intern->print_errno = errno;
|
||||
stream->intern->print_err = 1;
|
||||
fclose (stream->intern->print_fp);
|
||||
stream->intern->print_fp = NULL;
|
||||
}
|
||||
if (stream->intern->print_err)
|
||||
{
|
||||
errno = stream->intern->print_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = estream_format (print_writer, stream, format, ap);
|
||||
if (rc)
|
||||
return -1;
|
||||
return (int)stream->intern->print_ntotal;
|
||||
|
||||
#else /* No funopen or fopencookie. */
|
||||
|
||||
char data[BUFFER_BLOCK_SIZE];
|
||||
size_t bytes_read;
|
||||
size_t bytes_written;
|
||||
FILE *tmp_stream;
|
||||
int err;
|
||||
|
||||
bytes_written = 0;
|
||||
tmp_stream = NULL;
|
||||
err = 0;
|
||||
|
||||
tmp_stream = tmpfile ();
|
||||
if (! tmp_stream)
|
||||
{
|
||||
err = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = vfprintf (tmp_stream, format, ap);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
err = fseek (tmp_stream, 0, SEEK_SET);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
while (1)
|
||||
{
|
||||
bytes_read = fread (data, 1, sizeof (data), tmp_stream);
|
||||
if (ferror (tmp_stream))
|
||||
{
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
err = es_writen (stream, data, bytes_read, NULL);
|
||||
if (err)
|
||||
break;
|
||||
else
|
||||
bytes_written += bytes_read;
|
||||
if (feof (tmp_stream))
|
||||
break;
|
||||
}
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (tmp_stream)
|
||||
fclose (tmp_stream);
|
||||
|
||||
return err ? -1 : bytes_written;
|
||||
#endif /* no funopen or fopencookie */
|
||||
}
|
||||
|
||||
|
||||
|
@ -2718,7 +2624,7 @@ es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format,
|
|||
|
||||
static int
|
||||
es_fprintf_unlocked (estream_t ES__RESTRICT stream,
|
||||
const char *ES__RESTRICT format, ...)
|
||||
const char *ES__RESTRICT format, ...)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -2868,8 +2774,6 @@ es_opaque_get (estream_t stream)
|
|||
return opaque;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print a BUFFER to STREAM while replacing all control characters and
|
||||
the characters in DELIMITERS by standard C escape sequences.
|
||||
Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL
|
||||
|
@ -2992,7 +2896,7 @@ es_write_hexstring (estream_t ES__RESTRICT stream,
|
|||
encoding. The interface is the same as es_write_sanitized, however
|
||||
only one delimiter may be supported.
|
||||
|
||||
THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG. */
|
||||
THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG!. */
|
||||
int
|
||||
es_write_sanitized_utf8_buffer (estream_t stream,
|
||||
const void *buffer, size_t length,
|
||||
|
@ -3025,6 +2929,3 @@ es_write_sanitized_utf8_buffer (estream_t stream,
|
|||
return es_write_sanitized (stream, p, length, delimiters, bytes_written);
|
||||
}
|
||||
#endif /*GNUPG_MAJOR_VERSION*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* estream.h - Extended stream I/O/ Library
|
||||
* Copyright (C) 2004 g10 Code GmbH
|
||||
* Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
|
||||
*
|
||||
* This file is part of Libestream.
|
||||
*
|
||||
|
@ -211,7 +211,6 @@ void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
|
|||
void *es_opaque_get (estream_t stream);
|
||||
|
||||
|
||||
|
||||
#ifdef GNUPG_MAJOR_VERSION
|
||||
int es_write_sanitized_utf8_buffer (estream_t stream,
|
||||
const void *buffer, size_t length,
|
||||
|
@ -220,5 +219,6 @@ int es_write_sanitized_utf8_buffer (estream_t stream,
|
|||
#endif /*GNUPG_MAJOR_VERSION*/
|
||||
|
||||
|
||||
|
||||
#endif /*ESTREAM_H*/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* sexp-parse.h - S-Exp helper functions
|
||||
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -97,4 +97,34 @@ smatch (unsigned char const **buf, size_t buflen, const char *token)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Format VALUE for use as the length indicatior of an S-expression.
|
||||
The caller needs to provide a buffer HELP_BUFFER wth a length of
|
||||
HELP_BUFLEN. The return value is a pointer into HELP_BUFFER with
|
||||
the formatted length string. The colon and a trailing nul are
|
||||
appended. HELP_BUFLEN must be at least 3 - a more useful value is
|
||||
15. If LENGTH is not NULL, the LENGTH of the resulting string
|
||||
(excluding the terminating nul) is stored at that address. */
|
||||
static inline char *
|
||||
smklen (char *help_buffer, size_t help_buflen, size_t value, size_t *length)
|
||||
{
|
||||
char *p = help_buffer + help_buflen;
|
||||
|
||||
if (help_buflen >= 3)
|
||||
{
|
||||
*--p = 0;
|
||||
*--p = ':';
|
||||
do
|
||||
{
|
||||
*--p = '0' + (value % 10);
|
||||
value /= 10;
|
||||
}
|
||||
while (value && p > help_buffer);
|
||||
}
|
||||
|
||||
if (length)
|
||||
*length = (help_buffer + help_buflen) - p;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#endif /*SEXP_PARSE_H*/
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#endif
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "sexp-parse.h"
|
||||
|
||||
/* Return the so called "keygrip" which is the SHA-1 hash of the
|
||||
public key parameters expressed in a way depended on the algorithm.
|
||||
|
@ -115,7 +115,8 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
|
|||
const char *s;
|
||||
unsigned char *buf;
|
||||
unsigned char *p;
|
||||
char numbuf[50];
|
||||
char numbuf[50], *numbufp;
|
||||
size_t numbuflen;
|
||||
|
||||
for (n=0, s=line; hexdigitp (s); s++, n++)
|
||||
;
|
||||
|
@ -124,11 +125,12 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
|
|||
if (!n)
|
||||
return NULL;
|
||||
len = ((n+1) & ~0x01)/2;
|
||||
sprintf (numbuf, "(%u:", (unsigned int)len);
|
||||
buf = xtrymalloc (strlen (numbuf) + len + 1 + 1);
|
||||
numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
|
||||
buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
p = (unsigned char *)stpcpy ((char *)buf, numbuf);
|
||||
buf[0] = '(';
|
||||
p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
|
||||
s = line;
|
||||
if ((n&1))
|
||||
{
|
||||
|
|
|
@ -27,10 +27,6 @@
|
|||
#include <errno.h> /* We need errno. */
|
||||
#include <gpg-error.h> /* We need gpg_error_t. */
|
||||
|
||||
/* Common GNUlib includes (-I ../gl/). */
|
||||
#include "vasprintf.h"
|
||||
|
||||
|
||||
/* Hash function used with libksba. */
|
||||
#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
|
||||
|
||||
|
@ -43,6 +39,14 @@
|
|||
#include "../jnlib/dotlock.h"
|
||||
#include "../jnlib/utf8conv.h"
|
||||
|
||||
/* Redefine asprintf by our estream version which uses our own memory
|
||||
allocator.. */
|
||||
#include "estream-printf.h"
|
||||
#define asprintf estream_asprintf
|
||||
#define vasprintf estream_vasprintf
|
||||
|
||||
|
||||
/* GCC attributes. */
|
||||
#if __GNUC__ >= 4
|
||||
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
|
||||
#else
|
||||
|
@ -175,13 +179,9 @@ void gnupg_rl_initialize (void);
|
|||
logging subsystem. */
|
||||
void setup_libgcrypt_logging (void);
|
||||
|
||||
/* Same as asprintf but return an allocated buffer suitable to be
|
||||
freed using xfree. This function simply dies on memory failure,
|
||||
thus no extra check is required. */
|
||||
/* Same as estream_asprintf but die on memory failure. */
|
||||
char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2);
|
||||
/* Same as asprintf but return an allocated buffer suitable to be
|
||||
freed using xfree. This function returns NULL on memory failure and
|
||||
sets errno. */
|
||||
/* This is now an alias to estream_asprintf. */
|
||||
char *xtryasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2);
|
||||
|
||||
const char *print_fname_stdout (const char *s);
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
/* Like vsprintf but provides a pointer to malloc'd storage, which must
|
||||
be freed by the caller.
|
||||
Copyright (C) 1994, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the libiberty library.
|
||||
Libiberty is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libiberty is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libiberty; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef TEST
|
||||
int global_total_width;
|
||||
#endif
|
||||
|
||||
int
|
||||
vasprintf (char **result, const char *format, va_list args)
|
||||
{
|
||||
const char *p = format;
|
||||
/* Add one to make sure that it is never zero, which might cause malloc
|
||||
to return NULL. */
|
||||
int total_width = strlen (format) + 1;
|
||||
va_list ap;
|
||||
|
||||
#ifdef va_copy
|
||||
va_copy (ap, args);
|
||||
#else
|
||||
#ifdef __va_copy
|
||||
__va_copy (ap, args);
|
||||
#else
|
||||
memcpy (&ap, args, sizeof (va_list));
|
||||
#endif /* __va_copy */
|
||||
#endif /* va_copy */
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (*p++ == '%')
|
||||
{
|
||||
while (strchr ("-+ #0", *p))
|
||||
++p;
|
||||
if (*p == '*')
|
||||
{
|
||||
++p;
|
||||
total_width += abs (va_arg (ap, int));
|
||||
}
|
||||
else
|
||||
total_width += strtoul (p, (char**)&p, 10);
|
||||
if (*p == '.')
|
||||
{
|
||||
++p;
|
||||
if (*p == '*')
|
||||
{
|
||||
++p;
|
||||
total_width += abs (va_arg (ap, int));
|
||||
}
|
||||
else
|
||||
total_width += strtoul (p, (char**)&p, 10);
|
||||
}
|
||||
while (strchr ("hlL", *p))
|
||||
++p;
|
||||
/* Should be big enough for any format specifier except %s
|
||||
and floats. */
|
||||
total_width += 30;
|
||||
switch (*p)
|
||||
{
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'c':
|
||||
(void) va_arg (ap, int);
|
||||
break;
|
||||
case 'f':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
(void) va_arg (ap, double);
|
||||
/* Since an ieee double can have an exponent of 307, we'll
|
||||
make the buffer wide enough to cover the gross case. */
|
||||
total_width += 307;
|
||||
break;
|
||||
case 's':
|
||||
{
|
||||
char *tmp = va_arg (ap, char *);
|
||||
if (tmp)
|
||||
total_width += strlen (tmp);
|
||||
else /* in case the vsprintf does prints a text */
|
||||
total_width += 25; /* e.g. "(null pointer reference)" */
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
case 'n':
|
||||
(void) va_arg (ap, char *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef TEST
|
||||
global_total_width = total_width;
|
||||
#endif
|
||||
*result = malloc (total_width);
|
||||
if (*result != NULL)
|
||||
return vsprintf (*result, format, args);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
asprintf (char **buf, const char *fmt, ...)
|
||||
{
|
||||
int status;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
status = vasprintf (buf, fmt, ap);
|
||||
va_end (ap);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
void
|
||||
checkit (const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *result;
|
||||
|
||||
va_start (args, format);
|
||||
vasprintf (&result, format, args);
|
||||
if (strlen (result) < global_total_width)
|
||||
printf ("PASS: ");
|
||||
else
|
||||
printf ("FAIL: ");
|
||||
printf ("%d %s\n", global_total_width, result);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
checkit ("%d", 0x12345678);
|
||||
checkit ("%200d", 5);
|
||||
checkit ("%.300d", 6);
|
||||
checkit ("%100.150d", 7);
|
||||
checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
|
||||
777777777777777777333333333333366666666666622222222222777777777777733333");
|
||||
checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
|
||||
}
|
||||
#endif /* TEST */
|
|
@ -25,6 +25,11 @@
|
|||
|
||||
#include "util.h"
|
||||
#include "iobuf.h"
|
||||
#include "estream-printf.h"
|
||||
|
||||
#if !defined(ESTREAM_ASPRINTF_MALLOC) || !defined(ESTREAM_ASPRINTF_FREE)
|
||||
#error Need to define ESTREAM_ASPRINTF_MALLOC and _FREE
|
||||
#endif
|
||||
|
||||
/* Same as asprintf but return an allocated buffer suitable to be
|
||||
freed using xfree. This function simply dies on memory failure,
|
||||
|
@ -33,15 +38,13 @@ char *
|
|||
xasprintf (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf, *p;
|
||||
char *buf;
|
||||
|
||||
va_start (ap, fmt);
|
||||
if (vasprintf (&buf, fmt, ap) < 0)
|
||||
log_fatal ("asprintf failed: %s\n", strerror (errno));
|
||||
if (estream_vasprintf (&buf, fmt, ap) < 0)
|
||||
log_fatal ("estream_asprintf failed: %s\n", strerror (errno));
|
||||
va_end (ap);
|
||||
p = xstrdup (buf);
|
||||
free (buf);
|
||||
return p;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Same as above but return NULL on memory failure. */
|
||||
|
@ -50,14 +53,12 @@ xtryasprintf (const char *fmt, ...)
|
|||
{
|
||||
int rc;
|
||||
va_list ap;
|
||||
char *buf, *p;
|
||||
char *buf;
|
||||
|
||||
va_start (ap, fmt);
|
||||
rc = vasprintf (&buf, fmt, ap);
|
||||
rc = estream_vasprintf (&buf, fmt, ap);
|
||||
va_end (ap);
|
||||
if (rc < 0)
|
||||
return NULL;
|
||||
p = xtrystrdup (buf);
|
||||
free (buf);
|
||||
return p;
|
||||
return buf;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue