diff options
author | Yang Tse <yangsita@gmail.com> | 2008-08-22 11:11:33 +0000 |
---|---|---|
committer | Yang Tse <yangsita@gmail.com> | 2008-08-22 11:11:33 +0000 |
commit | 9bb5da968c7ab38434d426f9928bcd69cf4ebb02 (patch) | |
tree | 96c7f3e785aff54c0a0713dd3affe087ae0a3636 /lib/mprintf.c | |
parent | d5a71fd567fc8e4f75c19fb36e7e9424532e1f44 (diff) | |
download | curl-9bb5da968c7ab38434d426f9928bcd69cf4ebb02.tar.gz |
Improved curl_m*printf() integral data type size and signedness handling
Diffstat (limited to 'lib/mprintf.c')
-rw-r--r-- | lib/mprintf.c | 108 |
1 files changed, 53 insertions, 55 deletions
diff --git a/lib/mprintf.c b/lib/mprintf.c index 0623aaea9..2f7f31e29 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -49,6 +49,10 @@ #include <curl/mprintf.h> +#include "memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + #ifndef SIZEOF_LONG_DOUBLE #define SIZEOF_LONG_DOUBLE 0 #endif @@ -74,9 +78,17 @@ # endif #endif -#include "memory.h" -/* The last #include file should be: */ -#include "memdebug.h" +/* + * Max integer data types that mprintf.c is capable + */ + +#ifdef HAVE_LONG_LONG_TYPE +# define mp_intmax_t LONG_LONG_TYPE +# define mp_uintmax_t unsigned LONG_LONG_TYPE +#else +# define mp_intmax_t long +# define mp_uintmax_t unsigned long +#endif #define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */ #define MAX_PARAMETERS 128 /* lame static limit */ @@ -146,10 +158,10 @@ typedef struct { union { char *str; void *ptr; - long num; -#ifdef HAVE_LONG_LONG_TYPE - LONG_LONG_TYPE lnum; -#endif + union { + mp_intmax_t as_signed; + mp_uintmax_t as_unsigned; + } num; double dnum; } data; } va_stack_t; @@ -544,7 +556,7 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos, /* Width/precision arguments must be read before the main argument * they are attached to */ - vto[i + 1].data.num = va_arg(arglist, int); + vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int); } switch (vto[i].type) @@ -561,15 +573,27 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos, case FORMAT_INT: #ifdef HAVE_LONG_LONG_TYPE - if(vto[i].flags & FLAGS_LONGLONG) - vto[i].data.lnum = va_arg(arglist, LONG_LONG_TYPE); + if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED)) + vto[i].data.num.as_unsigned = + (mp_uintmax_t)va_arg(arglist, unsigned LONG_LONG_TYPE); + else if(vto[i].flags & FLAGS_LONGLONG) + vto[i].data.num.as_signed = + (mp_intmax_t)va_arg(arglist, LONG_LONG_TYPE); else #endif { - if(vto[i].flags & FLAGS_LONG) - vto[i].data.num = va_arg(arglist, long); + if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED)) + vto[i].data.num.as_unsigned = + (mp_uintmax_t)va_arg(arglist, unsigned long); + else if(vto[i].flags & FLAGS_LONG) + vto[i].data.num.as_signed = + (mp_intmax_t)va_arg(arglist, long); + else if(vto[i].flags & FLAGS_UNSIGNED) + vto[i].data.num.as_unsigned = + (mp_uintmax_t)va_arg(arglist, unsigned int); else - vto[i].data.num = va_arg(arglist, int); + vto[i].data.num.as_signed = + (mp_intmax_t)va_arg(arglist, int); } break; @@ -645,13 +669,10 @@ static int dprintf_formatf( long base; /* Integral values to be written. */ -#ifdef HAVE_LONG_LONG_TYPE - unsigned LONG_LONG_TYPE num; - LONG_LONG_TYPE signed_num; -#else - unsigned long num; - long signed_num; -#endif + mp_uintmax_t num; + + /* Used to convert negative in positive. */ + mp_intmax_t signed_num; if(*f != '%') { /* This isn't a format spec, so write everything out until the next one @@ -690,13 +711,13 @@ static int dprintf_formatf( /* pick up the specified width */ if(p->flags & FLAGS_WIDTHPARAM) - width = vto[p->width].data.num; + width = (long)vto[p->width].data.num.as_signed; else width = p->width; /* pick up the specified precision */ if(p->flags & FLAGS_PRECPARAM) { - prec = vto[p->precision].data.num; + prec = (long)vto[p->precision].data.num.as_signed; param_num++; /* since the precision is extraced from a parameter, we must skip that to get to the next one properly */ } @@ -709,12 +730,7 @@ static int dprintf_formatf( switch (p->type) { case FORMAT_INT: -#ifdef HAVE_LONG_LONG_TYPE - if(p->flags & FLAGS_LONGLONG) - num = (unsigned LONG_LONG_TYPE)p->data.lnum; - else -#endif - num = (unsigned long)p->data.num; + num = p->data.num.as_unsigned; if(p->flags & FLAGS_CHAR) { /* Character. */ if(!(p->flags & FLAGS_LEFT)) @@ -747,32 +763,14 @@ static int dprintf_formatf( /* Decimal integer. */ base = 10; -#ifdef HAVE_LONG_LONG_TYPE - if(p->flags & FLAGS_LONGLONG) { - /* long long */ - is_neg = (p->data.lnum < 0); - if(is_neg) { - /* signed long long might fail to hold absolute LLONG_MIN by 1 */ - signed_num = p->data.lnum + (LONG_LONG_TYPE)1; - num = (unsigned LONG_LONG_TYPE)-signed_num; - num += (unsigned LONG_LONG_TYPE)1; - } - else - num = p->data.lnum; - } - else -#endif - { - is_neg = (p->data.num < 0); - if(is_neg) { - /* signed long might fail to hold absolute LONG_MIN by 1 */ - signed_num = p->data.num + (long)1; - num = (unsigned long)-signed_num; - num += (unsigned long)1; - } - else - num = p->data.num; + is_neg = p->data.num.as_signed < 0; + if(is_neg) { + /* signed_num might fail to hold absolute negative minimum by 1 */ + signed_num = p->data.num.as_signed + (mp_intmax_t)1; + num = (mp_uintmax_t)-signed_num; + num += (mp_uintmax_t)1; } + goto number; unsigned_number: @@ -938,13 +936,13 @@ static int dprintf_formatf( if(p->flags & FLAGS_WIDTH) width = p->width; else if(p->flags & FLAGS_WIDTHPARAM) - width = vto[p->width].data.num; + width = (long)vto[p->width].data.num.as_signed; prec = -1; if(p->flags & FLAGS_PREC) prec = p->precision; else if(p->flags & FLAGS_PRECPARAM) - prec = vto[p->precision].data.num; + prec = (long)vto[p->precision].data.num.as_signed; if(p->flags & FLAGS_LEFT) strcat(formatbuf, "-"); |