Skip to content

Commit 89d4388

Browse files
committed
Implement GMP::__construct
1 parent ca4eb3b commit 89d4388

File tree

4 files changed

+99
-9
lines changed

4 files changed

+99
-9
lines changed

ext/gmp/gmp.c

+50-8
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,27 @@ static inline void _gmp_unary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_opl_t
862862
}
863863
/* }}} */
864864

865+
static bool gmp_verify_base(zend_long base)
866+
{
867+
if (base && (base < 2 || base > GMP_MAX_BASE)) {
868+
zend_argument_value_error(2, "must be between 2 and %d", GMP_MAX_BASE);
869+
return false;
870+
}
871+
872+
return true;
873+
}
874+
875+
static int gmp_initialize_number(mpz_ptr gmp_number, const zend_string *arg_str, zend_long arg_l, zend_long base)
876+
{
877+
if (arg_str) {
878+
return convert_zstr_to_gmp(gmp_number, arg_str, base, 1);
879+
} else {
880+
mpz_set_si(gmp_number, arg_l);
881+
}
882+
883+
return SUCCESS;
884+
}
885+
865886
/* {{{ Initializes GMP number */
866887
ZEND_FUNCTION(gmp_init)
867888
{
@@ -876,18 +897,14 @@ ZEND_FUNCTION(gmp_init)
876897
Z_PARAM_LONG(base)
877898
ZEND_PARSE_PARAMETERS_END();
878899

879-
if (base && (base < 2 || base > GMP_MAX_BASE)) {
880-
zend_argument_value_error(2, "must be between 2 and %d", GMP_MAX_BASE);
900+
if (!gmp_verify_base(base)) {
881901
RETURN_THROWS();
882902
}
883903

884904
INIT_GMP_RETVAL(gmp_number);
885-
if (arg_str) {
886-
if (convert_zstr_to_gmp(gmp_number, arg_str, base, 1) == FAILURE) {
887-
RETURN_THROWS();
888-
}
889-
} else {
890-
mpz_set_si(gmp_number, arg_l);
905+
906+
if (gmp_initialize_number(gmp_number, arg_str, arg_l, base) == FAILURE) {
907+
RETURN_THROWS();
891908
}
892909
}
893910
/* }}} */
@@ -2021,6 +2038,31 @@ ZEND_FUNCTION(gmp_scan1)
20212038
}
20222039
/* }}} */
20232040

2041+
ZEND_METHOD(GMP, __construct)
2042+
{
2043+
zend_string *arg_str = NULL;
2044+
zend_long arg_l = 0;
2045+
zend_long base = 0;
2046+
2047+
ZEND_PARSE_PARAMETERS_START(0, 2)
2048+
Z_PARAM_OPTIONAL
2049+
Z_PARAM_STR_OR_LONG(arg_str, arg_l)
2050+
Z_PARAM_OPTIONAL
2051+
Z_PARAM_LONG(base)
2052+
ZEND_PARSE_PARAMETERS_END();
2053+
2054+
if (!gmp_verify_base(base)) {
2055+
RETURN_THROWS();
2056+
}
2057+
2058+
return_value = ZEND_THIS;
2059+
mpz_ptr gmp_number = GET_GMP_FROM_ZVAL(ZEND_THIS);
2060+
2061+
if (gmp_initialize_number(gmp_number, arg_str, arg_l, base) == FAILURE) {
2062+
RETURN_THROWS();
2063+
}
2064+
}
2065+
20242066
ZEND_METHOD(GMP, __serialize)
20252067
{
20262068
ZEND_PARSE_PARAMETERS_NONE();

ext/gmp/gmp.stub.php

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959

6060
class GMP
6161
{
62+
public function __construct(int|string $num = 0, int $base = 0) {}
63+
6264
public function __serialize(): array {}
6365

6466
public function __unserialize(array $data): void {}

ext/gmp/gmp_arginfo.h

+8-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/gmp/tests/construct.phpt

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Constructor for GMP
3+
--EXTENSIONS--
4+
gmp
5+
--FILE--
6+
<?php
7+
var_dump(new GMP);
8+
var_dump(new GMP(0));
9+
var_dump(new GMP(123));
10+
var_dump(new GMP("0xAA"));
11+
var_dump(new GMP("12", 4));
12+
try {
13+
var_dump(new GMP("12", 999));
14+
} catch (ValueError $e) {
15+
echo $e->getMessage() . "\n";
16+
}
17+
?>
18+
--EXPECT--
19+
object(GMP)#1 (1) {
20+
["num"]=>
21+
string(1) "0"
22+
}
23+
object(GMP)#1 (1) {
24+
["num"]=>
25+
string(1) "0"
26+
}
27+
object(GMP)#1 (1) {
28+
["num"]=>
29+
string(3) "123"
30+
}
31+
object(GMP)#1 (1) {
32+
["num"]=>
33+
string(3) "170"
34+
}
35+
object(GMP)#1 (1) {
36+
["num"]=>
37+
string(1) "6"
38+
}
39+
GMP::__construct(): Argument #2 ($base) must be between 2 and 62

0 commit comments

Comments
 (0)