Hi Daniel, Daniel Llorens <daniel.llor...@bluewin.ch> 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 <daniel.llor...@bluewin.ch> > 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} > > +@item @nicode{~N} > +@tab @nicode{char-numeric?} > +@tab nanosecond > +@tab @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"