diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rwxr-xr-x | configure | 86 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | lib.c | 52 | ||||
-rw-r--r-- | lib.h | 3 | ||||
-rw-r--r-- | txr.1 | 12 |
6 files changed, 160 insertions, 14 deletions
@@ -1,3 +1,23 @@ +2013-11-29 Kaz Kylheku <kaz@kylheku.com> + + * configure (config_flags): New variable, allowing us to + have stricter diagnosis for configure tests. + (have_timegm, need_svid_source, need_bsd_source): New + variables. sys/stat.h test only declares static data and + compiles an object file. Adding tests for timegm, tzset, + setenv and unsetenv. + + * eval.c (eval_init): Register new intrinsic, make_time_utc. + + * lib.c (make_time_impl): New static function. + (make_time): Reimplemented as call to make_time_impl. + (timegm_hack): New conditionally-defined static function. + (make_time_utc): New function. + + * lib.h (make_time_utc): Declared. + + * txr.1: make-time-utc documented. + 2013-11-28 Kaz Kylheku <kaz@kylheku.com> * lib.c (make_time): We must subtract from the 1-12 @@ -84,6 +84,7 @@ opt_flags=-O2 lang_flags='-ansi -D_XOPEN_SOURCE=2' diag_flags='-Wall -Wmissing-prototypes -Wstrict-prototypes' debug_flags=-g +config_flags=' -Werror' # special: used only during configure inline= platform_flags= remove_flags= @@ -98,6 +99,9 @@ mpi_version=1.8.6 have_quilt= have_patch= have_unistd= +have_timegm= +need_svid_source= +need_bsd_source= # # Parse configuration variables @@ -583,7 +587,7 @@ NM := $nm OPT_FLAGS := $opt_flags LANG_FLAGS := $lang_flags -DIAG_FLAGS := $diag_flags +DIAG_FLAGS := $diag_flags$config_flags DBG_FLAGS := $debug_flags PLATFORM_FLAGS := $platform_flags REMOVE_FLAGS := $remove_flags @@ -1152,14 +1156,10 @@ printf "Checking whether we have <sys/stat.h> ... " cat > conftest.c <<! #include <sys/stat.h> -int main(void) -{ - struct stat s; - return 0; -} +struct stat s; ! rm -f conftest -if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then +if ! $make conftest.o > conftest.err 2>&1; then printf "no\n" else printf "yes\n" @@ -1250,7 +1250,7 @@ fi # Check for fields inside struct tm # -printf "Printf detecting timezone fields in struct tm ..." +printf "Printf detecting timezone fields in struct tm ... " tm_gmtoff= tm_tmzone= @@ -1283,6 +1283,69 @@ done printf "done\n" +printf "Checking for timegm function ... " + +cat > conftest.c <<! +#include <time.h> + +int main(void) +{ + struct tm tms = { 0 }; + timegm(&tms); + return 0; +} +! +rm -f conftest +if ! $make EXTRA_FLAGS='-D_SVID_SOURCE' conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then + printf "no\n" +else + printf "yes\n" + printf "#define HAVE_TIMEGM 1\n" >> config.h + have_timegm=y + need_svid_source=y +fi + +if [ -z "$have_timegm" ] ; then + printf "Checking for setenv and unsetenv functions ... " + + cat > conftest.c <<! +#include <stdlib.h> + +int main(void) +{ + setenv("TERM", "foo", 1); + unsetenv("TERM"); + return 0; +} +! + rm -f conftest + if ! $make EXTRA_FLAGS='-D_BSD_SOURCE' conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then + printf "no\n" + else + printf "yes\n" + printf "#define HAVE_SETENV 1\n" >> config.h + need_bsd_source=y + fi +fi +printf "Checking for tzset function ... " + +cat > conftest.c <<! +#include <time.h> + +int main(void) +{ + tzset(); + return 0; +} +! +rm -f conftest +if ! $make conftest > conftest.err 2>&1 || ! [ -x conftest ] ; then + printf "no\n" +else + printf "yes\n" + printf "#define HAVE_TZSET 1\n" >> config.h +fi + printf "Checking for POSIX sleep function ... " cat > conftest.c <<! @@ -1423,6 +1486,13 @@ fi # printf "Regenerating config.make ... " +config_flags= +if [ -n "$need_svid_source" ] ; then + lang_flags="$lang_flags -D_SVID_SOURCE" +fi +if [ -n "$need_bsd_source" ] ; then + lang_flags="$lang_flags -D_BSD_SOURCE" +fi gen_config_make printf "done\n" @@ -2548,6 +2548,7 @@ void eval_init(void) reg_fun(intern(lit("time-string-local"), user_package), func_n2(time_string_local)); reg_fun(intern(lit("time-string-utc"), user_package), func_n2(time_string_utc)); reg_fun(intern(lit("make-time"), user_package), func_n7(make_time)); + reg_fun(intern(lit("make-time-utc"), user_package), func_n7(make_time_utc)); reg_fun(intern(lit("errno"), user_package), func_n1o(errno_wrap, 0)); reg_fun(intern(lit("daemon"), user_package), func_n2(daemon_wrap)); @@ -5027,9 +5027,10 @@ val time_string_utc(val time, val format) return timestr; } -val make_time(val year, val month, val day, - val hour, val minute, val second, - val isdst) +static val make_time_impl(time_t (*pmktime)(struct tm *), + val year, val month, val day, + val hour, val minute, val second, + val isdst) { struct tm local = { 0 }; time_t time; @@ -5048,11 +5049,54 @@ val make_time(val year, val month, val day, else local.tm_isdst = 1; - time = mktime(&local); + time = pmktime(&local); return time == -1 ? nil : num(time); } +val make_time(val year, val month, val day, + val hour, val minute, val second, + val isdst) +{ + return make_time_impl(mktime, year, month, day, hour, minute, second, isdst); +} + +#if !HAVE_TIMEGM +static time_t timegm_hack(struct tm *tm) +{ + time_t ret; + char *tz; + + tz = getenv("TZ"); + setenv("TZ", "UTC", 1); +#if HAVE_TZSET + tzset(); +#endif + ret = mktime(tm); + if (tz) + setenv("TZ", tz, 1); + else + unsetenv("TZ"); +#if HAVE_TZSET + tzset(); +#endif + return ret; +} +#endif + +val make_time_utc(val year, val month, val day, + val hour, val minute, val second, + val isdst) +{ +#if HAVE_TIMEGM + time_t (*pmktime)(struct tm *) = timegm; +#else + time_t (*pmktime)(struct tm *) = timegm_hack; +#endif + + return make_time_impl(pmktime, year, month, day, hour, minute, second, isdst); +} + void init(const wchar_t *pn, mem_t *(*oom)(mem_t *, size_t), val *stack_bottom) { @@ -682,6 +682,9 @@ val time_string_utc(val time, val format); val make_time(val year, val month, val day, val hour, val minute, val second, val isdst); +val make_time_utc(val year, val month, val day, + val hour, val minute, val second, + val isdst); void init(const wchar_t *progname, mem_t *(*oom_realloc)(mem_t *, size_t), val *stack_bottom); @@ -1,4 +1,4 @@ -.\"Copyright (C) 2011, Kaz Kylheku <kaz@kylheku.com>. +.\"Copyright (C) 20114 Kaz Kylheku <kaz@kylheku.com>. .\"All rights reserved. .\" .\"BSD License: @@ -10775,12 +10775,13 @@ the format string of the C library function strftime. The <time> argument is an integer representing seconds obtained from the time function or from the time-usec function. -.SS Function make-time +.SS Functions make-time and make-time-utc .TP Syntax: (make-time <year> <month> <day> <hour> <minute> <second> <dst-advice>) + (make-time-utc <year> <month> <day> <hour> <minute> <second> <dst-advice>) .TP Description @@ -10800,6 +10801,13 @@ If the argument is nil, then the time is assumed not to be in DST. If <dst-advice> is :auto, then the function tries to determine whether DST is in effect in the current time zone for the specified date and time. +The make-time-utc function is similar to make-time, except that +it treats the time as UTC rather than in the local time zone. +The <dst-advice> argument is supported by make-time-utc for function +call compatibility with make-time. It may or may not have any effect +on the output (since the UTC zone by definition doesn't have daylight +savings time). + .SH UNIX PROGRAMMING .SS Functions errno and set-errno |