#include "system.h" #include #include "popt.h" static int _debug = 0; static int _verbose = 1; static const char * dictfn = "/usr/share/dict/words"; static poptBits dictbits = NULL; static struct { unsigned total; unsigned hits; unsigned misses; } e; static int loadDict(const char * fn, poptBits * ap) { char b[BUFSIZ]; size_t nb = sizeof(b); FILE * fp = fopen(fn, "r"); char * t, *te; int nlines = -1; if (fp == NULL || ferror(fp)) goto exit; nlines = 0; while ((t = fgets(b, nb, fp)) != NULL) { while (*t && isspace(*t)) t++; if (*t == '#') continue; te = t + strlen(t); while (te-- > t && isspace(*te)) *te = '\0'; if (*t == '\0') continue; if (ap) { if (_debug) fprintf(stderr, "==> poptSaveBits(%p, \"%s\")\n", *ap, t); (void) poptSaveBits(ap, 0, t); } nlines++; } exit: if (fp) (void) fclose(fp); return nlines; } static struct poptOption options[] = { { "debug", 'd', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &_debug, 1, "Set debugging.", NULL }, { "verbose", 'v', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &_verbose, 0, "Set verbosity.", NULL }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; int main(int argc, const char ** argv) { poptContext optCon = NULL; const char ** av = NULL; poptBits avbits = NULL; int ec = 2; /* assume failure */ int rc; #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ #endif /* XXX Scale the Bloom filters in popt. */ if ((rc = loadDict(dictfn, NULL)) <= 0) goto exit; _poptBitsK = 10; _poptBitsM = 0; _poptBitsN = 2 * _poptBitsK * rc; optCon = poptGetContext("tdict", argc, argv, options, 0); /* Read all the options (if any). */ while ((rc = poptGetNextOpt(optCon)) > 0) { char * optArg = poptGetOptArg(optCon); if (optArg) free(optArg); switch (rc) { default: goto exit; break; } } if (rc < -1) { fprintf(stderr, "tdict: %s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); goto exit; } if ((rc = loadDict(dictfn, &dictbits)) <= 0) goto exit; av = poptGetArgs(optCon); if ((rc = poptBitsArgs(optCon, &avbits)) != 0) goto exit; if (avbits) { poptBits Ibits = NULL; (void) poptBitsUnion(&Ibits, dictbits); rc = poptBitsIntersect(&Ibits, avbits); fprintf(stdout, "===== %s words are in %s\n", (rc ? "Some" : "No"), dictfn); if (Ibits) free(Ibits); } if (av && avbits) while (*av) { rc = poptBitsChk(dictbits, *av); if (rc < 0) goto exit; e.total++; if (rc > 0) { if (_verbose) fprintf(stdout, "%s:\tYES\n", *av); e.hits++; } else { if (_verbose) fprintf(stdout, "%s:\tNO\n", *av); e.misses++; } av++; } ec = 0; exit: /* XXX : depends on the /usr/share/dict/words contents so no default*/ if (rc >= 0) { if (_debug) { fprintf(stdout, "===== poptBits N:%u M:%u K:%u (%uKb) ", _poptBitsN, _poptBitsM, _poptBitsK, (((_poptBitsM/8)+1)+1023)/1024); } fprintf(stdout, "total(%u) = hits(%u) + misses(%u)\n", e.total, e.hits, e.misses); } if (avbits) free(avbits); optCon = poptFreeContext(optCon); #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ #endif return ec; }