]> granicus.if.org Git - nethack/commitdiff
elapsed time handling
authorPatR <rankin@nethack.org>
Wed, 25 Aug 2021 21:14:23 +0000 (14:14 -0700)
committerPatR <rankin@nethack.org>
Wed, 25 Aug 2021 21:14:23 +0000 (14:14 -0700)
The code has been assuming that time_t is some number of seconds.
That's valid for traditional Unix systems and for Posix compliant
systems but is not something guaranteed by the C standard.  (We ran
into a long time ago when trying out an alternate way to calculate
phase of moon.  That code made a similar assumption and broke one
of the ports.)

'ubirthday' also warrants being re-done but I've run out of energy.

include/extern.h
src/allmain.c
src/end.c
src/save.c
src/topten.c

index 0a6eb66bf4f294b0798640893295464ff2b7221b..3305405b60e50bf048d9e6b462ee8e26e86a28f9 100644 (file)
@@ -18,15 +18,16 @@ extern char *fmt_ptr(const void *);
 
 /* ### allmain.c ### */
 
+extern void early_init(void);
 extern void moveloop_core(void);
 extern void moveloop(boolean);
 extern void stop_occupation(void);
 extern void display_gamewindows(void);
 extern void newgame(void);
 extern void welcome(boolean);
-extern time_t get_realtime(void);
 extern int argcheck(int, char **, enum earlyarg);
-extern void early_init(void);
+extern long timet_to_seconds(time_t);
+extern long timet_delta(time_t, time_t);
 
 /* ### apply.c ### */
 
index 47eefbb34abdbac2096e9c319406b61d5fbdb20e..05e0e5a1f16fdcbedb33b94a9282b4c0bb9fb11e 100644 (file)
@@ -964,6 +964,24 @@ debug_fields(const char *opts)
     return;
 }
 
+/* convert from time_t to number of seconds */
+long
+timet_to_seconds(time_t ttim)
+{
+    /* for Unix-based and Posix-compliant systems, a cast to 'long' would
+       suffice but the C Standard doesn't require time_t to be that simple */
+    return timet_delta(ttim, (time_t) 0);
+}
+
+/* calculate the difference in seconds between two time_t values */
+long
+timet_delta(time_t etim, time_t stim) /* end and start times */
+{
+    /* difftime() is a STDC routine which returns the number of seconds
+       between two time_t values as a 'double' */
+    return (long) difftime(etim, stim);
+}
+
 #ifndef NODUMPENUMS
 void
 dump_enums(void)
@@ -1018,4 +1036,5 @@ dump_enums(void)
     raw_print("");
 }
 #endif /* NODUMPENUMS */
+
 /*allmain.c*/
index ac9cfd6d51ecea816eb74023367660dc60ad03f6..640350ce3f6860ef5ca033fa3c5d01cb7de9d193 100644 (file)
--- a/src/end.c
+++ b/src/end.c
@@ -1273,7 +1273,7 @@ really_done(int how)
        topten figure it out separately and possibly getting different
        time or even day if player is slow responding to --More-- */
     urealtime.finish_time = endtime = getnow();
-    urealtime.realtime += (long) (endtime - urealtime.start_timing);
+    urealtime.realtime += timet_delta(endtime, urealtime.start_timing);
     /* collect these for end of game disclosure (not used during play) */
     iflags.at_night = night();
     iflags.at_midnight = midnight();
index 6334edee06fdabf84ce53b8caed444d0d6efe594..285dc10b9d701e77bc3cb58ee923db8410bec0b5 100644 (file)
@@ -244,8 +244,8 @@ savegamestate(NHFILE* nhfp)
         bwrite(nhfp->fd, (genericptr_t) &flags, sizeof flags);
     }
     urealtime.finish_time = getnow();
-    urealtime.realtime += (long) (urealtime.finish_time
-                                    - urealtime.start_timing);
+    urealtime.realtime += timet_delta(urealtime.finish_time,
+                                      urealtime.start_timing);
     if (nhfp->structlevel) {
         bwrite(nhfp->fd, (genericptr_t) &u, sizeof u);
         bwrite(nhfp->fd, yyyymmddhhmmss(ubirthday), 14);
index 11aa6129fd15f4f59e2b479471a177a200300f89..a57f09b70986d9ed6889e4a4eb38aa6d387a4f84 100644 (file)
@@ -367,8 +367,9 @@ writexlentry(FILE* rfile, struct toptenentry* tt, int how)
     Fprintf(rfile, "%cachieveX=%s", XLOG_SEP, encode_extended_achievements());
     Fprintf(rfile, "%cconductX=%s", XLOG_SEP, encode_extended_conducts());
     Fprintf(rfile, "%crealtime=%ld%cstarttime=%ld%cendtime=%ld", XLOG_SEP,
-            (long) urealtime.realtime, XLOG_SEP,
-            (long) ubirthday, XLOG_SEP, (long) urealtime.finish_time);
+            urealtime.realtime, XLOG_SEP,
+            timet_to_seconds(ubirthday), XLOG_SEP,
+            timet_to_seconds(urealtime.finish_time));
     Fprintf(rfile, "%cgender0=%s%calign0=%s", XLOG_SEP,
             genders[flags.initgend].filecode, XLOG_SEP,
             aligns[1 - u.ualignbase[A_ORIGINAL]].filecode);