- Add %Z to *printf

This commit is contained in:
Marcus Boerger 2008-02-07 18:40:29 +00:00
parent b00b0c2dca
commit 602dd615e9
3 changed files with 71 additions and 16 deletions

View 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

View 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);

View 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);