chiark / gitweb /
Missing file.
[anag] / mono.c
1 /* -*-c-*-
2  *
3  * $Id: mono.c,v 1.1 2003/09/15 02:48:54 mdw Exp $
4  *
5  * Monoalphabetic matcher
6  *
7  * (c) 2003 Mark Wooding
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Anag: a simple wordgame helper.
13  *
14  * Anag is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * Anag is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with Anag; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Revision history --------------------------------------------------* 
30  *
31  * $Log: mono.c,v $
32  * Revision 1.1  2003/09/15 02:48:54  mdw
33  * Monoalphabetic match filter.
34  *
35  */
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #include "anag.h"
40
41 /*----- Data structures ---------------------------------------------------*/
42
43 typedef struct node_mono {
44   node n;
45   unsigned len;
46   unsigned char *p;
47 } node_mono;
48
49 /*----- Main code ---------------------------------------------------------*/
50
51 /* --- Matching --- */
52
53 static int n_mono(node *nn, const char *p, size_t sz)
54 {
55   node_mono *n = (node_mono *)nn;
56   unsigned map[UCHAR_MAX], imap[UCHAR_MAX];
57   const unsigned char *q = n->p;
58   int ch, i;
59
60   if (sz != n->len)
61     return (0);
62   memset(map, 0, sizeof(map));
63   memset(imap, 0, sizeof(imap));
64   while (*p) {
65     ch = *p++;
66     i = *q++;
67     if (!map[i]) {
68       if (imap[ch])
69         return (0);
70       map[i] = ch;
71       imap[ch] = 1;
72     } else if (map[i] != ch)
73       return (0);
74   }
75   return (1);
76 }
77
78 /* --- Node creation --- */
79
80 node *mono(const char *const *av)
81 {
82   unsigned char map[UCHAR_MAX];
83   unsigned max;
84   int ch;
85   const char *p;
86   unsigned char *q;
87
88   node_mono *n = xmalloc(sizeof(*n));
89   n->n.func = n_mono;
90   memset(map, UCHAR_MAX, sizeof(map));
91   max = 0;
92   p = av[0];
93   n->len = strlen(p);
94   q = xmalloc(n->len);
95   n->p = q;
96   while (*p) {
97     ch = *p++;
98     if (map[ch] >= max)
99       map[ch] = max++;
100     *q++ = map[ch];
101   }
102   return (&n->n);
103 }
104
105 /*----- That's all, folks -------------------------------------------------*/