bug#81501: 30.2; Problems in timeclock log entry parsing

Eli Zaretskii <[email protected]> Sat, 01 Aug 2026 12:26:29 +0300
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
> From: Petteri Hintsanen <[email protected]>
> Date: Sun, 26 Jul 2026 18:19:19 +0300
> 
> In timeclock package clock in / out events may have comments attached to
> them.  These comments do not round-trip properly, that is, when they are
> saved to disk and later restored, comments are not necessary identical.
> 
> Specifically, the function timeclock-read-moment parses the timelog file
> for events.  timelog file format is described in the docstring of
> timeclock-log-data:
> 
>   "A timelog contains data in the form of a single entry per line.
>   Each entry has the form:
>   
>     CODE YYYY/MM/DD HH:MM:SS [COMMENT]
>   
>   CODE is one of: b, h, i, o or O.  COMMENT is optional when the code is
>   i, o or O."
> 
> timeclock-read-moment uses timeclock-moment-regexp for parsing event
> fields from each line.  This regexp has a couple of problems.  Given the
> following lines in timelog file (\n denotes newline character):
> 
> i 2026/07/25 20:56:44aaa\n
> o 2026/07/25 20:56:48   	bbb\n
> i 2026/07/25 21:03:21 ccc    \n
> o 2026/07/25 21:07:45\n
> 
> timeclock-read-moment will parse four events "aaa", "bbb", "ccc    ", and
> "".
> 
> "aaa" is wrong as there ought to be whitespace before the comment.
> "bbb" will lose its leading whitespace while
> "ccc    " will keep its trailing whitespace, which is inconsistent.
> These are minor problems.
> 
> The last event has no comment, but upon reading it will get an empty
> comment.  This is a real problem as it leads to subtle bugs in other
> timeclock functions.  For example, this recipe demonstrates buggy
> behavior with timeclock-status-string:
> 
> 1. emacs -Q
> 2. Evaluate the following:
> 
> (setopt timeclock-file "/tmp/timelog")  ; or some other non-existent file
> (setopt timeclock-get-project-function nil)
> (setopt timeclock-get-reason-function nil)
> 
> 3. M-x timeclock-in
> 4. M-x timeclock-status-string
> 
> timeclock-status-string call causes re-reading of timelog data, and thus
> triggers the bug.
> 
> Expected message: Currently IN since 9:14  (**UNKNOWN**), 7:59 remaining, leave at 5:14 
> Observed message: Currently IN since 9:14  (), 7:59 remaining, leave at 5:14 
> 
> The text in parentheses is the current project, which is empty and thus
> wrong.  When the current project is nil, **UNKNOWN** should be
> displayed.
> 
> Continue further:
> 
> 5. M-x timeclock-out
> 6. M-x timeclock-status-string
> 
> => Currently OUT since 9:15  (workday over), 7:58 remaining, leave at 5:14 
> 
> This is expected.  The string "(workday over)" means that the reason for
> clocking out is nil.
> 
> 7. M-x timeclock-reread-log
> 8. M-x timeclock-status-string
> 
> => Currently OUT since 9:15  (), 7:58 remaining, leave at 5:14 
> 
> This is wrong: the current project has become an empty string due to
> re-reading the log file in step (7).
> 
> 
> 
> I'd suggest to change timeclock-moment-regexp so that it requires a
> comment to have exactly one space after the seconds field, and then one
> or more non-newline characters.  Then timeclock-read-moment would be
> able to differentiate between nil and empty comments and also preserve
> any leading or trailing whitespace in comments.  It would be a backwards
> incompatible change, but I consider this acceptable because I find the
> current behavior clearly buggy.
> 
> I can send a patch if maintainers agree.

Yes, please send a patch, and thanks.