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 }