]> granicus.if.org Git - php/commitdiff
- Add length modifiers(ll, j, t, h, hh)
authorMarcus Boerger <helly@php.net>
Sun, 14 Sep 2003 09:12:54 +0000 (09:12 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 14 Sep 2003 09:12:54 +0000 (09:12 +0000)
# 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.

configure.in
main/config.w32.h
main/snprintf.c
main/snprintf.h
main/spprintf.c

index 68b97badf1d20eed06123accdb3e971c56a1092a..101e650a88039cdb0d40bbc51d83ad0620cc658a 100644 (file)
@@ -401,6 +401,12 @@ PHP_TM_GMTOFF
 PHP_STRUCT_FLOCK
 PHP_SOCKLEN_T
 
+AC_CHECK_SIZEOF(intmax_t, 0)
+AC_CHECK_SIZEOF(size_t, 8)
+AC_CHECK_SIZEOF(ssize_t, 8)
+AC_CHECK_SIZEOF(ptrdiff_t, 8)
+AC_CHECK_SIZEOF(long long, 8)
+AC_CHECK_SIZEOF(long long int, 8)
 AC_CHECK_SIZEOF(long, 8)
 AC_CHECK_SIZEOF(int, 4)
 
@@ -1166,7 +1172,8 @@ PHP_ADD_SOURCES(Zend, \
     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c)
 
 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
-  PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c zend_default_classes.c zend_reflection_api.c)
+  PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
+    zend_default_classes.c zend_reflection_api.c zend_interfaces.c)
 fi
 
 dnl Selectively disable optimization due to high RAM usage during
index 4d5bdc6a95a76ba8d44934b7f72e2754c982c395..7df0d0d18411a8b38e906e7199280579cc21b5f3 100644 (file)
 #define HAVE_CUSERID 0
 #undef HAVE_RINT
 #define HAVE_STRFTIME 1
+/* int and long are stll 32bit in 64bit compiles */
 #define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+/* MSVC.6/NET don't allow 'long long' or know 'intmax_t' */
+#define SIZEOF_LONG_LONG_INT 0
+#define SIZEOF_LONG_LONG 0
+#define SIZEOF_INTMAX_T 0
+#define ssize_t ptrdiff_t
+#ifdef _WIN64
+# define SIZEOF_SIZE_T 8
+# define SIZEOF_PTRDIFF_T 8
+#else
+# define SIZEOF_SIZE_T 4
+# define SIZEOF_PTRDIFF_T 4
+#endif
 #define HAVE_GLOB
 #define PHP_SHLIB_SUFFIX "dll"
 #define HAVE_SQLDATASOURCES
index e9cbd196461eacfc91196c51e9f5318fe434c806..6c61f21938f2225e23713443dfd144ac8ec24f89 100644 (file)
@@ -75,6 +75,7 @@
 
 #include "php.h"
 
+#include <stddef.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
@@ -577,8 +578,7 @@ static int format_converter(register buffy * odp, const char *fmt,
        /*
         * 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;
@@ -669,17 +669,43 @@ static int format_converter(register buffy * odp, const char *fmt,
                        /*
                         * 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;
                        }
 
                        /*
@@ -695,12 +721,32 @@ static int format_converter(register buffy * odp, const char *fmt,
                         */
                        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.
@@ -711,13 +757,37 @@ static int format_converter(register buffy * odp, const char *fmt,
                                         * 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);
@@ -734,12 +804,32 @@ static int format_converter(register buffy * odp, const char *fmt,
 
 
                                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);
@@ -752,12 +842,32 @@ static int format_converter(register buffy * odp, const char *fmt,
 
                                case 'x':
                                case 'X':
-                                       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);
@@ -865,7 +975,7 @@ static int format_converter(register buffy * odp, const char *fmt,
                                         */
                                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) {
index e810826a6e081448bbdf185db5831fd70250ff2f..da659c3bec63087dc847c885d33cebc06c1329b9 100644 (file)
@@ -83,12 +83,35 @@ typedef enum {
        NO = 0, YES = 1
 } boolean_e;
 
+typedef enum {
+       LM_STD = 0,
+#if SIZEOF_INTMAX_T
+       LM_INTMAX_T,
+#endif
+#if SIZEOF_PTRDIFF_T
+       LM_PTRDIFF_T,
+#endif
+#if SIZEOF_LONG_LONG
+       LM_LONG_LONG,
+#endif
+       LM_SIZE_T,
+       LM_LONG
+} length_modifier_e;
+
 extern char * ap_php_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf);
 extern char * ap_php_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf);
 extern char * ap_php_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf);
 extern char * ap_php_gcvt(double number, int ndigit, char *buf, boolean_e altform);
 
-#define WIDE_INT               long
+#if SIZEOF_LONG_LONG_INT
+# define WIDE_INT              long long int
+#elif SIZEOF_LONG_LONG
+# define WIDE_INT              long long
+#elif _WIN64
+# define WIDE_INT              __int64
+#else
+# define WIDE_INT              long
+#endif
 typedef WIDE_INT wide_int;
 typedef unsigned WIDE_INT u_wide_int;
 
index be5509a7ac1e711acb4c35c478b1e5510efae1cb..f248e8eeb53fc02a5bff767eca2cee448b3243ed 100644 (file)
  */
 
 #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) {