hare

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

commit 11db66bdb7574ee8f6d642dea0498907f9121b6b
parent da66885288284907c25dbaec6a7f29f44213050e
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Tue,  2 May 2023 04:44:23 +0200

all: use strings::slice where appropriate

Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Mdatetime/parse.ha | 37++++++++++++++-----------------------
Mfmt/fmt.ha | 9+++------
Mfnmatch/fnmatch.ha | 13+++----------
Mglob/glob.ha | 1+
Mnet/uri/fmt.ha | 4+---
Mnet/uri/parse.ha | 39+++++++++++++--------------------------
6 files changed, 35 insertions(+), 68 deletions(-)

diff --git a/datetime/parse.ha b/datetime/parse.ha @@ -161,8 +161,7 @@ fn scan_for(iter: *strings::iterator, list: str...) (int | failure) = { // Returns the resulting int. // If pad is true, the number is right-padded with zeroes upto n digits. fn scan_int(iter: *strings::iterator, n: size, pad: bool) (int | failure) = { - let buf: [64]u8 = [0...]; - let bufstr = strio::fixed(buf); + let copy = *iter; for (let i = 0z; i < n; i += 1) { let rn: rune = match (strings::next(iter)) { case void => @@ -174,19 +173,14 @@ fn scan_int(iter: *strings::iterator, n: size, pad: bool) (int | failure) = { strings::prev(iter); break; }; - match (strio::appendrune(&bufstr, rn)) { - case io::error => - return failure; - case => - void; - }; }; - const s = strings::padend(strio::string(&bufstr), '0', if (pad) n else 0); - defer free(s); - + const s = strings::slice(&copy, iter); match (strconv::stoi(s)) { - case let n: int => - return n; + case let num: int => + for (let i = 0z; i < n - len(s); i += 1) { + num *= 10; + }; + return num; case => return failure; }; @@ -228,22 +222,19 @@ fn scan_zo(iter: *strings::iterator) (time::duration | failure) = { // Scans and parses locality names, made of printable characters. fn scan_str(iter: *strings::iterator) (str | failure) = { - static let buf: [64]u8 = [0...]; - let bufstr = strio::fixed(buf); + let copy = *iter; for (true) { - let rn: rune = match (strings::next(iter)) { + match (strings::next(iter)) { case void => break; case let rn: rune => - yield rn; - }; - if (!ascii::isgraph(rn)) { - strings::prev(iter); - break; + if (!ascii::isgraph(rn)) { + strings::prev(iter); + break; + }; }; - strio::appendrune(&bufstr, rn)!; }; - return strio::string(&bufstr); + return strings::slice(&copy, iter); }; @test fn parse() void = { diff --git a/fmt/fmt.ha b/fmt/fmt.ha @@ -406,8 +406,7 @@ fn is_negative(n: types::numeric) bool = { }; fn scan_uint(iter: *strings::iterator) uint = { - let num: []u8 = []; - defer free(num); + let copy = *iter; for (true) { let r = match (strings::next(iter)) { case void => @@ -416,11 +415,9 @@ fn scan_uint(iter: *strings::iterator) uint = { yield r; }; - if (ascii::isdigit(r)) { - append(num, r: u32: u8); - } else { + if (!ascii::isdigit(r)) { strings::prev(iter); - match (strconv::stou(strings::fromutf8(num)!)) { + match (strconv::stou(strings::slice(&copy, iter))) { case (strconv::invalid | strconv::overflow) => abort("Invalid format string (invalid index)"); case let u: uint => diff --git a/fnmatch/fnmatch.ha b/fnmatch/fnmatch.ha @@ -88,7 +88,7 @@ fn fnmatch_pathname( yield s; }; strings::prev(&p_iter); - let p = cut_tail(strings::iterstr(&start), &p_iter); + let p = strings::slice(&start, &p_iter); strings::next(&p_iter); if (!fnmatch_internal(p, s, fl)?) { return false; @@ -194,8 +194,8 @@ fn fnmatch_internal( }; // match the "sea of stars" in the middle - s_copy = strings::iter(cut_tail(strings::iterstr(&s_copy), &s_last)); - p_copy = strings::iter(cut_tail(strings::iterstr(&p_copy), &p_last.0)); + s_copy = strings::iter(strings::slice(&s_copy, &s_last)); + p_copy = strings::iter(strings::slice(&p_copy, &p_last.0)); for (true) :outer { p = p_copy; if (len(strings::iterstr(&p)) == 0) { @@ -360,10 +360,3 @@ fn advance_or_err(it: *strings::iterator) (rune | errors::invalid) = { return errors::invalid; }; }; - -fn cut_tail(s: str, it: *strings::iterator) str = { - let s_len = len(s), t_len = len(strings::iterstr(it)); - let b = strings::toutf8(s); - return strings::fromutf8(b[..s_len - t_len])!; -}; - diff --git a/glob/glob.ha b/glob/glob.ha @@ -38,6 +38,7 @@ export type strstack = struct { }; export type pattern = struct { + // TODO: look into working with a couple of string iterators instead dir: strio::stream, pat: strio::stream, rem: strio::stream, diff --git a/net/uri/fmt.ha b/net/uri/fmt.ha @@ -99,9 +99,7 @@ fn percent_encode(out: io::handle, src: str, allowed: str) (size | io::error) = } else { const en = utf8::encoderune(r); for (let i = 0z; i < len(en); i += 1) { - n += fmt::fprintf(out, "%{}", - strconv::u8tosb(en[i], - strconv::base::HEX))?; + n += fmt::fprintf(out, "%{:X}", en[i])?; }; }; }; diff --git a/net/uri/parse.ha b/net/uri/parse.ha @@ -106,11 +106,11 @@ export fn parse(in: str) (uri | invalid) = { }; fn parse_scheme(in: *strings::iterator) (str | invalid) = { - let buf = strio::dynamic(); - + let copy = *in; for (let i = 0z; true; i += 1) { const r = wantrune(in)?; if (i > 0 && r == ':') { + strings::prev(in); break; }; if (i == 0) { @@ -122,10 +122,10 @@ fn parse_scheme(in: *strings::iterator) (str | invalid) = { return invalid; }; }; - strio::appendrune(&buf, r)!; }; - - return strio::string(&buf); + let s = strings::dup(strings::slice(&copy, in)); + strings::next(in); + return s; }; fn parse_authority( @@ -219,9 +219,7 @@ type path_mode = enum { }; fn parse_path(in: *strings::iterator, mode: path_mode) (str | invalid) = { - let buf = strio::dynamic(); - defer io::close(&buf)!; - + let copy = *in; // With rootless path, we need at least one segment if (mode == path_mode::ROOTLESS) { for (let i = 0z; true; i += 1) { @@ -235,14 +233,12 @@ fn parse_path(in: *strings::iterator, mode: path_mode) (str | invalid) = { if (i == 0) { return invalid; } else { - strio::appendrune(&buf, '/')!; break; }; }; if (!is_pchar(r)) { return invalid; }; - strio::appendrune(&buf, r)!; case void => break; }; @@ -259,18 +255,16 @@ fn parse_path(in: *strings::iterator, mode: path_mode) (str | invalid) = { if (!is_pchar(r) && r != '/') { return invalid; }; - strio::appendrune(&buf, r)!; case void => break; }; }; - return percent_decode(strio::string(&buf)); + return percent_decode(strings::slice(&copy, in)); }; fn parse_query(in: *strings::iterator) (str | invalid) = { - let buf = strio::dynamic(); - + let copy = *in; for (true) { match (strings::next(in)) { case let r: rune => @@ -281,37 +275,31 @@ fn parse_query(in: *strings::iterator) (str | invalid) = { if (!is_pchar(r) && r != '/' && r != '?') { return invalid; }; - strio::appendrune(&buf, r)!; case void => break; }; }; - - return strio::string(&buf); + return strings::dup(strings::slice(&copy, in)); }; fn parse_fragment(in: *strings::iterator) (str | invalid) = { - let buf = strio::dynamic(); - defer io::close(&buf)!; - + let copy = *in; for (true) { match (strings::next(in)) { case let r: rune => if (!is_pchar(r) && r != '/' && r != '?') { return invalid; }; - strio::appendrune(&buf, r)!; case void => break; }; }; - return percent_decode(strio::string(&buf))?; + return percent_decode(strings::slice(&copy, in))?; }; fn parse_port(in: *strings::iterator) (u16 | invalid) = { - let buf = strio::dynamic(); - defer io::close(&buf)!; + let copy = *in; for (true) { const r = match (strings::next(in)) { case let r: rune => @@ -324,10 +312,9 @@ fn parse_port(in: *strings::iterator) (u16 | invalid) = { strings::prev(in); break; }; - strio::appendrune(&buf, r)!; }; - match (strconv::stou16(strio::string(&buf))) { + match (strconv::stou16(strings::slice(&copy, in))) { case let port: u16 => if (port == 0) { // There's no port 0