Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add println(string $data = ''): int #6639

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ext/standard/basic_functions.stub.php
Expand Up @@ -966,6 +966,7 @@ function fprintf($stream, string $format, mixed ...$values): int {}
/** @param resource $stream */
function vfprintf($stream, string $format, array $values): int {}

function println(string $data = ''): int {}
/* fsock.c */

/**
Expand Down
8 changes: 7 additions & 1 deletion ext/standard/basic_functions_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 97edf8c87780c892984099e52ad1c6c745b919f8 */
* Stub hash: 0909e41211d2c51032e107c7829979dff46a6944 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
Expand Down Expand Up @@ -1489,6 +1489,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vfprintf, 0, 3, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_println, 0, 0, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data, IS_STRING, 0, "\'\'")
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_fsockopen, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 0, "-1")
Expand Down Expand Up @@ -2621,6 +2625,7 @@ ZEND_FUNCTION(vprintf);
ZEND_FUNCTION(vsprintf);
ZEND_FUNCTION(fprintf);
ZEND_FUNCTION(vfprintf);
ZEND_FUNCTION(println);
ZEND_FUNCTION(fsockopen);
ZEND_FUNCTION(pfsockopen);
ZEND_FUNCTION(http_build_query);
Expand Down Expand Up @@ -3261,6 +3266,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(vsprintf, arginfo_vsprintf)
ZEND_FE(fprintf, arginfo_fprintf)
ZEND_FE(vfprintf, arginfo_vfprintf)
ZEND_FE(println, arginfo_println)
ZEND_FE(fsockopen, arginfo_fsockopen)
ZEND_FE(pfsockopen, arginfo_pfsockopen)
ZEND_FE(http_build_query, arginfo_http_build_query)
Expand Down
23 changes: 23 additions & 0 deletions ext/standard/formatted_print.c
Expand Up @@ -919,3 +919,26 @@ PHP_FUNCTION(vfprintf)
zend_string_efree(result);
}
/* }}} */

/* {{{ Output a string followed by a unix newline */
PHP_FUNCTION(println)
{
char* input = NULL;
size_t input_len = 0;

ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_STRING(input, input_len)
ZEND_PARSE_PARAMETERS_END();

if (input_len > 0) {
size_t rlen = PHPWRITE(input, input_len);
if (UNEXPECTED(rlen != input_len)) {
RETURN_LONG(rlen);
}
rlen += PHPWRITE("\n", 1);
RETURN_LONG(rlen);
}
RETURN_LONG(PHPWRITE("\n", 1));
}
/* }}} */
42 changes: 42 additions & 0 deletions ext/standard/tests/general_functions/formatted_print1.phpt
@@ -0,0 +1,42 @@
--TEST--
println() function with strict_types=0
--FILE--
<?php

// Normally, you would never bother checking the number of bytes returned,
// but this is a unit test of the function itself.
$v1 = println('');
$v2 = println('println always adds a newline');
println("the above string was $v2 bytes including the newline, the below appends \\n to \\n");
$v3 = println("\n");
$v4 = println('strict_types=0 allows string coercion the exact same way as any other function');
$v5 = println(1);
$v6 = println(true);
$v7 = println(); // the default argument is the empty string
println('println byte lengths');
println(json_encode([$v1, $v2, $v3, $v4, $v5, $v6, $v7]));
try {
println([]);
} catch (TypeError $e) {
echo "Caught TypeError {$e->getMessage()}\n";
}
try {
println('test', 'too many');
} catch (ArgumentCountError $e) {
echo "Caught ArgumentCountError {$e->getMessage()}\n";
}

?>
--EXPECT--
println always adds a newline
the above string was 30 bytes including the newline, the below appends \n to \n


strict_types=0 allows string coercion the exact same way as any other function
1
1

println byte lengths
[1,30,2,79,2,2,1]
Caught TypeError println(): Argument #1 ($data) must be of type string, array given
Caught ArgumentCountError println() expects at most 1 argument, 2 given
28 changes: 28 additions & 0 deletions ext/standard/tests/general_functions/formatted_print2.phpt
@@ -0,0 +1,28 @@
--TEST--
println() function with strict_types=1 throws for non-string
--FILE--
<?php

declare(strict_types=1);

$v1 = println('println always adds a newline');
println("wrote $v1 bytes");
try {
println(1);
} catch (TypeError $e) {
println("Caught: " . $e->getMessage());
}
println(); // valid
try {
println(null);
} catch (TypeError $e) {
println("Caught: " . $e->getMessage());
}

?>
--EXPECT--
println always adds a newline
wrote 30 bytes
Caught: println(): Argument #1 ($data) must be of type string, int given

Caught: println(): Argument #1 ($data) must be of type string, null given