diff options
| author | Paul Eggert | 2017-12-07 18:07:54 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-12-07 18:08:56 -0800 |
| commit | 47423f0603f2ecfb78352be5477fb02c44f1fd35 (patch) | |
| tree | 78c40843566e2464c5d84dd12d4057d064b768e3 | |
| parent | d4db37b283daffa0f8c942a5b526b6444edc34c5 (diff) | |
| download | emacs-47423f0603f2ecfb78352be5477fb02c44f1fd35.tar.gz emacs-47423f0603f2ecfb78352be5477fb02c44f1fd35.zip | |
Fix zero-padding bug with (format "%#08x" n)
Problem reported by Gustaf Waldemarson (Bug#29609).
* src/editfns.c (styled_format):
Put zero padding after a leading "0x", not before.
* test/src/editfns-tests.el (format-sharp-0-x): New test.
| -rw-r--r-- | src/editfns.c | 24 | ||||
| -rw-r--r-- | test/src/editfns-tests.el | 6 |
2 files changed, 22 insertions, 8 deletions
diff --git a/src/editfns.c b/src/editfns.c index e671ba0761c..ebf6518994b 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -4722,11 +4722,19 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4722 | char src0 = src[0]; | 4722 | char src0 = src[0]; |
| 4723 | int exponent_bytes = 0; | 4723 | int exponent_bytes = 0; |
| 4724 | bool signedp = src0 == '-' || src0 == '+' || src0 == ' '; | 4724 | bool signedp = src0 == '-' || src0 == '+' || src0 == ' '; |
| 4725 | unsigned char after_sign = src[signedp]; | 4725 | int prefix_bytes = (signedp |
| 4726 | if (zero_flag && 0 <= char_hexdigit (after_sign)) | 4726 | + ((src[signedp] == '0' |
| 4727 | && (src[signedp + 1] == 'x' | ||
| 4728 | || src[signedp + 1] == 'X')) | ||
| 4729 | ? 2 : 0)); | ||
| 4730 | if (zero_flag) | ||
| 4727 | { | 4731 | { |
| 4728 | leading_zeros += padding; | 4732 | unsigned char after_prefix = src[prefix_bytes]; |
| 4729 | padding = 0; | 4733 | if (0 <= char_hexdigit (after_prefix)) |
| 4734 | { | ||
| 4735 | leading_zeros += padding; | ||
| 4736 | padding = 0; | ||
| 4737 | } | ||
| 4730 | } | 4738 | } |
| 4731 | 4739 | ||
| 4732 | if (excess_precision | 4740 | if (excess_precision |
| @@ -4745,13 +4753,13 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4745 | nchars += padding; | 4753 | nchars += padding; |
| 4746 | } | 4754 | } |
| 4747 | 4755 | ||
| 4748 | *p = src0; | 4756 | memcpy (p, src, prefix_bytes); |
| 4749 | src += signedp; | 4757 | p += prefix_bytes; |
| 4750 | p += signedp; | 4758 | src += prefix_bytes; |
| 4751 | memset (p, '0', leading_zeros); | 4759 | memset (p, '0', leading_zeros); |
| 4752 | p += leading_zeros; | 4760 | p += leading_zeros; |
| 4753 | int significand_bytes | 4761 | int significand_bytes |
| 4754 | = sprintf_bytes - signedp - exponent_bytes; | 4762 | = sprintf_bytes - prefix_bytes - exponent_bytes; |
| 4755 | memcpy (p, src, significand_bytes); | 4763 | memcpy (p, src, significand_bytes); |
| 4756 | p += significand_bytes; | 4764 | p += significand_bytes; |
| 4757 | src += significand_bytes; | 4765 | src += significand_bytes; |
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index 70dc9372fad..283a642dd97 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el | |||
| @@ -136,6 +136,12 @@ | |||
| 136 | (ert-deftest format-c-float () | 136 | (ert-deftest format-c-float () |
| 137 | (should-error (format "%c" 0.5))) | 137 | (should-error (format "%c" 0.5))) |
| 138 | 138 | ||
| 139 | ;;; Test for Bug#29609. | ||
| 140 | (ert-deftest format-sharp-0-x () | ||
| 141 | (should (string-equal (format "%#08x" #x10) "0x000010")) | ||
| 142 | (should (string-equal (format "%#05X" #x10) "0X010")) | ||
| 143 | (should (string-equal (format "%#04x" 0) "0000"))) | ||
| 144 | |||
| 139 | ;;; Check format-time-string with various TZ settings. | 145 | ;;; Check format-time-string with various TZ settings. |
| 140 | ;;; Use only POSIX-compatible TZ values, since the tests should work | 146 | ;;; Use only POSIX-compatible TZ values, since the tests should work |
| 141 | ;;; even if tzdb is not in use. | 147 | ;;; even if tzdb is not in use. |