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