> I’m asking because if we do that, ‘--list-generations’ may just as well > print out *all* the generation records. Users who want to select only > less than one-month old generations can do that with ‘recsel’, and we > don’t have anything more to do. > WDYT? I see recutils as an advanced option (for those who need it), not a replacement for the basic functionality. > OTOH, for ‘--delete-generations’ it will still be more convenient to > support ‘--delete-generations’. Could you rephrase? I don’t understand the above. I believe we should think from a user’s perspective. One should be able to select the needed generations without relying on a different program. > I think you find it difficult to test because the parsing and generation > enumeration are intermingled. Right, I agree. >>> What about splitting it in two functions: >>> ‘string->time-range’ → return two SRFI-19 time objects representing a >>> time interval, or #f and #f on failure >>> ‘generation-within-time-range?’ >>> Writing tests for the former will be easy. > What do you think of the separation I proposed? We have the following cases: ‘1’, ‘1,2,3’, ‘1..9’, ‘1..’, ‘..9’, ‘first-month’, and ‘last-month’. It’s easy to parse the first three and output a list of generations without checking them. However, you’ll have to check the profile in the other cases. That’s the problem. It’s also possible to write something like this (untested): (define (available-generations str) (define (integer?*) (integer? (string->number str))) (define (comma-separated-integers?) (every integer? (delete-duplicates (map string->number (delete "" (string-split str #\,)))))) (define (safe-match:substring->number match n) (false-if-exception (string->number (match:substring match n)))) (define (maybe-whole-range-lst) (let* ((rx (make-regexp "^([0-9]+)\\.\\.([0-9]+)$")) (res (regexp-exec rx str)) (x (safe-match:substring->number res 1)) (y (safe-match:substring->number res 2))) (list x y))) (define (whole-range?) (let ((x (first maybe-whole-range-lst)) (y (last maybe-whole-range-lst))) (and (every integer? (maybe-whole-range-lst)) (<= x y)))) (define (maybe-start-range) (let* ((rx (make-regexp "^([0-9]+)\\.\\.$")) (res (regexp-exec rx str))) (safe-match:substring->number res 1))) (define (start-range?) (integer? (maybe-start-range))) ;; ... ) First, this is quite wordy. Moreover, we’ll have to move every definition to the global namespace if we want to test only syntax. I doubt that the above is the way to go. I don’t understand how the ‘string->time-range’ function will help to solve the above problem. There are only two time-related cases: ‘first-month’ and ‘last-month’. Why do you want to return a time range for every case? Could you show an example?