1 /* Copyright (C) 2006, Index Data ApS
2 * See the file LICENSE for details.
4 * $Id: nfatest1.c,v 1.8 2006-10-09 14:22:44 heikki Exp $
16 char *printfunc(void *result) {
18 sprintf(buf, "\"%s\"", (char*) result);
22 char *printfunc2(void *result) {
24 sprintf(buf,"(%p)", result);
28 void test_match(yaz_nfa *n,
29 yaz_nfa_char *buf, size_t buflen,
30 int expcode, char *expstr) {
31 yaz_nfa_char *c = buf;
32 yaz_nfa_char *cp1, *cp2;
35 size_t buflen2 = buflen;
36 i = yaz_nfa_match(n,&c, &buflen2,&resptr);
37 if (yaz_test_get_verbosity()>3)
38 printf("\n'%s' returned %d. Moved c by %ld, and resulted in '%s'\n",
39 expstr, i, (long)(c-buf),(char*)resptr);
40 YAZ_CHECK_EQ(buflen-buflen2, c-buf);
41 YAZ_CHECK_EQ(i, expcode);
43 YAZ_CHECK_EQ(strcmp(expstr,(char*)resptr), 0);
46 while((bi!=2) && (yaz_test_get_verbosity()>3)){
47 bi = yaz_nfa_get_backref(n, i,&cp1,&cp2);
48 if (bi==0 && ( cp1 || cp2 ) ) {
49 printf(" got backref %d of %ld chars (%p to %p): '",
50 i, (long)(cp2-cp1+1), cp1, cp2);
59 void construction_test(void) {
60 yaz_nfa* n= yaz_nfa_init();
61 yaz_nfa_char *cp, *cp1, *cp2;
62 yaz_nfa_state *s, *s0, *s1, *s2, *s3, *s4, *s5;
64 yaz_nfa_char seq1[]={'p', 'r', 'e', 'f', 'i', 'x', 0};
65 yaz_nfa_char seq2[]={'p', 'r', 'e', 'l', 'i', 'm', 0};
66 yaz_nfa_char tst1[]={'c', 0};
67 yaz_nfa_char tst2[]={'c', 'k', 0};
68 yaz_nfa_char tst3[]={'c', 'x', 0};
69 yaz_nfa_char tst4[]={'z', 'k', 0};
70 yaz_nfa_char tst5[]={'y', 'k', 'l', 'k', 'k', 'l', 'k', 'd', 0};
71 yaz_nfa_char tst6[]={'x', 'z', 'k', 'a', 'b', 0};
77 s = yaz_nfa_get_first(n);
80 s0 = yaz_nfa_add_state(n);
82 s = yaz_nfa_get_first(n);
84 s = yaz_nfa_get_next(n, s);
87 s1 = yaz_nfa_add_state(n);
88 i = yaz_nfa_set_result(n, s1, "first");
91 i = yaz_nfa_set_result(n, s1, "DUPLICATE");
92 YAZ_CHECK_EQ(i, YAZ_NFA_ALREADY);
94 p = yaz_nfa_get_result(n, s1);
96 YAZ_CHECK( strcmp((char*)p, "first")==0 );
98 i = yaz_nfa_set_result(n, s1, 0);
100 p = yaz_nfa_get_result(n, s1);
102 i = yaz_nfa_set_result(n, s1, "first");
105 s2 = yaz_nfa_add_state(n);
106 s3 = yaz_nfa_add_state(n);
107 yaz_nfa_set_result(n, s3, "a-k, x-z");
109 s = yaz_nfa_get_first(n);
111 s = yaz_nfa_get_next(n, s);
115 yaz_nfa_add_transition(n, s0, s1, 'a', 'k');
116 yaz_nfa_add_transition(n, s1, s1, 'k', 'k');
117 yaz_nfa_add_transition(n, s0, s2, 'p', 'p');
118 yaz_nfa_add_transition(n, s1, s3, 'x', 'z');
120 s = yaz_nfa_add_range(n, 0, 'k', 's' );
121 yaz_nfa_set_result(n, s, "K-S");
123 s4 = yaz_nfa_add_range(n, s2, 'l', 'r' );
124 s5 = yaz_nfa_add_range(n, s2, 'l', 'r' );
126 s = yaz_nfa_add_range(n, 0, 'c', 'c' );
128 s = yaz_nfa_add_range(n, 0, 'z', 'z' );
129 yaz_nfa_add_empty_transition(n, s, s);
130 yaz_nfa_set_result(n, s, "loop");
132 s = yaz_nfa_add_range(n, 0, 'y', 'y' );
133 yaz_nfa_set_backref_point(n, s, 1, 1);
134 s1 = yaz_nfa_add_state(n);
135 yaz_nfa_add_empty_transition(n, s, s1);
137 yaz_nfa_add_transition(n, s, s, 'k', 'l');
138 s = yaz_nfa_add_range(n, s, 'd', 'd' );
139 yaz_nfa_set_result(n, s, "y k+ d");
140 yaz_nfa_set_backref_point(n, s, 1, 0);
142 s = yaz_nfa_add_sequence(n, 0, seq1,6 );
143 yaz_nfa_set_result(n, s, "PREFIX");
144 s = yaz_nfa_add_sequence(n, 0, seq2,6 );
145 yaz_nfa_set_result(n, s, "PRELIM");
147 s = yaz_nfa_add_range(n, 0, 'x', 'x' );
148 i=yaz_nfa_set_backref_point(n, s, 2, 0);
149 YAZ_CHECK_EQ(i,YAZ_NFA_NOSTART);
150 i=yaz_nfa_set_backref_point(n, s, 2, 1);
151 YAZ_CHECK_EQ(i,YAZ_NFA_SUCCESS);
152 i=yaz_nfa_set_backref_point(n, s, 2, 1);
153 YAZ_CHECK_EQ(i,YAZ_NFA_ALREADY);
154 s1 = yaz_nfa_add_sequence(n, s, tst4,2);
155 yaz_nfa_set_backref_point(n, s1, 2, 0);
156 yaz_nfa_set_result(n, s1, "xzk");
158 /* check return codes before doing any matches */
159 i = yaz_nfa_get_backref(n, 0, &cp1, &cp2 );
160 YAZ_CHECK_EQ(i, YAZ_NFA_NOMATCH);
161 i = yaz_nfa_get_backref(n, 3, &cp1, &cp2 );
162 YAZ_CHECK_EQ(i, YAZ_NFA_NOSUCHBACKREF );
163 i = yaz_nfa_get_backref(n, 1, &cp1, &cp2 );
164 YAZ_CHECK_EQ(i, YAZ_NFA_NOMATCH );
167 if (yaz_test_get_verbosity()>3)
168 yaz_nfa_dump(0, n, printfunc);
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");
178 cp = tst6; /* xzkab */
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 );
184 YAZ_CHECK_EQ(cp2-cp1+1,2);
185 YAZ_CHECK_EQ(*cp1, 'z' );
186 YAZ_CHECK_EQ(*cp2, 'k' );
187 if (yaz_test_get_verbosity()>3)
188 printf("backref from %p '%c' to %p '%c' is %ld long. sz is now %ld\n",
189 cp1, *cp1, cp2, *cp2, (long)(cp2-cp1+1), (long)sz );
194 void converter_test(void) {
195 yaz_nfa* n= yaz_nfa_init();
196 yaz_nfa_converter *c1, *c2, *c3;
197 yaz_nfa_char str1[]={'a','b','c'};
198 yaz_nfa_char seq1[]={'A','B','C'};
199 yaz_nfa_char seq2[]={'k','m','n','m','x','P','Q','X',0};
200 yaz_nfa_char outbuf[1024];
201 yaz_nfa_char *outp, *cp, *cp1, *cp2;
202 yaz_nfa_state *s, *s2;
207 c1=yaz_nfa_create_string_converter(n,str1,3);
213 i=yaz_nfa_run_converters(n, c1, &outp, &sz);
214 YAZ_CHECK_EQ(i,4); /* overrun */
215 YAZ_CHECK_EQ(outbuf[0],'a');
216 YAZ_CHECK_EQ(outbuf[1],10000+1);
222 i=yaz_nfa_run_converters(n, c1, &outp, &sz);
224 YAZ_CHECK_EQ(outbuf[0],'a');
225 YAZ_CHECK_EQ(outbuf[1],'b');
226 YAZ_CHECK_EQ(outbuf[2],'c');
227 YAZ_CHECK_EQ(outbuf[3],10000+3);
230 c2=yaz_nfa_create_string_converter(n,str1,2);
231 yaz_nfa_append_converter(n,c1,c2);
237 i=yaz_nfa_run_converters(n, c1, &outp, &sz);
239 YAZ_CHECK_EQ(outbuf[0],'a');
240 YAZ_CHECK_EQ(outbuf[1],'b');
241 YAZ_CHECK_EQ(outbuf[2],'c');
242 YAZ_CHECK_EQ(outbuf[3],'a');
243 YAZ_CHECK_EQ(outbuf[4],'b');
244 YAZ_CHECK_EQ(outbuf[5],10000+5);
248 (void) yaz_nfa_add_state(n);/* start state */
249 s=yaz_nfa_add_state(n);
250 yaz_nfa_add_empty_transition(n,0,s);
251 yaz_nfa_set_backref_point(n,s,1,1);
252 s=yaz_nfa_add_sequence(n, s, seq1,3 );
253 yaz_nfa_set_result(n,s,c1);
254 yaz_nfa_set_backref_point(n,s,1,0);
256 /* ([k-o][m-n]*)x -> \1 */
257 s=yaz_nfa_add_state(n);
258 yaz_nfa_add_empty_transition(n,0,s);
259 yaz_nfa_set_backref_point(n,s,2,1);
260 s2=yaz_nfa_add_state(n);
261 yaz_nfa_add_transition(n,s,s2,'k','o');
262 yaz_nfa_add_transition(n,s2,s2,'m','n');
263 s=yaz_nfa_add_state(n);
264 yaz_nfa_add_transition(n,s2,s,'x','x');
265 yaz_nfa_set_backref_point(n,s,2,0);
267 c1=yaz_nfa_create_backref_converter(n,2);
268 yaz_nfa_set_result(n,s,c1);
270 if (yaz_test_get_verbosity()>3)
271 yaz_nfa_dump(0,n, printfunc2);
275 i=yaz_nfa_match(n,&cp,&sz,&vp);
277 YAZ_CHECK_EQ(i,YAZ_NFA_SUCCESS);
278 i=yaz_nfa_get_backref(n, 2, &cp1, &cp2 );
279 if (yaz_test_get_verbosity()>3)
280 printf("backref from %p '%c' to %p '%c' is %ld long. sz is now %ld\n",
281 cp1, *cp1, cp2, *cp2, (long)(cp2-cp1+1), (long)sz );
283 /*YAZ_CHECK_EQ((int)c1,(int)c2);*/ /* got our pointer back from nfa */
284 YAZ_CHECK(c1==c2); /* got our pointer back from nfa */
289 i=yaz_nfa_run_converters(n, c2, &outp, &sz);
291 YAZ_CHECK_EQ(outbuf[0],'k');
292 YAZ_CHECK_EQ(outbuf[1],'m');
293 YAZ_CHECK_EQ(outbuf[2],'n');
294 YAZ_CHECK_EQ(outbuf[3],'m');
295 YAZ_CHECK_EQ(outbuf[4],'x');
296 YAZ_CHECK_EQ(outbuf[5],10000+5);
297 YAZ_CHECK_EQ(sz,11-5);
299 c3=yaz_nfa_create_range_converter(n,2, 'a', 'A' );
304 i=yaz_nfa_run_converters(n, c3, &outp, &sz);
306 YAZ_CHECK_EQ(outbuf[0],'K');
307 YAZ_CHECK_EQ(outbuf[1],'M');
308 YAZ_CHECK_EQ(outbuf[2],'N');
309 YAZ_CHECK_EQ(outbuf[3],'M');
310 YAZ_CHECK_EQ(outbuf[4],'X');
311 YAZ_CHECK_EQ(outbuf[5],10000+5);
312 YAZ_CHECK_EQ(sz,11-5);
317 yaz_nfa_char *makebuff(NMEM nmem, char *in) {
318 yaz_nfa_char *buff = nmem_malloc(nmem, strlen(in)*sizeof(yaz_nfa_char));
319 yaz_nfa_char *op=buff;
320 while ( (*op++ = *in++) )
325 void dumpbuff(char *msg, yaz_nfa_char *start, yaz_nfa_char *end) {
326 if (yaz_test_get_verbosity()>3) {
329 printf("%c",*start++);
334 void chkbuff( yaz_nfa_char *start, yaz_nfa_char *end, char *exp) {
337 if ( *start++ != *exp++ ) {
338 if (yaz_test_get_verbosity()>3) {
341 printf ("chkbuff: unexpected conversion '%c' != '%c' \n"
342 "\"%s\"\n", *start, *exp, orig_exp );
344 YAZ_CHECK(!"conversion differs! ");
350 void high_level_test(void) {
351 NMEM nmem=nmem_create();
352 yaz_nfa_char from1[] = {'f','o','o','b','a','r'};
353 yaz_nfa_char to1[] = {'f','u','b','a','r'};
354 yaz_nfa_char tospace[] = {' '};
355 yaz_nfa_char todot[] = {'.'};
357 "It was a Dark and Rainy Night, when alpha and beta "
358 "fixme - FIND better names ?? !! ## - "
359 "went out to fix the foobar "
362 "IT WAS A DARK AND RAINY NIGHT. WHEN ALPHA AND b "
363 "to-be-fixed-later . FIND BETTER NAMES .. .. .. . "
364 "WENT OUT TO (fix) THE fubar "
366 yaz_nfa_char *from3 = makebuff(nmem,fromtext);
367 yaz_nfa_char *to3 = nmem_malloc(nmem, 1024*sizeof(yaz_nfa_char));
368 yaz_nfa_char *fromp=from3;
369 yaz_nfa_char *top=to3;
370 size_t insize=strlen(fromtext);
372 size_t prev_insize=0;
374 yaz_nfa *n = yaz_nfa_init();
376 i = yaz_nfa_add_string_rule(n, from1, 6, to1, 5);
378 i = yaz_nfa_add_string_rule(n, from1, 6, to1, 5);
379 YAZ_CHECK_EQ(i,YAZ_NFA_ALREADY);
380 i = yaz_nfa_add_ascii_string_rule(n,"beta","b");
382 i = yaz_nfa_add_ascii_string_rule(n,"fixme","to-be-fixed-later");
384 i = yaz_nfa_add_ascii_string_rule(n,"fix","(fix)");
386 i = yaz_nfa_add_char_range_rule(n, 'a','z','A');
388 i = yaz_nfa_add_char_string_rule(n, 0,' ', tospace,1);
390 i = yaz_nfa_add_char_string_rule(n, '!','/', todot,1);
392 i = yaz_nfa_add_char_string_rule(n, ':','?', todot,1);
394 if (yaz_test_get_verbosity()>3)
395 yaz_nfa_dump(0,n, printfunc2);
397 YAZ_CHECK_EQ( *from3, 'I' ); /* just to be sure my copy func works */
400 i=yaz_nfa_convert_slice(n, &fromp, &insize, &top, &outsize);
401 YAZ_CHECK_EQ(i,YAZ_NFA_SUCCESS);
402 YAZ_CHECK_EQ(*to3,'I');
403 YAZ_CHECK_EQ(insize, strlen(fromtext)-1);
404 YAZ_CHECK_EQ(outsize, 1024-1);
406 while ( (i==YAZ_NFA_SUCCESS) && (insize > 0) && (prev_insize!=insize) ) {
407 prev_insize=insize; /* detect dead loops if something goes wrong */
408 i=yaz_nfa_convert_slice(n, &fromp, &insize, &top, &outsize);
410 YAZ_CHECK_EQ(i,YAZ_NFA_SUCCESS);
411 YAZ_CHECK_EQ(insize,0);
412 YAZ_CHECK(prev_insize != insize); /* the loop would have been endless */
414 dumpbuff("Original text: ",from3, fromp);
415 dumpbuff("Converted text: ",to3, top);
417 chkbuff(to3, top, expected);
423 int main(int argc, char **argv)
425 YAZ_CHECK_INIT(argc, argv);
438 * indent-tabs-mode: nil
440 * vim: shiftwidth=4 tabstop=8 expandtab