stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

search-fltp.c (3956B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include <regexp.h>
      5 
      6 Biobuf *bout;
      7 
      8 #include "../fltp/fltp.h"
      9 
     10 #define AFTER(X) ( (char *)X + sizeof(*X) )
     11 
     12 enum{
     13 	MaxTags = 256,
     14 	BufSize = 4096,
     15 	ListSize = 256,
     16 };
     17 
     18 int tagsqn, typeqn;
     19 char *buf, *tagsquery[MaxTags + 1], *typequery[MaxTags + 1], *tagslist[MaxTags];
     20 FLTNode *uuid, *name, *tags, *type;
     21 Reprog *re;
     22 
     23 FLTP *wdb;
     24 
     25 void
     26 node2buf(FLTNode *p)
     27 {
     28 	snprint(buf, BufSize, "%.*s", (int)p->nbytes, AFTER(p));
     29 }
     30 
     31 int
     32 _testtag(char **tags, int n, char *test){
     33 	char **p;
     34 	for(p = tags; p < tags + n; p++){
     35 		if (strcmp(test, *p) == 0) return 1;
     36 	}
     37 	return 0;
     38 }
     39 
     40 int
     41 _testtags(FLTNode *p){
     42 	int n, i, t;
     43 	node2buf(p);
     44 	t = tokenize(buf, tagslist, MaxTags);
     45 	n = 0;
     46 	for(i = 0; i < t; i++){
     47 		if (_testtag(tagsquery, tagsqn, tagslist[i]) != 0) n++;
     48 	}
     49 	return n;
     50 }
     51 
     52 int
     53 _testtype(FLTNode *p){
     54 	int n, i, t;
     55 	node2buf(p);
     56 	t = tokenize(buf, tagslist, MaxTags);
     57 	n = 0;
     58 	for(i = 0; i < t; i++){
     59 		if (_testtag(typequery, typeqn, tagslist[i]) != 0) n++;
     60 	}
     61 	return n;
     62 }
     63 
     64 int
     65 _iselem(FLTNode *p){
     66 	fprint(2, "elem %.*s\n", (int)p->nbytes, AFTER(p));
     67 	return 0;
     68 }
     69 
     70 int
     71 _islist(FLTNode *p){
     72 	fprint(2, "list %.*s\n", (int)p->nbytes, AFTER(p));
     73 	return 0;
     74 }
     75 
     76 int
     77 _testnameelem(FLTNode *p)
     78 {
     79 	node2buf(p);
     80 	return regexec(re, buf, nil, 0);
     81 }
     82 
     83 int
     84 _testnamelist(FLTNode *)
     85 {
     86 	node2buf(uuid);
     87 	fprint(2, "sublist in name field: %s\n", buf);
     88 	return 0;
     89 }
     90 
     91 int
     92 testlist(FLTNode *lp, int (*elemfp)(FLTNode *), int (*listfp)(FLTNode *)){
     93 	FLTNode *p, *root;
     94 	int r;
     95 	r = 0;
     96 	root = lp->parent;
     97 	for(p = lp->prev; p->prev != root; p = p->prev){
     98 		if(p->parent != root) continue;
     99 		if(p->next->parent == p) r += (listfp == nil) ? 0 : listfp(p);
    100 		else r += (elemfp == nil) ? 0 : elemfp(p);
    101 	}
    102 	return r;
    103 }
    104 
    105 int
    106 testname(FLTP *){
    107 	if (re == nil) return 1;
    108 	if(name == nil) sysfatal("name == nil");
    109 	return testlist(name, _testnameelem, _testnamelist);
    110 }
    111 
    112 int
    113 testtags(FLTP *){
    114 	int n;
    115 	if (tagsquery[0] == nil) return 1;
    116 	if(tags == nil) sysfatal("tags == nil");
    117 	n = testlist(tags, _testtags, nil);
    118 	return n >= tagsqn;
    119 }
    120 
    121 int
    122 testtype(FLTP *){
    123 	if (typequery[0] == nil) return 1;
    124 	if(type == nil) sysfatal("type == nil");
    125 	return testlist(type, _testtype, nil);
    126 }
    127 
    128 void
    129 runtests(FLTP *fltp){
    130 	if (testname(fltp) == 0) return;
    131 	if (testtags(fltp) == 0) return;
    132 	if (testtype(fltp) == 0) return;
    133 	print("%.*s\n", (int)(uuid->parent->next->nbytes), AFTER(uuid->parent->next));
    134 }
    135 
    136 void
    137 fltpnewendlist(FLTP *fltp){
    138 	char *s;
    139 	FLTNode *ls;
    140 	fltpendlist(fltp);
    141 	ls = fltp->np->parent->next;
    142 	s = (char *)(ls) + sizeof(FLTNode);
    143 	snprint(buf, BufSize, "%.*s", (int)ls->nbytes, s);
    144 	if(ls->prev->parent == nil){
    145 		uuid = fltp->np;
    146 		runtests(fltp);
    147 		name = nil;
    148 		tags = nil;
    149 		type = nil;
    150 		return;
    151 	} else if(strcmp(buf, "name") == 0) name = fltp->np;
    152 	else if(strcmp(buf, "tags") == 0) tags = fltp->np;
    153 	else 	if(strcmp(buf, "type") == 0)type = fltp->np;
    154 }
    155 
    156 void
    157 fltpnewgetline(FLTP *fltp){
    158 	FLTNode *old, *new;
    159 	old = fltp->np;
    160 	fltpgetline(fltp);
    161 	new = fltp->np;
    162 
    163 	new->prev = old->prev;
    164 	new->parent = old->parent;
    165 	if(old->prev != nil) old->prev->next = new;
    166 	
    167 	free(old);
    168 }
    169 
    170 void
    171 loadindex(void){
    172 	Biobuf *bfd;
    173 	char *bp, *path = "/usr/rpa/lib/wdb/index/fltp";
    174 	wdb = initfltp();
    175 	FLTWord nw[] = {
    176 		{ &nw[1], "}", fltpnewendlist },
    177 		{ wdb->wp, ".n", fltpnewgetline },
    178 	};
    179 	wdb->wp = nw;
    180 	bfd = Bopen(path, OREAD);
    181 	while((bp = Brdline(bfd, '\n')) != nil){
    182 		evalfltp(wdb, bp, Blinelen(bfd));
    183 	}
    184 	Bterm(bfd);
    185 }
    186 
    187 void
    188 usage(void){
    189 	fprint(2, "usage: %s [-t tags] [-T type] [query]\n", argv0);
    190 	exits("usage");
    191 }
    192 
    193 void
    194 main(int argc, char *argv[]){
    195 	char *t;
    196 	ARGBEGIN{
    197 	case 't':
    198 		t = EARGF(usage());
    199 		tagsqn = tokenize(t, tagsquery, MaxTags);
    200 		break;
    201 	case 'T':
    202 		t = EARGF(usage());
    203 		typeqn = tokenize(t, typequery, MaxTags);
    204 		break;
    205 	default:
    206 		usage();
    207 	} ARGEND
    208 	if(argc > 1) usage();
    209 	if(argc == 1) re = regcomp(argv[0]);
    210 	else re = nil;
    211 	buf = malloc(BufSize);
    212 	bout = Bfdopen(1, OWRITE);
    213 	loadindex();
    214 }