Imported Upstream version 0.2.7 56/154756/1 upstream/0.2.7
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 11 Oct 2017 08:33:39 +0000 (17:33 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 11 Oct 2017 08:33:43 +0000 (17:33 +0900)
Change-Id: Ia81601958dd81ca3f86c3f493d1c1e5c81d2b4b4
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
21 files changed:
ChangeLog
Makefile.am
NEWS
configure.ac
datrie/Makefile.am
datrie/alpha-map.c
datrie/alpha-map.h
datrie/dstring.c
datrie/libdatrie.def
datrie/libdatrie.map
datrie/trie-string.c
datrie/trie.c
doc/Doxyfile.in
tests/Makefile.am [new file with mode: 0644]
tests/test_file.c [new file with mode: 0644]
tests/test_iterator.c [new file with mode: 0644]
tests/test_store-retrieve.c [new file with mode: 0644]
tests/test_walk.c [new file with mode: 0644]
tests/utils.c [new file with mode: 0644]
tests/utils.h [new file with mode: 0644]
tools/Makefile.am

index baa1859..f13520d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,149 @@
+2013-10-21  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       * NEWS, configure.ac:
+       === Version 0.2.7 ===
+
+2013-10-21  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Add missing distributed file.
+
+       * tests/Makefile.am:
+         - Add utils.h to distribution.
+
+2013-10-20  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Reorder tests from primitive to applied.
+
+       * tests/Makefile.am:
+         - Test walk & iterator before store-retrieve & file.
+
+2013-10-20  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Write a test suite for trie walk.
+
+       * tests/test_walk.c:
+         - Write test code.
+
+2013-10-18  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Write a test suite for trie store/retrieval.
+
+       * tests/utils.h, tests/utils.c (+dict_src_n_entries):
+         - Add function to get total entries in dict_src[].
+       * tests/test_store-retrieve.c (main):
+         - Write test code.
+
+2013-10-18  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Fix messages in test_iterator.
+
+       * tests/test_iterator.c (main):
+         - s/file/trie/. No file is written or read in this test.
+
+2013-10-18  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Skip further iteration tests if key is NULL.
+
+       * tests/test_iterator.c (main):
+         - Insert 'continue' if trie_iterator_get_key() returns NULL.
+
+2013-10-17  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Document availibility of alpha_char_strcmp()
+
+       * datrie/alpha-map.c (alpha_char_strcmp):
+         - Document that it's available since 0.2.7.
+
+2013-10-17  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Write a test for trie iterator.
+
+       * tests/test_iterator.c:
+         - Write test suite for trie iterator.
+
+2013-10-17  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Add skeleton test suites & a test for file I/O.
+
+       * configure.ac, Makefile.am, +tests/, +tests/Makefile.am:
+         - Add tests/ dir to the build system.
+       * +tests/utils.h, +tests/utils.c:
+       * +tests/test_file.c:
+       * +tests/test_iterator.c:
+       * +tests/test_store-retrieve.c:
+       * +tests/test_walk.c:
+         - Add skeleton for test suites.
+       * tests/utils.h, tests/utils.c, tests/test_file.c:
+         - Write test suite for file I/O.
+
+2013-10-17  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Add alpha_char_strcmp() API.
+
+       * datrie/alpha-map.h, datrie/alpha-map.c (+alpha_char_strcmp):
+         - Add alpha_char_strcmp() declaration & body.
+       * datrie/libdatrie.def, datrie/libdatrie.map:
+         - Add alpha_char_strcmp symbols.
+
+2013-10-16  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Add missing info in alpha_map_add_range() doc.
+
+       * datrie/alpha-map.c (alpha_map_add_range):
+         - Add documentation on return value.
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Fix build for Visual Studio on Windows.
+
+       * datrie/dstring.c (dstring_append, dstring_append_string,
+         dstring_append_char, dstring_terminate):
+         - Cast (void *) pointers to (char *) before calculating offsets,
+           for portability.
+
+       Thanks Gabi Davar for the report and fix (via Mikhail Korobov
+       <kmike84@gmail.com>).
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Check for doxygen required version.
+
+       * configure.ac:
+         - When doxygen-doc is enabled, also check doxygen version.
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Fix doxygen warning.
+
+       * doc/Doxyfile.in:
+         - doxygen no longer ships with the FreeSans font. Just drop it.
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Update Doxyfile.
+
+       * doc/Doxyfile.in:
+         - Updated with 'doxygen -u'.
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Fix compiler warnings.
+       * datrie/trie-string.c (trie_string_append_string):
+       * datrie/trie.c (trie_iterator_get_key):
+         - Cast strlen() args from (const TrieChar *) to (const char *),
+           to fix signedness mismatch warnings.
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       Fix automake warnings.
+
+       * datrie/Makefile.am, tools/Makefile.am:
+         - Replace deprecated INCLUDES with AM_CPPFLAGS.
+
+2013-09-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
+
+       * configure.ac: Post-release version suffix added.
+
 2013-01-23  Theppitak Karoonboonyanan  <thep@linux.thai.net>
 
        * NEWS, configure.ac:
index cab7e26..09a70ee 100644 (file)
@@ -1,6 +1,6 @@
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = datrie tools man doc
+SUBDIRS = datrie tools man doc tests
 
 EXTRA_DIST = README.migration
 
diff --git a/NEWS b/NEWS
index a6c40fb..2dde7e6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,14 @@
 libdatrie
 
+0.2.7 (2013-10-21)
+=====
+- Fix portability issue with non-GCC compilers.
+  [Thanks Gabi Daver for the report and fix (via Mikhail Korobov).]
+- Fix compiler warnings.
+- New utility API for comparing AlphaChar strings.
+- Add test suites.
+- Update doxygen doc generation.
+
 0.2.6 (2013-01-23)
 =====
 - New API trie_state_walkable_chars() for breadth-first traversal.
index 11cb008..36a844e 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT(libdatrie, 0.2.6, thep@linux.thai.net)
+AC_INIT(libdatrie, 0.2.7, thep@linux.thai.net)
 AC_CONFIG_SRCDIR([datrie/trie.h])
 AC_CONFIG_HEADER([config.h])
 AC_CONFIG_MACRO_DIR([m4])
@@ -20,6 +20,8 @@ AC_SUBST(LT_CURRENT)
 AC_SUBST(LT_REVISION)
 AC_SUBST(LT_AGE)
 
+DOXYGEN_REQ_VER=1.8.4
+
 # Checks for programs.
 AC_PROG_CC
 AC_PROG_INSTALL
@@ -107,6 +109,15 @@ if test "x$enable_doxygen_doc" = "xyes"; then
   AC_CHECK_PROG(DOXYGEN,doxygen,doxygen,no)
   if test "x$DOXYGEN" = "xno"; then
     enable_doxygen_doc="no"
+  else
+    AC_MSG_CHECKING([doxygen >= $DOXYGEN_REQ_VER])
+    DOXYGEN_VER=$($DOXYGEN --version)
+    if expr $DOXYGEN_VER \< $DOXYGEN_REQ_VER > /dev/null; then
+      AC_MSG_RESULT([$DOXYGEN_VER, no, documentation disabled])
+      enable_doxygen_doc="no"
+    else
+      AC_MSG_RESULT([$DOXYGEN_VER, yes])
+    fi
   fi
 fi
 
@@ -128,5 +139,6 @@ AC_CONFIG_FILES([Makefile
                  tools/Makefile
                  man/Makefile
                  doc/Makefile
-                 doc/Doxyfile])
+                 doc/Doxyfile
+                 tests/Makefile])
 AC_OUTPUT
index 9d567ff..e46af46 100644 (file)
@@ -8,7 +8,7 @@ pkginclude_HEADERS =    \
 
 EXTRA_DIST = libdatrie.map libdatrie.def
 
