aboutsummaryrefslogtreecommitdiffstats
path: root/src/strftime.c
diff options
context:
space:
mode:
authorUlrich Drepper1997-11-04 03:28:47 +0000
committerUlrich Drepper1997-11-04 03:28:47 +0000
commit4b7c78fcf17e578b61c0c8ea6eae30b45acf7f0e (patch)
treebb61a2283065aaa7fb694b2242fee983b21db146 /src/strftime.c
parent79d137ffe7dac5fe3041b4916c715f4ce91143af (diff)
downloademacs-4b7c78fcf17e578b61c0c8ea6eae30b45acf7f0e.tar.gz
emacs-4b7c78fcf17e578b61c0c8ea6eae30b45acf7f0e.zip
automatically generated from GPLed version
Diffstat (limited to 'src/strftime.c')
-rw-r--r--src/strftime.c140
1 files changed, 117 insertions, 23 deletions
diff --git a/src/strftime.c b/src/strftime.c
index 711529e72b3..51dbc389a75 100644
--- a/src/strftime.c
+++ b/src/strftime.c
@@ -277,7 +277,7 @@ memcpy_lowcase (dest, src, len)
277 size_t len; 277 size_t len;
278{ 278{
279 while (len-- > 0) 279 while (len-- > 0)
280 dest[len] = TOLOWER (src[len]); 280 dest[len] = TOLOWER ((unsigned char) src[len]);
281 return dest; 281 return dest;
282} 282}
283 283
@@ -290,7 +290,7 @@ memcpy_uppcase (dest, src, len)
290 size_t len; 290 size_t len;
291{ 291{
292 while (len-- > 0) 292 while (len-- > 0)
293 dest[len] = TOUPPER (src[len]); 293 dest[len] = TOUPPER ((unsigned char) src[len]);
294 return dest; 294 return dest;
295} 295}
296 296
@@ -350,7 +350,7 @@ iso_week_days (yday, wday)
350} 350}
351 351
352 352
353#ifndef _NL_CURRENT 353#if !(defined _NL_CURRENT || HAVE_STRFTIME)
354static char const weekday_name[][10] = 354static char const weekday_name[][10] =
355 { 355 {
356 "Sunday", "Monday", "Tuesday", "Wednesday", 356 "Sunday", "Monday", "Tuesday", "Wednesday",
@@ -364,13 +364,27 @@ static char const month_name[][10] =
364#endif 364#endif
365 365
366 366
367#ifdef emacs
368# define my_strftime emacs_strftime
369 /* Emacs 20.2 uses `-Dstrftime=emacs_strftime' when compiling,
370 because that's how strftime used to be configured.
371 Undo this, since it gets in the way of accessing the underlying strftime,
372 which is needed for things like %Ec in Solaris.
373 The following two lines can be removed once Emacs stops compiling with
374 `-Dstrftime=emacs_strftime'. */
375# undef strftime
376size_t strftime __P ((char *, size_t, const char *, const struct tm *));
377#else
378# define my_strftime strftime
379#endif
380
367#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET 381#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
368 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. 382 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
369 Work around this bug by copying *tp before it might be munged. */ 383 Work around this bug by copying *tp before it might be munged. */
370 size_t _strftime_copytm __P ((char *, size_t, const char *, 384 size_t _strftime_copytm __P ((char *, size_t, const char *,
371 const struct tm *)); 385 const struct tm *));
372 size_t 386 size_t
373 strftime (s, maxsize, format, tp) 387 my_strftime (s, maxsize, format, tp)
374 char *s; 388 char *s;
375 size_t maxsize; 389 size_t maxsize;
376 const char *format; 390 const char *format;
@@ -380,10 +394,8 @@ static char const month_name[][10] =
380 tmcopy = *tp; 394 tmcopy = *tp;
381 return _strftime_copytm (s, maxsize, format, &tmcopy); 395 return _strftime_copytm (s, maxsize, format, &tmcopy);
382 } 396 }
383# ifdef strftime 397# undef my_strftime
384# undef strftime 398# define my_strftime(S, Maxsize, Format, Tp) \
385# endif
386# define strftime(S, Maxsize, Format, Tp) \
387 _strftime_copytm (S, Maxsize, Format, Tp) 399 _strftime_copytm (S, Maxsize, Format, Tp)
388#endif 400#endif
389 401
@@ -395,7 +407,7 @@ static char const month_name[][10] =
395 anywhere, so to determine how many characters would be 407 anywhere, so to determine how many characters would be
396 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ 408 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
397size_t 409size_t
398strftime (s, maxsize, format, tp) 410my_strftime (s, maxsize, format, tp)
399 char *s; 411 char *s;
400 size_t maxsize; 412 size_t maxsize;
401 const char *format; 413 const char *format;
@@ -413,6 +425,7 @@ strftime (s, maxsize, format, tp)
413 size_t am_len = strlen (a_month); 425 size_t am_len = strlen (a_month);
414 size_t ap_len = strlen (ampm); 426 size_t ap_len = strlen (ampm);
415#else 427#else
428# if !HAVE_STRFTIME
416 const char *const f_wkday = weekday_name[tp->tm_wday]; 429 const char *const f_wkday = weekday_name[tp->tm_wday];
417 const char *const f_month = month_name[tp->tm_mon]; 430 const char *const f_month = month_name[tp->tm_mon];
418 const char *const a_wkday = f_wkday; 431 const char *const a_wkday = f_wkday;
@@ -421,9 +434,12 @@ strftime (s, maxsize, format, tp)
421 size_t aw_len = 3; 434 size_t aw_len = 3;
422 size_t am_len = 3; 435 size_t am_len = 3;
423 size_t ap_len = 2; 436 size_t ap_len = 2;
437# endif
424#endif 438#endif
439#if defined _NL_CURRENT || !HAVE_STRFTIME
425 size_t wkday_len = strlen (f_wkday); 440 size_t wkday_len = strlen (f_wkday);
426 size_t month_len = strlen (f_month); 441 size_t month_len = strlen (f_month);
442#endif
427 const char *zone; 443 const char *zone;
428 size_t zonelen; 444 size_t zonelen;
429 size_t i = 0; 445 size_t i = 0;
@@ -477,6 +493,7 @@ strftime (s, maxsize, format, tp)
477 int to_lowcase = 0; 493 int to_lowcase = 0;
478 int to_uppcase = 0; 494 int to_uppcase = 0;
479 int change_case = 0; 495 int change_case = 0;
496 int format_char;
480 497
481#if DO_MULTIBYTE 498#if DO_MULTIBYTE
482 499
@@ -605,7 +622,8 @@ strftime (s, maxsize, format, tp)
605 } 622 }
606 623
607 /* Now do the specified format. */ 624 /* Now do the specified format. */
608 switch (*f) 625 format_char = *f;
626 switch (format_char)
609 { 627 {
610#define DO_NUMBER(d, v) \ 628#define DO_NUMBER(d, v) \
611 digits = width == -1 ? d : width; \ 629 digits = width == -1 ? d : width; \
@@ -628,8 +646,12 @@ strftime (s, maxsize, format, tp)
628 to_uppcase = 1; 646 to_uppcase = 1;
629 to_lowcase = 0; 647 to_lowcase = 0;
630 } 648 }
649#if defined _NL_CURRENT || !HAVE_STRFTIME
631 cpy (aw_len, a_wkday); 650 cpy (aw_len, a_wkday);
632 break; 651 break;
652#else
653 goto underlying_strftime;
654#endif
633 655
634 case 'A': 656 case 'A':
635 if (modifier != 0) 657 if (modifier != 0)
@@ -639,15 +661,23 @@ strftime (s, maxsize, format, tp)
639 to_uppcase = 1; 661 to_uppcase = 1;
640 to_lowcase = 0; 662 to_lowcase = 0;
641 } 663 }
664#if defined _NL_CURRENT || !HAVE_STRFTIME
642 cpy (wkday_len, f_wkday); 665 cpy (wkday_len, f_wkday);
643 break; 666 break;
667#else
668 goto underlying_strftime;
669#endif
644 670
645 case 'b': 671 case 'b':
646 case 'h': /* POSIX.2 extension. */ 672 case 'h': /* POSIX.2 extension. */
647 if (modifier != 0) 673 if (modifier != 0)
648 goto bad_format; 674 goto bad_format;
675#if defined _NL_CURRENT || !HAVE_STRFTIME
649 cpy (am_len, a_month); 676 cpy (am_len, a_month);
650 break; 677 break;
678#else
679 goto underlying_strftime;
680#endif
651 681
652 case 'B': 682 case 'B':
653 if (modifier != 0) 683 if (modifier != 0)
@@ -657,8 +687,12 @@ strftime (s, maxsize, format, tp)
657 to_uppcase = 1; 687 to_uppcase = 1;
658 to_lowcase = 0; 688 to_lowcase = 0;
659 } 689 }
690#if defined _NL_CURRENT || !HAVE_STRFTIME
660 cpy (month_len, f_month); 691 cpy (month_len, f_month);
661 break; 692 break;
693#else
694 goto underlying_strftime;
695#endif
662 696
663 case 'c': 697 case 'c':
664 if (modifier == 'O') 698 if (modifier == 'O')
@@ -668,32 +702,58 @@ strftime (s, maxsize, format, tp)
668 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0')) 702 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
669 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); 703 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
670#else 704#else
705# if HAVE_STRFTIME
706 goto underlying_strftime;
707# else
671 subfmt = "%a %b %e %H:%M:%S %Y"; 708 subfmt = "%a %b %e %H:%M:%S %Y";
709# endif
672#endif 710#endif
673 711
674 subformat: 712 subformat:
675 { 713 {
676 char *old_start = p; 714 char *old_start = p;
677 size_t len = strftime (NULL, maxsize - i, subfmt, tp); 715 size_t len = my_strftime (NULL, maxsize - i, subfmt, tp);
678 if (len == 0 && *subfmt) 716 if (len == 0 && *subfmt)
679 return 0; 717 return 0;
680 add (len, strftime (p, maxsize - i, subfmt, tp)); 718 add (len, my_strftime (p, maxsize - i, subfmt, tp));
681 719
682 if (to_uppcase) 720 if (to_uppcase)
683 while (old_start < p) 721 while (old_start < p)
684 { 722 {
685 *old_start = TOUPPER (*old_start); 723 *old_start = TOUPPER ((unsigned char) *old_start);
686 ++old_start; 724 ++old_start;
687 } 725 }
688 } 726 }
689 break; 727 break;
690 728
729#if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
730 underlying_strftime:
731 {
732 /* The relevant information is available only via the
733 underlying strftime implementation, so use that. */
734 char ufmt[4];
735 char *u = ufmt;
736 char ubuf[1024]; /* enough for any single format in practice */
737 size_t len;
738 *u++ = '%';
739 if (modifier != 0)
740 *u++ = modifier;
741 *u++ = format_char;
742 *u = '\0';
743 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
744 if (len == 0)
745 return 0;
746 cpy (len, ubuf);
747 }
748 break;
749#endif
750
691 case 'C': /* POSIX.2 extension. */ 751 case 'C': /* POSIX.2 extension. */
692 if (modifier == 'O') 752 if (modifier == 'O')
693 goto bad_format; 753 goto bad_format;
694#if HAVE_STRUCT_ERA_ENTRY
695 if (modifier == 'E') 754 if (modifier == 'E')
696 { 755 {
756#if HAVE_STRUCT_ERA_ENTRY
697 struct era_entry *era = _nl_get_era_entry (tp); 757 struct era_entry *era = _nl_get_era_entry (tp);
698 if (era) 758 if (era)
699 { 759 {
@@ -701,8 +761,13 @@ strftime (s, maxsize, format, tp)
701 cpy (len, era->name_fmt); 761 cpy (len, era->name_fmt);
702 break; 762 break;
703 } 763 }
704 } 764#else
765# if HAVE_STRFTIME
766 goto underlying_strftime;
767# endif
705#endif 768#endif
769 }
770
706 { 771 {
707 int year = tp->tm_year + TM_YEAR_BASE; 772 int year = tp->tm_year + TM_YEAR_BASE;
708 DO_NUMBER (1, year / 100 - (year % 100 < 0)); 773 DO_NUMBER (1, year / 100 - (year % 100 < 0));
@@ -716,8 +781,13 @@ strftime (s, maxsize, format, tp)
716 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0')) 781 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
717 subfmt = _NL_CURRENT (LC_TIME, D_FMT); 782 subfmt = _NL_CURRENT (LC_TIME, D_FMT);
718 goto subformat; 783 goto subformat;
719#endif 784#else
785# if HAVE_STRFTIME
786 goto underlying_strftime;
787# else
720 /* Fall through. */ 788 /* Fall through. */
789# endif
790#endif
721 case 'D': /* POSIX.2 extension. */ 791 case 'D': /* POSIX.2 extension. */
722 if (modifier != 0) 792 if (modifier != 0)
723 goto bad_format; 793 goto bad_format;
@@ -747,9 +817,9 @@ strftime (s, maxsize, format, tp)
747 do_number: 817 do_number:
748 /* Format the number according to the MODIFIER flag. */ 818 /* Format the number according to the MODIFIER flag. */
749 819
750#ifdef _NL_CURRENT
751 if (modifier == 'O' && 0 <= number_value) 820 if (modifier == 'O' && 0 <= number_value)
752 { 821 {
822#ifdef _NL_CURRENT
753 /* Get the locale specific alternate representation of 823 /* Get the locale specific alternate representation of
754 the number NUMBER_VALUE. If none exist NULL is returned. */ 824 the number NUMBER_VALUE. If none exist NULL is returned. */
755 const char *cp = _nl_get_alt_digit (number_value); 825 const char *cp = _nl_get_alt_digit (number_value);
@@ -763,8 +833,12 @@ strftime (s, maxsize, format, tp)
763 break; 833 break;
764 } 834 }
765 } 835 }
766 } 836#else
837# if HAVE_STRFTIME
838 goto underlying_strftime;
839# endif
767#endif 840#endif
841 }
768 { 842 {
769 unsigned int u = number_value; 843 unsigned int u = number_value;
770 844
@@ -854,6 +928,9 @@ strftime (s, maxsize, format, tp)
854 928
855 case 'P': 929 case 'P':
856 to_lowcase = 1; 930 to_lowcase = 1;
931#if !defined _NL_CURRENT && HAVE_STRFTIME
932 format_char = 'p';
933#endif
857 /* FALLTHROUGH */ 934 /* FALLTHROUGH */
858 935
859 case 'p': 936 case 'p':
@@ -862,8 +939,12 @@ strftime (s, maxsize, format, tp)
862 to_uppcase = 0; 939 to_uppcase = 0;
863 to_lowcase = 1; 940 to_lowcase = 1;
864 } 941 }
942#if defined _NL_CURRENT || !HAVE_STRFTIME
865 cpy (ap_len, ampm); 943 cpy (ap_len, ampm);
866 break; 944 break;
945#else
946 goto underlying_strftime;
947#endif
867 948
868 case 'R': /* GNU extension. */ 949 case 'R': /* GNU extension. */
869 subfmt = "%H:%M"; 950 subfmt = "%H:%M";
@@ -929,8 +1010,13 @@ strftime (s, maxsize, format, tp)
929 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0')) 1010 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
930 subfmt = _NL_CURRENT (LC_TIME, T_FMT); 1011 subfmt = _NL_CURRENT (LC_TIME, T_FMT);
931 goto subformat; 1012 goto subformat;
932#endif 1013#else
1014# if HAVE_STRFTIME
1015 goto underlying_strftime;
1016# else
933 /* Fall through. */ 1017 /* Fall through. */
1018# endif
1019#endif
934 case 'T': /* POSIX.2 extension. */ 1020 case 'T': /* POSIX.2 extension. */
935 subfmt = "%H:%M:%S"; 1021 subfmt = "%H:%M:%S";
936 goto subformat; 1022 goto subformat;
@@ -1002,26 +1088,30 @@ strftime (s, maxsize, format, tp)
1002 DO_NUMBER (1, tp->tm_wday); 1088 DO_NUMBER (1, tp->tm_wday);
1003 1089
1004 case 'Y': 1090 case 'Y':
1005#if HAVE_STRUCT_ERA_ENTRY
1006 if (modifier == 'E') 1091 if (modifier == 'E')
1007 { 1092 {
1093#if HAVE_STRUCT_ERA_ENTRY
1008 struct era_entry *era = _nl_get_era_entry (tp); 1094 struct era_entry *era = _nl_get_era_entry (tp);
1009 if (era) 1095 if (era)
1010 { 1096 {
1011 subfmt = strchr (era->name_fmt, '\0') + 1; 1097 subfmt = strchr (era->name_fmt, '\0') + 1;
1012 goto subformat; 1098 goto subformat;
1013 } 1099 }
1014 } 1100#else
1101# if HAVE_STRFTIME
1102 goto underlying_strftime;
1103# endif
1015#endif 1104#endif
1105 }
1016 if (modifier == 'O') 1106 if (modifier == 'O')
1017 goto bad_format; 1107 goto bad_format;
1018 else 1108 else
1019 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE); 1109 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1020 1110
1021 case 'y': 1111 case 'y':
1022#if HAVE_STRUCT_ERA_ENTRY
1023 if (modifier == 'E') 1112 if (modifier == 'E')
1024 { 1113 {
1114#if HAVE_STRUCT_ERA_ENTRY
1025 struct era_entry *era = _nl_get_era_entry (tp); 1115 struct era_entry *era = _nl_get_era_entry (tp);
1026 if (era) 1116 if (era)
1027 { 1117 {
@@ -1029,8 +1119,12 @@ strftime (s, maxsize, format, tp)
1029 DO_NUMBER (1, (era->offset 1119 DO_NUMBER (1, (era->offset
1030 + (era->direction == '-' ? -delta : delta))); 1120 + (era->direction == '-' ? -delta : delta)));
1031 } 1121 }
1032 } 1122#else
1123# if HAVE_STRFTIME
1124 goto underlying_strftime;
1125# endif
1033#endif 1126#endif
1127 }
1034 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); 1128 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1035 1129
1036 case 'Z': 1130 case 'Z':