hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 2eab33f08315016a6d5edaf5021555cf6b68aa0b
parent eb62889ab2cdea07360fb16db1c10a9ea981fc7e
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Sun, 30 Apr 2023 00:35:08 +0200

datetime: parse: fix %z scanning, add test

(rune | void) was incorrectly compared to rune and harec didn't complain
because of #787.

References: https://todo.sr.ht/~sircmpwn/hare/787
Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Mdatetime/parse.ha | 36++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/datetime/parse.ha b/datetime/parse.ha @@ -197,25 +197,33 @@ fn scan_int(iter: *strings::iterator, n: size, pad: bool) (int | failure) = { // Z // z // +nn:nn +// +nnnn // -nn:nn +// -nnnn // fn scan_zo(iter: *strings::iterator) (time::duration | failure) = { - const rest = strings::iterstr(iter); - if (strings::hasprefix(rest, 'Z') || strings::hasprefix(rest, 'z')) { + const r = match (strings::next(iter)) { + case void => + return failure; + case let r: rune => + yield r; + }; + if (r == 'Z' || r == 'z') { return 0; - } else { - const prefix = strings::next(iter); - let zo = scan_int(iter, 2, false)? * time::HOUR; - const rest = strings::iterstr(iter); - if (strings::hasprefix(rest, ":")) { + }; + let zo = scan_int(iter, 2, false)? * time::HOUR; + match (strings::next(iter)) { + case void => void; + case let r: rune => + if (r == ':') { strings::next(iter); }; - zo += scan_int(iter, 2, false)? * time::MINUTE; - if (prefix == '-') { - zo *= -1; - }; - return zo; }; + zo += scan_int(iter, 2, false)? * time::MINUTE; + if (r == '-') { + zo *= -1; + }; + return zo; }; // Scans and parses locality names, made of printable characters. @@ -364,6 +372,10 @@ fn scan_str(iter: *strings::iterator) (str | failure) = { assert(parse(&v, "%z", "+0100") is void , "%z: parsefail"); assert(v.zoff is i64 , "%z: void"); assert(v.zoff as i64 == 1 * time::HOUR , "%z: incorrect"); + let v = newvirtual(); + assert(parse(&v, "%z", "+01:00") is void , "%z: parsefail"); + assert(v.zoff is i64 , "%z: void"); + assert(v.zoff as i64 == 1 * time::HOUR , "%z: incorrect"); let v = newvirtual(); assert(parse(&v, "%Z", "CET") is void , "%Z: parsefail");