summaryrefslogtreecommitdiff
path: root/main/spprintf.c
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2003-09-14 09:12:54 +0000
committerMarcus Boerger <helly@php.net>2003-09-14 09:12:54 +0000
commit9b98e42f3590e4b2d70923632b445df32a9dfc5e (patch)
tree2001a0f0cf2545722de983b2d5dab7de5b0b61de /main/spprintf.c
parentcb5b1690ace07cf4af15b04c2a09b80f376fc976 (diff)
downloadphp-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.c200
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) {