diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2019-12-06 15:16:15 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2019-12-06 15:17:08 -0800 |
commit | c4cd2a0b9f251ed830ef32ac6537e62ae5e3d944 (patch) | |
tree | 25aec8ec7432bae87fd6b38f06a6d191d96151c4 /lib/nstrftime.c | |
parent | 99ad65eda44e3b6edcc51cf0fb70ea499c3ccb07 (diff) | |
download | emacs-c4cd2a0b9f251ed830ef32ac6537e62ae5e3d944.tar.gz |
Update from Gnulib
This incorporates:
2019-12-06 nstrftime: better width support for %N, %z
2019-12-03 Avoid hassles caused by [[noreturn]] in C++
2019-12-02 Fix mistakes in --enable-threads=isoc fixes from 2019-12-01
* admin/merge-gnulib (AVOIDED_MODULES): Avoid pthread-h.
* lib/_Noreturn.h, lib/nstrftime.c, m4/gnulib-common.m4:
* m4/timer_time.m4:
Copy from Gnulib.
* lib/gnulib.mk.in: Regenerate.
Diffstat (limited to 'lib/nstrftime.c')
-rw-r--r-- | lib/nstrftime.c | 138 |
1 files changed, 59 insertions, 79 deletions
diff --git a/lib/nstrftime.c b/lib/nstrftime.c index 461dadb2929..4eae1dc4ebb 100644 --- a/lib/nstrftime.c +++ b/lib/nstrftime.c @@ -162,19 +162,20 @@ extern char *tzname[]; # define advance(P, N) ((P) += (N)) #endif -#define add(n, f) \ +#define add(n, f) width_add (width, n, f) +#define width_add(width, n, f) \ do \ { \ size_t _n = (n); \ - size_t _w = (width < 0 ? 0 : width); \ + size_t _w = pad == L_('-') || width < 0 ? 0 : width; \ size_t _incr = _n < _w ? _w : _n; \ if (_incr >= maxsize - i) \ return 0; \ if (p) \ { \ - if (digits == 0 && _n < _w) \ + if (_n < _w) \ { \ - size_t _delta = width - _n; \ + size_t _delta = _w - _n; \ if (pad == L_('0') || pad == L_('+')) \ memset_zero (p, _delta); \ else \ @@ -186,15 +187,17 @@ extern char *tzname[]; i += _incr; \ } while (0) +#define add1(c) width_add1 (width, c) #if FPRINTFTIME -# define add1(C) add (1, fputc (C, p)) +# define width_add1(width, c) width_add (width, 1, fputc (c, p)) #else -# define add1(C) add (1, *p = C) +# define width_add1(width, c) width_add (width, 1, *p = c) #endif +#define cpy(n, s) width_cpy (width, n, s) #if FPRINTFTIME -# define cpy(n, s) \ - add ((n), \ +# define width_cpy(width, n, s) \ + width_add (width, n, \ do \ { \ if (to_lowcase) \ @@ -214,8 +217,8 @@ extern char *tzname[]; while (0) \ ) #else -# define cpy(n, s) \ - add ((n), \ +# define width_cpy(width, n, s) \ + width_add (width, n, \ if (to_lowcase) \ memcpy_lowcase (p, (s), _n LOCALE_ARG); \ else if (to_uppcase) \ @@ -435,9 +438,10 @@ my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) libc_hidden_def (my_strftime) #endif -/* Just like my_strftime, above, but with two more parameters. - UPCASE indicate that the result should be converted to upper case, - and *TZSET_CALLED indicates whether tzset has been called here. */ +/* Just like my_strftime, above, but with more parameters. + UPCASE indicates that the result should be converted to upper case. + YR_SPEC and WIDTH specify the padding and width for the year. + *TZSET_CALLED indicates whether tzset has been called here. */ static size_t __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) const CHAR_T *format, @@ -556,7 +560,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) for (f = format; *f != '\0'; width = -1, f++) { - int pad = 0; /* Padding for number ('-', '_', or 0). */ + int pad = 0; /* Padding for number ('_', '-', '+', '0', or 0). */ int modifier; /* Field modifier ('E', 'O', or 0). */ int digits = 0; /* Max digits for numeric format. */ int number_value; /* Numeric value to be printed. */ @@ -565,7 +569,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) bool always_output_a_sign; /* +/- should always be output. */ int tz_colon_mask; /* Bitmask of where ':' should appear. */ const CHAR_T *subfmt; - CHAR_T sign_char; CHAR_T *bufp; CHAR_T buf[1 + 2 /* for the two colons in a %::z or %:::z time zone */ @@ -1035,59 +1038,34 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) while (u_number_value != 0 || tz_colon_mask != 0); do_number_sign_and_padding: - if (digits < width) - digits = width; - - sign_char = (negative_number ? L_('-') - : always_output_a_sign ? L_('+') - : 0); - - if (pad == L_('-')) - { - if (sign_char) - add1 (sign_char); - } - else - { - int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0])) - - bufp) - !!sign_char; - - if (padding > 0) - { - if (pad == L_('_')) - { - if ((size_t) padding >= maxsize - i) - return 0; - - if (p) - memset_space (p, padding); - i += padding; - width = width > padding ? width - padding : 0; - if (sign_char) - add1 (sign_char); - } - else - { - if ((size_t) digits >= maxsize - i) - return 0; - - if (sign_char) - add1 (sign_char); + if (pad == 0) + pad = L_('0'); + if (width < 0) + width = digits; - if (p) - memset_zero (p, padding); - i += padding; - width = 0; - } - } - else - { - if (sign_char) - add1 (sign_char); - } - } + { + CHAR_T sign_char = (negative_number ? L_('-') + : always_output_a_sign ? L_('+') + : 0); + int numlen = buf + sizeof buf / sizeof buf[0] - bufp; + int shortage = width - !!sign_char - numlen; + int padding = pad == L_('-') || shortage <= 0 ? 0 : shortage; + + if (sign_char) + { + if (pad == L_('_')) + { + if (p) + memset_space (p, padding); + i += padding; + width -= padding; + } + width_add1 (0, sign_char); + width--; + } - cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp); + cpy (numlen, bufp); + } break; case L_('F'): @@ -1153,19 +1131,21 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) case L_('N'): /* GNU extension. */ if (modifier == L_('E')) goto bad_format; - - number_value = ns; - if (width == -1) - width = 9; - else - { - /* Take an explicit width less than 9 as a precision. */ - int j; - for (j = width; j < 9; j++) - number_value /= 10; - } - - DO_NUMBER (width, number_value); + { + int n = ns, ns_digits = 9; + if (width <= 0) + width = ns_digits; + int ndigs = ns_digits; + while (width < ndigs || (1 < ndigs && n % 10 == 0)) + ndigs--, n /= 10; + for (int i = ndigs; 0 < i; i--) + buf[i - 1] = n % 10 + L_('0'), n /= 10; + if (!pad) + pad = L_('0'); + width_cpy (0, ndigs, buf); + width_add (width - ndigs, 0, (void) 0); + } + break; #endif case L_('n'): |