mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-04 20:38:50 +01:00
372 lines
7.6 KiB
C
372 lines
7.6 KiB
C
|
/* Formatted output to strings, using POSIX/XSI format strings with positions.
|
||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||
|
Written by Bruno Haible <bruno@clisp.org>, 2003.
|
||
|
|
||
|
This program 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, or (at your option)
|
||
|
any later version.
|
||
|
|
||
|
This program 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 this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||
|
USA. */
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
# include <config.h>
|
||
|
#endif
|
||
|
|
||
|
#ifdef __GNUC__
|
||
|
# define alloca __builtin_alloca
|
||
|
# define HAVE_ALLOCA 1
|
||
|
#else
|
||
|
# ifdef _MSC_VER
|
||
|
# include <malloc.h>
|
||
|
# define alloca _alloca
|
||
|
# else
|
||
|
# if defined HAVE_ALLOCA_H || defined _LIBC
|
||
|
# include <alloca.h>
|
||
|
# else
|
||
|
# ifdef _AIX
|
||
|
#pragma alloca
|
||
|
# else
|
||
|
# ifndef alloca
|
||
|
char *alloca ();
|
||
|
# endif
|
||
|
# endif
|
||
|
# endif
|
||
|
# endif
|
||
|
#endif
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#if !HAVE_POSIX_PRINTF
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/* When building a DLL, we must export some functions. Note that because
|
||
|
the functions are only defined for binary backward compatibility, we
|
||
|
don't need to use __declspec(dllimport) in any case. */
|
||
|
#if defined _MSC_VER && BUILDING_DLL
|
||
|
# define DLL_EXPORTED __declspec(dllexport)
|
||
|
#else
|
||
|
# define DLL_EXPORTED
|
||
|
#endif
|
||
|
|
||
|
#define STATIC static
|
||
|
|
||
|
/* Define auxiliary functions declared in "printf-args.h". */
|
||
|
#include "printf-args.c"
|
||
|
|
||
|
/* Define auxiliary functions declared in "printf-parse.h". */
|
||
|
#include "printf-parse.c"
|
||
|
|
||
|
/* Define functions declared in "vasnprintf.h". */
|
||
|
#define vasnprintf libintl_vasnprintf
|
||
|
#include "vasnprintf.c"
|
||
|
#if 0 /* not needed */
|
||
|
#define asnprintf libintl_asnprintf
|
||
|
#include "asnprintf.c"
|
||
|
#endif
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vfprintf (FILE *stream, const char *format, va_list args)
|
||
|
{
|
||
|
if (strchr (format, '$') == NULL)
|
||
|
return vfprintf (stream, format, args);
|
||
|
else
|
||
|
{
|
||
|
size_t length;
|
||
|
char *result = libintl_vasnprintf (NULL, &length, format, args);
|
||
|
int retval = -1;
|
||
|
if (result != NULL)
|
||
|
{
|
||
|
if (fwrite (result, 1, length, stream) == length)
|
||
|
retval = length;
|
||
|
free (result);
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_fprintf (FILE *stream, const char *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vfprintf (stream, format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vprintf (const char *format, va_list args)
|
||
|
{
|
||
|
return libintl_vfprintf (stdout, format, args);
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_printf (const char *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vprintf (format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vsprintf (char *resultbuf, const char *format, va_list args)
|
||
|
{
|
||
|
if (strchr (format, '$') == NULL)
|
||
|
return vsprintf (resultbuf, format, args);
|
||
|
else
|
||
|
{
|
||
|
size_t length = (size_t) ~0 / (4 * sizeof (char));
|
||
|
char *result = libintl_vasnprintf (resultbuf, &length, format, args);
|
||
|
if (result != resultbuf)
|
||
|
{
|
||
|
free (result);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
return length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_sprintf (char *resultbuf, const char *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vsprintf (resultbuf, format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
#if HAVE_SNPRINTF
|
||
|
|
||
|
# if HAVE_DECL__SNPRINTF
|
||
|
/* Windows. */
|
||
|
# define system_vsnprintf _vsnprintf
|
||
|
# else
|
||
|
/* Unix. */
|
||
|
# define system_vsnprintf vsnprintf
|
||
|
# endif
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
|
||
|
{
|
||
|
if (strchr (format, '$') == NULL)
|
||
|
return system_vsnprintf (resultbuf, length, format, args);
|
||
|
else
|
||
|
{
|
||
|
size_t maxlength = length;
|
||
|
char *result = libintl_vasnprintf (resultbuf, &length, format, args);
|
||
|
if (result != resultbuf)
|
||
|
{
|
||
|
if (maxlength > 0)
|
||
|
{
|
||
|
if (length < maxlength)
|
||
|
abort ();
|
||
|
memcpy (resultbuf, result, maxlength - 1);
|
||
|
resultbuf[maxlength - 1] = '\0';
|
||
|
}
|
||
|
free (result);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
return length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vsnprintf (resultbuf, length, format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if HAVE_ASPRINTF
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vasprintf (char **resultp, const char *format, va_list args)
|
||
|
{
|
||
|
size_t length;
|
||
|
char *result = libintl_vasnprintf (NULL, &length, format, args);
|
||
|
if (result == NULL)
|
||
|
return -1;
|
||
|
*resultp = result;
|
||
|
return length;
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_asprintf (char **resultp, const char *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vasprintf (resultp, format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if HAVE_FWPRINTF
|
||
|
|
||
|
#include <wchar.h>
|
||
|
|
||
|
#define WIDE_CHAR_VERSION 1
|
||
|
|
||
|
/* Define auxiliary functions declared in "wprintf-parse.h". */
|
||
|
#include "printf-parse.c"
|
||
|
|
||
|
/* Define functions declared in "vasnprintf.h". */
|
||
|
#define vasnwprintf libintl_vasnwprintf
|
||
|
#include "vasnprintf.c"
|
||
|
#if 0 /* not needed */
|
||
|
#define asnwprintf libintl_asnwprintf
|
||
|
#include "asnprintf.c"
|
||
|
#endif
|
||
|
|
||
|
# if HAVE_DECL__SNWPRINTF
|
||
|
/* Windows. */
|
||
|
# define system_vswprintf _vsnwprintf
|
||
|
# else
|
||
|
/* Unix. */
|
||
|
# define system_vswprintf vswprintf
|
||
|
# endif
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
|
||
|
{
|
||
|
if (wcschr (format, '$') == NULL)
|
||
|
return vfwprintf (stream, format, args);
|
||
|
else
|
||
|
{
|
||
|
size_t length;
|
||
|
wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
|
||
|
int retval = -1;
|
||
|
if (result != NULL)
|
||
|
{
|
||
|
size_t i;
|
||
|
for (i = 0; i < length; i++)
|
||
|
if (fputwc (result[i], stream) == WEOF)
|
||
|
break;
|
||
|
if (i == length)
|
||
|
retval = length;
|
||
|
free (result);
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vfwprintf (stream, format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vwprintf (const wchar_t *format, va_list args)
|
||
|
{
|
||
|
return libintl_vfwprintf (stdout, format, args);
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_wprintf (const wchar_t *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vwprintf (format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
|
||
|
{
|
||
|
if (wcschr (format, '$') == NULL)
|
||
|
return system_vswprintf (resultbuf, length, format, args);
|
||
|
else
|
||
|
{
|
||
|
size_t maxlength = length;
|
||
|
wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
|
||
|
if (result != resultbuf)
|
||
|
{
|
||
|
if (maxlength > 0)
|
||
|
{
|
||
|
if (length < maxlength)
|
||
|
abort ();
|
||
|
memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t));
|
||
|
resultbuf[maxlength - 1] = 0;
|
||
|
}
|
||
|
free (result);
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
return length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DLL_EXPORTED
|
||
|
int
|
||
|
libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
|
||
|
{
|
||
|
va_list args;
|
||
|
int retval;
|
||
|
|
||
|
va_start (args, format);
|
||
|
retval = libintl_vswprintf (resultbuf, length, format, args);
|
||
|
va_end (args);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|