diff options
| author | Paul Eggert | 2016-11-19 16:00:57 -0800 |
|---|---|---|
| committer | Paul Eggert | 2016-11-19 16:01:32 -0800 |
| commit | bbd84f86bce9c04ae08d9bccbad19c48e74f3f8b (patch) | |
| tree | 19d511f0e9094149fc61dfe19af992bff0cb03d8 /lib | |
| parent | 493a8f33ba916403d1fab620e08146632b826101 (diff) | |
| download | emacs-bbd84f86bce9c04ae08d9bccbad19c48e74f3f8b.tar.gz emacs-bbd84f86bce9c04ae08d9bccbad19c48e74f3f8b.zip | |
Merge from gnulib
This incorporates:
2016-11-15 sys_time: add gnulib::timeval for C++
2016-11-14 snippet/c++defs: fix real-floating arg functions in C++ mode
2016-11-13 strftime: don't use __THROW
2016-11-12 strftime: tune %q
2016-11-12 Merge strftime.c changes from glibc
2016-11-09 manywarnings: fix -Wno-missing-field-initializers detection
2016-11-05 strftime,strptime: support %q to represent the quarter
The glibc changes in turn incorporate the following strftime.c changes:
2015-10-20 Convert misc function definitions to prototype style
2015-09-26 [BZ #18985] out of range data to strftime() causes segfault
2010-01-09 Add support for XPG7 testing
2009-10-30 Implement Burmese language locale for Myanmar
2008-06-13 [BZ #6612] pass reference to tzset_called around
2007-10-16 [BZ #5184] Add tzset_called argument
* build-aux/snippet/c++defs.h, lib/strftime.c, lib/sys_time.in.h:
* m4/manywarnings.m4: Copy from gnulib.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/strftime.c | 162 | ||||
| -rw-r--r-- | lib/sys_time.in.h | 7 |
2 files changed, 105 insertions, 64 deletions
diff --git a/lib/strftime.c b/lib/strftime.c index 4e65190386d..2e010830f7a 100644 --- a/lib/strftime.c +++ b/lib/strftime.c | |||
| @@ -1,22 +1,22 @@ | |||
| 1 | /* Copyright (C) 1991-2001, 2003-2007, 2009-2016 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1991-2016 Free Software Foundation, Inc. |
| 2 | This file is part of the GNU C Library. | ||
| 2 | 3 | ||
| 3 | NOTE: The canonical source of this file is maintained with the GNU C Library. | 4 | The GNU C Library is free software; you can redistribute it and/or |
| 4 | Bugs can be reported to bug-glibc@prep.ai.mit.edu. | 5 | modify it under the terms of the GNU General Public |
| 6 | License as published by the Free Software Foundation; either | ||
| 7 | version 3 of the License, or (at your option) any later version. | ||
| 5 | 8 | ||
| 6 | This program is free software: you can redistribute it and/or modify | 9 | The GNU C Library is distributed in the hope that it will be useful, |
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | GNU General Public License for more details. | 12 | General Public License for more details. |
| 15 | 13 | ||
| 16 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public |
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 15 | License along with the GNU C Library; if not, see |
| 16 | <http://www.gnu.org/licenses/>. */ | ||
| 18 | 17 | ||
| 19 | #ifdef _LIBC | 18 | #ifdef _LIBC |
| 19 | # define USE_IN_EXTENDED_LOCALE_MODEL 1 | ||
| 20 | # define HAVE_STRUCT_ERA_ENTRY 1 | 20 | # define HAVE_STRUCT_ERA_ENTRY 1 |
| 21 | # define HAVE_TM_GMTOFF 1 | 21 | # define HAVE_TM_GMTOFF 1 |
| 22 | # define HAVE_TM_ZONE 1 | 22 | # define HAVE_TM_ZONE 1 |
| @@ -63,10 +63,10 @@ extern char *tzname[]; | |||
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | #include <limits.h> | 65 | #include <limits.h> |
| 66 | #include <stdbool.h> | ||
| 67 | #include <stddef.h> | 66 | #include <stddef.h> |
| 68 | #include <stdlib.h> | 67 | #include <stdlib.h> |
| 69 | #include <string.h> | 68 | #include <string.h> |
| 69 | #include <stdbool.h> | ||
| 70 | 70 | ||
| 71 | #ifdef COMPILE_WIDE | 71 | #ifdef COMPILE_WIDE |
| 72 | # include <endian.h> | 72 | # include <endian.h> |
| @@ -247,11 +247,11 @@ extern char *tzname[]; | |||
| 247 | # undef _NL_CURRENT | 247 | # undef _NL_CURRENT |
| 248 | # define _NL_CURRENT(category, item) \ | 248 | # define _NL_CURRENT(category, item) \ |
| 249 | (current->values[_NL_ITEM_INDEX (item)].string) | 249 | (current->values[_NL_ITEM_INDEX (item)].string) |
| 250 | # define LOCALE_PARAM , __locale_t loc | ||
| 250 | # define LOCALE_ARG , loc | 251 | # define LOCALE_ARG , loc |
| 251 | # define LOCALE_PARAM_PROTO , __locale_t loc | ||
| 252 | # define HELPER_LOCALE_ARG , current | 252 | # define HELPER_LOCALE_ARG , current |
| 253 | #else | 253 | #else |
| 254 | # define LOCALE_PARAM_PROTO | 254 | # define LOCALE_PARAM |
| 255 | # define LOCALE_ARG | 255 | # define LOCALE_ARG |
| 256 | # ifdef _LIBC | 256 | # ifdef _LIBC |
| 257 | # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME) | 257 | # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME) |
| @@ -304,18 +304,22 @@ fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len) | |||
| 304 | } | 304 | } |
| 305 | } | 305 | } |
| 306 | #else | 306 | #else |
| 307 | static CHAR_T *memcpy_lowcase (CHAR_T *dest, const CHAR_T *src, | ||
| 308 | size_t len LOCALE_PARAM); | ||
| 309 | |||
| 307 | static CHAR_T * | 310 | static CHAR_T * |
| 308 | memcpy_lowcase (CHAR_T *dest, const CHAR_T *src, | 311 | memcpy_lowcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM) |
| 309 | size_t len LOCALE_PARAM_PROTO) | ||
| 310 | { | 312 | { |
| 311 | while (len-- > 0) | 313 | while (len-- > 0) |
| 312 | dest[len] = TOLOWER ((UCHAR_T) src[len], loc); | 314 | dest[len] = TOLOWER ((UCHAR_T) src[len], loc); |
| 313 | return dest; | 315 | return dest; |
| 314 | } | 316 | } |
| 315 | 317 | ||
| 318 | static CHAR_T *memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, | ||
| 319 | size_t len LOCALE_PARAM); | ||
| 320 | |||
| 316 | static CHAR_T * | 321 | static CHAR_T * |
| 317 | memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, | 322 | memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM) |
| 318 | size_t len LOCALE_PARAM_PROTO) | ||
| 319 | { | 323 | { |
| 320 | while (len-- > 0) | 324 | while (len-- > 0) |
| 321 | dest[len] = TOUPPER ((UCHAR_T) src[len], loc); | 325 | dest[len] = TOUPPER ((UCHAR_T) src[len], loc); |
| @@ -328,6 +332,7 @@ memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, | |||
| 328 | /* Yield the difference between *A and *B, | 332 | /* Yield the difference between *A and *B, |
| 329 | measured in seconds, ignoring leap seconds. */ | 333 | measured in seconds, ignoring leap seconds. */ |
| 330 | # define tm_diff ftime_tm_diff | 334 | # define tm_diff ftime_tm_diff |
| 335 | static int tm_diff (const struct tm *, const struct tm *); | ||
| 331 | static int | 336 | static int |
| 332 | tm_diff (const struct tm *a, const struct tm *b) | 337 | tm_diff (const struct tm *a, const struct tm *b) |
| 333 | { | 338 | { |
| @@ -359,6 +364,7 @@ tm_diff (const struct tm *a, const struct tm *b) | |||
| 359 | #define ISO_WEEK_START_WDAY 1 /* Monday */ | 364 | #define ISO_WEEK_START_WDAY 1 /* Monday */ |
| 360 | #define ISO_WEEK1_WDAY 4 /* Thursday */ | 365 | #define ISO_WEEK1_WDAY 4 /* Thursday */ |
| 361 | #define YDAY_MINIMUM (-366) | 366 | #define YDAY_MINIMUM (-366) |
| 367 | static int iso_week_days (int, int); | ||
| 362 | #ifdef __GNUC__ | 368 | #ifdef __GNUC__ |
| 363 | __inline__ | 369 | __inline__ |
| 364 | #endif | 370 | #endif |
| @@ -401,17 +407,41 @@ iso_week_days (int yday, int wday) | |||
| 401 | # define ns 0 | 407 | # define ns 0 |
| 402 | #endif | 408 | #endif |
| 403 | 409 | ||
| 410 | static size_t __strftime_internal (STREAM_OR_CHAR_T *, STRFTIME_ARG (size_t) | ||
| 411 | const CHAR_T *, const struct tm *, | ||
| 412 | bool, bool * | ||
| 413 | extra_args_spec LOCALE_PARAM); | ||
| 404 | 414 | ||
| 405 | /* Just like my_strftime, below, but with one more parameter, UPCASE, | 415 | /* Write information from TP into S according to the format |
| 406 | to indicate that the result should be converted to upper case. */ | 416 | string FORMAT, writing no more that MAXSIZE characters |
| 417 | (including the terminating '\0') and returning number of | ||
| 418 | characters written. If S is NULL, nothing will be written | ||
| 419 | anywhere, so to determine how many characters would be | ||
| 420 | written, use NULL for S and (size_t) -1 for MAXSIZE. */ | ||
| 421 | size_t | ||
| 422 | my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) | ||
| 423 | const CHAR_T *format, | ||
| 424 | const struct tm *tp extra_args_spec LOCALE_PARAM) | ||
| 425 | { | ||
| 426 | bool tzset_called = false; | ||
| 427 | return __strftime_internal (s, STRFTIME_ARG (maxsize) format, tp, | ||
| 428 | false, &tzset_called extra_args LOCALE_ARG); | ||
| 429 | } | ||
| 430 | #if defined _LIBC && ! FPRINTFTIME | ||
| 431 | libc_hidden_def (my_strftime) | ||
| 432 | #endif | ||
| 433 | |||
| 434 | /* Just like my_strftime, above, but with two more parameters. | ||
| 435 | UPCASE indicate that the result should be converted to upper case, | ||
| 436 | and *TZSET_CALLED indicates whether tzset has been called here. */ | ||
| 407 | static size_t | 437 | static size_t |
| 408 | strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | 438 | __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) |
| 409 | STRFTIME_ARG (size_t maxsize) | 439 | const CHAR_T *format, |
| 410 | const CHAR_T *format, | 440 | const struct tm *tp, bool upcase, bool *tzset_called |
| 411 | const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO) | 441 | extra_args_spec LOCALE_PARAM) |
| 412 | { | 442 | { |
| 413 | #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL | 443 | #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL |
| 414 | struct locale_data *const current = loc->__locales[LC_TIME]; | 444 | struct __locale_data *const current = loc->__locales[LC_TIME]; |
| 415 | #endif | 445 | #endif |
| 416 | #if FPRINTFTIME | 446 | #if FPRINTFTIME |
| 417 | size_t maxsize = (size_t) -1; | 447 | size_t maxsize = (size_t) -1; |
| @@ -426,13 +456,17 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 426 | only a few elements. Dereference the pointers only if the format | 456 | only a few elements. Dereference the pointers only if the format |
| 427 | requires this. Then it is ok to fail if the pointers are invalid. */ | 457 | requires this. Then it is ok to fail if the pointers are invalid. */ |
| 428 | # define a_wkday \ | 458 | # define a_wkday \ |
| 429 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) | 459 | ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ |
| 460 | ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))) | ||
| 430 | # define f_wkday \ | 461 | # define f_wkday \ |
| 431 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) | 462 | ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ |
| 463 | ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))) | ||
| 432 | # define a_month \ | 464 | # define a_month \ |
| 433 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) | 465 | ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ |
| 466 | ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))) | ||
| 434 | # define f_month \ | 467 | # define f_month \ |
| 435 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) | 468 | ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ |
| 469 | ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) | ||
| 436 | # define ampm \ | 470 | # define ampm \ |
| 437 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ | 471 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ |
| 438 | ? NLW(PM_STR) : NLW(AM_STR))) | 472 | ? NLW(PM_STR) : NLW(AM_STR))) |
| @@ -483,15 +517,21 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 483 | /* Infer the zone name from *TZ instead of from TZNAME. */ | 517 | /* Infer the zone name from *TZ instead of from TZNAME. */ |
| 484 | tzname_vec = tz->tzname_copy; | 518 | tzname_vec = tz->tzname_copy; |
| 485 | # endif | 519 | # endif |
| 520 | } | ||
| 521 | /* The tzset() call might have changed the value. */ | ||
| 522 | if (!(zone && *zone) && tp->tm_isdst >= 0) | ||
| 523 | { | ||
| 486 | /* POSIX.1 requires that local time zone information be used as | 524 | /* POSIX.1 requires that local time zone information be used as |
| 487 | though strftime called tzset. */ | 525 | though strftime called tzset. */ |
| 488 | # if HAVE_TZSET | 526 | # if HAVE_TZSET |
| 489 | tzset (); | 527 | if (!*tzset_called) |
| 528 | { | ||
| 529 | tzset (); | ||
| 530 | *tzset_called = true; | ||
| 531 | } | ||
| 490 | # endif | 532 | # endif |
| 533 | zone = tzname_vec[tp->tm_isdst != 0]; | ||
| 491 | } | 534 | } |
| 492 | /* The tzset() call might have changed the value. */ | ||
| 493 | if (!(zone && *zone) && tp->tm_isdst >= 0) | ||
| 494 | zone = tzname_vec[tp->tm_isdst != 0]; | ||
| 495 | #endif | 535 | #endif |
| 496 | if (! zone) | 536 | if (! zone) |
| 497 | zone = ""; | 537 | zone = ""; |
| @@ -801,14 +841,15 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 801 | 841 | ||
| 802 | subformat: | 842 | subformat: |
| 803 | { | 843 | { |
| 804 | size_t len = strftime_case_ (to_uppcase, | 844 | size_t len = __strftime_internal (NULL, STRFTIME_ARG ((size_t) -1) |
| 805 | NULL, STRFTIME_ARG ((size_t) -1) | 845 | subfmt, |
| 806 | subfmt, | 846 | tp, to_uppcase, tzset_called |
| 807 | tp extra_args LOCALE_ARG); | 847 | extra_args LOCALE_ARG); |
| 808 | add (len, strftime_case_ (to_uppcase, p, | 848 | add (len, __strftime_internal (p, |
| 809 | STRFTIME_ARG (maxsize - i) | 849 | STRFTIME_ARG (maxsize - i) |
| 810 | subfmt, | 850 | subfmt, |
| 811 | tp extra_args LOCALE_ARG)); | 851 | tp, to_uppcase, tzset_called |
| 852 | extra_args LOCALE_ARG)); | ||
| 812 | } | 853 | } |
| 813 | break; | 854 | break; |
| 814 | 855 | ||
| @@ -845,8 +886,6 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 845 | #endif | 886 | #endif |
| 846 | 887 | ||
| 847 | case L_('C'): | 888 | case L_('C'): |
| 848 | if (modifier == L_('O')) | ||
| 849 | goto bad_format; | ||
| 850 | if (modifier == L_('E')) | 889 | if (modifier == L_('E')) |
| 851 | { | 890 | { |
| 852 | #if HAVE_STRUCT_ERA_ENTRY | 891 | #if HAVE_STRUCT_ERA_ENTRY |
| @@ -1115,6 +1154,10 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 1115 | goto underlying_strftime; | 1154 | goto underlying_strftime; |
| 1116 | #endif | 1155 | #endif |
| 1117 | 1156 | ||
| 1157 | case L_('q'): /* GNU extension. */ | ||
| 1158 | DO_SIGNED_NUMBER (1, false, ((tp->tm_mon * 11) >> 5) + 1); | ||
| 1159 | break; | ||
| 1160 | |||
| 1118 | case L_('R'): | 1161 | case L_('R'): |
| 1119 | subfmt = L_("%H:%M"); | 1162 | subfmt = L_("%H:%M"); |
| 1120 | goto subformat; | 1163 | goto subformat; |
| @@ -1364,6 +1407,16 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 1364 | struct tm ltm; | 1407 | struct tm ltm; |
| 1365 | time_t lt; | 1408 | time_t lt; |
| 1366 | 1409 | ||
| 1410 | /* POSIX.1 requires that local time zone information be used as | ||
| 1411 | though strftime called tzset. */ | ||
| 1412 | # if HAVE_TZSET | ||
| 1413 | if (!*tzset_called) | ||
| 1414 | { | ||
| 1415 | tzset (); | ||
| 1416 | *tzset_called = true; | ||
| 1417 | } | ||
| 1418 | # endif | ||
| 1419 | |||
| 1367 | ltm = *tp; | 1420 | ltm = *tp; |
| 1368 | lt = mktime_z (tz, <m); | 1421 | lt = mktime_z (tz, <m); |
| 1369 | 1422 | ||
| @@ -1444,22 +1497,3 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s, | |||
| 1444 | 1497 | ||
| 1445 | return i; | 1498 | return i; |
| 1446 | } | 1499 | } |
| 1447 | |||
| 1448 | /* Write information from TP into S according to the format | ||
| 1449 | string FORMAT, writing no more that MAXSIZE characters | ||
| 1450 | (including the terminating '\0') and returning number of | ||
| 1451 | characters written. If S is NULL, nothing will be written | ||
| 1452 | anywhere, so to determine how many characters would be | ||
| 1453 | written, use NULL for S and (size_t) -1 for MAXSIZE. */ | ||
| 1454 | size_t | ||
| 1455 | my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) | ||
| 1456 | const CHAR_T *format, | ||
| 1457 | const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO) | ||
| 1458 | { | ||
| 1459 | return strftime_case_ (false, s, STRFTIME_ARG (maxsize) | ||
| 1460 | format, tp extra_args LOCALE_ARG); | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | #if defined _LIBC && ! FPRINTFTIME | ||
| 1464 | libc_hidden_def (my_strftime) | ||
| 1465 | #endif | ||
diff --git a/lib/sys_time.in.h b/lib/sys_time.in.h index 1623a1dba02..d535a6a48b2 100644 --- a/lib/sys_time.in.h +++ b/lib/sys_time.in.h | |||
| @@ -109,6 +109,13 @@ _GL_CXXALIAS_SYS_CAST (gettimeofday, int, | |||
| 109 | (struct timeval *restrict, void *restrict)); | 109 | (struct timeval *restrict, void *restrict)); |
| 110 | # endif | 110 | # endif |
| 111 | _GL_CXXALIASWARN (gettimeofday); | 111 | _GL_CXXALIASWARN (gettimeofday); |
| 112 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 113 | namespace GNULIB_NAMESPACE { | ||
| 114 | typedef ::timeval | ||
| 115 | #undef timeval | ||
| 116 | timeval; | ||
| 117 | } | ||
| 118 | # endif | ||
| 112 | #elif defined GNULIB_POSIXCHECK | 119 | #elif defined GNULIB_POSIXCHECK |
| 113 | # undef gettimeofday | 120 | # undef gettimeofday |
| 114 | # if HAVE_RAW_DECL_GETTIMEOFDAY | 121 | # if HAVE_RAW_DECL_GETTIMEOFDAY |