From: PatR Date: Wed, 25 Aug 2021 21:14:23 +0000 (-0700) Subject: elapsed time handling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b1f3d1f864d744fdae1ba4b77a789a953af7557c;p=nethack elapsed time handling 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. --- diff --git a/include/extern.h b/include/extern.h index 0a6eb66bf..3305405b6 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 ### */ diff --git a/src/allmain.c b/src/allmain.c index 47eefbb34..05e0e5a1f 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -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*/ diff --git a/src/end.c b/src/end.c index ac9cfd6d5..640350ce3 100644 --- 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(); diff --git a/src/save.c b/src/save.c index 6334edee0..285dc10b9 100644 --- a/src/save.c +++ b/src/save.c @@ -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); diff --git a/src/topten.c b/src/topten.c index 11aa6129f..a57f09b70 100644 --- a/src/topten.c +++ b/src/topten.c @@ -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);