chiark / gitweb /
build: Fix for newer Auto tools.
[anag] / mono.c
1 /* -*-c-*-
2  *
3  * $Id: mono.c,v 1.2 2004/04/08 01:36:19 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 /*----- Header files ------------------------------------------------------*/
30
31 #include "anag.h"
32
33 /*----- Data structures ---------------------------------------------------*/
34
35 typedef struct node_mono {
36   node n;
37   unsigned len;
38   unsigned char *p;
39 } node_mono;
40
41 /*----- Main code ---------------------------------------------------------*/
42
43 /* --- Matching --- */
44
45 static int n_mono(node *nn, const char *p, size_t sz)
46 {
47   node_mono *n = (node_mono *)nn;
48   unsigned map[UCHAR_MAX], imap[UCHAR_MAX];
49   const unsigned char *q = n->p;
50   int ch, i;
51
52   if (sz != n->len)
53     return (0);
54   memset(map, 0, sizeof(map));
55   memset(imap, 0, sizeof(imap));
56   while (*p) {
57     ch = *p++;
58     i = *q++;
59     if (!map[i]) {
60       if (imap[ch])
61         return (0);
62       map[i] = ch;
63       imap[ch] = 1;
64     } else if (map[i] != ch)
65       return (0);
66   }
67   return (1);
68 }
69
70 /* --- Node creation --- */
71
72 node *mono(const char *const *av)
73 {
74   unsigned char map[UCHAR_MAX];
75   unsigned max;
76   int ch;
77   const char *p;
78   unsigned char *q;
79
80   node_mono *n = xmalloc(sizeof(*n));
81   n->n.func = n_mono;
82   memset(map, UCHAR_MAX, sizeof(map));
83   max = 0;
84   p = av[0];
85   n->len = strlen(p);
86   q = xmalloc(n->len);
87   n->p = q;
88   while (*p) {
89     ch = *p++;
90     if (map[ch] >= max)
91       map[ch] = max++;
92     *q++ = map[ch];
93   }
94   return (&n->n);
95 }
96
97 /*----- That's all, folks -------------------------------------------------*/