[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Support ~N in SRFI-19 string->date
From: |
Mark H Weaver |
Subject: |
Re: [PATCH] Support ~N in SRFI-19 string->date |
Date: |
Tue, 11 Dec 2018 15:52:06 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) |
Hi Daniel,
Daniel Llorens <address@hidden> writes:
> The previous patch had a broken test. New attempt, tested on stable-2.2.
Looks good to me. Please push!
Thanks,
Mark
> From 53ebca4c8c439148dcdf9990714aaea2a1bc6305 Mon Sep 17 00:00:00 2001
> From: Daniel Llorens <address@hidden>
> Date: Mon, 10 Dec 2018 11:57:05 +0100
> Subject: [PATCH] Support ~N in SRFI-19 string->date
>
> * module/srfi/srfi-19.scm (fractional-integer-reader,
> make-fractional-integer-reader): From reference implementation.
> (reader-directives): Handle #\N, from reference implementation.
> * test-suite/tests/srfi-19: Add tests for string->date ~N.
> * doc/ref/srfi-modules.texi (string->date): Add line for ~N.
> ---
> doc/ref/srfi-modules.texi | 5 +++++
> module/srfi/srfi-19.scm | 22 ++++++++++++++++++++++
> test-suite/tests/srfi-19.test | 10 ++++++++++
> 3 files changed, 37 insertions(+)
>
> diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
> index 99967e574..11fa24d68 100644
> --- a/doc/ref/srfi-modules.texi
> +++ b/doc/ref/srfi-modules.texi
> @@ -2926,6 +2926,11 @@ the date.
> @tab minute
> @tab @nicode{date-minute}
>
> address@hidden @nicode{~N}
> address@hidden @nicode{char-numeric?}
> address@hidden nanosecond
> address@hidden @nicode{date-nanosecond}
> +
> @item @nicode{~S}
> @tab @nicode{char-numeric?}
> @tab second
> diff --git a/module/srfi/srfi-19.scm b/module/srfi/srfi-19.scm
> index 46de91a7e..66939f92c 100644
> --- a/module/srfi/srfi-19.scm
> +++ b/module/srfi/srfi-19.scm
> @@ -1193,6 +1193,24 @@
> (lambda (port)
> (integer-reader upto port)))
>
> +;; read an fractional integer upto n characters long on port; upto -> #f if
> any length
> +;;
> +;; The return value is normalized to upto decimal places. For example, if
> upto is 9 and
> +;; the string read is "123", the return value is 123000000.
> +(define (fractional-integer-reader upto port)
> + (define (accum-int port accum nchars)
> + (let ((ch (peek-char port)))
> + (if (or (eof-object? ch)
> + (not (char-numeric? ch))
> + (and upto (>= nchars upto)))
> + (* accum (expt 10 (- upto nchars)))
> + (accum-int port (+ (* accum 10) (char->int (read-char port))) (+
> nchars 1)))))
> + (accum-int port 0 0))
> +
> +(define (make-fractional-integer-reader upto)
> + (lambda (port)
> + (fractional-integer-reader upto port)))
> +
> ;; read *exactly* n characters and convert to integer; could be padded
> (define (integer-reader-exact n port)
> (let ((padding-ok #t))
> @@ -1305,6 +1323,7 @@
> (define read-directives
> (let ((ireader4 (make-integer-reader 4))
> (ireader2 (make-integer-reader 2))
> + (fireader9 (make-fractional-integer-reader 9))
> (eireader2 (make-integer-exact-reader 2))
> (locale-reader-abbr-weekday (make-locale-reader
> locale-abbr-weekday->index))
> @@ -1343,6 +1362,9 @@
> (list #\M char-numeric? ireader2 (lambda (val object)
> (set-date-minute!
> object val)))
> + (list #\N char-numeric? fireader9 (lambda (val object)
> + (set-date-nanosecond!
> + object val)))
> (list #\S char-numeric? ireader2 (lambda (val object)
> (set-date-second! object val)))
> (list #\y char-fail eireader2
> diff --git a/test-suite/tests/srfi-19.test b/test-suite/tests/srfi-19.test
> index 4d79f1043..256ff74a0 100644
> --- a/test-suite/tests/srfi-19.test
> +++ b/test-suite/tests/srfi-19.test
> @@ -176,6 +176,16 @@ incomplete numerical tower implementation.)"
> (equal? "Sun Jun 05 18:33:00+0200 2005"
> (date->string date))))
>
> + (pass-if "string->date understands nanoseconds (1)"
> + (time=? (date->time-utc (string->date "2018-12-10 10:53:24.189"
> + "~Y-~m-~d ~H:~M:~S.~N"))
> + (date->time-utc (make-date 189000000 24 53 10 10 12 2018 3600))))
> +
> + (pass-if "string->date understands nanoseconds (2)"
> + (time=? (date->time-utc (string->date "2018-12-10 10:53:24.189654321"
> + "~Y-~m-~d ~H:~M:~S.~N"))
> + (date->time-utc (make-date 189654321 24 53 10 10 12 2018 3600))))
> +
> (pass-if "date->string pads small nanoseconds values correctly"
> (let* ((date (make-date 99999999 5 34 12 26 3 2017 0)))
> (equal? "099999999"