commit faeacbedade2cb621e276ae2cc6c1358aea06d33
parent 5c745a502396955c68f7b7aad70a81b169cf883b
Author: tongong <tongong@gmx.net>
Date: Mon, 20 Jun 2022 13:39:29 +0200
added tests and removed []rune->str conversion etc
My understanding of utf8 was wrong.
Diffstat:
5 files changed, 70 insertions(+), 100 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,10 @@
PREFIX=/usr/local
tacker: *.ha
- hare build -o tacker .
+ hare build -o tacker
+
+test:
+ hare test
clean:
rm -rf tacker
@@ -14,4 +17,4 @@ install: tacker
uninstall:
rm -rf $(DESTDIR)$(PREFIX)/bin/tacker
-.PHONY: clean install uninstall
+.PHONY: test clean install uninstall
diff --git a/main.ha b/main.ha
@@ -52,13 +52,10 @@ export fn main() void = {
// (because of fmt::fatalf)
// defer free(ifile);
- let slc = strings::runes(ifile);
- defer free(slc);
- let extstart = lastdotindex(slc);
+ let extstart = lastdotindex(ifile);
if (extstart == -1)
fmt::fatalf("file \"{}\" has broken filetype.", ifile);
- let ext = runes_to_str(slc[(extstart + 1)..]);
- defer free(ext);
+ let ext = strings::fromutf8(strings::toutf8(ifile)[(extstart + 1)..]);
switch (ext) {
case "html" => tacker_html(ifile, ofile);
diff --git a/path_helpers.ha b/path_helpers.ha
@@ -1,6 +1,7 @@
use fmt;
use fs;
use os;
+use slices;
use strings;
// All bundled files must be within this directory so that malicious modules
@@ -47,3 +48,42 @@ fn resolve_path(path: str, from: str) str = {
r, basepath);
return r;
};
+
+// Returns index of the last dot in the filename or -1 if the file contains no
+// dot.
+fn lastdotindex(filename: str) int = {
+ const filename = strings::toutf8(filename);
+ let index = (len(filename) - 1): int;
+ for (index >= 0 && filename[index] != '.') {
+ if (filename[index] == '/') return -1;
+ index -= 1;
+ };
+ return index;
+};
+
+// return value has to be freed.
+fn file_name_bundled(filename: str) str = {
+ let lastdot = lastdotindex(filename);
+ // files without extension get the .bundle at the end
+ if (lastdot == -1) lastdot = len(filename): int;
+
+ const output = strings::dup(filename);
+ const output = strings::toutf8(output);
+
+ const ext = strings::toutf8(".bundle");
+ let bptr: [7]*void = [&ext: *void ...];
+ for (let i = 0z; i < len(ext); i += 1) {
+ bptr[i] = &ext[i];
+ };
+ slices::insertinto(&output: *[]void, size(u8), lastdot: size, bptr...);
+ return strings::fromutf8(output);
+};
+
+@test fn file_name_bundled() void = {
+ assert(file_name_bundled("test.js") == "test.bundle.js");
+ assert(file_name_bundled("test.dot.js") == "test.dot.bundle.js");
+ assert(file_name_bundled("no-ext") == "no-ext.bundle");
+ assert(file_name_bundled("./dir.a/no-ext") == "./dir.a/no-ext.bundle");
+ assert(file_name_bundled("./test.dir/ütf8.html") ==
+ "./test.dir/ütf8.bundle.html");
+};
diff --git a/searchio/searchio.ha b/searchio/searchio.ha
@@ -1,31 +1,9 @@
-use fmt;
+use bufio;
use io;
use os;
use sort;
use strings;
-// // reads until end is read and pipes all read bytes to ofile (end itself not)
-// // returns true if end is reached, false on EOF
-// fn read_until(ifile: io::handle, ofile: io::handle, end: str) bool = {
-// let end = strings::toutf8(end);
-// let currIndex = 0z; // the current index in the buffer to check
-// for (true) {
-// const buf: [1]u8 = [' '];
-// if (io::read(ifile, buf) is io::EOF) return false;
-// if (buf[0] == end[currIndex]) {
-// currIndex += 1;
-// if (currIndex == len(end)) return true;
-// } else {
-// if (currIndex != 0) {
-// io::write(ofile, end[..currIndex])!;
-// currIndex = 0;
-// };
-// io::write(ofile, buf)!;
-// };
-// };
-// return false; // unreachable
-// };
-
// sorted
export type pattern = []patternelem;
export type patternelem = struct {
@@ -68,14 +46,6 @@ export fn compile(s: []str) pattern = {
} else break;
};
};
- // for (let i = 0z; i < len(p); i+= 1) {
- // fmt::print(p[i].index)!;
- // for (let j = 0z; j < len(p[i].data); j+= 1) {
- // fmt::print(" ")!;
- // fmt::print(p[i].data[j])!;
- // };
- // fmt::println()!;
- // };
return p;
};
@@ -135,3 +105,25 @@ export fn search(ifile: io::handle, ofile: io::handle, end: pattern)
};
return io::EOF; // unreachable
};
+
+@test fn searchio() void = {
+ const input = "inputstreamtesttest word2word1 tertemp";
+ const input = &bufio::fixed(strings::toutf8(input), io::mode::READ);
+ const output = bufio::dynamic(io::mode::WRITE);
+ const outbuf = &output.buf;
+ const output = &output;
+ defer io::close(output)!;
+
+ const p = compile(["temp", "test", "word1"]);
+ const matches: [_]size = [1, 1, 2, 0];
+ let matchesindex = 0;
+ for (true) {
+ const m = search(input, output, p);
+ if (m is size) {
+ const m = m: size;
+ assert(matches[matchesindex] == m);
+ matchesindex += 1;
+ } else break;
+ };
+ assert("inputstream word2 ter" == strings::fromutf8(*outbuf));
+};
diff --git a/string_helpers.ha b/string_helpers.ha
@@ -1,62 +0,0 @@
-use encoding::utf8;
-use fmt;
-use rt;
-use slices;
-use strings;
-use types;
-
-// Inverse of strings::runes().
-// why is not something like this in the stdlib?
-// why does insertinto take a slice of pointers and not a pointer to a slice?
-fn runes_to_str(runes: []rune) str = {
- let buffer = alloc([], len(runes) * 4): []u8: *[*]u8;
- let index = 0z;
- for (let i = 0z; i < len(runes); i += 1) {
- const u = encoding::utf8::encoderune(runes[i]);
- rt::memcpy(&buffer[index], &u[0], len(u));
- index += len(u);
- };
- const s = types::string {
- data = buffer,
- length = index,
- capacity = len(runes) * 4,
- };
- return *(&s: *const str);
-};
-
-// Returns index of the last dot in the filename or -1 if the file contains no
-// dot.
-fn lastdotindex(filename: []rune) int = {
- let index = (len(filename) - 1): int;
- for (index >= 0 && filename[index] != '.') {
- if (filename[index] == '/') {
- index = -1;
- break;
- };
- index -= 1;
- };
- return index;
-};
-
-// Input is borrowed, return value has to be freed.
-// test.js -> test.bundle.js
-// test.dot.js -> test.dot.bundle.js
-// no-ext -> no-ext.bundle
-fn file_name_bundled(ifile: str) str = {
- let slc = strings::runes(ifile);
- defer free(slc);
- let lastdot = lastdotindex(slc);
- // files without extension get the .bundle at the end
- if (lastdot == -1) lastdot = len(slc): int;
-
- static let b: []rune = [];
- static let bptr: [7]*void = [&b: *void ...];
- if (len(b) == 0) {
- b = strings::runes(".bundle");
- for (let i = 0z; i < len(b); i += 1) {
- bptr[i] = &b[i];
- };
- };
- slices::insertinto(&slc: *[]void, size(rune), lastdot: size, bptr...);
- return runes_to_str(slc);
-};