From 409a6daf22b593bc9dfd27ce019c9ff48d3df486 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Fri, 12 Jul 2024 12:16:22 +0200 Subject: [PATCH] Simplify timestamp decoding * src/timefns.c (current_time_in_form, time_spec_invalid): New. (enum timeform): Remove TIMEFORM_INVALID. (decode_time_components): Move handling of TIMEFORM_INVALID, TIMEFORM_TICKS_HZ and TIMEFORM_NIL... (decode_lisp_time): ...here, avoiding the detour. (cherry picked from commit b23ab371756b5f77f62020cdfda5fe7b6fb04470) --- src/timefns.c | 81 ++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/src/timefns.c b/src/timefns.c index 1e551009df8..7b8107ee12e 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -357,6 +357,12 @@ time_overflow (void) error ("Specified time is not representable"); } +static AVOID +time_spec_invalid (void) +{ + error ("Invalid time specification"); +} + static AVOID time_error (int err) { @@ -364,7 +370,7 @@ time_error (int err) { case ENOMEM: memory_full (SIZE_MAX); case EOVERFLOW: time_overflow (); - default: error ("Invalid time specification"); + default: time_spec_invalid (); } } @@ -844,7 +850,6 @@ struct err_time /* Lisp timestamp classification. */ enum timeform { - TIMEFORM_INVALID = 0, TIMEFORM_HI_LO, /* seconds in the form (HI << LO_TIME_BITS) + LO. */ TIMEFORM_HI_LO_US, /* seconds plus microseconds (HI LO US) */ TIMEFORM_NIL, /* current time in nanoseconds */ @@ -853,10 +858,8 @@ enum timeform TIMEFORM_TICKS_HZ /* fractional time: HI is ticks, LO is ticks per second */ }; -/* From the non-float form FORM and the time components HIGH, LOW, USEC - and PSEC, generate the corresponding time value in CFORM form. If LOW is - floating point, the other components should be zero and FORM should - not be TIMEFORM_TICKS_HZ. +/* From the time components HIGH, LOW, USEC and PSEC, + generate the corresponding time value in CFORM form. Return a (0, valid timestamp) pair if successful, an (error number, unspecified timestamp) pair otherwise. */ @@ -870,30 +873,10 @@ decode_time_components (enum timeform form, switch (form) { - case TIMEFORM_INVALID: - return (struct err_time) { .err = EINVAL }; - case TIMEFORM_TICKS_HZ: - if (! (INTEGERP (high) - && (FIXNUMP (low) ? 0 < XFIXNUM (low) : !NILP (Fnatnump (low))))) - return (struct err_time) { .err = EINVAL }; - ticks = high; - hz = low; - break; - case TIMEFORM_FLOAT: - eassume (false); - case TIMEFORM_NIL: - { - struct timespec now = current_timespec (); - if (FASTER_TIMEFNS - && (cform == CFORM_TIMESPEC || cform == CFORM_SECS_ONLY)) - return (struct err_time) { .time = { .ts = now } }; - ticks = timespec_ticks (now); - hz = timespec_hz; - } - break; + eassume (false); case TIMEFORM_HI_LO: hz = make_fixnum (1); @@ -1022,6 +1005,17 @@ struct form_time union c_time time; }; +/* Current time (seconds since epoch) in form CFORM. */ +static union c_time +current_time_in_form (enum cform cform) +{ + struct timespec now = current_timespec (); + return ((FASTER_TIMEFNS + && (cform == CFORM_TIMESPEC || cform == CFORM_SECS_ONLY)) + ? (union c_time) {.ts = now} + : decode_ticks_hz (timespec_ticks (now), timespec_hz, cform)); +} + /* Decode a Lisp timestamp SPECIFIED_TIME that represents a time. Return a (form, time) pair that is the form of SPECIFIED-TIME @@ -1033,15 +1027,29 @@ struct form_time static struct form_time decode_lisp_time (Lisp_Object specified_time, enum cform cform) { + /* specified_time is one of: + + nil + current time + NUMBER + that number of seconds + (A . B) ; A, B : integer, B>0 + A/B s + (A B C D) ; A, B : integer, C, D : fixnum + (A * 2**16 + B + C / 10**6 + D / 10**12) s + */ + + if (NILP (specified_time)) + return (struct form_time) {.form = TIMEFORM_NIL, + .time = current_time_in_form (cform) }; + Lisp_Object high = make_fixnum (0); Lisp_Object low = specified_time; Lisp_Object usec = make_fixnum (0); Lisp_Object psec = make_fixnum (0); enum timeform form = TIMEFORM_HI_LO; - if (NILP (specified_time)) - form = TIMEFORM_NIL; - else if (CONSP (specified_time)) + if (CONSP (specified_time)) { high = XCAR (specified_time); low = XCDR (specified_time); @@ -1072,13 +1080,14 @@ decode_lisp_time (Lisp_Object specified_time, enum cform cform) } else { - form = TIMEFORM_TICKS_HZ; + /* (TICKS . HZ) */ + if (!(INTEGERP (high) && (FIXNUMP (low) ? XFIXNUM (low) > 0 + : !NILP (Fnatnump (low))))) + time_spec_invalid (); + return (struct form_time) { .form = TIMEFORM_TICKS_HZ, + .time = decode_ticks_hz (high, low, + cform) }; } - - /* Require LOW to be an integer, as otherwise the computation - would be considerably trickier. */ - if (! INTEGERP (low)) - form = TIMEFORM_INVALID; } else if (FASTER_TIMEFNS && INTEGERP (specified_time)) return (struct form_time) -- 2.39.2