diff options
author | Marcus Boerger <helly@php.net> | 2003-09-14 09:12:54 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2003-09-14 09:12:54 +0000 |
commit | 9b98e42f3590e4b2d70923632b445df32a9dfc5e (patch) | |
tree | 2001a0f0cf2545722de983b2d5dab7de5b0b61de /main/spprintf.c | |
parent | cb5b1690ace07cf4af15b04c2a09b80f376fc976 (diff) | |
download | php-git-9b98e42f3590e4b2d70923632b445df32a9dfc5e.tar.gz |
- Add length modifiers(ll, j, t, h, hh)
# Still missing formats (%a, %A)
# Still missing modifier (l) in (%lc, %ls)
# Still missing modifier (L) in (%La, %LA, %Le, %LE, %Lf, %LF, %Lg, %LG)
# C99 requires any conversion to be able to produce at least 4095
# characters. Implementation only allows less then 512.
#
# Only inside ext/mbstring etc. we could use %lc and %ls. And none of the
# rest should affect us until we stay with double and avoid long double.
Diffstat (limited to 'main/spprintf.c')
-rw-r--r-- | main/spprintf.c | 200 |
1 files changed, 158 insertions, 42 deletions
diff --git a/main/spprintf.c b/main/spprintf.c index be5509a7ac..f248e8eeb5 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -78,6 +78,16 @@ */ #include "php.h" + +#include <stddef.h> +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> + #include "snprintf.h" #define FALSE 0 @@ -186,8 +196,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* * Flag variables */ - boolean_e is_long; - boolean_e is_size_t; + length_modifier_e modifier; boolean_e alternate_form; boolean_e print_sign; boolean_e print_blank; @@ -275,17 +284,43 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* * Modifier check */ - if (*fmt == 'l') { - is_long = YES; - is_size_t = NO; - fmt++; - } else if (*fmt == 'z') { - is_size_t = YES; - is_long = NO; - fmt++; - } else { - is_size_t = NO; - is_long = NO; + switch (*fmt) { + case 'l': + fmt++; +#if SIZEOF_LONG_LONG + if (*fmt == 'l') { + fmt++; + modifier = LM_LONG_LONG; + } else +#endif + modifier = LM_LONG; + break; + case 'z': + modifier = LM_SIZE_T; + break; + case 'j': +#if SIZEOF_INTMAX_T + modifier = LM_INTMAX_T; +#else + modifier = LM_SIZE_T; +#endif + break; + case 't': +#if SIZEOF_PTRDIFF_T + modifier = LM_PTRDIFF_T; +#else + modifier = LM_SIZE_T; +#endif + break; + case 'h': + fmt++; + if (*fmt == 'h') { + fmt++; + } + /* these are promoted to int, so no break */ + default: + modifier = LM_STD; + break; } /* @@ -301,12 +336,32 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) */ switch (*fmt) { case 'u': - if (is_long) - i_num = va_arg(ap, u_wide_int); - else if (is_size_t) - i_num = (wide_int) va_arg(ap, size_t); - else - i_num = (wide_int) va_arg(ap, unsigned int); + switch(modifier) { + default: + i_num = (wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG: + i_num = (wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + i_num = (wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + i_num = (wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + i_num = (wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + i_num = (wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } /* * The rest also applies to other integer formats, so fall * into that case. @@ -317,13 +372,37 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) * Get the arg if we haven't already. */ if ((*fmt) != 'u') { - if (is_long) - i_num = va_arg(ap, wide_int); - else if (is_size_t) - i_num = (wide_int) va_arg(ap, size_t); - else - i_num = (wide_int) va_arg(ap, int); - }; + switch(modifier) { + default: + i_num = (wide_int) va_arg(ap, int); + break; + case LM_LONG: + i_num = (wide_int) va_arg(ap, long int); + break; + case LM_SIZE_T: +#if SIZEOF_SSIZE_T + i_num = (wide_int) va_arg(ap, ssize_t); +#else + i_num = (wide_int) va_arg(ap, size_t); +#endif + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + i_num = (wide_int) va_arg(ap, wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + i_num = (wide_int) va_arg(ap, intmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + i_num = (wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } + } s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); FIX_PRECISION(adjust_precision, precision, s, s_len); @@ -340,12 +419,32 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) case 'o': - if (is_long) - ui_num = va_arg(ap, u_wide_int); - else if (is_size_t) - ui_num = (u_wide_int) va_arg(ap, size_t); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); + switch(modifier) { + default: + ui_num = (u_wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG: + ui_num = (u_wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + ui_num = (u_wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + ui_num = (u_wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); FIX_PRECISION(adjust_precision, precision, s, s_len); @@ -358,15 +457,32 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) case 'x': case 'X': - /* - * Get the arg if we haven't already. - */ - if (is_long) - ui_num = (u_wide_int) va_arg(ap, u_wide_int); - else if (is_size_t) - ui_num = (u_wide_int) va_arg(ap, size_t); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); + switch(modifier) { + default: + ui_num = (u_wide_int) va_arg(ap, unsigned int); + break; + case LM_LONG: + ui_num = (u_wide_int) va_arg(ap, unsigned long int); + break; + case LM_SIZE_T: + ui_num = (u_wide_int) va_arg(ap, size_t); + break; +#if SIZEOF_LONG_LONG + case LM_LONG_LONG: + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + break; +#endif +#if SIZEOF_INTMAX_T + case LM_INTMAX_T: + ui_num = (u_wide_int) va_arg(ap, uintmax_t); + break; +#endif +#if SIZEOF_PTRDIFF_T + case LM_PTRDIFF_T: + ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); + break; +#endif + } s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); FIX_PRECISION(adjust_precision, precision, s, s_len); @@ -474,7 +590,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) */ case 'p': if (sizeof(char *) <= sizeof(u_wide_int)) { - ui_num = (u_wide_int) va_arg(ap, char *); + ui_num = (u_wide_int)((size_t) va_arg(ap, char *)); s = ap_php_conv_p2(ui_num, 4, 'x', &num_buf[NUM_BUF_SIZE], &s_len); if (i_num != 0) { |