@@ -577,6 +577,36 @@ ZEND_MODULE_INFO_D(gmp)
577
577
}
578
578
/* }}} */
579
579
580
+ static zend_result convert_zstr_to_gmp (mpz_t gmp_number , const zend_string * val , zend_long base , uint32_t arg_pos )
581
+ {
582
+ const char * num_str = ZSTR_VAL (val );
583
+ bool skip_lead = false;
584
+
585
+ if (ZSTR_LEN (val ) >= 2 && num_str [0 ] == '0' ) {
586
+ if ((base == 0 || base == 16 ) && (num_str [1 ] == 'x' || num_str [1 ] == 'X' )) {
587
+ base = 16 ;
588
+ skip_lead = true;
589
+ } else if ((base == 0 || base == 8 ) && (num_str [1 ] == 'o' || num_str [1 ] == 'O' )) {
590
+ base = 8 ;
591
+ skip_lead = true;
592
+ } else if ((base == 0 || base == 2 ) && (num_str [1 ] == 'b' || num_str [1 ] == 'B' )) {
593
+ base = 2 ;
594
+ skip_lead = true;
595
+ }
596
+ }
597
+
598
+ int gmp_ret = mpz_set_str (gmp_number , (skip_lead ? & num_str [2 ] : num_str ), (int ) base );
599
+ if (-1 == gmp_ret ) {
600
+ if (arg_pos == 0 ) {
601
+ zend_value_error ("Number is not an integer string" );
602
+ } else {
603
+ zend_argument_value_error (arg_pos , "is not an integer string" );
604
+ }
605
+ return FAILURE ;
606
+ }
607
+
608
+ return SUCCESS ;
609
+ }
580
610
581
611
/* {{{ convert_to_gmp
582
612
* Convert zval to be gmp number */
@@ -587,34 +617,7 @@ static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, ui
587
617
mpz_set_si (gmpnumber , Z_LVAL_P (val ));
588
618
return SUCCESS ;
589
619
case IS_STRING : {
590
- char * numstr = Z_STRVAL_P (val );
591
- bool skip_lead = 0 ;
592
- int ret ;
593
-
594
- if (Z_STRLEN_P (val ) >= 2 && numstr [0 ] == '0' ) {
595
- if ((base == 0 || base == 16 ) && (numstr [1 ] == 'x' || numstr [1 ] == 'X' )) {
596
- base = 16 ;
597
- skip_lead = 1 ;
598
- } else if ((base == 0 || base == 8 ) && (numstr [1 ] == 'o' || numstr [1 ] == 'O' )) {
599
- base = 8 ;
600
- skip_lead = 1 ;
601
- } else if ((base == 0 || base == 2 ) && (numstr [1 ] == 'b' || numstr [1 ] == 'B' )) {
602
- base = 2 ;
603
- skip_lead = 1 ;
604
- }
605
- }
606
-
607
- ret = mpz_set_str (gmpnumber , (skip_lead ? & numstr [2 ] : numstr ), (int ) base );
608
- if (-1 == ret ) {
609
- if (arg_pos == 0 ) {
610
- zend_value_error ("Number is not an integer string" );
611
- } else {
612
- zend_argument_value_error (arg_pos , "is not an integer string" );
613
- }
614
- return FAILURE ;
615
- }
616
-
617
- return SUCCESS ;
620
+ return convert_zstr_to_gmp (gmpnumber , Z_STR_P (val ), base , arg_pos );
618
621
}
619
622
default : {
620
623
zend_long lval ;
@@ -862,22 +865,29 @@ static inline void _gmp_unary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_opl_t
862
865
/* {{{ Initializes GMP number */
863
866
ZEND_FUNCTION (gmp_init )
864
867
{
865
- zval * number_arg ;
866
- mpz_ptr gmpnumber ;
868
+ mpz_ptr gmp_number ;
869
+ zend_string * arg_str = NULL ;
870
+ zend_long arg_l = 0 ;
867
871
zend_long base = 0 ;
868
872
869
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "z|l" , & number_arg , & base ) == FAILURE ) {
870
- RETURN_THROWS ();
871
- }
873
+ ZEND_PARSE_PARAMETERS_START (1 , 2 )
874
+ Z_PARAM_STR_OR_LONG (arg_str , arg_l )
875
+ Z_PARAM_OPTIONAL
876
+ Z_PARAM_LONG (base )
877
+ ZEND_PARSE_PARAMETERS_END ();
872
878
873
879
if (base && (base < 2 || base > GMP_MAX_BASE )) {
874
880
zend_argument_value_error (2 , "must be between 2 and %d" , GMP_MAX_BASE );
875
881
RETURN_THROWS ();
876
882
}
877
883
878
- INIT_GMP_RETVAL (gmpnumber );
879
- if (convert_to_gmp (gmpnumber , number_arg , base , 1 ) == FAILURE ) {
880
- RETURN_THROWS ();
884
+ 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 );
881
891
}
882
892
}
883
893
/* }}} */
0 commit comments