]> granicus.if.org Git - php/commitdiff
- Add %Z to *printf
authorMarcus Boerger <helly@php.net>
Thu, 7 Feb 2008 18:40:29 +0000 (18:40 +0000)
committerMarcus Boerger <helly@php.net>
Thu, 7 Feb 2008 18:40:29 +0000 (18:40 +0000)
README.UNICODE-UPGRADES
main/snprintf.c
main/spprintf.c

index dac7f8b2afcbbe0d509800f93f9706076189d350..a7c7f8dc8b15b211a706429ab3d52a0f9c8b6865 100644 (file)
@@ -540,6 +540,19 @@ Unicode strings:
     zend_error(E_WARNING, "%v::__toString() did not return anything",
             Z_OBJCE_P(object)->name);
 
+  %Z
+    This format prints a zval's value. You can specify the minimum length
+    of the string representation using "%*Z" as well as the absolute length
+    using "%.*Z". The following example is taken from the engine and
+    therefor uses zend_spprintf rather than spprintf. Further more clen is
+    an integer that is smaller than Z_UNILEN_P(callable).
+
+    zend_spprintf(error, 0, "class '%.*Z' not found", clen, callable);
+
+    The function allows to output any kind of zaval values, as long as a
+    string (or unicode) conversion is available. Note that printing non
+    string zvals outside of request time is not possible.
+
 Since [v]spprintf() can only output native strings there are also the new
 functions [v]uspprintf() and [v]zspprintf() that create unicode strings and
 return the number of characters printed. That is they return the length rather
index 91e0b67cd49ca546d912a229924f16fbe98a1b73..3890871c1d227b0eea551a3567a0da65144b40d2 100644 (file)
@@ -573,17 +573,18 @@ typedef struct buf_area buffy;
  */
 static int format_converter(register buffy * odp, const char *fmt, va_list ap) /* {{{ */
 {
-       register char *sp;
-       register char *bep;
-       register int cc = 0;
-       register int i;
+       char *sp;
+       char *bep;
+       int cc = 0;
+       int i;
 
-       register char *s = NULL;
-       register UChar *u = NULL;
+       char *s = NULL;
+       UChar *u = NULL;
        char *q;
-       int s_len, s_unicode, u_len;
+       int s_len, s_unicode, u_len, free_zcopy;
+       zval *zvp, zcopy;
 
-       register int min_width = 0;
+       int min_width = 0;
        int precision = 0;
        enum {
                LEFT, RIGHT
@@ -631,6 +632,7 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) /
                        pad_char = ' ';
                        prefix_char = NUL;
                        s_to_free = NULL;
+                       free_zcopy = 0;
                        s_unicode = 0;
 
                        fmt++;
@@ -778,6 +780,18 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) /
                         *   It is reset to ' ' by non-numeric formats
                         */
                        switch (*fmt) {
+                               case 'Z':
+                                       zvp = (zval*) va_arg(ap, zval*);
+                                       zend_make_string_zval(zvp, &zcopy, &free_zcopy);
+                                       if (free_zcopy) {
+                                               zvp = &zcopy;
+                                       }
+                                       s_len = Z_UNILEN_P(zvp);
+                                       s = Z_STRVAL_P(zvp);
+                                       if (adjust_precision && precision < s_len) {
+                                               s_len = precision;
+                                       }
+                                       break;
                                case 'u':
                                        switch(modifier) {
                                                default:
@@ -1203,7 +1217,12 @@ fmt_error:
                                s++;
                        }
 
-                       if (s_to_free) efree(s_to_free);
+                       if (s_to_free) {
+                               efree(s_to_free);
+                       }
+                       if (free_zcopy) {
+                               zval_dtor(&zcopy);
+                       }
 
                        if (adjust_width && adjust == LEFT && min_width > s_len)
                                PAD(min_width, s_len, pad_char);
index 219a767322d5d167f09d1082cbde0d123ae065e7..90f3c380fb930730691dcad1dbc22fb3ef1f6c05 100644 (file)
@@ -214,12 +214,12 @@ do {                                                                                              \
  */
 static void xbuf_format_converter(int unicode, smart_str *xbuf, const char *fmt, va_list ap) /* {{{ */
 {
-       register char *s = NULL;
-       register UChar *u = NULL;
+       char *s = NULL;
+       UChar *u = NULL;
        char *q;
-       int s_len, s_unicode, u_len;
-
-       register int min_width = 0;
+       int s_len, s_unicode, u_len, free_zcopy;
+       zval *zvp, zcopy;
+       int min_width = 0;
        int precision = 0;
        enum {
                LEFT, RIGHT
@@ -232,7 +232,7 @@ static void xbuf_format_converter(int unicode, smart_str *xbuf, const char *fmt,
        u_wide_int ui_num;
 
        char num_buf[NUM_BUF_SIZE];
-       char char_buf[2];                       /* for printing %% and %<unknown> */
+       char char_buf[2]; /* for printing %% and %<unknown> */
        zend_bool free_s; /* free string if allocated here */
 
 #ifdef HAVE_LOCALE_H
@@ -264,6 +264,7 @@ static void xbuf_format_converter(int unicode, smart_str *xbuf, const char *fmt,
                        pad_char = ' ';
                        prefix_char = NUL;
                        free_s = 0;
+                       free_zcopy = 0;
                        s_unicode = 0;
 
                        fmt++;
@@ -411,6 +412,23 @@ static void xbuf_format_converter(int unicode, smart_str *xbuf, const char *fmt,
                         *   It is reset to ' ' by non-numeric formats
                         */
                        switch (*fmt) {
+                               case 'Z':
+                                       zvp = (zval*) va_arg(ap, zval*);
+                                       if (unicode) {
+                                               zend_make_unicode_zval(zvp, &zcopy, &free_zcopy);
+                                               s_unicode = 1;
+                                       } else {
+                                               zend_make_string_zval(zvp, &zcopy, &free_zcopy);
+                                       }
+                                       if (free_zcopy) {
+                                               zvp = &zcopy;
+                                       }
+                                       s_len = Z_UNILEN_P(zvp);
+                                       s = Z_STRVAL_P(zvp);
+                                       if (adjust_precision && precision < s_len) {
+                                               s_len = precision;
+                                       }
+                                       break;
                                case 'u':
                                        switch(modifier) {
                                                default:
@@ -838,7 +856,12 @@ fmt_error:
                         * Print the string s.
                         */
                        INS_STRING(unicode, s_unicode, xbuf, s, s_len);
-                       if (free_s) efree(s);
+                       if (free_s) {
+                               efree(s);
+                       }
+                       if (free_zcopy) {
+                               zval_dtor(&zcopy);
+                       }
 
                        if (adjust_width && adjust == LEFT && min_width > s_len) {
                                PAD(unicode, xbuf, min_width - s_len, pad_char);