mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Implement fprintf() and vfprintf().
Add a couple of tests.
This commit is contained in:
parent
32eb31719a
commit
59e4fdcc10
4 changed files with 117 additions and 30 deletions
|
@ -387,6 +387,8 @@ function_entry basic_functions[] = {
|
||||||
PHP_NAMED_FE(printf, PHP_FN(user_printf), NULL)
|
PHP_NAMED_FE(printf, PHP_FN(user_printf), NULL)
|
||||||
PHP_FE(vprintf, NULL)
|
PHP_FE(vprintf, NULL)
|
||||||
PHP_FE(vsprintf, NULL)
|
PHP_FE(vsprintf, NULL)
|
||||||
|
PHP_FE(fprintf, NULL)
|
||||||
|
PHP_FE(vfprintf, NULL)
|
||||||
PHP_FE(sscanf, third_and_rest_force_ref)
|
PHP_FE(sscanf, third_and_rest_force_ref)
|
||||||
PHP_FE(fscanf, third_and_rest_force_ref)
|
PHP_FE(fscanf, third_and_rest_force_ref)
|
||||||
PHP_FE(parse_url, NULL)
|
PHP_FE(parse_url, NULL)
|
||||||
|
|
|
@ -83,6 +83,8 @@ PHP_FUNCTION(set_include_path);
|
||||||
PHP_FUNCTION(restore_include_path);
|
PHP_FUNCTION(restore_include_path);
|
||||||
|
|
||||||
PHP_FUNCTION(print_r);
|
PHP_FUNCTION(print_r);
|
||||||
|
PHP_FUNCTION(fprintf);
|
||||||
|
PHP_FUNCTION(vfprintf);
|
||||||
|
|
||||||
PHP_FUNCTION(connection_aborted);
|
PHP_FUNCTION(connection_aborted);
|
||||||
PHP_FUNCTION(connection_status);
|
PHP_FUNCTION(connection_status);
|
||||||
|
|
|
@ -452,9 +452,9 @@ php_sprintf_getnumber(char *buffer, int *pos)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
php_formatted_print(int ht, int *len, int use_array TSRMLS_DC)
|
php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC)
|
||||||
{
|
{
|
||||||
zval ***args, **z_format, **array;
|
zval ***args, **z_format;
|
||||||
int argc, size = 240, inpos = 0, outpos = 0, temppos;
|
int argc, size = 240, inpos = 0, outpos = 0, temppos;
|
||||||
int alignment, width, precision, currarg, adjusting, argnum;
|
int alignment, width, precision, currarg, adjusting, argnum;
|
||||||
char *format, *result, padding;
|
char *format, *result, padding;
|
||||||
|
@ -462,39 +462,49 @@ php_formatted_print(int ht, int *len, int use_array TSRMLS_DC)
|
||||||
|
|
||||||
argc = ZEND_NUM_ARGS();
|
argc = ZEND_NUM_ARGS();
|
||||||
|
|
||||||
if (use_array) {
|
/* verify the number of args */
|
||||||
int i = 1;
|
if ((use_array && argc != (2 + format_offset))
|
||||||
|
|| (!use_array && argc < (1 + format_offset))) {
|
||||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(argc, &z_format, &array) == FAILURE) {
|
|
||||||
WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
|
WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
|
||||||
}
|
}
|
||||||
SEPARATE_ZVAL(array);
|
|
||||||
convert_to_array_ex(array);
|
|
||||||
argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array));
|
|
||||||
args = (zval ***)emalloc(argc * sizeof(zval *));
|
|
||||||
args[0] = z_format;
|
|
||||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array));
|
|
||||||
zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&args[i++]) == SUCCESS;
|
|
||||||
zend_hash_move_forward(Z_ARRVAL_PP(array)));
|
|
||||||
} else {
|
|
||||||
if (argc < 1) {
|
|
||||||
WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
args = (zval ***)emalloc(argc * sizeof(zval *));
|
args = (zval ***)emalloc(argc * sizeof(zval *));
|
||||||
|
|
||||||
if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
|
if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
|
||||||
efree(args);
|
efree(args);
|
||||||
WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
|
WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_array) {
|
||||||
|
int i = 1;
|
||||||
|
zval ***newargs;
|
||||||
|
zval **array;
|
||||||
|
|
||||||
|
z_format = args[format_offset];
|
||||||
|
array = args[1 + format_offset];
|
||||||
|
|
||||||
|
SEPARATE_ZVAL(array);
|
||||||
|
convert_to_array_ex(array);
|
||||||
|
|
||||||
|
argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array));
|
||||||
|
newargs = (zval ***)emalloc(argc * sizeof(zval *));
|
||||||
|
newargs[0] = z_format;
|
||||||
|
|
||||||
|
for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array));
|
||||||
|
zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&newargs[i++]) == SUCCESS;
|
||||||
|
zend_hash_move_forward(Z_ARRVAL_PP(array)));
|
||||||
|
|
||||||
|
efree(args);
|
||||||
|
args = newargs;
|
||||||
|
format_offset = 0;
|
||||||
}
|
}
|
||||||
convert_to_string_ex(args[0]);
|
|
||||||
format = Z_STRVAL_PP(args[0]);
|
convert_to_string_ex(args[format_offset]);
|
||||||
|
format = Z_STRVAL_PP(args[format_offset]);
|
||||||
result = emalloc(size);
|
result = emalloc(size);
|
||||||
|
|
||||||
currarg = 1;
|
currarg = 1;
|
||||||
|
|
||||||
while (inpos<Z_STRLEN_PP(args[0])) {
|
while (inpos<Z_STRLEN_PP(args[format_offset])) {
|
||||||
int expprec = 0;
|
int expprec = 0;
|
||||||
|
|
||||||
PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos]));
|
PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos]));
|
||||||
|
@ -538,6 +548,9 @@ php_formatted_print(int ht, int *len, int use_array TSRMLS_DC)
|
||||||
} else {
|
} else {
|
||||||
argnum = currarg++;
|
argnum = currarg++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argnum += format_offset;
|
||||||
|
|
||||||
if (argnum >= argc) {
|
if (argnum >= argc) {
|
||||||
efree(result);
|
efree(result);
|
||||||
efree(args);
|
efree(args);
|
||||||
|
@ -596,7 +609,7 @@ php_formatted_print(int ht, int *len, int use_array TSRMLS_DC)
|
||||||
PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
|
PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
|
||||||
} else {
|
} else {
|
||||||
width = precision = 0;
|
width = precision = 0;
|
||||||
argnum = currarg++;
|
argnum = currarg++ + format_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format[inpos] == 'l') {
|
if (format[inpos] == 'l') {
|
||||||
|
@ -708,11 +721,10 @@ PHP_FUNCTION(user_sprintf)
|
||||||
char *result;
|
char *result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if ((result=php_formatted_print(ht, &len, 0 TSRMLS_CC))==NULL) {
|
if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
RETVAL_STRINGL(result, len, 1);
|
RETVAL_STRINGL(result, len, 0);
|
||||||
efree(result);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -723,11 +735,10 @@ PHP_FUNCTION(vsprintf)
|
||||||
char *result;
|
char *result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if ((result=php_formatted_print(ht, &len, 1 TSRMLS_CC))==NULL) {
|
if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
RETVAL_STRINGL(result, len, 1);
|
RETVAL_STRINGL(result, len, 0);
|
||||||
efree(result);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -738,7 +749,7 @@ PHP_FUNCTION(user_printf)
|
||||||
char *result;
|
char *result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if ((result=php_formatted_print(ht, &len, 0 TSRMLS_CC))==NULL) {
|
if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
PHPWRITE(result, len);
|
PHPWRITE(result, len);
|
||||||
|
@ -753,7 +764,7 @@ PHP_FUNCTION(vprintf)
|
||||||
char *result;
|
char *result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if ((result=php_formatted_print(ht, &len, 1 TSRMLS_CC))==NULL) {
|
if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
PHPWRITE(result, len);
|
PHPWRITE(result, len);
|
||||||
|
@ -761,6 +772,68 @@ PHP_FUNCTION(vprintf)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ proto int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])
|
||||||
|
Output a formatted string into a stream */
|
||||||
|
PHP_FUNCTION(fprintf)
|
||||||
|
{
|
||||||
|
php_stream *stream;
|
||||||
|
zval **arg1;
|
||||||
|
char *result;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (ZEND_NUM_ARGS() < 2) {
|
||||||
|
WRONG_PARAM_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zend_get_parameters_ex(1, &arg1)==FAILURE) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
php_stream_from_zval(stream, arg1);
|
||||||
|
|
||||||
|
if ((result=php_formatted_print(ht, &len, 0, 1 TSRMLS_CC))==NULL) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
php_stream_write(stream, result, len);
|
||||||
|
|
||||||
|
efree(result);
|
||||||
|
|
||||||
|
RETVAL_LONG(len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* {{{ proto int vfprintf(resource stream, string format, array args)
|
||||||
|
Output a formatted string into a stream */
|
||||||
|
PHP_FUNCTION(vfprintf)
|
||||||
|
{
|
||||||
|
php_stream *stream;
|
||||||
|
zval **arg1;
|
||||||
|
char *result;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (ZEND_NUM_ARGS() != 3) {
|
||||||
|
WRONG_PARAM_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zend_get_parameters_ex(1, &arg1)==FAILURE) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
php_stream_from_zval(stream, arg1);
|
||||||
|
|
||||||
|
if ((result=php_formatted_print(ht, &len, 1, 1 TSRMLS_CC))==NULL) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
php_stream_write(stream, result, len);
|
||||||
|
|
||||||
|
efree(result);
|
||||||
|
|
||||||
|
RETVAL_LONG(len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* tab-width: 4
|
* tab-width: 4
|
||||||
|
|
|
@ -39,6 +39,13 @@ printf("printf test 27:%3\$d %d %d\n", 1, 2, 3);
|
||||||
printf("printf test 28:%2\$02d %1\$2d\n", 1, 2);
|
printf("printf test 28:%2\$02d %1\$2d\n", 1, 2);
|
||||||
printf("printf test 29:%2\$-2d %1\$2d\n", 1, 2);
|
printf("printf test 29:%2\$-2d %1\$2d\n", 1, 2);
|
||||||
print("printf test 30:"); printf("%0\$s", 1); print("x\n");
|
print("printf test 30:"); printf("%0\$s", 1); print("x\n");
|
||||||
|
vprintf("vprintf test 1:%2\$-2d %1\$2d\n", array(1, 2));
|
||||||
|
|
||||||
|
$fp = fopen("php://stdout", "w") or die("Arrggsgg!!");
|
||||||
|
$x = fprintf($fp, "fprintf test 1:%.5s\n", "abcdefghij");
|
||||||
|
var_dump($x);
|
||||||
|
fclose($fp);
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
|
@ -74,3 +81,6 @@ printf test 27:3 1 2
|
||||||
printf test 28:02 1
|
printf test 28:02 1
|
||||||
printf test 29:2 1
|
printf test 29:2 1
|
||||||
printf test 30:x
|
printf test 30:x
|
||||||
|
vprintf test 1:2 1
|
||||||
|
fprintf test 1:abcde
|
||||||
|
int(20)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue