commit 59105ffb7403a05caaf0a4ee83e2c7d4049d40e5
parent 5bf94bdb21bfe9dc2a4b7816b763ab57e654e229
Author: ssnf <ssnf@ssnf.xyz>
Date: Thu, 10 Jul 2025 00:59:57 -0500
port libsdbr
Diffstat:
17 files changed, 359 insertions(+), 0 deletions(-)
diff --git a/include/sdbr.h b/include/sdbr.h
@@ -0,0 +1,24 @@
+AUTOLIB(sdbr)
+
+typedef struct {
+ String *attr;
+ String *val;
+} Sdbr;
+
+void sdbr_add(Sdbr*, String, String);
+void sdbr_arg2r(Sdbr*, char**);
+int sdbr_attr(Sdbr, char*);
+void sdbr_close(Sdbr*);
+void sdbr_dup(Sdbr*, Sdbr);
+void sdbr_edit(Sdbr*, Sdbr);
+void sdbr_edit2(Sdbr*, String, String);
+char* sdbr_escape(String*, String);
+void sdbr_init(Sdbr*);
+char sdbr_match(char*, char*);
+unsigned long sdbr_n(Sdbr);
+void sdbr_print(Sdbr);
+int sdbr_query(Sdbr, Sdbr);
+void sdbr_str2r(Sdbr*, String);
+String sdbr_val(Sdbr, char*);
+void sdbr_zero(Sdbr*);
+void vsdbr_join(Sdbr**, Sdbr);
diff --git a/src/libsdbr/mkfile b/src/libsdbr/mkfile
@@ -0,0 +1,23 @@
+<$PLAN9/src/mkhdr
+
+LIB=libsdbr.a
+
+OFILES=\
+ sbdr_val.$O\
+ sdbr_add.$O\
+ sdbr_arg2r.$O\
+ sdbr_attr.$O\
+ sdbr_dup.$O\
+ sdbr_edit.$O\
+ sdbr_escape.$O\
+ sdbr_init.$O\
+ sdbr_match.$O\
+ sdbr_print.$O\
+ sdbr_query.$O\
+ sdbr_str2r.$O\
+ sdbr_zero.$O\
+ vsdbr_join.$O\
+
+HFILES= $PLAN9/include/sdbr.h
+
+<$PLAN9/src/mksyslib
diff --git a/src/libsdbr/sbdr_val.c b/src/libsdbr/sbdr_val.c
@@ -0,0 +1,12 @@
+#include "std.h"
+
+String
+sdbr_val(Sdbr r, char *attr)
+{
+ ulong i;
+
+ for (i = 0; i < Vecsiz(r.attr); ++i)
+ if (sdbr_match(attr, r.attr[i].s))
+ return r.val[i];
+ return Strn(NULL, 0);
+}
diff --git a/src/libsdbr/sdbr_add.c b/src/libsdbr/sdbr_add.c
@@ -0,0 +1,8 @@
+#include "std.h"
+
+void
+sdbr_add(Sdbr *r, String attr, String val)
+{
+ Stradds(Vecadd(&r->attr), attr);
+ Stradds(Vecadd(&r->val), val);
+}
diff --git a/src/libsdbr/sdbr_arg2r.c b/src/libsdbr/sdbr_arg2r.c
@@ -0,0 +1,13 @@
+#include "std.h"
+
+void
+sdbr_arg2r(Sdbr* r, char* argv[])
+{
+ for (;argv[0] != NULL; argv += 2) {
+ if (argv[1] == NULL) {
+ sdbr_add(r, Str(argv[0]), Str(""));
+ break;
+ }
+ sdbr_add(r, Str(argv[0]), Str(argv[1]));
+ }
+}
diff --git a/src/libsdbr/sdbr_attr.c b/src/libsdbr/sdbr_attr.c
@@ -0,0 +1,13 @@
+#include "std.h"
+
+int
+sdbr_attr(Sdbr r, char *attr)
+{
+ int i;
+
+ for (i = 0; i < Vecsiz(r.attr); ++i)
+ if (sdbr_match(attr, r.attr[i].s))
+ return i;
+ return -1;
+}
+
diff --git a/src/libsdbr/sdbr_dup.c b/src/libsdbr/sdbr_dup.c
@@ -0,0 +1,11 @@
+#include "std.h"
+
+void
+sdbr_dup(Sdbr *sr, Sdbr r)
+{
+ ulong i;
+
+ sdbr_zero(sr);
+ for (i = 0; i < Vecsiz(r.attr); ++i)
+ sdbr_add(sr, r.attr[i], r.val[i]);
+}
diff --git a/src/libsdbr/sdbr_edit.c b/src/libsdbr/sdbr_edit.c
@@ -0,0 +1,23 @@
+#include "std.h"
+
+void
+sdbr_edit(Sdbr *sr, Sdbr r)
+{
+ ulong i, n;
+
+ n = Vecsiz(r.attr);
+ for (i = 0; i < n; ++i)
+ sdbr_edit2(sr, r.attr[i], r.val[i]);
+}
+
+void
+sdbr_edit2(Sdbr *r, String attr, String val)
+{
+ ulong n;
+
+ n = sdbr_attr(*r, attr.s);
+ if (n == -1)
+ sdbr_add(r, attr, val);
+ else
+ Strdup(r->val + n, val);
+}
diff --git a/src/libsdbr/sdbr_escape.c b/src/libsdbr/sdbr_escape.c
@@ -0,0 +1,41 @@
+#include "std.h"
+
+char*
+sdbr_escape(String *s, String val)
+{
+ String q;
+ ulong i;
+ uchar c, w;
+
+ Strzero(s);
+ w = 0;
+ for (i = 0; i < val.n; ++i) {
+ if (!w && isspace(val.s[i]) && val.s[i] != '\n')
+ w = 1;
+ switch (val.s[i]) {
+ case '\0': c = '0'; break;
+ case '\t': c = 't'; break;
+ case '\n': c = 'n'; break;
+ case '"': c = '"'; break;
+ case '\\':
+ if (val.s[i + 1] && val.s[i + 1] != 'n') {
+ c = '\\';
+ break;
+ }
+ default:
+ Straddc(s, val.s[i]);
+ continue;
+ }
+ Straddc(s, '\\');
+ Straddc(s, c);
+ }
+ if (w) {
+ Strinit(&q);
+ Straddc(&q, '"');
+ Strinsert(s, q, 0);
+ Strclose(&q);
+ Straddc(s, '"');
+ }
+ return s->s;
+}
+
diff --git a/src/libsdbr/sdbr_init.c b/src/libsdbr/sdbr_init.c
@@ -0,0 +1,23 @@
+#include "std.h"
+
+void
+sdbr_init(Sdbr *r)
+{
+ Vecinitf(&r->attr, Strinit, Strclose);
+ Vecinitf(&r->val, Strinit, Strclose);
+}
+
+void
+sdbr_close(Sdbr *r)
+{
+ Vecclose(&r->attr);
+ Vecclose(&r->val);
+}
+
+ulong
+sdbr_n(Sdbr r)
+{
+ return Vecsiz(r.attr);
+}
+
+
diff --git a/src/libsdbr/sdbr_match.c b/src/libsdbr/sdbr_match.c
@@ -0,0 +1,37 @@
+#include "std.h"
+
+char
+sdbr_match(char *k, char *v)
+{
+ size_t l, n;
+
+ if (*k == '>') {
+ if (*++k == '=')
+ return strcmp(v, k + 1) >= 0 ? 1 : 0;
+ return strcmp(v, k) > 0 ? 1 : 0;
+ } else if (*k == '<') {
+ if (*++k == '=')
+ return strcmp(v, k + 1) <= 0 ? 1 : 0;
+ return strcmp(v, k) < 0 ? 1 : 0;
+ }
+ for (;*k;) {
+ if (*k == '*') {
+ if (!*++k)
+ return *v ? 1 : 0;
+ if (k[strcspn(k, "*\\")]) {
+ v = strchr(v, *k);
+ return v == NULL ? 0 : sdbr_match(k, v);
+ }
+ l = strlen(k);
+ n = strlen(v);
+ if (l > n)
+ return 0;
+ v += n - l;
+ }
+ if (*k == '\\' && *(k + 1) == '*')
+ ++k;
+ if (*k++ != *v++)
+ return 0;
+ }
+ return !*v ? 1 : 0;
+}
diff --git a/src/libsdbr/sdbr_print.c b/src/libsdbr/sdbr_print.c
@@ -0,0 +1,15 @@
+#include "std.h"
+
+void
+sdbr_print(Sdbr r)
+{
+ String s;
+ ulong i;
+
+ Strinit(&s);
+ for (i = 0; i < Vecsiz(r.attr); ++i)
+ print("%s=%s", r.attr[i].s, sdbr_escape(&s, r.val[i]));
+ Strclose(&s);
+ write(1, "\n", 1);
+}
+
diff --git a/src/libsdbr/sdbr_query.c b/src/libsdbr/sdbr_query.c
@@ -0,0 +1,22 @@
+#include "std.h"
+
+int
+sdbr_query(Sdbr r, Sdbr q)
+{
+ char *attr;
+ ulong i;
+ int m;
+
+ for (i = 0; i < Vecsiz(q.attr); ++i) {
+ attr = q.attr[i].s;
+ m = sdbr_attr(r, attr[0] == '!' ? attr + 1 : attr);
+ if (m < 0) {
+ if (attr[0] == '!')
+ continue;
+ return 0;
+ }
+ if (!sdbr_match(q.val[i].s, r.val[m].s))
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/libsdbr/sdbr_str2r.c b/src/libsdbr/sdbr_str2r.c
@@ -0,0 +1,62 @@
+#include "std.h"
+
+void
+sdbr_str2r(Sdbr *sr, String s)
+{
+ char *p, *q, *k, *v;
+ ulong vn;
+
+ v = nil;
+ for (p = s.s; *p;) {
+ vn = 0;
+ for (;isspace(*p); ++p);
+ for (k = p; *p; ++p) {
+ if (isspace(*p)) {
+ *p++ = '\0';
+ break;
+ } else if (*p != '=')
+ continue;
+ *p++ = '\0';
+ for (v = p; *p; ++p) {
+ if (isspace(*p)) {
+ *p++ = '\0';
+ break;
+ } else if (*p != '"') {
+ ++vn;
+ continue;
+ }
+ for (v = q = ++p
+ ; *q != '"' && *q != '\n'
+ ; ++q
+ ) {
+ if (*q == '\\')
+ switch (*(q + 1)) {
+ case '0':
+ *++q = '\0';
+ break;
+ case 't':
+ *++q = '\t';
+ break;
+ case 'n':
+ *++q = '\n';
+ break;
+ case '"':
+ *++q = '"';
+ break;
+ case '\\':
+ *++q = '\\';
+ break;
+ }
+ *p++ = *q;
+ ++vn;
+ }
+ *p = '\0';
+ p = q + 1;
+ break;
+ }
+ break;
+ }
+ sdbr_add(sr, Str(k), Strn(v, vn));
+ for (;isspace(*p); ++p);
+ }
+}
diff --git a/src/libsdbr/sdbr_zero.c b/src/libsdbr/sdbr_zero.c
@@ -0,0 +1,9 @@
+#include "std.h"
+
+void
+sdbr_zero(Sdbr *r)
+{
+ Veczero(&r->attr);
+ Veczero(&r->val);
+}
+
diff --git a/src/libsdbr/std.h b/src/libsdbr/std.h
@@ -0,0 +1,7 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <vec.h>
+#include <str.h>
+#include <sdbr.h>
+
diff --git a/src/libsdbr/vsdbr_join.c b/src/libsdbr/vsdbr_join.c
@@ -0,0 +1,16 @@
+#include "std.h"
+
+void
+vsdbr_join(Sdbr *v[], Sdbr r)
+{
+ int i, n;
+
+ for (i = 0; i < Vecsiz(*v); ++i) {
+ n = sdbr_attr((*v)[i], r.attr[0].s);
+ if (n < 0 || strcmp((*v)[i].val[n].s, r.val[0].s))
+ continue; /*exact val, not match*/
+ sdbr_edit(*v + i, r);
+ return;
+ }
+ sdbr_dup(Vecadd(v), r);
+}