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