2 * Copyright (C) 1994, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.6 1996-02-02 13:43:51 adam
8 * The public functions simply use char instead of Dict_char to represent
9 * search strings. Dict_char is used internally only.
11 * Revision 1.5 1995/01/24 16:01:03 adam
12 * Added -ansi to CFLAGS.
13 * Use new API of dfa module.
15 * Revision 1.4 1994/10/05 12:16:51 adam
16 * Pagesize is a resource now.
18 * Revision 1.3 1994/09/26 16:31:06 adam
21 * Revision 1.2 1994/09/22 14:43:57 adam
22 * First functional version of lookup with error correction. A 'range'
23 * specified the maximum number of insertions+deletions+substitutions.
25 * Revision 1.1 1994/09/22 10:43:44 adam
26 * Two versions of depend. Type 1 is the tail-type compatible with
27 * all make programs. Type 2 is the GNU make with include facility.
28 * Type 2 is default. depend rule chooses current rule.
38 typedef unsigned MatchWord;
45 #define SH(x) (((x)<<1)+1)
47 int dict_look_ec (Dict dict, Dict_ptr ptr, MatchInfo *mi, MatchWord *ri_base,
48 int pos, int (*userfunc)(char *), int range,
55 MatchWord match_mask = 1<<(mi->m-1);
57 dict_bf_readp (dict->dbf, ptr, &p);
60 indxp = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short));
65 /* string (Dict_char *) DICT_EOS terminated */
66 /* unsigned char length of information */
67 /* char * information */
68 MatchWord *ri = ri_base, sc;
70 info = (char*)p + indxp[-lo];
75 memcpy (&ch, info+j*sizeof(Dict_char), sizeof(Dict_char));
79 if (ri[range] & match_mask)
80 (*userfunc)((char*) prefix);
83 if (j+pos >= mi->m+range)
86 ri[1+range] = SH(ri[0]) & sc;
87 for (i=1; i<=range; i++)
88 ri[i+1+range] = (SH(ri[i]) & sc) | SH(ri[i-1])
89 | SH(ri[i+range]) | ri[i-1];
91 if (!(ri[range] & (1<<(pos+j))))
98 MatchWord *ri = ri_base, sc;
101 /* Dict_ptr subptr */
102 /* Dict_char sub char */
103 /* unsigned char length of information */
104 /* char * information */
105 info = (char*)p - indxp[-lo];
106 memcpy (&ch, info+sizeof(Dict_ptr), sizeof(Dict_char));
109 sc = mi->s[ch & 255];
110 ri[1+range] = SH(ri[0]) & sc;
111 for (i=1; i<=range; i++)
112 ri[i+1+range] = (SH(ri[i]) & sc) | SH(ri[i-1])
113 | SH(ri[i+range]) | ri[i-1];
115 if (ri[range] & (1<<pos))
118 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)] &&
119 (ri[range] & match_mask))
121 prefix[pos+1] = DICT_EOS;
122 (*userfunc)((char*) prefix);
124 memcpy (&subptr, info, sizeof(Dict_ptr));
127 dict_look_ec (dict, subptr, mi, ri, pos+1,
128 userfunc, range, prefix);
129 dict_bf_readp (dict->dbf, ptr, &p);
130 indxp = (short*) ((char*) p +
131 DICT_pagesize(dict)-sizeof(short));
140 static MatchInfo *prepare_match (Dict_char *pattern)
146 mi = xmalloc (sizeof(*mi));
147 mi->m = dict_strlen (pattern);
148 mi->s = s = xmalloc (sizeof(*s)*256); /* 256 !!! */
149 for (i=0; i<256; i++)
151 for (i=0; pattern[i]; i++)
152 s[pattern[i]&255] += 1<<i;
156 int dict_lookup_ec (Dict dict, char *pattern, int range,
157 int (*userfunc)(char *name))
162 Dict_char prefix[2048];
164 if (dict->head.last == 1)
167 mi = prepare_match ((Dict_char*) pattern);
169 ri = xmalloc ((dict_strlen((Dict_char*) pattern)+range+2)
170 * (range+1)*sizeof(*ri));
171 for (i=0; i<=range; i++)
174 i = dict_look_ec (dict, 1, mi, ri, 0, userfunc, range, prefix);