stew

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

search.c (4052B)


      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 linecount, 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 	char buf[256];
    131 	if (testname(fltp) == 0) return;
    132 	if (testtags(fltp) == 0) return;
    133 	if (testtype(fltp) == 0) return;
    134 	sprint(buf, "%.*s\n", (int)(uuid->parent->next->nbytes), AFTER(uuid->parent->next));
    135 	if(buf[0] == '{') sysfatal("parser lost the plot :%d", linecount);
    136 	print(buf);
    137 	
    138 }
    139 
    140 void
    141 fltpnewendlist(FLTP *fltp){
    142 	char *s;
    143 	FLTNode *ls;
    144 	fltpendlist(fltp);
    145 	ls = fltp->np->parent->next;
    146 	s = (char *)(ls) + sizeof(FLTNode);
    147 	snprint(buf, BufSize, "%.*s", (int)ls->nbytes, s);
    148 	if(ls->prev->parent == nil){
    149 		uuid = fltp->np;
    150 		runtests(fltp);
    151 		name = nil;
    152 		tags = nil;
    153 		type = nil;
    154 		return;
    155 	} else if(strcmp(buf, "name") == 0) name = fltp->np;
    156 	else if(strcmp(buf, "tags") == 0) tags = fltp->np;
    157 	else 	if(strcmp(buf, "type") == 0)type = fltp->np;
    158 }
    159 
    160 void
    161 fltpnewgetline(FLTP *fltp){
    162 	FLTNode *old, *new;
    163 	old = fltp->np;
    164 	fltpgetline(fltp);
    165 	new = fltp->np;
    166 
    167 	new->prev = old->prev;
    168 	new->parent = old->parent;
    169 	if(old->prev != nil) old->prev->next = new;
    170 	
    171 	free(old);
    172 }
    173 
    174 void
    175 loadindex(void){
    176 	Biobuf *bfd;
    177 	char *bp;
    178 	wdb = initfltp();
    179 	FLTWord nw[] = {
    180 		{ &nw[1], "}", fltpnewendlist },
    181 		{ wdb->wp, ".n", fltpnewgetline },
    182 	};
    183 	wdb->wp = nw;
    184 	bfd = Bfdopen(0, OREAD);
    185 	while((bp = Brdline(bfd, '\n')) != nil){
    186 		linecount++;
    187 		evalfltp(wdb, bp, Blinelen(bfd));
    188 	}
    189 	Bterm(bfd);
    190 }
    191 
    192 void
    193 usage(void){
    194 	fprint(2, "usage: %s [-t tags] [-T type] [name query]\n", argv0);
    195 	exits("usage");
    196 }
    197 
    198 void
    199 main(int argc, char *argv[]){
    200 	char *t;
    201 	ARGBEGIN{
    202 	case 't':
    203 		t = EARGF(usage());
    204 		tagsqn = tokenize(t, tagsquery, MaxTags);
    205 		break;
    206 	case 'T':
    207 		t = EARGF(usage());
    208 		typeqn = tokenize(t, typequery, MaxTags);
    209 		break;
    210 	default:
    211 		usage();
    212 	} ARGEND
    213 	if(argc > 1) usage();
    214 	if(argc == 1) re = regcomp(argv[0]);
    215 	else re = nil;
    216 	buf = malloc(BufSize);
    217 	bout = Bfdopen(1, OWRITE);
    218 	loadindex();
    219 }