37#define LCONV_DECIMAL_POINT (*lconv.decimal_point)
39#define LCONV_DECIMAL_POINT (*lconv->decimal_point)
62static char * __cvt(
double value,
int ndigit,
int *decpt,
bool *
sign,
int fmode,
int pad)
78 if ((rve =
s = (
char *)malloc(ndigit?siz:2)) ==
NULL) {
93 return strdup((c ==
'I' ?
"INF" :
"NAN"));
99 if ((
s = (
char *)malloc(siz+1)) ==
NULL) {
121static inline char *php_ecvt(
double value,
int ndigit,
int *decpt,
bool *
sign)
123 return(__cvt(
value, ndigit, decpt,
sign, 0, 1));
127static inline char *php_fcvt(
double value,
int ndigit,
int *decpt,
bool *
sign)
129 return(__cvt(
value, ndigit, decpt,
sign, 1, 1));
191#define INT_NULL ((int *)0)
193#define S_NULL "(null)"
196#define FLOAT_DIGITS 6
197#define EXPONENT_LENGTH 10
214 bool * is_negative,
char *buf_end,
size_t *
len)
220 magnitude = (uint64_t) num;
221 *is_negative =
false;
223 *is_negative = (num < 0);
236 magnitude = ((uint64_t) - t) + 1;
238 magnitude = (uint64_t) num;
246 uint64_t new_magnitude = magnitude / 10;
248 *--
p = (char)(magnitude - new_magnitude * 10 +
'0');
249 magnitude = new_magnitude;
272 bool add_dp,
int precision,
char dec_point,
bool * is_negative,
char *
buf,
size_t *
len)
278 if (precision >=
NDIG - 1) {
279 precision =
NDIG - 2;
283 p_orig =
p = php_fcvt(num, precision, &decimal_point, is_negative);
285 p_orig =
p = php_ecvt(num, precision + 1, &decimal_point, is_negative);
291 if (isalpha((
int)*
p)) {
294 *is_negative =
false;
299 if (decimal_point <= 0) {
300 if (num != 0 || precision > 0) {
304 while (decimal_point++ < 0) {
312 int addz = decimal_point >=
NDIG ? decimal_point -
NDIG + 1 : 0;
313 decimal_point -= addz;
314 while (decimal_point-- > 0) {
320 if (precision > 0 || add_dp) {
326 if (precision > 0 || add_dp) {
341 bool exponent_is_negative;
345 if (decimal_point != 0) {
347 *
s++ = exponent_is_negative ?
'-' :
'+';
378 int mask = (1 << nbits) - 1;
380 static const char low_digits[] =
"0123456789abcdef";
381 static const char upper_digits[] =
"0123456789ABCDEF";
382 const char *digits = (format ==
'X') ? upper_digits : low_digits;
385 *--
p = digits[num & mask];
403#define NUM_BUF_SIZE 2048
426#define INS_CHAR(c, sp, bep, cc) \
435#define NUM( c ) ( c - '0' )
437#define STR_TO_DEC( str, num ) \
438 num = NUM( *str++ ) ; \
439 while ( isdigit((int)*str ) ) \
442 num += NUM( *str++ ) ; \
451#define FIX_PRECISION( adjust, precision, s, s_len ) \
453 while ( s_len < (size_t)precision ) \
463#define PAD( width, len, ch ) do \
465 INS_CHAR( ch, sp, bep, cc ) ; \
468 while ( (size_t)width > len )
473static size_t format_converter(
buffy * odp,
const char *fmt, va_list ap)
492 int64_t i_num = (int64_t) 0;
501 struct lconv *lconv =
NULL;
511 bool adjust_precision;
527 alternate_form = print_sign = print_blank =
false;
536 if (isascii((
int)*fmt) && !islower((
int)*fmt)) {
543 else if (*fmt ==
'+')
545 else if (*fmt ==
'#')
546 alternate_form =
true;
547 else if (*fmt ==
' ')
549 else if (*fmt ==
'0')
558 if (isdigit((
int)*fmt)) {
561 }
else if (*fmt ==
'*') {
562 min_width = va_arg(ap,
int);
567 min_width = -min_width;
570 adjust_width =
false;
576 adjust_precision =
true;
578 if (isdigit((
int)*fmt)) {
580 }
else if (*fmt ==
'*') {
581 precision = va_arg(ap,
int);
588 adjust_precision =
false;
590 adjust_precision = adjust_width =
false;
605 modifier = LM_LONG_LONG;
617 modifier = LM_INTMAX_T;
625 modifier = LM_PTRDIFF_T;
632 char __next = *(fmt+1);
633 if (
'd' == __next ||
'u' == __next ||
'x' == __next ||
'o' == __next) {
635 "printf \"p\" modifier is no longer supported, use ZEND_LONG_FMT");
666 zend_string *str = zval_get_tmp_string(zvp, &tmp_str);
669 if (adjust_precision && (
size_t)precision < s_len) {
677 i_num = (int64_t) va_arg(ap,
unsigned int);
682 i_num = (int64_t) va_arg(ap,
unsigned long int);
685 i_num = (int64_t) va_arg(ap,
size_t);
689 i_num = (int64_t) va_arg(ap,
unsigned long long int);
694 i_num = (int64_t) va_arg(ap, uintmax_t);
716 i_num = (int64_t) va_arg(ap,
int);
721 i_num = (int64_t) va_arg(ap,
long int);
725 i_num = (int64_t) va_arg(ap, ssize_t);
727 i_num = (int64_t) va_arg(ap,
size_t);
732 i_num = (int64_t) va_arg(ap,
long long int);
737 i_num = (int64_t) va_arg(ap, intmax_t);
754 }
else if (print_sign) {
756 }
else if (print_blank) {
766 ui_num = (uint64_t) va_arg(ap,
unsigned int);
771 ui_num = (uint64_t) va_arg(ap,
unsigned long int);
774 ui_num = (uint64_t) va_arg(ap,
size_t);
778 ui_num = (uint64_t) va_arg(ap,
unsigned long long int);
783 ui_num = (uint64_t) va_arg(ap, uintmax_t);
788 ui_num = (uint64_t) va_arg(ap,
ptrdiff_t);
794 if (alternate_form && *
s !=
'0') {
805 ui_num = (uint64_t) va_arg(ap,
unsigned int);
810 ui_num = (uint64_t) va_arg(ap,
unsigned long int);
813 ui_num = (uint64_t) va_arg(ap,
size_t);
817 ui_num = (uint64_t) va_arg(ap,
unsigned long long int);
822 ui_num = (uint64_t) va_arg(ap, uintmax_t);
827 ui_num = (uint64_t) va_arg(ap,
ptrdiff_t);
833 if (alternate_form && i_num != 0) {
842 s = va_arg(ap,
char *);
845 if (adjust_precision && (
size_t)precision < s_len) {
862 fp_num = (double) va_arg(ap,
long double);
865 fp_num = va_arg(ap,
double);
885 s =
php_conv_fp((*fmt ==
'f')?
'F':*fmt, fp_num, alternate_form,
888 &is_negative, &num_buf[1], &s_len);
893 else if (print_blank)
905 fp_num = (double) va_arg(ap,
long double);
908 fp_num = va_arg(ap,
double);
929 if (adjust_precision ==
false) {
931 }
else if (precision == 0) {
947 }
else if (print_sign) {
949 }
else if (print_blank) {
962 char_buf[0] = (char) (va_arg(ap,
int));
978 *(va_arg(ap,
int *)) = cc;
990 if (
sizeof(
char *) <=
sizeof(uint64_t)) {
991 ui_num = (uint64_t)((
size_t) va_arg(ap,
char *));
1016 php_error(
E_ERROR,
"Illegal length modifier specified '%c' in s[np]printf call", *fmt);
1037 if (prefix_char !=
NUL) {
1041 if (adjust_width && adjust == RIGHT && (
size_t)min_width > s_len) {
1042 if (pad_char ==
'0' && prefix_char !=
NUL) {
1048 PAD(min_width, s_len, pad_char);
1053 for (i = s_len; i != 0; i--) {
1058 if (adjust_width && adjust == LEFT && (
size_t)min_width > s_len)
1059 PAD(min_width, s_len, pad_char);
1060 zend_tmp_string_release(tmp_str);
1073static size_t strx_printv(
char *
buf,
size_t len,
const char *format, va_list ap)
1085 od.
nextb = (
char *) ~0;
1094 cc = format_converter(&od, format, ap);
1107 va_start(ap, format);
1108 cc = strx_printv(
buf,
len, format, ap);
1120 size_t cc = strx_printv(
buf,
len, format, ap);
1134 va_start(ap, format);
1135 cc = strx_printv(
buf,
len, format, ap);
1143 size_t cc = strx_printv(
buf,
len, format, ap);
1160 if ((*
buf = malloc(++cc)) !=
NULL) {
1177 va_start(ap, format);
strchr(string $haystack, string $needle, bool $before_needle=false)
zend_ffi_ctype_name_buf buf
PHPAPI struct lconv * localeconv_r(struct lconv *out)
PHPAPI int ap_php_snprintf(char *buf, size_t len, const char *format,...)
#define STR_TO_DEC(str, num)
PHPAPI int ap_php_slprintf(char *buf, size_t len, const char *format,...)
#define LCONV_DECIMAL_POINT
PHPAPI int ap_php_asprintf(char **buf, const char *format,...)
#define INS_CHAR(c, sp, bep, cc)
PHPAPI int ap_php_vsnprintf(char *buf, size_t len, const char *format, va_list ap)
#define PAD(width, len, ch)
#define FIX_PRECISION(adjust, precision, s, s_len)
PHPAPI char * php_conv_fp(char format, double num, bool add_dp, int precision, char dec_point, bool *is_negative, char *buf, size_t *len)
PHPAPI int ap_php_vasprintf(char **buf, const char *format, va_list ap)
PHPAPI char * ap_php_conv_p2(uint64_t num, int nbits, char format, char *buf_end, size_t *len)
PHPAPI int ap_php_vslprintf(char *buf, size_t len, const char *format, va_list ap)
PHPAPI char * ap_php_conv_10(int64_t num, bool is_unsigned, bool *is_negative, char *buf_end, size_t *len)
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
struct _zend_string zend_string
ZEND_API void zend_freedtoa(char *s)
ZEND_API char * zend_dtoa(double dd, int mode, int ndigits, int *decpt, bool *sign, char **rve)
ZEND_API char * zend_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf)