hare

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

commit 256a60f7dc307f3f2d38fe79370c0b9a0f0b4180
parent 198b6bc554ae29cc49c21d7904fd130716e60f14
Author: Byron Torres <b@torresjrjr.com>
Date:   Tue, 26 Dec 2023 08:46:38 +0000

strings: readd pad functions

This reverts commit 4b5d45099f87315a879a3787ad0d6e23b3ea254e.

The fmt way of padding is not as trivial as the strings::pad* functions,
nor should we expect users to import fmt in one module just for padding,
nor should we be afraid of small code dupication, especially this small.

Signed-off-by: Byron Torres <b@torresjrjr.com>

Diffstat:
Mmakefiles/freebsd.aarch64.mk | 2+-
Mmakefiles/freebsd.riscv64.mk | 2+-
Mmakefiles/freebsd.x86_64.mk | 2+-
Mmakefiles/linux.aarch64.mk | 2+-
Mmakefiles/linux.riscv64.mk | 2+-
Mmakefiles/linux.x86_64.mk | 2+-
Astrings/pad.ha | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/makefiles/freebsd.aarch64.mk b/makefiles/freebsd.aarch64.mk @@ -39,7 +39,7 @@ $(HARECACHE)/sort_cmp.ssa: $(sort_cmp_ha) @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/sort_cmp.ssa -t $(HARECACHE)/sort_cmp.td.tmp -N sort::cmp $(sort_cmp_ha) -strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha +strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/pad.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha $(HARECACHE)/strings.ssa: $(strings_ha) $(HARECACHE)/bytes.td $(HARECACHE)/encoding_utf8.td $(HARECACHE)/sort_cmp.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/freebsd.riscv64.mk b/makefiles/freebsd.riscv64.mk @@ -39,7 +39,7 @@ $(HARECACHE)/sort_cmp.ssa: $(sort_cmp_ha) @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/sort_cmp.ssa -t $(HARECACHE)/sort_cmp.td.tmp -N sort::cmp $(sort_cmp_ha) -strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha +strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/pad.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha $(HARECACHE)/strings.ssa: $(strings_ha) $(HARECACHE)/bytes.td $(HARECACHE)/encoding_utf8.td $(HARECACHE)/sort_cmp.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/freebsd.x86_64.mk b/makefiles/freebsd.x86_64.mk @@ -39,7 +39,7 @@ $(HARECACHE)/sort_cmp.ssa: $(sort_cmp_ha) @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/sort_cmp.ssa -t $(HARECACHE)/sort_cmp.td.tmp -N sort::cmp $(sort_cmp_ha) -strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha +strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/pad.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha $(HARECACHE)/strings.ssa: $(strings_ha) $(HARECACHE)/bytes.td $(HARECACHE)/encoding_utf8.td $(HARECACHE)/sort_cmp.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.aarch64.mk b/makefiles/linux.aarch64.mk @@ -39,7 +39,7 @@ $(HARECACHE)/sort_cmp.ssa: $(sort_cmp_ha) @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/sort_cmp.ssa -t $(HARECACHE)/sort_cmp.td.tmp -N sort::cmp $(sort_cmp_ha) -strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha +strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/pad.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha $(HARECACHE)/strings.ssa: $(strings_ha) $(HARECACHE)/bytes.td $(HARECACHE)/encoding_utf8.td $(HARECACHE)/sort_cmp.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.riscv64.mk b/makefiles/linux.riscv64.mk @@ -39,7 +39,7 @@ $(HARECACHE)/sort_cmp.ssa: $(sort_cmp_ha) @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/sort_cmp.ssa -t $(HARECACHE)/sort_cmp.td.tmp -N sort::cmp $(sort_cmp_ha) -strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha +strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/pad.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha $(HARECACHE)/strings.ssa: $(strings_ha) $(HARECACHE)/bytes.td $(HARECACHE)/encoding_utf8.td $(HARECACHE)/sort_cmp.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.x86_64.mk b/makefiles/linux.x86_64.mk @@ -39,7 +39,7 @@ $(HARECACHE)/sort_cmp.ssa: $(sort_cmp_ha) @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/sort_cmp.ssa -t $(HARECACHE)/sort_cmp.td.tmp -N sort::cmp $(sort_cmp_ha) -strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha +strings_ha = strings/compare.ha strings/concat.ha strings/contains.ha strings/dup.ha strings/index.ha strings/iter.ha strings/pad.ha strings/replace.ha strings/runes.ha strings/sub.ha strings/suffix.ha strings/tokenize.ha strings/trim.ha strings/utf8.ha $(HARECACHE)/strings.ssa: $(strings_ha) $(HARECACHE)/bytes.td $(HARECACHE)/encoding_utf8.td $(HARECACHE)/sort_cmp.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/strings/pad.ha b/strings/pad.ha @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use encoding::utf8; + +// Pads a string's start with 'prefix' until it reaches length 'target_len'. +// The caller must free the return value. +export fn padstart(s: str, prefix: rune, target_len: size) str = { + if (len(s) >= target_len) { + return dup(s); + }; + let res: []u8 = alloc([], target_len); + for (let i = 0z; i < target_len - len(s); i += 1) { + append(res, utf8::encoderune(prefix)...); + }; + append(res, toutf8(s)...); + return fromutf8_unsafe(res[..target_len]); +}; + +@test fn padstart() void = { + let s = padstart("2", '0', 5); + assert(s == "00002"); + free(s); + + let s = padstart("12345", '0', 5); + assert(s == "12345"); + free(s); + + let s = padstart("", '0', 5); + assert(s == "00000"); + free(s); +}; + +// Pads a string's end with 'prefix' until it reaches length 'target_len'. +// The caller must free the return value. +export fn padend(s: str, prefix: rune, target_len: size) str = { + if (len(s) >= target_len) { + return dup(s); + }; + let res: []u8 = alloc([], target_len); + append(res, toutf8(s)...); + for (let i = 0z; i < target_len - len(s); i += 1) { + append(res, utf8::encoderune(prefix)...); + }; + return fromutf8_unsafe(res[..target_len]); +}; + +@test fn padend() void = { + let s = padend("2", '0', 5); + assert(s == "20000"); + free(s); + + let s = padend("12345", '0', 5); + assert(s == "12345"); + free(s); + + let s = padend("", '0', 5); + assert(s == "00000"); + free(s); +};