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