• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "system.h"
2 #include <stdio.h>
3 #include "popt.h"
4 
5 static int _debug = 0;
6 static int _verbose = 1;
7 static const char * dictfn = "/usr/share/dict/words";
8 static poptBits dictbits = NULL;
9 static struct {
10     unsigned total;
11     unsigned hits;
12     unsigned misses;
13 } e;
14 
loadDict(const char * fn,poptBits * ap)15 static int loadDict(const char * fn, poptBits * ap)
16 {
17     char b[BUFSIZ];
18     size_t nb = sizeof(b);
19     FILE * fp = fopen(fn, "r");
20     char * t, *te;
21     int nlines = -1;
22 
23     if (fp == NULL || ferror(fp)) goto exit;
24 
25     nlines = 0;
26     while ((t = fgets(b, nb, fp)) != NULL) {
27 	while (*t && isspace(*t)) t++;
28 	if (*t == '#') continue;
29 	te = t + strlen(t);
30 	while (te-- > t && isspace(*te)) *te = '\0';
31 	if (*t == '\0') continue;
32 	if (ap) {
33 if (_debug)
34 fprintf(stderr, "==> poptSaveBits(%p, \"%s\")\n", *ap, t);
35 	    (void) poptSaveBits(ap, 0, t);
36 	}
37 	nlines++;
38     }
39 exit:
40     if (fp) (void) fclose(fp);
41     return nlines;
42 }
43 
44 static struct poptOption options[] = {
45   { "debug", 'd', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &_debug, 1,
46         "Set debugging.", NULL },
47   { "verbose", 'v', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &_verbose, 1,
48         "Set verbosity.", NULL },
49 
50   POPT_AUTOALIAS
51   POPT_AUTOHELP
52   POPT_TABLEEND
53 };
54 
main(int argc,const char ** argv)55 int main(int argc, const char ** argv)
56 {
57     poptContext optCon = NULL;
58     const char ** av = NULL;
59     poptBits avbits = NULL;
60     int ec = 2;		/* assume failure */
61     int rc;
62 
63 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
64     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
65 #endif
66 
67     /* XXX Scale the Bloom filters in popt. */
68     if ((rc = loadDict(dictfn, NULL)) <= 0)
69 	goto exit;
70     _poptBitsK = 2;
71     _poptBitsM = 0;
72     _poptBitsN = _poptBitsK * rc;
73 
74     optCon = poptGetContext("tdict", argc, argv, options, 0);
75 
76     /* Read all the options (if any). */
77     while ((rc = poptGetNextOpt(optCon)) > 0) {
78         char * optArg = poptGetOptArg(optCon);
79 	if (optArg) free(optArg);
80         switch (rc) {
81         default:	goto exit;	break;
82         }
83     }
84     if (rc < -1) {
85         fprintf(stderr, "tdict: %s: %s\n",
86                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
87                 poptStrerror(rc));
88 	goto exit;
89     }
90 
91     if ((rc = loadDict(dictfn, &dictbits)) <= 0)
92 	goto exit;
93 
94     av = poptGetArgs(optCon);
95     if ((rc = poptBitsArgs(optCon, &avbits)) != 0)
96 	goto exit;
97     if (avbits) {
98 	poptBits Ibits = NULL;
99 	(void) poptBitsUnion(&Ibits, dictbits);
100 	rc = poptBitsIntersect(&Ibits, avbits);
101 	fprintf(stdout, "===== %s words are in %s\n", (rc ? "Some" : "No"), dictfn);
102 	if (Ibits) free(Ibits);
103     }
104     if (av && avbits)
105     while (*av) {
106 	rc = poptBitsChk(dictbits, *av);
107 	if (rc < 0) goto exit;
108 	e.total++;
109 	if (rc > 0) {
110 	    if (_verbose)
111 		fprintf(stdout, "%s:\tYES\n", *av);
112 	    e.hits++;
113 	} else {
114 	    if (_verbose)
115 		fprintf(stdout, "%s:\tNO\n", *av);
116 	    e.misses++;
117 	}
118 	av++;
119     }
120 
121     ec = 0;
122 
123 exit:
124     fprintf(stdout, "===== poptBits N:%u M:%u K:%u (%uKb) total(%u) = hits(%u) + misses(%u)\n",
125 	_poptBitsN, _poptBitsM, _poptBitsK, (((_poptBitsM/8)+1)+1023)/1024, e.total, e.hits, e.misses);
126     if (avbits) free(avbits);
127     optCon = poptFreeContext(optCon);
128 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
129     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
130 #endif
131     return ec;
132 }
133