mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Added vstrpprintf strpprintf to avoid duplicate string
(the function name maybe improvement)
This commit is contained in:
parent
e2890e3a0f
commit
88c550a799
@ -55,6 +55,7 @@ ZEND_API void (*zend_unblock_interruptions)(void);
|
||||
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);
|
||||
|
||||
@ -676,6 +677,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
|
||||
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;
|
||||
|
||||
|
@ -522,6 +522,7 @@ typedef struct _zend_utility_functions {
|
||||
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;
|
||||
@ -632,6 +633,7 @@ extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, cons
|
||||
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);
|
||||
|
||||
|
@ -313,23 +313,20 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
|
||||
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);
|
||||
|
@ -618,7 +618,7 @@ ZEND_METHOD(exception, getPrevious)
|
||||
|
||||
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, ...) /* {{{ */
|
||||
{
|
||||
@ -632,19 +632,30 @@ 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);
|
||||
@ -677,17 +688,17 @@ ZEND_METHOD(exception, __toString)
|
||||
}
|
||||
|
||||
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);
|
||||
@ -701,11 +712,9 @@ ZEND_METHOD(exception, __toString)
|
||||
|
||||
/* 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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -54,6 +54,7 @@ ZEND_API void zend_exception_error(zend_object *exception, int severity TSRMLS_D
|
||||
|
||||
/* 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()
|
||||
|
||||
|
@ -621,15 +621,13 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
|
||||
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:
|
||||
@ -910,11 +908,7 @@ try_again:
|
||||
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");
|
||||
@ -2529,12 +2523,10 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /
|
||||
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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -2095,6 +2095,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
|
||||
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);
|
||||
|
@ -799,7 +799,7 @@ PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap
|
||||
|
||||
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);
|
||||
@ -829,6 +829,33 @@ PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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
|
||||
|
@ -40,6 +40,10 @@ BEGIN_EXTERN_C()
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user