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 */
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php