mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 11:26:16 +01:00
Add gnulib vasnprintf().
This commit is contained in:
parent
e4f08fe7eb
commit
3389a051da
24
glib/gnulib/Makefile.am
Normal file
24
glib/gnulib/Makefile.am
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libgnulib.la
|
||||||
|
|
||||||
|
libgnulib_la_SOURCES = \
|
||||||
|
asnprintf.c \
|
||||||
|
printf-args.c \
|
||||||
|
printf-args.h \
|
||||||
|
printf-parse.c \
|
||||||
|
printf-parse.h \
|
||||||
|
vasnprintf.c \
|
||||||
|
vasnprintf.h \
|
||||||
|
printf.c \
|
||||||
|
printf.h \
|
||||||
|
g-gnulib.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
38
glib/gnulib/README
Normal file
38
glib/gnulib/README
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
The files
|
||||||
|
|
||||||
|
asnprintf.c
|
||||||
|
printf-args.c
|
||||||
|
printf-args.h
|
||||||
|
printf-parse.c
|
||||||
|
printf-parse.h
|
||||||
|
vasnprintf.c
|
||||||
|
vasnprintf.h
|
||||||
|
|
||||||
|
are taken from the vasnprintf module of the GNUlib package, which can
|
||||||
|
be found at:
|
||||||
|
|
||||||
|
http://www.gnu.org/software/gnulib/
|
||||||
|
|
||||||
|
They have been modified to include g-gnulib.h. vasnprintf.c has also been modified to
|
||||||
|
include support for long long printing if the system printf doesn't. This code is protected
|
||||||
|
by #ifndef HAVE_LON_LONG_FORMAT.
|
||||||
|
|
||||||
|
The files
|
||||||
|
|
||||||
|
printf.h
|
||||||
|
printf.c
|
||||||
|
g-gnulib.h
|
||||||
|
|
||||||
|
have been written by me. printf.[hc] contain implementations of the
|
||||||
|
remaining functions in the printf family based on
|
||||||
|
vasnprintf. g-gnulib.h is included by all source files in order to
|
||||||
|
move all exported functions to the _g_gnulib namespace, replace malloc
|
||||||
|
by g_malloc and make sure that snprintf is only used if it implements
|
||||||
|
C99 return value semantics.
|
||||||
|
|
||||||
|
Matthias Clasen
|
||||||
|
July 28, 2003
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
40
glib/gnulib/asnprintf.c
Normal file
40
glib/gnulib/asnprintf.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Formatted output to strings.
|
||||||
|
Copyright (C) 1999, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "g-gnulib.h"
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include "vasnprintf.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
result = vasnprintf (resultbuf, lengthp, format, args);
|
||||||
|
va_end (args);
|
||||||
|
return result;
|
||||||
|
}
|
45
glib/gnulib/g-gnulib.h
Normal file
45
glib/gnulib/g-gnulib.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* GLIB - Library of useful routines for C programming
|
||||||
|
* Copyright (C) 2003 Matthias Clasen
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef __G_GNULIB_H__
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "glib/glib.h"
|
||||||
|
|
||||||
|
/* Private namespace for gnulib functions */
|
||||||
|
#define asnprintf _g_gnulib_asnprintf
|
||||||
|
#define vasnprintf _g_gnulib_vasnprintf
|
||||||
|
#define printf_parse _g_gnulib_printf_parse
|
||||||
|
#define printf_fetchargs _g_gnulib_printf_fetchargs
|
||||||
|
|
||||||
|
/* Use GLib memory allocation */
|
||||||
|
#define malloc g_malloc
|
||||||
|
#define realloc g_realloc
|
||||||
|
#define free g_free
|
||||||
|
|
||||||
|
/* Ensure only C99 snprintf gets used */
|
||||||
|
#ifdef HAVE_C99_SNPRINTF
|
||||||
|
#define HAVE_SNPRINTF 1
|
||||||
|
#else
|
||||||
|
#define HAVE_SNPRINTF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __G_GNULIB_H__ */
|
||||||
|
|
121
glib/gnulib/printf-args.c
Normal file
121
glib/gnulib/printf-args.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* Decomposed printf argument list.
|
||||||
|
Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "g-gnulib.h"
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include "printf-args.h"
|
||||||
|
|
||||||
|
#ifdef STATIC
|
||||||
|
STATIC
|
||||||
|
#endif
|
||||||
|
int
|
||||||
|
printf_fetchargs (va_list args, arguments *a)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
argument *ap;
|
||||||
|
|
||||||
|
for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
|
||||||
|
switch (ap->type)
|
||||||
|
{
|
||||||
|
case TYPE_SCHAR:
|
||||||
|
ap->a.a_schar = va_arg (args, /*signed char*/ int);
|
||||||
|
break;
|
||||||
|
case TYPE_UCHAR:
|
||||||
|
ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
|
||||||
|
break;
|
||||||
|
case TYPE_SHORT:
|
||||||
|
ap->a.a_short = va_arg (args, /*short*/ int);
|
||||||
|
break;
|
||||||
|
case TYPE_USHORT:
|
||||||
|
ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
|
||||||
|
break;
|
||||||
|
case TYPE_INT:
|
||||||
|
ap->a.a_int = va_arg (args, int);
|
||||||
|
break;
|
||||||
|
case TYPE_UINT:
|
||||||
|
ap->a.a_uint = va_arg (args, unsigned int);
|
||||||
|
break;
|
||||||
|
case TYPE_LONGINT:
|
||||||
|
ap->a.a_longint = va_arg (args, long int);
|
||||||
|
break;
|
||||||
|
case TYPE_ULONGINT:
|
||||||
|
ap->a.a_ulongint = va_arg (args, unsigned long int);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
case TYPE_LONGLONGINT:
|
||||||
|
ap->a.a_longlongint = va_arg (args, long long int);
|
||||||
|
break;
|
||||||
|
case TYPE_ULONGLONGINT:
|
||||||
|
ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
ap->a.a_double = va_arg (args, double);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_LONG_DOUBLE
|
||||||
|
case TYPE_LONGDOUBLE:
|
||||||
|
ap->a.a_longdouble = va_arg (args, long double);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case TYPE_CHAR:
|
||||||
|
ap->a.a_char = va_arg (args, int);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_WINT_T
|
||||||
|
case TYPE_WIDE_CHAR:
|
||||||
|
ap->a.a_wide_char = va_arg (args, wint_t);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case TYPE_STRING:
|
||||||
|
ap->a.a_string = va_arg (args, const char *);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_WCHAR_T
|
||||||
|
case TYPE_WIDE_STRING:
|
||||||
|
ap->a.a_wide_string = va_arg (args, const wchar_t *);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case TYPE_POINTER:
|
||||||
|
ap->a.a_pointer = va_arg (args, void *);
|
||||||
|
break;
|
||||||
|
case TYPE_COUNT_SCHAR_POINTER:
|
||||||
|
ap->a.a_count_schar_pointer = va_arg (args, signed char *);
|
||||||
|
break;
|
||||||
|
case TYPE_COUNT_SHORT_POINTER:
|
||||||
|
ap->a.a_count_short_pointer = va_arg (args, short *);
|
||||||
|
break;
|
||||||
|
case TYPE_COUNT_INT_POINTER:
|
||||||
|
ap->a.a_count_int_pointer = va_arg (args, int *);
|
||||||
|
break;
|
||||||
|
case TYPE_COUNT_LONGINT_POINTER:
|
||||||
|
ap->a.a_count_longint_pointer = va_arg (args, long int *);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
case TYPE_COUNT_LONGLONGINT_POINTER:
|
||||||
|
ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
/* Unknown type. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
134
glib/gnulib/printf-args.h
Normal file
134
glib/gnulib/printf-args.h
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* Decomposed printf argument list.
|
||||||
|
Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#ifndef _PRINTF_ARGS_H
|
||||||
|
#define _PRINTF_ARGS_H
|
||||||
|
|
||||||
|
/* Get wchar_t. */
|
||||||
|
#ifdef HAVE_WCHAR_T
|
||||||
|
# include <stddef.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get wint_t. */
|
||||||
|
#ifdef HAVE_WINT_T
|
||||||
|
# include <wchar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get va_list. */
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Argument types */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TYPE_NONE,
|
||||||
|
TYPE_SCHAR,
|
||||||
|
TYPE_UCHAR,
|
||||||
|
TYPE_SHORT,
|
||||||
|
TYPE_USHORT,
|
||||||
|
TYPE_INT,
|
||||||
|
TYPE_UINT,
|
||||||
|
TYPE_LONGINT,
|
||||||
|
TYPE_ULONGINT,
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
TYPE_LONGLONGINT,
|
||||||
|
TYPE_ULONGLONGINT,
|
||||||
|
#endif
|
||||||
|
TYPE_DOUBLE,
|
||||||
|
#ifdef HAVE_LONG_DOUBLE
|
||||||
|
TYPE_LONGDOUBLE,
|
||||||
|
#endif
|
||||||
|
TYPE_CHAR,
|
||||||
|
#ifdef HAVE_WINT_T
|
||||||
|
TYPE_WIDE_CHAR,
|
||||||
|
#endif
|
||||||
|
TYPE_STRING,
|
||||||
|
#ifdef HAVE_WCHAR_T
|
||||||
|
TYPE_WIDE_STRING,
|
||||||
|
#endif
|
||||||
|
TYPE_POINTER,
|
||||||
|
TYPE_COUNT_SCHAR_POINTER,
|
||||||
|
TYPE_COUNT_SHORT_POINTER,
|
||||||
|
TYPE_COUNT_INT_POINTER,
|
||||||
|
TYPE_COUNT_LONGINT_POINTER
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
, TYPE_COUNT_LONGLONGINT_POINTER
|
||||||
|
#endif
|
||||||
|
} arg_type;
|
||||||
|
|
||||||
|
/* Polymorphic argument */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
arg_type type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
signed char a_schar;
|
||||||
|
unsigned char a_uchar;
|
||||||
|
short a_short;
|
||||||
|
unsigned short a_ushort;
|
||||||
|
int a_int;
|
||||||
|
unsigned int a_uint;
|
||||||
|
long int a_longint;
|
||||||
|
unsigned long int a_ulongint;
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
long long int a_longlongint;
|
||||||
|
unsigned long long int a_ulonglongint;
|
||||||
|
#endif
|
||||||
|
float a_float;
|
||||||
|
double a_double;
|
||||||
|
#ifdef HAVE_LONG_DOUBLE
|
||||||
|
long double a_longdouble;
|
||||||
|
#endif
|
||||||
|
int a_char;
|
||||||
|
#ifdef HAVE_WINT_T
|
||||||
|
wint_t a_wide_char;
|
||||||
|
#endif
|
||||||
|
const char* a_string;
|
||||||
|
#ifdef HAVE_WCHAR_T
|
||||||
|
const wchar_t* a_wide_string;
|
||||||
|
#endif
|
||||||
|
void* a_pointer;
|
||||||
|
signed char * a_count_schar_pointer;
|
||||||
|
short * a_count_short_pointer;
|
||||||
|
int * a_count_int_pointer;
|
||||||
|
long int * a_count_longint_pointer;
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
long long int * a_count_longlongint_pointer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
argument;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int count;
|
||||||
|
argument *arg;
|
||||||
|
}
|
||||||
|
arguments;
|
||||||
|
|
||||||
|
|
||||||
|
/* Fetch the arguments, putting them into a. */
|
||||||
|
#ifdef STATIC
|
||||||
|
STATIC
|
||||||
|
#else
|
||||||
|
extern
|
||||||
|
#endif
|
||||||
|
int printf_fetchargs (va_list args, arguments *a);
|
||||||
|
|
||||||
|
#endif /* _PRINTF_ARGS_H */
|
479
glib/gnulib/printf-parse.c
Normal file
479
glib/gnulib/printf-parse.c
Normal file
@ -0,0 +1,479 @@
|
|||||||
|
/* Formatted output to strings.
|
||||||
|
Copyright (C) 1999-2000, 2002-2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "g-gnulib.h"
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include "printf-parse.h"
|
||||||
|
|
||||||
|
/* Get size_t, NULL. */
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Get intmax_t. */
|
||||||
|
#if HAVE_STDINT_H_WITH_UINTMAX
|
||||||
|
# include <stdint.h>
|
||||||
|
#endif
|
||||||
|
#if HAVE_INTTYPES_H_WITH_UINTMAX
|
||||||
|
# include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* malloc(), realloc(), free(). */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef STATIC
|
||||||
|
STATIC
|
||||||
|
#endif
|
||||||
|
int
|
||||||
|
printf_parse (const char *format, char_directives *d, arguments *a)
|
||||||
|
{
|
||||||
|
const char *cp = format; /* pointer into format */
|
||||||
|
int arg_posn = 0; /* number of regular arguments consumed */
|
||||||
|
unsigned int d_allocated; /* allocated elements of d->dir */
|
||||||
|
unsigned int a_allocated; /* allocated elements of a->arg */
|
||||||
|
unsigned int max_width_length = 0;
|
||||||
|
unsigned int max_precision_length = 0;
|
||||||
|
|
||||||
|
d->count = 0;
|
||||||
|
d_allocated = 1;
|
||||||
|
d->dir = malloc (d_allocated * sizeof (char_directive));
|
||||||
|
if (d->dir == NULL)
|
||||||
|
/* Out of memory. */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
a->count = 0;
|
||||||
|
a_allocated = 0;
|
||||||
|
a->arg = NULL;
|
||||||
|
|
||||||
|
#define REGISTER_ARG(_index_,_type_) \
|
||||||
|
{ \
|
||||||
|
unsigned int n = (_index_); \
|
||||||
|
if (n >= a_allocated) \
|
||||||
|
{ \
|
||||||
|
argument *memory; \
|
||||||
|
a_allocated = 2 * a_allocated; \
|
||||||
|
if (a_allocated <= n) \
|
||||||
|
a_allocated = n + 1; \
|
||||||
|
memory = (a->arg \
|
||||||
|
? realloc (a->arg, a_allocated * sizeof (argument)) \
|
||||||
|
: malloc (a_allocated * sizeof (argument))); \
|
||||||
|
if (memory == NULL) \
|
||||||
|
/* Out of memory. */ \
|
||||||
|
goto error; \
|
||||||
|
a->arg = memory; \
|
||||||
|
} \
|
||||||
|
while (a->count <= n) \
|
||||||
|
a->arg[a->count++].type = TYPE_NONE; \
|
||||||
|
if (a->arg[n].type == TYPE_NONE) \
|
||||||
|
a->arg[n].type = (_type_); \
|
||||||
|
else if (a->arg[n].type != (_type_)) \
|
||||||
|
/* Ambiguous type for positional argument. */ \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*cp != '\0')
|
||||||
|
{
|
||||||
|
char c = *cp++;
|
||||||
|
if (c == '%')
|
||||||
|
{
|
||||||
|
int arg_index = -1;
|
||||||
|
char_directive *dp = &d->dir[d->count];/* pointer to next directive */
|
||||||
|
|
||||||
|
/* Initialize the next directive. */
|
||||||
|
dp->dir_start = cp - 1;
|
||||||
|
dp->flags = 0;
|
||||||
|
dp->width_start = NULL;
|
||||||
|
dp->width_end = NULL;
|
||||||
|
dp->width_arg_index = -1;
|
||||||
|
dp->precision_start = NULL;
|
||||||
|
dp->precision_end = NULL;
|
||||||
|
dp->precision_arg_index = -1;
|
||||||
|
dp->arg_index = -1;
|
||||||
|
|
||||||
|
/* Test for positional argument. */
|
||||||
|
if (*cp >= '0' && *cp <= '9')
|
||||||
|
{
|
||||||
|
const char *np;
|
||||||
|
|
||||||
|
for (np = cp; *np >= '0' && *np <= '9'; np++)
|
||||||
|
;
|
||||||
|
if (*np == '$')
|
||||||
|
{
|
||||||
|
unsigned int n = 0;
|
||||||
|
|
||||||
|
for (np = cp; *np >= '0' && *np <= '9'; np++)
|
||||||
|
n = 10 * n + (*np - '0');
|
||||||
|
if (n == 0)
|
||||||
|
/* Positional argument 0. */
|
||||||
|
goto error;
|
||||||
|
arg_index = n - 1;
|
||||||
|
cp = np + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the flags. */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (*cp == '\'')
|
||||||
|
{
|
||||||
|
dp->flags |= FLAG_GROUP;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == '-')
|
||||||
|
{
|
||||||
|
dp->flags |= FLAG_LEFT;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == '+')
|
||||||
|
{
|
||||||
|
dp->flags |= FLAG_SHOWSIGN;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == ' ')
|
||||||
|
{
|
||||||
|
dp->flags |= FLAG_SPACE;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == '#')
|
||||||
|
{
|
||||||
|
dp->flags |= FLAG_ALT;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == '0')
|
||||||
|
{
|
||||||
|
dp->flags |= FLAG_ZERO;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the field width. */
|
||||||
|
if (*cp == '*')
|
||||||
|
{
|
||||||
|
dp->width_start = cp;
|
||||||
|
cp++;
|
||||||
|
dp->width_end = cp;
|
||||||
|
if (max_width_length < 1)
|
||||||
|
max_width_length = 1;
|
||||||
|
|
||||||
|
/* Test for positional argument. */
|
||||||
|
if (*cp >= '0' && *cp <= '9')
|
||||||
|
{
|
||||||
|
const char *np;
|
||||||
|
|
||||||
|
for (np = cp; *np >= '0' && *np <= '9'; np++)
|
||||||
|
;
|
||||||
|
if (*np == '$')
|
||||||
|
{
|
||||||
|
unsigned int n = 0;
|
||||||
|
|
||||||
|
for (np = cp; *np >= '0' && *np <= '9'; np++)
|
||||||
|
n = 10 * n + (*np - '0');
|
||||||
|
if (n == 0)
|
||||||
|
/* Positional argument 0. */
|
||||||
|
goto error;
|
||||||
|
dp->width_arg_index = n - 1;
|
||||||
|
cp = np + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dp->width_arg_index < 0)
|
||||||
|
dp->width_arg_index = arg_posn++;
|
||||||
|
REGISTER_ARG (dp->width_arg_index, TYPE_INT);
|
||||||
|
}
|
||||||
|
else if (*cp >= '0' && *cp <= '9')
|
||||||
|
{
|
||||||
|
unsigned int width_length;
|
||||||
|
|
||||||
|
dp->width_start = cp;
|
||||||
|
for (; *cp >= '0' && *cp <= '9'; cp++)
|
||||||
|
;
|
||||||
|
dp->width_end = cp;
|
||||||
|
width_length = dp->width_end - dp->width_start;
|
||||||
|
if (max_width_length < width_length)
|
||||||
|
max_width_length = width_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the precision. */
|
||||||
|
if (*cp == '.')
|
||||||
|
{
|
||||||
|
cp++;
|
||||||
|
if (*cp == '*')
|
||||||
|
{
|
||||||
|
dp->precision_start = cp - 1;
|
||||||
|
cp++;
|
||||||
|
dp->precision_end = cp;
|
||||||
|
if (max_precision_length < 2)
|
||||||
|
max_precision_length = 2;
|
||||||
|
|
||||||
|
/* Test for positional argument. */
|
||||||
|
if (*cp >= '0' && *cp <= '9')
|
||||||
|
{
|
||||||
|
const char *np;
|
||||||
|
|
||||||
|
for (np = cp; *np >= '0' && *np <= '9'; np++)
|
||||||
|
;
|
||||||
|
if (*np == '$')
|
||||||
|
{
|
||||||
|
unsigned int n = 0;
|
||||||
|
|
||||||
|
for (np = cp; *np >= '0' && *np <= '9'; np++)
|
||||||
|
n = 10 * n + (*np - '0');
|
||||||
|
if (n == 0)
|
||||||
|
/* Positional argument 0. */
|
||||||
|
goto error;
|
||||||
|
dp->precision_arg_index = n - 1;
|
||||||
|
cp = np + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dp->precision_arg_index < 0)
|
||||||
|
dp->precision_arg_index = arg_posn++;
|
||||||
|
REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int precision_length;
|
||||||
|
|
||||||
|
dp->precision_start = cp - 1;
|
||||||
|
for (; *cp >= '0' && *cp <= '9'; cp++)
|
||||||
|
;
|
||||||
|
dp->precision_end = cp;
|
||||||
|
precision_length = dp->precision_end - dp->precision_start;
|
||||||
|
if (max_precision_length < precision_length)
|
||||||
|
max_precision_length = precision_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
arg_type type;
|
||||||
|
|
||||||
|
/* Parse argument type/size specifiers. */
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (*cp == 'h')
|
||||||
|
{
|
||||||
|
flags |= (1 << (flags & 1));
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == 'L')
|
||||||
|
{
|
||||||
|
flags |= 4;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == 'l')
|
||||||
|
{
|
||||||
|
flags += 8;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_INTMAX_T
|
||||||
|
else if (*cp == 'j')
|
||||||
|
{
|
||||||
|
if (sizeof (intmax_t) > sizeof (long))
|
||||||
|
{
|
||||||
|
/* intmax_t = long long */
|
||||||
|
flags += 16;
|
||||||
|
}
|
||||||
|
else if (sizeof (intmax_t) > sizeof (int))
|
||||||
|
{
|
||||||
|
/* intmax_t = long */
|
||||||
|
flags += 8;
|
||||||
|
}
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (*cp == 'z' || *cp == 'Z')
|
||||||
|
{
|
||||||
|
/* 'z' is standardized in ISO C 99, but glibc uses 'Z'
|
||||||
|
because the warning facility in gcc-2.95.2 understands
|
||||||
|
only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
|
||||||
|
if (sizeof (size_t) > sizeof (long))
|
||||||
|
{
|
||||||
|
/* size_t = long long */
|
||||||
|
flags += 16;
|
||||||
|
}
|
||||||
|
else if (sizeof (size_t) > sizeof (int))
|
||||||
|
{
|
||||||
|
/* size_t = long */
|
||||||
|
flags += 8;
|
||||||
|
}
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else if (*cp == 't')
|
||||||
|
{
|
||||||
|
if (sizeof (ptrdiff_t) > sizeof (long))
|
||||||
|
{
|
||||||
|
/* ptrdiff_t = long long */
|
||||||
|
flags += 16;
|
||||||
|
}
|
||||||
|
else if (sizeof (ptrdiff_t) > sizeof (int))
|
||||||
|
{
|
||||||
|
/* ptrdiff_t = long */
|
||||||
|
flags += 8;
|
||||||
|
}
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the conversion character. */
|
||||||
|
c = *cp++;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'd': case 'i':
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
if (flags >= 16 || (flags & 4))
|
||||||
|
type = TYPE_LONGLONGINT;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (flags >= 8)
|
||||||
|
type = TYPE_LONGINT;
|
||||||
|
else if (flags & 2)
|
||||||
|
type = TYPE_SCHAR;
|
||||||
|
else if (flags & 1)
|
||||||
|
type = TYPE_SHORT;
|
||||||
|
else
|
||||||
|
type = TYPE_INT;
|
||||||
|
break;
|
||||||
|
case 'o': case 'u': case 'x': case 'X':
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
if (flags >= 16 || (flags & 4))
|
||||||
|
type = TYPE_ULONGLONGINT;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (flags >= 8)
|
||||||
|
type = TYPE_ULONGINT;
|
||||||
|
else if (flags & 2)
|
||||||
|
type = TYPE_UCHAR;
|
||||||
|
else if (flags & 1)
|
||||||
|
type = TYPE_USHORT;
|
||||||
|
else
|
||||||
|
type = TYPE_UINT;
|
||||||
|
break;
|
||||||
|
case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
|
||||||
|
case 'a': case 'A':
|
||||||
|
#ifdef HAVE_LONG_DOUBLE
|
||||||
|
if (flags >= 16 || (flags & 4))
|
||||||
|
type = TYPE_LONGDOUBLE;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
type = TYPE_DOUBLE;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (flags >= 8)
|
||||||
|
#ifdef HAVE_WINT_T
|
||||||
|
type = TYPE_WIDE_CHAR;
|
||||||
|
#else
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
type = TYPE_CHAR;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_WINT_T
|
||||||
|
case 'C':
|
||||||
|
type = TYPE_WIDE_CHAR;
|
||||||
|
c = 'c';
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 's':
|
||||||
|
if (flags >= 8)
|
||||||
|
#ifdef HAVE_WCHAR_T
|
||||||
|
type = TYPE_WIDE_STRING;
|
||||||
|
#else
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
type = TYPE_STRING;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_WCHAR_T
|
||||||
|
case 'S':
|
||||||
|
type = TYPE_WIDE_STRING;
|
||||||
|
c = 's';
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 'p':
|
||||||
|
type = TYPE_POINTER;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
if (flags >= 16 || (flags & 4))
|
||||||
|
type = TYPE_COUNT_LONGLONGINT_POINTER;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (flags >= 8)
|
||||||
|
type = TYPE_COUNT_LONGINT_POINTER;
|
||||||
|
else if (flags & 2)
|
||||||
|
type = TYPE_COUNT_SCHAR_POINTER;
|
||||||
|
else if (flags & 1)
|
||||||
|
type = TYPE_COUNT_SHORT_POINTER;
|
||||||
|
else
|
||||||
|
type = TYPE_COUNT_INT_POINTER;
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
type = TYPE_NONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown conversion character. */
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != TYPE_NONE)
|
||||||
|
{
|
||||||
|
dp->arg_index = arg_index;
|
||||||
|
if (dp->arg_index < 0)
|
||||||
|
dp->arg_index = arg_posn++;
|
||||||
|
REGISTER_ARG (dp->arg_index, type);
|
||||||
|
}
|
||||||
|
dp->conversion = c;
|
||||||
|
dp->dir_end = cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->count++;
|
||||||
|
if (d->count >= d_allocated)
|
||||||
|
{
|
||||||
|
char_directive *memory;
|
||||||
|
|
||||||
|
d_allocated = 2 * d_allocated;
|
||||||
|
memory = realloc (d->dir, d_allocated * sizeof (char_directive));
|
||||||
|
if (memory == NULL)
|
||||||
|
/* Out of memory. */
|
||||||
|
goto error;
|
||||||
|
d->dir = memory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d->dir[d->count].dir_start = cp;
|
||||||
|
|
||||||
|
d->max_width_length = max_width_length;
|
||||||
|
d->max_precision_length = max_precision_length;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (a->arg)
|
||||||
|
free (a->arg);
|
||||||
|
if (d->dir)
|
||||||
|
free (d->dir);
|
||||||
|
return -1;
|
||||||
|
}
|
74
glib/gnulib/printf-parse.h
Normal file
74
glib/gnulib/printf-parse.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/* Parse printf format string.
|
||||||
|
Copyright (C) 1999, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#ifndef _PRINTF_PARSE_H
|
||||||
|
#define _PRINTF_PARSE_H
|
||||||
|
|
||||||
|
#include "printf-args.h"
|
||||||
|
|
||||||
|
/* Private namespace for gnulib functions */
|
||||||
|
#define printf_parse _g_gnulib_printf_parse
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
#define FLAG_GROUP 1 /* ' flag */
|
||||||
|
#define FLAG_LEFT 2 /* - flag */
|
||||||
|
#define FLAG_SHOWSIGN 4 /* + flag */
|
||||||
|
#define FLAG_SPACE 8 /* space flag */
|
||||||
|
#define FLAG_ALT 16 /* # flag */
|
||||||
|
#define FLAG_ZERO 32
|
||||||
|
|
||||||
|
/* A parsed directive. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char* dir_start;
|
||||||
|
const char* dir_end;
|
||||||
|
int flags;
|
||||||
|
const char* width_start;
|
||||||
|
const char* width_end;
|
||||||
|
int width_arg_index;
|
||||||
|
const char* precision_start;
|
||||||
|
const char* precision_end;
|
||||||
|
int precision_arg_index;
|
||||||
|
char conversion; /* d i o u x X f e E g G c s p n U % but not C S */
|
||||||
|
int arg_index;
|
||||||
|
}
|
||||||
|
char_directive;
|
||||||
|
|
||||||
|
/* A parsed format string. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int count;
|
||||||
|
char_directive *dir;
|
||||||
|
unsigned int max_width_length;
|
||||||
|
unsigned int max_precision_length;
|
||||||
|
}
|
||||||
|
char_directives;
|
||||||
|
|
||||||
|
|
||||||
|
/* Parses the format string. Fills in the number N of directives, and fills
|
||||||
|
in directives[0], ..., directives[N-1], and sets directives[N].dir_start
|
||||||
|
to the end of the format string. Also fills in the arg_type fields of the
|
||||||
|
arguments and the needed count of arguments. */
|
||||||
|
#ifdef STATIC
|
||||||
|
STATIC
|
||||||
|
#else
|
||||||
|
extern
|
||||||
|
#endif
|
||||||
|
int printf_parse (const char *format, char_directives *d, arguments *a);
|
||||||
|
|
||||||
|
#endif /* _PRINTF_PARSE_H */
|
154
glib/gnulib/printf.c
Normal file
154
glib/gnulib/printf.c
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* GLIB - Library of useful routines for C programming
|
||||||
|
* Copyright (C) 2003 Matthias Clasen
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modified by the GLib Team and others 2003. See the AUTHORS
|
||||||
|
* file for a list of people on the GLib Team. See the ChangeLog
|
||||||
|
* files for a list of changes. These files are distributed with
|
||||||
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "g-gnulib.h"
|
||||||
|
#include "vasnprintf.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
|
int _g_gnulib_printf (char const *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
retval = _g_gnulib_vprintf (format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_fprintf (FILE *file, char const *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
retval = _g_gnulib_vfprintf (file, format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_sprintf (char *string, char const *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
retval = _g_gnulib_vsprintf (string, format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_snprintf (char *string, size_t n, char const *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
retval = _g_gnulib_vsnprintf (string, n, format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_vprintf (char const *format, va_list args)
|
||||||
|
{
|
||||||
|
return _g_gnulib_vfprintf (stdout, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_vfprintf (FILE *file, char const *format, va_list args)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
result = vasnprintf (NULL, &length, format, args);
|
||||||
|
if (result == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fwrite (result, 1, length + 1, file);
|
||||||
|
free (result);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_vsprintf (char *string, char const *format, va_list args)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
result = vasnprintf (NULL, &length, format, args);
|
||||||
|
if (result == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy (string, result, length + 1);
|
||||||
|
free (result);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_vsnprintf (char *string, size_t n, char const *format, va_list args)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
result = vasnprintf (NULL, &length, format, args);
|
||||||
|
if (result == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
memcpy (string, result, MIN(length + 1, n));
|
||||||
|
string[n - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (result);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _g_gnulib_vasprintf (char **result, char const *format, va_list args)
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
*result = vasnprintf (NULL, &length, format, args);
|
||||||
|
if (*result == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
56
glib/gnulib/printf.h
Normal file
56
glib/gnulib/printf.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* GLIB - Library of useful routines for C programming
|
||||||
|
* Copyright (C) 2003 Matthias Clasen
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef __GNULIB_PRINTF_H__
|
||||||
|
#define __GNULIB_PRINTF_H__
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int _g_gnulib_printf (char const *format,
|
||||||
|
...);
|
||||||
|
int _g_gnulib_fprintf (FILE *file,
|
||||||
|
char const *format,
|
||||||
|
...);
|
||||||
|
int _g_gnulib_sprintf (char *string,
|
||||||
|
char const *format,
|
||||||
|
...);
|
||||||
|
int _g_gnulib_snprintf (char *string,
|
||||||
|
size_t n,
|
||||||
|
char const *format,
|
||||||
|
...);
|
||||||
|
int _g_gnulib_vprintf (char const *format,
|
||||||
|
va_list args);
|
||||||
|
int _g_gnulib_vfprintf (FILE *file,
|
||||||
|
char const *format,
|
||||||
|
va_list args);
|
||||||
|
int _g_gnulib_vsprintf (char *string,
|
||||||
|
char const *format,
|
||||||
|
va_list args);
|
||||||
|
int _g_gnulib_vsnprintf (char *string,
|
||||||
|
size_t n,
|
||||||
|
char const *format,
|
||||||
|
va_list args);
|
||||||
|
int _g_gnulib_vasprintf (char **result,
|
||||||
|
char const *format,
|
||||||
|
va_list args);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GNULIB_PRINTF_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
1000
glib/gnulib/vasnprintf.c
Normal file
1000
glib/gnulib/vasnprintf.c
Normal file
File diff suppressed because it is too large
Load Diff
61
glib/gnulib/vasnprintf.h
Normal file
61
glib/gnulib/vasnprintf.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* vsprintf with automatic memory allocation.
|
||||||
|
Copyright (C) 2002-2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#ifndef _VASNPRINTF_H
|
||||||
|
#define _VASNPRINTF_H
|
||||||
|
|
||||||
|
/* Get va_list. */
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* Get size_t. */
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef __attribute__
|
||||||
|
/* This feature is available in gcc versions 2.5 and later. */
|
||||||
|
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
||||||
|
# define __attribute__(Spec) /* empty */
|
||||||
|
# endif
|
||||||
|
/* The __-protected variants of `format' and `printf' attributes
|
||||||
|
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||||
|
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
||||||
|
# define __format__ format
|
||||||
|
# define __printf__ printf
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Write formatted output to a string dynamically allocated with malloc().
|
||||||
|
You can pass a preallocated buffer for the result in RESULTBUF and its
|
||||||
|
size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
|
||||||
|
If successful, return the address of the string (this may be = RESULTBUF
|
||||||
|
if no dynamic memory allocation was necessary) and set *LENGTHP to the
|
||||||
|
number of resulting bytes, excluding the trailing NUL. Upon error, set
|
||||||
|
errno and return NULL. */
|
||||||
|
extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
|
||||||
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||||
|
extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
|
||||||
|
__attribute__ ((__format__ (__printf__, 3, 0)));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _VASNPRINTF_H */
|
Loading…
Reference in New Issue
Block a user