-INCLUDES = -I$(top_srcdir)
+AM_CPPFLAGS = -I$(top_srcdir)
 
 lib_LTLIBRARIES = libdatrie.la
 
index 86afdbc..f25604f 100644 (file)
@@ -51,6 +51,31 @@ alpha_char_strlen (const AlphaChar *str)
     return p - str;
 }
 
+/**
+ * @brief Compare alphabet strings
+ *
+ * @param str1, str2  : the arrays of null-terminated AlphaChar strings
+ *                      to compare
+ *
+ * @return negative if @a str1 < @a str2;
+ *         0 if @a str1 == @a str2; 
+ *         positive if @a str1 > @a str2
+ *
+ * Available since: 0.2.7
+ */
+int
+alpha_char_strcmp (const AlphaChar *str1, const AlphaChar *str2)
+{
+    while (*str1 && *str1 == *str2) {
+        str1++; str2++;
+    }
+    if (*str1 < *str2)
+        return -1;
+    if (*str1 > *str2)
+        return 1;
+    return 0;
+}
+
 /*------------------------------*
  *    PRIVATE DATA DEFINITONS   *
  *------------------------------*/
@@ -241,6 +266,8 @@ alpha_map_fwrite_bin (const AlphaMap *alpha_map, FILE *file)
  * @param begin     : the first character of the range
  * @param end       : the last character of the range
  *
+ * @return 0 on success, non-zero on failure
+ *
  * Add a range of character codes from @a begin to @a end to the
  * alphabet set.
  */
index f6ec422..7246160 100644 (file)
@@ -57,6 +57,7 @@ int         alpha_map_add_range (AlphaMap  *alpha_map,
                                  AlphaChar  end);
 
 int         alpha_char_strlen (const AlphaChar *str);
+int         alpha_char_strcmp (const AlphaChar *str1, const AlphaChar *str2);
 
 #ifdef __cplusplus
 }
index 1004e3a..20d336f 100644 (file)
@@ -126,7 +126,7 @@ dstring_append (DString *dst, const DString *src)
         return FALSE;
     }
 
-    memcpy (dst->val + (dst->char_size * dst->str_len), src->val,
+    memcpy ((char *)dst->val + (dst->char_size * dst->str_len), src->val,
             (src->str_len + 1) * dst->char_size);
 
     dst->str_len += src->str_len;
@@ -140,7 +140,8 @@ dstring_append_string (DString *ds, const void *data, int len)
     if (!dstring_ensure_space (ds, (ds->str_len + len + 1) * ds->char_size))
         return FALSE;
 
-    memcpy (ds->val + (ds->char_size * ds->str_len), data, ds->char_size * len);
+    memcpy ((char  *)ds->val + (ds->char_size * ds->str_len), data,
+            ds->char_size * len);
 
     ds->str_len += len;
 
@@ -153,7 +154,8 @@ dstring_append_char (DString *ds, const void *data)
     if (!dstring_ensure_space (ds, (ds->str_len + 2) * ds->char_size))
         return FALSE;
 
-    memcpy (ds->val + (ds->char_size * ds->str_len), data, ds->char_size);
+    memcpy ((char *)ds->val + (ds->char_size * ds->str_len), data,
+            ds->char_size);
 
     ds->str_len++;
 
@@ -166,7 +168,7 @@ dstring_terminate (DString *ds)
     if (!dstring_ensure_space (ds, (ds->str_len + 2) * ds->char_size))
         return FALSE;
 
-    memset (ds->val + (ds->char_size * ds->str_len), 0, ds->char_size);
+    memset ((char *)ds->val + (ds->char_size * ds->str_len), 0, ds->char_size);
 
     return TRUE;
 }
index 19d4a87..185bda5 100644 (file)
@@ -3,6 +3,7 @@ alpha_map_clone
 alpha_map_free
 alpha_map_add_range
 alpha_char_strlen
+alpha_char_strcmp
 trie_new
 trie_new_from_file
 trie_fread
index d6a518a..8c9a0da 100644 (file)
@@ -41,3 +41,7 @@ DATRIE_0.2.6 {
   trie_iterator_get_data;
 } DATRIE_0.2.4;
 
+DATRIE_0.2.7 {
+  alpha_char_strcmp;
+} DATRIE_0.2.6;
+
index 7deddeb..069324a 100644 (file)
@@ -87,7 +87,8 @@ trie_string_append (TrieString *dst, const TrieString *src)
 Bool
 trie_string_append_string (TrieString *ts, const TrieChar *str)
 {
-    return dstring_append_string ((DString *)ts, str, strlen (str));
+    return dstring_append_string ((DString *)ts,
+                                  str, strlen ((const char *)str));
 }
 
 Bool
