Function dict_lookup_grep got extra parameter, init_pos, which marks
[idzebra-moved-to-github.git] / dict / dicttest.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: dicttest.c,v $
7  * Revision 1.20  1996-03-20 09:35:16  adam
8  * Function dict_lookup_grep got extra parameter, init_pos, which marks
9  * from which position in pattern approximate pattern matching should occur.
10  *
11  * Revision 1.19  1996/02/02  13:43:50  adam
12  * The public functions simply use char instead of Dict_char to represent
13  * search strings. Dict_char is used internally only.
14  *
15  * Revision 1.18  1996/02/01  20:39:52  adam
16  * Bug fix: insert didn't work on 8-bit characters due to unsigned char
17  * compares in dict_strcmp (strcmp) and signed Dict_char. Dict_char is
18  * unsigned now.
19  *
20  * Revision 1.17  1995/12/06  17:48:30  adam
21  * Bug fix: delete didn't work.
22  *
23  * Revision 1.16  1995/10/09  16:18:31  adam
24  * Function dict_lookup_grep got extra client data parameter.
25  *
26  * Revision 1.15  1995/09/04  12:33:31  adam
27  * Various cleanup. YAZ util used instead.
28  *
29  * Revision 1.14  1994/10/04  17:46:55  adam
30  * Function options now returns arg with error option.
31  *
32  * Revision 1.13  1994/10/04  12:08:05  adam
33  * Some bug fixes and some optimizations.
34  *
35  * Revision 1.12  1994/10/03  17:23:03  adam
36  * First version of dictionary lookup with regular expressions and errors.
37  *
38  * Revision 1.11  1994/09/28  13:07:09  adam
39  * Use log_mask_str now.
40  *
41  * Revision 1.10  1994/09/26  10:17:24  adam
42  * Minor changes.
43  *
44  * Revision 1.9  1994/09/22  14:43:56  adam
45  * First functional version of lookup with error correction. A 'range'
46  * specified the maximum number of insertions+deletions+substitutions.
47  *
48  * Revision 1.8  1994/09/22  10:43:44  adam
49  * Two versions of depend. Type 1 is the tail-type compatible with
50  * all make programs. Type 2 is the GNU make with include facility.
51  * Type 2 is default. depend rule chooses current rule.
52  *
53  * Revision 1.7  1994/09/19  16:34:26  adam
54  * Depend rule change. Minor changes in dicttest.c
55  *
56  * Revision 1.6  1994/09/16  15:39:12  adam
57  * Initial code of lookup - not tested yet.
58  *
59  * Revision 1.5  1994/09/06  13:05:14  adam
60  * Further development of insertion. Some special cases are
61  * not properly handled yet! assert(0) are put here. The
62  * binary search in each page definitely reduce usr CPU.
63  *
64  * Revision 1.4  1994/09/01  17:49:37  adam
65  * Removed stupid line. Work on insertion in dictionary. Not finished yet.
66  *
67  * Revision 1.3  1994/09/01  17:44:06  adam
68  * depend include change.
69  *
70  * Revision 1.2  1994/08/18  12:40:54  adam
71  * Some development of dictionary. Not finished at all!
72  *
73  * Revision 1.1  1994/08/16  16:26:47  adam
74  * Added dict.
75  *
76  */
77
78 #include <stdlib.h>
79 #include <string.h>
80 #include <stdio.h>
81 #include <ctype.h>
82
83 #include <dict.h>
84
85 char *prog;
86 static Dict dict;
87
88 static int look_hits;
89
90 static int grep_handle (char *name, const char *info, void *client)
91 {
92     look_hits++;
93     printf ("%s\n", name);
94     return 0;
95 }
96
97 int main (int argc, char **argv)
98 {
99     const char *name = NULL;
100     const char *inputfile = NULL;
101     const char *base = NULL;
102     int do_delete = 0;
103     int range = -1;
104     int srange = 0;
105     int rw = 0;
106     int infosize = 4;
107     int cache = 10;
108     int ret;
109     int unique = 0;
110     char *grep_pattern = NULL;
111     char *arg;
112     int no_of_iterations = 0;
113     int no_of_new = 0, no_of_same = 0, no_of_change = 0;
114     int no_of_hits = 0, no_of_misses = 0, no_not_found = 0, no_of_deleted = 0;
115     int max_pos;
116     
117     prog = argv[0];
118     if (argc < 2)
119     {
120         fprintf (stderr, "usage:\n "
121                  " %s [-d] [-r n] [-p n] [-u] [-g pat] [-s n] [-v n] [-i f]"
122                  " [-w] [-c n] base file\n\n",
123                  prog);
124         fprintf (stderr, "  -d      delete instead of insert\n");
125         fprintf (stderr, "  -r n    set regular match range\n");
126         fprintf (stderr, "  -p n    set regular match start range\n");
127         fprintf (stderr, "  -u      report if keys change during insert\n");
128         fprintf (stderr, "  -g p    try pattern n (see -r)\n");
129         fprintf (stderr, "  -s n    set info size to n (instead of 4)\n");
130         fprintf (stderr, "  -v n    set logging level\n");
131         fprintf (stderr, "  -i f    read file with words\n");
132         fprintf (stderr, "  -w      insert/delete instead of lookup\n");
133         fprintf (stderr, "  -c n    cache size (number of pages)\n");
134         exit (1);
135     }
136     while ((ret = options ("dr:p:ug:s:v:i:wc:", argv, argc, &arg)) != -2)
137     {
138         if (ret == 0)
139         {
140             if (!base)
141                 base = arg;
142             else if (!name)
143                 name = arg;
144             else
145             {
146                 logf (LOG_FATAL, "too many files specified\n");
147                 exit (1);
148             }
149         }
150         else if (ret == 'd')
151             do_delete = 1;
152         else if (ret == 'g')
153         {
154             grep_pattern = arg;
155         }
156         else if (ret == 'r')
157         {
158             range = atoi (arg);
159         }
160         else if (ret == 'p')
161         {
162             srange = atoi (arg);
163         }
164         else if (ret == 'u')
165         {
166             unique = 1;
167         }
168         else if (ret == 'c')
169         {
170             cache = atoi(arg);
171             if (cache<2)
172                 cache = 2;
173         }
174         else if (ret == 'w')
175             rw = 1;
176         else if (ret == 'i')
177             inputfile = arg;
178         else if (ret == 's')
179         {
180             infosize = atoi(arg);
181         }
182         else if (ret == 'v')
183         {
184             log_init (log_mask_str(arg), prog, NULL);
185         }
186         else
187         {
188             logf (LOG_FATAL, "Unknown option '-%s'", arg);
189             exit (1);
190         }
191     }
192     if (!base || !name)
193     {
194         logf (LOG_FATAL, "no base and/or dictionary specified");
195         exit (1);
196     }
197     common_resource = res_open (base);
198     if (!common_resource)
199     {
200         logf (LOG_FATAL, "cannot open resource `%s'", base);
201         exit (1);
202     }
203     dict = dict_open (name, cache, rw);
204     if (!dict)
205     {
206         logf (LOG_FATAL, "dict_open fail of `%s'", name);
207         exit (1);
208     }
209     if (inputfile)
210     {
211         FILE *ipf;
212         char ipf_buf[1024];
213         int line = 1;
214         char infobytes[120];
215         memset (infobytes, 0, 120);
216
217         if (!(ipf = fopen(inputfile, "r")))
218         {
219             logf (LOG_FATAL|LOG_ERRNO, "cannot open %s", inputfile);
220             exit (1);
221         }
222         
223         while (fgets (ipf_buf, 1023, ipf))
224         {
225             char *ipf_ptr = ipf_buf;
226             sprintf (infobytes, "%d", line);
227             for (;*ipf_ptr && *ipf_ptr != '\n';ipf_ptr++)
228             {
229                 if (isalpha(*ipf_ptr) || *ipf_ptr == '_')
230                 {
231                     int i = 1;
232                     while (ipf_ptr[i] && (isalnum(ipf_ptr[i]) ||
233                                           ipf_ptr[i] == '_'))
234                         i++;
235                     if (ipf_ptr[i])
236                         ipf_ptr[i++] = '\0';
237                     if (rw)
238                     {
239                         if (do_delete)
240                             switch (dict_delete (dict, ipf_ptr))
241                             {
242                             case 0:
243                                 no_not_found++;
244                                 break;
245                             case 1:
246                                 no_of_deleted++;
247                             }
248                         else
249                             switch(dict_insert (dict, ipf_ptr,
250                                                 infosize, infobytes))
251                             {
252                             case 0:
253                                 no_of_new++;
254                                 break;
255                             case 1:
256                                 no_of_change++;
257                                 if (unique)
258                                     logf (LOG_LOG, "%s change\n", ipf_ptr);
259                                 break;
260                             case 2:
261                                 if (unique)
262                                     logf (LOG_LOG, "%s duplicate\n", ipf_ptr);
263                                 no_of_same++;
264                                 break;
265                             }
266                     }
267                     else if(range < 0)
268                     {
269                         char *cp;
270
271                         cp = dict_lookup (dict, ipf_ptr);
272                         if (cp && *cp)
273                             no_of_hits++;
274                         else
275                             no_of_misses++;
276                     }
277                     else
278                     {
279                         look_hits = 0;
280                         dict_lookup_grep (dict, ipf_ptr, range, NULL,
281                                           &max_pos, srange, grep_handle);
282                         if (look_hits)
283                             no_of_hits++;
284                         else
285                             no_of_misses++;
286                     }
287                     ++no_of_iterations;
288                     ipf_ptr += (i-1);
289                 }
290             }
291             ++line;
292         }
293         fclose (ipf);
294     }
295     if (grep_pattern)
296     {
297         if (range < 0)
298             range = 0;
299         logf (LOG_LOG, "Grepping '%s'", grep_pattern);
300         dict_lookup_grep (dict, grep_pattern, range, NULL, &max_pos,
301                           srange, grep_handle);
302     }
303     if (rw)
304     {
305         logf (LOG_LOG, "Iterations.... %d", no_of_iterations);            
306         if (do_delete)
307         {
308             logf (LOG_LOG, "No of deleted. %d", no_of_deleted);
309             logf (LOG_LOG, "No not found.. %d", no_not_found);
310         }
311         else
312         {
313             logf (LOG_LOG, "No of new..... %d", no_of_new);
314             logf (LOG_LOG, "No of change.. %d", no_of_change);
315         }
316     }
317     else
318     {
319         logf (LOG_LOG, "Lookups....... %d", no_of_iterations);
320         logf (LOG_LOG, "No of hits.... %d", no_of_hits);
321         logf (LOG_LOG, "No of misses.. %d", no_of_misses);
322     }
323     dict_close (dict);
324     res_close (common_resource);
325     return 0;
326 }