commit a2212304f043fadd9884383833e684c1527ecadd
parent be770c2636f10d9056698fae130238ecb4d523ec
Author: Renev Pavel <an2qzavok@gmail.com>
Date: Wed, 4 Jan 2023 17:53:14 +0000
src/wdb: Weeb Data Base interface
Diffstat:
5 files changed, 197 insertions(+), 0 deletions(-)
diff --git a/src/wdb/mkfile b/src/wdb/mkfile
@@ -0,0 +1,5 @@
+</$objtype/mkfile
+TARG=wdb
+HFILES=wdb.h util.h
+OFILES=wdb.$O util.$O
+</sys/src/cmd/mkmany
+\ No newline at end of file
diff --git a/src/wdb/util.c b/src/wdb/util.c
@@ -0,0 +1,22 @@
+#include <u.h>
+#include <libc.h>
+
+long
+voidlen(void **pp)
+{
+ long n;
+ for (n = 0; *pp != nil; n++, pp++);
+ return n;
+}
+
+char **
+strfind(char **pp, long n, char *s)
+{
+ if ((pp == nil) || (s == nil)) return nil;
+ long i;
+ for (i = 0; i < n; pp++, i++) {
+ if (*pp == nil) break;
+ if (strcmp(*pp, s) == 0) return pp;
+ }
+ return nil;
+}
diff --git a/src/wdb/util.h b/src/wdb/util.h
@@ -0,0 +1,2 @@
+long voidlen(void **); /* strlen, but for array of pointers */
+char ** strfind(char **, long n, char *); /* find string in array of strings */
diff --git a/src/wdb/wdb.c b/src/wdb/wdb.c
@@ -0,0 +1,145 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <regexp.h>
+
+Biobuf *bout;
+
+#include "wdb.h"
+#include "util.h"
+
+enum { MaxTags = 256, };
+
+WDB db;
+char *tags[MaxTags];
+
+int
+testtag(char **tags, char *test)
+{
+ for (; *tags != nil; tags++) {
+ if (strcmp(test, *tags) == 0) return 1;
+ }
+ return 0;
+}
+
+int
+testtags(char **tags, char **test)
+{
+ for (; *test != nil; test++) {
+ if (testtag(tags, *test) == 0) return 0;
+ }
+ return 1;
+}
+
+int
+testtagsstr(char **tags, char *str)
+{
+ char *test[MaxTags];
+ char *s;
+ int n, r;
+ s = strdup(str);
+ n = tokenize(s, test, MaxTags);
+ test[n] = nil;
+ r = testtags(test, tags);
+ free(s);
+ return r;
+}
+
+long
+wdbgrow(WDB *db)
+{
+ int i;
+ long j;
+ for (i = 0; i < WDBMax; i++) {
+ db->pp[i] = realloc(db->pp[i], sizeof(char *) * (db->n + 8));
+ for (j = db->n; j < db->n + 8; j++) db->pp[i][j] = nil;
+ }
+ db->n += 8;
+ return db->n - 8;
+}
+
+long
+wdbnewentry(WDB *db)
+{
+ long i;
+ for (i = 0; i < db->n; i++) if (db->pp[0][i] == 0) return i;
+ return wdbgrow(db);
+}
+
+void
+_loadindex(char *fname, int f)
+{
+ char *path = smprint("/usr/rpa/lib/wdb/index/%s", fname);
+ Biobuf *b = Bopen(path, OREAD);
+ free(path);
+ if (b == nil) sysfatal("%r");
+ char *s;
+ while((s = Brdstr(b, '\n', 1)) != nil) {
+ long n;
+ char *fields[2];
+ getfields(s, fields, 2, 1, "\t");
+ char **e = strfind(db.pp[WDBId], db.n, fields[0]);
+ if (e == nil) {
+ n = wdbnewentry(&db);
+ db.pp[WDBId][n] = strdup(fields[0]);
+ } else {
+ n = e - db.pp[WDBId];
+ }
+ if (db.pp[f][n] == nil) db.pp[f][n] = strdup(fields[1]);
+ else {
+ char *ss = smprint("%s\n%s", db.pp[f][n], fields[1]);
+ free(db.pp[f][n]);
+ db.pp[f][n] = ss;
+ }
+ free(s);
+ }
+ Bterm(b);
+ Bflush(bout);
+}
+
+void
+loadindex(void)
+{
+ _loadindex("name", WDBName);
+ _loadindex("tags", WDBTags);
+ _loadindex("type", WDBType);
+
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [query]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ Reprog *re;
+ char *t;
+ ARGBEGIN {
+ case 't':
+ t = EARGF(usage());
+ tokenize(t, tags, MaxTags);
+ break;
+ default:
+ usage();
+ } ARGEND
+ if (argc > 1) usage();
+ if (argc == 1) re = regcomp(argv[0]);
+ else re = regcomp(".*");
+
+ bout = Bfdopen(1, OWRITE);
+ loadindex();
+ long i;
+ for (i = 0; i < db.n; i++) {
+ int rn;
+ char *name = db.pp[WDBName][i];
+ if (name == nil) break;
+ rn = regexec(re, name, nil, 0);
+ if (rn != 0) {
+ Bprint(bout, "%s\n", db.pp[WDBId][i]);
+ }
+ }
+}
diff --git a/src/wdb/wdb.h b/src/wdb/wdb.h
@@ -0,0 +1,22 @@
+enum {
+ WDBId,
+ WDBName,
+ WDBTags,
+ WDBType,
+
+ WDBMax,
+};
+
+typedef struct WDB WDB;
+struct WDB {
+ union {
+ char **pp[WDBMax];
+ struct {
+ char **id;
+ char **name;
+ char **tags;
+ char **type;
+ };
+ };
+ long n;
+};