1 /* $Id: lookupec.c,v 1.10 2002-08-02 19:26:55 adam Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 typedef unsigned MatchWord;
38 #define SH(x) (((x)<<1)+1)
40 int dict_look_ec (Dict dict, Dict_ptr ptr, MatchInfo *mi, MatchWord *ri_base,
41 int pos, int (*userfunc)(char *), int range,
48 MatchWord match_mask = 1<<(mi->m-1);
50 dict_bf_readp (dict->dbf, ptr, &p);
53 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
58 /* string (Dict_char *) DICT_EOS terminated */
59 /* unsigned char length of information */
60 /* char * information */
61 MatchWord *ri = ri_base, sc;
63 info = (char*)p + indxp[-lo];
68 memcpy (&ch, info+j*sizeof(Dict_char), sizeof(Dict_char));
72 if (ri[range] & match_mask)
73 (*userfunc)((char*) prefix);
76 if (j+pos >= mi->m+range)
79 ri[1+range] = SH(ri[0]) & sc;
80 for (i=1; i<=range; i++)
81 ri[i+1+range] = (SH(ri[i]) & sc) | SH(ri[i-1])
82 | SH(ri[i+range]) | ri[i-1];
84 if (!(ri[range] & (1<<(pos+j))))
91 MatchWord *ri = ri_base, sc;
95 /* Dict_char sub char */
96 /* unsigned char length of information */
97 /* char * information */
98 info = (char*)p - indxp[-lo];
99 memcpy (&ch, info+sizeof(Dict_ptr), sizeof(Dict_char));
102 sc = mi->s[ch & 255];
103 ri[1+range] = SH(ri[0]) & sc;
104 for (i=1; i<=range; i++)
105 ri[i+1+range] = (SH(ri[i]) & sc) | SH(ri[i-1])
106 | SH(ri[i+range]) | ri[i-1];
108 if (ri[range] & (1<<pos))
111 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)] &&
112 (ri[range] & match_mask))
114 prefix[pos+1] = DICT_EOS;
115 (*userfunc)((char*) prefix);
117 memcpy (&subptr, info, sizeof(Dict_ptr));
120 dict_look_ec (dict, subptr, mi, ri, pos+1,
121 userfunc, range, prefix);
122 dict_bf_readp (dict->dbf, ptr, &p);
123 indxp = (short*) ((char*) p +
124 DICT_bsize(p)-sizeof(short));
133 static MatchInfo *prepare_match (Dict_char *pattern)
139 mi = (MatchInfo *) xmalloc (sizeof(*mi));
140 mi->m = dict_strlen (pattern);
141 mi->s = s = (MatchWord *) xmalloc (sizeof(*s)*256); /* 256 !!! */
142 for (i=0; i<256; i++)
144 for (i=0; pattern[i]; i++)
145 s[pattern[i]&255] += 1<<i;
149 int dict_lookup_ec (Dict dict, char *pattern, int range,
150 int (*userfunc)(char *name))
155 Dict_char prefix[2048];
157 if (!dict->head.root)
160 mi = prepare_match ((Dict_char*) pattern);
162 ri = (MatchWord *) xmalloc ((dict_strlen((Dict_char*) pattern)+range+2)
163 * (range+1)*sizeof(*ri));
164 for (i=0; i<=range; i++)
167 i = dict_look_ec (dict, dict->head.root, mi, ri, 0, userfunc,