diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/strftime.c | 204 |
1 files changed, 142 insertions, 62 deletions
diff --git a/time/strftime.c b/time/strftime.c index c47fc07548..40a7a747cf 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -21,22 +21,57 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <ansidecl.h> -#include "../locale/localeinfo.h" -#include <ctype.h> -#include <limits.h> -#include <stddef.h> +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# define HAVE_MBLEN 1 +# define HAVE_TM_ZONE 1 +# define STDC_HEADERS 1 +# include <ansidecl.h> +# include "../locale/localeinfo.h" +#endif + #include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include <sys/types.h> /* Some systems define `time_t' here. */ #include <time.h> -#ifndef HAVE_GNU_LD -#define __tzname tzname -#define __daylight daylight -#define __timezone timezone +#if HAVE_MBLEN +# include <ctype.h> +#endif + +#if HAVE_LIMITS_H +# include <limits.h> #endif +#if STDC_HEADERS +# include <stddef.h> +# include <stdlib.h> +# include <string.h> +#else +# define memcpy(d, s, n) bcopy (s, d, n) +#endif + +#ifndef __P +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define __P(args) args +#else +#define __P(args) () +#endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef PTR +#ifdef __STDC__ +#define PTR void * +#else +#define PTR char * +#endif +#endif + +static unsigned int week __P((const struct tm *const, int)); + #define add(n, f) \ do \ @@ -45,14 +80,19 @@ Cambridge, MA 02139, USA. */ if (i >= maxsize) \ return 0; \ else \ - if (p != NULL) \ + if (p) \ { \ f; \ p += (n); \ } \ } while (0) #define cpy(n, s) add((n), memcpy((PTR) p, (PTR) (s), (n))) + +#ifdef _LIBC #define fmt(n, args) add((n), if (sprintf args != (n)) return 0) +#else +#define fmt(n, args) add((n), sprintf args; if (strlen (p) != (n)) return 0) +#endif /* Return the week in the year specified by TP, with weeks starting on STARTING_DAY. */ @@ -60,8 +100,9 @@ Cambridge, MA 02139, USA. */ inline #endif static unsigned int -DEFUN(week, (tp, starting_day), - CONST struct tm *CONST tp AND int starting_day) +week (tp, starting_day) + const struct tm *const tp; + int starting_day; { int wday, dl; @@ -78,6 +119,18 @@ DEFUN(week, (tp, starting_day), return dl <= 0 ? 0 : ((dl / 7) + ((dl % 7) == 0 ? 0 : 1)); } +#ifndef _NL_CURRENT +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +#endif /* Write information from TP into S according to the format string FORMAT, writing no more that MAXSIZE characters @@ -86,40 +139,55 @@ DEFUN(week, (tp, starting_day), anywhere, so to determine how many characters would be written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ size_t -DEFUN(strftime, (s, maxsize, format, tp), - char *s AND size_t maxsize AND - CONST char *format AND register CONST struct tm *tp) +strftime (s, maxsize, format, tp) + char *s; + size_t maxsize; + const char *format; + register const struct tm *tp; { - CONST char *CONST a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday); - CONST char *CONST f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); - CONST char *CONST a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); - CONST char *CONST f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); + int hour12 = tp->tm_hour; +#ifdef _NL_CURRENT + const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday); + const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); + const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); + const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); + const char *const ampm = _NL_CURRENT (LC_TIME, + hour12 > 12 ? PM_STR : AM_STR); size_t aw_len = strlen(a_wkday); size_t am_len = strlen(a_month); + size_t ap_len = strlen (ampm); +#else + const char *const f_wkday = weekday_name[tp->tm_wday]; + const char *const f_month = month_name[tp->tm_mon]; + const char *const a_wkday = f_wkday; + const char *const a_month = f_month; + const char *const ampm = "AMPM" + 2 * (hour12 > 12); + size_t aw_len = 3; + size_t am_len = 3; + size_t ap_len = 2; +#endif size_t wkday_len = strlen(f_wkday); size_t month_len = strlen(f_month); - int hour12 = tp->tm_hour; - CONST char *CONST ampm = _NL_CURRENT (LC_TIME, - hour12 > 12 ? PM_STR : AM_STR); - size_t ap_len = strlen (ampm); - CONST unsigned int y_week0 = week (tp, 0); - CONST unsigned int y_week1 = week (tp, 1); - CONST char *zone; + const unsigned int y_week0 = week (tp, 0); + const unsigned int y_week1 = week (tp, 1); + const char *zone; size_t zonelen; register size_t i = 0; register char *p = s; - register CONST char *f; + register const char *f; - if (tp->tm_isdst < 0) - { - zone = ""; - zonelen = 0; - } - else - { - zone = __tzname[tp->tm_isdst]; - zonelen = strlen(zone); - } + zone = 0; +#if HAVE_TM_ZONE + zone = (const char *) tp->tm_zone; +#endif +#if HAVE_TZNAME + if (!(zone && *zone) && tp->tm_isdst >= 0) + zone = tzname[tp->tm_isdst]; +#endif + if (!(zone && *zone)) + zone = "???"; + + zonelen = strlen (zone); if (hour12 > 12) hour12 -= 12; @@ -128,8 +196,9 @@ DEFUN(strftime, (s, maxsize, format, tp), for (f = format; *f != '\0'; ++f) { - CONST char *subfmt; + const char *subfmt; +#if HAVE_MBLEN if (!isascii(*f)) { /* Non-ASCII, may be a multibyte. */ @@ -140,6 +209,7 @@ DEFUN(strftime, (s, maxsize, format, tp), continue; } } +#endif if (*f != '%') { @@ -173,24 +243,36 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'c': +#ifdef _NL_CURRENT subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); +#else + subfmt = "%a %b %d %H:%M:%S %Z %Y"; +#endif subformat: { size_t len = strftime (p, maxsize - i, subfmt, tp); + if (len == 0 && *subfmt) + return 0; add(len, ); } break; case 'C': - fmt (2, (p, "%.2d", (1900 + tp->tm_year) / 100)); + fmt (2, (p, "%02d", (1900 + tp->tm_year) / 100)); break; + case 'x': +#ifdef _NL_CURRENT + subfmt = _NL_CURRENT (LC_TIME, D_FMT); + goto subformat; +#endif + /* Fall through. */ case 'D': /* GNU extension. */ subfmt = "%m/%d/%y"; goto subformat; case 'd': - fmt(2, (p, "%.2d", tp->tm_mday)); + fmt(2, (p, "%02d", tp->tm_mday)); break; case 'e': /* GNU extension: %d, but blank-padded. */ @@ -198,11 +280,11 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'H': - fmt(2, (p, "%.2d", tp->tm_hour)); + fmt(2, (p, "%02d", tp->tm_hour)); break; case 'I': - fmt(2, (p, "%.2d", hour12)); + fmt(2, (p, "%02d", hour12)); break; case 'k': /* GNU extension. */ @@ -214,15 +296,15 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'j': - fmt(3, (p, "%.3d", 1 + tp->tm_yday)); + fmt(3, (p, "%03d", 1 + tp->tm_yday)); break; case 'M': - fmt(2, (p, "%.2d", tp->tm_min)); + fmt(2, (p, "%02d", tp->tm_min)); break; case 'm': - fmt(2, (p, "%.2d", tp->tm_mon + 1)); + fmt(2, (p, "%02d", tp->tm_mon + 1)); break; case 'n': /* GNU extension. */ @@ -242,9 +324,15 @@ DEFUN(strftime, (s, maxsize, format, tp), goto subformat; case 'S': - fmt(2, (p, "%.2d", tp->tm_sec)); + fmt(2, (p, "%02d", tp->tm_sec)); break; + case 'X': +#ifdef _NL_CURRENT + subfmt = _NL_CURRENT (LC_TIME, T_FMT); + goto subformat; +#endif + /* Fall through. */ case 'T': /* GNU extenstion. */ subfmt = "%H:%M:%S"; goto subformat; @@ -254,31 +342,23 @@ DEFUN(strftime, (s, maxsize, format, tp), break; case 'U': - fmt(2, (p, "%.2u", y_week0)); + fmt(2, (p, "%02u", y_week0)); break; case 'W': - fmt(2, (p, "%.2u", y_week1)); + fmt(2, (p, "%02u", y_week1)); break; case 'w': - fmt(2, (p, "%.2d", tp->tm_wday)); + fmt(2, (p, "%02d", tp->tm_wday)); break; - case 'X': - subfmt = _NL_CURRENT (LC_TIME, T_FMT); - goto subformat; - - case 'x': - subfmt = _NL_CURRENT (LC_TIME, D_FMT); - goto subformat; - case 'Y': - fmt(4, (p, "%.4d", 1900 + tp->tm_year)); + fmt(4, (p, "%04d", 1900 + tp->tm_year)); break; case 'y': - fmt(2, (p, "%.2d", tp->tm_year % 100)); + fmt(2, (p, "%02d", tp->tm_year % 100)); break; case 'Z': @@ -291,7 +371,7 @@ DEFUN(strftime, (s, maxsize, format, tp), } } - if (p != NULL) + if (p) *p = '\0'; return i; } |