blob: b2e0859d19c1a2745154c726b05de2019fb6f7ef [file] [log] [blame]
#include "system.h"
#include <stdio.h>
#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, 1,
"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 = 2;
_poptBitsM = 0;
_poptBitsN = _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:
fprintf(stdout, "===== poptBits N:%u M:%u K:%u (%uKb) total(%u) = hits(%u) + misses(%u)\n",
_poptBitsN, _poptBitsM, _poptBitsK, (((_poptBitsM/8)+1)+1023)/1024, 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;
}