# include "stdio.h"
# include "assert.h"
# include "refer.h"
# include "re.h"
#ifndef D1
#define D1 0
#endif
#if D1
#define D(x) x
#else
#define D(x)
#endif
static void overflo(void);
/*
* checks list of drops for false drops;
* uses rprog (usually "deliv") to find items
*/
void dropout(List *master, FILE *fc, int nitem, char *qitem[], char *rprog, int full)
{
int nf;
int i, j, len;
char res[100], output[TXTLEN];
extern int colevel, reached;
int need;
re_ac *fg;
D(fprintf(stderr, "in dropout, nf %d master %ld %ld %ld\n", nf, master->el[0], master->el[1], master->el[2]));
nf = master->n;
master->n = 0;
/*
* build aho-corasick machine to check for false drops
*/
fg = re_acinit();
for (j = 0; j < nitem; j++) {
char *keyw = qitem[j];
if (!re_acadd(fg, keyw, keyw+strlen(keyw)))
overflo();
}
if (!re_accomp(fg))
overflo();
/*
* check each candidate
*/
for (i = 0; i < nf; i++) {
D(fprintf(stderr, "i %d master %lo\n", i, master->el[i]));
xseek(fc, master->el[i], 0);
fgets(res, sizeof(res), fc);
D(fprintf(stderr, "tag %s", res));
if (!rdkeyfile(res, output, sizeof(output))) {
char *s;
D(fprintf(stderr, "not rdkeyfile try rprog %c\n", rprog? 'y': 'n'));
if ((s = strchr(res, ';')) != 0 ||
(s = strchr(res, '\n')) != 0)
*s = 0;
if (rprog)
corout(res, output, rprog, 0, sizeof(output));
else
findline(res, output, sizeof(output), indexdate);
}
len = strlen(output);
D(fprintf(stderr, "item %d of %d, tag %s len %d output\n%s\n..\n", i, nf, res, len, output));
if (len == 0)
continue;
need = colevel? reached: nitem; /* min. number of matches required */
if (re_run(fg, output, len, need) >= need) {
D(fprintf(stderr, "fgrep found it\n"));
applist(master, master->el[i]);
if (master->n <= full) {
if (soutput == 0)
fputs(output, stdout);
else
strcpy(soutput, output);
}
}
}
/* free(fg); */ /* not done: space allocated statically in fgrep.c */
}
int rdkeyfile(char *res, char *output, unsigned outlen)
{
extern FILE *fd;
long lp;
int len;
char *ref;
if (fd == 0) {
D(fprintf(stderr, "no fd in rdkeyfile\n"));
return 0;
}
if (outlen)
*output = 0;
if ((ref = strchr(res, ';')) != 0 &&
sscanf(ref+1, "%ld,%d", &lp, &len) == 2) {
fseek(fd, lp, 0);
if (len < 0)
len = 0;
if (len > outlen)
len = outlen;
fgets(output, len, fd);
return 1;
}
return 0;
}
static void overflo(void)
{
err("too many keywords to check (fgrep)\n");
}
|