cvs: php-src /ext/standard php_smart_str.h /main spprintf.c spprintf.h
| From: | Marcus Boerger | Date: | Sun, 14 Aug 2005 17:14:43 +0000 |
| Subject: | cvs: php-src /ext/standard php_smart_str.h /main spprintf.c spprintf.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-33380@lists.php.net to get a copy of this message | ||
helly Sun Aug 14 13:14:43 2005 EDT
Modified files:
/php-src/ext/standard php_smart_str.h
/php-src/main spprintf.c spprintf.h
Log:
- Initial support of easy way to generate unicode strings: [v]uspprinf()
# Same semantics as [v]spprintf, only it prints unicode strings instead of
# native strings. Atm it has a little problem since it length doesn't take
# the difference between UTF-16 code points vs units into account. But as
# long as no 4 byte codes are involved it should already run everything.
http://cvs.php.net/diff.php/php-src/ext/standard/php_smart_str.h?r1=1.30&r2=1.31&ty=u Index: php-src/ext/standard/php_smart_str.h diff -u php-src/ext/standard/php_smart_str.h:1.30 php-src/ext/standard/php_smart_str.h:1.31 --- php-src/ext/standard/php_smart_str.h:1.30 Wed Aug 3 10:08:11 2005 +++ php-src/ext/standard/php_smart_str.h Sun Aug 14 13:14:40 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_smart_str.h,v 1.30 2005/08/03 14:08:11 sniper Exp $ */ +/* $Id: php_smart_str.h,v 1.31 2005/08/14 17:14:40 helly Exp $ */ #ifndef PHP_SMART_STR_H #define PHP_SMART_STR_H @@ -78,8 +78,16 @@ #define smart_str_appends(dest, src) \ smart_str_appendl((dest), (src), strlen(src)) +/* normall character appending */ #define smart_str_appendc(dest, c) \ smart_str_appendc_ex((dest), (c), 0) + +/* appending of a single UTF-16 code unit (2 byte)*/ +#define smart_str_append2c(dest, c) while (0) { \ + smart_str_appendc_ex((dest), (c&0xFF), 0); \ + smart_str_appendc_ex((dest), (c&0xFF00 ? c>>8 : '\0'), 0); \ +} + #define smart_str_free(s) \ smart_str_free_ex((s), 0) #define smart_str_appendl(dest, src, len) \ http://cvs.php.net/diff.php/php-src/main/spprintf.c?r1=1.26&r2=1.27&ty=u Index: php-src/main/spprintf.c diff -u php-src/main/spprintf.c:1.26 php-src/main/spprintf.c:1.27 --- php-src/main/spprintf.c:1.26 Thu Aug 11 19:36:06 2005 +++ php-src/main/spprintf.c Sun Aug 14 13:14:42 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spprintf.c,v 1.26 2005/08/11 23:36:06 andrei Exp $ */ +/* $Id: spprintf.c,v 1.27 2005/08/14 17:14:42 helly Exp $ */ /* This is the spprintf implementation. * It has emerged from apache snprintf. See original header: @@ -118,42 +118,60 @@ * * NOTE: Evaluation of the ch argument should not have any side-effects */ -#define INS_CHAR_NR(xbuf, ch) do { \ - smart_str_appendc(xbuf, ch); \ +#define INS_CHAR_NR(unicode, xbuf, ch) do { \ + if (unicode) { \ + smart_str_append2c(xbuf, ch); \ + } else { \ + smart_str_appendc(xbuf, ch); \ + } \ } while (0) -#define INS_STRING(xbuf, s, slen) do { \ - smart_str_appendl(xbuf, s, slen); \ +#define INS_STRING(unicode, xbuf, s, slen) do { \ + if (unicode) { \ + smart_str_appendl(xbuf, s, slen); \ + } else { \ + size_t newlen, sz = 2*(slen); \ + smart_str_alloc(xbuf, (sz), 0); \ + memcpy(xbuf->c + xbuf->len, s, (sz)); \ + xbuf->len += (sz); \ + } \ } while (0) -#define INS_CHAR(xbuf, ch) \ - INS_CHAR_NR(xbuf, ch) +#define INS_CHAR(unicode, xbuf, ch) \ + INS_CHAR_NR(unicode, xbuf, ch) /* * Macro that does padding. The padding is done by printing * the character ch. */ -#define PAD(xbuf, count, ch) do { \ +#define PAD(unicode, xbuf, count, ch) do { \ if ((count) > 0) { \ - size_t newlen; \ - smart_str_alloc(xbuf, (count), 0); \ - memset(xbuf->c + xbuf->len, ch, (count)); \ - xbuf->len += (count); \ + size_t newlen, p, sz = (count); \ + if (unicode) { \ + p = sz; \ + sz <<= 1; \ + smart_str_alloc(xbuf, sz, 0); \ + while(p--) smart_str_appendc(xbuf, ch); \ + } else { \ + smart_str_alloc(xbuf, sz, 0); \ + memset(xbuf->c + xbuf->len, ch, sz); \ + } \ + xbuf->len += sz; \ } \ } while (0) #define NUM(c) (c - '0') -#define STR_TO_DEC(str, num) do { \ - num = NUM(*str++); \ - while (isdigit((int)*str)) { \ - num *= 10; \ - num += NUM(*str++); \ - if (num >= INT_MAX / 10) { \ - while (isdigit((int)*str++)); \ - break; \ - } \ - } \ +#define STR_TO_DEC(str, num) do { \ + num = NUM(*str++); \ + while (isdigit((int)*str)) { \ + num *= 10; \ + num += NUM(*str++); \ + if (num >= INT_MAX / 10) { \ + while (isdigit((int)*str++)); \ + break; \ + } \ + } \ } while (0) /* @@ -162,12 +180,13 @@ * adding '0's to the left of the string that is going * to be printed. */ -#define FIX_PRECISION(adjust, precision, s, s_len) do { \ - if (adjust) \ - while (s_len < precision) { \ - *--s = '0'; \ - s_len++; \ - } \ +#define FIX_PRECISION(adjust, precision, s, s_len) \ + do { \ + if (adjust) \ + while (s_len < precision) { \ + *--s = '0'; \ + s_len++; \ + } \ } while (0) @@ -175,12 +194,12 @@ /* * Do format conversion placing the output in buffer */ -static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) +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 *q; - int s_len; + int s_len, s_unicode; int32_t u_len; register int min_width = 0; @@ -214,7 +233,7 @@ while (*fmt) { if (*fmt != '%') { - INS_CHAR(xbuf, *fmt); + INS_CHAR(unicode, xbuf, *fmt); } else { /* * Default variable settings @@ -224,6 +243,7 @@ pad_char = ' '; prefix_char = NUL; free_s = 0; + s_unicode = 0; fmt++; @@ -556,13 +576,20 @@ } u_len = u_strlen(u); - zend_convert_from_unicode(conv, &res, &s_len, u, u_len, &status); - if (U_FAILURE(status)) { - php_error(E_WARNING, "Could not convert Unicode to printable form in s[np]printf call"); - return; + if (unicode) { + s_len = u_len; /* UTODO actually we think of 2bytes each atm */ + s = (char*)u; + s_unicode = 1; + } else { + zend_convert_from_unicode(conv, &res, &s_len, u, u_len, &status); + if (U_FAILURE(status)) { + php_error(E_WARNING, "Could not convert Unicode to printable form in s[np]printf call"); + return; + } + s = res; + free_s = 1; } - s = res; - free_s = 1; + pad_char = ' '; break; } @@ -747,23 +774,24 @@ *--s = prefix_char; s_len++; } - if (adjust_width && adjust == RIGHT && min_width > s_len) { + if (adjust_width && adjust == RIGHT && min_width > u_len) { if (pad_char == '0' && prefix_char != NUL) { - INS_CHAR(xbuf, *s); + INS_CHAR(unicode, xbuf, *s); s++; s_len--; min_width--; } - PAD(xbuf, min_width - s_len, pad_char); + PAD(unicode, xbuf, min_width - s_len, pad_char); } /* * Print the string s. */ - INS_STRING(xbuf, s, s_len); + INS_STRING(s_unicode, xbuf, s, s_len); if (free_s) efree(s); - if (adjust_width && adjust == LEFT && min_width > s_len) - PAD(xbuf, min_width - s_len, pad_char); + if (adjust_width && adjust == LEFT && min_width > s_len) { + PAD(unicode, xbuf, min_width - s_len, pad_char); + } } fmt++; } @@ -778,7 +806,7 @@ { smart_str xbuf = {0}; - xbuf_format_converter(&xbuf, format, ap); + xbuf_format_converter(0, &xbuf, format, ap); if (max_len && xbuf.len > max_len) { xbuf.len = max_len; @@ -802,6 +830,34 @@ return (cc); } +PHPAPI int vuspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) +{ + smart_str xbuf = {0}; + + xbuf_format_converter(1, &xbuf, format, ap); + + if (max_len && xbuf.len > max_len) { + xbuf.len = max_len; + } + smart_str_0(&xbuf); + + *pbuf = xbuf.c; + + return xbuf.len; +} + + +PHPAPI int uspprintf(char **pbuf, size_t max_len, const char *format, ...) +{ + int cc; + va_list ap; + + va_start(ap, format); + cc = vuspprintf(pbuf, max_len, format, ap); + va_end(ap); + return (cc); +} + /* * Local variables: * tab-width: 4 http://cvs.php.net/diff.php/php-src/main/spprintf.h?r1=1.12&r2=1.13&ty=u Index: php-src/main/spprintf.h diff -u php-src/main/spprintf.h:1.12 php-src/main/spprintf.h:1.13 --- php-src/main/spprintf.h:1.12 Thu Aug 11 19:36:06 2005 +++ php-src/main/spprintf.h Sun Aug 14 13:14:42 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spprintf.h,v 1.12 2005/08/11 23:36:06 andrei Exp $ */ +/* $Id: spprintf.h,v 1.13 2005/08/14 17:14:42 helly Exp $ */ /* @@ -38,8 +38,9 @@ BEGIN_EXTERN_C() PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...); - PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap); +PHPAPI int uspprintf( char **pbuf, size_t max_len, const char *format, ...); +PHPAPI int vuspprintf(char **pbuf, size_t max_len, const char *format, va_list ap); END_EXTERN_C() #endif /* SNPRINTF_H */
http://cvs.php.net/diff.php/php-src/ext/standard/php_smart_str.h?r1=1.30&r2=1.31&ty=u Index: php-src/ext/standard/php_smart_str.h diff -u php-src/ext/standard/php_smart_str.h:1.30 php-src/ext/standard/php_smart_str.h:1.31 --- php-src/ext/standard/php_smart_str.h:1.30 Wed Aug 3 10:08:11 2005 +++ php-src/ext/standard/php_smart_str.h Sun Aug 14 13:14:40 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_smart_str.h,v 1.30 2005/08/03 14:08:11 sniper Exp $ */ +/* $Id: php_smart_str.h,v 1.31 2005/08/14 17:14:40 helly Exp $ */ #ifndef PHP_SMART_STR_H #define PHP_SMART_STR_H @@ -78,8 +78,16 @@ #define smart_str_appends(dest, src) \ smart_str_appendl((dest), (src), strlen(src)) +/* normall character appending */ #define smart_str_appendc(dest, c) \ smart_str_appendc_ex((dest), (c), 0) + +/* appending of a single UTF-16 code unit (2 byte)*/ +#define smart_str_append2c(dest, c) while (0) { \ + smart_str_appendc_ex((dest), (c&0xFF), 0); \ + smart_str_appendc_ex((dest), (c&0xFF00 ? c>>8 : '\0'), 0); \ +} + #define smart_str_free(s) \ smart_str_free_ex((s), 0) #define smart_str_appendl(dest, src, len) \ http://cvs.php.net/diff.php/php-src/main/spprintf.c?r1=1.26&r2=1.27&ty=u Index: php-src/main/spprintf.c diff -u php-src/main/spprintf.c:1.26 php-src/main/spprintf.c:1.27 --- php-src/main/spprintf.c:1.26 Thu Aug 11 19:36:06 2005 +++ php-src/main/spprintf.c Sun Aug 14 13:14:42 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spprintf.c,v 1.26 2005/08/11 23:36:06 andrei Exp $ */ +/* $Id: spprintf.c,v 1.27 2005/08/14 17:14:42 helly Exp $ */ /* This is the spprintf implementation. * It has emerged from apache snprintf. See original header: @@ -118,42 +118,60 @@ * * NOTE: Evaluation of the ch argument should not have any side-effects */ -#define INS_CHAR_NR(xbuf, ch) do { \ - smart_str_appendc(xbuf, ch); \ +#define INS_CHAR_NR(unicode, xbuf, ch) do { \ + if (unicode) { \ + smart_str_append2c(xbuf, ch); \ + } else { \ + smart_str_appendc(xbuf, ch); \ + } \ } while (0) -#define INS_STRING(xbuf, s, slen) do { \ - smart_str_appendl(xbuf, s, slen); \ +#define INS_STRING(unicode, xbuf, s, slen) do { \ + if (unicode) { \ + smart_str_appendl(xbuf, s, slen); \ + } else { \ + size_t newlen, sz = 2*(slen); \ + smart_str_alloc(xbuf, (sz), 0); \ + memcpy(xbuf->c + xbuf->len, s, (sz)); \ + xbuf->len += (sz); \ + } \ } while (0) -#define INS_CHAR(xbuf, ch) \ - INS_CHAR_NR(xbuf, ch) +#define INS_CHAR(unicode, xbuf, ch) \ + INS_CHAR_NR(unicode, xbuf, ch) /* * Macro that does padding. The padding is done by printing * the character ch. */ -#define PAD(xbuf, count, ch) do { \ +#define PAD(unicode, xbuf, count, ch) do { \ if ((count) > 0) { \ - size_t newlen; \ - smart_str_alloc(xbuf, (count), 0); \ - memset(xbuf->c + xbuf->len, ch, (count)); \ - xbuf->len += (count); \ + size_t newlen, p, sz = (count); \ + if (unicode) { \ + p = sz; \ + sz <<= 1; \ + smart_str_alloc(xbuf, sz, 0); \ + while(p--) smart_str_appendc(xbuf, ch); \ + } else { \ + smart_str_alloc(xbuf, sz, 0); \ + memset(xbuf->c + xbuf->len, ch, sz); \ + } \ + xbuf->len += sz; \ } \ } while (0) #define NUM(c) (c - '0') -#define STR_TO_DEC(str, num) do { \ - num = NUM(*str++); \ - while (isdigit((int)*str)) { \ - num *= 10; \ - num += NUM(*str++); \ - if (num >= INT_MAX / 10) { \ - while (isdigit((int)*str++)); \ - break; \ - } \ - } \ +#define STR_TO_DEC(str, num) do { \ + num = NUM(*str++); \ + while (isdigit((int)*str)) { \ + num *= 10; \ + num += NUM(*str++); \ + if (num >= INT_MAX / 10) { \ + while (isdigit((int)*str++)); \ + break; \ + } \ + } \ } while (0) /* @@ -162,12 +180,13 @@ * adding '0's to the left of the string that is going * to be printed. */ -#define FIX_PRECISION(adjust, precision, s, s_len) do { \ - if (adjust) \ - while (s_len < precision) { \ - *--s = '0'; \ - s_len++; \ - } \ +#define FIX_PRECISION(adjust, precision, s, s_len) \ + do { \ + if (adjust) \ + while (s_len < precision) { \ + *--s = '0'; \ + s_len++; \ + } \ } while (0) @@ -175,12 +194,12 @@ /* * Do format conversion placing the output in buffer */ -static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) +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 *q; - int s_len; + int s_len, s_unicode; int32_t u_len; register int min_width = 0; @@ -214,7 +233,7 @@ while (*fmt) { if (*fmt != '%') { - INS_CHAR(xbuf, *fmt); + INS_CHAR(unicode, xbuf, *fmt); } else { /* * Default variable settings @@ -224,6 +243,7 @@ pad_char = ' '; prefix_char = NUL; free_s = 0; + s_unicode = 0; fmt++; @@ -556,13 +576,20 @@ } u_len = u_strlen(u); - zend_convert_from_unicode(conv, &res, &s_len, u, u_len, &status); - if (U_FAILURE(status)) { - php_error(E_WARNING, "Could not convert Unicode to printable form in s[np]printf call"); - return; + if (unicode) { + s_len = u_len; /* UTODO actually we think of 2bytes each atm */ + s = (char*)u; + s_unicode = 1; + } else { + zend_convert_from_unicode(conv, &res, &s_len, u, u_len, &status); + if (U_FAILURE(status)) { + php_error(E_WARNING, "Could not convert Unicode to printable form in s[np]printf call"); + return; + } + s = res; + free_s = 1; } - s = res; - free_s = 1; + pad_char = ' '; break; } @@ -747,23 +774,24 @@ *--s = prefix_char; s_len++; } - if (adjust_width && adjust == RIGHT && min_width > s_len) { + if (adjust_width && adjust == RIGHT && min_width > u_len) { if (pad_char == '0' && prefix_char != NUL) { - INS_CHAR(xbuf, *s); + INS_CHAR(unicode, xbuf, *s); s++; s_len--; min_width--; } - PAD(xbuf, min_width - s_len, pad_char); + PAD(unicode, xbuf, min_width - s_len, pad_char); } /* * Print the string s. */ - INS_STRING(xbuf, s, s_len); + INS_STRING(s_unicode, xbuf, s, s_len); if (free_s) efree(s); - if (adjust_width && adjust == LEFT && min_width > s_len) - PAD(xbuf, min_width - s_len, pad_char); + if (adjust_width && adjust == LEFT && min_width > s_len) { + PAD(unicode, xbuf, min_width - s_len, pad_char); + } } fmt++; } @@ -778,7 +806,7 @@ { smart_str xbuf = {0}; - xbuf_format_converter(&xbuf, format, ap); + xbuf_format_converter(0, &xbuf, format, ap); if (max_len && xbuf.len > max_len) { xbuf.len = max_len; @@ -802,6 +830,34 @@ return (cc); } +PHPAPI int vuspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) +{ + smart_str xbuf = {0}; + + xbuf_format_converter(1, &xbuf, format, ap); + + if (max_len && xbuf.len > max_len) { + xbuf.len = max_len; + } + smart_str_0(&xbuf); + + *pbuf = xbuf.c; + + return xbuf.len; +} + + +PHPAPI int uspprintf(char **pbuf, size_t max_len, const char *format, ...) +{ + int cc; + va_list ap; + + va_start(ap, format); + cc = vuspprintf(pbuf, max_len, format, ap); + va_end(ap); + return (cc); +} + /* * Local variables: * tab-width: 4 http://cvs.php.net/diff.php/php-src/main/spprintf.h?r1=1.12&r2=1.13&ty=u Index: php-src/main/spprintf.h diff -u php-src/main/spprintf.h:1.12 php-src/main/spprintf.h:1.13 --- php-src/main/spprintf.h:1.12 Thu Aug 11 19:36:06 2005 +++ php-src/main/spprintf.h Sun Aug 14 13:14:42 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spprintf.h,v 1.12 2005/08/11 23:36:06 andrei Exp $ */ +/* $Id: spprintf.h,v 1.13 2005/08/14 17:14:42 helly Exp $ */ /* @@ -38,8 +38,9 @@ BEGIN_EXTERN_C() PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...); - PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap); +PHPAPI int uspprintf( char **pbuf, size_t max_len, const char *format, ...); +PHPAPI int vuspprintf(char **pbuf, size_t max_len, const char *format, va_list ap); END_EXTERN_C() #endif /* SNPRINTF_H */