1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * libdatrie - Double-Array Trie Library
4 * Copyright (C) 2013 Theppitak Karoonboonyanan <thep@linux.thai.net>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * test_walk.c - Test for datrie walking operations
24 * Author: Theppitak Karoonboonyanan <thep@linux.thai.net>
27 #include <datrie/trie.h>
32 * Sample trie in http://linux.thai.net/~thep/datrie/datrie.html
34 * +---o-> (3) -o-> (4) -l-> [5]
36 * | +---i-> (7) -z-> (8) -e-> [9]
38 * (1) -p-> (2) -r-> (6) -e-> (10) -v-> (11) -i-> (12) -e-> (13) -w-> [14]
40 * | +---p-> (15) -a-> (16) -r-> (17) -e-> [18]
42 * +---o-> (19) -d-> (20) -u-> (21) -c-> (22) -e-> [23]
44 * +---g-> (24) -r-> (25) -e-> (26) -s-> (27) -s-> [28]
47 DictRec walk_dict[] = {
48 {L"pool", TRIE_DATA_UNREAD},
49 {L"prize", TRIE_DATA_UNREAD},
50 {L"preview", TRIE_DATA_UNREAD},
51 {L"prepare", TRIE_DATA_UNREAD},
52 {L"produce", TRIE_DATA_UNREAD},
53 {L"progress", TRIE_DATA_UNREAD},
54 {NULL, TRIE_DATA_ERROR},
58 is_walkables_include (AlphaChar c, const AlphaChar *walkables, int n_elm)
61 if (walkables[--n_elm] == c)
68 print_walkables (const AlphaChar *walkables, int n_elm)
73 for (i = 0; i < n_elm; i++) {
77 printf ("'%lc'", walkables[i]);
82 #define ALPHABET_SIZE 256
90 AlphaChar walkables[ALPHABET_SIZE];
95 msg_step ("Preparing trie");
96 test_trie = en_trie_new ();
98 fprintf (stderr, "Fail to create test trie\n");
99 goto err_trie_not_created;
103 for (dict_p = walk_dict; dict_p->key; dict_p++) {
104 if (!trie_store (test_trie, dict_p->key, dict_p->data)) {
105 printf ("Failed to add key '%ls', data %d.\n",
106 dict_p->key, dict_p->data);
107 goto err_trie_created;
112 "Now the trie structure is supposed to be:\n"
114 " +---o-> (3) -o-> (4) -l-> [5]\n"
116 " | +---i-> (7) -z-> (8) -e-> [9]\n"
118 "(1) -p-> (2) -r-> (6) -e-> (10) -v-> (11) -i-> (12) -e-> (13) -w-> [14]\n"
120 " | +---p-> (15) -a-> (16) -r-> (17) -e-> [18]\n"
122 " +---o-> (19) -d-> (20) -u-> (21) -c-> (22) -e-> [23]\n"
124 " +---g-> (24) -r-> (25) -e-> (26) -s-> (27) -s-> [28]\n"
129 msg_step ("Test walking");
130 s = trie_root (test_trie);
132 printf ("Failed to get trie root state\n");
133 goto err_trie_created;
136 msg_step ("Test walking with 'p'");
137 if (!trie_state_is_walkable (s, L'p')) {
138 printf ("Trie state is not walkable with 'p'\n");
139 goto err_trie_state_s_created;
141 if (!trie_state_walk (s, L'p')) {
142 printf ("Failed to walk with 'p'\n");
143 goto err_trie_state_s_created;
146 msg_step ("Now at (2), walkable chars should be {'o', 'r'}");
148 n = trie_state_walkable_chars (s, walkables, ALPHABET_SIZE);
150 printf ("Walkable chars should be exactly 2, got %d\n", n);
153 if (!is_walkables_include (L'o', walkables, n)) {
154 printf ("Walkable chars do not include 'o'\n", n);
157 if (!is_walkables_include (L'r', walkables, n)) {
158 printf ("Walkable chars do not include 'r'\n", n);
162 printf ("Walkables = ");
163 print_walkables (walkables, n);
165 goto err_trie_state_s_created;
168 msg_step ("Try walking from (2) with 'o' to (3)");
169 t = trie_state_clone (s);
171 printf ("Failed to clone trie state\n");
172 goto err_trie_state_s_created;
174 if (!trie_state_walk (t, L'o')) {
175 printf ("Failed to walk from (2) with 'o' to (3)\n");
176 goto err_trie_state_t_created;
178 if (!trie_state_is_single (t)) {
179 printf ("(3) should be single, but isn't.\n");
180 goto err_trie_state_t_created;
183 msg_step ("Try walking from (3) with 'o' to (4)");
184 if (!trie_state_walk (t, L'o')) {
185 printf ("Failed to walk from (3) with 'o' to (4)\n");
186 goto err_trie_state_t_created;
188 if (!trie_state_is_single (t)) {
189 printf ("(4) should be single, but isn't.\n");
190 goto err_trie_state_t_created;
193 msg_step ("Try walking from (4) with 'l' to (5)");
194 if (!trie_state_walk (t, L'l')) {
195 printf ("Failed to walk from (4) with 'l' to (5)\n");
196 goto err_trie_state_t_created;
198 if (!trie_state_is_terminal (t)) {
199 printf ("(5) should be terminal, but isn't.\n");
200 goto err_trie_state_t_created;
204 msg_step ("Try getting data from (5)");
205 data = trie_state_get_data (t);
206 if (TRIE_DATA_ERROR == data) {
207 printf ("Failed to get data from (5)\n");
208 goto err_trie_state_t_created;
210 if (TRIE_DATA_UNREAD != data) {
211 printf ("Mismatched data from (5), expected %d, got %d\n",
212 TRIE_DATA_UNREAD, data);
213 goto err_trie_state_t_created;
216 /* walk s from (2) with 'r' to (6) */
217 msg_step ("Try walking from (2) with 'r' to (6)");
218 if (!trie_state_walk (s, L'r')) {
219 printf ("Failed to walk from (2) with 'r' to (6)\n");
220 goto err_trie_state_t_created;
223 msg_step ("Now at (6), walkable chars should be {'e', 'i', 'o'}");
225 n = trie_state_walkable_chars (s, walkables, ALPHABET_SIZE);
227 printf ("Walkable chars should be exactly 3, got %d\n", n);
230 if (!is_walkables_include (L'e', walkables, n)) {
231 printf ("Walkable chars do not include 'e'\n", n);
234 if (!is_walkables_include (L'i', walkables, n)) {
235 printf ("Walkable chars do not include 'i'\n", n);
238 if (!is_walkables_include (L'o', walkables, n)) {
239 printf ("Walkable chars do not include 'o'\n", n);
243 printf ("Walkables = ");
244 print_walkables (walkables, n);
246 goto err_trie_state_t_created;
249 /* walk from s (6) with "ize" */
250 msg_step ("Try walking from (6) with 'i' to (7)");
251 trie_state_copy (t, s);
252 if (!trie_state_walk (t, L'i')) {
253 printf ("Failed to walk from (6) with 'i' to (7)\n");
254 goto err_trie_state_t_created;
256 msg_step ("Try walking from (7) with 'z' to (8)");
257 if (!trie_state_walk (t, L'z')) {
258 printf ("Failed to walk from (7) with 'z' to (8)\n");
259 goto err_trie_state_t_created;
261 if (!trie_state_is_single (t)) {
262 printf ("(7) should be single, but isn't.\n");
263 goto err_trie_state_t_created;
265 msg_step ("Try walking from (8) with 'e' to (9)");
266 if (!trie_state_walk (t, L'e')) {
267 printf ("Failed to walk from (8) with 'e' to (9)\n");
268 goto err_trie_state_t_created;
270 if (!trie_state_is_terminal (t)) {
271 printf ("(9) should be terminal, but isn't.\n");
272 goto err_trie_state_t_created;
275 msg_step ("Try getting data from (9)");
276 data = trie_state_get_data (t);
277 if (TRIE_DATA_ERROR == data) {
278 printf ("Failed to get data from (9)\n");
279 goto err_trie_state_t_created;
281 if (TRIE_DATA_UNREAD != data) {
282 printf ("Mismatched data from (9), expected %d, got %d\n",
283 TRIE_DATA_UNREAD, data);
284 goto err_trie_state_t_created;
287 /* walk from u = s (6) with 'e' to (10) */
288 msg_step ("Try walking from (6) with 'e' to (10)");
289 u = trie_state_clone (s);
291 printf ("Failed to clone trie state\n");
292 goto err_trie_state_t_created;
294 if (!trie_state_walk (u, L'e')) {
295 printf ("Failed to walk from (6) with 'e' to (10)\n");
296 goto err_trie_state_u_created;
299 /* walkable chars from (10) should be {'p', 'v'} */
300 msg_step ("Now at (10), walkable chars should be {'p', 'v'}");
302 n = trie_state_walkable_chars (u, walkables, ALPHABET_SIZE);
304 printf ("Walkable chars should be exactly 2, got %d\n", n);
307 if (!is_walkables_include (L'p', walkables, n)) {
308 printf ("Walkable chars do not include 'p'\n", n);
311 if (!is_walkables_include (L'v', walkables, n)) {
312 printf ("Walkable chars do not include 'v'\n", n);
316 printf ("Walkables = ");
317 print_walkables (walkables, n);
319 goto err_trie_state_u_created;
322 /* walk from u (10) with "view" */
323 msg_step ("Try walking from (10) with 'v' to (11)");
324 trie_state_copy (t, u);
325 if (!trie_state_walk (t, L'v')) {
326 printf ("Failed to walk from (10) with 'v' to (11)\n");
327 goto err_trie_state_u_created;
329 if (!trie_state_is_single (t)) {
330 printf ("(11) should be single, but isn't.\n");
331 goto err_trie_state_u_created;
333 msg_step ("Try walking from (11) with 'i' to (12)");
334 if (!trie_state_walk (t, L'i')) {
335 printf ("Failed to walk from (11) with 'i' to (12)\n");
336 goto err_trie_state_u_created;
338 msg_step ("Try walking from (12) with 'e' to (13)");
339 if (!trie_state_walk (t, L'e')) {
340 printf ("Failed to walk from (12) with 'e' to (13)\n");
341 goto err_trie_state_u_created;
343 msg_step ("Try walking from (13) with 'w' to (14)");
344 if (!trie_state_walk (t, L'w')) {
345 printf ("Failed to walk from (13) with 'w' to (14)\n");
346 goto err_trie_state_u_created;
348 if (!trie_state_is_terminal (t)) {
349 printf ("(14) should be terminal, but isn't.\n");
350 goto err_trie_state_u_created;
353 msg_step ("Try getting data from (14)");
354 data = trie_state_get_data (t);
355 if (TRIE_DATA_ERROR == data) {
356 printf ("Failed to get data from (14)\n");
357 goto err_trie_state_u_created;
359 if (TRIE_DATA_UNREAD != data) {
360 printf ("Mismatched data from (14), expected %d, got %d\n",
361 TRIE_DATA_UNREAD, data);
362 goto err_trie_state_u_created;
365 /* walk from u (10) with "pare" */
366 msg_step ("Try walking from (10) with 'p' to (15)");
367 trie_state_copy (t, u);
368 if (!trie_state_walk (t, L'p')) {
369 printf ("Failed to walk from (10) with 'p' to (15)\n");
370 goto err_trie_state_u_created;
372 if (!trie_state_is_single (t)) {
373 printf ("(15) should be single, but isn't.\n");
374 goto err_trie_state_u_created;
376 msg_step ("Try walking from (15) with 'a' to (16)");
377 if (!trie_state_walk (t, L'a')) {
378 printf ("Failed to walk from (15) with 'a' to (16)\n");
379 goto err_trie_state_u_created;
381 msg_step ("Try walking from (16) with 'r' to (17)");
382 if (!trie_state_walk (t, L'r')) {
383 printf ("Failed to walk from (16) with 'r' to (17)\n");
384 goto err_trie_state_u_created;
386 msg_step ("Try walking from (17) with 'e' to (18)");
387 if (!trie_state_walk (t, L'e')) {
388 printf ("Failed to walk from (17) with 'e' to (18)\n");
389 goto err_trie_state_u_created;
391 if (!trie_state_is_terminal (t)) {
392 printf ("(18) should be terminal, but isn't.\n");
393 goto err_trie_state_u_created;
396 msg_step ("Try getting data from (18)");
397 data = trie_state_get_data (t);
398 if (TRIE_DATA_ERROR == data) {
399 printf ("Failed to get data from (18)\n");
400 goto err_trie_state_u_created;
402 if (TRIE_DATA_UNREAD != data) {
403 printf ("Mismatched data from (18), expected %d, got %d\n",
404 TRIE_DATA_UNREAD, data);
405 goto err_trie_state_u_created;
410 /* walk s from (6) with 'o' to (19) */
411 msg_step ("Try walking from (6) with 'o' to (19)");
412 if (!trie_state_walk (s, L'o')) {
413 printf ("Failed to walk from (6) with 'o' to (19)\n");
414 goto err_trie_state_t_created;
417 msg_step ("Now at (19), walkable chars should be {'d', 'g'}");
419 n = trie_state_walkable_chars (s, walkables, ALPHABET_SIZE);
421 printf ("Walkable chars should be exactly 2, got %d\n", n);
424 if (!is_walkables_include (L'd', walkables, n)) {
425 printf ("Walkable chars do not include 'd'\n", n);
428 if (!is_walkables_include (L'g', walkables, n)) {
429 printf ("Walkable chars do not include 'g'\n", n);
433 printf ("Walkables = ");
434 print_walkables (walkables, n);
436 goto err_trie_state_t_created;
439 /* walk from s (19) with "duce" */
440 msg_step ("Try walking from (19) with 'd' to (20)");
441 trie_state_copy (t, s);
442 if (!trie_state_walk (t, L'd')) {
443 printf ("Failed to walk from (19) with 'd' to (20)\n");
444 goto err_trie_state_t_created;
446 if (!trie_state_is_single (t)) {
447 printf ("(20) should be single, but isn't.\n");
448 goto err_trie_state_t_created;
450 msg_step ("Try walking from (20) with 'u' to (21)");
451 if (!trie_state_walk (t, L'u')) {
452 printf ("Failed to walk from (20) with 'u' to (21)\n");
453 goto err_trie_state_t_created;
455 msg_step ("Try walking from (21) with 'c' to (22)");
456 if (!trie_state_walk (t, L'c')) {
457 printf ("Failed to walk from (21) with 'c' to (22)\n");
458 goto err_trie_state_t_created;
460 msg_step ("Try walking from (22) with 'e' to (23)");
461 if (!trie_state_walk (t, L'e')) {
462 printf ("Failed to walk from (22) with 'e' to (23)\n");
463 goto err_trie_state_t_created;
465 if (!trie_state_is_terminal (t)) {
466 printf ("(23) should be terminal, but isn't.\n");
467 goto err_trie_state_t_created;
470 msg_step ("Try getting data from (23)");
471 data = trie_state_get_data (t);
472 if (TRIE_DATA_ERROR == data) {
473 printf ("Failed to get data from (23)\n");
474 goto err_trie_state_t_created;
476 if (TRIE_DATA_UNREAD != data) {
477 printf ("Mismatched data from (23), expected %d, got %d\n",
478 TRIE_DATA_UNREAD, data);
479 goto err_trie_state_t_created;
484 /* walk from s (19) with "gress" */
485 msg_step ("Try walking from (19) with 'g' to (24)");
486 if (!trie_state_walk (s, L'g')) {
487 printf ("Failed to walk from (19) with 'g' to (24)\n");
488 goto err_trie_state_s_created;
490 if (!trie_state_is_single (s)) {
491 printf ("(24) should be single, but isn't.\n");
492 goto err_trie_state_s_created;
494 msg_step ("Try walking from (24) with 'r' to (25)");
495 if (!trie_state_walk (s, L'r')) {
496 printf ("Failed to walk from (24) with 'r' to (25)\n");
497 goto err_trie_state_s_created;
499 msg_step ("Try walking from (25) with 'e' to (26)");
500 if (!trie_state_walk (s, L'e')) {
501 printf ("Failed to walk from (25) with 'e' to (26)\n");
502 goto err_trie_state_s_created;
504 msg_step ("Try walking from (26) with 's' to (27)");
505 if (!trie_state_walk (s, L's')) {
506 printf ("Failed to walk from (26) with 's' to (27)\n");
507 goto err_trie_state_s_created;
509 msg_step ("Try walking from (27) with 's' to (28)");
510 if (!trie_state_walk (s, L's')) {
511 printf ("Failed to walk from (27) with 's' to (28)\n");
512 goto err_trie_state_s_created;
514 if (!trie_state_is_terminal (s)) {
515 printf ("(28) should be terminal, but isn't.\n");
516 goto err_trie_state_s_created;
519 msg_step ("Try getting data from (28)");
520 data = trie_state_get_data (s);
521 if (TRIE_DATA_ERROR == data) {
522 printf ("Failed to get data from (28)\n");
523 goto err_trie_state_s_created;
525 if (TRIE_DATA_UNREAD != data) {
526 printf ("Mismatched data from (28), expected %d, got %d\n",
527 TRIE_DATA_UNREAD, data);
528 goto err_trie_state_s_created;
532 trie_free (test_trie);
535 err_trie_state_u_created:
537 err_trie_state_t_created:
539 err_trie_state_s_created:
542 trie_free (test_trie);
543 err_trie_not_created: