Add gnulib vasnprintf().

This commit is contained in:
Matthias Clasen 2003-07-28 22:58:01 +00:00
parent e4f08fe7eb
commit 3389a051da
12 changed files with 2226 additions and 0 deletions

24
glib/gnulib/Makefile.am Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}

View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

61
glib/gnulib/vasnprintf.h Normal file
View 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 */