Skip to content

Commit 9931f43

Browse files
committed
Implement GMP::__construct
1 parent ca4eb3b commit 9931f43

File tree

4 files changed

+109
-9
lines changed

4 files changed

+109
-9
lines changed

ext/gmp/gmp.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,26 @@ 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, uint32_t arg_num)
866+
{
867+
if (base && (base < 2 || base > GMP_MAX_BASE)) {
868+
zend_argument_value_error(arg_num, "must be between 2 and %d", GMP_MAX_BASE);
869+
return false;
870+
}
871+
872+
return true;
873+
}
874+
875+
static zend_result 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+
}
880+
881+
mpz_set_si(gmp_number, arg_l);
882+
return SUCCESS;
883+
}
884+
865885
/* {{{ Initializes GMP number */
866886
ZEND_FUNCTION(gmp_init)
867887
{
@@ -876,18 +896,14 @@ ZEND_FUNCTION(gmp_init)
876896
Z_PARAM_LONG(base)
877897
ZEND_PARSE_PARAMETERS_END();
878898

879-
if (base && (base < 2 || base > GMP_MAX_BASE)) {
880-
zend_argument_value_error(2, "must be between 2 and %d", GMP_MAX_BASE);
899+
if (!gmp_verify_base(base, 2)) {
881900
RETURN_THROWS();
882901
}
883902

884903
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);
904+
905+
if (gmp_initialize_number(gmp_number, arg_str, arg_l, base) == FAILURE) {
906+
RETURN_THROWS();
891907
}
892908
}
893909
/* }}} */
@@ -2021,6 +2037,30 @@ ZEND_FUNCTION(gmp_scan1)
20212037
}
20222038
/* }}} */
20232039

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

ext/gmp/gmp.stub.php

Lines changed: 2 additions & 0 deletions
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

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/gmp/tests/construct.phpt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
try {
18+
var_dump(new GMP("", 10));
19+
} catch (ValueError $e) {
20+
echo $e->getMessage() . "\n";
21+
}
22+
try {
23+
var_dump(new GMP("hello"));
24+
} catch (ValueError $e) {
25+
echo $e->getMessage() . "\n";
26+
}
27+
?>
28+
--EXPECT--
29+
object(GMP)#1 (1) {
30+
["num"]=>
31+
string(1) "0"
32+
}
33+
object(GMP)#1 (1) {
34+
["num"]=>
35+
string(1) "0"
36+
}
37+
object(GMP)#1 (1) {
38+
["num"]=>
39+
string(3) "123"
40+
}
41+
object(GMP)#1 (1) {
42+
["num"]=>
43+
string(3) "170"
44+
}
45+
object(GMP)#1 (1) {
46+
["num"]=>
47+
string(1) "6"
48+
}
49+
GMP::__construct(): Argument #2 ($base) must be between 2 and 62
50+
GMP::__construct(): Argument #1 ($num) is not an integer string
51+
GMP::__construct(): Argument #1 ($num) is not an integer string

0 commit comments

Comments
 (0)