From c4cd2a0b9f251ed830ef32ac6537e62ae5e3d944 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 6 Dec 2019 15:16:15 -0800 Subject: [PATCH] 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. --- admin/merge-gnulib | 2 +- lib/_Noreturn.h | 9 ++- lib/gnulib.mk.in | 1 + lib/nstrftime.c | 138 +++++++++++++++++++------------------------- m4/gnulib-common.m4 | 11 +++- m4/timer_time.m4 | 8 +-- 6 files changed, 82 insertions(+), 87 deletions(-) diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 5192916abd0..04ba624856a 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -50,7 +50,7 @@ GNULIB_MODULES=' AVOIDED_MODULES=' btowc close dup fchdir fstat langinfo lock malloc-posix mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo - openat-die opendir raise + openat-die opendir pthread-h raise save-cwd select setenv sigprocmask stat stdarg stdbool threadlib tzset unsetenv utime utime-h wchar wcrtomb wctype-h diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h index db9b45554c5..7570f828883 100644 --- a/lib/_Noreturn.h +++ b/lib/_Noreturn.h @@ -17,7 +17,14 @@ #ifndef _Noreturn # if (defined __cplusplus \ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ - || (defined _MSC_VER && 1900 <= _MSC_VER))) + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + AIX system header files and several gnulib header files use precisely + this syntax with 'extern'. */ # define _Noreturn [[noreturn]] # elif ((!defined __cplusplus || defined __clang__) \ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 8e3b569b94f..4d5798b06e3 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -51,6 +51,7 @@ # --avoid=nl_langinfo \ # --avoid=openat-die \ # --avoid=opendir \ +# --avoid=pthread-h \ # --avoid=raise \ # --avoid=save-cwd \ # --avoid=select \ 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'): diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 479c9de9eab..d8f0d3fb566 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,4 +1,4 @@ -# gnulib-common.m4 serial 45 +# gnulib-common.m4 serial 46 dnl Copyright (C) 2007-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,7 +19,14 @@ AC_DEFUN([gl_COMMON_BODY], [ #ifndef _Noreturn # if (defined __cplusplus \ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ - || (defined _MSC_VER && 1900 <= _MSC_VER))) + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + AIX system header files and several gnulib header files use precisely + this syntax with 'extern'. */ # define _Noreturn [[noreturn]] # elif ((!defined __cplusplus || defined __clang__) \ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ diff --git a/m4/timer_time.m4 b/m4/timer_time.m4 index 2c9b93c63b8..347d04dbe45 100644 --- a/m4/timer_time.m4 +++ b/m4/timer_time.m4 @@ -1,4 +1,4 @@ -# timer_time.m4 serial 3 +# timer_time.m4 serial 4 dnl Copyright (C) 2011-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -16,7 +16,7 @@ AC_DEFUN([gl_TIMER_TIME], dnl Some packages like Emacs use --avoid=threadlib. dnl Write the symbol in such a way that it does not cause 'aclocal' to pick dnl the threadlib.m4 file that is installed in $PREFIX/share/aclocal/. - m4_ifdef([gl_][THREADLIB], [AC_REQUIRE([gl_][THREADLIB])]) + m4_ifdef([gl_][PTHREADLIB], [AC_REQUIRE([gl_][PTHREADLIB])]) LIB_TIMER_TIME= AC_SUBST([LIB_TIMER_TIME]) @@ -24,7 +24,7 @@ AC_DEFUN([gl_TIMER_TIME], AC_SEARCH_LIBS([timer_settime], [rt posix4], [test "$ac_cv_search_timer_settime" = "none required" || LIB_TIMER_TIME=$ac_cv_search_timer_settime]) - m4_ifdef([gl_][THREADLIB], + m4_ifdef([gl_][PTHREADLIB], [dnl GLIBC uses threads to emulate posix timers when kernel support dnl is not available (like Linux < 2.6 or when used with kFreeBSD) dnl Now the pthread lib is linked automatically in the normal case, @@ -38,7 +38,7 @@ AC_DEFUN([gl_TIMER_TIME], #endif #endif ], - [LIB_TIMER_TIME="$LIB_TIMER_TIME $LIBMULTITHREAD"])]) + [LIB_TIMER_TIME="$LIB_TIMER_TIME $LIBPMULTITHREAD"])]) AC_CHECK_FUNCS([timer_settime]) LIBS=$gl_saved_libs ]) -- 2.39.2