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