# 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"); }