[m-rev.] for review: improve error checking in the time module
Zoltan Somogyi
zoltan.somogyi at runbox.com
Mon Aug 9 02:00:15 AEST 2021
On Sun, 8 Aug 2021 23:25:58 +1000 (AEST), Julien Fischer <jfischer at opturion.com> wrote:
> @@ -205,7 +206,10 @@
> #include <unistd.h>
> #endif
>
> - #include ""mercury_timing.h"" // for MR_CLOCK_TICKS_PER_SECOND
> + #include ""mercury_timing.h"" // for MR_CLOCK_TICKS_PER_SECOND
> + #include ""mercury_runtime_util.h"" // For MR_sterror.
MR_stRerror
> localtime(Time, TM, !IO) :-
> Time = time_t(RawTime),
> - c_localtime(RawTime, Yr, Mnt, MD, Hrs, Min, Sec, YD, WD, N, !IO),
> - TM = tm(Yr, Mnt, MD, Hrs, Min, Sec, YD, WD, int_to_maybe_dst(N)).
> + c_localtime(RawTime, IsOk, Yr, Mnt, MD, Hrs, Min, Sec, YD, WD, N,
> + ErrorMsg, !IO),
You may want to rename c_X to something like target_X, since it is
a bit surprising to have a non-C foreign proc for something whose name
implies it is specifically for C.
> @@ -647,27 +704,37 @@ gmtime(time_t(Time)) = TM :-
> t = Time;
>
> p = gmtime(&t);
> -
> - // XXX do we need to handle the case where p == NULL here?
> -
> - Sec = (MR_Integer) p->tm_sec;
> - Min = (MR_Integer) p->tm_min;
> - Hrs = (MR_Integer) p->tm_hour;
> - Mnt = (MR_Integer) p->tm_mon;
> - Yr = (MR_Integer) p->tm_year;
> - WD = (MR_Integer) p->tm_wday;
> - MD = (MR_Integer) p->tm_mday;
> - YD = (MR_Integer) p->tm_yday;
> - N = (MR_Integer) p->tm_isdst;
> + if (p == NULL) {
> + char errbuf[MR_STRERROR_BUF_SIZE];
> + const char *errno_msg;
> + IsOk = MR_NO;
> + errno_msg = MR_strerror(errno, errbuf, sizeof(errbuf));
> + MR_save_transient_hp();
> + MR_make_aligned_string_copy(ErrorMsg, errno_msg);
> + MR_restore_transient_hp();
> + } else {
> + IsOk = MR_YES;
> + Sec = (MR_Integer) p->tm_sec;
> + Min = (MR_Integer) p->tm_min;
> + Hrs = (MR_Integer) p->tm_hour;
> + Mnt = (MR_Integer) p->tm_mon;
> + Yr = (MR_Integer) p->tm_year;
> + WD = (MR_Integer) p->tm_wday;
> + MD = (MR_Integer) p->tm_mday;
> + YD = (MR_Integer) p->tm_yday;
> + N = (MR_Integer) p->tm_isdst;
> + ErrorMsg = MR_make_string_const(\"\");
> + }
You should be consistent about whether you fill in
the "success" output args if IsOk = no. Either do it
in all the foreign procs that return IsOk, or none of them.
Likewise, set ErrorMsg to "" either in all the IsOk = yes cases,
or none of them.
> - if (N == 1 & !isDST) {
> - // If the time we constructed is not in daylight savings time, but it
> - // should be, we need to subtract the DSTSavings.
> - java.time.Duration savings = rules.getDaylightSavings(Time0);
> - Time = Time0.minus(savings);
> - if (!rules.isDaylightSavings(Time)) {
> - throw new RuntimeException(
> - ""time.mktime: failed to correct for DST"");
> + try {
> + java.time.ZoneId tz = java.time.ZoneId.systemDefault();
> + java.time.Instant Time0 = java.time.ZonedDateTime.of(
> + java.time.LocalDateTime.of(Yr + 1900, Mnt + 1, MD, Hrs, Min, Sec),
> + tz).toInstant();
Seeing "tz)" at the *start* of a line is jarring.
I am not familiar with the non-C primitives some of this code
is calling, but as far as I can tell, the rest is fine.
Zoltan.
More information about the reviews
mailing list