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