stew

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

extract.c (2185B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <regexp.h>
      4 
      5 #include "../util/util.h"
      6 #include "../tablist/tablist.h"
      7 
      8 enum {
      9 	MDefault = 0,
     10 	MPrune,
     11 	MTail,
     12 	MHead,
     13 };
     14 Reprog **query;
     15 int mode = MDefault, qcount;
     16 
     17 void
     18 usage(void)
     19 {
     20 	fprint(2, "usage: [-pth] %s query\n", argv0);
     21 	exits("usage");
     22 }
     23 
     24 int
     25 fnoop(TLnode *, void *)
     26 {
     27 	return 1;
     28 }
     29 
     30 int
     31 fregex(TLnode *n, void *v)
     32 {
     33 	int ret;
     34 	char *buf;
     35 	Reprog *r = v;
     36 	Slice *data = n->name;
     37 	if (data == nil) data = n->value;
     38 	buf = malloc(data->len + 1);
     39 	memcpy(buf, data->p, data->len);
     40 	buf[data->len] = 0;
     41 
     42 	ret = regexec(r, buf, nil, 0);
     43 	
     44 	free(buf);
     45 
     46 	return ret;
     47 }
     48 
     49 int
     50 frecur(TLnode *n, void *v)
     51 {
     52 	int i, x = (int)v;
     53 	TLnode **c;
     54 	if (x >= qcount) {
     55 		return 1;
     56 	}
     57 	if (fregex(n, query[x]) == 0) {
     58 		return 0;
     59 	}
     60 	if (x + 1 == qcount) return 1;
     61 	for (i = 0; i < n->children->len; i++) {
     62 		c = slicegetp(n->children, i);
     63 		if (frecur(*c, (void *)(x + 1)) == 1) {
     64 			return 1;
     65 		}
     66 	}
     67 	return 0;
     68 }
     69 
     70 Slice *
     71 filter(Slice *in, int (*ffunc)(TLnode *, void *))
     72 {
     73 	int i;
     74 	Slice *out;
     75 	TLnode **v, *n;
     76 	out = allocslice(&TLnodeType, 0, in->len);
     77 	for (i = 0; i < in->len; i++) {
     78 		v = slicegetp(in, i);
     79 		n = *v;
     80 		if (ffunc(n, nil)) {
     81 			sliceappendp(out, 1, v);
     82 		}
     83 	}
     84 	return out;
     85 }
     86 
     87 void
     88 main(int argc, char **argv)
     89 {
     90 	char buf[8096];
     91 	int i, n;
     92 	TLdecoder *dec;
     93 	TLencoder *enc;
     94 	Slice *out;
     95 
     96 	ARGBEGIN {
     97 	case 'p':
     98 		mode = MPrune;
     99 		break;
    100 	case 't':
    101 		mode = MTail;
    102 		break;
    103 	case 'h':
    104 		mode = MHead;
    105 		break;
    106 	default:
    107 		usage();
    108 	} ARGEND
    109 	
    110 	qcount = argc;
    111 	query = malloc(sizeof(Reprog *) * qcount);
    112 	for (i = 0; i < qcount; i++) {
    113 		query[i] = regcompnl(argv[i]);
    114 	}
    115 
    116 	dec = initTLdecoder(nil);
    117 	while ((n = read(0, buf, sizeof(buf))) > 0) {
    118 		TLdecode(dec, buf, n);
    119 	}
    120 
    121 	switch (mode) {
    122 	case MDefault:
    123 		out = filter(dec->nodes, frecur);
    124 		break;
    125 	case MPrune:
    126 		break;
    127 	case MTail:
    128 		break;
    129 	case MHead:
    130 		out = filter(dec->nodes, frecur);
    131 		for (i = 0; i < out->len; i++) {
    132 			TLnode **v = slicegetp(out, i);
    133 			TLnode *n = *v;
    134 			n->children->len = 0;
    135 		}
    136 		break;
    137 	default:
    138 		sysfatal("unknown mode %d", mode);
    139 	}
    140 
    141 	enc = initTLencoder(out);
    142 	while ((n = TLencode(enc, buf, sizeof(buf))) > 0) {
    143 		write(1, buf, n);
    144 	}
    145 }