Fixed the interface to match,
[yaz-moved-to-github.git] / test / nfatest1.c
1 /*  Copyright (C) 2006, Index Data ApS
2  *  See the file LICENSE for details.
3  *
4  *  $Id: nfatest1.c,v 1.4 2006-05-05 09:14:42 heikki Exp $
5  *
6  */
7
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <yaz/nfa.h>
12 #include <yaz/nmem.h>
13 #include <yaz/test.h>
14
15 #define VERBOSE 1
16
17 char *printfunc(void *result) {
18     static char buf[200];
19     sprintf(buf, "\"%s\"", (char*) result);
20     return buf;
21 }
22
23 char *printfunc2(void *result) {
24     static char buf[200];
25     sprintf(buf,"(%p)",  result);
26     return buf;
27 }
28
29 void test_match(yaz_nfa *n, 
30         yaz_nfa_char *buf, size_t buflen, 
31         int expcode, char *expstr) {
32     yaz_nfa_char *c = buf;
33     yaz_nfa_char *cp1, *cp2;
34     void *resptr = 0;
35     int i, bi;
36     size_t buflen2 = buflen;
37     i = yaz_nfa_match(n,&c, &buflen2,&resptr);
38 #if VERBOSE    
39     printf("\n'%s' returned %d. Moved c by %d, and resulted in '%s'\n",
40             expstr, i, (c-buf),(char*)resptr);
41 #endif
42     YAZ_CHECK_EQ(buflen-buflen2, c-buf);
43     YAZ_CHECK_EQ(i, expcode);
44     if (i!=1)
45         YAZ_CHECK_EQ(strcmp(expstr,(char*)resptr), 0);
46     i = 0;
47     bi = 0;
48     while(bi!=2){
49         bi = yaz_nfa_get_backref(n, i,&cp1,&cp2);
50         if (bi==0 && ( cp1 || cp2 ) ) {
51 #if VERBOSE    
52             printf("  got backref %d of %d chars (%p to %p): '",
53                     i, cp2-cp1+1, cp1, cp2);
54             while (cp2-cp1 >= 0 )
55                 printf("%c", *cp1++);
56             printf("'\n");
57 #endif
58         }
59         i++;
60     }
61 }
62
63 void construction_test() {
64     yaz_nfa* n= yaz_nfa_init();
65     yaz_nfa_char *cp, *cp1, *cp2;
66     yaz_nfa_state *s, *s0, *s1, *s2, *s3, *s4, *s5;
67     int i;
68     yaz_nfa_char seq1[]={'p', 'r', 'e', 'f', 'i', 'x', 0};
69     yaz_nfa_char seq2[]={'p', 'r', 'e', 'l', 'i', 'm', 0};
70     yaz_nfa_char tst1[]={'c', 0};
71     yaz_nfa_char tst2[]={'c', 'k', 0};
72     yaz_nfa_char tst3[]={'c', 'x', 0};
73     yaz_nfa_char tst4[]={'z', 'k', 0};
74     yaz_nfa_char tst5[]={'y', 'k', 'l', 'k', 'k', 'l', 'k', 'd', 0};
75     yaz_nfa_char tst6[]={'x', 'z', 'k', 'a', 'b', 0};
76     void *p;
77     size_t sz;
78
79     YAZ_CHECK(n);
80
81     s = yaz_nfa_get_first(n);
82     YAZ_CHECK(!s);
83
84     s0 = yaz_nfa_add_state(n);
85
86     s = yaz_nfa_get_first(n);
87     YAZ_CHECK(s);
88     s = yaz_nfa_get_next(n, s);
89     YAZ_CHECK(!s);
90
91     s1 = yaz_nfa_add_state(n);
92     i = yaz_nfa_set_result(n, s1, "first");
93     YAZ_CHECK_EQ(i, 0);
94
95     i = yaz_nfa_set_result(n, s1, "DUPLICATE");
96     YAZ_CHECK_EQ(i, 1);
97
98     p = yaz_nfa_get_result(n, s1);
99     YAZ_CHECK(p);
100     YAZ_CHECK( strcmp((char*)p, "first")==0 );
101
102     i = yaz_nfa_set_result(n, s1, 0);
103     YAZ_CHECK_EQ(i, 0);
104     p = yaz_nfa_get_result(n, s1);
105     YAZ_CHECK(!p);
106     i = yaz_nfa_set_result(n, s1, "first");
107     YAZ_CHECK_EQ(i, 0);
108     
109     s2 = yaz_nfa_add_state(n);
110     s3 = yaz_nfa_add_state(n);
111     yaz_nfa_set_result(n, s3, "a-k, x-z");
112
113     s = yaz_nfa_get_first(n);
114     YAZ_CHECK(s);
115     s = yaz_nfa_get_next(n, s);
116     YAZ_CHECK(s);
117
118     
119     yaz_nfa_add_transition(n, s0, s1, 'a', 'k');
120     yaz_nfa_add_transition(n, s1, s1, 'k', 'k');
121     yaz_nfa_add_transition(n, s0, s2, 'p', 'p');
122     yaz_nfa_add_transition(n, s1, s3, 'x', 'z');
123
124     s = yaz_nfa_add_range(n, 0, 'k', 's' );
125     yaz_nfa_set_result(n, s, "K-S");
126
127     s4 = yaz_nfa_add_range(n, s2, 'l', 'r' );
128     s5 = yaz_nfa_add_range(n, s2, 'l', 'r' );
129     YAZ_CHECK((s4==s5));
130     s = yaz_nfa_add_range(n, 0, 'c', 'c' );
131
132     s = yaz_nfa_add_range(n, 0, 'z', 'z' );
133     yaz_nfa_add_empty_transition(n, s, s);
134     yaz_nfa_set_result(n, s, "loop");
135
136     s = yaz_nfa_add_range(n, 0, 'y', 'y' );
137     yaz_nfa_set_backref_point(n, s, 1, 1);
138     s1 = yaz_nfa_add_state(n);
139     yaz_nfa_add_empty_transition(n, s, s1);
140     s = s1;
141     yaz_nfa_add_transition(n, s, s, 'k', 'l');
142     s = yaz_nfa_add_range(n, s, 'd', 'd' );
143     yaz_nfa_set_result(n, s, "y k+ d");
144     yaz_nfa_set_backref_point(n, s, 1, 0);
145
146     s = yaz_nfa_add_sequence(n, 0, seq1 ); 
147     yaz_nfa_set_result(n, s, "PREFIX");
148     s = yaz_nfa_add_sequence(n, 0, seq2 ); 
149     yaz_nfa_set_result(n, s, "PRELIM");
150
151     s = yaz_nfa_add_range(n, 0, 'x', 'x' );
152     yaz_nfa_set_backref_point(n, s, 2, 1);
153     s1 = yaz_nfa_add_sequence(n, s, tst4);
154     yaz_nfa_set_backref_point(n, s1, 2, 0);
155     yaz_nfa_set_result(n, s1, "xzk");
156
157     /* check return codes before doing any matches */
158     i = yaz_nfa_get_backref(n, 0, &cp1, &cp2 );
159     YAZ_CHECK_EQ(i, 1);
160     i = yaz_nfa_get_backref(n, 3, &cp1, &cp2 );
161     YAZ_CHECK_EQ(i, 2);
162     i = yaz_nfa_get_backref(n, 1, &cp1, &cp2 );
163     YAZ_CHECK_EQ(i, 1);
164
165     
166 #if VERBOSE    
167     yaz_nfa_dump(0, n, printfunc);
168 #endif
169
170     test_match(n, seq2, 3, YAZ_NFA_OVERRUN, "K-S");
171     test_match(n, seq2, 6, YAZ_NFA_SUCCESS, "PRELIM");
172     test_match(n, tst1, 3, YAZ_NFA_SUCCESS, "first");
173     test_match(n, tst2, 3, YAZ_NFA_SUCCESS, "first");
174     test_match(n, tst3, 3, YAZ_NFA_SUCCESS, "a-k, x-z");
175     test_match(n, tst4, 9, YAZ_NFA_LOOP, "loop");
176     test_match(n, tst5, 9, YAZ_NFA_SUCCESS, "y k+ d");
177
178     cp = tst6;
179     sz = 8;
180     i = yaz_nfa_match(n, &cp, &sz, &p);
181     YAZ_CHECK_EQ(i, YAZ_NFA_SUCCESS); 
182     i = yaz_nfa_get_backref(n, 2, &cp1, &cp2 );
183     YAZ_CHECK_EQ(i, 0);
184 #if VERBOSE    
185     printf("backref from %p to %p is %d long. sz is now %d\n",
186             cp1,cp2, cp2-cp1,sz );
187 #endif
188
189     yaz_nfa_destroy(n);
190 }
191
192 void converter_test() {
193     yaz_nfa* n= yaz_nfa_init();
194     yaz_nfa_converter *c1,*c2;
195     yaz_nfa_char str1[]={'a','b','c'};
196     yaz_nfa_char seq1[]={'A','B','C',0};
197     yaz_nfa_char seq2[]={'k','m','n','m','x','P','Q','X',0};
198     yaz_nfa_char outbuf[1024];
199     yaz_nfa_char *outp,*cp, *cp1, *cp2;
200     yaz_nfa_state *s, *s2;
201     void *vp;
202     int i;
203     size_t sz;
204
205     c1=yaz_nfa_create_string_converter(n,str1,3);
206
207     for(i=0;i<1024;i++)
208         outbuf[i]=10000+i;
209     outp=outbuf;
210     sz=1;
211     i=yaz_nfa_run_converters(n, c1, &outp, &sz);
212     YAZ_CHECK_EQ(i,2); /* overrun */
213     YAZ_CHECK_EQ(outbuf[0],'a');
214     YAZ_CHECK_EQ(outbuf[1],10000+1);
215
216     for(i=0;i<1024;i++)
217         outbuf[i]=10000+i;
218     outp=outbuf;
219     sz=3;
220     i=yaz_nfa_run_converters(n, c1, &outp, &sz);
221     YAZ_CHECK_EQ(i,0); 
222     YAZ_CHECK_EQ(outbuf[0],'a');
223     YAZ_CHECK_EQ(outbuf[1],'b');
224     YAZ_CHECK_EQ(outbuf[2],'c');
225     YAZ_CHECK_EQ(outbuf[3],10000+3);
226     YAZ_CHECK_EQ(sz,0);
227     
228     c2=yaz_nfa_create_string_converter(n,str1,2);
229     yaz_nfa_append_converter(n,c1,c2);
230
231     for(i=0;i<1024;i++)
232         outbuf[i]=10000+i;
233     outp=outbuf;
234     sz=10;
235     i=yaz_nfa_run_converters(n, c1, &outp, &sz);
236     YAZ_CHECK_EQ(i,0); 
237     YAZ_CHECK_EQ(outbuf[0],'a');
238     YAZ_CHECK_EQ(outbuf[1],'b');
239     YAZ_CHECK_EQ(outbuf[2],'c');
240     YAZ_CHECK_EQ(outbuf[3],'a');
241     YAZ_CHECK_EQ(outbuf[4],'b');
242     YAZ_CHECK_EQ(outbuf[5],10000+5);
243     YAZ_CHECK_EQ(sz,5);
244     
245     /* ABC -> abcab */
246     (void) yaz_nfa_add_state(n);/* start state */
247     s=yaz_nfa_add_state(n);
248     yaz_nfa_add_empty_transition(n,0,s);
249     yaz_nfa_set_backref_point(n,s,1,1);
250     s=yaz_nfa_add_sequence(n, s, seq1 ); 
251     yaz_nfa_set_result(n,s,c1);
252     yaz_nfa_set_backref_point(n,s,1,0);
253
254     /* [k-o][m-n]*x -> m-n sequence */
255     s=yaz_nfa_add_state(n);
256     yaz_nfa_add_empty_transition(n,0,s);
257     yaz_nfa_set_backref_point(n,s,2,1);
258     s2=yaz_nfa_add_state(n);
259     yaz_nfa_add_transition(n,s,s2,'k','o');
260     yaz_nfa_add_transition(n,s2,s2,'m','n');
261     s=yaz_nfa_add_state(n);
262     yaz_nfa_add_transition(n,s2,s,'x','x');
263     yaz_nfa_set_backref_point(n,s,2,0);
264
265     c1=yaz_nfa_create_backref_converter(n,2);
266     yaz_nfa_set_result(n,s,c1);
267
268 #if VERBOSE    
269     yaz_nfa_dump(0,n, printfunc2);
270 #endif
271
272     cp=seq2;
273     sz=18;
274     i=yaz_nfa_match(n,&cp,&sz,&vp);
275     c2=vp;
276     YAZ_CHECK_EQ(i,YAZ_NFA_SUCCESS); 
277     i=yaz_nfa_get_backref(n, 2, &cp1, &cp2 );
278     YAZ_CHECK_EQ(i,0);
279     YAZ_CHECK_EQ((int)c1,(int)c2);
280     for(i=0;i<1024;i++)
281         outbuf[i]=10000+i;
282     outp=outbuf;
283     sz=11;
284     i=yaz_nfa_run_converters(n, c2, &outp, &sz);
285     YAZ_CHECK_EQ(i,0); 
286     YAZ_CHECK_EQ(outbuf[0],'k');
287     YAZ_CHECK_EQ(outbuf[1],'m');
288     YAZ_CHECK_EQ(outbuf[2],'n');
289     YAZ_CHECK_EQ(outbuf[3],'m');
290     YAZ_CHECK_EQ(outbuf[4],'x');
291     YAZ_CHECK_EQ(outbuf[5],10000+5);
292     YAZ_CHECK_EQ(sz,11-5);
293
294     yaz_nfa_destroy(n);
295 }
296
297
298 int main(int argc, char **argv)
299 {
300     YAZ_CHECK_INIT(argc, argv);
301     nmem_init ();
302     construction_test(); 
303     converter_test();
304     nmem_exit ();
305     YAZ_CHECK_TERM;
306 }
307
308
309 /* 
310  * Local variables:
311  * c-basic-offset: 4
312  * indent-tabs-mode: nil
313  * End:
314  * vim: shiftwidth=4 tabstop=8 expandtab
315  */