aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2024-07-12 12:16:22 +0200
committerMattias EngdegÄrd2024-07-13 11:33:44 +0200
commitb23ab371756b5f77f62020cdfda5fe7b6fb04470 (patch)
tree6453eab80d09bfe83cd5cfb86e9441af4a239b77 /src
parent900f135b68b4e9830eac5d7500b3175f160f6c34 (diff)
downloademacs-b23ab371756b5f77f62020cdfda5fe7b6fb04470.tar.gz
emacs-b23ab371756b5f77f62020cdfda5fe7b6fb04470.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/timefns.c81
1 files 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
@@ -358,13 +358,19 @@ time_overflow (void)
358} 358}
359 359
360static AVOID 360static AVOID
361time_spec_invalid (void)
362{
363 error ("Invalid time specification");
364}
365
366static AVOID
361time_error (int err) 367time_error (int err)
362{ 368{
363 switch (err) 369 switch (err)
364 { 370 {
365 case ENOMEM: memory_full (SIZE_MAX); 371 case ENOMEM: memory_full (SIZE_MAX);
366 case EOVERFLOW: time_overflow (); 372 case EOVERFLOW: time_overflow ();
367 default: error ("Invalid time specification"); 373 default: time_spec_invalid ();
368 } 374 }
369} 375}
370 376
@@ -844,7 +850,6 @@ struct err_time
844/* Lisp timestamp classification. */ 850/* Lisp timestamp classification. */
845enum timeform 851enum timeform
846 { 852 {
847 TIMEFORM_INVALID = 0,
848 TIMEFORM_HI_LO, /* seconds in the form (HI << LO_TIME_BITS) + LO. */ 853 TIMEFORM_HI_LO, /* seconds in the form (HI << LO_TIME_BITS) + LO. */
849 TIMEFORM_HI_LO_US, /* seconds plus microseconds (HI LO US) */ 854 TIMEFORM_HI_LO_US, /* seconds plus microseconds (HI LO US) */
850 TIMEFORM_NIL, /* current time in nanoseconds */ 855 TIMEFORM_NIL, /* current time in nanoseconds */
@@ -853,10 +858,8 @@ enum timeform
853 TIMEFORM_TICKS_HZ /* fractional time: HI is ticks, LO is ticks per second */ 858 TIMEFORM_TICKS_HZ /* fractional time: HI is ticks, LO is ticks per second */
854 }; 859 };
855 860
856/* From the non-float form FORM and the time components HIGH, LOW, USEC 861/* From the time components HIGH, LOW, USEC and PSEC,
857 and PSEC, generate the corresponding time value in CFORM form. If LOW is 862 generate the corresponding time value in CFORM form.
858 floating point, the other components should be zero and FORM should
859 not be TIMEFORM_TICKS_HZ.
860 863
861 Return a (0, valid timestamp) pair if successful, an (error number, 864 Return a (0, valid timestamp) pair if successful, an (error number,
862 unspecified timestamp) pair otherwise. */ 865 unspecified timestamp) pair otherwise. */
@@ -870,30 +873,10 @@ decode_time_components (enum timeform form,
870 873
871 switch (form) 874 switch (form)
872 { 875 {
873 case TIMEFORM_INVALID:
874 return (struct err_time) { .err = EINVAL };
875
876 case TIMEFORM_TICKS_HZ: 876 case TIMEFORM_TICKS_HZ:
877 if (! (INTEGERP (high)
878 && (FIXNUMP (low) ? 0 < XFIXNUM (low) : !NILP (Fnatnump (low)))))
879 return (struct err_time) { .err = EINVAL };
880 ticks = high;
881 hz = low;
882 break;
883
884 case TIMEFORM_FLOAT: 877 case TIMEFORM_FLOAT:
885 eassume (false);
886
887 case TIMEFORM_NIL: 878 case TIMEFORM_NIL:
888 { 879 eassume (false);
889 struct timespec now = current_timespec ();
890 if (FASTER_TIMEFNS
891 && (cform == CFORM_TIMESPEC || cform == CFORM_SECS_ONLY))
892 return (struct err_time) { .time = { .ts = now } };
893 ticks = timespec_ticks (now);
894 hz = timespec_hz;
895 }
896 break;
897 880
898 case TIMEFORM_HI_LO: 881 case TIMEFORM_HI_LO:
899 hz = make_fixnum (1); 882 hz = make_fixnum (1);
@@ -1022,6 +1005,17 @@ struct form_time
1022 union c_time time; 1005 union c_time time;
1023}; 1006};
1024 1007
1008/* Current time (seconds since epoch) in form CFORM. */
1009static union c_time
1010current_time_in_form (enum cform cform)
1011{
1012 struct timespec now = current_timespec ();
1013 return ((FASTER_TIMEFNS
1014 && (cform == CFORM_TIMESPEC || cform == CFORM_SECS_ONLY))
1015 ? (union c_time) {.ts = now}
1016 : decode_ticks_hz (timespec_ticks (now), timespec_hz, cform));
1017}
1018
1025/* Decode a Lisp timestamp SPECIFIED_TIME that represents a time. 1019/* Decode a Lisp timestamp SPECIFIED_TIME that represents a time.
1026 1020
1027 Return a (form, time) pair that is the form of SPECIFIED-TIME 1021 Return a (form, time) pair that is the form of SPECIFIED-TIME
@@ -1033,15 +1027,29 @@ struct form_time
1033static struct form_time 1027static struct form_time
1034decode_lisp_time (Lisp_Object specified_time, enum cform cform) 1028decode_lisp_time (Lisp_Object specified_time, enum cform cform)
1035{ 1029{
1030 /* specified_time is one of:
1031
1032 nil
1033 current time
1034 NUMBER
1035 that number of seconds
1036 (A . B) ; A, B : integer, B>0
1037 A/B s
1038 (A B C D) ; A, B : integer, C, D : fixnum
1039 (A * 2**16 + B + C / 10**6 + D / 10**12) s
1040 */
1041
1042 if (NILP (specified_time))
1043 return (struct form_time) {.form = TIMEFORM_NIL,
1044 .time = current_time_in_form (cform) };
1045
1036 Lisp_Object high = make_fixnum (0); 1046 Lisp_Object high = make_fixnum (0);
1037 Lisp_Object low = specified_time; 1047 Lisp_Object low = specified_time;
1038 Lisp_Object usec = make_fixnum (0); 1048 Lisp_Object usec = make_fixnum (0);
1039 Lisp_Object psec = make_fixnum (0); 1049 Lisp_Object psec = make_fixnum (0);
1040 enum timeform form = TIMEFORM_HI_LO; 1050 enum timeform form = TIMEFORM_HI_LO;
1041 1051
1042 if (NILP (specified_time)) 1052 if (CONSP (specified_time))
1043 form = TIMEFORM_NIL;
1044 else if (CONSP (specified_time))
1045 { 1053 {
1046 high = XCAR (specified_time); 1054 high = XCAR (specified_time);
1047 low = XCDR (specified_time); 1055 low = XCDR (specified_time);
@@ -1072,13 +1080,14 @@ decode_lisp_time (Lisp_Object specified_time, enum cform cform)
1072 } 1080 }
1073 else 1081 else
1074 { 1082 {
1075 form = TIMEFORM_TICKS_HZ; 1083 /* (TICKS . HZ) */
1084 if (!(INTEGERP (high) && (FIXNUMP (low) ? XFIXNUM (low) > 0
1085 : !NILP (Fnatnump (low)))))
1086 time_spec_invalid ();
1087 return (struct form_time) { .form = TIMEFORM_TICKS_HZ,
1088 .time = decode_ticks_hz (high, low,
1089 cform) };
1076 } 1090 }
1077
1078 /* Require LOW to be an integer, as otherwise the computation
1079 would be considerably trickier. */
1080 if (! INTEGERP (low))
1081 form = TIMEFORM_INVALID;
1082 } 1091 }
1083 else if (FASTER_TIMEFNS && INTEGERP (specified_time)) 1092 else if (FASTER_TIMEFNS && INTEGERP (specified_time))
1084 return (struct form_time) 1093 return (struct form_time)