version 1.1.1.1, 2012/02/21 16:23:02
|
version 1.1.1.3, 2014/06/15 16:12:54
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 1999-2005, 2008, 2010-2011 | * Copyright (c) 1999-2005, 2008, 2010-2013 |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1990, 1993 |
* Copyright (c) 1990, 1993 |
* The Regents of the University of California. All rights reserved. |
* The Regents of the University of California. All rights reserved. |
Line 41
|
Line 41
|
|
|
#include <config.h> |
#include <config.h> |
|
|
|
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF) || \ |
|
!defined(HAVE_VASPRINTF) || !defined(HAVE_ASPRINTF) || \ |
|
defined(PREFER_PORTABLE_SNPRINTF) |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
|
|
|
#include <stdio.h> |
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
Line 53
|
Line 56
|
# include <stdlib.h> |
# include <stdlib.h> |
# endif |
# endif |
#endif /* STDC_HEADERS */ |
#endif /* STDC_HEADERS */ |
#ifdef HAVE_STDINT_H | #if defined(HAVE_STDINT_H) |
# include <stdint.h> |
# include <stdint.h> |
|
#elif defined(HAVE_INTTYPES_H) |
|
# include <inttypes.h> |
#endif |
#endif |
#ifdef HAVE_STRING_H |
#ifdef HAVE_STRING_H |
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) |
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) |
Line 76
|
Line 81
|
static int xxxprintf(char **, size_t, int, const char *, va_list); |
static int xxxprintf(char **, size_t, int, const char *, va_list); |
|
|
/* |
/* |
* Some systems may not have these defined in <limits.h> |
|
*/ |
|
#ifndef ULONG_MAX |
|
# define ULONG_MAX ((unsigned long)-1) |
|
#endif |
|
#ifndef LONG_MAX |
|
# define LONG_MAX (ULONG_MAX / 2) |
|
#endif |
|
#ifdef HAVE_LONG_LONG_INT |
|
# ifndef ULLONG_MAX |
|
# ifdef UQUAD_MAX |
|
# define ULLONG_MAX UQUAD_MAX |
|
# else |
|
# define ULLONG_MAX ((unsigned long long)-1) |
|
# endif |
|
# endif |
|
# ifndef LLONG_MAX |
|
# ifdef QUAD_MAX |
|
# define LLONG_MAX QUAD_MAX |
|
# else |
|
# define LLONG_MAX (ULLONG_MAX / 2) |
|
# endif |
|
# endif |
|
#endif /* HAVE_LONG_LONG_INT */ |
|
|
|
/* |
|
* Macros for converting digits to letters and vice versa |
* Macros for converting digits to letters and vice versa |
*/ |
*/ |
#define to_digit(c) ((c) - '0') |
#define to_digit(c) ((c) - '0') |
Line 116 static int xxxprintf(char **, size_t, int, const char
|
Line 95 static int xxxprintf(char **, size_t, int, const char
|
#define LADJUST 0x004 /* left adjustment */ |
#define LADJUST 0x004 /* left adjustment */ |
#define LONGDBL 0x008 /* long double; unimplemented */ |
#define LONGDBL 0x008 /* long double; unimplemented */ |
#define LONGINT 0x010 /* long integer */ |
#define LONGINT 0x010 /* long integer */ |
#define QUADINT 0x020 /* quad integer */ | #define LLONGINT 0x020 /* quad integer */ |
#define SHORTINT 0x040 /* short integer */ |
#define SHORTINT 0x040 /* short integer */ |
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ |
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ |
|
|
Line 184 __ultoa(unsigned long val, char *endp, int base, int o
|
Line 163 __ultoa(unsigned long val, char *endp, int base, int o
|
} |
} |
|
|
/* Identical to __ultoa, but for quads. */ |
/* Identical to __ultoa, but for quads. */ |
#ifdef HAVE_LONG_LONG_INT | #if SIZEOF_LONG_INT == 8 |
# if SIZEOF_LONG_INT == 8 | # define __ulltoa(v, e, b, o, x) __ultoa((unsigned long)(v), (e), (b), (o), (x)) |
# define __uqtoa(v, e, b, o, x) __ultoa((unsigned long)(v), (e), (b), (o), (x)) | #else |
# else | |
static char * |
static char * |
__uqtoa(unsigned long long val, char *endp, int base, int octzero, char *xdigs) | __ulltoa(unsigned long long val, char *endp, int base, int octzero, char *xdigs) |
{ |
{ |
char *cp = endp; |
char *cp = endp; |
long long sval; |
long long sval; |
Line 236 __uqtoa(unsigned long long val, char *endp, int base,
|
Line 214 __uqtoa(unsigned long long val, char *endp, int base,
|
} |
} |
return cp; |
return cp; |
} |
} |
# endif /* !SIZEOF_LONG_INT */ | #endif /* !SIZEOF_LONG_INT */ |
#endif /* HAVE_LONG_LONG_INT */ | |
|
|
/* |
/* |
* Actual printf innards. |
* Actual printf innards. |
Line 255 xxxprintf(char **strp, size_t strsize, int alloc, cons
|
Line 232 xxxprintf(char **strp, size_t strsize, int alloc, cons
|
int prec; /* precision from format (%.3d), or -1 */ |
int prec; /* precision from format (%.3d), or -1 */ |
char sign; /* sign prefix (' ', '+', '-', or \0) */ |
char sign; /* sign prefix (' ', '+', '-', or \0) */ |
unsigned long ulval = 0; /* integer arguments %[diouxX] */ |
unsigned long ulval = 0; /* integer arguments %[diouxX] */ |
#ifdef HAVE_LONG_LONG_INT | unsigned long long ullval = 0; /* long long arguments %ll[diouxX] */ |
unsigned long long uqval = 0; /* %q (quad) integers */ | |
#endif | |
int base; /* base for [diouxX] conversion */ |
int base; /* base for [diouxX] conversion */ |
int dprec; /* a copy of prec if [diouxX], 0 otherwise */ |
int dprec; /* a copy of prec if [diouxX], 0 otherwise */ |
int fieldsz; /* field size expanded by sign, etc */ |
int fieldsz; /* field size expanded by sign, etc */ |
Line 430 reswitch: switch (ch) {
|
Line 405 reswitch: switch (ch) {
|
flags |= SHORTINT; |
flags |= SHORTINT; |
goto rflag; |
goto rflag; |
case 'l': |
case 'l': |
flags |= LONGINT; | if (*fmt == 'l') { |
| fmt++; |
| flags |= LLONGINT; |
| } else { |
| flags |= LONGINT; |
| } |
goto rflag; |
goto rflag; |
#ifdef HAVE_LONG_LONG_INT |
|
case 'q': |
|
flags |= QUADINT; |
|
goto rflag; |
|
#endif /* HAVE_LONG_LONG_INT */ |
|
case 'c': |
case 'c': |
*(cp = buf) = va_arg(ap, int); |
*(cp = buf) = va_arg(ap, int); |
size = 1; |
size = 1; |
Line 447 reswitch: switch (ch) {
|
Line 422 reswitch: switch (ch) {
|
/*FALLTHROUGH*/ |
/*FALLTHROUGH*/ |
case 'd': |
case 'd': |
case 'i': |
case 'i': |
#ifdef HAVE_LONG_LONG_INT | if (flags & LLONGINT) { |
if (flags & QUADINT) { | ullval = va_arg(ap, long long); |
uqval = va_arg(ap, long long); | if ((long long)ullval < 0) { |
if ((long long)uqval < 0) { | ullval = -ullval; |
uqval = -uqval; | |
sign = '-'; |
sign = '-'; |
} |
} |
} | } else { |
else | |
#endif /* HAVE_LONG_LONG_INT */ | |
{ | |
ulval = SARG(); |
ulval = SARG(); |
if ((long)ulval < 0) { |
if ((long)ulval < 0) { |
ulval = -ulval; |
ulval = -ulval; |
Line 467 reswitch: switch (ch) {
|
Line 438 reswitch: switch (ch) {
|
base = 10; |
base = 10; |
goto number; |
goto number; |
case 'n': |
case 'n': |
#ifdef HAVE_LONG_LONG_INT | if (flags & LLONGINT) |
if (flags & QUADINT) | |
*va_arg(ap, long long *) = ret; |
*va_arg(ap, long long *) = ret; |
else | else if (flags & LONGINT) |
#endif /* HAVE_LONG_LONG_INT */ | |
if (flags & LONGINT) | |
*va_arg(ap, long *) = ret; |
*va_arg(ap, long *) = ret; |
else if (flags & SHORTINT) |
else if (flags & SHORTINT) |
*va_arg(ap, short *) = ret; |
*va_arg(ap, short *) = ret; |
Line 483 reswitch: switch (ch) {
|
Line 451 reswitch: switch (ch) {
|
flags |= LONGINT; |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
/*FALLTHROUGH*/ |
case 'o': |
case 'o': |
#ifdef HAVE_LONG_LONG_INT | if (flags & LLONGINT) |
if (flags & QUADINT) | ullval = va_arg(ap, unsigned long long); |
uqval = va_arg(ap, unsigned long long); | |
else |
else |
#endif /* HAVE_LONG_LONG_INT */ |
|
ulval = UARG(); |
ulval = UARG(); |
base = 8; |
base = 8; |
goto nosign; |
goto nosign; |
Line 502 reswitch: switch (ch) {
|
Line 468 reswitch: switch (ch) {
|
ulval = (unsigned long)va_arg(ap, void *); |
ulval = (unsigned long)va_arg(ap, void *); |
base = 16; |
base = 16; |
xdigs = "0123456789abcdef"; |
xdigs = "0123456789abcdef"; |
flags = (flags & ~QUADINT) | HEXPREFIX; | flags = (flags & ~LLONGINT) | HEXPREFIX; |
ch = 'x'; |
ch = 'x'; |
goto nosign; |
goto nosign; |
case 's': |
case 's': |
Line 530 reswitch: switch (ch) {
|
Line 496 reswitch: switch (ch) {
|
flags |= LONGINT; |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
/*FALLTHROUGH*/ |
case 'u': |
case 'u': |
#ifdef HAVE_LONG_LONG_INT | if (flags & LLONGINT) |
if (flags & QUADINT) | ullval = va_arg(ap, unsigned long long); |
uqval = va_arg(ap, unsigned long long); | |
else |
else |
#endif /* HAVE_LONG_LONG_INT */ |
|
ulval = UARG(); |
ulval = UARG(); |
base = 10; |
base = 10; |
goto nosign; |
goto nosign; |
Line 544 reswitch: switch (ch) {
|
Line 508 reswitch: switch (ch) {
|
case 'x': |
case 'x': |
xdigs = "0123456789abcdef"; |
xdigs = "0123456789abcdef"; |
hex: |
hex: |
#ifdef HAVE_LONG_LONG_INT | if (flags & LLONGINT) |
if (flags & QUADINT) | ullval = va_arg(ap, unsigned long long); |
uqval = va_arg(ap, unsigned long long); | |
else |
else |
#endif /* HAVE_LONG_LONG_INT */ |
|
ulval = UARG(); |
ulval = UARG(); |
base = 16; |
base = 16; |
/* leading 0x/X only if non-zero */ |
/* leading 0x/X only if non-zero */ |
if (flags & ALT && |
if (flags & ALT && |
#ifdef HAVE_LONG_LONG_INT | (flags & LLONGINT ? ullval != 0 : ulval != 0)) |
(flags & QUADINT ? uqval != 0 : ulval != 0)) | |
#else | |
ulval != 0) | |
#endif /* HAVE_LONG_LONG_INT */ | |
flags |= HEXPREFIX; |
flags |= HEXPREFIX; |
|
|
/* unsigned conversions */ |
/* unsigned conversions */ |
Line 576 number: if ((dprec = prec) >= 0)
|
Line 534 number: if ((dprec = prec) >= 0)
|
* -- ANSI X3J11 |
* -- ANSI X3J11 |
*/ |
*/ |
cp = buf + BUF; |
cp = buf + BUF; |
#ifdef HAVE_LONG_LONG_INT | if (flags & LLONGINT) { |
if (flags & QUADINT) { | if (ullval != 0 || prec != 0) |
if (uqval != 0 || prec != 0) | cp = __ulltoa(ullval, cp, base, |
cp = __uqtoa(uqval, cp, base, | |
flags & ALT, xdigs); |
flags & ALT, xdigs); |
} | } else { |
else | |
#endif /* HAVE_LONG_LONG_INT */ | |
{ | |
if (ulval != 0 || prec != 0) |
if (ulval != 0 || prec != 0) |
cp = __ultoa(ulval, cp, base, |
cp = __ultoa(ulval, cp, base, |
flags & ALT, xdigs); |
flags & ALT, xdigs); |
Line 660 done:
|
Line 614 done:
|
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
#ifndef HAVE_VSNPRINTF | #if !defined(HAVE_VSNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
int |
int |
vsnprintf(char *str, size_t n, const char *fmt, va_list ap) | rpl_vsnprintf(char *str, size_t n, const char *fmt, va_list ap) |
{ |
{ |
|
|
return xxxprintf(&str, n, 0, fmt, ap); |
return xxxprintf(&str, n, 0, fmt, ap); |
} |
} |
#endif /* HAVE_VSNPRINTF */ | #endif /* !HAVE_VSNPRINTF || PREFER_PORTABLE_SNPRINTF */ |
|
|
#ifndef HAVE_SNPRINTF | #if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
int |
int |
snprintf(char *str, size_t n, char const *fmt, ...) | rpl_snprintf(char *str, size_t n, char const *fmt, ...) |
{ |
{ |
int ret; |
int ret; |
va_list ap; |
va_list ap; |
Line 681 snprintf(char *str, size_t n, char const *fmt, ...)
|
Line 635 snprintf(char *str, size_t n, char const *fmt, ...)
|
va_end(ap); |
va_end(ap); |
return ret; |
return ret; |
} |
} |
#endif /* HAVE_SNPRINTF */ | #endif /* !HAVE_SNPRINTF || PREFER_PORTABLE_SNPRINTF */ |
|
|
#ifndef HAVE_VASPRINTF | #if !defined(HAVE_VASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
int |
int |
vasprintf(char **str, const char *fmt, va_list ap) | rpl_vasprintf(char **str, const char *fmt, va_list ap) |
{ |
{ |
|
|
return xxxprintf(str, 0, 1, fmt, ap); |
return xxxprintf(str, 0, 1, fmt, ap); |
} |
} |
#endif /* HAVE_VASPRINTF */ | #endif /* !HAVE_VASPRINTF || PREFER_PORTABLE_SNPRINTF */ |
|
|
#ifndef HAVE_ASPRINTF | #if !defined(HAVE_ASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
int |
int |
asprintf(char **str, char const *fmt, ...) | rpl_asprintf(char **str, char const *fmt, ...) |
{ |
{ |
int ret; |
int ret; |
va_list ap; |
va_list ap; |
Line 704 asprintf(char **str, char const *fmt, ...)
|
Line 658 asprintf(char **str, char const *fmt, ...)
|
va_end(ap); |
va_end(ap); |
return ret; |
return ret; |
} |
} |
#endif /* HAVE_ASPRINTF */ | #endif /* !HAVE_ASPRINTF || PREFER_PORTABLE_SNPRINTF */ |
| |
| #endif /* !HAVE_VSNPRINTF || !HAVE_SNPRINTF || !HAVE_VASPRINTF || !HAVE_ASPRINTF || PREFER_PORTABLE_SNPRINTF */ |