chiark / gitweb /
Monoalphabetic match filter.
[anag] / anag.c
diff --git a/anag.c b/anag.c
index 97b31c1196f842066e8718784904298098bcea32..56aa565e9f82f33654c51a525b5e703d33925059 100644 (file)
--- a/anag.c
+++ b/anag.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: anag.c,v 1.1 2001/02/04 17:14:42 mdw Exp $
+ * $Id: anag.c,v 1.6 2003/09/15 02:48:54 mdw Exp $
  *
  * Main driver for anag
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: anag.c,v $
+ * Revision 1.6  2003/09/15 02:48:54  mdw
+ * Monoalphabetic match filter.
+ *
+ * Revision 1.5  2002/08/11 12:58:09  mdw
+ * Added support for regular expression matching, if supported by the C
+ * library.
+ *
+ * Revision 1.4  2001/02/19 19:18:50  mdw
+ * Minor big fixes to parser.
+ *
+ * Revision 1.3  2001/02/16 21:45:19  mdw
+ * Be more helpful.  Improve full help message.  Special-case error for
+ * empty command strings.
+ *
+ * Revision 1.2  2001/02/07 09:09:11  mdw
+ * Fix spurious error when `-file' is used.
+ *
  * Revision 1.1  2001/02/04 17:14:42  mdw
  * Initial checkin
  *
@@ -61,12 +78,28 @@ static void help(FILE *fp)
   usage(fp);
   fputs("\n\
 Searches a wordlist, printing all of the words which match an expression.\n\
+\n\
+Options supported are:\n\
+\n\
+-h, --help             display this help text\n\
+-v, --version          display the program's version number\n\
+-u, --usage            display a very brief usage message\n\
+-f, --file FILE                read wordlist from FILE, not `" DICTIONARY "'\n\
+\n\
 The basic tests in the expression are:\n\
 \n\
 -anagram WORD          matches a full-length anagram\n\
 -subgram WORD          matches words which only use letters in WORD\n\
 -wildcard PATTERN      matches with wildcards `*' and `?'\n\
 -trackword WORD                matches words which can be found in a trackword\n\
+-mono PATTERN          matches words isomorphic to the given PATTERN\n\
+"
+#ifdef HAVE_REGCOMP
+"\
+-regexp REGEXP         matches with an (extended) regular expression\n\
+"
+#endif
+"\
 \n\
 These simple tests can be combined using the operators `-a', `-o' and `-n'\n\
 (for `and', `or' and `not'; they may also be written `&', `|' and `!' if\n\
@@ -89,7 +122,7 @@ enum {
   O_HELP, O_VERSION, O_USAGE,
   O_FILE,
   O_AND, O_OR, O_NOT, O_LPAREN, O_RPAREN,
-  O_ANAG, O_SUBG, O_WILD, O_TRACK,
+  O_ANAG, O_SUBG, O_WILD, O_TRACK, O_REGEXP, O_MONO,
   O_EOF
 };
 
@@ -119,6 +152,10 @@ static const struct opt opttab[] = {
   { "subgram",         1,      0,              O_SUBG },
   { "wildcard",                1,      0,              O_WILD },
   { "trackword",       1,      0,              O_TRACK },
+  { "mono",            1,      0,              O_MONO },
+#ifdef HAVE_REGCOMP
+  { "regexp",          1,      0,              O_REGEXP },
+#endif
 
   /* --- End marker --- */
 
@@ -230,6 +267,7 @@ static unsigned nextopt(const char *const **arg)
       default:
        return (oo->tag);
     }
+    continue;
   bad:
     die("syntax error near `%s': unknown token type", av[ai - 1]);
   }
@@ -304,7 +342,7 @@ static void p_factor(p_ctx *p, node **nn)
     p_next(p);
     p_expr(p, nn);
     if (p->t != O_RPAREN)
-      die("syntax error near `%s': missing `('", *p->a);
+      die("syntax error near `%s': missing `)'", *p->a);
     p_next(p);
   } else if (p->t == O_NOT) {
     n = xmalloc(sizeof(node_un));
@@ -318,6 +356,10 @@ static void p_factor(p_ctx *p, node **nn)
       case O_SUBG: *nn = subgram(p->a + 1); break;
       case O_WILD: *nn = wildcard(p->a + 1); break;
       case O_TRACK: *nn = trackword(p->a + 1); break;
+#ifdef HAVE_REGCOMP
+      case O_REGEXP: *nn = regexp(p->a + 1); break;
+#endif
+      case O_MONO: *nn = mono(p->a + 1); break;
       default: die("syntax error near `%s': unexpected token", *p->a);
     }
     p_next(p);
@@ -334,7 +376,6 @@ static void p_term(p_ctx *p, node **nn)
        p_next(p);
       default:
        break;
-      case O_LPAREN:
       case O_RPAREN:
       case O_OR:
       case O_EOF:
@@ -383,6 +424,11 @@ static node *p_argv(int argc, const char *const argv[])
   ac = argc;
   ai = 1;
   p_next(&p);
+  if (p.t == O_EOF) {
+    usage(stderr);
+    pquis(stderr, "(Run `$ --help' for more detail.)\n");
+    exit(EXIT_FAILURE);
+  }
   p_expr(&p, &n);
   if (p.t != O_EOF) {
     die("syntax error near `%s': rubbish at end of line (too many `)'s?)",