ZEND_API void (*zend_ticks_function)(int ticks TSRMLS_DC);
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
+zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
zend_ticks_function = utility_functions->ticks_function;
zend_on_timeout = utility_functions->on_timeout;
zend_vspprintf = utility_functions->vspprintf_function;
+ zend_vstrpprintf = utility_functions->vstrpprintf_function;
zend_getenv = utility_functions->getenv_function;
zend_resolve_path = utility_functions->resolve_path_function;
void (*on_timeout)(int seconds TSRMLS_DC);
int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
+ zend_string *(*vstrpprintf_function)(size_t max_len, const char *format, va_list ap);
char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
char *(*resolve_path_function)(const char *filename, int filename_len TSRMLS_DC);
} zend_utility_functions;
extern ZEND_API void (*zend_on_timeout)(int seconds TSRMLS_DC);
extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
+extern zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
array_init(&val);
for (i = 0; i < closure->func.common.num_args; i++) {
- char *name, *info;
- int name_len, info_len;
+ zend_string *name;
+ zval info;
if (arg_info->name) {
- name_len = zend_spprintf(&name, 0, "%s$%s",
- arg_info->pass_by_reference ? "&" : "",
- arg_info->name);
+ name = zend_strpprintf(0, "%s$%s",
+ arg_info->pass_by_reference ? "&" : "",
+ arg_info->name);
} else {
- name_len = zend_spprintf(&name, 0, "%s$param%d",
- arg_info->pass_by_reference ? "&" : "",
- i + 1);
+ name = zend_strpprintf(0, "%s$param%d",
+ arg_info->pass_by_reference ? "&" : "",
+ i + 1);
}
- info_len = zend_spprintf(&info, 0, "%s",
- i >= required ? "<optional>" : "<required>");
- // TODO: avoid reallocation ???
- add_assoc_stringl_ex(&val, name, name_len, info, info_len);
- efree(info);
- efree(name);
+ ZVAL_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
+ zend_hash_update(Z_ARRVAL(val), name, &info);
+ STR_RELEASE(name);
arg_info++;
}
zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val);
previous = zend_read_property(default_exception_ce, getThis(), "previous", sizeof("previous")-1, 1 TSRMLS_CC);
RETURN_ZVAL(previous, 1, 0);
-}
+} /* }}} */
int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
{
}
/* }}} */
+zend_string *zend_strpprintf(int max_len, const char *format, ...) /* {{{ */
+{
+ va_list arg;
+ zend_string *str;
+
+ va_start(arg, format);
+ str = zend_vstrpprintf(max_len, format, arg);
+ va_end(arg);
+ return str;
+}
+/* }}} */
+
/* {{{ proto string Exception::__toString()
Obtain the string representation of the Exception object */
ZEND_METHOD(exception, __toString)
{
zval message, file, line, trace, *exception;
- char *str, *prev_str;
- int len = 0;
+ zend_string *str, *prev_str;
zend_fcall_info fci;
zval fname;
DEFAULT_0_PARAMS;
- str = estrndup("", 0);
+ str = STR_EMPTY_ALLOC();
exception = getThis();
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1);
}
if (Z_STRLEN(message) > 0) {
- len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
- Z_OBJCE_P(exception)->name->val, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
- (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
- len ? "\n\nNext " : "", prev_str);
+ str = zend_strpprintf(0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
+ Z_OBJCE_P(exception)->name->val, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
+ (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
+ prev_str->len ? "\n\nNext " : "", prev_str->val);
} else {
- len = zend_spprintf(&str, 0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
- Z_OBJCE_P(exception)->name->val, Z_STRVAL(file), Z_LVAL(line),
- (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
- len ? "\n\nNext " : "", prev_str);
+ str = zend_strpprintf(0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
+ Z_OBJCE_P(exception)->name->val, Z_STRVAL(file), Z_LVAL(line),
+ (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
+ prev_str->len ? "\n\nNext " : "", prev_str->val);
}
- efree(prev_str);
+ STR_RELEASE(prev_str);
zval_dtor(&message);
zval_dtor(&file);
zval_dtor(&line);
/* We store the result in the private property string so we can access
* the result in uncaught exception handlers without memleaks. */
- zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
+ zend_update_property_str(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
- // TODO: avoid reallocation ???
- RETVAL_STRINGL(str, len);
- efree(str);
+ RETURN_STR(str);
}
/* }}} */
/* do not export, in php it's available thru spprintf directly */
int zend_spprintf(char **message, int max_len, const char *format, ...);
+zend_string *zend_strpprintf(int max_len, const char *format, ...);
END_EXTERN_C()
break;
}
case IS_DOUBLE: {
- char *str;
- int len;
+ zend_string *str;
double dval = Z_DVAL_P(op);
TSRMLS_FETCH();
- len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), dval);
+ str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);
/* %G already handles removing trailing zeros from the fractional part, yay */
- ZVAL_NEW_STR(op, STR_INIT(str, len, 0));
- efree(str);
+ ZVAL_NEW_STR(op, str);
break;
}
case IS_ARRAY:
return STR_INIT(buf, len, 0);
}
case IS_DOUBLE: {
- char *str;
- int len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
- zend_string *retval = STR_INIT(str, len, 0);
- efree(str);
- return retval;
+ return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
}
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
{
TSRMLS_FETCH();
- char *str;
- int len;
+ zend_string *str;
- len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
- ZVAL_NEW_STR(op, STR_INIT(str, len, 0));
- efree(str);
+ str = zend_strpprintf(0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
+ ZVAL_NEW_STR(op, str);
}
/* }}} */
zuf.on_timeout = php_on_timeout;
zuf.stream_open_function = php_stream_open_for_zend;
zuf.vspprintf_function = vspprintf;
+ zuf.vstrpprintf_function = vstrpprintf;
zuf.getenv_function = sapi_getenv;
zuf.resolve_path_function = php_resolve_path_for_zend;
zend_startup(&zuf, NULL TSRMLS_CC);
xbuf_format_converter(&xbuf, format, ap);
- if (max_len && xbuf.s->len > max_len) {
+ if (max_len && xbuf.s && xbuf.s->len > max_len) {
xbuf.s->len = max_len;
}
smart_str_0(&xbuf);
}
/* }}} */
+PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */
+{
+ smart_str xbuf = {0};
+
+ xbuf_format_converter(&xbuf, format, ap);
+
+ if (max_len && xbuf.s && xbuf.s->len > max_len) {
+ xbuf.s->len = max_len;
+ }
+ smart_str_0(&xbuf);
+
+ return xbuf.s;
+}
+/* }}} */
+
+PHPAPI zend_string *strpprintf(size_t max_len, const char *format, ...) /* {{{ */
+{
+ va_list ap;
+ zend_string *str;
+
+ va_start(ap, format);
+ str = vstrpprintf(max_len, format, ap);
+ va_end(ap);
+ return str;
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) PHP_ATTRIBUTE_FORMAT(printf, 3, 0);
+
+PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap);
+
+PHPAPI zend_string *strpprintf(size_t max_len, const char *format, ...);
END_EXTERN_C()
#endif /* SNPRINTF_H */