tdict.c 3.2 KB

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