diff options
author | Gary Houston <ghouston@arglist.com> | 1997-04-12 20:18:12 +0000 |
---|---|---|
committer | Gary Houston <ghouston@arglist.com> | 1997-04-12 20:18:12 +0000 |
commit | b9525b92bbffe61b53686471e2b13184546080f7 (patch) | |
tree | 9194df197652973ad5ceba7fd2b7e986f53befc2 | |
parent | 6549522160a5bd3594ccc47f95ea9ac8698fb7e5 (diff) | |
download | guile-b9525b92bbffe61b53686471e2b13184546080f7.tar.gz |
* stime.c (scm_mktime): take an optional zone argument.
(scm_localtime): check putenv return value.
(scm_strftime, scm_strptime): moved from posix.c. move #include
sequences.h too.
stime.h, posix.h: update prototypes.
(bdtime2c, setzone, restorezone): new static procedures.
(scm_mktime, scm_strftime): use them.
(scm_strftime): don't call mktime before strftime. Use
filltime for return value.
(filltime): convert NULL zname to #f.
* (scm_strptime): return a count of characters consumed, not
the remaining string.
* stime.c (scm_localtime): check HAVE_TM_ZONE and HAVE_TZNAME.
(scm_mktime): likewise.
Declare *tzname[].
Uncomment localtime and mktime.
* configure.in: add AC_STRUCT_TIMEZONE.
-rw-r--r-- | libguile/ChangeLog | 24 | ||||
-rw-r--r-- | libguile/Makefile.in | 2 | ||||
-rw-r--r-- | libguile/configure.in | 1 | ||||
-rw-r--r-- | libguile/posix.c | 123 | ||||
-rw-r--r-- | libguile/posix.h | 2 | ||||
-rw-r--r-- | libguile/scmconfig.h.in | 10 | ||||
-rw-r--r-- | libguile/stime.c | 255 | ||||
-rw-r--r-- | libguile/stime.h | 4 |
8 files changed, 236 insertions, 185 deletions
diff --git a/libguile/ChangeLog b/libguile/ChangeLog index b2db829a2..319ed1078 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -28,6 +28,30 @@ Wed Apr 9 18:01:20 1997 Jim Blandy <jimb@floss.cyclic.com> readability. * Makefile.in: Rebuild. +Wed Apr 9 09:08:54 1997 Gary Houston <ghouston@actrix.gen.nz> + + * stime.c (scm_mktime): take an optional zone argument. + (scm_localtime): check putenv return value. + (scm_strftime, scm_strptime): moved from posix.c. move #include + sequences.h too. + stime.h, posix.h: update prototypes. + (bdtime2c, setzone, restorezone): new static procedures. + (scm_mktime, scm_strftime): use them. + (scm_strftime): don't call mktime before strftime. Use + filltime for return value. + (filltime): convert NULL zname to #f. +* (scm_strptime): return a count of characters consumed, not + the remaining string. + +Sun Apr 6 05:44:11 1997 Gary Houston <ghouston@actrix.gen.nz> + + * stime.c (scm_localtime): check HAVE_TM_ZONE and HAVE_TZNAME. + (scm_mktime): likewise. + Declare *tzname[]. + Uncomment localtime and mktime. + + * configure.in: add AC_STRUCT_TIMEZONE. + Sat Apr 5 23:56:40 1997 Gary Houston <ghouston@actrix.gen.nz> * stime.c (scm_init_stime): don't define ticks/sec. diff --git a/libguile/Makefile.in b/libguile/Makefile.in index 7f06f229f..f04543fa7 100644 --- a/libguile/Makefile.in +++ b/libguile/Makefile.in @@ -271,7 +271,7 @@ distclean-libtool: maintainer-clean-libtool: libguile.la: $(libguile_la_OBJECTS) $(libguile_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libguile_la_LDFLAGS) $(libguile_la_OBJECTS) $(libguile_la_LIBADD) $(LIBS) + $(LINK) -rpath lib $(libguile_la_LDFLAGS) $(libguile_la_OBJECTS) $(libguile_la_LIBADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) diff --git a/libguile/configure.in b/libguile/configure.in index 3bdab6f3c..aaf642663 100644 --- a/libguile/configure.in +++ b/libguile/configure.in @@ -60,6 +60,7 @@ AC_FUNC_ALLOCA AC_STRUCT_ST_RDEV AC_STRUCT_ST_BLKSIZE AC_STRUCT_ST_BLOCKS +AC_STRUCT_TIMEZONE GUILE_STRUCT_UTIMBUF # Checks for dynamic linking diff --git a/libguile/posix.c b/libguile/posix.c index f2102f1bb..b511179c1 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -45,7 +45,6 @@ #include "fports.h" #include "scmsigs.h" #include "feature.h" -#include "sequences.h" #include "posix.h" @@ -138,8 +137,6 @@ extern char ** environ; # endif #endif -char *strptime (); - #ifdef HAVE_SETLOCALE #include <locale.h> #endif @@ -1075,126 +1072,6 @@ scm_setlocale (category, locale) #endif } -SCM_PROC (s_strftime, "strftime", 2, 0, 0, scm_strftime); - -SCM -scm_strftime (format, stime) - SCM format; - SCM stime; -{ - struct tm t; - - char *tbuf; - int n; - int size = 50; - char *fmt; - int len; - - SCM_ASSERT (SCM_NIMP (format) && SCM_STRINGP (format), format, SCM_ARG1, - s_strftime); - SCM_ASSERT (SCM_NIMP (stime) && SCM_VECTORP (stime) - && scm_obj_length (stime) == 9, - stime, SCM_ARG2, s_strftime); - - fmt = SCM_ROCHARS (format); - len = SCM_ROLENGTH (format); - -#define tm_deref scm_num2long (SCM_VELTS (stime)[n++], (char *)SCM_ARG2, s_strftime) - n = 0; - t.tm_sec = tm_deref; - t.tm_min = tm_deref; - t.tm_hour = tm_deref; - t.tm_mday = tm_deref; - t.tm_mon = tm_deref; - t.tm_year = tm_deref; - /* not used by mktime. - t.tm_wday = tm_deref; - t.tm_yday = tm_deref; */ - t.tm_isdst = tm_deref; -#undef tm_deref - - /* fill in missing fields and set the timezone. */ - mktime (&t); - - tbuf = scm_must_malloc (size, s_strftime); - while ((len = strftime (tbuf, size, fmt, &t)) == size) - { - scm_must_free (tbuf); - size *= 2; - tbuf = scm_must_malloc (size, s_strftime); - } - return scm_makfromstr (tbuf, len, 0); -} - -SCM_PROC (s_strptime, "strptime", 2, 0, 0, scm_strptime); - -SCM -scm_strptime (format, string) - SCM format; - SCM string; -{ -#ifdef HAVE_STRPTIME - SCM stime; - struct tm t; - - char *fmt, *str, *rest; - int n; - - SCM_ASSERT (SCM_NIMP (format) && SCM_ROSTRINGP (format), format, SCM_ARG1, - s_strptime); - if (SCM_SUBSTRP (format)) - format = scm_makfromstr (SCM_ROCHARS (format), SCM_ROLENGTH (format), 0); - SCM_ASSERT (SCM_NIMP (string) && SCM_ROSTRINGP (string), string, SCM_ARG2, - s_strptime); - if (SCM_SUBSTRP (string)) - string = scm_makfromstr (SCM_ROCHARS (string), SCM_ROLENGTH (string), 0); - - fmt = SCM_CHARS (format); - str = SCM_CHARS (string); - - /* initialize the struct tm */ -#define tm_init(field) t.field = 0 - tm_init (tm_sec); - tm_init (tm_min); - tm_init (tm_hour); - tm_init (tm_mday); - tm_init (tm_mon); - tm_init (tm_year); - tm_init (tm_wday); - tm_init (tm_yday); - tm_init (tm_isdst); -#undef tm_init - - SCM_DEFER_INTS; - rest = strptime (str, fmt, &t); - SCM_ALLOW_INTS; - - if (rest == NULL) - scm_syserror (s_strptime); - - stime = scm_make_vector (SCM_MAKINUM (9), scm_long2num (0), SCM_UNDEFINED); - -#define stime_set(val) scm_vector_set_x (stime, SCM_MAKINUM (n++), scm_long2num (t.val)); - n = 0; - stime_set (tm_sec); - stime_set (tm_min); - stime_set (tm_hour); - stime_set (tm_mday); - stime_set (tm_mon); - stime_set (tm_year); - stime_set (tm_wday); - stime_set (tm_yday); - stime_set (tm_isdst); -#undef stime_set - - return scm_cons (stime, scm_makfrom0str (rest)); -#else - scm_sysmissing (s_strptime); - /* not reached. */ - return SCM_BOOL_F; -#endif -} - SCM_PROC (s_mknod, "mknod", 4, 0, 0, scm_mknod); SCM diff --git a/libguile/posix.h b/libguile/posix.h index c39cc99ba..700591cd6 100644 --- a/libguile/posix.h +++ b/libguile/posix.h @@ -90,8 +90,6 @@ extern SCM scm_access SCM_P ((SCM path, SCM how)); extern SCM scm_getpid SCM_P ((void)); extern SCM scm_putenv SCM_P ((SCM str)); extern SCM scm_setlocale SCM_P ((SCM category, SCM locale)); -extern SCM scm_strftime SCM_P ((SCM format, SCM stime)); -extern SCM scm_strptime SCM_P ((SCM format, SCM string)); extern SCM scm_mknod SCM_P ((SCM path, SCM type, SCM perms, SCM dev)); extern SCM scm_nice SCM_P ((SCM incr)); extern SCM scm_sync SCM_P ((void)); diff --git a/libguile/scmconfig.h.in b/libguile/scmconfig.h.in index a18964bb6..6fe08123a 100644 --- a/libguile/scmconfig.h.in +++ b/libguile/scmconfig.h.in @@ -42,6 +42,13 @@ /* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H +/* Define if your struct tm has tm_zone. */ +#undef HAVE_TM_ZONE + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#undef HAVE_TZNAME + /* Define if on MINIX. */ #undef _MINIX @@ -73,6 +80,9 @@ /* Define if you can safely include both <sys/time.h> and <time.h>. */ #undef TIME_WITH_SYS_TIME +/* Define if your <sys/time.h> declares struct tm. */ +#undef TM_IN_SYS_TIME + /* Define to `int' if <sys/types.h> doesn't define. */ #undef uid_t diff --git a/libguile/stime.c b/libguile/stime.c index f95a85301..90bbde93a 100644 --- a/libguile/stime.c +++ b/libguile/stime.c @@ -43,6 +43,7 @@ #include <stdio.h> #include "_scm.h" #include "feature.h" +#include "sequences.h" #include "stime.h" @@ -76,6 +77,12 @@ # endif # endif +#ifndef tzname /* For SGI. */ +extern char *tzname[]; /* RS6000 and others reject char **tzname. */ +#endif + +char *strptime (); + /* This should be figured out by autoconf. */ #ifdef CLK_TCK # define CLKTCK CLK_TCK @@ -230,11 +237,53 @@ filltime (struct tm *bd_time, int zoff, char *zname) SCM_VELTS (result)[7] = SCM_MAKINUM (bd_time->tm_yday); SCM_VELTS (result)[8] = SCM_MAKINUM (bd_time->tm_isdst); SCM_VELTS (result)[9] = SCM_MAKINUM (zoff); - SCM_VELTS (result)[10] = scm_makfrom0str (zname); + SCM_VELTS (result)[10] = zname ? scm_makfrom0str (zname) : SCM_BOOL_F; return result; } -#if 0 +static char * +setzone (SCM zone, int pos, char *subr) +{ + char *oldtz = 0; + + if (!SCM_UNBNDP (zone)) + { + char *buf; + + /* if zone was supplied, set the environment variable TZ temporarily. */ + SCM_ASSERT (SCM_NIMP (zone) && SCM_STRINGP (zone), zone, pos, subr); + buf = malloc (SCM_LENGTH (zone) + 4); + if (buf == 0) + scm_memory_error (subr); + oldtz = getenv ("TZ"); + if (oldtz != NULL) + oldtz = oldtz - 3; + sprintf (buf, "TZ=%s", SCM_CHARS (zone)); + if (putenv (buf) < 0) + scm_syserror (subr); + tzset(); + } + return oldtz; +} + +static void +restorezone (SCM zone, char *oldzone) +{ + if (!SCM_UNBNDP (zone)) + { + int rv; + + if (oldzone) + rv = putenv (oldzone); + else + rv = putenv ("TZ"); + if (rv < 0) + scm_syserror ("restorezone"); + tzset(); + } +} + + SCM_PROC (s_localtime, "localtime", 1, 1, 0, scm_localtime); SCM scm_localtime (SCM time, SCM zone) @@ -244,27 +293,12 @@ scm_localtime (SCM time, SCM zone) SCM result; int zoff; char *zname = 0; - char *tzvar = "TZ"; - char *oldtz = 0; + char *oldtz; int err; itime = scm_num2long (time, (char *) SCM_ARG1, s_localtime); SCM_DEFER_INTS; - if (!SCM_UNBNDP (zone)) - { - char *buf; - - /* if zone was supplied, set the environment variable TZ temporarily. */ - SCM_ASSERT (SCM_NIMP (zone) && SCM_STRINGP (zone), zone, SCM_ARG2, - s_localtime); - buf = malloc (SCM_LENGTH (zone) + 4); - if (buf == 0) - scm_memory_error (s_localtime); - oldtz = getenv (tzvar); - sprintf (buf, "%s=%s", tzvar, SCM_CHARS (zone)); - putenv (buf); - tzset(); - } + oldtz = setzone (zone, SCM_ARG2, s_localtime); lt = localtime (&itime); err = errno; utc = gmtime (&itime); @@ -272,25 +306,22 @@ scm_localtime (SCM time, SCM zone) err = errno; if (lt) { +#ifdef HAVE_TM_ZONE + zname = lt->tm_zone; +#else +# ifdef HAVE_TZNAME /* must be copied before calling tzset again. */ char *ptr = tzname[ (lt->tm_isdst == 1) ? 1 : 0 ]; zname = scm_must_malloc (strlen (ptr) + 1, s_localtime); strcpy (zname, ptr); +#endif +#endif } - if (!SCM_UNBNDP (zone)) - { - /* restore the old environment value of TZ. */ - if (oldtz) - putenv (oldtz - 3); - else - putenv (tzvar); - tzset(); - } + restorezone (zone, oldtz); + /* delayed until zone has been restored. */ errno = err; - if (utc == NULL) - scm_syserror (s_localtime); - if (lt == NULL) + if (utc == NULL || lt == NULL) scm_syserror (s_localtime); /* calculate timezone offset in seconds west of UTC. */ @@ -309,7 +340,6 @@ scm_localtime (SCM time, SCM zone) SCM_ALLOW_INTS; return result; } -#endif SCM_PROC (s_gmtime, "gmtime", 1, 0, 0, scm_gmtime); SCM @@ -329,41 +359,79 @@ scm_gmtime (SCM time) return result; } -#if 0 -SCM_PROC (s_mktime, "mktime", 1, 0, 0, scm_mktime); -SCM -scm_mktime (SCM sbd_time) +/* copy time components from a Scheme object to a struct tm. */ +static void +bdtime2c (SCM sbd_time, struct tm *lt, int pos, char *subr) { - timet itime; - struct tm lt, *utc; - SCM result; - int zoff; - char *zname; - - SCM_ASSERT (SCM_VECTORP (sbd_time), sbd_time, SCM_ARG1, s_mktime); - SCM_ASSERT (SCM_INUMP (SCM_VELTS (sbd_time)[0]) + SCM_ASSERT (SCM_NIMP (sbd_time) && SCM_VECTORP (sbd_time) + && scm_obj_length (sbd_time) == 11 + && SCM_INUMP (SCM_VELTS (sbd_time)[0]) && SCM_INUMP (SCM_VELTS (sbd_time)[1]) && SCM_INUMP (SCM_VELTS (sbd_time)[2]) && SCM_INUMP (SCM_VELTS (sbd_time)[3]) && SCM_INUMP (SCM_VELTS (sbd_time)[4]) && SCM_INUMP (SCM_VELTS (sbd_time)[5]) + && SCM_INUMP (SCM_VELTS (sbd_time)[6]) + && SCM_INUMP (SCM_VELTS (sbd_time)[7]) && SCM_INUMP (SCM_VELTS (sbd_time)[8]), - sbd_time, SCM_ARG1, s_mktime); - lt.tm_sec = SCM_INUM (SCM_VELTS (sbd_time)[0]); - lt.tm_min = SCM_INUM (SCM_VELTS (sbd_time)[1]); - lt.tm_hour = SCM_INUM (SCM_VELTS (sbd_time)[2]); - lt.tm_mday = SCM_INUM (SCM_VELTS (sbd_time)[3]); - lt.tm_mon = SCM_INUM (SCM_VELTS (sbd_time)[4]); - lt.tm_year = SCM_INUM (SCM_VELTS (sbd_time)[5]); - lt.tm_isdst = SCM_INUM (SCM_VELTS (sbd_time)[8]); + sbd_time, pos, subr); + lt->tm_sec = SCM_INUM (SCM_VELTS (sbd_time)[0]); + lt->tm_min = SCM_INUM (SCM_VELTS (sbd_time)[1]); + lt->tm_hour = SCM_INUM (SCM_VELTS (sbd_time)[2]); + lt->tm_mday = SCM_INUM (SCM_VELTS (sbd_time)[3]); + lt->tm_mon = SCM_INUM (SCM_VELTS (sbd_time)[4]); + lt->tm_year = SCM_INUM (SCM_VELTS (sbd_time)[5]); + lt->tm_wday = SCM_INUM (SCM_VELTS (sbd_time)[6]); + lt->tm_yday = SCM_INUM (SCM_VELTS (sbd_time)[7]); + lt->tm_isdst = SCM_INUM (SCM_VELTS (sbd_time)[8]); +} + +SCM_PROC (s_mktime, "mktime", 1, 1, 0, scm_mktime); +SCM +scm_mktime (SCM sbd_time, SCM zone) +{ + timet itime; + struct tm lt, *utc; + SCM result; + int zoff; + char *zname = 0; + char *oldtz = 0; + int err; + + SCM_ASSERT (SCM_NIMP (sbd_time) && SCM_VECTORP (sbd_time), sbd_time, + SCM_ARG1, s_mktime); + bdtime2c (sbd_time, <, SCM_ARG1, s_mktime); SCM_DEFER_INTS; + oldtz = setzone (zone, SCM_ARG2, s_mktime); itime = mktime (<); - if (itime == -1) - scm_syserror (s_mktime); + err = errno; /* timezone offset in seconds west of UTC. */ utc = gmtime (&itime); + if (utc == NULL) + err = errno; + + if (itime != -1) + { +#ifdef HAVE_TM_ZONE + zname = lt->tm_zone; +#else +# ifdef HAVE_TZNAME + /* must be copied before calling tzset again. */ + char *ptr = tzname[ (lt.tm_isdst == 1) ? 1 : 0 ]; + + zname = scm_must_malloc (strlen (ptr) + 1, s_mktime); + strcpy (zname, ptr); +#endif +#endif + } + restorezone (zone, oldtz); + /* delayed until zone has been restored. */ + errno = err; + if (utc == NULL || itime == -1) + scm_syserror (s_mktime); + zoff = (utc->tm_hour - lt.tm_hour) * 3600 + (utc->tm_min - lt.tm_min) * 60 + utc->tm_sec - lt.tm_sec; if (utc->tm_year < lt.tm_year) @@ -375,15 +443,11 @@ scm_mktime (SCM sbd_time) else if (utc->tm_yday > lt.tm_yday) zoff += 24 * 60 * 60; - /* timezone name. */ - zname = tzname[ (lt.tm_isdst == 1) ? 1 : 0 ]; - result = scm_cons (scm_long2num ((long) itime), filltime (<, zoff, zname)); SCM_ALLOW_INTS; return result; } -#endif SCM_PROC (s_tzset, "tzset", 0, 0, 0, scm_tzset); SCM @@ -393,6 +457,81 @@ scm_tzset (void) return SCM_UNSPECIFIED; } +SCM_PROC (s_strftime, "strftime", 2, 0, 0, scm_strftime); + +SCM +scm_strftime (format, stime) + SCM format; + SCM stime; +{ + struct tm t; + + char *tbuf; + int size = 50; + char *fmt; + int len; + + SCM_ASSERT (SCM_NIMP (format) && SCM_STRINGP (format), format, SCM_ARG1, + s_strftime); + bdtime2c (stime, &t, SCM_ARG2, s_strftime); + + fmt = SCM_ROCHARS (format); + len = SCM_ROLENGTH (format); + + tbuf = scm_must_malloc (size, s_strftime); + while ((len = strftime (tbuf, size, fmt, &t)) == size) + { + scm_must_free (tbuf); + size *= 2; + tbuf = scm_must_malloc (size, s_strftime); + } + return scm_makfromstr (tbuf, len, 0); +} + +SCM_PROC (s_strptime, "strptime", 2, 0, 0, scm_strptime); + +SCM +scm_strptime (format, string) + SCM format; + SCM string; +{ +#ifdef HAVE_STRPTIME + struct tm t; + char *fmt, *str, *rest; + + SCM_ASSERT (SCM_NIMP (format) && SCM_ROSTRINGP (format), format, SCM_ARG1, + s_strptime); + SCM_ASSERT (SCM_NIMP (string) && SCM_ROSTRINGP (string), string, SCM_ARG2, + s_strptime); + + fmt = SCM_ROCHARS (format); + str = SCM_ROCHARS (string); + + /* initialize the struct tm */ +#define tm_init(field) t.field = 0 + tm_init (tm_sec); + tm_init (tm_min); + tm_init (tm_hour); + tm_init (tm_mday); + tm_init (tm_mon); + tm_init (tm_year); + tm_init (tm_wday); + tm_init (tm_yday); +#undef tm_init + + t.tm_isdst = -1; + SCM_DEFER_INTS; + if ((rest = strptime (str, fmt, &t)) == NULL) + scm_syserror (s_strptime); + + SCM_ALLOW_INTS; + return scm_cons (filltime (&t, 0, NULL), SCM_MAKINUM (rest - str)); + +#else + scm_sysmissing (s_strptime); +#endif +} + void scm_init_stime() { diff --git a/libguile/stime.h b/libguile/stime.h index 6acee3a8e..d25f8378b 100644 --- a/libguile/stime.h +++ b/libguile/stime.h @@ -53,8 +53,10 @@ extern SCM scm_current_time SCM_P ((void)); extern SCM scm_gettimeofday (void); extern SCM scm_localtime (SCM time, SCM zone); extern SCM scm_gmtime (SCM time); -extern SCM scm_mktime (SCM sbd_time); +extern SCM scm_mktime (SCM sbd_time, SCM zone); extern SCM scm_tzset (void); +extern SCM scm_strftime SCM_P ((SCM format, SCM stime)); +extern SCM scm_strptime SCM_P ((SCM format, SCM string)); extern void scm_init_stime SCM_P ((void)); #endif /* TIMEH */ |