aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/editfns.c96
1 files changed, 41 insertions, 55 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 96bb271b2d6..3a34dd0980b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4563,32 +4563,30 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4563 and with pM inserted for integer formats. 4563 and with pM inserted for integer formats.
4564 At most two flags F can be specified at once. */ 4564 At most two flags F can be specified at once. */
4565 char convspec[sizeof "%FF.*d" + max (INT_AS_LDBL, pMlen)]; 4565 char convspec[sizeof "%FF.*d" + max (INT_AS_LDBL, pMlen)];
4566 { 4566 char *f = convspec;
4567 char *f = convspec; 4567 *f++ = '%';
4568 *f++ = '%'; 4568 /* MINUS_FLAG and ZERO_FLAG are dealt with later. */
4569 /* MINUS_FLAG and ZERO_FLAG are dealt with later. */ 4569 *f = '+'; f += plus_flag;
4570 *f = '+'; f += plus_flag; 4570 *f = ' '; f += space_flag;
4571 *f = ' '; f += space_flag; 4571 *f = '#'; f += sharp_flag;
4572 *f = '#'; f += sharp_flag; 4572 *f++ = '.';
4573 *f++ = '.'; 4573 *f++ = '*';
4574 *f++ = '*'; 4574 if (float_conversion)
4575 if (float_conversion) 4575 {
4576 { 4576 if (INT_AS_LDBL)
4577 if (INT_AS_LDBL) 4577 {
4578 { 4578 *f = 'L';
4579 *f = 'L'; 4579 f += INTEGERP (arg);
4580 f += INTEGERP (arg); 4580 }
4581 } 4581 }
4582 } 4582 else if (conversion != 'c')
4583 else if (conversion != 'c') 4583 {
4584 { 4584 memcpy (f, pMd, pMlen);
4585 memcpy (f, pMd, pMlen); 4585 f += pMlen;
4586 f += pMlen; 4586 zero_flag &= ! precision_given;
4587 zero_flag &= ! precision_given; 4587 }
4588 } 4588 *f++ = conversion;
4589 *f++ = conversion; 4589 *f = '\0';
4590 *f = '\0';
4591 }
4592 4590
4593 int prec = -1; 4591 int prec = -1;
4594 if (precision_given) 4592 if (precision_given)
@@ -4630,29 +4628,20 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4630 } 4628 }
4631 else if (conversion == 'd' || conversion == 'i') 4629 else if (conversion == 'd' || conversion == 'i')
4632 { 4630 {
4633 /* For float, maybe we should use "%1.0f"
4634 instead so it also works for values outside
4635 the integer range. */
4636 printmax_t x;
4637 if (INTEGERP (arg)) 4631 if (INTEGERP (arg))
4638 x = XINT (arg); 4632 {
4633 printmax_t x = XINT (arg);
4634 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4635 }
4639 else 4636 else
4640 { 4637 {
4641 double d = XFLOAT_DATA (arg); 4638 strcpy (f - pMlen - 1, "f");
4642 if (d < 0) 4639 double x = XFLOAT_DATA (arg);
4643 { 4640 sprintf_bytes = sprintf (sprintf_buf, convspec, 0, x);
4644 x = TYPE_MINIMUM (printmax_t); 4641 char c0 = sprintf_buf[0];
4645 if (x < d) 4642 bool signedp = ! ('0' <= c0 && c0 <= '9');
4646 x = d; 4643 prec = min (precision, sprintf_bytes - signedp);
4647 }
4648 else
4649 {
4650 x = TYPE_MAXIMUM (printmax_t);
4651 if (d < x)
4652 x = d;
4653 }
4654 } 4644 }
4655 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4656 } 4645 }
4657 else 4646 else
4658 { 4647 {
@@ -4663,22 +4652,19 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4663 else 4652 else
4664 { 4653 {
4665 double d = XFLOAT_DATA (arg); 4654 double d = XFLOAT_DATA (arg);
4666 if (d < 0) 4655 double uprintmax = TYPE_MAXIMUM (uprintmax_t);
4667 x = 0; 4656 if (! (0 <= d && d < uprintmax + 1))
4668 else 4657 xsignal1 (Qoverflow_error, arg);
4669 { 4658 x = d;
4670 x = TYPE_MAXIMUM (uprintmax_t);
4671 if (d < x)
4672 x = d;
4673 }
4674 } 4659 }
4675 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x); 4660 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4676 } 4661 }
4677 4662
4678 /* Now the length of the formatted item is known, except it omits 4663 /* Now the length of the formatted item is known, except it omits
4679 padding and excess precision. Deal with excess precision 4664 padding and excess precision. Deal with excess precision
4680 first. This happens only when the format specifies 4665 first. This happens when the format specifies ridiculously
4681 ridiculously large precision. */ 4666 large precision, or when %d or %i formats a float that would
4667 ordinarily need fewer digits than a specified precision. */
4682 ptrdiff_t excess_precision 4668 ptrdiff_t excess_precision
4683 = precision_given ? precision - prec : 0; 4669 = precision_given ? precision - prec : 0;
4684 ptrdiff_t leading_zeros = 0, trailing_zeros = 0; 4670 ptrdiff_t leading_zeros = 0, trailing_zeros = 0;