diff options
| author | Mattias EngdegÄrd | 2024-07-12 12:16:22 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2024-07-13 11:33:44 +0200 |
| commit | b23ab371756b5f77f62020cdfda5fe7b6fb04470 (patch) | |
| tree | 6453eab80d09bfe83cd5cfb86e9441af4a239b77 /src | |
| parent | 900f135b68b4e9830eac5d7500b3175f160f6c34 (diff) | |
| download | emacs-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.c | 81 |
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 | ||
| 360 | static AVOID | 360 | static AVOID |
| 361 | time_spec_invalid (void) | ||
| 362 | { | ||
| 363 | error ("Invalid time specification"); | ||
| 364 | } | ||
| 365 | |||
| 366 | static AVOID | ||
| 361 | time_error (int err) | 367 | time_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. */ |
| 845 | enum timeform | 851 | enum 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. */ | ||
| 1009 | static union c_time | ||
| 1010 | current_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 | |||
| 1033 | static struct form_time | 1027 | static struct form_time |
| 1034 | decode_lisp_time (Lisp_Object specified_time, enum cform cform) | 1028 | decode_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) |