~sircmpwn/himitsu-devel

himitsu: himitsu::query: Add parse_str convenience function v1 APPLIED

Alexey Yerin: 2
 himitsu::query: Add parse_str convenience function
 himitsu::client: Return a parsed query instead of a string from next

 4 files changed, 27 insertions(+), 16 deletions(-)
Thanks!

Did you alread fix some of the other modules? Otherwise I can also do
it.

To https://git.sr.ht/~sircmpwn/himitsu
   734a34b..c657d70  master -> master
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/himitsu-devel/patches/47199/mbox | git am -3
Learn more about email & git

[PATCH himitsu 1/2] himitsu::query: Add parse_str convenience function Export this patch

---
 cmd/hiq/main.ha        | 14 +++++++++-----
 himitsu/query/parse.ha |  7 ++++++-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/cmd/hiq/main.ha b/cmd/hiq/main.ha
index a6dc518..5e6191e 100644
--- a/cmd/hiq/main.ha
+++ b/cmd/hiq/main.ha
@@ -82,14 +82,18 @@ export fn main() void = {
			case let line: []u8 =>
				// NB. Can't defer free(line), causes a
				// use-after-free in fmt::fatal
				const query = memio::fixed(line);
				const query = match (query::parse(&query)) {
				const line = match (strings::fromutf8(line)) {
				case let s: str =>
					yield s;
				case =>
					free(line);
					fmt::fatal("Error: Query is not valid UTF-8");
				};
				const query = match (query::parse_str(line)) {
				case let q: query::query =>
					yield q;
				case query::invalid =>
					fmt::fatal("Invalid query:", strings::fromutf8(line)!);
				case let err: io::error =>
					abort(); // reading from a fixed buffer shouldn't fail
					fmt::fatal("Invalid query:", line);
				};
				defer query::finish(&query);
				free(line);
diff --git a/himitsu/query/parse.ha b/himitsu/query/parse.ha
index 74aa3e5..e9c2722 100644
--- a/himitsu/query/parse.ha
+++ b/himitsu/query/parse.ha
@@ -61,8 +61,13 @@ export fn parse(in: io::handle) (query | error | io::error) = {
	case utf8::invalid =>
		return invalid;
	};
	return parse_str(data);
};

	const items = match (shlex::split(data)) {
// Parses a query from a string, returning its key/value pairs. The caller must
// pass the return value to [[finish]] when they are done with it.
export fn parse_str(in: str) (query | error) = {
	const items = match (shlex::split(in)) {
	case let items: []str =>
		yield items;
	case shlex::syntaxerr =>
-- 
2.43.0

[PATCH himitsu 2/2] himitsu::client: Return a parsed query instead of a string from next Export this patch

This is much more useful to most programs interacting with himitsu that don't
need to output keys as-is.

Unfortunately, this will require updating all code that uses himitsu::client.
---
 cmd/hiq/main.ha          | 12 ++++--------
 himitsu/client/client.ha | 10 ++++++++--
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/cmd/hiq/main.ha b/cmd/hiq/main.ha
index 5e6191e..93b1404 100644
--- a/cmd/hiq/main.ha
+++ b/cmd/hiq/main.ha
@@ -132,7 +132,7 @@ fn send(

	for (let i = 0; true; i += 1) {
		let key = match (client::next(&keys)) {
		case let k: const str =>
		case let k: query::query =>
			if (one && i > 0) {
				fmt::fatal("Error: ambiguous match");
			};
@@ -143,18 +143,14 @@ fn send(
		};
		match (field) {
		case let field: str =>
			const items = shlex::split(key)!;
			defer strings::freeall(items);
			const query = query::parse_items(items)!;
			defer query::finish(&query);
			for (let i = 0z; i < len(query.items); i += 1) {
				let item = query.items[i];
			for (let i = 0z; i < len(key.items); i += 1) {
				let item = key.items[i];
				if (item.key == field) {
					fmt::fprintln(&buf, item.value)!;
				};
			};
		case void =>
			fmt::fprintln(&buf, key)!;
			query::unparse(&buf, &key)!;
		};
	};

diff --git a/himitsu/client/client.ha b/himitsu/client/client.ha
index 7dec0be..0e12dfd 100644
--- a/himitsu/client/client.ha
+++ b/himitsu/client/client.ha
@@ -105,7 +105,7 @@ export fn query(

// Returns the next key from a key iterator, or void if no further keys are
// provided.
export fn next(iter: *keyiter) (const str | void | error) = {
export fn next(iter: *keyiter) (query::query | void | error) = {
	memio::reset(&iter.buf);
	match (bufio::read_line(iter.conn)?) {
	case let buf: []u8 =>
@@ -130,7 +130,13 @@ export fn next(iter: *keyiter) (const str | void | error) = {
		return strings::sub(string, 6, strings::end): hierror: error;
	};
	if (strings::hasprefix(string, "key ")) {
		return strings::sub(string, 4, strings::end);
		const key = strings::sub(string, 4, strings::end);
		match (query::parse_str(key)) {
		case let q: query::query =>
			return q;
		case query::error =>
			abort("himitsu returned an invalid key");
		};
	};
	abort("himitsu returned unexpected response");
};
-- 
2.43.0
Thanks!

Did you alread fix some of the other modules? Otherwise I can also do
it.

To https://git.sr.ht/~sircmpwn/himitsu
   734a34b..c657d70  master -> master