diff options
author | Roland McGrath <roland@gnu.org> | 1996-01-24 06:03:37 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-01-24 06:03:37 +0000 |
commit | 0793d3483ae525d659ea13cfd0563e6ea9a0c9ce (patch) | |
tree | df880e6d7e2a3acfd35756c19311c57eff1e76ac /time/strftime.c | |
parent | 8ebd0a71be7bb15b5abdcf1b9d218923a9e2eec5 (diff) | |
download | glibc-0793d3483ae525d659ea13cfd0563e6ea9a0c9ce.zip glibc-0793d3483ae525d659ea13cfd0563e6ea9a0c9ce.tar.gz glibc-0793d3483ae525d659ea13cfd0563e6ea9a0c9ce.tar.bz2 |
Wed Jan 24 04:18:36 1996 Paul Eggert <eggert@twinsun.com>
* strftime.c (strftime):
When invoking self, check whether the subsidiary invocation failed.
Use "???" (not "") to denote unknown time zone information.
Make this source file portable to standalone contexts (e.g. GNU Emacs).
<config.h>: Include if HAVE_CONFIG_H is defined.
(HAVE_LIMITS_H, HAVE_MBLEN, HAVE_TM_ZONE, STDC_HEADERS): New symbols,
defined if _LIBC or if <config.h> defines them.
<ansidecl.h>, "../locale/localeinfo.h": Include only if _LIBC.
<sys/types.h>: New include; some hosts require it for `time_t'.
<ctype.h>: Include only if HAVE_MBLEN (since it's only needed then).
<limits.h>: Include only if HAVE_LIMITS_H.
<stddef.h, stdlib.h, string.h>: Include only if STDC_HEADERS.
(memcpy): Define in terms of bcopy if !STDC_HEADERS.
(__P, PTR): Define if not already defined.
(__tzname, __daylight, __timezone): Remove macros; no longer needed.
(add, strftime): Don't use NULL, for portability to some weird hosts.
(fmt): If !_LIBC, don't assume sprintf returns a count.
(week, strftime): Use old-style function declarations.
(weekday_name, month_name): New constants.
(strftime): Use traditional C values if locale support isn't available.
Use `const' instead of CONST. For time zones, use tm_zone if
possible, then fall back on tzname. Don't check for multibyte
characters unless mblen is supported. Use formats like %02d instead
of %.2d, for portability to older hosts.
Wed Jan 24 04:18:36 1996 Paul Eggert <eggert@twinsun.com>
* strftime.c (strftime):
When invoking self, check whether the subsidiary invocation failed.
Use "???" (not "") to denote unknown time zone information.
Make this source file portable to standalone contexts (e.g. GNU Emacs).
<config.h>: Include if HAVE_CONFIG_H is defined.
(HAVE_LIMITS_H, HAVE_MBLEN, HAVE_TM_ZONE, STDC_HEADERS): New symbols,
defined if _LIBC or if <config.h> defines them.
<ansidecl.h>, "../locale/localeinfo.h": Include only if _LIBC.
<sys/types.h>: New include; some hosts require it for `time_t'.
<ctype.h>: Include only if HAVE_MBLEN (since it's only needed then).
<limits.h>: Include only if HAVE_LIMITS_H.
<stddef.h, stdlib.h, string.h>: Include only if STDC_HEADERS.
(memcpy): Define in terms of bcopy if !STDC_HEADERS.
(__P, PTR): Define if not already defined.
(__tzname, __daylight, __timezone): Remove macros; no longer needed.
(add, strftime): Don't use NULL, for portability to some weird hosts.
(fmt): If !_LIBC, don't assume sprintf returns a count.
(week, strftime): Use old-style function declarations.
(weekday_name, month_name): New constants.
(strftime): Use traditional C values if locale support isn't available.
Use `const' instead of CONST. For time zones, use tm_zone if
possible, then fall back on tzname. Don't check for multibyte
characters unless mblen is supported. Use formats like %02d instead
of %.2d, for portability to older hosts.
Wed Jan 24 00:07:52 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* stdio-common/vfscanf.c (GROUP, MALLOC): New flag macros.
(__vfscanf): Eliminate flag vars that were redundant with FLAGS bits.
Fix bug in recognition of %ll flag for long long.
Fix overeager checks for conflicting type modifiers.
With ' flag, match thousands separators for decimal numbers.
Tue Jan 23 22:02:40 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* locale/Makefile (CFLAGS-locfile-lex.c): New variable.
* resolv/Makefile (CFLAGS): Disable some warnings.
* sysdeps/generic/Makefile (elided-routines): Removed hypot.
(+gccwarn): Set with override.
* stdio-common/Makefile (CFLAGS-tst-printf.c): New variable.
* posix/Makefile (CFLAGS-regex.c): New variable.
* malloc/Makefile (CFLAGS-obstack.c): New variable.
* io/Makefile (CFLAGS-fts.c): New variable.
* io/fts.c (fts_open): Use prototypes for COMPAR decl.
Tue Jan 23 21:35:32 1996 Miles Bader <miles@gnu.ai.mit.edu>
* sysdeps/mach/hurd/bind.c (bind): Ensure NAME for the AF_LOCAL
case is '\0'-terminated.
Tue Jan 23 19:49:54 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/rtld.c (dl_main): Support additional args in --list mode for
debugging: look them up as symbol names and print values.
* misc/getttyent.c (skip, value): Declare with prototypes in file
scope.
* csu/initfini.c (_init): Explicitly set a variable that is
pointer to volatile with the address of __gmon_start__, to avoid
the test being optimized out.
Diffstat (limited to 'time/strftime.c')
-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 c47fc07..40a7a74 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; } |