index 21a6fee..ae3ff25 100644 (file)
@@ -1004,7 +1004,8 @@ trie_iterator_get_key (const TrieIterator *iter)
         tail_str += s->suffix_idx;
 
         alpha_key = (AlphaChar *) malloc (sizeof (AlphaChar)
-                                          * (strlen (tail_str) + 1));
+                                          * (strlen ((const char *)tail_str)
+                                             + 1));
         alpha_p = alpha_key;
     } else {
         TrieIndex  tail_idx;
@@ -1019,7 +1020,8 @@ trie_iterator_get_key (const TrieIterator *iter)
         key_len = trie_string_length (iter->key);
         key_p = trie_string_get_val (iter->key);
         alpha_key = (AlphaChar *) malloc (
-                        sizeof (AlphaChar) * (key_len + strlen (tail_str) + 1)
+                        sizeof (AlphaChar)
+                        * (key_len + strlen ((const char *)tail_str) + 1)
                     );
         alpha_p = alpha_key;
         for (i = key_len; i > 0; i--) {
index 265a48c..1adbb20 100644 (file)
@@ -1,8 +1,10 @@
-# Doxyfile 1.8.1.2
+# Doxyfile 1.8.4
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project.
 #
+# All text after a double hash (##) is considered a comment and is placed
+# in front of the TAG it is preceding .
 # All text after a hash (#) is considered a comment and will be ignored.
 # The format is:
 #       TAG = value [value, ...]
@@ -70,9 +72,9 @@ CREATE_SUBDIRS         = NO
 # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
 # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
 # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
 
 OUTPUT_LANGUAGE        = English
 
@@ -136,7 +138,9 @@ FULL_PATH_NAMES        = YES
 # only done if one of the specified strings matches the left-hand part of
 # the path. The tag can be used to show relative paths in the file list.
 # If left blank the directory from which doxygen is run is used as the
-# path to strip.
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
 
 STRIP_FROM_PATH        = @top_srcdir@
 
@@ -239,14 +243,15 @@ OPTIMIZE_FOR_FORTRAN   = NO
 OPTIMIZE_OUTPUT_VHDL   = NO
 
 # Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this
-# tag. The format is ext=language, where ext is a file extension, and language
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
 
 EXTENSION_MAPPING      =
 
@@ -259,6 +264,13 @@ EXTENSION_MAPPING      =
 
 MARKDOWN_SUPPORT       = YES
 
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT       = YES
+
 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
 # to include (a tag file for) the STL sources as input, then you should
 # set this tag to YES in order to let doxygen match functions declarations and
@@ -279,10 +291,10 @@ CPP_CLI_SUPPORT        = NO
 
 SIP_SUPPORT            = NO
 
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
 # setting a simple type. If this is not the case, or you want to show the
 # methods anyway, you should set this option to NO.
 
@@ -311,11 +323,11 @@ SUBGROUPING            = YES
 INLINE_GROUPED_CLASSES = NO
 
 # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
-# unions with only public data fields will be shown inline in the documentation
-# of the scope in which they are defined (i.e. file, namespace, or group
-# documentation), provided this scope is documented. If set to NO (the default),
-# structs, classes, and unions are shown on a separate page (for HTML and Man
-# pages) or section (for LaTeX and RTF).
+# unions with only public data fields or simple typedef fields will be shown
+# inline in the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO (the default), structs, classes, and unions are shown on a separate
+# page (for HTML and Man pages) or section (for LaTeX and RTF).
 
 INLINE_SIMPLE_STRUCTS  = NO
 
@@ -329,30 +341,14 @@ INLINE_SIMPLE_STRUCTS  = NO
 
 TYPEDEF_HIDES_STRUCT   = NO
 
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penalty.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will roughly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols.
-
-SYMBOL_CACHE_SIZE      = 0
-
-# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
-# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
-# their name and scope. Since this can be an expensive process and often the
-# same symbol appear multiple times in the code, doxygen keeps a cache of
-# pre-resolved symbols. If the cache is too small doxygen will become slower.
-# If the cache is too large, memory is wasted. The cache size is given by this
-# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols.
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can
+# be an expensive process and often the same symbol appear multiple times in
+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
+# small doxygen will become slower. If the cache is too large, memory is wasted.
+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
+# symbols.
 
 LOOKUP_CACHE_SIZE      = 0
 
@@ -363,7 +359,7 @@ LOOKUP_CACHE_SIZE      = 0
 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
 # documentation are documented, even if no documentation was available.
 # Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
 
 EXTRACT_ALL            = NO
 
@@ -372,7 +368,8 @@ EXTRACT_ALL            = NO
 
 EXTRACT_PRIVATE        = NO
 
-# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
 
 EXTRACT_PACKAGE        = NO
 
@@ -543,7 +540,8 @@ GENERATE_BUGLIST       = YES
 GENERATE_DEPRECATEDLIST= YES
 
 # The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
+# documentation sections, marked by \if section-label ... \endif
+# and \cond section-label ... \endcond blocks.
 
 ENABLED_SECTIONS       =
 
@@ -601,7 +599,8 @@ LAYOUT_FILE            =
 # requires the bibtex tool to be installed. See also
 # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
 # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
-# feature you need bibtex and perl available in the search path.
+# feature you need bibtex and perl available in the search path. Do not use
+# file names with spaces, bibtex cannot handle them.
 
 CITE_BIB_FILES         =
 
@@ -758,8 +757,10 @@ IMAGE_PATH             =
 # is the value of the INPUT_FILTER tag, and <input-file> is the name of an
 # input file. Doxygen will then use the output that the filter program writes
 # to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
-# ignored.
+# If FILTER_PATTERNS is specified, this tag will be ignored.
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
 
 INPUT_FILTER           =
 
@@ -788,6 +789,13 @@ FILTER_SOURCE_FILES    = NO
 
 FILTER_SOURCE_PATTERNS =
 
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
@@ -909,17 +917,27 @@ HTML_FOOTER            =
 
 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading
 # style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# style sheet in the HTML output directory as well, or it will be erased!
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
 
 HTML_STYLESHEET        =
 
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET  =
+
 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the HTML output directory. Note
 # that these files will be copied to the base HTML output directory. Use the
-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
 # files. In the HTML_STYLESHEET file, use the file name only. Also note that
 # the files will be copied as-is; there are no commands or markers available.
 
@@ -1000,9 +1018,9 @@ DOCSET_FEEDNAME        = "Doxygen generated docs"
 
 DOCSET_BUNDLE_ID       = org.doxygen.Project
 
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
 
 DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
 
@@ -1187,6 +1205,13 @@ FORMULA_TRANSPARENT    = YES
 
 USE_MATHJAX            = NO
 
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
+# SVG. The default value is HTML-CSS, which is slower, but has the best
+# compatibility.
+
+MATHJAX_FORMAT         = HTML-CSS
+
 # When MathJax is enabled you need to specify the location relative to the
 # HTML output directory using the MATHJAX_RELPATH option. The destination
 # directory should contain the MathJax.js script. For instance, if the mathjax
@@ -1204,6 +1229,11 @@ MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
 
 MATHJAX_EXTENSIONS     =
 
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
+# pieces of code that will be used on startup of the MathJax code.
+
+MATHJAX_CODEFILE       =
+
 # When the SEARCHENGINE tag is enabled doxygen will generate a search box
 # for the HTML output. The underlying search engine uses javascript
 # and DHTML and should work on any modern browser. Note that when using
@@ -1215,15 +1245,55 @@ MATHJAX_EXTENSIONS     =
 SEARCHENGINE           = NO
 
 # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a PHP enabled web server instead of at the web client
-# using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server
-# based approach is that it scales better to large projects and allows
-# full text search. The disadvantages are that it is more difficult to setup
-# and does not have live searching capabilities.
+# implemented using a web server instead of a web client using Javascript.
+# There are two flavours of web server based search depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools.
+# See the manual for details.
 
 SERVER_BASED_SEARCH    = NO
 
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
+# the search results. Doxygen ships with an example indexer (doxyindexer) and
+# search engine (doxysearch.cgi) which are based on the open source search
+# engine library Xapian. See the manual for configuration details.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will returned the search results when EXTERNAL_SEARCH is enabled.
+# Doxygen ships with an example search engine (doxysearch) which is based on
+# the open source search engine library Xapian. See the manual for configuration
+# details.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
+# of to a relative location where the documentation can be found.
+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
+
+EXTRA_SEARCH_MAPPINGS  =
+
 #---------------------------------------------------------------------------
 # configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
@@ -1261,7 +1331,7 @@ COMPACT_LATEX          = NO
 
 # The PAPER_TYPE tag can be used to set the paper type that is used
 # by the printer. Possible values are: a4, letter, legal and
-# executive. If left blank a4wide will be used.
+# executive. If left blank a4 will be used.
 
 PAPER_TYPE             = a4wide
 
@@ -1284,6 +1354,13 @@ LATEX_HEADER           =
 
 LATEX_FOOTER           =
 
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
+# or other source files which should be copied to the LaTeX output directory.
+# Note that the files will be copied as-is; there are no commands or markers
+# available.
+
+LATEX_EXTRA_FILES      =
+
 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
 # is prepared for conversion to pdf (using ps2pdf). The pdf file will
 # contain links (just like the HTML output) instead of page references
@@ -1429,6 +1506,21 @@ XML_DTD                =
 XML_PROGRAMLISTING     = YES
 
 #---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
+# that can be used to generate PDF.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it. If left blank docbook will be used as the default path.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
 # configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
@@ -1577,6 +1669,12 @@ ALLEXTERNALS           = NO
 
 EXTERNAL_GROUPS        = YES
 
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
+# in the related pages index. If set to NO, only the current project's
+# pages will be listed.
+
+EXTERNAL_PAGES         = YES
+
 # The PERL_PATH should be the absolute path and name of the perl script
 # interpreter (i.e. the result of `which perl').
 
@@ -1631,7 +1729,7 @@ DOT_NUM_THREADS        = 0
 # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
 # directory containing the font.
 
-DOT_FONTNAME           = FreeSans
+DOT_FONTNAME           =
 
 # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
 # The default size is 10pt.
@@ -1673,7 +1771,7 @@ UML_LOOK               = NO
 # the class node. If there are many fields or methods and many nodes the
 # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
 # threshold limits the number of items for each type to make the size more
-# managable. Set this to 0 for no limit. Note that the threshold may be
+# manageable. Set this to 0 for no limit. Note that the threshold may be
 # exceeded by 50% before the limit is enforced.
 
 UML_LIMIT_NUM_FIELDS   = 10
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..410f36b
--- /dev/null
@@ -0,0 +1,46 @@
+AM_CPPFLAGS = -I$(top_srcdir)
+
+TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
+
+TESTS = \
+       test_walk \
+       test_iterator \
+       test_store-retrieve \
+       test_file \
+       $(NULL)
+
+check_PROGRAMS = \
+       test_walk \
+       test_iterator \
+       test_store-retrieve \
+       test_file \
+       $(NULL)
+
+noinst_HEADERS = \
+       utils.h \
+       $(NULL)
+
+test_walk_SOURCES = \
+       test_walk.c \
+       utils.c \
+       $(NULL)
+test_walk_LDADD = $(top_builddir)/datrie/libdatrie.la
+
+test_iterator_SOURCES = \
+       test_iterator.c \
+       utils.c \
+       $(NULL)
+test_iterator_LDADD = $(top_builddir)/datrie/libdatrie.la
+
+test_store_retrieve_SOURCES = \
+       test_store-retrieve.c \
+       utils.c \
+       $(NULL)
+test_store_retrieve_LDADD = $(top_builddir)/datrie/libdatrie.la
+
+test_file_SOURCES = \
+       test_file.c \
+       utils.c \
+       $(NULL)
+test_file_LDADD = $(top_builddir)/datrie/libdatrie.la
+
diff --git a/tests/test_file.c b/tests/test_file.c
new file mode 100644 (file)
index 0000000..3e5217c
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2013  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * test_file.c - Test for datrie file operations
+ * Created: 2013-10-16
+ * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ */
+
+#include <datrie/trie.h>
+#include "utils.h"
+#include <stdio.h>
+#include <unistd.h>
+
+#define TRIE_FILENAME "test.tri"
+
+static Bool
+trie_enum_mark_rec (const AlphaChar *key, TrieData key_data, void *user_data)
+{
+    Bool *is_failed = (Bool *)user_data;
+    TrieData src_data;
+
+    src_data = dict_src_get_data (key);
+    if (TRIE_DATA_ERROR == src_data) {
+        printf ("Extra entry in file: key '%ls', data %d.\n", key, key_data);
+        *is_failed = TRUE;
+    } else if (src_data != key_data) {
+        printf ("Data mismatch for: key '%ls', expected %d, got %d.\n",
+                key, src_data, key_data);
+        *is_failed = TRUE;
+    } else {
+        dict_src_set_data (key, TRIE_DATA_READ);
+    }
+
+    return TRUE;
+}
+
+int
+main ()
+{
+    Trie    *test_trie;
+    DictRec *dict_p;
+    Bool     is_failed;
+
+    msg_step ("Preparing trie");
+    test_trie = en_trie_new ();
+    if (!test_trie) {
+        printf ("Failed to allocate test trie.\n");
+        goto err_trie_not_created;
+    }
+
+    /* add/remove some words */
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (!trie_store (test_trie, dict_p->key, dict_p->data)) {
+            printf ("Failed to add key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            goto err_trie_created;
+        }
+    }
+
+    /* save & close */
+    msg_step ("Saving trie to file");
+    unlink (TRIE_FILENAME);  /* error ignored */
+    if (trie_save (test_trie, TRIE_FILENAME) != 0) {
+        printf ("Failed to save trie to file '%s'.\n", TRIE_FILENAME);
+        goto err_trie_created;
+    }
+    trie_free (test_trie);
+
+    /* reload from file */
+    msg_step ("Reloading trie from the saved file");
+    test_trie = trie_new_from_file (TRIE_FILENAME);
+    if (!test_trie) {
+        printf ("Failed to reload saved trie from '%s'.\n",
+                 TRIE_FILENAME);
+        goto err_trie_saved;
+    }
+
+    /* enumerate & check */
+    msg_step ("Checking trie contents");
+    is_failed = FALSE;
+    /* mark entries found in file */
+    if (!trie_enumerate (test_trie, trie_enum_mark_rec, (void *)&is_failed)) {
+        printf ("Failed to enumerate trie file contents.\n");
+        goto err_trie_saved;
+    }
+    /* check for unmarked entries, (i.e. missed in file) */
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (dict_p->data != TRIE_DATA_READ) {
+            printf ("Entry missed in file: key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            is_failed = TRUE;
+        }
+    }
+    if (is_failed) {
+        printf ("Errors found in trie saved contents.\n");
+        goto err_trie_saved;
+    }
+
+    unlink (TRIE_FILENAME);
+    trie_free (test_trie);
+    return 0;
+
+err_trie_saved:
+    unlink (TRIE_FILENAME);
+err_trie_created:
+    trie_free (test_trie);
+err_trie_not_created:
+    return 1;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/tests/test_iterator.c b/tests/test_iterator.c
new file mode 100644 (file)
index 0000000..21ab7ff
--- /dev/null
@@ -0,0 +1,135 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2013  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * test_iterator.c - Test for datrie iterator operations
+ * Created: 2013-10-16
+ * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ */
+
+#include <datrie/trie.h>
+#include "utils.h"
+#include <stdio.h>
+
+int
+main ()
+{
+    Trie         *test_trie;
+    DictRec      *dict_p;
+    TrieState    *trie_root_state;
+    TrieIterator *trie_it;
+    Bool          is_failed;
+
+    msg_step ("Preparing trie");
+    test_trie = en_trie_new ();
+    if (!test_trie) {
+        fprintf (stderr, "Fail to create test trie\n");
+        goto err_trie_not_created;
+    }
+
+    /* store */
+    msg_step ("Adding data to trie");
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (!trie_store (test_trie, dict_p->key, dict_p->data)) {
+            printf ("Failed to add key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            goto err_trie_created;
+        }
+    }
+
+    /* iterate & check */
+    msg_step ("Iterating and checking trie contents");
+    trie_root_state = trie_root (test_trie);
+    if (!trie_root_state) {
+        printf ("Failed to get trie root state\n");
+        goto err_trie_created;
+    }
+    trie_it = trie_iterator_new (trie_root_state);
+    if (!trie_it) {
+        printf ("Failed to get trie iterator\n");
+        goto err_trie_root_created;
+    }
+
+    is_failed = FALSE;
+    while (trie_iterator_next (trie_it)) {
+        AlphaChar *key;
+        TrieData   key_data, src_data;
+
+        key = trie_iterator_get_key (trie_it);
+        if (!key) {
+            printf ("Failed to get key from trie iterator\n");
+            is_failed = TRUE;
+            continue;
+        }
+        key_data = trie_iterator_get_data (trie_it);
+        if (TRIE_DATA_ERROR == key_data) {
+            printf ("Failed to get data from trie iterator for key '%ls'\n",
+                    key);
+            is_failed = TRUE;
+        }
+        /* mark entries found in trie */
+        src_data = dict_src_get_data (key);
+        if (TRIE_DATA_ERROR == src_data) {
+            printf ("Extra entry in trie: key '%ls', data %d.\n",
+                    key, key_data);
+            is_failed = TRUE;
+        } else if (src_data != key_data) {
+            printf ("Data mismatch for: key '%ls', expected %d, got %d.\n",
+                    key, src_data, key_data);
+            is_failed = TRUE;
+        } else {
+            dict_src_set_data (key, TRIE_DATA_READ);
+        }
+
+        free (key);
+    }
+
+    /* check for unmarked entries, (i.e. missed in trie) */
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (dict_p->data != TRIE_DATA_READ) {
+            printf ("Entry missed in trie: key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            is_failed = TRUE;
+        }
+    }
+
+    if (is_failed) {
+        printf ("Errors found in trie iteration.\n");
+        goto err_trie_it_created;
+    }
+
+    trie_iterator_free (trie_it);
+    trie_state_free (trie_root_state);
+    trie_free (test_trie);
+    return 0;
+
+err_trie_it_created:
+    trie_iterator_free (trie_it);
+err_trie_root_created:
+    trie_state_free (trie_root_state);
+err_trie_created:
+    trie_free (test_trie);
+err_trie_not_created:
+    return 1;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/tests/test_store-retrieve.c b/tests/test_store-retrieve.c
new file mode 100644 (file)
index 0000000..28e5aef
--- /dev/null
@@ -0,0 +1,201 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2013  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * test_store-retrieve.c - Test for datrie store/retrieve operations
+ * Created: 2013-10-16
+ * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ */
+
+#include <datrie/trie.h>
+#include "utils.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+int
+main ()
+{
+    Trie         *test_trie;
+    DictRec      *dict_p;
+    TrieData      trie_data;
+    Bool          is_failed;
+    int           n_entries, n_dels, i;
+    TrieState    *trie_root_state;
+    TrieIterator *trie_it;
+
+    msg_step ("Preparing trie");
+    test_trie = en_trie_new ();
+    if (!test_trie) {
+        fprintf (stderr, "Fail to create test trie\n");
+        goto err_trie_not_created;
+    }
+
+    /* store */
+    msg_step ("Adding data to trie");
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (!trie_store (test_trie, dict_p->key, dict_p->data)) {
+            printf ("Failed to add key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            goto err_trie_created;
+        }
+    }
+
+    /* retrieve */
+    msg_step ("Retrieving data from trie");
+    is_failed = FALSE;
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) {
+            printf ("Failed to retrieve key '%ls'.\n", dict_p->key);
+            is_failed = TRUE;
+        }
+        if (trie_data != dict_p->data) {
+            printf ("Wrong data for key '%ls'; expected %d, got %d.\n",
+                    dict_p->key, dict_p->data, trie_data);
+            is_failed = TRUE;
+        }
+    }
+    if (is_failed) {
+        printf ("Trie store/retrieval test failed.\n");
+        goto err_trie_created;
+    }
+
+    /* delete */
+    msg_step ("Deleting some entries from trie");
+    n_entries = dict_src_n_entries ();
+    srand (time (NULL));
+    for (n_dels = n_entries/3 + 1; n_dels > 0; n_dels--) {
+        /* pick an undeleted entry */
+        do {
+            i = rand () % n_entries;
+        } while (TRIE_DATA_READ == dict_src[i].data);
+
+        printf ("Deleting '%ls'\n", dict_src[i].key);
+        if (!trie_delete (test_trie, dict_src[i].key)) {
+            printf ("Failed to delete '%ls'\n", dict_src[i].key);
+            is_failed = TRUE;
+        }
+        dict_src[i].data = TRIE_DATA_READ;
+    }
+    if (is_failed) {
+        printf ("Trie deletion test failed.\n");
+        goto err_trie_created;
+    }
+
+    /* retrieve */
+    msg_step ("Retrieving data from trie again after deletions");
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        /* skip deleted entries */
+        if (TRIE_DATA_READ == dict_p->data)
+            continue;
+
+        if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) {
+            printf ("Failed to retrieve key '%ls'.\n", dict_p->key);
+            is_failed = TRUE;
+        }
+        if (trie_data != dict_p->data) {
+            printf ("Wrong data for key '%ls'; expected %d, got %d.\n",
+                    dict_p->key, dict_p->data, trie_data);
+            is_failed = TRUE;
+        }
+    }
+    if (is_failed) {
+        printf ("Trie retrival-after-deletion test failed.\n");
+        goto err_trie_created;
+    }
+
+    /* enumerate & check */
+    msg_step ("Iterating trie contents after deletions");
+    trie_root_state = trie_root (test_trie);
+    if (!trie_root_state) {
+        printf ("Failed to get trie root state\n");
+        goto err_trie_created;
+    }
+    trie_it = trie_iterator_new (trie_root_state);
+    if (!trie_it) {
+        printf ("Failed to get trie iterator\n");
+        goto err_trie_root_created;
+    }
+
+    while (trie_iterator_next (trie_it)) {
+        AlphaChar *key;
+        TrieData   key_data, src_data;
+
+        key = trie_iterator_get_key (trie_it);
+        if (!key) {
+            printf ("Failed to get key from trie iterator\n");
+            is_failed = TRUE;
+            continue;
+        }
+        key_data = trie_iterator_get_data (trie_it);
+        if (TRIE_DATA_ERROR == key_data) {
+            printf ("Failed to get data from trie iterator for key '%ls'\n",
+                    key);
+            is_failed = TRUE;
+        }
+        /* mark entries found in trie */
+        src_data = dict_src_get_data (key);
+        if (TRIE_DATA_ERROR == src_data) {
+            printf ("Extra entry in trie: key '%ls', data %d.\n",
+                    key, key_data);
+            is_failed = TRUE;
+        } else if (src_data != key_data) {
+            printf ("Data mismatch for: key '%ls', expected %d, got %d.\n",
+                    key, src_data, key_data);
+            is_failed = TRUE;
+        } else {
+            dict_src_set_data (key, TRIE_DATA_READ);
+        }
+
+        free (key);
+    }
+
+    /* check for unmarked entries, (i.e. missed in trie) */
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (dict_p->data != TRIE_DATA_READ) {
+            printf ("Entry missed in trie: key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            is_failed = TRUE;
+        }
+    }
+
+    if (is_failed) {
+        printf ("Errors found in trie iteration after deletions.\n");
+        goto err_trie_it_created;
+    }
+
+    trie_iterator_free (trie_it);
+    trie_state_free (trie_root_state);
+    trie_free (test_trie);
+    return 0;
+
+err_trie_it_created:
+    trie_iterator_free (trie_it);
+err_trie_root_created:
+    trie_state_free (trie_root_state);
+err_trie_created:
+    trie_free (test_trie);
+err_trie_not_created:
+    return 1;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/tests/test_walk.c b/tests/test_walk.c
new file mode 100644 (file)
index 0000000..4a2783f
--- /dev/null
@@ -0,0 +1,549 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2013  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * test_walk.c - Test for datrie walking operations
+ * Created: 2013-10-16
+ * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ */
+
+#include <datrie/trie.h>
+#include "utils.h"
+#include <stdio.h>
+
+/*
+ * Sample trie in http://linux.thai.net/~thep/datrie/datrie.html
+ *
+ *           +---o-> (3) -o-> (4) -l-> [5]
+ *           |
+ *           |        +---i-> (7) -z-> (8) -e-> [9]
+ *           |        |
+ * (1) -p-> (2) -r-> (6) -e-> (10) -v-> (11) -i-> (12) -e-> (13) -w-> [14]
+ *                    |         |
+ *                    |         +---p-> (15) -a-> (16) -r-> (17) -e-> [18]
+ *                    |
+ *                    +---o-> (19) -d-> (20) -u-> (21) -c-> (22) -e-> [23]
+ *                              |
+ *                              +---g-> (24) -r-> (25) -e-> (26) -s-> (27) -s-> [28]
+ *
+ */
+DictRec walk_dict[] = {
+    {L"pool",       TRIE_DATA_UNREAD},
+    {L"prize",      TRIE_DATA_UNREAD},
+    {L"preview",    TRIE_DATA_UNREAD},
+    {L"prepare",    TRIE_DATA_UNREAD},
+    {L"produce",    TRIE_DATA_UNREAD},
+    {L"progress",   TRIE_DATA_UNREAD},
+    {NULL,          TRIE_DATA_ERROR},
+};
+
+static Bool
+is_walkables_include (AlphaChar c, const AlphaChar *walkables, int n_elm)
+{
+    while (n_elm > 0) {
+        if (walkables[--n_elm] == c)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+print_walkables (const AlphaChar *walkables, int n_elm)
+{
+    int i;
+
+    printf ("{");
+    for (i = 0; i < n_elm; i++) {
+        if (i > 0) {
+            printf (", ");
+        }
+        printf ("'%lc'", walkables[i]);
+    }
+    printf ("}");
+}
+
+#define ALPHABET_SIZE 256
+
+int
+main ()
+{
+    Trie       *test_trie;
+    DictRec    *dict_p;
+    TrieState  *s, *t, *u;
+    AlphaChar   walkables[ALPHABET_SIZE];
+    int         n, i;
+    Bool        is_failed;
+    TrieData    data;
+
+    msg_step ("Preparing trie");
+    test_trie = en_trie_new ();
+    if (!test_trie) {
+        fprintf (stderr, "Fail to create test trie\n");
+        goto err_trie_not_created;
+    }
+
+    /* store */
+    for (dict_p = walk_dict; dict_p->key; dict_p++) {
+        if (!trie_store (test_trie, dict_p->key, dict_p->data)) {
+            printf ("Failed to add key '%ls', data %d.\n",
+                    dict_p->key, dict_p->data);
+            goto err_trie_created;
+        }
+    }
+
+    printf (
+        "Now the trie structure is supposed to be:\n"
+        "\n"
+        "          +---o-> (3) -o-> (4) -l-> [5]\n"
+        "          |\n"
+        "          |        +---i-> (7) -z-> (8) -e-> [9]\n"
+        "          |        |\n"
+        "(1) -p-> (2) -r-> (6) -e-> (10) -v-> (11) -i-> (12) -e-> (13) -w-> [14]\n"
+        "                   |         |\n"
+        "                   |         +---p-> (15) -a-> (16) -r-> (17) -e-> [18]\n"
+        "                   |\n"
+        "                   +---o-> (19) -d-> (20) -u-> (21) -c-> (22) -e-> [23]\n"
+        "                             |\n"
+        "                             +---g-> (24) -r-> (25) -e-> (26) -s-> (27) -s-> [28]\n"
+        "\n"
+    );
+
+    /* walk */
+    msg_step ("Test walking");
+    s = trie_root (test_trie);
+    if (!s) {
+        printf ("Failed to get trie root state\n");
+        goto err_trie_created;
+    }
+
+    msg_step ("Test walking with 'p'");
+    if (!trie_state_is_walkable (s, L'p')) {
+        printf ("Trie state is not walkable with 'p'\n");
+        goto err_trie_state_s_created;
+    }
+    if (!trie_state_walk (s, L'p')) {
+        printf ("Failed to walk with 'p'\n");
+        goto err_trie_state_s_created;
+    }
+
+    msg_step ("Now at (2), walkable chars should be {'o', 'r'}");
+    is_failed = FALSE;
+    n = trie_state_walkable_chars (s, walkables, ALPHABET_SIZE);
+    if (2 != n) {
+        printf ("Walkable chars should be exactly 2, got %d\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'o', walkables, n)) {
+        printf ("Walkable chars do not include 'o'\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'r', walkables, n)) {
+        printf ("Walkable chars do not include 'r'\n", n);
+        is_failed = TRUE;
+    }
+    if (is_failed) {
+        printf ("Walkables = ");
+        print_walkables (walkables, n);
+        printf ("\n");
+        goto err_trie_state_s_created;
+    }
+
+    msg_step ("Try walking from (2) with 'o' to (3)");
+    t = trie_state_clone (s);
+    if (!t) {
+        printf ("Failed to clone trie state\n");
+        goto err_trie_state_s_created;
+    }
+    if (!trie_state_walk (t, L'o')) {
+        printf ("Failed to walk from (2) with 'o' to (3)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_single (t)) {
+        printf ("(3) should be single, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+
+    msg_step ("Try walking from (3) with 'o' to (4)");
+    if (!trie_state_walk (t, L'o')) {
+        printf ("Failed to walk from (3) with 'o' to (4)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_single (t)) {
+        printf ("(4) should be single, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+
+    msg_step ("Try walking from (4) with 'l' to (5)");
+    if (!trie_state_walk (t, L'l')) {
+        printf ("Failed to walk from (4) with 'l' to (5)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_terminal (t)) {
+        printf ("(5) should be terminal, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+
+    /* get key & data */
+    msg_step ("Try getting data from (5)");
+    data = trie_state_get_data (t);
+    if (TRIE_DATA_ERROR == data) {
+        printf ("Failed to get data from (5)\n");
+        goto err_trie_state_t_created;
+    }
+    if (TRIE_DATA_UNREAD != data) {
+        printf ("Mismatched data from (5), expected %d, got %d\n",
+                TRIE_DATA_UNREAD, data);
+        goto err_trie_state_t_created;
+    }
+
+    /* walk s from (2) with 'r' to (6) */
+    msg_step ("Try walking from (2) with 'r' to (6)");
+    if (!trie_state_walk (s, L'r')) {
+        printf ("Failed to walk from (2) with 'r' to (6)\n");
+        goto err_trie_state_t_created;
+    }
+
+    msg_step ("Now at (6), walkable chars should be {'e', 'i', 'o'}");
+    is_failed = FALSE;
+    n = trie_state_walkable_chars (s, walkables, ALPHABET_SIZE);
+    if (3 != n) {
+        printf ("Walkable chars should be exactly 3, got %d\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'e', walkables, n)) {
+        printf ("Walkable chars do not include 'e'\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'i', walkables, n)) {
+        printf ("Walkable chars do not include 'i'\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'o', walkables, n)) {
+        printf ("Walkable chars do not include 'o'\n", n);
+        is_failed = TRUE;
+    }
+    if (is_failed) {
+        printf ("Walkables = ");
+        print_walkables (walkables, n);
+        printf ("\n");
+        goto err_trie_state_t_created;
+    }
+
+    /* walk from s (6) with "ize" */
+    msg_step ("Try walking from (6) with 'i' to (7)");
+    trie_state_copy (t, s);
+    if (!trie_state_walk (t, L'i')) {
+        printf ("Failed to walk from (6) with 'i' to (7)\n");
+        goto err_trie_state_t_created;
+    }
+    msg_step ("Try walking from (7) with 'z' to (8)");
+    if (!trie_state_walk (t, L'z')) {
+        printf ("Failed to walk from (7) with 'z' to (8)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_single (t)) {
+        printf ("(7) should be single, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+    msg_step ("Try walking from (8) with 'e' to (9)");
+    if (!trie_state_walk (t, L'e')) {
+        printf ("Failed to walk from (8) with 'e' to (9)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_terminal (t)) {
+        printf ("(9) should be terminal, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+
+    msg_step ("Try getting data from (9)");
+    data = trie_state_get_data (t);
+    if (TRIE_DATA_ERROR == data) {
+        printf ("Failed to get data from (9)\n");
+        goto err_trie_state_t_created;
+    }
+    if (TRIE_DATA_UNREAD != data) {
+        printf ("Mismatched data from (9), expected %d, got %d\n",
+                TRIE_DATA_UNREAD, data);
+        goto err_trie_state_t_created;
+    }
+
+    /* walk from u = s (6) with 'e' to (10) */
+    msg_step ("Try walking from (6) with 'e' to (10)");
+    u = trie_state_clone (s);
+    if (!u) {
+        printf ("Failed to clone trie state\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_walk (u, L'e')) {
+        printf ("Failed to walk from (6) with 'e' to (10)\n");
+        goto err_trie_state_u_created;
+    }
+
+    /* walkable chars from (10) should be {'p', 'v'} */
+    msg_step ("Now at (10), walkable chars should be {'p', 'v'}");
+    is_failed = FALSE;
+    n = trie_state_walkable_chars (u, walkables, ALPHABET_SIZE);
+    if (2 != n) {
+        printf ("Walkable chars should be exactly 2, got %d\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'p', walkables, n)) {
+        printf ("Walkable chars do not include 'p'\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'v', walkables, n)) {
+        printf ("Walkable chars do not include 'v'\n", n);
+        is_failed = TRUE;
+    }
+    if (is_failed) {
+        printf ("Walkables = ");
+        print_walkables (walkables, n);
+        printf ("\n");
+        goto err_trie_state_u_created;
+    }
+
+    /* walk from u (10) with "view" */
+    msg_step ("Try walking from (10) with 'v' to (11)");
+    trie_state_copy (t, u);
+    if (!trie_state_walk (t, L'v')) {
+        printf ("Failed to walk from (10) with 'v' to (11)\n");
+        goto err_trie_state_u_created;
+    }
+    if (!trie_state_is_single (t)) {
+        printf ("(11) should be single, but isn't.\n");
+        goto err_trie_state_u_created;
+    }
+    msg_step ("Try walking from (11) with 'i' to (12)");
+    if (!trie_state_walk (t, L'i')) {
+        printf ("Failed to walk from (11) with 'i' to (12)\n");
+        goto err_trie_state_u_created;
+    }
+    msg_step ("Try walking from (12) with 'e' to (13)");
+    if (!trie_state_walk (t, L'e')) {
+        printf ("Failed to walk from (12) with 'e' to (13)\n");
+        goto err_trie_state_u_created;
+    }
+    msg_step ("Try walking from (13) with 'w' to (14)");
+    if (!trie_state_walk (t, L'w')) {
+        printf ("Failed to walk from (13) with 'w' to (14)\n");
+        goto err_trie_state_u_created;
+    }
+    if (!trie_state_is_terminal (t)) {
+        printf ("(14) should be terminal, but isn't.\n");
+        goto err_trie_state_u_created;
+    }
+
+    msg_step ("Try getting data from (14)");
+    data = trie_state_get_data (t);
+    if (TRIE_DATA_ERROR == data) {
+        printf ("Failed to get data from (14)\n");
+        goto err_trie_state_u_created;
+    }
+    if (TRIE_DATA_UNREAD != data) {
+        printf ("Mismatched data from (14), expected %d, got %d\n",
+                TRIE_DATA_UNREAD, data);
+        goto err_trie_state_u_created;
+    }
+
+    /* walk from u (10) with "pare" */
+    msg_step ("Try walking from (10) with 'p' to (15)");
+    trie_state_copy (t, u);
+    if (!trie_state_walk (t, L'p')) {
+        printf ("Failed to walk from (10) with 'p' to (15)\n");
+        goto err_trie_state_u_created;
+    }
+    if (!trie_state_is_single (t)) {
+        printf ("(15) should be single, but isn't.\n");
+        goto err_trie_state_u_created;
+    }
+    msg_step ("Try walking from (15) with 'a' to (16)");
+    if (!trie_state_walk (t, L'a')) {
+        printf ("Failed to walk from (15) with 'a' to (16)\n");
+        goto err_trie_state_u_created;
+    }
+    msg_step ("Try walking from (16) with 'r' to (17)");
+    if (!trie_state_walk (t, L'r')) {
+        printf ("Failed to walk from (16) with 'r' to (17)\n");
+        goto err_trie_state_u_created;
+    }
+    msg_step ("Try walking from (17) with 'e' to (18)");
+    if (!trie_state_walk (t, L'e')) {
+        printf ("Failed to walk from (17) with 'e' to (18)\n");
+        goto err_trie_state_u_created;
+    }
+    if (!trie_state_is_terminal (t)) {
+        printf ("(18) should be terminal, but isn't.\n");
+        goto err_trie_state_u_created;
+    }
+
+    msg_step ("Try getting data from (18)");
+    data = trie_state_get_data (t);
+    if (TRIE_DATA_ERROR == data) {
+        printf ("Failed to get data from (18)\n");
+        goto err_trie_state_u_created;
+    }
+    if (TRIE_DATA_UNREAD != data) {
+        printf ("Mismatched data from (18), expected %d, got %d\n",
+                TRIE_DATA_UNREAD, data);
+        goto err_trie_state_u_created;
+    }
+
+    trie_state_free (u);
+
+    /* walk s from (6) with 'o' to (19) */
+    msg_step ("Try walking from (6) with 'o' to (19)");
+    if (!trie_state_walk (s, L'o')) {
+        printf ("Failed to walk from (6) with 'o' to (19)\n");
+        goto err_trie_state_t_created;
+    }
+
+    msg_step ("Now at (19), walkable chars should be {'d', 'g'}");
+    is_failed = FALSE;
+    n = trie_state_walkable_chars (s, walkables, ALPHABET_SIZE);
+    if (2 != n) {
+        printf ("Walkable chars should be exactly 2, got %d\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'd', walkables, n)) {
+        printf ("Walkable chars do not include 'd'\n", n);
+        is_failed = TRUE;
+    }
+    if (!is_walkables_include (L'g', walkables, n)) {
+        printf ("Walkable chars do not include 'g'\n", n);
+        is_failed = TRUE;
+    }
+    if (is_failed) {
+        printf ("Walkables = ");
+        print_walkables (walkables, n);
+        printf ("\n");
+        goto err_trie_state_t_created;
+    }
+
+    /* walk from s (19) with "duce" */
+    msg_step ("Try walking from (19) with 'd' to (20)");
+    trie_state_copy (t, s);
+    if (!trie_state_walk (t, L'd')) {
+        printf ("Failed to walk from (19) with 'd' to (20)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_single (t)) {
+        printf ("(20) should be single, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+    msg_step ("Try walking from (20) with 'u' to (21)");
+    if (!trie_state_walk (t, L'u')) {
+        printf ("Failed to walk from (20) with 'u' to (21)\n");
+        goto err_trie_state_t_created;
+    }
+    msg_step ("Try walking from (21) with 'c' to (22)");
+    if (!trie_state_walk (t, L'c')) {
+        printf ("Failed to walk from (21) with 'c' to (22)\n");
+        goto err_trie_state_t_created;
+    }
+    msg_step ("Try walking from (22) with 'e' to (23)");
+    if (!trie_state_walk (t, L'e')) {
+        printf ("Failed to walk from (22) with 'e' to (23)\n");
+        goto err_trie_state_t_created;
+    }
+    if (!trie_state_is_terminal (t)) {
+        printf ("(23) should be terminal, but isn't.\n");
+        goto err_trie_state_t_created;
+    }
+
+    msg_step ("Try getting data from (23)");
+    data = trie_state_get_data (t);
+    if (TRIE_DATA_ERROR == data) {
+        printf ("Failed to get data from (23)\n");
+        goto err_trie_state_t_created;
+    }
+    if (TRIE_DATA_UNREAD != data) {
+        printf ("Mismatched data from (23), expected %d, got %d\n",
+                TRIE_DATA_UNREAD, data);
+        goto err_trie_state_t_created;
+    }
+
+    trie_state_free (t);
+
+    /* walk from s (19) with "gress" */
+    msg_step ("Try walking from (19) with 'g' to (24)");
+    if (!trie_state_walk (s, L'g')) {
+        printf ("Failed to walk from (19) with 'g' to (24)\n");
+        goto err_trie_state_s_created;
+    }
+    if (!trie_state_is_single (s)) {
+        printf ("(24) should be single, but isn't.\n");
+        goto err_trie_state_s_created;
+    }
+    msg_step ("Try walking from (24) with 'r' to (25)");
+    if (!trie_state_walk (s, L'r')) {
+        printf ("Failed to walk from (24) with 'r' to (25)\n");
+        goto err_trie_state_s_created;
+    }
+    msg_step ("Try walking from (25) with 'e' to (26)");
+    if (!trie_state_walk (s, L'e')) {
+        printf ("Failed to walk from (25) with 'e' to (26)\n");
+        goto err_trie_state_s_created;
+    }
+    msg_step ("Try walking from (26) with 's' to (27)");
+    if (!trie_state_walk (s, L's')) {
+        printf ("Failed to walk from (26) with 's' to (27)\n");
+        goto err_trie_state_s_created;
+    }
+    msg_step ("Try walking from (27) with 's' to (28)");
+    if (!trie_state_walk (s, L's')) {
+        printf ("Failed to walk from (27) with 's' to (28)\n");
+        goto err_trie_state_s_created;
+    }
+    if (!trie_state_is_terminal (s)) {
+        printf ("(28) should be terminal, but isn't.\n");
+        goto err_trie_state_s_created;
+    }
+
+    msg_step ("Try getting data from (28)");
+    data = trie_state_get_data (s);
+    if (TRIE_DATA_ERROR == data) {
+        printf ("Failed to get data from (28)\n");
+        goto err_trie_state_s_created;
+    }
+    if (TRIE_DATA_UNREAD != data) {
+        printf ("Mismatched data from (28), expected %d, got %d\n",
+                TRIE_DATA_UNREAD, data);
+        goto err_trie_state_s_created;
+    }
+
+    trie_state_free (s);
+    trie_free (test_trie);
+    return 0;
+
+err_trie_state_u_created:
+    trie_state_free (u);
+err_trie_state_t_created:
+    trie_state_free (t);
+err_trie_state_s_created:
+    trie_state_free (s);
+err_trie_created:
+    trie_free (test_trie);
+err_trie_not_created:
+    return 1;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/tests/utils.c b/tests/utils.c
new file mode 100644 (file)
index 0000000..eeb0468
--- /dev/null
@@ -0,0 +1,168 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2013  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * utils.c - Utility functions for datrie test cases
+ * Created: 2013-10-16
+ * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ */
+
+#include <datrie/trie.h>
+#include "utils.h"
+
+/*---------------------*
+ *  Debugging helpers  *
+ *---------------------*/
+void
+msg_step (const char *msg)
+{
+    printf ("=> %s...\n", msg);
+}
+
+/*-------------------------*
+ *  Trie creation helpers  *
+ *-------------------------*/
+static AlphaMap *
+en_alpha_map_new ()
+{
+    AlphaMap *en_map;
+
+    en_map = alpha_map_new ();
+    if (!en_map)
+        goto err_map_not_created;
+
+    if (alpha_map_add_range (en_map, 0x0061, 0x007a) != 0)
+        goto err_map_created;
+
+    return en_map;
+
+err_map_created:
+    alpha_map_free (en_map);
+err_map_not_created:
+    return NULL;
+}
+
+Trie *
+en_trie_new ()
+{
+    AlphaMap *en_map;
+    Trie     *en_trie;
+
+    en_map = en_alpha_map_new ();
+    if (!en_map)
+        goto err_map_not_created;
+
+    en_trie = trie_new (en_map);
+    if (!en_trie)
+        goto err_map_created;
+
+    alpha_map_free (en_map);
+    return en_trie;
+
+err_map_created:
+    alpha_map_free (en_map);
+err_map_not_created:
+    return NULL;
+}
+
+/*---------------------------*
+ *  Dict source for testing  *
+ *---------------------------*/
+DictRec dict_src[] = {
+    {L"a",          TRIE_DATA_UNREAD},
+    {L"abacus",     TRIE_DATA_UNREAD},
+    {L"abandon",    TRIE_DATA_UNREAD},
+    {L"accident",   TRIE_DATA_UNREAD},
+    {L"accredit",   TRIE_DATA_UNREAD},
+    {L"algorithm",  TRIE_DATA_UNREAD},
+    {L"ammonia",    TRIE_DATA_UNREAD},
+    {L"angel",      TRIE_DATA_UNREAD},
+    {L"angle",      TRIE_DATA_UNREAD},
+    {L"azure",      TRIE_DATA_UNREAD},
+    {L"bat",        TRIE_DATA_UNREAD},
+    {L"bet",        TRIE_DATA_UNREAD},
+    {L"best",       TRIE_DATA_UNREAD},
+    {L"home",       TRIE_DATA_UNREAD},
+    {L"house",      TRIE_DATA_UNREAD},
+    {L"hut",        TRIE_DATA_UNREAD},
+    {L"king",       TRIE_DATA_UNREAD},
+    {L"kite",       TRIE_DATA_UNREAD},
+    {L"name",       TRIE_DATA_UNREAD},
+    {L"net",        TRIE_DATA_UNREAD},
+    {L"network",    TRIE_DATA_UNREAD},
+    {L"nut",        TRIE_DATA_UNREAD},
+    {L"nutshell",   TRIE_DATA_UNREAD},
+    {L"quality",    TRIE_DATA_UNREAD},
+    {L"quantum",    TRIE_DATA_UNREAD},
+    {L"quantity",   TRIE_DATA_UNREAD},
+    {L"quartz",     TRIE_DATA_UNREAD},
+    {L"quick",      TRIE_DATA_UNREAD},
+    {L"quiz",       TRIE_DATA_UNREAD},
+    {L"run",        TRIE_DATA_UNREAD},
+    {L"tape",       TRIE_DATA_UNREAD},
+    {L"test",       TRIE_DATA_UNREAD},
+    {L"what",       TRIE_DATA_UNREAD},
+    {L"when",       TRIE_DATA_UNREAD},
+    {L"where",      TRIE_DATA_UNREAD},
+    {L"which",      TRIE_DATA_UNREAD},
+    {L"who",        TRIE_DATA_UNREAD},
+    {L"why",        TRIE_DATA_UNREAD},
+    {L"zebra",      TRIE_DATA_UNREAD},
+    {NULL,          TRIE_DATA_ERROR},
+};
+
+int
+dict_src_n_entries ()
+{
+    return sizeof (dict_src) / sizeof (dict_src[0]) - 1;
+}
+
+TrieData
+dict_src_get_data (const AlphaChar *key)
+{
+    const DictRec *dict_p;
+
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (alpha_char_strcmp (dict_p->key, key) == 0) {
+            return dict_p->data;
+        }
+    }
+
+    return TRIE_DATA_ERROR;
+}
+
+int
+dict_src_set_data (const AlphaChar *key, TrieData data)
+{
+    DictRec *dict_p;
+
+    for (dict_p = dict_src; dict_p->key; dict_p++) {
+        if (alpha_char_strcmp (dict_p->key, key) == 0) {
+            dict_p->data = data;
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+/*
+vi:ts=4:ai:expandtab
+*/
diff --git a/tests/utils.h b/tests/utils.h
new file mode 100644 (file)
index 0000000..2fc957c
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * libdatrie - Double-Array Trie Library
+ * Copyright (C) 2013  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * utils.h - Utility functions for datrie test cases
+ * Created: 2013-10-16
+ * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net>
+ */
+
+#include <datrie/trie.h>
+
+/*---------------------*
+ *  Debugging helpers  *
+ *---------------------*/
+void msg_step (const char *msg);
+
+/*-------------------------*
+ *  Trie creation helpers  *
+ *-------------------------*/
+Trie * en_trie_new ();
+
+/*---------------------------*
+ *  Dict source for testing  *
+ *---------------------------*/
+typedef struct _DictRec DictRec;
+struct _DictRec {
+    AlphaChar *key;
+    TrieData   data;
+};
+
+#define TRIE_DATA_UNREAD    1
+#define TRIE_DATA_READ      2
+
+extern DictRec dict_src[];
+
+int      dict_src_n_entries ();
+TrieData dict_src_get_data (const AlphaChar *key);
+int      dict_src_set_data (const AlphaChar *key, TrieData data);
+
+/*
+vi:ts=4:ai:expandtab
+*/
index 4f44b2f..8d30622 100644 (file)
@@ -1,4 +1,4 @@
-INCLUDES = -I$(top_srcdir)
+AM_CPPFLAGS = -I$(top_srcdir)
 
 bin_PROGRAMS = trietool-0.2